diff --git a/js/src/jit/CacheIRHealth.cpp b/js/src/jit/CacheIRHealth.cpp
index 2ae30bb707a0a..9514bf2f768c4 100644
--- a/js/src/jit/CacheIRHealth.cpp
+++ b/js/src/jit/CacheIRHealth.cpp
@@ -12,6 +12,7 @@
 #  include "gc/Zone.h"
 #  include "jit/CacheIRCompiler.h"
 #  include "jit/JitScript.h"
+#  include "vm/JSObject-inl.h"
 
 using namespace js;
 using namespace js::jit;
@@ -69,8 +70,28 @@ CacheIRHealth::Happiness CacheIRHealth::spewStubHealth(
   return stubHappiness;
 }
 
+BaseScript* CacheIRHealth::maybeExtractBaseScript(JSContext* cx, Shape* shape) {
+  TaggedProto taggedProto = shape->base()->proto();
+  if (!taggedProto.isObject()) {
+    return nullptr;
+  }
+  Value cval;
+  if (!GetPropertyPure(cx, taggedProto.toObject(),
+                       NameToId(cx->names().constructor), &cval)) {
+    return nullptr;
+  }
+  if (!IsFunctionObject(cval)) {
+    return nullptr;
+  }
+  JSFunction& jsfun = cval.toObject().as<JSFunction>();
+  if (!jsfun.hasBaseScript()) {
+    return nullptr;
+  }
+  return jsfun.baseScript();
+}
+
 void CacheIRHealth::spewShapeInformation(AutoStructuredSpewer& spew,
-                                         ICStub* stub) {
+                                         JSContext* cx, ICStub* stub) {
   bool shapesStarted = false;
   const CacheIRStubInfo* stubInfo = stub->toCacheIRStub()->stubInfo();
   size_t offset = 0;
@@ -109,6 +130,16 @@ void CacheIRHealth::spewShapeInformation(AutoStructuredSpewer& spew,
               }
             }
             spew->property("totalKeys", propMap->approximateEntryCount());
+            BaseScript* baseScript = maybeExtractBaseScript(cx, shape);
+            if (baseScript) {
+              spew->beginObjectProperty("shapeAllocSite");
+              {
+                spew->property("filename", baseScript->filename());
+                spew->property("line", baseScript->lineno());
+                spew->property("column", baseScript->column());
+              }
+              spew->endObject();
+            }
           }
         }
         spew->endObject();
@@ -124,6 +155,7 @@ void CacheIRHealth::spewShapeInformation(AutoStructuredSpewer& spew,
 }
 
 bool CacheIRHealth::spewNonFallbackICInformation(AutoStructuredSpewer& spew,
+                                                 JSContext* cx,
                                                  ICStub* firstStub,
                                                  Happiness* entryHappiness) {
   const CacheIRStubInfo* stubInfo = firstStub->toCacheIRStub()->stubInfo();
@@ -142,7 +174,7 @@ bool CacheIRHealth::spewNonFallbackICInformation(AutoStructuredSpewer& spew,
         *entryHappiness = stubHappiness;
       }
 
-      spewShapeInformation(spew, stub);
+      spewShapeInformation(spew, cx, stub);
 
       ICStub* nextStub = stub->toCacheIRStub()->next();
       if (!nextStub->isFallback()) {
@@ -225,7 +257,7 @@ bool CacheIRHealth::spewNonFallbackICInformation(AutoStructuredSpewer& spew,
   return true;
 }
 
-bool CacheIRHealth::spewICEntryHealth(AutoStructuredSpewer& spew,
+bool CacheIRHealth::spewICEntryHealth(AutoStructuredSpewer& spew, JSContext* cx,
                                       HandleScript script, ICEntry* entry,
                                       ICFallbackStub* fallback, jsbytecode* pc,
                                       JSOp op, Happiness* entryHappiness) {
@@ -239,7 +271,7 @@ bool CacheIRHealth::spewICEntryHealth(AutoStructuredSpewer& spew,
 
   ICStub* firstStub = entry->firstStub();
   if (!firstStub->isFallback()) {
-    if (!spewNonFallbackICInformation(spew, firstStub, entryHappiness)) {
+    if (!spewNonFallbackICInformation(spew, cx, firstStub, entryHappiness)) {
       return false;
     }
   }
@@ -321,7 +353,7 @@ void CacheIRHealth::healthReportForIC(JSContext* cx, ICEntry* entry,
   JSOp jsOp = JSOp(*op);
 
   Happiness entryHappiness = Happy;
-  if (!spewICEntryHealth(spew, script, entry, fallback, op, jsOp,
+  if (!spewICEntryHealth(spew, cx, script, entry, fallback, op, jsOp,
                          &entryHappiness)) {
     cx->recoverFromOutOfMemory();
     return;
@@ -360,7 +392,7 @@ void CacheIRHealth::healthReportForScript(JSContext* cx, HandleScript script,
 
     spew->beginObject();
     Happiness entryHappiness = Happy;
-    if (!spewICEntryHealth(spew, script, &entry, fallback, pc, op,
+    if (!spewICEntryHealth(spew, cx, script, &entry, fallback, pc, op,
                            &entryHappiness)) {
       cx->recoverFromOutOfMemory();
       return;
diff --git a/js/src/jit/CacheIRHealth.h b/js/src/jit/CacheIRHealth.h
index 6fa0425d8ec66..471720f9fa7d8 100644
--- a/js/src/jit/CacheIRHealth.h
+++ b/js/src/jit/CacheIRHealth.h
@@ -64,15 +64,20 @@ class CacheIRHealth {
   Happiness spewStubHealth(AutoStructuredSpewer& spew, ICCacheIRStub* stub);
   // If there is more than just a fallback stub in an IC Entry, then additional
   // information about the IC entry.
-  bool spewNonFallbackICInformation(AutoStructuredSpewer& spew,
+  bool spewNonFallbackICInformation(AutoStructuredSpewer& spew, JSContext* cx,
                                     ICStub* firstStub,
                                     Happiness* entryHappiness);
   // Health of all the stubs in an individual CacheIR Entry.
-  bool spewICEntryHealth(AutoStructuredSpewer& spew, HandleScript script,
-                         ICEntry* entry, ICFallbackStub* fallback,
-                         jsbytecode* pc, JSOp op, Happiness* entryHappiness);
-  // Spews information about shapes in an ICStub.
-  void spewShapeInformation(AutoStructuredSpewer& spew, ICStub* stub);
+  bool spewICEntryHealth(AutoStructuredSpewer& spew, JSContext* cx,
+                         HandleScript script, ICEntry* entry,
+                         ICFallbackStub* fallback, jsbytecode* pc, JSOp op,
+                         Happiness* entryHappiness);
+  // Spews first and last property name for each shape checked by
+  // GuardShape in the stub.
+  void spewShapeInformation(AutoStructuredSpewer& spew, JSContext* cx,
+                            ICStub* stub);
+  // Returns the BaseScript of a Shape if available.
+  BaseScript* maybeExtractBaseScript(JSContext* cx, Shape* shape);
 
  public:
   // Spews the final hit count for scripts where we care about its final hit