Change native function call stubs to use JIT operations instead of ctiVMHandleException
authormsaboff@apple.com <msaboff@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 18 Oct 2013 16:25:02 +0000 (16:25 +0000)
committermsaboff@apple.com <msaboff@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 18 Oct 2013 16:25:02 +0000 (16:25 +0000)
https://bugs.webkit.org/show_bug.cgi?id=122982

Reviewed by Geoffrey Garen.

Change ctiVMHandleException to operationVMHandleException.  Change all exception operations to
return the catch callFrame and entryPC via vm.callFrameForThrow and vm.targetMachinePCForThrow.
This removed calling convention headaches, fixing https://bugs.webkit.org/show_bug.cgi?id=122980
in the process.

* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::compileExceptionHandlers):
* jit/CCallHelpers.h:
(JSC::CCallHelpers::jumpToExceptionHandler):
* jit/JIT.cpp:
(JSC::JIT::privateCompileExceptionHandlers):
* jit/JIT.h:
* jit/JITExceptions.cpp:
(JSC::genericUnwind):
* jit/JITExceptions.h:
* jit/JITInlines.h:
(JSC::JIT::callOperationNoExceptionCheck):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_throw):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::privateCompileCTINativeCall):
(JSC::JIT::emit_op_throw):
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* jit/JITStubs.cpp:
* jit/JITStubs.h:
* jit/JITStubsARM.h:
* jit/JITStubsARM64.h:
* jit/JITStubsARMv7.h:
* jit/JITStubsMIPS.h:
* jit/JITStubsMSVC64.asm:
* jit/JITStubsSH4.h:
* jit/JITStubsX86.h:
* jit/JITStubsX86_64.h:
* jit/Repatch.cpp:
(JSC::tryBuildGetByIDList):
* jit/SlowPathCall.h:
(JSC::JITSlowPathCall::call):
* jit/ThunkGenerators.cpp:
(JSC::throwExceptionFromCallSlowPathGenerator):
(JSC::nativeForGenerator):
* runtime/VM.h:
(JSC::VM::callFrameForThrowOffset):
(JSC::VM::targetMachinePCForThrowOffset):

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

26 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
Source/JavaScriptCore/jit/CCallHelpers.h
Source/JavaScriptCore/jit/JIT.cpp
Source/JavaScriptCore/jit/JIT.h
Source/JavaScriptCore/jit/JITExceptions.cpp
Source/JavaScriptCore/jit/JITExceptions.h
Source/JavaScriptCore/jit/JITInlines.h
Source/JavaScriptCore/jit/JITOpcodes.cpp
Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
Source/JavaScriptCore/jit/JITOperations.cpp
Source/JavaScriptCore/jit/JITOperations.h
Source/JavaScriptCore/jit/JITStubs.cpp
Source/JavaScriptCore/jit/JITStubs.h
Source/JavaScriptCore/jit/JITStubsARM.h
Source/JavaScriptCore/jit/JITStubsARM64.h
Source/JavaScriptCore/jit/JITStubsARMv7.h
Source/JavaScriptCore/jit/JITStubsMIPS.h
Source/JavaScriptCore/jit/JITStubsMSVC64.asm
Source/JavaScriptCore/jit/JITStubsSH4.h
Source/JavaScriptCore/jit/JITStubsX86.h
Source/JavaScriptCore/jit/JITStubsX86_64.h
Source/JavaScriptCore/jit/Repatch.cpp
Source/JavaScriptCore/jit/SlowPathCall.h
Source/JavaScriptCore/jit/ThunkGenerators.cpp
Source/JavaScriptCore/runtime/VM.h

index 922a633..d3a7a0c 100644 (file)
@@ -1,3 +1,55 @@
+2013-10-18  Michael Saboff  <msaboff@apple.com>
+
+        Change native function call stubs to use JIT operations instead of ctiVMHandleException
+        https://bugs.webkit.org/show_bug.cgi?id=122982
+
+        Reviewed by Geoffrey Garen.
+
+        Change ctiVMHandleException to operationVMHandleException.  Change all exception operations to
+        return the catch callFrame and entryPC via vm.callFrameForThrow and vm.targetMachinePCForThrow.
+        This removed calling convention headaches, fixing https://bugs.webkit.org/show_bug.cgi?id=122980
+        in the process.
+
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::compileExceptionHandlers):
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::jumpToExceptionHandler):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileExceptionHandlers):
+        * jit/JIT.h:
+        * jit/JITExceptions.cpp:
+        (JSC::genericUnwind):
+        * jit/JITExceptions.h:
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperationNoExceptionCheck):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_throw):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::privateCompileCTINativeCall):
+        (JSC::JIT::emit_op_throw):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * jit/JITStubs.cpp:
+        * jit/JITStubs.h:
+        * jit/JITStubsARM.h:
+        * jit/JITStubsARM64.h:
+        * jit/JITStubsARMv7.h:
+        * jit/JITStubsMIPS.h:
+        * jit/JITStubsMSVC64.asm:
+        * jit/JITStubsSH4.h:
+        * jit/JITStubsX86.h:
+        * jit/JITStubsX86_64.h:
+        * jit/Repatch.cpp:
+        (JSC::tryBuildGetByIDList):
+        * jit/SlowPathCall.h:
+        (JSC::JITSlowPathCall::call):
+        * jit/ThunkGenerators.cpp:
+        (JSC::throwExceptionFromCallSlowPathGenerator):
+        (JSC::nativeForGenerator):
+        * runtime/VM.h:
+        (JSC::VM::callFrameForThrowOffset):
+        (JSC::VM::targetMachinePCForThrowOffset):
+
 2013-10-18  Julien Brianceau  <jbriance@cisco.com>
 
         Fix J_JITOperation_EAapJ call for MIPS and ARM EABI.
