| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 5682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5693 void DescriptorArray::CopyFrom(int dst_index, | 5693 void DescriptorArray::CopyFrom(int dst_index, |
| 5694 DescriptorArray* src, | 5694 DescriptorArray* src, |
| 5695 int src_index, | 5695 int src_index, |
| 5696 const WhitenessWitness& witness) { | 5696 const WhitenessWitness& witness) { |
| 5697 Object* value = src->GetValue(src_index); | 5697 Object* value = src->GetValue(src_index); |
| 5698 PropertyDetails details = src->GetDetails(src_index); | 5698 PropertyDetails details = src->GetDetails(src_index); |
| 5699 Descriptor desc(src->GetKey(src_index), value, details); | 5699 Descriptor desc(src->GetKey(src_index), value, details); |
| 5700 Set(dst_index, &desc, witness); | 5700 Set(dst_index, &desc, witness); |
| 5701 } | 5701 } |
| 5702 | 5702 |
| 5703 |
| 5703 MaybeObject* DescriptorArray::CopyReplace(Descriptor* descriptor, | 5704 MaybeObject* DescriptorArray::CopyReplace(Descriptor* descriptor, |
| 5704 int insertion_index) { | 5705 int insertion_index) { |
| 5705 ASSERT(0 <= insertion_index && insertion_index < number_of_descriptors()); | 5706 ASSERT(0 <= insertion_index && insertion_index < number_of_descriptors()); |
| 5706 | 5707 |
| 5707 // Ensure the key is a symbol. | 5708 // Ensure the key is a symbol. |
| 5708 { MaybeObject* maybe_result = descriptor->KeyToSymbol(); | 5709 MaybeObject* maybe_failure = descriptor->KeyToSymbol(); |
| 5709 if (maybe_result->IsFailure()) return maybe_result; | 5710 if (maybe_failure->IsFailure()) return maybe_failure; |
| 5710 } | |
| 5711 | 5711 |
| 5712 int size = number_of_descriptors(); | 5712 int size = number_of_descriptors(); |
| 5713 | 5713 |
| 5714 DescriptorArray* new_descriptors; | 5714 DescriptorArray* new_descriptors; |
| 5715 { MaybeObject* maybe_result = Allocate(size, MAY_BE_SHARED); | 5715 MaybeObject* maybe_descriptors = Allocate(size, MAY_BE_SHARED); |
| 5716 if (!maybe_result->To(&new_descriptors)) return maybe_result; | 5716 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; |
| 5717 } | |
| 5718 | 5717 |
| 5719 FixedArray::WhitenessWitness witness(new_descriptors); | 5718 FixedArray::WhitenessWitness witness(new_descriptors); |
| 5720 | 5719 |
| 5721 // Copy the descriptors, replacing a descriptor. | 5720 // Copy the descriptors, replacing a descriptor. |
| 5722 for (int index = 0; index < size; ++index) { | 5721 for (int index = 0; index < size; ++index) { |
| 5723 if (index == insertion_index) continue; | 5722 if (index == insertion_index) continue; |
| 5724 new_descriptors->CopyFrom(index, this, index, witness); | 5723 new_descriptors->CopyFrom(index, this, index, witness); |
| 5725 } | 5724 } |
| 5726 | 5725 |
| 5727 descriptor->SetEnumerationIndex(GetDetails(insertion_index).index()); | 5726 descriptor->SetEnumerationIndex(GetDetails(insertion_index).index()); |
| 5728 new_descriptors->Set(insertion_index, descriptor, witness); | 5727 new_descriptors->Set(insertion_index, descriptor, witness); |
| 5729 new_descriptors->SetLastAdded(LastAdded()); | 5728 new_descriptors->SetLastAdded(LastAdded()); |
| 5730 | 5729 |
| 5731 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates()); | 5730 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates()); |
| 5732 | 5731 |
| 5733 return new_descriptors; | 5732 return new_descriptors; |
| 5734 } | 5733 } |
| 5735 | 5734 |
| 5736 | 5735 |
| 5737 MaybeObject* DescriptorArray::CopyAdd(Descriptor* descriptor) { | 5736 MaybeObject* DescriptorArray::CopyAdd(Descriptor* descriptor) { |
| 5738 // Ensure the key is a symbol. | 5737 // Ensure the key is a symbol. |
| 5739 MaybeObject* maybe_result = descriptor->KeyToSymbol(); | 5738 MaybeObject* maybe_failure = descriptor->KeyToSymbol(); |
| 5740 if (maybe_result->IsFailure()) return maybe_result; | 5739 if (maybe_failure->IsFailure()) return maybe_failure; |
| 5741 | 5740 |
| 5742 String* key = descriptor->GetKey(); | 5741 String* key = descriptor->GetKey(); |
| 5743 ASSERT(Search(key) == kNotFound); | 5742 ASSERT(Search(key) == kNotFound); |
| 5744 | 5743 |
| 5745 int new_size = number_of_descriptors() + 1; | 5744 int new_size = number_of_descriptors() + 1; |
| 5746 | 5745 |
| 5747 DescriptorArray* new_descriptors; | 5746 DescriptorArray* new_descriptors; |
| 5748 MaybeObject* maybe_descriptors = Allocate(new_size, MAY_BE_SHARED); | 5747 MaybeObject* maybe_descriptors = Allocate(new_size, MAY_BE_SHARED); |
| 5749 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; | 5748 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; |
| 5750 | 5749 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5786 FixedArray::WhitenessWitness witness(new_descriptors); | 5785 FixedArray::WhitenessWitness witness(new_descriptors); |
| 5787 for (int i = 0; i < number_of_descriptors; i++) { | 5786 for (int i = 0; i < number_of_descriptors; i++) { |
| 5788 new_descriptors->CopyFrom(i, this, i, witness); | 5787 new_descriptors->CopyFrom(i, this, i, witness); |
| 5789 } | 5788 } |
| 5790 new_descriptors->SetLastAdded(LastAdded()); | 5789 new_descriptors->SetLastAdded(LastAdded()); |
| 5791 } | 5790 } |
| 5792 | 5791 |
| 5793 return new_descriptors; | 5792 return new_descriptors; |
| 5794 } | 5793 } |
| 5795 | 5794 |
| 5795 |
| 5796 // We need the whiteness witness since sort will reshuffle the entries in the | 5796 // We need the whiteness witness since sort will reshuffle the entries in the |
| 5797 // descriptor array. If the descriptor array were to be black, the shuffling | 5797 // descriptor array. If the descriptor array were to be black, the shuffling |
| 5798 // would move a slot that was already recorded as pointing into an evacuation | 5798 // would move a slot that was already recorded as pointing into an evacuation |
| 5799 // candidate. This would result in missing updates upon evacuation. | 5799 // candidate. This would result in missing updates upon evacuation. |
| 5800 void DescriptorArray::SortUnchecked(const WhitenessWitness& witness) { | 5800 void DescriptorArray::Sort(const WhitenessWitness& witness) { |
| 5801 // In-place heap sort. | 5801 // In-place heap sort. |
| 5802 int len = number_of_descriptors(); | 5802 int len = number_of_descriptors(); |
| 5803 // Nothing to sort. | |
| 5804 if (len == 0) return; | |
| 5805 | |
| 5806 ASSERT(LastAdded() == kNoneAdded || | |
| 5807 GetDetails(LastAdded()).index() == number_of_descriptors()); | |
| 5808 | |
| 5809 // Bottom-up max-heap construction. | 5803 // Bottom-up max-heap construction. |
| 5810 // Index of the last node with children | 5804 // Index of the last node with children |
| 5811 const int max_parent_index = (len / 2) - 1; | 5805 const int max_parent_index = (len / 2) - 1; |
| 5812 for (int i = max_parent_index; i >= 0; --i) { | 5806 for (int i = max_parent_index; i >= 0; --i) { |
| 5813 int parent_index = i; | 5807 int parent_index = i; |
| 5814 const uint32_t parent_hash = GetKey(i)->Hash(); | 5808 const uint32_t parent_hash = GetKey(i)->Hash(); |
| 5815 while (parent_index <= max_parent_index) { | 5809 while (parent_index <= max_parent_index) { |
| 5816 int child_index = 2 * parent_index + 1; | 5810 int child_index = 2 * parent_index + 1; |
| 5817 uint32_t child_hash = GetKey(child_index)->Hash(); | 5811 uint32_t child_hash = GetKey(child_index)->Hash(); |
| 5818 if (child_index + 1 < len) { | 5812 if (child_index + 1 < len) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 5845 if (right_child_hash > child_hash) { | 5839 if (right_child_hash > child_hash) { |
| 5846 child_index++; | 5840 child_index++; |
| 5847 child_hash = right_child_hash; | 5841 child_hash = right_child_hash; |
| 5848 } | 5842 } |
| 5849 } | 5843 } |
| 5850 if (child_hash <= parent_hash) break; | 5844 if (child_hash <= parent_hash) break; |
| 5851 NoIncrementalWriteBarrierSwapDescriptors(parent_index, child_index); | 5845 NoIncrementalWriteBarrierSwapDescriptors(parent_index, child_index); |
| 5852 parent_index = child_index; | 5846 parent_index = child_index; |
| 5853 } | 5847 } |
| 5854 } | 5848 } |
| 5855 | |
| 5856 #ifdef DEBUG | |
| 5857 // Ensure that all enumeration indexes between 1 and length occur uniquely in | |
| 5858 // the descriptor array. | |
| 5859 for (int i = 1; i <= len; ++i) { | |
| 5860 int j; | |
| 5861 for (j = 0; j < len; ++j) { | |
| 5862 if (GetDetails(j).index() == i) break; | |
| 5863 } | |
| 5864 ASSERT(j != len); | |
| 5865 for (j++; j < len; ++j) { | |
| 5866 ASSERT(GetDetails(j).index() != i); | |
| 5867 } | |
| 5868 } | |
| 5869 #endif | |
| 5870 | |
| 5871 for (int i = 0; i < len; ++i) { | |
| 5872 if (GetDetails(i).index() == len) { | |
| 5873 SetLastAdded(i); | |
| 5874 return; | |
| 5875 } | |
| 5876 } | |
| 5877 | |
| 5878 UNREACHABLE(); | |
| 5879 } | 5849 } |
| 5880 | 5850 |
| 5881 | 5851 |
| 5882 void DescriptorArray::Sort(const WhitenessWitness& witness) { | |
| 5883 SortUnchecked(witness); | |
| 5884 SLOW_ASSERT(IsSortedNoDuplicates()); | |
| 5885 } | |
| 5886 | |
| 5887 | |
| 5888 MaybeObject* AccessorPair::Copy() { | 5852 MaybeObject* AccessorPair::Copy() { |
| 5889 Heap* heap = GetHeap(); | 5853 Heap* heap = GetHeap(); |
| 5890 AccessorPair* copy; | 5854 AccessorPair* copy; |
| 5891 MaybeObject* maybe_copy = heap->AllocateAccessorPair(); | 5855 MaybeObject* maybe_copy = heap->AllocateAccessorPair(); |
| 5892 if (!maybe_copy->To(©)) return maybe_copy; | 5856 if (!maybe_copy->To(©)) return maybe_copy; |
| 5893 | 5857 |
| 5894 copy->set_getter(getter()); | 5858 copy->set_getter(getter()); |
| 5895 copy->set_setter(setter()); | 5859 copy->set_setter(setter()); |
| 5896 return copy; | 5860 return copy; |
| 5897 } | 5861 } |
| (...skipping 6650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12548 UNREACHABLE(); | 12512 UNREACHABLE(); |
| 12549 } | 12513 } |
| 12550 ++next_descriptor; | 12514 ++next_descriptor; |
| 12551 } | 12515 } |
| 12552 } | 12516 } |
| 12553 ASSERT(current_offset == number_of_fields); | 12517 ASSERT(current_offset == number_of_fields); |
| 12554 | 12518 |
| 12555 descriptors->Sort(witness); | 12519 descriptors->Sort(witness); |
| 12556 // Allocate new map. | 12520 // Allocate new map. |
| 12557 Map* new_map; | 12521 Map* new_map; |
| 12558 MaybeObject* maybe_new_map = | 12522 MaybeObject* maybe_new_map = obj->map()->CopyDropDescriptors(); |
| 12559 obj->map()->CopyReplaceDescriptors(descriptors, NULL, OMIT_TRANSITION); | |
| 12560 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | 12523 if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
| 12561 | 12524 |
| 12525 new_map->InitializeDescriptors(descriptors); |
| 12562 new_map->set_unused_property_fields(unused_property_fields); | 12526 new_map->set_unused_property_fields(unused_property_fields); |
| 12563 | 12527 |
| 12564 // Transform the object. | 12528 // Transform the object. |
| 12565 obj->set_map(new_map); | 12529 obj->set_map(new_map); |
| 12566 | 12530 |
| 12567 obj->set_properties(fields); | 12531 obj->set_properties(fields); |
| 12568 ASSERT(obj->IsJSObject()); | 12532 ASSERT(obj->IsJSObject()); |
| 12569 | 12533 |
| 12570 // Check that it really works. | 12534 // Check that it really works. |
| 12571 ASSERT(obj->HasFastProperties()); | 12535 ASSERT(obj->HasFastProperties()); |
| (...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13071 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 13035 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
| 13072 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 13036 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
| 13073 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 13037 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
| 13074 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 13038 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
| 13075 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 13039 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
| 13076 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 13040 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
| 13077 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 13041 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
| 13078 } | 13042 } |
| 13079 | 13043 |
| 13080 } } // namespace v8::internal | 13044 } } // namespace v8::internal |
| OLD | NEW |