Ignore:
Timestamp:
Jun 22, 2010, 5:25:03 AM (15 years ago)
Author:
[email protected]
Message:

Add native call support for ARM and Thumb-2 JIT.
https://bugs.webkit.org/show_bug.cgi?id=40231

Reviewed by Geoffrey Garen.

  • jit/JITOpcodes.cpp:

(JSC::JIT::privateCompileCTINativeCall):

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::privateCompileCTINativeCall):

  • wtf/Platform.h:
File:
1 edited

Legend:

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

    r61588 r61614  
    197197    Label nativeCallThunk = align();
    198198
     199#if CPU(X86)
    199200    // Load caller frame's scope chain into this callframe so that whatever we call can
    200201    // get to its global data.
     
    206207    emitPutToCallFrameHeader(regT1, RegisterFile::ReturnPC);
    207208
    208 #if CPU(X86)
    209209    // Calling convention:      f(ecx, edx, ...);
    210210    // Host function signature: f(ExecState*);
     
    220220
    221221    addPtr(Imm32(16 - sizeof(void*)), stackPointerRegister);
     222
     223#elif CPU(ARM)
     224    // Load caller frame's scope chain into this callframe so that whatever we call can
     225    // get to its global data.
     226    emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT2);
     227    emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT2);
     228    emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
     229
     230    preserveReturnAddressAfterCall(regT3); // Callee preserved
     231    emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC);
     232
     233    // Calling convention:      f(r0 == regT0, r1 == regT1, ...);
     234    // Host function signature: f(ExecState*);
     235    move(callFrameRegister, ARMRegisters::r0);
     236
     237    // call the function
     238    emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, ARMRegisters::r1);
     239    move(regT2, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
     240    loadPtr(Address(ARMRegisters::r1, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
     241    call(Address(regT2, executableOffsetToFunction));
     242
     243    restoreReturnAddressBeforeReturn(regT3);
    222244
    223245#elif ENABLE(JIT_OPTIMIZE_NATIVE_CALL)
     
    236258    // Handle an exception
    237259    sawException.link(this);
    238     peek(regT1);
     260
     261    // Grab the return address.
     262    preserveReturnAddressAfterCall(regT1);
     263
    239264    move(ImmPtr(&globalData->exceptionLocation), regT2);
    240265    storePtr(regT1, regT2);
    241     poke(callFrameRegister, 1 + OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*));
    242     poke(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()));
     266    poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*));
     267
     268    // Set the return address.
     269    move(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), regT1);
     270    restoreReturnAddressBeforeReturn(regT1);
     271
    243272    ret();
    244273
     
    274303    addPtr(Imm32(16 - sizeof(void*)), stackPointerRegister);
    275304
     305#elif CPU(ARM)
     306    // Load caller frame's scope chain into this callframe so that whatever we call can
     307    // get to its global data.
     308    emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT2);
     309    emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT2);
     310    emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
     311
     312    preserveReturnAddressAfterCall(regT3); // Callee preserved
     313    emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC);
     314
     315    // Calling convention:      f(r0 == regT0, r1 == regT1, ...);
     316    // Host function signature: f(ExecState*);
     317    move(callFrameRegister, ARMRegisters::r0);
     318
     319    emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, ARMRegisters::r1);
     320    move(regT2, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
     321    loadPtr(Address(ARMRegisters::r1, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
     322
     323    // call the function
     324    nativeCall = call();
     325
     326    restoreReturnAddressBeforeReturn(regT3);
     327
    276328#elif ENABLE(JIT_OPTIMIZE_NATIVE_CALL)
    277329#error "JIT_OPTIMIZE_NATIVE_CALL not yet supported on this platform."
     
    288340    // Handle an exception
    289341    sawException.link(this);
    290     peek(regT1);
     342
     343    // Grab the return address.
     344    preserveReturnAddressAfterCall(regT1);
     345
    291346    move(ImmPtr(&globalData->exceptionLocation), regT2);
    292347    storePtr(regT1, regT2);
    293     poke(callFrameRegister, 1 + OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*));
    294     poke(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()));
     348    poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*));
     349
     350    // Set the return address.
     351    move(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), regT1);
     352    restoreReturnAddressBeforeReturn(regT1);
     353
    295354    ret();
    296355
Note: See TracChangeset for help on using the changeset viewer.