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

Unified Diff: src/heap/mark-compact.cc

Issue 985453003: Eliminate invalid pointers in store buffer after marking. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/store-buffer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/heap/mark-compact.cc
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc
index 44262e42b162b58974cf7b2092ea141047856d2a..8539596a62e5cfbd8f4c8850f929ade5e31f1d96 100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -314,6 +314,14 @@ void MarkCompactCollector::CollectGarbage() {
}
#endif
+ heap_->store_buffer()->ClearInvalidStoreBufferEntries();
+
+#ifdef VERIFY_HEAP
+ if (FLAG_verify_heap) {
+ heap_->store_buffer()->VerifyValidStoreBufferEntries();
+ }
+#endif
+
SweepSpaces();
#ifdef VERIFY_HEAP
@@ -3048,6 +3056,137 @@ bool MarkCompactCollector::TryPromoteObject(HeapObject* object,
}
+bool MarkCompactCollector::IsSlotInBlackObject(Page* p, Address slot) {
+ // This function does not support large objects right now.
+ if (p->owner() == NULL) return true;
+
+ uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot);
+ unsigned int start_index = mark_bit_index >> Bitmap::kBitsPerCellLog2;
+ MarkBit::CellType index_in_cell = 1U
+ << (mark_bit_index & Bitmap::kBitIndexMask);
+ MarkBit::CellType* cells = p->markbits()->cells();
+ Address cell_base = p->area_start();
+ unsigned int cell_base_start_index = Bitmap::IndexToCell(
+ Bitmap::CellAlignIndex(p->AddressToMarkbitIndex(cell_base)));
+
+ // First check if the object is in the current cell.
+ MarkBit::CellType slot_mask;
+ if ((cells[start_index] == 0) ||
+ (base::bits::CountTrailingZeros32(cells[start_index]) >
+ base::bits::CountTrailingZeros32(cells[start_index] | index_in_cell))) {
+ // If we are already in the first cell, there is no live object.
+ if (start_index == cell_base_start_index) return false;
+
+ // If not, find a cell in a preceding cell slot that has a mark bit set.
+ do {
+ start_index--;
+ } while (start_index > cell_base_start_index && cells[start_index] == 0);
+
+ // The slot must be in a dead object if there are no preceding cells that
+ // have mark bits set.
+ if (cells[start_index] == 0) {
+ return false;
+ }
+
+ // The object is in a preceding cell. Set the mask to find any object.
+ slot_mask = 0xffffffff;
+ } else {
+ // We are interested in object mark bits right before the slot.
+ slot_mask = index_in_cell - 1;
+ }
+
+ MarkBit::CellType current_cell = cells[start_index];
+ DCHECK(current_cell != 0);
+
+ // Find the last live object in the cell.
+ unsigned int leading_zeros =
+ base::bits::CountLeadingZeros32(current_cell & slot_mask);
+ DCHECK(leading_zeros != 32);
+ unsigned int offset = Bitmap::kBitIndexMask - leading_zeros;
+
+ cell_base += (start_index - cell_base_start_index) * 32 * kPointerSize;
+ Address address = cell_base + offset * kPointerSize;
+ HeapObject* object = HeapObject::FromAddress(address);
+ DCHECK(object->address() < reinterpret_cast<Address>(slot));
+ if (object->address() <= slot &&
+ (object->address() + object->Size()) > slot) {
+ // If the slot is within the last found object in the cell, the slot is
+ // in a live object.
+ return true;
+ }
+ return false;
+}
+
+
+bool MarkCompactCollector::IsSlotInBlackObjectSlow(Page* p, Address slot) {
+ // This function does not support large objects right now.
+ if (p->owner() == NULL) return true;
+
+ for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) {
+ Address cell_base = it.CurrentCellBase();
+ MarkBit::CellType* cell = it.CurrentCell();
+
+ MarkBit::CellType current_cell = *cell;
+ if (current_cell == 0) continue;
+
+ int offset = 0;
+ while (current_cell != 0) {
+ int trailing_zeros = base::bits::CountTrailingZeros32(current_cell);
+ current_cell >>= trailing_zeros;
+ offset += trailing_zeros;
+ Address address = cell_base + offset * kPointerSize;
+
+ HeapObject* object = HeapObject::FromAddress(address);
+ int size = object->Size();
+
+ if (object->address() > slot) return false;
+ if (object->address() <= slot && slot < (object->address() + size)) {
+ return true;
+ }
+
+ offset++;
+ current_cell >>= 1;
+ }
+ }
+ return false;
+}
+
+
+bool MarkCompactCollector::IsSlotInLiveObject(HeapObject** address,
+ HeapObject* object) {
+ // If the target object is not black, the source slot must be part
+ // of a non-black (dead) object.
+ if (!Marking::IsBlack(Marking::MarkBitFrom(object))) {
+ return false;
+ }
+
+ // The target object is black but we don't know if the source slot is black.
+ // The source object could have died and the slot could be part of a free
+ // space. Find out based on mark bits if the slot is part of a live object.
+ if (!IsSlotInBlackObject(
+ Page::FromAddress(reinterpret_cast<Address>(address)),
+ reinterpret_cast<Address>(address))) {
+ return false;
+ }
+
+ return true;
+}
+
+
+void MarkCompactCollector::VerifyIsSlotInLiveObject(HeapObject** address,
+ HeapObject* object) {
+ // The target object has to be black.
+ CHECK(Marking::IsBlack(Marking::MarkBitFrom(object)));
+
+ // The target object is black but we don't know if the source slot is black.
+ // The source object could have died and the slot could be part of a free
+ // space. Use the mark bit iterator to find out about liveness of the slot.
+ CHECK(IsSlotInBlackObjectSlow(
+ Page::FromAddress(reinterpret_cast<Address>(address)),
+ reinterpret_cast<Address>(address)));
+}
+
+
void MarkCompactCollector::EvacuateNewSpace() {
// There are soft limits in the allocation code, designed trigger a mark
// sweep collection by failing allocations. But since we are already in
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/store-buffer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698