Bug 1533755 - Cleanups in PrivateScriptData. r=jandem
authorTed Campbell <tcampbell@mozilla.com>
Tue, 12 Mar 2019 02:38:51 +0000
changeset 521520 53c759ed45e4
parent 521519 c1e7e2cb32cd
child 521521 65c88218fbb2
push id10867
push userdvarga@mozilla.com
push dateThu, 14 Mar 2019 15:20:45 +0000
treeherdermozilla-beta@abad13547875 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1533755
milestone67.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 1533755 - Cleanups in PrivateScriptData. r=jandem Also add a GCManagedDeletePolicy so that the script data can be dropped even when we are not sweeping. Differential Revision: https://phabricator.services.mozilla.com/D22715
js/src/vm/JSScript.cpp
js/src/vm/JSScript.h
--- a/js/src/vm/JSScript.cpp
+++ b/js/src/vm/JSScript.cpp
@@ -613,18 +613,17 @@ XDRResult js::PrivateScriptData::XDR(XDR
   {
     MOZ_ASSERT(nscopes > 0);
     GCPtrScope* vector = data->scopes().data();
     for (uint32_t i = 0; i < nscopes; ++i) {
       RootedScope scope(cx);
       if (mode == XDR_ENCODE) {
         scope = vector[i];
       }
-      MOZ_TRY(
-          XDRScope(xdr, script->data_, scriptEnclosingScope, fun, i, &scope));
+      MOZ_TRY(XDRScope(xdr, data, scriptEnclosingScope, fun, i, &scope));
       if (mode == XDR_DECODE) {
         vector[i].init(scope);
       }
     }
 
     // Verify marker to detect data corruption after decoding scope data. A
     // mismatch here indicates we will almost certainly crash in release.
     MOZ_TRY(xdr->codeMarker(0x48922BAB));
@@ -636,17 +635,17 @@ XDRResult js::PrivateScriptData::XDR(XDR
    * after the enclosing block has been XDR'd.
    */
   if (nobjects) {
     for (GCPtrObject& elem : data->objects()) {
       RootedObject inner(cx);
       if (mode == XDR_ENCODE) {
         inner = elem;
       }
-      MOZ_TRY(XDRInnerObject(xdr, script->data_, sourceObject, &inner));
+      MOZ_TRY(XDRInnerObject(xdr, data, sourceObject, &inner));
       if (mode == XDR_DECODE) {
         elem.init(inner);
       }
     }
   }
 
   // Verify marker to detect data corruption after decoding object data. A
   // mismatch here indicates we will almost certainly crash in release.
@@ -3257,17 +3256,17 @@ PrivateScriptData* PrivateScriptData::ne
   }
   if (nresumeoffsets) {
     bce->resumeOffsetList.finish(data->resumeOffsets());
   }
 
   return true;
 }
 
-void PrivateScriptData::traceChildren(JSTracer* trc) {
+void PrivateScriptData::trace(JSTracer* trc) {
   auto scopearray = scopes();
   TraceRange(trc, scopearray.size(), scopearray.data(), "scopes");
 
   if (hasConsts()) {
     auto constarray = consts();
     TraceRange(trc, constarray.size(), constarray.data(), "consts");
   }
 
@@ -4552,17 +4551,17 @@ void JSScript::traceChildren(JSTracer* t
   // JSScript::Create(), but not yet finished initializing it with
   // fullyInitFromEmitter() or fullyInitTrivial().
 
   MOZ_ASSERT_IF(trc->isMarkingTracer() &&
                     GCMarker::fromTracer(trc)->shouldCheckCompartments(),
                 zone()->isCollecting());
 
   if (data_) {
-    data_->traceChildren(trc);
+    data_->trace(trc);
   }
 
   if (scriptData()) {
     scriptData()->traceChildren(trc);
   }
 
   MOZ_ASSERT_IF(sourceObject(),
                 MaybeForwarded(sourceObject())->compartment() == compartment());
--- a/js/src/vm/JSScript.h
+++ b/js/src/vm/JSScript.h
@@ -1350,17 +1350,17 @@ class alignas(JS::Value) PrivateScriptDa
   // the private data.
   struct alignas(uintptr_t) PackedSpan {
     uint32_t offset;
     uint32_t length;
   };
 
   // Concrete Fields
   PackedOffsets packedOffsets = {};  // zeroes
-  uint32_t nscopes;
+  uint32_t nscopes = 0;
 
   // Translate an offset into a concrete pointer.
   template <typename T>
   T* offsetToPointer(size_t offset) {
     uintptr_t base = reinterpret_cast<uintptr_t>(this);
     uintptr_t elem = base + offset;
     return reinterpret_cast<T*>(elem);
   }
@@ -1445,17 +1445,21 @@ class alignas(JS::Value) PrivateScriptDa
 
   // Clone src script data into dst script.
   static bool Clone(JSContext* cx, js::HandleScript src, js::HandleScript dst,
                     js::MutableHandle<JS::GCVector<js::Scope*>> scopes);
 
   static bool InitFromEmitter(JSContext* cx, js::HandleScript script,
                               js::frontend::BytecodeEmitter* bce);
 
-  void traceChildren(JSTracer* trc);
+  void trace(JSTracer* trc);
+
+  // PrivateScriptData has trailing data so isn't copyable or movable.
+  PrivateScriptData(const PrivateScriptData&) = delete;
+  PrivateScriptData& operator=(const PrivateScriptData&) = delete;
 };
 
 /*
  * Common data that can be shared between many scripts in a single runtime.
  */
 class SharedScriptData {
   // This class is reference counted as follows: each pointer from a JSScript
   // counts as one reference plus there may be one reference from the shared
@@ -1570,16 +1574,26 @@ using ScriptDataTable =
     HashSet<SharedScriptData*, ScriptBytecodeHasher, SystemAllocPolicy>;
 
 extern void SweepScriptData(JSRuntime* rt);
 
 extern void FreeScriptData(JSRuntime* rt);
 
 } /* namespace js */
 
+namespace JS {
+
+// Define a GCManagedDeletePolicy to allow deleting type outside of normal
+// sweeping.
+template <>
+struct DeletePolicy<js::PrivateScriptData>
+    : public js::GCManagedDeletePolicy<js::PrivateScriptData> {};
+
+} /* namespace JS */
+
 class JSScript : public js::gc::TenuredCell {
  private:
   // Pointer to baseline->method()->raw(), ion->method()->raw(), a wasm jit
   // entry, the JIT's EnterInterpreter stub, or the lazy link stub. Must be
   // non-null.
   uint8_t* jitCodeRaw_ = nullptr;
   uint8_t* jitCodeSkipArgCheck_ = nullptr;