Bug 1568740 - (part 6) Remove Nursery::chunkCountLimit() r=jonco
authorPaul Bone <pbone@mozilla.com>
Mon, 02 Sep 2019 23:27:42 +0000
changeset 491238 e7596cc4156278362096cc2db562feea274308f1
parent 491237 e31e7762b04b58f3d0ebd0ba6e60be638bae51de
child 491239 de7e00f6cc24f97fd55944cb30dbc6f72bce1455
push id36524
push userdluca@mozilla.com
push dateTue, 03 Sep 2019 04:03:24 +0000
treeherdermozilla-central@1d2a2360d4df [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs1568740
milestone71.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 1568740 - (part 6) Remove Nursery::chunkCountLimit() r=jonco This method & the chunkCountLimit_ variable are unnecessary. The maximum permitted nursery size is tracked in the GCSchedulingTunables class. Differential Revision: https://phabricator.services.mozilla.com/D39285
js/src/gc/GC.cpp
js/src/gc/Nursery.cpp
js/src/gc/Nursery.h
--- a/js/src/gc/GC.cpp
+++ b/js/src/gc/GC.cpp
@@ -1209,17 +1209,17 @@ bool GCRuntime::init(uint32_t maxbytes, 
     MOZ_ALWAYS_TRUE(
         tunables.setParameter(JSGC_MAX_NURSERY_BYTES, maxNurseryBytes, lock));
 
     const char* size = getenv("JSGC_MARK_STACK_LIMIT");
     if (size) {
       setMarkStackLimit(atoi(size), lock);
     }
 
-    if (!nursery().init(maxNurseryBytes, lock)) {
+    if (!nursery().init(lock)) {
       return false;
     }
 
     const char* pretenureThresholdStr = getenv("JSGC_PRETENURE_THRESHOLD");
     if (pretenureThresholdStr && pretenureThresholdStr[0]) {
       char* last;
       long pretenureThreshold = strtol(pretenureThresholdStr, &last, 10);
       if (last[0] || !tunables.setParameter(JSGC_PRETENURE_THRESHOLD,
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -213,17 +213,16 @@ js::Nursery::Nursery(JSRuntime* rt)
     : runtime_(rt),
       position_(0),
       currentStartChunk_(0),
       currentStartPosition_(0),
       currentEnd_(0),
       currentStringEnd_(0),
       currentChunk_(0),
       capacity_(0),
-      chunkCountLimit_(0),
       timeInChunkAlloc_(0),
       profileThreshold_(0),
       enableProfiling_(false),
       canAllocateStrings_(true),
       reportTenurings_(0),
       minorGCTriggerReason_(JS::GCReason::NO_REASON),
       decommitTask(rt)
 #ifdef JS_GC_ZEAL
@@ -232,36 +231,29 @@ js::Nursery::Nursery(JSRuntime* rt)
 #endif
 {
   const char* env = getenv("MOZ_NURSERY_STRINGS");
   if (env && *env) {
     canAllocateStrings_ = (*env == '1');
   }
 }
 
-bool js::Nursery::init(uint32_t maxNurseryBytes, AutoLockGCBgAlloc& lock) {
+bool js::Nursery::init(AutoLockGCBgAlloc& lock) {
   // The nursery is permanently disabled when recording or replaying. Nursery
   // collections may occur at non-deterministic points in execution.
   if (mozilla::recordreplay::IsRecordingOrReplaying()) {
-    maxNurseryBytes = 0;
-  }
-
-  // maxNurseryBytes parameter is rounded down to a multiple of chunk size.
-  chunkCountLimit_ = maxNurseryBytes >> ChunkShift;
-
-  // If no chunks are specified then the nursery is permanently disabled.
-  if (chunkCountLimit_ == 0) {
     return true;
   }
 
+  capacity_ = roundSize(tunables().gcMinNurseryBytes());
+  MOZ_ASSERT(capacity_ >= ArenaSize);
   if (!allocateNextChunk(0, lock)) {
+    capacity_ = 0;
     return false;
   }
-  capacity_ = roundSize(tunables().gcMinNurseryBytes());
-  MOZ_ASSERT(capacity_ >= ArenaSize);
   // After this point the Nursery has been enabled.
 
   setCurrentChunk(0);
   setStartPosition();
   poisonAndInitCurrentChunk();
 
   char* env = getenv("JS_GC_PROFILE_NURSERY");
   if (env) {
@@ -295,26 +287,27 @@ bool js::Nursery::init(uint32_t maxNurse
   return true;
 }
 
 js::Nursery::~Nursery() { disable(); }
 
 void js::Nursery::enable() {
   MOZ_ASSERT(isEmpty());
   MOZ_ASSERT(!runtime()->gc.isVerifyPreBarriersEnabled());
-  if (isEnabled() || !chunkCountLimit()) {
+  if (isEnabled() || mozilla::recordreplay::IsRecordingOrReplaying()) {
     return;
   }
 
   {
     AutoLockGCBgAlloc lock(runtime());
+    capacity_ = roundSize(tunables().gcMinNurseryBytes());
     if (!allocateNextChunk(0, lock)) {
+      capacity_ = 0;
       return;
     }
-    capacity_ = roundSize(tunables().gcMinNurseryBytes());
     MOZ_ASSERT(capacity_ >= ArenaSize);
   }
 
   setCurrentChunk(0);
   setStartPosition();
   poisonAndInitCurrentChunk();
 #ifdef JS_GC_ZEAL
   if (runtime()->hasZealMode(ZealMode::GenerationalGC)) {
@@ -387,17 +380,17 @@ void js::Nursery::enterZealMode() {
       }
 
       // It'd be simpler to poison the whole chunk, but we can't do that
       // because the nursery might be partially used.
       chunk(0).poisonRange(capacity_, NurseryChunkUsableSize - capacity_,
                            JS_FRESH_NURSERY_PATTERN,
                            MemCheckKind::MakeUndefined);
     }
-    capacity_ = chunkCountLimit() * ChunkSize;
+    capacity_ = JS_ROUNDUP(tunables().gcMaxNurseryBytes(), ChunkSize);
     setCurrentEnd();
   }
 }
 
 void js::Nursery::leaveZealMode() {
   if (isEnabled()) {
     MOZ_ASSERT(isEmpty());
     setCurrentChunk(0);
@@ -480,17 +473,16 @@ void* js::Nursery::allocate(size_t size)
       (sizeof(Nursery::Canary) + CellAlignBytes - 1) & ~CellAlignMask;
   if (runtime()->gc.hasZealMode(ZealMode::CheckNursery)) {
     size += CanarySize;
   }
 #endif
 
   if (currentEnd() < position() + size) {
     unsigned chunkno = currentChunk_ + 1;
-    MOZ_ASSERT(chunkno <= chunkCountLimit());
     MOZ_ASSERT(chunkno <= maxChunkCount());
     MOZ_ASSERT(chunkno <= allocatedChunkCount());
     if (chunkno == maxChunkCount()) {
       return nullptr;
     }
     if (MOZ_UNLIKELY(chunkno == allocatedChunkCount())) {
       mozilla::TimeStamp start = ReallyNow();
       {
@@ -1296,17 +1288,16 @@ size_t js::Nursery::spaceToEnd(unsigned 
   }
 
   MOZ_ASSERT(bytes <= maxChunkCount() * ChunkSize);
 
   return bytes;
 }
 
 MOZ_ALWAYS_INLINE void js::Nursery::setCurrentChunk(unsigned chunkno) {
-  MOZ_ASSERT(chunkno < chunkCountLimit());
   MOZ_ASSERT(chunkno < allocatedChunkCount());
 
   currentChunk_ = chunkno;
   position_ = chunk(chunkno).start();
   setCurrentEnd();
 }
 
 void js::Nursery::poisonAndInitCurrentChunk(size_t extent) {
@@ -1332,17 +1323,17 @@ MOZ_ALWAYS_INLINE void js::Nursery::setC
 bool js::Nursery::allocateNextChunk(const unsigned chunkno,
                                     AutoLockGCBgAlloc& lock) {
   const unsigned priorCount = allocatedChunkCount();
   const unsigned newCount = priorCount + 1;
 
   MOZ_ASSERT((chunkno == currentChunk_ + 1) ||
              (chunkno == 0 && allocatedChunkCount() == 0));
   MOZ_ASSERT(chunkno == allocatedChunkCount());
-  MOZ_ASSERT(chunkno < chunkCountLimit());
+  MOZ_ASSERT(chunkno < JS_HOWMANY(capacity(), ChunkSize));
 
   if (!chunks_.resize(newCount)) {
     return false;
   }
 
   Chunk* newChunk;
   newChunk = runtime()->gc.getOrAllocChunk(lock);
   if (!newChunk) {
@@ -1457,17 +1448,17 @@ size_t js::Nursery::roundSize(size_t siz
     size = Min(JS_ROUND(size, SubChunkStep),
                JS_ROUNDDOWN(NurseryChunkUsableSize, SubChunkStep));
   }
   return size;
 }
 
 void js::Nursery::growAllocableSpace(size_t newCapacity) {
   MOZ_ASSERT_IF(!isSubChunkMode(), newCapacity > currentChunk_ * ChunkSize);
-  MOZ_ASSERT(newCapacity <= chunkCountLimit_ * ChunkSize);
+  MOZ_ASSERT(newCapacity <= roundSize(tunables().gcMaxNurseryBytes()));
   MOZ_ASSERT(newCapacity > capacity());
 
   if (isSubChunkMode()) {
     // Avoid growing into an area that's about to be decommitted.
     decommitTask.join();
 
     MOZ_ASSERT(currentChunk_ == 0);
 
--- a/js/src/gc/Nursery.h
+++ b/js/src/gc/Nursery.h
@@ -178,19 +178,17 @@ class Nursery {
     CellAlignedByte cell;
   };
 
   using BufferSet = HashSet<void*, PointerHasher<void*>, SystemAllocPolicy>;
 
   explicit Nursery(JSRuntime* rt);
   ~Nursery();
 
-  MOZ_MUST_USE bool init(uint32_t maxNurseryBytes, AutoLockGCBgAlloc& lock);
-
-  unsigned chunkCountLimit() const { return chunkCountLimit_; }
+  MOZ_MUST_USE bool init(AutoLockGCBgAlloc& lock);
 
   // Number of allocated (ready to use) chunks.
   unsigned allocatedChunkCount() const { return chunks_.length(); }
 
   // Total number of chunks and the capacity of the nursery. Chunks will be
   // lazilly allocated and added to the chunks array up to this limit, after
   // that the nursery must be collected, this limit may be raised during
   // collection.
@@ -431,20 +429,16 @@ class Nursery {
   unsigned currentChunk_;
 
   // The current nursery capacity measured in bytes. It may grow up to this
   // value without a collection, allocating chunks on demand. This limit may be
   // changed by maybeResizeNursery() each collection. It does not include chunk
   // trailers.
   size_t capacity_;
 
-  // This limit is fixed by configuration. It represents the maximum size
-  // the nursery is permitted to tune itself to in maybeResizeNursery();
-  unsigned chunkCountLimit_;
-
   mozilla::TimeDuration timeInChunkAlloc_;
 
   // Report minor collections taking at least this long, if enabled.
   mozilla::TimeDuration profileThreshold_;
   bool enableProfiling_;
 
   // Whether we will nursery-allocate strings.
   bool canAllocateStrings_;