Rollout r189411, r189413: Broke JSC tests.
authormark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 5 Sep 2015 03:10:23 +0000 (03:10 +0000)
committermark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 5 Sep 2015 03:10:23 +0000 (03:10 +0000)
Not reviewed.

* API/tests/PingPongStackOverflowTest.cpp: Removed.
* API/tests/PingPongStackOverflowTest.h: Removed.
* API/tests/testapi.c:
(main):
* JavaScriptCore.xcodeproj/project.pbxproj:
* interpreter/CallFrame.h:
(JSC::ExecState::operator=):
(JSC::ExecState::callerFrame):
(JSC::ExecState::argIndexForRegister):
(JSC::ExecState::callerFrameOrVMEntryFrame):
(JSC::ExecState::callerFrameAndPC):
* interpreter/Interpreter.cpp:
(JSC::UnwindFunctor::UnwindFunctor):
(JSC::UnwindFunctor::operator()):
(JSC::Interpreter::unwind):
* interpreter/Interpreter.h:
(JSC::NativeCallFrameTracer::NativeCallFrameTracer):
(JSC::Interpreter::sampler):
* jit/CCallHelpers.h:
(JSC::CCallHelpers::jumpToExceptionHandler):
* jit/JITExceptions.cpp:
(JSC::genericUnwind):
* jit/JITExceptions.h:
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_catch):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_catch):
* jit/JITOperations.cpp:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/VM.h:
(JSC::VM::exceptionOffset):
(JSC::VM::vmEntryFrameForThrowOffset):
(JSC::VM::topVMEntryFrameOffset):
(JSC::VM::callFrameForThrowOffset):

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

17 files changed:
Source/JavaScriptCore/API/tests/PingPongStackOverflowTest.cpp [deleted file]
Source/JavaScriptCore/API/tests/PingPongStackOverflowTest.h [deleted file]
Source/JavaScriptCore/API/tests/testapi.c
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/interpreter/CallFrame.h
Source/JavaScriptCore/interpreter/Interpreter.cpp
Source/JavaScriptCore/interpreter/Interpreter.h
Source/JavaScriptCore/jit/CCallHelpers.h
Source/JavaScriptCore/jit/JITExceptions.cpp
Source/JavaScriptCore/jit/JITExceptions.h
Source/JavaScriptCore/jit/JITOpcodes.cpp
Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
Source/JavaScriptCore/jit/JITOperations.cpp
Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
Source/JavaScriptCore/runtime/VM.h

