Title: [276226] trunk/Source/_javascript_Core
Revision
276226
Author
[email protected]
Date
2021-04-18 01:06:48 -0700 (Sun, 18 Apr 2021)

Log 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.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (276225 => 276226)


--- trunk/Source/_javascript_Core/ChangeLog	2021-04-18 07:43:33 UTC (rev 276225)
+++ trunk/Source/_javascript_Core/ChangeLog	2021-04-18 08:06:48 UTC (rev 276226)
@@ -1,5 +1,69 @@
 2021-04-18  Yusuke Suzuki  <[email protected]>
 
+        [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.
+
+2021-04-18  Yusuke Suzuki  <[email protected]>
+
         [JSC] Make more DFG/FTL data FixedVector/Vector
         https://bugs.webkit.org/show_bug.cgi?id=224713
 

Modified: trunk/Source/_javascript_Core/bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp (276225 => 276226)


--- trunk/Source/_javascript_Core/bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp	2021-04-18 07:43:33 UTC (rev 276225)
+++ trunk/Source/_javascript_Core/bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp	2021-04-18 08:06:48 UTC (rev 276226)
@@ -36,6 +36,12 @@
     RELEASE_ASSERT(key.kind() == PropertyCondition::Equivalence);
 }
 
+void AdaptiveInferredPropertyValueWatchpointBase::initialize(const ObjectPropertyCondition& key)
+{
+    m_key = key;
+    RELEASE_ASSERT(key.kind() == PropertyCondition::Equivalence);
+}
+
 void AdaptiveInferredPropertyValueWatchpointBase::install(VM& vm)
 {
     RELEASE_ASSERT(m_key.isWatchable());

Modified: trunk/Source/_javascript_Core/bytecode/AdaptiveInferredPropertyValueWatchpointBase.h (276225 => 276226)


--- trunk/Source/_javascript_Core/bytecode/AdaptiveInferredPropertyValueWatchpointBase.h	2021-04-18 07:43:33 UTC (rev 276225)
+++ trunk/Source/_javascript_Core/bytecode/AdaptiveInferredPropertyValueWatchpointBase.h	2021-04-18 08:06:48 UTC (rev 276226)
@@ -40,9 +40,11 @@
 
 public:
     AdaptiveInferredPropertyValueWatchpointBase(const ObjectPropertyCondition&);
+    AdaptiveInferredPropertyValueWatchpointBase() = default;
 
     const ObjectPropertyCondition& key() const { return m_key; }
 
+    void initialize(const ObjectPropertyCondition&);
     void install(VM&);
 
     virtual ~AdaptiveInferredPropertyValueWatchpointBase() = default;

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlockJettisoningWatchpoint.h (276225 => 276226)


--- trunk/Source/_javascript_Core/bytecode/CodeBlockJettisoningWatchpoint.h	2021-04-18 07:43:33 UTC (rev 276225)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlockJettisoningWatchpoint.h	2021-04-18 08:06:48 UTC (rev 276226)
@@ -33,11 +33,16 @@
 
 class CodeBlockJettisoningWatchpoint final : public Watchpoint {
 public:
-    CodeBlockJettisoningWatchpoint(CodeBlock* codeBlock)
+    CodeBlockJettisoningWatchpoint(CodeBlock* codeBlock = nullptr)
         : Watchpoint(Watchpoint::Type::CodeBlockJettisoning)
         , m_codeBlock(codeBlock)
     {
     }
+
+    void initialize(CodeBlock* codeBlock)
+    {
+        m_codeBlock = codeBlock;
+    }
     
     void fireInternal(VM&, const FireDetail&);
 

Modified: trunk/Source/_javascript_Core/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.cpp (276225 => 276226)


--- trunk/Source/_javascript_Core/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.cpp	2021-04-18 07:43:33 UTC (rev 276225)
+++ trunk/Source/_javascript_Core/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.cpp	2021-04-18 08:06:48 UTC (rev 276226)
@@ -39,6 +39,12 @@
 {
 }
 
+void AdaptiveInferredPropertyValueWatchpoint::initialize(const ObjectPropertyCondition& key, CodeBlock* codeBlock)
+{
+    Base::initialize(key);
+    m_codeBlock = codeBlock;
+}
+
 void AdaptiveInferredPropertyValueWatchpoint::handleFire(VM&, const FireDetail& detail)
 {
     if (DFG::shouldDumpDisassembly())

Modified: trunk/Source/_javascript_Core/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h (276225 => 276226)


--- trunk/Source/_javascript_Core/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h	2021-04-18 07:43:33 UTC (rev 276225)
+++ trunk/Source/_javascript_Core/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h	2021-04-18 08:06:48 UTC (rev 276226)
@@ -35,13 +35,16 @@
 public:
     typedef AdaptiveInferredPropertyValueWatchpointBase Base;
     AdaptiveInferredPropertyValueWatchpoint(const ObjectPropertyCondition&, CodeBlock*);
+    AdaptiveInferredPropertyValueWatchpoint() = default;
 
+    void initialize(const ObjectPropertyCondition&, CodeBlock*);
+
 private:
     bool isValid() const final;
 
     void handleFire(VM&, const FireDetail&) final;
 
-    CodeBlock* m_codeBlock;
+    CodeBlock* m_codeBlock { nullptr };
 };
 
 } } // namespace JSC::DFG