index b8b5447..ad438ee 100644 (file)
@@ -146,9 +146,7 @@ void JITCompiler::compileExceptionHandlers()
     poke(GPRInfo::argumentGPR0);
 #endif
     m_calls.append(CallLinkRecord(call(), lookupExceptionHandler));
-    // lookupExceptionHandler leaves the handler CallFrame* in the returnValueGPR,
-    // and the address of the handler in returnValueGPR2.
-    jump(GPRInfo::returnValueGPR2);
+    jumpToExceptionHandler();
 }
 
 void JITCompiler::link(LinkBuffer& linkBuffer)
index 0c3ba60..5ec59fb 100644 (file)
@@ -1335,6 +1335,17 @@ public:
         } else
             swap(destA, destB);
     }
+    
+    void jumpToExceptionHandler()
+    {
+        // genericUnwind() leaves the handler CallFrame* in vm->callFrameForThrow,
+        // and the address of the handler in vm->targetMachinePCForThrow.
+        // The exception handler expects the CallFrame* in regT0.
+        move(TrustedImmPtr(vm()), GPRInfo::regT0);
+        loadPtr(Address(GPRInfo::regT0, VM::targetMachinePCForThrowOffset()), GPRInfo::regT1);
+        loadPtr(Address(GPRInfo::regT0, VM::callFrameForThrowOffset()), GPRInfo::regT0);
+        jump(GPRInfo::regT1);
+    }
 };
 
 } // namespace JSC
index db699c7..07750d2 100644 (file)
@@ -868,9 +868,7 @@ void JIT::privateCompileExceptionHandlers()
     poke(GPRInfo::argumentGPR0);
 #endif
     m_calls.append(CallRecord(call(), (unsigned)-1, FunctionPtr(lookupExceptionHandler).value()));
-    // lookupExceptionHandler leaves the handler CallFrame* in the returnValueGPR,
-    // and the address of the handler in returnValueGPR2.
-    jump(GPRInfo::returnValueGPR2);
+    jumpToExceptionHandler();
 }
 
 
