Bug 1298018 - Part 5: Remove allocateFirstChunk(). r=jonco
authorPaul Bone <pbone@mozilla.com>
Mon, 30 Oct 2017 17:46:23 +1100
changeset 443523 7bd9208b8c7c92521abfc8e4cae34bfbf419547a
parent 443522 d8dbac587181077425996af8a29fb3df03765614
child 443524 00b5d1cc54d3f45a0c2064b7530f131b9ad9c919
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs1298018
milestone58.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 1298018 - Part 5: Remove allocateFirstChunk(). r=jonco
js/src/gc/Nursery.cpp
js/src/gc/Nursery.h
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -142,18 +142,22 @@ js::Nursery::init(uint32_t maxNurseryByt
 
     /* 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;
 
-    if (!allocateFirstChunk(lock))
+    maxChunkCount_ = 1;
+    if (!allocateNextChunk(0, lock)) {
+        maxChunkCount_ = 0;
         return false;
+    }
+    /* After this point the Nursery has been enabled */
 
     setCurrentChunk(0);
     setStartPosition();
 
     char* env = getenv("JS_GC_PROFILE_NURSERY");
     if (env) {
         if (0 == strcmp(env, "help")) {
             fprintf(stderr, "JS_GC_PROFILE_NURSERY=N\n"
@@ -192,18 +196,21 @@ js::Nursery::enable()
 {
     MOZ_ASSERT(isEmpty());
     MOZ_ASSERT(!runtime()->gc.isVerifyPreBarriersEnabled());
     if (isEnabled() || !chunkCountLimit())
         return;
 
     {
         AutoLockGCBgAlloc lock(runtime());
-        if (!allocateFirstChunk(lock))
+        maxChunkCount_ = 1;
+        if (!allocateNextChunk(0, lock)) {
+            maxChunkCount_ = 0;
             return;
+        }
     }
 
     setCurrentChunk(0);
     setStartPosition();
 #ifdef JS_GC_ZEAL
     if (runtime()->hasZealMode(ZealMode::GenerationalGC))
         enterZealMode();
 #endif
@@ -311,17 +318,18 @@ js::Nursery::allocate(size_t size)
     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())) {
-            if (!allocateNextChunk(chunkno))
+            AutoLockGCBgAlloc lock(runtime());
+            if (!allocateNextChunk(chunkno, lock))
                 return nullptr;
             MOZ_ASSERT(chunkno < allocatedChunkCount());
         }
         setCurrentChunk(chunkno);
     }
 
     void* thing = (void*)position();
     position_ = position() + size;
@@ -974,34 +982,32 @@ js::Nursery::setCurrentChunk(unsigned ch
     MOZ_ASSERT(chunkno < allocatedChunkCount());
     currentChunk_ = chunkno;
     position_ = chunk(chunkno).start();
     currentEnd_ = chunk(chunkno).end();
     chunk(chunkno).poisonAndInit(runtime(), JS_FRESH_NURSERY_PATTERN);
 }
 
 bool
-js::Nursery::allocateNextChunk(const unsigned chunkno)
+js::Nursery::allocateNextChunk(const unsigned chunkno,
+    AutoLockGCBgAlloc& lock)
 {
     const unsigned priorCount = allocatedChunkCount();
     const unsigned newCount = priorCount + 1;
 
-    MOZ_ASSERT(chunkno == currentChunk_ + 1);
+    MOZ_ASSERT((chunkno == currentChunk_ + 1) || (chunkno == 0 && allocatedChunkCount() == 0));
     MOZ_ASSERT(chunkno == allocatedChunkCount());
     MOZ_ASSERT(chunkno < chunkCountLimit());
     MOZ_ASSERT(chunkno < maxChunkCount());
 
     if (!chunks_.resize(newCount))
         return false;
 
     Chunk* newChunk;
-    {
-        AutoLockGCBgAlloc lock(runtime());
-        newChunk = runtime()->gc.getOrAllocChunk(lock);
-    }
+    newChunk = runtime()->gc.getOrAllocChunk(lock);
     if (!newChunk) {
         chunks_.shrinkTo(priorCount);
         return false;
     }
 
     chunks_[chunkno] = NurseryChunk::fromChunk(newChunk);
     return true;
 }
@@ -1106,41 +1112,16 @@ js::Nursery::shrinkAllocableSpace(unsign
 
 void
 js::Nursery::minimizeAllocableSpace()
 {
     shrinkAllocableSpace(1);
 }
 
 bool
-js::Nursery::allocateFirstChunk(AutoLockGCBgAlloc& lock)
-{
-    // These assertions aren't required for correctness, but we do assume this
-    // is only called to initialize or re-enable the nursery.
-    MOZ_ASSERT(allocatedChunkCount() == 0);
-    MOZ_ASSERT(maxChunkCount() == 0);
-
-    MOZ_ASSERT(chunkCountLimit() > 0);
-
-    if (!chunks_.resize(1))
-        return false;
-
-    auto chunk = runtime()->gc.getOrAllocChunk(lock);
-    if (!chunk) {
-        chunks_.shrinkTo(0);
-        return false;
-    }
-
-    chunks_[0] = NurseryChunk::fromChunk(chunk);
-    maxChunkCount_ = 1;
-
-    return true;
-}
-
-bool
 js::Nursery::queueDictionaryModeObjectToSweep(NativeObject* obj)
 {
     MOZ_ASSERT(IsInsideNursery(obj));
     return dictionaryModeObjects_.append(obj);
 }
 
 uintptr_t
 js::Nursery::currentEnd() const
--- a/js/src/gc/Nursery.h
+++ b/js/src/gc/Nursery.h
@@ -439,22 +439,21 @@ class Nursery
     NurseryChunk& chunk(unsigned index) const {
         return *chunks_[index];
     }
 
     void setCurrentChunk(unsigned chunkno);
     void setStartPosition();
 
     /*
-     * Ensure that the first chunk has been allocated. Callers will probably
-     * want to call setCurrentChunk(0) next.
+     * Allocate the next chunk, or the first chunk for initialization.
+     * Callers will probably want to call setCurrentChunk(0) next.
      */
-    MOZ_MUST_USE bool allocateFirstChunk(AutoLockGCBgAlloc& lock);
-
-    MOZ_MUST_USE bool allocateNextChunk(unsigned chunkno);
+    MOZ_MUST_USE bool allocateNextChunk(unsigned chunkno,
+        AutoLockGCBgAlloc& lock);
 
     MOZ_ALWAYS_INLINE uintptr_t currentEnd() const;
 
     uintptr_t position() const { return position_; }
 
     JSRuntime* runtime() const { return runtime_; }
 
     /* Allocates a new GC thing from the tenured generation during minor GC. */