Bug 816046 - Intermittent "Assertion failure: key.kind != CrossCompartmentKey::StringWrapper r=billm
authorJon Coppeard <jcoppeard@mozilla.com>
Wed, 28 Nov 2012 17:39:12 +0000
changeset 123581 b2175d0f4770574f63d1d9345cd8887508643240
parent 123580 f039a331337f99a623667140c1d96b5554e71a22
child 123582 13ee7ebc101a00c4b9b7a7f9abeff8bf972a3061
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs816046
milestone20.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 816046 - Intermittent "Assertion failure: key.kind != CrossCompartmentKey::StringWrapper r=billm
js/src/jscompartment.cpp
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -332,17 +332,32 @@ JSCompartment::wrap(JSContext *cx, Value
         RootedValue orig(cx, *vp);
         JSStableString *str = vp->toString()->ensureStable(cx);
         if (!str)
             return false;
         JSString *wrapped = js_NewStringCopyN(cx, str->chars().get(), str->length());
         if (!wrapped)
             return false;
         vp->setString(wrapped);
-        return crossCompartmentWrappers.put(orig, *vp);
+        if (!crossCompartmentWrappers.put(orig, *vp))
+            return false;
+
+        if (str->compartment()->isGCMarking()) {
+            /*
+             * All string wrappers are dropped when collection starts, but we
+             * just created a new one.  Mark the wrapped string to stop it being
+             * finalized, because if it was then the pointer in this
+             * compartment's wrapper map would be left dangling.
+             */
+            JSString *tmp = str;
+            MarkStringUnbarriered(&rt->gcMarker, &tmp, "wrapped string");
+            JS_ASSERT(tmp == str);
+        }
+
+        return true;
     }
 
     RootedObject obj(cx, &vp->toObject());
 
     JSObject *proto = Proxy::LazyProto;
     if (existing) {
         /* Is it possible to reuse |existing|? */
         if (!existing->getTaggedProto().isLazy() ||