[JSC] PropertyTable should have compact mode
https://bugs.webkit.org/show_bug.cgi?id=239451

Reviewed by Saam Barati.

This patch introduces "compact" version of PropertyTable. PropertyTable needs to hold two kind of integers: index and property offset.
But for most of objects, both are pretty small and they can fit in uint8_t. If we can use uint8_t for both, we can significantly reduce
size of allocated memory for PropertyTable (only 40% of memory is required!). This is good for memory, but also good for performance.
Now each CompactPropertyTableEntry is 8bytes while original PropertyMapEntry was 16bytes, so CompactPropertyTableEntry can fit in CPU cache well.
Also, not allocating large amount of memory can reduce memory allocation / deallocation cost. One of costly destruction of GC-managed objects is
PropertyTable (and CodeBlock), and we can reduce that cost by not allocating much memory.

The approach is following.

1. For index vector, we use uint8_t if index can fit within uint8_t.
2. For proprety offset, we use uint8_t and CompactPropertyTableEntry if it is suitable.
3. Once the table gets non-compact, we keep it non-compact since we could have deleted index which has larger than uint8_t. We could improve this
   strategy when deleted indexes are cleared, but for now, we are taking simple approach.
4. We store isCompactFlag 1 bit in the pointer to the table.
5. We encapsulate functions modifying property table entry in PropertyTable itself, so we do not leak internal compact / non-compact mode to the user
   of PropertyTable. We remove begin() / end() iterators and instead use forEachproperty, which can implement iteration for each mode more efficiently.

We have a further opportunity to improve this further: we can deploy 75% load factor only for compact table. Then we can increase threshold of
compact table further and keep more and more tables compact mode. Plus, for small sized tables, small backing memory is better in terms of
CPU cache hit (and that's measured in WTF::HashTable, and that's why WTF::Hashtable deploys 75% load factor only for small tables). This is left
for the subsequent change.

This change is neutral in JetStream2, 0.3% improvement in Speedometer2 with 80% confidence, and 0.41% improvement in RAMification with 95% confidence.

