⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 276226 in webkit


Ignore:
Timestamp:
Apr 18, 2021, 1:06:48 AM (5 years ago)
Author:
ysuzuki@apple.com
Message:

[JSC] Do not use Bag<> for DFG / FTL watchpoints
https://bugs.webkit.org/show_bug.cgi?id=224715

Reviewed by Darin Adler.

While Bag<> is useful since its allocated memory will not be moved,
this is really memory-inefficient data structure. Each entry gets a
tail pointer (so adding 8 bytes) and we allocate each entry separately.

In DFG and FTL, we are using Bag<> for watchpoints. But this is not necessary actually: thanks to
concurrent compilers, our watchpoint registration is batched at the end of compilation. This means
that we have a way to know how many watchpoints we should register at that point.

In this patch, we introduce WatchpointCollector. In DesiredGlobalProperties, we run reallyAdd twice
with WatchpointCollector. First time, we just count # of watchpoints. Then we allocate FixedVector<XXXWatchpoint>
and install them. Since we do not (cannot) grow this fixed vector, watchpoint's address will not be changed as required.

We also move DesiredGlobalProperties under DesiredWatchpoints since this basically registers watchpoints.

  • bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp:

(JSC::AdaptiveInferredPropertyValueWatchpointBase::AdaptiveInferredPropertyValueWatchpointBase):
(JSC::AdaptiveInferredPropertyValueWatchpointBase::initialize):

  • bytecode/AdaptiveInferredPropertyValueWatchpointBase.h:
  • bytecode/CodeBlockJettisoningWatchpoint.h:
  • dfg/DFGAdaptiveInferredPropertyValueWatchpoint.cpp:

(JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::AdaptiveInferredPropertyValueWatchpoint):
(JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::initialize):

  • dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h:
  • dfg/DFGAdaptiveStructureWatchpoint.cpp:

(JSC::DFG::AdaptiveStructureWatchpoint::AdaptiveStructureWatchpoint):
(JSC::DFG::AdaptiveStructureWatchpoint::initialize):

  • dfg/DFGAdaptiveStructureWatchpoint.h:
  • dfg/DFGCommonData.cpp:

(JSC::DFG::CommonData::validateReferences):
(JSC::DFG::CommonData::clearWatchpoints):

  • dfg/DFGCommonData.h:
  • dfg/DFGDesiredGlobalProperties.cpp:

(JSC::DFG::DesiredGlobalProperties::reallyAdd):

  • dfg/DFGDesiredGlobalProperties.h:
  • dfg/DFGDesiredWatchpoints.cpp:

(JSC::DFG::ArrayBufferViewWatchpointAdaptor::add):
(JSC::DFG::SymbolTableAdaptor::add):
(JSC::DFG::FunctionExecutableAdaptor::add):
(JSC::DFG::AdaptiveStructureWatchpointAdaptor::add):
(JSC::DFG::DesiredWatchpoints::addLazily):
(JSC::DFG::DesiredWatchpoints::reallyAdd):
(JSC::DFG::DesiredWatchpoints::areStillValidOnMainThread):
(JSC::DFG::WatchpointCollector::finalize):

  • dfg/DFGDesiredWatchpoints.h:

(JSC::DFG::SetPointerAdaptor::add):
(JSC::DFG::GenericDesiredWatchpoints::reallyAdd):

  • dfg/DFGGraph.cpp:

(JSC::DFG::Graph::watchGlobalProperty):

  • dfg/DFGGraph.h:
  • dfg/DFGPlan.cpp:

(JSC::DFG::Plan::reallyAdd):
(JSC::DFG::Plan::isStillValidOnMainThread):
(JSC::DFG::Plan::cancel):

  • dfg/DFGPlan.h:

(JSC::DFG::Plan::transitions):
(JSC::DFG::Plan::globalProperties): Deleted.

