Bug 946546 - copy JS strings directly into the destination compartment; r=billm
authorNathan Froyd <froydnj@mozilla.com>
Mon, 27 Jan 2014 17:24:35 -0500
changeset 182171 bffc2528c3a88d645d97c5b3fe6309a938e2d023
parent 182170 b199295c353768a51633a63458126ebb04822ed5
child 182172 ff3c388e54109c6906c881e462c60078c871952f
push id3343
push userffxbld
push dateMon, 17 Mar 2014 21:55:32 +0000
treeherdermozilla-beta@2f7d3415f79f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs946546
milestone29.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 946546 - copy JS strings directly into the destination compartment; r=billm
js/src/jscompartment.cpp
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -301,39 +301,37 @@ JSCompartment::wrap(JSContext *cx, JSStr
 
     /* Check the cache. */
     RootedValue key(cx, StringValue(str));
     if (WrapperMap::Ptr p = crossCompartmentWrappers.lookup(key)) {
         *strp = p->value().get().toString();
         return true;
     }
 
-    /* No dice. Make a copy, and cache it. */
-    Rooted<JSLinearString *> linear(cx, str->ensureLinear(cx));
-    if (!linear)
-        return false;
-    JSString *copy = js_NewStringCopyN<CanGC>(cx, linear->chars(),
-                                              linear->length());
+    /*
+     * No dice. Make a copy, and cache it. Directly allocate the copy in the
+     * destination compartment, rather than first flattening it (and possibly
+     * allocating in source compartment), because we don't know whether the
+     * flattening will pay off later.
+     */
+    JSString *copy;
+    if (str->hasPureChars()) {
+        copy = js_NewStringCopyN<CanGC>(cx, str->pureChars(), str->length());
+    } else {
+        ScopedJSFreePtr<jschar> copiedChars;
+        if (!str->copyNonPureCharsZ(cx, copiedChars))
+            return false;
+        copy = js_NewString<CanGC>(cx, copiedChars.forget(), str->length());
+    }
+
     if (!copy)
         return false;
     if (!putWrapper(cx, key, StringValue(copy)))
         return false;
 
-    if (linear->zone()->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 = linear;
-        MarkStringUnbarriered(&cx->runtime()->gcMarker, &tmp, "wrapped string");
-        JS_ASSERT(tmp == linear);
-    }
-
     *strp = copy;
     return true;
 }
 
 bool
 JSCompartment::wrap(JSContext *cx, HeapPtrString *strp)
 {
     RootedString str(cx, *strp);