Bug 981809 - Postbarrier WeakMapPtr keys, r=terrence
authorSteve Fink <sfink@mozilla.com>
Thu, 13 Mar 2014 13:53:34 -0700
changeset 173950 b239389ec1e6dc842168fe906743c03b28ef6547
parent 173949 409036268a8eef4600410ac1b98f6c7990b3c023
child 173951 08d252ee432ad51a00fd6a419db107dd711dc4d6
push id26438
push userphilringnalda@gmail.com
push dateTue, 18 Mar 2014 05:39:07 +0000
treeherderautoland@89275f0ae29f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs981809
milestone30.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 981809 - Postbarrier WeakMapPtr keys, r=terrence
js/public/WeakMapPtr.h
js/src/vm/WeakMapPtr.cpp
js/xpconnect/src/XPCWrappedNativeScope.cpp
--- a/js/public/WeakMapPtr.h
+++ b/js/public/WeakMapPtr.h
@@ -26,17 +26,19 @@ class JS_PUBLIC_API(WeakMapPtr)
     WeakMapPtr() : ptr(nullptr) {};
     bool init(JSContext *cx);
     bool initialized() { return ptr != nullptr; };
     void destroy();
     virtual ~WeakMapPtr() { MOZ_ASSERT(!initialized()); }
     void trace(JSTracer *tracer);
 
     V lookup(const K &key);
-    bool put(const K &key, const V &value);
+    bool put(JSContext *cx, const K &key, const V &value);
+
+    static void keyMarkCallback(JSTracer *trc, K key, void *data);
 
   private:
     void *ptr;
 
     // WeakMapPtr is neither copyable nor assignable.
     WeakMapPtr(const WeakMapPtr &wmp) MOZ_DELETE;
     WeakMapPtr &operator=(const WeakMapPtr &wmp) MOZ_DELETE;
 };
--- a/js/src/vm/WeakMapPtr.cpp
+++ b/js/src/vm/WeakMapPtr.cpp
@@ -90,21 +90,36 @@ JS::WeakMapPtr<K, V>::lookup(const K &ke
     MOZ_ASSERT(initialized());
     typename Utils<K, V>::Type::Ptr result = Utils<K, V>::cast(ptr)->lookup(key);
     if (!result)
         return DataType<V>::NullValue();
     return result->value();
 }
 
 template <typename K, typename V>
+/* static */ void
+JS::WeakMapPtr<K, V>::keyMarkCallback(JSTracer *trc, K key, void *data)
+{
+    auto map = static_cast< JS::WeakMapPtr<K, V>* >(data);
+    K prior = key;
+    JS_CallObjectTracer(trc, &key, "WeakMapPtr key");
+    return Utils<K, V>::cast(map->ptr)->rekeyIfMoved(prior, key);
+}
+
+template <typename K, typename V>
 bool
-JS::WeakMapPtr<K, V>::put(const K &key, const V &value)
+JS::WeakMapPtr<K, V>::put(JSContext *cx, const K &key, const V &value)
 {
     MOZ_ASSERT(initialized());
-    return Utils<K, V>::cast(ptr)->put(key, value);
+    if (!Utils<K, V>::cast(ptr)->put(key, value))
+        return false;
+    JS_StoreObjectPostBarrierCallback(cx, keyMarkCallback, key, this);
+    // Values do not need to be barriered because only put() is supported,
+    // which is always an initializing write.
+    return true;
 }
 
 //
 // Supported specializations of JS::WeakMap:
 //
 
 template class JS::WeakMapPtr<JSObject*, JSObject*>;
 
--- a/js/xpconnect/src/XPCWrappedNativeScope.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp
@@ -615,17 +615,17 @@ bool
 XPCWrappedNativeScope::SetExpandoChain(JSContext *cx, HandleObject target,
                                        HandleObject chain)
 {
     MOZ_ASSERT(GetObjectScope(target) == this);
     MOZ_ASSERT(js::IsObjectInContextCompartment(target, cx));
     MOZ_ASSERT_IF(chain, GetObjectScope(chain) == this);
     if (!mXrayExpandos.initialized() && !mXrayExpandos.init(cx))
         return false;
-    return mXrayExpandos.put(target, chain);
+    return mXrayExpandos.put(cx, target, chain);
 }
 
 /***************************************************************************/
 
 // static
 void
 XPCWrappedNativeScope::DebugDumpAllScopes(int16_t depth)
 {