Changeset 188555 in webkit


Ignore:
Timestamp:
Aug 17, 2015, 4:58:00 PM (10 years ago)
Author:
msaboff@apple.com
Message:

jsc-tailcall: Handling exception in caller frame cannot unwind past VMEntry frame
https://bugs.webkit.org/show_bug.cgi?id=148076

Reviewed by Basile Clement.

When we are unwinding from our caller, we need to check if we are the top JavaScript entry frame.
If so, we don't need to unwind any further, we just process as an unhandled exception.
Moved the processing of "unwind from caller frame" into genericUnwind(). Added an enum parameter
to indicate whether or not we start unwinding from the current frame or caller's frame.
In the case of the LLInt, we now handle a stack overflow exception from the current frame and not
the caller's frame. This is needed because the unwind code needs to restore the callee saves
that the LLInt has saved, namely the PC register which is needed to make slow path calls.

  • interpreter/CallFrame.cpp:

(JSC::CallFrame::callerFrameIsVMEntryFrame):

  • interpreter/CallFrame.h:

(JSC::CallFrame::callerFrameIsVMEntryFrame):
New helper function to determine if we are the top JavaScript frame.

  • jit/JITExceptions.cpp:

(JSC::genericUnwind):

  • jit/JITExceptions.h:

Added enum parameter to genericUnwind() to indicate if we are unwinding from the current or
caller frame.

  • jit/JITOperations.cpp:

(JSC:lookupExceptionHandlerFromCallerFrame): Moved the caller frame processing to genericUnwind().

  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::llint_stack_check): Changed to process the exception in the current frame.

  • llint/LowLevelInterpreter.asm:

Made sure to account for calle save register space when making a call to llint_stack_check.

