Ignore:
Timestamp:
Aug 15, 2013, 6:47:41 PM (12 years ago)
Author:
[email protected]
Message:

Fix crash when performing activation tearoff.
https://bugs.webkit.org/show_bug.cgi?id=119848

Reviewed by Oliver Hunt.

The activation tearoff crash was due to a bug in the baseline JIT.
If we have a scenario where the a baseline JIT frame calls a LLINT
frame, an exception may be thrown while in the LLINT.

Interpreter::throwException() which handles the exception will unwind
all frames until it finds a catcher or sees a host frame. When we
return from the LLINT to the baseline JIT code, the baseline JIT code
errorneously sets topCallFrame to the value in its call frame register,
and starts unwinding the stack frames that have already been unwound.

The fix is:

  1. Rename ctiVMThrowTrampolineSlowpath to ctiVMHandleException. This is a more accurate description of what this runtime function is supposed to do i.e. it handles the exception which include doing nothing (if there are no more frames to unwind).
  2. Fix up topCallFrame values so that the HostCallFrameFlag is never set on it.
  3. Reloading the call frame register from topCallFrame when we're returning from a callee and detect exception handling in progress.
  • interpreter/Interpreter.cpp:

(JSC::Interpreter::unwindCallFrame):

  • Ensure that topCallFrame is not set with the HostCallFrameFlag.

(JSC::Interpreter::getStackTrace):

  • interpreter/Interpreter.h:

(JSC::TopCallFrameSetter::TopCallFrameSetter):
(JSC::TopCallFrameSetter::~TopCallFrameSetter):
(JSC::NativeCallFrameTracer::NativeCallFrameTracer):

  • Ensure that topCallFrame is not set with the HostCallFrameFlag.
  • jit/JIT.h:
  • jit/JITExceptions.cpp:

(JSC::uncaughtExceptionHandler):

  • Convenience function to get the handler for uncaught exceptions.
  • jit/JITExceptions.h:
  • jit/JITInlines.h:

(JSC::JIT::reloadCallFrameFromTopCallFrame):

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::privateCompileCTINativeCall):

  • Rename ctiVMThrowTrampolineSlowpath to ctiVMHandleException.
  • jit/JITStubs.cpp:

(JSC::throwExceptionFromOpCall):

  • Ensure that topCallFrame is not set with the HostCallFrameFlag.

(JSC::cti_vm_handle_exception):

  • Check for the case when there are no more frames to unwind.
  • jit/JITStubs.h:
  • jit/JITStubsARM.h:
  • jit/JITStubsARMv7.h:
  • jit/JITStubsMIPS.h:
  • jit/JITStubsSH4.h:
  • jit/JITStubsX86.h:
  • jit/JITStubsX86_64.h:
  • Rename ctiVMThrowTrampolineSlowpath to ctiVMHandleException.
  • jit/SlowPathCall.h:

(JSC::JITSlowPathCall::call):

  • reload cfr from topcallFrame when handling an exception.
  • Rename ctiVMThrowTrampolineSlowpath to ctiVMHandleException.
  • jit/ThunkGenerators.cpp:

(JSC::nativeForGenerator):

  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
  • reload cfr from topcallFrame when handling an exception.
  • runtime/VM.cpp:

(JSC::VM::VM):

  • Ensure that topCallFrame is not set with the HostCallFrameFlag.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/jit/JITStubs.cpp

    r154016 r154156  
    418418template<typename T> static T throwExceptionFromOpCall(JITStackFrame& jitStackFrame, CallFrame* newCallFrame, ReturnAddressPtr& returnAddressSlot, ErrorFunctor& createError )
    419419{
    420     CallFrame* callFrame = newCallFrame->callerFrame();
     420    CallFrame* callFrame = newCallFrame->callerFrame()->removeHostCallFrameFlag();
    421421    jitStackFrame.callFrame = callFrame;
    422422    callFrame->vm().topCallFrame = callFrame;
     
    21602160
    21612161#if USE(JSVALUE32_64)
    2162 EncodedExceptionHandler JIT_STUB cti_vm_throw_slowpath(CallFrame* callFrame)
    2163 {
     2162EncodedExceptionHandler JIT_STUB cti_vm_handle_exception(CallFrame* callFrame)
     2163{
     2164    ASSERT(!callFrame->hasHostCallFrameFlag());
     2165    if (!callFrame) {
     2166        // The entire stack has already been unwound. Nothing more to handle.
     2167        return uncaughtExceptionHandler();
     2168    }
     2169
    21642170    VM* vm = callFrame->codeBlock()->vm();
    21652171    vm->topCallFrame = callFrame;
     
    21672173}
    21682174#else
    2169 ExceptionHandler JIT_STUB cti_vm_throw_slowpath(CallFrame* callFrame)
    2170 {
     2175ExceptionHandler JIT_STUB cti_vm_handle_exception(CallFrame* callFrame)
     2176{
     2177    ASSERT(!callFrame->hasHostCallFrameFlag());
     2178    if (!callFrame) {
     2179        // The entire stack has already been unwound. Nothing more to handle.
     2180        return uncaughtExceptionHandler();
     2181    }
     2182
    21712183    VM* vm = callFrame->codeBlock()->vm();
    21722184    vm->topCallFrame = callFrame;
Note: See TracChangeset for help on using the changeset viewer.