Diff
Modified: trunk/Source/_javascript_Core/CMakeLists.txt (286033 => 286034)
--- trunk/Source/_javascript_Core/CMakeLists.txt 2021-11-18 23:09:07 UTC (rev 286033)
+++ trunk/Source/_javascript_Core/CMakeLists.txt 2021-11-18 23:19:03 UTC (rev 286034)
@@ -1139,12 +1139,12 @@
runtime/PrivateName.h
runtime/ProgramExecutable.h
runtime/PropertyDescriptor.h
- runtime/PropertyMapHashTable.h
runtime/PropertyName.h
runtime/PropertyNameArray.h
runtime/PropertyOffset.h
runtime/PropertySlot.h
runtime/PropertyStorage.h
+ runtime/PropertyTable.h
runtime/Protect.h
runtime/PrototypeKey.h
runtime/ProxyObject.h
Modified: trunk/Source/_javascript_Core/ChangeLog (286033 => 286034)
--- trunk/Source/_javascript_Core/ChangeLog 2021-11-18 23:09:07 UTC (rev 286033)
+++ trunk/Source/_javascript_Core/ChangeLog 2021-11-18 23:19:03 UTC (rev 286034)
@@ -1,5 +1,35 @@
2021-11-18 Mark Lam <[email protected]>
+ Rename PropertyMapHashTable.h to PropertyTable.h to match the class.
+ https://bugs.webkit.org/show_bug.cgi?id=233333
+ rdar://85565760
+
+ Reviewed by Yusuke Suzuki.
+
+ Also renamed some supporting data structures to match. This is just a refactoring
+ patch. There are no behavior changes.
+
+ * CMakeLists.txt:
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * runtime/PropertyMapHashTable.h: Removed.
+ * runtime/PropertyTable.cpp:
+ * runtime/PropertyTable.h: Copied from Source/_javascript_Core/runtime/PropertyMapHashTable.h.
+ (JSC::PropertyTable::find):
+ (JSC::PropertyTable::get):
+ (JSC::PropertyTable::add):
+ (JSC::PropertyTable::remove):
+ (JSC::PropertyTable::reinsert):
+ (JSC::PropertyTable::rehash):
+ * runtime/Structure.cpp:
+ (JSC::PropertyTableStatisticsExitLogger::PropertyTableStatisticsExitLogger):
+ (JSC::PropertyTableStatisticsExitLogger::~PropertyTableStatisticsExitLogger):
+ (JSC::PropertyMapStatisticsExitLogger::PropertyMapStatisticsExitLogger): Deleted.
+ (JSC::PropertyMapStatisticsExitLogger::~PropertyMapStatisticsExitLogger): Deleted.
+ * runtime/StructureInlines.h:
+ * runtime/VM.cpp:
+
+2021-11-18 Mark Lam <[email protected]>
+
CellAttributes should be returned by value.
https://bugs.webkit.org/show_bug.cgi?id=233335
rdar://85568435
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (286033 => 286034)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2021-11-18 23:09:07 UTC (rev 286033)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2021-11-18 23:19:03 UTC (rev 286034)
@@ -1750,7 +1750,7 @@
BC756FC90E2031B200DE7D12 /* JSGlobalObjectFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = BC756FC70E2031B200DE7D12 /* JSGlobalObjectFunctions.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC87CDB910712AD4000614CF /* JSONObject.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC87CDB810712ACA000614CF /* JSONObject.lut.h */; };
BC9041480EB9250900FE26FA /* StructureTransitionTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BC9041470EB9250900FE26FA /* StructureTransitionTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC95437D0EBA70FD0072B6D3 /* PropertyMapHashTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BC95437C0EBA70FD0072B6D3 /* PropertyMapHashTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BC95437D0EBA70FD0072B6D3 /* PropertyTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BC95437C0EBA70FD0072B6D3 /* PropertyTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCBE2CAE14E985AA000593AD /* GCAssertions.h in Headers */ = {isa = PBXBuildFile; fileRef = BCBE2CAD14E985AA000593AD /* GCAssertions.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCCF0D080EF0AAB900413C8F /* StructureStubInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = BCCF0D070EF0AAB900413C8F /* StructureStubInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCD202C20E1706A7002C7E82 /* RegExpConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD202BE0E1706A7002C7E82 /* RegExpConstructor.h */; };
@@ -4991,7 +4991,7 @@
BC87CDB810712ACA000614CF /* JSONObject.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSONObject.lut.h; sourceTree = "<group>"; };
BC8F3CCF0DAF17BA00577A80 /* ConstructData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstructData.h; sourceTree = "<group>"; };
BC9041470EB9250900FE26FA /* StructureTransitionTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureTransitionTable.h; sourceTree = "<group>"; };
- BC95437C0EBA70FD0072B6D3 /* PropertyMapHashTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PropertyMapHashTable.h; sourceTree = "<group>"; };
+ BC95437C0EBA70FD0072B6D3 /* PropertyTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PropertyTable.h; sourceTree = "<group>"; };
BC9BB95B0E19680600DF8855 /* InternalFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InternalFunction.cpp; sourceTree = "<group>"; };
BCA62DFE0E2826230004F30D /* CallData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CallData.cpp; sourceTree = "<group>"; };
BCA62DFF0E2826310004F30D /* ConstructData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConstructData.cpp; sourceTree = "<group>"; };
@@ -7958,7 +7958,6 @@
147341D31DC02E6D00AA29BA /* ProgramExecutable.h */,
A7FB60A3103F7DC20017A286 /* PropertyDescriptor.cpp */,
A7FB604B103F5EAB0017A286 /* PropertyDescriptor.h */,
- BC95437C0EBA70FD0072B6D3 /* PropertyMapHashTable.h */,
86158AB2155C8B3F00B45C9C /* PropertyName.h */,
65400C100A69BAF200509887 /* PropertyNameArray.h */,
0FF7168A15A3B231008F5DAA /* PropertyOffset.h */,
@@ -7966,6 +7965,7 @@
65621E6C089E859700760F35 /* PropertySlot.h */,
0FB7F39015ED8E3800F167B2 /* PropertyStorage.h */,
AD1CF06816DCAB2D00B97123 /* PropertyTable.cpp */,
+ BC95437C0EBA70FD0072B6D3 /* PropertyTable.h */,
65C02FBB0637462A003E7EE6 /* Protect.h */,
0F74B93A1F89614500B935D3 /* PrototypeKey.h */,
79B00CB81C6AB07E0088C65D /* ProxyConstructor.cpp */,
@@ -10676,7 +10676,7 @@
147341D41DC02E6D00AA29BA /* ProgramExecutable.h in Headers */,
0FD3E40E1B618B6600C80E1E /* PropertyCondition.h in Headers */,
A7FB61001040C38B0017A286 /* PropertyDescriptor.h in Headers */,
- BC95437D0EBA70FD0072B6D3 /* PropertyMapHashTable.h in Headers */,
+ BC95437D0EBA70FD0072B6D3 /* PropertyTable.h in Headers */,
86158AB3155C8B4000B45C9C /* PropertyName.h in Headers */,
BC18C4540E16F5CD00B34460 /* PropertyNameArray.h in Headers */,
0FF7168C15A3B235008F5DAA /* PropertyOffset.h in Headers */,
Deleted: trunk/Source/_javascript_Core/runtime/PropertyMapHashTable.h (286033 => 286034)
--- trunk/Source/_javascript_Core/runtime/PropertyMapHashTable.h 2021-11-18 23:09:07 UTC (rev 286033)
+++ trunk/Source/_javascript_Core/runtime/PropertyMapHashTable.h 2021-11-18 23:19:03 UTC (rev 286034)
@@ -1,587 +0,0 @@
-/*
- * Copyright (C) 2004-2021 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#pragma once
-
-#include "JSExportMacros.h"
-#include "PropertyOffset.h"
-#include "Structure.h"
-#include "WriteBarrier.h"
-#include <wtf/HashTable.h>
-#include <wtf/MathExtras.h>
-#include <wtf/StdLibExtras.h>
-#include <wtf/Vector.h>
-#include <wtf/text/AtomStringImpl.h>
-
-
-#define DUMP_PROPERTYMAP_STATS 0
-#define DUMP_PROPERTYMAP_COLLISIONS 0
-
-#define PROPERTY_MAP_DELETED_ENTRY_KEY ((UniquedStringImpl*)1)
-
-namespace JSC {
-
-DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(PropertyTable);
-
-#if DUMP_PROPERTYMAP_STATS
-
-struct PropertyMapHashTableStats {
- std::atomic<unsigned> numFinds;
- std::atomic<unsigned> numCollisions;
- std::atomic<unsigned> numLookups;
- std::atomic<unsigned> numLookupProbing;
- std::atomic<unsigned> numAdds;
- std::atomic<unsigned> numRemoves;
- std::atomic<unsigned> numRehashes;
- std::atomic<unsigned> numReinserts;
-};
-
-JS_EXPORT_PRIVATE extern PropertyMapHashTableStats* propertyMapHashTableStats;
-
-#endif
-
-inline bool isPowerOf2(unsigned v)
-{
- return hasOneBitSet(v);
-}
-
-inline unsigned nextPowerOf2(unsigned v)
-{
- // Taken from http://www.cs.utk.edu/~vose/c-stuff/bithacks.html
- // Devised by Sean Anderson, Sepember 14, 2001
-
- v--;
- v |= v >> 1;
- v |= v >> 2;
- v |= v >> 4;
- v |= v >> 8;
- v |= v >> 16;
- v++;
-
- return v;
-}
-
-class PropertyTable final : public JSCell {
-
- // This is the implementation for 'iterator' and 'const_iterator',
- // used for iterating over the table in insertion order.
- template<typename T>
- class ordered_iterator {
- public:
- ordered_iterator<T>& operator++()
- {
- m_valuePtr = skipDeletedEntries(m_valuePtr + 1, m_endValuePtr);
- return *this;
- }
-
- bool operator==(const ordered_iterator<T>& other)
- {
- return m_valuePtr == other.m_valuePtr;
- }
-
- bool operator!=(const ordered_iterator<T>& other)
- {
- return m_valuePtr != other.m_valuePtr;
- }
-
- T& operator*()
- {
- return *m_valuePtr;
- }
-
- T* operator->()
- {
- return m_valuePtr;
- }
-
- ordered_iterator(T* valuePtr, T* endValuePtr)
- : m_valuePtr(valuePtr)
- , m_endValuePtr(endValuePtr)
- {
- }
-
- private:
- T* m_valuePtr;
- T* m_endValuePtr;
- };
-
-public:
- typedef JSCell Base;
- static constexpr unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
-
- template<typename CellType, SubspaceAccess>
- static IsoSubspace* subspaceFor(VM& vm)
- {
- return &vm.propertyTableSpace;
- }
-
- static constexpr bool needsDestruction = true;
- static void destroy(JSCell*);
- DECLARE_VISIT_CHILDREN;
-
- DECLARE_EXPORT_INFO;
-
- static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
- {
- return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
- }
-
- typedef UniquedStringImpl* KeyType;
- typedef PropertyMapEntry ValueType;
-
- // The in order iterator provides overloaded * and -> to access the Value at the current position.
- typedef ordered_iterator<ValueType> iterator;
- typedef ordered_iterator<const ValueType> const_iterator;
-
- // The find_iterator is a pair of a pointer to a Value* an the entry in the index.
- // If 'find' does not find an entry then iter.first will be 0, and iter.second will
- // give the point in m_index where an entry should be inserted.
- typedef std::pair<ValueType*, unsigned> find_iterator;
-
- // Constructor is passed an initial capacity, a PropertyTable to copy, or both.
- static PropertyTable* create(VM&, unsigned initialCapacity);
- static PropertyTable* clone(VM&, const PropertyTable&);
- static PropertyTable* clone(VM&, unsigned initialCapacity, const PropertyTable&);
- ~PropertyTable();
-
- // Ordered iteration methods.
- iterator begin();
- iterator end();
- const_iterator begin() const;
- const_iterator end() const;
-
- // Find a value in the table.
- find_iterator find(const KeyType&);
- ValueType* get(const KeyType&);
- // Add a value to the table
- std::pair<find_iterator, bool> WARN_UNUSED_RETURN add(VM&, const ValueType& entry);
- // Remove a value from the table.
- void remove(VM&, const find_iterator& iter);
- void remove(VM&, const KeyType& key);
-
- // Returns the number of values in the hashtable.
- unsigned size() const;
-
- // Checks if there are any values in the hashtable.
- bool isEmpty() const;
-
- // Number of slots in the property storage array in use, included deletedOffsets.
- unsigned propertyStorageSize() const;
-
- // Used to maintain a list of unused entries in the property storage.
- void clearDeletedOffsets();
- bool hasDeletedOffset();
- PropertyOffset getDeletedOffset();
- void addDeletedOffset(PropertyOffset);
-
- PropertyOffset nextOffset(PropertyOffset inlineCapacity);
-
- // Copy this PropertyTable, ensuring the copy has at least the capacity provided.
- PropertyTable* copy(VM&, unsigned newCapacity);
-
-#ifndef NDEBUG
- size_t sizeInMemory();
- void checkConsistency();
-#endif
-
- static ptrdiff_t offsetOfIndexSize() { return OBJECT_OFFSETOF(PropertyTable, m_indexSize); }
- static ptrdiff_t offsetOfIndexMask() { return OBJECT_OFFSETOF(PropertyTable, m_indexMask); }
- static ptrdiff_t offsetOfIndex() { return OBJECT_OFFSETOF(PropertyTable, m_index); }
-
- static constexpr unsigned EmptyEntryIndex = 0;
-
-private:
- PropertyTable(VM&, unsigned initialCapacity);
- PropertyTable(VM&, const PropertyTable&);
- PropertyTable(VM&, unsigned initialCapacity, const PropertyTable&);
-
- PropertyTable(const PropertyTable&);
-
- void finishCreation(VM&);
-
- // Used to insert a value known not to be in the table, and where we know capacity to be available.
- void reinsert(const ValueType& entry);
-
- // Rehash the table. Used to grow, or to recover deleted slots.
- void rehash(VM&, unsigned newCapacity);
-
- // The capacity of the table of values is half of the size of the index.
- unsigned tableCapacity() const;
-
- // We keep an extra deleted slot after the array to make iteration work,
- // and to use for deleted values. Index values into the array are 1-based,
- // so this is tableCapacity() + 1.
- // For example, if m_tableSize is 16, then tableCapacity() is 8 - but the
- // values array is actually 9 long (the 9th used for the deleted value/
- // iteration guard). The 8 valid entries are numbered 1..8, so the
- // deleted index is 9 (0 being reserved for empty).
- unsigned deletedEntryIndex() const;
-
- // Used in iterator creation/progression.
- template<typename T>
- static T* skipDeletedEntries(T* valuePtr, T* endValuePtr);
-
- // The table of values lies after the hash index.
- ValueType* table();
- const ValueType* table() const;
-
- ValueType* tableEnd() { return table() + usedCount(); }
- const ValueType* tableEnd() const { return table() + usedCount(); }
-
- // total number of used entries in the values array - by either valid entries, or deleted ones.
- unsigned usedCount() const;
-
- // The size in bytes of data needed for by the table.
- size_t dataSize();
-
- // Calculates the appropriate table size (rounds up to a power of two).
- static unsigned sizeForCapacity(unsigned capacity);
-
- // Check if capacity is available.
- bool canInsert();
-
- unsigned m_indexSize;
- unsigned m_indexMask;
- unsigned* m_index;
- unsigned m_keyCount;
- unsigned m_deletedCount;
- std::unique_ptr<Vector<PropertyOffset>> m_deletedOffsets;
-
- static constexpr unsigned MinimumTableSize = 16;
-};
-
-inline PropertyTable::iterator PropertyTable::begin()
-{
- auto* tableEnd = this->tableEnd();
- return iterator(skipDeletedEntries(table(), tableEnd), tableEnd);
-}
-
-inline PropertyTable::iterator PropertyTable::end()
-{
- auto* tableEnd = this->tableEnd();
- return iterator(tableEnd, tableEnd);
-}
-
-inline PropertyTable::const_iterator PropertyTable::begin() const
-{
- auto* tableEnd = this->tableEnd();
- return const_iterator(skipDeletedEntries(table(), tableEnd), tableEnd);
-}
-
-inline PropertyTable::const_iterator PropertyTable::end() const
-{
- auto* tableEnd = this->tableEnd();
- return const_iterator(tableEnd, tableEnd);
-}
-
-inline PropertyTable::find_iterator PropertyTable::find(const KeyType& key)
-{
- ASSERT(key);
- ASSERT(key->isAtom() || key->isSymbol());
- unsigned hash = IdentifierRepHash::hash(key);
-
-#if DUMP_PROPERTYMAP_STATS
- ++propertyMapHashTableStats->numFinds;
-#endif
-
- while (true) {
- unsigned entryIndex = m_index[hash & m_indexMask];
- if (entryIndex == EmptyEntryIndex)
- return std::make_pair((ValueType*)nullptr, hash & m_indexMask);
- if (key == table()[entryIndex - 1].key)
- return std::make_pair(&table()[entryIndex - 1], hash & m_indexMask);
-
-#if DUMP_PROPERTYMAP_STATS
- ++propertyMapHashTableStats->numCollisions;
-#endif
-
-#if DUMP_PROPERTYMAP_COLLISIONS
- dataLog("PropertyTable collision for ", key, " (", hash, ")\n");
- dataLog("Collided with ", table()[entryIndex - 1].key, "(", IdentifierRepHash::hash(table()[entryIndex - 1].key), ")\n");
-#endif
-
- hash++;
- }
-}
-
-inline PropertyTable::ValueType* PropertyTable::get(const KeyType& key)
-{
- ASSERT(key);
- ASSERT(key->isAtom() || key->isSymbol());
- ASSERT(key != PROPERTY_MAP_DELETED_ENTRY_KEY);
-
- if (!m_keyCount)
- return nullptr;
-
- unsigned hash = IdentifierRepHash::hash(key);
-
-#if DUMP_PROPERTYMAP_STATS
- ++propertyMapHashTableStats->numLookups;
-#endif
-
- while (true) {
- unsigned entryIndex = m_index[hash & m_indexMask];
- if (entryIndex == EmptyEntryIndex)
- return nullptr;
- if (key == table()[entryIndex - 1].key) {
- ASSERT(!m_deletedOffsets || !m_deletedOffsets->contains(table()[entryIndex - 1].offset));
- return &table()[entryIndex - 1];
- }
-
-#if DUMP_PROPERTYMAP_STATS
- ++propertyMapHashTableStats->numLookupProbing;
-#endif
-
- hash++;
- }
-}
-
-inline std::pair<PropertyTable::find_iterator, bool> WARN_UNUSED_RETURN PropertyTable::add(VM& vm, const ValueType& entry)
-{
- ASSERT(!m_deletedOffsets || !m_deletedOffsets->contains(entry.offset));
-
- // Look for a value with a matching key already in the array.
- find_iterator iter = find(entry.key);
- if (iter.first)
- return std::make_pair(iter, false);
-
-#if DUMP_PROPERTYMAP_STATS
- ++propertyMapHashTableStats->numAdds;
-#endif
-
- // Ref the key
- entry.key->ref();
-
- // ensure capacity is available.
- if (!canInsert()) {
- rehash(vm, m_keyCount + 1);
- iter = find(entry.key);
- ASSERT(!iter.first);
- }
-
- // Allocate a slot in the hashtable, and set the index to reference this.
- unsigned entryIndex = usedCount() + 1;
- m_index[iter.second] = entryIndex;
- iter.first = &table()[entryIndex - 1];
- *iter.first = entry;
-
- ++m_keyCount;
-
- return std::make_pair(iter, true);
-}
-
-inline void PropertyTable::remove(VM& vm, const find_iterator& iter)
-{
- // Removing a key that doesn't exist does nothing!
- if (!iter.first)
- return;
-
-#if DUMP_PROPERTYMAP_STATS
- ++propertyMapHashTableStats->numRemoves;
-#endif
-
- // Replace this one element with the deleted sentinel. Also clear out
- // the entry so we can iterate all the entries as needed.
- m_index[iter.second] = deletedEntryIndex();
- iter.first->key->deref();
- iter.first->key = PROPERTY_MAP_DELETED_ENTRY_KEY;
-
- ASSERT(m_keyCount >= 1);
- --m_keyCount;
- ++m_deletedCount;
-
- if (m_deletedCount * 4 >= m_indexSize)
- rehash(vm, m_keyCount);
-}
-
-inline void PropertyTable::remove(VM& vm, const KeyType& key)
-{
- remove(vm, find(key));
-}
-
-// returns the number of values in the hashtable.
-inline unsigned PropertyTable::size() const
-{
- return m_keyCount;
-}
-
-inline bool PropertyTable::isEmpty() const
-{
- return !m_keyCount;
-}
-
-inline unsigned PropertyTable::propertyStorageSize() const
-{
- return size() + (m_deletedOffsets ? m_deletedOffsets->size() : 0);
-}
-
-inline void PropertyTable::clearDeletedOffsets()
-{
- m_deletedOffsets = nullptr;
-}
-
-inline bool PropertyTable::hasDeletedOffset()
-{
- return m_deletedOffsets && !m_deletedOffsets->isEmpty();
-}
-
-inline PropertyOffset PropertyTable::getDeletedOffset()
-{
- PropertyOffset offset = m_deletedOffsets->last();
- m_deletedOffsets->removeLast();
- return offset;
-}
-
-inline void PropertyTable::addDeletedOffset(PropertyOffset offset)
-{
- if (!m_deletedOffsets)
- m_deletedOffsets = makeUnique<Vector<PropertyOffset>>();
- ASSERT(!m_deletedOffsets->contains(offset));
- m_deletedOffsets->append(offset);
-}
-
-inline PropertyOffset PropertyTable::nextOffset(PropertyOffset inlineCapacity)
-{
- if (hasDeletedOffset())
- return getDeletedOffset();
-
- return offsetForPropertyNumber(size(), inlineCapacity);
-}
-
-inline PropertyTable* PropertyTable::copy(VM& vm, unsigned newCapacity)
-{
- ASSERT(newCapacity >= m_keyCount);
-
- // Fast case; if the new table will be the same m_indexSize as this one, we can memcpy it,
- // save rehashing all keys.
- if (sizeForCapacity(newCapacity) == m_indexSize)
- return PropertyTable::clone(vm, *this);
- return PropertyTable::clone(vm, newCapacity, *this);
-}
-
-#ifndef NDEBUG
-inline size_t PropertyTable::sizeInMemory()
-{
- size_t result = sizeof(PropertyTable) + dataSize();
- if (m_deletedOffsets)
- result += (m_deletedOffsets->capacity() * sizeof(PropertyOffset));
- return result;
-}
-#endif
-
-inline void PropertyTable::reinsert(const ValueType& entry)
-{
-#if DUMP_PROPERTYMAP_STATS
- ++propertyMapHashTableStats->numReinserts;
-#endif
-
- // Used to insert a value known not to be in the table, and where
- // we know capacity to be available.
- ASSERT(canInsert());
- find_iterator iter = find(entry.key);
- ASSERT(!iter.first);
-
- unsigned entryIndex = usedCount() + 1;
- m_index[iter.second] = entryIndex;
- table()[entryIndex - 1] = entry;
-
- ++m_keyCount;
-}
-
-inline void PropertyTable::rehash(VM& vm, unsigned newCapacity)
-{
-#if DUMP_PROPERTYMAP_STATS
- ++propertyMapHashTableStats->numRehashes;
-#endif
-
- size_t oldDataSize = dataSize();
- unsigned* oldEntryIndices = m_index;
- iterator iter = this->begin();
- iterator end = this->end();
-
- m_indexSize = sizeForCapacity(newCapacity);
- m_indexMask = m_indexSize - 1;
- m_keyCount = 0;
- m_deletedCount = 0;
-
- m_index = static_cast<unsigned*>(PropertyTableMalloc::zeroedMalloc(dataSize()));
-
- for (; iter != end; ++iter) {
- ASSERT(canInsert());
- reinsert(*iter);
- }
-
- PropertyTableMalloc::free(oldEntryIndices);
-
- if (oldDataSize < dataSize())
- vm.heap.reportExtraMemoryAllocated(dataSize() - oldDataSize);
-}
-
-inline unsigned PropertyTable::tableCapacity() const { return m_indexSize >> 1; }
-
-inline unsigned PropertyTable::deletedEntryIndex() const { return tableCapacity() + 1; }
-
-template<typename T>
-inline T* PropertyTable::skipDeletedEntries(T* valuePtr, T* endValuePtr)
-{
- while (valuePtr < endValuePtr && valuePtr->key == PROPERTY_MAP_DELETED_ENTRY_KEY)
- ++valuePtr;
- return valuePtr;
-}
-
-inline PropertyTable::ValueType* PropertyTable::table()
-{
- // The table of values lies after the hash index.
- return reinterpret_cast_ptr<ValueType*>(m_index + m_indexSize);
-}
-
-inline const PropertyTable::ValueType* PropertyTable::table() const
-{
- // The table of values lies after the hash index.
- return reinterpret_cast_ptr<const ValueType*>(m_index + m_indexSize);
-}
-
-inline unsigned PropertyTable::usedCount() const
-{
- // Total number of used entries in the values array - by either valid entries, or deleted ones.
- return m_keyCount + m_deletedCount;
-}
-
-inline size_t PropertyTable::dataSize()
-{
- // The size in bytes of data needed for by the table.
- // Ensure that this function can be called concurrently.
- unsigned indexSize = m_indexSize;
- return indexSize * sizeof(unsigned) + ((indexSize >> 1) + 1) * sizeof(ValueType);
-}
-
-inline unsigned PropertyTable::sizeForCapacity(unsigned capacity)
-{
- if (capacity < MinimumTableSize / 2)
- return MinimumTableSize;
- return nextPowerOf2(capacity + 1) * 2;
-}
-
-inline bool PropertyTable::canInsert()
-{
- return usedCount() < tableCapacity();
-}
-
-} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/PropertyTable.cpp (286033 => 286034)
--- trunk/Source/_javascript_Core/runtime/PropertyTable.cpp 2021-11-18 23:09:07 UTC (rev 286033)
+++ trunk/Source/_javascript_Core/runtime/PropertyTable.cpp 2021-11-18 23:19:03 UTC (rev 286034)
@@ -24,7 +24,7 @@
*/
#include "config.h"
-#include "PropertyMapHashTable.h"
+#include "PropertyTable.h"
#include "JSCJSValueInlines.h"
Copied: trunk/Source/_javascript_Core/runtime/PropertyTable.h (from rev 286033, trunk/Source/_javascript_Core/runtime/PropertyMapHashTable.h) (0 => 286034)
--- trunk/Source/_javascript_Core/runtime/PropertyTable.h (rev 0)
+++ trunk/Source/_javascript_Core/runtime/PropertyTable.h 2021-11-18 23:19:03 UTC (rev 286034)
@@ -0,0 +1,587 @@
+/*
+ * Copyright (C) 2004-2021 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#pragma once
+
+#include "JSExportMacros.h"
+#include "PropertyOffset.h"
+#include "Structure.h"
+#include "WriteBarrier.h"
+#include <wtf/HashTable.h>
+#include <wtf/MathExtras.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/Vector.h>
+#include <wtf/text/AtomStringImpl.h>
+
+
+#define DUMP_PROPERTYMAP_STATS 0
+#define DUMP_PROPERTYMAP_COLLISIONS 0
+
+#define PROPERTY_MAP_DELETED_ENTRY_KEY ((UniquedStringImpl*)1)
+
+namespace JSC {
+
+DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(PropertyTable);
+
+#if DUMP_PROPERTYMAP_STATS
+
+struct PropertyTableStats {
+ std::atomic<unsigned> numFinds;
+ std::atomic<unsigned> numCollisions;
+ std::atomic<unsigned> numLookups;
+ std::atomic<unsigned> numLookupProbing;
+ std::atomic<unsigned> numAdds;
+ std::atomic<unsigned> numRemoves;
+ std::atomic<unsigned> numRehashes;
+ std::atomic<unsigned> numReinserts;
+};
+
+JS_EXPORT_PRIVATE extern PropertyTableStats* propertyTableStats;
+
+#endif
+
+inline bool isPowerOf2(unsigned v)
+{
+ return hasOneBitSet(v);
+}
+
+inline unsigned nextPowerOf2(unsigned v)
+{
+ // Taken from http://www.cs.utk.edu/~vose/c-stuff/bithacks.html
+ // Devised by Sean Anderson, Sepember 14, 2001
+
+ v--;
+ v |= v >> 1;
+ v |= v >> 2;
+ v |= v >> 4;
+ v |= v >> 8;
+ v |= v >> 16;
+ v++;
+
+ return v;
+}
+
+class PropertyTable final : public JSCell {
+
+ // This is the implementation for 'iterator' and 'const_iterator',
+ // used for iterating over the table in insertion order.
+ template<typename T>
+ class ordered_iterator {
+ public:
+ ordered_iterator<T>& operator++()
+ {
+ m_valuePtr = skipDeletedEntries(m_valuePtr + 1, m_endValuePtr);
+ return *this;
+ }
+
+ bool operator==(const ordered_iterator<T>& other)
+ {
+ return m_valuePtr == other.m_valuePtr;
+ }
+
+ bool operator!=(const ordered_iterator<T>& other)
+ {
+ return m_valuePtr != other.m_valuePtr;
+ }
+
+ T& operator*()
+ {
+ return *m_valuePtr;
+ }
+
+ T* operator->()
+ {
+ return m_valuePtr;
+ }
+
+ ordered_iterator(T* valuePtr, T* endValuePtr)
+ : m_valuePtr(valuePtr)
+ , m_endValuePtr(endValuePtr)
+ {
+ }
+
+ private:
+ T* m_valuePtr;
+ T* m_endValuePtr;
+ };
+
+public:
+ typedef JSCell Base;
+ static constexpr unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+
+ template<typename CellType, SubspaceAccess>
+ static IsoSubspace* subspaceFor(VM& vm)
+ {
+ return &vm.propertyTableSpace;
+ }
+
+ static constexpr bool needsDestruction = true;
+ static void destroy(JSCell*);
+ DECLARE_VISIT_CHILDREN;
+
+ DECLARE_EXPORT_INFO;
+
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+ {
+ return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
+ }
+
+ typedef UniquedStringImpl* KeyType;
+ typedef PropertyMapEntry ValueType;
+
+ // The in order iterator provides overloaded * and -> to access the Value at the current position.
+ typedef ordered_iterator<ValueType> iterator;
+ typedef ordered_iterator<const ValueType> const_iterator;
+
+ // The find_iterator is a pair of a pointer to a Value* an the entry in the index.
+ // If 'find' does not find an entry then iter.first will be 0, and iter.second will
+ // give the point in m_index where an entry should be inserted.
+ typedef std::pair<ValueType*, unsigned> find_iterator;
+
+ // Constructor is passed an initial capacity, a PropertyTable to copy, or both.
+ static PropertyTable* create(VM&, unsigned initialCapacity);
+ static PropertyTable* clone(VM&, const PropertyTable&);
+ static PropertyTable* clone(VM&, unsigned initialCapacity, const PropertyTable&);
+ ~PropertyTable();
+
+ // Ordered iteration methods.
+ iterator begin();
+ iterator end();
+ const_iterator begin() const;
+ const_iterator end() const;
+
+ // Find a value in the table.
+ find_iterator find(const KeyType&);
+ ValueType* get(const KeyType&);
+ // Add a value to the table
+ std::pair<find_iterator, bool> WARN_UNUSED_RETURN add(VM&, const ValueType& entry);
+ // Remove a value from the table.
+ void remove(VM&, const find_iterator&);
+ void remove(VM&, const KeyType&);
+
+ // Returns the number of values in the hashtable.
+ unsigned size() const;
+
+ // Checks if there are any values in the hashtable.
+ bool isEmpty() const;
+
+ // Number of slots in the property storage array in use, included deletedOffsets.
+ unsigned propertyStorageSize() const;
+
+ // Used to maintain a list of unused entries in the property storage.
+ void clearDeletedOffsets();
+ bool hasDeletedOffset();
+ PropertyOffset getDeletedOffset();
+ void addDeletedOffset(PropertyOffset);
+
+ PropertyOffset nextOffset(PropertyOffset inlineCapacity);
+
+ // Copy this PropertyTable, ensuring the copy has at least the capacity provided.
+ PropertyTable* copy(VM&, unsigned newCapacity);
+
+#ifndef NDEBUG
+ size_t sizeInMemory();
+ void checkConsistency();
+#endif
+
+ static ptrdiff_t offsetOfIndexSize() { return OBJECT_OFFSETOF(PropertyTable, m_indexSize); }
+ static ptrdiff_t offsetOfIndexMask() { return OBJECT_OFFSETOF(PropertyTable, m_indexMask); }
+ static ptrdiff_t offsetOfIndex() { return OBJECT_OFFSETOF(PropertyTable, m_index); }
+
+ static constexpr unsigned EmptyEntryIndex = 0;
+
+private:
+ PropertyTable(VM&, unsigned initialCapacity);
+ PropertyTable(VM&, const PropertyTable&);
+ PropertyTable(VM&, unsigned initialCapacity, const PropertyTable&);
+
+ PropertyTable(const PropertyTable&);
+
+ void finishCreation(VM&);
+
+ // Used to insert a value known not to be in the table, and where we know capacity to be available.
+ void reinsert(const ValueType& entry);
+
+ // Rehash the table. Used to grow, or to recover deleted slots.
+ void rehash(VM&, unsigned newCapacity);
+
+ // The capacity of the table of values is half of the size of the index.
+ unsigned tableCapacity() const;
+
+ // We keep an extra deleted slot after the array to make iteration work,
+ // and to use for deleted values. Index values into the array are 1-based,
+ // so this is tableCapacity() + 1.
+ // For example, if m_tableSize is 16, then tableCapacity() is 8 - but the
+ // values array is actually 9 long (the 9th used for the deleted value/
+ // iteration guard). The 8 valid entries are numbered 1..8, so the
+ // deleted index is 9 (0 being reserved for empty).
+ unsigned deletedEntryIndex() const;
+
+ // Used in iterator creation/progression.
+ template<typename T>
+ static T* skipDeletedEntries(T* valuePtr, T* endValuePtr);
+
+ // The table of values lies after the hash index.
+ ValueType* table();
+ const ValueType* table() const;
+
+ ValueType* tableEnd() { return table() + usedCount(); }
+ const ValueType* tableEnd() const { return table() + usedCount(); }
+
+ // total number of used entries in the values array - by either valid entries, or deleted ones.
+ unsigned usedCount() const;
+
+ // The size in bytes of data needed for by the table.
+ size_t dataSize();
+
+ // Calculates the appropriate table size (rounds up to a power of two).
+ static unsigned sizeForCapacity(unsigned capacity);
+
+ // Check if capacity is available.
+ bool canInsert();
+
+ unsigned m_indexSize;
+ unsigned m_indexMask;
+ unsigned* m_index;
+ unsigned m_keyCount;
+ unsigned m_deletedCount;
+ std::unique_ptr<Vector<PropertyOffset>> m_deletedOffsets;
+
+ static constexpr unsigned MinimumTableSize = 16;
+};
+
+inline PropertyTable::iterator PropertyTable::begin()
+{
+ auto* tableEnd = this->tableEnd();
+ return iterator(skipDeletedEntries(table(), tableEnd), tableEnd);
+}
+
+inline PropertyTable::iterator PropertyTable::end()
+{
+ auto* tableEnd = this->tableEnd();
+ return iterator(tableEnd, tableEnd);
+}
+
+inline PropertyTable::const_iterator PropertyTable::begin() const
+{
+ auto* tableEnd = this->tableEnd();
+ return const_iterator(skipDeletedEntries(table(), tableEnd), tableEnd);
+}
+
+inline PropertyTable::const_iterator PropertyTable::end() const
+{
+ auto* tableEnd = this->tableEnd();
+ return const_iterator(tableEnd, tableEnd);
+}
+
+inline PropertyTable::find_iterator PropertyTable::find(const KeyType& key)
+{
+ ASSERT(key);
+ ASSERT(key->isAtom() || key->isSymbol());
+ unsigned hash = IdentifierRepHash::hash(key);
+
+#if DUMP_PROPERTYMAP_STATS
+ ++propertyTableStats->numFinds;
+#endif
+
+ while (true) {
+ unsigned entryIndex = m_index[hash & m_indexMask];
+ if (entryIndex == EmptyEntryIndex)
+ return std::make_pair((ValueType*)nullptr, hash & m_indexMask);
+ if (key == table()[entryIndex - 1].key)
+ return std::make_pair(&table()[entryIndex - 1], hash & m_indexMask);
+
+#if DUMP_PROPERTYMAP_STATS
+ ++propertyTableStats->numCollisions;
+#endif
+
+#if DUMP_PROPERTYMAP_COLLISIONS
+ dataLog("PropertyTable collision for ", key, " (", hash, ")\n");
+ dataLog("Collided with ", table()[entryIndex - 1].key, "(", IdentifierRepHash::hash(table()[entryIndex - 1].key), ")\n");
+#endif
+
+ hash++;
+ }
+}
+
+inline PropertyTable::ValueType* PropertyTable::get(const KeyType& key)
+{
+ ASSERT(key);
+ ASSERT(key->isAtom() || key->isSymbol());
+ ASSERT(key != PROPERTY_MAP_DELETED_ENTRY_KEY);
+
+ if (!m_keyCount)
+ return nullptr;
+
+ unsigned hash = IdentifierRepHash::hash(key);
+
+#if DUMP_PROPERTYMAP_STATS
+ ++propertyTableStats->numLookups;
+#endif
+
+ while (true) {
+ unsigned entryIndex = m_index[hash & m_indexMask];
+ if (entryIndex == EmptyEntryIndex)
+ return nullptr;
+ if (key == table()[entryIndex - 1].key) {
+ ASSERT(!m_deletedOffsets || !m_deletedOffsets->contains(table()[entryIndex - 1].offset));
+ return &table()[entryIndex - 1];
+ }
+
+#if DUMP_PROPERTYMAP_STATS
+ ++propertyTableStats->numLookupProbing;
+#endif
+
+ hash++;
+ }
+}
+
+inline std::pair<PropertyTable::find_iterator, bool> WARN_UNUSED_RETURN PropertyTable::add(VM& vm, const ValueType& entry)
+{
+ ASSERT(!m_deletedOffsets || !m_deletedOffsets->contains(entry.offset));
+
+ // Look for a value with a matching key already in the array.
+ find_iterator iter = find(entry.key);
+ if (iter.first)
+ return std::make_pair(iter, false);
+
+#if DUMP_PROPERTYMAP_STATS
+ ++propertyTableStats->numAdds;
+#endif
+
+ // Ref the key
+ entry.key->ref();
+
+ // ensure capacity is available.
+ if (!canInsert()) {
+ rehash(vm, m_keyCount + 1);
+ iter = find(entry.key);
+ ASSERT(!iter.first);
+ }
+
+ // Allocate a slot in the hashtable, and set the index to reference this.
+ unsigned entryIndex = usedCount() + 1;
+ m_index[iter.second] = entryIndex;
+ iter.first = &table()[entryIndex - 1];
+ *iter.first = entry;
+
+ ++m_keyCount;
+
+ return std::make_pair(iter, true);
+}
+
+inline void PropertyTable::remove(VM& vm, const find_iterator& iter)
+{
+ // Removing a key that doesn't exist does nothing!
+ if (!iter.first)
+ return;
+
+#if DUMP_PROPERTYMAP_STATS
+ ++propertyTableStats->numRemoves;
+#endif
+
+ // Replace this one element with the deleted sentinel. Also clear out
+ // the entry so we can iterate all the entries as needed.
+ m_index[iter.second] = deletedEntryIndex();
+ iter.first->key->deref();
+ iter.first->key = PROPERTY_MAP_DELETED_ENTRY_KEY;
+
+ ASSERT(m_keyCount >= 1);
+ --m_keyCount;
+ ++m_deletedCount;
+
+ if (m_deletedCount * 4 >= m_indexSize)
+ rehash(vm, m_keyCount);
+}
+
+inline void PropertyTable::remove(VM& vm, const KeyType& key)
+{
+ remove(vm, find(key));
+}
+
+// returns the number of values in the hashtable.
+inline unsigned PropertyTable::size() const
+{
+ return m_keyCount;
+}
+
+inline bool PropertyTable::isEmpty() const
+{
+ return !m_keyCount;
+}
+
+inline unsigned PropertyTable::propertyStorageSize() const
+{
+ return size() + (m_deletedOffsets ? m_deletedOffsets->size() : 0);
+}
+
+inline void PropertyTable::clearDeletedOffsets()
+{
+ m_deletedOffsets = nullptr;
+}
+
+inline bool PropertyTable::hasDeletedOffset()
+{
+ return m_deletedOffsets && !m_deletedOffsets->isEmpty();
+}
+
+inline PropertyOffset PropertyTable::getDeletedOffset()
+{
+ PropertyOffset offset = m_deletedOffsets->last();
+ m_deletedOffsets->removeLast();
+ return offset;
+}
+
+inline void PropertyTable::addDeletedOffset(PropertyOffset offset)
+{
+ if (!m_deletedOffsets)
+ m_deletedOffsets = makeUnique<Vector<PropertyOffset>>();
+ ASSERT(!m_deletedOffsets->contains(offset));
+ m_deletedOffsets->append(offset);
+}
+
+inline PropertyOffset PropertyTable::nextOffset(PropertyOffset inlineCapacity)
+{
+ if (hasDeletedOffset())
+ return getDeletedOffset();
+
+ return offsetForPropertyNumber(size(), inlineCapacity);
+}
+
+inline PropertyTable* PropertyTable::copy(VM& vm, unsigned newCapacity)
+{
+ ASSERT(newCapacity >= m_keyCount);
+
+ // Fast case; if the new table will be the same m_indexSize as this one, we can memcpy it,
+ // save rehashing all keys.
+ if (sizeForCapacity(newCapacity) == m_indexSize)
+ return PropertyTable::clone(vm, *this);
+ return PropertyTable::clone(vm, newCapacity, *this);
+}
+
+#ifndef NDEBUG
+inline size_t PropertyTable::sizeInMemory()
+{
+ size_t result = sizeof(PropertyTable) + dataSize();
+ if (m_deletedOffsets)
+ result += (m_deletedOffsets->capacity() * sizeof(PropertyOffset));
+ return result;
+}
+#endif
+
+inline void PropertyTable::reinsert(const ValueType& entry)
+{
+#if DUMP_PROPERTYMAP_STATS
+ ++propertyTableStats->numReinserts;
+#endif
+
+ // Used to insert a value known not to be in the table, and where
+ // we know capacity to be available.
+ ASSERT(canInsert());
+ find_iterator iter = find(entry.key);
+ ASSERT(!iter.first);
+
+ unsigned entryIndex = usedCount() + 1;
+ m_index[iter.second] = entryIndex;
+ table()[entryIndex - 1] = entry;
+
+ ++m_keyCount;
+}
+
+inline void PropertyTable::rehash(VM& vm, unsigned newCapacity)
+{
+#if DUMP_PROPERTYMAP_STATS
+ ++propertyTableStats->numRehashes;
+#endif
+
+ size_t oldDataSize = dataSize();
+ unsigned* oldEntryIndices = m_index;
+ iterator iter = this->begin();
+ iterator end = this->end();
+
+ m_indexSize = sizeForCapacity(newCapacity);
+ m_indexMask = m_indexSize - 1;
+ m_keyCount = 0;
+ m_deletedCount = 0;
+
+ m_index = static_cast<unsigned*>(PropertyTableMalloc::zeroedMalloc(dataSize()));
+
+ for (; iter != end; ++iter) {
+ ASSERT(canInsert());
+ reinsert(*iter);
+ }
+
+ PropertyTableMalloc::free(oldEntryIndices);
+
+ if (oldDataSize < dataSize())
+ vm.heap.reportExtraMemoryAllocated(dataSize() - oldDataSize);
+}
+
+inline unsigned PropertyTable::tableCapacity() const { return m_indexSize >> 1; }
+
+inline unsigned PropertyTable::deletedEntryIndex() const { return tableCapacity() + 1; }
+
+template<typename T>
+inline T* PropertyTable::skipDeletedEntries(T* valuePtr, T* endValuePtr)
+{
+ while (valuePtr < endValuePtr && valuePtr->key == PROPERTY_MAP_DELETED_ENTRY_KEY)
+ ++valuePtr;
+ return valuePtr;
+}
+
+inline PropertyTable::ValueType* PropertyTable::table()
+{
+ // The table of values lies after the hash index.
+ return reinterpret_cast_ptr<ValueType*>(m_index + m_indexSize);
+}
+
+inline const PropertyTable::ValueType* PropertyTable::table() const
+{
+ // The table of values lies after the hash index.
+ return reinterpret_cast_ptr<const ValueType*>(m_index + m_indexSize);
+}
+
+inline unsigned PropertyTable::usedCount() const
+{
+ // Total number of used entries in the values array - by either valid entries, or deleted ones.
+ return m_keyCount + m_deletedCount;
+}
+
+inline size_t PropertyTable::dataSize()
+{
+ // The size in bytes of data needed for by the table.
+ // Ensure that this function can be called concurrently.
+ unsigned indexSize = m_indexSize;
+ return indexSize * sizeof(unsigned) + ((indexSize >> 1) + 1) * sizeof(ValueType);
+}
+
+inline unsigned PropertyTable::sizeForCapacity(unsigned capacity)
+{
+ if (capacity < MinimumTableSize / 2)
+ return MinimumTableSize;
+ return nextPowerOf2(capacity + 1) * 2;
+}
+
+inline bool PropertyTable::canInsert()
+{
+ return usedCount() < tableCapacity();
+}
+
+} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/Structure.cpp (286033 => 286034)
--- trunk/Source/_javascript_Core/runtime/Structure.cpp 2021-11-18 23:09:07 UTC (rev 286033)
+++ trunk/Source/_javascript_Core/runtime/Structure.cpp 2021-11-18 23:19:03 UTC (rev 286034)
@@ -31,8 +31,8 @@
#include "BuiltinNames.h"
#include "DumpContext.h"
#include "JSCInlines.h"
-#include "PropertyMapHashTable.h"
#include "PropertyNameArray.h"
+#include "PropertyTable.h"
#include <wtf/CommaPrinter.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/RefPtr.h>
@@ -1048,33 +1048,33 @@
#if DUMP_PROPERTYMAP_STATS
-PropertyMapHashTableStats* propertyMapHashTableStats = 0;
+PropertyTableStats* propertyTableStats = 0;
-struct PropertyMapStatisticsExitLogger {
- PropertyMapStatisticsExitLogger();
- ~PropertyMapStatisticsExitLogger();
+struct PropertyTableStatisticsExitLogger {
+ PropertyTableStatisticsExitLogger();
+ ~PropertyTableStatisticsExitLogger();
};
-DEFINE_GLOBAL_FOR_LOGGING(PropertyMapStatisticsExitLogger, logger, );
+DEFINE_GLOBAL_FOR_LOGGING(PropertyTableStatisticsExitLogger, logger, { });
-PropertyMapStatisticsExitLogger::PropertyMapStatisticsExitLogger()
+PropertyTableStatisticsExitLogger::PropertyTableStatisticsExitLogger()
{
- propertyMapHashTableStats = adoptPtr(new PropertyMapHashTableStats()).leakPtr();
+ propertyTableStats = adoptPtr(new PropertyTableStats()).leakPtr();
}
-PropertyMapStatisticsExitLogger::~PropertyMapStatisticsExitLogger()
+PropertyTableStatisticsExitLogger::~PropertyTableStatisticsExitLogger()
{
- unsigned finds = propertyMapHashTableStats->numFinds;
- unsigned collisions = propertyMapHashTableStats->numCollisions;
+ unsigned finds = propertyTableStats->numFinds;
+ unsigned collisions = propertyTableStats->numCollisions;
dataLogF("\nJSC::PropertyMap statistics for process %d\n\n", getCurrentProcessID());
dataLogF("%d finds\n", finds);
dataLogF("%d collisions (%.1f%%)\n", collisions, 100.0 * collisions / finds);
- dataLogF("%d lookups\n", propertyMapHashTableStats->numLookups.load());
- dataLogF("%d lookup probings\n", propertyMapHashTableStats->numLookupProbing.load());
- dataLogF("%d adds\n", propertyMapHashTableStats->numAdds.load());
- dataLogF("%d removes\n", propertyMapHashTableStats->numRemoves.load());
- dataLogF("%d rehashes\n", propertyMapHashTableStats->numRehashes.load());
- dataLogF("%d reinserts\n", propertyMapHashTableStats->numReinserts.load());
+ dataLogF("%d lookups\n", propertyTableStats->numLookups.load());
+ dataLogF("%d lookup probings\n", propertyTableStats->numLookupProbing.load());
+ dataLogF("%d adds\n", propertyTableStats->numAdds.load());
+ dataLogF("%d removes\n", propertyTableStats->numRemoves.load());
+ dataLogF("%d rehashes\n", propertyTableStats->numRehashes.load());
+ dataLogF("%d reinserts\n", propertyTableStats->numReinserts.load());
}
#endif
Modified: trunk/Source/_javascript_Core/runtime/StructureInlines.h (286033 => 286034)
--- trunk/Source/_javascript_Core/runtime/StructureInlines.h 2021-11-18 23:09:07 UTC (rev 286033)
+++ trunk/Source/_javascript_Core/runtime/StructureInlines.h 2021-11-18 23:19:03 UTC (rev 286034)
@@ -29,7 +29,7 @@
#include "JSArrayBufferView.h"
#include "JSCJSValueInlines.h"
#include "JSGlobalObject.h"
-#include "PropertyMapHashTable.h"
+#include "PropertyTable.h"
#include "Structure.h"
#include "StructureChain.h"
#include "StructureRareDataInlines.h"
Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (286033 => 286034)
--- trunk/Source/_javascript_Core/runtime/VM.cpp 2021-11-18 23:09:07 UTC (rev 286033)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp 2021-11-18 23:19:03 UTC (rev 286034)
@@ -149,7 +149,7 @@
#include "ProfilerDatabase.h"
#include "ProgramCodeBlock.h"
#include "ProgramExecutable.h"
-#include "PropertyMapHashTable.h"
+#include "PropertyTable.h"
#include "ProxyRevoke.h"
#include "RandomizingFuzzerAgent.h"
#include "RegExpCache.h"