Index: test/cctest/test-heap.cc |
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc |
index d39e85078234bb57ba77bb6b66df1e497f0e3c40..99c606be7c3b8955c6fcf81f2bccde3fdd956549 100644 |
--- a/test/cctest/test-heap.cc |
+++ b/test/cctest/test-heap.cc |
@@ -5312,3 +5312,54 @@ TEST(WritableVsImmortalRoots) { |
CHECK(!immortal || !writable); |
} |
} |
+ |
+ |
+static void TestRightTrimFixedTypedArray(v8::ExternalArrayType type, |
+ int initial_length, |
+ int elements_to_trim) { |
+ v8::HandleScope scope(CcTest::isolate()); |
+ Isolate* isolate = CcTest::i_isolate(); |
+ Factory* factory = isolate->factory(); |
+ Heap* heap = isolate->heap(); |
+ |
+ Handle<FixedTypedArrayBase> array = |
+ factory->NewFixedTypedArray(initial_length, type); |
+ int old_size = array->size(); |
+ heap->RightTrimFixedArray<Heap::FROM_MUTATOR>(*array, elements_to_trim); |
+ |
+ // Check that free space filler is at the right place and did not smash the |
+ // array header. |
+ CHECK(array->IsFixedArrayBase()); |
+ CHECK_EQ(initial_length - elements_to_trim, array->length()); |
+ int new_size = array->size(); |
+ if (new_size != old_size) { |
+ // Free space filler should be created in this case. |
+ Address next_obj_address = array->address() + array->size(); |
+ CHECK(HeapObject::FromAddress(next_obj_address)->IsFiller()); |
+ } |
+ heap->CollectAllAvailableGarbage(); |
+} |
+ |
+ |
+TEST(Regress472513) { |
+ CcTest::InitializeVM(); |
+ v8::HandleScope scope(CcTest::isolate()); |
+ |
+ // The combination of type/initial_length/elements_to_trim triggered |
+ // typed array header smashing with free space filler (crbug/472513). |
+ |
+ // 64-bit cases. |
+ TestRightTrimFixedTypedArray(v8::kExternalUint8Array, 32, 6); |
+ TestRightTrimFixedTypedArray(v8::kExternalUint8Array, 32 - 7, 6); |
+ TestRightTrimFixedTypedArray(v8::kExternalUint16Array, 16, 6); |
+ TestRightTrimFixedTypedArray(v8::kExternalUint16Array, 16 - 3, 6); |
+ TestRightTrimFixedTypedArray(v8::kExternalUint32Array, 8, 6); |
+ TestRightTrimFixedTypedArray(v8::kExternalUint32Array, 8 - 1, 6); |
+ |
+ // 32-bit cases. |
+ TestRightTrimFixedTypedArray(v8::kExternalUint8Array, 16, 3); |
+ TestRightTrimFixedTypedArray(v8::kExternalUint8Array, 16 - 3, 3); |
+ TestRightTrimFixedTypedArray(v8::kExternalUint16Array, 8, 3); |
+ TestRightTrimFixedTypedArray(v8::kExternalUint16Array, 8 - 1, 3); |
+ TestRightTrimFixedTypedArray(v8::kExternalUint32Array, 4, 3); |
+} |