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

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

Issue 2025833002: [heap] Store the host address in the typed remembered set. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase. Created 4 years, 6 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.h ('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 "src/allocation.h" 8 #include "src/allocation.h"
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/utils.h" 10 #include "src/utils.h"
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 226
227 // Data structure for maintaining a multiset of typed slots in a page. 227 // Data structure for maintaining a multiset of typed slots in a page.
228 // Typed slots can only appear in Code and JSFunction objects, so 228 // Typed slots can only appear in Code and JSFunction objects, so
229 // the maximum possible offset is limited by the LargePage::kMaxCodePageSize. 229 // the maximum possible offset is limited by the LargePage::kMaxCodePageSize.
230 // The implementation is a chain of chunks, where each chunks is an array of 230 // The implementation is a chain of chunks, where each chunks is an array of
231 // encoded (slot type, slot offset) pairs. 231 // encoded (slot type, slot offset) pairs.
232 // There is no duplicate detection and we do not expect many duplicates because 232 // There is no duplicate detection and we do not expect many duplicates because
233 // typed slots contain V8 internal pointers that are not directly exposed to JS. 233 // typed slots contain V8 internal pointers that are not directly exposed to JS.
234 class TypedSlotSet { 234 class TypedSlotSet {
235 public: 235 public:
236 typedef uint32_t TypedSlot; 236 struct TypedSlot {
237 TypedSlot() : type_and_offset_(0), host_offset_(0) {}
238
239 TypedSlot(SlotType type, uint32_t host_offset, uint32_t offset)
240 : type_and_offset_(TypeField::encode(type) |
241 OffsetField::encode(offset)),
242 host_offset_(host_offset) {}
243
244 bool operator==(const TypedSlot other) {
245 return type_and_offset_ == other.type_and_offset_ &&
246 host_offset_ == other.host_offset_;
247 }
248
249 bool operator!=(const TypedSlot other) { return !(*this == other); }
250
251 SlotType type() { return TypeField::decode(type_and_offset_); }
252
253 uint32_t offset() { return OffsetField::decode(type_and_offset_); }
254
255 uint32_t host_offset() { return host_offset_; }
256
257 uint32_t type_and_offset_;
258 uint32_t host_offset_;
259 };
237 static const int kMaxOffset = 1 << 29; 260 static const int kMaxOffset = 1 << 29;
238 261
239 explicit TypedSlotSet(Address page_start) : page_start_(page_start) { 262 explicit TypedSlotSet(Address page_start) : page_start_(page_start) {
240 chunk_ = new Chunk(nullptr, kInitialBufferSize); 263 chunk_ = new Chunk(nullptr, kInitialBufferSize);
241 } 264 }
242 265
243 ~TypedSlotSet() { 266 ~TypedSlotSet() {
244 Chunk* chunk = chunk_; 267 Chunk* chunk = chunk_;
245 while (chunk != nullptr) { 268 while (chunk != nullptr) {
246 Chunk* next = chunk->next; 269 Chunk* next = chunk->next;
247 delete chunk; 270 delete chunk;
248 chunk = next; 271 chunk = next;
249 } 272 }
250 } 273 }
251 274
252 // The slot offset specifies a slot at address page_start_ + offset. 275 // The slot offset specifies a slot at address page_start_ + offset.
253 void Insert(SlotType type, int offset) { 276 void Insert(SlotType type, uint32_t host_offset, uint32_t offset) {
254 TypedSlot slot = ToTypedSlot(type, offset); 277 TypedSlot slot(type, host_offset, offset);
255 if (!chunk_->AddSlot(slot)) { 278 if (!chunk_->AddSlot(slot)) {
256 chunk_ = new Chunk(chunk_, NextCapacity(chunk_->capacity)); 279 chunk_ = new Chunk(chunk_, NextCapacity(chunk_->capacity));
257 bool added = chunk_->AddSlot(slot); 280 bool added = chunk_->AddSlot(slot);
258 DCHECK(added); 281 DCHECK(added);
259 USE(added); 282 USE(added);
260 } 283 }
261 } 284 }
262 285
263 // Iterate over all slots in the set and for each slot invoke the callback. 286 // Iterate over all slots in the set and for each slot invoke the callback.
264 // If the callback returns REMOVE_SLOT then the slot is removed from the set. 287 // If the callback returns REMOVE_SLOT then the slot is removed from the set.
265 // Returns the new number of slots. 288 // Returns the new number of slots.
266 // 289 //
267 // Sample usage: 290 // Sample usage:
268 // Iterate([](SlotType slot_type, Address slot_address) { 291 // Iterate([](SlotType slot_type, Address slot_address) {
269 // if (good(slot_type, slot_address)) return KEEP_SLOT; 292 // if (good(slot_type, slot_address)) return KEEP_SLOT;
270 // else return REMOVE_SLOT; 293 // else return REMOVE_SLOT;
271 // }); 294 // });
272 template <typename Callback> 295 template <typename Callback>
273 int Iterate(Callback callback) { 296 int Iterate(Callback callback) {
274 STATIC_ASSERT(NUMBER_OF_SLOT_TYPES < 8); 297 STATIC_ASSERT(NUMBER_OF_SLOT_TYPES < 8);
275 const TypedSlot kRemovedSlot = TypeField::encode(NUMBER_OF_SLOT_TYPES); 298 const TypedSlot kRemovedSlot(NUMBER_OF_SLOT_TYPES, 0, 0);
276 Chunk* chunk = chunk_; 299 Chunk* chunk = chunk_;
277 int new_count = 0; 300 int new_count = 0;
278 while (chunk != nullptr) { 301 while (chunk != nullptr) {
279 TypedSlot* buffer = chunk->buffer; 302 TypedSlot* buffer = chunk->buffer;
280 int count = chunk->count; 303 int count = chunk->count;
281 for (int i = 0; i < count; i++) { 304 for (int i = 0; i < count; i++) {
282 TypedSlot slot = buffer[i]; 305 TypedSlot slot = buffer[i];
283 if (slot != kRemovedSlot) { 306 if (slot != kRemovedSlot) {
284 SlotType type = TypeField::decode(slot); 307 SlotType type = slot.type();
285 Address addr = page_start_ + OffsetField::decode(slot); 308 Address addr = page_start_ + slot.offset();
286 if (callback(type, addr) == KEEP_SLOT) { 309 Address host_addr = page_start_ + slot.host_offset();
310 if (callback(type, host_addr, addr) == KEEP_SLOT) {
287 new_count++; 311 new_count++;
288 } else { 312 } else {
289 buffer[i] = kRemovedSlot; 313 buffer[i] = kRemovedSlot;
290 } 314 }
291 } 315 }
292 } 316 }
293 chunk = chunk->next; 317 chunk = chunk->next;
294 } 318 }
295 return new_count; 319 return new_count;
296 } 320 }
297 321
298 private: 322 private:
299 static const int kInitialBufferSize = 100; 323 static const int kInitialBufferSize = 100;
300 static const int kMaxBufferSize = 16 * KB; 324 static const int kMaxBufferSize = 16 * KB;
301 325
302 static int NextCapacity(int capacity) { 326 static int NextCapacity(int capacity) {
303 return Min(kMaxBufferSize, capacity * 2); 327 return Min(kMaxBufferSize, capacity * 2);
304 } 328 }
305 329
306 static TypedSlot ToTypedSlot(SlotType type, int offset) {
307 return TypeField::encode(type) | OffsetField::encode(offset);
308 }
309
310 class OffsetField : public BitField<int, 0, 29> {}; 330 class OffsetField : public BitField<int, 0, 29> {};
311 class TypeField : public BitField<SlotType, 29, 3> {}; 331 class TypeField : public BitField<SlotType, 29, 3> {};
312 332
313 struct Chunk : Malloced { 333 struct Chunk : Malloced {
314 explicit Chunk(Chunk* next_chunk, int capacity) 334 explicit Chunk(Chunk* next_chunk, int capacity)
315 : next(next_chunk), count(0), capacity(capacity) { 335 : next(next_chunk), count(0), capacity(capacity) {
316 buffer = NewArray<TypedSlot>(capacity); 336 buffer = NewArray<TypedSlot>(capacity);
317 } 337 }
318 bool AddSlot(TypedSlot slot) { 338 bool AddSlot(TypedSlot slot) {
319 if (count == capacity) return false; 339 if (count == capacity) return false;
320 buffer[count++] = slot; 340 buffer[count++] = slot;
321 return true; 341 return true;
322 } 342 }
323 ~Chunk() { DeleteArray(buffer); } 343 ~Chunk() { DeleteArray(buffer); }
324 Chunk* next; 344 Chunk* next;
325 int count; 345 int count;
326 int capacity; 346 int capacity;
327 TypedSlot* buffer; 347 TypedSlot* buffer;
328 }; 348 };
329 349
330 Address page_start_; 350 Address page_start_;
331 Chunk* chunk_; 351 Chunk* chunk_;
332 }; 352 };
333 353
334 } // namespace internal 354 } // namespace internal
335 } // namespace v8 355 } // namespace v8
336 356
337 #endif // V8_SLOT_SET_H 357 #endif // V8_SLOT_SET_H
OLDNEW
« no previous file with comments | « src/heap/remembered-set.h ('k') | test/unittests/heap/slot-set-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698