Location:
branches/jsc-tailcall/Source/JavaScriptCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • branches/jsc-tailcall/Source/JavaScriptCore/ChangeLog

    r188318 r188555  
     12015-08-17  Michael Saboff  <msaboff@apple.com>
     2
     3        jsc-tailcall: Handling exception in caller frame cannot unwind past VMEntry frame
     4        https://bugs.webkit.org/show_bug.cgi?id=148076
     5
     6        Reviewed by Basile Clement.
     7
     8        When we are unwinding from our caller, we need to check if we are the top JavaScript entry frame.
     9        If so, we don't need to unwind any further, we just process as an unhandled exception.
     10        Moved the processing of "unwind from caller frame" into genericUnwind().  Added an enum parameter
     11        to indicate whether or not we start unwinding from the current frame or caller's frame.
     12        In the case of the LLInt, we now handle a stack overflow exception from the current frame and not
     13        the caller's frame.  This is needed because the unwind code needs to restore the callee saves
     14        that the LLInt has saved, namely the PC register which is needed to make slow path calls.
     15
     16        * interpreter/CallFrame.cpp:
     17        (JSC::CallFrame::callerFrameIsVMEntryFrame):
     18        * interpreter/CallFrame.h:
     19        (JSC::CallFrame::callerFrameIsVMEntryFrame):
     20        New helper function to determine if we are the top JavaScript frame.
     21
     22        * jit/JITExceptions.cpp:
     23        (JSC::genericUnwind):
     24        * jit/JITExceptions.h:
     25        Added enum parameter to genericUnwind() to indicate if we are unwinding from the current or
     26        caller frame.
     27
     28        * jit/JITOperations.cpp:
     29        (JSC:lookupExceptionHandlerFromCallerFrame): Moved the caller frame processing to genericUnwind().
     30
     31        * llint/LLIntSlowPaths.cpp:
     32        (JSC::LLInt::llint_stack_check): Changed to process the exception in the current frame.
     33
     34        * llint/LowLevelInterpreter.asm:
     35        Made sure to account for calle save register space when making a call to llint_stack_check.
     36
    1372015-08-11  Basile Clement  <basile_clement@apple.com>
    238
  • branches/jsc-tailcall/Source/JavaScriptCore/interpreter/CallFrame.cpp

    r187791 r188555  
    147147}
    148148
     149bool CallFrame::callerFrameIsVMEntryFrame(VMEntryFrame* vmEntryFrame)
     150{
     151    return callerFrameOrVMEntryFrame() == vmEntryFrame;
     152}
     153
    149154JSLexicalEnvironment* CallFrame::lexicalEnvironment() const
    150155{
  • branches/jsc-tailcall/Source/JavaScriptCore/interpreter/CallFrame.h

    r185487 r188555  
    100100        JS_EXPORT_PRIVATE CallFrame* callerFrame(VMEntryFrame*&);
    101101
     102        bool callerFrameIsVMEntryFrame(VMEntryFrame*);
     103
    102104        static ptrdiff_t callerFrameOffset() { return OBJECT_OFFSETOF(CallerFrameAndPC, callerFrame); }
    103105
  • branches/jsc-tailcall/Source/JavaScriptCore/jit/JITExceptions.cpp

    r185259 r188555  
    4141namespace JSC {
    4242
    43 void genericUnwind(VM* vm, ExecState* callFrame)
     43void genericUnwind(VM* vm, ExecState* callFrame, UnwindStart unwindStart)
    4444{
    4545    if (Options::breakOnThrow()) {
     
    5151    RELEASE_ASSERT(exception);
    5252    VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
     53
     54    if (unwindStart == UnwindFromCallerFrame) {
     55        if (callFrame->callerFrameIsVMEntryFrame(vmEntryFrame)) {
     56            // If we are unwinding from our caller and our caller is a VMEntryFrame, we don't need to unwind.
     57            // We can go straight to handleUncaughtException.
     58            vm->vmEntryFrameForThrow = vmEntryFrame;
     59            vm->callFrameForThrow = callFrame;
     60            vm->targetMachinePCForThrow = LLInt::getCodePtr(handleUncaughtException);
     61            vm->targetInterpreterPCForThrow = nullptr;
     62
     63            return;
     64        }
     65
     66        // Start unwinding from our caller's frame.
     67        callFrame = callFrame->callerFrame();
     68        vm->topCallFrame = callFrame;
     69    }
    5370    HandlerInfo* handler = vm->interpreter->unwind(vmEntryFrame, callFrame, exception); // This may update vmEntryFrame and callFrame.
    5471
  • branches/jsc-tailcall/Source/JavaScriptCore/jit/JITExceptions.h

    r185259 r188555  
    3434class VM;
    3535
    36 void genericUnwind(VM*, ExecState*);
     36enum UnwindStart { UnwindFromCurrentFrame, UnwindFromCallerFrame };
     37
     38void genericUnwind(VM*, ExecState*, UnwindStart unwindStart = UnwindFromCurrentFrame);
    3739
    3840} // namespace JSC
  • branches/jsc-tailcall/Source/JavaScriptCore/jit/JITOperations.cpp

    r187639 r188555  
    19371937void JIT_OPERATION lookupExceptionHandlerFromCallerFrame(VM* vm, ExecState* exec)
    19381938{
    1939     VMEntryFrame* vmEntryFrame = vm->topVMEntryFrame;
    1940     CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
    1941     ASSERT(callerFrame);
    1942 
    1943     NativeCallFrameTracerWithRestore tracer(vm, vmEntryFrame, callerFrame);
    1944     genericUnwind(vm, callerFrame);
     1939    NativeCallFrameTracer tracer(vm, exec);
     1940    genericUnwind(vm, exec, UnwindFromCallerFrame);
    19451941    ASSERT(vm->targetMachinePCForThrow);
    19461942}
  • branches/jsc-tailcall/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r186606 r188555  
    484484    vm.topCallFrame = exec;
    485485    ErrorHandlingScope errorScope(vm);
    486     CommonSlowPaths::interpreterThrowInCaller(exec, createStackOverflowError(exec));
    487     pc = returnToThrowForThrownException(exec);
     486    vm.throwException(exec, createStackOverflowError(exec));
     487    pc = returnToThrow(exec);
    488488    LLINT_RETURN_TWO(pc, exec);
    489489}
  • branches/jsc-tailcall/Source/JavaScriptCore/llint/LowLevelInterpreter.asm

    r188318 r188555  
    227227    const CalleeSaveSpaceAsVirtualRegisters = 0
    228228end
     229
     230const CalleeSaveSpaceStackAligned = (CalleeSaveSpaceAsVirtualRegisters * SlotSize + StackAlignment - 1) & ~StackAlignmentMask
     231
    229232
    230233# Watchpoint states
     
    917920
    918921    # Stack height check failed - need to call a slow_path.
    919     subp maxFrameExtentForSlowPathCall, sp # Set up temporary stack pointer for call
     922    # Set up temporary stack pointer for call including callee saves
     923    subp maxFrameExtentForSlowPathCall + CalleeSaveSpaceStackAligned, sp
    920924    callSlowPath(_llint_stack_check)
    921925    bpeq r1, 0, .stackHeightOKGetCodeBlock
Note: See TracChangeset for help on using the changeset viewer.