diff options
author | Konstantin Tokarev <annulen@yandex.ru> | 2016-08-25 19:20:41 +0300 |
---|---|---|
committer | Konstantin Tokarev <annulen@yandex.ru> | 2017-02-02 12:30:55 +0000 |
commit | 6882a04fb36642862b11efe514251d32070c3d65 (patch) | |
tree | b7959826000b061fd5ccc7512035c7478742f7b0 /Source/JavaScriptCore/runtime/StructureRareData.cpp | |
parent | ab6df191029eeeb0b0f16f127d553265659f739e (diff) | |
download | qtwebkit-6882a04fb36642862b11efe514251d32070c3d65.tar.gz |
Imported QtWebKit TP3 (git b57bc6801f1876c3220d5a4bfea33d620d477443)
Change-Id: I3b1d8a2808782c9f34d50240000e20cb38d3680f
Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
Diffstat (limited to 'Source/JavaScriptCore/runtime/StructureRareData.cpp')
-rw-r--r-- | Source/JavaScriptCore/runtime/StructureRareData.cpp | 180 |
1 files changed, 161 insertions, 19 deletions
diff --git a/Source/JavaScriptCore/runtime/StructureRareData.cpp b/Source/JavaScriptCore/runtime/StructureRareData.cpp index 00880d32c..add963ce4 100644 --- a/Source/JavaScriptCore/runtime/StructureRareData.cpp +++ b/Source/JavaScriptCore/runtime/StructureRareData.cpp @@ -26,16 +26,19 @@ #include "config.h" #include "StructureRareData.h" +#include "AdaptiveInferredPropertyValueWatchpointBase.h" +#include "JSPropertyNameEnumerator.h" #include "JSString.h" -#include "Operations.h" +#include "JSCInlines.h" +#include "ObjectPropertyConditionSet.h" namespace JSC { -const ClassInfo StructureRareData::s_info = { "StructureRareData", 0, 0, 0, CREATE_METHOD_TABLE(StructureRareData) }; +const ClassInfo StructureRareData::s_info = { "StructureRareData", 0, 0, CREATE_METHOD_TABLE(StructureRareData) }; Structure* StructureRareData::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) { - return Structure::create(vm, globalObject, prototype, TypeInfo(CompoundType, StructureFlags), &s_info); + return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info()); } StructureRareData* StructureRareData::create(VM& vm, Structure* previous) @@ -45,39 +48,178 @@ StructureRareData* StructureRareData::create(VM& vm, Structure* previous) return rareData; } -StructureRareData* StructureRareData::clone(VM& vm, const StructureRareData* other) +void StructureRareData::destroy(JSCell* cell) { - StructureRareData* newRareData = new (NotNull, allocateCell<StructureRareData>(vm.heap)) StructureRareData(vm, other); - newRareData->finishCreation(vm); - return newRareData; + static_cast<StructureRareData*>(cell)->StructureRareData::~StructureRareData(); } StructureRareData::StructureRareData(VM& vm, Structure* previous) : JSCell(vm, vm.structureRareDataStructure.get()) + , m_giveUpOnObjectToStringValueCache(false) { if (previous) m_previous.set(vm, this, previous); } -StructureRareData::StructureRareData(VM& vm, const StructureRareData* other) - : JSCell(vm, other->structure()) -{ - if (other->previousID()) - m_previous.set(vm, this, other->previousID()); - if (other->objectToStringValue()) - m_objectToStringValue.set(vm, this, other->objectToStringValue()); -} - void StructureRareData::visitChildren(JSCell* cell, SlotVisitor& visitor) { StructureRareData* thisObject = jsCast<StructureRareData*>(cell); - ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); - ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); JSCell::visitChildren(thisObject, visitor); visitor.append(&thisObject->m_previous); visitor.append(&thisObject->m_objectToStringValue); - visitor.append(&thisObject->m_enumerationCache); + visitor.append(&thisObject->m_cachedPropertyNameEnumerator); +} + +JSPropertyNameEnumerator* StructureRareData::cachedPropertyNameEnumerator() const +{ + return m_cachedPropertyNameEnumerator.get(); +} + +void StructureRareData::setCachedPropertyNameEnumerator(VM& vm, JSPropertyNameEnumerator* enumerator) +{ + m_cachedPropertyNameEnumerator.set(vm, this, enumerator); +} + +// ----------- Object.prototype.toString() helper watchpoint classes ----------- + +class ObjectToStringAdaptiveInferredPropertyValueWatchpoint : public AdaptiveInferredPropertyValueWatchpointBase { +public: + typedef AdaptiveInferredPropertyValueWatchpointBase Base; + ObjectToStringAdaptiveInferredPropertyValueWatchpoint(const ObjectPropertyCondition&, StructureRareData*); + +private: + virtual void handleFire(const FireDetail&) override; + + StructureRareData* m_structureRareData; +}; + +class ObjectToStringAdaptiveStructureWatchpoint : public Watchpoint { +public: + ObjectToStringAdaptiveStructureWatchpoint(const ObjectPropertyCondition&, StructureRareData*); + + void install(); + +protected: + virtual void fireInternal(const FireDetail&) override; + +private: + ObjectPropertyCondition m_key; + StructureRareData* m_structureRareData; +}; + +void StructureRareData::setObjectToStringValue(ExecState* exec, VM& vm, Structure* ownStructure, JSString* value, PropertySlot toStringTagSymbolSlot) +{ + if (m_giveUpOnObjectToStringValueCache) + return; + + ObjectPropertyConditionSet conditionSet; + if (toStringTagSymbolSlot.isValue()) { + // We don't handle the own property case of Symbol.toStringTag because we would never know if a new + // object transitioning to the same structure had the same value stored in Symbol.toStringTag. + // Additionally, this is a super unlikely case anyway. + if (!toStringTagSymbolSlot.isCacheable() || toStringTagSymbolSlot.slotBase()->structure(vm) == ownStructure) + return; + + + // This will not create a condition for the current structure but that is good because we know the Symbol.toStringTag + // is not on the ownStructure so we will transisition if one is added and this cache will no longer be used. + conditionSet = generateConditionsForPrototypePropertyHit(vm, this, exec, ownStructure, toStringTagSymbolSlot.slotBase(), vm.propertyNames->toStringTagSymbol.impl()); + ASSERT(conditionSet.hasOneSlotBaseCondition()); + } else if (toStringTagSymbolSlot.isUnset()) + conditionSet = generateConditionsForPropertyMiss(vm, this, exec, ownStructure, vm.propertyNames->toStringTagSymbol.impl()); + else + return; + + if (!conditionSet.isValid()) { + m_giveUpOnObjectToStringValueCache = true; + return; + } + + ObjectPropertyCondition equivCondition; + for (const ObjectPropertyCondition& condition : conditionSet) { + if (condition.condition().kind() == PropertyCondition::Presence) { + ASSERT(isValidOffset(condition.offset())); + condition.object()->structure(vm)->startWatchingPropertyForReplacements(vm, condition.offset()); + equivCondition = condition.attemptToMakeEquivalenceWithoutBarrier(); + + // The equivalence condition won't be watchable if we have already seen a replacement. + if (!equivCondition.isWatchable()) { + m_giveUpOnObjectToStringValueCache = true; + return; + } + } else if (!condition.isWatchable()) { + m_giveUpOnObjectToStringValueCache = true; + return; + } + } + + ASSERT(conditionSet.structuresEnsureValidity()); + for (ObjectPropertyCondition condition : conditionSet) { + if (condition.condition().kind() == PropertyCondition::Presence) { + m_objectToStringAdaptiveInferredValueWatchpoint = std::make_unique<ObjectToStringAdaptiveInferredPropertyValueWatchpoint>(equivCondition, this); + m_objectToStringAdaptiveInferredValueWatchpoint->install(); + } else + m_objectToStringAdaptiveWatchpointSet.add(condition, this)->install(); + } + + m_objectToStringValue.set(vm, this, value); +} + +inline void StructureRareData::clearObjectToStringValue() +{ + m_objectToStringAdaptiveWatchpointSet.clear(); + m_objectToStringAdaptiveInferredValueWatchpoint.reset(); + m_objectToStringValue.clear(); +} + +// ------------- Methods for Object.prototype.toString() helper watchpoint classes -------------- + +ObjectToStringAdaptiveStructureWatchpoint::ObjectToStringAdaptiveStructureWatchpoint(const ObjectPropertyCondition& key, StructureRareData* structureRareData) + : m_key(key) + , m_structureRareData(structureRareData) +{ + RELEASE_ASSERT(key.watchingRequiresStructureTransitionWatchpoint()); + RELEASE_ASSERT(!key.watchingRequiresReplacementWatchpoint()); +} + +void ObjectToStringAdaptiveStructureWatchpoint::install() +{ + RELEASE_ASSERT(m_key.isWatchable()); + + m_key.object()->structure()->addTransitionWatchpoint(this); +} + +void ObjectToStringAdaptiveStructureWatchpoint::fireInternal(const FireDetail& detail) +{ + if (m_key.isWatchable(PropertyCondition::EnsureWatchability)) { + install(); + return; + } + + StringPrintStream out; + out.print("ObjectToStringValue Adaptation of ", m_key, " failed: ", detail); + + StringFireDetail stringDetail(out.toCString().data()); + + m_structureRareData->clearObjectToStringValue(); +} + +ObjectToStringAdaptiveInferredPropertyValueWatchpoint::ObjectToStringAdaptiveInferredPropertyValueWatchpoint(const ObjectPropertyCondition& key, StructureRareData* structureRareData) + : Base(key) + , m_structureRareData(structureRareData) +{ +} + +void ObjectToStringAdaptiveInferredPropertyValueWatchpoint::handleFire(const FireDetail& detail) +{ + StringPrintStream out; + out.print("Adaptation of ", key(), " failed: ", detail); + + StringFireDetail stringDetail(out.toCString().data()); + + m_structureRareData->clearObjectToStringValue(); } } // namespace JSC |