Title: [292493] trunk/Source/_javascript_Core
Revision
292493
Author
sbar...@apple.com
Date
2022-04-06 12:35:37 -0700 (Wed, 06 Apr 2022)

Log Message

Call Structure::get instead of Structure::getConcurrently on the mutator thread
https://bugs.webkit.org/show_bug.cgi?id=238823

Reviewed by Yusuke Suzuki.

We try to call Structure::get instead of Structure::getConcurrently when
we know for sure we're on the main thread. This is because getConcurrently
is slower than get.

* bytecode/AccessCase.cpp:
(JSC::AccessCase::couldStillSucceed const):
(JSC::AccessCase::generateImpl):
* bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp:
(JSC::AdaptiveInferredPropertyValueWatchpointBase::install):
* bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp:
(JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::install):
* bytecode/ObjectPropertyCondition.cpp:
(JSC::ObjectPropertyCondition::structureEnsuresValidityAssumingImpurePropertyWatchpoint const):
(JSC::ObjectPropertyCondition::isStillValidAssumingImpurePropertyWatchpoint const):
(JSC::ObjectPropertyCondition::isStillValid const):
(JSC::ObjectPropertyCondition::structureEnsuresValidity const):
* bytecode/ObjectPropertyCondition.h:
* bytecode/ObjectPropertyConditionSet.cpp:
(JSC::ObjectPropertyConditionSet::structuresEnsureValidity const):
(JSC::generateConditionsForPropertyMiss):
(JSC::generateConditionsForPropertySetterMiss):
(JSC::generateConditionsForPrototypePropertyHit):
(JSC::generateConditionsForPrototypePropertyHitCustom):
(JSC::generateConditionsForPrototypeEquivalenceConcurrently):
(JSC::generateConditionsForPropertyMissConcurrently):
(JSC::generateConditionsForPropertySetterMissConcurrently):
(JSC::generateConditionForSelfEquivalence):
(JSC::ObjectPropertyConditionSet::structuresEnsureValidityAssumingImpurePropertyWatchpoint const): Deleted.
(JSC::ObjectPropertyConditionSet::isValidAndWatchable const): Deleted.
* bytecode/ObjectPropertyConditionSet.h:
* bytecode/PropertyCondition.cpp:
(JSC::PropertyCondition::isStillValidAssumingImpurePropertyWatchpoint const):
(JSC::watchabilityToConcurrency):
(JSC::PropertyCondition::isStillValid const):
(JSC::PropertyCondition::isWatchableWhenValid const):
(JSC::PropertyCondition::isWatchableAssumingImpurePropertyWatchpoint const):
(JSC::PropertyCondition::isWatchable const):
* bytecode/PropertyCondition.h:
* dfg/DFGAdaptiveStructureWatchpoint.cpp:
(JSC::DFG::AdaptiveStructureWatchpoint::install):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::check):
(JSC::DFG::ByteCodeParser::planLoad):
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::tryFoldAsPutByOffset):
* dfg/DFGDesiredWatchpoints.h:
(JSC::DFG::AdaptiveStructureWatchpointAdaptor::hasBeenInvalidated):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::watchCondition):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::setupGetByIdPrototypeCache):
* runtime/CachedSpecialPropertyAdaptiveStructureWatchpoint.cpp:
(JSC::CachedSpecialPropertyAdaptiveStructureWatchpoint::install):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::tryInstallSpeciesWatchpoint):
* runtime/JSObject.h:
(JSC::JSObject::getDirect const):
* runtime/Structure.h:
(JSC::Structure::get):
* runtime/StructureRareData.cpp:
(JSC::StructureRareData::cacheSpecialPropertySlow):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (292492 => 292493)


