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

Side by Side Diff: src/objects.cc

Issue 11188031: Move DescriptorArray into the map (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: remove padding area Created 8 years, 2 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 1746 matching lines...) Expand 10 before | Expand all | Expand 10 after
1757 1757
1758 MaybeObject* JSObject::ConvertTransitionToMapTransition( 1758 MaybeObject* JSObject::ConvertTransitionToMapTransition(
1759 int transition_index, 1759 int transition_index,
1760 String* name, 1760 String* name,
1761 Object* new_value, 1761 Object* new_value,
1762 PropertyAttributes attributes) { 1762 PropertyAttributes attributes) {
1763 Map* old_map = map(); 1763 Map* old_map = map();
1764 Map* old_target = old_map->GetTransition(transition_index); 1764 Map* old_target = old_map->GetTransition(transition_index);
1765 Object* result; 1765 Object* result;
1766 1766
1767 // To sever a transition to a map with which the descriptors are shared, the
1768 // larger map (more descriptors) needs to store its own descriptors array.
1769 // Both sides of the severed chain need to have their own descriptors pointer
1770 // to store distinct descriptor arrays.
1771
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
1774 // the back pointer and setting its descriptor array.
1775
1776 // This phase is executed before creating the new map since it requires
1777 // allocation that may fail.
1778 if (!old_target->StoresOwnDescriptors()) {
1779 DescriptorArray* old_descriptors = old_map->instance_descriptors();
1780 MaybeObject* maybe_failure = old_target->SetDescriptors(old_descriptors);
1781 if (maybe_failure->IsFailure()) return maybe_failure;
1782 }
1783
1784 MaybeObject* maybe_result = 1767 MaybeObject* maybe_result =
1785 ConvertDescriptorToField(name, new_value, attributes); 1768 ConvertDescriptorToField(name, new_value, attributes);
1786 if (!maybe_result->To(&result)) return maybe_result; 1769 if (!maybe_result->To(&result)) return maybe_result;
1787 1770
1788 if (!HasFastProperties()) return result; 1771 if (!HasFastProperties()) return result;
1789 1772
1790 // This method should only be used to convert existing transitions. Objects 1773 // This method should only be used to convert existing transitions. Objects
1791 // with the map of "new Object()" cannot have transitions in the first place. 1774 // with the map of "new Object()" cannot have transitions in the first place.
1792 Map* new_map = map(); 1775 Map* new_map = map();
1793 ASSERT(new_map != GetIsolate()->empty_object_map()); 1776 ASSERT(new_map != GetIsolate()->empty_object_map());
1794 1777
1795 // TODO(verwaest): From here on we lose existing map transitions, causing 1778 // TODO(verwaest): From here on we lose existing map transitions, causing
1796 // invalid back pointers. This will change once we can store multiple 1779 // invalid back pointers. This will change once we can store multiple
1797 // transitions with the same key. 1780 // transitions with the same key.
1798 1781
1799 bool owned_descriptors = old_map->owns_descriptors(); 1782 bool owned_descriptors = old_map->owns_descriptors();
1800 if (owned_descriptors || 1783 if (owned_descriptors ||
1801 old_target->instance_descriptors() == old_map->instance_descriptors()) { 1784 old_target->instance_descriptors() == old_map->instance_descriptors()) {
1802 // Since the conversion above generated a new fast map with an additional 1785 // Since the conversion above generated a new fast map with an additional
1803 // property which can be shared as well, install this descriptor pointer 1786 // property which can be shared as well, install this descriptor pointer
1804 // along the entire chain of smaller maps; and remove the transition array 1787 // along the entire chain of smaller maps.
1805 // that is only in place to hold the descriptor array in the new map.
1806 Map* map; 1788 Map* map;
1807 DescriptorArray* new_descriptors = new_map->instance_descriptors(); 1789 DescriptorArray* new_descriptors = new_map->instance_descriptors();
1808 DescriptorArray* old_descriptors = old_map->instance_descriptors(); 1790 DescriptorArray* old_descriptors = old_map->instance_descriptors();
1809 for (Object* current = old_map; 1791 for (Object* current = old_map;
1810 !current->IsUndefined(); 1792 !current->IsUndefined();
1811 current = map->GetBackPointer()) { 1793 current = map->GetBackPointer()) {
1812 map = Map::cast(current); 1794 map = Map::cast(current);
1813 if (!map->HasTransitionArray()) break; 1795 if (map->instance_descriptors() != old_descriptors) break;
1814 TransitionArray* transitions = map->transitions();
1815 if (transitions->descriptors() != old_descriptors) break;
1816 map->SetEnumLength(Map::kInvalidEnumCache); 1796 map->SetEnumLength(Map::kInvalidEnumCache);
1817 transitions->set_descriptors(new_descriptors); 1797 map->set_instance_descriptors(new_descriptors);
1818 } 1798 }
1819 old_map->set_owns_descriptors(false); 1799 old_map->set_owns_descriptors(false);
1820 new_map->ClearTransitions(GetHeap());
1821 } 1800 }
1822 1801
1823 old_map->SetTransition(transition_index, new_map); 1802 old_map->SetTransition(transition_index, new_map);
1824 new_map->SetBackPointer(old_map); 1803 new_map->SetBackPointer(old_map);
1825 return result; 1804 return result;
1826 } 1805 }
1827 1806
1828 1807
1829 MaybeObject* JSObject::ConvertDescriptorToField(String* name, 1808 MaybeObject* JSObject::ConvertDescriptorToField(String* name,
1830 Object* new_value, 1809 Object* new_value,
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
2194 int number_of_descriptors = descriptors->number_of_descriptors(); 2173 int number_of_descriptors = descriptors->number_of_descriptors();
2195 Isolate* isolate = map->GetIsolate(); 2174 Isolate* isolate = map->GetIsolate();
2196 Handle<DescriptorArray> new_descriptors = 2175 Handle<DescriptorArray> new_descriptors =
2197 isolate->factory()->NewDescriptorArray(number_of_descriptors, slack); 2176 isolate->factory()->NewDescriptorArray(number_of_descriptors, slack);
2198 DescriptorArray::WhitenessWitness witness(*new_descriptors); 2177 DescriptorArray::WhitenessWitness witness(*new_descriptors);
2199 2178
2200 for (int i = 0; i < number_of_descriptors; ++i) { 2179 for (int i = 0; i < number_of_descriptors; ++i) {
2201 new_descriptors->CopyFrom(i, *descriptors, i, witness); 2180 new_descriptors->CopyFrom(i, *descriptors, i, witness);
2202 } 2181 }
2203 2182
2204 Map::SetDescriptors(map, new_descriptors); 2183 map->set_instance_descriptors(*new_descriptors);
2205 } 2184 }
2206 2185
2207 2186
2208 void Map::AppendCallbackDescriptors(Handle<Map> map, 2187 void Map::AppendCallbackDescriptors(Handle<Map> map,
2209 Handle<Object> descriptors) { 2188 Handle<Object> descriptors) {
2210 Isolate* isolate = map->GetIsolate(); 2189 Isolate* isolate = map->GetIsolate();
2211 Handle<DescriptorArray> array(map->instance_descriptors()); 2190 Handle<DescriptorArray> array(map->instance_descriptors());
2212 NeanderArray callbacks(descriptors); 2191 NeanderArray callbacks(descriptors);
2213 int nof_callbacks = callbacks.length(); 2192 int nof_callbacks = callbacks.length();
2214 2193
(...skipping 2007 matching lines...) Expand 10 before | Expand all | Expand 10 after
4222 ASSERT(!curr->HasNamedInterceptor()); 4201 ASSERT(!curr->HasNamedInterceptor());
4223 ASSERT(!curr->HasIndexedInterceptor()); 4202 ASSERT(!curr->HasIndexedInterceptor());
4224 ASSERT(!curr->IsAccessCheckNeeded()); 4203 ASSERT(!curr->IsAccessCheckNeeded());
4225 if (curr->NumberOfEnumElements() > 0) return false; 4204 if (curr->NumberOfEnumElements() > 0) return false;
4226 if (curr != this && enum_length != 0) return false; 4205 if (curr != this && enum_length != 0) return false;
4227 } 4206 }
4228 return true; 4207 return true;
4229 } 4208 }
4230 4209
4231 4210
4232 void Map::SetDescriptors(Handle<Map> map,
4233 Handle<DescriptorArray> descriptors) {
4234 Isolate* isolate = map->GetIsolate();
4235 CALL_HEAP_FUNCTION_VOID(isolate, map->SetDescriptors(*descriptors));
4236 }
4237
4238
4239 int Map::NumberOfDescribedProperties(DescriptorFlag which, 4211 int Map::NumberOfDescribedProperties(DescriptorFlag which,
4240 PropertyAttributes filter) { 4212 PropertyAttributes filter) {
4241 int result = 0; 4213 int result = 0;
4242 DescriptorArray* descs = instance_descriptors(); 4214 DescriptorArray* descs = instance_descriptors();
4243 int limit = which == ALL_DESCRIPTORS 4215 int limit = which == ALL_DESCRIPTORS
4244 ? descs->number_of_descriptors() 4216 ? descs->number_of_descriptors()
4245 : NumberOfOwnDescriptors(); 4217 : NumberOfOwnDescriptors();
4246 for (int i = 0; i < limit; i++) { 4218 for (int i = 0; i < limit; i++) {
4247 if ((descs->GetDetails(i).attributes() & filter) == 0) result++; 4219 if ((descs->GetDetails(i).attributes() & filter) == 0) result++;
4248 } 4220 }
(...skipping 757 matching lines...) Expand 10 before | Expand all | Expand 10 after
5006 4978
5007 DescriptorArray::WhitenessWitness witness(new_descriptors); 4979 DescriptorArray::WhitenessWitness witness(new_descriptors);
5008 4980
5009 // Copy the descriptors, inserting a descriptor. 4981 // Copy the descriptors, inserting a descriptor.
5010 for (int i = 0; i < old_size; ++i) { 4982 for (int i = 0; i < old_size; ++i) {
5011 new_descriptors->CopyFrom(i, descriptors, i, witness); 4983 new_descriptors->CopyFrom(i, descriptors, i, witness);
5012 } 4984 }
5013 4985
5014 new_descriptors->Append(descriptor, witness); 4986 new_descriptors->Append(descriptor, witness);
5015 4987
5016 // If the source descriptors had an enum cache we copy it. This ensures that 4988 if (old_size > 0) {
5017 // the maps to which we push the new descriptor array back can rely on a 4989 // If the source descriptors had an enum cache we copy it. This ensures
5018 // cache always being available once it is set. If the map has more 4990 // that the maps to which we push the new descriptor array back can rely
5019 // enumerated descriptors than available in the original cache, the cache 4991 // on a cache always being available once it is set. If the map has more
5020 // will be lazily replaced by the extended cache when needed. 4992 // enumerated descriptors than available in the original cache, the cache
5021 if (descriptors->HasEnumCache()) { 4993 // will be lazily replaced by the extended cache when needed.
5022 new_descriptors->CopyEnumCacheFrom(descriptors); 4994 if (descriptors->HasEnumCache()) {
4995 new_descriptors->CopyEnumCacheFrom(descriptors);
4996 }
4997
4998 Map* map;
4999 // Replace descriptors by new_descriptors in all maps that share it.
5000 for (Object* current = GetBackPointer();
5001 !current->IsUndefined();
5002 current = map->GetBackPointer()) {
5003 map = Map::cast(current);
5004 if (map->instance_descriptors() != descriptors) break;
5005 map->set_instance_descriptors(new_descriptors);
5006 }
5007
5008 set_instance_descriptors(new_descriptors);
5023 } 5009 }
5024
5025 Map* map;
5026 // Replace descriptors by new_descriptors in all maps that share it.
5027 for (Object* current = GetBackPointer();
5028 !current->IsUndefined();
5029 current = map->GetBackPointer()) {
5030 map = Map::cast(current);
5031 if (!map->HasTransitionArray()) break;
5032 TransitionArray* transitions = map->transitions();
5033 if (transitions->descriptors() != descriptors) break;
5034 transitions->set_descriptors(new_descriptors);
5035 }
5036
5037 transitions->set_descriptors(new_descriptors);
5038 } 5010 }
5039 5011
5012 result->SetBackPointer(this);
5013 result->InitializeDescriptors(new_descriptors);
5014 ASSERT(result->NumberOfOwnDescriptors() == NumberOfOwnDescriptors() + 1);
5015
5040 set_transitions(transitions); 5016 set_transitions(transitions);
5041 result->SetBackPointer(this);
5042 set_owns_descriptors(false); 5017 set_owns_descriptors(false);
5043 5018
5044 result->SetNumberOfOwnDescriptors(new_descriptors->number_of_descriptors());
5045 ASSERT(result->NumberOfOwnDescriptors() == NumberOfOwnDescriptors() + 1);
5046
5047 return result; 5019 return result;
5048 } 5020 }
5049 5021
5050 5022
5051 MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors, 5023 MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors,
5052 String* name, 5024 String* name,
5053 TransitionFlag flag, 5025 TransitionFlag flag,
5054 int descriptor_index) { 5026 int descriptor_index) {
5055 ASSERT(descriptors->IsSortedNoDuplicates()); 5027 ASSERT(descriptors->IsSortedNoDuplicates());
5056 5028
5057 Map* result; 5029 Map* result;
5058 MaybeObject* maybe_result = CopyDropDescriptors(); 5030 MaybeObject* maybe_result = CopyDropDescriptors();
5059 if (!maybe_result->To(&result)) return maybe_result; 5031 if (!maybe_result->To(&result)) return maybe_result;
5060 5032
5061 // Unless we are creating a map with no descriptors and no back pointer, we 5033 result->InitializeDescriptors(descriptors);
5062 // insert the descriptor array locally.
5063 if (!descriptors->IsEmpty()) {
5064 MaybeObject* maybe_failure = result->SetDescriptors(descriptors);
5065 if (maybe_failure->IsFailure()) return maybe_failure;
5066 result->SetNumberOfOwnDescriptors(descriptors->number_of_descriptors());
5067 }
5068 5034
5069 if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) { 5035 if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) {
5070 TransitionArray* transitions; 5036 TransitionArray* transitions;
5071 SimpleTransitionFlag simple_flag = 5037 SimpleTransitionFlag simple_flag =
5072 (descriptor_index == descriptors->number_of_descriptors() - 1) 5038 (descriptor_index == descriptors->number_of_descriptors() - 1)
5073 ? SIMPLE_TRANSITION 5039 ? SIMPLE_TRANSITION
5074 : FULL_TRANSITION; 5040 : FULL_TRANSITION;
5075 MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag); 5041 MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag);
5076 if (!maybe_transitions->To(&transitions)) return maybe_transitions; 5042 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
5077 5043
5078 if (descriptors->IsEmpty()) {
5079 if (owns_descriptors()) {
5080 // If the copied map has no added fields, and the parent map owns its
5081 // descriptors, those descriptors have to be empty. In that case,
5082 // transfer ownership of the descriptors to the new child.
5083 ASSERT(instance_descriptors()->IsEmpty());
5084 set_owns_descriptors(false);
5085 } else {
5086 // If the parent did not own its own descriptors, it may share a larger
5087 // descriptors array already. In that case, force a split by setting
5088 // the descriptor array of the new map to the empty descriptor array.
5089 MaybeObject* maybe_failure =
5090 result->SetDescriptors(GetHeap()->empty_descriptor_array());
5091 if (maybe_failure->IsFailure()) return maybe_failure;
5092 }
5093 }
5094
5095 set_transitions(transitions); 5044 set_transitions(transitions);
5096 result->SetBackPointer(this); 5045 result->SetBackPointer(this);
5097 } 5046 }
5098 5047
5099 return result; 5048 return result;
5100 } 5049 }
5101 5050
5102 5051
5103 MaybeObject* Map::CopyAsElementsKind(ElementsKind kind, TransitionFlag flag) { 5052 MaybeObject* Map::CopyAsElementsKind(ElementsKind kind, TransitionFlag flag) {
5104 if (flag == INSERT_TRANSITION) { 5053 if (flag == INSERT_TRANSITION) {
5105 ASSERT(!HasElementsTransition() || 5054 ASSERT(!HasElementsTransition() ||
5106 ((elements_transition_map()->elements_kind() == DICTIONARY_ELEMENTS || 5055 ((elements_transition_map()->elements_kind() == DICTIONARY_ELEMENTS ||
5107 IsExternalArrayElementsKind( 5056 IsExternalArrayElementsKind(
5108 elements_transition_map()->elements_kind())) && 5057 elements_transition_map()->elements_kind())) &&
5109 (kind == DICTIONARY_ELEMENTS || 5058 (kind == DICTIONARY_ELEMENTS ||
5110 IsExternalArrayElementsKind(kind)))); 5059 IsExternalArrayElementsKind(kind))));
5111 ASSERT(!IsFastElementsKind(kind) || 5060 ASSERT(!IsFastElementsKind(kind) ||
5112 IsMoreGeneralElementsKindTransition(elements_kind(), kind)); 5061 IsMoreGeneralElementsKindTransition(elements_kind(), kind));
5113 ASSERT(kind != elements_kind()); 5062 ASSERT(kind != elements_kind());
5114 } 5063 }
5115 5064
5116 if (flag == INSERT_TRANSITION && owns_descriptors()) { 5065 bool insert_transition =
5066 flag == INSERT_TRANSITION && !HasElementsTransition();
5067
5068 if (insert_transition && owns_descriptors()) {
5117 // In case the map owned its own descriptors, share the descriptors and 5069 // In case the map owned its own descriptors, share the descriptors and
5118 // transfer ownership to the new map. 5070 // transfer ownership to the new map.
5119 Map* new_map; 5071 Map* new_map;
5120 MaybeObject* maybe_new_map = CopyDropDescriptors(); 5072 MaybeObject* maybe_new_map = CopyDropDescriptors();
5121 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 5073 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
5122 5074
5123 MaybeObject* added_elements = set_elements_transition_map(new_map); 5075 MaybeObject* added_elements = set_elements_transition_map(new_map);
5124 if (added_elements->IsFailure()) return added_elements; 5076 if (added_elements->IsFailure()) return added_elements;
5125 5077
5126 new_map->set_elements_kind(kind); 5078 new_map->set_elements_kind(kind);
5079 new_map->InitializeDescriptors(instance_descriptors());
5127 new_map->SetBackPointer(this); 5080 new_map->SetBackPointer(this);
5128 new_map->SetNumberOfOwnDescriptors(NumberOfOwnDescriptors());
5129 set_owns_descriptors(false); 5081 set_owns_descriptors(false);
5130 return new_map; 5082 return new_map;
5131 } 5083 }
5132 5084
5133 // In case the map did not own its own descriptors, a split is forced by 5085 // In case the map did not own its own descriptors, a split is forced by
5134 // copying the map; creating a new descriptor array cell. 5086 // copying the map; creating a new descriptor array cell.
5135 // Create a new free-floating map only if we are not allowed to store it. 5087 // Create a new free-floating map only if we are not allowed to store it.
5136 Map* new_map; 5088 Map* new_map;
5137 MaybeObject* maybe_new_map = Copy(); 5089 MaybeObject* maybe_new_map = Copy();
5138 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 5090 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
5139 ASSERT(new_map->NumberOfOwnDescriptors() == NumberOfOwnDescriptors()); 5091
5140 new_map->set_elements_kind(kind); 5092 new_map->set_elements_kind(kind);
5141 5093
5142 if (flag == INSERT_TRANSITION && !HasElementsTransition()) { 5094 if (insert_transition) {
5143 // Map::Copy does not store the descriptor array in case it is empty, since
5144 // it does not insert a back pointer; implicitly indicating that its
5145 // descriptor array is empty. Since in this case we do want to insert a back
5146 // pointer, we have to manually set the empty descriptor array to force a
5147 // split.
5148 if (!new_map->StoresOwnDescriptors()) {
5149 ASSERT(new_map->NumberOfOwnDescriptors() == 0);
5150 MaybeObject* maybe_failure =
5151 new_map->SetDescriptors(GetHeap()->empty_descriptor_array());
5152 if (maybe_failure->IsFailure()) return maybe_failure;
5153 }
5154 MaybeObject* added_elements = set_elements_transition_map(new_map); 5095 MaybeObject* added_elements = set_elements_transition_map(new_map);
5155 if (added_elements->IsFailure()) return added_elements; 5096 if (added_elements->IsFailure()) return added_elements;
5156
5157 new_map->SetBackPointer(this); 5097 new_map->SetBackPointer(this);
5158 } 5098 }
5159 5099
5160 return new_map; 5100 return new_map;
5161 } 5101 }
5162 5102
5163 5103
5164 MaybeObject* Map::CopyWithPreallocatedFieldDescriptors() { 5104 MaybeObject* Map::CopyWithPreallocatedFieldDescriptors() {
5165 if (pre_allocated_property_fields() == 0) return CopyDropDescriptors(); 5105 if (pre_allocated_property_fields() == 0) return CopyDropDescriptors();
5166 5106
(...skipping 2293 matching lines...) Expand 10 before | Expand all | Expand 10 after
7460 RightTrimFixedArray<FROM_GC>(heap, descriptors, to_trim); 7400 RightTrimFixedArray<FROM_GC>(heap, descriptors, to_trim);
7461 descriptors->SetNumberOfDescriptors(number_of_own_descriptors); 7401 descriptors->SetNumberOfDescriptors(number_of_own_descriptors);
7462 7402
7463 if (descriptors->HasEnumCache()) TrimEnumCache(heap, map, descriptors); 7403 if (descriptors->HasEnumCache()) TrimEnumCache(heap, map, descriptors);
7464 descriptors->Sort(); 7404 descriptors->Sort();
7465 } 7405 }
7466 7406
7467 7407
7468 // Clear a possible back pointer in case the transition leads to a dead map. 7408 // Clear a possible back pointer in case the transition leads to a dead map.
7469 // Return true in case a back pointer has been cleared and false otherwise. 7409 // Return true in case a back pointer has been cleared and false otherwise.
7470 static bool ClearBackPointer(Heap* heap, 7410 static bool ClearBackPointer(Heap* heap, Map* target) {
7471 Map* target,
7472 DescriptorArray* descriptors,
7473 bool* descriptors_owner_died) {
7474 if (Marking::MarkBitFrom(target).Get()) return false; 7411 if (Marking::MarkBitFrom(target).Get()) return false;
7475 if (target->instance_descriptors() == descriptors) {
7476 *descriptors_owner_died = true;
7477 }
7478 target->SetBackPointer(heap->undefined_value(), SKIP_WRITE_BARRIER); 7412 target->SetBackPointer(heap->undefined_value(), SKIP_WRITE_BARRIER);
7479 return true; 7413 return true;
7480 } 7414 }
7481 7415
7482 7416
7483 // TODO(mstarzinger): This method should be moved into MarkCompactCollector, 7417 // TODO(mstarzinger): This method should be moved into MarkCompactCollector,
7484 // because it cannot be called from outside the GC and we already have methods 7418 // because it cannot be called from outside the GC and we already have methods
7485 // depending on the transitions layout in the GC anyways. 7419 // depending on the transitions layout in the GC anyways.
7486 void Map::ClearNonLiveTransitions(Heap* heap) { 7420 void Map::ClearNonLiveTransitions(Heap* heap) {
7487 // If there are no transitions to be cleared, return. 7421 // If there are no transitions to be cleared, return.
7488 // TODO(verwaest) Should be an assert, otherwise back pointers are not 7422 // TODO(verwaest) Should be an assert, otherwise back pointers are not
7489 // properly cleared. 7423 // properly cleared.
7490 if (!HasTransitionArray()) return; 7424 if (!HasTransitionArray()) return;
7491 7425
7492 TransitionArray* t = transitions(); 7426 TransitionArray* t = transitions();
7493 MarkCompactCollector* collector = heap->mark_compact_collector(); 7427 MarkCompactCollector* collector = heap->mark_compact_collector();
7494 7428
7495 int transition_index = 0; 7429 int transition_index = 0;
7496 7430
7497 DescriptorArray* descriptors = t->descriptors(); 7431 DescriptorArray* descriptors = instance_descriptors();
7498 bool descriptors_owner_died = false; 7432 bool descriptors_owner_died = false;
7499 7433
7500 // Compact all live descriptors to the left. 7434 // Compact all live descriptors to the left.
7501 for (int i = 0; i < t->number_of_transitions(); ++i) { 7435 for (int i = 0; i < t->number_of_transitions(); ++i) {
7502 Map* target = t->GetTarget(i); 7436 Map* target = t->GetTarget(i);
7503 if (!ClearBackPointer(heap, target, descriptors, &descriptors_owner_died)) { 7437 if (ClearBackPointer(heap, target)) {
7438 if (target->instance_descriptors() == descriptors) {
7439 descriptors_owner_died = true;
7440 descriptors_owner_died = true;
7441 }
7442 } else {
7504 if (i != transition_index) { 7443 if (i != transition_index) {
7505 String* key = t->GetKey(i); 7444 String* key = t->GetKey(i);
7506 t->SetKey(transition_index, key); 7445 t->SetKey(transition_index, key);
7507 Object** key_slot = t->GetKeySlot(transition_index); 7446 Object** key_slot = t->GetKeySlot(transition_index);
7508 collector->RecordSlot(key_slot, key_slot, key); 7447 collector->RecordSlot(key_slot, key_slot, key);
7509 // Target slots do not need to be recorded since maps are not compacted. 7448 // Target slots do not need to be recorded since maps are not compacted.
7510 t->SetTarget(transition_index, t->GetTarget(i)); 7449 t->SetTarget(transition_index, t->GetTarget(i));
7511 } 7450 }
7512 transition_index++; 7451 transition_index++;
7513 } 7452 }
7514 } 7453 }
7515 7454
7516 if (t->HasElementsTransition() && 7455 if (t->HasElementsTransition() &&
7517 ClearBackPointer(heap, 7456 ClearBackPointer(heap, t->elements_transition())) {
7518 t->elements_transition(), 7457 if (t->elements_transition()->instance_descriptors() == descriptors) {
7519 descriptors, 7458 descriptors_owner_died = true;
7520 &descriptors_owner_died)) { 7459 }
7521 t->ClearElementsTransition(); 7460 t->ClearElementsTransition();
7522 } else { 7461 } else {
7523 // If there are no transitions to be cleared, return. 7462 // If there are no transitions to be cleared, return.
7524 // TODO(verwaest) Should be an assert, otherwise back pointers are not 7463 // TODO(verwaest) Should be an assert, otherwise back pointers are not
7525 // properly cleared. 7464 // properly cleared.
7526 if (transition_index == t->number_of_transitions()) return; 7465 if (transition_index == t->number_of_transitions()) return;
7527 } 7466 }
7528 7467
7529 int number_of_own_descriptors = NumberOfOwnDescriptors(); 7468 int number_of_own_descriptors = NumberOfOwnDescriptors();
7530 7469
7531 if (descriptors_owner_died) { 7470 if (descriptors_owner_died) {
7532 if (number_of_own_descriptors > 0) { 7471 if (number_of_own_descriptors > 0) {
7533 TrimDescriptorArray(heap, this, descriptors, number_of_own_descriptors); 7472 TrimDescriptorArray(heap, this, descriptors, number_of_own_descriptors);
7534 ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors); 7473 ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors);
7535 } else { 7474 } else {
7536 t->set_descriptors(heap->empty_descriptor_array()); 7475 ASSERT(descriptors == GetHeap()->empty_descriptor_array());
7537 } 7476 }
7538 } 7477 }
7539 7478
7540 int trim = t->number_of_transitions() - transition_index; 7479 int trim = t->number_of_transitions() - transition_index;
7541 if (trim > 0) { 7480 if (trim > 0) {
7542 RightTrimFixedArray<FROM_GC>(heap, t, t->IsSimpleTransition() 7481 RightTrimFixedArray<FROM_GC>(heap, t, t->IsSimpleTransition()
7543 ? trim : trim * TransitionArray::kTransitionSize); 7482 ? trim : trim * TransitionArray::kTransitionSize);
7544 } 7483 }
7545 } 7484 }
7546 7485
(...skipping 5461 matching lines...) Expand 10 before | Expand all | Expand 10 after
13008 descriptors->Set(enumeration_index - 1, &d, witness); 12947 descriptors->Set(enumeration_index - 1, &d, witness);
13009 } else { 12948 } else {
13010 UNREACHABLE(); 12949 UNREACHABLE();
13011 } 12950 }
13012 } 12951 }
13013 } 12952 }
13014 ASSERT(current_offset == number_of_fields); 12953 ASSERT(current_offset == number_of_fields);
13015 12954
13016 descriptors->Sort(); 12955 descriptors->Sort();
13017 12956
13018 MaybeObject* maybe_failure = new_map->InitializeDescriptors(descriptors); 12957 new_map->InitializeDescriptors(descriptors);
13019 if (maybe_failure->IsFailure()) return maybe_failure;
13020 new_map->set_unused_property_fields(unused_property_fields); 12958 new_map->set_unused_property_fields(unused_property_fields);
13021 12959
13022 // Transform the object. 12960 // Transform the object.
13023 obj->set_map(new_map); 12961 obj->set_map(new_map);
13024 12962
13025 obj->set_properties(fields); 12963 obj->set_properties(fields);
13026 ASSERT(obj->IsJSObject()); 12964 ASSERT(obj->IsJSObject());
13027 12965
13028 // Check that it really works. 12966 // Check that it really works.
13029 ASSERT(obj->HasFastProperties()); 12967 ASSERT(obj->HasFastProperties());
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
13529 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); 13467 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
13530 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); 13468 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
13531 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); 13469 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
13532 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); 13470 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
13533 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); 13471 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
13534 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); 13472 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
13535 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); 13473 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
13536 } 13474 }
13537 13475
13538 } } // namespace v8::internal 13476 } } // 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