Index: test/cctest/test-heap.cc |
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc |
index 1461532d2846bfa7f166f26d76fac002f3a96adc..ddb90763339dd32170be6830d41f6b7fe713e7e5 100644 |
--- a/test/cctest/test-heap.cc |
+++ b/test/cctest/test-heap.cc |
@@ -4441,6 +4441,64 @@ TEST(PromotionQueue) { |
} |
+TEST(Regress388880) { |
+ i::FLAG_expose_gc = true; |
+ CcTest::InitializeVM(); |
+ v8::HandleScope scope(CcTest::isolate()); |
+ Isolate* isolate = CcTest::i_isolate(); |
+ Factory* factory = isolate->factory(); |
+ Heap* heap = isolate->heap(); |
+ |
+ Handle<Map> map1 = Map::Create(isolate->object_function(), 1); |
+ Handle<Map> map2 = |
+ Map::CopyWithField(map1, factory->NewStringFromStaticAscii("foo"), |
+ HeapType::Any(isolate), NONE, Representation::Tagged(), |
+ OMIT_TRANSITION).ToHandleChecked(); |
+ |
+ // Allocate two fixed arrays in old pointer space so, that object allocated |
+ // afterwards would end at the end of the page. |
+ SimulateFullSpace(heap->old_pointer_space()); |
Hannes Payer (out of office)
2014/07/28 14:34:50
I do not think you need the first fixed array. I g
|
+ Handle<FixedArray> temp1 = factory->NewFixedArray(1, TENURED); |
+ CHECK(heap->InOldPointerSpace(*temp1)); |
+ Page* page = Page::FromAddress(temp1->address()); |
+ |
+ int desired_offset = page->size() - map1->instance_size(); |
+ |
+ Address desired_address = page->OffsetToAddress(desired_offset); |
+ Address next_object_address = |
+ temp1->address() + FixedArray::OffsetOfElementAt(temp1->length()); |
+ |
+ int desired_object_size = desired_address - next_object_address; |
+ int desired_array_length = |
+ (desired_object_size - FixedArray::kHeaderSize) / kPointerSize; |
+ Handle<FixedArray> temp2 = |
+ factory->NewFixedArray(desired_array_length, TENURED); |
+ Page* page2 = Page::FromAddress(temp2->address()); |
+ CHECK_EQ(page, page2); |
+ CHECK_EQ(next_object_address, temp2->address()); |
+ |
+ Handle<JSObject> o = factory->NewJSObjectFromMap(map1, TENURED, false); |
+ o->set_properties(*factory->empty_fixed_array()); |
+ |
+ CHECK_EQ(page, Page::FromAddress(o->address())); |
+ CHECK_EQ(desired_address, o->address()); |
+ |
+ // Now we have an object right at the end of the page. |
+ |
+ // Enable incremental marking to trigger actions in Heap::AdjustLiveBytes() |
+ // that would cause crash. |
+ IncrementalMarking* marking = CcTest::heap()->incremental_marking(); |
+ marking->Abort(); |
+ marking->Start(); |
+ CHECK(marking->IsMarking()); |
+ |
+ // Now everything is set up for crashing in JSObject::MigrateFastToFast() |
+ // when it calls heap->AdjustLiveBytes(...). |
+ CHECK_EQ(desired_address, o->address()); |
+ JSObject::MigrateToMap(o, map2); |
+} |
+ |
+ |
#ifdef DEBUG |
TEST(PathTracer) { |
CcTest::InitializeVM(); |