diff --git a/Source/JavaScriptCore/API/tests/PingPongStackOverflowTest.cpp b/Source/JavaScriptCore/API/tests/PingPongStackOverflowTest.cpp
deleted file mode 100644 (file)
index 33f0772..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "PingPongStackOverflowTest.h"
-
-#include "InitializeThreading.h"
-#include "JSContextRefPrivate.h"
-#include "JavaScriptCore.h"
-#include "Options.h"
-#include <wtf/text/StringBuilder.h>
-
-using JSC::Options;
-
-static JSGlobalContextRef context = nullptr;
-static int nativeRecursionCount = 0;
-
-static bool PingPongStackOverflowObject_hasInstance(JSContextRef context, JSObjectRef constructor, JSValueRef possibleValue, JSValueRef* exception)
-{
-    UNUSED_PARAM(context);
-    UNUSED_PARAM(constructor);
-
-    JSStringRef hasInstanceName = JSStringCreateWithUTF8CString("hasInstance");
-    JSValueRef hasInstance = JSObjectGetProperty(context, constructor, hasInstanceName, exception);
-    JSStringRelease(hasInstanceName);
-    if (!hasInstance)
-        return false;
-
-    int countAtEntry = nativeRecursionCount++;
-
-    JSValueRef result = 0;
-    if (nativeRecursionCount < 100) {
-        JSObjectRef function = JSValueToObject(context, hasInstance, exception);
-        result = JSObjectCallAsFunction(context, function, constructor, 1, &possibleValue, exception);
-    } else {
-        StringBuilder builder;
-        builder.append("dummy.valueOf([0]");
-        for (int i = 1; i < 35000; i++) {
-            builder.append(", [");
-            builder.appendNumber(i);
-            builder.append("]");
-        }
-        builder.append(");");
-
-        JSStringRef script = JSStringCreateWithUTF8CString(builder.toString().utf8().data());
-        result = JSEvaluateScript(context, script, NULL, NULL, 1, exception);
-        JSStringRelease(script);
-    }
-
-    --nativeRecursionCount;
-    if (nativeRecursionCount != countAtEntry)
-        printf("    ERROR: PingPongStackOverflow test saw a recursion count mismatch\n");
-
-    return result && JSValueToBoolean(context, result);
-}
-
-JSClassDefinition PingPongStackOverflowObject_definition = {
-    0,
-    kJSClassAttributeNone,
-    
-    "PingPongStackOverflowObject",
-    NULL,
-    
-    NULL,
-    NULL,
-    
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    PingPongStackOverflowObject_hasInstance,
-    NULL,
-};
-
-static JSClassRef PingPongStackOverflowObject_class(JSContextRef context)
-{
-    UNUSED_PARAM(context);
-    
-    static JSClassRef jsClass;
-    if (!jsClass)
-        jsClass = JSClassCreate(&PingPongStackOverflowObject_definition);
-    
-    return jsClass;
-}
-
-// This tests tests a stack overflow on VM reentry into a JS function from a native function
-// after ping-pong'ing back and forth between JS and native functions multiple times.
-// This test should not hang or crash.
-int testPingPongStackOverflow()
-{
-    bool failed = false;
-
-    JSC::initializeThreading();
-    Options::initialize(); // Ensure options is initialized first.
-
-    auto origReservedZoneSize = Options::reservedZoneSize();
-    auto origErrorModeReservedZoneSize = Options::errorModeReservedZoneSize();
-    auto origUseLLInt = Options::useLLInt();
-    auto origMaxPerThreadStackUsage = Options::maxPerThreadStackUsage();
-
-    Options::reservedZoneSize() = 128 * KB;
-    Options::errorModeReservedZoneSize() = 64 * KB;
-#if ENABLE(JIT)
-    // Normally, we want to disable the LLINT to force the use of JITted code which is necessary for
-    // reproducing the regression in https://bugs.webkit.org/show_bug.cgi?id=148749. However, we only
-    // want to do this if the LLINT isn't the only available execution engine.
-    Options::useLLInt() = false;
-#endif
-
-    const char* scriptString =
-        "var count = 0;" \
-        "PingPongStackOverflowObject.hasInstance = function f() {" \
-        "    return (undefined instanceof PingPongStackOverflowObject);" \
-        "};" \
-        "PingPongStackOverflowObject.__proto__ = undefined;" \
-        "undefined instanceof PingPongStackOverflowObject;";
-
-    JSValueRef scriptResult = nullptr;
-    JSValueRef exception = nullptr;
-    JSStringRef script = JSStringCreateWithUTF8CString(scriptString);
-
-    nativeRecursionCount = 0;
-    context = JSGlobalContextCreateInGroup(nullptr, nullptr);
-
-    JSObjectRef globalObject = JSContextGetGlobalObject(context);
-    ASSERT(JSValueIsObject(context, globalObject));
-
-    JSObjectRef PingPongStackOverflowObject = JSObjectMake(context, PingPongStackOverflowObject_class(context), NULL);
-    JSStringRef PingPongStackOverflowObjectString = JSStringCreateWithUTF8CString("PingPongStackOverflowObject");
-    JSObjectSetProperty(context, globalObject, PingPongStackOverflowObjectString, PingPongStackOverflowObject, kJSPropertyAttributeNone, NULL);
-    JSStringRelease(PingPongStackOverflowObjectString);
-
-    unsigned stackSize = 32 * KB;
-    Options::maxPerThreadStackUsage() = stackSize + Options::reservedZoneSize();
-
-    exception = nullptr;
-    scriptResult = JSEvaluateScript(context, script, nullptr, nullptr, 1, &exception);
-
-    if (!exception) {
-        printf("FAIL: PingPongStackOverflowError not thrown in PingPongStackOverflow test\n");
-        failed = true;
-    } else if (nativeRecursionCount) {
-        printf("FAIL: Unbalanced native recursion count: %d in PingPongStackOverflow test\n", nativeRecursionCount);
-        failed = true;
-    } else {
-        printf("PASS: PingPongStackOverflow test.\n");
-    }
-
-    Options::reservedZoneSize() = origReservedZoneSize;
-    Options::errorModeReservedZoneSize() = origErrorModeReservedZoneSize;
-    Options::useLLInt() = origUseLLInt;
-    Options::maxPerThreadStackUsage() = origMaxPerThreadStackUsage;
-
-    return failed;
-}
diff --git a/Source/JavaScriptCore/API/tests/PingPongStackOverflowTest.h b/Source/JavaScriptCore/API/tests/PingPongStackOverflowTest.h
deleted file mode 100644 (file)
index 7f5911b..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef PingPongStackOverflowTest_h
-#define PingPongStackOverflowTest_h
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int testPingPongStackOverflow();
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* PingPongStackOverflowTest_h */
index cbf9daf..81cbc40 100644 (file)
@@ -41,9 +41,9 @@
 
 #include "CompareAndSwapTest.h"
 #include "CustomGlobalObjectClassTest.h"
