Bug 1242810. r=jandem, a=ritu
authorJeff Walden <jwalden@mit.edu>
Wed, 02 Mar 2016 17:52:08 -0800
changeset 323646 094bebe3dafd9c7603ecabd181e0110375f64781
parent 323645 35a5dfe62c0b08e0af289f0969e6ef91e9b151dc
child 323647 b68ca8f1122c22f4dd58dfc902f43438b40ca848
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem, ritu
bugs1242810
milestone47.0a2
Bug 1242810. r=jandem, a=ritu
js/src/vm/RegExpObject.cpp
--- a/js/src/vm/RegExpObject.cpp
+++ b/js/src/vm/RegExpObject.cpp
@@ -913,56 +913,54 @@ RegExpCompartment::sizeOfExcludingThis(m
 
 /* Functions */
 
 JSObject*
 js::CloneRegExpObject(JSContext* cx, JSObject* obj_)
 {
     Rooted<RegExpObject*> regex(cx, &obj_->as<RegExpObject>());
 
-    // Check that the RegExpShared for |regex| is okay to reuse in the clone.
-    // If the |RegExpStatics| provides additional flags, we'll need a new
-    // |RegExpShared|.
-    RegExpStatics* currentStatics = regex->getProto()->global().getRegExpStatics(cx);
-    if (!currentStatics)
-        return nullptr;
-
-    Rooted<JSAtom*> source(cx, regex->getSource());
-
-    RegExpFlag origFlags = regex->getFlags();
-    RegExpFlag staticsFlags = currentStatics->getFlags();
-    if ((origFlags & staticsFlags) != staticsFlags) {
-        Rooted<RegExpObject*> clone(cx, RegExpAlloc(cx));
-        if (!clone)
-            return nullptr;
-
-        if (!RegExpObject::initFromAtom(cx, clone, source, RegExpFlag(origFlags | staticsFlags)))
-            return nullptr;
-
-        return clone;
-    }
-
-    // Otherwise, the clone can use |regexp|'s RegExpShared.
+    // Unlike RegExpAlloc, all clones must use |regex|'s group.  Allocate
+    // in the tenured heap to simplify embedding them in JIT code.
     RootedObjectGroup group(cx, regex->group());
-
-    // Note: RegExp objects are always allocated in the tenured heap. This is
-    // not strictly required, but it simplifies embedding them in jitcode.
     Rooted<RegExpObject*> clone(cx, NewObjectWithGroup<RegExpObject>(cx, group, TenuredObject));
     if (!clone)
         return nullptr;
     clone->initPrivate(nullptr);
 
-    RegExpGuard g(cx);
-    if (!regex->getShared(cx, &g))
+    if (!EmptyShape::ensureInitialCustomShape<RegExpObject>(cx, clone))
+        return nullptr;
+
+    Rooted<JSAtom*> source(cx, regex->getSource());
+
+    // Check that the RegExpShared for |regex| is okay to reuse in the clone.
+    RegExpStatics* currentStatics = regex->getProto()->global().getRegExpStatics(cx);
+    if (!currentStatics)
         return nullptr;
 
-    if (!RegExpObject::initFromAtom(cx, clone, source, g->getFlags()))
-        return nullptr;
+    RegExpFlag origFlags = regex->getFlags();
+    RegExpFlag staticsFlags = currentStatics->getFlags();
+    if ((origFlags & staticsFlags) != staticsFlags) {
+        // If |currentStatics| provides additional flags, we'll have to use a
+        // new |RegExpShared|.
+        if (!RegExpObject::initFromAtom(cx, clone, source, RegExpFlag(origFlags | staticsFlags)))
+            return nullptr;
+    } else {
+        // Otherwise we can use |regexp|'s RegExpShared.  Initialize using its
+        // flags and associate it with the clone.
+        RegExpGuard g(cx);
+        if (!regex->getShared(cx, &g))
+            return nullptr;
 
-    clone->setShared(*g.re());
+        if (!RegExpObject::initFromAtom(cx, clone, source, g->getFlags()))
+            return nullptr;
+
+        clone->setShared(*g.re());
+    }
+
     return clone;
 }
 
 static bool
 HandleRegExpFlag(RegExpFlag flag, RegExpFlag* flags)
 {
     if (*flags & flag)
         return false;