[JSC] Optimize padding of InferredTypeTable by using cellLock
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 8 Jul 2018 16:41:14 +0000 (16:41 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 8 Jul 2018 16:41:14 +0000 (16:41 +0000)
https://bugs.webkit.org/show_bug.cgi?id=187447

Reviewed by Mark Lam.

Use cellLock() in InferredTypeTable to guard changes of internal structures.
This is the same usage to SparseArrayValueMap. By using cellLock(), we can
reduce the size of InferredTypeTable from 40 to 32.

* runtime/InferredTypeTable.cpp:
(JSC::InferredTypeTable::visitChildren):
(JSC::InferredTypeTable::get):
(JSC::InferredTypeTable::willStoreValue):
(JSC::InferredTypeTable::makeTop):
* runtime/InferredTypeTable.h:
Using enum class and using. And remove `isEmpty()` since it is not used.

* runtime/Structure.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@233627 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/InferredTypeTable.cpp
Source/JavaScriptCore/runtime/InferredTypeTable.h
Source/JavaScriptCore/runtime/Structure.h

index d105f19..6543774 100644 (file)
@@ -1,3 +1,24 @@
+2018-07-08  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [JSC] Optimize padding of InferredTypeTable by using cellLock
+        https://bugs.webkit.org/show_bug.cgi?id=187447
+
+        Reviewed by Mark Lam.
+
+        Use cellLock() in InferredTypeTable to guard changes of internal structures.
+        This is the same usage to SparseArrayValueMap. By using cellLock(), we can
+        reduce the size of InferredTypeTable from 40 to 32.
+
+        * runtime/InferredTypeTable.cpp:
+        (JSC::InferredTypeTable::visitChildren):
+        (JSC::InferredTypeTable::get):
+        (JSC::InferredTypeTable::willStoreValue):
+        (JSC::InferredTypeTable::makeTop):
+        * runtime/InferredTypeTable.h:
+        Using enum class and using. And remove `isEmpty()` since it is not used.
+
+        * runtime/Structure.h:
+
 2018-07-07  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         [JSC] Optimize layout of SourceProvider to reduce padding
index 47a42e8..eefa5d6 100644 (file)
@@ -55,7 +55,7 @@ void InferredTypeTable::visitChildren(JSCell* cell, SlotVisitor& visitor)
     InferredTypeTable* inferredTypeTable = jsCast<InferredTypeTable*>(cell);
     Base::visitChildren(cell, visitor);
 
-    ConcurrentJSLocker locker(inferredTypeTable->m_lock);
+    auto locker = holdLock(inferredTypeTable->cellLock());
     
     for (auto& entry : inferredTypeTable->m_table) {
         auto entryValue = entry.value;
@@ -69,7 +69,7 @@ void InferredTypeTable::visitChildren(JSCell* cell, SlotVisitor& visitor)
     }
 }
 
