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;
}