Bug 1470250 part 1 - Use correct realm in ObjectGroupRealm::makeGroup. r=luke
authorJan de Mooij <jdemooij@mozilla.com>
Tue, 26 Jun 2018 09:42:05 +0200
changeset 423672 2f70bd2a3a9b4ee46613b08533bb106e9a73cd20
parent 423671 748ba658c02b66030b99ce7576c85c57c95225b7
child 423673 c2d21705dacecbfad027535eb52962d05a38a0e9
push id34190
push userebalazs@mozilla.com
push dateTue, 26 Jun 2018 14:53:39 +0000
treeherdermozilla-central@348090c6b5c4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1470250
milestone63.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 1470250 part 1 - Use correct realm in ObjectGroupRealm::makeGroup. r=luke
js/src/builtin/MapObject.cpp
js/src/vm/EnvironmentObject.cpp
js/src/vm/Iteration.cpp
js/src/vm/JSObject-inl.h
js/src/vm/JSObject.cpp
js/src/vm/ObjectGroup.cpp
js/src/vm/ObjectGroup.h
js/src/vm/RegExpObject.cpp
js/src/vm/TypeInference.cpp
js/src/vm/UnboxedObject.cpp
--- a/js/src/builtin/MapObject.cpp
+++ b/js/src/builtin/MapObject.cpp
@@ -371,17 +371,18 @@ MapIteratorObject::next(Handle<MapIterat
 /* static */ JSObject*
 MapIteratorObject::createResultPair(JSContext* cx)
 {
     RootedArrayObject resultPairObj(cx, NewDenseFullyAllocatedArray(cx, 2, nullptr, TenuredObject));
     if (!resultPairObj)
         return nullptr;
 
     Rooted<TaggedProto> proto(cx, resultPairObj->taggedProto());
-    ObjectGroup* group = ObjectGroupRealm::makeGroup(cx, resultPairObj->getClass(), proto);
+    ObjectGroup* group = ObjectGroupRealm::makeGroup(cx, resultPairObj->realm(),
+                                                     resultPairObj->getClass(), proto);
     if (!group)
         return nullptr;
     resultPairObj->setGroup(group);
 
     resultPairObj->setDenseInitializedLength(2);
     resultPairObj->initDenseElement(0, NullValue());
     resultPairObj->initDenseElement(1, NullValue());
 
@@ -1202,17 +1203,18 @@ SetIteratorObject::next(Handle<SetIterat
 /* static */ JSObject*
 SetIteratorObject::createResult(JSContext* cx)
 {
     RootedArrayObject resultObj(cx, NewDenseFullyAllocatedArray(cx, 1, nullptr, TenuredObject));
     if (!resultObj)
         return nullptr;
 
     Rooted<TaggedProto> proto(cx, resultObj->taggedProto());
-    ObjectGroup* group = ObjectGroupRealm::makeGroup(cx, resultObj->getClass(), proto);
+    ObjectGroup* group = ObjectGroupRealm::makeGroup(cx, resultObj->realm(),
+                                                     resultObj->getClass(), proto);
     if (!group)
         return nullptr;
     resultObj->setGroup(group);
 
     resultObj->setDenseInitializedLength(1);
     resultObj->initDenseElement(0, NullValue());
 
     // See comments in SetIteratorObject::next.
--- a/js/src/vm/EnvironmentObject.cpp
+++ b/js/src/vm/EnvironmentObject.cpp
@@ -140,19 +140,18 @@ CallObject::create(JSContext* cx, Handle
 
 CallObject*
 CallObject::createSingleton(JSContext* cx, HandleShape shape)
 {
     gc::AllocKind kind = gc::GetGCObjectKind(shape->numFixedSlots());
     MOZ_ASSERT(CanBeFinalizedInBackground(kind, &CallObject::class_));
     kind = gc::GetBackgroundAllocKind(kind);
 
-    ObjectGroupRealm& realm = ObjectGroupRealm::getForNewObject(cx);
-    RootedObjectGroup group(cx, ObjectGroup::lazySingletonGroup(cx, realm, &class_,
-                                                                TaggedProto(nullptr)));
+    RootedObjectGroup group(cx, ObjectGroup::lazySingletonGroup(cx, /* oldGroup = */ nullptr,
+                                                                &class_, TaggedProto(nullptr)));
     if (!group)
         return nullptr;
 
     JSObject* obj;
     JS_TRY_VAR_OR_RETURN_NULL(cx, obj, NativeObject::create(cx, kind, gc::TenuredHeap, shape, group));
 
     MOZ_ASSERT(obj->isSingleton(),
                "group created inline above must be a singleton");
--- a/js/src/vm/Iteration.cpp
+++ b/js/src/vm/Iteration.cpp
@@ -975,17 +975,18 @@ Realm::getOrCreateIterResultTemplateObje
 
     // Create template plain object
     RootedNativeObject templateObject(cx, NewBuiltinClassInstance<PlainObject>(cx, TenuredObject));
     if (!templateObject)
         return iterResultTemplate_; // = nullptr
 
     // Create a new group for the template.
     Rooted<TaggedProto> proto(cx, templateObject->taggedProto());
-    RootedObjectGroup group(cx, ObjectGroupRealm::makeGroup(cx, templateObject->getClass(),
+    RootedObjectGroup group(cx, ObjectGroupRealm::makeGroup(cx, templateObject->realm(),
+                                                            templateObject->getClass(),
                                                             proto));
     if (!group)
         return iterResultTemplate_; // = nullptr
     templateObject->setGroup(group);
 
     // Set dummy `value` property
     if (!NativeDefineDataProperty(cx, templateObject, cx->names().value, UndefinedHandleValue,
                                   JSPROP_ENUMERATE))
--- a/js/src/vm/JSObject-inl.h
+++ b/js/src/vm/JSObject-inl.h
@@ -153,18 +153,17 @@ js::NativeObject::updateDictionaryListPo
         shape()->listp = shapePtr();
 }
 
 /* static */ inline bool
 JSObject::setSingleton(JSContext* cx, js::HandleObject obj)
 {
     MOZ_ASSERT(!IsInsideNursery(obj));
 
-    js::ObjectGroupRealm& realm = js::ObjectGroupRealm::get(obj->group_);
-    js::ObjectGroup* group = js::ObjectGroup::lazySingletonGroup(cx, realm, obj->getClass(),
+    js::ObjectGroup* group = js::ObjectGroup::lazySingletonGroup(cx, obj->group_, obj->getClass(),
                                                                  obj->taggedProto());
     if (!group)
         return false;
 
     obj->group_ = group;
     return true;
 }
 
--- a/js/src/vm/JSObject.cpp
+++ b/js/src/vm/JSObject.cpp
@@ -2104,17 +2104,17 @@ SetClassAndProto(JSContext* cx, HandleOb
     RootedObjectGroup oldGroup(cx, obj->group());
 
     ObjectGroup* newGroup;
     if (oldGroup->maybeInterpretedFunction()) {
         // We're changing the group/proto of a scripted function. Create a new
         // group so we can keep track of the interpreted function for Ion
         // inlining.
         MOZ_ASSERT(obj->is<JSFunction>());
-        newGroup = ObjectGroupRealm::makeGroup(cx, &JSFunction::class_, proto);
+        newGroup = ObjectGroupRealm::makeGroup(cx, oldGroup->realm(), &JSFunction::class_, proto);
         if (!newGroup)
             return false;
         newGroup->setInterpretedFunction(oldGroup->maybeInterpretedFunction());
     } else {
         newGroup = ObjectGroup::defaultNewGroup(cx, clasp, proto);
         if (!newGroup)
             return false;
     }
@@ -2140,18 +2140,17 @@ SetClassAndProto(JSContext* cx, HandleOb
 
 /* static */ bool
 JSObject::changeToSingleton(JSContext* cx, HandleObject obj)
 {
     MOZ_ASSERT(!obj->isSingleton());
 
     MarkObjectGroupUnknownProperties(cx, obj->group());
 
-    ObjectGroupRealm& realm = ObjectGroupRealm::get(obj->group());
-    ObjectGroup* group = ObjectGroup::lazySingletonGroup(cx, realm, obj->getClass(),
+    ObjectGroup* group = ObjectGroup::lazySingletonGroup(cx, obj->group(), obj->getClass(),
                                                          obj->taggedProto());
     if (!group)
         return false;
 
     obj->group_ = group;
     return true;
 }
 
--- a/js/src/vm/ObjectGroup.cpp
+++ b/js/src/vm/ObjectGroup.cpp
@@ -319,18 +319,18 @@ JSObject::makeLazyGroup(JSContext* cx, H
 
     if (obj->isNative() && obj->as<NativeObject>().isIndexed())
         initialFlags |= OBJECT_FLAG_SPARSE_INDEXES;
 
     if (obj->is<ArrayObject>() && obj->as<ArrayObject>().length() > INT32_MAX)
         initialFlags |= OBJECT_FLAG_LENGTH_OVERFLOW;
 
     Rooted<TaggedProto> proto(cx, obj->taggedProto());
-    ObjectGroup* group = ObjectGroupRealm::makeGroup(cx, obj->getClass(), proto,
-                                                     initialFlags);
+    ObjectGroup* group = ObjectGroupRealm::makeGroup(cx, obj->nonCCWRealm(), obj->getClass(),
+                                                     proto, initialFlags);
     if (!group)
         return nullptr;
 
     AutoEnterAnalysis enter(cx);
 
     /* Fill in the type according to the state of this object. */
 
     if (obj->is<JSFunction>() && obj->as<JSFunction>().isInterpreted())
@@ -575,17 +575,18 @@ ObjectGroup::defaultNewGroup(JSContext* 
         return group;
     }
 
     ObjectGroupFlags initialFlags = 0;
     if (proto.isDynamic() || (proto.isObject() && proto.toObject()->isNewGroupUnknown()))
         initialFlags = OBJECT_FLAG_DYNAMIC_MASK;
 
     Rooted<TaggedProto> protoRoot(cx, proto);
-    ObjectGroup* group = ObjectGroupRealm::makeGroup(cx, clasp ? clasp : &PlainObject::class_,
+    ObjectGroup* group = ObjectGroupRealm::makeGroup(cx, cx->realm(),
+                                                     clasp ? clasp : &PlainObject::class_,
                                                      protoRoot, initialFlags);
     if (!group)
         return nullptr;
 
     if (!table->add(p, ObjectGroupRealm::NewEntry(group, associated))) {
         ReportOutOfMemory(cx);
         return nullptr;
     }
@@ -618,19 +619,23 @@ ObjectGroup::defaultNewGroup(JSContext* 
         AddTypePropertyId(cx, group, nullptr, NameToId(names.columnNumber), TypeSet::Int32Type());
     }
 
     groups.defaultNewGroupCache.put(group, associated);
     return group;
 }
 
 /* static */ ObjectGroup*
-ObjectGroup::lazySingletonGroup(JSContext* cx, ObjectGroupRealm& realm, const Class* clasp,
+ObjectGroup::lazySingletonGroup(JSContext* cx, ObjectGroup* oldGroup, const Class* clasp,
                                 TaggedProto proto)
 {
+    ObjectGroupRealm& realm = oldGroup
+                              ? ObjectGroupRealm::get(oldGroup)
+                              : ObjectGroupRealm::getForNewObject(cx);
+
     MOZ_ASSERT_IF(proto.isObject(), cx->compartment() == proto.toObject()->compartment());
 
     ObjectGroupRealm::NewTable*& table = realm.lazyTable;
 
     if (!table) {
         table = cx->new_<ObjectGroupRealm::NewTable>(cx->zone());
         if (!table)
             return nullptr;
@@ -651,17 +656,19 @@ ObjectGroup::lazySingletonGroup(JSContex
 
         return group;
     }
 
     AutoEnterAnalysis enter(cx);
 
     Rooted<TaggedProto> protoRoot(cx, proto);
     ObjectGroup* group =
-        ObjectGroupRealm::makeGroup(cx, clasp, protoRoot,
+        ObjectGroupRealm::makeGroup(cx,
+                                    oldGroup ? oldGroup->realm() : cx->realm(),
+                                    clasp, protoRoot,
                                     OBJECT_FLAG_SINGLETON | OBJECT_FLAG_LAZY_SINGLETON);
     if (!group)
         return nullptr;
 
     if (!table->add(p, ObjectGroupRealm::NewEntry(group, nullptr))) {
         ReportOutOfMemory(cx);
         return nullptr;
     }
@@ -878,17 +885,17 @@ ObjectGroup::newArrayObject(JSContext* c
     RootedObjectGroup group(cx);
     if (p) {
         group = p->value();
     } else {
         JSObject* proto = GlobalObject::getOrCreateArrayPrototype(cx, cx->global());
         if (!proto)
             return nullptr;
         Rooted<TaggedProto> taggedProto(cx, TaggedProto(proto));
-        group = ObjectGroupRealm::makeGroup(cx, &ArrayObject::class_, taggedProto);
+        group = ObjectGroupRealm::makeGroup(cx, cx->realm(), &ArrayObject::class_, taggedProto);
         if (!group)
             return nullptr;
 
         AddTypePropertyId(cx, group, nullptr, JSID_VOID, elementType);
 
         if (!p.add(cx, *table, ObjectGroupRealm::ArrayObjectKey(elementType), group))
             return nullptr;
     }
@@ -1205,17 +1212,18 @@ ObjectGroup::newPlainObject(JSContext* c
         if (!CanShareObjectGroup(properties, nproperties))
             return NewPlainObjectWithProperties(cx, properties, nproperties, newKind);
 
         JSObject* proto = GlobalObject::getOrCreatePrototype(cx, JSProto_Object);
         if (!proto)
             return nullptr;
 
         Rooted<TaggedProto> tagged(cx, TaggedProto(proto));
-        RootedObjectGroup group(cx, ObjectGroupRealm::makeGroup(cx, &PlainObject::class_,
+        RootedObjectGroup group(cx, ObjectGroupRealm::makeGroup(cx, cx->realm(),
+                                                                &PlainObject::class_,
                                                                 tagged));
         if (!group)
             return nullptr;
 
         gc::AllocKind allocKind = gc::GetGCObjectKind(nproperties);
         RootedPlainObject obj(cx, NewObjectWithGroup<PlainObject>(cx, group,
                                                                   allocKind, TenuredObject));
         if (!obj || !AddPlainObjectProperties(cx, obj, properties, nproperties))
@@ -1480,17 +1488,18 @@ ObjectGroup::allocationSiteGroup(JSConte
 
     ObjectGroupRealm::AllocationSiteTable::AddPtr p = table->lookupForAdd(key);
     if (p)
         return p->value();
 
     AutoEnterAnalysis enter(cx);
 
     Rooted<TaggedProto> tagged(cx, TaggedProto(proto));
-    ObjectGroup* res = ObjectGroupRealm::makeGroup(cx, GetClassForProtoKey(kind), tagged,
+    ObjectGroup* res = ObjectGroupRealm::makeGroup(cx, script->realm(),
+                                                   GetClassForProtoKey(kind), tagged,
                                                    OBJECT_FLAG_FROM_ALLOCATION_SITE);
     if (!res)
         return nullptr;
 
     if (JSOp(*pc) == JSOP_NEWOBJECT) {
         // Keep track of the preliminary objects with this group, so we can try
         // to use an unboxed layout for the object once some are allocated.
         Shape* shape = script->getObject(pc)->as<PlainObject>().lastProperty();
@@ -1684,26 +1693,26 @@ ObjectGroupRealm::replaceDefaultNewGroup
         AutoEnterOOMUnsafeRegion oomUnsafe;
         if (!defaultNewTable->putNew(lookup, NewEntry(group, associated)))
             oomUnsafe.crash("Inconsistent object table");
     }
 }
 
 /* static */
 ObjectGroup*
-ObjectGroupRealm::makeGroup(JSContext* cx, const Class* clasp,
+ObjectGroupRealm::makeGroup(JSContext* cx, Realm* realm, const Class* clasp,
                             Handle<TaggedProto> proto,
                             ObjectGroupFlags initialFlags /* = 0 */)
 {
     MOZ_ASSERT_IF(proto.isObject(), cx->isInsideCurrentCompartment(proto.toObject()));
 
     ObjectGroup* group = Allocate<ObjectGroup>(cx);
     if (!group)
         return nullptr;
-    new(group) ObjectGroup(clasp, proto, cx->realm(), initialFlags);
+    new(group) ObjectGroup(clasp, proto, realm, initialFlags);
 
     return group;
 }
 
 /* static */
 ObjectGroup*
 ObjectGroupRealm::getStringSplitStringGroup(JSContext* cx)
 {
@@ -1719,17 +1728,17 @@ ObjectGroupRealm::getStringSplitStringGr
 
     const Class* clasp = GetClassForProtoKey(JSProto_Array);
 
     JSObject* proto = GlobalObject::getOrCreateArrayPrototype(cx, cx->global());
     if (!proto)
         return nullptr;
     Rooted<TaggedProto> tagged(cx, TaggedProto(proto));
 
-    group = makeGroup(cx, clasp, tagged, /* initialFlags = */ 0);
+    group = makeGroup(cx, cx->realm(), clasp, tagged, /* initialFlags = */ 0);
     if (!group)
         return nullptr;
 
     groups.stringSplitStringGroup.set(group);
     return group;
 }
 
 void
--- a/js/src/vm/ObjectGroup.h
+++ b/js/src/vm/ObjectGroup.h
@@ -528,17 +528,17 @@ class ObjectGroup : public gc::TenuredCe
     static bool useSingletonForAllocationSite(JSScript* script, jsbytecode* pc,
                                               const Class* clasp);
 
     // Static accessors for ObjectGroupRealm NewTable.
 
     static ObjectGroup* defaultNewGroup(JSContext* cx, const Class* clasp,
                                         TaggedProto proto,
                                         JSObject* associated = nullptr);
-    static ObjectGroup* lazySingletonGroup(JSContext* cx, ObjectGroupRealm& realm,
+    static ObjectGroup* lazySingletonGroup(JSContext* cx, ObjectGroup* oldGroup,
                                            const Class* clasp, TaggedProto proto);
 
     static void setDefaultNewGroupUnknown(JSContext* cx, ObjectGroupRealm& realm,
                                           const js::Class* clasp, JS::HandleObject obj);
 
 #ifdef DEBUG
     static bool hasDefaultNewGroup(JSObject* proto, const Class* clasp, ObjectGroup* group);
 #endif
@@ -694,17 +694,17 @@ class ObjectGroupRealm
 
     void replaceAllocationSiteGroup(JSScript* script, jsbytecode* pc,
                                     JSProtoKey kind, ObjectGroup* group);
 
     void removeDefaultNewGroup(const Class* clasp, TaggedProto proto, JSObject* associated);
     void replaceDefaultNewGroup(const Class* clasp, TaggedProto proto, JSObject* associated,
                                 ObjectGroup* group);
 
-    static ObjectGroup* makeGroup(JSContext* cx, const Class* clasp,
+    static ObjectGroup* makeGroup(JSContext* cx, JS::Realm* realm, const Class* clasp,
                                   Handle<TaggedProto> proto,
                                   ObjectGroupFlags initialFlags = 0);
 
     static ObjectGroup* getStringSplitStringGroup(JSContext* cx);
 
     void addSizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf,
                                 size_t* allocationSiteTables,
                                 size_t* arrayGroupTables,
--- a/js/src/vm/RegExpObject.cpp
+++ b/js/src/vm/RegExpObject.cpp
@@ -1224,17 +1224,18 @@ RegExpRealm::createMatchResultTemplateOb
     /* Create template array object */
     RootedArrayObject templateObject(cx, NewDenseUnallocatedArray(cx, RegExpObject::MaxPairCount,
                                                                   nullptr, TenuredObject));
     if (!templateObject)
         return matchResultTemplateObject_; // = nullptr
 
     // Create a new group for the template.
     Rooted<TaggedProto> proto(cx, templateObject->taggedProto());
-    ObjectGroup* group = ObjectGroupRealm::makeGroup(cx, templateObject->getClass(), proto);
+    ObjectGroup* group = ObjectGroupRealm::makeGroup(cx, templateObject->realm(),
+                                                     templateObject->getClass(), proto);
     if (!group)
         return matchResultTemplateObject_; // = nullptr
     templateObject->setGroup(group);
 
     /* Set dummy index property */
     RootedValue index(cx, Int32Value(0));
     if (!NativeDefineDataProperty(cx, templateObject, cx->names().index, index, JSPROP_ENUMERATE))
         return matchResultTemplateObject_; // = nullptr
--- a/js/src/vm/TypeInference.cpp
+++ b/js/src/vm/TypeInference.cpp
@@ -3471,17 +3471,17 @@ JSFunction::setTypeForScriptedFunction(J
                                        bool singleton /* = false */)
 {
     if (singleton) {
         if (!setSingleton(cx, fun))
             return false;
     } else {
         RootedObject funProto(cx, fun->staticPrototype());
         Rooted<TaggedProto> taggedProto(cx, TaggedProto(funProto));
-        ObjectGroup* group = ObjectGroupRealm::makeGroup(cx, &JSFunction::class_,
+        ObjectGroup* group = ObjectGroupRealm::makeGroup(cx, fun->realm(), &JSFunction::class_,
                                                          taggedProto);
         if (!group)
             return false;
 
         fun->setGroup(group);
         group->setInterpretedFunction(fun);
     }
 
@@ -3990,18 +3990,18 @@ TypeNewScript::maybeAnalyze(JSContext* c
     // existing group to represent fully initialized objects with all
     // definite properties in the prefix shape, and make a new group to
     // represent partially initialized objects.
     MOZ_ASSERT(prefixShape->slotSpan() > templateObject()->slotSpan());
 
     ObjectGroupFlags initialFlags = group->flags(sweep) & OBJECT_FLAG_DYNAMIC_MASK;
 
     Rooted<TaggedProto> protoRoot(cx, group->proto());
-    ObjectGroup* initialGroup = ObjectGroupRealm::makeGroup(cx, group->clasp(), protoRoot,
-                                                            initialFlags);
+    ObjectGroup* initialGroup = ObjectGroupRealm::makeGroup(cx, group->realm(), group->clasp(),
+                                                            protoRoot, initialFlags);
     if (!initialGroup)
         return false;
 
     initialGroup->addDefiniteProperties(cx, templateObject()->lastProperty());
     group->addDefiniteProperties(cx, prefixShape);
 
     ObjectGroupRealm& realm = ObjectGroupRealm::get(group);
     realm.replaceDefaultNewGroup(nullptr, group->proto(), function(), initialGroup);
--- a/js/src/vm/UnboxedObject.cpp
+++ b/js/src/vm/UnboxedObject.cpp
@@ -567,17 +567,18 @@ UnboxedLayout::makeNativeGroup(JSContext
 
     // Immediately clear any new script on the group. This is done by replacing
     // the existing new script with one for a replacement default new group.
     // This is done so that the size of the replacment group's objects is the
     // same as that for the unboxed group, so that we do not see polymorphic
     // slot accesses later on for sites that see converted objects from this
     // group and objects that were allocated using the replacement new group.
     if (layout.newScript()) {
-        replacementGroup = ObjectGroupRealm::makeGroup(cx, &PlainObject::class_, proto);
+        replacementGroup = ObjectGroupRealm::makeGroup(cx, group->realm(), &PlainObject::class_,
+                                                       proto);
         if (!replacementGroup)
             return false;
 
         PlainObject* templateObject = MakeReplacementTemplateObject(cx, replacementGroup, layout);
         if (!templateObject)
             return false;
 
         TypeNewScript* replacementNewScript =
@@ -592,17 +593,18 @@ UnboxedLayout::makeNativeGroup(JSContext
     }
 
     // Similarly, if this group is keyed to an allocation site, replace its
     // entry with a new group that has no unboxed layout.
     if (layout.allocationScript()) {
         RootedScript script(cx, layout.allocationScript());
         jsbytecode* pc = layout.allocationPc();
 
-        replacementGroup = ObjectGroupRealm::makeGroup(cx, &PlainObject::class_, proto);
+        replacementGroup = ObjectGroupRealm::makeGroup(cx, group->realm(), &PlainObject::class_,
+                                                       proto);
         if (!replacementGroup)
             return false;
 
         PlainObject* templateObject = &script->getObject(pc)->as<PlainObject>();
         replacementGroup->addDefiniteProperties(cx, templateObject->lastProperty());
 
         ObjectGroupRealm& realm = ObjectGroupRealm::get(group);
         realm.replaceAllocationSiteGroup(script, pc, JSProto_Object, replacementGroup);
@@ -633,17 +635,17 @@ UnboxedLayout::makeNativeGroup(JSContext
         Rooted<StackShape> child(cx, StackShape(shape->base()->unowned(), NameToId(property.name),
                                                 i, JSPROP_ENUMERATE));
         shape = cx->zone()->propertyTree().getChild(cx, shape, child);
         if (!shape)
             return false;
     }
 
     ObjectGroup* nativeGroup =
-        ObjectGroupRealm::makeGroup(cx, &PlainObject::class_, proto,
+        ObjectGroupRealm::makeGroup(cx, group->realm(), &PlainObject::class_, proto,
                                     group->flags(sweep) & OBJECT_FLAG_DYNAMIC_MASK);
     if (!nativeGroup)
         return false;
 
     // No sense propagating if we don't know what we started with.
     AutoSweepObjectGroup sweepNative(nativeGroup);
     if (!group->unknownProperties(sweep)) {
         for (size_t i = 0; i < layout.properties().length(); i++) {