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

Side by Side Diff: src/objects.cc

Issue 437953004: Don't insert transitions between maps for prototypes. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Insert transition in ConnectTransition Created 6 years, 4 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') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/allocation-site-scopes.h" 8 #include "src/allocation-site-scopes.h"
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/arguments.h" 10 #include "src/arguments.h"
(...skipping 2056 matching lines...) Expand 10 before | Expand all | Expand 10 after
2067 DCHECK(target_inobject < inobject_properties()); 2067 DCHECK(target_inobject < inobject_properties());
2068 if (target_number_of_fields <= target_inobject) { 2068 if (target_number_of_fields <= target_inobject) {
2069 DCHECK(target_number_of_fields + target_unused == target_inobject); 2069 DCHECK(target_number_of_fields + target_unused == target_inobject);
2070 return false; 2070 return false;
2071 } 2071 }
2072 // Otherwise, properties will need to be moved to the backing store. 2072 // Otherwise, properties will need to be moved to the backing store.
2073 return true; 2073 return true;
2074 } 2074 }
2075 2075
2076 2076
2077 Handle<TransitionArray> Map::SetElementsTransitionMap( 2077 void Map::ConnectElementsTransition(Handle<Map> parent, Handle<Map> child) {
2078 Handle<Map> map, Handle<Map> transitioned_map) { 2078 Isolate* isolate = parent->GetIsolate();
2079 Handle<TransitionArray> transitions = TransitionArray::CopyInsert( 2079 Handle<Name> name = isolate->factory()->elements_transition_symbol();
2080 map, 2080 ConnectTransition(parent, child, name, FULL_TRANSITION);
2081 map->GetIsolate()->factory()->elements_transition_symbol(),
2082 transitioned_map,
2083 FULL_TRANSITION);
2084 map->set_transitions(*transitions);
2085 return transitions;
2086 } 2081 }
2087 2082
2088 2083
2089 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) { 2084 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
2090 if (object->map() == *new_map) return; 2085 if (object->map() == *new_map) return;
2091 if (object->HasFastProperties()) { 2086 if (object->HasFastProperties()) {
2092 if (!new_map->is_dictionary_map()) { 2087 if (!new_map->is_dictionary_map()) {
2088 Handle<Map> old_map(object->map());
2093 MigrateFastToFast(object, new_map); 2089 MigrateFastToFast(object, new_map);
2090 if (old_map->is_prototype_map()) {
2091 // Clear out the old descriptor array to avoid problems to sharing
2092 // the descriptor array without using an explicit.
2093 old_map->InitializeDescriptors(
2094 old_map->GetHeap()->empty_descriptor_array());
2095 // Ensure that no transition was inserted for prototype migrations.
2096 DCHECK(!old_map->HasTransitionArray());
2097 DCHECK(new_map->GetBackPointer()->IsUndefined());
2098 }
2094 } else { 2099 } else {
2095 MigrateFastToSlow(object, new_map, 0); 2100 MigrateFastToSlow(object, new_map, 0);
2096 } 2101 }
2097 } else { 2102 } else {
2098 // For slow-to-fast migrations JSObject::TransformToFastProperties() 2103 // For slow-to-fast migrations JSObject::TransformToFastProperties()
2099 // must be used instead. 2104 // must be used instead.
2100 CHECK(new_map->is_dictionary_map()); 2105 CHECK(new_map->is_dictionary_map());
2101 2106
2102 // Slow-to-slow migration is trivial. 2107 // Slow-to-slow migration is trivial.
2103 object->set_map(*new_map); 2108 object->set_map(*new_map);
(...skipping 1348 matching lines...) Expand 10 before | Expand all | Expand 10 after
3452 } 3457 }
3453 3458
3454 3459
3455 static Handle<Map> AddMissingElementsTransitions(Handle<Map> map, 3460 static Handle<Map> AddMissingElementsTransitions(Handle<Map> map,
3456 ElementsKind to_kind) { 3461 ElementsKind to_kind) {
3457 DCHECK(IsTransitionElementsKind(map->elements_kind())); 3462 DCHECK(IsTransitionElementsKind(map->elements_kind()));
3458 3463
3459 Handle<Map> current_map = map; 3464 Handle<Map> current_map = map;
3460 3465
3461 ElementsKind kind = map->elements_kind(); 3466 ElementsKind kind = map->elements_kind();
3462 while (kind != to_kind && !IsTerminalElementsKind(kind)) { 3467 if (!map->is_prototype_map()) {
3463 kind = GetNextTransitionElementsKind(kind); 3468 while (kind != to_kind && !IsTerminalElementsKind(kind)) {
3464 current_map = Map::CopyAsElementsKind( 3469 kind = GetNextTransitionElementsKind(kind);
3465 current_map, kind, INSERT_TRANSITION); 3470 current_map =
3471 Map::CopyAsElementsKind(current_map, kind, INSERT_TRANSITION);
3472 }
3466 } 3473 }
3467 3474
3468 // In case we are exiting the fast elements kind system, just add the map in 3475 // In case we are exiting the fast elements kind system, just add the map in
3469 // the end. 3476 // the end.
3470 if (kind != to_kind) { 3477 if (kind != to_kind) {
3471 current_map = Map::CopyAsElementsKind( 3478 current_map = Map::CopyAsElementsKind(
3472 current_map, to_kind, INSERT_TRANSITION); 3479 current_map, to_kind, INSERT_TRANSITION);
3473 } 3480 }
3474 3481
3475 DCHECK(current_map->elements_kind() == to_kind); 3482 DCHECK(current_map->elements_kind() == to_kind);
(...skipping 2225 matching lines...) Expand 10 before | Expand all | Expand 10 after
5701 Handle<Map> transition_map(old_map->GetTransition(transition_index)); 5708 Handle<Map> transition_map(old_map->GetTransition(transition_index));
5702 DCHECK(transition_map->has_dictionary_elements()); 5709 DCHECK(transition_map->has_dictionary_elements());
5703 DCHECK(transition_map->is_frozen()); 5710 DCHECK(transition_map->is_frozen());
5704 DCHECK(!transition_map->is_extensible()); 5711 DCHECK(!transition_map->is_extensible());
5705 JSObject::MigrateToMap(object, transition_map); 5712 JSObject::MigrateToMap(object, transition_map);
5706 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) { 5713 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) {
5707 // Create a new descriptor array with fully-frozen properties 5714 // Create a new descriptor array with fully-frozen properties
5708 Handle<Map> new_map = Map::CopyForFreeze(old_map); 5715 Handle<Map> new_map = Map::CopyForFreeze(old_map);
5709 JSObject::MigrateToMap(object, new_map); 5716 JSObject::MigrateToMap(object, new_map);
5710 } else { 5717 } else {
5711 ASSERT(!old_map->is_prototype_map()); 5718 DCHECK(!old_map->is_prototype_map());
5712 // Slow path: need to normalize properties for safety 5719 // Slow path: need to normalize properties for safety
5713 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); 5720 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
5714 5721
5715 // Create a new map, since other objects with this map may be extensible. 5722 // Create a new map, since other objects with this map may be extensible.
5716 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. 5723 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
5717 Handle<Map> new_map = Map::Copy(handle(object->map())); 5724 Handle<Map> new_map = Map::Copy(handle(object->map()));
5718 new_map->freeze(); 5725 new_map->freeze();
5719 new_map->set_is_extensible(false); 5726 new_map->set_is_extensible(false);
5720 new_map->set_elements_kind(DICTIONARY_ELEMENTS); 5727 new_map->set_elements_kind(DICTIONARY_ELEMENTS);
5721 JSObject::MigrateToMap(object, new_map); 5728 JSObject::MigrateToMap(object, new_map);
(...skipping 1381 matching lines...) Expand 10 before | Expand all | Expand 10 after
7103 Handle<DescriptorArray> descriptors, 7110 Handle<DescriptorArray> descriptors,
7104 Descriptor* descriptor) { 7111 Descriptor* descriptor) {
7105 // Sanity check. This path is only to be taken if the map owns its descriptor 7112 // Sanity check. This path is only to be taken if the map owns its descriptor
7106 // array, implying that its NumberOfOwnDescriptors equals the number of 7113 // array, implying that its NumberOfOwnDescriptors equals the number of
7107 // descriptors in the descriptor array. 7114 // descriptors in the descriptor array.
7108 DCHECK(map->NumberOfOwnDescriptors() == 7115 DCHECK(map->NumberOfOwnDescriptors() ==
7109 map->instance_descriptors()->number_of_descriptors()); 7116 map->instance_descriptors()->number_of_descriptors());
7110 7117
7111 Handle<Map> result = CopyDropDescriptors(map); 7118 Handle<Map> result = CopyDropDescriptors(map);
7112 Handle<Name> name = descriptor->GetKey(); 7119 Handle<Name> name = descriptor->GetKey();
7113 Handle<TransitionArray> transitions =
7114 TransitionArray::CopyInsert(map, name, result, SIMPLE_TRANSITION);
7115 7120
7116 // Ensure there's space for the new descriptor in the shared descriptor array. 7121 // Ensure there's space for the new descriptor in the shared descriptor array.
7117 if (descriptors->NumberOfSlackDescriptors() == 0) { 7122 if (descriptors->NumberOfSlackDescriptors() == 0) {
7118 int old_size = descriptors->number_of_descriptors(); 7123 int old_size = descriptors->number_of_descriptors();
7119 if (old_size == 0) { 7124 if (old_size == 0) {
7120 descriptors = DescriptorArray::Allocate(map->GetIsolate(), 0, 1); 7125 descriptors = DescriptorArray::Allocate(map->GetIsolate(), 0, 1);
7121 } else { 7126 } else {
7122 EnsureDescriptorSlack(map, old_size < 4 ? 1 : old_size / 2); 7127 EnsureDescriptorSlack(map, old_size < 4 ? 1 : old_size / 2);
7123 descriptors = handle(map->instance_descriptors()); 7128 descriptors = handle(map->instance_descriptors());
7124 } 7129 }
7125 } 7130 }
7126 7131
7127 // Commit the state atomically. 7132 {
7128 DisallowHeapAllocation no_gc; 7133 DisallowHeapAllocation no_gc;
7129 7134 descriptors->Append(descriptor);
7130 descriptors->Append(descriptor); 7135 result->InitializeDescriptors(*descriptors);
7131 result->SetBackPointer(*map); 7136 }
7132 result->InitializeDescriptors(*descriptors);
7133 7137
7134 DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1); 7138 DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1);
7135 7139 ConnectTransition(map, result, name, SIMPLE_TRANSITION);
7136 map->set_transitions(*transitions);
7137 map->set_owns_descriptors(false);
7138 7140
7139 return result; 7141 return result;
7140 } 7142 }
7141 7143
7142 7144
7145 void Map::ConnectTransition(Handle<Map> parent, Handle<Map> child,
7146 Handle<Name> name, SimpleTransitionFlag flag) {
7147 parent->set_owns_descriptors(false);
7148 if (parent->is_prototype_map()) {
7149 DCHECK(child->is_prototype_map());
7150 } else {
7151 Handle<TransitionArray> transitions =
7152 TransitionArray::CopyInsert(parent, name, child, flag);
7153 parent->set_transitions(*transitions);
7154 child->SetBackPointer(*parent);
7155 }
7156 }
7157
7158
7143 Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map, 7159 Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map,
7144 Handle<DescriptorArray> descriptors, 7160 Handle<DescriptorArray> descriptors,
7145 TransitionFlag flag, 7161 TransitionFlag flag,
7146 MaybeHandle<Name> maybe_name, 7162 MaybeHandle<Name> maybe_name,
7147 SimpleTransitionFlag simple_flag) { 7163 SimpleTransitionFlag simple_flag) {
7148 DCHECK(descriptors->IsSortedNoDuplicates()); 7164 DCHECK(descriptors->IsSortedNoDuplicates());
7149 7165
7150 Handle<Map> result = CopyDropDescriptors(map); 7166 Handle<Map> result = CopyDropDescriptors(map);
7151 result->InitializeDescriptors(*descriptors); 7167 result->InitializeDescriptors(*descriptors);
7152 7168
7153 if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) { 7169 if (!map->is_prototype_map()) {
7154 Handle<Name> name; 7170 if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) {
7155 CHECK(maybe_name.ToHandle(&name)); 7171 Handle<Name> name;
7156 Handle<TransitionArray> transitions = TransitionArray::CopyInsert( 7172 CHECK(maybe_name.ToHandle(&name));
7157 map, name, result, simple_flag); 7173 ConnectTransition(map, result, name, simple_flag);
7158 map->set_transitions(*transitions); 7174 } else {
7159 result->SetBackPointer(*map); 7175 int length = descriptors->number_of_descriptors();
7160 } else { 7176 for (int i = 0; i < length; i++) {
7161 int length = descriptors->number_of_descriptors(); 7177 descriptors->SetRepresentation(i, Representation::Tagged());
7162 for (int i = 0; i < length; i++) { 7178 if (descriptors->GetDetails(i).type() == FIELD) {
7163 descriptors->SetRepresentation(i, Representation::Tagged()); 7179 descriptors->SetValue(i, HeapType::Any());
7164 if (descriptors->GetDetails(i).type() == FIELD) { 7180 }
7165 descriptors->SetValue(i, HeapType::Any());
7166 } 7181 }
7167 } 7182 }
7168 } 7183 }
7169 7184
7170 return result; 7185 return result;
7171 } 7186 }
7172 7187
7173 7188
7174 // Since this method is used to rewrite an existing transition tree, it can 7189 // Since this method is used to rewrite an existing transition tree, it can
7175 // always insert transitions without checking. 7190 // always insert transitions without checking.
7176 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map, 7191 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map,
7177 int new_descriptor, 7192 int new_descriptor,
7178 Handle<DescriptorArray> descriptors) { 7193 Handle<DescriptorArray> descriptors) {
7179 DCHECK(descriptors->IsSortedNoDuplicates()); 7194 DCHECK(descriptors->IsSortedNoDuplicates());
7180 7195
7181 Handle<Map> result = CopyDropDescriptors(map); 7196 Handle<Map> result = CopyDropDescriptors(map);
7182 7197
7183 result->InitializeDescriptors(*descriptors); 7198 result->InitializeDescriptors(*descriptors);
7184 result->SetNumberOfOwnDescriptors(new_descriptor + 1); 7199 result->SetNumberOfOwnDescriptors(new_descriptor + 1);
7185 7200
7186 int unused_property_fields = map->unused_property_fields(); 7201 int unused_property_fields = map->unused_property_fields();
7187 if (descriptors->GetDetails(new_descriptor).type() == FIELD) { 7202 if (descriptors->GetDetails(new_descriptor).type() == FIELD) {
7188 unused_property_fields = map->unused_property_fields() - 1; 7203 unused_property_fields = map->unused_property_fields() - 1;
7189 if (unused_property_fields < 0) { 7204 if (unused_property_fields < 0) {
7190 unused_property_fields += JSObject::kFieldsAdded; 7205 unused_property_fields += JSObject::kFieldsAdded;
7191 } 7206 }
7192 } 7207 }
7193 7208
7194 result->set_unused_property_fields(unused_property_fields); 7209 result->set_unused_property_fields(unused_property_fields);
7195 result->set_owns_descriptors(false); 7210 result->set_owns_descriptors(false);
Igor Sheludko 2014/08/04 14:25:55 This is going to be done again in ConnectTransitio
7196 7211
7197 Handle<Name> name = handle(descriptors->GetKey(new_descriptor)); 7212 Handle<Name> name = handle(descriptors->GetKey(new_descriptor));
7198 Handle<TransitionArray> transitions = TransitionArray::CopyInsert( 7213 ConnectTransition(map, result, name, SIMPLE_TRANSITION);
7199 map, name, result, SIMPLE_TRANSITION);
7200
7201 map->set_transitions(*transitions);
7202 result->SetBackPointer(*map);
7203 7214
7204 return result; 7215 return result;
7205 } 7216 }
7206 7217
7207 7218
7208 Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind, 7219 Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind,
7209 TransitionFlag flag) { 7220 TransitionFlag flag) {
7210 if (flag == INSERT_TRANSITION) { 7221 if (flag == INSERT_TRANSITION) {
7211 DCHECK(!map->HasElementsTransition() || 7222 DCHECK(!map->HasElementsTransition() ||
7212 ((map->elements_transition_map()->elements_kind() == 7223 ((map->elements_transition_map()->elements_kind() ==
7213 DICTIONARY_ELEMENTS || 7224 DICTIONARY_ELEMENTS ||
7214 IsExternalArrayElementsKind( 7225 IsExternalArrayElementsKind(
7215 map->elements_transition_map()->elements_kind())) && 7226 map->elements_transition_map()->elements_kind())) &&
7216 (kind == DICTIONARY_ELEMENTS || 7227 (kind == DICTIONARY_ELEMENTS ||
7217 IsExternalArrayElementsKind(kind)))); 7228 IsExternalArrayElementsKind(kind))));
7218 DCHECK(!IsFastElementsKind(kind) || 7229 DCHECK(!IsFastElementsKind(kind) ||
7219 IsMoreGeneralElementsKindTransition(map->elements_kind(), kind)); 7230 IsMoreGeneralElementsKindTransition(map->elements_kind(), kind));
7220 DCHECK(kind != map->elements_kind()); 7231 DCHECK(kind != map->elements_kind());
7221 } 7232 }
7222 7233
7223 bool insert_transition = 7234 bool insert_transition =
7224 flag == INSERT_TRANSITION && !map->HasElementsTransition(); 7235 flag == INSERT_TRANSITION && !map->HasElementsTransition();
7225 7236
7226 if (insert_transition && map->owns_descriptors()) { 7237 if (insert_transition && map->owns_descriptors()) {
7227 // In case the map owned its own descriptors, share the descriptors and 7238 // In case the map owned its own descriptors, share the descriptors and
7228 // transfer ownership to the new map. 7239 // transfer ownership to the new map.
7229 Handle<Map> new_map = CopyDropDescriptors(map); 7240 Handle<Map> new_map = CopyDropDescriptors(map);
7230 7241
7231 SetElementsTransitionMap(map, new_map); 7242 ConnectElementsTransition(map, new_map);
7232 7243
7233 new_map->set_elements_kind(kind); 7244 new_map->set_elements_kind(kind);
7234 new_map->InitializeDescriptors(map->instance_descriptors()); 7245 new_map->InitializeDescriptors(map->instance_descriptors());
7235 new_map->SetBackPointer(*map);
7236 map->set_owns_descriptors(false);
7237 return new_map; 7246 return new_map;
7238 } 7247 }
7239 7248
7240 // In case the map did not own its own descriptors, a split is forced by 7249 // In case the map did not own its own descriptors, a split is forced by
7241 // copying the map; creating a new descriptor array cell. 7250 // copying the map; creating a new descriptor array cell.
7242 // Create a new free-floating map only if we are not allowed to store it. 7251 // Create a new free-floating map only if we are not allowed to store it.
7243 Handle<Map> new_map = Copy(map); 7252 Handle<Map> new_map = Copy(map);
7244 7253
7245 new_map->set_elements_kind(kind); 7254 new_map->set_elements_kind(kind);
7246 7255
7247 if (insert_transition) { 7256 if (insert_transition) {
7248 SetElementsTransitionMap(map, new_map); 7257 ConnectElementsTransition(map, new_map);
7249 new_map->SetBackPointer(*map);
7250 } 7258 }
7251 7259
7252 return new_map; 7260 return new_map;
7253 } 7261 }
7254 7262
7255 7263
7256 Handle<Map> Map::CopyForObserved(Handle<Map> map) { 7264 Handle<Map> Map::CopyForObserved(Handle<Map> map) {
7257 DCHECK(!map->is_observed()); 7265 DCHECK(!map->is_observed());
7258 7266
7259 Isolate* isolate = map->GetIsolate(); 7267 Isolate* isolate = map->GetIsolate();
7260 7268
7261 // In case the map owned its own descriptors, share the descriptors and 7269 // In case the map owned its own descriptors, share the descriptors and
7262 // transfer ownership to the new map. 7270 // transfer ownership to the new map.
7263 Handle<Map> new_map; 7271 Handle<Map> new_map;
7264 if (map->owns_descriptors()) { 7272 if (map->owns_descriptors()) {
7265 new_map = CopyDropDescriptors(map); 7273 new_map = CopyDropDescriptors(map);
7266 } else { 7274 } else {
7275 DCHECK(!map->is_prototype_map());
7267 new_map = Copy(map); 7276 new_map = Copy(map);
7268 } 7277 }
7269 7278
7270 Handle<TransitionArray> transitions = TransitionArray::CopyInsert(
7271 map, isolate->factory()->observed_symbol(), new_map, FULL_TRANSITION);
7272
7273 map->set_transitions(*transitions);
7274
7275 new_map->set_is_observed(); 7279 new_map->set_is_observed();
7276
7277 if (map->owns_descriptors()) { 7280 if (map->owns_descriptors()) {
7278 new_map->InitializeDescriptors(map->instance_descriptors()); 7281 new_map->InitializeDescriptors(map->instance_descriptors());
7279 map->set_owns_descriptors(false);
7280 } 7282 }
7281 7283
7282 new_map->SetBackPointer(*map); 7284 Handle<Name> name = isolate->factory()->observed_symbol();
7285 ConnectTransition(map, new_map, name, FULL_TRANSITION);
7286
7283 return new_map; 7287 return new_map;
7284 } 7288 }
7285 7289
7286 7290
7287 Handle<Map> Map::CopyAsPrototypeMap(Handle<Map> map) { 7291 Handle<Map> Map::CopyAsPrototypeMap(Handle<Map> map) {
7288 Handle<Map> result = Copy(map); 7292 Handle<Map> result = Copy(map);
7289 result->mark_prototype_map(); 7293 result->mark_prototype_map();
7290 return result; 7294 return result;
7291 } 7295 }
7292 7296
(...skipping 4623 matching lines...) Expand 10 before | Expand all | Expand 10 after
11916 } 11920 }
11917 return Handle<Map>(); 11921 return Handle<Map>();
11918 } 11922 }
11919 11923
11920 11924
11921 Handle<Map> Map::PutPrototypeTransition(Handle<Map> map, 11925 Handle<Map> Map::PutPrototypeTransition(Handle<Map> map,
11922 Handle<Object> prototype, 11926 Handle<Object> prototype,
11923 Handle<Map> target_map) { 11927 Handle<Map> target_map) {
11924 DCHECK(target_map->IsMap()); 11928 DCHECK(target_map->IsMap());
11925 DCHECK(HeapObject::cast(*prototype)->map()->IsMap()); 11929 DCHECK(HeapObject::cast(*prototype)->map()->IsMap());
11926 // Don't cache prototype transition if this map is shared. 11930 // Don't cache prototype transition if this map is either shared, or a map of
11931 // a prototype.
11932 if (map->is_prototype_map()) return map;
11927 if (map->is_shared() || !FLAG_cache_prototype_transitions) return map; 11933 if (map->is_shared() || !FLAG_cache_prototype_transitions) return map;
11928 11934
11929 const int step = kProtoTransitionElementsPerEntry; 11935 const int step = kProtoTransitionElementsPerEntry;
11930 const int header = kProtoTransitionHeaderSize; 11936 const int header = kProtoTransitionHeaderSize;
11931 11937
11932 Handle<FixedArray> cache(map->GetPrototypeTransitions()); 11938 Handle<FixedArray> cache(map->GetPrototypeTransitions());
11933 int capacity = (cache->length() - header) / step; 11939 int capacity = (cache->length() - header) / step;
11934 int transitions = map->NumberOfProtoTransitions() + 1; 11940 int transitions = map->NumberOfProtoTransitions() + 1;
11935 11941
11936 if (transitions > capacity) { 11942 if (transitions > capacity) {
(...skipping 5108 matching lines...) Expand 10 before | Expand all | Expand 10 after
17045 #define ERROR_MESSAGES_TEXTS(C, T) T, 17051 #define ERROR_MESSAGES_TEXTS(C, T) T,
17046 static const char* error_messages_[] = { 17052 static const char* error_messages_[] = {
17047 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 17053 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
17048 }; 17054 };
17049 #undef ERROR_MESSAGES_TEXTS 17055 #undef ERROR_MESSAGES_TEXTS
17050 return error_messages_[reason]; 17056 return error_messages_[reason];
17051 } 17057 }
17052 17058
17053 17059
17054 } } // namespace v8::internal 17060 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698