-#include "ExecutionTimeLimitTest.h"
 #include "GlobalContextWithFinalizerTest.h"
-#include "PingPongStackOverflowTest.h"
+
+#include "ExecutionTimeLimitTest.h"
 
 #if JSC_OBJC_API_ENABLED
 void testObjectiveCAPI(void);
@@ -1893,7 +1893,6 @@ int main(int argc, char* argv[])
 
     failed = testExecutionTimeLimit() || failed;
     failed = testGlobalContextWithFinalizer() || failed;
-    failed = testPingPongStackOverflow() || failed;
 
     // Clear out local variables pointing at JSObjectRefs to allow their values to be collected
     function = NULL;
index b56a9f8..c3ca776 100644 (file)
@@ -1,3 +1,45 @@
+2015-09-04  Mark Lam  <mark.lam@apple.com>
+
+        Rollout r189411, r189413: Broke JSC tests.
+
+        Not reviewed.
+
+        * API/tests/PingPongStackOverflowTest.cpp: Removed.
+        * API/tests/PingPongStackOverflowTest.h: Removed.
+        * API/tests/testapi.c:
+        (main):
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * interpreter/CallFrame.h:
+        (JSC::ExecState::operator=):
+        (JSC::ExecState::callerFrame):
+        (JSC::ExecState::argIndexForRegister):
+        (JSC::ExecState::callerFrameOrVMEntryFrame):
+        (JSC::ExecState::callerFrameAndPC):
+        * interpreter/Interpreter.cpp:
+        (JSC::UnwindFunctor::UnwindFunctor):
+        (JSC::UnwindFunctor::operator()):
+        (JSC::Interpreter::unwind):
+        * interpreter/Interpreter.h:
+        (JSC::NativeCallFrameTracer::NativeCallFrameTracer):
+        (JSC::Interpreter::sampler):
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::jumpToExceptionHandler):
+        * jit/JITExceptions.cpp:
+        (JSC::genericUnwind):
+        * jit/JITExceptions.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_catch):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_catch):
+        * jit/JITOperations.cpp:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/VM.h:
+        (JSC::VM::exceptionOffset):
+        (JSC::VM::vmEntryFrameForThrowOffset):
+        (JSC::VM::topVMEntryFrameOffset):
+        (JSC::VM::callFrameForThrowOffset):
+
 2015-09-04  Joseph Pecoraro  <pecoraro@apple.com>
 
         Web Inspector: Test Runtime.saveResult and $n values
