| 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
|
| @@ -48,12 +48,6 @@ static Handle<String> MakeName(const char* str, int suffix) {
|
| }
|
|
|
|
|
| -Handle<JSObject> GetObject(const char* name) {
|
| - return v8::Utils::OpenHandle(
|
| - *v8::Handle<v8::Object>::Cast(CcTest::global()->Get(v8_str(name))));
|
| -}
|
| -
|
| -
|
| static double GetDoubleFieldValue(JSObject* obj, FieldIndex field_index) {
|
| if (obj->IsUnboxedDoubleField(field_index)) {
|
| return obj->RawFastDoublePropertyAt(field_index);
|
| @@ -1311,223 +1305,4 @@ TEST(WriteBarriersInCopyJSObject) {
|
| 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
|
|
|