Bug 1395509 - Add FreeOp methods free memory and update memory accounting r=sfink
authorJon Coppeard <jcoppeard@mozilla.com>
Thu, 09 May 2019 13:19:35 +0100
changeset 532258 95399bf8d949c78b5d7d67019f203fea85fb755e
parent 532257 772b3ec0102d042221de27abe26841a08336f390
child 532259 54227b6122129de93a5348d3ff6300acd04f80ae
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1395509
milestone68.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 1395509 - Add FreeOp methods free memory and update memory accounting r=sfink Differential Revision: https://phabricator.services.mozilla.com/D30515
js/src/gc/FreeOp-inl.h
js/src/gc/FreeOp.h
js/src/vm/JSObject-inl.h
new file mode 100644
--- /dev/null
+++ b/js/src/gc/FreeOp-inl.h
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: set ts=8 sts=2 et sw=2 tw=80:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef gc_FreeOp_inl_h
+#define gc_FreeOp_inl_h
+
+#include "gc/FreeOp.h"
+
+#include "gc/Zone.h"
+
+namespace js {
+
+inline void FreeOp::free_(gc::Cell* cell, void* p, size_t nbytes,
+                          MemoryUse use) {
+  if (p) {
+    RemoveCellMemory(cell, nbytes, use);
+    js_free(p);
+  }
+}
+
+inline void FreeOp::freeLater(gc::Cell* cell, void* p, size_t nbytes,
+                              MemoryUse use) {
+  if (p) {
+    RemoveCellMemory(cell, nbytes, use);
+    freeLater(p);
+  }
+}
+
+inline void FreeOp::freeLater(void* p) {
+  // FreeOps other than the defaultFreeOp() are constructed on the stack,
+  // and won't hold onto the pointers to free indefinitely.
+  MOZ_ASSERT(!isDefaultFreeOp());
+
+  AutoEnterOOMUnsafeRegion oomUnsafe;
+  if (!freeLaterList.append(p)) {
+    oomUnsafe.crash("FreeOp::freeLater");
+  }
+}
+
+} // namespace js
+
+#endif // gc_FreeOp_inl_h
--- a/js/src/gc/FreeOp.h
+++ b/js/src/gc/FreeOp.h
@@ -14,16 +14,18 @@
 #include "js/MemoryFunctions.h"       // JSFreeOp
 #include "js/Utility.h"               // AutoEnterOOMUnsafeRegion, js_free
 #include "js/Vector.h"                // js::Vector
 
 struct JSRuntime;
 
 namespace js {
 
+enum class MemoryUse : uint8_t;
+
 /*
  * A FreeOp can do one thing: free memory. For convenience, it has delete_
  * convenience methods that also call destructors.
  *
  * FreeOp is passed to finalizers and other sweep-phase hooks so that we do not
  * need to pass a JSContext to those hooks.
  */
 class FreeOp : public JSFreeOp {
@@ -44,39 +46,54 @@ class FreeOp : public JSFreeOp {
     // runtime_ being null doesn't always mean we are off thread.
     return !runtime_;
   }
 
   bool isDefaultFreeOp() const { return isDefault; }
 
   void free_(void* p) { js_free(p); }
 
-  void freeLater(void* p) {
-    // FreeOps other than the defaultFreeOp() are constructed on the stack,
-    // and won't hold onto the pointers to free indefinitely.
-    MOZ_ASSERT(!isDefaultFreeOp());
+  // Free memory that was associated with a GC thing using js::AddCellMemory.
+  void free_(gc::Cell* cell, void* p, size_t nbytes, MemoryUse use);
 
-    AutoEnterOOMUnsafeRegion oomUnsafe;
-    if (!freeLaterList.append(p)) {
-      oomUnsafe.crash("FreeOp::freeLater");
-    }
-  }
+  void freeLater(void* p);
+
+  // Free memory that was associated with a GC thing using js::AddCellMemory.
+  void freeLater(gc::Cell* cell, void* p, size_t nbytes, MemoryUse use);
 
   bool appendJitPoisonRange(const jit::JitPoisonRange& range) {
     // FreeOps other than the defaultFreeOp() are constructed on the stack,
     // and won't hold onto the pointers to free indefinitely.
     MOZ_ASSERT(!isDefaultFreeOp());
 
     return jitPoisonRanges.append(range);
   }
 
   template <class T>
   void delete_(T* p) {
     if (p) {
       p->~T();
       free_(p);
     }
   }
+
+  // Delete a C++ object that was associated with a GC thing using
+  // js::AddCellMemory. The size is determined by the type T.
+  template <class T>
+  void delete_(gc::Cell* cell, T* p, MemoryUse use) {
+    delete_(cell, p, sizeof(T), use);
+  }
+
+  // Delete a C++ object that was associated with a GC thing using
+  // js::AddCellMemory. The size of the allocation is passed in to allow for
+  // allocations with trailing data after the object.
+  template <class T>
+  void delete_(gc::Cell* cell, T* p, size_t nbytes, MemoryUse use) {
+    if (p) {
+      p->~T();
+      free_(cell, p, nbytes, use);
+    }
+  }
 };
 
 }  // namespace js
 
 #endif  // gc_FreeOp_h
--- a/js/src/vm/JSObject-inl.h
+++ b/js/src/vm/JSObject-inl.h
@@ -4,22 +4,22 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef vm_JSObject_inl_h
 #define vm_JSObject_inl_h
 
 #include "vm/JSObject.h"
 
-#include "gc/FreeOp.h"
 #include "vm/ArrayObject.h"
 #include "vm/EnvironmentObject.h"
 #include "vm/JSFunction.h"
 #include "vm/Probes.h"
 
+#include "gc/FreeOp-inl.h"
 #include "gc/Marking-inl.h"
 #include "gc/ObjectKind-inl.h"
 #include "vm/ObjectOperations-inl.h"  // js::MaybeHasInterestingSymbolProperty
 #include "vm/Realm-inl.h"
 
 inline void JSObject::finalize(js::FreeOp* fop) {
   js::probes::FinalizeObject(this);