Backed out 2 changesets (bug 1533755) build bustage. CLOSED TREE
authorDorel Luca <dluca@mozilla.com>
Mon, 11 Mar 2019 22:23:28 +0200
changeset 521425 638b7cfb8639
parent 521424 d5eff5c34ce9
child 521426 c4ecd45d3d5a
push id10866
push usernerli@mozilla.com
push dateTue, 12 Mar 2019 18:59:09 +0000
treeherdermozilla-beta@445c24a51727 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1533755
milestone67.0a1
backs outd5eff5c34ce9
35825a8005ab
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
Backed out 2 changesets (bug 1533755) build bustage. CLOSED TREE Backed out changeset d5eff5c34ce9 (bug 1533755) Backed out changeset 35825a8005ab (bug 1533755)
js/src/vm/JSScript.cpp
js/src/vm/JSScript.h
--- a/js/src/vm/JSScript.cpp
+++ b/js/src/vm/JSScript.cpp
@@ -613,17 +613,18 @@ 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, data, scriptEnclosingScope, fun, i, &scope));
+      MOZ_TRY(
+          XDRScope(xdr, script->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));
@@ -635,17 +636,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, data, sourceObject, &inner));
+      MOZ_TRY(XDRInnerObject(xdr, script->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.
@@ -2903,27 +2904,50 @@ SharedScriptData* js::SharedScriptData::
   // Sanity check the dataLength() computation
   MOZ_ASSERT(entry->dataLength() == dataLength);
 
   return entry;
 }
 
 inline js::ScriptBytecodeHasher::Lookup::Lookup(SharedScriptData* data)
     : scriptData(data),
-      hash(mozilla::HashBytes(scriptData->data(), scriptData->dataLength())) {}
+      hash(mozilla::HashBytes(scriptData->data(), scriptData->dataLength())) {
+  scriptData->incRefCount();
+}
+
+inline js::ScriptBytecodeHasher::Lookup::~Lookup() {
+  scriptData->decRefCount();
+}
 
 bool JSScript::createSharedScriptData(JSContext* cx, uint32_t codeLength,
                                       uint32_t noteLength, uint32_t natoms) {
+  MOZ_ASSERT(!scriptData());
+  SharedScriptData* ssd =
+      SharedScriptData::new_(cx, codeLength, noteLength, natoms);
+  if (!ssd) {
+    return false;
+  }
+
+  setScriptData(ssd);
+  return true;
+}
+
+void JSScript::freeScriptData() {
+  if (scriptData_) {
+    scriptData_->decRefCount();
+    scriptData_ = nullptr;
+  }
+}
+
+void JSScript::setScriptData(js::SharedScriptData* data) {
   MOZ_ASSERT(!scriptData_);
-  scriptData_ = SharedScriptData::new_(cx, codeLength, noteLength, natoms);
-  return !!scriptData_;
+  scriptData_ = data;
+  scriptData_->incRefCount();
 }
 
-void JSScript::freeScriptData() { scriptData_ = nullptr; }
-
 /*
  * Takes ownership of its *ssd parameter and either adds it into the runtime's
  * ScriptDataTable or frees it if a matching entry already exists.
  *
  * Sets the |code| and |atoms| fields on the given JSScript.
  */
 bool JSScript::shareScriptData(JSContext* cx) {
   SharedScriptData* ssd = scriptData();
@@ -2934,44 +2958,44 @@ bool JSScript::shareScriptData(JSContext
   // counted, it also will be freed after releasing the lock if necessary.
   ScriptBytecodeHasher::Lookup lookup(ssd);
 
   AutoLockScriptData lock(cx->runtime());
 
   ScriptDataTable::AddPtr p = cx->scriptDataTable(lock).lookupForAdd(lookup);
   if (p) {
     MOZ_ASSERT(ssd != *p);
-    scriptData_ = *p;
+    freeScriptData();
+    setScriptData(*p);
   } else {
     if (!cx->scriptDataTable(lock).add(p, ssd)) {
+      freeScriptData();
       ReportOutOfMemory(cx);
       return false;
     }
 
     // Being in the table counts as a reference on the script data.
-    ssd->AddRef();
-  }
-
-  // Refs: JSScript, Lookup, ScriptDataTable
-  MOZ_ASSERT(scriptData()->refCount() >= 3);
-
+    scriptData()->incRefCount();
+  }
+
+  MOZ_ASSERT(scriptData()->refCount() >= 2);
   return true;
 }
 
 void js::SweepScriptData(JSRuntime* rt) {
   // Entries are removed from the table when their reference count is one,
   // i.e. when the only reference to them is from the table entry.
 
   AutoLockScriptData lock(rt);
   ScriptDataTable& table = rt->scriptDataTable(lock);
 
   for (ScriptDataTable::Enum e(table); !e.empty(); e.popFront()) {
     SharedScriptData* scriptData = e.front();
     if (scriptData->refCount() == 1) {
-      scriptData->Release();
+      scriptData->decRefCount();
       e.removeFront();
     }
   }
 }
 
 void js::FreeScriptData(JSRuntime* rt) {
   AutoLockScriptData lock(rt);
 
@@ -3233,17 +3257,17 @@ PrivateScriptData* PrivateScriptData::ne
   }
   if (nresumeoffsets) {
     bce->resumeOffsetList.finish(data->resumeOffsets());
   }
 
   return true;
 }
 
