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
This commit is contained in:
danno@chromium.org 2011-07-20 10:54:58 +00:00
parent 9de5255b60
commit 8bc3254e4b
2 changed files with 73 additions and 6 deletions

View File

@ -8142,6 +8142,15 @@ bool JSObject::HasElementWithReceiver(JSReceiver* receiver, uint32_t index) {
!FixedArray::cast(elements())->get(index)->IsTheHole()) return true; !FixedArray::cast(elements())->get(index)->IsTheHole()) return true;
break; break;
} }
case FAST_DOUBLE_ELEMENTS: {
uint32_t length = IsJSArray() ?
static_cast<uint32_t>
(Smi::cast(JSArray::cast(this)->length())->value()) :
static_cast<uint32_t>(FixedDoubleArray::cast(elements())->length());
if ((index < length) &&
!FixedDoubleArray::cast(elements())->is_the_hole(index)) return true;
break;
}
case EXTERNAL_PIXEL_ELEMENTS: { case EXTERNAL_PIXEL_ELEMENTS: {
ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); ExternalPixelArray* pixels = ExternalPixelArray::cast(elements());
if (index < static_cast<uint32_t>(pixels->length())) { if (index < static_cast<uint32_t>(pixels->length())) {
@ -8163,9 +8172,6 @@ bool JSObject::HasElementWithReceiver(JSReceiver* receiver, uint32_t index) {
} }
break; break;
} }
case FAST_DOUBLE_ELEMENTS:
UNREACHABLE();
break;
case DICTIONARY_ELEMENTS: { case DICTIONARY_ELEMENTS: {
if (element_dictionary()->FindEntry(index) if (element_dictionary()->FindEntry(index)
!= NumberDictionary::kNotFound) { != NumberDictionary::kNotFound) {
@ -9603,6 +9609,21 @@ int JSObject::GetLocalElementKeys(FixedArray* storage,
ASSERT(!storage || storage->length() >= counter); ASSERT(!storage || storage->length() >= counter);
break; 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: { case EXTERNAL_PIXEL_ELEMENTS: {
int length = ExternalPixelArray::cast(elements())->length(); int length = ExternalPixelArray::cast(elements())->length();
while (counter < length) { while (counter < length) {
@ -9632,9 +9653,6 @@ int JSObject::GetLocalElementKeys(FixedArray* storage,
ASSERT(!storage || storage->length() >= counter); ASSERT(!storage || storage->length() >= counter);
break; break;
} }
case FAST_DOUBLE_ELEMENTS:
UNREACHABLE();
break;
case DICTIONARY_ELEMENTS: { case DICTIONARY_ELEMENTS: {
if (storage != NULL) { if (storage != NULL) {
element_dictionary()->CopyKeysTo(storage, element_dictionary()->CopyKeysTo(storage,

View File

@ -417,3 +417,52 @@ assertEquals(undefined, large_array3[large_array3.length-1]);
assertEquals(undefined, large_array3[large_array_size-1]); assertEquals(undefined, large_array3[large_array_size-1]);
assertEquals(undefined, large_array3[-1]); assertEquals(undefined, large_array3[-1]);
gc(); 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();