From a1e851e916e354ed3d5087c50f46792650931260 Mon Sep 17 00:00:00 2001 From: "danno@chromium.org" Date: Tue, 19 Jul 2011 16:34:17 +0000 Subject: [PATCH] Rollback 8683: Implement setting the length property for FixedDoubleArrays R=ager@chromium.org BUG=none TEST=none Review URL: http://codereview.chromium.org/7448002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8684 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/objects-inl.h | 3 +- src/objects.cc | 66 ++++----------- src/objects.h | 3 - test/mjsunit/unbox-double-arrays.js | 126 +++++++--------------------- 4 files changed, 48 insertions(+), 150 deletions(-) diff --git a/src/objects-inl.h b/src/objects-inl.h index 5726b37393..e069b7994e 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -4007,8 +4007,7 @@ bool JSObject::HasIndexedInterceptor() { bool JSObject::AllowsSetElementsLength() { - bool result = elements()->IsFixedArray() || - elements()->IsFixedDoubleArray(); + bool result = elements()->IsFixedArray(); ASSERT(result == !HasExternalArrayElements()); return result; } diff --git a/src/objects.cc b/src/objects.cc index 0b73049c92..b1d5f1453c 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -3207,7 +3207,7 @@ MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) { case FAST_DOUBLE_ELEMENTS: { int length = IsJSArray() ? Smi::cast(JSArray::cast(this)->length())->value() - : FixedDoubleArray::cast(elements())->length(); + : FixedArray::cast(elements())->length(); if (index < static_cast(length)) { FixedDoubleArray::cast(elements())->set_the_hole(index); } @@ -7628,54 +7628,31 @@ MaybeObject* JSObject::SetElementsLength(Object* len) { const int value = Smi::cast(smi_length)->value(); if (value < 0) return ArrayLengthRangeError(GetHeap()); switch (GetElementsKind()) { - case FAST_ELEMENTS: - case FAST_DOUBLE_ELEMENTS: { - int old_capacity = FixedArrayBase::cast(elements())->length(); + case FAST_ELEMENTS: { + int old_capacity = FixedArray::cast(elements())->length(); if (value <= old_capacity) { if (IsJSArray()) { + Object* obj; + { MaybeObject* maybe_obj = EnsureWritableFastElements(); + if (!maybe_obj->ToObject(&obj)) return maybe_obj; + } + FixedArray* fast_elements = FixedArray::cast(elements()); if (2 * value <= old_capacity) { // If more than half the elements won't be used, trim the array. if (value == 0) { initialize_elements(); } else { - Address filler_start; - int filler_size; - if (GetElementsKind() == FAST_ELEMENTS) { - Object* obj; - { MaybeObject* maybe_obj = EnsureWritableFastElements(); - if (!maybe_obj->ToObject(&obj)) return maybe_obj; - } - FixedArray* fast_elements = FixedArray::cast(elements()); - fast_elements->set_length(value); - filler_start = fast_elements->address() + - FixedArray::OffsetOfElementAt(value); - filler_size = (old_capacity - value) * kPointerSize; - } else { - ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS); - FixedDoubleArray* fast_double_elements = - FixedDoubleArray::cast(elements()); - fast_double_elements->set_length(value); - filler_start = fast_double_elements->address() + - FixedDoubleArray::OffsetOfElementAt(value); - filler_size = (old_capacity - value) * kDoubleSize; - } + fast_elements->set_length(value); + Address filler_start = fast_elements->address() + + FixedArray::OffsetOfElementAt(value); + int filler_size = (old_capacity - value) * kPointerSize; GetHeap()->CreateFillerObjectAt(filler_start, filler_size); } } else { // Otherwise, fill the unused tail with holes. int old_length = FastD2I(JSArray::cast(this)->length()->Number()); - if (GetElementsKind() == FAST_ELEMENTS) { - FixedArray* fast_elements = FixedArray::cast(elements()); - for (int i = value; i < old_length; i++) { - fast_elements->set_the_hole(i); - } - } else { - ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS); - FixedDoubleArray* fast_double_elements = - FixedDoubleArray::cast(elements()); - for (int i = value; i < old_length; i++) { - fast_double_elements->set_the_hole(i); - } + for (int i = value; i < old_length; i++) { + fast_elements->set_the_hole(i); } } JSArray::cast(this)->set_length(Smi::cast(smi_length)); @@ -7686,18 +7663,8 @@ MaybeObject* JSObject::SetElementsLength(Object* len) { int new_capacity = value > min ? value : min; if (new_capacity <= kMaxFastElementsLength || !ShouldConvertToSlowElements(new_capacity)) { - MaybeObject* result; - if (GetElementsKind() == FAST_ELEMENTS) { - Object* obj; - { MaybeObject* maybe_obj = EnsureWritableFastElements(); - if (!maybe_obj->ToObject(&obj)) return maybe_obj; - } - result = SetFastElementsCapacityAndLength(new_capacity, value); - } else { - ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS); - result = SetFastDoubleElementsCapacityAndLength(new_capacity, - value); - } + MaybeObject* result = + SetFastElementsCapacityAndLength(new_capacity, value); if (result->IsFailure()) return result; return this; } @@ -7733,6 +7700,7 @@ MaybeObject* JSObject::SetElementsLength(Object* len) { case EXTERNAL_FLOAT_ELEMENTS: case EXTERNAL_DOUBLE_ELEMENTS: case EXTERNAL_PIXEL_ELEMENTS: + case FAST_DOUBLE_ELEMENTS: UNREACHABLE(); break; } diff --git a/src/objects.h b/src/objects.h index 9b55ea7475..43747cc8fa 100644 --- a/src/objects.h +++ b/src/objects.h @@ -2169,9 +2169,6 @@ class FixedDoubleArray: public FixedArrayBase { return kHeaderSize + length * kDoubleSize; } - // Code Generation support. - static int OffsetOfElementAt(int index) { return SizeFor(index); } - inline static bool is_the_hole_nan(double value); inline static double hole_nan_as_double(); inline static double canonical_not_the_hole_nan_as_double(); diff --git a/test/mjsunit/unbox-double-arrays.js b/test/mjsunit/unbox-double-arrays.js index 11498389b3..312955bde9 100644 --- a/test/mjsunit/unbox-double-arrays.js +++ b/test/mjsunit/unbox-double-arrays.js @@ -28,8 +28,8 @@ // Test dictionary -> double elements -> dictionary elements round trip // Flags: --allow-natives-syntax --unbox-double-arrays --expose-gc -var large_array_size = 100000; -var approx_dict_to_elements_threshold = 75000; +var large_array_size = 500000; +var approx_dict_to_elements_threshold = 69000; var name = 0; @@ -42,21 +42,14 @@ function expected_array_value(i) { } function force_to_fast_double_array(a) { - a[large_array_size - 2] = 1; for (var i= 0; i < approx_dict_to_elements_threshold; ++i ) { a[i] = expected_array_value(i); } assertTrue(%HasFastDoubleElements(a)); } -function make_object_like_array(size) { - obj = new Object(); - obj.length = size; - return obj; -} - function testOneArrayType(allocator) { - var large_array = new allocator(large_array_size); + var large_array = new allocator(500000); force_to_fast_double_array(large_array); var six = 6; @@ -326,94 +319,35 @@ function testOneArrayType(allocator) { // Make sure that we haven't converted from fast double. assertTrue(%HasFastDoubleElements(large_array)); -} + // Cause the array to grow beyond it's JSArray length. This will double the + // size of the capacity and force the array into "slow" dictionary case. + large_array[large_array_size+1] = 50; + assertTrue(%HasDictionaryElements(large_array)); + assertEquals(50, large_array[large_array_size+1]); + assertEquals(large_array_size+2, large_array.length); + assertEquals(Infinity, large_array[5]); + assertEquals(undefined, large_array[large_array_size-1]); + assertEquals(undefined, large_array[-1]); + assertEquals(large_array_size+2, large_array.length); -testOneArrayType(make_object_like_array); -testOneArrayType(Array); + // Test dictionary -> double elements -> fast elements. + var large_array2 = new allocator(large_array_size); + force_to_fast_double_array(large_array2); + delete large_array2[5]; -var large_array = new Array(large_array_size); -force_to_fast_double_array(large_array); -assertTrue(%HasFastDoubleElements(large_array)); - -// Cause the array to grow beyond it's JSArray length. This will double the -// size of the capacity and force the array into "slow" dictionary case. -large_array[5] = Infinity; -large_array[large_array_size+10001] = 50; -assertTrue(%HasDictionaryElements(large_array)); -assertEquals(50, large_array[large_array_size+10001]); -assertEquals(large_array_size+10002, large_array.length); -assertEquals(Infinity, large_array[5]); -assertEquals(undefined, large_array[large_array_size-1]); -assertEquals(undefined, large_array[-1]); -assertEquals(large_array_size+10002, large_array.length); - -// Test dictionary -> double elements -> fast elements. -var large_array2 = new Array(large_array_size); -force_to_fast_double_array(large_array2); -delete large_array2[5]; - -// Convert back to fast elements and make sure the contents of the array are -// unchanged. -large_array2[25] = new Object(); -assertTrue(%HasFastElements(large_array2)); -for (var i= 0; i < approx_dict_to_elements_threshold; i += 500 ) { - if (i != 25 && i != 5) { - assertEquals(expected_array_value(i), large_array2[i]); + // Convert back to fast elements and make sure the contents of the array are + // unchanged. + large_array2[25] = new Object(); + assertTrue(%HasFastElements(large_array2)); + for (var i= 0; i < approx_dict_to_elements_threshold; i += 500 ) { + if (i != 25 && i != 5) { + assertEquals(expected_array_value(i), large_array2[i]); + } } -} -assertEquals(undefined, large_array2[5]); -assertEquals(undefined, large_array2[large_array_size-1]); -assertEquals(undefined, large_array2[-1]); -assertEquals(large_array_size, large_array2.length); - -// Make sure it's possible to change the array's length and that array is still -// intact after the resize. -var large_array3 = new Array(large_array_size); -force_to_fast_double_array(large_array3); -large_array3.length = 60000; -assertEquals(60000, large_array3.length); -assertEquals(undefined, large_array3[60000]); -assertTrue(%HasFastDoubleElements(large_array3)); -assertEquals(expected_array_value(5), large_array3[5]); -assertEquals(expected_array_value(6), large_array3[6]); -assertEquals(expected_array_value(7), large_array3[7]); -assertEquals(expected_array_value(large_array3.length-1), - large_array3[large_array3.length-1]); -assertEquals(undefined, large_array3[large_array_size-1]); -assertEquals(undefined, large_array3[-1]); -gc(); - -for (var i= 0; i < large_array3.length; i += 501 ) { - assertEquals(expected_array_value(i), large_array3[i]); + assertEquals(undefined, large_array2[5]) + assertEquals(undefined, large_array2[large_array_size-1]) + assertEquals(undefined, large_array2[-1]) + assertEquals(large_array_size, large_array2.length); } -large_array3.length = 25; -assertEquals(25, large_array3.length); -assertTrue(%HasFastDoubleElements(large_array3)); -assertEquals(undefined, large_array3[25]); -assertEquals(expected_array_value(5), large_array3[5]); -assertEquals(expected_array_value(6), large_array3[6]); -assertEquals(expected_array_value(7), large_array3[7]); -assertEquals(expected_array_value(large_array3.length-1), - large_array3[large_array3.length-1]); -assertEquals(undefined, large_array3[large_array_size-1]); -assertEquals(undefined, large_array3[-1]); -gc(); - -for (var i= 0; i < large_array3.length; ++i) { - assertEquals(expected_array_value(i), large_array3[i]); -} - -large_array3.length = 100; -assertEquals(100, large_array3.length); -large_array3[95] = 95; -assertTrue(%HasFastDoubleElements(large_array3)); -assertEquals(undefined, large_array3[100]); -assertEquals(95, large_array3[95]); -assertEquals(expected_array_value(5), large_array3[5]); -assertEquals(expected_array_value(6), large_array3[6]); -assertEquals(expected_array_value(7), large_array3[7]); -assertEquals(undefined, large_array3[large_array3.length-1]); -assertEquals(undefined, large_array3[large_array_size-1]); -assertEquals(undefined, large_array3[-1]); -gc(); +testOneArrayType(Array);