Bug 1556137 - Fix a memory leak by allocating memory statically r=sfink a=test-only
authorPaul Bone <pbone@mozilla.com>
Thu, 06 Jun 2019 01:41:47 +0000
changeset 536769 4b1e3622e260cbfc17e8347e8bcce1f528ae558b
parent 536768 230b796e687537a42e81776ccbcb62f93e91609a
child 536770 d92988e2d2b616d7948bb86a49f6f31e1c93d7cf
push id2082
push userffxbld-merge
push dateMon, 01 Jul 2019 08:34:18 +0000
treeherdermozilla-release@2fb19d0466d2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink, test-only
bugs1556137
milestone68.0
Bug 1556137 - Fix a memory leak by allocating memory statically r=sfink a=test-only Differential Revision: https://phabricator.services.mozilla.com/D33596
js/src/builtin/TestingFunctions.cpp
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -4305,20 +4305,19 @@ static void minorGC(JSContext* cx, JSGCS
     info->active = false;
     if (cx->zone() && !cx->zone()->isAtomsZone()) {
       cx->runtime()->gc.evictNursery(JS::GCReason::DEBUG_GC);
     }
     info->active = true;
   }
 }
 
-// Process global, should really be runtime-local. Also, the final one of these
-// is currently leaked, since they are only deleted when changing.
-MajorGC* prevMajorGC = nullptr;
-MinorGC* prevMinorGC = nullptr;
+// Process global, should really be runtime-local.
+static MajorGC majorGCInfo;
+static MinorGC minorGCInfo;
 
 } /* namespace gcCallback */
 
 static bool SetGCCallback(JSContext* cx, unsigned argc, Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
 
   if (args.length() != 1) {
     JS_ReportErrorASCII(cx, "Wrong number of arguments");
@@ -4370,38 +4369,20 @@ static bool SetGCCallback(JSContext* cx,
         phases = (1 << JSGC_BEGIN) | (1 << JSGC_END);
       } else {
         JS_ReportErrorASCII(cx, "Invalid callback phase");
         return false;
       }
     }
   }
 
-  if (gcCallback::prevMajorGC) {
-    JS_SetGCCallback(cx, nullptr, nullptr);
-    js_delete<gcCallback::MajorGC>(gcCallback::prevMajorGC);
-    gcCallback::prevMajorGC = nullptr;
-  }
-
-  if (gcCallback::prevMinorGC) {
-    JS_SetGCCallback(cx, nullptr, nullptr);
-    js_delete<gcCallback::MinorGC>(gcCallback::prevMinorGC);
-    gcCallback::prevMinorGC = nullptr;
-  }
-
   if (StringEqualsAscii(action, "minorGC")) {
-    auto info = js_new<gcCallback::MinorGC>();
-    if (!info) {
-      ReportOutOfMemory(cx);
-      return false;
-    }
-
-    info->phases = phases;
-    info->active = true;
-    JS_SetGCCallback(cx, gcCallback::minorGC, info);
+    gcCallback::minorGCInfo.phases = phases;
+    gcCallback::minorGCInfo.active = true;
+    JS_SetGCCallback(cx, gcCallback::minorGC, &gcCallback::minorGCInfo);
   } else if (StringEqualsAscii(action, "majorGC")) {
     if (!JS_GetProperty(cx, opts, "depth", &v)) {
       return false;
     }
     int32_t depth = 1;
     if (!v.isUndefined()) {
       if (!ToInt32(cx, v, &depth)) {
         return false;
@@ -4412,25 +4393,19 @@ static bool SetGCCallback(JSContext* cx,
       return false;
     }
     if (depth + gcstats::MAX_PHASE_NESTING >
         gcstats::Statistics::MAX_SUSPENDED_PHASES) {
       JS_ReportErrorASCII(cx, "Nesting depth too large, would overflow");
       return false;
     }
 
-    auto info = js_new<gcCallback::MajorGC>();
-    if (!info) {
-      ReportOutOfMemory(cx);
-      return false;
-    }
-
-    info->phases = phases;
-    info->depth = depth;
-    JS_SetGCCallback(cx, gcCallback::majorGC, info);
+    gcCallback::majorGCInfo.phases = phases;
+    gcCallback::majorGCInfo.depth = depth;
+    JS_SetGCCallback(cx, gcCallback::majorGC, &gcCallback::majorGCInfo);
   } else {
     JS_ReportErrorASCII(cx, "Unknown GC callback action");
     return false;
   }
 
   args.rval().setUndefined();
   return true;
 }