forked from mirrors/gecko-dev
Bug 1877124 - Part 7: Rename SortedArenaList segments to buckets r=sfink
Differential Revision: https://phabricator.services.mozilla.com/D201594
This commit is contained in:
parent
c8fa446f4b
commit
57d845b1ad
3 changed files with 60 additions and 60 deletions
|
|
@ -156,31 +156,31 @@ js::gc::SortedArenaList::SortedArenaList(js::gc::AllocKind allocKind)
|
|||
: thingsPerArena_(Arena::thingsPerArena(allocKind)) {
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(thingsPerArena_ <= MaxThingsPerArena);
|
||||
MOZ_ASSERT(emptyIndex() < SegmentCount);
|
||||
MOZ_ASSERT(emptyIndex() < BucketCount);
|
||||
allocKind_ = allocKind;
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t js::gc::SortedArenaList::index(size_t nfree, bool* frontOut) const {
|
||||
// Get the segment index to use for arenas with |nfree| free things and set
|
||||
// |frontOut| to indicate whether to prepend or append to the segment.
|
||||
// Get the bucket index to use for arenas with |nfree| free things and set
|
||||
// |frontOut| to indicate whether to prepend or append to the bucket.
|
||||
|
||||
MOZ_ASSERT(nfree <= thingsPerArena_);
|
||||
|
||||
// Full arenas go in the first segment on their own.
|
||||
// Full arenas go in the first bucket on their own.
|
||||
if (nfree == 0) {
|
||||
*frontOut = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Empty arenas go in the last segment on their own.
|
||||
// Empty arenas go in the last bucket on their own.
|
||||
if (nfree == thingsPerArena_) {
|
||||
*frontOut = false;
|
||||
return emptyIndex();
|
||||
}
|
||||
|
||||
// All other arenas are alternately added to the front and back of successive
|
||||
// segments as |nfree| increases.
|
||||
// buckets as |nfree| increases.
|
||||
*frontOut = (nfree % 2) != 0;
|
||||
size_t index = (nfree + 1) / 2;
|
||||
MOZ_ASSERT(index != 0);
|
||||
|
|
@ -189,13 +189,13 @@ size_t js::gc::SortedArenaList::index(size_t nfree, bool* frontOut) const {
|
|||
}
|
||||
|
||||
size_t js::gc::SortedArenaList::emptyIndex() const {
|
||||
// Get the segment index to use for empty arenas. This must have its own
|
||||
// segment so they can be removed with extractEmptyTo.
|
||||
return segmentsUsed() - 1;
|
||||
// Get the bucket index to use for empty arenas. This must have its own
|
||||
// bucket so they can be removed with extractEmptyTo.
|
||||
return bucketsUsed() - 1;
|
||||
}
|
||||
|
||||
size_t js::gc::SortedArenaList::segmentsUsed() const {
|
||||
// Get the total number of segments used for the current alloc kind.
|
||||
size_t js::gc::SortedArenaList::bucketsUsed() const {
|
||||
// Get the total number of buckets used for the current alloc kind.
|
||||
return HowMany(thingsPerArena_ - 1, 2) + 2;
|
||||
}
|
||||
|
||||
|
|
@ -205,11 +205,11 @@ void js::gc::SortedArenaList::insertAt(Arena* arena, size_t nfree) {
|
|||
|
||||
bool front;
|
||||
size_t i = index(nfree, &front);
|
||||
MOZ_ASSERT(i < SegmentCount);
|
||||
MOZ_ASSERT(i < BucketCount);
|
||||
if (front) {
|
||||
segments[i].pushFront(arena);
|
||||
buckets[i].pushFront(arena);
|
||||
} else {
|
||||
segments[i].pushBack(arena);
|
||||
buckets[i].pushBack(arena);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -217,63 +217,63 @@ void js::gc::SortedArenaList::extractEmptyTo(Arena** destListHeadPtr) {
|
|||
MOZ_ASSERT(!isConvertedToArenaList);
|
||||
check();
|
||||
|
||||
Segment& segment = segments[emptyIndex()];
|
||||
if (!segment.isEmpty()) {
|
||||
Bucket& bucket = buckets[emptyIndex()];
|
||||
if (!bucket.isEmpty()) {
|
||||
Arena* tail = *destListHeadPtr;
|
||||
Arena* segmentLast = segment.last();
|
||||
*destListHeadPtr = segment.release();
|
||||
segmentLast->next = tail;
|
||||
Arena* bucketLast = bucket.last();
|
||||
*destListHeadPtr = bucket.release();
|
||||
bucketLast->next = tail;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(segment.isEmpty());
|
||||
MOZ_ASSERT(bucket.isEmpty());
|
||||
}
|
||||
|
||||
js::gc::ArenaList js::gc::SortedArenaList::convertToArenaList(
|
||||
Arena* maybeSegmentLastOut[SegmentCount]) {
|
||||
Arena* maybeBucketLastOut[BucketCount]) {
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(!isConvertedToArenaList);
|
||||
isConvertedToArenaList = true;
|
||||
check();
|
||||
#endif
|
||||
|
||||
if (maybeSegmentLastOut) {
|
||||
for (size_t i = 0; i < SegmentCount; i++) {
|
||||
maybeSegmentLastOut[i] = segments[i].last();
|
||||
if (maybeBucketLastOut) {
|
||||
for (size_t i = 0; i < BucketCount; i++) {
|
||||
maybeBucketLastOut[i] = buckets[i].last();
|
||||
}
|
||||
}
|
||||
|
||||
// The cursor of the returned ArenaList needs to be between the last full
|
||||
// arena and the first arena with space. Record that here.
|
||||
Arena* lastFullArena = segments[0].last();
|
||||
Arena* lastFullArena = buckets[0].last();
|
||||
|
||||
Segment result;
|
||||
for (size_t i = 0; i < segmentsUsed(); ++i) {
|
||||
result.append(std::move(segments[i]));
|
||||
Bucket result;
|
||||
for (size_t i = 0; i < bucketsUsed(); ++i) {
|
||||
result.append(std::move(buckets[i]));
|
||||
}
|
||||
|
||||
return ArenaList(result.release(), lastFullArena);
|
||||
}
|
||||
|
||||
void js::gc::SortedArenaList::restoreFromArenaList(
|
||||
ArenaList& list, Arena* segmentLast[SegmentCount]) {
|
||||
ArenaList& list, Arena* bucketLast[BucketCount]) {
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(isConvertedToArenaList);
|
||||
isConvertedToArenaList = false;
|
||||
#endif
|
||||
|
||||
// Group the ArenaList elements into SinglyLinkedList buckets, where the
|
||||
// boundaries between buckets are retrieved from |segmentLast|.
|
||||
// boundaries between buckets are retrieved from |bucketLast|.
|
||||
|
||||
Arena* remaining = list.head();
|
||||
list.clear();
|
||||
|
||||
for (size_t i = 0; i < segmentsUsed(); i++) {
|
||||
MOZ_ASSERT(segments[i].isEmpty());
|
||||
if (segmentLast[i]) {
|
||||
for (size_t i = 0; i < bucketsUsed(); i++) {
|
||||
MOZ_ASSERT(buckets[i].isEmpty());
|
||||
if (bucketLast[i]) {
|
||||
Arena* first = remaining;
|
||||
Arena* last = segmentLast[i];
|
||||
Arena* last = bucketLast[i];
|
||||
remaining = last->next;
|
||||
new (&segments[i]) Segment(first, last);
|
||||
new (&buckets[i]) Bucket(first, last);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -282,16 +282,16 @@ void js::gc::SortedArenaList::restoreFromArenaList(
|
|||
|
||||
void js::gc::SortedArenaList::check() const {
|
||||
#ifdef DEBUG
|
||||
const auto& fullSegment = segments[0];
|
||||
for (auto arena = fullSegment.iter(); !arena.done(); arena.next()) {
|
||||
const auto& fullBucket = buckets[0];
|
||||
for (auto arena = fullBucket.iter(); !arena.done(); arena.next()) {
|
||||
MOZ_ASSERT(arena->getAllocKind() == allocKind());
|
||||
MOZ_ASSERT(!arena->hasFreeThings());
|
||||
}
|
||||
|
||||
for (size_t i = 1; i < emptyIndex(); i++) {
|
||||
const auto& segment = segments[i];
|
||||
const auto& bucket = buckets[i];
|
||||
size_t lastFree = 0;
|
||||
for (auto arena = segment.iter(); !arena.done(); arena.next()) {
|
||||
for (auto arena = bucket.iter(); !arena.done(); arena.next()) {
|
||||
MOZ_ASSERT(arena->getAllocKind() == allocKind());
|
||||
size_t nfree = arena->countFreeCells();
|
||||
MOZ_ASSERT(nfree == i * 2 - 1 || nfree == i * 2);
|
||||
|
|
@ -300,14 +300,14 @@ void js::gc::SortedArenaList::check() const {
|
|||
}
|
||||
}
|
||||
|
||||
const auto& emptySegment = segments[emptyIndex()];
|
||||
for (auto arena = emptySegment.iter(); !arena.done(); arena.next()) {
|
||||
const auto& emptyBucket = buckets[emptyIndex()];
|
||||
for (auto arena = emptyBucket.iter(); !arena.done(); arena.next()) {
|
||||
MOZ_ASSERT(arena->getAllocKind() == allocKind());
|
||||
MOZ_ASSERT(arena->isEmpty());
|
||||
}
|
||||
|
||||
for (size_t i = emptyIndex() + 1; i < SegmentCount; i++) {
|
||||
MOZ_ASSERT(segments[i].isEmpty());
|
||||
for (size_t i = emptyIndex() + 1; i < BucketCount; i++) {
|
||||
MOZ_ASSERT(buckets[i].isEmpty());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -146,10 +146,10 @@ class ArenaList {
|
|||
* A class that is used to sort arenas of a single AllocKind into increasing
|
||||
* order of free space.
|
||||
*
|
||||
* It works by adding arenas to a segment corresponding to the number of free
|
||||
* things in the arena. Each segment is an independent linked list.
|
||||
* It works by adding arenas to a bucket corresponding to the number of free
|
||||
* things in the arena. Each bucket is an independent linked list.
|
||||
*
|
||||
* The segments can be linked up to form a sorted ArenaList.
|
||||
* The buckets can be linked up to form a sorted ArenaList.
|
||||
*/
|
||||
class SortedArenaList {
|
||||
public:
|
||||
|
|
@ -165,15 +165,15 @@ class SortedArenaList {
|
|||
static const size_t MaxThingsPerArena =
|
||||
(ArenaSize - ArenaHeaderSize) / MinCellSize;
|
||||
|
||||
// The number of segments required: one full arenas, one for empty arenas and
|
||||
// The number of buckets required: one full arenas, one for empty arenas and
|
||||
// half the number of remaining size classes.
|
||||
static const size_t SegmentCount = HowMany(MaxThingsPerArena - 1, 2) + 2;
|
||||
static const size_t BucketCount = HowMany(MaxThingsPerArena - 1, 2) + 2;
|
||||
|
||||
private:
|
||||
using Segment = SinglyLinkedList<Arena>;
|
||||
using Bucket = SinglyLinkedList<Arena>;
|
||||
|
||||
const size_t thingsPerArena_;
|
||||
Segment segments[SegmentCount];
|
||||
Bucket buckets[BucketCount];
|
||||
|
||||
#ifdef DEBUG
|
||||
AllocKind allocKind_;
|
||||
|
|
@ -185,7 +185,7 @@ class SortedArenaList {
|
|||
|
||||
size_t thingsPerArena() const { return thingsPerArena_; }
|
||||
|
||||
// Inserts an arena, which has room for |nfree| more things, in its segment.
|
||||
// Inserts an arena, which has room for |nfree| more things, in its bucket.
|
||||
inline void insertAt(Arena* arena, size_t nfree);
|
||||
|
||||
// Remove any empty arenas and prepend them to the list pointed to by
|
||||
|
|
@ -193,19 +193,19 @@ class SortedArenaList {
|
|||
inline void extractEmptyTo(Arena** destListHeadPtr);
|
||||
|
||||
// Converts the contents of this data structure to a single list, by linking
|
||||
// up the tail of each non-empty segment to the head of the next non-empty
|
||||
// segment.
|
||||
// up the tail of each non-empty bucket to the head of the next non-empty
|
||||
// bucket.
|
||||
//
|
||||
// Optionally saves internal state to |maybeSegmentLastOut| so that it can be
|
||||
// Optionally saves internal state to |maybeBucketLastOut| so that it can be
|
||||
// restored later by calling restoreFromArenaList. It is not valid to use this
|
||||
// class in the meantime.
|
||||
inline ArenaList convertToArenaList(
|
||||
Arena* maybeSegmentLastOut[SegmentCount] = nullptr);
|
||||
Arena* maybeBucketLastOut[BucketCount] = nullptr);
|
||||
|
||||
// Restore the internal state of this class following conversion to an
|
||||
// ArenaList by the previous method.
|
||||
inline void restoreFromArenaList(ArenaList& list,
|
||||
Arena* segmentLast[SegmentCount]);
|
||||
Arena* bucketLast[BucketCount]);
|
||||
|
||||
#ifdef DEBUG
|
||||
AllocKind allocKind() const { return allocKind_; }
|
||||
|
|
@ -214,7 +214,7 @@ class SortedArenaList {
|
|||
private:
|
||||
inline size_t index(size_t nfree, bool* frontOut) const;
|
||||
inline size_t emptyIndex() const;
|
||||
inline size_t segmentsUsed() const;
|
||||
inline size_t bucketsUsed() const;
|
||||
|
||||
inline void check() const;
|
||||
};
|
||||
|
|
@ -224,7 +224,7 @@ class MOZ_RAII AutoGatherSweptArenas {
|
|||
SortedArenaList* sortedList = nullptr;
|
||||
|
||||
// Internal state from SortedArenaList so we can restore it later.
|
||||
Arena* segmentLastPointers[SortedArenaList::SegmentCount];
|
||||
Arena* bucketLastPointers[SortedArenaList::BucketCount];
|
||||
|
||||
// Single result list.
|
||||
ArenaList linked;
|
||||
|
|
|
|||
|
|
@ -192,12 +192,12 @@ AutoGatherSweptArenas::AutoGatherSweptArenas(JS::Zone* zone, AllocKind kind) {
|
|||
|
||||
// Link individual sorted arena lists together for iteration, saving the
|
||||
// internal state so we can restore it later.
|
||||
linked = sortedList->convertToArenaList(segmentLastPointers);
|
||||
linked = sortedList->convertToArenaList(bucketLastPointers);
|
||||
}
|
||||
|
||||
AutoGatherSweptArenas::~AutoGatherSweptArenas() {
|
||||
if (sortedList) {
|
||||
sortedList->restoreFromArenaList(linked, segmentLastPointers);
|
||||
sortedList->restoreFromArenaList(linked, bucketLastPointers);
|
||||
}
|
||||
linked.clear();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue