Bug 953373 - Use NewObjectWithType when cloning regexps. r=bhackett, a=bajaj
authorJan de Mooij <jdemooij@mozilla.com>
Thu, 02 Jan 2014 17:39:00 +0100
changeset 175516 b38b8e812aa71146ddc565343e15222c3e8a0bb5
parent 175515 477aec9bca87972ba3f7ce011be935877e7fc817
child 175517 17f677b7df0c8b30803e7b0f248455b11a26a368
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbhackett, bajaj
bugs953373
milestone28.0a2
Bug 953373 - Use NewObjectWithType when cloning regexps. r=bhackett, a=bajaj
js/src/jsobj.cpp
js/src/jsobjinlines.h
js/src/vm/RegExpObject.cpp
js/src/vm/RegExpObject.h
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -1443,43 +1443,42 @@ js::NewObjectWithClassProtoCommon(Exclus
 /*
  * Create a plain object with the specified type. This bypasses getNewType to
  * avoid losing creation site information for objects made by scripted 'new'.
  */
 JSObject *
 js::NewObjectWithType(JSContext *cx, HandleTypeObject type, JSObject *parent, gc::AllocKind allocKind,
                       NewObjectKind newKind)
 {
-    JS_ASSERT(type->proto->hasNewType(&JSObject::class_, type));
     JS_ASSERT(parent);
 
     JS_ASSERT(allocKind <= gc::FINALIZE_OBJECT_LAST);
-    if (CanBeFinalizedInBackground(allocKind, &JSObject::class_))
+    if (CanBeFinalizedInBackground(allocKind, type->clasp))
         allocKind = GetBackgroundAllocKind(allocKind);
 
     NewObjectCache &cache = cx->runtime()->newObjectCache;
 
     NewObjectCache::EntryIndex entry = -1;
     if (parent == type->proto->getParent() &&
         newKind == GenericObject &&
         !cx->compartment()->hasObjectMetadataCallback())
     {
-        if (cache.lookupType(&JSObject::class_, type, allocKind, &entry)) {
-            JSObject *obj = cache.newObjectFromHit(cx, entry, GetInitialHeap(newKind, &JSObject::class_));
+        if (cache.lookupType(type->clasp, type, allocKind, &entry)) {
+            JSObject *obj = cache.newObjectFromHit(cx, entry, GetInitialHeap(newKind, type->clasp));
             if (obj)
                 return obj;
         }
     }
 
-    JSObject *obj = NewObject(cx, &JSObject::class_, type, parent, allocKind, newKind);
+    JSObject *obj = NewObject(cx, type->clasp, type, parent, allocKind, newKind);
     if (!obj)
         return nullptr;
 
     if (entry != -1 && !obj->hasDynamicSlots())
-        cache.fillType(entry, &JSObject::class_, type, allocKind, obj);
+        cache.fillType(entry, type->clasp, type, allocKind, obj);
 
     return obj;
 }
 
 bool
 js::NewObjectScriptedCall(JSContext *cx, MutableHandleObject pobj)
 {
     jsbytecode *pc;
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -914,16 +914,24 @@ CopyInitializerObject(JSContext *cx, Han
 
     return obj;
 }
 
 JSObject *
 NewObjectWithType(JSContext *cx, HandleTypeObject type, JSObject *parent, gc::AllocKind allocKind,
                   NewObjectKind newKind = GenericObject);
 
+inline JSObject *
+NewObjectWithType(JSContext *cx, HandleTypeObject type, JSObject *parent,
+                  NewObjectKind newKind = GenericObject)
+{
+    gc::AllocKind allocKind = gc::GetGCObjectKind(type->clasp);
+    return NewObjectWithType(cx, type, parent, allocKind, newKind);
+}
+
 JSObject *
 NewReshapedObject(JSContext *cx, HandleTypeObject type, JSObject *parent,
                   gc::AllocKind allocKind, HandleShape shape,
                   NewObjectKind newKind = GenericObject);
 
 /*
  * As for gc::GetGCObjectKind, where numSlots is a guess at the final size of
  * the object, zero if the final size is unknown. This should only be used for
--- a/js/src/vm/RegExpObject.cpp
+++ b/js/src/vm/RegExpObject.cpp
@@ -46,24 +46,26 @@ RegExpObjectBuilder::getOrCreate()
         return false;
     obj->initPrivate(nullptr);
 
     reobj_ = &obj->as<RegExpObject>();
     return true;
 }
 
 bool
-RegExpObjectBuilder::getOrCreateClone(RegExpObject *proto)
+RegExpObjectBuilder::getOrCreateClone(HandleTypeObject type)
 {
     JS_ASSERT(!reobj_);
+    JS_ASSERT(type->clasp == &RegExpObject::class_);
+
+    JSObject *parent = type->proto->getParent();
 
     // Note: RegExp objects are always allocated in the tenured heap. This is
     // not strictly required, but simplifies embedding them in jitcode.
-    JSObject *clone = NewObjectWithGivenProto(cx, &RegExpObject::class_, proto, proto->getParent(),
-                                              TenuredObject);
+    JSObject *clone = NewObjectWithType(cx->asJSContext(), type, parent, TenuredObject);
     if (!clone)
         return false;
     clone->initPrivate(nullptr);
 
     reobj_ = &clone->as<RegExpObject>();
     return true;
 }
 
@@ -87,17 +89,20 @@ RegExpObjectBuilder::build(HandleAtom so
         return nullptr;
 
     return reobj_->init(cx, source, flags) ? reobj_.get() : nullptr;
 }
 
 RegExpObject *
 RegExpObjectBuilder::clone(Handle<RegExpObject *> other, Handle<RegExpObject *> proto)
 {
-    if (!getOrCreateClone(proto))
+    RootedTypeObject type(cx, other->type());
+    JS_ASSERT(type->proto == proto);
+
+    if (!getOrCreateClone(type))
         return nullptr;
 
     /*
      * Check that the RegExpShared for the original is okay to use in
      * the clone -- if the |RegExpStatics| provides more flags we'll
      * need a different |RegExpShared|.
      */
     RegExpStatics *res = proto->getParent()->as<GlobalObject>().getRegExpStatics();
@@ -733,17 +738,19 @@ RegExpCompartment::sizeOfExcludingThis(m
 /* Functions */
 
 JSObject *
 js::CloneRegExpObject(JSContext *cx, JSObject *obj_, JSObject *proto_)
 {
     RegExpObjectBuilder builder(cx);
     Rooted<RegExpObject*> regex(cx, &obj_->as<RegExpObject>());
     Rooted<RegExpObject*> proto(cx, &proto_->as<RegExpObject>());
-    return builder.clone(regex, proto);
+    JSObject *res = builder.clone(regex, proto);
+    JS_ASSERT(res->type() == regex->type());
+    return res;
 }
 
 bool
 js::ParseRegExpFlags(JSContext *cx, JSString *flagStr, RegExpFlag *flagsOut)
 {
     size_t n = flagStr->length();
     const jschar *s = flagStr->getChars(cx);
     if (!s)
--- a/js/src/vm/RegExpObject.h
+++ b/js/src/vm/RegExpObject.h
@@ -68,17 +68,17 @@ enum RegExpRunStatus
 };
 
 class RegExpObjectBuilder
 {
     ExclusiveContext *cx;
     Rooted<RegExpObject*> reobj_;
 
     bool getOrCreate();
-    bool getOrCreateClone(RegExpObject *proto);
+    bool getOrCreateClone(HandleTypeObject type);
 
   public:
     RegExpObjectBuilder(ExclusiveContext *cx, RegExpObject *reobj = nullptr);
 
     RegExpObject *reobj() { return reobj_; }
 
     RegExpObject *build(HandleAtom source, RegExpFlag flags);
     RegExpObject *build(HandleAtom source, RegExpShared &shared);