* JSTests/stress/change-attribute-structure-transition.js:
(shouldBe.JSON.stringify.sd):
* Source/JavaScriptCore/bytecode/ObjectAllocationProfileInlines.h:
(JSC::ObjectAllocationProfileBase<Derived>::initializeProfile):
* Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
* Source/JavaScriptCore/dfg/DFGOperations.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:
* Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
* Source/JavaScriptCore/ftl/FTLOperations.cpp:
(JSC::FTL::JSC_DEFINE_JIT_OPERATION):
* Source/JavaScriptCore/runtime/ClonedArguments.h:
* Source/JavaScriptCore/runtime/IteratorOperations.cpp:
(JSC::createIteratorResultObjectStructure):
* Source/JavaScriptCore/runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
* Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
* Source/JavaScriptCore/runtime/JSONObject.cpp:
(JSC::Stringifier::Holder::appendNextProperty):
* Source/JavaScriptCore/runtime/JSObject.cpp:
(JSC::JSObject::analyzeHeap):
* Source/JavaScriptCore/runtime/JSObject.h:
* Source/JavaScriptCore/runtime/ObjectConstructor.h:
(JSC::constructEmptyObject):
(JSC::createDataPropertyDescriptorObjectStructure):
(JSC::createAccessorPropertyDescriptorObjectStructure):
* Source/JavaScriptCore/runtime/ObjectConstructorInlines.h:
(JSC::objectAssignFast):
* Source/JavaScriptCore/runtime/PropertyOffset.h:
* Source/JavaScriptCore/runtime/PropertySlot.h:
* Source/JavaScriptCore/runtime/PropertyTable.cpp:
(JSC::PropertyTable::PropertyTable):
(JSC::PropertyTable::finishCreation):
(JSC::PropertyTable::visitChildrenImpl):
(JSC::PropertyTable::~PropertyTable):
(JSC::PropertyTable::seal):
(JSC::PropertyTable::freeze):
(JSC::PropertyTable::isSealed const):
(JSC::PropertyTable::isFrozen const):
(JSC::PropertyTable::renumberPropertyOffsets):
* Source/JavaScriptCore/runtime/PropertyTable.h:
(JSC::isPowerOf2):
(JSC::nextPowerOf2):
(JSC::PropertyTable::findImpl):
(JSC::PropertyTable::find):
(JSC::PropertyTable::get):
(JSC::PropertyTable::add):
(JSC::PropertyTable::remove):
(JSC::PropertyTable::take):
(JSC::PropertyTable::updateAttributeIfExists):
(JSC::PropertyTable::sizeInMemory):
(JSC::PropertyTable::reinsert):
(JSC::PropertyTable::rehash):
(JSC::PropertyTable::skipDeletedEntries):
(JSC::PropertyTable::dataSize):
(JSC::PropertyTable::canInsert):
(JSC::PropertyTable::forEachProperty const):
(JSC::PropertyTable::forEachPropertyMutable):
(JSC::PropertyTable::begin): Deleted.
(JSC::PropertyTable::end): Deleted.
(JSC::PropertyTable::begin const): Deleted.
(JSC::PropertyTable::end const): Deleted.
(JSC::PropertyTable::table): Deleted.
(JSC::PropertyTable::table const): Deleted.
* Source/JavaScriptCore/runtime/RegExpMatchesArray.h:
* Source/JavaScriptCore/runtime/Structure.cpp:
(JSC::Structure::dumpStatistics):
(JSC::Structure::Structure):
(JSC::Structure::materializePropertyTable):
(JSC::Structure::nonPropertyTransitionSlow):
(JSC::Structure::isSealed):
(JSC::Structure::isFrozen):
(JSC::Structure::flattenDictionaryStructure):
(JSC::PropertyTableStatisticsExitLogger::~PropertyTableStatisticsExitLogger):
(JSC::Structure::getConcurrently):
(JSC::Structure::getPropertiesConcurrently):
(JSC::Structure::getPropertyNamesFromStructure):
(JSC::Structure::toStructureShape):
(JSC::Structure::dump const):
* Source/JavaScriptCore/runtime/Structure.h:
(JSC::CompactPropertyTableEntry::CompactPropertyTableEntry):
(JSC::CompactPropertyTableEntry::key const):
(JSC::CompactPropertyTableEntry::setKey):
(JSC::CompactPropertyTableEntry::offset const):
(JSC::CompactPropertyTableEntry::setOffset):
(JSC::CompactPropertyTableEntry::attributes const):
(JSC::CompactPropertyTableEntry::setAttributes):
(JSC::PropertyTableEntry::PropertyTableEntry):
(JSC::PropertyTableEntry::key const):
(JSC::PropertyTableEntry::setKey):
(JSC::PropertyTableEntry::offset const):
(JSC::PropertyTableEntry::setOffset):
(JSC::PropertyTableEntry::attributes const):
(JSC::PropertyTableEntry::setAttributes):
(JSC::PropertyMapEntry::PropertyMapEntry): Deleted.
* Source/JavaScriptCore/runtime/StructureInlines.h:
(JSC::Structure::get):
(JSC::Structure::forEachPropertyConcurrently):
(JSC::Structure::forEachProperty):
(JSC::Structure::add):
(JSC::Structure::remove):
(JSC::Structure::attributeChange):

Canonical link: https://commits.webkit.org/249881@main

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@293210 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/runtime/RegExpMatchesArray.h b/Source/JavaScriptCore/runtime/RegExpMatchesArray.h
index a91d20f..4b2c3f2 100644
--- a/Source/JavaScriptCore/runtime/RegExpMatchesArray.h
+++ b/Source/JavaScriptCore/runtime/RegExpMatchesArray.h
@@ -30,11 +30,11 @@
 
 namespace JSC {
 
-static const PropertyOffset RegExpMatchesArrayIndexPropertyOffset = 100;
-static const PropertyOffset RegExpMatchesArrayInputPropertyOffset = 101;
-static const PropertyOffset RegExpMatchesArrayGroupsPropertyOffset = 102;
-static const PropertyOffset RegExpMatchesArrayIndicesPropertyOffset = 103;
-static const PropertyOffset RegExpMatchesIndicesGroupsPropertyOffset = 100;
+static constexpr PropertyOffset RegExpMatchesArrayIndexPropertyOffset = firstOutOfLineOffset;
+static constexpr PropertyOffset RegExpMatchesArrayInputPropertyOffset = firstOutOfLineOffset + 1;
+static constexpr PropertyOffset RegExpMatchesArrayGroupsPropertyOffset = firstOutOfLineOffset + 2;
+static constexpr PropertyOffset RegExpMatchesArrayIndicesPropertyOffset = firstOutOfLineOffset + 3;
+static constexpr PropertyOffset RegExpMatchesIndicesGroupsPropertyOffset = firstOutOfLineOffset;
 
 ALWAYS_INLINE JSArray* tryCreateUninitializedRegExpMatchesArray(ObjectInitializationScope& scope, GCDeferralContext* deferralContext, Structure* structure, unsigned initialLength)
 {