Title: [253931] trunk/Source/_javascript_Core
Revision
253931
Author
[email protected]
Date
2019-12-28 20:47:44 -0800 (Sat, 28 Dec 2019)

Log Message

[JSC] StructureChain should hold vector of StructureID
https://bugs.webkit.org/show_bug.cgi?id=205592

Reviewed by Mark Lam.

StructureChain should keep vector of StructureID instead of Structure* to minimize the size of vector.

* llint/LowLevelInterpreter64.asm:
* runtime/JSPropertyNameEnumerator.h:
(JSC::propertyNameEnumerator):
* runtime/ProxyObject.h:
* runtime/Structure.cpp:
(JSC::Structure::canCachePropertyNameEnumerator const):
* runtime/Structure.h:
* runtime/StructureChain.cpp:
(JSC::StructureChain::StructureChain):
(JSC::StructureChain::create):
(JSC::StructureChain::finishCreation):
(JSC::StructureChain::visitChildren):
* runtime/StructureChain.h:
* runtime/StructureInlines.h:
(JSC::Structure::isValid const):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (253930 => 253931)


--- trunk/Source/_javascript_Core/ChangeLog	2019-12-29 03:39:27 UTC (rev 253930)
+++ trunk/Source/_javascript_Core/ChangeLog	2019-12-29 04:47:44 UTC (rev 253931)
@@ -1,3 +1,28 @@
+2019-12-28  Yusuke Suzuki  <[email protected]>
+
+        [JSC] StructureChain should hold vector of StructureID
+        https://bugs.webkit.org/show_bug.cgi?id=205592
+
+        Reviewed by Mark Lam.
+
+        StructureChain should keep vector of StructureID instead of Structure* to minimize the size of vector.
+
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/JSPropertyNameEnumerator.h:
+        (JSC::propertyNameEnumerator):
+        * runtime/ProxyObject.h:
+        * runtime/Structure.cpp:
+        (JSC::Structure::canCachePropertyNameEnumerator const):
+        * runtime/Structure.h:
+        * runtime/StructureChain.cpp:
+        (JSC::StructureChain::StructureChain):
+        (JSC::StructureChain::create):
+        (JSC::StructureChain::finishCreation):
+        (JSC::StructureChain::visitChildren):
+        * runtime/StructureChain.h:
+        * runtime/StructureInlines.h:
+        (JSC::Structure::isValid const):
+
 2019-12-25  Yusuke Suzuki  <[email protected]>
 
         [JSC] Compact Bytecodes more by emitting 1-byte Opcode

Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm (253930 => 253931)


--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm	2019-12-29 03:39:27 UTC (rev 253930)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm	2019-12-29 04:47:44 UTC (rev 253931)
@@ -1448,11 +1448,20 @@
     loadp OpPutById::Metadata::m_structureChain[t5], t3
     btpz t3, .opPutByIdTransitionDirect
 
-    structureIDToStructureWithScratch(t2, t1, t3)
+    loadp CodeBlock[cfr], t1
+    loadp CodeBlock::m_vm[t1], t1
+    loadp VM::heap + Heap::m_structureIDTable + StructureIDTable::m_table[t1], t1
 
-    # reload the StructureChain since we used t3 as a scratch above
-    loadp OpPutById::Metadata::m_structureChain[t5], t3
+    macro structureIDToStructureWithScratchAndTable(structureIDThenStructure, table, scratch)
+        move structureIDThenStructure, scratch
+        rshifti NumberOfStructureIDEntropyBits, scratch
+        loadp [table, scratch, PtrSize], scratch
+        lshiftp StructureEntropyBitsShift, structureIDThenStructure
+        xorp scratch, structureIDThenStructure
+    end
 
+    structureIDToStructureWithScratchAndTable(t2, t1, t0)
+
     loadp StructureChain::m_vector[t3], t3
     assert(macro (ok) btpnz t3, ok end)
 
@@ -1459,20 +1468,19 @@
     loadq Structure::m_prototype[t2], t2
     bqeq t2, ValueNull, .opPutByIdTransitionChainDone
 .opPutByIdTransitionChainLoop:
-    # At this point, t2 contains a prototye, and [t3] contains the Structure* that we want that
-    # prototype to have. We don't want to have to load the Structure* for t2. Instead, we load
-    # the Structure* from [t3], and then we compare its id to the id in the header of t2.
-    loadp [t3], t1
     loadi JSCell::m_structureID[t2], t2
-    # Now, t1 has the Structure* and t2 has the StructureID that we want that Structure* to have.
-    bineq t2, Structure::m_blob + StructureIDBlob::u.fields.structureID[t1], .opPutByIdSlow
-    addp PtrSize, t3
-    loadq Structure::m_prototype[t1], t2
+    bineq t2, [t3], .opPutByIdSlow
+    addp 4, t3
+    structureIDToStructureWithScratchAndTable(t2, t1, t0)
+    loadq Structure::m_prototype[t2], t2
     bqneq t2, ValueNull, .opPutByIdTransitionChainLoop
 
 .opPutByIdTransitionChainDone:
     # Reload the new structure, since we clobbered it above.
     loadi OpPutById::Metadata::m_newStructureID[t5], t1
