Change callToJavaScript thunk into an offline assembled stub
authormsaboff@apple.com <msaboff@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 14 Nov 2013 07:39:30 +0000 (07:39 +0000)
committermsaboff@apple.com <msaboff@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 14 Nov 2013 07:39:30 +0000 (07:39 +0000)
https://bugs.webkit.org/show_bug.cgi?id=124251

Reviewed by Geoffrey Garen.

Changed callToJavaScript and throwNotCaught into stubs generated by the offline assembler.
Added popCalleeSaves and pushCalleeSaves pseudo ops to the offline assembler to handle
the saving and restoring of callee save registers.  Fixed callFrameRegister differences
between arm traditional (r11) and arm Thumb2 (r7) in GPRInfo.h.  Also fixed implementation
of pop & push in arm.rb.

Since the offline assembler and therefore the LLInt don't work on Windows, the Windows stubs
are handled as inline assembly in JITStubsX86.h and JITStubsMSVC64.asm.

* dfg/DFGDriver.cpp:
(JSC::DFG::compileImpl):
* jit/GPRInfo.h:
(JSC::GPRInfo::toIndex):
(JSC::GPRInfo::debugName):
* jit/JITCode.cpp:
(JSC::JITCode::execute):
* jit/JITExceptions.cpp:
(JSC::genericUnwind):
* jit/JITStubs.h:
* jit/JITStubsMSVC64.asm:
* jit/JITStubsX86.h:
* jit/ThunkGenerators.cpp:
* jit/ThunkGenerators.h:
* llint/LLIntThunks.h:
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* offlineasm/arm.rb:
* offlineasm/arm64.rb:
* offlineasm/instructions.rb:
* offlineasm/mips.rb:
* offlineasm/registers.rb:
* offlineasm/sh4.rb:
* offlineasm/x86.rb:
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@159276 268f45cc-cd09-0410-ab3c-d52691b4dbfc

23 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGDriver.cpp
Source/JavaScriptCore/jit/GPRInfo.h
Source/JavaScriptCore/jit/JITCode.cpp
Source/JavaScriptCore/jit/JITExceptions.cpp
Source/JavaScriptCore/jit/JITStubs.h
Source/JavaScriptCore/jit/JITStubsMSVC64.asm
Source/JavaScriptCore/jit/JITStubsX86.h
Source/JavaScriptCore/jit/ThunkGenerators.cpp
Source/JavaScriptCore/jit/ThunkGenerators.h
Source/JavaScriptCore/llint/LLIntThunks.h
Source/JavaScriptCore/llint/LowLevelInterpreter.asm
Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
Source/JavaScriptCore/offlineasm/arm.rb
Source/JavaScriptCore/offlineasm/arm64.rb
Source/JavaScriptCore/offlineasm/instructions.rb
Source/JavaScriptCore/offlineasm/mips.rb
Source/JavaScriptCore/offlineasm/registers.rb
Source/JavaScriptCore/offlineasm/sh4.rb
Source/JavaScriptCore/offlineasm/x86.rb
Source/JavaScriptCore/runtime/VM.cpp
Source/JavaScriptCore/runtime/VM.h

index 196d7c0..cbd8fc6 100644 (file)
@@ -1,3 +1,48 @@
+2013-11-13  Michael Saboff  <msaboff@apple.com>
+
+        Change callToJavaScript thunk into an offline assembled stub
+        https://bugs.webkit.org/show_bug.cgi?id=124251
+
+        Reviewed by Geoffrey Garen.
+
+        Changed callToJavaScript and throwNotCaught into stubs generated by the offline assembler.
+        Added popCalleeSaves and pushCalleeSaves pseudo ops to the offline assembler to handle
+        the saving and restoring of callee save registers.  Fixed callFrameRegister differences
+        between arm traditional (r11) and arm Thumb2 (r7) in GPRInfo.h.  Also fixed implementation
+        of pop & push in arm.rb.
+
+        Since the offline assembler and therefore the LLInt don't work on Windows, the Windows stubs
+        are handled as inline assembly in JITStubsX86.h and JITStubsMSVC64.asm.
+
+        * dfg/DFGDriver.cpp:
+        (JSC::DFG::compileImpl):
+        * jit/GPRInfo.h:
+        (JSC::GPRInfo::toIndex):
+        (JSC::GPRInfo::debugName):
+        * jit/JITCode.cpp:
+        (JSC::JITCode::execute):
+        * jit/JITExceptions.cpp:
+        (JSC::genericUnwind):
+        * jit/JITStubs.h:
+        * jit/JITStubsMSVC64.asm:
+        * jit/JITStubsX86.h:
+        * jit/ThunkGenerators.cpp:
+        * jit/ThunkGenerators.h:
+        * llint/LLIntThunks.h:
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * offlineasm/arm.rb:
+        * offlineasm/arm64.rb:
+        * offlineasm/instructions.rb:
+        * offlineasm/mips.rb:
+        * offlineasm/registers.rb:
+        * offlineasm/sh4.rb:
+        * offlineasm/x86.rb:
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+
 2013-11-13  Andy Estes  <aestes@apple.com>
 
         Fix the ARM64 build after recent JavaScriptCore changes
