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 10661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10672 Object* new_array; | 10672 Object* new_array; |
10673 { MaybeObject* maybe_new_array = | 10673 { MaybeObject* maybe_new_array = |
10674 heap->AllocateFixedArray(dict->NumberOfElements(), tenure); | 10674 heap->AllocateFixedArray(dict->NumberOfElements(), tenure); |
10675 if (!maybe_new_array->ToObject(&new_array)) return maybe_new_array; | 10675 if (!maybe_new_array->ToObject(&new_array)) return maybe_new_array; |
10676 } | 10676 } |
10677 FixedArray* fast_elements = FixedArray::cast(new_array); | 10677 FixedArray* fast_elements = FixedArray::cast(new_array); |
10678 dict->CopyValuesTo(fast_elements); | 10678 dict->CopyValuesTo(fast_elements); |
10679 | 10679 |
10680 set_map(new_map); | 10680 set_map(new_map); |
10681 set_elements(fast_elements); | 10681 set_elements(fast_elements); |
10682 } else { | 10682 } else if (!HasFastDoubleElements()) { |
10683 Object* obj; | 10683 Object* obj; |
10684 { MaybeObject* maybe_obj = EnsureWritableFastElements(); | 10684 { MaybeObject* maybe_obj = EnsureWritableFastElements(); |
10685 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 10685 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
10686 } | 10686 } |
10687 } | 10687 } |
10688 ASSERT(HasFastElements()); | 10688 ASSERT(HasFastElements() || HasFastDoubleElements()); |
10689 | 10689 |
10690 // Collect holes at the end, undefined before that and the rest at the | 10690 // Collect holes at the end, undefined before that and the rest at the |
10691 // start, and return the number of non-hole, non-undefined values. | 10691 // start, and return the number of non-hole, non-undefined values. |
10692 | 10692 |
10693 FixedArray* elements = FixedArray::cast(this->elements()); | 10693 FixedArrayBase* elements_base = FixedArrayBase::cast(this->elements()); |
10694 uint32_t elements_length = static_cast<uint32_t>(elements->length()); | 10694 uint32_t elements_length = static_cast<uint32_t>(elements_base->length()); |
10695 if (limit > elements_length) { | 10695 if (limit > elements_length) { |
10696 limit = elements_length ; | 10696 limit = elements_length ; |
10697 } | 10697 } |
10698 if (limit == 0) { | 10698 if (limit == 0) { |
10699 return Smi::FromInt(0); | 10699 return Smi::FromInt(0); |
10700 } | 10700 } |
10701 | 10701 |
10702 HeapNumber* result_double = NULL; | 10702 HeapNumber* result_double = NULL; |
10703 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { | 10703 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { |
10704 // Pessimistically allocate space for return value before | 10704 // Pessimistically allocate space for return value before |
10705 // we start mutating the array. | 10705 // we start mutating the array. |
10706 Object* new_double; | 10706 Object* new_double; |
10707 { MaybeObject* maybe_new_double = heap->AllocateHeapNumber(0.0); | 10707 { MaybeObject* maybe_new_double = heap->AllocateHeapNumber(0.0); |
10708 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double; | 10708 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double; |
10709 } | 10709 } |
10710 result_double = HeapNumber::cast(new_double); | 10710 result_double = HeapNumber::cast(new_double); |
10711 } | 10711 } |
10712 | 10712 |
10713 AssertNoAllocation no_alloc; | 10713 uint32_t result = 0; |
| 10714 if (elements_base->map() == heap->fixed_double_array_map()) { |
| 10715 FixedDoubleArray* elements = FixedDoubleArray::cast(elements_base); |
| 10716 // Split elements into defined and the_hole, in that order. |
| 10717 unsigned int holes = limit; |
| 10718 // Assume most arrays contain no holes and undefined values, so minimize the |
| 10719 // number of stores of non-undefined, non-the-hole values. |
| 10720 for (unsigned int i = 0; i < holes; i++) { |
| 10721 if (elements->is_the_hole(i)) { |
| 10722 holes--; |
| 10723 } else { |
| 10724 continue; |
| 10725 } |
| 10726 // Position i needs to be filled. |
| 10727 while (holes > i) { |
| 10728 if (elements->is_the_hole(holes)) { |
| 10729 holes--; |
| 10730 } else { |
| 10731 elements->set(i, elements->get(holes)); |
| 10732 break; |
| 10733 } |
| 10734 } |
| 10735 } |
| 10736 result = holes; |
| 10737 while (holes < limit) { |
| 10738 elements->set_the_hole(holes); |
| 10739 holes++; |
| 10740 } |
| 10741 } else { |
| 10742 FixedArray* elements = FixedArray::cast(elements_base); |
| 10743 AssertNoAllocation no_alloc; |
10714 | 10744 |
10715 // Split elements into defined, undefined and the_hole, in that order. | 10745 // Split elements into defined, undefined and the_hole, in that order. Only |
10716 // Only count locations for undefined and the hole, and fill them afterwards. | 10746 // count locations for undefined and the hole, and fill them afterwards. |
10717 WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_alloc); | 10747 WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_alloc); |
10718 unsigned int undefs = limit; | 10748 unsigned int undefs = limit; |
10719 unsigned int holes = limit; | 10749 unsigned int holes = limit; |
10720 // Assume most arrays contain no holes and undefined values, so minimize the | 10750 // Assume most arrays contain no holes and undefined values, so minimize the |
10721 // number of stores of non-undefined, non-the-hole values. | 10751 // number of stores of non-undefined, non-the-hole values. |
10722 for (unsigned int i = 0; i < undefs; i++) { | 10752 for (unsigned int i = 0; i < undefs; i++) { |
10723 Object* current = elements->get(i); | 10753 Object* current = elements->get(i); |
10724 if (current->IsTheHole()) { | |
10725 holes--; | |
10726 undefs--; | |
10727 } else if (current->IsUndefined()) { | |
10728 undefs--; | |
10729 } else { | |
10730 continue; | |
10731 } | |
10732 // Position i needs to be filled. | |
10733 while (undefs > i) { | |
10734 current = elements->get(undefs); | |
10735 if (current->IsTheHole()) { | 10754 if (current->IsTheHole()) { |
10736 holes--; | 10755 holes--; |
10737 undefs--; | 10756 undefs--; |
10738 } else if (current->IsUndefined()) { | 10757 } else if (current->IsUndefined()) { |
10739 undefs--; | 10758 undefs--; |
10740 } else { | 10759 } else { |
10741 elements->set(i, current, write_barrier); | 10760 continue; |
10742 break; | 10761 } |
| 10762 // Position i needs to be filled. |
| 10763 while (undefs > i) { |
| 10764 current = elements->get(undefs); |
| 10765 if (current->IsTheHole()) { |
| 10766 holes--; |
| 10767 undefs--; |
| 10768 } else if (current->IsUndefined()) { |
| 10769 undefs--; |
| 10770 } else { |
| 10771 elements->set(i, current, write_barrier); |
| 10772 break; |
| 10773 } |
10743 } | 10774 } |
10744 } | 10775 } |
10745 } | 10776 result = undefs; |
10746 uint32_t result = undefs; | 10777 while (undefs < holes) { |
10747 while (undefs < holes) { | 10778 elements->set_undefined(undefs); |
10748 elements->set_undefined(undefs); | 10779 undefs++; |
10749 undefs++; | 10780 } |
10750 } | 10781 while (holes < limit) { |
10751 while (holes < limit) { | 10782 elements->set_the_hole(holes); |
10752 elements->set_the_hole(holes); | 10783 holes++; |
10753 holes++; | 10784 } |
10754 } | 10785 } |
10755 | 10786 |
10756 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { | 10787 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { |
10757 return Smi::FromInt(static_cast<int>(result)); | 10788 return Smi::FromInt(static_cast<int>(result)); |
10758 } | 10789 } |
10759 ASSERT_NE(NULL, result_double); | 10790 ASSERT_NE(NULL, result_double); |
10760 result_double->set_value(static_cast<double>(result)); | 10791 result_double->set_value(static_cast<double>(result)); |
10761 return result_double; | 10792 return result_double; |
10762 } | 10793 } |
10763 | 10794 |
(...skipping 1319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12083 if (break_point_objects()->IsUndefined()) return 0; | 12114 if (break_point_objects()->IsUndefined()) return 0; |
12084 // Single beak point. | 12115 // Single beak point. |
12085 if (!break_point_objects()->IsFixedArray()) return 1; | 12116 if (!break_point_objects()->IsFixedArray()) return 1; |
12086 // Multiple break points. | 12117 // Multiple break points. |
12087 return FixedArray::cast(break_point_objects())->length(); | 12118 return FixedArray::cast(break_point_objects())->length(); |
12088 } | 12119 } |
12089 #endif | 12120 #endif |
12090 | 12121 |
12091 | 12122 |
12092 } } // namespace v8::internal | 12123 } } // namespace v8::internal |
OLD | NEW |