Changeset 248187 in webkit


Ignore:
Timestamp:
Aug 2, 2019 3:58:09 PM (5 years ago)
Author:
ysuzuki@apple.com
Message:

[JSC] Support WebAssembly in SamplingProfiler
https://bugs.webkit.org/show_bug.cgi?id=200329

Reviewed by Saam Barati.

JSTests:

  • stress/sampling-profiler-wasm-name-section.js: Added.

(const.compile):
(platformSupportsSamplingProfiler.vm.isWasmSupported.wasmEntry):
(platformSupportsSamplingProfiler.vm.isWasmSupported):

  • stress/sampling-profiler-wasm.js: Added.

(platformSupportsSamplingProfiler.vm.isWasmSupported.wasmEntry):
(platformSupportsSamplingProfiler.vm.isWasmSupported):

  • stress/sampling-profiler/loop.wasm: Added.
  • stress/sampling-profiler/loop.wast: Added.
  • stress/sampling-profiler/nameSection.wasm: Added.

Source/JavaScriptCore:

The sampling profiler support is critical to investigate what is actually time-consuming. This patch adds the sampling profiler support for Wasm functions
to list up hot Wasm functions with compilation mode (BBQ or OMG). This allows us to investigate the hot functions in JetStream2 wasm tests.

In order to retrieve wasm function information from the sampling profiler safely, we need to know whether the given Wasm CalleeBits is valid in the call frame.
To achieve this, we start collecting valid Wasm::Callee pointers in a global hash set. Previously, each Wasm::Callee registered its code region to a hash set
for wasm fault signal handler to know whether the faulted program-counter is in wasm region. We reuse and change this mechanism. Instead of registering code region,
we register Wasm::Callee* to a hash set. The sampling profiler reuses this hash set to determine whether the given bits is a valid Wasm::Callee.

The sampling profiler retrieves the information safely from valid Wasm::Callee* pointer. It is possible that this Wasm::Callee is about to be dead: ref-count is 0,
now in the middle of the destructor of Wasm::Callee. Even in that case, fields of Wasm::Callee are still valid and can be accessed since destroying these fields happens
after we unregister Wasm::Callee from the global hash set.

We retrieve Wasm::IndexOrName and Wasm::CompilationMode. Copying them does not involve any allocations, locking etc. So we can safely copy them while some of threads are suspended.

This patch also fixes the issue that we never called unregisterCode while every Wasm::Calllee registers its code region through registerCode.

  • CMakeLists.txt:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • Sources.txt:
  • runtime/InitializeThreading.cpp:

(JSC::initializeThreading):

  • runtime/SamplingProfiler.cpp:

(JSC::FrameWalker::FrameWalker):
(JSC::FrameWalker::recordJSFrame):
(JSC::CFrameWalker::CFrameWalker):
(JSC::SamplingProfiler::takeSample):
(JSC::SamplingProfiler::processUnverifiedStackTraces):
(JSC::SamplingProfiler::StackFrame::displayName):
(JSC::SamplingProfiler::StackFrame::displayNameForJSONTests):
(JSC::SamplingProfiler::StackFrame::functionStartLine):
(JSC::SamplingProfiler::StackFrame::functionStartColumn):
(JSC::SamplingProfiler::StackFrame::sourceID):
(JSC::SamplingProfiler::StackFrame::url):
(JSC::SamplingProfiler::reportTopBytecodes):
(WTF::printInternal):

  • runtime/SamplingProfiler.h:
  • tools/JSDollarVM.cpp:

(JSC::functionIsWasmSupported):
(JSC::JSDollarVM::finishCreation):

  • wasm/WasmB3IRGenerator.h:
  • wasm/WasmBBQPlan.cpp:

(JSC::Wasm::BBQPlan::complete):

  • wasm/WasmBBQPlanInlines.h:

(JSC::Wasm::BBQPlan::initializeCallees):

  • wasm/WasmCallee.cpp:

(JSC::Wasm::Callee::Callee):
(JSC::Wasm::Callee::~Callee):

  • wasm/WasmCallee.h:

(JSC::Wasm::Callee::create): Deleted.
(JSC::Wasm::Callee::entrypoint const): Deleted.
(JSC::Wasm::Callee::calleeSaveRegisters): Deleted.
(JSC::Wasm::Callee::indexOrName const): Deleted.

  • wasm/WasmCalleeRegistry.cpp: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.

(JSC::Wasm::CalleeRegistry::initialize):
(JSC::Wasm::CalleeRegistry::singleton):

  • wasm/WasmCalleeRegistry.h: Copied from Source/JavaScriptCore/wasm/WasmCallee.cpp.

(JSC::Wasm::CalleeRegistry::getLock):
(JSC::Wasm::CalleeRegistry::registerCallee):
(JSC::Wasm::CalleeRegistry::unregisterCallee):
(JSC::Wasm::CalleeRegistry::isValidCallee):

  • wasm/WasmCompilationMode.cpp: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.

(JSC::Wasm::makeString):

  • wasm/WasmCompilationMode.h: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
  • wasm/WasmFaultSignalHandler.cpp:

(JSC::Wasm::trapHandler):
(JSC::Wasm::enableFastMemory):
(JSC::Wasm::registerCode): Deleted.
(JSC::Wasm::unregisterCode): Deleted.

  • wasm/WasmFaultSignalHandler.h:
  • wasm/WasmIndexOrName.h:
  • wasm/WasmOMGPlan.cpp:

(JSC::Wasm::OMGPlan::work):