index 0f68a9f..04a123f 100644 (file)
                FE68C6381B90DE0B0042BCB3 /* MacroAssemblerPrinter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE68C6351B90DDD90042BCB3 /* MacroAssemblerPrinter.cpp */; };
                FE7BA60F1A1A7CEC00F1F7B4 /* HeapVerifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE7BA60D1A1A7CEC00F1F7B4 /* HeapVerifier.cpp */; };
                FE7BA6101A1A7CEC00F1F7B4 /* HeapVerifier.h in Headers */ = {isa = PBXBuildFile; fileRef = FE7BA60E1A1A7CEC00F1F7B4 /* HeapVerifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               FE7C41961B97FC4B00F4D598 /* PingPongStackOverflowTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEDA50D41B97F442009A3B4F /* PingPongStackOverflowTest.cpp */; };
                FEA08620182B7A0400F6D851 /* Breakpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = FEA0861E182B7A0400F6D851 /* Breakpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
                FEA08621182B7A0400F6D851 /* DebuggerPrimitives.h in Headers */ = {isa = PBXBuildFile; fileRef = FEA0861F182B7A0400F6D851 /* DebuggerPrimitives.h */; settings = {ATTRIBUTES = (Private, ); }; };
                FEB51F6C1A97B688001F921C /* Regress141809.mm in Sources */ = {isa = PBXBuildFile; fileRef = FEB51F6B1A97B688001F921C /* Regress141809.mm */; };
                FED287B115EC9A5700DA8161 /* LLIntOpcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntOpcode.h; path = llint/LLIntOpcode.h; sourceTree = "<group>"; };
                FED94F2B171E3E2300BE77A4 /* Watchdog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Watchdog.cpp; sourceTree = "<group>"; };
                FED94F2C171E3E2300BE77A4 /* Watchdog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Watchdog.h; sourceTree = "<group>"; };
-               FEDA50D41B97F442009A3B4F /* PingPongStackOverflowTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PingPongStackOverflowTest.cpp; path = API/tests/PingPongStackOverflowTest.cpp; sourceTree = "<group>"; };
-               FEDA50D51B97F4D9009A3B4F /* PingPongStackOverflowTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PingPongStackOverflowTest.h; path = API/tests/PingPongStackOverflowTest.h; sourceTree = "<group>"; };
                FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CompareAndSwapTest.cpp; path = API/tests/CompareAndSwapTest.cpp; sourceTree = "<group>"; };
                FEF040521AAEC4ED00BD28B0 /* CompareAndSwapTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CompareAndSwapTest.h; path = API/tests/CompareAndSwapTest.h; sourceTree = "<group>"; };
                FEF6835A174343CC00A32E25 /* JITStubsARM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITStubsARM.h; sourceTree = "<group>"; };
                                FE0D4A081ABA2437002F54BF /* GlobalContextWithFinalizerTest.h */,
                                C2181FC018A948FB0025A235 /* JSExportTests.h */,
                                C2181FC118A948FB0025A235 /* JSExportTests.mm */,
-                               FEDA50D41B97F442009A3B4F /* PingPongStackOverflowTest.cpp */,
-                               FEDA50D51B97F4D9009A3B4F /* PingPongStackOverflowTest.h */,
                                65570F581AA4C00A009B3C23 /* Regress141275.h */,
                                65570F591AA4C00A009B3C23 /* Regress141275.mm */,
                                FEB51F6A1A97B688001F921C /* Regress141809.h */,
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
-                               FE7C41961B97FC4B00F4D598 /* PingPongStackOverflowTest.cpp in Sources */,
                                FE0D4A091ABA2437002F54BF /* GlobalContextWithFinalizerTest.cpp in Sources */,
                                65570F5A1AA4C3EA009B3C23 /* Regress141275.mm in Sources */,
                                C29ECB031804D0ED00D2CBB4 /* CurrentThisInsideBlockGetterTest.mm in Sources */,
