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

Side by Side Diff: src/objects.cc

Issue 10808011: Let DescriptorArray::Append insert at proper position, avoiding need for resorting. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments Created 8 years, 5 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 | « src/objects.h ('k') | src/objects-inl.h » ('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 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
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
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
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(&copy)) return maybe_copy; 5856 if (!maybe_copy->To(&copy)) 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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698