Modified: trunk/Source/_javascript_Core/dfg/DFGAdaptiveStructureWatchpoint.cpp (276225 => 276226)


--- trunk/Source/_javascript_Core/dfg/DFGAdaptiveStructureWatchpoint.cpp	2021-04-18 07:43:33 UTC (rev 276225)
+++ trunk/Source/_javascript_Core/dfg/DFGAdaptiveStructureWatchpoint.cpp	2021-04-18 08:06:48 UTC (rev 276226)
@@ -42,6 +42,20 @@
     RELEASE_ASSERT(!key.watchingRequiresReplacementWatchpoint());
 }
 
+AdaptiveStructureWatchpoint::AdaptiveStructureWatchpoint()
+    : Watchpoint(Watchpoint::Type::AdaptiveStructure)
+    , m_codeBlock(nullptr)
+{
+}
+
+void AdaptiveStructureWatchpoint::initialize(const ObjectPropertyCondition& key, CodeBlock* codeBlock)
+{
+    m_codeBlock = codeBlock;
+    m_key = key;
+    RELEASE_ASSERT(key.watchingRequiresStructureTransitionWatchpoint());
+    RELEASE_ASSERT(!key.watchingRequiresReplacementWatchpoint());
+}
+
 void AdaptiveStructureWatchpoint::install(VM& vm)
 {
     RELEASE_ASSERT(m_key.isWatchable());

Modified: trunk/Source/_javascript_Core/dfg/DFGAdaptiveStructureWatchpoint.h (276225 => 276226)


--- trunk/Source/_javascript_Core/dfg/DFGAdaptiveStructureWatchpoint.h	2021-04-18 07:43:33 UTC (rev 276225)
+++ trunk/Source/_javascript_Core/dfg/DFGAdaptiveStructureWatchpoint.h	2021-04-18 08:06:48 UTC (rev 276226)
@@ -37,9 +37,12 @@
 class AdaptiveStructureWatchpoint final : public Watchpoint {
 public:
     AdaptiveStructureWatchpoint(const ObjectPropertyCondition&, CodeBlock*);
+    AdaptiveStructureWatchpoint();
     
     const ObjectPropertyCondition& key() const { return m_key; }
-    
+
+    void initialize(const ObjectPropertyCondition&, CodeBlock*);
+
     void install(VM&);
 
     void fireInternal(VM&, const FireDetail&);

Modified: trunk/Source/_javascript_Core/dfg/DFGCommonData.cpp (276225 => 276226)


--- trunk/Source/_javascript_Core/dfg/DFGCommonData.cpp	2021-04-18 07:43:33 UTC (rev 276225)
+++ trunk/Source/_javascript_Core/dfg/DFGCommonData.cpp	2021-04-18 08:06:48 UTC (rev 276226)
@@ -148,8 +148,8 @@
         }
     }
     
-    for (AdaptiveStructureWatchpoint* watchpoint : adaptiveStructureWatchpoints)
-        watchpoint->key().validateReferences(trackedReferences);
+    for (auto& watchpoint : m_adaptiveStructureWatchpoints)
+        watchpoint.key().validateReferences(trackedReferences);
 }
 
 void CommonData::finalizeCatchEntrypoints(Vector<CatchEntrypointData>&& catchEntrypoints)