Location:
trunk
Files:
5 added
18 edited
4 copied

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r248185 r248187  
     12019-08-02  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Support WebAssembly in SamplingProfiler
     4        https://bugs.webkit.org/show_bug.cgi?id=200329
     5
     6        Reviewed by Saam Barati.
     7
     8        * stress/sampling-profiler-wasm-name-section.js: Added.
     9        (const.compile):
     10        (platformSupportsSamplingProfiler.vm.isWasmSupported.wasmEntry):
     11        (platformSupportsSamplingProfiler.vm.isWasmSupported):
     12        * stress/sampling-profiler-wasm.js: Added.
     13        (platformSupportsSamplingProfiler.vm.isWasmSupported.wasmEntry):
     14        (platformSupportsSamplingProfiler.vm.isWasmSupported):
     15        * stress/sampling-profiler/loop.wasm: Added.
     16        * stress/sampling-profiler/loop.wast: Added.
     17        * stress/sampling-profiler/nameSection.wasm: Added.
     18
    1192019-08-02  Yusuke Suzuki  <ysuzuki@apple.com>
    220
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r247542 r248187  
    998998    wasm/WasmCapabilities.h
    999999    wasm/WasmCodeBlock.h
     1000    wasm/WasmCompilationMode.h
    10001001    wasm/WasmContext.h
    10011002    wasm/WasmEmbedder.h
  • trunk/Source/JavaScriptCore/ChangeLog

    r248185 r248187  
     12019-08-02  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Support WebAssembly in SamplingProfiler
     4        https://bugs.webkit.org/show_bug.cgi?id=200329
     5
     6        Reviewed by Saam Barati.
     7
     8        The sampling profiler support is critical to investigate what is actually time-consuming. This patch adds the sampling profiler support for Wasm functions
     9        to list up hot Wasm functions with compilation mode (BBQ or OMG). This allows us to investigate the hot functions in JetStream2 wasm tests.
     10
     11        In order to retrieve wasm function information from the sampling profiler safely, we need to know whether the given Wasm CalleeBits is valid in the call frame.
     12        To achieve this, we start collecting valid Wasm::Callee pointers in a global hash set. Previously, each Wasm::Callee registered its code region to a hash set
     13        for wasm fault signal handler to know whether the faulted program-counter is in wasm region. We reuse and change this mechanism. Instead of registering code region,
     14        we register Wasm::Callee* to a hash set. The sampling profiler reuses this hash set to determine whether the given bits is a valid Wasm::Callee.
     15
     16        The sampling profiler retrieves the information safely from valid Wasm::Callee* pointer. It is possible that this Wasm::Callee is about to be dead: ref-count is 0,
     17        now in the middle of the destructor of Wasm::Callee. Even in that case, fields of Wasm::Callee are still valid and can be accessed since destroying these fields happens
     18        after we unregister Wasm::Callee from the global hash set.
     19
     20        We retrieve Wasm::IndexOrName and Wasm::CompilationMode. Copying them does not involve any allocations, locking etc. So we can safely copy them while some of threads are suspended.
     21
     22        This patch also fixes the issue that we never called `unregisterCode` while every Wasm::Calllee registers its code region through `registerCode`.
     23
     24        * CMakeLists.txt:
     25        * JavaScriptCore.xcodeproj/project.pbxproj:
     26        * Sources.txt:
     27        * runtime/InitializeThreading.cpp:
     28        (JSC::initializeThreading):
     29        * runtime/SamplingProfiler.cpp:
     30        (JSC::FrameWalker::FrameWalker):
     31        (JSC::FrameWalker::recordJSFrame):
     32        (JSC::CFrameWalker::CFrameWalker):
     33        (JSC::SamplingProfiler::takeSample):
     34        (JSC::SamplingProfiler::processUnverifiedStackTraces):
     35        (JSC::SamplingProfiler::StackFrame::displayName):
     36        (JSC::SamplingProfiler::StackFrame::displayNameForJSONTests):
     37        (JSC::SamplingProfiler::StackFrame::functionStartLine):
     38        (JSC::SamplingProfiler::StackFrame::functionStartColumn):
     39        (JSC::SamplingProfiler::StackFrame::sourceID):
     40        (JSC::SamplingProfiler::StackFrame::url):
     41        (JSC::SamplingProfiler::reportTopBytecodes):
     42        (WTF::printInternal):
     43        * runtime/SamplingProfiler.h:
     44        * tools/JSDollarVM.cpp:
     45        (JSC::functionIsWasmSupported):
     46        (JSC::JSDollarVM::finishCreation):
     47        * wasm/WasmB3IRGenerator.h:
     48        * wasm/WasmBBQPlan.cpp:
     49        (JSC::Wasm::BBQPlan::complete):
     50        * wasm/WasmBBQPlanInlines.h:
     51        (JSC::Wasm::BBQPlan::initializeCallees):
     52        * wasm/WasmCallee.cpp:
     53        (JSC::Wasm::Callee::Callee):
     54        (JSC::Wasm::Callee::~Callee):
     55        * wasm/WasmCallee.h:
     56        (JSC::Wasm::Callee::create): Deleted.
     57        (JSC::Wasm::Callee::entrypoint const): Deleted.
     58        (JSC::Wasm::Callee::calleeSaveRegisters): Deleted.
     59        (JSC::Wasm::Callee::indexOrName const): Deleted.
     60        * wasm/WasmCalleeRegistry.cpp: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
     61        (JSC::Wasm::CalleeRegistry::initialize):
     62        (JSC::Wasm::CalleeRegistry::singleton):
     63        * wasm/WasmCalleeRegistry.h: Copied from Source/JavaScriptCore/wasm/WasmCallee.cpp.
     64        (JSC::Wasm::CalleeRegistry::getLock):
     65        (JSC::Wasm::CalleeRegistry::registerCallee):
     66        (JSC::Wasm::CalleeRegistry::unregisterCallee):
     67        (JSC::Wasm::CalleeRegistry::isValidCallee):
     68        * wasm/WasmCompilationMode.cpp: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
     69        (JSC::Wasm::makeString):
     70        * wasm/WasmCompilationMode.h: Copied from Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h.
     71        * wasm/WasmFaultSignalHandler.cpp:
     72        (JSC::Wasm::trapHandler):
     73        (JSC::Wasm::enableFastMemory):
     74        (JSC::Wasm::registerCode): Deleted.
     75        (JSC::Wasm::unregisterCode): Deleted.
     76        * wasm/WasmFaultSignalHandler.h:
     77        * wasm/WasmIndexOrName.h:
     78        * wasm/WasmOMGPlan.cpp:
     79        (JSC::Wasm::OMGPlan::work):
     80
    1812019-08-02  Yusuke Suzuki  <ysuzuki@apple.com>
    282
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r248178 r248187  
    18161816                E3A421431D6F58930007C617 /* PreciseJumpTargetsInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A421421D6F588F0007C617 /* PreciseJumpTargetsInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
    18171817                E3AC277721FDB4940024452C /* RegExpCachedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 86F75EFC151C062F007C9BA3 /* RegExpCachedResult.h */; settings = {ATTRIBUTES = (Private, ); }; };
     1818                E3BD2B7622F275020011765C /* WasmCompilationMode.h in Headers */ = {isa = PBXBuildFile; fileRef = E3BD2B7522F275020011765C /* WasmCompilationMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
    18181819                E3BFA5D021E853A1009C0EBA /* DFGDesiredGlobalProperty.h in Headers */ = {isa = PBXBuildFile; fileRef = E3BFA5CD21E853A1009C0EBA /* DFGDesiredGlobalProperty.h */; };
    18191820                E3BFD0BC1DAF808E0065DEA2 /* AccessCaseSnippetParams.h in Headers */ = {isa = PBXBuildFile; fileRef = E3BFD0BA1DAF807C0065DEA2 /* AccessCaseSnippetParams.h */; };
     
    18271828                E3F23A811ECF13FA00978D99 /* SnippetParams.h in Headers */ = {isa = PBXBuildFile; fileRef = E3F23A7C1ECF13E500978D99 /* SnippetParams.h */; settings = {ATTRIBUTES = (Private, ); }; };
    18281829                E3F23A821ECF13FE00978D99 /* Snippet.h in Headers */ = {isa = PBXBuildFile; fileRef = E3F23A7B1ECF13E500978D99 /* Snippet.h */; settings = {ATTRIBUTES = (Private, ); }; };
     1830                E3FB853A22F3667B008F90ED /* WasmCalleeRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = E3FB853822F36674008F90ED /* WasmCalleeRegistry.h */; };
    18291831                E3FF75331D9CEA1800C7E16D /* DOMJITGetterSetter.h in Headers */ = {isa = PBXBuildFile; fileRef = E3FF752F1D9CEA1200C7E16D /* DOMJITGetterSetter.h */; settings = {ATTRIBUTES = (Private, ); }; };
    18301832                E49DC16C12EF294E00184A1F /* SourceProviderCache.h in Headers */ = {isa = PBXBuildFile; fileRef = E49DC15112EF272200184A1F /* SourceProviderCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    48164818                E3794E731B77EB97005543AE /* ModuleAnalyzer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ModuleAnalyzer.cpp; sourceTree = "<group>"; };
    48174819                E3794E741B77EB97005543AE /* ModuleAnalyzer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModuleAnalyzer.h; sourceTree = "<group>"; };
     4820                E37CFB2D22F27C57009A7B38 /* WasmCompilationMode.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WasmCompilationMode.cpp; sourceTree = "<group>"; };
    48184821                E380A76B1DCD7195000F89E6 /* MacroAssemblerHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerHelpers.h; sourceTree = "<group>"; };
    48194822                E380D66B1F19249D00A59095 /* BuiltinNames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BuiltinNames.cpp; sourceTree = "<group>"; };
     
    48424845                E3A32BC61FC8312E007D7E76 /* WeakMapImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakMapImpl.h; sourceTree = "<group>"; };
    48434846                E3A421421D6F588F0007C617 /* PreciseJumpTargetsInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PreciseJumpTargetsInlines.h; sourceTree = "<group>"; };
     4847                E3BD2B7522F275020011765C /* WasmCompilationMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmCompilationMode.h; sourceTree = "<group>"; };
    48444848                E3BFA5CB21E853A0009C0EBA /* DFGDesiredGlobalProperties.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDesiredGlobalProperties.cpp; path = dfg/DFGDesiredGlobalProperties.cpp; sourceTree = "<group>"; };
    48454849                E3BFA5CC21E853A0009C0EBA /* DFGDesiredGlobalProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDesiredGlobalProperties.h; path = dfg/DFGDesiredGlobalProperties.h; sourceTree = "<group>"; };
     
    48644868                E3F23A7D1ECF13E500978D99 /* SnippetReg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SnippetReg.h; sourceTree = "<group>"; };
    48654869                E3F23A7E1ECF13E500978D99 /* SnippetSlowPathCalls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SnippetSlowPathCalls.h; sourceTree = "<group>"; };
     4870                E3FB853822F36674008F90ED /* WasmCalleeRegistry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WasmCalleeRegistry.h; sourceTree = "<group>"; };
     4871                E3FB853922F36674008F90ED /* WasmCalleeRegistry.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WasmCalleeRegistry.cpp; sourceTree = "<group>"; };
    48664872                E3FC25102256ECF400583518 /* DoublePredictionFuzzerAgent.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DoublePredictionFuzzerAgent.cpp; sourceTree = "<group>"; };
    48674873                E3FC25112256ECF400583518 /* DoublePredictionFuzzerAgent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DoublePredictionFuzzerAgent.h; sourceTree = "<group>"; };
     
    66066612                                525C0DD71E935847002184CD /* WasmCallee.cpp */,
    66076613                                525C0DD81E935847002184CD /* WasmCallee.h */,
     6614                                E3FB853922F36674008F90ED /* WasmCalleeRegistry.cpp */,
     6615                                E3FB853822F36674008F90ED /* WasmCalleeRegistry.h */,
    66086616                                53FD04D11D7AB187003287D3 /* WasmCallingConvention.cpp */,
    66096617                                53FD04D21D7AB187003287D3 /* WasmCallingConvention.h */,
     
    66116619                                526AC4B41E977C5D003500E1 /* WasmCodeBlock.cpp */,
    66126620                                526AC4B51E977C5D003500E1 /* WasmCodeBlock.h */,
     6621                                E37CFB2D22F27C57009A7B38 /* WasmCompilationMode.cpp */,
     6622                                E3BD2B7522F275020011765C /* WasmCompilationMode.h */,
    66136623                                AD412B321E7B2E8A008AF157 /* WasmContext.h */,
    66146624                                A27958D7FA1142B0AC9E364D /* WasmContextInlines.h */,
     
    1000910019                                AD4B1DFA1DF244E20071AE32 /* WasmBinding.h in Headers */,
    1001010020                                525C0DDA1E935847002184CD /* WasmCallee.h in Headers */,
     10021                                E3FB853A22F3667B008F90ED /* WasmCalleeRegistry.h in Headers */,
    1001110022                                53FD04D41D7AB291003287D3 /* WasmCallingConvention.h in Headers */,
    1001210023                                E337B967224324EA0093A820 /* WasmCapabilities.h in Headers */,
    1001310024                                526AC4B71E977C5D003500E1 /* WasmCodeBlock.h in Headers */,
     10025                                E3BD2B7622F275020011765C /* WasmCompilationMode.h in Headers */,
    1001410026                                AD412B341E7B2E9E008AF157 /* WasmContext.h in Headers */,
    1001510027                                7593C898BE714A64BE93A6E7 /* WasmContextInlines.h in Headers */,
  • trunk/Source/JavaScriptCore/Sources.txt

    r248178 r248187  
    997997wasm/WasmBinding.cpp
    998998wasm/WasmCallee.cpp
     999wasm/WasmCalleeRegistry.cpp
    9991000wasm/WasmCallingConvention.cpp
    10001001wasm/WasmCodeBlock.cpp
     1002wasm/WasmCompilationMode.cpp
    10011003wasm/WasmEmbedder.h
    10021004wasm/WasmFaultSignalHandler.cpp
  • trunk/Source/JavaScriptCore/runtime/InitializeThreading.cpp

    r243312 r248187  
    4444#include "StructureIDTable.h"
    4545#include "SuperSampler.h"
     46#include "WasmCalleeRegistry.h"
    4647#include "WasmCapabilities.h"
    4748#include "WasmThunks.h"
     
    8788
    8889#if ENABLE(WEBASSEMBLY)
    89         if (Wasm::isSupported())
     90        if (Wasm::isSupported()) {
    9091            Wasm::Thunks::initialize();
     92            Wasm::CalleeRegistry::initialize();
     93        }
    9194#endif
    9295
  • trunk/Source/JavaScriptCore/runtime/SamplingProfiler.cpp

    r245288 r248187  
    4949#include "StrongInlines.h"
    5050#include "VM.h"
     51#include "WasmCallee.h"
     52#include "WasmCalleeRegistry.h"
    5153#include <thread>
    5254#include <wtf/FilePrintStream.h>
     
    8284class FrameWalker {
    8385public:
    84     FrameWalker(VM& vm, ExecState* callFrame, const AbstractLocker& codeBlockSetLocker, const AbstractLocker& machineThreadsLocker)
     86    FrameWalker(VM& vm, ExecState* callFrame, const AbstractLocker& codeBlockSetLocker, const AbstractLocker& machineThreadsLocker, const AbstractLocker& wasmCalleeLocker)
    8587        : m_vm(vm)
    8688        , m_callFrame(callFrame)
     
    8890        , m_codeBlockSetLocker(codeBlockSetLocker)
    8991        , m_machineThreadsLocker(machineThreadsLocker)
     92        , m_wasmCalleeLocker(wasmCalleeLocker)
    9093    {
    9194    }
     
    99102        size_t maxStackTraceSize = stackTrace.size();
    100103        while (!isAtTop() && !m_bailingOut && m_depth < maxStackTraceSize) {
    101             recordJSFrame(stackTrace);
     104            recordJITFrame(stackTrace);
    102105            advanceToParentFrame();
    103106            resetAtMachineFrame();
     
    116119
    117120    SUPPRESS_ASAN
    118     void recordJSFrame(Vector<UnprocessedStackFrame>& stackTrace)
     121    void recordJITFrame(Vector<UnprocessedStackFrame>& stackTrace)
    119122    {
    120123        CallSiteIndex callSiteIndex;
     
    126129        }
    127130        stackTrace[m_depth] = UnprocessedStackFrame(codeBlock, unsafeCallee, callSiteIndex);
     131#if ENABLE(WEBASSEMBLY)
     132        if (unsafeCallee.isWasm()) {
     133            auto* wasmCallee = unsafeCallee.asWasmCallee();
     134            if (Wasm::CalleeRegistry::singleton().isValidCallee(m_wasmCalleeLocker, wasmCallee)) {
     135                // At this point, Wasm::Callee would be dying (ref count is 0), but its fields are still live.
     136                // And we can safely copy Wasm::IndexOrName even when any lock is held by suspended threads.
     137                stackTrace[m_depth].wasmIndexOrName = wasmCallee->indexOrName();
     138                stackTrace[m_depth].wasmCompilationMode = wasmCallee->compilationMode();
     139            }
     140        }
     141#endif
    128142        m_depth++;
    129143    }
     
    194208    const AbstractLocker& m_codeBlockSetLocker;
    195209    const AbstractLocker& m_machineThreadsLocker;
     210    const AbstractLocker& m_wasmCalleeLocker;
    196211    bool m_bailingOut { false };
    197212    size_t m_depth { 0 };
     
    202217    typedef FrameWalker Base;
    203218
    204     CFrameWalker(VM& vm, void* machineFrame, ExecState* callFrame, const AbstractLocker& codeBlockSetLocker, const AbstractLocker& machineThreadsLocker)
    205         : Base(vm, callFrame, codeBlockSetLocker, machineThreadsLocker)
     219    CFrameWalker(VM& vm, void* machineFrame, ExecState* callFrame, const AbstractLocker& codeBlockSetLocker, const AbstractLocker& machineThreadsLocker, const AbstractLocker& wasmCalleeLocker)
     220        : Base(vm, callFrame, codeBlockSetLocker, machineThreadsLocker, wasmCalleeLocker)
    206221        , m_machineFrame(machineFrame)
    207222    {
     
    217232        // ensuring m_callFrame points to some frame above the machineFrame.
    218233        if (!isAtTop() && !m_bailingOut && m_machineFrame == m_callFrame) {
    219             recordJSFrame(stackTrace);
     234            recordJITFrame(stackTrace);
    220235            Base::advanceToParentFrame();
    221236            resetAtMachineFrame();
     
    234249                m_depth++;
    235250            } else
    236                 recordJSFrame(stackTrace);
     251                recordJITFrame(stackTrace);
    237252            advanceToParentFrame();
    238253            resetAtMachineFrame();
     
    342357
    343358        auto machineThreadsLocker = holdLock(m_vm.heap.machineThreads().getLock());
    344         LockHolder codeBlockSetLocker(m_vm.heap.codeBlockSet().getLock());
    345         LockHolder executableAllocatorLocker(ExecutableAllocator::singleton().getLock());
     359        auto codeBlockSetLocker = holdLock(m_vm.heap.codeBlockSet().getLock());
     360        auto executableAllocatorLocker = holdLock(ExecutableAllocator::singleton().getLock());
     361#if ENABLE(WEBASSEMBLY)
     362        auto wasmCalleesLocker = holdLock(Wasm::CalleeRegistry::singleton().getLock());
     363#else
     364        LockHolder wasmCalleesLocker(NoLockingNecessary);
     365#endif
    346366
    347367        auto didSuspend = m_jscExecutionThread->suspend();
     
    389409            bool didRunOutOfVectorSpace;
    390410            if (Options::sampleCCode()) {
    391                 CFrameWalker walker(m_vm, machineFrame, callFrame, codeBlockSetLocker, machineThreadsLocker);
     411                CFrameWalker walker(m_vm, machineFrame, callFrame, codeBlockSetLocker, machineThreadsLocker, wasmCalleesLocker);
    392412                walkSize = walker.walk(m_currentFrames, didRunOutOfVectorSpace);
    393413                wasValidWalk = walker.wasValidWalk();
    394414            } else {
    395                 FrameWalker walker(m_vm, callFrame, codeBlockSetLocker, machineThreadsLocker);
     415                FrameWalker walker(m_vm, callFrame, codeBlockSetLocker, machineThreadsLocker, wasmCalleesLocker);
    396416                walkSize = walker.walk(m_currentFrames, didRunOutOfVectorSpace);
    397417                wasValidWalk = walker.wasValidWalk();
     
    490510        };
    491511
    492         auto storeCalleeIntoLastFrame = [&] (CalleeBits calleeBits) {
     512        auto storeCalleeIntoLastFrame = [&] (UnprocessedStackFrame& unprocessedStackFrame) {
    493513            // Set the callee if it's a valid GC object.
     514            CalleeBits calleeBits = unprocessedStackFrame.unverifiedCallee;
    494515            StackFrame& stackFrame = stackTrace.frames.last();
    495516            bool alreadyHasExecutable = !!stackFrame.executable;
     517#if ENABLE(WEBASSEMBLY)
    496518            if (calleeBits.isWasm()) {
    497                 stackFrame.frameType = FrameType::Unknown;
     519                stackFrame.frameType = FrameType::Wasm;
     520                stackFrame.wasmIndexOrName = unprocessedStackFrame.wasmIndexOrName;
     521                stackFrame.wasmCompilationMode = unprocessedStackFrame.wasmCompilationMode;
    498522                return;
    499523            }
     524#endif
    500525
    501526            JSValue callee = calleeBits.asCell();
     
    604629
    605630                    appendCodeBlock(topCodeBlock, bytecodeIndex);
    606                     storeCalleeIntoLastFrame(unprocessedStackTrace.frames[0].unverifiedCallee);
     631                    storeCalleeIntoLastFrame(unprocessedStackTrace.frames[0]);
    607632                    startIndex = 1;
    608633                }
     
    611636                if (Optional<CodeOrigin> codeOrigin = topCodeBlock->findPC(unprocessedStackTrace.topPC)) {
    612637                    appendCodeOrigin(topCodeBlock, *codeOrigin);
    613                     storeCalleeIntoLastFrame(unprocessedStackTrace.frames[0].unverifiedCallee);
     638                    storeCalleeIntoLastFrame(unprocessedStackTrace.frames[0]);
    614639                    startIndex = 1;
    615640                }
     
    650675            // the machine frame will be at the top of the processed stack trace.
    651676            if (!unprocessedStackFrame.cCodePC)
    652                 storeCalleeIntoLastFrame(unprocessedStackFrame.unverifiedCallee);
     677                storeCalleeIntoLastFrame(unprocessedStackFrame);
    653678        }
    654679    }
     
    762787    }
    763788
    764     if (frameType == FrameType::Unknown || frameType == FrameType::C) {
     789    switch (frameType) {
     790    case FrameType::Unknown:
     791    case FrameType::C:
    765792#if HAVE(DLADDR)
    766793        if (frameType == FrameType::C) {
     
    772799#endif
    773800        return "(unknown)"_s;
    774     }
    775     if (frameType == FrameType::Host)
     801
     802    case FrameType::Host:
    776803        return "(host)"_s;
    777804
    778     if (executable->isHostFunction())
    779         return static_cast<NativeExecutable*>(executable)->name();
    780 
    781     if (executable->isFunctionExecutable())
    782         return static_cast<FunctionExecutable*>(executable)->ecmaName().string();
    783     if (executable->isProgramExecutable() || executable->isEvalExecutable())
    784         return "(program)"_s;
    785     if (executable->isModuleProgramExecutable())
    786         return "(module)"_s;
    787 
     805    case FrameType::Wasm:
     806#if ENABLE(WEBASSEMBLY)
     807        if (wasmIndexOrName)
     808            return makeString(wasmIndexOrName.value());
     809#endif
     810        return "(wasm)"_s;
     811
     812    case FrameType::Executable:
     813        if (executable->isHostFunction())
     814            return static_cast<NativeExecutable*>(executable)->name();
     815
     816        if (executable->isFunctionExecutable())
     817            return static_cast<FunctionExecutable*>(executable)->ecmaName().string();
     818        if (executable->isProgramExecutable() || executable->isEvalExecutable())
     819            return "(program)"_s;
     820        if (executable->isModuleProgramExecutable())
     821            return "(module)"_s;
     822
     823        RELEASE_ASSERT_NOT_REACHED();
     824        return String();
     825    }
    788826    RELEASE_ASSERT_NOT_REACHED();
    789827    return String();
     
    798836    }
    799837
    800     if (frameType == FrameType::Unknown || frameType == FrameType::C)
     838    switch (frameType) {
     839    case FrameType::Unknown:
     840    case FrameType::C:
    801841        return "(unknown)"_s;
    802     if (frameType == FrameType::Host)
     842
     843    case FrameType::Host:
    803844        return "(host)"_s;
    804845
    805     if (executable->isHostFunction())
    806         return static_cast<NativeExecutable*>(executable)->name();
    807 
    808     if (executable->isFunctionExecutable()) {
    809         String result = static_cast<FunctionExecutable*>(executable)->ecmaName().string();
    810         if (result.isEmpty())
    811             return "(anonymous function)"_s;
    812         return result;
    813     }
    814     if (executable->isEvalExecutable())
    815         return "(eval)"_s;
    816     if (executable->isProgramExecutable())
    817         return "(program)"_s;
    818     if (executable->isModuleProgramExecutable())
    819         return "(module)"_s;
    820 
     846    case FrameType::Wasm: {
     847#if ENABLE(WEBASSEMBLY)
     848        if (wasmIndexOrName)
     849            return makeString(wasmIndexOrName.value());
     850#endif
     851        return "(wasm)"_s;
     852    }
     853
     854    case FrameType::Executable:
     855        if (executable->isHostFunction())
     856            return static_cast<NativeExecutable*>(executable)->name();
     857
     858        if (executable->isFunctionExecutable()) {
     859            String result = static_cast<FunctionExecutable*>(executable)->ecmaName().string();
     860            if (result.isEmpty())
     861                return "(anonymous function)"_s;
     862            return result;
     863        }
     864        if (executable->isEvalExecutable())
     865            return "(eval)"_s;
     866        if (executable->isProgramExecutable())
     867            return "(program)"_s;
     868        if (executable->isModuleProgramExecutable())
     869            return "(module)"_s;
     870
     871        RELEASE_ASSERT_NOT_REACHED();
     872        return String();
     873    }
    821874    RELEASE_ASSERT_NOT_REACHED();
    822875    return String();
     
    825878int SamplingProfiler::StackFrame::functionStartLine()
    826879{
    827     if (frameType == FrameType::Unknown || frameType == FrameType::Host || frameType == FrameType::C)
     880    switch (frameType) {
     881    case FrameType::Unknown:
     882    case FrameType::Host:
     883    case FrameType::C:
     884    case FrameType::Wasm:
    828885        return -1;
    829886
    830     if (executable->isHostFunction())
     887    case FrameType::Executable:
     888        if (executable->isHostFunction())
     889            return -1;
     890        return static_cast<ScriptExecutable*>(executable)->firstLine();
     891    }
     892    RELEASE_ASSERT_NOT_REACHED();
     893    return -1;
     894}
     895
     896unsigned SamplingProfiler::StackFrame::functionStartColumn()
     897{
     898    switch (frameType) {
     899    case FrameType::Unknown:
     900    case FrameType::Host:
     901    case FrameType::C:
     902    case FrameType::Wasm:
     903        return std::numeric_limits<unsigned>::max();
     904
     905    case FrameType::Executable:
     906        if (executable->isHostFunction())
     907            return std::numeric_limits<unsigned>::max();
     908
     909        return static_cast<ScriptExecutable*>(executable)->startColumn();
     910    }
     911    RELEASE_ASSERT_NOT_REACHED();
     912    return std::numeric_limits<unsigned>::max();
     913}
     914
     915intptr_t SamplingProfiler::StackFrame::sourceID()
     916{
     917    switch (frameType) {
     918    case FrameType::Unknown:
     919    case FrameType::Host:
     920    case FrameType::C:
     921    case FrameType::Wasm:
    831922        return -1;
    832     return static_cast<ScriptExecutable*>(executable)->firstLine();
    833 }
    834 
    835 unsigned SamplingProfiler::StackFrame::functionStartColumn()
    836 {
    837     if (frameType == FrameType::Unknown || frameType == FrameType::Host || frameType == FrameType::C)
    838         return std::numeric_limits<unsigned>::max();
    839 
    840     if (executable->isHostFunction())
    841         return std::numeric_limits<unsigned>::max();
    842 
    843     return static_cast<ScriptExecutable*>(executable)->startColumn();
    844 }
    845 
    846 intptr_t SamplingProfiler::StackFrame::sourceID()
    847 {
    848     if (frameType == FrameType::Unknown || frameType == FrameType::Host || frameType == FrameType::C)
    849         return -1;
    850 
    851     if (executable->isHostFunction())
    852         return -1;
    853 
    854     return static_cast<ScriptExecutable*>(executable)->sourceID();
     923
     924    case FrameType::Executable:
     925        if (executable->isHostFunction())
     926            return -1;
     927
     928        return static_cast<ScriptExecutable*>(executable)->sourceID();
     929    }
     930    RELEASE_ASSERT_NOT_REACHED();
     931    return -1;
    855932}
    856933
    857934String SamplingProfiler::StackFrame::url()
    858935{
    859     if (frameType == FrameType::Unknown || frameType == FrameType::Host || frameType == FrameType::C)
     936    switch (frameType) {
     937    case FrameType::Unknown:
     938    case FrameType::Host:
     939    case FrameType::C:
     940    case FrameType::Wasm:
    860941        return emptyString();
    861 
    862     if (executable->isHostFunction())
    863         return emptyString();
    864 
    865     String url = static_cast<ScriptExecutable*>(executable)->sourceURL();
    866     if (url.isEmpty())
    867         return static_cast<ScriptExecutable*>(executable)->source().provider()->sourceURLDirective(); // Fall back to sourceURL directive.
    868     return url;
     942    case FrameType::Executable:
     943        if (executable->isHostFunction())
     944            return emptyString();
     945
     946        String url = static_cast<ScriptExecutable*>(executable)->sourceURL();
     947        if (url.isEmpty())
     948            return static_cast<ScriptExecutable*>(executable)->source().provider()->sourceURLDirective(); // Fall back to sourceURL directive.
     949        return url;
     950    }
     951    RELEASE_ASSERT_NOT_REACHED();
     952    return String();
    869953}
    870954
     
    10261110            continue;
    10271111
    1028         auto descriptionForLocation = [&] (StackFrame::CodeLocation location) -> String {
     1112        auto descriptionForLocation = [&] (StackFrame::CodeLocation location, Optional<Wasm::CompilationMode> wasmCompilationMode) -> String {
    10291113            String bytecodeIndex;
    10301114            String codeBlockHash;
     1115            String jitType;
    10311116            if (location.hasBytecodeIndex())
    10321117                bytecodeIndex = String::number(location.bytecodeIndex);
     
    10411126                codeBlockHash = "<nil>";
    10421127
    1043             return makeString("#", codeBlockHash, ":", JITCode::typeName(location.jitType), ":", bytecodeIndex);
     1128            if (wasmCompilationMode)
     1129                jitType = Wasm::makeString(wasmCompilationMode.value());
     1130            else
     1131                jitType = JITCode::typeName(location.jitType);
     1132
     1133            return makeString("#", codeBlockHash, ":", jitType, ":", bytecodeIndex);
    10441134        };
    10451135
    10461136        StackFrame& frame = stackTrace.frames.first();
    1047         String frameDescription = makeString(frame.displayName(m_vm), descriptionForLocation(frame.semanticLocation));
     1137        String frameDescription = makeString(frame.displayName(m_vm), descriptionForLocation(frame.semanticLocation, frame.wasmCompilationMode));
    10481138        if (Optional<std::pair<StackFrame::CodeLocation, CodeBlock*>> machineLocation = frame.machineLocation) {
    10491139            frameDescription = makeString(frameDescription, " <-- ",
    1050                 machineLocation->second->inferredName().data(), descriptionForLocation(machineLocation->first));
     1140                machineLocation->second->inferredName().data(), descriptionForLocation(machineLocation->first, WTF::nullopt));
    10511141        }
    10521142        bytecodeCounts.add(frameDescription, 0).iterator->value++;
     
    11021192        out.print("Executable");
    11031193        break;
     1194    case SamplingProfiler::FrameType::Wasm:
     1195        out.print("Wasm");
     1196        break;
    11041197    case SamplingProfiler::FrameType::Host:
    11051198        out.print("Host");
  • trunk/Source/JavaScriptCore/runtime/SamplingProfiler.h

    r244764 r248187  
    3232#include "JITCode.h"
    3333#include "MachineStackMarker.h"
     34#include "WasmCompilationMode.h"
     35#include "WasmIndexOrName.h"
    3436#include <wtf/HashSet.h>
    3537#include <wtf/Lock.h>
     
    6466        CodeBlock* verifiedCodeBlock { nullptr };
    6567        CallSiteIndex callSiteIndex;
     68#if ENABLE(WEBASSEMBLY)
     69        Optional<Wasm::IndexOrName> wasmIndexOrName;
     70#endif
     71        Optional<Wasm::CompilationMode> wasmCompilationMode;
    6672    };
    6773
    6874    enum class FrameType {
    6975        Executable,
     76        Wasm,
    7077        Host,
    7178        C,
    72         Unknown
     79        Unknown,
    7380    };
    7481
     
    8693        ExecutableBase* executable { nullptr };
    8794        JSObject* callee { nullptr };
     95#if ENABLE(WEBASSEMBLY)
     96        Optional<Wasm::IndexOrName> wasmIndexOrName;
     97#endif
     98        Optional<Wasm::CompilationMode> wasmCompilationMode;
    8899
    89100        struct CodeLocation {
  • trunk/Source/JavaScriptCore/tools/JSDollarVM.cpp

    r248143 r248187  
    4848#include "TypeProfilerLog.h"
    4949#include "VMInspector.h"
     50#include "WasmCapabilities.h"
    5051#include <wtf/Atomics.h>
    5152#include <wtf/DataLog.h>
     
    22022203}
    22032204
     2205static EncodedJSValue JSC_HOST_CALL functionIsWasmSupported(ExecState*)
     2206{
     2207#if ENABLE(WEBASSEMBLY)
     2208    return JSValue::encode(jsBoolean(Wasm::isSupported()));
     2209#else
     2210    return JSValue::encode(jsBoolean(false));
     2211#endif
     2212}
     2213
    22042214void JSDollarVM::finishCreation(VM& vm)
    22052215{
     
    23182328
    23192329    addFunction(vm, "parseCount", functionParseCount, 0);
     2330
     2331    addFunction(vm, "isWasmSupported", functionIsWasmSupported, 0);
    23202332}
    23212333
  • trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.h

    r223907 r248187  
    3232#include "B3OpaqueByproducts.h"
    3333#include "CCallHelpers.h"
     34#include "WasmCompilationMode.h"
    3435#include "WasmEmbedder.h"
    3536#include "WasmMemory.h"
     
    4344
    4445class MemoryInformation;
    45 
    46 enum class CompilationMode {
    47     BBQMode,
    48     OMGMode,
    49 };
    5046
    5147struct CompilationContext {
  • trunk/Source/JavaScriptCore/wasm/WasmBBQPlan.cpp

    r246504 r248187  
    307307            SignatureIndex signatureIndex = m_moduleInformation->internalFunctionSignatureIndices[functionIndex];
    308308            const Signature& signature = SignatureInformation::get(signatureIndex);
     309            const uint32_t functionIndexSpace = functionIndex + m_moduleInformation->importFunctionCount();
     310            ASSERT(functionIndexSpace < m_moduleInformation->functionIndexSpaceSize());
    309311            {
    310312                LinkBuffer linkBuffer(*context.wasmEntrypointJIT, nullptr, JITCompilationCanFail);
     
    315317
    316318                m_wasmInternalFunctions[functionIndex]->entrypoint.compilation = std::make_unique<B3::Compilation>(
    317                     FINALIZE_CODE(linkBuffer, B3CompilationPtrTag, "WebAssembly BBQ function[%i] %s", functionIndex, signature.toString().ascii().data()),
     319                    FINALIZE_CODE(linkBuffer, B3CompilationPtrTag, "WebAssembly BBQ function[%i] %s name %s", functionIndex, signature.toString().ascii().data(), makeString(IndexOrName(functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace))).ascii().data()),
    318320                    WTFMove(context.wasmEntrypointByproducts));
    319321            }
     
    327329
    328330                embedderToWasmInternalFunction->entrypoint.compilation = std::make_unique<B3::Compilation>(
    329                     FINALIZE_CODE(linkBuffer, B3CompilationPtrTag, "Embedder->WebAssembly entrypoint[%i] %s", functionIndex, signature.toString().ascii().data()),
     331                    FINALIZE_CODE(linkBuffer, B3CompilationPtrTag, "Embedder->WebAssembly entrypoint[%i] %s name %s", functionIndex, signature.toString().ascii().data(), makeString(IndexOrName(functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace))).ascii().data()),
    330332                    WTFMove(context.embedderEntrypointByproducts));
    331333            }
  • trunk/Source/JavaScriptCore/wasm/WasmBBQPlanInlines.h

    r224272 r248187  
    4343        RefPtr<Wasm::Callee> embedderEntrypointCallee;
    4444        if (auto embedderToWasmFunction = m_embedderToWasmInternalFunctions.get(internalFunctionIndex)) {
    45             embedderEntrypointCallee = Wasm::Callee::create(WTFMove(embedderToWasmFunction->entrypoint));
     45            embedderEntrypointCallee = Wasm::Callee::create(CompilationMode::BBQMode, WTFMove(embedderToWasmFunction->entrypoint));
    4646            MacroAssembler::repatchPointer(embedderToWasmFunction->calleeMoveLocation, CalleeBits::boxWasm(embedderEntrypointCallee.get()));
    4747        }
     
    4949        InternalFunction* function = m_wasmInternalFunctions[internalFunctionIndex].get();
    5050        size_t functionIndexSpace = internalFunctionIndex + m_moduleInformation->importFunctionCount();
    51         Ref<Wasm::Callee> wasmEntrypointCallee = Wasm::Callee::create(WTFMove(function->entrypoint), functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace));
     51        Ref<Wasm::Callee> wasmEntrypointCallee = Wasm::Callee::create(CompilationMode::BBQMode, WTFMove(function->entrypoint), functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace));
    5252        MacroAssembler::repatchPointer(function->calleeMoveLocation, CalleeBits::boxWasm(wasmEntrypointCallee.ptr()));
    5353
  • trunk/Source/JavaScriptCore/wasm/WasmCallee.cpp

    r231175 r248187  
    2929#if ENABLE(WEBASSEMBLY)
    3030
    31 #include "WasmFaultSignalHandler.h"
     31#include "WasmCalleeRegistry.h"
    3232
    3333namespace JSC { namespace Wasm {
    3434
    35 Callee::Callee(Entrypoint&& entrypoint)
    36     : m_entrypoint(WTFMove(entrypoint))
     35Callee::Callee(Wasm::CompilationMode compilationMode, Entrypoint&& entrypoint)
     36    : m_compilationMode(compilationMode)
     37    , m_entrypoint(WTFMove(entrypoint))
    3738{
    38     registerCode(m_entrypoint.compilation->codeRef().executableMemory()->start().untaggedPtr(), m_entrypoint.compilation->codeRef().executableMemory()->end().untaggedPtr());
     39    CalleeRegistry::singleton().registerCallee(this);
    3940}
    4041
    41 Callee::Callee(Entrypoint&& entrypoint, size_t index, std::pair<const Name*, RefPtr<NameSection>>&& name)
    42     : m_entrypoint(WTFMove(entrypoint))
     42Callee::Callee(Wasm::CompilationMode compilationMode, Entrypoint&& entrypoint, size_t index, std::pair<const Name*, RefPtr<NameSection>>&& name)
     43    : m_compilationMode(compilationMode)
     44    , m_entrypoint(WTFMove(entrypoint))
    4345    , m_indexOrName(index, WTFMove(name))
    4446{
    45     registerCode(m_entrypoint.compilation->codeRef().executableMemory()->start().untaggedPtr(), m_entrypoint.compilation->codeRef().executableMemory()->end().untaggedPtr());
     47    CalleeRegistry::singleton().registerCallee(this);
     48}
     49
     50Callee::~Callee()
     51{
     52    CalleeRegistry::singleton().unregisterCallee(this);
    4653}
    4754
  • trunk/Source/JavaScriptCore/wasm/WasmCallee.h

    r230748 r248187  
    3030#include "B3Compilation.h"
    3131#include "RegisterAtOffsetList.h"
     32#include "WasmCompilationMode.h"
    3233#include "WasmFormat.h"
    3334#include "WasmIndexOrName.h"
     
    3637namespace JSC { namespace Wasm {
    3738
    38 class Callee : public ThreadSafeRefCounted<Callee> {
     39class Callee final : public ThreadSafeRefCounted<Callee> {
    3940    WTF_MAKE_FAST_ALLOCATED;
    4041public:
    41     static Ref<Callee> create(Wasm::Entrypoint&& entrypoint)
     42    static Ref<Callee> create(Wasm::CompilationMode compilationMode, Wasm::Entrypoint&& entrypoint)
    4243    {
    43         Callee* callee = new Callee(WTFMove(entrypoint));
     44        Callee* callee = new Callee(compilationMode, WTFMove(entrypoint));
    4445        return adoptRef(*callee);
    4546    }
    4647
    47     static Ref<Callee> create(Wasm::Entrypoint&& entrypoint, size_t index, std::pair<const Name*, RefPtr<NameSection>>&& name)
     48    static Ref<Callee> create(Wasm::CompilationMode compilationMode, Wasm::Entrypoint&& entrypoint, size_t index, std::pair<const Name*, RefPtr<NameSection>>&& name)
    4849    {
    49         Callee* callee = new Callee(WTFMove(entrypoint), index, WTFMove(name));
     50        Callee* callee = new Callee(compilationMode, WTFMove(entrypoint), index, WTFMove(name));
    5051        return adoptRef(*callee);
    5152    }
     
    5556    RegisterAtOffsetList* calleeSaveRegisters() { return &m_entrypoint.calleeSaveRegisters; }
    5657    IndexOrName indexOrName() const { return m_indexOrName; }
     58    CompilationMode compilationMode() const { return m_compilationMode; }
     59
     60    std::tuple<void*, void*> range() const
     61    {
     62        void* start = m_entrypoint.compilation->codeRef().executableMemory()->start().untaggedPtr();
     63        void* end = m_entrypoint.compilation->codeRef().executableMemory()->end().untaggedPtr();
     64        return { start, end };
     65    }
     66
     67    JS_EXPORT_PRIVATE ~Callee();
    5768
    5869private:
    59     JS_EXPORT_PRIVATE Callee(Wasm::Entrypoint&&);
    60     JS_EXPORT_PRIVATE Callee(Wasm::Entrypoint&&, size_t, std::pair<const Name*, RefPtr<NameSection>>&&);
     70    JS_EXPORT_PRIVATE Callee(Wasm::CompilationMode, Wasm::Entrypoint&&);
     71    JS_EXPORT_PRIVATE Callee(Wasm::CompilationMode, Wasm::Entrypoint&&, size_t, std::pair<const Name*, RefPtr<NameSection>>&&);
    6172
     73    CompilationMode m_compilationMode;
    6274    Wasm::Entrypoint m_entrypoint;
    6375    IndexOrName m_indexOrName;
  • trunk/Source/JavaScriptCore/wasm/WasmCalleeRegistry.cpp

    r248185 r248187  
    11/*
    2  * Copyright (C) 2017 Apple Inc. All rights reserved.
     2 * Copyright (C) 2019 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
     26#include "config.h"
     27#include "WasmCalleeRegistry.h"
     28
    2629#if ENABLE(WEBASSEMBLY)
    2730
    28 namespace JSC {
     31#include <wtf/NeverDestroyed.h>
    2932
    30 namespace Wasm {
     33namespace JSC { namespace Wasm {
    3134
    32 void registerCode(void* start, void* end);
    33 void unregisterCode(void* start, void* end);
     35static LazyNeverDestroyed<CalleeRegistry> calleeRegistry;
    3436
    35 bool fastMemoryEnabled();
    36 JS_EXPORT_PRIVATE void enableFastMemory();
     37void CalleeRegistry::initialize()
     38{
     39    calleeRegistry.construct();
     40}
     41
     42CalleeRegistry& CalleeRegistry::singleton()
     43{
     44    return calleeRegistry.get();
     45}
    3746
    3847} } // namespace JSC::Wasm
  • trunk/Source/JavaScriptCore/wasm/WasmCalleeRegistry.h

    r248185 r248187  
    11/*
    2  * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
     2 * Copyright (C) 2019 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 #include "config.h"
    27 #include "WasmCallee.h"
     26#pragma once
    2827
    2928#if ENABLE(WEBASSEMBLY)
    3029
    31 #include "WasmFaultSignalHandler.h"
     30#include <wtf/HashSet.h>
     31#include <wtf/Lock.h>
    3232
    3333namespace JSC { namespace Wasm {
    3434
    35 Callee::Callee(Entrypoint&& entrypoint)
    36     : m_entrypoint(WTFMove(entrypoint))
    37 {
    38     registerCode(m_entrypoint.compilation->codeRef().executableMemory()->start().untaggedPtr(), m_entrypoint.compilation->codeRef().executableMemory()->end().untaggedPtr());
    39 }
     35class Callee;
    4036
    41 Callee::Callee(Entrypoint&& entrypoint, size_t index, std::pair<const Name*, RefPtr<NameSection>>&& name)
    42     : m_entrypoint(WTFMove(entrypoint))
    43     , m_indexOrName(index, WTFMove(name))
    44 {
    45     registerCode(m_entrypoint.compilation->codeRef().executableMemory()->start().untaggedPtr(), m_entrypoint.compilation->codeRef().executableMemory()->end().untaggedPtr());
    46 }
     37class CalleeRegistry {
     38    WTF_MAKE_FAST_ALLOCATED;
     39    WTF_MAKE_NONCOPYABLE(CalleeRegistry);
     40public:
     41    static void initialize();
     42    static CalleeRegistry& singleton();
     43
     44    Lock& getLock() { return m_lock; }
     45
     46    void registerCallee(Callee* callee)
     47    {
     48        auto locker = holdLock(m_lock);
     49        m_calleeSet.add(callee);
     50    }
     51
     52    void unregisterCallee(Callee* callee)
     53    {
     54        auto locker = holdLock(m_lock);
     55        m_calleeSet.remove(callee);
     56    }
     57
     58    const HashSet<Callee*>& allCallees(const AbstractLocker&)
     59    {
     60        return m_calleeSet;
     61    }
     62
     63    bool isValidCallee(const AbstractLocker&, Callee* callee)
     64    {
     65        return m_calleeSet.contains(callee);
     66    }
     67
     68    CalleeRegistry() = default;
     69
     70private:
     71    Lock m_lock;
     72    HashSet<Callee*> m_calleeSet;
     73};
    4774
    4875} } // namespace JSC::Wasm
  • trunk/Source/JavaScriptCore/wasm/WasmCompilationMode.cpp

    r248185 r248187  
    11/*
    2  * Copyright (C) 2017 Apple Inc. All rights reserved.
     2 * Copyright (C) 2019 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 #if ENABLE(WEBASSEMBLY)
     26#include "config.h"
     27#include "WasmCompilationMode.h"
    2728
    28 namespace JSC {
     29#include <wtf/Assertions.h>
    2930
    30 namespace Wasm {
     31namespace JSC { namespace Wasm {
    3132
    32 void registerCode(void* start, void* end);
    33 void unregisterCode(void* start, void* end);
    34 
    35 bool fastMemoryEnabled();
    36 JS_EXPORT_PRIVATE void enableFastMemory();
     33const char* makeString(CompilationMode mode)
     34{
     35    switch (mode) {
     36    case CompilationMode::BBQMode:
     37        return "BBQ";
     38    case CompilationMode::OMGMode:
     39        return "OMG";
     40    }
     41    RELEASE_ASSERT_NOT_REACHED();
     42    return "";
     43}
    3744
    3845} } // namespace JSC::Wasm
    39 
    40 #endif // ENABLE(WEBASSEMBLY)
  • trunk/Source/JavaScriptCore/wasm/WasmCompilationMode.h

    r248185 r248187  
    11/*
    2  * Copyright (C) 2017 Apple Inc. All rights reserved.
     2 * Copyright (C) 2019 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 #if ENABLE(WEBASSEMBLY)
     26#pragma once
    2727
    28 namespace JSC {
     28namespace JSC { namespace Wasm {
    2929
    30 namespace Wasm {
     30enum class CompilationMode : uint8_t {
     31    BBQMode,
     32    OMGMode,
     33};
    3134
    32 void registerCode(void* start, void* end);
    33 void unregisterCode(void* start, void* end);
    34 
    35 bool fastMemoryEnabled();
    36 JS_EXPORT_PRIVATE void enableFastMemory();
     35const char* makeString(CompilationMode);
    3736
    3837} } // namespace JSC::Wasm
    39 
    40 #endif // ENABLE(WEBASSEMBLY)
  • trunk/Source/JavaScriptCore/wasm/WasmFaultSignalHandler.cpp

    r247102 r248187  
    3131#include "ExecutableAllocator.h"
    3232#include "MachineContext.h"
     33#include "WasmCallee.h"
     34#include "WasmCalleeRegistry.h"
    3335#include "WasmCapabilities.h"
    3436#include "WasmExceptionType.h"
     
    4850}
    4951}
    50 
    51 static Lock codeLocationsLock;
    52 static LazyNeverDestroyed<HashSet<std::tuple<void*, void*>>> codeLocations; // (start, end)
    5352
    5453static bool fastHandlerInstalled { false };
     
    7776        if (faultedInActiveFastMemory) {
    7877            dataLogLnIf(WasmFaultSignalHandlerInternal::verbose, "found active fast memory for faulting address");
    79             LockHolder locker(codeLocationsLock);
    80             for (auto [start, end] : codeLocations.get()) {
     78            auto& calleeRegistry = CalleeRegistry::singleton();
     79            auto locker = holdLock(calleeRegistry.getLock());
     80            for (auto* callee : calleeRegistry.allCallees(locker)) {
     81                auto [start, end] = callee->range();
    8182                dataLogLnIf(WasmFaultSignalHandlerInternal::verbose, "function start: ", RawPointer(start), " end: ", RawPointer(end));
    8283                if (start <= faultingInstruction && faultingInstruction < end) {
     
    9899
    99100#endif // ENABLE(WEBASSEMBLY_FAST_MEMORY)
    100 
    101 void registerCode(void* start, void* end)
    102 {
    103     if (!fastMemoryEnabled())
    104         return;
    105     LockHolder locker(codeLocationsLock);
    106     codeLocations->add(std::make_tuple(start, end));
    107 }
    108 
    109 void unregisterCode(void* start, void* end)
    110 {
    111     if (!fastMemoryEnabled())
    112         return;
    113     LockHolder locker(codeLocationsLock);
    114     codeLocations->remove(std::make_tuple(start, end));
    115 }
    116101
    117102bool fastMemoryEnabled()
     
    135120        });
    136121
    137         codeLocations.construct();
    138122        fastHandlerInstalled = true;
    139123    });
  • trunk/Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h

    r223738 r248187  
    3030namespace Wasm {
    3131
    32 void registerCode(void* start, void* end);
    33 void unregisterCode(void* start, void* end);
    34 
    3532bool fastMemoryEnabled();
    3633JS_EXPORT_PRIVATE void enableFastMemory();
  • trunk/Source/JavaScriptCore/wasm/WasmIndexOrName.h

    r225416 r248187  
    3636struct NameSection;
    3737
     38// Keep this class copyable when the world is stopped: do not allocate any memory while copying this.
     39// SamplingProfiler copies it while suspending threads.
    3840struct IndexOrName {
    3941    typedef size_t Index;
  • trunk/Source/JavaScriptCore/wasm/WasmOMGPlan.cpp

    r243886 r248187  
    9797
    9898    omgEntrypoint.compilation = std::make_unique<B3::Compilation>(
    99         FINALIZE_CODE(linkBuffer, B3CompilationPtrTag, "WebAssembly OMG function[%i] %s", m_functionIndex, signature.toString().ascii().data()),
     99        FINALIZE_CODE(linkBuffer, B3CompilationPtrTag, "WebAssembly OMG function[%i] %s name %s", m_functionIndex, signature.toString().ascii().data(), makeString(IndexOrName(functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace))).ascii().data()),
    100100        WTFMove(context.wasmEntrypointByproducts));
    101101
     
    105105    {
    106106        ASSERT(m_codeBlock.ptr() == m_module->codeBlockFor(mode()));
    107         Ref<Callee> callee = Callee::create(WTFMove(omgEntrypoint), functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace));
     107        Ref<Callee> callee = Callee::create(CompilationMode::OMGMode, WTFMove(omgEntrypoint), functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace));
    108108        MacroAssembler::repatchPointer(parseAndCompileResult.value()->calleeMoveLocation, CalleeBits::boxWasm(callee.ptr()));
    109109        ASSERT(!m_codeBlock->m_optimizedCallees[m_functionIndex]);
Note: See TracChangeset for help on using the changeset viewer.