Title: [256988] branches/safari-609.1.20.0-branch/Source/_javascript_Core

Diff

Modified: branches/safari-609.1.20.0-branch/Source/_javascript_Core/ChangeLog (256987 => 256988)


--- branches/safari-609.1.20.0-branch/Source/_javascript_Core/ChangeLog	2020-02-19 23:45:29 UTC (rev 256987)
+++ branches/safari-609.1.20.0-branch/Source/_javascript_Core/ChangeLog	2020-02-19 23:54:34 UTC (rev 256988)
@@ -1,3 +1,33 @@
+2020-02-19  Alan Coon  <alanc...@apple.com>
+
+        Apply patch. rdar://problem/59478911
+
+    2020-02-19  Yusuke Suzuki  <ysuz...@apple.com>
+
+            [JSC] Compact StructureTransitionTable
+            https://bugs.webkit.org/show_bug.cgi?id=207616
+
+            Reviewed by Mark Lam.
+
+            Some of StructureTransitionTable are shown as very large HashMap and we can compact it by encoding key.
+            We leverage 48bit pointers and 8byte alignment of UniquedStringImpl* to encode other parameters into it.
+
+            * runtime/Structure.cpp:
+            (JSC::StructureTransitionTable::contains const):
+            (JSC::StructureTransitionTable::get const):
+            (JSC::StructureTransitionTable::add):
+            * runtime/Structure.h:
+            * runtime/StructureTransitionTable.h:
+            (JSC::StructureTransitionTable::Hash::Key::Key):
+            (JSC::StructureTransitionTable::Hash::Key::isHashTableDeletedValue const):
+            (JSC::StructureTransitionTable::Hash::Key::impl const):
+            (JSC::StructureTransitionTable::Hash::Key::isAddition const):
+            (JSC::StructureTransitionTable::Hash::Key::attributes const):
+            (JSC::StructureTransitionTable::Hash::Key::operator==):
+            (JSC::StructureTransitionTable::Hash::Key::operator!=):
+            (JSC::StructureTransitionTable::Hash::hash):
+            (JSC::StructureTransitionTable::Hash::equal):
+
 2020-02-19  Russell Epstein  <repst...@apple.com>
 
         Cherry-pick r256898. rdar://problem/59551695

Modified: branches/safari-609.1.20.0-branch/Source/_javascript_Core/runtime/Structure.cpp (256987 => 256988)


--- branches/safari-609.1.20.0-branch/Source/_javascript_Core/runtime/Structure.cpp	2020-02-19 23:45:29 UTC (rev 256987)
+++ branches/safari-609.1.20.0-branch/Source/_javascript_Core/runtime/Structure.cpp	2020-02-19 23:54:34 UTC (rev 256988)
@@ -93,7 +93,7 @@
         Structure* transition = singleTransition();
         return transition && transition->m_nameInPrevious == rep && transition->attributesInPrevious() == attributes;
     }
-    return map()->get(std::make_pair(rep, attributes));
+    return map()->get(StructureTransitionTable::Hash::Key(rep, attributes, false));
 }
 
 inline Structure* StructureTransitionTable::get(UniquedStringImpl* rep, unsigned attributes) const
@@ -102,7 +102,7 @@
         Structure* transition = singleTransition();
         return (transition && transition->m_nameInPrevious == rep && transition->attributesInPrevious() == attributes) ? transition : 0;
     }
-    return map()->get(std::make_pair(rep, attributes));
+    return map()->get(StructureTransitionTable::Hash::Key(rep, attributes, false));
 }
 
 void StructureTransitionTable::add(VM& vm, Structure* structure)
@@ -123,11 +123,7 @@
     }
 
     // Add the structure to the map.
-
-    // Newer versions of the STL have an std::make_pair function that takes rvalue references.
-    // When either of the parameters are bitfields, the C++ compiler will try to bind them as lvalues, which is invalid. To work around this, use unary "+" to make the parameter an rvalue.
-    // See https://bugs.webkit.org/show_bug.cgi?id=59261 for more details
-    map()->set(std::make_pair(structure->m_nameInPrevious.get(), +structure->attributesInPrevious()), structure);
+    map()->set(StructureTransitionTable::Hash::Key(structure->m_nameInPrevious.get(), +structure->attributesInPrevious(), false), structure);
 }
 
 void Structure::dumpStatistics()

Modified: branches/safari-609.1.20.0-branch/Source/_javascript_Core/runtime/Structure.h (256987 => 256988)


--- branches/safari-609.1.20.0-branch/Source/_javascript_Core/runtime/Structure.h	2020-02-19 23:45:29 UTC (rev 256987)
+++ branches/safari-609.1.20.0-branch/Source/_javascript_Core/runtime/Structure.h	2020-02-19 23:54:34 UTC (rev 256988)
@@ -638,6 +638,7 @@
 #define DEFINE_BITFIELD(type, lowerName, upperName, width, offset) \
     static constexpr uint32_t s_##lowerName##Shift = offset;\
     static constexpr uint32_t s_##lowerName##Mask = ((1 << (width - 1)) | ((1 << (width - 1)) - 1));\
