Index: test/cctest/test-unboxed-doubles.cc |
diff --git a/test/cctest/test-unboxed-doubles.cc b/test/cctest/test-unboxed-doubles.cc |
index e99e99f08cbc2fe7561747828ade80b718ef9637..fdcac3af355067c2d1e5945ef39e83cdec439692 100644 |
--- a/test/cctest/test-unboxed-doubles.cc |
+++ b/test/cctest/test-unboxed-doubles.cc |
@@ -45,12 +45,6 @@ |
EmbeddedVector<char, 128> buffer; |
SNPrintF(buffer, "%s%d", str, suffix); |
return MakeString(buffer.start()); |
-} |
- |
- |
-Handle<JSObject> GetObject(const char* name) { |
- return v8::Utils::OpenHandle( |
- *v8::Handle<v8::Object>::Cast(CcTest::global()->Get(v8_str(name)))); |
} |
@@ -1311,223 +1305,4 @@ |
CHECK_EQ(boom_value, clone->RawFastDoublePropertyAt(index)); |
} |
- |
-static void TestWriteBarrier(Handle<Map> map, Handle<Map> new_map, |
- int tagged_descriptor, int double_descriptor, |
- bool check_tagged_value = true) { |
- FLAG_stress_compaction = true; |
- FLAG_manual_evacuation_candidates_selection = true; |
- Isolate* isolate = CcTest::i_isolate(); |
- Factory* factory = isolate->factory(); |
- Heap* heap = CcTest::heap(); |
- PagedSpace* old_pointer_space = heap->old_pointer_space(); |
- |
- // The plan: create |obj| by |map| in old space, create |obj_value| in |
- // new space and ensure that write barrier is triggered when |obj_value| is |
- // written to property |tagged_descriptor| of |obj|. |
- // Then migrate object to |new_map| and set proper value for property |
- // |double_descriptor|. Call GC and ensure that it did not crash during |
- // store buffer entries updating. |
- |
- Handle<JSObject> obj; |
- Handle<HeapObject> obj_value; |
- { |
- AlwaysAllocateScope always_allocate(isolate); |
- obj = factory->NewJSObjectFromMap(map, TENURED, false); |
- CHECK(old_pointer_space->Contains(*obj)); |
- |
- obj_value = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS); |
- } |
- |
- CHECK(heap->InNewSpace(*obj_value)); |
- |
- StoreBuffer* store_buffer = heap->store_buffer(); |
- USE(store_buffer); |
- Address slot; |
- { |
- FieldIndex index = FieldIndex::ForDescriptor(*map, tagged_descriptor); |
- int offset = index.offset(); |
- slot = reinterpret_cast<Address>(HeapObject::RawField(*obj, offset)); |
- USE(slot); |
- DCHECK(!store_buffer->CellIsInStoreBuffer(slot)); |
- |
- const int n = 153; |
- for (int i = 0; i < n; i++) { |
- obj->FastPropertyAtPut(index, *obj_value); |
- } |
- // Ensure that the slot was actually added to the store buffer. |
- DCHECK(store_buffer->CellIsInStoreBuffer(slot)); |
- } |
- |
- // Migrate |obj| to |new_map| which should shift fields and put the |
- // |boom_value| to the slot that was earlier recorded by write barrier. |
- JSObject::MigrateToMap(obj, new_map); |
- |
- // Ensure that invalid entries were removed from the store buffer. |
- DCHECK(!store_buffer->CellIsInStoreBuffer(slot)); |
- |
- Address fake_object = reinterpret_cast<Address>(*obj_value) + kPointerSize; |
- double boom_value = bit_cast<double>(fake_object); |
- |
- FieldIndex double_field_index = |
- FieldIndex::ForDescriptor(*new_map, double_descriptor); |
- CHECK(obj->IsUnboxedDoubleField(double_field_index)); |
- obj->RawFastDoublePropertyAtPut(double_field_index, boom_value); |
- |
- // Trigger GC to evacuate all candidates. |
- CcTest::heap()->CollectGarbage(NEW_SPACE, "boom"); |
- |
- if (check_tagged_value) { |
- FieldIndex tagged_field_index = |
- FieldIndex::ForDescriptor(*new_map, tagged_descriptor); |
- CHECK_EQ(*obj_value, obj->RawFastPropertyAt(tagged_field_index)); |
- } |
- CHECK_EQ(boom_value, obj->RawFastDoublePropertyAt(double_field_index)); |
-} |
- |
- |
-static void TestIncrementalWriteBarrier(Handle<Map> map, Handle<Map> new_map, |
- int tagged_descriptor, |
- int double_descriptor, |
- bool check_tagged_value = true) { |
- if (FLAG_never_compact || !FLAG_incremental_marking) return; |
- FLAG_stress_compaction = true; |
- FLAG_manual_evacuation_candidates_selection = true; |
- Isolate* isolate = CcTest::i_isolate(); |
- Factory* factory = isolate->factory(); |
- Heap* heap = CcTest::heap(); |
- PagedSpace* old_pointer_space = heap->old_pointer_space(); |
- |
- // The plan: create |obj| by |map| in old space, create |obj_value| in |
- // old space and ensure it end up in evacuation candidate page. Start |
- // incremental marking and ensure that incremental write barrier is triggered |
- // when |obj_value| is written to property |tagged_descriptor| of |obj|. |
- // Then migrate object to |new_map| and set proper value for property |
- // |double_descriptor|. Call GC and ensure that it did not crash during |
- // slots buffer entries updating. |
- |
- Handle<JSObject> obj; |
- Handle<HeapObject> obj_value; |
- Page* ec_page; |
- { |
- AlwaysAllocateScope always_allocate(isolate); |
- obj = factory->NewJSObjectFromMap(map, TENURED, false); |
- CHECK(old_pointer_space->Contains(*obj)); |
- |
- // Make sure |obj_value| is placed on an old-space evacuation candidate. |
- SimulateFullSpace(old_pointer_space); |
- obj_value = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, TENURED); |
- ec_page = Page::FromAddress(obj_value->address()); |
- CHECK_NE(ec_page, Page::FromAddress(obj->address())); |
- } |
- |
- // Heap is ready, force |ec_page| to become an evacuation candidate and |
- // simulate incremental marking. |
- ec_page->SetFlag(MemoryChunk::FORCE_EVACUATION_CANDIDATE_FOR_TESTING); |
- SimulateIncrementalMarking(heap); |
- |
- // Check that everything is ready for triggering incremental write barrier |
- // (i.e. that both |obj| and |obj_value| are black and the marking phase is |
- // still active and |obj_value|'s page is indeed an evacuation candidate). |
- IncrementalMarking* marking = heap->incremental_marking(); |
- CHECK(marking->IsMarking()); |
- CHECK(Marking::IsBlack(Marking::MarkBitFrom(*obj))); |
- CHECK(Marking::IsBlack(Marking::MarkBitFrom(*obj_value))); |
- CHECK(MarkCompactCollector::IsOnEvacuationCandidate(*obj_value)); |
- |
- // Trigger incremental write barrier, which should add a slot to |ec_page|'s |
- // slots buffer. |
- { |
- int slots_buffer_len = SlotsBuffer::SizeOfChain(ec_page->slots_buffer()); |
- FieldIndex index = FieldIndex::ForDescriptor(*map, tagged_descriptor); |
- const int n = SlotsBuffer::kNumberOfElements + 10; |
- for (int i = 0; i < n; i++) { |
- obj->FastPropertyAtPut(index, *obj_value); |
- } |
- // Ensure that the slot was actually added to the |ec_page|'s slots buffer. |
- CHECK_EQ(slots_buffer_len + n, |
- SlotsBuffer::SizeOfChain(ec_page->slots_buffer())); |
- } |
- |
- // Migrate |obj| to |new_map| which should shift fields and put the |
- // |boom_value| to the slot that was earlier recorded by incremental write |
- // barrier. |
- JSObject::MigrateToMap(obj, new_map); |
- |
- double boom_value = bit_cast<double>(UINT64_C(0xbaad0176a37c28e1)); |
- |
- FieldIndex double_field_index = |
- FieldIndex::ForDescriptor(*new_map, double_descriptor); |
- CHECK(obj->IsUnboxedDoubleField(double_field_index)); |
- obj->RawFastDoublePropertyAtPut(double_field_index, boom_value); |
- |
- // Trigger GC to evacuate all candidates. |
- CcTest::heap()->CollectGarbage(OLD_POINTER_SPACE, "boom"); |
- |
- // Ensure that the values are still there and correct. |
- CHECK(!MarkCompactCollector::IsOnEvacuationCandidate(*obj_value)); |
- |
- if (check_tagged_value) { |
- FieldIndex tagged_field_index = |
- FieldIndex::ForDescriptor(*new_map, tagged_descriptor); |
- CHECK_EQ(*obj_value, obj->RawFastPropertyAt(tagged_field_index)); |
- } |
- CHECK_EQ(boom_value, obj->RawFastDoublePropertyAt(double_field_index)); |
-} |
- |
- |
-enum WriteBarrierKind { OLD_TO_OLD_WRITE_BARRIER, OLD_TO_NEW_WRITE_BARRIER }; |
-static void TestWriteBarrierObjectShiftFieldsRight( |
- WriteBarrierKind write_barrier_kind) { |
- CcTest::InitializeVM(); |
- Isolate* isolate = CcTest::i_isolate(); |
- v8::HandleScope scope(CcTest::isolate()); |
- |
- Handle<HeapType> any_type = HeapType::Any(isolate); |
- |
- CompileRun("function func() { return 1; }"); |
- |
- Handle<JSObject> func = GetObject("func"); |
- |
- Handle<Map> map = Map::Create(isolate, 10); |
- map = Map::CopyWithConstant(map, MakeName("prop", 0), func, NONE, |
- INSERT_TRANSITION).ToHandleChecked(); |
- map = Map::CopyWithField(map, MakeName("prop", 1), any_type, NONE, |
- Representation::Double(), |
- INSERT_TRANSITION).ToHandleChecked(); |
- map = Map::CopyWithField(map, MakeName("prop", 2), any_type, NONE, |
- Representation::Tagged(), |
- INSERT_TRANSITION).ToHandleChecked(); |
- |
- // Shift fields right by turning constant property to a field. |
- Handle<Map> new_map = Map::ReconfigureProperty( |
- map, 0, kData, NONE, Representation::Tagged(), any_type, FORCE_FIELD); |
- |
- if (write_barrier_kind == OLD_TO_NEW_WRITE_BARRIER) { |
- TestWriteBarrier(map, new_map, 2, 1); |
- } else { |
- CHECK_EQ(OLD_TO_OLD_WRITE_BARRIER, write_barrier_kind); |
- TestIncrementalWriteBarrier(map, new_map, 2, 1); |
- } |
-} |
- |
- |
-TEST(WriteBarrierObjectShiftFieldsRight) { |
- TestWriteBarrierObjectShiftFieldsRight(OLD_TO_NEW_WRITE_BARRIER); |
-} |
- |
- |
-TEST(IncrementalWriteBarrierObjectShiftFieldsRight) { |
- TestWriteBarrierObjectShiftFieldsRight(OLD_TO_OLD_WRITE_BARRIER); |
-} |
- |
- |
-// TODO(ishell): add respective tests for property kind reconfiguring from |
-// accessor field to double, once accessor fields are supported by |
-// Map::ReconfigureProperty(). |
- |
- |
-// TODO(ishell): add respective tests for fast property removal case once |
-// Map::ReconfigureProperty() supports that. |
- |
#endif |