Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(190)

Side by Side Diff: src/objects.cc

Issue 7542008: Properly handle FixedDoubleArrays in sort() (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-91008.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-91008.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698