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 |