Commit 60f18c79 authored by ishell's avatar ishell Committed by Commit bot

[heap] Assert that there's no recodred slot corresponding to unboxed double field.

BUG=chromium:666046

Review-Url: https://codereview.chromium.org/2539503002
Cr-Commit-Position: refs/heads/master@{#41330}
parent 4c9f56d9
......@@ -5891,6 +5891,18 @@ void Heap::ClearRecordedSlot(HeapObject* object, Object** slot) {
}
}
bool Heap::HasRecordedSlot(HeapObject* object, Object** slot) {
if (InNewSpace(object)) {
return false;
}
Address slot_addr = reinterpret_cast<Address>(slot);
Page* page = Page::FromAddress(slot_addr);
DCHECK_EQ(page->owner()->identity(), OLD_SPACE);
store_buffer()->MoveAllEntriesToRememberedSet();
return RememberedSet<OLD_TO_NEW>::Contains(page, slot_addr) ||
RememberedSet<OLD_TO_OLD>::Contains(page, slot_addr);
}
void Heap::ClearRecordedSlotRange(Address start, Address end) {
Page* page = Page::FromAddress(start);
if (!page->InNewSpace()) {
......
......@@ -1172,6 +1172,8 @@ class Heap {
void ClearRecordedSlot(HeapObject* object, Object** slot);
void ClearRecordedSlotRange(Address start, Address end);
bool HasRecordedSlot(HeapObject* object, Object** slot);
// ===========================================================================
// Incremental marking API. ==================================================
// ===========================================================================
......
......@@ -31,6 +31,19 @@ class RememberedSet {
slot_set[offset / Page::kPageSize].Insert(offset % Page::kPageSize);
}
// Given a page and a slot in that page, this function returns true if
// the remembered set contains the slot.
static bool Contains(MemoryChunk* chunk, Address slot_addr) {
DCHECK(chunk->Contains(slot_addr));
SlotSet* slot_set = GetSlotSet(chunk);
if (slot_set == nullptr) {
return false;
}
uintptr_t offset = slot_addr - chunk->address();
return slot_set[offset / Page::kPageSize].Contains(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.
......
......@@ -65,6 +65,18 @@ class SlotSet : public Malloced {
}
}
// The slot offset specifies a slot at address page_start_ + slot_offset.
// Returns true if the set contains the slot.
bool Contains(int slot_offset) {
int bucket_index, cell_index, bit_index;
SlotToIndices(slot_offset, &bucket_index, &cell_index, &bit_index);
base::AtomicValue<uint32_t>* current_bucket = bucket[bucket_index].Value();
if (current_bucket == nullptr) {
return false;
}
return (current_bucket[cell_index].Value() & (1u << bit_index)) != 0;
}
// The slot offset specifies a slot at address page_start_ + slot_offset.
void Remove(int slot_offset) {
int bucket_index, cell_index, bit_index;
......
......@@ -3438,6 +3438,9 @@ void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
// Transition from tagged to untagged slot.
heap->ClearRecordedSlot(*object,
HeapObject::RawField(*object, index.offset()));
} else {
DCHECK(!heap->HasRecordedSlot(
*object, HeapObject::RawField(*object, index.offset())));
}
} else {
object->RawFastPropertyAtPut(index, value);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment