Index: src/heap/slot-set.h |
diff --git a/src/heap/slot-set.h b/src/heap/slot-set.h |
index f374c1d684696213b3c7c9f3a7c1ad72c03d9a14..6374a3d2126c24d5be22bed649cc011ad6b721eb 100644 |
--- a/src/heap/slot-set.h |
+++ b/src/heap/slot-set.h |
@@ -25,7 +25,13 @@ enum SlotCallbackResult { KEEP_SLOT, REMOVE_SLOT }; |
// Each bucket is a bitmap with a bit corresponding to a single slot offset. |
class SlotSet : public Malloced { |
public: |
- enum IterationMode { PREFREE_EMPTY_BUCKETS, KEEP_EMPTY_BUCKETS }; |
+ enum EmptyBucketMode { |
+ FREE_EMPTY_BUCKETS, // An empty bucket will be deallocated immediately. |
+ PREFREE_EMPTY_BUCKETS, // An empty bucket will be unlinked from the slot |
+ // set, but deallocated on demand by a sweeper |
+ // thread. |
+ KEEP_EMPTY_BUCKETS // An empty bucket will be kept. |
+ }; |
SlotSet() { |
for (int i = 0; i < kBuckets; i++) { |
@@ -74,9 +80,16 @@ class SlotSet : public Malloced { |
} |
} |
+ void PreFreeEmptyBucket(int bucket_index) { |
+ base::LockGuard<base::Mutex> guard(&to_be_freed_buckets_mutex_); |
+ base::AtomicValue<uint32_t>* bucket_ptr = bucket[bucket_index].Value(); |
+ to_be_freed_buckets_.push(bucket_ptr); |
+ bucket[bucket_index].SetValue(nullptr); |
+ } |
+ |
// The slot offsets specify a range of slots at addresses: |
// [page_start_ + start_offset ... page_start_ + end_offset). |
- void RemoveRange(int start_offset, int end_offset) { |
+ void RemoveRange(int start_offset, int end_offset, EmptyBucketMode mode) { |
CHECK_LE(end_offset, 1 << kPageSizeBits); |
DCHECK_LE(start_offset, end_offset); |
int start_bucket, start_cell, start_bit; |
@@ -108,7 +121,11 @@ class SlotSet : public Malloced { |
DCHECK(current_bucket == end_bucket || |
(current_bucket < end_bucket && current_cell == 0)); |
while (current_bucket < end_bucket) { |
- ReleaseBucket(current_bucket); |
+ if (mode == PREFREE_EMPTY_BUCKETS) { |
+ PreFreeEmptyBucket(current_bucket); |
+ } else if (mode == FREE_EMPTY_BUCKETS) { |
+ ReleaseBucket(current_bucket); |
+ } |
current_bucket++; |
} |
// All buckets between start_bucket and end_bucket are cleared. |
@@ -148,7 +165,7 @@ class SlotSet : public Malloced { |
// else return REMOVE_SLOT; |
// }); |
template <typename Callback> |
- int Iterate(Callback callback, IterationMode mode) { |
+ int Iterate(Callback callback, EmptyBucketMode mode) { |
int new_count = 0; |
for (int bucket_index = 0; bucket_index < kBuckets; bucket_index++) { |
if (bucket[bucket_index].Value() != nullptr) { |
@@ -186,11 +203,7 @@ class SlotSet : public Malloced { |
} |
} |
if (mode == PREFREE_EMPTY_BUCKETS && in_bucket_count == 0) { |
- base::LockGuard<base::Mutex> guard(&to_be_freed_buckets_mutex_); |
- base::AtomicValue<uint32_t>* bucket_ptr = |
- bucket[bucket_index].Value(); |
- to_be_freed_buckets_.push(bucket_ptr); |
- bucket[bucket_index].SetValue(nullptr); |
+ PreFreeEmptyBucket(bucket_index); |
} |
new_count += in_bucket_count; |
} |