index 6d38f31..8d847f8 100644 (file)
@@ -792,11 +792,6 @@ namespace JSC {
         MacroAssembler::Call callOperation(J_JITOperation_EP, int, void*);
         MacroAssembler::Call callOperation(WithProfileTag, J_JITOperation_EPc, int, Instruction*);
         MacroAssembler::Call callOperation(J_JITOperation_EZ, int, int32_t);
-#if USE(JSVALUE64)
-        MacroAssembler::Call callOperation(Jhe_JITOperation_EJ, RegisterID);
-#else
-        MacroAssembler::Call callOperation(Jhe_JITOperation_EJ, RegisterID, RegisterID);
-#endif
         MacroAssembler::Call callOperation(P_JITOperation_EJS, GPRReg, size_t);
         MacroAssembler::Call callOperation(P_JITOperation_EZ, int32_t);
         MacroAssembler::Call callOperation(S_JITOperation_ECC, RegisterID, RegisterID);
@@ -809,6 +804,11 @@ namespace JSC {
         MacroAssembler::Call callOperation(V_JITOperation_ECICC, RegisterID, const Identifier*, RegisterID, RegisterID);
         MacroAssembler::Call callOperation(V_JITOperation_EIdJZ, const Identifier*, RegisterID, int32_t);
         MacroAssembler::Call callOperation(V_JITOperation_EJ, RegisterID);
+#if USE(JSVALUE64)
+        MacroAssembler::Call callOperationNoExceptionCheck(V_JITOperation_EJ, RegisterID);
+#else
+        MacroAssembler::Call callOperationNoExceptionCheck(V_JITOperation_EJ, RegisterID, RegisterID);
+#endif
         MacroAssembler::Call callOperation(V_JITOperation_EJIdJJ, RegisterID, const Identifier*, RegisterID, RegisterID);
 #if USE(JSVALUE64)
         MacroAssembler::Call callOperation(V_JITOperation_EJJI, RegisterID, RegisterID, StringImpl*);
index 9e164f9..0a353e1 100644 (file)
 
 namespace JSC {
 
-#if USE(JSVALUE32_64)
-EncodedExceptionHandler encode(ExceptionHandler handler)
-{
-    ExceptionHandlerUnion u;
-    u.handler = handler;
-    return u.encodedHandler;
-}
-#endif
-
-ExceptionHandler uncaughtExceptionHandler()
-{
-    void* catchRoutine = FunctionPtr(LLInt::getCodePtr(ctiOpThrowNotCaught)).value();
-    ExceptionHandler exceptionHandler = { 0, catchRoutine};
-    return exceptionHandler;
-}
-
-ExceptionHandler genericUnwind(VM* vm, ExecState* callFrame, JSValue exceptionValue)
+void genericUnwind(VM* vm, ExecState* callFrame, JSValue exceptionValue)
 {
     RELEASE_ASSERT(exceptionValue);
     HandlerInfo* handler = vm->interpreter->unwind(callFrame, exceptionValue); // This may update callFrame.
@@ -72,8 +56,6 @@ ExceptionHandler genericUnwind(VM* vm, ExecState* callFrame, JSValue exceptionVa
     vm->targetInterpreterPCForThrow = catchPCForInterpreter;
     
     RELEASE_ASSERT(catchRoutine);
-    ExceptionHandler exceptionHandler = { callFrame, catchRoutine};
-    return exceptionHandler;
 }
 
 }
index 6e2c5ec..376e269 100644 (file)
@@ -27,7 +27,6 @@
 #define JITExceptions_h
 
 #include "JSCJSValue.h"
-#include "MacroAssemblerCodeRef.h"
 
 #if ENABLE(JIT) || ENABLE(LLINT)
 
@@ -36,29 +35,7 @@ namespace JSC {
 class ExecState;
 class VM;
 
-// This header gives other parts of the system access to the JIT's prototocol
-// for the throwing and handling exceptions.
-
-struct ExceptionHandler {
-    ExecState* callFrame;
-    void* catchRoutine;
-};
-
-#if USE(JSVALUE32_64)
-// EncodedExceptionHandler is used to convince the compiler to return an ExceptionHander
-// struct in two registers for 32 bit builds.
-typedef int64_t EncodedExceptionHandler;
-
-union ExceptionHandlerUnion {
-    ExceptionHandler handler;
-    EncodedExceptionHandler encodedHandler;
-};
-
-EncodedExceptionHandler encode(ExceptionHandler);
-#endif
-
-ExceptionHandler uncaughtExceptionHandler();
-ExceptionHandler genericUnwind(VM*, ExecState*, JSValue exceptionValue);
+void genericUnwind(VM*, ExecState*, JSValue exceptionValue);
 
 } // namespace JSC
 
index c16c951..fe9acf8 100644 (file)
@@ -292,26 +292,14 @@ ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EZ operatio
 }
 
 #if USE(JSVALUE64)
-ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(Jhe_JITOperation_EJ operation, GPRReg arg1)
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperationNoExceptionCheck(V_JITOperation_EJ operation, GPRReg arg1)
 {
-#if COMPILER(MSVC) && CPU(X86)
-    // Need to make space on stack for return value, use that address as first arg (in register),
-    // move callFrameRegister to second argument register and push the passed arg1.
-    updateTopCallFrame();
-    MacroAssembler::Call call = appendCall(operation);
-    // These may not be pops:
-    // pop(regT0); // Restore arg1 slot
-    // pop(regT0); // Get handler's call frame
-    // pop(regT1); // Get handler's address
-    return call;
-#else
     setupArgumentsWithExecState(arg1);
     updateTopCallFrame();
     return appendCall(operation);
-#endif
 }
 #else
-ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(Jhe_JITOperation_EJ operation, GPRReg arg1Tag, GPRReg arg1Payload)
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperationNoExceptionCheck(V_JITOperation_EJ operation, GPRReg arg1Tag, GPRReg arg1Payload)
 {
     setupArgumentsWithExecState(arg1Payload, arg1Tag);
     updateTopCallFrame();
index c592812..7f93914 100644 (file)
@@ -484,10 +484,8 @@ void JIT::emit_op_throw(Instruction* currentInstruction)
 {
     ASSERT(regT0 == returnValueRegister);
     emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
-    callOperation(operationThrow, regT0);
-    // After operationThrow returns, returnValueRegister (regT0) has the handler's callFrame and
-    // returnValue2Register has the handler's entry address.
-    jump(returnValue2Register);
+    callOperationNoExceptionCheck(operationThrow, regT0);
+    jumpToExceptionHandler();
 }
 
 void JIT::emit_op_get_pnames(Instruction* currentInstruction)
index ae31665..9b0b13c 100644 (file)
@@ -30,6 +30,7 @@
 #if USE(JSVALUE32_64)
 #include "JIT.h"
 
+#include "CCallHelpers.h"
 #include "JITInlines.h"
 #include "JSArray.h"
 #include "JSCell.h"
@@ -170,8 +171,20 @@ JIT::CodeRef JIT::privateCompileCTINativeCall(VM* vm, NativeFunction func)
     storePtr(regT1, regT2);
     storePtr(callFrameRegister, &m_vm->topCallFrame);
 
-    move(TrustedImmPtr(FunctionPtr(ctiVMHandleException).value()), regT1);
-    jump(regT1);
+#if CPU(X86)
+    addPtr(TrustedImm32(-12), stackPointerRegister);
+    push(callFrameRegister);
+#else
+    move(callFrameRegister, firstArgumentRegister);
+#endif
+    move(TrustedImmPtr(FunctionPtr(operationVMHandleException).value()), regT3);
+    call(regT3);
+
+#if CPU(X86)
+    addPtr(TrustedImm32(16), stackPointerRegister);
+#endif
+
+    jumpToExceptionHandler();
 
     // All trampolines constructed! copy the code, link up calls, and set the pointers on the Machine object.
     LinkBuffer patchBuffer(*m_vm, this, GLOBAL_THUNK_ID);
@@ -813,10 +826,8 @@ void JIT::emit_op_throw(Instruction* currentInstruction)
 {
     ASSERT(regT0 == returnValueRegister);
     emitLoad(currentInstruction[1].u.operand, regT1, regT0);
-    callOperation(operationThrow, regT1, regT0);
-    // After operationThrow returns, returnValueRegister (regT0) has the handler's callFrame and
-    // returnValue2Register has the handler's entry address.
-    jump(returnValue2Register);
+    callOperationNoExceptionCheck(operationThrow, regT1, regT0);
+    jumpToExceptionHandler();
 }
 
 void JIT::emit_op_get_pnames(Instruction* currentInstruction)
index 2fdcd90..53f2a41 100644 (file)
@@ -1615,18 +1615,19 @@ void JIT_OPERATION operationPutToScope(ExecState* exec, Instruction* bytecodePC)
     }
 }
 
-JITHandlerEncoded JIT_OPERATION operationThrow(ExecState* exec, EncodedJSValue encodedExceptionValue)
+void JIT_OPERATION operationThrow(ExecState* exec, EncodedJSValue encodedExceptionValue)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
 
     JSValue exceptionValue = JSValue::decode(encodedExceptionValue);
     vm->throwException(exec, exceptionValue);
-    ExceptionHandler handler = genericUnwind(vm, exec, exceptionValue);
-    return dfgHandlerEncoded(handler.callFrame, handler.catchRoutine);
+
+    // Results stored out-of-band in vm.targetMachinePCForThrow & vm.callFrameForThrow
+    genericUnwind(vm, exec, exceptionValue);
 }
 
-JITHandlerEncoded JIT_OPERATION lookupExceptionHandler(ExecState* exec)
+void JIT_OPERATION lookupExceptionHandler(ExecState* exec)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
@@ -1634,9 +1635,17 @@ JITHandlerEncoded JIT_OPERATION lookupExceptionHandler(ExecState* exec)
     JSValue exceptionValue = exec->exception();
     ASSERT(exceptionValue);
     
-    ExceptionHandler handler = genericUnwind(vm, exec, exceptionValue);
-    ASSERT(handler.catchRoutine);
-    return dfgHandlerEncoded(handler.callFrame, handler.catchRoutine);
+    genericUnwind(vm, exec, exceptionValue);
+    ASSERT(vm->targetMachinePCForThrow);
+}
+
+void JIT_OPERATION operationVMHandleException(ExecState* exec)
+{
+    VM* vm = &exec->vm();
+    NativeCallFrameTracer tracer(vm, exec);
+
+    ASSERT(!exec->hasHostCallFrameFlag());
+    genericUnwind(vm, exec, vm->exception());
 }
 
 } // extern "C"
index 7b2446e..88af1ba 100644 (file)
@@ -47,45 +47,6 @@ class ArrayAllocationProfile;
 
 extern "C" {
 
-// This method is used to lookup an exception hander, keyed by faultLocation, which is
-// the return location from one of the calls out to one of the helper operations above.
-
-// According to C++ rules, a type used for the return signature of function with C linkage (i.e.
-// 'extern "C"') needs to be POD; hence putting any constructors into it could cause either compiler
-// warnings, or worse, a change in the ABI used to return these types.
-struct JITHandler {
-    union Union {
-        struct Struct {
-            ExecState* exec;
-            void* handler;
-        } s;
-        uint64_t encoded;
-    } u;
-};
-
-inline JITHandler createJITHandler(ExecState* exec, void* handler)
-{
-    JITHandler result;
-    result.u.s.exec = exec;
-    result.u.s.handler = handler;
-    return result;
-}
-
-#if CPU(X86_64)
-typedef JITHandler JITHandlerEncoded;
-inline JITHandlerEncoded dfgHandlerEncoded(ExecState* exec, void* handler)
-{
-    return createJITHandler(exec, handler);
-}
-#else
-typedef uint64_t JITHandlerEncoded;
-inline JITHandlerEncoded dfgHandlerEncoded(ExecState* exec, void* handler)
-{
-    COMPILE_ASSERT(sizeof(JITHandler::Union) == sizeof(uint64_t), JITHandler_Union_is_64bit);
-    return createJITHandler(exec, handler).u.encoded;
-}
-#endif
-
 // These typedefs provide typechecking when generating calls out to helper routines;
 // this helps prevent calling a helper routine with the wrong arguments!
 /*
@@ -102,7 +63,6 @@ inline JITHandlerEncoded dfgHandlerEncoded(ExecState* exec, void* handler)
     Idc: const Identifier*
     J: EncodedJSValue
     Jcp: const JSValue*
-    Jhe: JITHandlerEncoded
     Jsa: JSActivation*
     Jss: JSString*
     O: JSObject*
@@ -112,6 +72,7 @@ inline JITHandlerEncoded dfgHandlerEncoded(ExecState* exec, void* handler)
     S: size_t
     St: Structure*
     V: void
+    Vm: VM*
     W: WatchpointSet*
     Z: int32_t
 */
@@ -142,7 +103,6 @@ typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_ESS)(ExecState*, size_t, s
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EZ)(ExecState*, int32_t);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EZIcfZ)(ExecState*, int32_t, InlineCallFrame*, int32_t);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EZZ)(ExecState*, int32_t, int32_t);
-typedef JITHandlerEncoded JIT_OPERATION (*Jhe_JITOperation_EJ)(ExecState*, EncodedJSValue);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_E)(ExecState*);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EZ)(ExecState*, int32_t);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EC)(ExecState*, JSCell*);
@@ -191,6 +151,7 @@ typedef void JIT_OPERATION (*V_JITOperation_EPc)(ExecState*, Instruction*);
 typedef void JIT_OPERATION (*V_JITOperation_EPZJ)(ExecState*, void*, int32_t, EncodedJSValue);
 typedef void JIT_OPERATION (*V_JITOperation_W)(WatchpointSet*);
 typedef void JIT_OPERATION (*V_JITOperation_EZ)(ExecState*, int32_t);
+typedef void JIT_OPERATION (*V_JITOperation_EVm)(ExecState*, VM*);
 typedef char* JIT_OPERATION (*P_JITOperation_E)(ExecState*);
 typedef char* JIT_OPERATION (*P_JITOperation_EC)(ExecState*, JSCell*);
 typedef char* JIT_OPERATION (*P_JITOperation_EJS)(ExecState*, EncodedJSValue, size_t);
@@ -210,7 +171,11 @@ typedef char* JIT_OPERATION (*P_JITOperation_EZZ)(ExecState*, int32_t, int32_t);
 typedef StringImpl* JIT_OPERATION (*I_JITOperation_EJss)(ExecState*, JSString*);
 typedef JSString* JIT_OPERATION (*Jss_JITOperation_EZ)(ExecState*, int32_t);
 
-JITHandlerEncoded JIT_OPERATION lookupExceptionHandler(ExecState*) WTF_INTERNAL;
+// This method is used to lookup an exception hander, keyed by faultLocation, which is
+// the return location from one of the calls out to one of the helper operations above.
+    
+void JIT_OPERATION lookupExceptionHandler(ExecState*) WTF_INTERNAL;
+void JIT_OPERATION operationVMHandleException(ExecState*) WTF_INTERNAL;
 
 void JIT_OPERATION operationStackCheck(ExecState*, CodeBlock*) WTF_INTERNAL;
 int32_t JIT_OPERATION operationCallArityCheck(ExecState*) WTF_INTERNAL;
@@ -264,7 +229,7 @@ JSCell* JIT_OPERATION operationNewObject(ExecState*, Structure*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationNewRegexp(ExecState*, void*) WTF_INTERNAL;
 void JIT_OPERATION operationHandleWatchdogTimer(ExecState*) WTF_INTERNAL;
 void JIT_OPERATION operationThrowStaticError(ExecState*, EncodedJSValue, int32_t) WTF_INTERNAL;
-JITHandlerEncoded JIT_OPERATION operationThrow(ExecState*, EncodedJSValue) WTF_INTERNAL;
+void JIT_OPERATION operationThrow(ExecState*, EncodedJSValue) WTF_INTERNAL;
 void JIT_OPERATION operationDebug(ExecState*, int32_t) WTF_INTERNAL;
 #if ENABLE(DFG_JIT)
 char* JIT_OPERATION operationOptimize(ExecState*, int32_t) WTF_INTERNAL;
index d4d5c22..c26a2cc 100644 (file)
@@ -109,34 +109,6 @@ namespace JSC {
     #define CTI_SAMPLER 0
 #endif
 
-#if USE(JSVALUE32_64)
-EncodedExceptionHandler JIT_STUB cti_vm_handle_exception(CallFrame* callFrame)
-{
-    ASSERT(!callFrame->hasHostCallFrameFlag());
-    if (!callFrame) {
-        // The entire stack has already been unwound. Nothing more to handle.
-        return encode(uncaughtExceptionHandler());
-    }
-
-    VM* vm = callFrame->codeBlock()->vm();
-    vm->topCallFrame = callFrame;
-    return encode(genericUnwind(vm, callFrame, vm->exception()));
-}
-#else
-ExceptionHandler JIT_STUB cti_vm_handle_exception(CallFrame* callFrame)
-{
-    ASSERT(!callFrame->hasHostCallFrameFlag());
-    if (!callFrame) {
-        // The entire stack has already been unwound. Nothing more to handle.
-        return uncaughtExceptionHandler();
-    }
-
-    VM* vm = callFrame->codeBlock()->vm();
-    vm->topCallFrame = callFrame;
-    return genericUnwind(vm, callFrame, vm->exception());
-}
-#endif
-
 } // namespace JSC
 
 #endif // ENABLE(JIT)
index 5e9bc94..3cffa9e 100644 (file)
@@ -96,16 +96,6 @@ inline bool returnAddressIsInCtiTrampoline(ReturnAddressPtr returnAddress)
 extern "C" void ctiMasmProbeTrampoline();
 #endif
 
-extern "C" {
-
-#if USE(JSVALUE32_64)
-EncodedExceptionHandler JIT_STUB cti_vm_handle_exception(CallFrame*) REFERENCED_FROM_ASM WTF_INTERNAL;
-#else
-ExceptionHandler JIT_STUB cti_vm_handle_exception(CallFrame*) REFERENCED_FROM_ASM WTF_INTERNAL;
-#endif
-
-} // extern "C"
-
 #endif // ENABLE(JIT)
 
 } // namespace JSC
