Ignore:
Timestamp:
May 12, 2017, 6:30:13 PM (8 years ago)
Author:
[email protected]
Message:

Use Mach exceptions instead of signals where possible
https://bugs.webkit.org/show_bug.cgi?id=171865

Reviewed by Mark Lam.

Source/JavaScriptCore:

This patch adds some new JSC options. The first is an option that
enables or disables web assembly tier up. The second controls
whether or not we use mach exceptions (where available).

  • API/tests/ExecutionTimeLimitTest.cpp:

(dispatchTermitateCallback):
(testExecutionTimeLimit):

  • runtime/JSLock.cpp:

(JSC::JSLock::didAcquireLock):

  • runtime/Options.cpp:

(JSC::overrideDefaults):
(JSC::Options::initialize):

  • runtime/Options.h:
  • runtime/VMTraps.cpp:

(JSC::SignalContext::SignalContext):
(JSC::SignalContext::adjustPCToPointToTrappingInstruction):
(JSC::installSignalHandler):
(JSC::VMTraps::SignalSender::send):

  • tools/SigillCrashAnalyzer.cpp:

(JSC::SignalContext::SignalContext):
(JSC::SignalContext::dump):
(JSC::installCrashHandler):

  • wasm/WasmBBQPlan.cpp:

(JSC::Wasm::BBQPlan::compileFunctions):

  • wasm/WasmFaultSignalHandler.cpp:

(JSC::Wasm::trapHandler):
(JSC::Wasm::enableFastMemory):

  • wasm/WasmMachineThreads.cpp:

(JSC::Wasm::resetInstructionCacheOnAllThreads):

Source/WTF:

This patch enables using mach exceptions on darwin. The way the
mach exception api works is that we create a mach port, which is
like a file descriptor. We then wait for a message to arrive on
that port in a thread. When another thread raises an exception (say
due to a bad memory access) the OS sends our thread a message. The
payload of that message is the register file of the crashing
thread. We then call our custom handlers that change the state as
needed. In order to restart the thread we send a payload back to
the OS with an updated register file along with a success message
header.

This patch also makes thread messages work without signals by
simply suspending the thread, and then running the message at that
time.

You can read more about mach exceptions here:
http://www.cs.cmu.edu/afs/cs/project/mach/public/doc/unpublished/exception.ps
and the Mach interface Generator (MiG) here:
http://www.cs.cmu.edu/afs/cs/project/mach/public/doc/unpublished/mig.ps

  • Configurations/WTF.xcconfig:
  • WTF.xcodeproj/project.pbxproj:
  • wtf/Platform.h:
  • wtf/PlatformRegisters.h:

(WTF::registersFromUContext):

  • wtf/StackBounds.h:

(WTF::StackBounds::StackBounds):

  • wtf/ThreadHolder.cpp:

(WTF::ThreadHolder::~ThreadHolder):

  • wtf/ThreadMessage.cpp:

(WTF::sendMessageUsingSignal):
(WTF::sendMessageUsingMach):
(WTF::deliverMessagesUsingMach):
(WTF::sendMessageScoped):

  • wtf/ThreadMessage.h:

(WTF::sendMessage):

  • wtf/Threading.h:

(WTF::Thread::machThread):

  • wtf/mac/MachExceptions.defs: Copied from Source/WTF/wtf/ThreadMessage.h.
  • wtf/threads/Signals.cpp:

(WTF::startMachExceptionHandlerThread):
(WTF::fromMachException):
(WTF::toMachMask):
(WTF::handleSignalsWithMach):
(WTF::setExceptionPorts):
(WTF::activeThreads):
(WTF::registerThreadForMachExceptionHandling):
(WTF::unregisterThreadForMachExceptionHandling):
(WTF::installSignalHandler):
(WTF::jscSignalHandler):

  • wtf/threads/Signals.h:

Tools:

  • TestWebKitAPI/Tests/WTF/ThreadMessages.cpp:

(runThreadMessageTest):
(TEST):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/VMTraps.cpp

    r215671 r216808  
    5454
    5555struct SignalContext {
    56     SignalContext(mcontext_t& mcontext)
    57         : mcontext(mcontext)
    58         , trapPC(MachineContext::instructionPointer(mcontext))
    59         , stackPointer(MachineContext::stackPointer(mcontext))
    60         , framePointer(MachineContext::framePointer(mcontext))
     56    SignalContext(PlatformRegisters& registers)
     57        : registers(registers)
     58        , trapPC(MachineContext::instructionPointer(registers))
     59        , stackPointer(MachineContext::stackPointer(registers))
     60        , framePointer(MachineContext::framePointer(registers))
    6161    {
    6262#if CPU(X86_64) || CPU(X86)
     
    6969    {
    7070#if CPU(X86_64) || CPU(X86)
    71         MachineContext::instructionPointer(mcontext) = trapPC;
    72 #endif
    73     }
    74 
    75     mcontext_t& mcontext;
     71        MachineContext::instructionPointer(registers) = trapPC;
     72#endif
     73    }
     74
     75    PlatformRegisters& registers;
    7676    void* trapPC;
    7777    void* stackPointer;
     
    131131static void installSignalHandler()
    132132{
    133     installSignalHandler(Signal::Trap, [] (int, siginfo_t*, void* uap) -> SignalAction {
    134         SignalContext context(static_cast<ucontext_t*>(uap)->uc_mcontext);
     133    installSignalHandler(Signal::Trap, [] (Signal, SigInfo&, PlatformRegisters& registers) -> SignalAction {
     134        SignalContext context(registers);
    135135
    136136        if (!isJITPC(context.trapPC))
     
    405405            auto optionalOwnerThread = vm.ownerThread();
    406406            if (optionalOwnerThread) {
    407                 sendMessage(*optionalOwnerThread.value().get(), [] (siginfo_t*, ucontext_t* ucontext) -> void {
    408                     SignalContext context(ucontext->uc_mcontext);
     407                sendMessage(*optionalOwnerThread.value().get(), [] (PlatformRegisters& registers) -> void {
     408                    SignalContext context(registers);
    409409                    auto activeVMAndStackBounds = findActiveVMAndStackBounds(context);
    410410                    if (activeVMAndStackBounds) {
Note: See TracChangeset for help on using the changeset viewer.