OLD | NEW |
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 <sstream> | 5 #include <sstream> |
6 | 6 |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
10 #include "src/allocation-site-scopes.h" | 10 #include "src/allocation-site-scopes.h" |
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 if (object->IsGlobalObject()) { | 701 if (object->IsGlobalObject()) { |
702 PropertyDetails details = dictionary->DetailsAt(entry); | 702 PropertyDetails details = dictionary->DetailsAt(entry); |
703 if (!details.IsConfigurable()) { | 703 if (!details.IsConfigurable()) { |
704 if (mode != FORCE_DELETION) return isolate->factory()->false_value(); | 704 if (mode != FORCE_DELETION) return isolate->factory()->false_value(); |
705 // When forced to delete global properties, we have to make a | 705 // When forced to delete global properties, we have to make a |
706 // map change to invalidate any ICs that think they can load | 706 // map change to invalidate any ICs that think they can load |
707 // from the non-configurable cell without checking if it contains | 707 // from the non-configurable cell without checking if it contains |
708 // the hole value. | 708 // the hole value. |
709 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); | 709 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); |
710 DCHECK(new_map->is_dictionary_map()); | 710 DCHECK(new_map->is_dictionary_map()); |
| 711 #if TRACE_MAPS |
| 712 if (FLAG_trace_maps) { |
| 713 PrintF("[TraceMaps: GlobalDeleteNormalized from= %p to= %p ]\n", |
| 714 reinterpret_cast<void*>(object->map()), |
| 715 reinterpret_cast<void*>(*new_map)); |
| 716 } |
| 717 #endif |
711 JSObject::MigrateToMap(object, new_map); | 718 JSObject::MigrateToMap(object, new_map); |
712 } | 719 } |
713 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); | 720 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); |
714 Handle<Object> value = isolate->factory()->the_hole_value(); | 721 Handle<Object> value = isolate->factory()->the_hole_value(); |
715 PropertyCell::SetValueInferType(cell, value); | 722 PropertyCell::SetValueInferType(cell, value); |
716 dictionary->DetailsAtPut(entry, details.AsDeleted()); | 723 dictionary->DetailsAtPut(entry, details.AsDeleted()); |
717 } else { | 724 } else { |
718 Handle<Object> deleted( | 725 Handle<Object> deleted( |
719 NameDictionary::DeleteProperty(dictionary, entry, mode)); | 726 NameDictionary::DeleteProperty(dictionary, entry, mode)); |
720 if (*deleted == isolate->heap()->true_value()) { | 727 if (*deleted == isolate->heap()->true_value()) { |
(...skipping 1422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2143 return result; | 2150 return result; |
2144 } | 2151 } |
2145 | 2152 |
2146 | 2153 |
2147 Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map, | 2154 Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map, |
2148 int modify_index, | 2155 int modify_index, |
2149 StoreMode store_mode, | 2156 StoreMode store_mode, |
2150 PropertyAttributes attributes, | 2157 PropertyAttributes attributes, |
2151 const char* reason) { | 2158 const char* reason) { |
2152 Isolate* isolate = map->GetIsolate(); | 2159 Isolate* isolate = map->GetIsolate(); |
2153 Handle<Map> new_map = Copy(map); | 2160 Handle<Map> new_map = Copy(map, reason); |
2154 | 2161 |
2155 DescriptorArray* descriptors = new_map->instance_descriptors(); | 2162 DescriptorArray* descriptors = new_map->instance_descriptors(); |
2156 int length = descriptors->number_of_descriptors(); | 2163 int length = descriptors->number_of_descriptors(); |
2157 for (int i = 0; i < length; i++) { | 2164 for (int i = 0; i < length; i++) { |
2158 descriptors->SetRepresentation(i, Representation::Tagged()); | 2165 descriptors->SetRepresentation(i, Representation::Tagged()); |
2159 if (descriptors->GetDetails(i).type() == FIELD) { | 2166 if (descriptors->GetDetails(i).type() == FIELD) { |
2160 descriptors->SetValue(i, HeapType::Any()); | 2167 descriptors->SetValue(i, HeapType::Any()); |
2161 } | 2168 } |
2162 } | 2169 } |
2163 | 2170 |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2452 old_descriptors->GetFieldType(modify_index), *new_field_type); | 2459 old_descriptors->GetFieldType(modify_index), *new_field_type); |
2453 } | 2460 } |
2454 old_descriptors->SetRepresentation(modify_index, new_representation); | 2461 old_descriptors->SetRepresentation(modify_index, new_representation); |
2455 old_descriptors->SetValue(modify_index, *new_field_type); | 2462 old_descriptors->SetValue(modify_index, *new_field_type); |
2456 return old_map; | 2463 return old_map; |
2457 } | 2464 } |
2458 | 2465 |
2459 // Check the state of the root map. | 2466 // Check the state of the root map. |
2460 Handle<Map> root_map(old_map->FindRootMap(), isolate); | 2467 Handle<Map> root_map(old_map->FindRootMap(), isolate); |
2461 if (!old_map->EquivalentToForTransition(*root_map)) { | 2468 if (!old_map->EquivalentToForTransition(*root_map)) { |
2462 return CopyGeneralizeAllRepresentations( | 2469 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
2463 old_map, modify_index, store_mode, "not equivalent"); | 2470 "GenAll_NotEquivalent"); |
2464 } | 2471 } |
2465 int root_nof = root_map->NumberOfOwnDescriptors(); | 2472 int root_nof = root_map->NumberOfOwnDescriptors(); |
2466 if (modify_index < root_nof) { | 2473 if (modify_index < root_nof) { |
2467 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 2474 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
2468 if ((old_details.type() != FIELD && store_mode == FORCE_FIELD) || | 2475 if ((old_details.type() != FIELD && store_mode == FORCE_FIELD) || |
2469 (old_details.type() == FIELD && | 2476 (old_details.type() == FIELD && |
2470 (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) || | 2477 (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) || |
2471 !new_representation.fits_into(old_details.representation())))) { | 2478 !new_representation.fits_into(old_details.representation())))) { |
2472 return CopyGeneralizeAllRepresentations( | 2479 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
2473 old_map, modify_index, store_mode, "root modification"); | 2480 "GenAll_RootModification"); |
2474 } | 2481 } |
2475 } | 2482 } |
2476 | 2483 |
2477 Handle<Map> target_map = root_map; | 2484 Handle<Map> target_map = root_map; |
2478 for (int i = root_nof; i < old_nof; ++i) { | 2485 for (int i = root_nof; i < old_nof; ++i) { |
2479 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2486 PropertyDetails old_details = old_descriptors->GetDetails(i); |
2480 int j = target_map->SearchTransition(old_details.type(), | 2487 int j = target_map->SearchTransition(old_details.type(), |
2481 old_descriptors->GetKey(i), | 2488 old_descriptors->GetKey(i), |
2482 old_details.attributes()); | 2489 old_details.attributes()); |
2483 if (j == TransitionArray::kNotFound) break; | 2490 if (j == TransitionArray::kNotFound) break; |
2484 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); | 2491 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); |
2485 Handle<DescriptorArray> tmp_descriptors = handle( | 2492 Handle<DescriptorArray> tmp_descriptors = handle( |
2486 tmp_map->instance_descriptors(), isolate); | 2493 tmp_map->instance_descriptors(), isolate); |
2487 | 2494 |
2488 // Check if target map is incompatible. | 2495 // Check if target map is incompatible. |
2489 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); | 2496 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); |
2490 PropertyType old_type = old_details.type(); | 2497 PropertyType old_type = old_details.type(); |
2491 PropertyType tmp_type = tmp_details.type(); | 2498 PropertyType tmp_type = tmp_details.type(); |
2492 DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); | 2499 DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); |
2493 if ((tmp_type == CALLBACKS || old_type == CALLBACKS) && | 2500 if ((tmp_type == CALLBACKS || old_type == CALLBACKS) && |
2494 (tmp_type != old_type || | 2501 (tmp_type != old_type || |
2495 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { | 2502 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { |
2496 return CopyGeneralizeAllRepresentations( | 2503 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
2497 old_map, modify_index, store_mode, "incompatible"); | 2504 "GenAll_Incompatible"); |
2498 } | 2505 } |
2499 Representation old_representation = old_details.representation(); | 2506 Representation old_representation = old_details.representation(); |
2500 Representation tmp_representation = tmp_details.representation(); | 2507 Representation tmp_representation = tmp_details.representation(); |
2501 if (!old_representation.fits_into(tmp_representation) || | 2508 if (!old_representation.fits_into(tmp_representation) || |
2502 (!new_representation.fits_into(tmp_representation) && | 2509 (!new_representation.fits_into(tmp_representation) && |
2503 modify_index == i)) { | 2510 modify_index == i)) { |
2504 break; | 2511 break; |
2505 } | 2512 } |
2506 if (tmp_type == FIELD) { | 2513 if (tmp_type == FIELD) { |
2507 // Generalize the field type as necessary. | 2514 // Generalize the field type as necessary. |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2552 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); | 2559 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); |
2553 Handle<DescriptorArray> tmp_descriptors( | 2560 Handle<DescriptorArray> tmp_descriptors( |
2554 tmp_map->instance_descriptors(), isolate); | 2561 tmp_map->instance_descriptors(), isolate); |
2555 | 2562 |
2556 // Check if target map is compatible. | 2563 // Check if target map is compatible. |
2557 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); | 2564 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); |
2558 DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); | 2565 DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); |
2559 if ((tmp_details.type() == CALLBACKS || old_details.type() == CALLBACKS) && | 2566 if ((tmp_details.type() == CALLBACKS || old_details.type() == CALLBACKS) && |
2560 (tmp_details.type() != old_details.type() || | 2567 (tmp_details.type() != old_details.type() || |
2561 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { | 2568 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { |
2562 return CopyGeneralizeAllRepresentations( | 2569 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
2563 old_map, modify_index, store_mode, "incompatible"); | 2570 "GenAll_Incompatible"); |
2564 } | 2571 } |
2565 target_map = tmp_map; | 2572 target_map = tmp_map; |
2566 } | 2573 } |
2567 target_nof = target_map->NumberOfOwnDescriptors(); | 2574 target_nof = target_map->NumberOfOwnDescriptors(); |
2568 target_descriptors = handle(target_map->instance_descriptors(), isolate); | 2575 target_descriptors = handle(target_map->instance_descriptors(), isolate); |
2569 | 2576 |
2570 // Allocate a new descriptor array large enough to hold the required | 2577 // Allocate a new descriptor array large enough to hold the required |
2571 // descriptors, with minimally the exact same size as the old descriptor | 2578 // descriptors, with minimally the exact same size as the old descriptor |
2572 // array. | 2579 // array. |
2573 int new_slack = Max( | 2580 int new_slack = Max( |
(...skipping 1679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4253 void HeapObject::UpdateMapCodeCache(Handle<HeapObject> object, | 4260 void HeapObject::UpdateMapCodeCache(Handle<HeapObject> object, |
4254 Handle<Name> name, | 4261 Handle<Name> name, |
4255 Handle<Code> code) { | 4262 Handle<Code> code) { |
4256 Handle<Map> map(object->map()); | 4263 Handle<Map> map(object->map()); |
4257 Map::UpdateCodeCache(map, name, code); | 4264 Map::UpdateCodeCache(map, name, code); |
4258 } | 4265 } |
4259 | 4266 |
4260 | 4267 |
4261 void JSObject::NormalizeProperties(Handle<JSObject> object, | 4268 void JSObject::NormalizeProperties(Handle<JSObject> object, |
4262 PropertyNormalizationMode mode, | 4269 PropertyNormalizationMode mode, |
4263 int expected_additional_properties) { | 4270 int expected_additional_properties, |
| 4271 const char* reason) { |
4264 if (!object->HasFastProperties()) return; | 4272 if (!object->HasFastProperties()) return; |
4265 | 4273 |
4266 Handle<Map> map(object->map()); | 4274 Handle<Map> map(object->map()); |
4267 Handle<Map> new_map = Map::Normalize(map, mode); | 4275 Handle<Map> new_map = Map::Normalize(map, mode, reason); |
4268 | 4276 |
4269 MigrateFastToSlow(object, new_map, expected_additional_properties); | 4277 MigrateFastToSlow(object, new_map, expected_additional_properties); |
4270 } | 4278 } |
4271 | 4279 |
4272 | 4280 |
4273 void JSObject::MigrateFastToSlow(Handle<JSObject> object, | 4281 void JSObject::MigrateFastToSlow(Handle<JSObject> object, |
4274 Handle<Map> new_map, | 4282 Handle<Map> new_map, |
4275 int expected_additional_properties) { | 4283 int expected_additional_properties) { |
4276 // The global object is always normalized. | 4284 // The global object is always normalized. |
4277 DCHECK(!object->IsGlobalObject()); | 4285 DCHECK(!object->IsGlobalObject()); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4365 if (FLAG_trace_normalization) { | 4373 if (FLAG_trace_normalization) { |
4366 OFStream os(stdout); | 4374 OFStream os(stdout); |
4367 os << "Object properties have been normalized:\n"; | 4375 os << "Object properties have been normalized:\n"; |
4368 object->Print(os); | 4376 object->Print(os); |
4369 } | 4377 } |
4370 #endif | 4378 #endif |
4371 } | 4379 } |
4372 | 4380 |
4373 | 4381 |
4374 void JSObject::MigrateSlowToFast(Handle<JSObject> object, | 4382 void JSObject::MigrateSlowToFast(Handle<JSObject> object, |
4375 int unused_property_fields) { | 4383 int unused_property_fields, |
| 4384 const char* reason) { |
4376 if (object->HasFastProperties()) return; | 4385 if (object->HasFastProperties()) return; |
4377 DCHECK(!object->IsGlobalObject()); | 4386 DCHECK(!object->IsGlobalObject()); |
4378 Isolate* isolate = object->GetIsolate(); | 4387 Isolate* isolate = object->GetIsolate(); |
4379 Factory* factory = isolate->factory(); | 4388 Factory* factory = isolate->factory(); |
4380 Handle<NameDictionary> dictionary(object->property_dictionary()); | 4389 Handle<NameDictionary> dictionary(object->property_dictionary()); |
4381 | 4390 |
4382 // Make sure we preserve dictionary representation if there are too many | 4391 // Make sure we preserve dictionary representation if there are too many |
4383 // descriptors. | 4392 // descriptors. |
4384 int number_of_elements = dictionary->NumberOfElements(); | 4393 int number_of_elements = dictionary->NumberOfElements(); |
4385 if (number_of_elements > kMaxNumberOfDescriptors) return; | 4394 if (number_of_elements > kMaxNumberOfDescriptors) return; |
(...skipping 21 matching lines...) Expand all Loading... |
4407 number_of_fields += 1; | 4416 number_of_fields += 1; |
4408 } | 4417 } |
4409 } | 4418 } |
4410 | 4419 |
4411 int inobject_props = object->map()->inobject_properties(); | 4420 int inobject_props = object->map()->inobject_properties(); |
4412 | 4421 |
4413 // Allocate new map. | 4422 // Allocate new map. |
4414 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); | 4423 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); |
4415 new_map->set_dictionary_map(false); | 4424 new_map->set_dictionary_map(false); |
4416 | 4425 |
| 4426 #if TRACE_MAPS |
| 4427 if (FLAG_trace_maps) { |
| 4428 PrintF("[TraceMaps: SlowToFast from= %p to= %p reason= %s ]\n", |
| 4429 reinterpret_cast<void*>(object->map()), |
| 4430 reinterpret_cast<void*>(*new_map), reason); |
| 4431 } |
| 4432 #endif |
| 4433 |
4417 if (instance_descriptor_length == 0) { | 4434 if (instance_descriptor_length == 0) { |
4418 DisallowHeapAllocation no_gc; | 4435 DisallowHeapAllocation no_gc; |
4419 DCHECK_LE(unused_property_fields, inobject_props); | 4436 DCHECK_LE(unused_property_fields, inobject_props); |
4420 // Transform the object. | 4437 // Transform the object. |
4421 new_map->set_unused_property_fields(inobject_props); | 4438 new_map->set_unused_property_fields(inobject_props); |
4422 object->synchronized_set_map(*new_map); | 4439 object->synchronized_set_map(*new_map); |
4423 object->set_properties(isolate->heap()->empty_fixed_array()); | 4440 object->set_properties(isolate->heap()->empty_fixed_array()); |
4424 // Check that it really works. | 4441 // Check that it really works. |
4425 DCHECK(object->HasFastProperties()); | 4442 DCHECK(object->HasFastProperties()); |
4426 return; | 4443 return; |
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5067 PropertyNormalizationMode mode = object->map()->is_prototype_map() | 5084 PropertyNormalizationMode mode = object->map()->is_prototype_map() |
5068 ? KEEP_INOBJECT_PROPERTIES | 5085 ? KEEP_INOBJECT_PROPERTIES |
5069 : CLEAR_INOBJECT_PROPERTIES; | 5086 : CLEAR_INOBJECT_PROPERTIES; |
5070 Handle<JSObject> holder = it.GetHolder<JSObject>(); | 5087 Handle<JSObject> holder = it.GetHolder<JSObject>(); |
5071 // TODO(verwaest): Remove this temporary compatibility hack when blink | 5088 // TODO(verwaest): Remove this temporary compatibility hack when blink |
5072 // tests are updated. | 5089 // tests are updated. |
5073 if (!holder.is_identical_to(object) && | 5090 if (!holder.is_identical_to(object) && |
5074 !(object->IsJSGlobalProxy() && holder->IsJSGlobalObject())) { | 5091 !(object->IsJSGlobalProxy() && holder->IsJSGlobalObject())) { |
5075 return it.isolate()->factory()->true_value(); | 5092 return it.isolate()->factory()->true_value(); |
5076 } | 5093 } |
5077 NormalizeProperties(holder, mode, 0); | 5094 NormalizeProperties(holder, mode, 0, "DeletingProperty"); |
5078 Handle<Object> result = | 5095 Handle<Object> result = |
5079 DeleteNormalizedProperty(holder, name, delete_mode); | 5096 DeleteNormalizedProperty(holder, name, delete_mode); |
5080 ReoptimizeIfPrototype(holder); | 5097 ReoptimizeIfPrototype(holder); |
5081 | 5098 |
5082 if (is_observed) { | 5099 if (is_observed) { |
5083 RETURN_ON_EXCEPTION( | 5100 RETURN_ON_EXCEPTION( |
5084 it.isolate(), | 5101 it.isolate(), |
5085 EnqueueChangeRecord(object, "delete", name, old_value), Object); | 5102 EnqueueChangeRecord(object, "delete", name, old_value), Object); |
5086 } | 5103 } |
5087 | 5104 |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5285 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); | 5302 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
5286 DCHECK(object->HasDictionaryElements() || | 5303 DCHECK(object->HasDictionaryElements() || |
5287 object->HasDictionaryArgumentsElements()); | 5304 object->HasDictionaryArgumentsElements()); |
5288 | 5305 |
5289 // Make sure that we never go back to fast case. | 5306 // Make sure that we never go back to fast case. |
5290 dictionary->set_requires_slow_elements(); | 5307 dictionary->set_requires_slow_elements(); |
5291 | 5308 |
5292 // Do a map transition, other objects with this map may still | 5309 // Do a map transition, other objects with this map may still |
5293 // be extensible. | 5310 // be extensible. |
5294 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. | 5311 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. |
5295 Handle<Map> new_map = Map::Copy(handle(object->map())); | 5312 Handle<Map> new_map = Map::Copy(handle(object->map()), "PreventExtensions"); |
5296 | 5313 |
5297 new_map->set_is_extensible(false); | 5314 new_map->set_is_extensible(false); |
5298 JSObject::MigrateToMap(object, new_map); | 5315 JSObject::MigrateToMap(object, new_map); |
5299 DCHECK(!object->map()->is_extensible()); | 5316 DCHECK(!object->map()->is_extensible()); |
5300 | 5317 |
5301 if (object->map()->is_observed()) { | 5318 if (object->map()->is_observed()) { |
5302 RETURN_ON_EXCEPTION( | 5319 RETURN_ON_EXCEPTION( |
5303 isolate, | 5320 isolate, |
5304 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), | 5321 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), |
5305 isolate->factory()->the_hole_value()), | 5322 isolate->factory()->the_hole_value()), |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5397 DCHECK(transition_map->is_frozen()); | 5414 DCHECK(transition_map->is_frozen()); |
5398 DCHECK(!transition_map->is_extensible()); | 5415 DCHECK(!transition_map->is_extensible()); |
5399 JSObject::MigrateToMap(object, transition_map); | 5416 JSObject::MigrateToMap(object, transition_map); |
5400 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) { | 5417 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) { |
5401 // Create a new descriptor array with fully-frozen properties | 5418 // Create a new descriptor array with fully-frozen properties |
5402 Handle<Map> new_map = Map::CopyForFreeze(old_map); | 5419 Handle<Map> new_map = Map::CopyForFreeze(old_map); |
5403 JSObject::MigrateToMap(object, new_map); | 5420 JSObject::MigrateToMap(object, new_map); |
5404 } else { | 5421 } else { |
5405 DCHECK(old_map->is_dictionary_map() || !old_map->is_prototype_map()); | 5422 DCHECK(old_map->is_dictionary_map() || !old_map->is_prototype_map()); |
5406 // Slow path: need to normalize properties for safety | 5423 // Slow path: need to normalize properties for safety |
5407 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); | 5424 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0, "SlowFreeze"); |
5408 | 5425 |
5409 // Create a new map, since other objects with this map may be extensible. | 5426 // Create a new map, since other objects with this map may be extensible. |
5410 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. | 5427 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. |
5411 Handle<Map> new_map = Map::Copy(handle(object->map())); | 5428 Handle<Map> new_map = Map::Copy(handle(object->map()), "SlowCopyForFreeze"); |
5412 new_map->freeze(); | 5429 new_map->freeze(); |
5413 new_map->set_is_extensible(false); | 5430 new_map->set_is_extensible(false); |
5414 new_map->set_elements_kind(DICTIONARY_ELEMENTS); | 5431 new_map->set_elements_kind(DICTIONARY_ELEMENTS); |
5415 JSObject::MigrateToMap(object, new_map); | 5432 JSObject::MigrateToMap(object, new_map); |
5416 | 5433 |
5417 // Freeze dictionary-mode properties | 5434 // Freeze dictionary-mode properties |
5418 FreezeDictionary(object->property_dictionary()); | 5435 FreezeDictionary(object->property_dictionary()); |
5419 } | 5436 } |
5420 | 5437 |
5421 DCHECK(object->map()->has_dictionary_elements()); | 5438 DCHECK(object->map()->has_dictionary_elements()); |
(...skipping 21 matching lines...) Expand all Loading... |
5443 Handle<Map> old_map(object->map(), isolate); | 5460 Handle<Map> old_map(object->map(), isolate); |
5444 DCHECK(!old_map->is_observed()); | 5461 DCHECK(!old_map->is_observed()); |
5445 int transition_index = | 5462 int transition_index = |
5446 old_map->SearchSpecialTransition(isolate->heap()->observed_symbol()); | 5463 old_map->SearchSpecialTransition(isolate->heap()->observed_symbol()); |
5447 if (transition_index != TransitionArray::kNotFound) { | 5464 if (transition_index != TransitionArray::kNotFound) { |
5448 new_map = handle(old_map->GetTransition(transition_index), isolate); | 5465 new_map = handle(old_map->GetTransition(transition_index), isolate); |
5449 DCHECK(new_map->is_observed()); | 5466 DCHECK(new_map->is_observed()); |
5450 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) { | 5467 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) { |
5451 new_map = Map::CopyForObserved(old_map); | 5468 new_map = Map::CopyForObserved(old_map); |
5452 } else { | 5469 } else { |
5453 new_map = Map::Copy(old_map); | 5470 new_map = Map::Copy(old_map, "SlowObserved"); |
5454 new_map->set_is_observed(); | 5471 new_map->set_is_observed(); |
5455 } | 5472 } |
5456 JSObject::MigrateToMap(object, new_map); | 5473 JSObject::MigrateToMap(object, new_map); |
5457 } | 5474 } |
5458 | 5475 |
5459 | 5476 |
5460 Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object, | 5477 Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object, |
5461 Representation representation, | 5478 Representation representation, |
5462 FieldIndex index) { | 5479 FieldIndex index) { |
5463 Isolate* isolate = object->GetIsolate(); | 5480 Isolate* isolate = object->GetIsolate(); |
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6160 | 6177 |
6161 | 6178 |
6162 void JSObject::SetPropertyCallback(Handle<JSObject> object, | 6179 void JSObject::SetPropertyCallback(Handle<JSObject> object, |
6163 Handle<Name> name, | 6180 Handle<Name> name, |
6164 Handle<Object> structure, | 6181 Handle<Object> structure, |
6165 PropertyAttributes attributes) { | 6182 PropertyAttributes attributes) { |
6166 PropertyNormalizationMode mode = object->map()->is_prototype_map() | 6183 PropertyNormalizationMode mode = object->map()->is_prototype_map() |
6167 ? KEEP_INOBJECT_PROPERTIES | 6184 ? KEEP_INOBJECT_PROPERTIES |
6168 : CLEAR_INOBJECT_PROPERTIES; | 6185 : CLEAR_INOBJECT_PROPERTIES; |
6169 // Normalize object to make this operation simple. | 6186 // Normalize object to make this operation simple. |
6170 NormalizeProperties(object, mode, 0); | 6187 NormalizeProperties(object, mode, 0, "SetPropertyCallback"); |
6171 | 6188 |
6172 // For the global object allocate a new map to invalidate the global inline | 6189 // For the global object allocate a new map to invalidate the global inline |
6173 // caches which have a global property cell reference directly in the code. | 6190 // caches which have a global property cell reference directly in the code. |
6174 if (object->IsGlobalObject()) { | 6191 if (object->IsGlobalObject()) { |
6175 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); | 6192 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); |
6176 DCHECK(new_map->is_dictionary_map()); | 6193 DCHECK(new_map->is_dictionary_map()); |
| 6194 #if TRACE_MAPS |
| 6195 if (FLAG_trace_maps) { |
| 6196 PrintF("[TraceMaps: GlobalPropertyCallback from= %p to= %p ]\n", |
| 6197 reinterpret_cast<void*>(object->map()), |
| 6198 reinterpret_cast<void*>(*new_map)); |
| 6199 } |
| 6200 #endif |
6177 JSObject::MigrateToMap(object, new_map); | 6201 JSObject::MigrateToMap(object, new_map); |
6178 | 6202 |
6179 // When running crankshaft, changing the map is not enough. We | 6203 // When running crankshaft, changing the map is not enough. We |
6180 // need to deoptimize all functions that rely on this global | 6204 // need to deoptimize all functions that rely on this global |
6181 // object. | 6205 // object. |
6182 Deoptimizer::DeoptimizeGlobalObject(*object); | 6206 Deoptimizer::DeoptimizeGlobalObject(*object); |
6183 } | 6207 } |
6184 | 6208 |
6185 // Update the dictionary with the new CALLBACKS property. | 6209 // Update the dictionary with the new CALLBACKS property. |
6186 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); | 6210 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6487 if (!map->is_dictionary_map()) { | 6511 if (!map->is_dictionary_map()) { |
6488 new_bit_field3 = IsUnstable::update(new_bit_field3, false); | 6512 new_bit_field3 = IsUnstable::update(new_bit_field3, false); |
6489 } | 6513 } |
6490 new_bit_field3 = ConstructionCount::update(new_bit_field3, | 6514 new_bit_field3 = ConstructionCount::update(new_bit_field3, |
6491 JSFunction::kNoSlackTracking); | 6515 JSFunction::kNoSlackTracking); |
6492 result->set_bit_field3(new_bit_field3); | 6516 result->set_bit_field3(new_bit_field3); |
6493 return result; | 6517 return result; |
6494 } | 6518 } |
6495 | 6519 |
6496 | 6520 |
6497 Handle<Map> Map::Normalize(Handle<Map> fast_map, | 6521 Handle<Map> Map::Normalize(Handle<Map> fast_map, PropertyNormalizationMode mode, |
6498 PropertyNormalizationMode mode) { | 6522 const char* reason) { |
6499 DCHECK(!fast_map->is_dictionary_map()); | 6523 DCHECK(!fast_map->is_dictionary_map()); |
6500 | 6524 |
6501 Isolate* isolate = fast_map->GetIsolate(); | 6525 Isolate* isolate = fast_map->GetIsolate(); |
6502 Handle<Object> maybe_cache(isolate->native_context()->normalized_map_cache(), | 6526 Handle<Object> maybe_cache(isolate->native_context()->normalized_map_cache(), |
6503 isolate); | 6527 isolate); |
6504 bool use_cache = !maybe_cache->IsUndefined(); | 6528 bool use_cache = !maybe_cache->IsUndefined(); |
6505 Handle<NormalizedMapCache> cache; | 6529 Handle<NormalizedMapCache> cache; |
6506 if (use_cache) cache = Handle<NormalizedMapCache>::cast(maybe_cache); | 6530 if (use_cache) cache = Handle<NormalizedMapCache>::cast(maybe_cache); |
6507 | 6531 |
6508 Handle<Map> new_map; | 6532 Handle<Map> new_map; |
(...skipping 18 matching lines...) Expand all Loading... |
6527 new_map->address() + offset, | 6551 new_map->address() + offset, |
6528 Map::kSize - offset) == 0); | 6552 Map::kSize - offset) == 0); |
6529 } | 6553 } |
6530 #endif | 6554 #endif |
6531 } else { | 6555 } else { |
6532 new_map = Map::CopyNormalized(fast_map, mode); | 6556 new_map = Map::CopyNormalized(fast_map, mode); |
6533 if (use_cache) { | 6557 if (use_cache) { |
6534 cache->Set(fast_map, new_map); | 6558 cache->Set(fast_map, new_map); |
6535 isolate->counters()->normalized_maps()->Increment(); | 6559 isolate->counters()->normalized_maps()->Increment(); |
6536 } | 6560 } |
| 6561 #if TRACE_MAPS |
| 6562 if (FLAG_trace_maps) { |
| 6563 PrintF("[TraceMaps: Normalize from= %p to= %p reason= %s ]\n", |
| 6564 reinterpret_cast<void*>(*fast_map), |
| 6565 reinterpret_cast<void*>(*new_map), reason); |
| 6566 } |
| 6567 #endif |
6537 } | 6568 } |
6538 fast_map->NotifyLeafMapLayoutChange(); | 6569 fast_map->NotifyLeafMapLayoutChange(); |
6539 return new_map; | 6570 return new_map; |
6540 } | 6571 } |
6541 | 6572 |
6542 | 6573 |
6543 Handle<Map> Map::CopyNormalized(Handle<Map> map, | 6574 Handle<Map> Map::CopyNormalized(Handle<Map> map, |
6544 PropertyNormalizationMode mode) { | 6575 PropertyNormalizationMode mode) { |
6545 int new_instance_size = map->instance_size(); | 6576 int new_instance_size = map->instance_size(); |
6546 if (mode == CLEAR_INOBJECT_PROPERTIES) { | 6577 if (mode == CLEAR_INOBJECT_PROPERTIES) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6609 result->InitializeDescriptors(*descriptors); | 6640 result->InitializeDescriptors(*descriptors); |
6610 } | 6641 } |
6611 | 6642 |
6612 DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1); | 6643 DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1); |
6613 ConnectTransition(map, result, name, SIMPLE_PROPERTY_TRANSITION); | 6644 ConnectTransition(map, result, name, SIMPLE_PROPERTY_TRANSITION); |
6614 | 6645 |
6615 return result; | 6646 return result; |
6616 } | 6647 } |
6617 | 6648 |
6618 | 6649 |
| 6650 #if TRACE_MAPS |
| 6651 |
| 6652 // static |
| 6653 void Map::TraceTransition(const char* what, Map* from, Map* to, Name* name) { |
| 6654 if (FLAG_trace_maps) { |
| 6655 PrintF("[TraceMaps: %s from= %p to= %p name= ", what, |
| 6656 reinterpret_cast<void*>(from), reinterpret_cast<void*>(to)); |
| 6657 name->NameShortPrint(); |
| 6658 PrintF(" ]\n"); |
| 6659 } |
| 6660 } |
| 6661 |
| 6662 |
| 6663 // static |
| 6664 void Map::TraceAllTransitions(Map* map) { |
| 6665 if (!map->HasTransitionArray()) return; |
| 6666 TransitionArray* transitions = map->transitions(); |
| 6667 for (int i = 0; i < transitions->number_of_transitions(); ++i) { |
| 6668 Map* target = transitions->GetTarget(i); |
| 6669 Map::TraceTransition("Transition", map, target, transitions->GetKey(i)); |
| 6670 Map::TraceAllTransitions(target); |
| 6671 } |
| 6672 } |
| 6673 |
| 6674 #endif // TRACE_MAPS |
| 6675 |
| 6676 |
6619 void Map::ConnectTransition(Handle<Map> parent, Handle<Map> child, | 6677 void Map::ConnectTransition(Handle<Map> parent, Handle<Map> child, |
6620 Handle<Name> name, SimpleTransitionFlag flag) { | 6678 Handle<Name> name, SimpleTransitionFlag flag) { |
6621 parent->set_owns_descriptors(false); | 6679 parent->set_owns_descriptors(false); |
6622 if (parent->is_prototype_map()) { | 6680 if (parent->is_prototype_map()) { |
6623 DCHECK(child->is_prototype_map()); | 6681 DCHECK(child->is_prototype_map()); |
| 6682 #if TRACE_MAPS |
| 6683 Map::TraceTransition("NoTransition", *parent, *child, *name); |
| 6684 #endif |
6624 } else { | 6685 } else { |
6625 Handle<TransitionArray> transitions = | 6686 Handle<TransitionArray> transitions = |
6626 TransitionArray::Insert(parent, name, child, flag); | 6687 TransitionArray::Insert(parent, name, child, flag); |
6627 if (!parent->HasTransitionArray() || | 6688 if (!parent->HasTransitionArray() || |
6628 *transitions != parent->transitions()) { | 6689 *transitions != parent->transitions()) { |
6629 parent->set_transitions(*transitions); | 6690 parent->set_transitions(*transitions); |
6630 } | 6691 } |
6631 child->SetBackPointer(*parent); | 6692 child->SetBackPointer(*parent); |
| 6693 #if TRACE_MAPS |
| 6694 Map::TraceTransition("Transition", *parent, *child, *name); |
| 6695 #endif |
6632 } | 6696 } |
6633 } | 6697 } |
6634 | 6698 |
6635 | 6699 |
6636 Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map, | 6700 Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map, |
6637 Handle<DescriptorArray> descriptors, | 6701 Handle<DescriptorArray> descriptors, |
6638 TransitionFlag flag, | 6702 TransitionFlag flag, |
6639 MaybeHandle<Name> maybe_name, | 6703 MaybeHandle<Name> maybe_name, |
| 6704 const char* reason, |
6640 SimpleTransitionFlag simple_flag) { | 6705 SimpleTransitionFlag simple_flag) { |
6641 DCHECK(descriptors->IsSortedNoDuplicates()); | 6706 DCHECK(descriptors->IsSortedNoDuplicates()); |
6642 | 6707 |
6643 Handle<Map> result = CopyDropDescriptors(map); | 6708 Handle<Map> result = CopyDropDescriptors(map); |
6644 result->InitializeDescriptors(*descriptors); | 6709 result->InitializeDescriptors(*descriptors); |
6645 | 6710 |
6646 if (!map->is_prototype_map()) { | 6711 if (!map->is_prototype_map()) { |
6647 if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) { | 6712 if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) { |
6648 Handle<Name> name; | 6713 Handle<Name> name; |
6649 CHECK(maybe_name.ToHandle(&name)); | 6714 CHECK(maybe_name.ToHandle(&name)); |
6650 ConnectTransition(map, result, name, simple_flag); | 6715 ConnectTransition(map, result, name, simple_flag); |
6651 } else { | 6716 } else { |
6652 int length = descriptors->number_of_descriptors(); | 6717 int length = descriptors->number_of_descriptors(); |
6653 for (int i = 0; i < length; i++) { | 6718 for (int i = 0; i < length; i++) { |
6654 descriptors->SetRepresentation(i, Representation::Tagged()); | 6719 descriptors->SetRepresentation(i, Representation::Tagged()); |
6655 if (descriptors->GetDetails(i).type() == FIELD) { | 6720 if (descriptors->GetDetails(i).type() == FIELD) { |
6656 descriptors->SetValue(i, HeapType::Any()); | 6721 descriptors->SetValue(i, HeapType::Any()); |
6657 } | 6722 } |
6658 } | 6723 } |
6659 } | 6724 } |
6660 } | 6725 } |
| 6726 #if TRACE_MAPS |
| 6727 if (FLAG_trace_maps && |
| 6728 // Mirror conditions above that did not call ConnectTransition(). |
| 6729 (map->is_prototype_map() || |
| 6730 !(flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()))) { |
| 6731 PrintF("[TraceMaps: ReplaceDescriptors from= %p to= %p reason= %s ]\n", |
| 6732 reinterpret_cast<void*>(*map), reinterpret_cast<void*>(*result), |
| 6733 reason); |
| 6734 } |
| 6735 #endif |
6661 | 6736 |
6662 return result; | 6737 return result; |
6663 } | 6738 } |
6664 | 6739 |
6665 | 6740 |
6666 // Since this method is used to rewrite an existing transition tree, it can | 6741 // Since this method is used to rewrite an existing transition tree, it can |
6667 // always insert transitions without checking. | 6742 // always insert transitions without checking. |
6668 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map, | 6743 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map, |
6669 int new_descriptor, | 6744 int new_descriptor, |
6670 Handle<DescriptorArray> descriptors) { | 6745 Handle<DescriptorArray> descriptors) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6719 ConnectElementsTransition(map, new_map); | 6794 ConnectElementsTransition(map, new_map); |
6720 | 6795 |
6721 new_map->set_elements_kind(kind); | 6796 new_map->set_elements_kind(kind); |
6722 new_map->InitializeDescriptors(map->instance_descriptors()); | 6797 new_map->InitializeDescriptors(map->instance_descriptors()); |
6723 return new_map; | 6798 return new_map; |
6724 } | 6799 } |
6725 | 6800 |
6726 // In case the map did not own its own descriptors, a split is forced by | 6801 // In case the map did not own its own descriptors, a split is forced by |
6727 // copying the map; creating a new descriptor array cell. | 6802 // copying the map; creating a new descriptor array cell. |
6728 // Create a new free-floating map only if we are not allowed to store it. | 6803 // Create a new free-floating map only if we are not allowed to store it. |
6729 Handle<Map> new_map = Copy(map); | 6804 Handle<Map> new_map = Copy(map, "CopyAsElementsKind"); |
6730 | 6805 |
6731 new_map->set_elements_kind(kind); | 6806 new_map->set_elements_kind(kind); |
6732 | 6807 |
6733 if (insert_transition) { | 6808 if (insert_transition) { |
6734 ConnectElementsTransition(map, new_map); | 6809 ConnectElementsTransition(map, new_map); |
6735 } | 6810 } |
6736 | 6811 |
6737 return new_map; | 6812 return new_map; |
6738 } | 6813 } |
6739 | 6814 |
6740 | 6815 |
6741 Handle<Map> Map::CopyForObserved(Handle<Map> map) { | 6816 Handle<Map> Map::CopyForObserved(Handle<Map> map) { |
6742 DCHECK(!map->is_observed()); | 6817 DCHECK(!map->is_observed()); |
6743 | 6818 |
6744 Isolate* isolate = map->GetIsolate(); | 6819 Isolate* isolate = map->GetIsolate(); |
6745 | 6820 |
6746 // In case the map owned its own descriptors, share the descriptors and | 6821 // In case the map owned its own descriptors, share the descriptors and |
6747 // transfer ownership to the new map. | 6822 // transfer ownership to the new map. |
6748 Handle<Map> new_map; | 6823 Handle<Map> new_map; |
6749 if (map->owns_descriptors()) { | 6824 if (map->owns_descriptors()) { |
6750 new_map = CopyDropDescriptors(map); | 6825 new_map = CopyDropDescriptors(map); |
6751 } else { | 6826 } else { |
6752 DCHECK(!map->is_prototype_map()); | 6827 DCHECK(!map->is_prototype_map()); |
6753 new_map = Copy(map); | 6828 new_map = Copy(map, "CopyForObserved"); |
6754 } | 6829 } |
6755 | 6830 |
6756 new_map->set_is_observed(); | 6831 new_map->set_is_observed(); |
6757 if (map->owns_descriptors()) { | 6832 if (map->owns_descriptors()) { |
6758 new_map->InitializeDescriptors(map->instance_descriptors()); | 6833 new_map->InitializeDescriptors(map->instance_descriptors()); |
6759 } | 6834 } |
6760 | 6835 |
6761 if (map->CanHaveMoreTransitions()) { | 6836 if (map->CanHaveMoreTransitions()) { |
6762 Handle<Name> name = isolate->factory()->observed_symbol(); | 6837 Handle<Name> name = isolate->factory()->observed_symbol(); |
6763 ConnectTransition(map, new_map, name, SPECIAL_TRANSITION); | 6838 ConnectTransition(map, new_map, name, SPECIAL_TRANSITION); |
6764 } | 6839 } |
6765 return new_map; | 6840 return new_map; |
6766 } | 6841 } |
6767 | 6842 |
6768 | 6843 |
6769 Handle<Map> Map::Copy(Handle<Map> map) { | 6844 Handle<Map> Map::Copy(Handle<Map> map, const char* reason) { |
6770 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 6845 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
6771 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); | 6846 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); |
6772 Handle<DescriptorArray> new_descriptors = | 6847 Handle<DescriptorArray> new_descriptors = |
6773 DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors); | 6848 DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors); |
6774 return CopyReplaceDescriptors(map, new_descriptors, OMIT_TRANSITION, | 6849 return CopyReplaceDescriptors(map, new_descriptors, OMIT_TRANSITION, |
6775 MaybeHandle<Name>(), SPECIAL_TRANSITION); | 6850 MaybeHandle<Name>(), reason, |
| 6851 SPECIAL_TRANSITION); |
6776 } | 6852 } |
6777 | 6853 |
6778 | 6854 |
6779 Handle<Map> Map::Create(Isolate* isolate, int inobject_properties) { | 6855 Handle<Map> Map::Create(Isolate* isolate, int inobject_properties) { |
6780 Handle<Map> copy = Copy(handle(isolate->object_function()->initial_map())); | 6856 Handle<Map> copy = |
| 6857 Copy(handle(isolate->object_function()->initial_map()), "MapCreate"); |
6781 | 6858 |
6782 // Check that we do not overflow the instance size when adding the extra | 6859 // Check that we do not overflow the instance size when adding the extra |
6783 // inobject properties. If the instance size overflows, we allocate as many | 6860 // inobject properties. If the instance size overflows, we allocate as many |
6784 // properties as we can as inobject properties. | 6861 // properties as we can as inobject properties. |
6785 int max_extra_properties = | 6862 int max_extra_properties = |
6786 (JSObject::kMaxInstanceSize - JSObject::kHeaderSize) >> kPointerSizeLog2; | 6863 (JSObject::kMaxInstanceSize - JSObject::kHeaderSize) >> kPointerSizeLog2; |
6787 | 6864 |
6788 if (inobject_properties > max_extra_properties) { | 6865 if (inobject_properties > max_extra_properties) { |
6789 inobject_properties = max_extra_properties; | 6866 inobject_properties = max_extra_properties; |
6790 } | 6867 } |
(...skipping 10 matching lines...) Expand all Loading... |
6801 } | 6878 } |
6802 | 6879 |
6803 | 6880 |
6804 Handle<Map> Map::CopyForFreeze(Handle<Map> map) { | 6881 Handle<Map> Map::CopyForFreeze(Handle<Map> map) { |
6805 int num_descriptors = map->NumberOfOwnDescriptors(); | 6882 int num_descriptors = map->NumberOfOwnDescriptors(); |
6806 Isolate* isolate = map->GetIsolate(); | 6883 Isolate* isolate = map->GetIsolate(); |
6807 Handle<DescriptorArray> new_desc = DescriptorArray::CopyUpToAddAttributes( | 6884 Handle<DescriptorArray> new_desc = DescriptorArray::CopyUpToAddAttributes( |
6808 handle(map->instance_descriptors(), isolate), num_descriptors, FROZEN); | 6885 handle(map->instance_descriptors(), isolate), num_descriptors, FROZEN); |
6809 Handle<Map> new_map = CopyReplaceDescriptors( | 6886 Handle<Map> new_map = CopyReplaceDescriptors( |
6810 map, new_desc, INSERT_TRANSITION, isolate->factory()->frozen_symbol(), | 6887 map, new_desc, INSERT_TRANSITION, isolate->factory()->frozen_symbol(), |
6811 SPECIAL_TRANSITION); | 6888 "CopyForFreeze", SPECIAL_TRANSITION); |
6812 new_map->freeze(); | 6889 new_map->freeze(); |
6813 new_map->set_is_extensible(false); | 6890 new_map->set_is_extensible(false); |
6814 new_map->set_elements_kind(DICTIONARY_ELEMENTS); | 6891 new_map->set_elements_kind(DICTIONARY_ELEMENTS); |
6815 return new_map; | 6892 return new_map; |
6816 } | 6893 } |
6817 | 6894 |
6818 | 6895 |
6819 bool DescriptorArray::CanHoldValue(int descriptor, Object* value) { | 6896 bool DescriptorArray::CanHoldValue(int descriptor, Object* value) { |
6820 PropertyDetails details = GetDetails(descriptor); | 6897 PropertyDetails details = GetDetails(descriptor); |
6821 switch (details.type()) { | 6898 switch (details.type()) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6891 } else if (!map->TooManyFastProperties(store_mode)) { | 6968 } else if (!map->TooManyFastProperties(store_mode)) { |
6892 Isolate* isolate = name->GetIsolate(); | 6969 Isolate* isolate = name->GetIsolate(); |
6893 Representation representation = value->OptimalRepresentation(); | 6970 Representation representation = value->OptimalRepresentation(); |
6894 Handle<HeapType> type = value->OptimalType(isolate, representation); | 6971 Handle<HeapType> type = value->OptimalType(isolate, representation); |
6895 maybe_map = | 6972 maybe_map = |
6896 Map::CopyWithField(map, name, type, attributes, representation, flag); | 6973 Map::CopyWithField(map, name, type, attributes, representation, flag); |
6897 } | 6974 } |
6898 | 6975 |
6899 Handle<Map> result; | 6976 Handle<Map> result; |
6900 if (!maybe_map.ToHandle(&result)) { | 6977 if (!maybe_map.ToHandle(&result)) { |
6901 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES); | 6978 #if TRACE_MAPS |
| 6979 if (FLAG_trace_maps) { |
| 6980 Vector<char> name_buffer = Vector<char>::New(100); |
| 6981 name->NameShortPrint(name_buffer); |
| 6982 Vector<char> buffer = Vector<char>::New(128); |
| 6983 SNPrintF(buffer, "TooManyFastProperties %s", name_buffer.start()); |
| 6984 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, buffer.start()); |
| 6985 } |
| 6986 #endif |
| 6987 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, |
| 6988 "TooManyFastProperties"); |
6902 } | 6989 } |
6903 | 6990 |
6904 return result; | 6991 return result; |
6905 } | 6992 } |
6906 | 6993 |
6907 | 6994 |
6908 Handle<Map> Map::ReconfigureDataProperty(Handle<Map> map, int descriptor, | 6995 Handle<Map> Map::ReconfigureDataProperty(Handle<Map> map, int descriptor, |
6909 PropertyAttributes attributes) { | 6996 PropertyAttributes attributes) { |
6910 // Dictionaries have to be reconfigured in-place. | 6997 // Dictionaries have to be reconfigured in-place. |
6911 DCHECK(!map->is_dictionary_map()); | 6998 DCHECK(!map->is_dictionary_map()); |
6912 | 6999 |
6913 // For now, give up on transitioning and just create a unique map. | 7000 // For now, give up on transitioning and just create a unique map. |
6914 // TODO(verwaest/ishell): Cache transitions with different attributes. | 7001 // TODO(verwaest/ishell): Cache transitions with different attributes. |
6915 return CopyGeneralizeAllRepresentations(map, descriptor, FORCE_FIELD, | 7002 return CopyGeneralizeAllRepresentations( |
6916 attributes, "attributes mismatch"); | 7003 map, descriptor, FORCE_FIELD, attributes, "GenAll_AttributesMismatch"); |
6917 } | 7004 } |
6918 | 7005 |
6919 | 7006 |
6920 Handle<Map> Map::TransitionToAccessorProperty(Handle<Map> map, | 7007 Handle<Map> Map::TransitionToAccessorProperty(Handle<Map> map, |
6921 Handle<Name> name, | 7008 Handle<Name> name, |
6922 AccessorComponent component, | 7009 AccessorComponent component, |
6923 Handle<Object> accessor, | 7010 Handle<Object> accessor, |
6924 PropertyAttributes attributes) { | 7011 PropertyAttributes attributes) { |
6925 Isolate* isolate = name->GetIsolate(); | 7012 Isolate* isolate = name->GetIsolate(); |
6926 | 7013 |
6927 // Dictionary maps can always have additional data properties. | 7014 // Dictionary maps can always have additional data properties. |
6928 if (map->is_dictionary_map()) { | 7015 if (map->is_dictionary_map()) { |
6929 // For global objects, property cells are inlined. We need to change the | 7016 // For global objects, property cells are inlined. We need to change the |
6930 // map. | 7017 // map. |
6931 if (map->IsGlobalObjectMap()) return Copy(map); | 7018 if (map->IsGlobalObjectMap()) return Copy(map, "GlobalAccessor"); |
6932 return map; | 7019 return map; |
6933 } | 7020 } |
6934 | 7021 |
6935 // Migrate to the newest map before transitioning to the new property. | 7022 // Migrate to the newest map before transitioning to the new property. |
6936 map = Update(map); | 7023 map = Update(map); |
6937 | 7024 |
6938 PropertyNormalizationMode mode = map->is_prototype_map() | 7025 PropertyNormalizationMode mode = map->is_prototype_map() |
6939 ? KEEP_INOBJECT_PROPERTIES | 7026 ? KEEP_INOBJECT_PROPERTIES |
6940 : CLEAR_INOBJECT_PROPERTIES; | 7027 : CLEAR_INOBJECT_PROPERTIES; |
6941 | 7028 |
6942 int index = map->SearchTransition(CALLBACKS, *name, attributes); | 7029 int index = map->SearchTransition(CALLBACKS, *name, attributes); |
6943 if (index != TransitionArray::kNotFound) { | 7030 if (index != TransitionArray::kNotFound) { |
6944 Handle<Map> transition(map->GetTransition(index)); | 7031 Handle<Map> transition(map->GetTransition(index)); |
6945 DescriptorArray* descriptors = transition->instance_descriptors(); | 7032 DescriptorArray* descriptors = transition->instance_descriptors(); |
6946 int descriptor = transition->LastAdded(); | 7033 int descriptor = transition->LastAdded(); |
6947 DCHECK(descriptors->GetKey(descriptor)->Equals(*name)); | 7034 DCHECK(descriptors->GetKey(descriptor)->Equals(*name)); |
6948 | 7035 |
6949 DCHECK_EQ(CALLBACKS, descriptors->GetDetails(descriptor).type()); | 7036 DCHECK_EQ(CALLBACKS, descriptors->GetDetails(descriptor).type()); |
6950 DCHECK_EQ(attributes, descriptors->GetDetails(descriptor).attributes()); | 7037 DCHECK_EQ(attributes, descriptors->GetDetails(descriptor).attributes()); |
6951 | 7038 |
6952 Handle<Object> maybe_pair(descriptors->GetValue(descriptor), isolate); | 7039 Handle<Object> maybe_pair(descriptors->GetValue(descriptor), isolate); |
6953 if (!maybe_pair->IsAccessorPair()) { | 7040 if (!maybe_pair->IsAccessorPair()) { |
6954 return Map::Normalize(map, mode); | 7041 return Map::Normalize(map, mode, "TransitionToAccessorFromNonPair"); |
6955 } | 7042 } |
6956 | 7043 |
6957 Handle<AccessorPair> pair = Handle<AccessorPair>::cast(maybe_pair); | 7044 Handle<AccessorPair> pair = Handle<AccessorPair>::cast(maybe_pair); |
6958 if (pair->get(component) != *accessor) { | 7045 if (pair->get(component) != *accessor) { |
6959 return Map::Normalize(map, mode); | 7046 return Map::Normalize(map, mode, "TransitionToDifferentAccessor"); |
6960 } | 7047 } |
6961 | 7048 |
6962 return transition; | 7049 return transition; |
6963 } | 7050 } |
6964 | 7051 |
6965 Handle<AccessorPair> pair; | 7052 Handle<AccessorPair> pair; |
6966 DescriptorArray* old_descriptors = map->instance_descriptors(); | 7053 DescriptorArray* old_descriptors = map->instance_descriptors(); |
6967 int descriptor = old_descriptors->SearchWithCache(*name, *map); | 7054 int descriptor = old_descriptors->SearchWithCache(*name, *map); |
6968 if (descriptor != DescriptorArray::kNotFound) { | 7055 if (descriptor != DescriptorArray::kNotFound) { |
6969 if (descriptor != map->LastAdded()) { | 7056 if (descriptor != map->LastAdded()) { |
6970 return Map::Normalize(map, mode); | 7057 return Map::Normalize(map, mode, "AccessorsOverwritingNonLast"); |
6971 } | 7058 } |
6972 PropertyDetails old_details = old_descriptors->GetDetails(descriptor); | 7059 PropertyDetails old_details = old_descriptors->GetDetails(descriptor); |
6973 if (old_details.type() != CALLBACKS) { | 7060 if (old_details.type() != CALLBACKS) { |
6974 return Map::Normalize(map, mode); | 7061 return Map::Normalize(map, mode, "AccessorsOverwritingNonAccessors"); |
6975 } | 7062 } |
6976 | 7063 |
6977 if (old_details.attributes() != attributes) { | 7064 if (old_details.attributes() != attributes) { |
6978 return Map::Normalize(map, mode); | 7065 return Map::Normalize(map, mode, "AccessorsWithAttributes"); |
6979 } | 7066 } |
6980 | 7067 |
6981 Handle<Object> maybe_pair(old_descriptors->GetValue(descriptor), isolate); | 7068 Handle<Object> maybe_pair(old_descriptors->GetValue(descriptor), isolate); |
6982 if (!maybe_pair->IsAccessorPair()) { | 7069 if (!maybe_pair->IsAccessorPair()) { |
6983 return Map::Normalize(map, mode); | 7070 return Map::Normalize(map, mode, "AccessorsOverwritingNonPair"); |
6984 } | 7071 } |
6985 | 7072 |
6986 Object* current = Handle<AccessorPair>::cast(maybe_pair)->get(component); | 7073 Object* current = Handle<AccessorPair>::cast(maybe_pair)->get(component); |
6987 if (current == *accessor) return map; | 7074 if (current == *accessor) return map; |
6988 | 7075 |
6989 if (!current->IsTheHole()) { | 7076 if (!current->IsTheHole()) { |
6990 return Map::Normalize(map, mode); | 7077 return Map::Normalize(map, mode, "AccessorsOverwritingAccessors"); |
6991 } | 7078 } |
6992 | 7079 |
6993 pair = AccessorPair::Copy(Handle<AccessorPair>::cast(maybe_pair)); | 7080 pair = AccessorPair::Copy(Handle<AccessorPair>::cast(maybe_pair)); |
6994 } else if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors || | 7081 } else if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors || |
6995 map->TooManyFastProperties(CERTAINLY_NOT_STORE_FROM_KEYED)) { | 7082 map->TooManyFastProperties(CERTAINLY_NOT_STORE_FROM_KEYED)) { |
6996 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES); | 7083 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, "TooManyAccessors"); |
6997 } else { | 7084 } else { |
6998 pair = isolate->factory()->NewAccessorPair(); | 7085 pair = isolate->factory()->NewAccessorPair(); |
6999 } | 7086 } |
7000 | 7087 |
7001 pair->set(component, *accessor); | 7088 pair->set(component, *accessor); |
7002 TransitionFlag flag = INSERT_TRANSITION; | 7089 TransitionFlag flag = INSERT_TRANSITION; |
7003 CallbacksDescriptor new_desc(name, pair, attributes); | 7090 CallbacksDescriptor new_desc(name, pair, attributes); |
7004 return Map::CopyInsertDescriptor(map, &new_desc, flag); | 7091 return Map::CopyInsertDescriptor(map, &new_desc, flag); |
7005 } | 7092 } |
7006 | 7093 |
(...skipping 10 matching lines...) Expand all Loading... |
7017 map->owns_descriptors() && | 7104 map->owns_descriptors() && |
7018 map->CanHaveMoreTransitions()) { | 7105 map->CanHaveMoreTransitions()) { |
7019 return ShareDescriptor(map, descriptors, descriptor); | 7106 return ShareDescriptor(map, descriptors, descriptor); |
7020 } | 7107 } |
7021 | 7108 |
7022 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( | 7109 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( |
7023 descriptors, map->NumberOfOwnDescriptors(), 1); | 7110 descriptors, map->NumberOfOwnDescriptors(), 1); |
7024 new_descriptors->Append(descriptor); | 7111 new_descriptors->Append(descriptor); |
7025 | 7112 |
7026 return CopyReplaceDescriptors(map, new_descriptors, flag, | 7113 return CopyReplaceDescriptors(map, new_descriptors, flag, |
7027 descriptor->GetKey(), | 7114 descriptor->GetKey(), "CopyAddDescriptor", |
7028 SIMPLE_PROPERTY_TRANSITION); | 7115 SIMPLE_PROPERTY_TRANSITION); |
7029 } | 7116 } |
7030 | 7117 |
7031 | 7118 |
7032 Handle<Map> Map::CopyInsertDescriptor(Handle<Map> map, | 7119 Handle<Map> Map::CopyInsertDescriptor(Handle<Map> map, |
7033 Descriptor* descriptor, | 7120 Descriptor* descriptor, |
7034 TransitionFlag flag) { | 7121 TransitionFlag flag) { |
7035 Handle<DescriptorArray> old_descriptors(map->instance_descriptors()); | 7122 Handle<DescriptorArray> old_descriptors(map->instance_descriptors()); |
7036 | 7123 |
7037 // Ensure the key is unique. | 7124 // Ensure the key is unique. |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7114 | 7201 |
7115 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( | 7202 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( |
7116 descriptors, map->NumberOfOwnDescriptors()); | 7203 descriptors, map->NumberOfOwnDescriptors()); |
7117 | 7204 |
7118 new_descriptors->Replace(insertion_index, descriptor); | 7205 new_descriptors->Replace(insertion_index, descriptor); |
7119 | 7206 |
7120 SimpleTransitionFlag simple_flag = | 7207 SimpleTransitionFlag simple_flag = |
7121 (insertion_index == descriptors->number_of_descriptors() - 1) | 7208 (insertion_index == descriptors->number_of_descriptors() - 1) |
7122 ? SIMPLE_PROPERTY_TRANSITION | 7209 ? SIMPLE_PROPERTY_TRANSITION |
7123 : PROPERTY_TRANSITION; | 7210 : PROPERTY_TRANSITION; |
7124 return CopyReplaceDescriptors(map, new_descriptors, flag, key, simple_flag); | 7211 return CopyReplaceDescriptors(map, new_descriptors, flag, key, |
| 7212 "CopyReplaceDescriptor", simple_flag); |
7125 } | 7213 } |
7126 | 7214 |
7127 | 7215 |
7128 void Map::UpdateCodeCache(Handle<Map> map, | 7216 void Map::UpdateCodeCache(Handle<Map> map, |
7129 Handle<Name> name, | 7217 Handle<Name> name, |
7130 Handle<Code> code) { | 7218 Handle<Code> code) { |
7131 Isolate* isolate = map->GetIsolate(); | 7219 Isolate* isolate = map->GetIsolate(); |
7132 HandleScope scope(isolate); | 7220 HandleScope scope(isolate); |
7133 // Allocate the code cache if not present. | 7221 // Allocate the code cache if not present. |
7134 if (map->code_cache()->IsFixedArray()) { | 7222 if (map->code_cache()->IsFixedArray()) { |
(...skipping 2272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9407 } | 9495 } |
9408 } | 9496 } |
9409 | 9497 |
9410 | 9498 |
9411 void JSObject::OptimizeAsPrototype(Handle<JSObject> object, | 9499 void JSObject::OptimizeAsPrototype(Handle<JSObject> object, |
9412 PrototypeOptimizationMode mode) { | 9500 PrototypeOptimizationMode mode) { |
9413 if (object->IsGlobalObject()) return; | 9501 if (object->IsGlobalObject()) return; |
9414 if (object->IsJSGlobalProxy()) return; | 9502 if (object->IsJSGlobalProxy()) return; |
9415 if (mode == FAST_PROTOTYPE && !object->map()->is_prototype_map()) { | 9503 if (mode == FAST_PROTOTYPE && !object->map()->is_prototype_map()) { |
9416 // First normalize to ensure all JSFunctions are CONSTANT. | 9504 // First normalize to ensure all JSFunctions are CONSTANT. |
9417 JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, 0); | 9505 JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, 0, |
| 9506 "NormalizeAsPrototype"); |
9418 } | 9507 } |
9419 if (!object->HasFastProperties()) { | 9508 if (!object->HasFastProperties()) { |
9420 JSObject::MigrateSlowToFast(object, 0); | 9509 JSObject::MigrateSlowToFast(object, 0, "OptimizeAsPrototype"); |
9421 } | 9510 } |
9422 if (mode == FAST_PROTOTYPE && object->HasFastProperties() && | 9511 if (mode == FAST_PROTOTYPE && object->HasFastProperties() && |
9423 !object->map()->is_prototype_map()) { | 9512 !object->map()->is_prototype_map()) { |
9424 Handle<Map> new_map = Map::Copy(handle(object->map())); | 9513 Handle<Map> new_map = Map::Copy(handle(object->map()), "CopyAsPrototype"); |
9425 JSObject::MigrateToMap(object, new_map); | 9514 JSObject::MigrateToMap(object, new_map); |
9426 object->map()->set_is_prototype_map(true); | 9515 object->map()->set_is_prototype_map(true); |
9427 } | 9516 } |
9428 } | 9517 } |
9429 | 9518 |
9430 | 9519 |
9431 void JSObject::ReoptimizeIfPrototype(Handle<JSObject> object) { | 9520 void JSObject::ReoptimizeIfPrototype(Handle<JSObject> object) { |
9432 if (!object->map()->is_prototype_map()) return; | 9521 if (!object->map()->is_prototype_map()) return; |
9433 OptimizeAsPrototype(object, FAST_PROTOTYPE); | 9522 OptimizeAsPrototype(object, FAST_PROTOTYPE); |
9434 } | 9523 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9484 | 9573 |
9485 Handle<Map> initial_map(function->initial_map(), isolate); | 9574 Handle<Map> initial_map(function->initial_map(), isolate); |
9486 | 9575 |
9487 if (!initial_map->GetIsolate()->bootstrapper()->IsActive() && | 9576 if (!initial_map->GetIsolate()->bootstrapper()->IsActive() && |
9488 initial_map->instance_type() == JS_OBJECT_TYPE) { | 9577 initial_map->instance_type() == JS_OBJECT_TYPE) { |
9489 // Put the value in the initial map field until an initial map is needed. | 9578 // Put the value in the initial map field until an initial map is needed. |
9490 // At that point, a new initial map is created and the prototype is put | 9579 // At that point, a new initial map is created and the prototype is put |
9491 // into the initial map where it belongs. | 9580 // into the initial map where it belongs. |
9492 function->set_prototype_or_initial_map(*value); | 9581 function->set_prototype_or_initial_map(*value); |
9493 } else { | 9582 } else { |
9494 Handle<Map> new_map = Map::Copy(initial_map); | 9583 Handle<Map> new_map = Map::Copy(initial_map, "SetInstancePrototype"); |
9495 JSFunction::SetInitialMap(function, new_map, value); | 9584 JSFunction::SetInitialMap(function, new_map, value); |
9496 | 9585 |
9497 // If the function is used as the global Array function, cache the | 9586 // If the function is used as the global Array function, cache the |
9498 // initial map (and transitioned versions) in the native context. | 9587 // initial map (and transitioned versions) in the native context. |
9499 Context* native_context = function->context()->native_context(); | 9588 Context* native_context = function->context()->native_context(); |
9500 Object* array_function = | 9589 Object* array_function = |
9501 native_context->get(Context::ARRAY_FUNCTION_INDEX); | 9590 native_context->get(Context::ARRAY_FUNCTION_INDEX); |
9502 if (array_function->IsJSFunction() && | 9591 if (array_function->IsJSFunction() && |
9503 *function == JSFunction::cast(array_function)) { | 9592 *function == JSFunction::cast(array_function)) { |
9504 CacheInitialJSArrayMaps(handle(native_context, isolate), new_map); | 9593 CacheInitialJSArrayMaps(handle(native_context, isolate), new_map); |
(...skipping 19 matching lines...) Expand all Loading... |
9524 Handle<Object> construct_prototype = value; | 9613 Handle<Object> construct_prototype = value; |
9525 | 9614 |
9526 // If the value is not a JSReceiver, store the value in the map's | 9615 // If the value is not a JSReceiver, store the value in the map's |
9527 // constructor field so it can be accessed. Also, set the prototype | 9616 // constructor field so it can be accessed. Also, set the prototype |
9528 // used for constructing objects to the original object prototype. | 9617 // used for constructing objects to the original object prototype. |
9529 // See ECMA-262 13.2.2. | 9618 // See ECMA-262 13.2.2. |
9530 if (!value->IsJSReceiver()) { | 9619 if (!value->IsJSReceiver()) { |
9531 // Copy the map so this does not affect unrelated functions. | 9620 // Copy the map so this does not affect unrelated functions. |
9532 // Remove map transitions because they point to maps with a | 9621 // Remove map transitions because they point to maps with a |
9533 // different prototype. | 9622 // different prototype. |
9534 Handle<Map> new_map = Map::Copy(handle(function->map())); | 9623 Handle<Map> new_map = Map::Copy(handle(function->map()), "SetPrototype"); |
9535 | 9624 |
9536 JSObject::MigrateToMap(function, new_map); | 9625 JSObject::MigrateToMap(function, new_map); |
9537 new_map->set_constructor(*value); | 9626 new_map->set_constructor(*value); |
9538 new_map->set_non_instance_prototype(true); | 9627 new_map->set_non_instance_prototype(true); |
9539 Isolate* isolate = new_map->GetIsolate(); | 9628 Isolate* isolate = new_map->GetIsolate(); |
9540 construct_prototype = handle( | 9629 construct_prototype = handle( |
9541 isolate->context()->native_context()->initial_object_prototype(), | 9630 isolate->context()->native_context()->initial_object_prototype(), |
9542 isolate); | 9631 isolate); |
9543 } else { | 9632 } else { |
9544 function->map()->set_non_instance_prototype(false); | 9633 function->map()->set_non_instance_prototype(false); |
(...skipping 27 matching lines...) Expand all Loading... |
9572 | 9661 |
9573 void JSFunction::SetInitialMap(Handle<JSFunction> function, Handle<Map> map, | 9662 void JSFunction::SetInitialMap(Handle<JSFunction> function, Handle<Map> map, |
9574 Handle<Object> prototype) { | 9663 Handle<Object> prototype) { |
9575 if (prototype->IsJSObject()) { | 9664 if (prototype->IsJSObject()) { |
9576 Handle<JSObject> js_proto = Handle<JSObject>::cast(prototype); | 9665 Handle<JSObject> js_proto = Handle<JSObject>::cast(prototype); |
9577 JSObject::OptimizeAsPrototype(js_proto, FAST_PROTOTYPE); | 9666 JSObject::OptimizeAsPrototype(js_proto, FAST_PROTOTYPE); |
9578 } | 9667 } |
9579 map->set_prototype(*prototype); | 9668 map->set_prototype(*prototype); |
9580 function->set_prototype_or_initial_map(*map); | 9669 function->set_prototype_or_initial_map(*map); |
9581 map->set_constructor(*function); | 9670 map->set_constructor(*function); |
| 9671 #if TRACE_MAPS |
| 9672 if (FLAG_trace_maps) { |
| 9673 PrintF("[TraceMaps: InitialMap map= %p SFI= %d_%s ]\n", |
| 9674 reinterpret_cast<void*>(*map), function->shared()->unique_id(), |
| 9675 function->shared()->DebugName()->ToCString().get()); |
| 9676 } |
| 9677 #endif |
9582 } | 9678 } |
9583 | 9679 |
9584 | 9680 |
9585 void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) { | 9681 void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) { |
9586 if (function->has_initial_map()) return; | 9682 if (function->has_initial_map()) return; |
9587 Isolate* isolate = function->GetIsolate(); | 9683 Isolate* isolate = function->GetIsolate(); |
9588 | 9684 |
9589 // First create a new map with the size and number of in-object properties | 9685 // First create a new map with the size and number of in-object properties |
9590 // suggested by the function. | 9686 // suggested by the function. |
9591 InstanceType instance_type; | 9687 InstanceType instance_type; |
(...skipping 2101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11693 } | 11789 } |
11694 UNREACHABLE(); | 11790 UNREACHABLE(); |
11695 return "?"; | 11791 return "?"; |
11696 } | 11792 } |
11697 | 11793 |
11698 | 11794 |
11699 Handle<Map> Map::TransitionToPrototype(Handle<Map> map, | 11795 Handle<Map> Map::TransitionToPrototype(Handle<Map> map, |
11700 Handle<Object> prototype) { | 11796 Handle<Object> prototype) { |
11701 Handle<Map> new_map = GetPrototypeTransition(map, prototype); | 11797 Handle<Map> new_map = GetPrototypeTransition(map, prototype); |
11702 if (new_map.is_null()) { | 11798 if (new_map.is_null()) { |
11703 new_map = Copy(map); | 11799 new_map = Copy(map, "TransitionToPrototype"); |
11704 PutPrototypeTransition(map, prototype, new_map); | 11800 PutPrototypeTransition(map, prototype, new_map); |
11705 new_map->set_prototype(*prototype); | 11801 new_map->set_prototype(*prototype); |
11706 } | 11802 } |
11707 return new_map; | 11803 return new_map; |
11708 } | 11804 } |
11709 | 11805 |
11710 | 11806 |
11711 MaybeHandle<Object> JSObject::SetPrototype(Handle<JSObject> object, | 11807 MaybeHandle<Object> JSObject::SetPrototype(Handle<JSObject> object, |
11712 Handle<Object> value, | 11808 Handle<Object> value, |
11713 bool from_javascript) { | 11809 bool from_javascript) { |
(...skipping 4853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16567 Handle<DependentCode> codes = | 16663 Handle<DependentCode> codes = |
16568 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), | 16664 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), |
16569 DependentCode::kPropertyCellChangedGroup, | 16665 DependentCode::kPropertyCellChangedGroup, |
16570 info->object_wrapper()); | 16666 info->object_wrapper()); |
16571 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 16667 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
16572 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 16668 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
16573 cell, info->zone()); | 16669 cell, info->zone()); |
16574 } | 16670 } |
16575 | 16671 |
16576 } } // namespace v8::internal | 16672 } } // namespace v8::internal |
OLD | NEW |