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

Side by Side Diff: src/objects.cc

Issue 722873004: Revert "TransitionArray now uses <is_data_property, name, attributes> tuple as a key, which allows … (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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 1921 matching lines...) Expand 10 before | Expand all | Expand 10 after
1932 return false; 1932 return false;
1933 } 1933 }
1934 // Otherwise, properties will need to be moved to the backing store. 1934 // Otherwise, properties will need to be moved to the backing store.
1935 return true; 1935 return true;
1936 } 1936 }
1937 1937
1938 1938
1939 void Map::ConnectElementsTransition(Handle<Map> parent, Handle<Map> child) { 1939 void Map::ConnectElementsTransition(Handle<Map> parent, Handle<Map> child) {
1940 Isolate* isolate = parent->GetIsolate(); 1940 Isolate* isolate = parent->GetIsolate();
1941 Handle<Name> name = isolate->factory()->elements_transition_symbol(); 1941 Handle<Name> name = isolate->factory()->elements_transition_symbol();
1942 ConnectTransition(parent, child, name, SPECIAL_TRANSITION); 1942 ConnectTransition(parent, child, name, FULL_TRANSITION);
1943 } 1943 }
1944 1944
1945 1945
1946 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) { 1946 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
1947 if (object->map() == *new_map) return; 1947 if (object->map() == *new_map) return;
1948 if (object->HasFastProperties()) { 1948 if (object->HasFastProperties()) {
1949 if (!new_map->is_dictionary_map()) { 1949 if (!new_map->is_dictionary_map()) {
1950 Handle<Map> old_map(object->map()); 1950 Handle<Map> old_map(object->map());
1951 MigrateFastToFast(object, new_map); 1951 MigrateFastToFast(object, new_map);
1952 if (old_map->is_prototype_map()) { 1952 if (old_map->is_prototype_map()) {
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
2252 deprecate(); 2252 deprecate();
2253 dependent_code()->DeoptimizeDependentCodeGroup( 2253 dependent_code()->DeoptimizeDependentCodeGroup(
2254 GetIsolate(), DependentCode::kTransitionGroup); 2254 GetIsolate(), DependentCode::kTransitionGroup);
2255 NotifyLeafMapLayoutChange(); 2255 NotifyLeafMapLayoutChange();
2256 } 2256 }
2257 2257
2258 2258
2259 // Invalidates a transition target at |key|, and installs |new_descriptors| over 2259 // Invalidates a transition target at |key|, and installs |new_descriptors| over
2260 // the current instance_descriptors to ensure proper sharing of descriptor 2260 // the current instance_descriptors to ensure proper sharing of descriptor
2261 // arrays. 2261 // arrays.
2262 void Map::DeprecateTarget(PropertyType type, Name* key, 2262 void Map::DeprecateTarget(Name* key, DescriptorArray* new_descriptors,
2263 PropertyAttributes attributes,
2264 DescriptorArray* new_descriptors,
2265 LayoutDescriptor* new_layout_descriptor) { 2263 LayoutDescriptor* new_layout_descriptor) {
2266 if (HasTransitionArray()) { 2264 if (HasTransitionArray()) {
2267 TransitionArray* transitions = this->transitions(); 2265 TransitionArray* transitions = this->transitions();
2268 int transition = transitions->Search(type, key, attributes); 2266 int transition = transitions->Search(key);
2269 if (transition != TransitionArray::kNotFound) { 2267 if (transition != TransitionArray::kNotFound) {
2270 transitions->GetTarget(transition)->DeprecateTransitionTree(); 2268 transitions->GetTarget(transition)->DeprecateTransitionTree();
2271 } 2269 }
2272 } 2270 }
2273 2271
2274 // Don't overwrite the empty descriptor array. 2272 // Don't overwrite the empty descriptor array.
2275 if (NumberOfOwnDescriptors() == 0) return; 2273 if (NumberOfOwnDescriptors() == 0) return;
2276 2274
2277 DescriptorArray* to_replace = instance_descriptors(); 2275 DescriptorArray* to_replace = instance_descriptors();
2278 Map* current = this; 2276 Map* current = this;
(...skipping 26 matching lines...) Expand all
2305 DisallowHeapAllocation no_allocation; 2303 DisallowHeapAllocation no_allocation;
2306 2304
2307 // This can only be called on roots of transition trees. 2305 // This can only be called on roots of transition trees.
2308 DCHECK(GetBackPointer()->IsUndefined()); 2306 DCHECK(GetBackPointer()->IsUndefined());
2309 2307
2310 Map* current = this; 2308 Map* current = this;
2311 2309
2312 for (int i = verbatim; i < length; i++) { 2310 for (int i = verbatim; i < length; i++) {
2313 if (!current->HasTransitionArray()) break; 2311 if (!current->HasTransitionArray()) break;
2314 Name* name = descriptors->GetKey(i); 2312 Name* name = descriptors->GetKey(i);
2315 PropertyDetails details = descriptors->GetDetails(i);
2316 TransitionArray* transitions = current->transitions(); 2313 TransitionArray* transitions = current->transitions();
2317 int transition = 2314 int transition = transitions->Search(name);
2318 transitions->Search(details.type(), name, details.attributes());
2319 if (transition == TransitionArray::kNotFound) break; 2315 if (transition == TransitionArray::kNotFound) break;
2320 2316
2321 Map* next = transitions->GetTarget(transition); 2317 Map* next = transitions->GetTarget(transition);
2322 DescriptorArray* next_descriptors = next->instance_descriptors(); 2318 DescriptorArray* next_descriptors = next->instance_descriptors();
2323 2319
2320 PropertyDetails details = descriptors->GetDetails(i);
2324 PropertyDetails next_details = next_descriptors->GetDetails(i); 2321 PropertyDetails next_details = next_descriptors->GetDetails(i);
2325 if (details.type() != next_details.type()) break; 2322 if (details.type() != next_details.type()) break;
2326 if (details.attributes() != next_details.attributes()) break; 2323 if (details.attributes() != next_details.attributes()) break;
2327 if (!details.representation().Equals(next_details.representation())) break; 2324 if (!details.representation().Equals(next_details.representation())) break;
2328 if (next_details.type() == FIELD) { 2325 if (next_details.type() == FIELD) {
2329 if (!descriptors->GetFieldType(i)->NowIs( 2326 if (!descriptors->GetFieldType(i)->NowIs(
2330 next_descriptors->GetFieldType(i))) break; 2327 next_descriptors->GetFieldType(i))) break;
2331 } else { 2328 } else {
2332 if (descriptors->GetValue(i) != next_descriptors->GetValue(i)) break; 2329 if (descriptors->GetValue(i) != next_descriptors->GetValue(i)) break;
2333 } 2330 }
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
2517 (old_details.type() == FIELD && 2514 (old_details.type() == FIELD &&
2518 (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) || 2515 (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) ||
2519 !new_representation.fits_into(old_details.representation())))) { 2516 !new_representation.fits_into(old_details.representation())))) {
2520 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, 2517 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
2521 "GenAll_RootModification"); 2518 "GenAll_RootModification");
2522 } 2519 }
2523 } 2520 }
2524 2521
2525 Handle<Map> target_map = root_map; 2522 Handle<Map> target_map = root_map;
2526 for (int i = root_nof; i < old_nof; ++i) { 2523 for (int i = root_nof; i < old_nof; ++i) {
2527 PropertyDetails old_details = old_descriptors->GetDetails(i); 2524 int j = target_map->SearchTransition(old_descriptors->GetKey(i));
2528 int j = target_map->SearchTransition(old_details.type(),
2529 old_descriptors->GetKey(i),
2530 old_details.attributes());
2531 if (j == TransitionArray::kNotFound) break; 2525 if (j == TransitionArray::kNotFound) break;
2532 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); 2526 Handle<Map> tmp_map(target_map->GetTransition(j), isolate);
2533 Handle<DescriptorArray> tmp_descriptors = handle( 2527 Handle<DescriptorArray> tmp_descriptors = handle(
2534 tmp_map->instance_descriptors(), isolate); 2528 tmp_map->instance_descriptors(), isolate);
2535 2529
2536 // Check if target map is incompatible. 2530 // Check if target map is incompatible.
2531 PropertyDetails old_details = old_descriptors->GetDetails(i);
2537 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); 2532 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i);
2538 PropertyType old_type = old_details.type(); 2533 PropertyType old_type = old_details.type();
2539 PropertyType tmp_type = tmp_details.type(); 2534 PropertyType tmp_type = tmp_details.type();
2540 DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); 2535 if (tmp_details.attributes() != old_details.attributes() ||
2541 if ((tmp_type == CALLBACKS || old_type == CALLBACKS) && 2536 ((tmp_type == CALLBACKS || old_type == CALLBACKS) &&
2542 (tmp_type != old_type || 2537 (tmp_type != old_type ||
2543 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { 2538 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i)))) {
2544 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, 2539 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
2545 "GenAll_Incompatible"); 2540 "GenAll_Incompatible");
2546 } 2541 }
2547 Representation old_representation = old_details.representation(); 2542 Representation old_representation = old_details.representation();
2548 Representation tmp_representation = tmp_details.representation(); 2543 Representation tmp_representation = tmp_details.representation();
2549 if (!old_representation.fits_into(tmp_representation) || 2544 if (!old_representation.fits_into(tmp_representation) ||
2550 (!new_representation.fits_into(tmp_representation) && 2545 (!new_representation.fits_into(tmp_representation) &&
2551 modify_index == i)) { 2546 modify_index == i)) {
2552 break; 2547 break;
2553 } 2548 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2585 DCHECK(new_representation.fits_into( 2580 DCHECK(new_representation.fits_into(
2586 target_descriptors->GetDetails(modify_index).representation())); 2581 target_descriptors->GetDetails(modify_index).representation()));
2587 DCHECK(target_descriptors->GetDetails(modify_index).type() != FIELD || 2582 DCHECK(target_descriptors->GetDetails(modify_index).type() != FIELD ||
2588 new_field_type->NowIs( 2583 new_field_type->NowIs(
2589 target_descriptors->GetFieldType(modify_index))); 2584 target_descriptors->GetFieldType(modify_index)));
2590 return target_map; 2585 return target_map;
2591 } 2586 }
2592 2587
2593 // Find the last compatible target map in the transition tree. 2588 // Find the last compatible target map in the transition tree.
2594 for (int i = target_nof; i < old_nof; ++i) { 2589 for (int i = target_nof; i < old_nof; ++i) {
2595 PropertyDetails old_details = old_descriptors->GetDetails(i); 2590 int j = target_map->SearchTransition(old_descriptors->GetKey(i));
2596 int j = target_map->SearchTransition(old_details.type(),
2597 old_descriptors->GetKey(i),
2598 old_details.attributes());
2599 if (j == TransitionArray::kNotFound) break; 2591 if (j == TransitionArray::kNotFound) break;
2600 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); 2592 Handle<Map> tmp_map(target_map->GetTransition(j), isolate);
2601 Handle<DescriptorArray> tmp_descriptors( 2593 Handle<DescriptorArray> tmp_descriptors(
2602 tmp_map->instance_descriptors(), isolate); 2594 tmp_map->instance_descriptors(), isolate);
2603 2595
2604 // Check if target map is compatible. 2596 // Check if target map is compatible.
2597 PropertyDetails old_details = old_descriptors->GetDetails(i);
2605 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); 2598 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i);
2606 DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); 2599 if (tmp_details.attributes() != old_details.attributes() ||
2607 if ((tmp_details.type() == CALLBACKS || old_details.type() == CALLBACKS) && 2600 ((tmp_details.type() == CALLBACKS || old_details.type() == CALLBACKS) &&
2608 (tmp_details.type() != old_details.type() || 2601 (tmp_details.type() != old_details.type() ||
2609 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { 2602 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i)))) {
2610 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, 2603 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
2611 "GenAll_Incompatible"); 2604 "GenAll_Incompatible");
2612 } 2605 }
2613 target_map = tmp_map; 2606 target_map = tmp_map;
2614 } 2607 }
2615 target_nof = target_map->NumberOfOwnDescriptors(); 2608 target_nof = target_map->NumberOfOwnDescriptors();
2616 target_descriptors = handle(target_map->instance_descriptors(), isolate); 2609 target_descriptors = handle(target_map->instance_descriptors(), isolate);
2617 2610
2618 // Allocate a new descriptor array large enough to hold the required 2611 // Allocate a new descriptor array large enough to hold the required
2619 // descriptors, with minimally the exact same size as the old descriptor 2612 // descriptors, with minimally the exact same size as the old descriptor
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
2731 DCHECK(store_mode != FORCE_FIELD || 2724 DCHECK(store_mode != FORCE_FIELD ||
2732 new_descriptors->GetDetails(modify_index).type() == FIELD); 2725 new_descriptors->GetDetails(modify_index).type() == FIELD);
2733 2726
2734 Handle<Map> split_map(root_map->FindLastMatchMap( 2727 Handle<Map> split_map(root_map->FindLastMatchMap(
2735 root_nof, old_nof, *new_descriptors), isolate); 2728 root_nof, old_nof, *new_descriptors), isolate);
2736 int split_nof = split_map->NumberOfOwnDescriptors(); 2729 int split_nof = split_map->NumberOfOwnDescriptors();
2737 DCHECK_NE(old_nof, split_nof); 2730 DCHECK_NE(old_nof, split_nof);
2738 2731
2739 Handle<LayoutDescriptor> new_layout_descriptor = 2732 Handle<LayoutDescriptor> new_layout_descriptor =
2740 LayoutDescriptor::New(split_map, new_descriptors, old_nof); 2733 LayoutDescriptor::New(split_map, new_descriptors, old_nof);
2741 PropertyDetails split_prop_details = old_descriptors->GetDetails(split_nof); 2734 split_map->DeprecateTarget(old_descriptors->GetKey(split_nof),
2742 split_map->DeprecateTarget(split_prop_details.type(), 2735 *new_descriptors, *new_layout_descriptor);
2743 old_descriptors->GetKey(split_nof),
2744 split_prop_details.attributes(), *new_descriptors,
2745 *new_layout_descriptor);
2746 2736
2747 if (FLAG_trace_generalization) { 2737 if (FLAG_trace_generalization) {
2748 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); 2738 PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
2749 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); 2739 PropertyDetails new_details = new_descriptors->GetDetails(modify_index);
2750 Handle<HeapType> old_field_type = (old_details.type() == FIELD) 2740 Handle<HeapType> old_field_type = (old_details.type() == FIELD)
2751 ? handle(old_descriptors->GetFieldType(modify_index), isolate) 2741 ? handle(old_descriptors->GetFieldType(modify_index), isolate)
2752 : HeapType::Constant(handle(old_descriptors->GetValue(modify_index), 2742 : HeapType::Constant(handle(old_descriptors->GetValue(modify_index),
2753 isolate), isolate); 2743 isolate), isolate);
2754 Handle<HeapType> new_field_type = (new_details.type() == FIELD) 2744 Handle<HeapType> new_field_type = (new_details.type() == FIELD)
2755 ? handle(new_descriptors->GetFieldType(modify_index), isolate) 2745 ? handle(new_descriptors->GetFieldType(modify_index), isolate)
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2825 // Check the state of the root map. 2815 // Check the state of the root map.
2826 Map* root_map = old_map->FindRootMap(); 2816 Map* root_map = old_map->FindRootMap();
2827 if (!old_map->EquivalentToForTransition(root_map)) return MaybeHandle<Map>(); 2817 if (!old_map->EquivalentToForTransition(root_map)) return MaybeHandle<Map>();
2828 int root_nof = root_map->NumberOfOwnDescriptors(); 2818 int root_nof = root_map->NumberOfOwnDescriptors();
2829 2819
2830 int old_nof = old_map->NumberOfOwnDescriptors(); 2820 int old_nof = old_map->NumberOfOwnDescriptors();
2831 DescriptorArray* old_descriptors = old_map->instance_descriptors(); 2821 DescriptorArray* old_descriptors = old_map->instance_descriptors();
2832 2822
2833 Map* new_map = root_map; 2823 Map* new_map = root_map;
2834 for (int i = root_nof; i < old_nof; ++i) { 2824 for (int i = root_nof; i < old_nof; ++i) {
2835 PropertyDetails old_details = old_descriptors->GetDetails(i); 2825 int j = new_map->SearchTransition(old_descriptors->GetKey(i));
2836 int j = new_map->SearchTransition(old_details.type(),
2837 old_descriptors->GetKey(i),
2838 old_details.attributes());
2839 if (j == TransitionArray::kNotFound) return MaybeHandle<Map>(); 2826 if (j == TransitionArray::kNotFound) return MaybeHandle<Map>();
2840 new_map = new_map->GetTransition(j); 2827 new_map = new_map->GetTransition(j);
2841 DescriptorArray* new_descriptors = new_map->instance_descriptors(); 2828 DescriptorArray* new_descriptors = new_map->instance_descriptors();
2842 2829
2843 PropertyDetails new_details = new_descriptors->GetDetails(i); 2830 PropertyDetails new_details = new_descriptors->GetDetails(i);
2831 PropertyDetails old_details = old_descriptors->GetDetails(i);
2844 if (old_details.attributes() != new_details.attributes() || 2832 if (old_details.attributes() != new_details.attributes() ||
2845 !old_details.representation().fits_into(new_details.representation())) { 2833 !old_details.representation().fits_into(new_details.representation())) {
2846 return MaybeHandle<Map>(); 2834 return MaybeHandle<Map>();
2847 } 2835 }
2848 PropertyType new_type = new_details.type(); 2836 PropertyType new_type = new_details.type();
2849 PropertyType old_type = old_details.type(); 2837 PropertyType old_type = old_details.type();
2850 Object* new_value = new_descriptors->GetValue(i); 2838 Object* new_value = new_descriptors->GetValue(i);
2851 Object* old_value = old_descriptors->GetValue(i); 2839 Object* old_value = old_descriptors->GetValue(i);
2852 switch (new_type) { 2840 switch (new_type) {
2853 case FIELD: 2841 case FIELD:
(...skipping 2606 matching lines...) Expand 10 before | Expand all | Expand 10 after
5460 handle(object->elements()), length, new_element_dictionary); 5448 handle(object->elements()), length, new_element_dictionary);
5461 } else { 5449 } else {
5462 // No existing elements, use a pre-allocated empty backing store 5450 // No existing elements, use a pre-allocated empty backing store
5463 new_element_dictionary = 5451 new_element_dictionary =
5464 isolate->factory()->empty_slow_element_dictionary(); 5452 isolate->factory()->empty_slow_element_dictionary();
5465 } 5453 }
5466 } 5454 }
5467 5455
5468 Handle<Map> old_map(object->map(), isolate); 5456 Handle<Map> old_map(object->map(), isolate);
5469 int transition_index = 5457 int transition_index =
5470 old_map->SearchSpecialTransition(isolate->heap()->frozen_symbol()); 5458 old_map->SearchTransition(isolate->heap()->frozen_symbol());
5471 if (transition_index != TransitionArray::kNotFound) { 5459 if (transition_index != TransitionArray::kNotFound) {
5472 Handle<Map> transition_map(old_map->GetTransition(transition_index)); 5460 Handle<Map> transition_map(old_map->GetTransition(transition_index));
5473 DCHECK(transition_map->has_dictionary_elements()); 5461 DCHECK(transition_map->has_dictionary_elements());
5474 DCHECK(transition_map->is_frozen()); 5462 DCHECK(transition_map->is_frozen());
5475 DCHECK(!transition_map->is_extensible()); 5463 DCHECK(!transition_map->is_extensible());
5476 JSObject::MigrateToMap(object, transition_map); 5464 JSObject::MigrateToMap(object, transition_map);
5477 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) { 5465 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) {
5478 // Create a new descriptor array with fully-frozen properties 5466 // Create a new descriptor array with fully-frozen properties
5479 Handle<Map> new_map = Map::CopyForFreeze(old_map); 5467 Handle<Map> new_map = Map::CopyForFreeze(old_map);
5480 JSObject::MigrateToMap(object, new_map); 5468 JSObject::MigrateToMap(object, new_map);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
5513 5501
5514 5502
5515 void JSObject::SetObserved(Handle<JSObject> object) { 5503 void JSObject::SetObserved(Handle<JSObject> object) {
5516 DCHECK(!object->IsJSGlobalProxy()); 5504 DCHECK(!object->IsJSGlobalProxy());
5517 DCHECK(!object->IsJSGlobalObject()); 5505 DCHECK(!object->IsJSGlobalObject());
5518 Isolate* isolate = object->GetIsolate(); 5506 Isolate* isolate = object->GetIsolate();
5519 Handle<Map> new_map; 5507 Handle<Map> new_map;
5520 Handle<Map> old_map(object->map(), isolate); 5508 Handle<Map> old_map(object->map(), isolate);
5521 DCHECK(!old_map->is_observed()); 5509 DCHECK(!old_map->is_observed());
5522 int transition_index = 5510 int transition_index =
5523 old_map->SearchSpecialTransition(isolate->heap()->observed_symbol()); 5511 old_map->SearchTransition(isolate->heap()->observed_symbol());
5524 if (transition_index != TransitionArray::kNotFound) { 5512 if (transition_index != TransitionArray::kNotFound) {
5525 new_map = handle(old_map->GetTransition(transition_index), isolate); 5513 new_map = handle(old_map->GetTransition(transition_index), isolate);
5526 DCHECK(new_map->is_observed()); 5514 DCHECK(new_map->is_observed());
5527 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) { 5515 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) {
5528 new_map = Map::CopyForObserved(old_map); 5516 new_map = Map::CopyForObserved(old_map);
5529 } else { 5517 } else {
5530 new_map = Map::Copy(old_map, "SlowObserved"); 5518 new_map = Map::Copy(old_map, "SlowObserved");
5531 new_map->set_is_observed(); 5519 new_map->set_is_observed();
5532 } 5520 }
5533 JSObject::MigrateToMap(object, new_map); 5521 JSObject::MigrateToMap(object, new_map);
(...skipping 1190 matching lines...) Expand 10 before | Expand all | Expand 10 after
6724 ? LayoutDescriptor::Append(map, descriptor->GetDetails()) 6712 ? LayoutDescriptor::Append(map, descriptor->GetDetails())
6725 : handle(LayoutDescriptor::FastPointerLayout(), map->GetIsolate()); 6713 : handle(LayoutDescriptor::FastPointerLayout(), map->GetIsolate());
6726 6714
6727 { 6715 {
6728 DisallowHeapAllocation no_gc; 6716 DisallowHeapAllocation no_gc;
6729 descriptors->Append(descriptor); 6717 descriptors->Append(descriptor);
6730 result->InitializeDescriptors(*descriptors, *layout_descriptor); 6718 result->InitializeDescriptors(*descriptors, *layout_descriptor);
6731 } 6719 }
6732 6720
6733 DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1); 6721 DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1);
6734 ConnectTransition(map, result, name, SIMPLE_PROPERTY_TRANSITION); 6722 ConnectTransition(map, result, name, SIMPLE_TRANSITION);
6735 6723
6736 return result; 6724 return result;
6737 } 6725 }
6738 6726
6739 6727
6740 #if TRACE_MAPS 6728 #if TRACE_MAPS
6741 6729
6742 // static 6730 // static
6743 void Map::TraceTransition(const char* what, Map* from, Map* to, Name* name) { 6731 void Map::TraceTransition(const char* what, Map* from, Map* to, Name* name) {
6744 if (FLAG_trace_maps) { 6732 if (FLAG_trace_maps) {
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
6857 if (FLAG_unbox_double_fields) { 6845 if (FLAG_unbox_double_fields) {
6858 Handle<LayoutDescriptor> layout_descriptor = 6846 Handle<LayoutDescriptor> layout_descriptor =
6859 LayoutDescriptor::AppendIfFastOrUseFull(map, details, 6847 LayoutDescriptor::AppendIfFastOrUseFull(map, details,
6860 full_layout_descriptor); 6848 full_layout_descriptor);
6861 result->set_layout_descriptor(*layout_descriptor); 6849 result->set_layout_descriptor(*layout_descriptor);
6862 SLOW_DCHECK(result->layout_descriptor()->IsConsistentWithMap(*result)); 6850 SLOW_DCHECK(result->layout_descriptor()->IsConsistentWithMap(*result));
6863 result->set_visitor_id(StaticVisitorBase::GetVisitorId(*result)); 6851 result->set_visitor_id(StaticVisitorBase::GetVisitorId(*result));
6864 } 6852 }
6865 6853
6866 Handle<Name> name = handle(descriptors->GetKey(new_descriptor)); 6854 Handle<Name> name = handle(descriptors->GetKey(new_descriptor));
6867 ConnectTransition(map, result, name, SIMPLE_PROPERTY_TRANSITION); 6855 ConnectTransition(map, result, name, SIMPLE_TRANSITION);
6868 6856
6869 return result; 6857 return result;
6870 } 6858 }
6871 6859
6872 6860
6873 Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind, 6861 Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind,
6874 TransitionFlag flag) { 6862 TransitionFlag flag) {
6875 if (flag == INSERT_TRANSITION) { 6863 if (flag == INSERT_TRANSITION) {
6876 DCHECK(!map->HasElementsTransition() || 6864 DCHECK(!map->HasElementsTransition() ||
6877 ((map->elements_transition_map()->elements_kind() == 6865 ((map->elements_transition_map()->elements_kind() ==
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
6935 6923
6936 new_map->set_is_observed(); 6924 new_map->set_is_observed();
6937 if (map->owns_descriptors()) { 6925 if (map->owns_descriptors()) {
6938 // The properties did not change, so reuse descriptors. 6926 // The properties did not change, so reuse descriptors.
6939 new_map->InitializeDescriptors(map->instance_descriptors(), 6927 new_map->InitializeDescriptors(map->instance_descriptors(),
6940 map->GetLayoutDescriptor()); 6928 map->GetLayoutDescriptor());
6941 } 6929 }
6942 6930
6943 if (map->CanHaveMoreTransitions()) { 6931 if (map->CanHaveMoreTransitions()) {
6944 Handle<Name> name = isolate->factory()->observed_symbol(); 6932 Handle<Name> name = isolate->factory()->observed_symbol();
6945 ConnectTransition(map, new_map, name, SPECIAL_TRANSITION); 6933 ConnectTransition(map, new_map, name, FULL_TRANSITION);
6946 } 6934 }
6947 return new_map; 6935 return new_map;
6948 } 6936 }
6949 6937
6950 6938
6951 Handle<Map> Map::Copy(Handle<Map> map, const char* reason) { 6939 Handle<Map> Map::Copy(Handle<Map> map, const char* reason) {
6952 Handle<DescriptorArray> descriptors(map->instance_descriptors()); 6940 Handle<DescriptorArray> descriptors(map->instance_descriptors());
6953 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); 6941 int number_of_own_descriptors = map->NumberOfOwnDescriptors();
6954 Handle<DescriptorArray> new_descriptors = 6942 Handle<DescriptorArray> new_descriptors =
6955 DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors); 6943 DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors);
6956 Handle<LayoutDescriptor> new_layout_descriptor(map->GetLayoutDescriptor(), 6944 Handle<LayoutDescriptor> new_layout_descriptor(map->GetLayoutDescriptor(),
6957 map->GetIsolate()); 6945 map->GetIsolate());
6958 return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor, 6946 return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor,
6959 OMIT_TRANSITION, MaybeHandle<Name>(), reason, 6947 OMIT_TRANSITION, MaybeHandle<Name>(), reason);
6960 SPECIAL_TRANSITION);
6961 } 6948 }
6962 6949
6963 6950
6964 Handle<Map> Map::Create(Isolate* isolate, int inobject_properties) { 6951 Handle<Map> Map::Create(Isolate* isolate, int inobject_properties) {
6965 Handle<Map> copy = 6952 Handle<Map> copy =
6966 Copy(handle(isolate->object_function()->initial_map()), "MapCreate"); 6953 Copy(handle(isolate->object_function()->initial_map()), "MapCreate");
6967 6954
6968 // Check that we do not overflow the instance size when adding the extra 6955 // Check that we do not overflow the instance size when adding the extra
6969 // inobject properties. If the instance size overflows, we allocate as many 6956 // inobject properties. If the instance size overflows, we allocate as many
6970 // properties as we can as inobject properties. 6957 // properties as we can as inobject properties.
(...skipping 18 matching lines...) Expand all
6989 6976
6990 Handle<Map> Map::CopyForFreeze(Handle<Map> map) { 6977 Handle<Map> Map::CopyForFreeze(Handle<Map> map) {
6991 int num_descriptors = map->NumberOfOwnDescriptors(); 6978 int num_descriptors = map->NumberOfOwnDescriptors();
6992 Isolate* isolate = map->GetIsolate(); 6979 Isolate* isolate = map->GetIsolate();
6993 Handle<DescriptorArray> new_desc = DescriptorArray::CopyUpToAddAttributes( 6980 Handle<DescriptorArray> new_desc = DescriptorArray::CopyUpToAddAttributes(
6994 handle(map->instance_descriptors(), isolate), num_descriptors, FROZEN); 6981 handle(map->instance_descriptors(), isolate), num_descriptors, FROZEN);
6995 Handle<LayoutDescriptor> new_layout_descriptor(map->GetLayoutDescriptor(), 6982 Handle<LayoutDescriptor> new_layout_descriptor(map->GetLayoutDescriptor(),
6996 isolate); 6983 isolate);
6997 Handle<Map> new_map = CopyReplaceDescriptors( 6984 Handle<Map> new_map = CopyReplaceDescriptors(
6998 map, new_desc, new_layout_descriptor, INSERT_TRANSITION, 6985 map, new_desc, new_layout_descriptor, INSERT_TRANSITION,
6999 isolate->factory()->frozen_symbol(), "CopyForFreeze", SPECIAL_TRANSITION); 6986 isolate->factory()->frozen_symbol(), "CopyForFreeze");
7000 new_map->freeze(); 6987 new_map->freeze();
7001 new_map->set_is_extensible(false); 6988 new_map->set_is_extensible(false);
7002 new_map->set_elements_kind(DICTIONARY_ELEMENTS); 6989 new_map->set_elements_kind(DICTIONARY_ELEMENTS);
7003 return new_map; 6990 return new_map;
7004 } 6991 }
7005 6992
7006 6993
7007 bool DescriptorArray::CanHoldValue(int descriptor, Object* value) { 6994 bool DescriptorArray::CanHoldValue(int descriptor, Object* value) {
7008 PropertyDetails details = GetDetails(descriptor); 6995 PropertyDetails details = GetDetails(descriptor);
7009 switch (details.type()) { 6996 switch (details.type()) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
7053 Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name, 7040 Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name,
7054 Handle<Object> value, 7041 Handle<Object> value,
7055 PropertyAttributes attributes, 7042 PropertyAttributes attributes,
7056 StoreFromKeyed store_mode) { 7043 StoreFromKeyed store_mode) {
7057 // Dictionary maps can always have additional data properties. 7044 // Dictionary maps can always have additional data properties.
7058 if (map->is_dictionary_map()) return map; 7045 if (map->is_dictionary_map()) return map;
7059 7046
7060 // Migrate to the newest map before storing the property. 7047 // Migrate to the newest map before storing the property.
7061 map = Update(map); 7048 map = Update(map);
7062 7049
7063 int index = map->SearchTransition(FIELD, *name, attributes); 7050 int index = map->SearchTransition(*name);
7064 if (index != TransitionArray::kNotFound) { 7051 if (index != TransitionArray::kNotFound) {
7065 Handle<Map> transition(map->GetTransition(index)); 7052 Handle<Map> transition(map->GetTransition(index));
7066 int descriptor = transition->LastAdded(); 7053 int descriptor = transition->LastAdded();
7067 7054
7068 DCHECK_EQ(attributes, transition->instance_descriptors() 7055 // TODO(verwaest): Handle attributes better.
7069 ->GetDetails(descriptor) 7056 DescriptorArray* descriptors = transition->instance_descriptors();
7070 .attributes()); 7057 if (descriptors->GetDetails(descriptor).attributes() != attributes) {
7058 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES,
7059 "IncompatibleAttributes");
7060 }
7071 7061
7072 return Map::PrepareForDataProperty(transition, descriptor, value); 7062 return Map::PrepareForDataProperty(transition, descriptor, value);
7073 } 7063 }
7074 7064
7075 TransitionFlag flag = INSERT_TRANSITION; 7065 TransitionFlag flag = INSERT_TRANSITION;
7076 MaybeHandle<Map> maybe_map; 7066 MaybeHandle<Map> maybe_map;
7077 if (value->IsJSFunction()) { 7067 if (value->IsJSFunction()) {
7078 maybe_map = Map::CopyWithConstant(map, name, value, attributes, flag); 7068 maybe_map = Map::CopyWithConstant(map, name, value, attributes, flag);
7079 } else if (!map->TooManyFastProperties(store_mode)) { 7069 } else if (!map->TooManyFastProperties(store_mode)) {
7080 Isolate* isolate = name->GetIsolate(); 7070 Isolate* isolate = name->GetIsolate();
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
7130 return map; 7120 return map;
7131 } 7121 }
7132 7122
7133 // Migrate to the newest map before transitioning to the new property. 7123 // Migrate to the newest map before transitioning to the new property.
7134 map = Update(map); 7124 map = Update(map);
7135 7125
7136 PropertyNormalizationMode mode = map->is_prototype_map() 7126 PropertyNormalizationMode mode = map->is_prototype_map()
7137 ? KEEP_INOBJECT_PROPERTIES 7127 ? KEEP_INOBJECT_PROPERTIES
7138 : CLEAR_INOBJECT_PROPERTIES; 7128 : CLEAR_INOBJECT_PROPERTIES;
7139 7129
7140 int index = map->SearchTransition(CALLBACKS, *name, attributes); 7130 int index = map->SearchTransition(*name);
7141 if (index != TransitionArray::kNotFound) { 7131 if (index != TransitionArray::kNotFound) {
7142 Handle<Map> transition(map->GetTransition(index)); 7132 Handle<Map> transition(map->GetTransition(index));
7143 DescriptorArray* descriptors = transition->instance_descriptors(); 7133 DescriptorArray* descriptors = transition->instance_descriptors();
7134 // Fast path, assume that we're modifying the last added descriptor.
7144 int descriptor = transition->LastAdded(); 7135 int descriptor = transition->LastAdded();
7145 DCHECK(descriptors->GetKey(descriptor)->Equals(*name)); 7136 if (descriptors->GetKey(descriptor) != *name) {
7137 // If not, search for the descriptor.
7138 descriptor = descriptors->SearchWithCache(*name, *transition);
7139 }
7146 7140
7147 DCHECK_EQ(CALLBACKS, descriptors->GetDetails(descriptor).type()); 7141 if (descriptors->GetDetails(descriptor).type() != CALLBACKS) {
7148 DCHECK_EQ(attributes, descriptors->GetDetails(descriptor).attributes()); 7142 return Map::Normalize(map, mode, "TransitionToAccessorFromNonPair");
7143 }
7144
7145 // TODO(verwaest): Handle attributes better.
7146 if (descriptors->GetDetails(descriptor).attributes() != attributes) {
7147 return Map::Normalize(map, mode,
7148 "TransitionToAccessorDifferentAttributes");
7149 }
7149 7150
7150 Handle<Object> maybe_pair(descriptors->GetValue(descriptor), isolate); 7151 Handle<Object> maybe_pair(descriptors->GetValue(descriptor), isolate);
7151 if (!maybe_pair->IsAccessorPair()) { 7152 if (!maybe_pair->IsAccessorPair()) {
7152 return Map::Normalize(map, mode, "TransitionToAccessorFromNonPair"); 7153 return Map::Normalize(map, mode, "TransitionToAccessorFromNonPair");
7153 } 7154 }
7154 7155
7155 Handle<AccessorPair> pair = Handle<AccessorPair>::cast(maybe_pair); 7156 Handle<AccessorPair> pair = Handle<AccessorPair>::cast(maybe_pair);
7156 if (pair->get(component) != *accessor) { 7157 if (pair->get(component) != *accessor) {
7157 return Map::Normalize(map, mode, "TransitionToDifferentAccessor"); 7158 return Map::Normalize(map, mode, "TransitionToDifferentAccessor");
7158 } 7159 }
7159 7160
7160 return transition; 7161 return transition;
7161 } 7162 }
7162 7163
7163 Handle<AccessorPair> pair; 7164 Handle<AccessorPair> pair;
7164 DescriptorArray* old_descriptors = map->instance_descriptors(); 7165 DescriptorArray* old_descriptors = map->instance_descriptors();
7165 int descriptor = old_descriptors->SearchWithCache(*name, *map); 7166 int descriptor = old_descriptors->SearchWithCache(*name, *map);
7166 if (descriptor != DescriptorArray::kNotFound) { 7167 if (descriptor != DescriptorArray::kNotFound) {
7167 if (descriptor != map->LastAdded()) {
7168 return Map::Normalize(map, mode, "AccessorsOverwritingNonLast");
7169 }
7170 PropertyDetails old_details = old_descriptors->GetDetails(descriptor); 7168 PropertyDetails old_details = old_descriptors->GetDetails(descriptor);
7171 if (old_details.type() != CALLBACKS) { 7169 if (old_details.type() != CALLBACKS) {
7172 return Map::Normalize(map, mode, "AccessorsOverwritingNonAccessors"); 7170 return Map::Normalize(map, mode, "AccessorsOverwritingNonAccessors");
7173 } 7171 }
7174 7172
7175 if (old_details.attributes() != attributes) { 7173 if (old_details.attributes() != attributes) {
7176 return Map::Normalize(map, mode, "AccessorsWithAttributes"); 7174 return Map::Normalize(map, mode, "AccessorsWithAttributes");
7177 } 7175 }
7178 7176
7179 Handle<Object> maybe_pair(old_descriptors->GetValue(descriptor), isolate); 7177 Handle<Object> maybe_pair(old_descriptors->GetValue(descriptor), isolate);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
7221 descriptors, map->NumberOfOwnDescriptors(), 1); 7219 descriptors, map->NumberOfOwnDescriptors(), 1);
7222 new_descriptors->Append(descriptor); 7220 new_descriptors->Append(descriptor);
7223 7221
7224 Handle<LayoutDescriptor> new_layout_descriptor = 7222 Handle<LayoutDescriptor> new_layout_descriptor =
7225 FLAG_unbox_double_fields 7223 FLAG_unbox_double_fields
7226 ? LayoutDescriptor::Append(map, descriptor->GetDetails()) 7224 ? LayoutDescriptor::Append(map, descriptor->GetDetails())
7227 : handle(LayoutDescriptor::FastPointerLayout(), map->GetIsolate()); 7225 : handle(LayoutDescriptor::FastPointerLayout(), map->GetIsolate());
7228 7226
7229 return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor, 7227 return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor,
7230 flag, descriptor->GetKey(), "CopyAddDescriptor", 7228 flag, descriptor->GetKey(), "CopyAddDescriptor",
7231 SIMPLE_PROPERTY_TRANSITION); 7229 SIMPLE_TRANSITION);
7232 } 7230 }
7233 7231
7234 7232
7235 Handle<Map> Map::CopyInsertDescriptor(Handle<Map> map, 7233 Handle<Map> Map::CopyInsertDescriptor(Handle<Map> map,
7236 Descriptor* descriptor, 7234 Descriptor* descriptor,
7237 TransitionFlag flag) { 7235 TransitionFlag flag) {
7238 Handle<DescriptorArray> old_descriptors(map->instance_descriptors()); 7236 Handle<DescriptorArray> old_descriptors(map->instance_descriptors());
7239 7237
7240 // Ensure the key is unique. 7238 // Ensure the key is unique.
7241 descriptor->KeyToUniqueName(); 7239 descriptor->KeyToUniqueName();
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
7317 7315
7318 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( 7316 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo(
7319 descriptors, map->NumberOfOwnDescriptors()); 7317 descriptors, map->NumberOfOwnDescriptors());
7320 7318
7321 new_descriptors->Replace(insertion_index, descriptor); 7319 new_descriptors->Replace(insertion_index, descriptor);
7322 Handle<LayoutDescriptor> new_layout_descriptor = LayoutDescriptor::New( 7320 Handle<LayoutDescriptor> new_layout_descriptor = LayoutDescriptor::New(
7323 map, new_descriptors, new_descriptors->number_of_descriptors()); 7321 map, new_descriptors, new_descriptors->number_of_descriptors());
7324 7322
7325 SimpleTransitionFlag simple_flag = 7323 SimpleTransitionFlag simple_flag =
7326 (insertion_index == descriptors->number_of_descriptors() - 1) 7324 (insertion_index == descriptors->number_of_descriptors() - 1)
7327 ? SIMPLE_PROPERTY_TRANSITION 7325 ? SIMPLE_TRANSITION
7328 : PROPERTY_TRANSITION; 7326 : FULL_TRANSITION;
7329 return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor, 7327 return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor,
7330 flag, key, "CopyReplaceDescriptor", 7328 flag, key, "CopyReplaceDescriptor",
7331 simple_flag); 7329 simple_flag);
7332 } 7330 }
7333 7331
7334 7332
7335 void Map::UpdateCodeCache(Handle<Map> map, 7333 void Map::UpdateCodeCache(Handle<Map> map,
7336 Handle<Name> name, 7334 Handle<Name> name,
7337 Handle<Code> code) { 7335 Handle<Code> code) {
7338 Isolate* isolate = map->GetIsolate(); 7336 Isolate* isolate = map->GetIsolate();
(...skipping 9452 matching lines...) Expand 10 before | Expand all | Expand 10 after
16791 Handle<DependentCode> codes = 16789 Handle<DependentCode> codes =
16792 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), 16790 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()),
16793 DependentCode::kPropertyCellChangedGroup, 16791 DependentCode::kPropertyCellChangedGroup,
16794 info->object_wrapper()); 16792 info->object_wrapper());
16795 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); 16793 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes);
16796 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( 16794 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add(
16797 cell, info->zone()); 16795 cell, info->zone());
16798 } 16796 }
16799 16797
16800 } } // namespace v8::internal 16798 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698