-InferredType* InferredTypeTable::get(const ConcurrentJSLocker&, UniquedStringImpl* uid)
+InferredType* InferredTypeTable::get(const AbstractLocker&, UniquedStringImpl* uid)
 {
     auto iter = m_table.find(uid);
     if (iter == m_table.end())
@@ -90,7 +90,7 @@ InferredType* InferredTypeTable::get(const ConcurrentJSLocker&, UniquedStringImp
 
 InferredType* InferredTypeTable::get(UniquedStringImpl* uid)
 {
-    ConcurrentJSLocker locker(m_lock);
+    auto locker = holdLock(cellLock());
     return get(locker, uid);
 }
 
@@ -104,7 +104,7 @@ bool InferredTypeTable::willStoreValue(
 {
     // The algorithm here relies on the fact that only one thread modifies the hash map.
     
-    if (age == OldProperty) {
+    if (age == StoredPropertyAge::OldProperty) {
         TableType::iterator iter = m_table.find(propertyName.uid());
         if (iter == m_table.end())
             return false; // Absence on replace => top.
@@ -122,7 +122,7 @@ bool InferredTypeTable::willStoreValue(
 
     TableType::AddResult result;
     {
-        ConcurrentJSLocker locker(m_lock);
+        auto locker = holdLock(cellLock());
         result = m_table.add(propertyName.uid(), WriteBarrier<InferredType>());
     }
     InferredType* entryValue = result.iterator->value.get();
@@ -145,7 +145,7 @@ bool InferredTypeTable::willStoreValue(
 void InferredTypeTable::makeTop(VM& vm, PropertyName propertyName, StoredPropertyAge age)
 {
     // The algorithm here relies on the fact that only one thread modifies the hash map.
-    if (age == OldProperty) {
+    if (age == StoredPropertyAge::OldProperty) {
         TableType::iterator iter = m_table.find(propertyName.uid());
         if (iter == m_table.end())
             return; // Absence on replace => top.
@@ -162,7 +162,7 @@ void InferredTypeTable::makeTop(VM& vm, PropertyName propertyName, StoredPropert
 
     TableType::AddResult result;
     {
-        ConcurrentJSLocker locker(m_lock);
+        auto locker = holdLock(cellLock());
         result = m_table.add(propertyName.uid(), WriteBarrier<InferredType>());
     }
     if (!result.iterator->value)
index e529eb4..be9ecff 100644 (file)
@@ -55,20 +55,13 @@ public:
 
     DECLARE_INFO;
 
-    ConcurrentJSLock& lock() { return m_lock; }
-
-    bool isEmpty() const { return m_table.isEmpty(); }
-
     // Get the current inferred type. Returns nullptr for both Top and Bottom. Null means Bottom if the
     // owning Structure doesn't know about the property.
-    InferredType* get(const ConcurrentJSLocker&, UniquedStringImpl*);
+    InferredType* get(const AbstractLocker&, UniquedStringImpl*);
     InferredType* get(UniquedStringImpl*);
     InferredType* get(PropertyName);
 
-    enum StoredPropertyAge {
-        NewProperty,
-        OldProperty
-    };
+    enum class StoredPropertyAge { NewProperty, OldProperty };
     
     // Returns true if the InferredType for this property is still relevant after the store. It's not
     // relevant if it's Top. Note that this table will internally prune Top entries.
@@ -97,13 +90,9 @@ private:
     // that's bad. We avoid such confusion by ensuring that a transition always adds an entry. Hence,
     // absence-means-bottom only comes into play for properties added before the InferredTypeTable was
     // created.
-    typedef HashMap<RefPtr<UniquedStringImpl>, WriteBarrier<InferredType>, IdentifierRepHash> TableType;
-    
-    TableType m_table;
+    using TableType = HashMap<RefPtr<UniquedStringImpl>, WriteBarrier<InferredType>, IdentifierRepHash>;
 
-    // We only grab this lock when we're doing modifications on the main thread, or reads on the compiler
-    // thread. The compiler thread is not allowed to do modifications.
-    ConcurrentJSLock m_lock;
+    TableType m_table;
 };
 
 } // namespace JSC
index a8bd4bb..c73b5e3 100644 (file)
@@ -617,7 +617,7 @@ public:
     {
         if (hasBeenDictionary() || (!shouldOptimize && !m_inferredTypeTable) || !VM::canUseJIT())
             return;
-        willStoreValueSlow(vm, propertyName, value, shouldOptimize, InferredTypeTable::NewProperty);
+        willStoreValueSlow(vm, propertyName, value, shouldOptimize, InferredTypeTable::StoredPropertyAge::NewProperty);
     }
 
     // Call this when we know that this is a new property for the object, but not new for the
@@ -628,7 +628,7 @@ public:
     {
         if (hasBeenDictionary() || !m_inferredTypeTable || !VM::canUseJIT())
             return;
-        willStoreValueSlow(vm, propertyName, value, shouldOptimize, InferredTypeTable::NewProperty);
+        willStoreValueSlow(vm, propertyName, value, shouldOptimize, InferredTypeTable::StoredPropertyAge::NewProperty);
     }
 
     // Call this when we know that the inferred type table exists and has an entry for this property.
@@ -637,7 +637,7 @@ public:
     {
         if (hasBeenDictionary() || !VM::canUseJIT())
             return;
-        willStoreValueSlow(vm, propertyName, value, shouldOptimize, InferredTypeTable::OldProperty);
+        willStoreValueSlow(vm, propertyName, value, shouldOptimize, InferredTypeTable::StoredPropertyAge::OldProperty);
     }
 
     Ref<StructureShape> toStructureShape(JSValue, bool& sawPolyProtoStructure);