Bug 1485615 - Make RegExpZone a separate allocation to Zone r=sfink
authorJon Coppeard <jcoppeard@mozilla.com>
Thu, 23 Aug 2018 16:58:47 +0100
changeset 433079 c70943a6b070698c59db4802c912a6c682b49ba4
parent 433078 f7d550d783449a155a5681f0db3939bd9ecad58b
child 433080 40001671f508bd5673f365c47cbbdbe6c9cdbdf2
push id34499
push usercsabou@mozilla.com
push dateThu, 23 Aug 2018 21:40:51 +0000
treeherdermozilla-central@49b70f7e6817 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1485615
milestone63.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 1485615 - Make RegExpZone a separate allocation to Zone r=sfink
js/src/builtin/RegExp.cpp
js/src/gc/Marking.cpp
js/src/gc/Zone.cpp
js/src/gc/Zone.h
js/src/proxy/CrossCompartmentWrapper.cpp
js/src/vm/RegExpObject.cpp
js/src/vm/RegExpStatics.cpp
js/src/vm/TypeInference.cpp
--- a/js/src/builtin/RegExp.cpp
+++ b/js/src/builtin/RegExp.cpp
@@ -181,33 +181,33 @@ CheckPatternSyntaxSlow(JSContext* cx, Ha
 }
 
 static RegExpShared*
 CheckPatternSyntax(JSContext* cx, HandleAtom pattern, RegExpFlag flags)
 {
     // If we already have a RegExpShared for this pattern/flags, we can
     // avoid the much slower CheckPatternSyntaxSlow call.
 
-    if (RegExpShared* shared = cx->zone()->regExps.maybeGet(pattern, flags)) {
+    if (RegExpShared* shared = cx->zone()->regExps().maybeGet(pattern, flags)) {
 #ifdef DEBUG
         // Assert the pattern is valid.
         if (!CheckPatternSyntaxSlow(cx, pattern, flags)) {
             MOZ_ASSERT(cx->isThrowingOutOfMemory() || cx->isThrowingOverRecursed());
             return nullptr;
         }
 #endif
         return shared;
     }
 
     if (!CheckPatternSyntaxSlow(cx, pattern, flags))
         return nullptr;
 
     // Allocate and return a new RegExpShared so we will hit the fast path
     // next time.
-    return cx->zone()->regExps.get(cx, pattern, flags);
+    return cx->zone()->regExps().get(cx, pattern, flags);
 }
 
 /*
  * ES 2016 draft Mar 25, 2016 21.2.3.2.2.
  *
  * Steps 14-15 set |obj|'s "lastIndex" property to zero.  Some of
  * RegExpInitialize's callers have a fresh RegExp not yet exposed to script:
  * in these cases zeroing "lastIndex" is infallible.  But others have a RegExp
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -21,17 +21,16 @@
 #include "js/SliceBudget.h"
 #include "vm/ArgumentsObject.h"
 #include "vm/ArrayObject.h"
 #ifdef ENABLE_BIGINT
 #include "vm/BigIntType.h"
 #endif
 #include "vm/Debugger.h"
 #include "vm/EnvironmentObject.h"
-#include "vm/RegExpObject.h"
 #include "vm/RegExpShared.h"
 #include "vm/Scope.h"
 #include "vm/Shape.h"
 #include "vm/SymbolType.h"
 #include "vm/TypedArrayObject.h"
 #include "vm/UnboxedObject.h"
 #include "wasm/WasmJS.h"
 
--- a/js/src/gc/Zone.cpp
+++ b/js/src/gc/Zone.cpp
@@ -38,17 +38,16 @@ JS::Zone::Zone(JSRuntime* rt)
     types(this),
     gcWeakMapList_(this),
     compartments_(),
     gcGrayRoots_(this),
     gcWeakRefs_(this),
     weakCaches_(this),
     gcWeakKeys_(this, SystemAllocPolicy(), rt->randomHashCodeScrambler()),
     typeDescrObjects_(this, this),
-    regExps(this),
     markedAtoms_(this),
     atomCache_(this),
     externalStringCache_(this),
     functionToStringCache_(this),
     keepAtomsCount(this, 0),
     purgeAtomsDeferred(this, 0),
     usage(&rt->gc.usage),
     threshold(),
@@ -92,26 +91,27 @@ Zone::~Zone()
     js_delete(debuggers.ref());
     js_delete(jitZone_.ref());
 
 #ifdef DEBUG
     // Avoid assertions failures warning that not everything has been destroyed
     // if the embedding leaked GC things.
     if (!rt->gc.shutdownCollectedEverything()) {
         gcWeakMapList().clear();
-        regExps.clear();
+        regExps().clear();
     }
 #endif
 }
 
 bool
 Zone::init(bool isSystemArg)
 {
     isSystem = isSystemArg;
-    return gcWeakKeys().init();
+    regExps_.ref() = make_unique<RegExpZone>(this);
+    return regExps_.ref() && gcWeakKeys().init();
 }
 
 void
 Zone::setNeedsIncrementalBarrier(bool needs)
 {
     MOZ_ASSERT_IF(needs, canCollect());
     needsIncrementalBarrier_ = needs;
 }
@@ -352,17 +352,17 @@ Zone::nextZone() const
 {
     MOZ_ASSERT(isOnList());
     return listNext_;
 }
 
 void
 Zone::clearTables()
 {
-    MOZ_ASSERT(regExps.empty());
+    MOZ_ASSERT(regExps().empty());
 
     baseShapes().clear();
     initialShapes().clear();
 }
 
 void
 Zone::fixupAfterMovingGC()
 {
--- a/js/src/gc/Zone.h
+++ b/js/src/gc/Zone.h
@@ -9,22 +9,22 @@
 
 #include "mozilla/Atomics.h"
 #include "mozilla/HashFunctions.h"
 
 #include "gc/FindSCCs.h"
 #include "gc/GCRuntime.h"
 #include "js/GCHashTable.h"
 #include "vm/MallocProvider.h"
-#include "vm/RegExpShared.h"
 #include "vm/Runtime.h"
 
 namespace js {
 
 class Debugger;
+class RegExpZone;
 
 namespace jit {
 class JitZone;
 } // namespace jit
 
 namespace gc {
 
 struct ZoneComponentFinder : public ComponentFinder<JS::Zone, ZoneComponentFinder>
@@ -454,18 +454,20 @@ class Zone : public JS::shadow::Zone,
                                   counter.bytes(), counter.maxBytes()))
         {
             return;
         }
 
         counter.recordTrigger(trigger);
     }
 
+    js::MainThreadData<js::UniquePtr<js::RegExpZone>> regExps_;
+
   public:
-    js::RegExpZone regExps;
+    js::RegExpZone& regExps() { return *regExps_.ref(); }
 
     JS::WeakCache<TypeDescrObjectSet>& typeDescrObjects() { return typeDescrObjects_.ref(); }
 
     bool addTypeDescrObject(JSContext* cx, HandleObject obj);
 
     void setGCMaxMallocBytes(size_t value, const js::AutoLockGC& lock) {
         gcMallocCounter.setMax(value, lock);
     }
--- a/js/src/proxy/CrossCompartmentWrapper.cpp
+++ b/js/src/proxy/CrossCompartmentWrapper.cpp
@@ -452,17 +452,17 @@ CrossCompartmentWrapper::regexp_toShared
         re = Wrapper::regexp_toShared(cx, wrapper);
         if (!re)
             return nullptr;
     }
 
     // Get an equivalent RegExpShared associated with the current compartment.
     RootedAtom source(cx, re->getSource());
     cx->markAtom(source);
-    return cx->zone()->regExps.get(cx, source, re->getFlags());
+    return cx->zone()->regExps().get(cx, source, re->getFlags());
 }
 
 bool
 CrossCompartmentWrapper::boxedValue_unbox(JSContext* cx, HandleObject wrapper, MutableHandleValue vp) const
 {
     PIERCE(cx, wrapper,
            NOTHING,
            Wrapper::boxedValue_unbox(cx, wrapper, vp),
--- a/js/src/vm/RegExpObject.cpp
+++ b/js/src/vm/RegExpObject.cpp
@@ -282,17 +282,17 @@ RegExpObject::create(JSContext* cx, Hand
     return regexp;
 }
 
 /* static */ RegExpShared*
 RegExpObject::createShared(JSContext* cx, Handle<RegExpObject*> regexp)
 {
     MOZ_ASSERT(!regexp->hasShared());
     RootedAtom source(cx, regexp->getSource());
-    RegExpShared* shared = cx->zone()->regExps.get(cx, source, regexp->getFlags());
+    RegExpShared* shared = cx->zone()->regExps().get(cx, source, regexp->getFlags());
     if (!shared)
         return nullptr;
 
     regexp->setShared(*shared);
     return shared;
 }
 
 Shape*
--- a/js/src/vm/RegExpStatics.cpp
+++ b/js/src/vm/RegExpStatics.cpp
@@ -77,17 +77,17 @@ RegExpStatics::executeLazy(JSContext* cx
         return true;
 
     MOZ_ASSERT(lazySource);
     MOZ_ASSERT(matchesInput);
     MOZ_ASSERT(lazyIndex != size_t(-1));
 
     /* Retrieve or create the RegExpShared in this zone. */
     RootedAtom source(cx, lazySource);
-    RootedRegExpShared shared(cx, cx->zone()->regExps.get(cx, source, lazyFlags));
+    RootedRegExpShared shared(cx, cx->zone()->regExps().get(cx, source, lazyFlags));
     if (!shared)
         return false;
 
     /*
      * It is not necessary to call aboutToWrite(): evaluation of
      * implicit copies is safe.
      */
 
--- a/js/src/vm/TypeInference.cpp
+++ b/js/src/vm/TypeInference.cpp
@@ -4627,17 +4627,17 @@ Zone::addSizeOfIncludingThis(mozilla::Ma
                              size_t* uniqueIdMap,
                              size_t* shapeTables,
                              size_t* atomsMarkBitmaps,
                              size_t* compartmentObjects,
                              size_t* crossCompartmentWrappersTables,
                              size_t* compartmentsPrivateData)
 {
     *typePool += types.typeLifoAlloc().sizeOfExcludingThis(mallocSizeOf);
-    *regexpZone += regExps.sizeOfExcludingThis(mallocSizeOf);
+    *regexpZone += regExps().sizeOfExcludingThis(mallocSizeOf);
     if (jitZone_)
         jitZone_->addSizeOfIncludingThis(mallocSizeOf, jitZone, baselineStubsOptimized, cachedCFG);
     *uniqueIdMap += uniqueIds().shallowSizeOfExcludingThis(mallocSizeOf);
     *shapeTables += baseShapes().sizeOfExcludingThis(mallocSizeOf)
                   + initialShapes().sizeOfExcludingThis(mallocSizeOf);
     *atomsMarkBitmaps += markedAtoms().sizeOfExcludingThis(mallocSizeOf);
 
     for (CompartmentsInZoneIter comp(this); !comp.done(); comp.next()) {