Bug 1531626 - (part 3) Include chunk trailers in nursery capacity r=jonco

The nursery capacity included the usable size of nursery chunks.  However
it'll simplify the parameters for the nursery size if it uses whole
nursery chunks, so include the chunk trailers in the nursery capacity.

This means changing the subchunk calculations slightly to handle the
sub-chunk/whole-chunk mode transitions.

Differential Revision: https://phabricator.services.mozilla.com/D22286

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Paul Bone 2019-03-22 05:15:24 +00:00
parent f7aa75fd25
commit 488211fb22
2 changed files with 24 additions and 21 deletions

View File

@ -252,7 +252,7 @@ bool js::Nursery::isEmpty() const {
#ifdef JS_GC_ZEAL
void js::Nursery::enterZealMode() {
if (isEnabled()) {
capacity_ = chunkCountLimit() * NurseryChunkUsableSize;
capacity_ = chunkCountLimit() * ChunkSize;
setCurrentEnd();
}
}
@ -1095,14 +1095,14 @@ size_t js::Nursery::spaceToEnd(unsigned chunkCount) const {
// (currentStartPosition_).
// + the size of all the other chunks.
bytes = (chunk(currentStartChunk_).end() - currentStartPosition_) +
((lastChunk - currentStartChunk_) * NurseryChunkUsableSize);
((lastChunk - currentStartChunk_) * ChunkSize);
} else {
// In sub-chunk mode, but it also works whenever chunkCount == 1, we need to
// use currentEnd_ since it may not refer to a full chunk.
bytes = currentEnd_ - currentStartPosition_;
}
MOZ_ASSERT(bytes <= maxChunkCount() * NurseryChunkUsableSize);
MOZ_ASSERT(bytes <= maxChunkCount() * ChunkSize);
return bytes;
}
@ -1202,9 +1202,9 @@ void js::Nursery::maybeResizeNursery(JS::GCReason reason) {
// nursery. This way the thresholds still have an effect even if the goal
// seeking says the current size is ideal.
size_t lowLimit = Max(SubChunkLimit, capacity() / 2);
size_t highLimit = Min(
(CheckedInt<size_t>(chunkCountLimit()) * NurseryChunkUsableSize).value(),
(CheckedInt<size_t>(capacity()) * 2).value());
size_t highLimit =
Min((CheckedInt<size_t>(chunkCountLimit()) * ChunkSize).value(),
(CheckedInt<size_t>(capacity()) * 2).value());
newCapacity = mozilla::Clamp(newCapacity, lowLimit, highLimit);
if (maxChunkCount() < chunkCountLimit() && promotionRate > GrowThreshold &&
@ -1246,7 +1246,7 @@ bool js::Nursery::maybeResizeExact(JS::GCReason reason) {
static_assert(NurseryChunkUsableSize < ChunkSize,
"Usable size must be smaller than total size or this "
"calculation might overflow");
shrinkAllocableSpace(newMaxNurseryChunks * NurseryChunkUsableSize);
shrinkAllocableSpace(newMaxNurseryChunks * ChunkSize);
return true;
}
}
@ -1255,15 +1255,18 @@ bool js::Nursery::maybeResizeExact(JS::GCReason reason) {
}
void js::Nursery::growAllocableSpace(size_t newCapacity) {
MOZ_ASSERT_IF(!isSubChunkMode(),
newCapacity > currentChunk_ * NurseryChunkUsableSize);
MOZ_ASSERT_IF(!isSubChunkMode(), newCapacity > currentChunk_ * ChunkSize);
if (isSubChunkMode()) {
capacity_ =
Min(JS_ROUNDUP(newCapacity, SubChunkStep), NurseryChunkUsableSize);
if (newCapacity >= NurseryChunkUsableSize) {
capacity_ = ChunkSize;
} else {
capacity_ =
Min(JS_ROUNDUP(newCapacity, SubChunkStep), NurseryChunkUsableSize);
}
} else {
capacity_ = JS_ROUNDUP(newCapacity, NurseryChunkUsableSize);
capacity_ = JS_ROUNDUP(newCapacity, ChunkSize);
}
MOZ_ASSERT(capacity_ <= chunkCountLimit_ * NurseryChunkUsableSize);
MOZ_ASSERT(capacity_ <= chunkCountLimit_ * ChunkSize);
setCurrentEnd();
}
@ -1299,8 +1302,7 @@ void js::Nursery::shrinkAllocableSpace(size_t newCapacity) {
}
MOZ_ASSERT(newCapacity < capacity());
unsigned newCount =
(newCapacity + NurseryChunkUsableSize - 1) / NurseryChunkUsableSize;
unsigned newCount = (newCapacity + ChunkSize - 1) / ChunkSize;
if (newCount < allocatedChunkCount()) {
freeChunksFrom(newCount);
}
@ -1322,7 +1324,7 @@ uintptr_t js::Nursery::currentEnd() const {
// These are separate asserts because it can be useful to see which one
// failed.
MOZ_ASSERT_IF(isSubChunkMode(), currentChunk_ == 0);
MOZ_ASSERT_IF(isSubChunkMode(), currentEnd_ < chunk(currentChunk_).end());
MOZ_ASSERT_IF(isSubChunkMode(), currentEnd_ <= chunk(currentChunk_).end());
MOZ_ASSERT_IF(!isSubChunkMode(), currentEnd_ == chunk(currentChunk_).end());
MOZ_ASSERT(currentEnd_ != chunk(currentChunk_).start());
return currentEnd_;
@ -1338,7 +1340,7 @@ MOZ_ALWAYS_INLINE const js::gc::GCSchedulingTunables& js::Nursery::tunables()
}
bool js::Nursery::isSubChunkMode() const {
return capacity() < NurseryChunkUsableSize;
return capacity() <= NurseryChunkUsableSize;
}
void js::Nursery::sweepDictionaryModeObjects() {

View File

@ -181,7 +181,7 @@ class Nursery {
// collection.
unsigned maxChunkCount() const {
MOZ_ASSERT(capacity());
return JS_HOWMANY(capacity(), NurseryChunkUsableSize);
return JS_HOWMANY(capacity(), gc::ChunkSize);
}
bool exists() const { return chunkCountLimit() != 0; }
@ -340,12 +340,13 @@ class Nursery {
size_t capacity() const {
MOZ_ASSERT(capacity_ >= SubChunkLimit || capacity_ == 0);
MOZ_ASSERT(capacity_ <= chunkCountLimit() * NurseryChunkUsableSize);
MOZ_ASSERT(capacity_ <= chunkCountLimit() * gc::ChunkSize);
return capacity_;
}
size_t committed() const { return spaceToEnd(allocatedChunkCount()); }
// Used and free space, not counting chunk trailers.
// Used and free space both include chunk trailers for that part of the
// nursery.
//
// usedSpace() + freeSpace() == capacity()
//
@ -357,7 +358,7 @@ class Nursery {
MOZ_ASSERT(currentEnd_ - position_ <= NurseryChunkUsableSize);
MOZ_ASSERT(currentChunk_ < maxChunkCount());
return (currentEnd_ - position_) +
(maxChunkCount() - currentChunk_ - 1) * NurseryChunkUsableSize;
(maxChunkCount() - currentChunk_ - 1) * gc::ChunkSize;
}
#ifdef JS_GC_ZEAL