Location:
trunk/Source/JavaScriptCore
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r276224 r276226  
     12021-04-18  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Do not use Bag<> for DFG / FTL watchpoints
     4        https://bugs.webkit.org/show_bug.cgi?id=224715
     5
     6        Reviewed by Darin Adler.
     7
     8        While Bag<> is useful since its allocated memory will not be moved,
     9        this is really memory-inefficient data structure. Each entry gets a
     10        tail pointer (so adding 8 bytes) and we allocate each entry separately.
     11
     12        In DFG and FTL, we are using Bag<> for watchpoints. But this is not necessary actually: thanks to
     13        concurrent compilers, our watchpoint registration is batched at the end of compilation. This means
     14        that we have a way to know how many watchpoints we should register at that point.
     15
     16        In this patch, we introduce WatchpointCollector. In DesiredGlobalProperties, we run reallyAdd twice
     17        with WatchpointCollector. First time, we just count # of watchpoints. Then we allocate FixedVector<XXXWatchpoint>
     18        and install them. Since we do not (cannot) grow this fixed vector, watchpoint's address will not be changed as required.
     19
     20        We also move DesiredGlobalProperties under DesiredWatchpoints since this basically registers watchpoints.
     21
     22        * bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp:
     23        (JSC::AdaptiveInferredPropertyValueWatchpointBase::AdaptiveInferredPropertyValueWatchpointBase):
     24        (JSC::AdaptiveInferredPropertyValueWatchpointBase::initialize):
     25        * bytecode/AdaptiveInferredPropertyValueWatchpointBase.h:
     26        * bytecode/CodeBlockJettisoningWatchpoint.h:
     27        * dfg/DFGAdaptiveInferredPropertyValueWatchpoint.cpp:
     28        (JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::AdaptiveInferredPropertyValueWatchpoint):
     29        (JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::initialize):
     30        * dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h:
     31        * dfg/DFGAdaptiveStructureWatchpoint.cpp:
     32        (JSC::DFG::AdaptiveStructureWatchpoint::AdaptiveStructureWatchpoint):
     33        (JSC::DFG::AdaptiveStructureWatchpoint::initialize):
     34        * dfg/DFGAdaptiveStructureWatchpoint.h:
     35        * dfg/DFGCommonData.cpp:
     36        (JSC::DFG::CommonData::validateReferences):
     37        (JSC::DFG::CommonData::clearWatchpoints):
     38        * dfg/DFGCommonData.h:
     39        * dfg/DFGDesiredGlobalProperties.cpp:
     40        (JSC::DFG::DesiredGlobalProperties::reallyAdd):
     41        * dfg/DFGDesiredGlobalProperties.h:
     42        * dfg/DFGDesiredWatchpoints.cpp:
     43        (JSC::DFG::ArrayBufferViewWatchpointAdaptor::add):
     44        (JSC::DFG::SymbolTableAdaptor::add):
     45        (JSC::DFG::FunctionExecutableAdaptor::add):
     46        (JSC::DFG::AdaptiveStructureWatchpointAdaptor::add):
     47        (JSC::DFG::DesiredWatchpoints::addLazily):
     48        (JSC::DFG::DesiredWatchpoints::reallyAdd):
     49        (JSC::DFG::DesiredWatchpoints::areStillValidOnMainThread):
     50        (JSC::DFG::WatchpointCollector::finalize):
     51        * dfg/DFGDesiredWatchpoints.h:
     52        (JSC::DFG::SetPointerAdaptor::add):
     53        (JSC::DFG::GenericDesiredWatchpoints::reallyAdd):
     54        * dfg/DFGGraph.cpp:
     55        (JSC::DFG::Graph::watchGlobalProperty):
     56        * dfg/DFGGraph.h:
     57        * dfg/DFGPlan.cpp:
     58        (JSC::DFG::Plan::reallyAdd):
     59        (JSC::DFG::Plan::isStillValidOnMainThread):
     60        (JSC::DFG::Plan::cancel):
     61        * dfg/DFGPlan.h:
     62        (JSC::DFG::Plan::transitions):
     63        (JSC::DFG::Plan::globalProperties): Deleted.
     64
    1652021-04-18  Yusuke Suzuki  <ysuzuki@apple.com>
    266
  • trunk/Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp

    r243420 r276226  
    3434    : m_key(key)
    3535{
     36    RELEASE_ASSERT(key.kind() == PropertyCondition::Equivalence);
     37}
     38
     39void AdaptiveInferredPropertyValueWatchpointBase::initialize(const ObjectPropertyCondition& key)
     40{
     41    m_key = key;
    3642    RELEASE_ASSERT(key.kind() == PropertyCondition::Equivalence);
    3743}
  • trunk/Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.h

    r250540 r276226  
    4141public:
    4242    AdaptiveInferredPropertyValueWatchpointBase(const ObjectPropertyCondition&);
     43    AdaptiveInferredPropertyValueWatchpointBase() = default;
    4344
    4445    const ObjectPropertyCondition& key() const { return m_key; }
    4546
     47    void initialize(const ObjectPropertyCondition&);
    4648    void install(VM&);
    4749
  • trunk/Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.h

    r247843 r276226  
    3434class CodeBlockJettisoningWatchpoint final : public Watchpoint {
    3535public:
    36     CodeBlockJettisoningWatchpoint(CodeBlock* codeBlock)
     36    CodeBlockJettisoningWatchpoint(CodeBlock* codeBlock = nullptr)
    3737        : Watchpoint(Watchpoint::Type::CodeBlockJettisoning)
    3838        , m_codeBlock(codeBlock)
    3939    {
     40    }
     41
     42    void initialize(CodeBlock* codeBlock)
     43    {
     44        m_codeBlock = codeBlock;
    4045    }
    4146   
  • trunk/Source/JavaScriptCore/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.cpp

    r261755 r276226  
    4040}
    4141
     42void AdaptiveInferredPropertyValueWatchpoint::initialize(const ObjectPropertyCondition& key, CodeBlock* codeBlock)
     43{
     44    Base::initialize(key);
     45    m_codeBlock = codeBlock;
     46}
     47
    4248void AdaptiveInferredPropertyValueWatchpoint::handleFire(VM&, const FireDetail& detail)
    4349{
  • trunk/Source/JavaScriptCore/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h

    r261569 r276226  
    3636    typedef AdaptiveInferredPropertyValueWatchpointBase Base;
    3737    AdaptiveInferredPropertyValueWatchpoint(const ObjectPropertyCondition&, CodeBlock*);
     38    AdaptiveInferredPropertyValueWatchpoint() = default;
     39
     40    void initialize(const ObjectPropertyCondition&, CodeBlock*);
    3841
    3942private:
     
    4245    void handleFire(VM&, const FireDetail&) final;
    4346
    44     CodeBlock* m_codeBlock;
     47    CodeBlock* m_codeBlock { nullptr };
    4548};
    4649
  • trunk/Source/JavaScriptCore/dfg/DFGAdaptiveStructureWatchpoint.cpp

    r261895 r276226  
    4343}
    4444
     45AdaptiveStructureWatchpoint::AdaptiveStructureWatchpoint()
     46    : Watchpoint(Watchpoint::Type::AdaptiveStructure)
     47    , m_codeBlock(nullptr)
     48{
     49}
     50
     51void AdaptiveStructureWatchpoint::initialize(const ObjectPropertyCondition& key, CodeBlock* codeBlock)
     52{
     53    m_codeBlock = codeBlock;
     54    m_key = key;
     55    RELEASE_ASSERT(key.watchingRequiresStructureTransitionWatchpoint());
     56    RELEASE_ASSERT(!key.watchingRequiresReplacementWatchpoint());
     57}
     58
    4559void AdaptiveStructureWatchpoint::install(VM& vm)
    4660{
  • trunk/Source/JavaScriptCore/dfg/DFGAdaptiveStructureWatchpoint.h

    r247843 r276226  
    3838public:
    3939    AdaptiveStructureWatchpoint(const ObjectPropertyCondition&, CodeBlock*);
     40    AdaptiveStructureWatchpoint();
    4041   
    4142    const ObjectPropertyCondition& key() const { return m_key; }
    42    
     43
     44    void initialize(const ObjectPropertyCondition&, CodeBlock*);
     45
    4346    void install(VM&);
    4447
  • trunk/Source/JavaScriptCore/dfg/DFGCommonData.cpp

    r276005 r276226  
    149149    }
    150150   
    151     for (AdaptiveStructureWatchpoint* watchpoint : adaptiveStructureWatchpoints)
    152         watchpoint->key().validateReferences(trackedReferences);
     151    for (auto& watchpoint : m_adaptiveStructureWatchpoints)
     152        watchpoint.key().validateReferences(trackedReferences);
    153153}
    154154
     
    168168void CommonData::clearWatchpoints()
    169169{
    170     watchpoints.clear();
    171     adaptiveStructureWatchpoints.clear();
    172     adaptiveInferredPropertyValueWatchpoints.clear();
     170    m_watchpoints = FixedVector<CodeBlockJettisoningWatchpoint>();
     171    m_adaptiveStructureWatchpoints = FixedVector<AdaptiveStructureWatchpoint>();
     172    m_adaptiveInferredPropertyValueWatchpoints = FixedVector<AdaptiveInferredPropertyValueWatchpoint>();
    173173}
    174174
  • trunk/Source/JavaScriptCore/dfg/DFGCommonData.h

    r276005 r276226  
    114114    FixedVector<StructureID> m_weakStructureReferences;
    115115    FixedVector<CatchEntrypointData> m_catchEntrypoints;
    116     Bag<CodeBlockJettisoningWatchpoint> watchpoints;
    117     Bag<AdaptiveStructureWatchpoint> adaptiveStructureWatchpoints;
    118     Bag<AdaptiveInferredPropertyValueWatchpoint> adaptiveInferredPropertyValueWatchpoints;
     116    FixedVector<CodeBlockJettisoningWatchpoint> m_watchpoints;
     117    FixedVector<AdaptiveStructureWatchpoint> m_adaptiveStructureWatchpoints;
     118    FixedVector<AdaptiveInferredPropertyValueWatchpoint> m_adaptiveInferredPropertyValueWatchpoints;
    119119    RecordedStatuses recordedStatuses;
    120120    Vector<JumpReplacement> m_jumpReplacements;
  • trunk/Source/JavaScriptCore/dfg/DFGDesiredGlobalProperties.cpp

    r261755 r276226  
    5555}
    5656
    57 void DesiredGlobalProperties::reallyAdd(CodeBlock* codeBlock, DesiredIdentifiers& identifiers, CommonData& common)
     57void DesiredGlobalProperties::reallyAdd(CodeBlock* codeBlock, DesiredIdentifiers& identifiers, WatchpointCollector& collector)
    5858{
    5959    for (const auto& property : m_set) {
    60         auto* uid = identifiers.at(property.identifierNumber());
    61         auto& watchpointSet = property.globalObject()->ensureReferencedPropertyWatchpointSet(uid);
    62         ASSERT(watchpointSet.isStillValid());
    63         CodeBlockJettisoningWatchpoint* watchpoint = nullptr;
    64         {
    65             ConcurrentJSLocker locker(codeBlock->m_lock);
    66             watchpoint = common.watchpoints.add(codeBlock);
    67         }
    68         watchpointSet.add(WTFMove(watchpoint));
     60        collector.addWatchpoint([&](CodeBlockJettisoningWatchpoint& watchpoint) {
     61            {
     62                ConcurrentJSLocker locker(codeBlock->m_lock);
     63                watchpoint.initialize(codeBlock);
     64            }
     65            auto* uid = identifiers.at(property.identifierNumber());
     66            auto& watchpointSet = property.globalObject()->ensureReferencedPropertyWatchpointSet(uid);
     67            ASSERT(watchpointSet.isStillValid());
     68            watchpointSet.add(&watchpoint);
     69        });
    6970    }
    7071}
  • trunk/Source/JavaScriptCore/dfg/DFGDesiredGlobalProperties.h

    r240254 r276226  
    4040class CommonData;
    4141class DesiredIdentifiers;
     42class WatchpointCollector;
    4243
    4344class DesiredGlobalProperties {
     
    5051    bool isStillValidOnMainThread(VM&, DesiredIdentifiers&);
    5152
    52     void reallyAdd(CodeBlock*, DesiredIdentifiers&, CommonData&);
     53    void reallyAdd(CodeBlock*, DesiredIdentifiers&, WatchpointCollector&);
    5354
    5455private:
  • trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.cpp

    r269343 r276226  
    3535namespace JSC { namespace DFG {
    3636
    37 void ArrayBufferViewWatchpointAdaptor::add(
    38     CodeBlock* codeBlock, JSArrayBufferView* view, CommonData& common)
    39 {
    40     // view is already frozen. If it is deallocated, jettisoning happens.
    41     CodeBlockJettisoningWatchpoint* watchpoint = nullptr;
    42     {
    43         ConcurrentJSLocker locker(codeBlock->m_lock);
    44         watchpoint = common.watchpoints.add(codeBlock);
    45     }
    46     ArrayBuffer* arrayBuffer = view->possiblySharedBuffer();
    47     if (!arrayBuffer) {
    48         watchpoint->fire(codeBlock->vm(), StringFireDetail("ArrayBuffer could not be allocated, probably because of OOM."));
    49         return;
    50     }
    51 
    52     // FIXME: We don't need to set this watchpoint at all for shared buffers.
    53     // https://bugs.webkit.org/show_bug.cgi?id=164108
    54     arrayBuffer->detachingWatchpointSet().add(WTFMove(watchpoint));
    55 }
    56 
    57 void SymbolTableAdaptor::add(
    58     CodeBlock* codeBlock, SymbolTable* symbolTable, CommonData& common)
    59 {
    60     codeBlock->addConstant(ConcurrentJSLocker(codeBlock->m_lock), symbolTable); // For common users, it doesn't really matter if it's weak or not. If references to it go away, we go away, too.
    61     CodeBlockJettisoningWatchpoint* watchpoint = nullptr;
    62     {
    63         ConcurrentJSLocker locker(codeBlock->m_lock);
    64         watchpoint = common.watchpoints.add(codeBlock);
    65     }
    66     symbolTable->singleton().add(WTFMove(watchpoint));
    67 }
    68 
    69 void FunctionExecutableAdaptor::add(
    70     CodeBlock* codeBlock, FunctionExecutable* executable, CommonData& common)
    71 {
    72     codeBlock->addConstant(ConcurrentJSLocker(codeBlock->m_lock), executable); // For common users, it doesn't really matter if it's weak or not. If references to it go away, we go away, too.
    73     CodeBlockJettisoningWatchpoint* watchpoint = nullptr;
    74     {
    75         ConcurrentJSLocker locker(codeBlock->m_lock);
    76         watchpoint = common.watchpoints.add(codeBlock);
    77     }
    78     executable->singleton().add(WTFMove(watchpoint));
    79 }
    80 
    81 void AdaptiveStructureWatchpointAdaptor::add(
    82     CodeBlock* codeBlock, const ObjectPropertyCondition& key, CommonData& common)
     37void ArrayBufferViewWatchpointAdaptor::add(CodeBlock* codeBlock, JSArrayBufferView* view, WatchpointCollector& collector)
     38{
     39    collector.addWatchpoint([&](CodeBlockJettisoningWatchpoint& watchpoint) {
     40        // view is already frozen. If it is deallocated, jettisoning happens.
     41        {
     42            ConcurrentJSLocker locker(codeBlock->m_lock);
     43            watchpoint.initialize(codeBlock);
     44        }
     45        ArrayBuffer* arrayBuffer = view->possiblySharedBuffer();
     46        if (!arrayBuffer) {
     47            watchpoint.fire(codeBlock->vm(), StringFireDetail("ArrayBuffer could not be allocated, probably because of OOM."));
     48            return;
     49        }
     50
     51        // FIXME: We don't need to set this watchpoint at all for shared buffers.
     52        // https://bugs.webkit.org/show_bug.cgi?id=164108
     53        arrayBuffer->detachingWatchpointSet().add(&watchpoint);
     54    });
     55}
     56
     57void SymbolTableAdaptor::add(CodeBlock* codeBlock, SymbolTable* symbolTable, WatchpointCollector& collector)
     58{
     59    collector.addWatchpoint([&](CodeBlockJettisoningWatchpoint& watchpoint) {
     60        {
     61            ConcurrentJSLocker locker(codeBlock->m_lock);
     62            watchpoint.initialize(codeBlock);
     63        }
     64        codeBlock->addConstant(ConcurrentJSLocker(codeBlock->m_lock), symbolTable); // For common users, it doesn't really matter if it's weak or not. If references to it go away, we go away, too.
     65        symbolTable->singleton().add(&watchpoint);
     66    });
     67}
     68
     69void FunctionExecutableAdaptor::add(CodeBlock* codeBlock, FunctionExecutable* executable, WatchpointCollector& collector)
     70{
     71    collector.addWatchpoint([&](CodeBlockJettisoningWatchpoint& watchpoint) {
     72        {
     73            ConcurrentJSLocker locker(codeBlock->m_lock);
     74            watchpoint.initialize(codeBlock);
     75        }
     76        codeBlock->addConstant(ConcurrentJSLocker(codeBlock->m_lock), executable); // For common users, it doesn't really matter if it's weak or not. If references to it go away, we go away, too.
     77        executable->singleton().add(&watchpoint);
     78    });
     79}
     80
     81void AdaptiveStructureWatchpointAdaptor::add(CodeBlock* codeBlock, const ObjectPropertyCondition& key, WatchpointCollector& collector)
    8382{
    8483    VM& vm = codeBlock->vm();
    8584    switch (key.kind()) {
    8685    case PropertyCondition::Equivalence: {
    87         AdaptiveInferredPropertyValueWatchpoint* watchpoint = nullptr;
    88         {
    89             ConcurrentJSLocker locker(codeBlock->m_lock);
    90             watchpoint = common.adaptiveInferredPropertyValueWatchpoints.add(key, codeBlock);
    91         }
    92         watchpoint->install(vm);
     86        collector.addAdaptiveInferredPropertyValueWatchpoint([&](AdaptiveInferredPropertyValueWatchpoint& watchpoint) {
     87            {
     88                ConcurrentJSLocker locker(codeBlock->m_lock);
     89                watchpoint.initialize(key, codeBlock);
     90            }
     91            watchpoint.install(vm);
     92        });
    9393        break;
    9494    }
    9595    default: {
    96         AdaptiveStructureWatchpoint* watchpoint = nullptr;
    97         {
    98             ConcurrentJSLocker locker(codeBlock->m_lock);
    99             watchpoint = common.adaptiveStructureWatchpoints.add(key, codeBlock);
    100         }
    101         watchpoint->install(vm);
     96        collector.addAdaptiveStructureWatchpoint([&](AdaptiveStructureWatchpoint& watchpoint) {
     97            {
     98                ConcurrentJSLocker locker(codeBlock->m_lock);
     99                watchpoint.initialize(key, codeBlock);
     100            }
     101            watchpoint.install(vm);
     102        });
    102103        break;
    103104    }
     
    136137{
    137138    m_adaptiveStructureSets.addLazily(key);
     139}
     140
     141void DesiredWatchpoints::addLazily(DesiredGlobalProperty&& property)
     142{
     143    m_globalProperties.addLazily(WTFMove(property));
    138144}
    139145
     
    146152}
    147153
    148 void DesiredWatchpoints::reallyAdd(CodeBlock* codeBlock, CommonData& commonData)
    149 {
    150     m_sets.reallyAdd(codeBlock, commonData);
    151     m_inlineSets.reallyAdd(codeBlock, commonData);
    152     m_symbolTables.reallyAdd(codeBlock, commonData);
    153     m_functionExecutables.reallyAdd(codeBlock, commonData);
    154     m_bufferViews.reallyAdd(codeBlock, commonData);
    155     m_adaptiveStructureSets.reallyAdd(codeBlock, commonData);
     154void DesiredWatchpoints::reallyAdd(CodeBlock* codeBlock, DesiredIdentifiers& identifiers, CommonData* commonData)
     155{
     156    WatchpointCollector collector;
     157
     158    auto reallyAdd = [&]() {
     159        m_sets.reallyAdd(codeBlock, collector);
     160        m_inlineSets.reallyAdd(codeBlock, collector);
     161        m_symbolTables.reallyAdd(codeBlock, collector);
     162        m_functionExecutables.reallyAdd(codeBlock, collector);
     163        m_bufferViews.reallyAdd(codeBlock, collector);
     164        m_adaptiveStructureSets.reallyAdd(codeBlock, collector);
     165        m_globalProperties.reallyAdd(codeBlock, identifiers, collector);
     166    };
     167    reallyAdd();
     168    collector.materialize();
     169
     170    reallyAdd();
     171    collector.finalize(codeBlock, *commonData);
    156172}
    157173
     
    164180        && m_bufferViews.areStillValid()
    165181        && m_adaptiveStructureSets.areStillValid();
     182}
     183
     184bool DesiredWatchpoints::areStillValidOnMainThread(VM& vm, DesiredIdentifiers& identifiers)
     185{
     186    return m_globalProperties.isStillValidOnMainThread(vm, identifiers);
    166187}
    167188
     
    179200}
    180201
     202void WatchpointCollector::finalize(CodeBlock* codeBlock, CommonData& common)
     203{
     204    ConcurrentJSLocker locker(codeBlock->m_lock);
     205    common.m_watchpoints = WTFMove(m_watchpoints);
     206    common.m_adaptiveStructureWatchpoints = WTFMove(m_adaptiveStructureWatchpoints);
     207    common.m_adaptiveInferredPropertyValueWatchpoints = WTFMove(m_adaptiveInferredPropertyValueWatchpoints);
     208}
     209
    181210} } // namespace JSC::DFG
    182211
  • trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.h

    r254087 r276226  
    2929
    3030#include "DFGCommonData.h"
     31#include "DFGDesiredGlobalProperties.h"
    3132#include "FunctionExecutable.h"
    3233#include "JSArrayBufferView.h"
     
    4243struct Prefix;
    4344
     45enum class WatchpointRegistrationMode : uint8_t { Collect, Add };
     46class WatchpointCollector final {
     47    WTF_MAKE_NONCOPYABLE(WatchpointCollector);
     48public:
     49    void materialize()
     50    {
     51        m_watchpoints = FixedVector<CodeBlockJettisoningWatchpoint>(m_watchpointCount);
     52        m_adaptiveStructureWatchpoints = FixedVector<AdaptiveStructureWatchpoint>(m_adaptiveStructureWatchpointCount);
     53        m_adaptiveInferredPropertyValueWatchpoints = FixedVector<AdaptiveInferredPropertyValueWatchpoint>(m_adaptiveInferredPropertyValueWatchpointCount);
     54        m_mode = WatchpointRegistrationMode::Add;
     55    }
     56
     57    template<typename Func>
     58    void addWatchpoint(const Func& function)
     59    {
     60        if (m_mode == WatchpointRegistrationMode::Add)
     61            function(m_watchpoints[m_watchpointIndex++]);
     62        else
     63            ++m_watchpointCount;
     64    }
     65
     66    template<typename Func>
     67    void addAdaptiveStructureWatchpoint(const Func& function)
     68    {
     69        if (m_mode == WatchpointRegistrationMode::Add)
     70            function(m_adaptiveStructureWatchpoints[m_adaptiveStructureWatchpointsIndex++]);
     71        else
     72            ++m_adaptiveStructureWatchpointCount;
     73    }
     74
     75    template<typename Func>
     76    void addAdaptiveInferredPropertyValueWatchpoint(const Func& function)
     77    {
     78        if (m_mode == WatchpointRegistrationMode::Add)
     79            function(m_adaptiveInferredPropertyValueWatchpoints[m_adaptiveInferredPropertyValueWatchpointsIndex++]);
     80        else
     81            ++m_adaptiveInferredPropertyValueWatchpointCount;
     82    }
     83
     84    void finalize(CodeBlock*, CommonData&);
     85
     86    WatchpointRegistrationMode mode() const { return m_mode; }
     87
     88private:
     89    unsigned m_watchpointCount { 0 };
     90    unsigned m_adaptiveStructureWatchpointCount { 0 };
     91    unsigned m_adaptiveInferredPropertyValueWatchpointCount { 0 };
     92
     93    unsigned m_watchpointIndex { 0 };
     94    unsigned m_adaptiveStructureWatchpointsIndex { 0 };
     95    unsigned m_adaptiveInferredPropertyValueWatchpointsIndex { 0 };
     96
     97    FixedVector<CodeBlockJettisoningWatchpoint> m_watchpoints;
     98    FixedVector<AdaptiveStructureWatchpoint> m_adaptiveStructureWatchpoints;
     99    FixedVector<AdaptiveInferredPropertyValueWatchpoint> m_adaptiveInferredPropertyValueWatchpoints;
     100    WatchpointRegistrationMode m_mode { WatchpointRegistrationMode::Collect };
     101};
     102
    44103template<typename T>
    45104struct SetPointerAdaptor {
    46     static void add(CodeBlock* codeBlock, T set, CommonData& common)
    47     {
    48         CodeBlockJettisoningWatchpoint* watchpoint = nullptr;
    49         {
    50             ConcurrentJSLocker locker(codeBlock->m_lock);
    51             watchpoint = common.watchpoints.add(codeBlock);
    52         }
    53         return set->add(WTFMove(watchpoint));
     105    static void add(CodeBlock* codeBlock, T set, WatchpointCollector& collector)
     106    {
     107        collector.addWatchpoint([&](CodeBlockJettisoningWatchpoint& watchpoint) {
     108            {
     109                ConcurrentJSLocker locker(codeBlock->m_lock);
     110                watchpoint.initialize(codeBlock);
     111            }
     112            set->add(&watchpoint);
     113        });
    54114    }
    55115    static bool hasBeenInvalidated(T set)
     
    64124
    65125struct SymbolTableAdaptor {
    66     static void add(CodeBlock*, SymbolTable*, CommonData&);
     126    static void add(CodeBlock*, SymbolTable*, WatchpointCollector&);
    67127    static bool hasBeenInvalidated(SymbolTable* symbolTable)
    68128    {
     
    76136
    77137struct FunctionExecutableAdaptor {
    78     static void add(CodeBlock*, FunctionExecutable*, CommonData&);
     138    static void add(CodeBlock*, FunctionExecutable*, WatchpointCollector&);
    79139    static bool hasBeenInvalidated(FunctionExecutable* executable)
    80140    {
     
    88148
    89149struct ArrayBufferViewWatchpointAdaptor {
    90     static void add(CodeBlock*, JSArrayBufferView*, CommonData&);
     150    static void add(CodeBlock*, JSArrayBufferView*, WatchpointCollector&);
    91151    static bool hasBeenInvalidated(JSArrayBufferView* view)
    92152    {
     
    100160
    101161struct AdaptiveStructureWatchpointAdaptor {
    102     static void add(CodeBlock*, const ObjectPropertyCondition&, CommonData&);
     162    static void add(CodeBlock*, const ObjectPropertyCondition&, WatchpointCollector&);
    103163    static bool hasBeenInvalidated(const ObjectPropertyCondition& key)
    104164    {
     
    128188    }
    129189   
    130     void reallyAdd(CodeBlock* codeBlock, CommonData& common)
    131     {
    132         RELEASE_ASSERT(!m_reallyAdded);
     190    void reallyAdd(CodeBlock* codeBlock, WatchpointCollector& collector)
     191    {
     192        if (collector.mode() == WatchpointRegistrationMode::Add)
     193            RELEASE_ASSERT(!m_reallyAdded);
    133194       
    134195        for (auto& set : m_sets)
    135             Adaptor::add(codeBlock, set, common);
     196            Adaptor::add(codeBlock, set, collector);
    136197       
    137         m_reallyAdded = true;
     198        if (collector.mode() == WatchpointRegistrationMode::Add)
     199            m_reallyAdded = true;
    138200    }
    139201   
     
    181243    // the required GC magic as well as some other bookkeeping.
    182244    void addLazily(const ObjectPropertyCondition&);
     245
     246    void addLazily(DesiredGlobalProperty&&);
    183247   
    184248    bool consider(Structure*);
    185249   
    186     void reallyAdd(CodeBlock*, CommonData&);
     250    void reallyAdd(CodeBlock*, DesiredIdentifiers&, CommonData*);
    187251   
    188252    bool areStillValid() const;
     253    bool areStillValidOnMainThread(VM&, DesiredIdentifiers&);
    189254   
    190255    bool isWatched(WatchpointSet* set)
     
    221286    GenericDesiredWatchpoints<JSArrayBufferView*, ArrayBufferViewWatchpointAdaptor> m_bufferViews;
    222287    GenericDesiredWatchpoints<ObjectPropertyCondition, AdaptiveStructureWatchpointAdaptor> m_adaptiveStructureSets;
     288    DesiredGlobalProperties m_globalProperties;
    223289};
    224290
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp

    r275866 r276226  
    11051105            return false;
    11061106    }
    1107     globalProperties().addLazily(DesiredGlobalProperty(globalObject, identifierNumber));
     1107    watchpoints().addLazily(DesiredGlobalProperty(globalObject, identifierNumber));
    11081108    return true;
    11091109}
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.h

    r276005 r276226  
    836836    DesiredIdentifiers& identifiers() { return m_plan.identifiers(); }
    837837    DesiredWatchpoints& watchpoints() { return m_plan.watchpoints(); }
    838     DesiredGlobalProperties& globalProperties() { return m_plan.globalProperties(); }
    839838
    840839    // Returns false if the key is already invalid or unwatchable. If this is a Presence condition,
  • trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp

    r276005 r276226  
    572572{
    573573    ASSERT(m_vm->heap.isDeferred());
    574     m_watchpoints.reallyAdd(m_codeBlock, *commonData);
    575574    m_identifiers.reallyAdd(*m_vm, commonData);
    576575    m_weakReferences.reallyAdd(*m_vm, commonData);
    577576    m_transitions.reallyAdd(*m_vm, commonData);
    578     m_globalProperties.reallyAdd(m_codeBlock, m_identifiers, *commonData);
     577    m_watchpoints.reallyAdd(m_codeBlock, m_identifiers, commonData);
    579578    {
    580579        ConcurrentJSLocker locker(m_codeBlock->m_lock);
     
    596595bool Plan::isStillValidOnMainThread()
    597596{
    598     return m_globalProperties.isStillValidOnMainThread(*m_vm, m_identifiers);
     597    return m_watchpoints.areStillValidOnMainThread(*m_vm, m_identifiers);
    599598}
    600599
     
    758757    m_watchpoints = DesiredWatchpoints();
    759758    m_identifiers = DesiredIdentifiers();
    760     m_globalProperties = DesiredGlobalProperties();
    761759    m_weakReferences = DesiredWeakReferences();
    762760    m_transitions = DesiredTransitions();
  • trunk/Source/JavaScriptCore/dfg/DFGPlan.h

    r275542 r276226  
    101101    DesiredWeakReferences& weakReferences() { return m_weakReferences; }
    102102    DesiredTransitions& transitions() { return m_transitions; }
    103     DesiredGlobalProperties& globalProperties() { return m_globalProperties; }
    104103    RecordedStatuses& recordedStatuses() { return m_recordedStatuses; }
    105104
     
    157156    DesiredWeakReferences m_weakReferences;
    158157    DesiredTransitions m_transitions;
    159     DesiredGlobalProperties m_globalProperties;
    160158    RecordedStatuses m_recordedStatuses;
    161159
Note: See TracChangeset for help on using the changeset viewer.