Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(172)

Side by Side Diff: src/heap/slot-set.h

Issue 2418773002: [heap] Move slot filtering logic into sweeper. (Closed)
Patch Set: remove prefree mode Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/heap/remembered-set.cc ('k') | test/unittests/heap/slot-set-unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_SLOT_SET_H 5 #ifndef V8_SLOT_SET_H
6 #define V8_SLOT_SET_H 6 #define V8_SLOT_SET_H
7 7
8 #include <stack> 8 #include <stack>
9 9
10 #include "src/allocation.h" 10 #include "src/allocation.h"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 uint32_t cell = current_bucket[cell_index].Value(); 73 uint32_t cell = current_bucket[cell_index].Value();
74 if (cell) { 74 if (cell) {
75 uint32_t bit_mask = 1u << bit_index; 75 uint32_t bit_mask = 1u << bit_index;
76 if (cell & bit_mask) { 76 if (cell & bit_mask) {
77 current_bucket[cell_index].ClearBit(bit_index); 77 current_bucket[cell_index].ClearBit(bit_index);
78 } 78 }
79 } 79 }
80 } 80 }
81 } 81 }
82 82
83 void PreFreeEmptyBucket(int bucket_index) {
84 base::AtomicValue<uint32_t>* bucket_ptr = bucket[bucket_index].Value();
85 if (bucket_ptr != nullptr) {
86 base::LockGuard<base::Mutex> guard(&to_be_freed_buckets_mutex_);
87 to_be_freed_buckets_.push(bucket_ptr);
88 bucket[bucket_index].SetValue(nullptr);
89 }
90 }
91
92 // The slot offsets specify a range of slots at addresses: 83 // The slot offsets specify a range of slots at addresses:
93 // [page_start_ + start_offset ... page_start_ + end_offset). 84 // [page_start_ + start_offset ... page_start_ + end_offset).
94 void RemoveRange(int start_offset, int end_offset, EmptyBucketMode mode) { 85 void RemoveRange(int start_offset, int end_offset, EmptyBucketMode mode) {
95 CHECK_LE(end_offset, 1 << kPageSizeBits); 86 CHECK_LE(end_offset, 1 << kPageSizeBits);
96 DCHECK_LE(start_offset, end_offset); 87 DCHECK_LE(start_offset, end_offset);
97 int start_bucket, start_cell, start_bit; 88 int start_bucket, start_cell, start_bit;
98 SlotToIndices(start_offset, &start_bucket, &start_cell, &start_bit); 89 SlotToIndices(start_offset, &start_bucket, &start_cell, &start_bit);
99 int end_bucket, end_cell, end_bit; 90 int end_bucket, end_cell, end_bit;
100 SlotToIndices(end_offset, &end_bucket, &end_cell, &end_bit); 91 SlotToIndices(end_offset, &end_bucket, &end_cell, &end_bit);
101 uint32_t start_mask = (1u << start_bit) - 1; 92 uint32_t start_mask = (1u << start_bit) - 1;
102 uint32_t end_mask = ~((1u << end_bit) - 1); 93 uint32_t end_mask = ~((1u << end_bit) - 1);
103 if (start_bucket == end_bucket && start_cell == end_cell) { 94 if (start_bucket == end_bucket && start_cell == end_cell) {
104 ClearCell(start_bucket, start_cell, ~(start_mask | end_mask)); 95 ClearCell(start_bucket, start_cell, ~(start_mask | end_mask));
105 return; 96 return;
106 } 97 }
107 int current_bucket = start_bucket; 98 int current_bucket = start_bucket;
108 int current_cell = start_cell; 99 int current_cell = start_cell;
109 ClearCell(current_bucket, current_cell, ~start_mask); 100 ClearCell(current_bucket, current_cell, ~start_mask);
110 current_cell++; 101 current_cell++;
102 base::AtomicValue<uint32_t>* bucket_ptr = bucket[current_bucket].Value();
111 if (current_bucket < end_bucket) { 103 if (current_bucket < end_bucket) {
112 if (bucket[current_bucket].Value() != nullptr) { 104 if (bucket_ptr != nullptr) {
113 while (current_cell < kCellsPerBucket) { 105 ClearBucket(bucket_ptr, current_cell, kCellsPerBucket);
114 bucket[current_bucket].Value()[current_cell].SetValue(0);
115 current_cell++;
116 }
117 } 106 }
118 // The rest of the current bucket is cleared. 107 // The rest of the current bucket is cleared.
119 // Move on to the next bucket. 108 // Move on to the next bucket.
120 current_bucket++; 109 current_bucket++;
121 current_cell = 0; 110 current_cell = 0;
122 } 111 }
123 DCHECK(current_bucket == end_bucket || 112 DCHECK(current_bucket == end_bucket ||
124 (current_bucket < end_bucket && current_cell == 0)); 113 (current_bucket < end_bucket && current_cell == 0));
125 while (current_bucket < end_bucket) { 114 while (current_bucket < end_bucket) {
126 if (mode == PREFREE_EMPTY_BUCKETS) { 115 if (mode == PREFREE_EMPTY_BUCKETS) {
127 PreFreeEmptyBucket(current_bucket); 116 PreFreeEmptyBucket(current_bucket);
128 } else if (mode == FREE_EMPTY_BUCKETS) { 117 } else if (mode == FREE_EMPTY_BUCKETS) {
129 ReleaseBucket(current_bucket); 118 ReleaseBucket(current_bucket);
119 } else {
120 DCHECK(mode == KEEP_EMPTY_BUCKETS);
121 bucket_ptr = bucket[current_bucket].Value();
122 if (bucket_ptr) {
123 ClearBucket(bucket_ptr, 0, kCellsPerBucket);
124 }
130 } 125 }
131 current_bucket++; 126 current_bucket++;
132 } 127 }
133 // All buckets between start_bucket and end_bucket are cleared. 128 // All buckets between start_bucket and end_bucket are cleared.
129 bucket_ptr = bucket[current_bucket].Value();
134 DCHECK(current_bucket == end_bucket && current_cell <= end_cell); 130 DCHECK(current_bucket == end_bucket && current_cell <= end_cell);
135 if (current_bucket == kBuckets || 131 if (current_bucket == kBuckets || bucket_ptr == nullptr) {
136 bucket[current_bucket].Value() == nullptr) {
137 return; 132 return;
138 } 133 }
139 while (current_cell < end_cell) { 134 while (current_cell < end_cell) {
140 bucket[current_bucket].Value()[current_cell].SetValue(0); 135 bucket_ptr[current_cell].SetValue(0);
141 current_cell++; 136 current_cell++;
142 } 137 }
143 // All cells between start_cell and end_cell are cleared. 138 // All cells between start_cell and end_cell are cleared.
144 DCHECK(current_bucket == end_bucket && current_cell == end_cell); 139 DCHECK(current_bucket == end_bucket && current_cell == end_cell);
145 ClearCell(end_bucket, end_cell, ~end_mask); 140 ClearCell(end_bucket, end_cell, ~end_mask);
146 } 141 }
147 142
148 // The slot offset specifies a slot at address page_start_ + slot_offset. 143 // The slot offset specifies a slot at address page_start_ + slot_offset.
149 bool Lookup(int slot_offset) { 144 bool Lookup(int slot_offset) {
150 int bucket_index, cell_index, bit_index; 145 int bucket_index, cell_index, bit_index;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 230
236 base::AtomicValue<uint32_t>* AllocateBucket() { 231 base::AtomicValue<uint32_t>* AllocateBucket() {
237 base::AtomicValue<uint32_t>* result = 232 base::AtomicValue<uint32_t>* result =
238 NewArray<base::AtomicValue<uint32_t>>(kCellsPerBucket); 233 NewArray<base::AtomicValue<uint32_t>>(kCellsPerBucket);
239 for (int i = 0; i < kCellsPerBucket; i++) { 234 for (int i = 0; i < kCellsPerBucket; i++) {
240 result[i].SetValue(0); 235 result[i].SetValue(0);
241 } 236 }
242 return result; 237 return result;
243 } 238 }
244 239
240 void ClearBucket(base::AtomicValue<uint32_t>* bucket, int start_cell,
241 int end_cell) {
242 DCHECK_GE(start_cell, 0);
243 DCHECK_LE(end_cell, kCellsPerBucket);
244 int current_cell = start_cell;
245 while (current_cell < kCellsPerBucket) {
246 bucket[current_cell].SetValue(0);
247 current_cell++;
248 }
249 }
250
251 void PreFreeEmptyBucket(int bucket_index) {
252 base::AtomicValue<uint32_t>* bucket_ptr = bucket[bucket_index].Value();
253 if (bucket_ptr != nullptr) {
254 base::LockGuard<base::Mutex> guard(&to_be_freed_buckets_mutex_);
255 to_be_freed_buckets_.push(bucket_ptr);
256 bucket[bucket_index].SetValue(nullptr);
257 }
258 }
259
245 void ReleaseBucket(int bucket_index) { 260 void ReleaseBucket(int bucket_index) {
246 DeleteArray<base::AtomicValue<uint32_t>>(bucket[bucket_index].Value()); 261 DeleteArray<base::AtomicValue<uint32_t>>(bucket[bucket_index].Value());
247 bucket[bucket_index].SetValue(nullptr); 262 bucket[bucket_index].SetValue(nullptr);
248 } 263 }
249 264
250 void ClearCell(int bucket_index, int cell_index, uint32_t mask) { 265 void ClearCell(int bucket_index, int cell_index, uint32_t mask) {
251 if (bucket_index < kBuckets) { 266 if (bucket_index < kBuckets) {
252 base::AtomicValue<uint32_t>* cells = bucket[bucket_index].Value(); 267 base::AtomicValue<uint32_t>* cells = bucket[bucket_index].Value();
253 if (cells != nullptr) { 268 if (cells != nullptr) {
254 uint32_t cell = cells[cell_index].Value(); 269 uint32_t cell = cells[cell_index].Value();
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 Address page_start_; 499 Address page_start_;
485 base::AtomicValue<Chunk*> chunk_; 500 base::AtomicValue<Chunk*> chunk_;
486 base::Mutex to_be_freed_chunks_mutex_; 501 base::Mutex to_be_freed_chunks_mutex_;
487 std::stack<Chunk*> to_be_freed_chunks_; 502 std::stack<Chunk*> to_be_freed_chunks_;
488 }; 503 };
489 504
490 } // namespace internal 505 } // namespace internal
491 } // namespace v8 506 } // namespace v8
492 507
493 #endif // V8_SLOT_SET_H 508 #endif // V8_SLOT_SET_H
OLDNEW
« no previous file with comments | « src/heap/remembered-set.cc ('k') | test/unittests/heap/slot-set-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698