@@ -167,9 +167,9 @@
 
 void CommonData::clearWatchpoints()
 {
-    watchpoints.clear();
-    adaptiveStructureWatchpoints.clear();
-    adaptiveInferredPropertyValueWatchpoints.clear();
+    m_watchpoints = FixedVector<CodeBlockJettisoningWatchpoint>();
+    m_adaptiveStructureWatchpoints = FixedVector<AdaptiveStructureWatchpoint>();
+    m_adaptiveInferredPropertyValueWatchpoints = FixedVector<AdaptiveInferredPropertyValueWatchpoint>();
 }
 
 } } // namespace JSC::DFG

Modified: trunk/Source/_javascript_Core/dfg/DFGCommonData.h (276225 => 276226)


--- trunk/Source/_javascript_Core/dfg/DFGCommonData.h	2021-04-18 07:43:33 UTC (rev 276225)
+++ trunk/Source/_javascript_Core/dfg/DFGCommonData.h	2021-04-18 08:06:48 UTC (rev 276226)
@@ -113,9 +113,9 @@
     FixedVector<WriteBarrier<JSCell>> m_weakReferences;
     FixedVector<StructureID> m_weakStructureReferences;
     FixedVector<CatchEntrypointData> m_catchEntrypoints;
-    Bag<CodeBlockJettisoningWatchpoint> watchpoints;
-    Bag<AdaptiveStructureWatchpoint> adaptiveStructureWatchpoints;
-    Bag<AdaptiveInferredPropertyValueWatchpoint> adaptiveInferredPropertyValueWatchpoints;
+    FixedVector<CodeBlockJettisoningWatchpoint> m_watchpoints;
+    FixedVector<AdaptiveStructureWatchpoint> m_adaptiveStructureWatchpoints;
+    FixedVector<AdaptiveInferredPropertyValueWatchpoint> m_adaptiveInferredPropertyValueWatchpoints;
     RecordedStatuses recordedStatuses;
     Vector<JumpReplacement> m_jumpReplacements;
     

Modified: trunk/Source/_javascript_Core/dfg/DFGDesiredGlobalProperties.cpp (276225 => 276226)


--- trunk/Source/_javascript_Core/dfg/DFGDesiredGlobalProperties.cpp	2021-04-18 07:43:33 UTC (rev 276225)
+++ trunk/Source/_javascript_Core/dfg/DFGDesiredGlobalProperties.cpp	2021-04-18 08:06:48 UTC (rev 276226)
@@ -54,18 +54,19 @@
     return isStillValid;
 }
 
-void DesiredGlobalProperties::reallyAdd(CodeBlock* codeBlock, DesiredIdentifiers& identifiers, CommonData& common)
+void DesiredGlobalProperties::reallyAdd(CodeBlock* codeBlock, DesiredIdentifiers& identifiers, WatchpointCollector& collector)
 {
     for (const auto& property : m_set) {
-        auto* uid = identifiers.at(property.identifierNumber());
-        auto& watchpointSet = property.globalObject()->ensureReferencedPropertyWatchpointSet(uid);
-        ASSERT(watchpointSet.isStillValid());
-        CodeBlockJettisoningWatchpoint* watchpoint = nullptr;
-        {
-            ConcurrentJSLocker locker(codeBlock->m_lock);
-            watchpoint = common.watchpoints.add(codeBlock);
-        }
-        watchpointSet.add(WTFMove(watchpoint));
+        collector.addWatchpoint([&](CodeBlockJettisoningWatchpoint& watchpoint) {
+            {
+                ConcurrentJSLocker locker(codeBlock->m_lock);
+                watchpoint.initialize(codeBlock);
+            }
+            auto* uid = identifiers.at(property.identifierNumber());
+            auto& watchpointSet = property.globalObject()->ensureReferencedPropertyWatchpointSet(uid);
+            ASSERT(watchpointSet.isStillValid());
+            watchpointSet.add(&watchpoint);
+        });
     }
 }
 

Modified: trunk/Source/_javascript_Core/dfg/DFGDesiredGlobalProperties.h (276225 => 276226)


--- trunk/Source/_javascript_Core/dfg/DFGDesiredGlobalProperties.h	2021-04-18 07:43:33 UTC (rev 276225)
+++ trunk/Source/_javascript_Core/dfg/DFGDesiredGlobalProperties.h	2021-04-18 08:06:48 UTC (rev 276226)
@@ -39,6 +39,7 @@
 
 class CommonData;
 class DesiredIdentifiers;
