Ignore:
Timestamp:
Aug 27, 2018, 10:01:05 PM (7 years ago)
Author:
[email protected]
Message:

Fix exception throwing code so that topCallFrame and topEntryFrame stay true to their names.
https://bugs.webkit.org/show_bug.cgi?id=188577
<rdar://problem/42985684>

Reviewed by Saam Barati.

JSTests:

  • stress/regress-188577.js: Added.

Source/JavaScriptCore:

  1. Introduced CallFrame::convertToStackOverflowFrame() which converts the current (top) CallFrame (which may not have a valid callee) into a StackOverflowFrame.

The StackOverflowFrame is a sentinel frame that the low level code (exception
throwing code, stack visitor, and stack unwinding code) will know to skip
over. The StackOverflowFrame will also have a valid JSCallee so that client
code can compute the globalObject or VM from this frame.

As a result, client code that throws StackOverflowErrors no longer need to
compute the caller frame to throw from: it just converts the top frame into
a StackOverflowFrame and everything should *Just Work*.

  1. NativeCallFrameTracerWithRestore is now obsolete.

Instead, client code should always call convertToStackOverflowFrame() on the
frame before instantiating a NativeCallFrameTracer with it.

This means that topCallFrame will always point to the top CallFrame (which
may be a StackOverflowFrame), and topEntryFrame will always point to the top
EntryFrame. We'll never temporarily point them to the previous EntryFrame
(which we used to do with NativeCallFrameTracerWithRestore).

  1. genericUnwind() and Interpreter::unwind() will now always unwind from the top CallFrame, and will know how to handle a StackOverflowFrame if they see one.

This obsoletes the UnwindStart flag.

  • CMakeLists.txt:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • Sources.txt:
  • debugger/Debugger.cpp:

(JSC::Debugger::pauseIfNeeded):

  • interpreter/CallFrame.cpp:

(JSC::CallFrame::callerFrame const):
(JSC::CallFrame::unsafeCallerFrame const):
(JSC::CallFrame::convertToStackOverflowFrame):
(JSC::CallFrame::callerFrame): Deleted.
(JSC::CallFrame::unsafeCallerFrame): Deleted.

  • interpreter/CallFrame.h:

(JSC::ExecState::iterate):

  • interpreter/CallFrameInlines.h: Added.

(JSC::CallFrame::isStackOverflowFrame const):
(JSC::CallFrame::isWasmFrame const):

  • interpreter/EntryFrame.h: Added.

(JSC::EntryFrame::vmEntryRecordOffset):
(JSC::EntryFrame::calleeSaveRegistersBufferOffset):

  • interpreter/FrameTracers.h:

(JSC::NativeCallFrameTracerWithRestore::NativeCallFrameTracerWithRestore): Deleted.
(JSC::NativeCallFrameTracerWithRestore::~NativeCallFrameTracerWithRestore): Deleted.

  • interpreter/Interpreter.cpp:

(JSC::Interpreter::unwind):

  • interpreter/Interpreter.h:
  • interpreter/StackVisitor.cpp:

(JSC::StackVisitor::StackVisitor):

  • interpreter/StackVisitor.h:

(JSC::StackVisitor::visit):
(JSC::StackVisitor::topEntryFrameIsEmpty const):

  • interpreter/VMEntryRecord.h:

(JSC::VMEntryRecord::callee const):
(JSC::EntryFrame::vmEntryRecordOffset): Deleted.
(JSC::EntryFrame::calleeSaveRegistersBufferOffset): Deleted.

  • jit/AssemblyHelpers.h:
  • jit/JITExceptions.cpp:

(JSC::genericUnwind):

  • jit/JITExceptions.h:
  • jit/JITOperations.cpp:
  • llint/LLIntOffsetsExtractor.cpp:
  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL):

  • llint/LowLevelInterpreter.asm:
  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
  • runtime/CallData.cpp:
  • runtime/CommonSlowPaths.cpp:

(JSC::throwArityCheckStackOverflowError):
(JSC::SLOW_PATH_DECL):

  • runtime/CommonSlowPathsExceptions.cpp: Removed.
  • runtime/CommonSlowPathsExceptions.h: Removed.
  • runtime/Completion.cpp:

(JSC::evaluateWithScopeExtension):

  • runtime/JSGeneratorFunction.h:
  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):

  • runtime/JSGlobalObject.h:

(JSC::JSGlobalObject::stackOverflowFrameCallee const):

  • runtime/VM.cpp:

(JSC::VM::throwException):

  • runtime/VM.h:
  • runtime/VMInlines.h:

(JSC::VM::topJSCallFrame const):

LayoutTests:

  • http/tests/misc/large-js-program-expected.txt:
File:
1 edited

Legend:

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

    r230865 r235419  
    3131#include "CodeBlock.h"
    3232#include "Disassembler.h"
     33#include "EntryFrame.h"
    3334#include "Interpreter.h"
    3435#include "JSCInlines.h"
     
    3940#include "Opcode.h"
    4041#include "ShadowChicken.h"
    41 #include "VM.h"
     42#include "VMInlines.h"
    4243
    4344namespace JSC {
    4445
    45 void genericUnwind(VM* vm, ExecState* callFrame, UnwindStart unwindStart)
     46void genericUnwind(VM* vm, ExecState* callFrame)
    4647{
    4748    auto scope = DECLARE_CATCH_SCOPE(*vm);
     49    CallFrame* topJSCallFrame = vm->topJSCallFrame();
    4850    if (Options::breakOnThrow()) {
    49         CodeBlock* codeBlock = callFrame->codeBlock();
    50         if (codeBlock)
    51             dataLog("In call frame ", RawPointer(callFrame), " for code block ", *codeBlock, "\n");
    52         else
    53             dataLog("In call frame ", RawPointer(callFrame), " with null CodeBlock\n");
     51        CodeBlock* codeBlock = topJSCallFrame->codeBlock();
     52        dataLog("In call frame ", RawPointer(topJSCallFrame), " for code block ", codeBlock, "\n");
    5453        CRASH();
    5554    }
    5655   
    57     ExecState* shadowChickenTopFrame = callFrame;
    58     if (unwindStart == UnwindFromCallerFrame) {
    59         EntryFrame* topEntryFrame = vm->topEntryFrame;
    60         shadowChickenTopFrame = callFrame->callerFrame(topEntryFrame);
    61     }
    62     vm->shadowChicken().log(*vm, shadowChickenTopFrame, ShadowChicken::Packet::throwPacket());
    63    
     56    vm->shadowChicken().log(*vm, topJSCallFrame, ShadowChicken::Packet::throwPacket());
     57
    6458    Exception* exception = scope.exception();
    6559    RELEASE_ASSERT(exception);
    66     HandlerInfo* handler = vm->interpreter->unwind(*vm, callFrame, exception, unwindStart); // This may update callFrame.
     60    HandlerInfo* handler = vm->interpreter->unwind(*vm, callFrame, exception); // This may update callFrame.
    6761
    6862    void* catchRoutine;
     
    8478    } else
    8579        catchRoutine = LLInt::getCodePtr<ExceptionHandlerPtrTag>(handleUncaughtException).executableAddress();
    86    
     80
    8781    ASSERT(bitwise_cast<uintptr_t>(callFrame) < bitwise_cast<uintptr_t>(vm->topEntryFrame));
    8882
     
    9589}
    9690
    97 void genericUnwind(VM* vm, ExecState* callFrame)
    98 {
    99     genericUnwind(vm, callFrame, UnwindFromCurrentFrame);
    100 }
    101 
    10291} // namespace JSC
Note: See TracChangeset for help on using the changeset viewer.