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 1759 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1770 // to store distinct descriptor arrays. | 1770 // to store distinct descriptor arrays. |
1771 | 1771 |
1772 // If the old_target did not yet store its own descriptors, the new | 1772 // If the old_target did not yet store its own descriptors, the new |
1773 // descriptors pointer is created for the old_target by temporarily clearing | 1773 // descriptors pointer is created for the old_target by temporarily clearing |
1774 // the back pointer and setting its descriptor array. | 1774 // the back pointer and setting its descriptor array. |
1775 | 1775 |
1776 // This phase is executed before creating the new map since it requires | 1776 // This phase is executed before creating the new map since it requires |
1777 // allocation that may fail. | 1777 // allocation that may fail. |
1778 if (!old_target->StoresOwnDescriptors()) { | 1778 if (!old_target->StoresOwnDescriptors()) { |
1779 DescriptorArray* old_descriptors = old_map->instance_descriptors(); | 1779 DescriptorArray* old_descriptors = old_map->instance_descriptors(); |
1780 | |
1781 old_target->SetBackPointer(GetHeap()->undefined_value()); | |
1782 MaybeObject* maybe_failure = old_target->SetDescriptors(old_descriptors); | 1780 MaybeObject* maybe_failure = old_target->SetDescriptors(old_descriptors); |
1783 // Reset the backpointer before returning failure, otherwise the map ends up | |
1784 // with an undefined backpointer and no descriptors, losing its own | |
1785 // descriptors. Setting the backpointer always succeeds. | |
1786 old_target->SetBackPointer(old_map); | |
1787 if (maybe_failure->IsFailure()) return maybe_failure; | 1781 if (maybe_failure->IsFailure()) return maybe_failure; |
1788 } | 1782 } |
1789 | 1783 |
1790 MaybeObject* maybe_result = | 1784 MaybeObject* maybe_result = |
1791 ConvertDescriptorToField(name, new_value, attributes); | 1785 ConvertDescriptorToField(name, new_value, attributes); |
1792 if (!maybe_result->To(&result)) return maybe_result; | 1786 if (!maybe_result->To(&result)) return maybe_result; |
1793 | 1787 |
1794 if (!HasFastProperties()) return result; | 1788 if (!HasFastProperties()) return result; |
1795 | 1789 |
1796 // This method should only be used to convert existing transitions. Objects | 1790 // This method should only be used to convert existing transitions. Objects |
1797 // with the map of "new Object()" cannot have transitions in the first place. | 1791 // with the map of "new Object()" cannot have transitions in the first place. |
1798 Map* new_map = map(); | 1792 Map* new_map = map(); |
1799 ASSERT(new_map != GetIsolate()->empty_object_map()); | 1793 ASSERT(new_map != GetIsolate()->empty_object_map()); |
1800 | 1794 |
1801 // TODO(verwaest): From here on we lose existing map transitions, causing | 1795 // TODO(verwaest): From here on we lose existing map transitions, causing |
1802 // invalid back pointers. This will change once we can store multiple | 1796 // invalid back pointers. This will change once we can store multiple |
1803 // transitions with the same key. | 1797 // transitions with the same key. |
1804 | 1798 |
1805 if (old_map->owns_descriptors()) { | 1799 bool owned_descriptors = old_map->owns_descriptors(); |
1806 // If the old map owns its own descriptors, transfer ownership to the | 1800 if (owned_descriptors || |
1807 // new_map and install its descriptors in the old_map. Since the old_map | 1801 old_target->instance_descriptors() == old_map->instance_descriptors()) { |
1808 // stores the descriptors for the new_map, remove the transition array of | |
1809 // the new_map that is only in place to store the descriptors. | |
1810 old_map->transitions()->descriptors_pointer()->set_value( | |
1811 new_map->instance_descriptors()); | |
1812 new_map->ClearTransitions(GetHeap()); | |
1813 old_map->set_owns_descriptors(false); | |
1814 } else if (old_target->instance_descriptors() == | |
1815 old_map->instance_descriptors()) { | |
1816 // Since the conversion above generated a new fast map with an additional | 1802 // Since the conversion above generated a new fast map with an additional |
1817 // property which can be shared as well, install this descriptor pointer | 1803 // property which can be shared as well, install this descriptor pointer |
1818 // along the entire chain of smaller maps; and remove the transition array | 1804 // along the entire chain of smaller maps; and remove the transition array |
1819 // that is only in place to hold the descriptor array in the new map. | 1805 // that is only in place to hold the descriptor array in the new map. |
1820 Map* map; | 1806 Map* map; |
1821 JSGlobalPropertyCell* new_pointer = | 1807 DescriptorArray* new_descriptors = new_map->instance_descriptors(); |
1822 new_map->transitions()->descriptors_pointer(); | 1808 DescriptorArray* old_descriptors = old_map->instance_descriptors(); |
1823 JSGlobalPropertyCell* old_pointer = | |
1824 old_map->transitions()->descriptors_pointer(); | |
1825 for (Object* current = old_map; | 1809 for (Object* current = old_map; |
1826 !current->IsUndefined(); | 1810 !current->IsUndefined(); |
1827 current = map->GetBackPointer()) { | 1811 current = map->GetBackPointer()) { |
1828 map = Map::cast(current); | 1812 map = Map::cast(current); |
1829 if (!map->HasTransitionArray()) break; | 1813 if (!map->HasTransitionArray()) break; |
1830 TransitionArray* transitions = map->transitions(); | 1814 TransitionArray* transitions = map->transitions(); |
1831 if (transitions->descriptors_pointer() != old_pointer) break; | 1815 if (transitions->descriptors() != old_descriptors) break; |
1832 map->SetEnumLength(Map::kInvalidEnumCache); | 1816 // Invalidate the enum caches only if the map did not own its descriptors. |
1833 transitions->set_descriptors_pointer(new_pointer); | 1817 if (!owned_descriptors) map->SetEnumLength(Map::kInvalidEnumCache); |
| 1818 transitions->set_descriptors(new_descriptors); |
1834 } | 1819 } |
| 1820 old_map->set_owns_descriptors(false); |
1835 new_map->ClearTransitions(GetHeap()); | 1821 new_map->ClearTransitions(GetHeap()); |
1836 } | 1822 } |
1837 | 1823 |
1838 old_map->SetTransition(transition_index, new_map); | 1824 old_map->SetTransition(transition_index, new_map); |
1839 new_map->SetBackPointer(old_map); | 1825 new_map->SetBackPointer(old_map); |
1840 return result; | 1826 return result; |
1841 } | 1827 } |
1842 | 1828 |
1843 | 1829 |
1844 MaybeObject* JSObject::ConvertDescriptorToField(String* name, | 1830 MaybeObject* JSObject::ConvertDescriptorToField(String* name, |
(...skipping 3123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4968 result->set_inobject_properties(inobject_properties()); | 4954 result->set_inobject_properties(inobject_properties()); |
4969 result->set_unused_property_fields(unused_property_fields()); | 4955 result->set_unused_property_fields(unused_property_fields()); |
4970 | 4956 |
4971 result->set_pre_allocated_property_fields(pre_allocated_property_fields()); | 4957 result->set_pre_allocated_property_fields(pre_allocated_property_fields()); |
4972 result->set_is_shared(false); | 4958 result->set_is_shared(false); |
4973 result->ClearCodeCache(GetHeap()); | 4959 result->ClearCodeCache(GetHeap()); |
4974 return result; | 4960 return result; |
4975 } | 4961 } |
4976 | 4962 |
4977 | 4963 |
4978 MaybeObject* Map::ShareDescriptor(Descriptor* descriptor) { | 4964 MaybeObject* Map::ShareDescriptor(DescriptorArray* descriptors, |
| 4965 Descriptor* descriptor) { |
4979 // Sanity check. This path is only to be taken if the map owns its descriptor | 4966 // Sanity check. This path is only to be taken if the map owns its descriptor |
4980 // array, implying that its NumberOfOwnDescriptors equals the number of | 4967 // array, implying that its NumberOfOwnDescriptors equals the number of |
4981 // descriptors in the descriptor array. | 4968 // descriptors in the descriptor array. |
4982 if (NumberOfOwnDescriptors() != | 4969 ASSERT(NumberOfOwnDescriptors() == |
4983 instance_descriptors()->number_of_descriptors()) { | 4970 instance_descriptors()->number_of_descriptors()); |
4984 Isolate::Current()->PushStackTraceAndDie( | |
4985 0xDEAD0002, GetBackPointer(), this, 0xDEAD0003); | |
4986 } | |
4987 Map* result; | 4971 Map* result; |
4988 MaybeObject* maybe_result = CopyDropDescriptors(); | 4972 MaybeObject* maybe_result = CopyDropDescriptors(); |
4989 if (!maybe_result->To(&result)) return maybe_result; | 4973 if (!maybe_result->To(&result)) return maybe_result; |
4990 | 4974 |
4991 String* name = descriptor->GetKey(); | 4975 String* name = descriptor->GetKey(); |
4992 | 4976 |
4993 TransitionArray* transitions; | 4977 TransitionArray* transitions; |
4994 MaybeObject* maybe_transitions = | 4978 MaybeObject* maybe_transitions = |
4995 AddTransition(name, result, SIMPLE_TRANSITION); | 4979 AddTransition(name, result, SIMPLE_TRANSITION); |
4996 if (!maybe_transitions->To(&transitions)) return maybe_transitions; | 4980 if (!maybe_transitions->To(&transitions)) return maybe_transitions; |
4997 | 4981 |
4998 DescriptorArray* descriptors = instance_descriptors(); | |
4999 int old_size = descriptors->number_of_descriptors(); | 4982 int old_size = descriptors->number_of_descriptors(); |
5000 | 4983 |
5001 DescriptorArray* new_descriptors; | 4984 DescriptorArray* new_descriptors; |
5002 | 4985 |
5003 if (descriptors->NumberOfSlackDescriptors() > 0) { | 4986 if (descriptors->NumberOfSlackDescriptors() > 0) { |
5004 new_descriptors = descriptors; | 4987 new_descriptors = descriptors; |
5005 new_descriptors->Append(descriptor); | 4988 new_descriptors->Append(descriptor); |
5006 } else { | 4989 } else { |
5007 // Descriptor arrays grow by 50%. | 4990 // Descriptor arrays grow by 50%. |
5008 MaybeObject* maybe_descriptors = DescriptorArray::Allocate( | 4991 MaybeObject* maybe_descriptors = DescriptorArray::Allocate( |
(...skipping 10 matching lines...) Expand all Loading... |
5019 new_descriptors->Append(descriptor, witness); | 5002 new_descriptors->Append(descriptor, witness); |
5020 | 5003 |
5021 // If the source descriptors had an enum cache we copy it. This ensures that | 5004 // If the source descriptors had an enum cache we copy it. This ensures that |
5022 // the maps to which we push the new descriptor array back can rely on a | 5005 // the maps to which we push the new descriptor array back can rely on a |
5023 // cache always being available once it is set. If the map has more | 5006 // cache always being available once it is set. If the map has more |
5024 // enumerated descriptors than available in the original cache, the cache | 5007 // enumerated descriptors than available in the original cache, the cache |
5025 // will be lazily replaced by the extended cache when needed. | 5008 // will be lazily replaced by the extended cache when needed. |
5026 if (descriptors->HasEnumCache()) { | 5009 if (descriptors->HasEnumCache()) { |
5027 new_descriptors->CopyEnumCacheFrom(descriptors); | 5010 new_descriptors->CopyEnumCacheFrom(descriptors); |
5028 } | 5011 } |
| 5012 |
| 5013 Map* map; |
| 5014 // Replace descriptors by new_descriptors in all maps that share it. |
| 5015 for (Object* current = GetBackPointer(); |
| 5016 !current->IsUndefined(); |
| 5017 current = map->GetBackPointer()) { |
| 5018 map = Map::cast(current); |
| 5019 if (!map->HasTransitionArray()) break; |
| 5020 TransitionArray* transitions = map->transitions(); |
| 5021 if (transitions->descriptors() != descriptors) break; |
| 5022 transitions->set_descriptors(new_descriptors); |
| 5023 } |
| 5024 |
| 5025 transitions->set_descriptors(new_descriptors); |
5029 } | 5026 } |
5030 | 5027 |
5031 transitions->set_descriptors(new_descriptors); | |
5032 | |
5033 set_transitions(transitions); | 5028 set_transitions(transitions); |
5034 result->SetBackPointer(this); | 5029 result->SetBackPointer(this); |
5035 set_owns_descriptors(false); | 5030 set_owns_descriptors(false); |
5036 | 5031 |
5037 result->SetNumberOfOwnDescriptors(new_descriptors->number_of_descriptors()); | 5032 result->SetNumberOfOwnDescriptors(new_descriptors->number_of_descriptors()); |
5038 ASSERT(result->NumberOfOwnDescriptors() == NumberOfOwnDescriptors() + 1); | 5033 ASSERT(result->NumberOfOwnDescriptors() == NumberOfOwnDescriptors() + 1); |
5039 | 5034 |
5040 return result; | 5035 return result; |
5041 } | 5036 } |
5042 | 5037 |
(...skipping 23 matching lines...) Expand all Loading... |
5066 ? SIMPLE_TRANSITION | 5061 ? SIMPLE_TRANSITION |
5067 : FULL_TRANSITION; | 5062 : FULL_TRANSITION; |
5068 MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag); | 5063 MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag); |
5069 if (!maybe_transitions->To(&transitions)) return maybe_transitions; | 5064 if (!maybe_transitions->To(&transitions)) return maybe_transitions; |
5070 | 5065 |
5071 if (descriptors->IsEmpty()) { | 5066 if (descriptors->IsEmpty()) { |
5072 if (owns_descriptors()) { | 5067 if (owns_descriptors()) { |
5073 // If the copied map has no added fields, and the parent map owns its | 5068 // If the copied map has no added fields, and the parent map owns its |
5074 // descriptors, those descriptors have to be empty. In that case, | 5069 // descriptors, those descriptors have to be empty. In that case, |
5075 // transfer ownership of the descriptors to the new child. | 5070 // transfer ownership of the descriptors to the new child. |
5076 CHECK(instance_descriptors()->IsEmpty()); | 5071 ASSERT(instance_descriptors()->IsEmpty()); |
5077 set_owns_descriptors(false); | 5072 set_owns_descriptors(false); |
5078 } else { | 5073 } else { |
5079 // If the parent did not own its own descriptors, it may share a larger | 5074 // If the parent did not own its own descriptors, it may share a larger |
5080 // descriptors array already. In that case, force a split by setting | 5075 // descriptors array already. In that case, force a split by setting |
5081 // the descriptor array of the new map to the empty descriptor array. | 5076 // the descriptor array of the new map to the empty descriptor array. |
5082 MaybeObject* maybe_failure = | 5077 MaybeObject* maybe_failure = |
5083 result->SetDescriptors(GetHeap()->empty_descriptor_array()); | 5078 result->SetDescriptors(GetHeap()->empty_descriptor_array()); |
5084 if (maybe_failure->IsFailure()) return maybe_failure; | 5079 if (maybe_failure->IsFailure()) return maybe_failure; |
5085 } | 5080 } |
5086 } | 5081 } |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5194 MaybeObject* maybe_failure = descriptor->KeyToSymbol(); | 5189 MaybeObject* maybe_failure = descriptor->KeyToSymbol(); |
5195 if (maybe_failure->IsFailure()) return maybe_failure; | 5190 if (maybe_failure->IsFailure()) return maybe_failure; |
5196 | 5191 |
5197 int old_size = NumberOfOwnDescriptors(); | 5192 int old_size = NumberOfOwnDescriptors(); |
5198 int new_size = old_size + 1; | 5193 int new_size = old_size + 1; |
5199 descriptor->SetEnumerationIndex(new_size); | 5194 descriptor->SetEnumerationIndex(new_size); |
5200 | 5195 |
5201 if (flag == INSERT_TRANSITION && | 5196 if (flag == INSERT_TRANSITION && |
5202 owns_descriptors() && | 5197 owns_descriptors() && |
5203 CanHaveMoreTransitions()) { | 5198 CanHaveMoreTransitions()) { |
5204 return ShareDescriptor(descriptor); | 5199 return ShareDescriptor(descriptors, descriptor); |
5205 } | 5200 } |
5206 | 5201 |
5207 DescriptorArray* new_descriptors; | 5202 DescriptorArray* new_descriptors; |
5208 MaybeObject* maybe_descriptors = DescriptorArray::Allocate(old_size, 1); | 5203 MaybeObject* maybe_descriptors = DescriptorArray::Allocate(old_size, 1); |
5209 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; | 5204 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; |
5210 | 5205 |
5211 DescriptorArray::WhitenessWitness witness(new_descriptors); | 5206 DescriptorArray::WhitenessWitness witness(new_descriptors); |
5212 | 5207 |
5213 // Copy the descriptors, inserting a descriptor. | 5208 // Copy the descriptors, inserting a descriptor. |
5214 for (int i = 0; i < old_size; ++i) { | 5209 for (int i = 0; i < old_size; ++i) { |
(...skipping 19 matching lines...) Expand all Loading... |
5234 TransitionFlag flag) { | 5229 TransitionFlag flag) { |
5235 DescriptorArray* old_descriptors = instance_descriptors(); | 5230 DescriptorArray* old_descriptors = instance_descriptors(); |
5236 | 5231 |
5237 // Ensure the key is a symbol. | 5232 // Ensure the key is a symbol. |
5238 MaybeObject* maybe_result = descriptor->KeyToSymbol(); | 5233 MaybeObject* maybe_result = descriptor->KeyToSymbol(); |
5239 if (maybe_result->IsFailure()) return maybe_result; | 5234 if (maybe_result->IsFailure()) return maybe_result; |
5240 | 5235 |
5241 // We replace the key if it is already present. | 5236 // We replace the key if it is already present. |
5242 int index = old_descriptors->SearchWithCache(descriptor->GetKey(), this); | 5237 int index = old_descriptors->SearchWithCache(descriptor->GetKey(), this); |
5243 if (index != DescriptorArray::kNotFound) { | 5238 if (index != DescriptorArray::kNotFound) { |
5244 return CopyReplaceDescriptor(descriptor, index, flag); | 5239 return CopyReplaceDescriptor(old_descriptors, descriptor, index, flag); |
5245 } | 5240 } |
5246 return CopyAddDescriptor(descriptor, flag); | 5241 return CopyAddDescriptor(descriptor, flag); |
5247 } | 5242 } |
5248 | 5243 |
5249 | 5244 |
5250 MaybeObject* DescriptorArray::CopyUpTo(int enumeration_index) { | 5245 MaybeObject* DescriptorArray::CopyUpTo(int enumeration_index) { |
5251 if (enumeration_index == 0) return GetHeap()->empty_descriptor_array(); | 5246 if (enumeration_index == 0) return GetHeap()->empty_descriptor_array(); |
5252 | 5247 |
5253 int size = enumeration_index; | 5248 int size = enumeration_index; |
5254 | 5249 |
5255 DescriptorArray* descriptors; | 5250 DescriptorArray* descriptors; |
5256 MaybeObject* maybe_descriptors = Allocate(size); | 5251 MaybeObject* maybe_descriptors = Allocate(size); |
5257 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors; | 5252 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors; |
5258 DescriptorArray::WhitenessWitness witness(descriptors); | 5253 DescriptorArray::WhitenessWitness witness(descriptors); |
5259 | 5254 |
5260 for (int i = 0; i < size; ++i) { | 5255 for (int i = 0; i < size; ++i) { |
5261 descriptors->CopyFrom(i, this, i, witness); | 5256 descriptors->CopyFrom(i, this, i, witness); |
5262 } | 5257 } |
5263 | 5258 |
5264 if (number_of_descriptors() != enumeration_index) descriptors->Sort(); | 5259 if (number_of_descriptors() != enumeration_index) descriptors->Sort(); |
5265 | 5260 |
5266 return descriptors; | 5261 return descriptors; |
5267 } | 5262 } |
5268 | 5263 |
5269 | 5264 |
5270 MaybeObject* Map::CopyReplaceDescriptor(Descriptor* descriptor, | 5265 MaybeObject* Map::CopyReplaceDescriptor(DescriptorArray* descriptors, |
| 5266 Descriptor* descriptor, |
5271 int insertion_index, | 5267 int insertion_index, |
5272 TransitionFlag flag) { | 5268 TransitionFlag flag) { |
5273 // Ensure the key is a symbol. | 5269 // Ensure the key is a symbol. |
5274 MaybeObject* maybe_failure = descriptor->KeyToSymbol(); | 5270 MaybeObject* maybe_failure = descriptor->KeyToSymbol(); |
5275 if (maybe_failure->IsFailure()) return maybe_failure; | 5271 if (maybe_failure->IsFailure()) return maybe_failure; |
5276 | 5272 |
5277 DescriptorArray* descriptors = instance_descriptors(); | |
5278 | |
5279 String* key = descriptor->GetKey(); | 5273 String* key = descriptor->GetKey(); |
5280 ASSERT(key == descriptors->GetKey(insertion_index)); | 5274 ASSERT(key == descriptors->GetKey(insertion_index)); |
5281 | 5275 |
5282 int new_size = NumberOfOwnDescriptors(); | 5276 int new_size = NumberOfOwnDescriptors(); |
5283 ASSERT(0 <= insertion_index && insertion_index < new_size); | 5277 ASSERT(0 <= insertion_index && insertion_index < new_size); |
5284 | 5278 |
5285 PropertyDetails details = descriptors->GetDetails(insertion_index); | 5279 PropertyDetails details = descriptors->GetDetails(insertion_index); |
5286 ASSERT_LE(details.descriptor_index(), new_size); | 5280 ASSERT_LE(details.descriptor_index(), new_size); |
5287 descriptor->SetEnumerationIndex(details.descriptor_index()); | 5281 descriptor->SetEnumerationIndex(details.descriptor_index()); |
5288 | 5282 |
(...skipping 2162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7451 | 7445 |
7452 | 7446 |
7453 static void TrimDescriptorArray(Heap* heap, | 7447 static void TrimDescriptorArray(Heap* heap, |
7454 Map* map, | 7448 Map* map, |
7455 DescriptorArray* descriptors, | 7449 DescriptorArray* descriptors, |
7456 int number_of_own_descriptors) { | 7450 int number_of_own_descriptors) { |
7457 int number_of_descriptors = descriptors->number_of_descriptors(); | 7451 int number_of_descriptors = descriptors->number_of_descriptors(); |
7458 int to_trim = number_of_descriptors - number_of_own_descriptors; | 7452 int to_trim = number_of_descriptors - number_of_own_descriptors; |
7459 if (to_trim <= 0) return; | 7453 if (to_trim <= 0) return; |
7460 | 7454 |
7461 // Maximally keep 50% of unused descriptors. | 7455 RightTrimFixedArray<FROM_GC>(heap, descriptors, to_trim); |
7462 int keep = Min(to_trim, number_of_own_descriptors / 2); | |
7463 for (int i = number_of_own_descriptors; | |
7464 i < number_of_own_descriptors + keep; | |
7465 ++i) { | |
7466 descriptors->EraseDescriptor(heap, i); | |
7467 } | |
7468 | |
7469 if (to_trim > keep) { | |
7470 RightTrimFixedArray<FROM_GC>(heap, descriptors, to_trim - keep); | |
7471 } | |
7472 descriptors->SetNumberOfDescriptors(number_of_own_descriptors); | 7456 descriptors->SetNumberOfDescriptors(number_of_own_descriptors); |
7473 | 7457 |
7474 if (descriptors->HasEnumCache()) TrimEnumCache(heap, map, descriptors); | 7458 if (descriptors->HasEnumCache()) TrimEnumCache(heap, map, descriptors); |
7475 descriptors->Sort(); | 7459 descriptors->Sort(); |
7476 } | 7460 } |
7477 | 7461 |
7478 | 7462 |
7479 // Clear a possible back pointer in case the transition leads to a dead map. | 7463 // Clear a possible back pointer in case the transition leads to a dead map. |
7480 // Return true in case a back pointer has been cleared and false otherwise. | 7464 // Return true in case a back pointer has been cleared and false otherwise. |
7481 static bool ClearBackPointer(Heap* heap, | 7465 static bool ClearBackPointer(Heap* heap, |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7539 | 7523 |
7540 int number_of_own_descriptors = NumberOfOwnDescriptors(); | 7524 int number_of_own_descriptors = NumberOfOwnDescriptors(); |
7541 | 7525 |
7542 if (descriptors_owner_died) { | 7526 if (descriptors_owner_died) { |
7543 if (number_of_own_descriptors > 0) { | 7527 if (number_of_own_descriptors > 0) { |
7544 TrimDescriptorArray(heap, this, descriptors, number_of_own_descriptors); | 7528 TrimDescriptorArray(heap, this, descriptors, number_of_own_descriptors); |
7545 ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors); | 7529 ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors); |
7546 } else { | 7530 } else { |
7547 t->set_descriptors(heap->empty_descriptor_array()); | 7531 t->set_descriptors(heap->empty_descriptor_array()); |
7548 } | 7532 } |
7549 set_owns_descriptors(true); | |
7550 } | 7533 } |
7551 | 7534 |
7552 int trim = t->number_of_transitions() - transition_index; | 7535 int trim = t->number_of_transitions() - transition_index; |
7553 if (trim > 0) { | 7536 if (trim > 0) { |
7554 RightTrimFixedArray<FROM_GC>(heap, t, t->IsSimpleTransition() | 7537 RightTrimFixedArray<FROM_GC>(heap, t, t->IsSimpleTransition() |
7555 ? trim : trim * TransitionArray::kTransitionSize); | 7538 ? trim : trim * TransitionArray::kTransitionSize); |
7556 } | 7539 } |
7557 } | 7540 } |
7558 | 7541 |
7559 | 7542 |
(...skipping 5965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13525 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 13508 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
13526 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 13509 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
13527 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 13510 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
13528 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 13511 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
13529 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 13512 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
13530 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 13513 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
13531 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 13514 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
13532 } | 13515 } |
13533 | 13516 |
13534 } } // namespace v8::internal | 13517 } } // namespace v8::internal |
OLD | NEW |