+class WatchpointCollector;
 
 class DesiredGlobalProperties {
 public:
@@ -49,7 +50,7 @@
 
     bool isStillValidOnMainThread(VM&, DesiredIdentifiers&);
 
-    void reallyAdd(CodeBlock*, DesiredIdentifiers&, CommonData&);
+    void reallyAdd(CodeBlock*, DesiredIdentifiers&, WatchpointCollector&);
 
 private:
     HashSet<DesiredGlobalProperty> m_set;

Modified: trunk/Source/_javascript_Core/dfg/DFGDesiredWatchpoints.cpp (276225 => 276226)


--- trunk/Source/_javascript_Core/dfg/DFGDesiredWatchpoints.cpp	2021-04-18 07:43:33 UTC (rev 276225)
+++ trunk/Source/_javascript_Core/dfg/DFGDesiredWatchpoints.cpp	2021-04-18 08:06:48 UTC (rev 276226)
@@ -34,71 +34,72 @@
 
 namespace JSC { namespace DFG {
 
-void ArrayBufferViewWatchpointAdaptor::add(
-    CodeBlock* codeBlock, JSArrayBufferView* view, CommonData& common)
+void ArrayBufferViewWatchpointAdaptor::add(CodeBlock* codeBlock, JSArrayBufferView* view, WatchpointCollector& collector)
 {
-    // view is already frozen. If it is deallocated, jettisoning happens.
-    CodeBlockJettisoningWatchpoint* watchpoint = nullptr;
-    {
-        ConcurrentJSLocker locker(codeBlock->m_lock);
-        watchpoint = common.watchpoints.add(codeBlock);
-    }
-    ArrayBuffer* arrayBuffer = view->possiblySharedBuffer();
-    if (!arrayBuffer) {
-        watchpoint->fire(codeBlock->vm(), StringFireDetail("ArrayBuffer could not be allocated, probably because of OOM."));
-        return;
-    }
+    collector.addWatchpoint([&](CodeBlockJettisoningWatchpoint& watchpoint) {
+        // view is already frozen. If it is deallocated, jettisoning happens.
+        {
+            ConcurrentJSLocker locker(codeBlock->m_lock);
+            watchpoint.initialize(codeBlock);
+        }
+        ArrayBuffer* arrayBuffer = view->possiblySharedBuffer();
+        if (!arrayBuffer) {
+            watchpoint.fire(codeBlock->vm(), StringFireDetail("ArrayBuffer could not be allocated, probably because of OOM."));
+            return;
+        }
 
-    // FIXME: We don't need to set this watchpoint at all for shared buffers.
-    // https://bugs.webkit.org/show_bug.cgi?id=164108
-    arrayBuffer->detachingWatchpointSet().add(WTFMove(watchpoint));
+        // FIXME: We don't need to set this watchpoint at all for shared buffers.
+        // https://bugs.webkit.org/show_bug.cgi?id=164108
+        arrayBuffer->detachingWatchpointSet().add(&watchpoint);
+    });
 }
 
-void SymbolTableAdaptor::add(
-    CodeBlock* codeBlock, SymbolTable* symbolTable, CommonData& common)
+void SymbolTableAdaptor::add(CodeBlock* codeBlock, SymbolTable* symbolTable, WatchpointCollector& collector)
 {
-    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.
-    CodeBlockJettisoningWatchpoint* watchpoint = nullptr;
-    {
-        ConcurrentJSLocker locker(codeBlock->m_lock);
-        watchpoint = common.watchpoints.add(codeBlock);
-    }
-    symbolTable->singleton().add(WTFMove(watchpoint));
+    collector.addWatchpoint([&](CodeBlockJettisoningWatchpoint& watchpoint) {
+        {
+            ConcurrentJSLocker locker(codeBlock->m_lock);
+            watchpoint.initialize(codeBlock);
+        }
+        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.
+        symbolTable->singleton().add(&watchpoint);
+    });
 }
 
-void FunctionExecutableAdaptor::add(
-    CodeBlock* codeBlock, FunctionExecutable* executable, CommonData& common)
+void FunctionExecutableAdaptor::add(CodeBlock* codeBlock, FunctionExecutable* executable, WatchpointCollector& collector)
 {
-    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.
-    CodeBlockJettisoningWatchpoint* watchpoint = nullptr;
-    {
-        ConcurrentJSLocker locker(codeBlock->m_lock);
-        watchpoint = common.watchpoints.add(codeBlock);
-    }
-    executable->singleton().add(WTFMove(watchpoint));
+    collector.addWatchpoint([&](CodeBlockJettisoningWatchpoint& watchpoint) {
+        {
+            ConcurrentJSLocker locker(codeBlock->m_lock);
+            watchpoint.initialize(codeBlock);
+        }
+        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.
+        executable->singleton().add(&watchpoint);
+    });
 }
 
-void AdaptiveStructureWatchpointAdaptor::add(
-    CodeBlock* codeBlock, const ObjectPropertyCondition& key, CommonData& common)
+void AdaptiveStructureWatchpointAdaptor::add(CodeBlock* codeBlock, const ObjectPropertyCondition& key, WatchpointCollector& collector)
 {
     VM& vm = codeBlock->vm();
     switch (key.kind()) {
     case PropertyCondition::Equivalence: {
-        AdaptiveInferredPropertyValueWatchpoint* watchpoint = nullptr;
-        {
-            ConcurrentJSLocker locker(codeBlock->m_lock);
-            watchpoint = common.adaptiveInferredPropertyValueWatchpoints.add(key, codeBlock);
-        }
-        watchpoint->install(vm);
+        collector.addAdaptiveInferredPropertyValueWatchpoint([&](AdaptiveInferredPropertyValueWatchpoint& watchpoint) {
+            {
+                ConcurrentJSLocker locker(codeBlock->m_lock);
+                watchpoint.initialize(key, codeBlock);
+            }
+            watchpoint.install(vm);
+        });
         break;
     }
     default: {
-        AdaptiveStructureWatchpoint* watchpoint = nullptr;
-        {
-            ConcurrentJSLocker locker(codeBlock->m_lock);
-            watchpoint = common.adaptiveStructureWatchpoints.add(key, codeBlock);
-        }
-        watchpoint->install(vm);
+        collector.addAdaptiveStructureWatchpoint([&](AdaptiveStructureWatchpoint& watchpoint) {
+            {
+                ConcurrentJSLocker locker(codeBlock->m_lock);
+                watchpoint.initialize(key, codeBlock);
+            }
+            watchpoint.install(vm);
+        });
         break;
     }
     }
@@ -137,6 +138,11 @@
     m_adaptiveStructureSets.addLazily(key);
 }
 
+void DesiredWatchpoints::addLazily(DesiredGlobalProperty&& property)
+{
+    m_globalProperties.addLazily(WTFMove(property));
+}
+
 bool DesiredWatchpoints::consider(Structure* structure)
 {
     if (!structure->dfgShouldWatch())
@@ -145,14 +151,24 @@
     return true;
 }
 
-void DesiredWatchpoints::reallyAdd(CodeBlock* codeBlock, CommonData& commonData)
+void DesiredWatchpoints::reallyAdd(CodeBlock* codeBlock, DesiredIdentifiers& identifiers, CommonData* commonData)
 {
-    m_sets.reallyAdd(codeBlock, commonData);
-    m_inlineSets.reallyAdd(codeBlock, commonData);
-    m_symbolTables.reallyAdd(codeBlock, commonData);
-    m_functionExecutables.reallyAdd(codeBlock, commonData);
-    m_bufferViews.reallyAdd(codeBlock, commonData);
-    m_adaptiveStructureSets.reallyAdd(codeBlock, commonData);
+    WatchpointCollector collector;
+
+    auto reallyAdd = [&]() {
+        m_sets.reallyAdd(codeBlock, collector);
+        m_inlineSets.reallyAdd(codeBlock, collector);
+        m_symbolTables.reallyAdd(codeBlock, collector);
+        m_functionExecutables.reallyAdd(codeBlock, collector);
+        m_bufferViews.reallyAdd(codeBlock, collector);
+        m_adaptiveStructureSets.reallyAdd(codeBlock, collector);
+        m_globalProperties.reallyAdd(codeBlock, identifiers, collector);
+    };
+    reallyAdd();
+    collector.materialize();
+
+    reallyAdd();
+    collector.finalize(codeBlock, *commonData);
 }
 
 bool DesiredWatchpoints::areStillValid() const
@@ -165,6 +181,11 @@
         && m_adaptiveStructureSets.areStillValid();
 }
 
+bool DesiredWatchpoints::areStillValidOnMainThread(VM& vm, DesiredIdentifiers& identifiers)
+{
+    return m_globalProperties.isStillValidOnMainThread(vm, identifiers);
+}
+
 void DesiredWatchpoints::dumpInContext(PrintStream& out, DumpContext* context) const
 {
     Prefix noPrefix(Prefix::NoHeader);
@@ -178,6 +199,14 @@
     out.print(prefix, "    Object property conditions: ", inContext(m_adaptiveStructureSets, context), "\n");
 }
 
+void WatchpointCollector::finalize(CodeBlock* codeBlock, CommonData& common)
+{
+    ConcurrentJSLocker locker(codeBlock->m_lock);
+    common.m_watchpoints = WTFMove(m_watchpoints);
+    common.m_adaptiveStructureWatchpoints = WTFMove(m_adaptiveStructureWatchpoints);
+    common.m_adaptiveInferredPropertyValueWatchpoints = WTFMove(m_adaptiveInferredPropertyValueWatchpoints);
+}
+
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)

Modified: trunk/Source/_javascript_Core/dfg/DFGDesiredWatchpoints.h (276225 => 276226)


--- trunk/Source/_javascript_Core/dfg/DFGDesiredWatchpoints.h	2021-04-18 07:43:33 UTC (rev 276225)
+++ trunk/Source/_javascript_Core/dfg/DFGDesiredWatchpoints.h	2021-04-18 08:06:48 UTC (rev 276226)
@@ -28,6 +28,7 @@
 #if ENABLE(DFG_JIT)
 
 #include "DFGCommonData.h"
+#include "DFGDesiredGlobalProperties.h"
 #include "FunctionExecutable.h"
 #include "JSArrayBufferView.h"
 #include "ObjectPropertyCondition.h"
@@ -41,16 +42,75 @@
 class Graph;
 struct Prefix;
 
+enum class WatchpointRegistrationMode : uint8_t { Collect, Add };
+class WatchpointCollector final {
+    WTF_MAKE_NONCOPYABLE(WatchpointCollector);
+public:
+    void materialize()
+    {
+        m_watchpoints = FixedVector<CodeBlockJettisoningWatchpoint>(m_watchpointCount);
+        m_adaptiveStructureWatchpoints = FixedVector<AdaptiveStructureWatchpoint>(m_adaptiveStructureWatchpointCount);
+        m_adaptiveInferredPropertyValueWatchpoints = FixedVector<AdaptiveInferredPropertyValueWatchpoint>(m_adaptiveInferredPropertyValueWatchpointCount);
+        m_mode = WatchpointRegistrationMode::Add;
+    }
+
+    template<typename Func>
+    void addWatchpoint(const Func& function)
+    {
+        if (m_mode == WatchpointRegistrationMode::Add)
+            function(m_watchpoints[m_watchpointIndex++]);
+        else
+            ++m_watchpointCount;
+    }
+
+    template<typename Func>
+    void addAdaptiveStructureWatchpoint(const Func& function)
+    {
+        if (m_mode == WatchpointRegistrationMode::Add)
+            function(m_adaptiveStructureWatchpoints[m_adaptiveStructureWatchpointsIndex++]);
+        else
+            ++m_adaptiveStructureWatchpointCount;
+    }
+
+    template<typename Func>
+    void addAdaptiveInferredPropertyValueWatchpoint(const Func& function)
+    {
+        if (m_mode == WatchpointRegistrationMode::Add)
+            function(m_adaptiveInferredPropertyValueWatchpoints[m_adaptiveInferredPropertyValueWatchpointsIndex++]);
+        else
+            ++m_adaptiveInferredPropertyValueWatchpointCount;
+    }
+
+    void finalize(CodeBlock*, CommonData&);
+
+    WatchpointRegistrationMode mode() const { return m_mode; }
+
+private:
+    unsigned m_watchpointCount { 0 };
+    unsigned m_adaptiveStructureWatchpointCount { 0 };
+    unsigned m_adaptiveInferredPropertyValueWatchpointCount { 0 };
+
+    unsigned m_watchpointIndex { 0 };
+    unsigned m_adaptiveStructureWatchpointsIndex { 0 };
+    unsigned m_adaptiveInferredPropertyValueWatchpointsIndex { 0 };
+
+    FixedVector<CodeBlockJettisoningWatchpoint> m_watchpoints;
+    FixedVector<AdaptiveStructureWatchpoint> m_adaptiveStructureWatchpoints;
+    FixedVector<AdaptiveInferredPropertyValueWatchpoint> m_adaptiveInferredPropertyValueWatchpoints;
+    WatchpointRegistrationMode m_mode { WatchpointRegistrationMode::Collect };
+};
+
 template<typename T>
 struct SetPointerAdaptor {
-    static void add(CodeBlock* codeBlock, T set, CommonData& common)
+    static void add(CodeBlock* codeBlock, T set, WatchpointCollector& collector)
     {
-        CodeBlockJettisoningWatchpoint* watchpoint = nullptr;
-        {
-            ConcurrentJSLocker locker(codeBlock->m_lock);
-            watchpoint = common.watchpoints.add(codeBlock);
-        }
-        return set->add(WTFMove(watchpoint));
+        collector.addWatchpoint([&](CodeBlockJettisoningWatchpoint& watchpoint) {
+            {
+                ConcurrentJSLocker locker(codeBlock->m_lock);
+                watchpoint.initialize(codeBlock);
+            }
+            set->add(&watchpoint);
+        });
     }
     static bool hasBeenInvalidated(T set)
     {
@@ -63,7 +123,7 @@
 };
 
 struct SymbolTableAdaptor {
-    static void add(CodeBlock*, SymbolTable*, CommonData&);
+    static void add(CodeBlock*, SymbolTable*, WatchpointCollector&);
     static bool hasBeenInvalidated(SymbolTable* symbolTable)
     {
         return symbolTable->singleton().hasBeenInvalidated();
@@ -75,7 +135,7 @@
 };
 
 struct FunctionExecutableAdaptor {
-    static void add(CodeBlock*, FunctionExecutable*, CommonData&);
+    static void add(CodeBlock*, FunctionExecutable*, WatchpointCollector&);
     static bool hasBeenInvalidated(FunctionExecutable* executable)
     {
         return executable->singleton().hasBeenInvalidated();
@@ -87,7 +147,7 @@
 };
 
 struct ArrayBufferViewWatchpointAdaptor {
-    static void add(CodeBlock*, JSArrayBufferView*, CommonData&);
+    static void add(CodeBlock*, JSArrayBufferView*, WatchpointCollector&);
     static bool hasBeenInvalidated(JSArrayBufferView* view)
     {
         return !view->length();
@@ -99,7 +159,7 @@
 };
 
 struct AdaptiveStructureWatchpointAdaptor {
-    static void add(CodeBlock*, const ObjectPropertyCondition&, CommonData&);
+    static void add(CodeBlock*, const ObjectPropertyCondition&, WatchpointCollector&);
     static bool hasBeenInvalidated(const ObjectPropertyCondition& key)
     {
         return !key.isWatchable();
@@ -127,14 +187,16 @@
         m_sets.add(set);
     }
     
-    void reallyAdd(CodeBlock* codeBlock, CommonData& common)
+    void reallyAdd(CodeBlock* codeBlock, WatchpointCollector& collector)
     {
-        RELEASE_ASSERT(!m_reallyAdded);
+        if (collector.mode() == WatchpointRegistrationMode::Add)
+            RELEASE_ASSERT(!m_reallyAdded);
         
         for (auto& set : m_sets)
-            Adaptor::add(codeBlock, set, common);
+            Adaptor::add(codeBlock, set, collector);
         
-        m_reallyAdded = true;
+        if (collector.mode() == WatchpointRegistrationMode::Add)
+            m_reallyAdded = true;
     }
     
     bool areStillValid() const
@@ -180,12 +242,15 @@
     // It's recommended that you don't call this directly. Use Graph::watchCondition(), which does
     // the required GC magic as well as some other bookkeeping.
     void addLazily(const ObjectPropertyCondition&);
+
+    void addLazily(DesiredGlobalProperty&&);
     
     bool consider(Structure*);
     
-    void reallyAdd(CodeBlock*, CommonData&);
+    void reallyAdd(CodeBlock*, DesiredIdentifiers&, CommonData*);
     
     bool areStillValid() const;
+    bool areStillValidOnMainThread(VM&, DesiredIdentifiers&);
     
     bool isWatched(WatchpointSet* set)
     {
@@ -220,6 +285,7 @@
     GenericDesiredWatchpoints<FunctionExecutable*, FunctionExecutableAdaptor> m_functionExecutables;
     GenericDesiredWatchpoints<JSArrayBufferView*, ArrayBufferViewWatchpointAdaptor> m_bufferViews;
     GenericDesiredWatchpoints<ObjectPropertyCondition, AdaptiveStructureWatchpointAdaptor> m_adaptiveStructureSets;
+    DesiredGlobalProperties m_globalProperties;
 };
 
 } } // namespace JSC::DFG

Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.cpp (276225 => 276226)


--- trunk/Source/_javascript_Core/dfg/DFGGraph.cpp	2021-04-18 07:43:33 UTC (rev 276225)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.cpp	2021-04-18 08:06:48 UTC (rev 276226)
@@ -1104,7 +1104,7 @@
         if (!watchpoint->isStillValid())
             return false;
     }
-    globalProperties().addLazily(DesiredGlobalProperty(globalObject, identifierNumber));
+    watchpoints().addLazily(DesiredGlobalProperty(globalObject, identifierNumber));
     return true;
 }
 

Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.h (276225 => 276226)


--- trunk/Source/_javascript_Core/dfg/DFGGraph.h	2021-04-18 07:43:33 UTC (rev 276225)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.h	2021-04-18 08:06:48 UTC (rev 276226)
@@ -835,7 +835,6 @@
 
     DesiredIdentifiers& identifiers() { return m_plan.identifiers(); }
     DesiredWatchpoints& watchpoints() { return m_plan.watchpoints(); }
-    DesiredGlobalProperties& globalProperties() { return m_plan.globalProperties(); }
 
     // Returns false if the key is already invalid or unwatchable. If this is a Presence condition,
     // this also makes it cheap to query if the condition holds. Also makes sure that the GC knows

Modified: trunk/Source/_javascript_Core/dfg/DFGPlan.cpp (276225 => 276226)


--- trunk/Source/_javascript_Core/dfg/DFGPlan.cpp	2021-04-18 07:43:33 UTC (rev 276225)
+++ trunk/Source/_javascript_Core/dfg/DFGPlan.cpp	2021-04-18 08:06:48 UTC (rev 276226)
@@ -571,11 +571,10 @@
 void Plan::reallyAdd(CommonData* commonData)
 {
     ASSERT(m_vm->heap.isDeferred());
-    m_watchpoints.reallyAdd(m_codeBlock, *commonData);
     m_identifiers.reallyAdd(*m_vm, commonData);
     m_weakReferences.reallyAdd(*m_vm, commonData);
     m_transitions.reallyAdd(*m_vm, commonData);
-    m_globalProperties.reallyAdd(m_codeBlock, m_identifiers, *commonData);
+    m_watchpoints.reallyAdd(m_codeBlock, m_identifiers, commonData);
     {
         ConcurrentJSLocker locker(m_codeBlock->m_lock);
         commonData->recordedStatuses = WTFMove(m_recordedStatuses);
@@ -595,7 +594,7 @@
 
 bool Plan::isStillValidOnMainThread()
 {
-    return m_globalProperties.isStillValidOnMainThread(*m_vm, m_identifiers);
+    return m_watchpoints.areStillValidOnMainThread(*m_vm, m_identifiers);
 }
 
 CompilationResult Plan::finalizeWithoutNotifyingCallback()
@@ -757,7 +756,6 @@
     m_inlineCallFrames = nullptr;
     m_watchpoints = DesiredWatchpoints();
     m_identifiers = DesiredIdentifiers();
-    m_globalProperties = DesiredGlobalProperties();
     m_weakReferences = DesiredWeakReferences();
     m_transitions = DesiredTransitions();
     m_callback = nullptr;

Modified: trunk/Source/_javascript_Core/dfg/DFGPlan.h (276225 => 276226)


--- trunk/Source/_javascript_Core/dfg/DFGPlan.h	2021-04-18 07:43:33 UTC (rev 276225)
+++ trunk/Source/_javascript_Core/dfg/DFGPlan.h	2021-04-18 08:06:48 UTC (rev 276226)
@@ -100,7 +100,6 @@
     DesiredIdentifiers& identifiers() { return m_identifiers; }
     DesiredWeakReferences& weakReferences() { return m_weakReferences; }
     DesiredTransitions& transitions() { return m_transitions; }
-    DesiredGlobalProperties& globalProperties() { return m_globalProperties; }
     RecordedStatuses& recordedStatuses() { return m_recordedStatuses; }
 
     bool willTryToTierUp() const { return m_willTryToTierUp; }
@@ -156,7 +155,6 @@
     DesiredIdentifiers m_identifiers;
     DesiredWeakReferences m_weakReferences;
     DesiredTransitions m_transitions;
-    DesiredGlobalProperties m_globalProperties;
     RecordedStatuses m_recordedStatuses;
 
     HashMap<BytecodeIndex, FixedVector<BytecodeIndex>> m_tierUpInLoopHierarchy;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to