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

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

Issue 2110213003: Fix clearing of slots on large page uncommit (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: x Created 4 years, 5 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 | « no previous file | src/heap/slot-set.h » ('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_REMEMBERED_SET_H 5 #ifndef V8_REMEMBERED_SET_H
6 #define V8_REMEMBERED_SET_H 6 #define V8_REMEMBERED_SET_H
7 7
8 #include "src/assembler.h" 8 #include "src/assembler.h"
9 #include "src/heap/heap.h" 9 #include "src/heap/heap.h"
10 #include "src/heap/slot-set.h" 10 #include "src/heap/slot-set.h"
11 #include "src/heap/spaces.h" 11 #include "src/heap/spaces.h"
12 12
13 namespace v8 { 13 namespace v8 {
14 namespace internal { 14 namespace internal {
15 15
16 enum PointerDirection { OLD_TO_OLD, OLD_TO_NEW }; 16 enum PointerDirection { OLD_TO_OLD, OLD_TO_NEW };
17 17
18 // TODO(ulan): Investigate performance of de-templatizing this class. 18 // TODO(ulan): Investigate performance of de-templatizing this class.
19 template <PointerDirection direction> 19 template <PointerDirection direction>
20 class RememberedSet { 20 class RememberedSet {
21 public: 21 public:
22 // Given a page and a slot in that page, this function adds the slot to the 22 // Given a page and a slot in that page, this function adds the slot to the
23 // remembered set. 23 // remembered set.
24 static void Insert(Page* page, Address slot_addr) { 24 static void Insert(MemoryChunk* chunk, Address slot_addr) {
25 DCHECK(page->Contains(slot_addr)); 25 DCHECK(chunk->Contains(slot_addr));
26 SlotSet* slot_set = GetSlotSet(page); 26 SlotSet* slot_set = GetSlotSet(chunk);
27 if (slot_set == nullptr) { 27 if (slot_set == nullptr) {
28 slot_set = AllocateSlotSet(page); 28 slot_set = AllocateSlotSet(chunk);
29 } 29 }
30 uintptr_t offset = slot_addr - page->address(); 30 uintptr_t offset = slot_addr - chunk->address();
31 slot_set[offset / Page::kPageSize].Insert(offset % Page::kPageSize); 31 slot_set[offset / Page::kPageSize].Insert(offset % Page::kPageSize);
32 } 32 }
33 33
34 // Given a page and a slot in that page, this function removes the slot from 34 // Given a page and a slot in that page, this function removes the slot from
35 // the remembered set. 35 // the remembered set.
36 // If the slot was never added, then the function does nothing. 36 // If the slot was never added, then the function does nothing.
37 static void Remove(Page* page, Address slot_addr) { 37 static void Remove(MemoryChunk* chunk, Address slot_addr) {
38 DCHECK(page->Contains(slot_addr)); 38 DCHECK(chunk->Contains(slot_addr));
39 SlotSet* slot_set = GetSlotSet(page); 39 SlotSet* slot_set = GetSlotSet(chunk);
40 if (slot_set != nullptr) { 40 if (slot_set != nullptr) {
41 uintptr_t offset = slot_addr - page->address(); 41 uintptr_t offset = slot_addr - chunk->address();
42 slot_set[offset / Page::kPageSize].Remove(offset % Page::kPageSize); 42 slot_set[offset / Page::kPageSize].Remove(offset % Page::kPageSize);
43 } 43 }
44 } 44 }
45 45
46 // Given a page and a range of slots in that page, this function removes the 46 // Given a page and a range of slots in that page, this function removes the
47 // slots from the remembered set. 47 // slots from the remembered set.
48 static void RemoveRange(Page* page, Address start, Address end) { 48 static void RemoveRange(MemoryChunk* chunk, Address start, Address end) {
49 SlotSet* slot_set = GetSlotSet(page); 49 SlotSet* slot_set = GetSlotSet(chunk);
50 if (slot_set != nullptr) { 50 if (slot_set != nullptr) {
51 uintptr_t start_offset = start - page->address(); 51 uintptr_t start_offset = start - chunk->address();
52 uintptr_t end_offset = end - page->address(); 52 uintptr_t end_offset = end - chunk->address();
53 DCHECK_LT(start_offset, end_offset); 53 DCHECK_LT(start_offset, end_offset);
54 DCHECK_LE(end_offset, static_cast<uintptr_t>(Page::kPageSize)); 54 if (end_offset < static_cast<uintptr_t>(Page::kPageSize)) {
55 slot_set->RemoveRange(static_cast<uint32_t>(start_offset), 55 slot_set->RemoveRange(static_cast<int>(start_offset),
56 static_cast<uint32_t>(end_offset)); 56 static_cast<int>(end_offset));
57 } else {
58 // The large page has multiple slot sets.
59 // Compute slot set indicies for the range [start_offset, end_offset).
60 int start_chunk = static_cast<int>(start_offset / Page::kPageSize);
61 int end_chunk = static_cast<int>((end_offset - 1) / Page::kPageSize);
62 int offset_in_start_chunk =
63 static_cast<int>(start_offset % Page::kPageSize);
64 // Note that using end_offset % Page::kPageSize would be incorrect
65 // because end_offset is one beyond the last slot to clear.
66 int offset_in_end_chunk = static_cast<int>(
67 end_offset - static_cast<uintptr_t>(end_chunk) * Page::kPageSize);
68 if (start_chunk == end_chunk) {
69 slot_set[start_chunk].RemoveRange(offset_in_start_chunk,
70 offset_in_end_chunk);
71 } else {
72 // Clear all slots from start_offset to the end of first chunk.
73 slot_set[start_chunk].RemoveRange(offset_in_start_chunk,
74 Page::kPageSize);
75 // Clear all slots in intermediate chunks.
76 for (int i = start_chunk + 1; i < end_chunk; i++) {
77 slot_set[i].RemoveRange(0, Page::kPageSize);
78 }
79 // Clear slots from the beginning of the last page to end_offset.
80 slot_set[end_chunk].RemoveRange(0, offset_in_end_chunk);
81 }
82 }
57 } 83 }
58 } 84 }
59 85
60 // Iterates and filters the remembered set with the given callback. 86 // Iterates and filters the remembered set with the given callback.
61 // The callback should take (Address slot) and return SlotCallbackResult. 87 // The callback should take (Address slot) and return SlotCallbackResult.
62 template <typename Callback> 88 template <typename Callback>
63 static void Iterate(Heap* heap, Callback callback) { 89 static void Iterate(Heap* heap, Callback callback) {
64 IterateMemoryChunks( 90 IterateMemoryChunks(
65 heap, [callback](MemoryChunk* chunk) { Iterate(chunk, callback); }); 91 heap, [callback](MemoryChunk* chunk) { Iterate(chunk, callback); });
66 } 92 }
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 return DEBUG_TARGET_SLOT; 382 return DEBUG_TARGET_SLOT;
357 } 383 }
358 UNREACHABLE(); 384 UNREACHABLE();
359 return NUMBER_OF_SLOT_TYPES; 385 return NUMBER_OF_SLOT_TYPES;
360 } 386 }
361 387
362 } // namespace internal 388 } // namespace internal
363 } // namespace v8 389 } // namespace v8
364 390
365 #endif // V8_REMEMBERED_SET_H 391 #endif // V8_REMEMBERED_SET_H
OLDNEW
« no previous file with comments | « no previous file | src/heap/slot-set.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698