Home | History | Annotate | Download | only in cctest
      1 // Copyright 2015 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/heap/slots-buffer.h"
      6 #include "test/cctest/cctest.h"
      7 #include "test/cctest/heap/heap-utils.h"
      8 
      9 namespace v8 {
     10 namespace internal {
     11 
     12 TEST(SlotsBufferObjectSlotsRemoval) {
     13   CcTest::InitializeVM();
     14   v8::HandleScope scope(CcTest::isolate());
     15   Isolate* isolate = CcTest::i_isolate();
     16   Heap* heap = isolate->heap();
     17   Factory* factory = isolate->factory();
     18 
     19   SlotsBuffer* buffer = new SlotsBuffer(NULL);
     20   void* fake_object[1];
     21 
     22   Handle<FixedArray> array = factory->NewFixedArray(2, TENURED);
     23   CHECK(heap->old_space()->Contains(*array));
     24   array->set(0, reinterpret_cast<Object*>(fake_object), SKIP_WRITE_BARRIER);
     25 
     26   // Firstly, let's test the regular slots buffer entry.
     27   buffer->Add(HeapObject::RawField(*array, FixedArray::kHeaderSize));
     28   CHECK(reinterpret_cast<void*>(buffer->Get(0)) ==
     29         HeapObject::RawField(*array, FixedArray::kHeaderSize));
     30   SlotsBuffer::RemoveObjectSlots(CcTest::i_isolate()->heap(), buffer,
     31                                  array->address(),
     32                                  array->address() + array->Size());
     33   CHECK(reinterpret_cast<void*>(buffer->Get(0)) ==
     34         HeapObject::RawField(heap->empty_fixed_array(),
     35                              FixedArrayBase::kLengthOffset));
     36 
     37   // Secondly, let's test the typed slots buffer entry.
     38   SlotsBuffer::AddTo(NULL, &buffer, SlotsBuffer::EMBEDDED_OBJECT_SLOT,
     39                      array->address() + FixedArray::kHeaderSize,
     40                      SlotsBuffer::FAIL_ON_OVERFLOW);
     41   CHECK(reinterpret_cast<void*>(buffer->Get(1)) ==
     42         reinterpret_cast<Object**>(SlotsBuffer::EMBEDDED_OBJECT_SLOT));
     43   CHECK(reinterpret_cast<void*>(buffer->Get(2)) ==
     44         HeapObject::RawField(*array, FixedArray::kHeaderSize));
     45   SlotsBuffer::RemoveObjectSlots(CcTest::i_isolate()->heap(), buffer,
     46                                  array->address(),
     47                                  array->address() + array->Size());
     48   CHECK(reinterpret_cast<void*>(buffer->Get(1)) ==
     49         HeapObject::RawField(heap->empty_fixed_array(),
     50                              FixedArrayBase::kLengthOffset));
     51   CHECK(reinterpret_cast<void*>(buffer->Get(2)) ==
     52         HeapObject::RawField(heap->empty_fixed_array(),
     53                              FixedArrayBase::kLengthOffset));
     54   delete buffer;
     55 }
     56 
     57 
     58 TEST(FilterInvalidSlotsBufferEntries) {
     59   FLAG_manual_evacuation_candidates_selection = true;
     60   CcTest::InitializeVM();
     61   v8::HandleScope scope(CcTest::isolate());
     62   Isolate* isolate = CcTest::i_isolate();
     63   Heap* heap = isolate->heap();
     64   Factory* factory = isolate->factory();
     65   SlotsBuffer* buffer = new SlotsBuffer(NULL);
     66 
     67   // Set up a fake black object that will contain a recorded SMI, a recorded
     68   // pointer to a new space object, and a recorded pointer to a non-evacuation
     69   // candidate object. These object should be filtered out. Additionally,
     70   // we point to an evacuation candidate object which should not be filtered
     71   // out.
     72 
     73   // Create fake object and mark it black.
     74   Handle<FixedArray> fake_object = factory->NewFixedArray(23, TENURED);
     75   MarkBit mark_bit = Marking::MarkBitFrom(*fake_object);
     76   Marking::MarkBlack(mark_bit);
     77 
     78   // Write a SMI into field one and record its address;
     79   Object** field_smi = fake_object->RawFieldOfElementAt(0);
     80   *field_smi = Smi::FromInt(100);
     81   buffer->Add(field_smi);
     82 
     83   // Write a new space reference into field 2 and record its address;
     84   Handle<FixedArray> new_space_object = factory->NewFixedArray(23);
     85   mark_bit = Marking::MarkBitFrom(*new_space_object);
     86   Marking::MarkBlack(mark_bit);
     87   Object** field_new_space = fake_object->RawFieldOfElementAt(1);
     88   *field_new_space = *new_space_object;
     89   buffer->Add(field_new_space);
     90 
     91   // Write an old space reference into field 3 which points to an object not on
     92   // an evacuation candidate.
     93   Handle<FixedArray> old_space_object_non_evacuation =
     94       factory->NewFixedArray(23, TENURED);
     95   mark_bit = Marking::MarkBitFrom(*old_space_object_non_evacuation);
     96   Marking::MarkBlack(mark_bit);
     97   Object** field_old_space_object_non_evacuation =
     98       fake_object->RawFieldOfElementAt(2);
     99   *field_old_space_object_non_evacuation = *old_space_object_non_evacuation;
    100   buffer->Add(field_old_space_object_non_evacuation);
    101 
    102   // Write an old space reference into field 4 which points to an object on an
    103   // evacuation candidate.
    104   heap::SimulateFullSpace(heap->old_space());
    105   Handle<FixedArray> valid_object =
    106       isolate->factory()->NewFixedArray(23, TENURED);
    107   Page* page = Page::FromAddress(valid_object->address());
    108   page->SetFlag(MemoryChunk::EVACUATION_CANDIDATE);
    109   Object** valid_field = fake_object->RawFieldOfElementAt(3);
    110   *valid_field = *valid_object;
    111   buffer->Add(valid_field);
    112 
    113   SlotsBuffer::RemoveInvalidSlots(heap, buffer);
    114   Object** kRemovedEntry = HeapObject::RawField(heap->empty_fixed_array(),
    115                                                 FixedArrayBase::kLengthOffset);
    116   CHECK_EQ(buffer->Get(0), kRemovedEntry);
    117   CHECK_EQ(buffer->Get(1), kRemovedEntry);
    118   CHECK_EQ(buffer->Get(2), kRemovedEntry);
    119   CHECK_EQ(buffer->Get(3), valid_field);
    120 
    121   // Clean-up to make verify heap happy.
    122   mark_bit = Marking::MarkBitFrom(*fake_object);
    123   Marking::MarkWhite(mark_bit);
    124   mark_bit = Marking::MarkBitFrom(*new_space_object);
    125   Marking::MarkWhite(mark_bit);
    126   mark_bit = Marking::MarkBitFrom(*old_space_object_non_evacuation);
    127   Marking::MarkWhite(mark_bit);
    128 
    129   delete buffer;
    130 }
    131 
    132 }  // namespace internal
    133 }  // namespace v8
    134