-void PrivateScriptData::trace(JSTracer* trc) {
+void PrivateScriptData::traceChildren(JSTracer* trc) {
   auto scopearray = scopes();
   TraceRange(trc, scopearray.size(), scopearray.data(), "scopes");
 
   if (hasConsts()) {
     auto constarray = consts();
     TraceRange(trc, constarray.size(), constarray.data(), "consts");
   }
 
@@ -3712,17 +3736,19 @@ void JSScript::finalize(FreeOp* fop) {
   }
 #endif
 
   if (data_) {
     AlwaysPoison(data_, 0xdb, computedSizeOfData(), MemCheckKind::MakeNoAccess);
     fop->free_(data_);
   }
 
-  freeScriptData();
+  if (scriptData_) {
+    scriptData_->decRefCount();
+  }
 
   // In most cases, our LazyScript's script pointer will reference this
   // script, and thus be nulled out by normal weakref processing. However, if
   // we unlazified the LazyScript during incremental sweeping, it will have a
   // completely different JSScript.
   MOZ_ASSERT_IF(
       lazyScript && !IsAboutToBeFinalizedUnbarriered(&lazyScript),
       !lazyScript->hasScript() || lazyScript->maybeScriptUnbarriered() != this);
@@ -4213,17 +4239,17 @@ JSScript* js::detail::CopyScript(JSConte
     return nullptr;
   }
 
   // The SharedScriptData can be reused by any zone in the Runtime as long as
   // we make sure to mark first (to sync Atom pointers).
   if (cx->zone() != src->zoneFromAnyThread()) {
     src->scriptData()->markForCrossZone(cx);
   }
-  dst->scriptData_ = src->scriptData();
+  dst->setScriptData(src->scriptData());
 
   return dst;
 }
 
 JSScript* js::CloneGlobalScript(JSContext* cx, ScopeKind scopeKind,
                                 HandleScript src) {
   MOZ_ASSERT(scopeKind == ScopeKind::Global ||
              scopeKind == ScopeKind::NonSyntactic);
@@ -4526,17 +4552,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_->trace(trc);
+    data_->traceChildren(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
@@ -9,17 +9,16 @@
 #ifndef vm_JSScript_h
 #define vm_JSScript_h
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Atomics.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/MaybeOneOf.h"
 #include "mozilla/MemoryReporting.h"
-#include "mozilla/RefPtr.h"
 #include "mozilla/Span.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/Utf8.h"
 #include "mozilla/Variant.h"
 
 #include <type_traits>  // std::is_same
 #include <utility>      // std::move
 
@@ -1351,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 = 0;
+  uint32_t nscopes;
 
   // 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);
   }
@@ -1393,20 +1392,16 @@ class alignas(JS::Value) PrivateScriptDa
                                uint32_t nobjects, uint32_t ntrynotes,
                                uint32_t nscopenotes, uint32_t nresumeoffsets);
 
   // Initialize header and PackedSpans
   PrivateScriptData(uint32_t nscopes_, uint32_t nconsts, uint32_t nobjects,
                     uint32_t ntrynotes, uint32_t nscopenotes,
                     uint32_t nresumeoffsets);
 
-  // PrivateScriptData has trailing data so isn't copyable or movable.
-  PrivateScriptData(const PrivateScriptData&) = delete;
-  PrivateScriptData& operator=(const PrivateScriptData&) = delete;
-
  public:
   // Accessors for typed array spans.
   mozilla::Span<GCPtrScope> scopes() {
     GCPtrScope* base =
         packedOffsetToPointer<GCPtrScope>(packedOffsets.scopesOffset);
     return mozilla::MakeSpan(base, nscopes);
   }
   mozilla::Span<GCPtrValue> consts() {
@@ -1450,17 +1445,17 @@ 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 trace(JSTracer* trc);
+  void traceChildren(JSTracer* trc);
 };
 
 /*
  * 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
@@ -1474,18 +1469,18 @@ class SharedScriptData {
   uint32_t noteLength_;
   uintptr_t data_[1];
 
  public:
   static SharedScriptData* new_(JSContext* cx, uint32_t codeLength,
                                 uint32_t srcnotesLength, uint32_t natoms);
 
   uint32_t refCount() const { return refCount_; }
-  void AddRef() { refCount_++; }
-  void Release() {
+  void incRefCount() { refCount_++; }
+  void decRefCount() {
     MOZ_ASSERT(refCount_ != 0);
     uint32_t remain = --refCount_;
     if (remain == 0) {
       js_free(this);
     }
   }
 
   size_t dataLength() const {
@@ -1539,21 +1534,22 @@ class SharedScriptData {
   SharedScriptData(const SharedScriptData&) = delete;
   SharedScriptData& operator=(const SharedScriptData&) = delete;
 };
 
 struct ScriptBytecodeHasher {
   class Lookup {
     friend struct ScriptBytecodeHasher;
 
-    RefPtr<SharedScriptData> scriptData;
+    SharedScriptData* scriptData;
     HashNumber hash;
 
    public:
     explicit Lookup(SharedScriptData* data);
+    ~Lookup();
   };
 
   static HashNumber hash(const Lookup& l) { return l.hash; }
   static bool match(SharedScriptData* entry, const Lookup& lookup) {
     const SharedScriptData* data = lookup.scriptData;
     if (entry->natoms() != data->natoms()) {
       return false;
     }
@@ -1574,36 +1570,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 JS::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;
 
   // Shareable script data
-  RefPtr<js::SharedScriptData> scriptData_ = {};
+  js::SharedScriptData* scriptData_ = nullptr;
 
   // Unshared variable-length data
   js::PrivateScriptData* data_ = nullptr;
 
  public:
   JS::Realm* realm_ = nullptr;
 
  private:
@@ -2532,16 +2518,17 @@ class JSScript : public js::gc::TenuredC
 
  private:
   bool makeTypes(JSContext* cx);
 
   bool createSharedScriptData(JSContext* cx, uint32_t codeLength,
                               uint32_t noteLength, uint32_t natoms);
   bool shareScriptData(JSContext* cx);
   void freeScriptData();
+  void setScriptData(js::SharedScriptData* data);
 
  public:
   uint32_t getWarmUpCount() const { return warmUpCount; }
   uint32_t incWarmUpCounter(uint32_t amount = 1) {
     return warmUpCount += amount;
   }
   uint32_t* addressOfWarmUpCounter() {
     return reinterpret_cast<uint32_t*>(&warmUpCount);