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;