Separate storage of Structure::m_offset into transition and max offset
https://bugs.webkit.org/show_bug.cgi?id=206365
Reviewed by Saam Barati.
Right now, deleteProperty/removePropertyTransition causes a structure transition to uncacheable dictionary. Other transitions
assume that the transition offset (m_offset) is monotonically increasing. In order to support structure transitions for deletion that
do not involve turning into a dictionary (<https://bugs.webkit.org/show_bug.cgi?id=206430>), we first need to separate the transition
offset (the offset of the property that was added/deleted) from the maximum offset.
For example, suppose we have the following operations:
Structure 1 (pinned property table, transitionOffset = _, maxOffset = 2): x y z (delete y, assuming that deletion transitions have been added)
Structure 2 (transitionOffset = 1, maxOffset = 2): x _ z (add w)
Structure 3 (transitionOffset = 1, maxOffset = 2): x w z
Note that without splitting the two, Structures 2/3 would be impossible to represent.
This change:
We split the existing Structure::m_offset into two 16-bit fields, transitionOffset and maxOffset, and put them in 32-bit rare data fields if they overflow. We also rename _inPrevious fields to
transition_ and lastOffset to maxOffset to make the code more clear.
* runtime/ClonedArguments.cpp:
(JSC::ClonedArguments::createStructure):
* runtime/JSObject.cpp:
(JSC::JSObject::markAuxiliaryAndVisitOutOfLineProperties):
(JSC::JSObject::visitButterflyImpl):
* runtime/JSObject.h:
* runtime/JSObjectInlines.h:
(JSC::JSObject::prepareToPutDirectWithoutTransition):
* runtime/ObjectInitializationScope.cpp:
(JSC::ObjectInitializationScope::verifyPropertiesAreInitialized):
* runtime/PropertyOffset.h:
(JSC::numberOfOutOfLineSlotsForMaxOffset):
(JSC::numberOfSlotsForMaxOffset):
(JSC::numberOfOutOfLineSlotsForLastOffset): Deleted.
(JSC::numberOfSlotsForLastOffset): Deleted.
* runtime/Structure.cpp:
(JSC::StructureTransitionTable::contains const):
(JSC::StructureTransitionTable::get const):
(JSC::StructureTransitionTable::add):
(JSC::Structure::Structure):
(JSC::Structure::create):
(JSC::Structure::materializePropertyTable):
(JSC::Structure::addPropertyTransitionToExistingStructureImpl):
(JSC::Structure::addNewPropertyTransition):
(JSC::Structure::changePrototypeTransition):
(JSC::Structure::attributeChangeTransition):
(JSC::Structure::toDictionaryTransition):
(JSC::Structure::nonPropertyTransitionSlow):
(JSC::Structure::flattenDictionaryStructure):
(JSC::Structure::pin):
(JSC::Structure::pinForCaching):
(JSC::Structure::add):
* runtime/Structure.h:
* runtime/StructureInlines.h:
(JSC::Structure::forEachPropertyConcurrently):
(JSC::Structure::checkOffsetConsistency const):
(JSC::Structure::add):
* runtime/StructureRareData.cpp:
(JSC::StructureRareData::StructureRareData):
* runtime/StructureRareData.h:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@254760 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index c7548b4..e50c4c7 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,68 @@
+2020-01-17 Justin Michaud <justin_michaud@apple.com>
+
+ Separate storage of Structure::m_offset into transition and max offset
+ https://bugs.webkit.org/show_bug.cgi?id=206365
+
+ Reviewed by Saam Barati.
+
+ Right now, deleteProperty/removePropertyTransition causes a structure transition to uncacheable dictionary. Other transitions
+ assume that the transition offset (m_offset) is monotonically increasing. In order to support structure transitions for deletion that
+ do not involve turning into a dictionary (<https://bugs.webkit.org/show_bug.cgi?id=206430>), we first need to separate the transition
+ offset (the offset of the property that was added/deleted) from the maximum offset.
+
+ For example, suppose we have the following operations:
+ Structure 1 (pinned property table, transitionOffset = _, maxOffset = 2): x y z (delete y, assuming that deletion transitions have been added)
+ Structure 2 (transitionOffset = 1, maxOffset = 2): x _ z (add w)
+ Structure 3 (transitionOffset = 1, maxOffset = 2): x w z
+
+ Note that without splitting the two, Structures 2/3 would be impossible to represent.
+
+ This change:
+
+ We split the existing Structure::m_offset into two 16-bit fields, transitionOffset and maxOffset, and put them in 32-bit rare data fields if they overflow. We also rename _inPrevious fields to
+ transition_ and lastOffset to maxOffset to make the code more clear.
+
+ * runtime/ClonedArguments.cpp:
+ (JSC::ClonedArguments::createStructure):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::markAuxiliaryAndVisitOutOfLineProperties):
+ (JSC::JSObject::visitButterflyImpl):
+ * runtime/JSObject.h:
+ * runtime/JSObjectInlines.h:
+ (JSC::JSObject::prepareToPutDirectWithoutTransition):
+ * runtime/ObjectInitializationScope.cpp:
+ (JSC::ObjectInitializationScope::verifyPropertiesAreInitialized):
+ * runtime/PropertyOffset.h:
+ (JSC::numberOfOutOfLineSlotsForMaxOffset):
+ (JSC::numberOfSlotsForMaxOffset):
+ (JSC::numberOfOutOfLineSlotsForLastOffset): Deleted.
+ (JSC::numberOfSlotsForLastOffset): Deleted.
+ * runtime/Structure.cpp:
+ (JSC::StructureTransitionTable::contains const):
+ (JSC::StructureTransitionTable::get const):
+ (JSC::StructureTransitionTable::add):
+ (JSC::Structure::Structure):
+ (JSC::Structure::create):
+ (JSC::Structure::materializePropertyTable):
+ (JSC::Structure::addPropertyTransitionToExistingStructureImpl):
+ (JSC::Structure::addNewPropertyTransition):
+ (JSC::Structure::changePrototypeTransition):
+ (JSC::Structure::attributeChangeTransition):
+ (JSC::Structure::toDictionaryTransition):
+ (JSC::Structure::nonPropertyTransitionSlow):
+ (JSC::Structure::flattenDictionaryStructure):
+ (JSC::Structure::pin):
+ (JSC::Structure::pinForCaching):
+ (JSC::Structure::add):
+ * runtime/Structure.h:
+ * runtime/StructureInlines.h:
+ (JSC::Structure::forEachPropertyConcurrently):
+ (JSC::Structure::checkOffsetConsistency const):
+ (JSC::Structure::add):
+ * runtime/StructureRareData.cpp:
+ (JSC::StructureRareData::StructureRareData):
+ * runtime/StructureRareData.h:
+
2020-01-17 Alexey Shvayka <shvaikalesh@gmail.com>
JSON.parse should lookup prototype chains during revival
diff --git a/Source/JavaScriptCore/runtime/ClonedArguments.cpp b/Source/JavaScriptCore/runtime/ClonedArguments.cpp
index 1ae3f62..96a3635 100644
--- a/Source/JavaScriptCore/runtime/ClonedArguments.cpp
+++ b/Source/JavaScriptCore/runtime/ClonedArguments.cpp
@@ -153,9 +153,9 @@
Structure* structure = Structure::create(vm, globalObject, prototype, TypeInfo(ClonedArgumentsType, StructureFlags), info(), indexingType);
structure->addPropertyWithoutTransition(
vm, vm.propertyNames->length, static_cast<unsigned>(PropertyAttribute::DontEnum),
- [&] (const GCSafeConcurrentJSLocker&, PropertyOffset offset, PropertyOffset newLastOffset) {
+ [&] (const GCSafeConcurrentJSLocker&, PropertyOffset offset, PropertyOffset newMaxOffset) {
RELEASE_ASSERT(offset == clonedArgumentsLengthPropertyOffset);
- structure->setLastOffset(newLastOffset);
+ structure->setMaxOffset(vm, newMaxOffset);
});
return structure;
}
diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp
index 64f95e1..d67ba8d 100644
--- a/Source/JavaScriptCore/runtime/JSObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSObject.cpp
@@ -92,7 +92,7 @@
}
}
-ALWAYS_INLINE void JSObject::markAuxiliaryAndVisitOutOfLineProperties(SlotVisitor& visitor, Butterfly* butterfly, Structure* structure, PropertyOffset lastOffset)
+ALWAYS_INLINE void JSObject::markAuxiliaryAndVisitOutOfLineProperties(SlotVisitor& visitor, Butterfly* butterfly, Structure* structure, PropertyOffset maxOffset)
{
// We call this when we found everything without races.
ASSERT(structure);
@@ -113,13 +113,13 @@
preCapacity = 0;
HeapCell* base = bitwise_cast<HeapCell*>(
- butterfly->base(preCapacity, Structure::outOfLineCapacity(lastOffset)));
+ butterfly->base(preCapacity, Structure::outOfLineCapacity(maxOffset)));
ASSERT(Heap::heap(base) == visitor.heap());
visitor.markAuxiliary(base);
- unsigned outOfLineSize = Structure::outOfLineSize(lastOffset);
+ unsigned outOfLineSize = Structure::outOfLineSize(maxOffset);
visitor.appendValuesHidden(butterfly->propertyStorage() - outOfLineSize, outOfLineSize);
}
@@ -138,7 +138,7 @@
Butterfly* butterfly;
Structure* structure;
- PropertyOffset lastOffset;
+ PropertyOffset maxOffset;
auto visitElements = [&] (IndexingType indexingMode) {
switch (indexingMode) {
@@ -159,9 +159,9 @@
if (visitor.mutatorIsStopped()) {
butterfly = this->butterfly();
structure = this->structure(vm);
- lastOffset = structure->lastOffset();
+ maxOffset = structure->maxOffset();
- markAuxiliaryAndVisitOutOfLineProperties(visitor, butterfly, structure, lastOffset);
+ markAuxiliaryAndVisitOutOfLineProperties(visitor, butterfly, structure, maxOffset);
visitElements(structure->indexingMode());
return structure;
@@ -174,7 +174,7 @@
//
// object->structure = nuke(object->structure)
// object->butterfly = newButterfly
- // structure->m_offset = newLastOffset
+ // structure->m_offset = newMaxOffset
// object->structure = newStructure
//
// It's OK to skip this when reallocating the butterfly in a way that does not affect the m_offset.
@@ -230,143 +230,143 @@
// the collector reads the size early and late as well. Lets consider the interleaving of the
// mutator changing the size without changing the structure:
//
- // NukeStructure ChangeButterfly ChangeLastOffset RestoreStructure
+ // NukeStructure ChangeButterfly ChangeMaxOffset RestoreStructure
//
// Meanwhile the collector does:
//
- // ReadStructureEarly ReadLastOffsetEarly ReadButterfly ReadStructureLate ReadLastOffsetLate
+ // ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ReadStructureLate ReadMaxOffsetLate
//
// The collector can detect races by not only comparing the early structure to the late structure
// (which will be the same before and after the algorithm runs) but also by comparing the early and
- // late lastOffsets. Note: the IGNORE proofs do not cite all of the reasons why the collector will
+ // late maxOffsets. Note: the IGNORE proofs do not cite all of the reasons why the collector will
// ignore the case, since we only need to identify one to say that we're in the ignore case.
//
- // NukeStructure ChangeButterfly ChangeLastOffset RestoreStructure ReadStructureEarly ReadLastOffsetEarly ReadButterfly ReadStructureLate ReadLastOffsetLate: AFTER, trivially
- // NukeStructure ChangeButterfly ChangeLastOffset ReadStructureEarly RestoreStructure ReadLastOffsetEarly ReadButterfly ReadStructureLate ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ChangeButterfly ChangeLastOffset ReadStructureEarly ReadLastOffsetEarly RestoreStructure ReadButterfly ReadStructureLate ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ChangeButterfly ChangeLastOffset ReadStructureEarly ReadLastOffsetEarly ReadButterfly RestoreStructure ReadStructureLate ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ChangeButterfly ChangeLastOffset ReadStructureEarly ReadLastOffsetEarly ReadButterfly ReadStructureLate RestoreStructure ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ChangeButterfly ChangeLastOffset ReadStructureEarly ReadLastOffsetEarly ReadButterfly ReadStructureLate ReadLastOffsetLate RestoreStructure: IGNORE, read nuked structure early
- // NukeStructure ChangeButterfly ReadStructureEarly ChangeLastOffset RestoreStructure ReadLastOffsetEarly ReadButterfly ReadStructureLate ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ChangeButterfly ReadStructureEarly ChangeLastOffset ReadLastOffsetEarly RestoreStructure ReadButterfly ReadStructureLate ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ChangeButterfly ReadStructureEarly ChangeLastOffset ReadLastOffsetEarly ReadButterfly RestoreStructure ReadStructureLate ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ChangeButterfly ReadStructureEarly ChangeLastOffset ReadLastOffsetEarly ReadButterfly ReadStructureLate RestoreStructure ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ChangeButterfly ReadStructureEarly ChangeLastOffset ReadLastOffsetEarly ReadButterfly ReadStructureLate ReadLastOffsetLate RestoreStructure: IGNORE, read nuked structure early
- // NukeStructure ChangeButterfly ReadStructureEarly ReadLastOffsetEarly ChangeLastOffset RestoreStructure ReadButterfly ReadStructureLate ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ChangeButterfly ReadStructureEarly ReadLastOffsetEarly ChangeLastOffset ReadButterfly RestoreStructure ReadStructureLate ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ChangeButterfly ReadStructureEarly ReadLastOffsetEarly ChangeLastOffset ReadButterfly ReadStructureLate RestoreStructure ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ChangeButterfly ReadStructureEarly ReadLastOffsetEarly ChangeLastOffset ReadButterfly ReadStructureLate ReadLastOffsetLate RestoreStructure: IGNORE, read nuked structure early
- // NukeStructure ChangeButterfly ReadStructureEarly ReadLastOffsetEarly ReadButterfly ChangeLastOffset RestoreStructure ReadStructureLate ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ChangeButterfly ReadStructureEarly ReadLastOffsetEarly ReadButterfly ChangeLastOffset ReadStructureLate RestoreStructure ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ChangeButterfly ReadStructureEarly ReadLastOffsetEarly ReadButterfly ChangeLastOffset ReadStructureLate ReadLastOffsetLate RestoreStructure: IGNORE, read nuked structure early
- // NukeStructure ChangeButterfly ReadStructureEarly ReadLastOffsetEarly ReadButterfly ReadStructureLate ChangeLastOffset RestoreStructure ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ChangeButterfly ReadStructureEarly ReadLastOffsetEarly ReadButterfly ReadStructureLate ChangeLastOffset ReadLastOffsetLate RestoreStructure: IGNORE, read nuked structure early
- // NukeStructure ChangeButterfly ReadStructureEarly ReadLastOffsetEarly ReadButterfly ReadStructureLate ReadLastOffsetLate ChangeLastOffset RestoreStructure: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ChangeButterfly ChangeLastOffset RestoreStructure ReadLastOffsetEarly ReadButterfly ReadStructureLate ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ChangeButterfly ChangeLastOffset ReadLastOffsetEarly RestoreStructure ReadButterfly ReadStructureLate ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ChangeButterfly ChangeLastOffset ReadLastOffsetEarly ReadButterfly RestoreStructure ReadStructureLate ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ChangeButterfly ChangeLastOffset ReadLastOffsetEarly ReadButterfly ReadStructureLate RestoreStructure ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ChangeButterfly ChangeLastOffset ReadLastOffsetEarly ReadButterfly ReadStructureLate ReadLastOffsetLate RestoreStructure: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ChangeButterfly ReadLastOffsetEarly ChangeLastOffset RestoreStructure ReadButterfly ReadStructureLate ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ChangeButterfly ReadLastOffsetEarly ChangeLastOffset ReadButterfly RestoreStructure ReadStructureLate ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ChangeButterfly ReadLastOffsetEarly ChangeLastOffset ReadButterfly ReadStructureLate RestoreStructure ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ChangeButterfly ReadLastOffsetEarly ChangeLastOffset ReadButterfly ReadStructureLate ReadLastOffsetLate RestoreStructure: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ChangeButterfly ReadLastOffsetEarly ReadButterfly ChangeLastOffset RestoreStructure ReadStructureLate ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ChangeButterfly ReadLastOffsetEarly ReadButterfly ChangeLastOffset ReadStructureLate RestoreStructure ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ChangeButterfly ReadLastOffsetEarly ReadButterfly ChangeLastOffset ReadStructureLate ReadLastOffsetLate RestoreStructure: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ChangeButterfly ReadLastOffsetEarly ReadButterfly ReadStructureLate ChangeLastOffset RestoreStructure ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ChangeButterfly ReadLastOffsetEarly ReadButterfly ReadStructureLate ChangeLastOffset ReadLastOffsetLate RestoreStructure: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ChangeButterfly ReadLastOffsetEarly ReadButterfly ReadStructureLate ReadLastOffsetLate ChangeLastOffset RestoreStructure: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ReadLastOffsetEarly ChangeButterfly ChangeLastOffset RestoreStructure ReadButterfly ReadStructureLate ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ReadLastOffsetEarly ChangeButterfly ChangeLastOffset ReadButterfly RestoreStructure ReadStructureLate ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ReadLastOffsetEarly ChangeButterfly ChangeLastOffset ReadButterfly ReadStructureLate RestoreStructure ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ReadLastOffsetEarly ChangeButterfly ChangeLastOffset ReadButterfly ReadStructureLate ReadLastOffsetLate RestoreStructure: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ReadLastOffsetEarly ChangeButterfly ReadButterfly ChangeLastOffset RestoreStructure ReadStructureLate ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ReadLastOffsetEarly ChangeButterfly ReadButterfly ChangeLastOffset ReadStructureLate RestoreStructure ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ReadLastOffsetEarly ChangeButterfly ReadButterfly ChangeLastOffset ReadStructureLate ReadLastOffsetLate RestoreStructure: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ReadLastOffsetEarly ChangeButterfly ReadButterfly ReadStructureLate ChangeLastOffset RestoreStructure ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ReadLastOffsetEarly ChangeButterfly ReadButterfly ReadStructureLate ChangeLastOffset ReadLastOffsetLate RestoreStructure: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ReadLastOffsetEarly ChangeButterfly ReadButterfly ReadStructureLate ReadLastOffsetLate ChangeLastOffset RestoreStructure: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ReadLastOffsetEarly ReadButterfly ChangeButterfly ChangeLastOffset RestoreStructure ReadStructureLate ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ReadLastOffsetEarly ReadButterfly ChangeButterfly ChangeLastOffset ReadStructureLate RestoreStructure ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ReadLastOffsetEarly ReadButterfly ChangeButterfly ChangeLastOffset ReadStructureLate ReadLastOffsetLate RestoreStructure: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ReadLastOffsetEarly ReadButterfly ChangeButterfly ReadStructureLate ChangeLastOffset RestoreStructure ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ReadLastOffsetEarly ReadButterfly ChangeButterfly ReadStructureLate ChangeLastOffset ReadLastOffsetLate RestoreStructure: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ReadLastOffsetEarly ReadButterfly ChangeButterfly ReadStructureLate ReadLastOffsetLate ChangeLastOffset RestoreStructure: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ReadLastOffsetEarly ReadButterfly ReadStructureLate ChangeButterfly ChangeLastOffset RestoreStructure ReadLastOffsetLate: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ReadLastOffsetEarly ReadButterfly ReadStructureLate ChangeButterfly ChangeLastOffset ReadLastOffsetLate RestoreStructure: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ReadLastOffsetEarly ReadButterfly ReadStructureLate ChangeButterfly ReadLastOffsetLate ChangeLastOffset RestoreStructure: IGNORE, read nuked structure early
- // NukeStructure ReadStructureEarly ReadLastOffsetEarly ReadButterfly ReadStructureLate ReadLastOffsetLate ChangeButterfly ChangeLastOffset RestoreStructure: IGNORE, read nuked structure early
- // ReadStructureEarly NukeStructure ChangeButterfly ChangeLastOffset RestoreStructure ReadLastOffsetEarly ReadButterfly ReadStructureLate ReadLastOffsetLate: AFTER, the ReadStructureEarly sees the same structure as after and everything else runs after.
- // ReadStructureEarly NukeStructure ChangeButterfly ChangeLastOffset ReadLastOffsetEarly RestoreStructure ReadButterfly ReadStructureLate ReadLastOffsetLate: AFTER, as above and the ReadLastOffsetEarly sees the lastOffset after.
- // ReadStructureEarly NukeStructure ChangeButterfly ChangeLastOffset ReadLastOffsetEarly ReadButterfly RestoreStructure ReadStructureLate ReadLastOffsetLate: AFTER, as above and the ReadButterfly sees the right butterfly after.
- // ReadStructureEarly NukeStructure ChangeButterfly ChangeLastOffset ReadLastOffsetEarly ReadButterfly ReadStructureLate RestoreStructure ReadLastOffsetLate: IGNORE, read nuked structure late
- // ReadStructureEarly NukeStructure ChangeButterfly ChangeLastOffset ReadLastOffsetEarly ReadButterfly ReadStructureLate ReadLastOffsetLate RestoreStructure: IGNORE, read nuked structure late
- // ReadStructureEarly NukeStructure ChangeButterfly ReadLastOffsetEarly ChangeLastOffset RestoreStructure ReadButterfly ReadStructureLate ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ChangeButterfly ReadLastOffsetEarly ChangeLastOffset ReadButterfly RestoreStructure ReadStructureLate ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ChangeButterfly ReadLastOffsetEarly ChangeLastOffset ReadButterfly ReadStructureLate RestoreStructure ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ChangeButterfly ReadLastOffsetEarly ChangeLastOffset ReadButterfly ReadStructureLate ReadLastOffsetLate RestoreStructure: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ChangeButterfly ReadLastOffsetEarly ReadButterfly ChangeLastOffset RestoreStructure ReadStructureLate ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ChangeButterfly ReadLastOffsetEarly ReadButterfly ChangeLastOffset ReadStructureLate RestoreStructure ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ChangeButterfly ReadLastOffsetEarly ReadButterfly ChangeLastOffset ReadStructureLate ReadLastOffsetLate RestoreStructure: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ChangeButterfly ReadLastOffsetEarly ReadButterfly ReadStructureLate ChangeLastOffset RestoreStructure ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ChangeButterfly ReadLastOffsetEarly ReadButterfly ReadStructureLate ChangeLastOffset ReadLastOffsetLate RestoreStructure: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ChangeButterfly ReadLastOffsetEarly ReadButterfly ReadStructureLate ReadLastOffsetLate ChangeLastOffset RestoreStructure: IGNORE, read nuked structure late
- // ReadStructureEarly NukeStructure ReadLastOffsetEarly ChangeButterfly ChangeLastOffset RestoreStructure ReadButterfly ReadStructureLate ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ReadLastOffsetEarly ChangeButterfly ChangeLastOffset ReadButterfly RestoreStructure ReadStructureLate ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ReadLastOffsetEarly ChangeButterfly ChangeLastOffset ReadButterfly ReadStructureLate RestoreStructure ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ReadLastOffsetEarly ChangeButterfly ChangeLastOffset ReadButterfly ReadStructureLate ReadLastOffsetLate RestoreStructure: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ReadLastOffsetEarly ChangeButterfly ReadButterfly ChangeLastOffset RestoreStructure ReadStructureLate ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ReadLastOffsetEarly ChangeButterfly ReadButterfly ChangeLastOffset ReadStructureLate RestoreStructure ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ReadLastOffsetEarly ChangeButterfly ReadButterfly ChangeLastOffset ReadStructureLate ReadLastOffsetLate RestoreStructure: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ReadLastOffsetEarly ChangeButterfly ReadButterfly ReadStructureLate ChangeLastOffset RestoreStructure ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ReadLastOffsetEarly ChangeButterfly ReadButterfly ReadStructureLate ChangeLastOffset ReadLastOffsetLate RestoreStructure: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ReadLastOffsetEarly ChangeButterfly ReadButterfly ReadStructureLate ReadLastOffsetLate ChangeLastOffset RestoreStructure: IGNORE, read nuked structure late
- // ReadStructureEarly NukeStructure ReadLastOffsetEarly ReadButterfly ChangeButterfly ChangeLastOffset RestoreStructure ReadStructureLate ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ReadLastOffsetEarly ReadButterfly ChangeButterfly ChangeLastOffset ReadStructureLate RestoreStructure ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ReadLastOffsetEarly ReadButterfly ChangeButterfly ChangeLastOffset ReadStructureLate ReadLastOffsetLate RestoreStructure: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ReadLastOffsetEarly ReadButterfly ChangeButterfly ReadStructureLate ChangeLastOffset RestoreStructure ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ReadLastOffsetEarly ReadButterfly ChangeButterfly ReadStructureLate ChangeLastOffset ReadLastOffsetLate RestoreStructure: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ReadLastOffsetEarly ReadButterfly ChangeButterfly ReadStructureLate ReadLastOffsetLate ChangeLastOffset RestoreStructure: IGNORE, read nuked structure late
- // ReadStructureEarly NukeStructure ReadLastOffsetEarly ReadButterfly ReadStructureLate ChangeButterfly ChangeLastOffset RestoreStructure ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ReadLastOffsetEarly ReadButterfly ReadStructureLate ChangeButterfly ChangeLastOffset ReadLastOffsetLate RestoreStructure: IGNORE, read different offsets
- // ReadStructureEarly NukeStructure ReadLastOffsetEarly ReadButterfly ReadStructureLate ChangeButterfly ReadLastOffsetLate ChangeLastOffset RestoreStructure: IGNORE, read nuked structure late
- // ReadStructureEarly NukeStructure ReadLastOffsetEarly ReadButterfly ReadStructureLate ReadLastOffsetLate ChangeButterfly ChangeLastOffset RestoreStructure: IGNORE, read nuked structure late
- // ReadStructureEarly ReadLastOffsetEarly NukeStructure ChangeButterfly ChangeLastOffset RestoreStructure ReadButterfly ReadStructureLate ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly ReadLastOffsetEarly NukeStructure ChangeButterfly ChangeLastOffset ReadButterfly RestoreStructure ReadStructureLate ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly ReadLastOffsetEarly NukeStructure ChangeButterfly ChangeLastOffset ReadButterfly ReadStructureLate RestoreStructure ReadLastOffsetLate: IGNORE, read nuked structure late
- // ReadStructureEarly ReadLastOffsetEarly NukeStructure ChangeButterfly ChangeLastOffset ReadButterfly ReadStructureLate ReadLastOffsetLate RestoreStructure: IGNORE, read nuked structure late
- // ReadStructureEarly ReadLastOffsetEarly NukeStructure ChangeButterfly ReadButterfly ChangeLastOffset RestoreStructure ReadStructureLate ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly ReadLastOffsetEarly NukeStructure ChangeButterfly ReadButterfly ChangeLastOffset ReadStructureLate RestoreStructure ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly ReadLastOffsetEarly NukeStructure ChangeButterfly ReadButterfly ChangeLastOffset ReadStructureLate ReadLastOffsetLate RestoreStructure: IGNORE, read different offsets
- // ReadStructureEarly ReadLastOffsetEarly NukeStructure ChangeButterfly ReadButterfly ReadStructureLate ChangeLastOffset RestoreStructure ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly ReadLastOffsetEarly NukeStructure ChangeButterfly ReadButterfly ReadStructureLate ChangeLastOffset ReadLastOffsetLate RestoreStructure: IGNORE, read different offsets
- // ReadStructureEarly ReadLastOffsetEarly NukeStructure ChangeButterfly ReadButterfly ReadStructureLate ReadLastOffsetLate ChangeLastOffset RestoreStructure: IGNORE, read nuked structure late
- // ReadStructureEarly ReadLastOffsetEarly NukeStructure ReadButterfly ChangeButterfly ChangeLastOffset RestoreStructure ReadStructureLate ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly ReadLastOffsetEarly NukeStructure ReadButterfly ChangeButterfly ChangeLastOffset ReadStructureLate RestoreStructure ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly ReadLastOffsetEarly NukeStructure ReadButterfly ChangeButterfly ChangeLastOffset ReadStructureLate ReadLastOffsetLate RestoreStructure: IGNORE, read different offsets
- // ReadStructureEarly ReadLastOffsetEarly NukeStructure ReadButterfly ChangeButterfly ReadStructureLate ChangeLastOffset RestoreStructure ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly ReadLastOffsetEarly NukeStructure ReadButterfly ChangeButterfly ReadStructureLate ChangeLastOffset ReadLastOffsetLate RestoreStructure: IGNORE, read different offsets
- // ReadStructureEarly ReadLastOffsetEarly NukeStructure ReadButterfly ChangeButterfly ReadStructureLate ReadLastOffsetLate ChangeLastOffset RestoreStructure: IGNORE, read nuked structure late
- // ReadStructureEarly ReadLastOffsetEarly NukeStructure ReadButterfly ReadStructureLate ChangeButterfly ChangeLastOffset RestoreStructure ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly ReadLastOffsetEarly NukeStructure ReadButterfly ReadStructureLate ChangeButterfly ChangeLastOffset ReadLastOffsetLate RestoreStructure: IGNORE, read nuked structure late
- // ReadStructureEarly ReadLastOffsetEarly NukeStructure ReadButterfly ReadStructureLate ChangeButterfly ReadLastOffsetLate ChangeLastOffset RestoreStructure: IGNORE, read nuked structure late
- // ReadStructureEarly ReadLastOffsetEarly NukeStructure ReadButterfly ReadStructureLate ReadLastOffsetLate ChangeButterfly ChangeLastOffset RestoreStructure: IGNORE, read nuked structure late
- // ReadStructureEarly ReadLastOffsetEarly ReadButterfly NukeStructure ChangeButterfly ChangeLastOffset RestoreStructure ReadStructureLate ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly ReadLastOffsetEarly ReadButterfly NukeStructure ChangeButterfly ChangeLastOffset ReadStructureLate RestoreStructure ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly ReadLastOffsetEarly ReadButterfly NukeStructure ChangeButterfly ChangeLastOffset ReadStructureLate ReadLastOffsetLate RestoreStructure: IGNORE, read different offsets
- // ReadStructureEarly ReadLastOffsetEarly ReadButterfly NukeStructure ChangeButterfly ReadStructureLate ChangeLastOffset RestoreStructure ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly ReadLastOffsetEarly ReadButterfly NukeStructure ChangeButterfly ReadStructureLate ChangeLastOffset ReadLastOffsetLate RestoreStructure: IGNORE, read different offsets
- // ReadStructureEarly ReadLastOffsetEarly ReadButterfly NukeStructure ChangeButterfly ReadStructureLate ReadLastOffsetLate ChangeLastOffset RestoreStructure: IGNORE, read nuked structure late
- // ReadStructureEarly ReadLastOffsetEarly ReadButterfly NukeStructure ReadStructureLate ChangeButterfly ChangeLastOffset RestoreStructure ReadLastOffsetLate: IGNORE, read nuked structure late
- // ReadStructureEarly ReadLastOffsetEarly ReadButterfly NukeStructure ReadStructureLate ChangeButterfly ChangeLastOffset ReadLastOffsetLate RestoreStructure: IGNORE, read nuked structure late
- // ReadStructureEarly ReadLastOffsetEarly ReadButterfly NukeStructure ReadStructureLate ChangeButterfly ReadLastOffsetLate ChangeLastOffset RestoreStructure: IGNORE, read nuked structure late
- // ReadStructureEarly ReadLastOffsetEarly ReadButterfly NukeStructure ReadStructureLate ReadLastOffsetLate ChangeButterfly ChangeLastOffset RestoreStructure: IGNORE, read nuked structure late
- // ReadStructureEarly ReadLastOffsetEarly ReadButterfly ReadStructureLate NukeStructure ChangeButterfly ChangeLastOffset RestoreStructure ReadLastOffsetLate: IGNORE, read different offsets
- // ReadStructureEarly ReadLastOffsetEarly ReadButterfly ReadStructureLate NukeStructure ChangeButterfly ChangeLastOffset ReadLastOffsetLate RestoreStructure: IGNORE, read different offsets
- // ReadStructureEarly ReadLastOffsetEarly ReadButterfly ReadStructureLate NukeStructure ChangeButterfly ReadLastOffsetLate ChangeLastOffset RestoreStructure: BEFORE, reads the offset before, everything else happens before
- // ReadStructureEarly ReadLastOffsetEarly ReadButterfly ReadStructureLate NukeStructure ReadLastOffsetLate ChangeButterfly ChangeLastOffset RestoreStructure: BEFORE, reads the offset before, everything else happens before
- // ReadStructureEarly ReadLastOffsetEarly ReadButterfly ReadStructureLate ReadLastOffsetLate NukeStructure ChangeButterfly ChangeLastOffset RestoreStructure: BEFORE, trivially
+ // NukeStructure ChangeButterfly ChangeMaxOffset RestoreStructure ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ReadStructureLate ReadMaxOffsetLate: AFTER, trivially
+ // NukeStructure ChangeButterfly ChangeMaxOffset ReadStructureEarly RestoreStructure ReadMaxOffsetEarly ReadButterfly ReadStructureLate ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ChangeButterfly ChangeMaxOffset ReadStructureEarly ReadMaxOffsetEarly RestoreStructure ReadButterfly ReadStructureLate ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ChangeButterfly ChangeMaxOffset ReadStructureEarly ReadMaxOffsetEarly ReadButterfly RestoreStructure ReadStructureLate ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ChangeButterfly ChangeMaxOffset ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ReadStructureLate RestoreStructure ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ChangeButterfly ChangeMaxOffset ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ReadStructureLate ReadMaxOffsetLate RestoreStructure: IGNORE, read nuked structure early
+ // NukeStructure ChangeButterfly ReadStructureEarly ChangeMaxOffset RestoreStructure ReadMaxOffsetEarly ReadButterfly ReadStructureLate ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ChangeButterfly ReadStructureEarly ChangeMaxOffset ReadMaxOffsetEarly RestoreStructure ReadButterfly ReadStructureLate ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ChangeButterfly ReadStructureEarly ChangeMaxOffset ReadMaxOffsetEarly ReadButterfly RestoreStructure ReadStructureLate ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ChangeButterfly ReadStructureEarly ChangeMaxOffset ReadMaxOffsetEarly ReadButterfly ReadStructureLate RestoreStructure ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ChangeButterfly ReadStructureEarly ChangeMaxOffset ReadMaxOffsetEarly ReadButterfly ReadStructureLate ReadMaxOffsetLate RestoreStructure: IGNORE, read nuked structure early
+ // NukeStructure ChangeButterfly ReadStructureEarly ReadMaxOffsetEarly ChangeMaxOffset RestoreStructure ReadButterfly ReadStructureLate ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ChangeButterfly ReadStructureEarly ReadMaxOffsetEarly ChangeMaxOffset ReadButterfly RestoreStructure ReadStructureLate ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ChangeButterfly ReadStructureEarly ReadMaxOffsetEarly ChangeMaxOffset ReadButterfly ReadStructureLate RestoreStructure ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ChangeButterfly ReadStructureEarly ReadMaxOffsetEarly ChangeMaxOffset ReadButterfly ReadStructureLate ReadMaxOffsetLate RestoreStructure: IGNORE, read nuked structure early
+ // NukeStructure ChangeButterfly ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ChangeMaxOffset RestoreStructure ReadStructureLate ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ChangeButterfly ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ChangeMaxOffset ReadStructureLate RestoreStructure ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ChangeButterfly ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ChangeMaxOffset ReadStructureLate ReadMaxOffsetLate RestoreStructure: IGNORE, read nuked structure early
+ // NukeStructure ChangeButterfly ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ReadStructureLate ChangeMaxOffset RestoreStructure ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ChangeButterfly ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ReadStructureLate ChangeMaxOffset ReadMaxOffsetLate RestoreStructure: IGNORE, read nuked structure early
+ // NukeStructure ChangeButterfly ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ReadStructureLate ReadMaxOffsetLate ChangeMaxOffset RestoreStructure: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ChangeButterfly ChangeMaxOffset RestoreStructure ReadMaxOffsetEarly ReadButterfly ReadStructureLate ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ChangeButterfly ChangeMaxOffset ReadMaxOffsetEarly RestoreStructure ReadButterfly ReadStructureLate ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ChangeButterfly ChangeMaxOffset ReadMaxOffsetEarly ReadButterfly RestoreStructure ReadStructureLate ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ChangeButterfly ChangeMaxOffset ReadMaxOffsetEarly ReadButterfly ReadStructureLate RestoreStructure ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ChangeButterfly ChangeMaxOffset ReadMaxOffsetEarly ReadButterfly ReadStructureLate ReadMaxOffsetLate RestoreStructure: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ChangeButterfly ReadMaxOffsetEarly ChangeMaxOffset RestoreStructure ReadButterfly ReadStructureLate ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ChangeButterfly ReadMaxOffsetEarly ChangeMaxOffset ReadButterfly RestoreStructure ReadStructureLate ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ChangeButterfly ReadMaxOffsetEarly ChangeMaxOffset ReadButterfly ReadStructureLate RestoreStructure ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ChangeButterfly ReadMaxOffsetEarly ChangeMaxOffset ReadButterfly ReadStructureLate ReadMaxOffsetLate RestoreStructure: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ChangeButterfly ReadMaxOffsetEarly ReadButterfly ChangeMaxOffset RestoreStructure ReadStructureLate ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ChangeButterfly ReadMaxOffsetEarly ReadButterfly ChangeMaxOffset ReadStructureLate RestoreStructure ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ChangeButterfly ReadMaxOffsetEarly ReadButterfly ChangeMaxOffset ReadStructureLate ReadMaxOffsetLate RestoreStructure: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ChangeButterfly ReadMaxOffsetEarly ReadButterfly ReadStructureLate ChangeMaxOffset RestoreStructure ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ChangeButterfly ReadMaxOffsetEarly ReadButterfly ReadStructureLate ChangeMaxOffset ReadMaxOffsetLate RestoreStructure: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ChangeButterfly ReadMaxOffsetEarly ReadButterfly ReadStructureLate ReadMaxOffsetLate ChangeMaxOffset RestoreStructure: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ReadMaxOffsetEarly ChangeButterfly ChangeMaxOffset RestoreStructure ReadButterfly ReadStructureLate ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ReadMaxOffsetEarly ChangeButterfly ChangeMaxOffset ReadButterfly RestoreStructure ReadStructureLate ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ReadMaxOffsetEarly ChangeButterfly ChangeMaxOffset ReadButterfly ReadStructureLate RestoreStructure ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ReadMaxOffsetEarly ChangeButterfly ChangeMaxOffset ReadButterfly ReadStructureLate ReadMaxOffsetLate RestoreStructure: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ReadMaxOffsetEarly ChangeButterfly ReadButterfly ChangeMaxOffset RestoreStructure ReadStructureLate ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ReadMaxOffsetEarly ChangeButterfly ReadButterfly ChangeMaxOffset ReadStructureLate RestoreStructure ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ReadMaxOffsetEarly ChangeButterfly ReadButterfly ChangeMaxOffset ReadStructureLate ReadMaxOffsetLate RestoreStructure: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ReadMaxOffsetEarly ChangeButterfly ReadButterfly ReadStructureLate ChangeMaxOffset RestoreStructure ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ReadMaxOffsetEarly ChangeButterfly ReadButterfly ReadStructureLate ChangeMaxOffset ReadMaxOffsetLate RestoreStructure: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ReadMaxOffsetEarly ChangeButterfly ReadButterfly ReadStructureLate ReadMaxOffsetLate ChangeMaxOffset RestoreStructure: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ChangeButterfly ChangeMaxOffset RestoreStructure ReadStructureLate ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ChangeButterfly ChangeMaxOffset ReadStructureLate RestoreStructure ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ChangeButterfly ChangeMaxOffset ReadStructureLate ReadMaxOffsetLate RestoreStructure: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ChangeButterfly ReadStructureLate ChangeMaxOffset RestoreStructure ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ChangeButterfly ReadStructureLate ChangeMaxOffset ReadMaxOffsetLate RestoreStructure: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ChangeButterfly ReadStructureLate ReadMaxOffsetLate ChangeMaxOffset RestoreStructure: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ReadStructureLate ChangeButterfly ChangeMaxOffset RestoreStructure ReadMaxOffsetLate: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ReadStructureLate ChangeButterfly ChangeMaxOffset ReadMaxOffsetLate RestoreStructure: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ReadStructureLate ChangeButterfly ReadMaxOffsetLate ChangeMaxOffset RestoreStructure: IGNORE, read nuked structure early
+ // NukeStructure ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ReadStructureLate ReadMaxOffsetLate ChangeButterfly ChangeMaxOffset RestoreStructure: IGNORE, read nuked structure early
+ // ReadStructureEarly NukeStructure ChangeButterfly ChangeMaxOffset RestoreStructure ReadMaxOffsetEarly ReadButterfly ReadStructureLate ReadMaxOffsetLate: AFTER, the ReadStructureEarly sees the same structure as after and everything else runs after.
+ // ReadStructureEarly NukeStructure ChangeButterfly ChangeMaxOffset ReadMaxOffsetEarly RestoreStructure ReadButterfly ReadStructureLate ReadMaxOffsetLate: AFTER, as above and the ReadMaxOffsetEarly sees the maxOffset after.
+ // ReadStructureEarly NukeStructure ChangeButterfly ChangeMaxOffset ReadMaxOffsetEarly ReadButterfly RestoreStructure ReadStructureLate ReadMaxOffsetLate: AFTER, as above and the ReadButterfly sees the right butterfly after.
+ // ReadStructureEarly NukeStructure ChangeButterfly ChangeMaxOffset ReadMaxOffsetEarly ReadButterfly ReadStructureLate RestoreStructure ReadMaxOffsetLate: IGNORE, read nuked structure late
+ // ReadStructureEarly NukeStructure ChangeButterfly ChangeMaxOffset ReadMaxOffsetEarly ReadButterfly ReadStructureLate ReadMaxOffsetLate RestoreStructure: IGNORE, read nuked structure late
+ // ReadStructureEarly NukeStructure ChangeButterfly ReadMaxOffsetEarly ChangeMaxOffset RestoreStructure ReadButterfly ReadStructureLate ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ChangeButterfly ReadMaxOffsetEarly ChangeMaxOffset ReadButterfly RestoreStructure ReadStructureLate ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ChangeButterfly ReadMaxOffsetEarly ChangeMaxOffset ReadButterfly ReadStructureLate RestoreStructure ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ChangeButterfly ReadMaxOffsetEarly ChangeMaxOffset ReadButterfly ReadStructureLate ReadMaxOffsetLate RestoreStructure: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ChangeButterfly ReadMaxOffsetEarly ReadButterfly ChangeMaxOffset RestoreStructure ReadStructureLate ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ChangeButterfly ReadMaxOffsetEarly ReadButterfly ChangeMaxOffset ReadStructureLate RestoreStructure ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ChangeButterfly ReadMaxOffsetEarly ReadButterfly ChangeMaxOffset ReadStructureLate ReadMaxOffsetLate RestoreStructure: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ChangeButterfly ReadMaxOffsetEarly ReadButterfly ReadStructureLate ChangeMaxOffset RestoreStructure ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ChangeButterfly ReadMaxOffsetEarly ReadButterfly ReadStructureLate ChangeMaxOffset ReadMaxOffsetLate RestoreStructure: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ChangeButterfly ReadMaxOffsetEarly ReadButterfly ReadStructureLate ReadMaxOffsetLate ChangeMaxOffset RestoreStructure: IGNORE, read nuked structure late
+ // ReadStructureEarly NukeStructure ReadMaxOffsetEarly ChangeButterfly ChangeMaxOffset RestoreStructure ReadButterfly ReadStructureLate ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ReadMaxOffsetEarly ChangeButterfly ChangeMaxOffset ReadButterfly RestoreStructure ReadStructureLate ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ReadMaxOffsetEarly ChangeButterfly ChangeMaxOffset ReadButterfly ReadStructureLate RestoreStructure ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ReadMaxOffsetEarly ChangeButterfly ChangeMaxOffset ReadButterfly ReadStructureLate ReadMaxOffsetLate RestoreStructure: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ReadMaxOffsetEarly ChangeButterfly ReadButterfly ChangeMaxOffset RestoreStructure ReadStructureLate ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ReadMaxOffsetEarly ChangeButterfly ReadButterfly ChangeMaxOffset ReadStructureLate RestoreStructure ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ReadMaxOffsetEarly ChangeButterfly ReadButterfly ChangeMaxOffset ReadStructureLate ReadMaxOffsetLate RestoreStructure: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ReadMaxOffsetEarly ChangeButterfly ReadButterfly ReadStructureLate ChangeMaxOffset RestoreStructure ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ReadMaxOffsetEarly ChangeButterfly ReadButterfly ReadStructureLate ChangeMaxOffset ReadMaxOffsetLate RestoreStructure: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ReadMaxOffsetEarly ChangeButterfly ReadButterfly ReadStructureLate ReadMaxOffsetLate ChangeMaxOffset RestoreStructure: IGNORE, read nuked structure late
+ // ReadStructureEarly NukeStructure ReadMaxOffsetEarly ReadButterfly ChangeButterfly ChangeMaxOffset RestoreStructure ReadStructureLate ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ReadMaxOffsetEarly ReadButterfly ChangeButterfly ChangeMaxOffset ReadStructureLate RestoreStructure ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ReadMaxOffsetEarly ReadButterfly ChangeButterfly ChangeMaxOffset ReadStructureLate ReadMaxOffsetLate RestoreStructure: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ReadMaxOffsetEarly ReadButterfly ChangeButterfly ReadStructureLate ChangeMaxOffset RestoreStructure ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ReadMaxOffsetEarly ReadButterfly ChangeButterfly ReadStructureLate ChangeMaxOffset ReadMaxOffsetLate RestoreStructure: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ReadMaxOffsetEarly ReadButterfly ChangeButterfly ReadStructureLate ReadMaxOffsetLate ChangeMaxOffset RestoreStructure: IGNORE, read nuked structure late
+ // ReadStructureEarly NukeStructure ReadMaxOffsetEarly ReadButterfly ReadStructureLate ChangeButterfly ChangeMaxOffset RestoreStructure ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ReadMaxOffsetEarly ReadButterfly ReadStructureLate ChangeButterfly ChangeMaxOffset ReadMaxOffsetLate RestoreStructure: IGNORE, read different offsets
+ // ReadStructureEarly NukeStructure ReadMaxOffsetEarly ReadButterfly ReadStructureLate ChangeButterfly ReadMaxOffsetLate ChangeMaxOffset RestoreStructure: IGNORE, read nuked structure late
+ // ReadStructureEarly NukeStructure ReadMaxOffsetEarly ReadButterfly ReadStructureLate ReadMaxOffsetLate ChangeButterfly ChangeMaxOffset RestoreStructure: IGNORE, read nuked structure late
+ // ReadStructureEarly ReadMaxOffsetEarly NukeStructure ChangeButterfly ChangeMaxOffset RestoreStructure ReadButterfly ReadStructureLate ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly ReadMaxOffsetEarly NukeStructure ChangeButterfly ChangeMaxOffset ReadButterfly RestoreStructure ReadStructureLate ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly ReadMaxOffsetEarly NukeStructure ChangeButterfly ChangeMaxOffset ReadButterfly ReadStructureLate RestoreStructure ReadMaxOffsetLate: IGNORE, read nuked structure late
+ // ReadStructureEarly ReadMaxOffsetEarly NukeStructure ChangeButterfly ChangeMaxOffset ReadButterfly ReadStructureLate ReadMaxOffsetLate RestoreStructure: IGNORE, read nuked structure late
+ // ReadStructureEarly ReadMaxOffsetEarly NukeStructure ChangeButterfly ReadButterfly ChangeMaxOffset RestoreStructure ReadStructureLate ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly ReadMaxOffsetEarly NukeStructure ChangeButterfly ReadButterfly ChangeMaxOffset ReadStructureLate RestoreStructure ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly ReadMaxOffsetEarly NukeStructure ChangeButterfly ReadButterfly ChangeMaxOffset ReadStructureLate ReadMaxOffsetLate RestoreStructure: IGNORE, read different offsets
+ // ReadStructureEarly ReadMaxOffsetEarly NukeStructure ChangeButterfly ReadButterfly ReadStructureLate ChangeMaxOffset RestoreStructure ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly ReadMaxOffsetEarly NukeStructure ChangeButterfly ReadButterfly ReadStructureLate ChangeMaxOffset ReadMaxOffsetLate RestoreStructure: IGNORE, read different offsets
+ // ReadStructureEarly ReadMaxOffsetEarly NukeStructure ChangeButterfly ReadButterfly ReadStructureLate ReadMaxOffsetLate ChangeMaxOffset RestoreStructure: IGNORE, read nuked structure late
+ // ReadStructureEarly ReadMaxOffsetEarly NukeStructure ReadButterfly ChangeButterfly ChangeMaxOffset RestoreStructure ReadStructureLate ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly ReadMaxOffsetEarly NukeStructure ReadButterfly ChangeButterfly ChangeMaxOffset ReadStructureLate RestoreStructure ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly ReadMaxOffsetEarly NukeStructure ReadButterfly ChangeButterfly ChangeMaxOffset ReadStructureLate ReadMaxOffsetLate RestoreStructure: IGNORE, read different offsets
+ // ReadStructureEarly ReadMaxOffsetEarly NukeStructure ReadButterfly ChangeButterfly ReadStructureLate ChangeMaxOffset RestoreStructure ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly ReadMaxOffsetEarly NukeStructure ReadButterfly ChangeButterfly ReadStructureLate ChangeMaxOffset ReadMaxOffsetLate RestoreStructure: IGNORE, read different offsets
+ // ReadStructureEarly ReadMaxOffsetEarly NukeStructure ReadButterfly ChangeButterfly ReadStructureLate ReadMaxOffsetLate ChangeMaxOffset RestoreStructure: IGNORE, read nuked structure late
+ // ReadStructureEarly ReadMaxOffsetEarly NukeStructure ReadButterfly ReadStructureLate ChangeButterfly ChangeMaxOffset RestoreStructure ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly ReadMaxOffsetEarly NukeStructure ReadButterfly ReadStructureLate ChangeButterfly ChangeMaxOffset ReadMaxOffsetLate RestoreStructure: IGNORE, read nuked structure late
+ // ReadStructureEarly ReadMaxOffsetEarly NukeStructure ReadButterfly ReadStructureLate ChangeButterfly ReadMaxOffsetLate ChangeMaxOffset RestoreStructure: IGNORE, read nuked structure late
+ // ReadStructureEarly ReadMaxOffsetEarly NukeStructure ReadButterfly ReadStructureLate ReadMaxOffsetLate ChangeButterfly ChangeMaxOffset RestoreStructure: IGNORE, read nuked structure late
+ // ReadStructureEarly ReadMaxOffsetEarly ReadButterfly NukeStructure ChangeButterfly ChangeMaxOffset RestoreStructure ReadStructureLate ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly ReadMaxOffsetEarly ReadButterfly NukeStructure ChangeButterfly ChangeMaxOffset ReadStructureLate RestoreStructure ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly ReadMaxOffsetEarly ReadButterfly NukeStructure ChangeButterfly ChangeMaxOffset ReadStructureLate ReadMaxOffsetLate RestoreStructure: IGNORE, read different offsets
+ // ReadStructureEarly ReadMaxOffsetEarly ReadButterfly NukeStructure ChangeButterfly ReadStructureLate ChangeMaxOffset RestoreStructure ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly ReadMaxOffsetEarly ReadButterfly NukeStructure ChangeButterfly ReadStructureLate ChangeMaxOffset ReadMaxOffsetLate RestoreStructure: IGNORE, read different offsets
+ // ReadStructureEarly ReadMaxOffsetEarly ReadButterfly NukeStructure ChangeButterfly ReadStructureLate ReadMaxOffsetLate ChangeMaxOffset RestoreStructure: IGNORE, read nuked structure late
+ // ReadStructureEarly ReadMaxOffsetEarly ReadButterfly NukeStructure ReadStructureLate ChangeButterfly ChangeMaxOffset RestoreStructure ReadMaxOffsetLate: IGNORE, read nuked structure late
+ // ReadStructureEarly ReadMaxOffsetEarly ReadButterfly NukeStructure ReadStructureLate ChangeButterfly ChangeMaxOffset ReadMaxOffsetLate RestoreStructure: IGNORE, read nuked structure late
+ // ReadStructureEarly ReadMaxOffsetEarly ReadButterfly NukeStructure ReadStructureLate ChangeButterfly ReadMaxOffsetLate ChangeMaxOffset RestoreStructure: IGNORE, read nuked structure late
+ // ReadStructureEarly ReadMaxOffsetEarly ReadButterfly NukeStructure ReadStructureLate ReadMaxOffsetLate ChangeButterfly ChangeMaxOffset RestoreStructure: IGNORE, read nuked structure late
+ // ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ReadStructureLate NukeStructure ChangeButterfly ChangeMaxOffset RestoreStructure ReadMaxOffsetLate: IGNORE, read different offsets
+ // ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ReadStructureLate NukeStructure ChangeButterfly ChangeMaxOffset ReadMaxOffsetLate RestoreStructure: IGNORE, read different offsets
+ // ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ReadStructureLate NukeStructure ChangeButterfly ReadMaxOffsetLate ChangeMaxOffset RestoreStructure: BEFORE, reads the offset before, everything else happens before
+ // ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ReadStructureLate NukeStructure ReadMaxOffsetLate ChangeButterfly ChangeMaxOffset RestoreStructure: BEFORE, reads the offset before, everything else happens before
+ // ReadStructureEarly ReadMaxOffsetEarly ReadButterfly ReadStructureLate ReadMaxOffsetLate NukeStructure ChangeButterfly ChangeMaxOffset RestoreStructure: BEFORE, trivially
//
// Whew.
//
@@ -392,7 +392,7 @@
if (isNuked(structureID))
return nullptr;
structure = vm.getStructure(structureID);
- lastOffset = structure->lastOffset();
+ maxOffset = structure->maxOffset();
IndexingType indexingMode = structure->indexingMode();
Dependency indexingModeDependency = Dependency::fence(indexingMode);
Locker<JSCellLock> locker(NoLockingNecessary);
@@ -415,10 +415,10 @@
return structure;
if (butterflyDependency.consume(this)->structureID() != structureID)
return nullptr;
- if (butterflyDependency.consume(structure)->lastOffset() != lastOffset)
+ if (butterflyDependency.consume(structure)->maxOffset() != maxOffset)
return nullptr;
- markAuxiliaryAndVisitOutOfLineProperties(visitor, butterfly, structure, lastOffset);
+ markAuxiliaryAndVisitOutOfLineProperties(visitor, butterfly, structure, maxOffset);
ASSERT(indexingMode == structure->indexingMode());
visitElements(indexingMode);
diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h
index ff04f59..ec6300e 100644
--- a/Source/JavaScriptCore/runtime/JSObject.h
+++ b/Source/JavaScriptCore/runtime/JSObject.h
@@ -941,7 +941,7 @@
Structure* visitButterflyImpl(SlotVisitor&);
- void markAuxiliaryAndVisitOutOfLineProperties(SlotVisitor&, Butterfly*, Structure*, PropertyOffset lastOffset);
+ void markAuxiliaryAndVisitOutOfLineProperties(SlotVisitor&, Butterfly*, Structure*, PropertyOffset maxOffset);
// Call this if you know that the object is in a mode where it has array
// storage. This will assert otherwise.
diff --git a/Source/JavaScriptCore/runtime/JSObjectInlines.h b/Source/JavaScriptCore/runtime/JSObjectInlines.h
index b241aea..a670034 100644
--- a/Source/JavaScriptCore/runtime/JSObjectInlines.h
+++ b/Source/JavaScriptCore/runtime/JSObjectInlines.h
@@ -216,16 +216,16 @@
PropertyOffset result;
structure->addPropertyWithoutTransition(
vm, propertyName, attributes,
- [&] (const GCSafeConcurrentJSLocker&, PropertyOffset offset, PropertyOffset newLastOffset) {
- unsigned newOutOfLineCapacity = Structure::outOfLineCapacity(newLastOffset);
+ [&] (const GCSafeConcurrentJSLocker&, PropertyOffset offset, PropertyOffset newMaxOffset) {
+ unsigned newOutOfLineCapacity = Structure::outOfLineCapacity(newMaxOffset);
if (newOutOfLineCapacity != oldOutOfLineCapacity) {
Butterfly* butterfly = allocateMoreOutOfLineStorage(vm, oldOutOfLineCapacity, newOutOfLineCapacity);
nukeStructureAndSetButterfly(vm, structureID, butterfly);
- structure->setLastOffset(newLastOffset);
+ structure->setMaxOffset(vm, newMaxOffset);
WTF::storeStoreFence();
setStructureIDDirectly(structureID);
} else
- structure->setLastOffset(newLastOffset);
+ structure->setMaxOffset(vm, newMaxOffset);
// This assertion verifies that the concurrent GC won't read garbage if the concurrentGC
// is running at the same time we put without transitioning.
diff --git a/Source/JavaScriptCore/runtime/ObjectInitializationScope.cpp b/Source/JavaScriptCore/runtime/ObjectInitializationScope.cpp
index a44fbb9..c4ebbec 100644
--- a/Source/JavaScriptCore/runtime/ObjectInitializationScope.cpp
+++ b/Source/JavaScriptCore/runtime/ObjectInitializationScope.cpp
@@ -104,7 +104,7 @@
for (int64_t i = 0; i < static_cast<int64_t>(structure->outOfLineCapacity()); i++) {
// We rely on properties past the last offset be zero for concurrent GC.
- if (i + firstOutOfLineOffset > structure->lastOffset())
+ if (i + firstOutOfLineOffset > structure->maxOffset())
ASSERT(isSafeEmptyValueForGCScanning(butterfly->propertyStorage()[-i - 1].get()));
else if (isScribbledValue(butterfly->propertyStorage()[-i - 1].get())) {
dataLogLn("Found scribbled property at i = ", -i - 1);
diff --git a/Source/JavaScriptCore/runtime/PropertyOffset.h b/Source/JavaScriptCore/runtime/PropertyOffset.h
index a83f54d..e70729f 100644
--- a/Source/JavaScriptCore/runtime/PropertyOffset.h
+++ b/Source/JavaScriptCore/runtime/PropertyOffset.h
@@ -47,8 +47,8 @@
inline size_t offsetInInlineStorage(PropertyOffset);
inline size_t offsetInOutOfLineStorage(PropertyOffset);
inline size_t offsetInRespectiveStorage(PropertyOffset);
-inline size_t numberOfOutOfLineSlotsForLastOffset(PropertyOffset);
-inline size_t numberOfSlotsForLastOffset(PropertyOffset, int inlineCapacity);
+inline size_t numberOfOutOfLineSlotsForMaxOffset(PropertyOffset);
+inline size_t numberOfSlotsForMaxOffset(PropertyOffset, int inlineCapacity);
inline void checkOffset(PropertyOffset offset)
{
@@ -117,7 +117,7 @@
return offsetInOutOfLineStorage(offset);
}
-inline size_t numberOfOutOfLineSlotsForLastOffset(PropertyOffset offset)
+inline size_t numberOfOutOfLineSlotsForMaxOffset(PropertyOffset offset)
{
checkOffset(offset);
if (offset < firstOutOfLineOffset)
@@ -125,12 +125,12 @@
return offset - firstOutOfLineOffset + 1;
}
-inline size_t numberOfSlotsForLastOffset(PropertyOffset offset, int inlineCapacity)
+inline size_t numberOfSlotsForMaxOffset(PropertyOffset offset, int inlineCapacity)
{
checkOffset(offset, inlineCapacity);
if (offset < inlineCapacity)
return offset + 1;
- return inlineCapacity + numberOfOutOfLineSlotsForLastOffset(offset);
+ return inlineCapacity + numberOfOutOfLineSlotsForMaxOffset(offset);
}
inline PropertyOffset offsetForPropertyNumber(int propertyNumber, int inlineCapacity)
diff --git a/Source/JavaScriptCore/runtime/Structure.cpp b/Source/JavaScriptCore/runtime/Structure.cpp
index 5f6bb1b..5a61213 100644
--- a/Source/JavaScriptCore/runtime/Structure.cpp
+++ b/Source/JavaScriptCore/runtime/Structure.cpp
@@ -91,7 +91,7 @@
{
if (isUsingSingleSlot()) {
Structure* transition = singleTransition();
- return transition && transition->m_nameInPrevious == rep && transition->attributesInPrevious() == attributes;
+ return transition && transition->m_transitionPropertyName == rep && transition->transitionPropertyAttributes() == attributes;
}
return map()->get(std::make_pair(rep, attributes));
}
@@ -100,7 +100,7 @@
{
if (isUsingSingleSlot()) {
Structure* transition = singleTransition();
- return (transition && transition->m_nameInPrevious == rep && transition->attributesInPrevious() == attributes) ? transition : 0;
+ return (transition && transition->m_transitionPropertyName == rep && transition->transitionPropertyAttributes() == attributes) ? transition : 0;
}
return map()->get(std::make_pair(rep, attributes));
}
@@ -127,7 +127,7 @@
// Newer versions of the STL have an std::make_pair function that takes rvalue references.
// When either of the parameters are bitfields, the C++ compiler will try to bind them as lvalues, which is invalid. To work around this, use unary "+" to make the parameter an rvalue.
// See https://bugs.webkit.org/show_bug.cgi?id=59261 for more details
- map()->set(std::make_pair(structure->m_nameInPrevious.get(), +structure->attributesInPrevious()), structure);
+ map()->set(std::make_pair(structure->m_transitionPropertyName.get(), +structure->transitionPropertyAttributes()), structure);
}
void Structure::dumpStatistics()
@@ -185,7 +185,6 @@
, m_prototype(vm, this, prototype)
, m_classInfo(classInfo)
, m_transitionWatchpointSet(IsWatched)
- , m_offset(invalidOffset)
, m_propertyHash(0)
{
setDictionaryKind(NoneDictionaryKind);
@@ -195,13 +194,15 @@
setHasReadOnlyOrGetterSetterPropertiesExcludingProto(classInfo->hasStaticSetterOrReadonlyProperties());
setHasUnderscoreProtoPropertyExcludingOriginalProto(false);
setIsQuickPropertyAccessAllowedForEnumeration(true);
- setAttributesInPrevious(0);
+ setTransitionPropertyAttributes(0);
setDidPreventExtensions(false);
setDidTransition(false);
setStaticPropertiesReified(false);
setTransitionWatchpointIsLikelyToBeFired(false);
setHasBeenDictionary(false);
setIsAddingPropertyForTransition(false);
+ setTransitionOffset(vm, invalidOffset);
+ setMaxOffset(vm, invalidOffset);
ASSERT(inlineCapacity <= JSFinalObject::maxInlineCapacity());
ASSERT(static_cast<PropertyOffset>(inlineCapacity) < firstOutOfLineOffset);
@@ -220,7 +221,6 @@
, m_prototype(vm, this, jsNull())
, m_classInfo(info())
, m_transitionWatchpointSet(IsWatched)
- , m_offset(invalidOffset)
, m_propertyHash(0)
{
setDictionaryKind(NoneDictionaryKind);
@@ -230,13 +230,15 @@
setHasReadOnlyOrGetterSetterPropertiesExcludingProto(m_classInfo->hasStaticSetterOrReadonlyProperties());
setHasUnderscoreProtoPropertyExcludingOriginalProto(false);
setIsQuickPropertyAccessAllowedForEnumeration(true);
- setAttributesInPrevious(0);
+ setTransitionPropertyAttributes(0);
setDidPreventExtensions(false);
setDidTransition(false);
setStaticPropertiesReified(false);
setTransitionWatchpointIsLikelyToBeFired(false);
setHasBeenDictionary(false);
setIsAddingPropertyForTransition(false);
+ setTransitionOffset(vm, invalidOffset);
+ setMaxOffset(vm, invalidOffset);
TypeInfo typeInfo = TypeInfo(CellType, StructureFlags);
m_blob = StructureIDBlob(vm.heap.structureIDTable().allocateID(this), 0, typeInfo);
@@ -254,7 +256,6 @@
, m_prototype(vm, this, previous->m_prototype.get())
, m_classInfo(previous->m_classInfo)
, m_transitionWatchpointSet(IsWatched)
- , m_offset(invalidOffset)
, m_propertyHash(previous->m_propertyHash)
, m_seenProperties(previous->m_seenProperties)
{
@@ -266,12 +267,14 @@
setHasReadOnlyOrGetterSetterPropertiesExcludingProto(previous->hasReadOnlyOrGetterSetterPropertiesExcludingProto());
setHasUnderscoreProtoPropertyExcludingOriginalProto(previous->hasUnderscoreProtoPropertyExcludingOriginalProto());
setIsQuickPropertyAccessAllowedForEnumeration(previous->isQuickPropertyAccessAllowedForEnumeration());
- setAttributesInPrevious(0);
+ setTransitionPropertyAttributes(0);
setDidPreventExtensions(previous->didPreventExtensions());
setDidTransition(true);
setStaticPropertiesReified(previous->staticPropertiesReified());
setHasBeenDictionary(previous->hasBeenDictionary());
setIsAddingPropertyForTransition(false);
+ setTransitionOffset(vm, invalidOffset);
+ setMaxOffset(vm, invalidOffset);
TypeInfo typeInfo = previous->typeInfo();
m_blob = StructureIDBlob(vm.heap.structureIDTable().allocateID(this), previous->indexingModeIncludingHistory(), typeInfo);
@@ -311,12 +314,12 @@
unsigned oldOutOfLineCapacity = result->outOfLineCapacity();
result->addPropertyWithoutTransition(
vm, vm.propertyNames->builtinNames().polyProtoName(), static_cast<unsigned>(PropertyAttribute::DontEnum),
- [&] (const GCSafeConcurrentJSLocker&, PropertyOffset offset, PropertyOffset newLastOffset) {
- RELEASE_ASSERT(Structure::outOfLineCapacity(newLastOffset) == oldOutOfLineCapacity);
+ [&] (const GCSafeConcurrentJSLocker&, PropertyOffset offset, PropertyOffset newMaxOffset) {
+ RELEASE_ASSERT(Structure::outOfLineCapacity(newMaxOffset) == oldOutOfLineCapacity);
RELEASE_ASSERT(offset == knownPolyProtoOffset);
RELEASE_ASSERT(isInlineOffset(knownPolyProtoOffset));
result->m_prototype.setWithoutWriteBarrier(JSValue());
- result->setLastOffset(newLastOffset);
+ result->setMaxOffset(vm, newMaxOffset);
});
return result;
@@ -363,7 +366,7 @@
findStructuresAndMapForMaterialization(structures, structure, table);
- unsigned capacity = numberOfSlotsForLastOffset(m_offset, m_inlineCapacity);
+ unsigned capacity = numberOfSlotsForMaxOffset(maxOffset(), m_inlineCapacity);
if (table) {
table = table->copy(vm, capacity);
structure->m_lock.unlock();
@@ -379,10 +382,12 @@
for (size_t i = structures.size(); i--;) {
structure = structures[i];
- if (!structure->m_nameInPrevious)
+ if (!structure->m_transitionPropertyName)
continue;
- PropertyMapEntry entry(structure->m_nameInPrevious.get(), structure->m_offset, structure->attributesInPrevious());
- table->add(entry, m_offset, PropertyTable::PropertyOffsetMustNotChange);
+ ASSERT(i == structures.size() - 1 || structure->maxOffset() > structures[i + 1]->maxOffset());
+ PropertyMapEntry entry(structure->m_transitionPropertyName.get(), structure->transitionOffset(), structure->transitionPropertyAttributes());
+ auto maxOffset = this->maxOffset();
+ table->add(entry, maxOffset, PropertyTable::PropertyOffsetMustNotChange);
}
checkOffsetConsistency(
@@ -406,8 +411,8 @@
ASSERT(structure->isObject());
if (Structure* existingTransition = structure->m_transitionTable.get(uid, attributes)) {
- validateOffset(existingTransition->m_offset, existingTransition->inlineCapacity());
- offset = existingTransition->m_offset;
+ validateOffset(existingTransition->transitionOffset(), existingTransition->inlineCapacity());
+ offset = existingTransition->transitionOffset();
return existingTransition;
}
@@ -474,11 +479,12 @@
maxTransitionLength = s_maxTransitionLengthForNonEvalPutById;
else
maxTransitionLength = s_maxTransitionLength;
- if (structure->transitionCount() > maxTransitionLength) {
+ if (structure->transitionCountEstimate() > maxTransitionLength) {
ASSERT(!isCopyOnWrite(structure->indexingMode()));
Structure* transition = toCacheableDictionaryTransition(vm, structure, deferred);
ASSERT(structure != transition);
offset = transition->add(vm, propertyName, attributes);
+ transition->setTransitionOffset(vm, offset);
return transition;
}
@@ -487,7 +493,7 @@
transition->m_cachedPrototypeChain.setMayBeNull(vm, transition, structure->m_cachedPrototypeChain.get());
// While we are adding the property, rematerializing the property table is super weird: we already
- // have a m_nameInPrevious and attributesInPrevious but the m_offset is still wrong. If the
+ // have a m_transitionPropertyName and transitionPropertyAttributes but the m_transitionOffset is still wrong. If the
// materialization algorithm runs, it'll build a property table that already has the property but
// at a bogus offset. Rather than try to teach the materialization code how to create a table under
// those conditions, we just tell the GC not to blow the table away during this period of time.
@@ -501,19 +507,20 @@
}
transition->m_blob.setIndexingModeIncludingHistory(structure->indexingModeIncludingHistory() & ~CopyOnWrite);
- transition->m_nameInPrevious = propertyName.uid();
- transition->setAttributesInPrevious(attributes);
+ transition->m_transitionPropertyName = propertyName.uid();
+ transition->setTransitionPropertyAttributes(attributes);
transition->setPropertyTable(vm, structure->takePropertyTableOrCloneIfPinned(vm));
- transition->m_offset = structure->m_offset;
+ transition->setMaxOffset(vm, structure->maxOffset());
offset = transition->add(vm, propertyName, attributes);
+ transition->setTransitionOffset(vm, offset);
// Now that everything is fine with the new structure's bookkeeping, the GC is free to blow the
// table away if it wants. We can now rebuild it fine.
WTF::storeStoreFence();
transition->setIsAddingPropertyForTransition(false);
- checkOffset(transition->m_offset, transition->inlineCapacity());
+ checkOffset(transition->transitionOffset(), transition->inlineCapacity());
{
ConcurrentJSLocker locker(structure->m_lock);
DeferGC deferGC(vm.heap);
@@ -559,7 +566,7 @@
PropertyTable* table = structure->copyPropertyTableForPinning(vm);
transition->pin(holdLock(transition->m_lock), vm, table);
- transition->m_offset = structure->m_offset;
+ transition->setMaxOffset(vm, structure->maxOffset());
transition->checkOffsetConsistency();
return transition;
@@ -572,7 +579,7 @@
PropertyTable* table = structure->copyPropertyTableForPinning(vm);
transition->pin(holdLock(transition->m_lock), vm, table);
- transition->m_offset = structure->m_offset;
+ transition->setMaxOffset(vm, structure->maxOffset());
structure = transition;
}
@@ -594,7 +601,7 @@
PropertyTable* table = structure->copyPropertyTableForPinning(vm);
transition->pin(holdLock(transition->m_lock), vm, table);
- transition->m_offset = structure->m_offset;
+ transition->setMaxOffset(vm, structure->maxOffset());
transition->setDictionaryKind(kind);
transition->setHasBeenDictionary(true);
@@ -649,7 +656,7 @@
Structure* existingTransition;
if (!structure->isDictionary() && (existingTransition = structure->m_transitionTable.get(0, attributes))) {
- ASSERT(existingTransition->attributesInPrevious() == attributes);
+ ASSERT(existingTransition->transitionPropertyAttributes() == attributes);
ASSERT(existingTransition->indexingModeIncludingHistory() == indexingModeIncludingHistory);
return existingTransition;
}
@@ -657,7 +664,7 @@
DeferGC deferGC(vm.heap);
Structure* transition = create(vm, structure);
- transition->setAttributesInPrevious(attributes);
+ transition->setTransitionPropertyAttributes(attributes);
transition->m_blob.setIndexingModeIncludingHistory(indexingModeIncludingHistory);
if (preventsExtensions(transitionKind))
@@ -671,7 +678,7 @@
PropertyTable* table = structure->copyPropertyTableForPinning(vm);
transition->pinForCaching(holdLock(transition->m_lock), vm, table);
- transition->m_offset = structure->m_offset;
+ transition->setMaxOffset(vm, structure->maxOffset());
table = transition->propertyTableOrNull();
RELEASE_ASSERT(table);
@@ -683,8 +690,8 @@
}
} else {
transition->setPropertyTable(vm, structure->takePropertyTableOrCloneIfPinned(vm));
- transition->m_offset = structure->m_offset;
- checkOffset(transition->m_offset, transition->inlineCapacity());
+ transition->setMaxOffset(vm, structure->maxOffset());
+ checkOffset(transition->maxOffset(), transition->inlineCapacity());
}
if (setsReadOnlyOnNonAccessorProperties(transitionKind)
@@ -764,11 +771,13 @@
// Copies out our values from their hashed locations, compacting property table offsets as we go.
unsigned i = 0;
PropertyTable::iterator end = table->end();
- m_offset = invalidOffset;
+ auto offset = invalidOffset;
for (PropertyTable::iterator iter = table->begin(); iter != end; ++iter, ++i) {
values[i] = object->getDirect(iter->offset);
- m_offset = iter->offset = offsetForPropertyNumber(i, m_inlineCapacity);
+ offset = iter->offset = offsetForPropertyNumber(i, m_inlineCapacity);
}
+ setMaxOffset(vm, offset);
+ ASSERT(transitionOffset() == invalidOffset);
// Copies in our values to their compacted locations.
for (unsigned i = 0; i < propertyCount; i++)
@@ -823,14 +832,14 @@
setIsPinnedPropertyTable(true);
setPropertyTable(vm, table);
clearPreviousID();
- m_nameInPrevious = nullptr;
+ m_transitionPropertyName = nullptr;
}
void Structure::pinForCaching(const AbstractLocker&, VM& vm, PropertyTable* table)
{
setIsPinnedPropertyTable(true);
setPropertyTable(vm, table);
- m_nameInPrevious = nullptr;
+ m_transitionPropertyName = nullptr;
}
void Structure::allocateRareData(VM& vm)
@@ -962,8 +971,8 @@
{
return add<ShouldPin::No>(
vm, propertyName, attributes,
- [this] (const GCSafeConcurrentJSLocker&, PropertyOffset, PropertyOffset newLastOffset) {
- setLastOffset(newLastOffset);
+ [this, &vm] (const GCSafeConcurrentJSLocker&, PropertyOffset, PropertyOffset newMaxOffset) {
+ setMaxOffset(vm, newMaxOffset);
});
}
diff --git a/Source/JavaScriptCore/runtime/Structure.h b/Source/JavaScriptCore/runtime/Structure.h
index ee8dfd6..38dc1d39 100644
--- a/Source/JavaScriptCore/runtime/Structure.h
+++ b/Source/JavaScriptCore/runtime/Structure.h
@@ -352,14 +352,52 @@
return static_cast<Structure*>(cell);
}
bool transitivelyTransitionedFrom(Structure* structureToFind);
-
- PropertyOffset lastOffset() const { return m_offset; }
-
- void setLastOffset(PropertyOffset offset) { m_offset = offset; }
- static unsigned outOfLineCapacity(PropertyOffset lastOffset)
+ PropertyOffset maxOffset() const
{
- unsigned outOfLineSize = Structure::outOfLineSize(lastOffset);
+ if (m_maxOffset == shortInvalidOffset)
+ return invalidOffset;
+ if (m_maxOffset == useRareDataFlag)
+ return rareData()->m_maxOffset;
+ return m_maxOffset;
+ }
+
+ void setMaxOffset(VM& vm, PropertyOffset offset)
+ {
+ if (offset == invalidOffset)
+ m_maxOffset = shortInvalidOffset;
+ else if (offset < useRareDataFlag && offset < shortInvalidOffset)
+ m_maxOffset = offset;
+ else {
+ m_maxOffset = useRareDataFlag;
+ ensureRareData(vm)->m_maxOffset = offset;
+ }
+ }
+
+ PropertyOffset transitionOffset() const
+ {
+ if (m_transitionOffset == shortInvalidOffset)
+ return invalidOffset;
+ if (m_transitionOffset == useRareDataFlag)
+ return rareData()->m_transitionOffset;
+ return m_transitionOffset;
+ }
+
+ void setTransitionOffset(VM& vm, PropertyOffset offset)
+ {
+ if (offset == invalidOffset)
+ m_transitionOffset = shortInvalidOffset;
+ else if (offset < useRareDataFlag && offset < shortInvalidOffset)
+ m_transitionOffset = offset;
+ else {
+ m_transitionOffset = useRareDataFlag;
+ ensureRareData(vm)->m_transitionOffset = offset;
+ }
+ }
+
+ static unsigned outOfLineCapacity(PropertyOffset maxOffset)
+ {
+ unsigned outOfLineSize = Structure::outOfLineSize(maxOffset);
// This algorithm completely determines the out-of-line property storage growth algorithm.
// The JSObject code will only trigger a resize if the value returned by this algorithm
@@ -377,18 +415,18 @@
return WTF::roundUpToPowerOfTwo(outOfLineSize);
}
- static unsigned outOfLineSize(PropertyOffset lastOffset)
+ static unsigned outOfLineSize(PropertyOffset maxOffset)
{
- return numberOfOutOfLineSlotsForLastOffset(lastOffset);
+ return numberOfOutOfLineSlotsForMaxOffset(maxOffset);
}
unsigned outOfLineCapacity() const
{
- return outOfLineCapacity(m_offset);
+ return outOfLineCapacity(maxOffset());
}
unsigned outOfLineSize() const
{
- return outOfLineSize(m_offset);
+ return outOfLineSize(maxOffset());
}
bool hasInlineStorage() const
{
@@ -400,11 +438,11 @@
}
unsigned inlineSize() const
{
- return std::min<unsigned>(m_offset + 1, m_inlineCapacity);
+ return std::min<unsigned>(maxOffset() + 1, m_inlineCapacity);
}
unsigned totalStorageSize() const
{
- return numberOfSlotsForLastOffset(m_offset, m_inlineCapacity);
+ return numberOfSlotsForMaxOffset(maxOffset(), m_inlineCapacity);
}
unsigned totalStorageCapacity() const
{
@@ -415,7 +453,7 @@
bool isValidOffset(PropertyOffset offset) const
{
return JSC::isValidOffset(offset)
- && offset <= m_offset
+ && offset <= maxOffset()
&& (offset < m_inlineCapacity || offset >= firstOutOfLineOffset);
}
@@ -467,12 +505,6 @@
if (!is__proto__)
setHasReadOnlyOrGetterSetterPropertiesExcludingProto(true);
}
-
- bool isEmpty() const
- {
- ASSERT(checkOffsetConsistency());
- return !JSC::isValidOffset(m_offset);
- }
void setCachedPropertyNameEnumerator(VM&, JSPropertyNameEnumerator*);
JSPropertyNameEnumerator* cachedPropertyNameEnumerator() const;
@@ -650,7 +682,7 @@
DEFINE_BITFIELD(bool, hasGetterSetterProperties, HasGetterSetterProperties, 1, 3);
DEFINE_BITFIELD(bool, hasReadOnlyOrGetterSetterPropertiesExcludingProto, HasReadOnlyOrGetterSetterPropertiesExcludingProto, 1, 4);
DEFINE_BITFIELD(bool, isQuickPropertyAccessAllowedForEnumeration, IsQuickPropertyAccessAllowedForEnumeration, 1, 5);
- DEFINE_BITFIELD(unsigned, attributesInPrevious, AttributesInPrevious, 14, 6);
+ DEFINE_BITFIELD(unsigned, transitionPropertyAttributes, TransitionPropertyAttributes, 14, 6);
DEFINE_BITFIELD(bool, didPreventExtensions, DidPreventExtensions, 1, 20);
DEFINE_BITFIELD(bool, didTransition, DidTransition, 1, 21);
DEFINE_BITFIELD(bool, staticPropertiesReified, StaticPropertiesReified, 1, 22);
@@ -732,10 +764,11 @@
m_previousOrRareData.clear();
}
- int transitionCount() const
+ int transitionCountEstimate() const
{
- // Since the number of transitions is always the same as m_offset, we keep the size of Structure down by not storing both.
- return numberOfSlotsForLastOffset(m_offset, m_inlineCapacity);
+ // Since the number of transitions is often the same as the last offset (except if there are deletes)
+ // we keep the size of Structure down by not storing both.
+ return numberOfSlotsForMaxOffset(maxOffset(), m_inlineCapacity);
}
bool isValid(JSGlobalObject*, StructureChain* cachedPrototypeChain, JSObject* base) const;
@@ -777,7 +810,7 @@
WriteBarrier<JSCell> m_previousOrRareData;
- RefPtr<UniquedStringImpl> m_nameInPrevious;
+ RefPtr<UniquedStringImpl> m_transitionPropertyName;
const ClassInfo* m_classInfo;
@@ -791,8 +824,11 @@
COMPILE_ASSERT(firstOutOfLineOffset < 256, firstOutOfLineOffset_fits);
- // m_offset does not account for anonymous slots
- PropertyOffset m_offset;
+ static constexpr uint16_t shortInvalidOffset = std::numeric_limits<uint16_t>::max();
+ static constexpr uint16_t useRareDataFlag = std::numeric_limits<uint16_t>::max() - 1;
+
+ uint16_t m_transitionOffset;
+ uint16_t m_maxOffset;
uint32_t m_propertyHash;
TinyBloomFilter m_seenProperties;
diff --git a/Source/JavaScriptCore/runtime/StructureInlines.h b/Source/JavaScriptCore/runtime/StructureInlines.h
index abf80ee..1a4f202 100644
--- a/Source/JavaScriptCore/runtime/StructureInlines.h
+++ b/Source/JavaScriptCore/runtime/StructureInlines.h
@@ -180,10 +180,10 @@
for (unsigned i = structures.size(); i--;) {
structure = structures[i];
- if (!structure->m_nameInPrevious)
+ if (!structure->m_transitionPropertyName)
continue;
- if (!functor(PropertyMapEntry(structure->m_nameInPrevious.get(), structure->m_offset, structure->attributesInPrevious())))
+ if (!functor(PropertyMapEntry(structure->m_transitionPropertyName.get(), structure->transitionOffset(), structure->transitionPropertyAttributes())))
return;
}
}
@@ -364,21 +364,22 @@
auto fail = [&] (const char* description) {
dataLog("Detected offset inconsistency: ", description, "!\n");
dataLog("this = ", RawPointer(this), "\n");
- dataLog("m_offset = ", m_offset, "\n");
+ dataLog("transitionOffset = ", transitionOffset(), "\n");
+ dataLog("maxOffset = ", maxOffset(), "\n");
dataLog("m_inlineCapacity = ", m_inlineCapacity, "\n");
dataLog("propertyTable = ", RawPointer(propertyTable), "\n");
- dataLog("numberOfSlotsForLastOffset = ", numberOfSlotsForLastOffset(m_offset, m_inlineCapacity), "\n");
+ dataLog("numberOfSlotsForMaxOffset = ", numberOfSlotsForMaxOffset(maxOffset(), m_inlineCapacity), "\n");
dataLog("totalSize = ", totalSize, "\n");
dataLog("inlineOverflowAccordingToTotalSize = ", inlineOverflowAccordingToTotalSize, "\n");
- dataLog("numberOfOutOfLineSlotsForLastOffset = ", numberOfOutOfLineSlotsForLastOffset(m_offset), "\n");
+ dataLog("numberOfOutOfLineSlotsForMaxOffset = ", numberOfOutOfLineSlotsForMaxOffset(maxOffset()), "\n");
detailsFunc();
UNREACHABLE_FOR_PLATFORM();
};
- if (numberOfSlotsForLastOffset(m_offset, m_inlineCapacity) != totalSize)
- fail("numberOfSlotsForLastOffset doesn't match totalSize");
- if (inlineOverflowAccordingToTotalSize != numberOfOutOfLineSlotsForLastOffset(m_offset))
- fail("inlineOverflowAccordingToTotalSize doesn't match numberOfOutOfLineSlotsForLastOffset");
+ if (numberOfSlotsForMaxOffset(maxOffset(), m_inlineCapacity) != totalSize)
+ fail("numberOfSlotsForMaxOffset doesn't match totalSize");
+ if (inlineOverflowAccordingToTotalSize != numberOfOutOfLineSlotsForMaxOffset(maxOffset()))
+ fail("inlineOverflowAccordingToTotalSize doesn't match numberOfOutOfLineSlotsForMaxOffset");
return true;
}
@@ -453,12 +454,12 @@
m_seenProperties.add(bitwise_cast<uintptr_t>(rep));
- PropertyOffset newLastOffset = m_offset;
- table->add(PropertyMapEntry(rep, newOffset, attributes), newLastOffset, PropertyTable::PropertyOffsetMayChange);
+ PropertyOffset newMaxOffset = maxOffset();
+ table->add(PropertyMapEntry(rep, newOffset, attributes), newMaxOffset, PropertyTable::PropertyOffsetMayChange);
- func(locker, newOffset, newLastOffset);
+ func(locker, newOffset, newMaxOffset);
- ASSERT(m_offset == newLastOffset);
+ ASSERT(maxOffset() == newMaxOffset);
checkConsistency();
return newOffset;
diff --git a/Source/JavaScriptCore/runtime/StructureRareData.cpp b/Source/JavaScriptCore/runtime/StructureRareData.cpp
index b149ded..0623494 100644
--- a/Source/JavaScriptCore/runtime/StructureRareData.cpp
+++ b/Source/JavaScriptCore/runtime/StructureRareData.cpp
@@ -58,6 +58,8 @@
StructureRareData::StructureRareData(VM& vm, Structure* previous)
: JSCell(vm, vm.structureRareDataStructure.get())
, m_giveUpOnObjectToStringValueCache(false)
+ , m_maxOffset(invalidOffset)
+ , m_transitionOffset(invalidOffset)
{
if (previous)
m_previous.set(vm, this, previous);
diff --git a/Source/JavaScriptCore/runtime/StructureRareData.h b/Source/JavaScriptCore/runtime/StructureRareData.h
index 658a126..679c9e6 100644
--- a/Source/JavaScriptCore/runtime/StructureRareData.h
+++ b/Source/JavaScriptCore/runtime/StructureRareData.h
@@ -114,6 +114,9 @@
std::unique_ptr<ObjectToStringAdaptiveInferredPropertyValueWatchpoint> m_objectToStringAdaptiveInferredValueWatchpoint;
Box<InlineWatchpointSet> m_polyProtoWatchpoint;
bool m_giveUpOnObjectToStringValueCache;
+
+ PropertyOffset m_maxOffset;
+ PropertyOffset m_transitionOffset;
};
} // namespace JSC