| Index: src/heap/remembered-set.h
|
| diff --git a/src/heap/remembered-set.h b/src/heap/remembered-set.h
|
| index 8c5e7ffa01fb739358c59d6538a12eda80a7c5f6..8022d52775f84a2300a6e54c926b5b1dca1c4c44 100644
|
| --- a/src/heap/remembered-set.h
|
| +++ b/src/heap/remembered-set.h
|
| @@ -21,39 +21,65 @@ class RememberedSet {
|
| public:
|
| // Given a page and a slot in that page, this function adds the slot to the
|
| // remembered set.
|
| - static void Insert(Page* page, Address slot_addr) {
|
| - DCHECK(page->Contains(slot_addr));
|
| - SlotSet* slot_set = GetSlotSet(page);
|
| + static void Insert(MemoryChunk* chunk, Address slot_addr) {
|
| + DCHECK(chunk->Contains(slot_addr));
|
| + SlotSet* slot_set = GetSlotSet(chunk);
|
| if (slot_set == nullptr) {
|
| - slot_set = AllocateSlotSet(page);
|
| + slot_set = AllocateSlotSet(chunk);
|
| }
|
| - uintptr_t offset = slot_addr - page->address();
|
| + uintptr_t offset = slot_addr - chunk->address();
|
| slot_set[offset / Page::kPageSize].Insert(offset % Page::kPageSize);
|
| }
|
|
|
| // Given a page and a slot in that page, this function removes the slot from
|
| // the remembered set.
|
| // If the slot was never added, then the function does nothing.
|
| - static void Remove(Page* page, Address slot_addr) {
|
| - DCHECK(page->Contains(slot_addr));
|
| - SlotSet* slot_set = GetSlotSet(page);
|
| + static void Remove(MemoryChunk* chunk, Address slot_addr) {
|
| + DCHECK(chunk->Contains(slot_addr));
|
| + SlotSet* slot_set = GetSlotSet(chunk);
|
| if (slot_set != nullptr) {
|
| - uintptr_t offset = slot_addr - page->address();
|
| + uintptr_t offset = slot_addr - chunk->address();
|
| slot_set[offset / Page::kPageSize].Remove(offset % Page::kPageSize);
|
| }
|
| }
|
|
|
| // Given a page and a range of slots in that page, this function removes the
|
| // slots from the remembered set.
|
| - static void RemoveRange(Page* page, Address start, Address end) {
|
| - SlotSet* slot_set = GetSlotSet(page);
|
| + static void RemoveRange(MemoryChunk* chunk, Address start, Address end) {
|
| + SlotSet* slot_set = GetSlotSet(chunk);
|
| if (slot_set != nullptr) {
|
| - uintptr_t start_offset = start - page->address();
|
| - uintptr_t end_offset = end - page->address();
|
| + uintptr_t start_offset = start - chunk->address();
|
| + uintptr_t end_offset = end - chunk->address();
|
| DCHECK_LT(start_offset, end_offset);
|
| - DCHECK_LE(end_offset, static_cast<uintptr_t>(Page::kPageSize));
|
| - slot_set->RemoveRange(static_cast<uint32_t>(start_offset),
|
| - static_cast<uint32_t>(end_offset));
|
| + if (end_offset < static_cast<uintptr_t>(Page::kPageSize)) {
|
| + slot_set->RemoveRange(static_cast<int>(start_offset),
|
| + static_cast<int>(end_offset));
|
| + } else {
|
| + // The large page has multiple slot sets.
|
| + // Compute slot set indicies for the range [start_offset, end_offset).
|
| + int start_chunk = static_cast<int>(start_offset / Page::kPageSize);
|
| + int end_chunk = static_cast<int>((end_offset - 1) / Page::kPageSize);
|
| + int offset_in_start_chunk =
|
| + static_cast<int>(start_offset % Page::kPageSize);
|
| + // Note that using end_offset % Page::kPageSize would be incorrect
|
| + // because end_offset is one beyond the last slot to clear.
|
| + int offset_in_end_chunk = static_cast<int>(
|
| + end_offset - static_cast<uintptr_t>(end_chunk) * Page::kPageSize);
|
| + if (start_chunk == end_chunk) {
|
| + slot_set[start_chunk].RemoveRange(offset_in_start_chunk,
|
| + offset_in_end_chunk);
|
| + } else {
|
| + // Clear all slots from start_offset to the end of first chunk.
|
| + slot_set[start_chunk].RemoveRange(offset_in_start_chunk,
|
| + Page::kPageSize);
|
| + // Clear all slots in intermediate chunks.
|
| + for (int i = start_chunk + 1; i < end_chunk; i++) {
|
| + slot_set[i].RemoveRange(0, Page::kPageSize);
|
| + }
|
| + // Clear slots from the beginning of the last page to end_offset.
|
| + slot_set[end_chunk].RemoveRange(0, offset_in_end_chunk);
|
| + }
|
| + }
|
| }
|
| }
|
|
|
|
|