Bug 981809 - Postbarrier WeakMapPtr keys, r=terrence
authorSteve Fink <sfink@mozilla.com>
Thu, 13 Mar 2014 13:53:34 -0700
changeset 173906 b239389ec1e6dc842168fe906743c03b28ef6547
parent 173905 409036268a8eef4600410ac1b98f6c7990b3c023
child 173907 08d252ee432ad51a00fd6a419db107dd711dc4d6
push id41133
push usersfink@mozilla.com
push dateMon, 17 Mar 2014 17:23:02 +0000
treeherdermozilla-inbound@b239389ec1e6 [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)
 {