--- trunk/Source/_javascript_Core/ChangeLog	2022-04-06 19:33:49 UTC (rev 292492)
+++ trunk/Source/_javascript_Core/ChangeLog	2022-04-06 19:35:37 UTC (rev 292493)
@@ -1,3 +1,72 @@
+2022-04-06  Saam Barati  <sbar...@apple.com>
+
+        Call Structure::get instead of Structure::getConcurrently on the mutator thread
+        https://bugs.webkit.org/show_bug.cgi?id=238823
+
+        Reviewed by Yusuke Suzuki.
+
+        We try to call Structure::get instead of Structure::getConcurrently when
+        we know for sure we're on the main thread. This is because getConcurrently
+        is slower than get.
+
+        * bytecode/AccessCase.cpp:
+        (JSC::AccessCase::couldStillSucceed const):
+        (JSC::AccessCase::generateImpl):
+        * bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp:
+        (JSC::AdaptiveInferredPropertyValueWatchpointBase::install):
+        * bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp:
+        (JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::install):
+        * bytecode/ObjectPropertyCondition.cpp:
+        (JSC::ObjectPropertyCondition::structureEnsuresValidityAssumingImpurePropertyWatchpoint const):
+        (JSC::ObjectPropertyCondition::isStillValidAssumingImpurePropertyWatchpoint const):
+        (JSC::ObjectPropertyCondition::isStillValid const):
+        (JSC::ObjectPropertyCondition::structureEnsuresValidity const):
+        * bytecode/ObjectPropertyCondition.h:
+        * bytecode/ObjectPropertyConditionSet.cpp:
+        (JSC::ObjectPropertyConditionSet::structuresEnsureValidity const):
+        (JSC::generateConditionsForPropertyMiss):
+        (JSC::generateConditionsForPropertySetterMiss):
+        (JSC::generateConditionsForPrototypePropertyHit):
+        (JSC::generateConditionsForPrototypePropertyHitCustom):
+        (JSC::generateConditionsForPrototypeEquivalenceConcurrently):
+        (JSC::generateConditionsForPropertyMissConcurrently):
+        (JSC::generateConditionsForPropertySetterMissConcurrently):
+        (JSC::generateConditionForSelfEquivalence):
+        (JSC::ObjectPropertyConditionSet::structuresEnsureValidityAssumingImpurePropertyWatchpoint const): Deleted.
+        (JSC::ObjectPropertyConditionSet::isValidAndWatchable const): Deleted.
+        * bytecode/ObjectPropertyConditionSet.h:
+        * bytecode/PropertyCondition.cpp:
+        (JSC::PropertyCondition::isStillValidAssumingImpurePropertyWatchpoint const):
+        (JSC::watchabilityToConcurrency):
+        (JSC::PropertyCondition::isStillValid const):
+        (JSC::PropertyCondition::isWatchableWhenValid const):
+        (JSC::PropertyCondition::isWatchableAssumingImpurePropertyWatchpoint const):
+        (JSC::PropertyCondition::isWatchable const):
+        * bytecode/PropertyCondition.h:
+        * dfg/DFGAdaptiveStructureWatchpoint.cpp:
+        (JSC::DFG::AdaptiveStructureWatchpoint::install):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::check):
+        (JSC::DFG::ByteCodeParser::planLoad):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::tryFoldAsPutByOffset):
+        * dfg/DFGDesiredWatchpoints.h:
+        (JSC::DFG::AdaptiveStructureWatchpointAdaptor::hasBeenInvalidated):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::watchCondition):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::setupGetByIdPrototypeCache):
+        * runtime/CachedSpecialPropertyAdaptiveStructureWatchpoint.cpp:
+        (JSC::CachedSpecialPropertyAdaptiveStructureWatchpoint::install):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::tryInstallSpeciesWatchpoint):
+        * runtime/JSObject.h:
+        (JSC::JSObject::getDirect const):
+        * runtime/Structure.h:
+        (JSC::Structure::get):
+        * runtime/StructureRareData.cpp:
+        (JSC::StructureRareData::cacheSpecialPropertySlow):
+
 2022-04-06  Chris Dumez  <cdu...@apple.com>
 
         Start replacing String(const char*) constructor with a String::fromLatin1(const char*) function

Modified: trunk/Source/_javascript_Core/bytecode/AccessCase.cpp (292492 => 292493)


--- trunk/Source/_javascript_Core/bytecode/AccessCase.cpp	2022-04-06 19:33:49 UTC (rev 292492)
+++ trunk/Source/_javascript_Core/bytecode/AccessCase.cpp	2022-04-06 19:35:37 UTC (rev 292493)
@@ -717,7 +717,7 @@
             if (!condition.isWatchableAssumingImpurePropertyWatchpoint(PropertyCondition::WatchabilityEffort::EnsureWatchability))
                 return false;
         } else {
-            if (!condition.structureEnsuresValidityAssumingImpurePropertyWatchpoint())
+            if (!condition.structureEnsuresValidityAssumingImpurePropertyWatchpoint(Concurrency::MainThread))
                 return false;
         }
     }
@@ -1803,7 +1803,7 @@
         // For now, we only allow equivalence when it's watchable.
         RELEASE_ASSERT(condition.condition().kind() != PropertyCondition::Equivalence);
 
-        if (!condition.structureEnsuresValidityAssumingImpurePropertyWatchpoint()) {
+        if (!condition.structureEnsuresValidityAssumingImpurePropertyWatchpoint(Concurrency::MainThread)) {
             // The reason why this cannot happen is that we require that PolymorphicAccess calls
             // AccessCase::generate() only after it has verified that
             // AccessCase::couldStillSucceed() returned true.

Modified: trunk/Source/_javascript_Core/bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp (292492 => 292493)


--- trunk/Source/_javascript_Core/bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp	2022-04-06 19:33:49 UTC (rev 292492)
+++ trunk/Source/_javascript_Core/bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp	2022-04-06 19:35:37 UTC (rev 292493)
@@ -44,13 +44,13 @@
 
 void AdaptiveInferredPropertyValueWatchpointBase::install(VM& vm)
 {
-    RELEASE_ASSERT(m_key.isWatchable());
+    RELEASE_ASSERT(m_key.isWatchable(PropertyCondition::MakeNoChanges));
 
     Structure* structure = m_key.object()->structure(vm);
 
     structure->addTransitionWatchpoint(&m_structureWatchpoint);
 
-    PropertyOffset offset = structure->getConcurrently(m_key.uid());
+    PropertyOffset offset = structure->get(vm, m_key.uid());
     WatchpointSet* set = structure->propertyReplacementWatchpointSet(offset);
     set->add(&m_propertyWatchpoint);
 }

Modified: trunk/Source/_javascript_Core/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp (292492 => 292493)


--- trunk/Source/_javascript_Core/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp	2022-04-06 19:33:49 UTC (rev 292492)
+++ trunk/Source/_javascript_Core/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp	2022-04-06 19:35:37 UTC (rev 292493)
@@ -58,7 +58,7 @@
 
 void LLIntPrototypeLoadAdaptiveStructureWatchpoint::install(VM& vm)
 {
-    RELEASE_ASSERT(m_key.isWatchable());
+    RELEASE_ASSERT(m_key.isWatchable(PropertyCondition::MakeNoChanges));
 
     m_key.object()->structure(vm)->addTransitionWatchpoint(this);
 }

Modified: trunk/Source/_javascript_Core/bytecode/ObjectPropertyCondition.cpp (292492 => 292493)


--- trunk/Source/_javascript_Core/bytecode/ObjectPropertyCondition.cpp	2022-04-06 19:33:49 UTC (rev 292492)
+++ trunk/Source/_javascript_Core/bytecode/ObjectPropertyCondition.cpp	2022-04-06 19:35:37 UTC (rev 292493)
@@ -46,12 +46,12 @@
     dumpInContext(out, nullptr);
 }
 
-bool ObjectPropertyCondition::structureEnsuresValidityAssumingImpurePropertyWatchpoint() const
+bool ObjectPropertyCondition::structureEnsuresValidityAssumingImpurePropertyWatchpoint(Concurrency concurrency) const
 {
     if (!*this)
         return false;
     
-    return m_condition.isStillValidAssumingImpurePropertyWatchpoint(m_object->structure(), nullptr);
+    return m_condition.isStillValidAssumingImpurePropertyWatchpoint(concurrency, m_object->structure(), nullptr);
 }
 
 bool ObjectPropertyCondition::validityRequiresImpurePropertyWatchpoint(Structure* structure) const
@@ -67,44 +67,44 @@
     return validityRequiresImpurePropertyWatchpoint(m_object->structure());
 }
 
