Chromium Code Reviews| Index: src/objects.cc |
| diff --git a/src/objects.cc b/src/objects.cc |
| index fcfbd1c6c3a4f08b2cc9e4d96e7620cc33eb2f8b..92c1a01889779ea86ef999abe3e4cad4e9f9d073 100644 |
| --- a/src/objects.cc |
| +++ b/src/objects.cc |
| @@ -4689,7 +4689,7 @@ MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) { |
| case JSObject::FAST_ELEMENTS: |
| return UnionOfKeys(FixedArray::cast(array->elements())); |
| case JSObject::FAST_DOUBLE_ELEMENTS: |
| - UNIMPLEMENTED(); |
| + return UnionOfDoubleKeys(FixedDoubleArray::cast(array->elements())); |
| break; |
| case JSObject::DICTIONARY_ELEMENTS: { |
| NumberDictionary* dict = array->element_dictionary(); |
| @@ -4786,6 +4786,65 @@ MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) { |
| } |
| +MaybeObject* FixedArray::UnionOfDoubleKeys(FixedDoubleArray* other) { |
| + int len0 = length(); |
| +#ifdef DEBUG |
| + if (FLAG_enable_slow_asserts) { |
| + for (int i = 0; i < len0; i++) { |
| + ASSERT(get(i)->IsString() || get(i)->IsNumber()); |
| + } |
| + } |
| +#endif |
| + int len1 = other->length(); |
| + // Optimize if 'other' is empty. |
| + // We cannot optimize if 'this' is empty, as other may have holes |
| + // or non keys. |
| + if (len1 == 0) return this; |
| + |
| + // Compute how many elements are not in this. |
| + int extra = 0; |
| + Heap* heap = GetHeap(); |
| + Object* obj; |
| + for (int y = 0; y < len1; y++) { |
| + if (!other->is_the_hole(y)) { |
| + MaybeObject* maybe_obj = heap->NumberFromDouble(other->get(y)); |
|
Mads Ager (chromium)
2011/07/22 08:29:20
This is nasty. This can lead to out-of-memory cras
danno
2011/07/22 09:10:12
Submitted as 1567.
On 2011/07/22 08:29:20, Mads Ag
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| + if (!HasKey(this, obj)) extra++; |
| + } |
| + } |
| + |
| + if (extra == 0) return this; |
| + |
| + // Allocate the result |
| + { MaybeObject* maybe_obj = GetHeap()->AllocateFixedArray(len0 + extra); |
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| + } |
| + // Fill in the content |
| + AssertNoAllocation no_gc; |
|
Mads Ager (chromium)
2011/07/22 08:29:20
Maybe we should change the name to AssertNoGC at s
danno
2011/07/22 09:10:12
Done.
|
| + FixedArray* result = FixedArray::cast(obj); |
| + WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
| + for (int i = 0; i < len0; i++) { |
| + Object* e = get(i); |
| + ASSERT(e->IsString() || e->IsNumber()); |
| + result->set(i, e, mode); |
| + } |
| + // Fill in the extra keys. |
| + int index = 0; |
| + for (int y = 0; y < len1; y++) { |
| + if (!other->is_the_hole(y)) { |
| + MaybeObject* maybe_obj = heap->NumberFromDouble(other->get(y)); |
|
Mads Ager (chromium)
2011/07/22 08:29:20
Here again. So we actually allocate two new heap n
danno
2011/07/22 09:10:12
See above.
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| + if (!HasKey(this, obj)) { |
| + result->set(len0 + index, obj); |
| + index++; |
| + } |
| + } |
| + } |
| + ASSERT(extra == index); |
| + return result; |
| +} |
| + |
| + |
| MaybeObject* FixedArray::CopySize(int new_length) { |
| Heap* heap = GetHeap(); |
| if (new_length == 0) return heap->empty_fixed_array(); |
| @@ -7541,9 +7600,10 @@ MaybeObject* JSObject::SetSlowElements(Object* len) { |
| switch (GetElementsKind()) { |
| case FAST_ELEMENTS: { |
| + case FAST_DOUBLE_ELEMENTS: |
| // Make sure we never try to shrink dense arrays into sparse arrays. |
| - ASSERT(static_cast<uint32_t>(FixedArray::cast(elements())->length()) <= |
| - new_length); |
| + ASSERT(static_cast<uint32_t>( |
| + FixedArrayBase::cast(elements())->length()) <= new_length); |
| MaybeObject* result = NormalizeElements(); |
| if (result->IsFailure()) return result; |
| @@ -7572,7 +7632,6 @@ MaybeObject* JSObject::SetSlowElements(Object* len) { |
| case EXTERNAL_FLOAT_ELEMENTS: |
| case EXTERNAL_DOUBLE_ELEMENTS: |
| case EXTERNAL_PIXEL_ELEMENTS: |
| - case FAST_DOUBLE_ELEMENTS: |
| UNREACHABLE(); |
| break; |
| } |
| @@ -7914,6 +7973,17 @@ bool JSObject::HasElementPostInterceptor(JSReceiver* receiver, uint32_t index) { |
| } |
| 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: { |
| ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); |
| if (index < static_cast<uint32_t>(pixels->length())) { |
| @@ -7928,8 +7998,7 @@ bool JSObject::HasElementPostInterceptor(JSReceiver* receiver, uint32_t index) { |
| case EXTERNAL_INT_ELEMENTS: |
| case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| case EXTERNAL_FLOAT_ELEMENTS: |
| - case EXTERNAL_DOUBLE_ELEMENTS: |
| - case FAST_DOUBLE_ELEMENTS: { |
| + case EXTERNAL_DOUBLE_ELEMENTS: { |
| ExternalArray* array = ExternalArray::cast(elements()); |
| if (index < static_cast<uint32_t>(array->length())) { |
| return true; |
| @@ -9381,6 +9450,15 @@ bool JSObject::HasRealElementProperty(uint32_t index) { |
| return (index < length) && |
| !FixedArray::cast(elements())->get(index)->IsTheHole(); |
| } |
| + 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()); |
| + return (index < length) && |
| + !FixedDoubleArray::cast(elements())->is_the_hole(index); |
| + break; |
| + } |
| case EXTERNAL_PIXEL_ELEMENTS: { |
| ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); |
| return index < static_cast<uint32_t>(pixels->length()); |
| @@ -9396,9 +9474,6 @@ bool JSObject::HasRealElementProperty(uint32_t index) { |
| ExternalArray* array = ExternalArray::cast(elements()); |
| return index < static_cast<uint32_t>(array->length()); |
| } |
| - case FAST_DOUBLE_ELEMENTS: |
| - UNREACHABLE(); |
| - break; |
| case DICTIONARY_ELEMENTS: { |
| return element_dictionary()->FindEntry(index) |
| != NumberDictionary::kNotFound; |