index 70e8f9c..bb98806 100644 (file)
@@ -186,19 +186,6 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
     "bx lr" "\n"
 );
 
-asm (
-".text" "\n"
-".globl " SYMBOL_STRING(ctiVMHandleException) "\n"
-HIDE_SYMBOL(ctiVMHandleException) "\n"
-INLINE_ARM_FUNCTION(ctiVMHandleException)
-SYMBOL_STRING(ctiVMHandleException) ":" "\n"
-    "mov r0, r5" "\n"
-    "bl " SYMBOL_STRING(cti_vm_handle_exception) "\n"
-    // When cti_vm_handle_exception returns, r0 has callFrame and r1 has handler address
-    "mov r5, r0" "\n"
-    "bx r1" "\n"
-);
-
 #if USE(MASM_PROBE)
 asm (
 ".text" "\n"
@@ -435,8 +422,6 @@ MSVC_BEGIN()
 MSVC_BEGIN(    EXPORT ctiTrampoline)
 MSVC_BEGIN(    EXPORT ctiTrampolineEnd)
 MSVC_BEGIN(    EXPORT ctiOpThrowNotCaught)
-MSVC_BEGIN(    EXPORT ctiVMHandleException)
-MSVC_BEGIN(    IMPORT cti_vm_handle_exception)
 MSVC_BEGIN()
 MSVC_BEGIN(ctiTrampoline PROC)
 MSVC_BEGIN(    stmdb sp!, {r1-r3})
@@ -454,13 +439,6 @@ MSVC_BEGIN(    bx lr)
 MSVC_BEGIN(ctiTrampolineEnd)
 MSVC_BEGIN(ctiTrampoline ENDP)
 MSVC_BEGIN()
-MSVC_BEGIN(ctiVMHandleException PROC)
-MSVC_BEGIN(    mov r0, r5)
-MSVC_BEGIN(    bl cti_vm_handle_exception)
-MSVC_BEGIN(    mov r5, r0)
-MSVC_BEGIN(    bx r1)
-MSVC_BEGIN(ctiVMHandleException ENDP)
-MSVC_BEGIN()
 
 MSVC(    EXPORT cti_#op#)
 MSVC(    IMPORT JITStubThunked_#op#)
index 926517d..ee6f968 100644 (file)
@@ -100,14 +100,6 @@ SYMBOL_STRING(ctiTrampoline) ":" "\n"
     "add sp, sp, #" STRINGIZE_VALUE_OF(SIZEOF_JITSTACKFRAME) "\n"
     "ret" "\n"
 
-HIDE_SYMBOL(ctiVMHandleException) "\n"
-SYMBOL_STRING(ctiVMHandleException) ":" "\n"
-    "mov x0, x25" "\n"
-    "bl " LOCAL_REFERENCE(cti_vm_handle_exception) "\n"
-    // When cti_vm_handle_exception returns, x0 has callFrame and x1 has handler address
-    "mov x25, x0" "\n"
-    "br x1" "\n"
-
 HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
 SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
     "ldr x28, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_X28_OFFSET) "]" "\n"
index a88ca78..fa401a2 100644 (file)
@@ -245,21 +245,6 @@ SYMBOL_STRING(ctiTrampolineEnd) ":" "\n"
 asm (
 ".text" "\n"
 ".align 2" "\n"
-".globl " SYMBOL_STRING(ctiVMHandleException) "\n"
-HIDE_SYMBOL(ctiVMHandleException) "\n"
-".thumb" "\n"
-".thumb_func " THUMB_FUNC_PARAM(ctiVMHandleException) "\n"
-SYMBOL_STRING(ctiVMHandleException) ":" "\n"
-    "mov r0, r5" "\n"
-    "bl " LOCAL_REFERENCE(cti_vm_handle_exception) "\n"
-    // When cti_vm_handle_exception returns, r0 has callFrame and r1 has handler address
-    "mov r5, r0" "\n"
-    "bx r1" "\n"
-);
-
-asm (
-".text" "\n"
-".align 2" "\n"
 ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
 HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
 ".thumb" "\n"
index d9b9d94..5f19778 100644 (file)
@@ -101,35 +101,6 @@ asm (
 ".set noreorder" "\n"
 ".set nomacro" "\n"
 ".set nomips16" "\n"
-".globl " SYMBOL_STRING(ctiVMHandleException) "\n"
-".ent " SYMBOL_STRING(ctiVMHandleException) "\n"
-SYMBOL_STRING(ctiVMHandleException) ":" "\n"
-#if WTF_MIPS_PIC
-".set macro" "\n"
-".cpload $25" "\n"
-    "la    $25," SYMBOL_STRING(cti_vm_handle_exception) "\n"
-".set nomacro" "\n"
-    "bal " SYMBOL_STRING(cti_vm_handle_exception) "\n"
-    "move  $4,$16" "\n"
-#else
-    "jal " SYMBOL_STRING(cti_vm_handle_exception) "\n"
-    "move  $4,$16" "\n"
-#endif
-    // When cti_vm_handle_exception returns, v0 has callFrame and v1 has handler address
-    "move  $31,$3" "\n"
-    "jr    $31" "\n"
-    "move  $16,$2 " "\n"
-".set reorder" "\n"
-".set macro" "\n"
-".end " SYMBOL_STRING(ctiVMHandleException) "\n"
-);
-
-asm (
-".text" "\n"
-".align 2" "\n"
-".set noreorder" "\n"
-".set nomacro" "\n"
-".set nomips16" "\n"
 ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
 ".ent " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
 SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
index 2ffadd4..2a53a87 100644 (file)
@@ -23,7 +23,6 @@
 ; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ;*/
 
-EXTERN cti_vm_handle_exception : near
 EXTERN getHostCallReturnValueWithExecState : near
 
 PUBLIC ctiTrampoline
@@ -64,18 +63,6 @@ ctiTrampoline PROC
     ret
 ctiTrampoline ENDP
 
-ctiVMHandleException PROC
-       sub rsp, 16
-    mov rcx, rsp
-       mov rdx, r13
-       call cti_vm_handle_exception
-    ; When cti_vm_handle_exception returns, rax points to the memory we allocated on stack
-       ; It contains the callFrame and handler address
-       pop rax         ; callFrame
-       pop rdx         ; handler
-    jmp rdx
-ctiVMHandleException ENDP
 ctiOpThrowNotCaught PROC
     add rsp, 58h
     pop rbx
index 980b943..c50ea3a 100644 (file)
@@ -83,24 +83,6 @@ SYMBOL_STRING(ctiTrampolineEnd) ":" "\n"
 );
 
 asm volatile (
-".globl " SYMBOL_STRING(ctiVMHandleException) "\n"
-HIDE_SYMBOL(ctiVMHandleException) "\n"
-SYMBOL_STRING(ctiVMHandleException) ":" "\n"
-    "mov.l .L2" SYMBOL_STRING(cti_vm_handle_exception) ",r0" "\n"
-    "mov r14, r4" "\n"
-    "mov.l @(r0,r12),r11" "\n"
-    "jsr @r11" "\n"
-    // When cti_vm_handle_exception returns, r0 has callFrame and r1 has handler address
-    "nop" "\n"
-    "mov r0, r14" "\n"
-    "lds r1, pr" "\n"
-    "rts" "\n"
-    "nop" "\n"
-    ".align 2" "\n"
-    ".L2" SYMBOL_STRING(cti_vm_handle_exception) ":.long " SYMBOL_STRING(cti_vm_handle_exception) "@GOT \n"
-);
-
-asm volatile (
 ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
 HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
 SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
index c951348..b24a7cf 100644 (file)
@@ -70,16 +70,6 @@ SYMBOL_STRING(ctiTrampolineEnd) ":" "\n"
 );
 
 asm (
-".globl " SYMBOL_STRING(ctiVMHandleException) "\n"
-HIDE_SYMBOL(ctiVMHandleException) "\n"
-SYMBOL_STRING(ctiVMHandleException) ":" "\n"
-    "movl %edi, %ecx" "\n"
-    "call " LOCAL_REFERENCE(cti_vm_handle_exception) "\n"
-    // When cti_vm_handle_exception returns, eax has callFrame and edx has handler address
-    "jmp *%edx" "\n"
-);
-
-asm (
 ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
 HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
 SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
@@ -271,16 +261,6 @@ extern "C" {
         }
     }
 
-    __declspec(naked) void ctiVMHandleException()
-    {
-        __asm {
-            mov ecx, edi;
-            call cti_vm_handle_exception;
-            // When cti_vm_handle_exception returns, eax has callFrame and edx has handler address
-            jmp edx
-        }
-    }
-
     __declspec(naked) void ctiOpThrowNotCaught()
     {
         __asm {
index b7aad54..75ee2c8 100644 (file)
@@ -84,16 +84,6 @@ SYMBOL_STRING(ctiTrampolineEnd) ":" "\n"
 );
 
 asm (
-".globl " SYMBOL_STRING(ctiVMHandleException) "\n"
-HIDE_SYMBOL(ctiVMHandleException) "\n"
-SYMBOL_STRING(ctiVMHandleException) ":" "\n"
-    "movq %r13, %rdi" "\n"
-    "call " LOCAL_REFERENCE(cti_vm_handle_exception) "\n"
-    // When cti_vm_handle_exception returns, rax has callFrame and rdx has handler address
-    "jmp *%rdx" "\n"
-);
-
-asm (
 ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
 HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
 SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
index dd7c03b..0d74df0 100644 (file)
@@ -517,7 +517,7 @@ static bool tryBuildGetByIDList(ExecState* exec, JSValue baseValue, const Identi
             
             stubJit.setupArgumentsExecState();
             handlerCall = stubJit.call();
-            stubJit.jump(GPRInfo::returnValueGPR2);
+            stubJit.jumpToExceptionHandler();
         } else {
             if (isInlineOffset(slot.cachedOffset())) {
 #if USE(JSVALUE64)
index ffa3c1b..522e02f 100644 (file)
@@ -81,18 +81,8 @@ public:
         m_jit->unmap();
 #else
         m_jit->killLastResultRegister();
-#endif
-        
-#if USE(JSVALUE32_64)
-        JIT::Jump noException = m_jit->branch32(JIT::Equal, JIT::AbsoluteAddress(reinterpret_cast<char*>(m_jit->m_codeBlock->vm()->addressOfException()) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), JIT::TrustedImm32(JSValue::EmptyValueTag));
-#else
-        JIT::Jump noException = m_jit->branchTest64(JIT::Zero, JIT::AbsoluteAddress(m_jit->m_codeBlock->vm()->addressOfException()));
-#endif
-        m_jit->updateTopCallFrame();
-        m_jit->move(JIT::TrustedImmPtr(FunctionPtr(ctiVMHandleException).value()), JIT::regT1);
-        m_jit->jump(JIT::regT1);
-        noException.link(m_jit);
-        
+#endif   
+        m_jit->exceptionCheck();
         return call;
     }
 
index 9c2034f..c98fc56 100644 (file)
@@ -77,9 +77,8 @@ MacroAssemblerCodeRef throwExceptionFromCallSlowPathGenerator(VM* vm)
     jit.move(CCallHelpers::TrustedImmPtr(bitwise_cast<void*>(lookupExceptionHandler)), GPRInfo::nonArgGPR0);
     emitPointerValidation(jit, GPRInfo::nonArgGPR0);
     jit.call(GPRInfo::nonArgGPR0);
-    emitPointerValidation(jit, GPRInfo::returnValueGPR2);
-    jit.jump(GPRInfo::returnValueGPR2);
-    
+    jit.jumpToExceptionHandler();
+
     LinkBuffer patchBuffer(*vm, &jit, GLOBAL_THUNK_ID);
     return FINALIZE_CODE(patchBuffer, ("Throw exception from call slow path thunk"));
 }
@@ -462,8 +461,19 @@ static MacroAssemblerCodeRef nativeForGenerator(VM* vm, CodeSpecializationKind k
 
     jit.storePtr(JSInterfaceJIT::callFrameRegister, &vm->topCallFrame);
 
-    jit.move(JSInterfaceJIT::TrustedImmPtr(FunctionPtr(ctiVMHandleException).value()), JSInterfaceJIT::regT1);
-    jit.jump(JSInterfaceJIT::regT1);
+#if CPU(X86) && USE(JSVALUE32_64)
+    jit.addPtr(JSInterfaceJIT::TrustedImm32(-12), JSInterfaceJIT::stackPointerRegister);
+    jit.push(JSInterfaceJIT::callFrameRegister);
+#else
+    jit.move(JSInterfaceJIT::callFrameRegister, JSInterfaceJIT::firstArgumentRegister);
+#endif
+    jit.move(JSInterfaceJIT::TrustedImmPtr(FunctionPtr(operationVMHandleException).value()), JSInterfaceJIT::regT3);
+    jit.call(JSInterfaceJIT::regT3);
+#if CPU(X86) && USE(JSVALUE32_64)
+    jit.addPtr(JSInterfaceJIT::TrustedImm32(16), JSInterfaceJIT::stackPointerRegister);
+#endif
+
+    jit.jumpToExceptionHandler();
 
     LinkBuffer patchBuffer(*vm, &jit, GLOBAL_THUNK_ID);
     return FINALIZE_CODE(patchBuffer, ("native %s trampoline", toCString(kind).data()));
index 460a640..fef4f5d 100644 (file)
@@ -340,7 +340,17 @@ namespace JSC {
         {
             return OBJECT_OFFSETOF(VM, m_exception);
         }
-        
+
+        static ptrdiff_t callFrameForThrowOffset()
+        {
+            return OBJECT_OFFSETOF(VM, callFrameForThrow);
+        }
+
+        static ptrdiff_t targetMachinePCForThrowOffset()
+        {
+            return OBJECT_OFFSETOF(VM, targetMachinePCForThrow);
+        }
+
         JS_EXPORT_PRIVATE void clearException();
         JS_EXPORT_PRIVATE void clearExceptionStack();
         void getExceptionInfo(JSValue& exception, RefCountedArray<StackFrame>& exceptionStack);