diff options
author | Kristian Monsen <kristianm@google.com> | 2010-06-28 16:42:48 +0100 |
---|---|---|
committer | Kristian Monsen <kristianm@google.com> | 2010-07-02 10:29:56 +0100 |
commit | 06ea8e899e48f1f2f396b70e63fae369f2f23232 (patch) | |
tree | 20c1428cd05c76f32394ab354ea35ed99acd86d8 /JavaScriptCore/jit/JITOpcodes32_64.cpp | |
parent | 72aad67af14193199e29cdd5c4ddc095a8b9a8a8 (diff) | |
download | external_webkit-06ea8e899e48f1f2f396b70e63fae369f2f23232.zip external_webkit-06ea8e899e48f1f2f396b70e63fae369f2f23232.tar.gz external_webkit-06ea8e899e48f1f2f396b70e63fae369f2f23232.tar.bz2 |
Merge WebKit at r61871: Initial merge by git.
Change-Id: I6cff43abca9cc4782e088a469ad4f03f166a65d5
Diffstat (limited to 'JavaScriptCore/jit/JITOpcodes32_64.cpp')
-rw-r--r-- | JavaScriptCore/jit/JITOpcodes32_64.cpp | 94 |
1 files changed, 84 insertions, 10 deletions
diff --git a/JavaScriptCore/jit/JITOpcodes32_64.cpp b/JavaScriptCore/jit/JITOpcodes32_64.cpp index 239751f..a44a8a1 100644 --- a/JavaScriptCore/jit/JITOpcodes32_64.cpp +++ b/JavaScriptCore/jit/JITOpcodes32_64.cpp @@ -66,8 +66,8 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable #endif // (2) Trampolines for the slow cases of op_call / op_call_eval / op_construct. - #if ENABLE(JIT_OPTIMIZE_CALL) + JumpList callLazyLinkFailures; // VirtualCallLink Trampoline // regT0 holds callee, regT1 holds argCount. regT2 will hold the FunctionExecutable. Label virtualCallLinkBegin = align(); @@ -76,6 +76,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC); restoreArgumentReference(); Call callLazyLinkCall = call(); + callLazyLinkFailures.append(branchTestPtr(Zero, regT0)); restoreReturnAddressBeforeReturn(regT3); emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT1); jump(regT0); @@ -89,8 +90,22 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable restoreArgumentReference(); Call callLazyLinkConstruct = call(); restoreReturnAddressBeforeReturn(regT3); + callLazyLinkFailures.append(branchTestPtr(Zero, regT0)); emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT1); jump(regT0); + + // If the parser fails we want to be able to be able to keep going, + // So we handle this as a parse failure. + callLazyLinkFailures.link(this); + emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1); + emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); + restoreReturnAddressBeforeReturn(regT1); + move(ImmPtr(&globalData->exceptionLocation), regT2); + storePtr(regT1, regT2); + poke(callFrameRegister, 1 + OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*)); + poke(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value())); + ret(); + #endif // ENABLE(JIT_OPTIMIZE_CALL) // VirtualCall Trampoline @@ -181,6 +196,7 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon Label nativeCallThunk = align(); +#if CPU(X86) // Load caller frame's scope chain into this callframe so that whatever we call can // get to its global data. emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT0); @@ -190,7 +206,6 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon peek(regT1); emitPutToCallFrameHeader(regT1, RegisterFile::ReturnPC); -#if CPU(X86) // Calling convention: f(ecx, edx, ...); // Host function signature: f(ExecState*); move(callFrameRegister, X86Registers::ecx); @@ -205,6 +220,28 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon addPtr(Imm32(16 - sizeof(void*)), stackPointerRegister); +#elif CPU(ARM) + // Load caller frame's scope chain into this callframe so that whatever we call can + // get to its global data. + emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT2); + emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT2); + emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain); + + preserveReturnAddressAfterCall(regT3); // Callee preserved + emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC); + + // Calling convention: f(r0 == regT0, r1 == regT1, ...); + // Host function signature: f(ExecState*); + move(callFrameRegister, ARMRegisters::r0); + + // call the function + emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, ARMRegisters::r1); + move(regT2, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack. + loadPtr(Address(ARMRegisters::r1, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); + call(Address(regT2, executableOffsetToFunction)); + + restoreReturnAddressBeforeReturn(regT3); + #elif ENABLE(JIT_OPTIMIZE_NATIVE_CALL) #error "JIT_OPTIMIZE_NATIVE_CALL not yet supported on this platform." #else @@ -220,11 +257,18 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon // Handle an exception sawException.link(this); - peek(regT1); + + // Grab the return address. + preserveReturnAddressAfterCall(regT1); + move(ImmPtr(&globalData->exceptionLocation), regT2); storePtr(regT1, regT2); - poke(callFrameRegister, 1 + OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*)); - poke(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value())); + poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*)); + + // Set the return address. + move(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), regT1); + restoreReturnAddressBeforeReturn(regT1); + ret(); return nativeCallThunk; @@ -258,6 +302,29 @@ JIT::CodePtr JIT::privateCompileCTINativeCall(PassRefPtr<ExecutablePool> executa addPtr(Imm32(16 - sizeof(void*)), stackPointerRegister); +#elif CPU(ARM) + // Load caller frame's scope chain into this callframe so that whatever we call can + // get to its global data. + emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT2); + emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT2); + emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain); + + preserveReturnAddressAfterCall(regT3); // Callee preserved + emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC); + + // Calling convention: f(r0 == regT0, r1 == regT1, ...); + // Host function signature: f(ExecState*); + move(callFrameRegister, ARMRegisters::r0); + + emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, ARMRegisters::r1); + move(regT2, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack. + loadPtr(Address(ARMRegisters::r1, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); + + // call the function + nativeCall = call(); + + restoreReturnAddressBeforeReturn(regT3); + #elif ENABLE(JIT_OPTIMIZE_NATIVE_CALL) #error "JIT_OPTIMIZE_NATIVE_CALL not yet supported on this platform." #else @@ -272,11 +339,18 @@ JIT::CodePtr JIT::privateCompileCTINativeCall(PassRefPtr<ExecutablePool> executa // Handle an exception sawException.link(this); - peek(regT1); + + // Grab the return address. + preserveReturnAddressAfterCall(regT1); + move(ImmPtr(&globalData->exceptionLocation), regT2); storePtr(regT1, regT2); - poke(callFrameRegister, 1 + OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*)); - poke(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value())); + poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*)); + + // Set the return address. + move(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), regT1); + restoreReturnAddressBeforeReturn(regT1); + ret(); // All trampolines constructed! copy the code, link up calls, and set the pointers on the Machine object. @@ -607,8 +681,8 @@ void JIT::emit_op_resolve_global(Instruction* currentInstruction, bool dynamic) // Load property. loadPtr(Address(regT0, OBJECT_OFFSETOF(JSGlobalObject, m_externalStorage)), regT2); load32(offsetAddr, regT3); - load32(BaseIndex(regT2, regT3, TimesEight), regT0); // payload - load32(BaseIndex(regT2, regT3, TimesEight, 4), regT1); // tag + load32(BaseIndex(regT2, regT3, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0); // payload + load32(BaseIndex(regT2, regT3, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1); // tag emitStore(dst, regT1, regT0); map(m_bytecodeOffset + dynamic ? OPCODE_LENGTH(op_resolve_global_dynamic) : OPCODE_LENGTH(op_resolve_global), dst, regT1, regT0); } |