Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (262599 => 262600)
--- trunk/Source/_javascript_Core/ChangeLog 2020-06-05 05:52:22 UTC (rev 262599)
+++ trunk/Source/_javascript_Core/ChangeLog 2020-06-05 05:58:55 UTC (rev 262600)
@@ -1,3 +1,27 @@
+2020-06-04 Yusuke Suzuki <ysuz...@apple.com>
+
+ [JSC] Report extra memory allocation from PropertyTable
+ https://bugs.webkit.org/show_bug.cgi?id=212793
+
+ Reviewed by Saam Barati.
+
+ This patch adds extra memory reporting from PropertyTable to make GC
+ responsive to the increase of memory in PropertyTable.
+
+ * runtime/PropertyMapHashTable.h:
+ (JSC::PropertyTable::add):
+ (JSC::PropertyTable::remove):
+ (JSC::PropertyTable::rehash):
+ (JSC::PropertyTable::dataSize):
+ * runtime/PropertyTable.cpp:
+ (JSC::PropertyTable::finishCreation):
+ (JSC::PropertyTable::visitChildren):
+ * runtime/Structure.cpp:
+ (JSC::Structure::materializePropertyTable):
+ * runtime/StructureInlines.h:
+ (JSC::Structure::add):
+ (JSC::Structure::remove):
+
2020-06-04 Commit Queue <commit-qu...@webkit.org>
Unreviewed, reverting r262583.
Modified: trunk/Source/_javascript_Core/runtime/PropertyMapHashTable.h (262599 => 262600)
--- trunk/Source/_javascript_Core/runtime/PropertyMapHashTable.h 2020-06-05 05:52:22 UTC (rev 262599)
+++ trunk/Source/_javascript_Core/runtime/PropertyMapHashTable.h 2020-06-05 05:58:55 UTC (rev 262600)
@@ -133,6 +133,7 @@
static constexpr bool needsDestruction = true;
static void destroy(JSCell*);
+ static void visitChildren(JSCell*, SlotVisitor&);
DECLARE_EXPORT_INFO;
@@ -169,10 +170,10 @@
find_iterator find(const KeyType&);
ValueType* get(const KeyType&);
// Add a value to the table
- std::pair<find_iterator, bool> WARN_UNUSED_RETURN add(const ValueType& entry);
+ std::pair<find_iterator, bool> WARN_UNUSED_RETURN add(VM&, const ValueType& entry);
// Remove a value from the table.
- void remove(const find_iterator& iter);
- void remove(const KeyType& key);
+ void remove(VM&, const find_iterator& iter);
+ void remove(VM&, const KeyType& key);
// Returns the number of values in the hashtable.
unsigned size() const;
@@ -211,11 +212,14 @@
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(unsigned newCapacity);
+ void rehash(VM&, unsigned newCapacity);
// The capacity of the table of values is half of the size of the index.
unsigned tableCapacity() const;
@@ -348,7 +352,7 @@
}
}
-inline std::pair<PropertyTable::find_iterator, bool> WARN_UNUSED_RETURN PropertyTable::add(const ValueType& entry)
+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));
@@ -366,7 +370,7 @@
// ensure capacity is available.
if (!canInsert()) {
- rehash(m_keyCount + 1);
+ rehash(vm, m_keyCount + 1);
iter = find(entry.key);
ASSERT(!iter.first);
}
@@ -382,7 +386,7 @@
return std::make_pair(iter, true);
}
-inline void PropertyTable::remove(const find_iterator& iter)
+inline void PropertyTable::remove(VM& vm, const find_iterator& iter)
{
// Removing a key that doesn't exist does nothing!
if (!iter.first)
@@ -403,12 +407,12 @@
++m_deletedCount;
if (m_deletedCount * 4 >= m_indexSize)
- rehash(m_keyCount);
+ rehash(vm, m_keyCount);
}
-inline void PropertyTable::remove(const KeyType& key)
+inline void PropertyTable::remove(VM& vm, const KeyType& key)
{
- remove(find(key));
+ remove(vm, find(key));
}
// returns the number of values in the hashtable.
@@ -500,12 +504,13 @@
++m_keyCount;
}
-inline void PropertyTable::rehash(unsigned newCapacity)
+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();
@@ -523,6 +528,9 @@
}
PropertyTableMalloc::free(oldEntryIndices);
+
+ if (oldDataSize < dataSize())
+ vm.heap.reportExtraMemoryAllocated(dataSize() - oldDataSize);
}
inline unsigned PropertyTable::tableCapacity() const { return m_indexSize >> 1; }
@@ -558,7 +566,9 @@
inline size_t PropertyTable::dataSize()
{
// The size in bytes of data needed for by the table.
- return m_indexSize * sizeof(unsigned) + ((tableCapacity()) + 1) * sizeof(ValueType);
+ // 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)
Modified: trunk/Source/_javascript_Core/runtime/PropertyTable.cpp (262599 => 262600)
--- trunk/Source/_javascript_Core/runtime/PropertyTable.cpp 2020-06-05 05:52:22 UTC (rev 262599)
+++ trunk/Source/_javascript_Core/runtime/PropertyTable.cpp 2020-06-05 05:58:55 UTC (rev 262600)
@@ -112,6 +112,20 @@
m_deletedOffsets = makeUnique<Vector<PropertyOffset>>(*otherDeletedOffsets);
}
+void PropertyTable::finishCreation(VM& vm)
+{
+ Base::finishCreation(vm);
+ vm.heap.reportExtraMemoryAllocated(dataSize());
+}
+
+void PropertyTable::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+ auto* thisObject = jsCast<PropertyTable*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ Base::visitChildren(cell, visitor);
+ visitor.reportExtraMemoryVisited(thisObject->dataSize());
+}
+
void PropertyTable::destroy(JSCell* cell)
{
static_cast<PropertyTable*>(cell)->PropertyTable::~PropertyTable();
Modified: trunk/Source/_javascript_Core/runtime/Structure.cpp (262599 => 262600)
--- trunk/Source/_javascript_Core/runtime/Structure.cpp 2020-06-05 05:52:22 UTC (rev 262599)
+++ trunk/Source/_javascript_Core/runtime/Structure.cpp 2020-06-05 05:58:55 UTC (rev 262600)
@@ -377,7 +377,7 @@
if (structure->isPropertyDeletionTransition()) {
auto item = table->find(structure->m_transitionPropertyName.get());
ASSERT(item.first);
- table->remove(item);
+ table->remove(vm, item);
table->addDeletedOffset(structure->transitionOffset());
continue;
}
@@ -384,7 +384,7 @@
PropertyMapEntry entry(structure->m_transitionPropertyName.get(), structure->transitionOffset(), structure->transitionPropertyAttributes());
auto nextOffset = table->nextOffset(structure->inlineCapacity());
ASSERT_UNUSED(nextOffset, nextOffset == structure->transitionOffset());
- auto result = table->add(entry);
+ auto result = table->add(vm, entry);
ASSERT_UNUSED(result, result.second);
ASSERT_UNUSED(result, result.first.first->offset == nextOffset);
}
Modified: trunk/Source/_javascript_Core/runtime/StructureInlines.h (262599 => 262600)
--- trunk/Source/_javascript_Core/runtime/StructureInlines.h 2020-06-05 05:52:22 UTC (rev 262599)
+++ trunk/Source/_javascript_Core/runtime/StructureInlines.h 2020-06-05 05:58:55 UTC (rev 262600)
@@ -465,7 +465,7 @@
m_propertyHash = m_propertyHash ^ rep->existingSymbolAwareHash();
m_seenProperties.add(bitwise_cast<uintptr_t>(rep));
- auto result = table->add(PropertyMapEntry(rep, newOffset, attributes));
+ auto result = table->add(vm, PropertyMapEntry(rep, newOffset, attributes));
ASSERT_UNUSED(result, result.second);
ASSERT_UNUSED(result, result.first.first->offset == newOffset);
auto newMaxOffset = std::max(newOffset, maxOffset());
@@ -507,7 +507,7 @@
PropertyOffset offset = position.first->offset;
- table->remove(position);
+ table->remove(vm, position);
table->addDeletedOffset(offset);
PropertyOffset newMaxOffset = maxOffset();