OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 4671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4682 return cache; | 4682 return cache; |
4683 } | 4683 } |
4684 | 4684 |
4685 | 4685 |
4686 MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) { | 4686 MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) { |
4687 ASSERT(!array->HasExternalArrayElements()); | 4687 ASSERT(!array->HasExternalArrayElements()); |
4688 switch (array->GetElementsKind()) { | 4688 switch (array->GetElementsKind()) { |
4689 case JSObject::FAST_ELEMENTS: | 4689 case JSObject::FAST_ELEMENTS: |
4690 return UnionOfKeys(FixedArray::cast(array->elements())); | 4690 return UnionOfKeys(FixedArray::cast(array->elements())); |
4691 case JSObject::FAST_DOUBLE_ELEMENTS: | 4691 case JSObject::FAST_DOUBLE_ELEMENTS: |
4692 UNIMPLEMENTED(); | 4692 return UnionOfDoubleKeys(FixedDoubleArray::cast(array->elements())); |
4693 break; | 4693 break; |
4694 case JSObject::DICTIONARY_ELEMENTS: { | 4694 case JSObject::DICTIONARY_ELEMENTS: { |
4695 NumberDictionary* dict = array->element_dictionary(); | 4695 NumberDictionary* dict = array->element_dictionary(); |
4696 int size = dict->NumberOfElements(); | 4696 int size = dict->NumberOfElements(); |
4697 | 4697 |
4698 // Allocate a temporary fixed array. | 4698 // Allocate a temporary fixed array. |
4699 Object* object; | 4699 Object* object; |
4700 { MaybeObject* maybe_object = GetHeap()->AllocateFixedArray(size); | 4700 { MaybeObject* maybe_object = GetHeap()->AllocateFixedArray(size); |
4701 if (!maybe_object->ToObject(&object)) return maybe_object; | 4701 if (!maybe_object->ToObject(&object)) return maybe_object; |
4702 } | 4702 } |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4779 ASSERT(e->IsString() || e->IsNumber()); | 4779 ASSERT(e->IsString() || e->IsNumber()); |
4780 result->set(len0 + index, e, mode); | 4780 result->set(len0 + index, e, mode); |
4781 index++; | 4781 index++; |
4782 } | 4782 } |
4783 } | 4783 } |
4784 ASSERT(extra == index); | 4784 ASSERT(extra == index); |
4785 return result; | 4785 return result; |
4786 } | 4786 } |
4787 | 4787 |
4788 | 4788 |
| 4789 MaybeObject* FixedArray::UnionOfDoubleKeys(FixedDoubleArray* other) { |
| 4790 int len0 = length(); |
| 4791 #ifdef DEBUG |
| 4792 if (FLAG_enable_slow_asserts) { |
| 4793 for (int i = 0; i < len0; i++) { |
| 4794 ASSERT(get(i)->IsString() || get(i)->IsNumber()); |
| 4795 } |
| 4796 } |
| 4797 #endif |
| 4798 int len1 = other->length(); |
| 4799 // Optimize if 'other' is empty. |
| 4800 // We cannot optimize if 'this' is empty, as other may have holes |
| 4801 // or non keys. |
| 4802 if (len1 == 0) return this; |
| 4803 |
| 4804 // Compute how many elements are not in this. |
| 4805 int extra = 0; |
| 4806 Heap* heap = GetHeap(); |
| 4807 Object* obj; |
| 4808 for (int y = 0; y < len1; y++) { |
| 4809 if (!other->is_the_hole(y)) { |
| 4810 MaybeObject* maybe_obj = heap->NumberFromDouble(other->get(y)); |
| 4811 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 4812 if (!HasKey(this, obj)) extra++; |
| 4813 } |
| 4814 } |
| 4815 |
| 4816 if (extra == 0) return this; |
| 4817 |
| 4818 // Allocate the result |
| 4819 { MaybeObject* maybe_obj = GetHeap()->AllocateFixedArray(len0 + extra); |
| 4820 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 4821 } |
| 4822 // Fill in the content |
| 4823 FixedArray* result = FixedArray::cast(obj); |
| 4824 { |
| 4825 // Limit the scope of the AssertNoAllocation |
| 4826 AssertNoAllocation no_gc; |
| 4827 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
| 4828 for (int i = 0; i < len0; i++) { |
| 4829 Object* e = get(i); |
| 4830 ASSERT(e->IsString() || e->IsNumber()); |
| 4831 result->set(i, e, mode); |
| 4832 } |
| 4833 } |
| 4834 |
| 4835 // Fill in the extra keys. |
| 4836 int index = 0; |
| 4837 for (int y = 0; y < len1; y++) { |
| 4838 if (!other->is_the_hole(y)) { |
| 4839 MaybeObject* maybe_obj = heap->NumberFromDouble(other->get(y)); |
| 4840 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 4841 if (!HasKey(this, obj)) { |
| 4842 result->set(len0 + index, obj); |
| 4843 index++; |
| 4844 } |
| 4845 } |
| 4846 } |
| 4847 ASSERT(extra == index); |
| 4848 return result; |
| 4849 } |
| 4850 |
| 4851 |
4789 MaybeObject* FixedArray::CopySize(int new_length) { | 4852 MaybeObject* FixedArray::CopySize(int new_length) { |
4790 Heap* heap = GetHeap(); | 4853 Heap* heap = GetHeap(); |
4791 if (new_length == 0) return heap->empty_fixed_array(); | 4854 if (new_length == 0) return heap->empty_fixed_array(); |
4792 Object* obj; | 4855 Object* obj; |
4793 { MaybeObject* maybe_obj = heap->AllocateFixedArray(new_length); | 4856 { MaybeObject* maybe_obj = heap->AllocateFixedArray(new_length); |
4794 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 4857 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
4795 } | 4858 } |
4796 FixedArray* result = FixedArray::cast(obj); | 4859 FixedArray* result = FixedArray::cast(obj); |
4797 // Copy the content | 4860 // Copy the content |
4798 AssertNoAllocation no_gc; | 4861 AssertNoAllocation no_gc; |
(...skipping 2736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7535 | 7598 |
7536 | 7599 |
7537 MaybeObject* JSObject::SetSlowElements(Object* len) { | 7600 MaybeObject* JSObject::SetSlowElements(Object* len) { |
7538 // We should never end in here with a pixel or external array. | 7601 // We should never end in here with a pixel or external array. |
7539 ASSERT(!HasExternalArrayElements()); | 7602 ASSERT(!HasExternalArrayElements()); |
7540 | 7603 |
7541 uint32_t new_length = static_cast<uint32_t>(len->Number()); | 7604 uint32_t new_length = static_cast<uint32_t>(len->Number()); |
7542 | 7605 |
7543 switch (GetElementsKind()) { | 7606 switch (GetElementsKind()) { |
7544 case FAST_ELEMENTS: { | 7607 case FAST_ELEMENTS: { |
| 7608 case FAST_DOUBLE_ELEMENTS: |
7545 // Make sure we never try to shrink dense arrays into sparse arrays. | 7609 // Make sure we never try to shrink dense arrays into sparse arrays. |
7546 ASSERT(static_cast<uint32_t>(FixedArray::cast(elements())->length()) <= | 7610 ASSERT(static_cast<uint32_t>( |
7547 new_length); | 7611 FixedArrayBase::cast(elements())->length()) <= new_length); |
7548 MaybeObject* result = NormalizeElements(); | 7612 MaybeObject* result = NormalizeElements(); |
7549 if (result->IsFailure()) return result; | 7613 if (result->IsFailure()) return result; |
7550 | 7614 |
7551 // Update length for JSArrays. | 7615 // Update length for JSArrays. |
7552 if (IsJSArray()) JSArray::cast(this)->set_length(len); | 7616 if (IsJSArray()) JSArray::cast(this)->set_length(len); |
7553 break; | 7617 break; |
7554 } | 7618 } |
7555 case DICTIONARY_ELEMENTS: { | 7619 case DICTIONARY_ELEMENTS: { |
7556 if (IsJSArray()) { | 7620 if (IsJSArray()) { |
7557 uint32_t old_length = | 7621 uint32_t old_length = |
7558 static_cast<uint32_t>(JSArray::cast(this)->length()->Number()); | 7622 static_cast<uint32_t>(JSArray::cast(this)->length()->Number()); |
7559 element_dictionary()->RemoveNumberEntries(new_length, old_length), | 7623 element_dictionary()->RemoveNumberEntries(new_length, old_length), |
7560 JSArray::cast(this)->set_length(len); | 7624 JSArray::cast(this)->set_length(len); |
7561 } | 7625 } |
7562 break; | 7626 break; |
7563 } | 7627 } |
7564 case NON_STRICT_ARGUMENTS_ELEMENTS: | 7628 case NON_STRICT_ARGUMENTS_ELEMENTS: |
7565 UNIMPLEMENTED(); | 7629 UNIMPLEMENTED(); |
7566 break; | 7630 break; |
7567 case EXTERNAL_BYTE_ELEMENTS: | 7631 case EXTERNAL_BYTE_ELEMENTS: |
7568 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 7632 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
7569 case EXTERNAL_SHORT_ELEMENTS: | 7633 case EXTERNAL_SHORT_ELEMENTS: |
7570 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 7634 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
7571 case EXTERNAL_INT_ELEMENTS: | 7635 case EXTERNAL_INT_ELEMENTS: |
7572 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 7636 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
7573 case EXTERNAL_FLOAT_ELEMENTS: | 7637 case EXTERNAL_FLOAT_ELEMENTS: |
7574 case EXTERNAL_DOUBLE_ELEMENTS: | 7638 case EXTERNAL_DOUBLE_ELEMENTS: |
7575 case EXTERNAL_PIXEL_ELEMENTS: | 7639 case EXTERNAL_PIXEL_ELEMENTS: |
7576 case FAST_DOUBLE_ELEMENTS: | |
7577 UNREACHABLE(); | 7640 UNREACHABLE(); |
7578 break; | 7641 break; |
7579 } | 7642 } |
7580 return this; | 7643 return this; |
7581 } | 7644 } |
7582 | 7645 |
7583 | 7646 |
7584 MaybeObject* JSArray::Initialize(int capacity) { | 7647 MaybeObject* JSArray::Initialize(int capacity) { |
7585 Heap* heap = GetHeap(); | 7648 Heap* heap = GetHeap(); |
7586 ASSERT(capacity >= 0); | 7649 ASSERT(capacity >= 0); |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7907 uint32_t length = IsJSArray() ? | 7970 uint32_t length = IsJSArray() ? |
7908 static_cast<uint32_t> | 7971 static_cast<uint32_t> |
7909 (Smi::cast(JSArray::cast(this)->length())->value()) : | 7972 (Smi::cast(JSArray::cast(this)->length())->value()) : |
7910 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 7973 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
7911 if ((index < length) && | 7974 if ((index < length) && |
7912 !FixedArray::cast(elements())->get(index)->IsTheHole()) { | 7975 !FixedArray::cast(elements())->get(index)->IsTheHole()) { |
7913 return true; | 7976 return true; |
7914 } | 7977 } |
7915 break; | 7978 break; |
7916 } | 7979 } |
| 7980 case FAST_DOUBLE_ELEMENTS: { |
| 7981 uint32_t length = IsJSArray() ? |
| 7982 static_cast<uint32_t> |
| 7983 (Smi::cast(JSArray::cast(this)->length())->value()) : |
| 7984 static_cast<uint32_t>(FixedDoubleArray::cast(elements())->length()); |
| 7985 if ((index < length) && |
| 7986 !FixedDoubleArray::cast(elements())->is_the_hole(index)) { |
| 7987 return true; |
| 7988 } |
| 7989 break; |
| 7990 } |
7917 case EXTERNAL_PIXEL_ELEMENTS: { | 7991 case EXTERNAL_PIXEL_ELEMENTS: { |
7918 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); | 7992 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); |
7919 if (index < static_cast<uint32_t>(pixels->length())) { | 7993 if (index < static_cast<uint32_t>(pixels->length())) { |
7920 return true; | 7994 return true; |
7921 } | 7995 } |
7922 break; | 7996 break; |
7923 } | 7997 } |
7924 case EXTERNAL_BYTE_ELEMENTS: | 7998 case EXTERNAL_BYTE_ELEMENTS: |
7925 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 7999 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
7926 case EXTERNAL_SHORT_ELEMENTS: | 8000 case EXTERNAL_SHORT_ELEMENTS: |
7927 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 8001 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
7928 case EXTERNAL_INT_ELEMENTS: | 8002 case EXTERNAL_INT_ELEMENTS: |
7929 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 8003 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
7930 case EXTERNAL_FLOAT_ELEMENTS: | 8004 case EXTERNAL_FLOAT_ELEMENTS: |
7931 case EXTERNAL_DOUBLE_ELEMENTS: | 8005 case EXTERNAL_DOUBLE_ELEMENTS: { |
7932 case FAST_DOUBLE_ELEMENTS: { | |
7933 ExternalArray* array = ExternalArray::cast(elements()); | 8006 ExternalArray* array = ExternalArray::cast(elements()); |
7934 if (index < static_cast<uint32_t>(array->length())) { | 8007 if (index < static_cast<uint32_t>(array->length())) { |
7935 return true; | 8008 return true; |
7936 } | 8009 } |
7937 break; | 8010 break; |
7938 } | 8011 } |
7939 case DICTIONARY_ELEMENTS: { | 8012 case DICTIONARY_ELEMENTS: { |
7940 if (element_dictionary()->FindEntry(index) | 8013 if (element_dictionary()->FindEntry(index) |
7941 != NumberDictionary::kNotFound) { | 8014 != NumberDictionary::kNotFound) { |
7942 return true; | 8015 return true; |
(...skipping 1430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9373 | 9446 |
9374 switch (GetElementsKind()) { | 9447 switch (GetElementsKind()) { |
9375 case FAST_ELEMENTS: { | 9448 case FAST_ELEMENTS: { |
9376 uint32_t length = IsJSArray() ? | 9449 uint32_t length = IsJSArray() ? |
9377 static_cast<uint32_t>( | 9450 static_cast<uint32_t>( |
9378 Smi::cast(JSArray::cast(this)->length())->value()) : | 9451 Smi::cast(JSArray::cast(this)->length())->value()) : |
9379 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 9452 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
9380 return (index < length) && | 9453 return (index < length) && |
9381 !FixedArray::cast(elements())->get(index)->IsTheHole(); | 9454 !FixedArray::cast(elements())->get(index)->IsTheHole(); |
9382 } | 9455 } |
| 9456 case FAST_DOUBLE_ELEMENTS: { |
| 9457 uint32_t length = IsJSArray() ? |
| 9458 static_cast<uint32_t>( |
| 9459 Smi::cast(JSArray::cast(this)->length())->value()) : |
| 9460 static_cast<uint32_t>(FixedDoubleArray::cast(elements())->length()); |
| 9461 return (index < length) && |
| 9462 !FixedDoubleArray::cast(elements())->is_the_hole(index); |
| 9463 break; |
| 9464 } |
9383 case EXTERNAL_PIXEL_ELEMENTS: { | 9465 case EXTERNAL_PIXEL_ELEMENTS: { |
9384 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); | 9466 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); |
9385 return index < static_cast<uint32_t>(pixels->length()); | 9467 return index < static_cast<uint32_t>(pixels->length()); |
9386 } | 9468 } |
9387 case EXTERNAL_BYTE_ELEMENTS: | 9469 case EXTERNAL_BYTE_ELEMENTS: |
9388 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 9470 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
9389 case EXTERNAL_SHORT_ELEMENTS: | 9471 case EXTERNAL_SHORT_ELEMENTS: |
9390 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 9472 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
9391 case EXTERNAL_INT_ELEMENTS: | 9473 case EXTERNAL_INT_ELEMENTS: |
9392 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 9474 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
9393 case EXTERNAL_FLOAT_ELEMENTS: | 9475 case EXTERNAL_FLOAT_ELEMENTS: |
9394 case EXTERNAL_DOUBLE_ELEMENTS: { | 9476 case EXTERNAL_DOUBLE_ELEMENTS: { |
9395 ExternalArray* array = ExternalArray::cast(elements()); | 9477 ExternalArray* array = ExternalArray::cast(elements()); |
9396 return index < static_cast<uint32_t>(array->length()); | 9478 return index < static_cast<uint32_t>(array->length()); |
9397 } | 9479 } |
9398 case FAST_DOUBLE_ELEMENTS: | |
9399 UNREACHABLE(); | |
9400 break; | |
9401 case DICTIONARY_ELEMENTS: { | 9480 case DICTIONARY_ELEMENTS: { |
9402 return element_dictionary()->FindEntry(index) | 9481 return element_dictionary()->FindEntry(index) |
9403 != NumberDictionary::kNotFound; | 9482 != NumberDictionary::kNotFound; |
9404 } | 9483 } |
9405 case NON_STRICT_ARGUMENTS_ELEMENTS: | 9484 case NON_STRICT_ARGUMENTS_ELEMENTS: |
9406 UNIMPLEMENTED(); | 9485 UNIMPLEMENTED(); |
9407 break; | 9486 break; |
9408 } | 9487 } |
9409 // All possibilities have been handled above already. | 9488 // All possibilities have been handled above already. |
9410 UNREACHABLE(); | 9489 UNREACHABLE(); |
(...skipping 2434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11845 if (break_point_objects()->IsUndefined()) return 0; | 11924 if (break_point_objects()->IsUndefined()) return 0; |
11846 // Single beak point. | 11925 // Single beak point. |
11847 if (!break_point_objects()->IsFixedArray()) return 1; | 11926 if (!break_point_objects()->IsFixedArray()) return 1; |
11848 // Multiple break points. | 11927 // Multiple break points. |
11849 return FixedArray::cast(break_point_objects())->length(); | 11928 return FixedArray::cast(break_point_objects())->length(); |
11850 } | 11929 } |
11851 #endif | 11930 #endif |
11852 | 11931 |
11853 | 11932 |
11854 } } // namespace v8::internal | 11933 } } // namespace v8::internal |
OLD | NEW |