index 9e5b55f..2075c87 100644 (file)
@@ -111,7 +111,6 @@ namespace JSC  {
         CallFrame& operator=(const Register& r) { *static_cast<Register*>(this) = r; return *this; }
 
         CallFrame* callerFrame() const { return static_cast<CallFrame*>(callerFrameOrVMEntryFrame()); }
-        void* callerFrameOrVMEntryFrame() const { return callerFrameAndPC().callerFrame; }
 
         JS_EXPORT_PRIVATE CallFrame* callerFrame(VMEntryFrame*&);
 
@@ -276,6 +275,8 @@ namespace JSC  {
             return argIndex;
         }
 
+        void* callerFrameOrVMEntryFrame() const { return callerFrameAndPC().callerFrame; }
+
         CallerFrameAndPC& callerFrameAndPC() { return *reinterpret_cast<CallerFrameAndPC*>(this); }
         const CallerFrameAndPC& callerFrameAndPC() const { return *reinterpret_cast<const CallerFrameAndPC*>(this); }
 
index 1f6773b..4b0f12c 100644 (file)
@@ -631,8 +631,9 @@ private:
 
 class UnwindFunctor {
 public:
-    UnwindFunctor(CallFrame*& callFrame, bool isTermination, CodeBlock*& codeBlock, HandlerInfo*& handler)
-        : m_callFrame(callFrame)
+    UnwindFunctor(VMEntryFrame*& vmEntryFrame, CallFrame*& callFrame, bool isTermination, CodeBlock*& codeBlock, HandlerInfo*& handler)
+        : m_vmEntryFrame(vmEntryFrame)
+        , m_callFrame(callFrame)
         , m_isTermination(isTermination)
         , m_codeBlock(codeBlock)
         , m_handler(handler)
@@ -642,6 +643,7 @@ public:
     StackVisitor::Status operator()(StackVisitor& visitor)
     {
         VM& vm = m_callFrame->vm();
+        m_vmEntryFrame = visitor->vmEntryFrame();
         m_callFrame = visitor->callFrame();
         m_codeBlock = visitor->codeBlock();
         unsigned bytecodeOffset = visitor->bytecodeOffset();
@@ -659,22 +661,15 @@ public:
     }
 
 private:
+    VMEntryFrame*& m_vmEntryFrame;
     CallFrame*& m_callFrame;
     bool m_isTermination;
     CodeBlock*& m_codeBlock;
     HandlerInfo*& m_handler;
 };
 
-NEVER_INLINE HandlerInfo* Interpreter::unwind(VM& vm, CallFrame*& callFrame, Exception* exception, UnwindStart unwindStart)
+NEVER_INLINE HandlerInfo* Interpreter::unwind(VMEntryFrame*& vmEntryFrame, CallFrame*& callFrame, Exception* exception)
 {
-    if (unwindStart == UnwindFromCallerFrame) {
-        if (callFrame->callerFrameOrVMEntryFrame() == vm.topVMEntryFrame)
-            return nullptr;
-
-        callFrame = callFrame->callerFrame();
-        vm.topCallFrame = callFrame;
-    }
-
     CodeBlock* codeBlock = callFrame->codeBlock();
     bool isTermination = false;
 
@@ -689,13 +684,13 @@ NEVER_INLINE HandlerInfo* Interpreter::unwind(VM& vm, CallFrame*& callFrame, Exc
     if (exceptionValue.isObject())
         isTermination = isTerminatedExecutionException(exception);
 
-    ASSERT(vm.exception() && vm.exception()->stack().size());
+    ASSERT(callFrame->vm().exception() && callFrame->vm().exception()->stack().size());
 
     Debugger* debugger = callFrame->vmEntryGlobalObject()->debugger();
     if (debugger && debugger->needsExceptionCallbacks() && !exception->didNotifyInspectorOfThrow()) {
         // We need to clear the exception here in order to see if a new exception happens.
         // Afterwards, the values are put back to continue processing this error.
-        SuspendExceptionScope scope(&vm);
+        SuspendExceptionScope scope(&callFrame->vm());
         // This code assumes that if the debugger is enabled then there is no inlining.
         // If that assumption turns out to be false then we'll ignore the inlined call
         // frames.
@@ -718,11 +713,13 @@ NEVER_INLINE HandlerInfo* Interpreter::unwind(VM& vm, CallFrame*& callFrame, Exc
     exception->setDidNotifyInspectorOfThrow();
 
     // Calculate an exception handler vPC, unwinding call frames as necessary.
-    HandlerInfo* handler = nullptr;
-    UnwindFunctor functor(callFrame, isTermination, codeBlock, handler);
+    HandlerInfo* handler = 0;
+    VM& vm = callFrame->vm();
+    ASSERT(callFrame == vm.topCallFrame);
+    UnwindFunctor functor(vmEntryFrame, callFrame, isTermination, codeBlock, handler);
     callFrame->iterate(functor);
     if (!handler)
-        return nullptr;
+        return 0;
 
     if (LegacyProfiler* profiler = vm.enabledProfiler())
         profiler->exceptionUnwind(callFrame);
index a96efb7..4fefaa6 100644 (file)
@@ -67,8 +67,6 @@ namespace JSC {
     struct Instruction;
     struct ProtoCallFrame;
 
-    enum UnwindStart { UnwindFromCurrentFrame, UnwindFromCallerFrame };
-
     enum DebugHookID {
         WillExecuteProgram,
         DidExecuteProgram,
@@ -147,7 +145,6 @@ namespace JSC {
         {
             ASSERT(vm);
             ASSERT(callFrame);
-            ASSERT(callFrame < vm->topVMEntryFrame);
             vm->topCallFrame = callFrame;
         }
     };
@@ -225,7 +222,7 @@ namespace JSC {
         
         SamplingTool* sampler() { return m_sampler.get(); }
 
-        NEVER_INLINE HandlerInfo* unwind(VM&, CallFrame*&, Exception*, UnwindStart);
+        NEVER_INLINE HandlerInfo* unwind(VMEntryFrame*&, CallFrame*&, Exception*);
         NEVER_INLINE void debug(CallFrame*, DebugHookID);
         JSString* stackTraceAsString(ExecState*, Vector<StackFrame>);
 
index b790e12..9bdefaf 100644 (file)
@@ -2078,6 +2078,7 @@ public:
     void jumpToExceptionHandler()
     {
         // genericUnwind() leaves the handler CallFrame* in vm->callFrameForThrow,
+        // the topVMEntryFrame for the handler in vm->vmEntryFrameForThrow,
         // and the address of the handler in vm->targetMachinePCForThrow.
         loadPtr(&vm()->targetMachinePCForThrow, GPRInfo::regT1);
         jump(GPRInfo::regT1);
index d634416..4f6d9e8 100644 (file)
@@ -40,7 +40,7 @@
 
 namespace JSC {
 
-void genericUnwind(VM* vm, ExecState* callFrame, UnwindStart unwindStart)
+void genericUnwind(VM* vm, ExecState* callFrame)
 {
     if (Options::breakOnThrow()) {
         dataLog("In call frame ", RawPointer(callFrame), " for code block ", *callFrame->codeBlock(), "\n");
@@ -49,7 +49,8 @@ void genericUnwind(VM* vm, ExecState* callFrame, UnwindStart unwindStart)
     
     Exception* exception = vm->exception();
     RELEASE_ASSERT(exception);
-    HandlerInfo* handler = vm->interpreter->unwind(*vm, callFrame, exception, unwindStart); // This may update callFrame.
+    VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
+    HandlerInfo* handler = vm->interpreter->unwind(vmEntryFrame, callFrame, exception); // This may update vmEntryFrame and callFrame.
 
     void* catchRoutine;
     Instruction* catchPCForInterpreter = 0;
@@ -63,6 +64,7 @@ void genericUnwind(VM* vm, ExecState* callFrame, UnwindStart unwindStart)
     } else
         catchRoutine = LLInt::getCodePtr(handleUncaughtException);
     
+    vm->vmEntryFrameForThrow = vmEntryFrame;
     vm->callFrameForThrow = callFrame;
     vm->targetMachinePCForThrow = catchRoutine;
     vm->targetInterpreterPCForThrow = catchPCForInterpreter;
index 3ccac84..43b92e7 100644 (file)
@@ -26,7 +26,6 @@
 #ifndef JITExceptions_h
 #define JITExceptions_h
 
-#include "Interpreter.h"
 #include "JSCJSValue.h"
 
 namespace JSC {
@@ -34,7 +33,7 @@ namespace JSC {
 class ExecState;
 class VM;
 
-void genericUnwind(VM*, ExecState*, UnwindStart = UnwindFromCurrentFrame);
+void genericUnwind(VM*, ExecState*);
 
 } // namespace JSC
 
index a2953e9..29eb64a 100644 (file)
@@ -501,6 +501,8 @@ void JIT::emit_op_catch(Instruction* currentInstruction)
     
     move(TrustedImmPtr(m_vm), regT3);
     load64(Address(regT3, VM::callFrameForThrowOffset()), callFrameRegister);
+    load64(Address(regT3, VM::vmEntryFrameForThrowOffset()), regT0);
+    store64(regT0, Address(regT3, VM::topVMEntryFrameOffset()));
 
     addPtr(TrustedImm32(stackPointerOffsetFor(codeBlock()) * sizeof(Register)), callFrameRegister, stackPointerRegister);
 
index fd79478..b421a54 100644 (file)
@@ -803,6 +803,8 @@ void JIT::emit_op_catch(Instruction* currentInstruction)
     move(TrustedImmPtr(m_vm), regT3);
     // operationThrow returns the callFrame for the handler.
     load32(Address(regT3, VM::callFrameForThrowOffset()), callFrameRegister);
+    load32(Address(regT3, VM::vmEntryFrameForThrowOffset()), regT0);
+    store32(regT0, Address(regT3, VM::topVMEntryFrameOffset()));
 
     addPtr(TrustedImm32(stackPointerOffsetFor(codeBlock()) * sizeof(Register)), callFrameRegister, stackPointerRegister);
 
index d7dc508..be3a9b0 100644 (file)
@@ -91,7 +91,8 @@ void JIT_OPERATION operationThrowStackOverflowError(ExecState* exec, CodeBlock*
         callerFrame = exec;
 
     NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
-    throwStackOverflowError(callerFrame);
+    ErrorHandlingScope errorScope(*vm);
+    vm->throwException(callerFrame, createStackOverflowError(callerFrame));
 }
 
 #if ENABLE(WEBASSEMBLY)
@@ -110,12 +111,13 @@ void JIT_OPERATION operationThrowDivideError(ExecState* exec)
 int32_t JIT_OPERATION operationCallArityCheck(ExecState* exec)
 {
     VM* vm = &exec->vm();
+    VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
+    CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
+
     JSStack& stack = vm->interpreter->stack();
 
     int32_t missingArgCount = CommonSlowPaths::arityCheckFor(exec, &stack, CodeForCall);
     if (missingArgCount < 0) {
-        VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
-        CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
         NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
         throwStackOverflowError(callerFrame);
     }
@@ -126,12 +128,13 @@ int32_t JIT_OPERATION operationCallArityCheck(ExecState* exec)
 int32_t JIT_OPERATION operationConstructArityCheck(ExecState* exec)
 {
     VM* vm = &exec->vm();
+    VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
+    CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
+
     JSStack& stack = vm->interpreter->stack();
 
     int32_t missingArgCount = CommonSlowPaths::arityCheckFor(exec, &stack, CodeForConstruct);
     if (missingArgCount < 0) {
-        VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
-        CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
         NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
         throwStackOverflowError(callerFrame);
     }
@@ -2033,7 +2036,7 @@ void JIT_OPERATION operationThrow(ExecState* exec, EncodedJSValue encodedExcepti
     JSValue exceptionValue = JSValue::decode(encodedExceptionValue);
     vm->throwException(exec, exceptionValue);
 
-    // Results stored out-of-band in vm.targetMachinePCForThrow & vm.callFrameForThrow
+    // Results stored out-of-band in vm.targetMachinePCForThrow, vm.callFrameForThrow & vm.vmEntryFrameForThrow
     genericUnwind(vm, exec);
 }
 
@@ -2079,8 +2082,12 @@ void JIT_OPERATION lookupExceptionHandler(VM* vm, ExecState* exec)
 
 void JIT_OPERATION lookupExceptionHandlerFromCallerFrame(VM* vm, ExecState* exec)
 {
-    NativeCallFrameTracer tracer(vm, exec);
-    genericUnwind(vm, exec, UnwindFromCallerFrame);
+    VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
+    CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
+    ASSERT(callerFrame);
+
+    NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
+    genericUnwind(vm, callerFrame);
     ASSERT(vm->targetMachinePCForThrow);
 }
 
index 082b173..4d3dc87 100644 (file)
@@ -127,7 +127,6 @@ macro doVMEntry(makeCall)
     storep t4, VMEntryRecord::m_prevTopCallFrame[sp]
     loadp VM::topVMEntryFrame[vm], t4
     storep t4, VMEntryRecord::m_prevTopVMEntryFrame[sp]
-    storep cfr, VM::topVMEntryFrame[vm]
 
     # Align stack pointer
     if X86_WIN
@@ -236,6 +235,7 @@ macro doVMEntry(makeCall)
 
 .copyArgsDone:
     storep sp, VM::topCallFrame[vm]
+    storep cfr, VM::topVMEntryFrame[vm]
 
     makeCall(entry, t3, t4)
 
@@ -1879,6 +1879,8 @@ _llint_op_catch:
     andp MarkedBlockMask, t3
     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
     loadp VM::callFrameForThrow[t3], cfr
+    loadp VM::vmEntryFrameForThrow[t3], t0
+    storep t0, VM::topVMEntryFrame[t3]
     restoreStackPointerAfterCall()
 
     loadi VM::targetInterpreterPCForThrow[t3], PC
index f9a0308..f80fb6f 100644 (file)
@@ -131,7 +131,6 @@ macro doVMEntry(makeCall)
     storep t4, VMEntryRecord::m_prevTopCallFrame[sp]
     loadp VM::topVMEntryFrame[vm], t4
     storep t4, VMEntryRecord::m_prevTopVMEntryFrame[sp]
-    storep cfr, VM::topVMEntryFrame[vm]
 
     loadi ProtoCallFrame::paddedArgCount[protoCallFrame], t4
     addp CallFrameHeaderSlots, t4, t4
@@ -214,6 +213,7 @@ macro doVMEntry(makeCall)
     else
         storep sp, VM::topCallFrame[vm]
     end
+    storep cfr, VM::topVMEntryFrame[vm]
 
     move TagTypeNumber, tagTypeNumber
     addp TagBitTypeOther, tagTypeNumber, tagMask
@@ -1775,6 +1775,8 @@ _llint_op_catch:
     andp MarkedBlockMask, t3
     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
     loadp VM::callFrameForThrow[t3], cfr
+    loadp VM::vmEntryFrameForThrow[t3], t0
+    storep t0, VM::topVMEntryFrame[t3]
     restoreStackPointerAfterCall()
 
     loadp CodeBlock[cfr], PB
index 2eb13d7..84a535a 100644 (file)
@@ -377,6 +377,16 @@ public:
         return OBJECT_OFFSETOF(VM, m_exception);
     }
 
+    static ptrdiff_t vmEntryFrameForThrowOffset()
+    {
+        return OBJECT_OFFSETOF(VM, vmEntryFrameForThrow);
+    }
+
+    static ptrdiff_t topVMEntryFrameOffset()
+    {
+        return OBJECT_OFFSETOF(VM, topVMEntryFrame);
+    }
+
     static ptrdiff_t callFrameForThrowOffset()
     {
         return OBJECT_OFFSETOF(VM, callFrameForThrow);
@@ -441,6 +451,7 @@ public:
     JSValue hostCallReturnValue;
     unsigned varargsLength;
     ExecState* newCallFrameReturnValue;
+    VMEntryFrame* vmEntryFrameForThrow;
     ExecState* callFrameForThrow;
     void* targetMachinePCForThrow;
     Instruction* targetInterpreterPCForThrow;