+    # Reload base into t0
+    get(m_base, t3)
+    loadConstantOrVariable(size, t3, t0)
 
 .opPutByIdTransitionDirect:
     storei t1, JSCell::m_structureID[t0]

Modified: trunk/Source/_javascript_Core/runtime/JSPropertyNameEnumerator.h (253930 => 253931)


--- trunk/Source/_javascript_Core/runtime/JSPropertyNameEnumerator.h	2019-12-29 03:39:27 UTC (rev 253930)
+++ trunk/Source/_javascript_Core/runtime/JSPropertyNameEnumerator.h	2019-12-29 04:47:44 UTC (rev 253931)
@@ -142,7 +142,7 @@
     enumerator = JSPropertyNameEnumerator::create(vm, structureAfterGettingPropertyNames, indexedLength, numberStructureProperties, WTFMove(propertyNames));
     if (!indexedLength && successfullyNormalizedChain && structureAfterGettingPropertyNames == structure) {
         enumerator->setCachedPrototypeChain(vm, structure->prototypeChain(globalObject, base));
-        if (structure->canCachePropertyNameEnumerator())
+        if (structure->canCachePropertyNameEnumerator(vm))
             structure->setCachedPropertyNameEnumerator(vm, enumerator);
     }
     return enumerator;

Modified: trunk/Source/_javascript_Core/runtime/ProxyObject.h (253930 => 253931)


--- trunk/Source/_javascript_Core/runtime/ProxyObject.h	2019-12-29 03:39:27 UTC (rev 253930)
+++ trunk/Source/_javascript_Core/runtime/ProxyObject.h	2019-12-29 04:47:44 UTC (rev 253931)
@@ -59,7 +59,7 @@
         Structure* result = Structure::create(vm, globalObject, prototype, TypeInfo(ProxyObjectType, flags), info(), NonArray | MayHaveIndexedAccessors);
         result->setIsQuickPropertyAccessAllowedForEnumeration(false);
         RELEASE_ASSERT(!result->canAccessPropertiesQuicklyForEnumeration());
-        RELEASE_ASSERT(!result->canCachePropertyNameEnumerator());
+        RELEASE_ASSERT(!result->canCachePropertyNameEnumerator(vm));
         return result;
     }
 

Modified: trunk/Source/_javascript_Core/runtime/Structure.cpp (253930 => 253931)


--- trunk/Source/_javascript_Core/runtime/Structure.cpp	2019-12-29 03:39:27 UTC (rev 253930)
+++ trunk/Source/_javascript_Core/runtime/Structure.cpp	2019-12-29 04:47:44 UTC (rev 253931)
@@ -1207,7 +1207,7 @@
     return rareData()->cachedPropertyNameEnumerator();
 }
 
