StackOverflow stack unwinding should stop at native frames.
authormark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 5 Sep 2015 01:03:45 +0000 (01:03 +0000)
committermark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 5 Sep 2015 01:03:45 +0000 (01:03 +0000)
commite546e1bac94696d3788f245be9913cdbf6b90d5f
treef1b3133277ebd5627d61090130bd785240703d0e
parent68770e0b3c50d6fac43e0a971f42faa928675226
StackOverflow stack unwinding should stop at native frames.
https://bugs.webkit.org/show_bug.cgi?id=148749

Reviewed by Michael Saboff.

In the present code, after ping-pong'ing back and forth between native and JS
code a few times, if we have a stack overflow on re-entry into the VM to run
JS code's whose stack frame would overflow the JS stack, the code will end up
unwinding past the native function that is making the call to re-enter the VM.
As a result, any clean up code (e.g. destructors for stack variables) in the
skipped native function frame (and its chain of native function callers) will
not be called.

This patch is based on the Michael Saboff's fix of this issue landed on the
jsc-tailcall branch: http://trac.webkit.org/changeset/188555

We now check for the case where there are no JS frames to unwind since the
last native frame, and treat the exception as an unhandled exception.  The
native function is responsible for further propagating the exception if needed.

Other supporting work:
1. Remove vm->vmEntryFrameForThrow.  It should always be the same as
   vm->topVMEntryFrame.
2. Change operationThrowStackOverflowError() to use the throwStackOverflowError()
   helper function instead of rolling its own.
3. In the LLINT vm entry, set vm->topVMEntryFrame as soon as the entry frame is
   fully initialized (instead of waiting).  With this, we can always reliably
   tell which VMEntryFrame is on top.
4. Added a test that exercises this edge case.  The test should not hang or crash.

* API/tests/PingPongStackOverflowTest.cpp: Added.
(PingPongStackOverflowObject_hasInstance):
(testPingPongStackOverflow):
* API/tests/PingPongStackOverflowTest.h: Added.
* API/tests/testapi.c:
(main):
* JavaScriptCore.xcodeproj/project.pbxproj:
* interpreter/Interpreter.cpp:
(JSC::unwindCallFrame):
(JSC::getStackFrameCodeType):
(JSC::UnwindFunctor::UnwindFunctor):
(JSC::UnwindFunctor::operator()):
(JSC::Interpreter::unwind):
* interpreter/Interpreter.h:
(JSC::NativeCallFrameTracer::NativeCallFrameTracer):
(JSC::NativeCallFrameTracerWithRestore::NativeCallFrameTracerWithRestore):
(JSC::NativeCallFrameTracerWithRestore::~NativeCallFrameTracerWithRestore):
(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::callFrameForThrowOffset):
(JSC::VM::vmEntryFrameForThrowOffset): Deleted.
(JSC::VM::topVMEntryFrameOffset): Deleted.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@189411 268f45cc-cd09-0410-ab3c-d52691b4dbfc
17 files changed:
Source/JavaScriptCore/API/tests/PingPongStackOverflowTest.cpp [new file with mode: 0644]
Source/JavaScriptCore/API/tests/PingPongStackOverflowTest.h [new file with mode: 0644]
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