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

Side by Side Diff: src/objects.cc

Issue 661133002: TransitionArray now uses <is_data_property, name, attributes> tuple as a key, which allows to have … (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | src/transitions-inl.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698