Changeset 293714 in webkit


Ignore:
Timestamp:
May 2, 2022, 10:07:01 PM (3 years ago)
Author:
[email protected]
Message:

[JSC] Introduce unlinked version of invalidation
https://bugs.webkit.org/show_bug.cgi?id=239887

Reviewed by Saam Barati.

This patch makes invalidation mechanism unlinked for unlinked DFG.

  1. We always use CheckTraps instead of InvalidationPoint with VMTraps so that we do not need

to repatch existing code.

  1. We introduce load-and-branch based InvalidationPoint for unlinked DFG so that we do not need

to repatch it to jump to OSR exit when watchpoint fires. We store this condition in DFG::JITData
so that code can quickly access to that.

  1. We make isStillValid conditions in DFG::CommonData always true for unlinked DFG code. Instead,

we check isJettisoned() condition of CodeBlock since it will become eventually per CodeBlock
information (while this CodeBlock gets invalidated, unlinked DFG code itself can be used for
the other CodeBlock).

After this change, now, jumpReplacements for unlinked DFG becomes empty. We no longer repatch these invalidation points.

  • Source/JavaScriptCore/bytecode/CodeBlock.cpp:

(JSC::CodeBlock::jettison):
(JSC::CodeBlock::hasInstalledVMTrapsBreakpoints const):
(JSC::CodeBlock::canInstallVMTrapBreakpoints const):
(JSC::CodeBlock::installVMTrapBreakpoints):
(JSC::CodeBlock::hasInstalledVMTrapBreakpoints const): Deleted.

  • Source/JavaScriptCore/bytecode/CodeBlock.h:
  • Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::parseBlock):

  • Source/JavaScriptCore/dfg/DFGCommonData.cpp:

(JSC::DFG::CommonData::invalidate):
(JSC::DFG::CommonData::~CommonData):
(JSC::DFG::CommonData::installVMTrapBreakpoints):
(JSC::DFG::CommonData::isVMTrapBreakpoint):

  • Source/JavaScriptCore/dfg/DFGCommonData.h:

(JSC::DFG::CommonData::CommonData):
(JSC::DFG::CommonData::hasInstalledVMTrapsBreakpoints const):
(JSC::DFG::CommonData::isStillValid const):

  • Source/JavaScriptCore/dfg/DFGDoesGC.cpp:

(JSC::DFG::doesGC):

  • Source/JavaScriptCore/dfg/DFGJITCode.cpp:

(JSC::DFG::JITCode::JITCode):

  • Source/JavaScriptCore/dfg/DFGJITCode.h:
  • Source/JavaScriptCore/dfg/DFGJITCompiler.cpp:

(JSC::DFG::JITCompiler::link):

  • Source/JavaScriptCore/dfg/DFGOSREntry.cpp:

(JSC::DFG::prepareOSREntry):
(JSC::DFG::prepareCatchOSREntry):

  • Source/JavaScriptCore/dfg/DFGPlan.cpp:

(JSC::DFG::Plan::finalize):

  • Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileInvalidationPoint):
(JSC::DFG::SpeculativeJIT::compileCheckTraps):
(JSC::DFG::SpeculativeJIT::emitInvalidationPoint): Deleted.

  • Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h:
  • Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • Source/JavaScriptCore/ftl/FTLJITCode.cpp:

(JSC::FTL::JITCode::JITCode):

  • Source/JavaScriptCore/ftl/FTLJITCode.h:

(JSC::FTL::JITCode::isUnlinked const):

  • Source/JavaScriptCore/ftl/FTLOSREntry.cpp:

(JSC::FTL::prepareOSREntry):

  • Source/JavaScriptCore/jit/JITCode.cpp:

(JSC::JITCode::isUnlinked const):

  • Source/JavaScriptCore/jit/JITCode.h:
  • Source/JavaScriptCore/runtime/VMTraps.cpp:

(JSC::VMTraps::tryInstallTrapBreakpoints):
(JSC::VMTraps::handleTraps):

