diff --git a/js/src/vm/Shape.cpp b/js/src/vm/Shape.cpp
index ac2a1e04f43f14c8cba8d291b0919b719214d78e..357dd8a75d65ed91fe81ef169fad3783fdd8e70b 100644
--- a/js/src/vm/Shape.cpp
+++ b/js/src/vm/Shape.cpp
@@ -986,13 +986,7 @@ bool NativeObject::generateNewDictionaryShape(JSContext* cx,
 
   MOZ_ASSERT(obj->inDictionaryMode());
 
-  Rooted<BaseShape*> base(cx, obj->shape()->base());
-  Rooted<DictionaryPropMap*> map(cx, obj->dictionaryShape()->propMap());
-  uint32_t mapLength = obj->shape()->propMapLength();
-
-  Shape* shape =
-      DictionaryShape::new_(cx, base, obj->shape()->objectFlags(),
-                            obj->shape()->numFixedSlots(), map, mapLength);
+  Shape* shape = DictionaryShape::new_(cx, obj);
   if (!shape) {
     return false;
   }
@@ -1128,6 +1122,18 @@ DictionaryShape* DictionaryShape::new_(JSContext* cx, Handle<BaseShape*> base,
                                       mapLength);
 }
 
+DictionaryShape::DictionaryShape(NativeObject* nobj)
+    : DictionaryShape(nobj->shape()->base(), nobj->shape()->objectFlags(),
+                      nobj->shape()->numFixedSlots(),
+                      nobj->dictionaryShape()->propMap(),
+                      nobj->shape()->propMapLength()) {}
+
+// static
+DictionaryShape* DictionaryShape::new_(JSContext* cx,
+                                       Handle<NativeObject*> obj) {
+  return cx->newCell<DictionaryShape>(obj);
+}
+
 // static
 ProxyShape* ProxyShape::new_(JSContext* cx, Handle<BaseShape*> base,
                              ObjectFlags objectFlags) {
diff --git a/js/src/vm/Shape.h b/js/src/vm/Shape.h
index 9af9df30419172021758ec3edc2d50cbb5f1d3e5..9492135d0f0a7d8cefc5646e36c74f399d9f6abb 100644
--- a/js/src/vm/Shape.h
+++ b/js/src/vm/Shape.h
@@ -511,7 +511,7 @@ class NativeShape : public Shape {
 class SharedShape : public NativeShape {
   friend class js::gc::CellAllocator;
   SharedShape(BaseShape* base, ObjectFlags objectFlags, uint32_t nfixed,
-              PropMap* map, uint32_t mapLength)
+              SharedPropMap* map, uint32_t mapLength)
       : NativeShape(Kind::Shared, base, objectFlags, nfixed, map, mapLength) {
     initSmallSlotSpan();
   }
@@ -622,11 +622,12 @@ class DictionaryShape : public NativeShape {
   friend class NativeObject;
 
   DictionaryShape(BaseShape* base, ObjectFlags objectFlags, uint32_t nfixed,
-                  PropMap* map, uint32_t mapLength)
+                  DictionaryPropMap* map, uint32_t mapLength)
       : NativeShape(Kind::Dictionary, base, objectFlags, nfixed, map,
                     mapLength) {
     MOZ_ASSERT(map);
   }
+  explicit DictionaryShape(NativeObject* nobj);
 
   // Methods to set fields of a new dictionary shape. Must not be used for
   // shapes that might have been exposed to script.
@@ -648,6 +649,7 @@ class DictionaryShape : public NativeShape {
                                ObjectFlags objectFlags, uint32_t nfixed,
                                Handle<DictionaryPropMap*> map,
                                uint32_t mapLength);
+  static DictionaryShape* new_(JSContext* cx, Handle<NativeObject*> obj);
 
   DictionaryPropMap* propMap() const {
     MOZ_ASSERT(isDictionary());