Only add prototypes to the PrototypeMap if they're not already present
authorsbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 5 Oct 2017 19:58:08 +0000 (19:58 +0000)
committersbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 5 Oct 2017 19:58:08 +0000 (19:58 +0000)
https://bugs.webkit.org/show_bug.cgi?id=177952

Reviewed by Michael Saboff and JF Bastien.

With poly proto, we need to call PrototypeMap::add more frequently since we don't
know if the prototype is already in the map or not based solely on Structure.
PrototypeMap::add was calling WeakMap::set unconditionally, which would unconditionally
allocate a Weak handle. Allocating a Weak handle is expensive. It's at least 8x more
expensive than just checking if the prototype is in the map prior to adding it. This
patch makes the change to only add the prototype if it's not already in the map. To
do this, I've added a WeakMap::add API that just forwards into HashMap's add API.
This allows us to both only do a single hash table lookup and also to allocate only
a single Weak handle when necessary.

* runtime/PrototypeMapInlines.h:
(JSC::PrototypeMap::addPrototype):
* runtime/WeakGCMap.h:
(JSC::WeakGCMap::add):

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

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/PrototypeMapInlines.h
Source/JavaScriptCore/runtime/WeakGCMap.h

index 77b2ffd..296c40b 100644 (file)
@@ -1,5 +1,27 @@
 2017-10-05  Saam Barati  <sbarati@apple.com>
 
+        Only add prototypes to the PrototypeMap if they're not already present
+        https://bugs.webkit.org/show_bug.cgi?id=177952
+
+        Reviewed by Michael Saboff and JF Bastien.
+
+        With poly proto, we need to call PrototypeMap::add more frequently since we don't
+        know if the prototype is already in the map or not based solely on Structure.
+        PrototypeMap::add was calling WeakMap::set unconditionally, which would unconditionally
+        allocate a Weak handle. Allocating a Weak handle is expensive. It's at least 8x more
+        expensive than just checking if the prototype is in the map prior to adding it. This
+        patch makes the change to only add the prototype if it's not already in the map. To
+        do this, I've added a WeakMap::add API that just forwards into HashMap's add API.
+        This allows us to both only do a single hash table lookup and also to allocate only
+        a single Weak handle when necessary.
+
+        * runtime/PrototypeMapInlines.h:
+        (JSC::PrototypeMap::addPrototype):
+        * runtime/WeakGCMap.h:
+        (JSC::WeakGCMap::add):
+
+2017-10-05  Saam Barati  <sbarati@apple.com>
+
         Unreviewed. Disable probe OSR exit on 32-bit until it's fixed.
 
         * runtime/Options.cpp:
index 1d269d0..4dcd7c9 100644 (file)
@@ -44,7 +44,11 @@ ALWAYS_INLINE TriState PrototypeMap::isPrototype(JSObject* object) const
 
 ALWAYS_INLINE void PrototypeMap::addPrototype(JSObject* object)
 {
-    m_prototypes.set(object, object);
+    auto addResult = m_prototypes.add(object, Weak<JSObject>());
+    if (addResult.isNewEntry)
+        addResult.iterator->value = Weak<JSObject>(object);
+    else
+        ASSERT(addResult.iterator->value.get() == object);
 
     // Note that this method makes the somewhat odd decision to not check if this
     // object currently has indexed accessors. We could do that check here, and if
index 6f99fc0..503a86d 100644 (file)
@@ -58,6 +58,11 @@ public:
         return m_map.set(key, WTFMove(value));
     }
 
+    AddResult add(const KeyType& key, ValueType value)
+    {
+        return m_map.add(key, WTFMove(value));
+    }
+
     bool remove(const KeyType& key)
     {
         return m_map.remove(key);