From 8bc3254e4b31fb9b995385013f7e5e3fc3450f38 Mon Sep 17 00:00:00 2001 From: "danno@chromium.org" Date: Wed, 20 Jul 2011 10:54:58 +0000 Subject: [PATCH] Implement for..in for FastDoubleArrays Also add tests for apply on FastDoubleArrays. R=ager@chromium.org BUG=none TEST=unboxed-double-array.js Review URL: http://codereview.chromium.org/7461018 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8693 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/objects.cc | 30 ++++++++++++++++++----- test/mjsunit/unbox-double-arrays.js | 49 +++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 6 deletions(-) diff --git a/src/objects.cc b/src/objects.cc index f25078b..341f929 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -8142,6 +8142,15 @@ bool JSObject::HasElementWithReceiver(JSReceiver* receiver, uint32_t index) { !FixedArray::cast(elements())->get(index)->IsTheHole()) return true; break; } + case FAST_DOUBLE_ELEMENTS: { + uint32_t length = IsJSArray() ? + static_cast + (Smi::cast(JSArray::cast(this)->length())->value()) : + static_cast(FixedDoubleArray::cast(elements())->length()); + if ((index < length) && + !FixedDoubleArray::cast(elements())->is_the_hole(index)) return true; + break; + } case EXTERNAL_PIXEL_ELEMENTS: { ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); if (index < static_cast(pixels->length())) { @@ -8163,9 +8172,6 @@ bool JSObject::HasElementWithReceiver(JSReceiver* receiver, uint32_t index) { } break; } - case FAST_DOUBLE_ELEMENTS: - UNREACHABLE(); - break; case DICTIONARY_ELEMENTS: { if (element_dictionary()->FindEntry(index) != NumberDictionary::kNotFound) { @@ -9603,6 +9609,21 @@ int JSObject::GetLocalElementKeys(FixedArray* storage, ASSERT(!storage || storage->length() >= counter); break; } + case FAST_DOUBLE_ELEMENTS: { + int length = IsJSArray() ? + Smi::cast(JSArray::cast(this)->length())->value() : + FixedDoubleArray::cast(elements())->length(); + for (int i = 0; i < length; i++) { + if (!FixedDoubleArray::cast(elements())->is_the_hole(i)) { + if (storage != NULL) { + storage->set(counter, Smi::FromInt(i)); + } + counter++; + } + } + ASSERT(!storage || storage->length() >= counter); + break; + } case EXTERNAL_PIXEL_ELEMENTS: { int length = ExternalPixelArray::cast(elements())->length(); while (counter < length) { @@ -9632,9 +9653,6 @@ int JSObject::GetLocalElementKeys(FixedArray* storage, ASSERT(!storage || storage->length() >= counter); break; } - case FAST_DOUBLE_ELEMENTS: - UNREACHABLE(); - break; case DICTIONARY_ELEMENTS: { if (storage != NULL) { element_dictionary()->CopyKeysTo(storage, diff --git a/test/mjsunit/unbox-double-arrays.js b/test/mjsunit/unbox-double-arrays.js index 1149838..351765e 100644 --- a/test/mjsunit/unbox-double-arrays.js +++ b/test/mjsunit/unbox-double-arrays.js @@ -417,3 +417,52 @@ assertEquals(undefined, large_array3[large_array3.length-1]); assertEquals(undefined, large_array3[large_array_size-1]); assertEquals(undefined, large_array3[-1]); gc(); + +// Test apply on arrays backed by double elements. +function called_by_apply(arg0, arg1, arg2, arg3, arg4, arg5, arg6) { + assertEquals(expected_array_value(0), arg0); + assertEquals(NaN, arg1); + assertEquals(-NaN, arg2); + assertEquals(Infinity, arg3); + assertEquals(-Infinity, arg4); + assertEquals(expected_array_value(5), arg5); +} + +large_array3[1] = NaN; +large_array3[2] = -NaN; +large_array3[3] = Infinity; +large_array3[4] = -Infinity; + +function call_apply() { + assertTrue(%HasFastDoubleElements(large_array3)); + called_by_apply.apply({}, large_array3); +} + +call_apply(); +call_apply(); +call_apply(); +%OptimizeFunctionOnNextCall(call_apply); +call_apply(); +call_apply(); +call_apply(); + +function test_for_in() { + // Due to previous tests, keys 0..25 and 95 should be present. + next_expected = 0; + assertTrue(%HasFastDoubleElements(large_array3)); + for (x in large_array3) { + assertTrue(next_expected++ == x); + if (next_expected == 25) { + next_expected = 95; + } + } + assertTrue(next_expected == 96); +} + +test_for_in(); +test_for_in(); +test_for_in(); +%OptimizeFunctionOnNextCall(test_for_in); +test_for_in(); +test_for_in(); +test_for_in(); -- 2.7.4