Ignore:
Timestamp:
May 9, 2010, 4:42:22 AM (15 years ago)
Author:
[email protected]
Message:

2010-05-09 Oliver Hunt <[email protected]>

Reviewed by Maciej Stachowiak.

Improve string indexing performance
https://bugs.webkit.org/show_bug.cgi?id=38814

Add an assembly stub to do indexed loads from strings much
more cheaply than the current stub dispatch logic. We can
do this because we are able to make guarantees about the
register contents when entering the stub so the call overhead
is negligible.

  • jit/JIT.h:
  • jit/JITInlineMethods.h:
  • jit/JITOpcodes.cpp:
  • jit/JITPropertyAccess.cpp: (JSC::JIT::stringGetByValStubGenerator): (JSC::JIT::emitSlow_op_get_by_val):

Moved from JITOpcodes.cpp to keep the slowcase next to
the normal case codegen as we do for everything else.

  • jit/JITPropertyAccess32_64.cpp: (JSC::JIT::stringGetByValStubGenerator): (JSC::JIT::emitSlow_op_get_by_val):
  • jit/JSInterfaceJIT.h: (JSC::JSInterfaceJIT::emitFastArithImmToInt):
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/jit/JITPropertyAccess32_64.cpp

    r55564 r59056  
    270270#endif
    271271
     272PassRefPtr<NativeExecutable> JIT::stringGetByValStubGenerator(JSGlobalData* globalData, ExecutablePool* pool)
     273{
     274    JSInterfaceJIT jit;
     275    JumpList failures;
     276    failures.append(jit.branchPtr(NotEqual, Address(regT0), ImmPtr(globalData->jsStringVPtr)));
     277    failures.append(jit.branchTest32(NonZero, Address(regT0, OBJECT_OFFSETOF(JSString, m_fiberCount))));
     278   
     279    // Load string length to regT1, and start the process of loading the data pointer into regT0
     280    jit.load32(Address(regT0, ThunkHelpers::jsStringLengthOffset()), regT1);
     281    jit.loadPtr(Address(regT0, ThunkHelpers::jsStringValueOffset()), regT0);
     282    jit.loadPtr(Address(regT0, ThunkHelpers::stringImplDataOffset()), regT0);
     283   
     284    // Do an unsigned compare to simultaneously filter negative indices as well as indices that are too large
     285    failures.append(jit.branch32(AboveOrEqual, regT2, regT1));
     286   
     287    // Load the character
     288    jit.load16(BaseIndex(regT0, regT2, TimesTwo, 0), regT0);
     289   
     290    failures.append(jit.branch32(AboveOrEqual, regT0, Imm32(0x100)));
     291    jit.move(ImmPtr(globalData->smallStrings.singleCharacterStrings()), regT1);
     292    jit.loadPtr(BaseIndex(regT1, regT0, ScalePtr, 0), regT0);
     293    jit.move(Imm32(JSValue::CellTag), regT1); // We null check regT0 on return so this is safe
     294    jit.ret();
     295
     296    failures.link(&jit);
     297    jit.move(Imm32(0), regT0);
     298    jit.ret();
     299   
     300    LinkBuffer patchBuffer(&jit, pool);
     301    return adoptRef(new NativeExecutable(patchBuffer.finalizeCode()));
     302}
     303
    272304void JIT::emit_op_get_by_val(Instruction* currentInstruction)
    273305{
     
    301333    linkSlowCase(iter); // property int32 check
    302334    linkSlowCaseIfNotJSCell(iter, base); // base cell check
     335
     336    Jump nonCell = jump();
    303337    linkSlowCase(iter); // base array check
     338    Jump notString = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr));
     339    emitNakedCall(m_globalData->getThunk(stringGetByValStubGenerator)->generatedJITCode().addressForCall());
     340    Jump failed = branchTestPtr(Zero, regT0);
     341    emitStore(dst, regT1, regT0);
     342    emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_get_by_val));
     343    failed.link(this);
     344    notString.link(this);
     345    nonCell.link(this);
     346
    304347    linkSlowCase(iter); // vector length check
    305348    linkSlowCase(iter); // empty value
Note: See TracChangeset for help on using the changeset viewer.