+    static constexpr uint32_t s_bitWidthOf##upperName = width;\
     type lowerName() const { return static_cast<type>((m_bitField >> offset) & s_##lowerName##Mask); }\
     void set##upperName(type newValue) \
     {\
@@ -662,6 +663,8 @@
     DEFINE_BITFIELD(bool, isAddingPropertyForTransition, IsAddingPropertyForTransition, 1, 28);
     DEFINE_BITFIELD(bool, hasUnderscoreProtoPropertyExcludingOriginalProto, HasUnderscoreProtoPropertyExcludingOriginalProto, 1, 29);
 
+    static_assert(s_bitWidthOfAttributesInPrevious <= sizeof(TransitionPropertyAttributes) * 8);
+
 private:
     friend class LLIntOffsetsExtractor;
 

Modified: branches/safari-609.1.20.0-branch/Source/_javascript_Core/runtime/StructureTransitionTable.h (256987 => 256988)


--- branches/safari-609.1.20.0-branch/Source/_javascript_Core/runtime/StructureTransitionTable.h	2020-02-19 23:45:29 UTC (rev 256987)
+++ branches/safari-609.1.20.0-branch/Source/_javascript_Core/runtime/StructureTransitionTable.h	2020-02-19 23:54:34 UTC (rev 256988)
@@ -52,6 +52,7 @@
     Seal,
     Freeze
 };
+using TransitionPropertyAttributes = uint16_t;
 
 inline unsigned toAttributes(NonPropertyTransition transition)
 {
@@ -143,8 +144,74 @@
     static constexpr intptr_t UsingSingleSlotFlag = 1;
 
     
+#if CPU(ADDRESS64)
     struct Hash {
-        typedef std::pair<UniquedStringImpl*, unsigned> Key;
+        // Logically, Key is a tuple of (1) UniquedStringImpl*, (2) unsigned attributes, and (3) bool isAddition.
+        // We encode (2) and (3) into (1)'s empty bits since a pointer is 48bit and lower 3 bits are usable because of alignment.
+        struct Key {
+            friend struct Hash;
+            static_assert(WTF_CPU_EFFECTIVE_ADDRESS_WIDTH <= 48);
+            static constexpr uintptr_t isAdditionMask = 1ULL;
+            static constexpr uintptr_t stringMask = ((1ULL << 48) - 1) & (~isAdditionMask);
+            static constexpr unsigned attributesShift = 48;
+            static constexpr uintptr_t hashTableDeletedValue = 0x2;
+            static_assert(sizeof(TransitionPropertyAttributes) * 8 <= 16);
+            static_assert(hashTableDeletedValue < alignof(UniquedStringImpl));
+
+            // Highest 16 bits are for TransitionPropertyAttributes.
+            // Lowest 1 bit is for isAddition flag.
+            // Remaining bits are for UniquedStringImpl*.
+            Key(UniquedStringImpl* impl, unsigned attributes, bool isAddition)
+                : m_encodedData(bitwise_cast<uintptr_t>(impl) | (static_cast<uintptr_t>(attributes) << attributesShift) | (static_cast<uintptr_t>(isAddition) & isAdditionMask))
+            {
+                ASSERT(impl == this->impl());
+                ASSERT(isAddition == this->isAddition());
+                ASSERT(attributes == this->attributes());
+            }
+
+            Key() = default;
+
+            Key(WTF::HashTableDeletedValueType)
+                : m_encodedData(hashTableDeletedValue)
+            { }
+
+            bool isHashTableDeletedValue() const { return m_encodedData == hashTableDeletedValue; }
+
+            UniquedStringImpl* impl() const { return bitwise_cast<UniquedStringImpl*>(m_encodedData & stringMask); }
+            bool isAddition() const { return m_encodedData & isAdditionMask; }
+            unsigned attributes() const { return m_encodedData >> attributesShift; }
+
+            friend bool operator==(const Key& a, const Key& b)
+            {
+                return a.m_encodedData == b.m_encodedData;
+            }
+
+            friend bool operator!=(const Key& a, const Key& b)
+            {
+                return a.m_encodedData != b.m_encodedData;
+            }
+
+        private:
+            uintptr_t m_encodedData { 0 };
+        };
+        using KeyTraits = SimpleClassHashTraits<Key>;
+
+        static unsigned hash(const Key& p)
+        {
+            return IntHash<uintptr_t>::hash(p.m_encodedData);
+        }
+
+        static bool equal(const Key& a, const Key& b)
+        {
+            return a == b;
+        }
+
+        static constexpr bool safeToCompareToEmptyOrDeleted = true;
+    };
+#else
+    struct Hash {
+        using Key = std::tuple<UniquedStringImpl*, unsigned, bool>;
+        using KeyTraits = HashTraits<Key>;
         
         static unsigned hash(const Key& p)
         {
@@ -158,8 +225,9 @@
 
         static constexpr bool safeToCompareToEmptyOrDeleted = true;
     };
+#endif
 
-    typedef WeakGCMap<Hash::Key, Structure, Hash> TransitionMap;
+    typedef WeakGCMap<Hash::Key, Structure, Hash, Hash::KeyTraits> TransitionMap;
 
 public:
     StructureTransitionTable()
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to