Index: test/cctest/test-heap.cc |
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc |
index 634deefbfb2190e5d94c31d08ac9ace20eef6ef5..eb4f07245a9c9927a800b13d834ab0d73189dadc 100644 |
--- a/test/cctest/test-heap.cc |
+++ b/test/cctest/test-heap.cc |
@@ -2694,3 +2694,87 @@ TEST(Regress169209) { |
HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
CHECK(shared1->code()->gc_metadata() == NULL); |
} |
+ |
+ |
+// Helper function that simulates a fill new-space in the heap. |
+static inline void AllocateAllButNBytes(v8::internal::NewSpace* space, |
+ int extra_bytes) { |
+ int space_remaining = static_cast<int>( |
+ *space->allocation_limit_address() - *space->allocation_top_address()); |
+ CHECK(space_remaining >= extra_bytes); |
+ int new_linear_size = space_remaining - extra_bytes; |
+ v8::internal::MaybeObject* maybe = space->AllocateRaw(new_linear_size); |
+ v8::internal::FreeListNode* node = v8::internal::FreeListNode::cast(maybe); |
+ node->set_size(space->heap(), new_linear_size); |
+} |
+ |
+ |
+TEST(Regress169928) { |
+ i::FLAG_allow_natives_syntax = true; |
+ i::FLAG_crankshaft = false; |
+ InitializeVM(); |
+ v8::HandleScope scope; |
+ |
+ // Some flags turn Scavenge collections into Mark-sweep collections |
+ // and hence are incompatible with this test case. |
+ if (FLAG_gc_global || FLAG_stress_compaction) return; |
+ |
+ // Prepare the environment |
+ CompileRun("function fastliteralcase(literal, value) {" |
+ " literal[0] = value;" |
+ " return literal;" |
+ "}" |
+ "function get_standard_literal() {" |
+ " var literal = [1, 2, 3];" |
+ " return literal;" |
+ "}" |
+ "obj = fastliteralcase(get_standard_literal(), 1);" |
+ "obj = fastliteralcase(get_standard_literal(), 1.5);" |
+ "obj = fastliteralcase(get_standard_literal(), 2);"); |
+ |
+ // prepare the heap |
+ v8::Local<v8::String> mote_code_string = |
+ v8_str("fastliteralcase(mote, 2.5);"); |
+ |
+ v8::Local<v8::String> array_name = v8_str("mote"); |
+ v8::Context::GetCurrent()->Global()->Set(array_name, v8::Int32::New(0)); |
+ |
+ // First make sure we flip spaces |
+ HEAP->CollectGarbage(NEW_SPACE); |
+ |
+ // Allocate the object. |
+ Handle<FixedArray> array_data = FACTORY->NewFixedArray(2, NOT_TENURED); |
+ array_data->set(0, Smi::FromInt(1)); |
+ array_data->set(1, Smi::FromInt(2)); |
+ |
+ AllocateAllButNBytes(HEAP->new_space(), |
+ JSArray::kSize + AllocationSiteInfo::kSize + |
+ kPointerSize); |
+ |
+ Handle<JSArray> array = FACTORY->NewJSArrayWithElements(array_data, |
+ FAST_SMI_ELEMENTS, |
+ NOT_TENURED); |
+ |
+ CHECK_EQ(Smi::FromInt(2), array->length()); |
+ CHECK(array->HasFastSmiOrObjectElements()); |
+ |
+ // We need filler the size of AllocationSiteInfo object, plus an extra |
+ // fill pointer value. |
+ MaybeObject* maybe_object = HEAP->AllocateRaw( |
+ AllocationSiteInfo::kSize + kPointerSize, NEW_SPACE, OLD_POINTER_SPACE); |
+ Object* obj = NULL; |
+ CHECK(maybe_object->ToObject(&obj)); |
+ Address addr_obj = reinterpret_cast<Address>( |
+ reinterpret_cast<byte*>(obj - kHeapObjectTag)); |
+ HEAP->CreateFillerObjectAt(addr_obj, |
+ AllocationSiteInfo::kSize + kPointerSize); |
+ |
+ // Give the array a name, making sure not to allocate strings. |
+ v8::Handle<v8::Object> array_obj = v8::Utils::ToLocal(array); |
+ v8::Context::GetCurrent()->Global()->Set(array_name, array_obj); |
+ |
+ // This should crash with a protection violation if we are running a build |
+ // with the bug. |
+ AlwaysAllocateScope aa_scope; |
+ v8::Script::Compile(mote_code_string)->Run(); |
+} |