Reviewers: Igor Sheludko,

Description:
Clear SMI entries when filtering the slots buffer.

BUG=

Please review this at https://codereview.chromium.org/1313383005/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+73, -1 lines):
  M src/heap/mark-compact.cc
  M test/cctest/test-heap.cc


Index: src/heap/mark-compact.cc
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc
index dc93a5a9a746549ce548a478a56b623dc34bc423..c8ef4146f92c7570abd8668b1b54170b920a0d9a 100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -4501,9 +4501,19 @@ void SlotsBuffer::RemoveInvalidSlots(Heap* heap, SlotsBuffer* buffer) {
       ObjectSlot slot = slots[slot_idx];
       if (!IsTypedSlot(slot)) {
         Object* object = *slot;
-        if ((object->IsHeapObject() && heap->InNewSpace(object)) ||
+        // Slots are invalid when they currently:
+        // - do not point to a heap object (SMI)
+        // - point to a heap object in new space
+        // - point to a heap object not on an evacuation candidate
+        // - are not within a live heap object
+        if (!object->IsHeapObject() ||
+            (object->IsHeapObject() && heap->InNewSpace(object)) ||
+            !Page::FromAddress(reinterpret_cast<Address>(object))
+                 ->IsEvacuationCandidate() ||
             !heap->mark_compact_collector()->IsSlotInLiveObject(
                 reinterpret_cast<Address>(slot))) {
+          // TODO(hpayer): Instead of replacing slots with kRemovedEntry we
+          // could shrink the slots buffer in-place.
           slots[slot_idx] = kRemovedEntry;
         }
       } else {
@@ -4535,6 +4545,8 @@ void SlotsBuffer::RemoveObjectSlots(Heap* heap, SlotsBuffer* buffer,
       if (!IsTypedSlot(slot)) {
         Address slot_address = reinterpret_cast<Address>(slot);
         if (slot_address >= start_slot && slot_address < end_slot) {
+          // TODO(hpayer): Instead of replacing slots with kRemovedEntry we
+          // could shrink the slots buffer in-place.
           slots[slot_idx] = kRemovedEntry;
           if (is_typed_slot) {
             slots[slot_idx - 1] = kRemovedEntry;
Index: test/cctest/test-heap.cc
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index 4d210317efc7e521a6701310de89da11eb913ba2..41d380e32629b3cff14ed3b702120b6952f68796 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -6483,6 +6483,66 @@ TEST(SlotsBufferObjectSlotsRemoval) {
 }


+TEST(FilterInvalidSlotsBufferEntries) {
+  CcTest::InitializeVM();
+  v8::HandleScope scope(CcTest::isolate());
+  Isolate* isolate = CcTest::i_isolate();
+  Heap* heap = isolate->heap();
+  Factory* factory = isolate->factory();
+  SlotsBuffer* buffer = new SlotsBuffer(NULL);
+
+ // Set up a fake black object that will contain a recorded SMI, a recorded + // pointer to a new space object, and a recorded pointer to a non-evacuation
+  // candidate object. These object should be filtered out. Additionally,
+ // we point to an evacuation candidate object which should not be filtered
+  // out.
+
+  // Create fake object and mark it black.
+  Handle<FixedArray> fake_object = factory->NewFixedArray(23, TENURED);
+  MarkBit mark_bit = Marking::MarkBitFrom(*fake_object);
+  Marking::MarkBlack(mark_bit);
+
+  // Write a SMI into field one and record its address;
+  Object** field_smi = fake_object->RawFieldOfElementAt(0);
+  *field_smi = Smi::FromInt(100);
+  buffer->Add(field_smi);
+
+  // Write a new space reference into field 2 and record its address;
+  Handle<FixedArray> new_space_object = factory->NewFixedArray(23);
+  mark_bit = Marking::MarkBitFrom(*new_space_object);
+  Marking::MarkBlack(mark_bit);
+  Object** field_new_space = fake_object->RawFieldOfElementAt(1);
+  *field_new_space = *new_space_object;
+  buffer->Add(field_new_space);
+
+  // Write a old space reference into field 3 which is not on an evacuation
+  // candidate.
+  Handle<FixedArray> old_space_object_non_evacuation =
+      factory->NewFixedArray(23, TENURED);
+  mark_bit = Marking::MarkBitFrom(*old_space_object_non_evacuation);
+  Marking::MarkBlack(mark_bit);
+  Object** field_old_space_object_non_evacuation =
+      fake_object->RawFieldOfElementAt(2);
+ *field_old_space_object_non_evacuation = *old_space_object_non_evacuation;
+  buffer->Add(field_old_space_object_non_evacuation);
+
+  SlotsBuffer::RemoveInvalidSlots(heap, buffer);
+  Object** kRemovedEntry = HeapObject::RawField(heap->empty_fixed_array(),
+ FixedArrayBase::kLengthOffset);
+  CHECK_EQ(buffer->Get(0), kRemovedEntry);
+  CHECK_EQ(buffer->Get(1), kRemovedEntry);
+  CHECK_EQ(buffer->Get(2), kRemovedEntry);
+
+  // Clean-up to make verify heap happy.
+  mark_bit = Marking::MarkBitFrom(*fake_object);
+  Marking::MarkWhite(mark_bit);
+  mark_bit = Marking::MarkBitFrom(*new_space_object);
+  Marking::MarkWhite(mark_bit);
+  mark_bit = Marking::MarkBitFrom(*old_space_object_non_evacuation);
+  Marking::MarkWhite(mark_bit);
+}
+
+
 TEST(ContextMeasure) {
   CcTest::InitializeVM();
   v8::HandleScope scope(CcTest::isolate());


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to