-bool ObjectPropertyCondition::isStillValidAssumingImpurePropertyWatchpoint(Structure* structure) const
+bool ObjectPropertyCondition::isStillValidAssumingImpurePropertyWatchpoint(Concurrency concurrency, Structure* structure) const
 {
-    return m_condition.isStillValidAssumingImpurePropertyWatchpoint(structure, m_object);
+    return m_condition.isStillValidAssumingImpurePropertyWatchpoint(concurrency, structure, m_object);
 }
 
-bool ObjectPropertyCondition::isStillValidAssumingImpurePropertyWatchpoint() const
+bool ObjectPropertyCondition::isStillValidAssumingImpurePropertyWatchpoint(Concurrency concurrency) const
 {
     if (!*this)
         return false;
 
-    return isStillValidAssumingImpurePropertyWatchpoint(m_object->structure());
+    return isStillValidAssumingImpurePropertyWatchpoint(concurrency, m_object->structure());
 }
 
 
-bool ObjectPropertyCondition::isStillValid(Structure* structure) const
+bool ObjectPropertyCondition::isStillValid(Concurrency concurrency, Structure* structure) const
 {
-    return m_condition.isStillValid(structure, m_object);
+    return m_condition.isStillValid(concurrency, structure, m_object);
 }
 
-bool ObjectPropertyCondition::isStillValid() const
+bool ObjectPropertyCondition::isStillValid(Concurrency concurrency) const
 {
     if (!*this)
         return false;
     
-    return isStillValid(m_object->structure());
+    return isStillValid(concurrency, m_object->structure());
 }
 
-bool ObjectPropertyCondition::structureEnsuresValidity(Structure* structure) const
+bool ObjectPropertyCondition::structureEnsuresValidity(Concurrency concurrency, Structure* structure) const
 {
-    return m_condition.isStillValid(structure);
+    return m_condition.isStillValid(concurrency, structure);
 }
 
-bool ObjectPropertyCondition::structureEnsuresValidity() const
+bool ObjectPropertyCondition::structureEnsuresValidity(Concurrency concurrency) const
 {
     if (!*this)
         return false;
     
-    return structureEnsuresValidity(m_object->structure());
+    return structureEnsuresValidity(concurrency, m_object->structure());
 }
 
 bool ObjectPropertyCondition::isWatchableAssumingImpurePropertyWatchpoint(

Modified: trunk/Source/_javascript_Core/bytecode/ObjectPropertyCondition.h (292492 => 292493)


--- trunk/Source/_javascript_Core/bytecode/ObjectPropertyCondition.h	2022-04-06 19:33:49 UTC (rev 292492)
+++ trunk/Source/_javascript_Core/bytecode/ObjectPropertyCondition.h	2022-04-06 19:35:37 UTC (rev 292493)
@@ -204,7 +204,7 @@
     
     // Checks if the object's structure claims that the property won't be intercepted. Validity
     // does not require watchpoints on the object.
-    bool structureEnsuresValidityAssumingImpurePropertyWatchpoint() const;
+    bool structureEnsuresValidityAssumingImpurePropertyWatchpoint(Concurrency) const;
     
     // Returns true if we need an impure property watchpoint to ensure validity even if
     // isStillValidAccordingToStructure() returned true.
@@ -213,8 +213,8 @@
 
     // Checks if the condition still holds setting aside the need for an impure property watchpoint.
     // Validity might still require watchpoints on the object.
-    bool isStillValidAssumingImpurePropertyWatchpoint(Structure*) const;
-    bool isStillValidAssumingImpurePropertyWatchpoint() const;
+    bool isStillValidAssumingImpurePropertyWatchpoint(Concurrency, Structure*) const;
+    bool isStillValidAssumingImpurePropertyWatchpoint(Concurrency) const;
 
     // Checks if the condition still holds. May conservatively return false, if the object and
     // structure alone don't guarantee the condition. Note that this may return true if the
@@ -221,28 +221,28 @@
     // condition still requires some watchpoints on the object in addition to checking the
     // structure. If you want to check if the condition holds by using the structure alone,
     // use structureEnsuresValidity().
-    bool isStillValid(Structure*) const;
-    bool isStillValid() const;
+    bool isStillValid(Concurrency, Structure*) const;
+    bool isStillValid(Concurrency) const;
     
     // Shorthand for condition().isStillValid(structure).
-    bool structureEnsuresValidity(Structure*) const;
-    bool structureEnsuresValidity() const;
+    bool structureEnsuresValidity(Concurrency, Structure*) const;
+    bool structureEnsuresValidity(Concurrency) const;
     
     // This means that it's still valid and we could enforce validity by setting a transition
     // watchpoint on the structure and possibly an impure property watchpoint.
     bool isWatchableAssumingImpurePropertyWatchpoint(
         Structure*,
-        PropertyCondition::WatchabilityEffort = PropertyCondition::MakeNoChanges) const;
+        PropertyCondition::WatchabilityEffort) const;
     bool isWatchableAssumingImpurePropertyWatchpoint(
-        PropertyCondition::WatchabilityEffort = PropertyCondition::MakeNoChanges) const;
+        PropertyCondition::WatchabilityEffort) const;
 
     // This means that it's still valid and we could enforce validity by setting a transition
     // watchpoint on the structure, and a value change watchpoint if we're Equivalence.
     bool isWatchable(
         Structure*,
-        PropertyCondition::WatchabilityEffort = PropertyCondition::MakeNoChanges) const;
+        PropertyCondition::WatchabilityEffort) const;
     bool isWatchable(
-        PropertyCondition::WatchabilityEffort = PropertyCondition::MakeNoChanges) const;
+        PropertyCondition::WatchabilityEffort) const;
     
     bool watchingRequiresStructureTransitionWatchpoint() const
     {

Modified: trunk/Source/_javascript_Core/bytecode/ObjectPropertyConditionSet.cpp (292492 => 292493)


--- trunk/Source/_javascript_Core/bytecode/ObjectPropertyConditionSet.cpp	2022-04-06 19:33:49 UTC (rev 292492)
+++ trunk/Source/_javascript_Core/bytecode/ObjectPropertyConditionSet.cpp	2022-04-06 19:35:37 UTC (rev 292493)
@@ -130,24 +130,12 @@
         return false;
     
     for (const ObjectPropertyCondition& condition : *this) {
-        if (!condition.structureEnsuresValidity())
+        if (!condition.structureEnsuresValidity(Concurrency::ConcurrentThread))
             return false;
     }
     return true;
 }
 
-bool ObjectPropertyConditionSet::structuresEnsureValidityAssumingImpurePropertyWatchpoint() const
-{
-    if (!isValid())
-        return false;
-    
-    for (const ObjectPropertyCondition& condition : *this) {
-        if (!condition.structureEnsuresValidityAssumingImpurePropertyWatchpoint())
-            return false;
-    }
-    return true;
-}
-
 bool ObjectPropertyConditionSet::needImpurePropertyWatchpoint() const
 {
     for (const ObjectPropertyCondition& condition : *this) {
@@ -184,18 +172,6 @@
     dumpInContext(out, nullptr);
 }
 
-bool ObjectPropertyConditionSet::isValidAndWatchable() const
-{
-    if (!isValid())
-        return false;
-
-    for (auto& condition : *m_data) {
-        if (!condition.isWatchable())
-            return false;
-    }
-    return true;
-}
-
 namespace {
 
 namespace ObjectPropertyConditionSetInternal {
@@ -203,7 +179,7 @@
 }
 
 ObjectPropertyCondition generateCondition(
-    VM& vm, JSCell* owner, JSObject* object, UniquedStringImpl* uid, PropertyCondition::Kind conditionKind)
+    VM& vm, JSCell* owner, JSObject* object, UniquedStringImpl* uid, PropertyCondition::Kind conditionKind, Concurrency concurrency)
 {
     Structure* structure = object->structure(vm);
     if (ObjectPropertyConditionSetInternal::verbose)
@@ -213,7 +189,7 @@
     switch (conditionKind) {
     case PropertyCondition::Presence: {
         unsigned attributes;
-        PropertyOffset offset = structure->getConcurrently(uid, attributes);
+        PropertyOffset offset = structure->get(vm, concurrency, uid, attributes);
         if (offset == invalidOffset)
             return ObjectPropertyCondition();
         result = ObjectPropertyCondition::presence(vm, owner, object, uid, offset, attributes);
@@ -235,10 +211,10 @@
     }
     case PropertyCondition::Equivalence: {
         unsigned attributes;
-        PropertyOffset offset = structure->getConcurrently(uid, attributes);
+        PropertyOffset offset = structure->get(vm, concurrency, uid, attributes);
         if (offset == invalidOffset)
             return ObjectPropertyCondition();
-        JSValue value = object->getDirectConcurrently(structure, offset);
+        JSValue value = object->getDirect(concurrency, structure, offset);
         if (!value)
             return ObjectPropertyCondition();
         result = ObjectPropertyCondition::equivalence(vm, owner, object, uid, value);
@@ -256,7 +232,7 @@
         return ObjectPropertyCondition();
     }
 
-    if (!result.isStillValidAssumingImpurePropertyWatchpoint()) {
+    if (!result.isStillValidAssumingImpurePropertyWatchpoint(concurrency)) {
         if (ObjectPropertyConditionSetInternal::verbose)
             dataLog("Failed to create condition: ", result, "\n");
         return ObjectPropertyCondition();
@@ -341,7 +317,7 @@
         vm, globalObject, headStructure, nullptr,
         [&] (Vector<ObjectPropertyCondition>& conditions, JSObject* object) -> bool {
             ObjectPropertyCondition result =
-                generateCondition(vm, owner, object, uid, PropertyCondition::Absence);
+                generateCondition(vm, owner, object, uid, PropertyCondition::Absence, Concurrency::MainThread);
             if (!result)
                 return false;
             conditions.append(result);
@@ -356,7 +332,7 @@
         vm, globalObject, headStructure, nullptr,
         [&] (Vector<ObjectPropertyCondition>& conditions, JSObject* object) -> bool {
             ObjectPropertyCondition result =
-                generateCondition(vm, owner, object, uid, PropertyCondition::AbsenceOfSetEffect);
+                generateCondition(vm, owner, object, uid, PropertyCondition::AbsenceOfSetEffect, Concurrency::MainThread);
             if (!result)
                 return false;
             conditions.append(result);
@@ -374,7 +350,7 @@
             PropertyCondition::Kind kind =
                 object == prototype ? PropertyCondition::Presence : PropertyCondition::Absence;
             ObjectPropertyCondition result =
-                generateCondition(vm, owner, object, uid, kind);
+                generateCondition(vm, owner, object, uid, kind, Concurrency::MainThread);
             if (!result)
                 return false;
             conditions.append(result);
@@ -422,7 +398,7 @@
                     return false;
                 }
             }
-            ObjectPropertyCondition result = generateCondition(vm, owner, object, uid, kind);
+            ObjectPropertyCondition result = generateCondition(vm, owner, object, uid, kind, Concurrency::MainThread);
             if (!result)
                 return false;
             conditions.append(result);
@@ -471,7 +447,7 @@
         [&] (Vector<ObjectPropertyCondition>& conditions, JSObject* object) -> bool {
             PropertyCondition::Kind kind =
                 object == prototype ? PropertyCondition::Equivalence : PropertyCondition::Absence;
-            ObjectPropertyCondition result = generateCondition(vm, nullptr, object, uid, kind);
+            ObjectPropertyCondition result = generateCondition(vm, nullptr, object, uid, kind, Concurrency::ConcurrentThread);
             if (!result)
                 return false;
             conditions.append(result);
@@ -485,7 +461,7 @@
     return generateConditions(
         vm, globalObject, headStructure, nullptr,
         [&] (Vector<ObjectPropertyCondition>& conditions, JSObject* object) -> bool {
-            ObjectPropertyCondition result = generateCondition(vm, nullptr, object, uid, PropertyCondition::Absence);
+            ObjectPropertyCondition result = generateCondition(vm, nullptr, object, uid, PropertyCondition::Absence, Concurrency::ConcurrentThread);
             if (!result)
                 return false;
             conditions.append(result);
@@ -500,7 +476,7 @@
         vm, globalObject, headStructure, nullptr,
         [&] (Vector<ObjectPropertyCondition>& conditions, JSObject* object) -> bool {
             ObjectPropertyCondition result =
-                generateCondition(vm, nullptr, object, uid, PropertyCondition::AbsenceOfSetEffect);
+                generateCondition(vm, nullptr, object, uid, PropertyCondition::AbsenceOfSetEffect, Concurrency::ConcurrentThread);
             if (!result)
                 return false;
             conditions.append(result);
@@ -511,7 +487,7 @@
 ObjectPropertyCondition generateConditionForSelfEquivalence(
     VM& vm, JSCell* owner, JSObject* object, UniquedStringImpl* uid)
 {
-    return generateCondition(vm, owner, object, uid, PropertyCondition::Equivalence);
+    return generateCondition(vm, owner, object, uid, PropertyCondition::Equivalence, Concurrency::MainThread);
 }
 
 // Current might be null. Structure can't be null.

Modified: trunk/Source/_javascript_Core/bytecode/ObjectPropertyConditionSet.h (292492 => 292493)


--- trunk/Source/_javascript_Core/bytecode/ObjectPropertyConditionSet.h	2022-04-06 19:33:49 UTC (rev 292492)
+++ trunk/Source/_javascript_Core/bytecode/ObjectPropertyConditionSet.h	2022-04-06 19:35:37 UTC (rev 292493)
@@ -71,8 +71,6 @@
         return !m_data || !m_data->isEmpty();
     }
 
-    bool isValidAndWatchable() const;
-
     size_t size() const { return m_data ? m_data->size() : 0; }
     bool isEmpty() const
     {
@@ -139,7 +137,6 @@
     ObjectPropertyConditionSet mergedWith(const ObjectPropertyConditionSet& other) const;
     
     bool structuresEnsureValidity() const;
-    bool structuresEnsureValidityAssumingImpurePropertyWatchpoint() const;
     
     bool needImpurePropertyWatchpoint() const;
 

Modified: trunk/Source/_javascript_Core/bytecode/PropertyCondition.cpp (292492 => 292493)


--- trunk/Source/_javascript_Core/bytecode/PropertyCondition.cpp	2022-04-06 19:33:49 UTC (rev 292492)
+++ trunk/Source/_javascript_Core/bytecode/PropertyCondition.cpp	2022-04-06 19:35:37 UTC (rev 292493)
@@ -70,7 +70,7 @@
 }
 
 bool PropertyCondition::isStillValidAssumingImpurePropertyWatchpoint(
-    Structure* structure, JSObject* base) const
+    Concurrency concurrency, Structure* structure, JSObject* base) const
 {
     if (PropertyConditionInternal::verbose) {
         dataLog(
@@ -109,7 +109,7 @@
     switch (m_header.type()) {
     case Presence: {
         unsigned currentAttributes;
-        PropertyOffset currentOffset = structure->getConcurrently(uid(), currentAttributes);
+        PropertyOffset currentOffset = structure->get(structure->vm(), concurrency, uid(), currentAttributes);
         if (currentOffset != offset() || currentAttributes != attributes()) {
             if (PropertyConditionInternal::verbose) {
                 dataLog(
@@ -136,7 +136,7 @@
             return false;
         }
 
-        PropertyOffset currentOffset = structure->getConcurrently(uid());
+        PropertyOffset currentOffset = structure->get(structure->vm(), concurrency, uid());
         if (currentOffset != invalidOffset) {
             if (PropertyConditionInternal::verbose)
                 dataLog("Invalid because the property exists at offset: ", currentOffset, "\n");
@@ -163,7 +163,7 @@
         }
         
         unsigned currentAttributes;
-        PropertyOffset currentOffset = structure->getConcurrently(uid(), currentAttributes);
+        PropertyOffset currentOffset = structure->get(structure->vm(), concurrency, uid(), currentAttributes);
         if (currentOffset != invalidOffset) {
             if (currentAttributes & (PropertyAttribute::ReadOnly | PropertyAttribute::Accessor | PropertyAttribute::CustomAccessorOrValue)) {
                 if (PropertyConditionInternal::verbose) {
@@ -231,7 +231,7 @@
         // FIXME: This is somewhat racy, and maybe more risky than we want.
         // https://bugs.webkit.org/show_bug.cgi?id=134641
         
-        PropertyOffset currentOffset = structure->getConcurrently(uid());
+        PropertyOffset currentOffset = structure->get(structure->vm(), concurrency, uid());
         if (currentOffset == invalidOffset) {
             if (PropertyConditionInternal::verbose) {
                 dataLog(
@@ -241,7 +241,7 @@
             return false;
         }
 
-        JSValue currentValue = base->getDirectConcurrently(structure, currentOffset);
+        JSValue currentValue = base->getDirect(concurrency, structure, currentOffset);
         if (currentValue != requiredValue()) {
             if (PropertyConditionInternal::verbose) {
                 dataLog(
@@ -254,7 +254,7 @@
         return true;
     } 
     case HasStaticProperty: {
-        if (isValidOffset(structure->getConcurrently(uid())))
+        if (isValidOffset(structure->get(structure->vm(), concurrency, uid())))
             return false;
         if (structure->staticPropertiesReified())
             return false;
@@ -266,6 +266,16 @@
     return false;
 }
 
+static ALWAYS_INLINE Concurrency watchabilityToConcurrency(PropertyCondition::WatchabilityEffort effort)
+{
+    switch (effort) {
+    case PropertyCondition::WatchabilityEffort::EnsureWatchability:
+        return Concurrency::MainThread;
+    case PropertyCondition::WatchabilityEffort::MakeNoChanges:
+        return Concurrency::ConcurrentThread;
+    }
+}
+
 bool PropertyCondition::validityRequiresImpurePropertyWatchpoint(Structure* structure) const
 {
     if (!*this)
@@ -286,9 +296,9 @@
     return false;
 }
 
-bool PropertyCondition::isStillValid(Structure* structure, JSObject* base) const
+bool PropertyCondition::isStillValid(Concurrency concurrency, Structure* structure, JSObject* base) const
 {
-    if (!isStillValidAssumingImpurePropertyWatchpoint(structure, base))
+    if (!isStillValidAssumingImpurePropertyWatchpoint(concurrency, structure, base))
         return false;
 
     // Currently we assume that an impure property can cause a property to appear, and can also
@@ -320,7 +330,7 @@
     
     switch (m_header.type()) {
     case Equivalence: {
-        PropertyOffset offset = structure->getConcurrently(uid());
+        PropertyOffset offset = structure->get(structure->vm(), watchabilityToConcurrency(effort), uid());
         
         // This method should only be called when some variant of isValid returned true, which
         // implies that we already confirmed that the structure knows of the property. We should
@@ -369,7 +379,7 @@
 bool PropertyCondition::isWatchableAssumingImpurePropertyWatchpoint(
     Structure* structure, JSObject* base, WatchabilityEffort effort) const
 {
-    return isStillValidAssumingImpurePropertyWatchpoint(structure, base)
+    return isStillValidAssumingImpurePropertyWatchpoint(watchabilityToConcurrency(effort), structure, base)
         && isWatchableWhenValid(structure, effort);
 }
 
@@ -376,7 +386,7 @@
 bool PropertyCondition::isWatchable(
     Structure* structure, JSObject* base, WatchabilityEffort effort) const
 {
-    return isStillValid(structure, base)
+    return isStillValid(watchabilityToConcurrency(effort), structure, base)
         && isWatchableWhenValid(structure, effort);
 }
 

Modified: trunk/Source/_javascript_Core/bytecode/PropertyCondition.h (292492 => 292493)


--- trunk/Source/_javascript_Core/bytecode/PropertyCondition.h	2022-04-06 19:33:49 UTC (rev 292492)
+++ trunk/Source/_javascript_Core/bytecode/PropertyCondition.h	2022-04-06 19:35:37 UTC (rev 292493)
@@ -249,7 +249,7 @@
     }
     
     // Checks if the object's structure claims that the property won't be intercepted.
-    bool isStillValidAssumingImpurePropertyWatchpoint(Structure*, JSObject* base = nullptr) const;
+    bool isStillValidAssumingImpurePropertyWatchpoint(Concurrency, Structure*, JSObject* base = nullptr) const;
     
     // Returns true if we need an impure property watchpoint to ensure validity even if
     // isStillValidAccordingToStructure() returned true.
@@ -262,7 +262,7 @@
     // an object has the given structure guarantees the condition still holds. If an object is
     // supplied, then you may need to use some other watchpoints on the object to guarantee the
     // condition in addition to the structure check.
-    bool isStillValid(Structure*, JSObject* base = nullptr) const;
+    bool isStillValid(Concurrency, Structure*, JSObject* base = nullptr) const;
     
     // In some cases, the condition is not watchable, but could be made watchable by enabling the
     // appropriate watchpoint. For example, replacement watchpoints are enabled only when some
@@ -291,12 +291,12 @@
     // This means that it's still valid and we could enforce validity by setting a transition
     // watchpoint on the structure and possibly an impure property watchpoint.
     bool isWatchableAssumingImpurePropertyWatchpoint(
-        Structure*, JSObject* base, WatchabilityEffort = MakeNoChanges) const;
+        Structure*, JSObject* base, WatchabilityEffort) const;
     
     // This means that it's still valid and we could enforce validity by setting a transition
     // watchpoint on the structure.
     bool isWatchable(
-        Structure*, JSObject*, WatchabilityEffort = MakeNoChanges) const;
+        Structure*, JSObject*, WatchabilityEffort) const;
     
     bool watchingRequiresStructureTransitionWatchpoint() const
     {

Modified: trunk/Source/_javascript_Core/dfg/DFGAdaptiveStructureWatchpoint.cpp (292492 => 292493)


--- trunk/Source/_javascript_Core/dfg/DFGAdaptiveStructureWatchpoint.cpp	2022-04-06 19:33:49 UTC (rev 292492)
+++ trunk/Source/_javascript_Core/dfg/DFGAdaptiveStructureWatchpoint.cpp	2022-04-06 19:35:37 UTC (rev 292493)
@@ -58,7 +58,7 @@
 
 void AdaptiveStructureWatchpoint::install(VM& vm)
 {
-    RELEASE_ASSERT(m_key.isWatchable());
+    RELEASE_ASSERT(m_key.isWatchable(PropertyCondition::MakeNoChanges));
     
     m_key.object()->structure(vm)->addTransitionWatchpoint(this);
 }

Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (292492 => 292493)


--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2022-04-06 19:33:49 UTC (rev 292492)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2022-04-06 19:35:37 UTC (rev 292493)
@@ -4251,7 +4251,7 @@
         return true;
     
     Structure* structure = condition.object()->structure(*m_vm);
-    if (!condition.structureEnsuresValidity(structure))
+    if (!condition.structureEnsuresValidity(Concurrency::ConcurrentThread, structure))
         return false;
     
     addToGraph(
@@ -4380,7 +4380,7 @@
     
     // Check if the structure that we've registered makes the condition hold. If not, just give
     // up. This is case (5) above.
-    if (!condition.structureEnsuresValidity(structure))
+    if (!condition.structureEnsuresValidity(Concurrency::ConcurrentThread, structure))
         return GetByOffsetMethod();
     
     // If the structure is watched by the DFG already, then just use this fact to emit the load.

Modified: trunk/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp (292492 => 292493)


--- trunk/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp	2022-04-06 19:33:49 UTC (rev 292492)
+++ trunk/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp	2022-04-06 19:35:37 UTC (rev 292493)
@@ -1435,7 +1435,7 @@
                         continue;
 
                     Structure* structure = condition.object()->structure(m_graph.m_vm);
-                    if (!condition.structureEnsuresValidity(structure))
+                    if (!condition.structureEnsuresValidity(Concurrency::ConcurrentThread, structure))
                         return;
 
                     m_insertionSet.insertNode(

Modified: trunk/Source/_javascript_Core/dfg/DFGDesiredWatchpoints.h (292492 => 292493)


--- trunk/Source/_javascript_Core/dfg/DFGDesiredWatchpoints.h	2022-04-06 19:33:49 UTC (rev 292492)
+++ trunk/Source/_javascript_Core/dfg/DFGDesiredWatchpoints.h	2022-04-06 19:35:37 UTC (rev 292493)
@@ -164,7 +164,7 @@
     static void add(CodeBlock*, const ObjectPropertyCondition&, WatchpointCollector&);
     static bool hasBeenInvalidated(const ObjectPropertyCondition& key)
     {
-        return !key.isWatchable();
+        return !key.isWatchable(PropertyCondition::MakeNoChanges);
     }
     static void dumpInContext(
         PrintStream& out, const ObjectPropertyCondition& key, DumpContext* context)

Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.cpp (292492 => 292493)


--- trunk/Source/_javascript_Core/dfg/DFGGraph.cpp	2022-04-06 19:33:49 UTC (rev 292492)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.cpp	2022-04-06 19:35:37 UTC (rev 292493)
@@ -1064,7 +1064,7 @@
     if (m_plan.isUnlinked())
         return false;
 
-    if (!key.isWatchable())
+    if (!key.isWatchable(PropertyCondition::MakeNoChanges))
         return false;
 
     DesiredWeakReferences& weakReferences = m_plan.weakReferences();

Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (292492 => 292493)


--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp	2022-04-06 19:33:49 UTC (rev 292492)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp	2022-04-06 19:35:37 UTC (rev 292493)
@@ -781,7 +781,7 @@
     unsigned index = 0;
     for (ObjectPropertyCondition condition : conditions) {
         auto& watchpoint = watchpoints[index++];
-        if (!condition.isWatchable())
+        if (!condition.isWatchable(PropertyCondition::MakeNoChanges))
             return;
         if (condition.condition().kind() == PropertyCondition::Presence)
             offset = condition.condition().offset();

Modified: trunk/Source/_javascript_Core/runtime/CachedSpecialPropertyAdaptiveStructureWatchpoint.cpp (292492 => 292493)


--- trunk/Source/_javascript_Core/runtime/CachedSpecialPropertyAdaptiveStructureWatchpoint.cpp	2022-04-06 19:33:49 UTC (rev 292492)
+++ trunk/Source/_javascript_Core/runtime/CachedSpecialPropertyAdaptiveStructureWatchpoint.cpp	2022-04-06 19:35:37 UTC (rev 292493)
@@ -42,7 +42,7 @@
 
 void CachedSpecialPropertyAdaptiveStructureWatchpoint::install(VM& vm)
 {
-    RELEASE_ASSERT(m_key.isWatchable());
+    RELEASE_ASSERT(m_key.isWatchable(PropertyCondition::MakeNoChanges));
 
     m_key.object()->structure(vm)->addTransitionWatchpoint(this);
 }

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (292492 => 292493)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2022-04-06 19:33:49 UTC (rev 292492)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2022-04-06 19:35:37 UTC (rev 292493)
@@ -2461,7 +2461,7 @@
     ObjectPropertyCondition constructorCondition = ObjectPropertyCondition::equivalence(vm, prototype, prototype, vm.propertyNames->constructor.impl(), constructor);
     ObjectPropertyCondition speciesCondition = ObjectPropertyCondition::equivalence(vm, prototype, constructor, vm.propertyNames->speciesSymbol.impl(), speciesGetterSetter());
 
-    if (!constructorCondition.isWatchable() || !speciesCondition.isWatchable()) {
+    if (!constructorCondition.isWatchable(PropertyCondition::MakeNoChanges) || !speciesCondition.isWatchable(PropertyCondition::MakeNoChanges)) {
         invalidateWatchpoint();
         return;
     }

Modified: trunk/Source/_javascript_Core/runtime/JSObject.h (292492 => 292493)


--- trunk/Source/_javascript_Core/runtime/JSObject.h	2022-04-06 19:33:49 UTC (rev 292492)
+++ trunk/Source/_javascript_Core/runtime/JSObject.h	2022-04-06 19:35:37 UTC (rev 292493)
@@ -835,6 +835,7 @@
 
     // Fast access to known property offsets.
     ALWAYS_INLINE JSValue getDirect(PropertyOffset offset) const { return locationForOffset(offset)->get(); }
+    JSValue getDirect(Concurrency, Structure* expectedStructure, PropertyOffset) const;
     JSValue getDirectConcurrently(Structure* expectedStructure, PropertyOffset) const;
     void putDirect(VM& vm, PropertyOffset offset, JSValue value) { locationForOffset(offset)->set(vm, this, value); }
     void putDirectWithoutBarrier(PropertyOffset offset, JSValue value) { locationForOffset(offset)->setWithoutWriteBarrier(value); }
@@ -1411,6 +1412,17 @@
 // past structure then it should be valid for any new structure. However, we may sometimes
 // shrink the butterfly when we are holding the Structure's ConcurrentJSLock, such as when we
 // flatten an object.
+ALWAYS_INLINE JSValue JSObject::getDirect(Concurrency concurrency, Structure* expectedStructure, PropertyOffset offset) const
+{
+    switch (concurrency) {
+    case Concurrency::MainThread:
+        ASSERT(!isCompilationThread() && !Thread::mayBeGCThread());
+        return getDirect(offset);
+    case Concurrency::ConcurrentThread:
+        return getDirectConcurrently(expectedStructure, offset);
+    }
+
+}
 inline JSValue JSObject::getDirectConcurrently(Structure* structure, PropertyOffset offset) const
 {
     ConcurrentJSLocker locker(structure->lock());

Modified: trunk/Source/_javascript_Core/runtime/Structure.h (292492 => 292493)


--- trunk/Source/_javascript_Core/runtime/Structure.h	2022-04-06 19:33:49 UTC (rev 292492)
+++ trunk/Source/_javascript_Core/runtime/Structure.h	2022-04-06 19:35:37 UTC (rev 292493)
@@ -26,6 +26,7 @@
 #pragma once
 
 #include "ClassInfo.h"
+#include "Concurrency.h"
 #include "ConcurrentJSLock.h"
 #include "DeletePropertySlot.h"
 #include "IndexingType.h"
@@ -512,6 +513,28 @@
 
     template<typename Functor>
     void forEachProperty(VM&, const Functor&);
+
+    ALWAYS_INLINE PropertyOffset get(VM& vm, Concurrency concurrency, UniquedStringImpl* uid, unsigned& attributes)
+    {
+        switch (concurrency) {
+        case Concurrency::MainThread:
+            ASSERT(!isCompilationThread() && !Thread::mayBeGCThread());
+            return get(vm, uid, attributes);
+        case Concurrency::ConcurrentThread:
+            return getConcurrently(uid, attributes);
+        }
+    }
+
+    ALWAYS_INLINE PropertyOffset get(VM& vm, Concurrency concurrency, UniquedStringImpl* uid)
+    {
+        switch (concurrency) {
+        case Concurrency::MainThread:
+            ASSERT(!isCompilationThread() && !Thread::mayBeGCThread());
+            return get(vm, uid);
+        case Concurrency::ConcurrentThread:
+            return getConcurrently(uid);
+        }
+    }
     
     PropertyOffset getConcurrently(UniquedStringImpl* uid);
     PropertyOffset getConcurrently(UniquedStringImpl* uid, unsigned& attributes);

Modified: trunk/Source/_javascript_Core/runtime/StructureRareData.cpp (292492 => 292493)


--- trunk/Source/_javascript_Core/runtime/StructureRareData.cpp	2022-04-06 19:33:49 UTC (rev 292492)
+++ trunk/Source/_javascript_Core/runtime/StructureRareData.cpp	2022-04-06 19:35:37 UTC (rev 292493)
@@ -190,11 +190,11 @@
             equivCondition = condition.attemptToMakeEquivalenceWithoutBarrier(vm);
 
             // The equivalence condition won't be watchable if we have already seen a replacement.
-            if (!equivCondition.isWatchable()) {
+            if (!equivCondition.isWatchable(PropertyCondition::MakeNoChanges)) {
                 giveUpOnSpecialPropertyCache(key);
                 return;
             }
-        } else if (!condition.isWatchable()) {
+        } else if (!condition.isWatchable(PropertyCondition::MakeNoChanges)) {
             giveUpOnSpecialPropertyCache(key);
             return;
         }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to