-bool Structure::canCachePropertyNameEnumerator() const
+bool Structure::canCachePropertyNameEnumerator(VM& vm) const
 {
     if (!this->canCacheOwnKeys())
         return false;
@@ -1214,13 +1214,15 @@
 
     StructureChain* structureChain = m_cachedPrototypeChain.get();
     ASSERT(structureChain);
-    WriteBarrier<Structure>* structure = structureChain->head();
+    StructureID* currentStructureID = structureChain->head();
     while (true) {
-        if (!structure->get())
+        StructureID structureID = *currentStructureID;
+        if (!structureID)
             return true;
-        if (!structure->get()->canCacheOwnKeys())
+        Structure* structure = vm.getStructure(structureID);
+        if (!structure->canCacheOwnKeys())
             return false;
-        structure++;
+        currentStructureID++;
     }
 
     ASSERT_NOT_REACHED();

Modified: trunk/Source/_javascript_Core/runtime/Structure.h (253930 => 253931)


--- trunk/Source/_javascript_Core/runtime/Structure.h	2019-12-29 03:39:27 UTC (rev 253930)
+++ trunk/Source/_javascript_Core/runtime/Structure.h	2019-12-29 04:47:44 UTC (rev 253931)
@@ -476,7 +476,7 @@
 
     void setCachedPropertyNameEnumerator(VM&, JSPropertyNameEnumerator*);
     JSPropertyNameEnumerator* cachedPropertyNameEnumerator() const;
-    bool canCachePropertyNameEnumerator() const;
+    bool canCachePropertyNameEnumerator(VM&) const;
     bool canAccessPropertiesQuicklyForEnumeration() const;
 
     void setCachedOwnKeys(VM&, JSImmutableButterfly*);

Modified: trunk/Source/_javascript_Core/runtime/StructureChain.cpp (253930 => 253931)


--- trunk/Source/_javascript_Core/runtime/StructureChain.cpp	2019-12-29 03:39:27 UTC (rev 253930)
+++ trunk/Source/_javascript_Core/runtime/StructureChain.cpp	2019-12-29 04:47:44 UTC (rev 253931)
@@ -34,7 +34,7 @@
     
 const ClassInfo StructureChain::s_info = { "StructureChain", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(StructureChain) };
 
-StructureChain::StructureChain(VM& vm, Structure* structure, WriteBarrier<Structure>* vector)
+StructureChain::StructureChain(VM& vm, Structure* structure, StructureID* vector)
     : Base(vm, structure)
     , m_vector(vm, this, vector)
 {
@@ -49,9 +49,9 @@
     for (JSObject* current = head; current; current = current->structure(vm)->storedPrototypeObject(current))
         ++size;
     ++size; // Sentinel nullptr.
-    WriteBarrier<Structure>* vector = static_cast<WriteBarrier<Structure>*>(vm.jsValueGigacageAuxiliarySpace.allocateNonVirtual(vm, (Checked<size_t>(size) * sizeof(WriteBarrier<Structure>)).unsafeGet(), nullptr, AllocationFailureMode::Assert));
-    for (size_t i = 0; i < size; ++i)
-        vector[i].clear();
+    size_t bytes = (Checked<size_t>(size) * sizeof(StructureID)).unsafeGet();
+    StructureID* vector = static_cast<StructureID*>(vm.jsValueGigacageAuxiliarySpace.allocateNonVirtual(vm, bytes, nullptr, AllocationFailureMode::Assert));
+    memset(vector, 0, bytes);
     StructureChain* chain = new (NotNull, allocateCell<StructureChain>(vm.heap)) StructureChain(vm, vm.structureChainStructure.get(), vector);
     chain->finishCreation(vm, head);
     return chain;
@@ -61,8 +61,11 @@
 {
     Base::finishCreation(vm);
     size_t i = 0;
-    for (JSObject* current = head; current; current = current->structure(vm)->storedPrototypeObject(current))
-        m_vector.get()[i++].set(vm, this, current->structure(vm));
+    for (JSObject* current = head; current; current = current->structure(vm)->storedPrototypeObject(current)) {
+        Structure* structure = current->structure(vm);
+        m_vector.get()[i++] = structure->id();
+        vm.heap.writeBarrier(this);
+    }
 }
 
 void StructureChain::visitChildren(JSCell* cell, SlotVisitor& visitor)
@@ -71,8 +74,12 @@
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
     Base::visitChildren(thisObject, visitor);
     visitor.markAuxiliary(thisObject->m_vector.get());
-    for (auto* current = thisObject->m_vector.get(); *current; ++current)
-        visitor.append(*current);
+    VM& vm = visitor.vm();
+    for (auto* current = thisObject->m_vector.get(); *current; ++current) {
+        StructureID structureID = *current;
+        Structure* structure = vm.getStructure(structureID);
+        visitor.appendUnbarriered(structure);
+    }
 }
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/StructureChain.h (253930 => 253931)


--- trunk/Source/_javascript_Core/runtime/StructureChain.h	2019-12-29 03:39:27 UTC (rev 253930)
+++ trunk/Source/_javascript_Core/runtime/StructureChain.h	2019-12-29 04:47:44 UTC (rev 253931)
@@ -50,7 +50,7 @@
     }
 
     static StructureChain* create(VM&, JSObject*);
-    WriteBarrier<Structure>* head() { return m_vector.get(); }
+    StructureID* head() { return m_vector.get(); }
     static void visitChildren(JSCell*, SlotVisitor&);
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
@@ -65,8 +65,8 @@
 
     void finishCreation(VM&, JSObject* head);
 
-    StructureChain(VM&, Structure*, WriteBarrier<Structure>*);
-    AuxiliaryBarrier<WriteBarrier<Structure>*> m_vector;
+    StructureChain(VM&, Structure*, StructureID*);
+    AuxiliaryBarrier<StructureID*> m_vector;
 };
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/StructureInlines.h (253930 => 253931)


--- trunk/Source/_javascript_Core/runtime/StructureInlines.h	2019-12-29 03:39:27 UTC (rev 253930)
+++ trunk/Source/_javascript_Core/runtime/StructureInlines.h	2019-12-29 04:47:44 UTC (rev 253931)
@@ -313,9 +313,9 @@
 
     VM& vm = globalObject->vm();
     JSValue prototype = prototypeForLookup(globalObject, base);
-    WriteBarrier<Structure>* cachedStructure = cachedPrototypeChain->head();
+    StructureID* cachedStructure = cachedPrototypeChain->head();
     while (*cachedStructure && !prototype.isNull()) {
-        if (asObject(prototype)->structure(vm) != cachedStructure->get())
+        if (asObject(prototype)->structureID() != *cachedStructure)
             return false;
         ++cachedStructure;
         prototype = asObject(prototype)->getPrototypeDirect(vm);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to