index f749bc1..a81f7f2 100644 (file)
@@ -78,8 +78,6 @@ static CompilationResult compileImpl(
     
     // Make sure that any stubs that the DFG is going to use are initialized. We want to
     // make sure that all JIT code generation does finalization on the main thread.
-    vm.getCTIStub(callToJavaScript);
-    vm.getCTIStub(throwNotCaught);
     vm.getCTIStub(osrExitGenerationThunkGenerator);
     vm.getCTIStub(throwExceptionFromCallSlowPathGenerator);
     vm.getCTIStub(linkCallThunkGenerator);
index 62158c8..7b1a45e 100644 (file)
@@ -460,7 +460,11 @@ public:
     static const GPRReg regT4 = ARMRegisters::r8;
     static const GPRReg regT5 = ARMRegisters::r9;
     static const GPRReg regT6 = ARMRegisters::r10;
-    static const GPRReg regT7 = ARMRegisters::r5;
+#if CPU(ARM_THUMB2)
+    static const GPRReg regT7 = ARMRegisters::r11;
+#else 
+    static const GPRReg regT7 = ARMRegisters::r7;
+#endif
     static const GPRReg regT8 = ARMRegisters::r3;
     // These registers match the baseline JIT.
     static const GPRReg cachedResultRegister = regT0;
@@ -488,8 +492,13 @@ public:
     static unsigned toIndex(GPRReg reg)
     {
         ASSERT(reg != InvalidGPRReg);
-        ASSERT(reg < 16);
-        static const unsigned indexForRegister[16] = { 0, 1, 2, 8, 3, 7, InvalidIndex, InvalidIndex, 4, 5, 6, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex };
+        ASSERT(static_cast<int>(reg) < 16);
+        static const unsigned indexForRegister[16] =
+#if CPU(ARM_THUMB2)
+            { 0, 1, 2, 8, 3, 9, InvalidIndex, InvalidIndex, 4, 5, 6, 7, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex };
+#else
+            { 0, 1, 2, 8, 3, 9, InvalidIndex, 7, 4, 5, 6, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex };
+#endif
         unsigned result = indexForRegister[reg];
         ASSERT(result != InvalidIndex);
         return result;
@@ -498,7 +507,7 @@ public:
     static const char* debugName(GPRReg reg)
     {
         ASSERT(reg != InvalidGPRReg);
-        ASSERT(reg < 16);
+        ASSERT(static_cast<int>(reg) < 16);
         static const char* nameForRegister[16] = {
             "r0", "r1", "r2", "r3",
             "r4", "r5", "r6", "r7",
index 1f48979..edab1a5 100644 (file)
@@ -26,8 +26,8 @@
 #include "config.h"
 #include "JITCode.h"
 
+#include "LLIntThunks.h"
 #include "Operations.h"
-#include "ThunkGenerators.h"
 #include <wtf/PrintStream.h>
 
 namespace JSC {
@@ -46,7 +46,7 @@ JSValue JITCode::execute(JSStack* stack, CallFrame* callFrame, VM* vm)
 {
     UNUSED_PARAM(stack);
 
-    JSValue result = JSValue::decode(vm->callJavaScriptJITFunction(executableAddress(), callFrame));
+    JSValue result = JSValue::decode(callToJavaScript(executableAddress(), callFrame));
     return vm->exception() ? jsNull() : result;
 }
 #endif
index 510f3b1..fc72f06 100644 (file)
@@ -30,7 +30,9 @@
 #include "CallFrameInlines.h"
 #include "CodeBlock.h"
 #include "Interpreter.h"
+#include "JITStubs.h"
 #include "JSCJSValue.h"
+#include "LLIntThunks.h"
 #include "VM.h"
 #include "Operations.h"
 
@@ -49,7 +51,7 @@ void genericUnwind(VM* vm, ExecState* callFrame, JSValue exceptionValue)
         catchPCForInterpreter = &callFrame->codeBlock()->instructions()[handler->target];
         catchRoutine = ExecutableBase::catchRoutineFor(handler, catchPCForInterpreter);
     } else
-        catchRoutine = vm->getCTIStub(throwNotCaught).code().executableAddress();
+        catchRoutine = FunctionPtr(LLInt::getCodePtr(returnFromJavaScript)).value();
     
     vm->callFrameForThrow = callFrame;
     vm->targetMachinePCForThrow = catchRoutine;
index 006adae..b0e7171 100644 (file)
 #ifndef JITStubs_h
 #define JITStubs_h
 
+#include "JSCJSValue.h"
+
 namespace JSC {
 
 #if ENABLE(JIT)
 
+#if OS(WINDOWS)
+class ExecState;
+
+extern "C" {
+    EncodedJSValue callToJavaScript(void*, ExecState*);
+    void returnFromJavaScript();
+}
+#endif
+
 #if USE(MASM_PROBE)
 extern "C" void ctiMasmProbeTrampoline();
 #endif
index 83db05f..2537d1e 100644 (file)
 
 EXTERN getHostCallReturnValueWithExecState : near
 
+PUBLIC callToJavaScript
+PUBLIC returnFromJavaScript
 PUBLIC getHostCallReturnValue
 
 _TEXT   SEGMENT
 
+callToJavaScript PROC
+    push rbp
+    mov rbp, rax ; Save previous frame pointer
+    mov rbp, rsp
+    push r12
+    push r13
+    push r14
+    push r15
+    push rbx
+
+    ; JIT operations can use up to 6 args (4 in registers and 2 on the stack).
+    ; In addition, X86_64 ABI specifies that the worse case stack alignment
+    ; requirement is 32 bytes. Based on these factors, we need to pad the stack
+    ; an additional 28h bytes.
+    sub rsp, 28h
+    mov rbp, rdx
+    mov r11, qword ptr[rbp] ; Put the previous frame pointer in the sentinel call frame above us
+    mov qword ptr[r11], rax
+    mov r14, 0FFFF000000000000h
+    mov r15, 0FFFF000000000002h
+    call rcx
+    add rsp, 28h
+    pop rbx
+    pop r15
+    pop r14
+    pop r13
+    pop r12
+    pop rbp
+    ret
+callToJavaScript ENDP
+
+returnFromJavaScript PROC
+    add rsp, 28h
+    pop rbx
+    pop r15
+    pop r14
+    pop r13
+    pop r12
+    pop rbp
+    ret
+returnFromJavaScript ENDP
+       
 getHostCallReturnValue PROC
     sub r13, 40
     mov r13, rdi
index dddb219..d107a3b 100644 (file)
@@ -200,6 +200,50 @@ SYMBOL_STRING(ctiMasmProbeTrampolineEnd) ":" "\n"
 
 #endif // COMPILER(GCC)
 
+#if COMPILER(MSVC)
+
+extern "C" {
+
+    // FIXME: Since Windows doesn't use the LLInt, we have inline stubs here.
+    // Until the LLInt is changed to support Windows, these stub needs to be updated.
+    __declspec(naked) EncodedJSValue callToJavaScript(void* code, ExecState*)
+    {
+        __asm {
+            push ebp;
+            mov eax, ebp;
+            mov ebp, esp;
+            push esi;
+            push edi;
+            push ebx;
+            sub esp, 0x1c;
+            mov ebp, [esp + 0x34];
+            mov ebx, [ebp];
+            mov [ebx], eax;
+            call [esp + 0x30];
+            add esp, 0x1c;
+            pop ebx;
+            pop edi;
+            pop esi;
+            pop ebp;
+            ret;
+        }
+    }
+
+    __declspec(naked) void returnFromJavaScript()
+    {
+        __asm {
+            add esp, 0x1c;
+            pop ebx;
+            pop edi;
+            pop esi;
+            pop ebp;
+            ret;
+        }
+    }
+}
+
+#endif // COMPILER(MSVC)
+
 } // namespace JSC
 
 #endif // JITStubsX86_h
index 314b9a3..36aa9fe 100644 (file)
@@ -56,277 +56,6 @@ inline void emitPointerValidation(CCallHelpers& jit, GPRReg pointerGPR)
 #endif
 }
 
-static void returnFromJavaScript(CCallHelpers& jit)
-{
-#if CPU(X86_64)
-#if OS(WINDOWS)
-    // JIT operations can use up to 6 args (4 in registers and 2 on the stack).
-    // In addition, X86_64 ABI specifies that the worse case stack alignment
-    // requirement is 32 bytes. Based on these factors, we need to pad the stack
-    // and additional 40 bytes.
-#   define EXTRA_STACK_SIZE              40
-    jit.addPtr(CCallHelpers::TrustedImm32(8), X86Registers::esp);
-#else
-    // We don't need extra stack space for out-going args, but we need to align the
-    // stack to 32 byte alignment, therefore add 8 bytes to the stack.
-#   define EXTRA_STACK_SIZE              8
-    jit.addPtr(CCallHelpers::TrustedImm32(EXTRA_STACK_SIZE), X86Registers::esp);
-#endif
-
-    jit.pop(X86Registers::ebx);
-    jit.pop(X86Registers::r15);
-    jit.pop(X86Registers::r14);
-    jit.pop(X86Registers::r13);
-    jit.pop(X86Registers::r12);
-    jit.pop(X86Registers::ebp);
-#elif CPU(X86)
-    // JIT Operation can use up to 6 arguments right now. So, we need to
-    // reserve space in this stack frame for the out-going args. To ensure that
-    // the stack remains aligned on an 16 byte boundary, we round the padding up
-    // by 28 bytes.
-#   define EXTRA_STACK_SIZE 28
-
-    jit.addPtr(CCallHelpers::TrustedImm32(EXTRA_STACK_SIZE), X86Registers::esp);
-
-    jit.pop(X86Registers::ebx);
-    jit.pop(X86Registers::edi);
-    jit.pop(X86Registers::esi);
-    jit.pop(X86Registers::ebp);
-#elif CPU(ARM_TRADITIONAL)
-    // JIT Operation can use up to 6 arguments right now. So, we need to
-    // reserve space in this stack frame for the out-going args. We need to
-    // add space for 16 more bytes.
-#   define EXTRA_STACK_SIZE              16
-
-    jit.addPtr(CCallHelpers::TrustedImm32(EXTRA_STACK_SIZE), ARMRegisters::sp);
-
-    jit.pop(ARMRegisters::lr);
-    jit.pop(ARMRegisters::r11);
-    jit.pop(ARMRegisters::r10);
-    jit.pop(ARMRegisters::r9);
-    jit.pop(ARMRegisters::r8);
-    jit.pop(ARMRegisters::r6);
-    jit.pop(ARMRegisters::r5);
-    jit.pop(ARMRegisters::r4);
-#elif CPU(ARM_THUMB2)
-    // JIT Operation can use up to 6 arguments right now. So, we need to
-    // reserve space in this stack frame for the out-going args. To ensure that
-    // the stack remains aligned on an 16 byte boundary, we round the padding up
-    // by 28 bytes.
-#   define EXTRA_STACK_SIZE              28
-
-    jit.addPtr(CCallHelpers::TrustedImm32(EXTRA_STACK_SIZE), ARMRegisters::sp);
-    jit.pop(ARMRegisters::r11);
-    jit.pop(ARMRegisters::r10);
-    jit.pop(ARMRegisters::r9);
-    jit.pop(ARMRegisters::r8);
-    jit.pop(ARMRegisters::r7);
-    jit.pop(ARMRegisters::r6);
-    jit.pop(ARMRegisters::r5);
-    jit.pop(ARMRegisters::r4);
-    jit.pop(ARMRegisters::lr);
-#elif CPU(ARM64)
-    jit.pop(ARM64Registers::x28);
-    jit.pop(ARM64Registers::x27);
-    jit.pop(ARM64Registers::x26);
-    jit.pop(ARM64Registers::x25);
-    jit.pop(ARM64Registers::x24);
-    jit.pop(ARM64Registers::x23);
-    jit.pop(ARM64Registers::x22);
-    jit.pop(ARM64Registers::x21);
-    jit.pop(ARM64Registers::x20);
-    jit.pop(ARM64Registers::x19);
-    jit.pop(ARM64Registers::lr);
-#elif CPU(MIPS)
-#   define PRESERVED_GP_OFFSET         60
-#   define PRESERVED_S0_OFFSET         64
-#   define PRESERVED_S1_OFFSET         68
-#   define PRESERVED_S2_OFFSET         72
-#   define PRESERVED_S3_OFFSET         76
-#   define PRESERVED_S4_OFFSET         80
-#   define PRESERVED_RETURN_ADDRESS_OFFSET 84
-#   define PRESERVED_FP_OFFSET         88
-#   define STACK_LENGTH               112
-
-    jit.loadPtr(CCallHelpers::Address(MIPSRegisters::sp, PRESERVED_S0_OFFSET), MIPSRegisters::s0);
-    jit.loadPtr(CCallHelpers::Address(MIPSRegisters::sp, PRESERVED_S1_OFFSET), MIPSRegisters::s1);
-    jit.loadPtr(CCallHelpers::Address(MIPSRegisters::sp, PRESERVED_S2_OFFSET), MIPSRegisters::s2);
-    jit.loadPtr(CCallHelpers::Address(MIPSRegisters::sp, PRESERVED_S3_OFFSET), MIPSRegisters::s3);
-    jit.loadPtr(CCallHelpers::Address(MIPSRegisters::sp, PRESERVED_S4_OFFSET), MIPSRegisters::s4);
-    jit.loadPtr(CCallHelpers::Address(MIPSRegisters::sp, PRESERVED_RETURN_ADDRESS_OFFSET), MIPSRegisters::ra);
-    jit.loadPtr(CCallHelpers::Address(MIPSRegisters::sp, PRESERVED_FP_OFFSET), MIPSRegisters::fp);
-    jit.addPtr(CCallHelpers::TrustedImm32(STACK_LENGTH), MIPSRegisters::sp);
-#elif CPU(SH4)
-#   define EXTRA_STACK_SIZE 20
-
-    jit.addPtr(CCallHelpers::TrustedImm32(EXTRA_STACK_SIZE), SH4Registers::sp);
-    jit.pop(SH4Registers::r8);
-    jit.pop(SH4Registers::r9);
-    jit.pop(SH4Registers::r10);
-    jit.pop(SH4Registers::r11);
-    jit.pop(SH4Registers::r13);
-    jit.pop(SH4Registers::pr);
-    jit.pop(SH4Registers::fp);
-#endif
-
-    jit.ret();
-}
-
-MacroAssemblerCodeRef callToJavaScript(VM* vm)
-{
-    // The signature of the code generated is EncodedJSValue callToJavaScript(void* code, CallFrame*)
-
-    CCallHelpers jit(vm);
-
-#if CPU(X86_64)
-#if OS(WINDOWS)
-    // Dump register parameters to their home address
-    jit.storePtr(X86Registers::r9, CCallHelpers::Address(X86Registers::esp, 0x20));
-    jit.storePtr(X86Registers::r8, CCallHelpers::Address(X86Registers::esp, 0x18));
-    jit.storePtr(X86Registers::edx, CCallHelpers::Address(X86Registers::esp, 0x10));
-    jit.storePtr(X86Registers::ecx, CCallHelpers::Address(X86Registers::esp, 0x8));
-#endif // OS(WINDOWS)
-    jit.push(X86Registers::ebp);
-    jit.move(X86Registers::ebp, GPRInfo::nonArgGPR0);
-    jit.move(X86Registers::esp, X86Registers::ebp);
-    jit.push(X86Registers::r12);
-    jit.push(X86Registers::r13);
-    jit.push(X86Registers::r14);
-    jit.push(X86Registers::r15);
-    jit.push(X86Registers::ebx);
-
-    jit.subPtr(CCallHelpers::TrustedImm32(EXTRA_STACK_SIZE), X86Registers::esp);
-
-#   define CALLFRAME_SRC_REG GPRInfo::argumentGPR1
-#   define PREVIOUS_CALLFRAME_REG GPRInfo::nonArgGPR0
-#elif CPU(X86)
-    jit.push(X86Registers::ebp);
-    jit.move(X86Registers::ebp, GPRInfo::nonArgGPR0);
-    jit.move(X86Registers::esp, X86Registers::ebp);
-    jit.push(X86Registers::esi);
-    jit.push(X86Registers::edi);
-    jit.push(X86Registers::ebx);
-
-    jit.subPtr(CCallHelpers::TrustedImm32(EXTRA_STACK_SIZE), X86Registers::esp);
-
-    jit.load32(CCallHelpers::Address(X86Registers::esp, EXTRA_STACK_SIZE + 24), GPRInfo::callFrameRegister);
-
-#   define CALLFRAME_SRC_REG GPRInfo::callFrameRegister
-#   define CALL_CODE jit.call(CCallHelpers::Address(X86Registers::esp, EXTRA_STACK_SIZE + 20))
-#   define PREVIOUS_CALLFRAME_REG GPRInfo::nonArgGPR0
-#elif CPU(ARM_TRADITIONAL)
-    jit.push(ARMRegisters::r4);
-    jit.push(ARMRegisters::r5);
-    jit.push(ARMRegisters::r6);
-    jit.push(ARMRegisters::r8);
-    jit.push(ARMRegisters::r9);
-    jit.push(ARMRegisters::r10);
-    jit.push(ARMRegisters::r11);
-    jit.push(ARMRegisters::lr);
-    jit.move(ARMRegisters::r11, GPRInfo::nonArgGPR0);
-    jit.subPtr(CCallHelpers::TrustedImm32(EXTRA_STACK_SIZE), ARMRegisters::sp);
-
-#   define CALLFRAME_SRC_REG GPRInfo::argumentGPR1
-#   define PREVIOUS_CALLFRAME_REG GPRInfo::nonArgGPR0
-#elif CPU(ARM_THUMB2)
-    jit.push(ARMRegisters::lr);
-    jit.push(ARMRegisters::r4);
-    jit.push(ARMRegisters::r5);
-    jit.push(ARMRegisters::r6);
-    jit.push(ARMRegisters::r7);
-    jit.push(ARMRegisters::r8);
-    jit.push(ARMRegisters::r9);
-    jit.push(ARMRegisters::r10);
-    jit.push(ARMRegisters::r11);
-    jit.move(ARMRegisters::r7, GPRInfo::nonArgGPR0);
-    jit.subPtr(CCallHelpers::TrustedImm32(EXTRA_STACK_SIZE), ARMRegisters::sp);
-
-#   define CALLFRAME_SRC_REG GPRInfo::argumentGPR1
-#   define PREVIOUS_CALLFRAME_REG GPRInfo::nonArgGPR0
-#elif CPU(ARM64)
-    jit.push(ARM64Registers::lr);
-    jit.push(ARM64Registers::x19);
-    jit.push(ARM64Registers::x20);
-    jit.push(ARM64Registers::x21);
-    jit.push(ARM64Registers::x22);
-    jit.push(ARM64Registers::x23);
-    jit.push(ARM64Registers::x24);
-    jit.push(ARM64Registers::x25);
-    jit.push(ARM64Registers::x26);
-    jit.push(ARM64Registers::x27);
-    jit.push(ARM64Registers::x28);
-    jit.push(ARM64Registers::x29);
-    jit.move(ARM64Registers::x29, GPRInfo::nonArgGPR0);
-
-#   define CALLFRAME_SRC_REG GPRInfo::argumentGPR1
-#   define PREVIOUS_CALLFRAME_REG GPRInfo::nonArgGPR0
-#elif CPU(MIPS)
-    jit.subPtr(CCallHelpers::TrustedImm32(STACK_LENGTH), MIPSRegisters::sp);
-    jit.storePtr(MIPSRegisters::fp, CCallHelpers::Address(MIPSRegisters::sp, PRESERVED_FP_OFFSET));
-    jit.storePtr(MIPSRegisters::ra, CCallHelpers::Address(MIPSRegisters::sp, PRESERVED_RETURN_ADDRESS_OFFSET));
-    jit.storePtr(MIPSRegisters::s4, CCallHelpers::Address(MIPSRegisters::sp, PRESERVED_S4_OFFSET));
-    jit.storePtr(MIPSRegisters::s3, CCallHelpers::Address(MIPSRegisters::sp, PRESERVED_S3_OFFSET));
-    jit.storePtr(MIPSRegisters::s2, CCallHelpers::Address(MIPSRegisters::sp, PRESERVED_S2_OFFSET));
-    jit.storePtr(MIPSRegisters::s1, CCallHelpers::Address(MIPSRegisters::sp, PRESERVED_S1_OFFSET));
-    jit.storePtr(MIPSRegisters::s0, CCallHelpers::Address(MIPSRegisters::sp, PRESERVED_S0_OFFSET));
-#if WTF_MIPS_PIC
-    jit.storePtr(MIPSRegisters::gp, CCallHelpers::Address(MIPSRegisters::sp, PRESERVED_GP_OFFSET));
-#endif
-    jit.move(MIPSRegisters::fp, GPRInfo::nonArgGPR0);
-
-#   define CALLFRAME_SRC_REG GPRInfo::argumentGPR1
-#   define PREVIOUS_CALLFRAME_REG GPRInfo::nonArgGPR0
-#elif CPU(SH4)
-    jit.push(SH4Registers::fp);
-    jit.push(SH4Registers::pr);
-    jit.push(SH4Registers::r13);
-    jit.push(SH4Registers::r11);
-    jit.push(SH4Registers::r10);
-    jit.push(SH4Registers::r9);
-    jit.push(SH4Registers::r8);
-    jit.subPtr(CCallHelpers::TrustedImm32(EXTRA_STACK_SIZE), SH4Registers::sp);
-    jit.move(SH4Registers::fp, GPRInfo::nonArgGPR0);
-
-#   define CALLFRAME_SRC_REG GPRInfo::argumentGPR1
-#   define PREVIOUS_CALLFRAME_REG GPRInfo::nonArgGPR0
-#endif
-
-    if (CALLFRAME_SRC_REG != GPRInfo::callFrameRegister)
-        jit.move(CALLFRAME_SRC_REG, GPRInfo::callFrameRegister);
-    jit.loadPtr(CCallHelpers::Address(GPRInfo::callFrameRegister), GPRInfo::nonArgGPR1);
-    jit.storePtr(PREVIOUS_CALLFRAME_REG, CCallHelpers::Address(GPRInfo::nonArgGPR1));
-
-#if USE(JSVALUE64)
-    jit.move(CCallHelpers::TrustedImm64(0xffff000000000000L), GPRInfo::tagTypeNumberRegister);
-    jit.move(CCallHelpers::TrustedImm64(0xffff000000000002L), GPRInfo::tagMaskRegister);
-#endif
-
-#if defined(CALL_CODE)
-    CALL_CODE;
-#else
-    jit.call(GPRInfo::argumentGPR0);
-#endif
-
-#undef CALLFRAME_SRC_REG
-#undef CALL_CODE
-#undef PREVIOUS_CALLFRAME_REG
-
-    returnFromJavaScript(jit);
-
-    LinkBuffer patchBuffer(*vm, &jit, GLOBAL_THUNK_ID);
-    return FINALIZE_CODE(patchBuffer, ("Call to JavaScript thunk"));
-}
-
-MacroAssemblerCodeRef throwNotCaught(VM* vm)
-{
-    CCallHelpers jit(vm);
-
-    returnFromJavaScript(jit);
-
-    LinkBuffer patchBuffer(*vm, &jit, GLOBAL_THUNK_ID);
-    return FINALIZE_CODE(patchBuffer, ("Uncaught throw thunk"));
-}
-
 // We will jump here if the JIT code tries to make a call, but the
 // linking helper (C++ code) decides to throw an exception instead.
 MacroAssemblerCodeRef throwExceptionFromCallSlowPathGenerator(VM* vm)
index c99af1a..0e27628 100644 (file)
@@ -31,9 +31,6 @@
 #if ENABLE(JIT)
 namespace JSC {
 
-MacroAssemblerCodeRef callToJavaScript(VM*);
-MacroAssemblerCodeRef throwNotCaught(VM*);
-
 MacroAssemblerCodeRef throwExceptionFromCallSlowPathGenerator(VM*);
 
 MacroAssemblerCodeRef linkCallThunkGenerator(VM*);
index b46cc00..7567d01 100644 (file)
 
 namespace JSC {
 
+class ExecState;
 class VM;
 
+extern "C" {
+    EncodedJSValue callToJavaScript(void*, ExecState*);
+    void returnFromJavaScript();
+}
+
 namespace LLInt {
 
 MacroAssemblerCodeRef functionForCallEntryThunkGenerator(VM*);
index 9f9d883..c6a70df 100644 (file)
@@ -421,6 +421,12 @@ macro doReturn()
     ret
 end
 
+# stub to call into JavaScript
+# EncodedJSValue callToJavaScript(void* code, Register* topOfStack)
+# Note, if this stub or one of it's related macros is changed, make the
+# equivalent changes in jit/JITStubsX86.h and/or jit/JITStubsMSVC64.asm
+_callToJavaScript:
+    doCallToJavaScript()
 
 # Indicate the beginning of LLInt.
 _llint_begin:
index 6a82bdc..90fff12 100644 (file)
@@ -149,6 +149,80 @@ macro callSlowPath(slowPath)
     move t1, cfr
 end
 
+macro functionPrologue(extraStackSpace)
+    if X86
+        push cfr
+        move sp, cfr
+    end
+    pushCalleeSaves
+    if ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS
+        push cfr
+        push lr
+    end
+    subp extraStackSpace, sp
+end
+
+macro functionEpilogue(extraStackSpace)
+    addp extraStackSpace, sp
+    if ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS
+        pop lr
+        pop cfr
+    end
+    popCalleeSaves
+    if X86
+        pop cfr
+    end
+end
+
+macro doCallToJavaScript()
+    if X86
+        const extraStackSpace = 28
+        const previousCFR = t0
+        const entry = t5
+        const newCallFrame = t4
+    elsif ARM or ARMv7_TRADITIONAL
+        const extraStackSpace = 16
+        const previousCFR = t3  
+        const entry = a0
+        const newCallFrame = a1
+    elsif ARMv7
+        const extraStackSpace = 28
+        const previousCFR = t3  
+        const entry = a0
+        const newCallFrame = a1
+    elsif MIPS
+        const extraStackSpace = 20
+        const previousCFR = t2  
+        const entry = a0
+        const newCallFrame = a1
+    elsif SH4
+        const extraStackSpace = 20
+        const previousCFR = t3  
+        const entry = a0
+        const newCallFrame = a1
+    end
+
+    if X86
+        move cfr, previousCFR
+    end
+    functionPrologue(extraStackSpace)
+    if X86
+        loadp extraStackSpace+20[sp], entry
+        loadp extraStackSpace+24[sp], newCallFrame
+    else
+        move cfr, previousCFR
+    end
+
+    move newCallFrame, cfr
+    loadp [cfr], newCallFrame
+    storep previousCFR, [newCallFrame]
+    call entry
+
+_returnFromJavaScript:
+    functionEpilogue(extraStackSpace)
+    ret
+end
+
 # Debugging operation if you'd like to print an operand in the instruction stream. fromWhere
 # should be an immediate integer - any integer you like; use it to identify the place you're
 # debugging from. operand should likewise be an immediate, and should identify the operand
index 9c23432..1de9bcb 100644 (file)
@@ -88,6 +88,61 @@ macro cCall4(function, arg1, arg2, arg3, arg4)
     end
 end
 
+macro functionPrologue(extraStackSpace)
+    if X86_64
+        push cfr
+        move sp, cfr
+    elsif ARM64
+        push lr
+    end
+    pushCalleeSaves
+    if X86_64
+        subp extraStackSpace, sp
+    elsif ARM64
+        push cfr
+    end
+end
+
+macro functionEpilogue(extraStackSpace)
+    if X86_64
+        addp extraStackSpace, sp
+    end
+    popCalleeSaves
+    if X86_64
+        pop cfr
+    elsif ARM64
+        pop lr
+    end
+end
+
+macro doCallToJavaScript()
+    if X86_64
+        const extraStackSpace = 8
+        const previousCFR = t0
+        const entry = t5
+        const newCallFrame = t4
+    elsif ARM64
+        const extraStackSpace = 0
+        const previousCFR = t4  
+        const entry = a0
+        const newCallFrame = a1
+    end
+
+    move cfr, previousCFR
+    functionPrologue(extraStackSpace)
+
+    move newCallFrame, cfr
+    loadp [cfr], newCallFrame
+    storep previousCFR, [newCallFrame]
+    move 0xffff000000000000, csr1
+    addp 2, csr1, csr2
+    call entry
+
+_returnFromJavaScript:
+    functionEpilogue(extraStackSpace)
+    ret
+end
+
 macro prepareStateForCCall()
     leap [PB, PC, 8], PC
     move PB, t3
index 75193f9..17a1bd8 100644 (file)
@@ -97,7 +97,9 @@ class RegisterID
         when "t3"
             "r4"
         when "t4"
-            "r10"
+            "r8"
+        when "t5"
+            "r9"
         when "cfr"
             isARMv7 ?  "r7" : "r11"
         when "lr"
@@ -451,9 +453,21 @@ class Instruction
             # FIXME: either support this or remove it.
             raise "ARM does not support this opcode yet, #{codeOrigin}"
         when "pop"
-            $asm.puts "pop #{operands[0].armOperand}"
+            $asm.puts "pop { #{operands[0].armOperand} }"
         when "push"
-            $asm.puts "push #{operands[0].armOperand}"
+            $asm.puts "push { #{operands[0].armOperand} }"
+        when "popCalleeSaves"
+            if isARMv7
+                $asm.puts "pop {r4-r6, r8-r11}"                
+            else
+                $asm.puts "pop {r4-r10}"
+            end
+        when "pushCalleeSaves"
+            if isARMv7
+                $asm.puts "push {r4-r6, r8-r11}"
+            else
+                $asm.puts "push {r4-r10}"
+            end
         when "move"
             if operands[0].immediate?
                 armMoveImmediate(operands[0].value, operands[1])
index e1d8bac..adca4a9 100644 (file)
@@ -38,7 +38,8 @@ require "risc"
 #
 #  x0  => return value, cached result, first argument, t0, a0, r0
 #  x1  => t1, a1, r1
-#  x2  => t2
+#  x2  => t2, a2
+#  x3  => a3
 #  x9  => (nonArgGPR1 in baseline)
 # x10  => t4 (unused in baseline)
 # x11  => t5 (unused in baseline)
@@ -47,10 +48,9 @@ require "risc"
 # x16  => scratch
 # x17  => scratch
 # x23  => t3
-# x25  => cfr
-# x26  => timeout check (i.e. not touched by LLInt)
 # x27  => csr1 (tagTypeNumber)
 # x28  => csr2 (tagMask)
+# x29  => cfr
 #  sp  => sp
 #  lr  => lr
 #
@@ -106,8 +106,10 @@ class RegisterID
             arm64GPRName('x0', kind)
         when 't1', 'a1', 'r1'
             arm64GPRName('x1', kind)
-        when 't2'
+        when 't2', 'a2'
             arm64GPRName('x2', kind)
+        when 'a3'
+            arm64GPRName('x3', kind)
         when 't3'
             arm64GPRName('x23', kind)
         when 't4'
@@ -567,6 +569,28 @@ class Instruction
             emitARM64Unflipped("pop", operands, :ptr)
         when "push"
             emitARM64Unflipped("push", operands, :ptr)
+        when "popCalleeSaves"
+            emitARM64Unflipped("pop", "x28", :ptr)
+            emitARM64Unflipped("pop", "x27", :ptr)
+            emitARM64Unflipped("pop", "x26", :ptr)
+            emitARM64Unflipped("pop", "x25", :ptr)
+            emitARM64Unflipped("pop", "x24", :ptr)
+            emitARM64Unflipped("pop", "x23", :ptr)
+            emitARM64Unflipped("pop", "x22", :ptr)
+            emitARM64Unflipped("pop", "x21", :ptr)
+            emitARM64Unflipped("pop", "x20", :ptr)
+            emitARM64Unflipped("pop", "x19", :ptr)
+        when "pushCalleeSaves"
+            emitARM64Unflipped("push", "x19", :ptr)
+            emitARM64Unflipped("push", "x20", :ptr)
+            emitARM64Unflipped("push", "x21", :ptr)
+            emitARM64Unflipped("push", "x22", :ptr)
+            emitARM64Unflipped("push", "x23", :ptr)
+            emitARM64Unflipped("push", "x24", :ptr)
+            emitARM64Unflipped("push", "x25", :ptr)
+            emitARM64Unflipped("push", "x26", :ptr)
+            emitARM64Unflipped("push", "x27", :ptr)
+            emitARM64Unflipped("push", "x28", :ptr)
         when "move"
             if operands[0].immediate?
                 emitARM64MoveImmediate(operands[0].value, operands[1])
index 271137e..6c089eb 100644 (file)
@@ -249,6 +249,8 @@ MACRO_INSTRUCTIONS =
      "bnz",
      "leai",
      "leap",
+     "pushCalleeSaves",
+     "popCalleeSaves"
     ]
 
 X86_INSTRUCTIONS =
index f2a4dd3..69b8eb1 100644 (file)
@@ -82,6 +82,10 @@ class RegisterID
             "$a0"
         when "a1"
             "$a1"
+        when "a2"
+            "$a2"
+        when "a3"
+            "$a3"
         when "r0", "t0"
             "$v0"
         when "r1", "t1"
@@ -792,6 +796,20 @@ class Instruction
         when "push"
             $asm.puts "addiu $sp, $sp, -4"
             $asm.puts "sw #{operands[0].mipsOperand}, 0($sp)"
+        when "popCalleeSaves"
+            $asm.puts "lw $16, 0($sp)"
+            $asm.puts "lw $17, 4($sp)"
+            $asm.puts "lw $18, 8($sp)"
+            $asm.puts "lw $19, 12($sp)"
+            $asm.puts "lw $20, 16($sp)"
+            $asm.puts "addiu $sp, $sp, 20"
+        when "pushCalleeSaves"
+            $asm.puts "addiu $sp, $sp, -20"
+            $asm.puts "sw $20, 16($sp)"
+            $asm.puts "sw $19, 12($sp)"
+            $asm.puts "sw $18, 8($sp)"
+            $asm.puts "sw $17, 4($sp)"
+            $asm.puts "sw $16, 0($sp)"
         when "move", "sxi2p", "zxi2p"
             if operands[0].is_a? Immediate
                 mipsMoveImmediate(operands[0].value, operands[1])
index f062ae6..54a6288 100644 (file)
@@ -30,19 +30,21 @@ GPRS =
      "t2",
      "t3",
      "t4",
+     "t5",
      "cfr",
      "a0",
      "a1",
+     "a2",
+     "a3",
      "r0",
      "r1",
      "sp",
      "lr",
      
      # 64-bit only registers:
-     "t5",
-     "t6",  # r10
-     "csr1",  # r14, tag type number register
-     "csr2"   # r15, tag mask register
+     "t6",
+     "csr1",  # tag type number register
+     "csr2"   # tag mask register
     ]
 
 FPRS =
index 277a0f4..3e5022c 100644 (file)
@@ -61,6 +61,10 @@ class RegisterID
             "r4"
         when "a1"
             "r5"
+        when "a2"
+            "r6"
+        when "a3"
+            "r7"
         when "t0"
             "r0"
         when "t1"
@@ -70,7 +74,9 @@ class RegisterID
         when "t3"
             "r10"
         when "t4"
-            "r6"
+            "r4"
+        when "t5"
+            "r5"
         when "cfr"
             "r14"
         when "sp"
@@ -905,6 +911,22 @@ class Instruction
             $asm.puts "lds #{sh4Operands(operands)}, pr"
         when "stspr"
             $asm.puts "sts pr, #{sh4Operands(operands)}"
+        when "popCalleeSaves"
+            $asm.puts "mov.l @r15+, r8"
+            $asm.puts "mov.l @r15+, r9"
+            $asm.puts "mov.l @r15+, r10"
+            $asm.puts "mov.l @r15+, r11"
+            $asm.puts "mov.l @r15+, r13"
+            $asm.puts "lds.l @r15+,pr"
+            $asm.puts "mov.l @r15+, fp"
+        when "pushCalleeSaves"
+            $asm.puts "mov.l fp, @-r15"
+            $asm.puts "sts.l pr, @-r15"
+            $asm.puts "mov.l r13, @-r15"
+            $asm.puts "mov.l r11, @-r15"
+            $asm.puts "mov.l r10, @-r15"
+            $asm.puts "mov.l r9, @-r15"
+            $asm.puts "mov.l r8, @-r15"
         when "break"
             # This special opcode always generates an illegal instruction exception.
             $asm.puts ".word 0xfffd"
index 634cab8..fc48078 100644 (file)
@@ -74,11 +74,11 @@ X64_SCRATCH_REGISTER = SpecialRegister.new("r11")
 class RegisterID
     def supports8BitOnX86
         case name
-        when "t0", "a0", "r0", "t1", "a1", "r1", "t2", "t3"
+        when "t0", "a0", "r0", "t1", "a1", "r1", "t2", "t3", "t4", "t5"
             true
         when "cfr", "ttnr", "tmr"
             false
-        when "t4", "t5"
+        when "t6"
             isX64
         else
             raise
@@ -204,7 +204,6 @@ class RegisterID
                 raise
             end
         when "t5"
-            raise "Cannot use #{name} in 32-bit X86 at #{codeOriginString}" unless isX64
             case kind
             when :byte
                 "%dil"
@@ -213,9 +212,9 @@ class RegisterID
             when :int
                 "%edi"
             when :ptr
-                "%rdi"
+                isX64 ? "%rdi" : "%edi"
             when :quad
-                "%rdi"
+                isX64 ? "%rdi" : raise
             end
         when "t6"
             raise "Cannot use #{name} in 32-bit X86 at #{codeOriginString}" unless isX64
@@ -982,6 +981,30 @@ class Instruction
             $asm.puts "pop #{operands[0].x86Operand(:ptr)}"
         when "push"
             $asm.puts "push #{operands[0].x86Operand(:ptr)}"
+        when "popCalleeSaves"
+            if isX64
+                $asm.puts "pop %rbx"
+                $asm.puts "pop %r15"
+                $asm.puts "pop %r14"
+                $asm.puts "pop %r13"
+                $asm.puts "pop %r12"
+            else
+                $asm.puts "pop %ebx"
+                $asm.puts "pop %edi"
+                $asm.puts "pop %esi"
+            end
+        when "pushCalleeSaves"
+            if isX64
+                $asm.puts "push %r12"
+                $asm.puts "push %r13"
+                $asm.puts "push %r14"
+                $asm.puts "push %r15"
+                $asm.puts "push %rbx"
+            else
+                $asm.puts "push %esi"
+                $asm.puts "push %edi"
+                $asm.puts "push %ebx"
+            end
         when "move"
             handleMove
         when "sxi2q"
index c13c9af..566aa28 100644 (file)
@@ -257,8 +257,6 @@ VM::VM(VMType vmType, HeapType heapType)
 
 #if ENABLE(JIT)
     jitStubs = adoptPtr(new JITThunks());
-
-    callJavaScriptJITFunction = reinterpret_cast<CallJavaScriptJITFunction>(getCTIStub(callToJavaScript).code().executableAddress());
 #endif
 
 #if ENABLE(FTL_JIT)
index f1ecfc9..f1ed6cf 100644 (file)
@@ -329,10 +329,6 @@ namespace JSC {
             return jitStubs->ctiStub(this, generator);
         }
         NativeExecutable* getHostFunction(NativeFunction, Intrinsic);
-
-        typedef EncodedJSValue(*CallJavaScriptJITFunction)(void *, ExecState*);
-
-        CallJavaScriptJITFunction callJavaScriptJITFunction;
 #endif
 #if ENABLE(FTL_JIT)
         std::unique_ptr<FTL::Thunks> ftlThunks;