Canonical link: https://commits.webkit.org/250203@main

Location:
trunk
Files:
1 added
23 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r293708 r293714  
     12022-04-29  Yusuke Suzuki  <[email protected]>
     2
     3        [JSC] Introduce unlinked version of invalidation
     4        https://bugs.webkit.org/show_bug.cgi?id=239887
     5
     6        Reviewed by Saam Barati.
     7
     8        * stress/polling-based-trap-on-unlinked-dfg.js: Added.
     9        (test):
     10
    1112022-05-01  Yusuke Suzuki  <[email protected]>
    212
  • trunk/Source/JavaScriptCore/ChangeLog

    r293710 r293714  
     12022-04-29  Yusuke Suzuki  <[email protected]>
     2
     3        [JSC] Introduce unlinked version of invalidation
     4        https://bugs.webkit.org/show_bug.cgi?id=239887
     5
     6        Reviewed by Saam Barati.
     7
     8        This patch makes invalidation mechanism unlinked for unlinked DFG.
     9
     10        1. We always use CheckTraps instead of InvalidationPoint with VMTraps so that we do not need
     11           to repatch existing code.
     12        2. We introduce load-and-branch based InvalidationPoint for unlinked DFG so that we do not need
     13           to repatch it to jump to OSR exit when watchpoint fires. We store this condition in DFG::JITData
     14           so that code can quickly access to that.
     15        3. We make isStillValid conditions in DFG::CommonData always true for unlinked DFG code. Instead,
     16           we check isJettisoned() condition of CodeBlock since it will become eventually per CodeBlock
     17           information (while this CodeBlock gets invalidated, unlinked DFG code itself can be used for
     18           the other CodeBlock).
     19
     20        After this change, now, jumpReplacements for unlinked DFG becomes empty. We no longer repatch these invalidation points.
     21
     22        * bytecode/CodeBlock.cpp:
     23        (JSC::CodeBlock::jettison):
     24        (JSC::CodeBlock::hasInstalledVMTrapsBreakpoints const):
     25        (JSC::CodeBlock::canInstallVMTrapBreakpoints const):
     26        (JSC::CodeBlock::installVMTrapBreakpoints):
     27        (JSC::CodeBlock::hasInstalledVMTrapBreakpoints const): Deleted.
     28        * bytecode/CodeBlock.h:
     29        (JSC::CodeBlock::isJettisoned const):
     30        * dfg/DFGByteCodeParser.cpp:
     31        (JSC::DFG::ByteCodeParser::parseBlock):
     32        * dfg/DFGCommonData.cpp:
     33        (JSC::DFG::CommonData::invalidateLinkedCode):
     34        (JSC::DFG::CommonData::~CommonData):
     35        (JSC::DFG::CommonData::installVMTrapBreakpoints):
     36        (JSC::DFG::CommonData::invalidate): Deleted.
     37        (JSC::DFG::CommonData::isVMTrapBreakpoint): Deleted.
     38        * dfg/DFGCommonData.h:
     39        (JSC::DFG::CommonData::CommonData):
     40        (JSC::DFG::CommonData::hasInstalledVMTrapsBreakpoints const):
     41        (JSC::DFG::CommonData::isUnlinked const):
     42        (JSC::DFG::CommonData::isStillValid const):
     43        * dfg/DFGDoesGC.cpp:
     44        (JSC::DFG::doesGC):
     45        * dfg/DFGJITCode.cpp:
     46        (JSC::DFG::JITCode::JITCode):
     47        * dfg/DFGJITCode.h:
     48        * dfg/DFGJITCompiler.cpp:
     49        (JSC::DFG::JITCompiler::link):
     50        * dfg/DFGOSREntry.cpp:
     51        (JSC::DFG::prepareOSREntry):
     52        (JSC::DFG::prepareCatchOSREntry):
     53        * dfg/DFGPlan.cpp:
     54        (JSC::DFG::Plan::finalize):
     55        * dfg/DFGSpeculativeJIT.cpp:
     56        (JSC::DFG::SpeculativeJIT::compileInvalidationPoint):
     57        (JSC::DFG::SpeculativeJIT::compileCheckTraps):
     58        (JSC::DFG::SpeculativeJIT::emitInvalidationPoint): Deleted.
     59        * dfg/DFGSpeculativeJIT.h:
     60        * dfg/DFGSpeculativeJIT32_64.cpp:
     61        (JSC::DFG::SpeculativeJIT::compile):
     62        * dfg/DFGSpeculativeJIT64.cpp:
     63        (JSC::DFG::SpeculativeJIT::compile):
     64        * ftl/FTLJITCode.cpp:
     65        (JSC::FTL::JITCode::JITCode):
     66        * ftl/FTLJITCode.h:
     67        (JSC::FTL::JITCode::isUnlinked const):
     68        * ftl/FTLOSREntry.cpp:
     69        (JSC::FTL::prepareOSREntry):
     70        * jit/JITCode.cpp:
     71        (JSC::JITCode::isUnlinked const):
     72        * jit/JITCode.h:
     73        * runtime/VMTraps.cpp:
     74        (JSC::VMTraps::tryInstallTrapBreakpoints):
     75        (JSC::VMTraps::handleTraps):
     76
    1772022-05-02  Yusuke Suzuki  <[email protected]>
    278
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r293605 r293714  
    22512251       
    22522252        // This accomplishes (1), and does its own book-keeping about whether it has already happened.
    2253         if (!jitCode()->dfgCommon()->invalidate()) {
    2254             // We've already been invalidated.
    2255             RELEASE_ASSERT(this != replacement() || (vm.heap.currentThreadIsDoingGCWork() && !vm.heap.isMarked(ownerExecutable())));
    2256             return;
     2253        if (auto* jitData = dfgJITData()) {
     2254            if (jitData->isInvalidated()) {
     2255                // We've already been invalidated.
     2256                RELEASE_ASSERT(this != replacement() || (vm.heap.currentThreadIsDoingGCWork() && !vm.heap.isMarked(ownerExecutable())));
     2257                return;
     2258            }
     2259            jitData->invalidate();
     2260        }
     2261        if (!jitCode()->isUnlinked()) {
     2262            if (!jitCode()->dfgCommon()->invalidateLinkedCode()) {
     2263                // We've already been invalidated.
     2264                RELEASE_ASSERT(this != replacement() || (vm.heap.currentThreadIsDoingGCWork() && !vm.heap.isMarked(ownerExecutable())));
     2265                return;
     2266            }
    22572267        }
    22582268    }
     
    34803490}
    34813491
    3482 bool CodeBlock::hasInstalledVMTrapBreakpoints() const
     3492bool CodeBlock::hasInstalledVMTrapsBreakpoints() const
     3493{
     3494#if ENABLE(SIGNAL_BASED_VM_TRAPS)
     3495    // This function may be called from a signal handler. We need to be
     3496    // careful to not call anything that is not signal handler safe, e.g.
     3497    // we should not perturb the refCount of m_jitCode.
     3498    if (!canInstallVMTrapBreakpoints())
     3499        return false;
     3500    return m_jitCode->dfgCommon()->hasInstalledVMTrapsBreakpoints();
     3501#else
     3502    return false;
     3503#endif
     3504}
     3505
     3506bool CodeBlock::canInstallVMTrapBreakpoints() const
    34833507{
    34843508#if ENABLE(SIGNAL_BASED_VM_TRAPS)
     
    34883512    if (!JITCode::isOptimizingJIT(jitType()))
    34893513        return false;
    3490     return m_jitCode->dfgCommon()->hasInstalledVMTrapsBreakpoints();
     3514    if (m_jitCode->isUnlinked())
     3515        return false;
     3516    return true;
    34913517#else
    34923518    return false;
     
    35003526    // careful to not call anything that is not signal handler safe, e.g.
    35013527    // we should not perturb the refCount of m_jitCode.
    3502     if (!JITCode::isOptimizingJIT(jitType()))
     3528    if (!canInstallVMTrapBreakpoints())
    35033529        return false;
    35043530    auto& commonData = *m_jitCode->dfgCommon();
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r293605 r293714  
    228228    JSParserScriptMode scriptMode() const { return m_unlinkedCode->scriptMode(); }
    229229
    230     bool hasInstalledVMTrapBreakpoints() const;
     230    bool hasInstalledVMTrapsBreakpoints() const;
     231    bool canInstallVMTrapBreakpoints() const;
    231232    bool installVMTrapBreakpoints();
    232233
     
    740741    }
    741742
     743    bool isJettisoned() const { return m_isJettisoned; }
     744
    742745    enum SteppingMode {
    743746        SteppingModeDisabled,
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r292929 r293714  
    81258125       
    81268126        case op_check_traps: {
    8127             addToGraph(Options::usePollingTraps() ? CheckTraps : InvalidationPoint);
     8127            addToGraph((Options::usePollingTraps() || m_graph.m_plan.isUnlinked()) ? CheckTraps : InvalidationPoint);
    81288128            NEXT_OPCODE(op_check_traps);
    81298129        }
  • trunk/Source/JavaScriptCore/dfg/DFGCommonData.cpp

    r293629 r293714  
    5656}
    5757
    58 bool CommonData::invalidate()
     58bool CommonData::invalidateLinkedCode()
    5959{
    60     if (!isStillValid)
     60    if (m_isUnlinked) {
     61        ASSERT(m_jumpReplacements.isEmpty());
     62        return true;
     63    }
     64
     65    if (!m_isStillValid)
    6166        return false;
    6267
    63     if (UNLIKELY(hasVMTrapsBreakpointsInstalled)) {
     68    if (UNLIKELY(m_hasVMTrapsBreakpointsInstalled)) {
    6469        Locker locker { pcCodeBlockMapLock };
    6570        auto& map = pcCodeBlockMap();
    6671        for (auto& jumpReplacement : m_jumpReplacements)
    6772            map.remove(jumpReplacement.dataLocation());
    68         hasVMTrapsBreakpointsInstalled = false;
     73        m_hasVMTrapsBreakpointsInstalled = false;
    6974    }
    7075
    7176    for (unsigned i = m_jumpReplacements.size(); i--;)
    7277        m_jumpReplacements[i].fire();
    73     isStillValid = false;
     78
     79    m_isStillValid = false;
    7480    return true;
    7581}
     
    7783CommonData::~CommonData()
    7884{
    79     if (UNLIKELY(hasVMTrapsBreakpointsInstalled)) {
     85    if (m_isUnlinked)
     86        return;
     87    if (UNLIKELY(m_hasVMTrapsBreakpointsInstalled)) {
    8088        Locker locker { pcCodeBlockMapLock };
    8189        auto& map = pcCodeBlockMap();
     
    8795void CommonData::installVMTrapBreakpoints(CodeBlock* owner)
    8896{
     97    ASSERT(!m_isUnlinked);
    8998    Locker locker { pcCodeBlockMapLock };
    90     if (!isStillValid || hasVMTrapsBreakpointsInstalled)
     99    if (!m_isStillValid || m_hasVMTrapsBreakpointsInstalled)
    91100        return;
    92     hasVMTrapsBreakpointsInstalled = true;
     101    m_hasVMTrapsBreakpointsInstalled = true;
    93102
    94103    auto& map = pcCodeBlockMap();
     
    119128        return nullptr;
    120129    return result->value;
    121 }
    122 
    123 bool CommonData::isVMTrapBreakpoint(void* address)
    124 {
    125     if (!isStillValid)
    126         return false;
    127     for (unsigned i = m_jumpReplacements.size(); i--;) {
    128         if (address == m_jumpReplacements[i].dataLocation())
    129             return true;
    130     }
    131     return false;
    132130}
    133131
  • trunk/Source/JavaScriptCore/dfg/DFGCommonData.h

    r293629 r293714  
    8080    WTF_MAKE_NONCOPYABLE(CommonData);
    8181public:
    82     CommonData()
     82    CommonData(bool isUnlinked)
    8383        : codeOrigins(CodeOriginPool::create())
     84        , m_isUnlinked(isUnlinked)
    8485    { }
    8586    ~CommonData();
     
    8788    void shrinkToFit();
    8889   
    89     bool invalidate(); // Returns true if we did invalidate, or false if the code block was already invalidated.
    90     bool hasInstalledVMTrapsBreakpoints() const { return isStillValid && hasVMTrapsBreakpointsInstalled; }
     90    bool invalidateLinkedCode(); // Returns true if we did invalidate, or false if the code block was already invalidated.
     91    bool hasInstalledVMTrapsBreakpoints() const { return m_isStillValid && m_hasVMTrapsBreakpointsInstalled; }
    9192    void installVMTrapBreakpoints(CodeBlock* owner);
    92     bool isVMTrapBreakpoint(void* address);
     93
     94    bool isUnlinked() const { return m_isUnlinked; }
     95    bool isStillValid() const { return m_isStillValid; }
    9396
    9497    CatchEntrypointData* catchOSREntryDataForBytecodeIndex(BytecodeIndex bytecodeIndex)
     
    137140    ScratchBuffer* catchOSREntryBuffer;
    138141    RefPtr<Profiler::Compilation> compilation;
    139     bool isStillValid { true };
    140     bool hasVMTrapsBreakpointsInstalled { false };
    141142   
    142143#if USE(JSVALUE32_64)
     
    146147    unsigned frameRegisterCount { std::numeric_limits<unsigned>::max() };
    147148    unsigned requiredRegisterCountForExit { std::numeric_limits<unsigned>::max() };
     149
     150private:
     151    bool m_isUnlinked { false };
     152    bool m_isStillValid { true };
     153    bool m_hasVMTrapsBreakpointsInstalled { false };
    148154};
    149155
  • trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp

    r292697 r293714  
    454454    case CheckTraps:
    455455        // FIXME: https://bugs.webkit.org/show_bug.cgi?id=194323
    456         ASSERT(Options::usePollingTraps());
     456        ASSERT(Options::usePollingTraps() || graph.m_plan.isUnlinked());
    457457        return true;
    458458
  • trunk/Source/JavaScriptCore/dfg/DFGJITCode.cpp

    r293629 r293714  
    3838JITCode::JITCode(bool isUnlinked)
    3939    : DirectJITCode(JITType::DFGJIT)
    40     , isUnlinked(isUnlinked)
     40    , common(isUnlinked)
    4141{
    4242}
  • trunk/Source/JavaScriptCore/dfg/DFGJITCode.h

    r293605 r293714  
    5858
    5959    static ptrdiff_t offsetOfExits() { return OBJECT_OFFSETOF(JITData, m_exits); }
     60    static ptrdiff_t offsetOfIsInvalidated() { return OBJECT_OFFSETOF(JITData, m_isInvalidated); }
    6061
    6162    static std::unique_ptr<JITData> create(unsigned poolSize, ExitVector&& exits)
     
    7071    const MacroAssemblerCodeRef<OSRExitPtrTag>& exitCode(unsigned exitIndex) const { return m_exits[exitIndex]; }
    7172
     73    bool isInvalidated() const { return !!m_isInvalidated; }
     74
     75    void invalidate()
     76    {
     77        m_isInvalidated = 1;
     78    }
     79
    7280private:
    7381    explicit JITData(unsigned size, ExitVector&& exits)
     
    7886
    7987    ExitVector m_exits;
     88    uint8_t m_isInvalidated { 0 };
    8089};
    8190
     
    8796    CommonData* dfgCommon() final;
    8897    JITCode* dfg() final;
     98    bool isUnlinked() const { return common.isUnlinked(); }
    8999   
    90100    OSREntryData* osrEntryDataForBytecodeIndex(BytecodeIndex bytecodeIndex)
     
    181191    bool abandonOSREntry { false };
    182192#endif // ENABLE(FTL_JIT)
    183     bool isUnlinked { false };
    184193};
    185194
  • trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp

    r293629 r293714  
    292292        linkBuffer.link(m_exceptionChecksWithCallFrameRollback, CodeLocationLabel(vm().getCTIStub(handleExceptionWithCallFrameRollbackGenerator).retaggedCode<NoPtrTag>()));
    293293
    294     Vector<JumpReplacement> jumpReplacements;
    295     MacroAssemblerCodeRef<JITThunkPtrTag> osrExitThunk = vm().getCTIStub(osrExitGenerationThunkGenerator);
    296     auto target = CodeLocationLabel<JITThunkPtrTag>(osrExitThunk.code());
    297     for (unsigned i = 0; i < m_osrExit.size(); ++i) {
    298         OSRExitCompilationInfo& info = m_exitCompilationInfo[i];
    299 
    300         if (!m_graph.m_plan.isUnlinked()) {
     294    if (!m_graph.m_plan.isUnlinked()) {
     295        MacroAssemblerCodeRef<JITThunkPtrTag> osrExitThunk = vm().getCTIStub(osrExitGenerationThunkGenerator);
     296        auto target = CodeLocationLabel<JITThunkPtrTag>(osrExitThunk.code());
     297        Vector<JumpReplacement> jumpReplacements;
     298        for (unsigned i = 0; i < m_osrExit.size(); ++i) {
     299            OSRExitCompilationInfo& info = m_exitCompilationInfo[i];
    301300            linkBuffer.link(info.m_patchableJump.m_jump, target);
    302301            OSRExit& exit = m_osrExit[i];
    303302            exit.m_patchableJumpLocation = linkBuffer.locationOf<JSInternalPtrTag>(info.m_patchableJump);
    304         }
    305 
    306         if (info.m_replacementSource.isSet()) {
    307             jumpReplacements.append(JumpReplacement(
    308                 linkBuffer.locationOf<JSInternalPtrTag>(info.m_replacementSource),
    309                 linkBuffer.locationOf<OSRExitPtrTag>(info.m_replacementDestination)));
    310         }
    311     }
    312     m_jitCode->common.m_jumpReplacements = WTFMove(jumpReplacements);
     303            if (info.m_replacementSource.isSet()) {
     304                jumpReplacements.append(JumpReplacement(
     305                    linkBuffer.locationOf<JSInternalPtrTag>(info.m_replacementSource),
     306                    linkBuffer.locationOf<OSRExitPtrTag>(info.m_replacementDestination)));
     307            }
     308        }
     309        m_jitCode->common.m_jumpReplacements = WTFMove(jumpReplacements);
     310    }
     311
     312#if ASSERT_ENABLED
     313    for (auto& info : m_exitCompilationInfo) {
     314        if (info.m_replacementSource.isSet())
     315            ASSERT(!m_graph.m_plan.isUnlinked());
     316    }
     317    if (m_graph.m_plan.isUnlinked())
     318        ASSERT(m_jitCode->common.m_jumpReplacements.isEmpty());
     319#endif
    313320   
    314321    if (UNLIKELY(m_graph.compilation())) {
  • trunk/Source/JavaScriptCore/dfg/DFGOSREntry.cpp

    r292372 r293714  
    9898    ASSERT(codeBlock->alternative());
    9999    ASSERT(codeBlock->alternative()->jitType() == JITType::BaselineJIT);
    100     ASSERT(codeBlock->jitCode()->dfgCommon()->isStillValid);
     100    ASSERT(codeBlock->jitCode()->dfgCommon()->isStillValid());
     101    ASSERT(!codeBlock->isJettisoned());
    101102
    102103    if (!Options::useOSREntryToDFG())
     
    347348{
    348349    ASSERT(optimizedCodeBlock->jitType() == JITType::DFGJIT || optimizedCodeBlock->jitType() == JITType::FTLJIT);
    349     ASSERT(optimizedCodeBlock->jitCode()->dfgCommon()->isStillValid);
     350    ASSERT(optimizedCodeBlock->jitCode()->dfgCommon()->isStillValid());
     351    ASSERT(!optimizedCodeBlock->isJettisoned());
    350352
    351353    if (!Options::useOSREntryToDFG() && optimizedCodeBlock->jitCode()->jitType() == JITType::DFGJIT)
  • trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp

    r293605 r293714  
    555555        }
    556556
    557         // Since Plan::reallyAdd could fire watchpoints (see ArrayBufferViewWatchpointAdaptor::add), it is possible that the current CodeBlock is now invalidated.
    558         if (!m_codeBlock->jitCode()->dfgCommon()->isStillValid) {
     557        // Since Plan::reallyAdd could fire watchpoints (see ArrayBufferViewWatchpointAdaptor::add),
     558        // it is possible that the current CodeBlock is now invalidated & jettisoned.
     559        if (m_codeBlock->isJettisoned()) {
    559560            CODEBLOCK_LOG_EVENT(m_codeBlock, "dfgFinalize", ("invalidated"));
    560561            return CompilationInvalidated;
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r293629 r293714  
    325325}
    326326
    327 void SpeculativeJIT::emitInvalidationPoint(Node* node)
     327void SpeculativeJIT::compileInvalidationPoint(Node* node)
    328328{
    329329    if (!m_compileOkay)
    330330        return;
     331
     332#if USE(JSVALUE64)
     333    if (m_graph.m_plan.isUnlinked()) {
     334        auto exitJump = m_jit.branchTest8(CCallHelpers::NonZero, CCallHelpers::Address(GPRInfo::constantsRegister, JITData::offsetOfIsInvalidated()));
     335        speculationCheck(UncountableInvalidation, JSValueRegs(), nullptr, exitJump);
     336        noResult(node);
     337        return;
     338    }
     339#endif
     340
    331341    OSRExitCompilationInfo& info = m_jit.appendExitInfo(JITCompiler::JumpList());
    332342    m_jit.appendOSRExit(OSRExit(
     
    24982508void SpeculativeJIT::compileCheckTraps(Node* node)
    24992509{
    2500     ASSERT(Options::usePollingTraps());
     2510    ASSERT(Options::usePollingTraps() || m_graph.m_plan.isUnlinked());
    25012511    GPRTemporary unused(this);
    25022512    GPRReg unusedGPR = unused.gpr();
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r293629 r293714  
    16751675    void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
    16761676   
    1677     void emitInvalidationPoint(Node*);
     1677    void compileInvalidationPoint(Node*);
    16781678   
    16791679    void unreachable(Node*);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r293629 r293714  
    40254025
    40264026    case InvalidationPoint:
    4027         emitInvalidationPoint(node);
     4027        compileInvalidationPoint(node);
    40284028        break;
    40294029
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r293629 r293714  
    54355435       
    54365436    case InvalidationPoint:
    5437         emitInvalidationPoint(node);
     5437        compileInvalidationPoint(node);
    54385438        break;
    54395439
  • trunk/Source/JavaScriptCore/ftl/FTLJITCode.cpp

    r278253 r293714  
    3838JITCode::JITCode()
    3939    : JSC::JITCode(JITType::FTLJIT)
     40    , common(/* isUnlinked */ false)
    4041{
    4142}
  • trunk/Source/JavaScriptCore/ftl/FTLJITCode.h

    r287596 r293714  
    7070    void shrinkToFit(const ConcurrentJSLocker&) override;
    7171
     72    bool isUnlinked() const { return common.isUnlinked(); }
     73
    7274    PCToCodeOriginMap* pcToCodeOriginMap() override { return common.m_pcToCodeOriginMap.get(); }
    7375
  • trunk/Source/JavaScriptCore/ftl/FTLOSREntry.cpp

    r278253 r293714  
    4949    ForOSREntryJITCode* entryCode = entryCodeBlock->jitCode()->ftlForOSREntry();
    5050
    51     if (!entryCode->dfgCommon()->isStillValid) {
     51    if (!entryCode->dfgCommon()->isStillValid()) {
    5252        dfgCode->clearOSREntryBlockAndResetThresholds(dfgCodeBlock);
    5353        return nullptr;
  • trunk/Source/JavaScriptCore/jit/JITCode.cpp

    r291779 r293714  
    2727#include "JITCode.h"
    2828
     29#include "DFGJITCode.h"
    2930#include "FTLJITCode.h"
    3031
     
    6667}
    6768
     69bool JITCode::isUnlinked() const
     70{
     71    switch (m_jitType) {
     72    case JITType::None:
     73    case JITType::HostCallThunk:
     74    case JITType::InterpreterThunk:
     75    case JITType::BaselineJIT:
     76        return true;
     77    case JITType::DFGJIT:
     78#if ENABLE(DFG_JIT)
     79        return static_cast<const DFG::JITCode*>(this)->isUnlinked();
     80#else
     81        return false;
     82#endif
     83    case JITType::FTLJIT:
     84#if ENABLE(FTL_JIT)
     85        return static_cast<const FTL::JITCode*>(this)->isUnlinked();
     86#else
     87        return false;
     88#endif
     89    }
     90    return true;
     91}
     92
    6893void JITCode::validateReferences(const TrackedReferences&)
    6994{
  • trunk/Source/JavaScriptCore/jit/JITCode.h

    r292447 r293714  
    190190        return m_jitType;
    191191    }
     192
     193    bool isUnlinked() const;
    192194   
    193195    template<typename PointerType>
  • trunk/Source/JavaScriptCore/runtime/VMTraps.cpp

    r292978 r293714  
    146146    }
    147147
    148     if (JITCode::isOptimizingJIT(foundCodeBlock->jitType())) {
     148    if (foundCodeBlock->canInstallVMTrapBreakpoints()) {
    149149        if (!m_lock->tryLock())
    150150            return; // Let the SignalSender try again later.
     
    156156        }
    157157
    158         if (!foundCodeBlock->hasInstalledVMTrapBreakpoints())
     158        if (!foundCodeBlock->hasInstalledVMTrapsBreakpoints())
    159159            foundCodeBlock->installVMTrapBreakpoints();
    160160        return;
     
    223223                    return SignalAction::NotHandled;
    224224                }
    225                 ASSERT(currentCodeBlock->hasInstalledVMTrapBreakpoints());
     225                ASSERT(currentCodeBlock->hasInstalledVMTrapsBreakpoints());
    226226                VM& vm = currentCodeBlock->vm();
    227227
     
    243243                vm.heap.forEachCodeBlockIgnoringJITPlans(codeBlockSetLocker, [&] (CodeBlock* codeBlock) {
    244244                    // We want to jettison all code blocks that have vm traps breakpoints, otherwise we could hit them later.
    245                     if (codeBlock->hasInstalledVMTrapBreakpoints()) {
     245                    if (codeBlock->hasInstalledVMTrapsBreakpoints()) {
    246246                        if (currentCodeBlock == codeBlock)
    247247                            sawCurrentCodeBlock = true;
     
    380380        vm.heap.forEachCodeBlockIgnoringJITPlans(codeBlockSetLocker, [&] (CodeBlock* codeBlock) {
    381381            // We want to jettison all code blocks that have vm traps breakpoints, otherwise we could hit them later.
    382             if (codeBlock->hasInstalledVMTrapBreakpoints())
     382            if (codeBlock->hasInstalledVMTrapsBreakpoints())
    383383                codeBlock->jettison(Profiler::JettisonDueToVMTraps);
    384384        });
Note: See TracChangeset for help on using the changeset viewer.