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 2246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2257 deprecate(); | 2257 deprecate(); |
2258 dependent_code()->DeoptimizeDependentCodeGroup( | 2258 dependent_code()->DeoptimizeDependentCodeGroup( |
2259 GetIsolate(), DependentCode::kTransitionGroup); | 2259 GetIsolate(), DependentCode::kTransitionGroup); |
2260 NotifyLeafMapLayoutChange(); | 2260 NotifyLeafMapLayoutChange(); |
2261 } | 2261 } |
2262 | 2262 |
2263 | 2263 |
2264 // Invalidates a transition target at |key|, and installs |new_descriptors| over | 2264 // Invalidates a transition target at |key|, and installs |new_descriptors| over |
2265 // the current instance_descriptors to ensure proper sharing of descriptor | 2265 // the current instance_descriptors to ensure proper sharing of descriptor |
2266 // arrays. | 2266 // arrays. |
2267 void Map::DeprecateTarget(Name* key, DescriptorArray* new_descriptors) { | 2267 void Map::DeprecateTarget(PropertyType type, Name* key, |
| 2268 PropertyAttributes attributes, |
| 2269 DescriptorArray* new_descriptors) { |
2268 if (HasTransitionArray()) { | 2270 if (HasTransitionArray()) { |
2269 TransitionArray* transitions = this->transitions(); | 2271 TransitionArray* transitions = this->transitions(); |
2270 int transition = transitions->Search(key); | 2272 int transition = transitions->Search(type, key, attributes); |
2271 if (transition != TransitionArray::kNotFound) { | 2273 if (transition != TransitionArray::kNotFound) { |
2272 transitions->GetTarget(transition)->DeprecateTransitionTree(); | 2274 transitions->GetTarget(transition)->DeprecateTransitionTree(); |
2273 } | 2275 } |
2274 } | 2276 } |
2275 | 2277 |
2276 // Don't overwrite the empty descriptor array. | 2278 // Don't overwrite the empty descriptor array. |
2277 if (NumberOfOwnDescriptors() == 0) return; | 2279 if (NumberOfOwnDescriptors() == 0) return; |
2278 | 2280 |
2279 DescriptorArray* to_replace = instance_descriptors(); | 2281 DescriptorArray* to_replace = instance_descriptors(); |
2280 Map* current = this; | 2282 Map* current = this; |
(...skipping 26 matching lines...) Expand all Loading... |
2307 DisallowHeapAllocation no_allocation; | 2309 DisallowHeapAllocation no_allocation; |
2308 | 2310 |
2309 // This can only be called on roots of transition trees. | 2311 // This can only be called on roots of transition trees. |
2310 DCHECK(GetBackPointer()->IsUndefined()); | 2312 DCHECK(GetBackPointer()->IsUndefined()); |
2311 | 2313 |
2312 Map* current = this; | 2314 Map* current = this; |
2313 | 2315 |
2314 for (int i = verbatim; i < length; i++) { | 2316 for (int i = verbatim; i < length; i++) { |
2315 if (!current->HasTransitionArray()) break; | 2317 if (!current->HasTransitionArray()) break; |
2316 Name* name = descriptors->GetKey(i); | 2318 Name* name = descriptors->GetKey(i); |
| 2319 PropertyDetails details = descriptors->GetDetails(i); |
2317 TransitionArray* transitions = current->transitions(); | 2320 TransitionArray* transitions = current->transitions(); |
2318 int transition = transitions->Search(name); | 2321 int transition = |
| 2322 transitions->Search(details.type(), name, details.attributes()); |
2319 if (transition == TransitionArray::kNotFound) break; | 2323 if (transition == TransitionArray::kNotFound) break; |
2320 | 2324 |
2321 Map* next = transitions->GetTarget(transition); | 2325 Map* next = transitions->GetTarget(transition); |
2322 DescriptorArray* next_descriptors = next->instance_descriptors(); | 2326 DescriptorArray* next_descriptors = next->instance_descriptors(); |
2323 | 2327 |
2324 PropertyDetails details = descriptors->GetDetails(i); | |
2325 PropertyDetails next_details = next_descriptors->GetDetails(i); | 2328 PropertyDetails next_details = next_descriptors->GetDetails(i); |
2326 if (details.type() != next_details.type()) break; | 2329 if (details.type() != next_details.type()) break; |
2327 if (details.attributes() != next_details.attributes()) break; | 2330 if (details.attributes() != next_details.attributes()) break; |
2328 if (!details.representation().Equals(next_details.representation())) break; | 2331 if (!details.representation().Equals(next_details.representation())) break; |
2329 if (next_details.type() == FIELD) { | 2332 if (next_details.type() == FIELD) { |
2330 if (!descriptors->GetFieldType(i)->NowIs( | 2333 if (!descriptors->GetFieldType(i)->NowIs( |
2331 next_descriptors->GetFieldType(i))) break; | 2334 next_descriptors->GetFieldType(i))) break; |
2332 } else { | 2335 } else { |
2333 if (descriptors->GetValue(i) != next_descriptors->GetValue(i)) break; | 2336 if (descriptors->GetValue(i) != next_descriptors->GetValue(i)) break; |
2334 } | 2337 } |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2504 (old_details.type() == FIELD && | 2507 (old_details.type() == FIELD && |
2505 (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) || | 2508 (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) || |
2506 !new_representation.fits_into(old_details.representation())))) { | 2509 !new_representation.fits_into(old_details.representation())))) { |
2507 return CopyGeneralizeAllRepresentations( | 2510 return CopyGeneralizeAllRepresentations( |
2508 old_map, modify_index, store_mode, "root modification"); | 2511 old_map, modify_index, store_mode, "root modification"); |
2509 } | 2512 } |
2510 } | 2513 } |
2511 | 2514 |
2512 Handle<Map> target_map = root_map; | 2515 Handle<Map> target_map = root_map; |
2513 for (int i = root_nof; i < old_nof; ++i) { | 2516 for (int i = root_nof; i < old_nof; ++i) { |
2514 int j = target_map->SearchTransition(old_descriptors->GetKey(i)); | 2517 PropertyDetails old_details = old_descriptors->GetDetails(i); |
| 2518 int j = target_map->SearchTransition(old_details.type(), |
| 2519 old_descriptors->GetKey(i), |
| 2520 old_details.attributes()); |
2515 if (j == TransitionArray::kNotFound) break; | 2521 if (j == TransitionArray::kNotFound) break; |
2516 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); | 2522 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); |
2517 Handle<DescriptorArray> tmp_descriptors = handle( | 2523 Handle<DescriptorArray> tmp_descriptors = handle( |
2518 tmp_map->instance_descriptors(), isolate); | 2524 tmp_map->instance_descriptors(), isolate); |
2519 | 2525 |
2520 // Check if target map is incompatible. | 2526 // Check if target map is incompatible. |
2521 PropertyDetails old_details = old_descriptors->GetDetails(i); | |
2522 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); | 2527 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); |
2523 PropertyType old_type = old_details.type(); | 2528 PropertyType old_type = old_details.type(); |
2524 PropertyType tmp_type = tmp_details.type(); | 2529 PropertyType tmp_type = tmp_details.type(); |
2525 if (tmp_details.attributes() != old_details.attributes() || | 2530 DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); |
2526 ((tmp_type == CALLBACKS || old_type == CALLBACKS) && | 2531 if ((tmp_type == CALLBACKS || old_type == CALLBACKS) && |
2527 (tmp_type != old_type || | 2532 (tmp_type != old_type || |
2528 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i)))) { | 2533 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { |
2529 return CopyGeneralizeAllRepresentations( | 2534 return CopyGeneralizeAllRepresentations( |
2530 old_map, modify_index, store_mode, "incompatible"); | 2535 old_map, modify_index, store_mode, "incompatible"); |
2531 } | 2536 } |
2532 Representation old_representation = old_details.representation(); | 2537 Representation old_representation = old_details.representation(); |
2533 Representation tmp_representation = tmp_details.representation(); | 2538 Representation tmp_representation = tmp_details.representation(); |
2534 if (!old_representation.fits_into(tmp_representation) || | 2539 if (!old_representation.fits_into(tmp_representation) || |
2535 (!new_representation.fits_into(tmp_representation) && | 2540 (!new_representation.fits_into(tmp_representation) && |
2536 modify_index == i)) { | 2541 modify_index == i)) { |
2537 break; | 2542 break; |
2538 } | 2543 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2570 DCHECK(new_representation.fits_into( | 2575 DCHECK(new_representation.fits_into( |
2571 target_descriptors->GetDetails(modify_index).representation())); | 2576 target_descriptors->GetDetails(modify_index).representation())); |
2572 DCHECK(target_descriptors->GetDetails(modify_index).type() != FIELD || | 2577 DCHECK(target_descriptors->GetDetails(modify_index).type() != FIELD || |
2573 new_field_type->NowIs( | 2578 new_field_type->NowIs( |
2574 target_descriptors->GetFieldType(modify_index))); | 2579 target_descriptors->GetFieldType(modify_index))); |
2575 return target_map; | 2580 return target_map; |
2576 } | 2581 } |
2577 | 2582 |
2578 // Find the last compatible target map in the transition tree. | 2583 // Find the last compatible target map in the transition tree. |
2579 for (int i = target_nof; i < old_nof; ++i) { | 2584 for (int i = target_nof; i < old_nof; ++i) { |
2580 int j = target_map->SearchTransition(old_descriptors->GetKey(i)); | 2585 PropertyDetails old_details = old_descriptors->GetDetails(i); |
| 2586 int j = target_map->SearchTransition(old_details.type(), |
| 2587 old_descriptors->GetKey(i), |
| 2588 old_details.attributes()); |
2581 if (j == TransitionArray::kNotFound) break; | 2589 if (j == TransitionArray::kNotFound) break; |
2582 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); | 2590 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); |
2583 Handle<DescriptorArray> tmp_descriptors( | 2591 Handle<DescriptorArray> tmp_descriptors( |
2584 tmp_map->instance_descriptors(), isolate); | 2592 tmp_map->instance_descriptors(), isolate); |
2585 | 2593 |
2586 // Check if target map is compatible. | 2594 // Check if target map is compatible. |
2587 PropertyDetails old_details = old_descriptors->GetDetails(i); | |
2588 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); | 2595 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); |
2589 if (tmp_details.attributes() != old_details.attributes() || | 2596 DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); |
2590 ((tmp_details.type() == CALLBACKS || old_details.type() == CALLBACKS) && | 2597 if ((tmp_details.type() == CALLBACKS || old_details.type() == CALLBACKS) && |
2591 (tmp_details.type() != old_details.type() || | 2598 (tmp_details.type() != old_details.type() || |
2592 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i)))) { | 2599 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { |
2593 return CopyGeneralizeAllRepresentations( | 2600 return CopyGeneralizeAllRepresentations( |
2594 old_map, modify_index, store_mode, "incompatible"); | 2601 old_map, modify_index, store_mode, "incompatible"); |
2595 } | 2602 } |
2596 target_map = tmp_map; | 2603 target_map = tmp_map; |
2597 } | 2604 } |
2598 target_nof = target_map->NumberOfOwnDescriptors(); | 2605 target_nof = target_map->NumberOfOwnDescriptors(); |
2599 target_descriptors = handle(target_map->instance_descriptors(), isolate); | 2606 target_descriptors = handle(target_map->instance_descriptors(), isolate); |
2600 | 2607 |
2601 // Allocate a new descriptor array large enough to hold the required | 2608 // Allocate a new descriptor array large enough to hold the required |
2602 // descriptors, with minimally the exact same size as the old descriptor | 2609 // descriptors, with minimally the exact same size as the old descriptor |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2714 new_descriptors->Sort(); | 2721 new_descriptors->Sort(); |
2715 | 2722 |
2716 DCHECK(store_mode != FORCE_FIELD || | 2723 DCHECK(store_mode != FORCE_FIELD || |
2717 new_descriptors->GetDetails(modify_index).type() == FIELD); | 2724 new_descriptors->GetDetails(modify_index).type() == FIELD); |
2718 | 2725 |
2719 Handle<Map> split_map(root_map->FindLastMatchMap( | 2726 Handle<Map> split_map(root_map->FindLastMatchMap( |
2720 root_nof, old_nof, *new_descriptors), isolate); | 2727 root_nof, old_nof, *new_descriptors), isolate); |
2721 int split_nof = split_map->NumberOfOwnDescriptors(); | 2728 int split_nof = split_map->NumberOfOwnDescriptors(); |
2722 DCHECK_NE(old_nof, split_nof); | 2729 DCHECK_NE(old_nof, split_nof); |
2723 | 2730 |
2724 split_map->DeprecateTarget( | 2731 PropertyDetails split_prop_details = old_descriptors->GetDetails(split_nof); |
2725 old_descriptors->GetKey(split_nof), *new_descriptors); | 2732 split_map->DeprecateTarget(split_prop_details.type(), |
| 2733 old_descriptors->GetKey(split_nof), |
| 2734 split_prop_details.attributes(), *new_descriptors); |
2726 | 2735 |
2727 if (FLAG_trace_generalization) { | 2736 if (FLAG_trace_generalization) { |
2728 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 2737 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
2729 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); | 2738 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); |
2730 Handle<HeapType> old_field_type = (old_details.type() == FIELD) | 2739 Handle<HeapType> old_field_type = (old_details.type() == FIELD) |
2731 ? handle(old_descriptors->GetFieldType(modify_index), isolate) | 2740 ? handle(old_descriptors->GetFieldType(modify_index), isolate) |
2732 : HeapType::Constant(handle(old_descriptors->GetValue(modify_index), | 2741 : HeapType::Constant(handle(old_descriptors->GetValue(modify_index), |
2733 isolate), isolate); | 2742 isolate), isolate); |
2734 Handle<HeapType> new_field_type = (new_details.type() == FIELD) | 2743 Handle<HeapType> new_field_type = (new_details.type() == FIELD) |
2735 ? handle(new_descriptors->GetFieldType(modify_index), isolate) | 2744 ? handle(new_descriptors->GetFieldType(modify_index), isolate) |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2800 // Check the state of the root map. | 2809 // Check the state of the root map. |
2801 Map* root_map = old_map->FindRootMap(); | 2810 Map* root_map = old_map->FindRootMap(); |
2802 if (!old_map->EquivalentToForTransition(root_map)) return MaybeHandle<Map>(); | 2811 if (!old_map->EquivalentToForTransition(root_map)) return MaybeHandle<Map>(); |
2803 int root_nof = root_map->NumberOfOwnDescriptors(); | 2812 int root_nof = root_map->NumberOfOwnDescriptors(); |
2804 | 2813 |
2805 int old_nof = old_map->NumberOfOwnDescriptors(); | 2814 int old_nof = old_map->NumberOfOwnDescriptors(); |
2806 DescriptorArray* old_descriptors = old_map->instance_descriptors(); | 2815 DescriptorArray* old_descriptors = old_map->instance_descriptors(); |
2807 | 2816 |
2808 Map* new_map = root_map; | 2817 Map* new_map = root_map; |
2809 for (int i = root_nof; i < old_nof; ++i) { | 2818 for (int i = root_nof; i < old_nof; ++i) { |
2810 int j = new_map->SearchTransition(old_descriptors->GetKey(i)); | 2819 PropertyDetails old_details = old_descriptors->GetDetails(i); |
| 2820 int j = new_map->SearchTransition(old_details.type(), |
| 2821 old_descriptors->GetKey(i), |
| 2822 old_details.attributes()); |
2811 if (j == TransitionArray::kNotFound) return MaybeHandle<Map>(); | 2823 if (j == TransitionArray::kNotFound) return MaybeHandle<Map>(); |
2812 new_map = new_map->GetTransition(j); | 2824 new_map = new_map->GetTransition(j); |
2813 DescriptorArray* new_descriptors = new_map->instance_descriptors(); | 2825 DescriptorArray* new_descriptors = new_map->instance_descriptors(); |
2814 | 2826 |
2815 PropertyDetails new_details = new_descriptors->GetDetails(i); | 2827 PropertyDetails new_details = new_descriptors->GetDetails(i); |
2816 PropertyDetails old_details = old_descriptors->GetDetails(i); | |
2817 if (old_details.attributes() != new_details.attributes() || | 2828 if (old_details.attributes() != new_details.attributes() || |
2818 !old_details.representation().fits_into(new_details.representation())) { | 2829 !old_details.representation().fits_into(new_details.representation())) { |
2819 return MaybeHandle<Map>(); | 2830 return MaybeHandle<Map>(); |
2820 } | 2831 } |
2821 PropertyType new_type = new_details.type(); | 2832 PropertyType new_type = new_details.type(); |
2822 PropertyType old_type = old_details.type(); | 2833 PropertyType old_type = old_details.type(); |
2823 Object* new_value = new_descriptors->GetValue(i); | 2834 Object* new_value = new_descriptors->GetValue(i); |
2824 Object* old_value = old_descriptors->GetValue(i); | 2835 Object* old_value = old_descriptors->GetValue(i); |
2825 switch (new_type) { | 2836 switch (new_type) { |
2826 case FIELD: | 2837 case FIELD: |
(...skipping 2574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5401 new_element_dictionary = CopyFastElementsToDictionary( | 5412 new_element_dictionary = CopyFastElementsToDictionary( |
5402 handle(object->elements()), length, new_element_dictionary); | 5413 handle(object->elements()), length, new_element_dictionary); |
5403 } else { | 5414 } else { |
5404 // No existing elements, use a pre-allocated empty backing store | 5415 // No existing elements, use a pre-allocated empty backing store |
5405 new_element_dictionary = | 5416 new_element_dictionary = |
5406 isolate->factory()->empty_slow_element_dictionary(); | 5417 isolate->factory()->empty_slow_element_dictionary(); |
5407 } | 5418 } |
5408 } | 5419 } |
5409 | 5420 |
5410 Handle<Map> old_map(object->map(), isolate); | 5421 Handle<Map> old_map(object->map(), isolate); |
5411 int transition_index = old_map->SearchTransition( | 5422 int transition_index = |
5412 isolate->heap()->frozen_symbol()); | 5423 old_map->SearchSpecialTransition(isolate->heap()->frozen_symbol()); |
5413 if (transition_index != TransitionArray::kNotFound) { | 5424 if (transition_index != TransitionArray::kNotFound) { |
5414 Handle<Map> transition_map(old_map->GetTransition(transition_index)); | 5425 Handle<Map> transition_map(old_map->GetTransition(transition_index)); |
5415 DCHECK(transition_map->has_dictionary_elements()); | 5426 DCHECK(transition_map->has_dictionary_elements()); |
5416 DCHECK(transition_map->is_frozen()); | 5427 DCHECK(transition_map->is_frozen()); |
5417 DCHECK(!transition_map->is_extensible()); | 5428 DCHECK(!transition_map->is_extensible()); |
5418 JSObject::MigrateToMap(object, transition_map); | 5429 JSObject::MigrateToMap(object, transition_map); |
5419 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) { | 5430 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) { |
5420 // Create a new descriptor array with fully-frozen properties | 5431 // Create a new descriptor array with fully-frozen properties |
5421 Handle<Map> new_map = Map::CopyForFreeze(old_map); | 5432 Handle<Map> new_map = Map::CopyForFreeze(old_map); |
5422 JSObject::MigrateToMap(object, new_map); | 5433 JSObject::MigrateToMap(object, new_map); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5454 } | 5465 } |
5455 | 5466 |
5456 | 5467 |
5457 void JSObject::SetObserved(Handle<JSObject> object) { | 5468 void JSObject::SetObserved(Handle<JSObject> object) { |
5458 DCHECK(!object->IsJSGlobalProxy()); | 5469 DCHECK(!object->IsJSGlobalProxy()); |
5459 DCHECK(!object->IsJSGlobalObject()); | 5470 DCHECK(!object->IsJSGlobalObject()); |
5460 Isolate* isolate = object->GetIsolate(); | 5471 Isolate* isolate = object->GetIsolate(); |
5461 Handle<Map> new_map; | 5472 Handle<Map> new_map; |
5462 Handle<Map> old_map(object->map(), isolate); | 5473 Handle<Map> old_map(object->map(), isolate); |
5463 DCHECK(!old_map->is_observed()); | 5474 DCHECK(!old_map->is_observed()); |
5464 int transition_index = old_map->SearchTransition( | 5475 int transition_index = |
5465 isolate->heap()->observed_symbol()); | 5476 old_map->SearchSpecialTransition(isolate->heap()->observed_symbol()); |
5466 if (transition_index != TransitionArray::kNotFound) { | 5477 if (transition_index != TransitionArray::kNotFound) { |
5467 new_map = handle(old_map->GetTransition(transition_index), isolate); | 5478 new_map = handle(old_map->GetTransition(transition_index), isolate); |
5468 DCHECK(new_map->is_observed()); | 5479 DCHECK(new_map->is_observed()); |
5469 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) { | 5480 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) { |
5470 new_map = Map::CopyForObserved(old_map); | 5481 new_map = Map::CopyForObserved(old_map); |
5471 } else { | 5482 } else { |
5472 new_map = Map::Copy(old_map); | 5483 new_map = Map::Copy(old_map); |
5473 new_map->set_is_observed(); | 5484 new_map->set_is_observed(); |
5474 } | 5485 } |
5475 JSObject::MigrateToMap(object, new_map); | 5486 JSObject::MigrateToMap(object, new_map); |
(...skipping 1401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6877 Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name, | 6888 Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name, |
6878 Handle<Object> value, | 6889 Handle<Object> value, |
6879 PropertyAttributes attributes, | 6890 PropertyAttributes attributes, |
6880 StoreFromKeyed store_mode) { | 6891 StoreFromKeyed store_mode) { |
6881 // Dictionary maps can always have additional data properties. | 6892 // Dictionary maps can always have additional data properties. |
6882 if (map->is_dictionary_map()) return map; | 6893 if (map->is_dictionary_map()) return map; |
6883 | 6894 |
6884 // Migrate to the newest map before storing the property. | 6895 // Migrate to the newest map before storing the property. |
6885 map = Update(map); | 6896 map = Update(map); |
6886 | 6897 |
6887 int index = map->SearchTransition(*name); | 6898 int index = map->SearchTransition(FIELD, *name, attributes); |
6888 if (index != TransitionArray::kNotFound) { | 6899 if (index != TransitionArray::kNotFound) { |
6889 Handle<Map> transition(map->GetTransition(index)); | 6900 Handle<Map> transition(map->GetTransition(index)); |
6890 int descriptor = transition->LastAdded(); | 6901 int descriptor = transition->LastAdded(); |
6891 | 6902 |
6892 // TODO(verwaest): Handle attributes better. | 6903 DCHECK_EQ(attributes, transition->instance_descriptors() |
6893 DescriptorArray* descriptors = transition->instance_descriptors(); | 6904 ->GetDetails(descriptor) |
6894 if (descriptors->GetDetails(descriptor).attributes() != attributes) { | 6905 .attributes()); |
6895 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES); | |
6896 } | |
6897 | 6906 |
6898 return Map::PrepareForDataProperty(transition, descriptor, value); | 6907 return Map::PrepareForDataProperty(transition, descriptor, value); |
6899 } | 6908 } |
6900 | 6909 |
6901 TransitionFlag flag = INSERT_TRANSITION; | 6910 TransitionFlag flag = INSERT_TRANSITION; |
6902 MaybeHandle<Map> maybe_map; | 6911 MaybeHandle<Map> maybe_map; |
6903 if (value->IsJSFunction()) { | 6912 if (value->IsJSFunction()) { |
6904 maybe_map = Map::CopyWithConstant(map, name, value, attributes, flag); | 6913 maybe_map = Map::CopyWithConstant(map, name, value, attributes, flag); |
6905 } else if (!map->TooManyFastProperties(store_mode)) { | 6914 } else if (!map->TooManyFastProperties(store_mode)) { |
6906 Isolate* isolate = name->GetIsolate(); | 6915 Isolate* isolate = name->GetIsolate(); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6946 return map; | 6955 return map; |
6947 } | 6956 } |
6948 | 6957 |
6949 // Migrate to the newest map before transitioning to the new property. | 6958 // Migrate to the newest map before transitioning to the new property. |
6950 map = Update(map); | 6959 map = Update(map); |
6951 | 6960 |
6952 PropertyNormalizationMode mode = map->is_prototype_map() | 6961 PropertyNormalizationMode mode = map->is_prototype_map() |
6953 ? KEEP_INOBJECT_PROPERTIES | 6962 ? KEEP_INOBJECT_PROPERTIES |
6954 : CLEAR_INOBJECT_PROPERTIES; | 6963 : CLEAR_INOBJECT_PROPERTIES; |
6955 | 6964 |
6956 int index = map->SearchTransition(*name); | 6965 int index = map->SearchTransition(CALLBACKS, *name, attributes); |
6957 if (index != TransitionArray::kNotFound) { | 6966 if (index != TransitionArray::kNotFound) { |
6958 Handle<Map> transition(map->GetTransition(index)); | 6967 Handle<Map> transition(map->GetTransition(index)); |
6959 DescriptorArray* descriptors = transition->instance_descriptors(); | 6968 DescriptorArray* descriptors = transition->instance_descriptors(); |
6960 // Fast path, assume that we're modifying the last added descriptor. | 6969 // Fast path, assume that we're modifying the last added descriptor. |
6961 int descriptor = transition->LastAdded(); | 6970 int descriptor = transition->LastAdded(); |
6962 if (descriptors->GetKey(descriptor) != *name) { | 6971 if (descriptors->GetKey(descriptor) != *name) { |
6963 // If not, search for the descriptor. | 6972 // If not, search for the descriptor. |
6964 descriptor = descriptors->SearchWithCache(*name, *transition); | 6973 descriptor = descriptors->SearchWithCache(*name, *transition); |
6965 } | 6974 } |
6966 | 6975 |
6967 if (descriptors->GetDetails(descriptor).type() != CALLBACKS) { | 6976 DCHECK_EQ(CALLBACKS, descriptors->GetDetails(descriptor).type()); |
6968 return Map::Normalize(map, mode); | 6977 DCHECK_EQ(attributes, descriptors->GetDetails(descriptor).attributes()); |
6969 } | |
6970 | |
6971 // TODO(verwaest): Handle attributes better. | |
6972 if (descriptors->GetDetails(descriptor).attributes() != attributes) { | |
6973 return Map::Normalize(map, mode); | |
6974 } | |
6975 | 6978 |
6976 Handle<Object> maybe_pair(descriptors->GetValue(descriptor), isolate); | 6979 Handle<Object> maybe_pair(descriptors->GetValue(descriptor), isolate); |
6977 if (!maybe_pair->IsAccessorPair()) { | 6980 if (!maybe_pair->IsAccessorPair()) { |
6978 return Map::Normalize(map, mode); | 6981 return Map::Normalize(map, mode); |
6979 } | 6982 } |
6980 | 6983 |
6981 Handle<AccessorPair> pair = Handle<AccessorPair>::cast(maybe_pair); | 6984 Handle<AccessorPair> pair = Handle<AccessorPair>::cast(maybe_pair); |
6982 if (pair->get(component) != *accessor) { | 6985 if (pair->get(component) != *accessor) { |
6983 return Map::Normalize(map, mode); | 6986 return Map::Normalize(map, mode); |
6984 } | 6987 } |
(...skipping 9526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16511 Handle<DependentCode> codes = | 16514 Handle<DependentCode> codes = |
16512 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), | 16515 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), |
16513 DependentCode::kPropertyCellChangedGroup, | 16516 DependentCode::kPropertyCellChangedGroup, |
16514 info->object_wrapper()); | 16517 info->object_wrapper()); |
16515 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 16518 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
16516 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 16519 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
16517 cell, info->zone()); | 16520 cell, info->zone()); |
16518 } | 16521 } |
16519 | 16522 |
16520 } } // namespace v8::internal | 16523 } } // namespace v8::internal |
OLD | NEW |