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

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
« 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 1916 matching lines...) Expand 10 before | Expand all | Expand 10 after
1927 return false; 1927 return false;
1928 } 1928 }
1929 // Otherwise, properties will need to be moved to the backing store. 1929 // Otherwise, properties will need to be moved to the backing store.
1930 return true; 1930 return true;
1931 } 1931 }
1932 1932
1933 1933
1934 void Map::ConnectElementsTransition(Handle<Map> parent, Handle<Map> child) { 1934 void Map::ConnectElementsTransition(Handle<Map> parent, Handle<Map> child) {
1935 Isolate* isolate = parent->GetIsolate(); 1935 Isolate* isolate = parent->GetIsolate();
1936 Handle<Name> name = isolate->factory()->elements_transition_symbol(); 1936 Handle<Name> name = isolate->factory()->elements_transition_symbol();
1937 ConnectTransition(parent, child, name, FULL_TRANSITION); 1937 ConnectTransition(parent, child, name, SPECIAL_TRANSITION);
1938 } 1938 }
1939 1939
1940 1940
1941 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) { 1941 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
1942 if (object->map() == *new_map) return; 1942 if (object->map() == *new_map) return;
1943 if (object->HasFastProperties()) { 1943 if (object->HasFastProperties()) {
1944 if (!new_map->is_dictionary_map()) { 1944 if (!new_map->is_dictionary_map()) {
1945 Handle<Map> old_map(object->map()); 1945 Handle<Map> old_map(object->map());
1946 MigrateFastToFast(object, new_map); 1946 MigrateFastToFast(object, new_map);
1947 if (old_map->is_prototype_map()) { 1947 if (old_map->is_prototype_map()) {
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
2221 deprecate(); 2221 deprecate();
2222 dependent_code()->DeoptimizeDependentCodeGroup( 2222 dependent_code()->DeoptimizeDependentCodeGroup(
2223 GetIsolate(), DependentCode::kTransitionGroup); 2223 GetIsolate(), DependentCode::kTransitionGroup);
2224 NotifyLeafMapLayoutChange(); 2224 NotifyLeafMapLayoutChange();
2225 } 2225 }
2226 2226
2227 2227
2228 // Invalidates a transition target at |key|, and installs |new_descriptors| over 2228 // Invalidates a transition target at |key|, and installs |new_descriptors| over
2229 // the current instance_descriptors to ensure proper sharing of descriptor 2229 // the current instance_descriptors to ensure proper sharing of descriptor
2230 // arrays. 2230 // arrays.
2231 void Map::DeprecateTarget(Name* key, DescriptorArray* new_descriptors) { 2231 void Map::DeprecateTarget(PropertyType type, Name* key,
2232 PropertyAttributes attributes,
2233 DescriptorArray* new_descriptors) {
2232 if (HasTransitionArray()) { 2234 if (HasTransitionArray()) {
2233 TransitionArray* transitions = this->transitions(); 2235 TransitionArray* transitions = this->transitions();
2234 int transition = transitions->Search(key); 2236 int transition = transitions->Search(type, key, attributes);
2235 if (transition != TransitionArray::kNotFound) { 2237 if (transition != TransitionArray::kNotFound) {
2236 transitions->GetTarget(transition)->DeprecateTransitionTree(); 2238 transitions->GetTarget(transition)->DeprecateTransitionTree();
2237 } 2239 }
2238 } 2240 }
2239 2241
2240 // Don't overwrite the empty descriptor array. 2242 // Don't overwrite the empty descriptor array.
2241 if (NumberOfOwnDescriptors() == 0) return; 2243 if (NumberOfOwnDescriptors() == 0) return;
2242 2244
2243 DescriptorArray* to_replace = instance_descriptors(); 2245 DescriptorArray* to_replace = instance_descriptors();
2244 Map* current = this; 2246 Map* current = this;
(...skipping 26 matching lines...) Expand all
2271 DisallowHeapAllocation no_allocation; 2273 DisallowHeapAllocation no_allocation;
2272 2274
2273 // This can only be called on roots of transition trees. 2275 // This can only be called on roots of transition trees.
2274 DCHECK(GetBackPointer()->IsUndefined()); 2276 DCHECK(GetBackPointer()->IsUndefined());
2275 2277
2276 Map* current = this; 2278 Map* current = this;
2277 2279
2278 for (int i = verbatim; i < length; i++) { 2280 for (int i = verbatim; i < length; i++) {
2279 if (!current->HasTransitionArray()) break; 2281 if (!current->HasTransitionArray()) break;
2280 Name* name = descriptors->GetKey(i); 2282 Name* name = descriptors->GetKey(i);
2283 PropertyDetails details = descriptors->GetDetails(i);
2281 TransitionArray* transitions = current->transitions(); 2284 TransitionArray* transitions = current->transitions();
2282 int transition = transitions->Search(name); 2285 int transition =
2286 transitions->Search(details.type(), name, details.attributes());
2283 if (transition == TransitionArray::kNotFound) break; 2287 if (transition == TransitionArray::kNotFound) break;
2284 2288
2285 Map* next = transitions->GetTarget(transition); 2289 Map* next = transitions->GetTarget(transition);
2286 DescriptorArray* next_descriptors = next->instance_descriptors(); 2290 DescriptorArray* next_descriptors = next->instance_descriptors();
2287 2291
2288 PropertyDetails details = descriptors->GetDetails(i);
2289 PropertyDetails next_details = next_descriptors->GetDetails(i); 2292 PropertyDetails next_details = next_descriptors->GetDetails(i);
2290 if (details.type() != next_details.type()) break; 2293 if (details.type() != next_details.type()) break;
2291 if (details.attributes() != next_details.attributes()) break; 2294 if (details.attributes() != next_details.attributes()) break;
2292 if (!details.representation().Equals(next_details.representation())) break; 2295 if (!details.representation().Equals(next_details.representation())) break;
2293 if (next_details.type() == FIELD) { 2296 if (next_details.type() == FIELD) {
2294 if (!descriptors->GetFieldType(i)->NowIs( 2297 if (!descriptors->GetFieldType(i)->NowIs(
2295 next_descriptors->GetFieldType(i))) break; 2298 next_descriptors->GetFieldType(i))) break;
2296 } else { 2299 } else {
2297 if (descriptors->GetValue(i) != next_descriptors->GetValue(i)) break; 2300 if (descriptors->GetValue(i) != next_descriptors->GetValue(i)) break;
2298 } 2301 }
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
2468 (old_details.type() == FIELD && 2471 (old_details.type() == FIELD &&
2469 (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) || 2472 (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) ||
2470 !new_representation.fits_into(old_details.representation())))) { 2473 !new_representation.fits_into(old_details.representation())))) {
2471 return CopyGeneralizeAllRepresentations( 2474 return CopyGeneralizeAllRepresentations(
2472 old_map, modify_index, store_mode, "root modification"); 2475 old_map, modify_index, store_mode, "root modification");
2473 } 2476 }
2474 } 2477 }
2475 2478
2476 Handle<Map> target_map = root_map; 2479 Handle<Map> target_map = root_map;
2477 for (int i = root_nof; i < old_nof; ++i) { 2480 for (int i = root_nof; i < old_nof; ++i) {
2478 int j = target_map->SearchTransition(old_descriptors->GetKey(i)); 2481 PropertyDetails old_details = old_descriptors->GetDetails(i);
2482 int j = target_map->SearchTransition(old_details.type(),
2483 old_descriptors->GetKey(i),
2484 old_details.attributes());
2479 if (j == TransitionArray::kNotFound) break; 2485 if (j == TransitionArray::kNotFound) break;
2480 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); 2486 Handle<Map> tmp_map(target_map->GetTransition(j), isolate);
2481 Handle<DescriptorArray> tmp_descriptors = handle( 2487 Handle<DescriptorArray> tmp_descriptors = handle(
2482 tmp_map->instance_descriptors(), isolate); 2488 tmp_map->instance_descriptors(), isolate);
2483 2489
2484 // Check if target map is incompatible. 2490 // Check if target map is incompatible.
2485 PropertyDetails old_details = old_descriptors->GetDetails(i);
2486 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); 2491 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i);
2487 PropertyType old_type = old_details.type(); 2492 PropertyType old_type = old_details.type();
2488 PropertyType tmp_type = tmp_details.type(); 2493 PropertyType tmp_type = tmp_details.type();
2489 if (tmp_details.attributes() != old_details.attributes() || 2494 DCHECK_EQ(old_details.attributes(), tmp_details.attributes());
2490 ((tmp_type == CALLBACKS || old_type == CALLBACKS) && 2495 if ((tmp_type == CALLBACKS || old_type == CALLBACKS) &&
2491 (tmp_type != old_type || 2496 (tmp_type != old_type ||
2492 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i)))) { 2497 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) {
2493 return CopyGeneralizeAllRepresentations( 2498 return CopyGeneralizeAllRepresentations(
2494 old_map, modify_index, store_mode, "incompatible"); 2499 old_map, modify_index, store_mode, "incompatible");
2495 } 2500 }
2496 Representation old_representation = old_details.representation(); 2501 Representation old_representation = old_details.representation();
2497 Representation tmp_representation = tmp_details.representation(); 2502 Representation tmp_representation = tmp_details.representation();
2498 if (!old_representation.fits_into(tmp_representation) || 2503 if (!old_representation.fits_into(tmp_representation) ||
2499 (!new_representation.fits_into(tmp_representation) && 2504 (!new_representation.fits_into(tmp_representation) &&
2500 modify_index == i)) { 2505 modify_index == i)) {
2501 break; 2506 break;
2502 } 2507 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2534 DCHECK(new_representation.fits_into( 2539 DCHECK(new_representation.fits_into(
2535 target_descriptors->GetDetails(modify_index).representation())); 2540 target_descriptors->GetDetails(modify_index).representation()));
2536 DCHECK(target_descriptors->GetDetails(modify_index).type() != FIELD || 2541 DCHECK(target_descriptors->GetDetails(modify_index).type() != FIELD ||
2537 new_field_type->NowIs( 2542 new_field_type->NowIs(
2538 target_descriptors->GetFieldType(modify_index))); 2543 target_descriptors->GetFieldType(modify_index)));
2539 return target_map; 2544 return target_map;
2540 } 2545 }
2541 2546
2542 // Find the last compatible target map in the transition tree. 2547 // Find the last compatible target map in the transition tree.
2543 for (int i = target_nof; i < old_nof; ++i) { 2548 for (int i = target_nof; i < old_nof; ++i) {
2544 int j = target_map->SearchTransition(old_descriptors->GetKey(i)); 2549 PropertyDetails old_details = old_descriptors->GetDetails(i);
2550 int j = target_map->SearchTransition(old_details.type(),
2551 old_descriptors->GetKey(i),
2552 old_details.attributes());
2545 if (j == TransitionArray::kNotFound) break; 2553 if (j == TransitionArray::kNotFound) break;
2546 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); 2554 Handle<Map> tmp_map(target_map->GetTransition(j), isolate);
2547 Handle<DescriptorArray> tmp_descriptors( 2555 Handle<DescriptorArray> tmp_descriptors(
2548 tmp_map->instance_descriptors(), isolate); 2556 tmp_map->instance_descriptors(), isolate);
2549 2557
2550 // Check if target map is compatible. 2558 // Check if target map is compatible.
2551 PropertyDetails old_details = old_descriptors->GetDetails(i);
2552 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); 2559 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i);
2553 if (tmp_details.attributes() != old_details.attributes() || 2560 DCHECK_EQ(old_details.attributes(), tmp_details.attributes());
2554 ((tmp_details.type() == CALLBACKS || old_details.type() == CALLBACKS) && 2561 if ((tmp_details.type() == CALLBACKS || old_details.type() == CALLBACKS) &&
2555 (tmp_details.type() != old_details.type() || 2562 (tmp_details.type() != old_details.type() ||
2556 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i)))) { 2563 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) {
2557 return CopyGeneralizeAllRepresentations( 2564 return CopyGeneralizeAllRepresentations(
2558 old_map, modify_index, store_mode, "incompatible"); 2565 old_map, modify_index, store_mode, "incompatible");
2559 } 2566 }
2560 target_map = tmp_map; 2567 target_map = tmp_map;
2561 } 2568 }
2562 target_nof = target_map->NumberOfOwnDescriptors(); 2569 target_nof = target_map->NumberOfOwnDescriptors();
2563 target_descriptors = handle(target_map->instance_descriptors(), isolate); 2570 target_descriptors = handle(target_map->instance_descriptors(), isolate);
2564 2571
2565 // Allocate a new descriptor array large enough to hold the required 2572 // Allocate a new descriptor array large enough to hold the required
2566 // descriptors, with minimally the exact same size as the old descriptor 2573 // descriptors, with minimally the exact same size as the old descriptor
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
2678 new_descriptors->Sort(); 2685 new_descriptors->Sort();
2679 2686
2680 DCHECK(store_mode != FORCE_FIELD || 2687 DCHECK(store_mode != FORCE_FIELD ||
2681 new_descriptors->GetDetails(modify_index).type() == FIELD); 2688 new_descriptors->GetDetails(modify_index).type() == FIELD);
2682 2689
2683 Handle<Map> split_map(root_map->FindLastMatchMap( 2690 Handle<Map> split_map(root_map->FindLastMatchMap(
2684 root_nof, old_nof, *new_descriptors), isolate); 2691 root_nof, old_nof, *new_descriptors), isolate);
2685 int split_nof = split_map->NumberOfOwnDescriptors(); 2692 int split_nof = split_map->NumberOfOwnDescriptors();
2686 DCHECK_NE(old_nof, split_nof); 2693 DCHECK_NE(old_nof, split_nof);
2687 2694
2688 split_map->DeprecateTarget( 2695 PropertyDetails split_prop_details = old_descriptors->GetDetails(split_nof);
2689 old_descriptors->GetKey(split_nof), *new_descriptors); 2696 split_map->DeprecateTarget(split_prop_details.type(),
2697 old_descriptors->GetKey(split_nof),
2698 split_prop_details.attributes(), *new_descriptors);
2690 2699
2691 if (FLAG_trace_generalization) { 2700 if (FLAG_trace_generalization) {
2692 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); 2701 PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
2693 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); 2702 PropertyDetails new_details = new_descriptors->GetDetails(modify_index);
2694 Handle<HeapType> old_field_type = (old_details.type() == FIELD) 2703 Handle<HeapType> old_field_type = (old_details.type() == FIELD)
2695 ? handle(old_descriptors->GetFieldType(modify_index), isolate) 2704 ? handle(old_descriptors->GetFieldType(modify_index), isolate)
2696 : HeapType::Constant(handle(old_descriptors->GetValue(modify_index), 2705 : HeapType::Constant(handle(old_descriptors->GetValue(modify_index),
2697 isolate), isolate); 2706 isolate), isolate);
2698 Handle<HeapType> new_field_type = (new_details.type() == FIELD) 2707 Handle<HeapType> new_field_type = (new_details.type() == FIELD)
2699 ? handle(new_descriptors->GetFieldType(modify_index), isolate) 2708 ? handle(new_descriptors->GetFieldType(modify_index), isolate)
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
2768 // Check the state of the root map. 2777 // Check the state of the root map.
2769 Map* root_map = old_map->FindRootMap(); 2778 Map* root_map = old_map->FindRootMap();
2770 if (!old_map->EquivalentToForTransition(root_map)) return MaybeHandle<Map>(); 2779 if (!old_map->EquivalentToForTransition(root_map)) return MaybeHandle<Map>();
2771 int root_nof = root_map->NumberOfOwnDescriptors(); 2780 int root_nof = root_map->NumberOfOwnDescriptors();
2772 2781
2773 int old_nof = old_map->NumberOfOwnDescriptors(); 2782 int old_nof = old_map->NumberOfOwnDescriptors();
2774 DescriptorArray* old_descriptors = old_map->instance_descriptors(); 2783 DescriptorArray* old_descriptors = old_map->instance_descriptors();
2775 2784
2776 Map* new_map = root_map; 2785 Map* new_map = root_map;
2777 for (int i = root_nof; i < old_nof; ++i) { 2786 for (int i = root_nof; i < old_nof; ++i) {
2778 int j = new_map->SearchTransition(old_descriptors->GetKey(i)); 2787 PropertyDetails old_details = old_descriptors->GetDetails(i);
2788 int j = new_map->SearchTransition(old_details.type(),
2789 old_descriptors->GetKey(i),
2790 old_details.attributes());
2779 if (j == TransitionArray::kNotFound) return MaybeHandle<Map>(); 2791 if (j == TransitionArray::kNotFound) return MaybeHandle<Map>();
2780 new_map = new_map->GetTransition(j); 2792 new_map = new_map->GetTransition(j);
2781 DescriptorArray* new_descriptors = new_map->instance_descriptors(); 2793 DescriptorArray* new_descriptors = new_map->instance_descriptors();
2782 2794
2783 PropertyDetails new_details = new_descriptors->GetDetails(i); 2795 PropertyDetails new_details = new_descriptors->GetDetails(i);
2784 PropertyDetails old_details = old_descriptors->GetDetails(i);
2785 if (old_details.attributes() != new_details.attributes() || 2796 if (old_details.attributes() != new_details.attributes() ||
2786 !old_details.representation().fits_into(new_details.representation())) { 2797 !old_details.representation().fits_into(new_details.representation())) {
2787 return MaybeHandle<Map>(); 2798 return MaybeHandle<Map>();
2788 } 2799 }
2789 PropertyType new_type = new_details.type(); 2800 PropertyType new_type = new_details.type();
2790 PropertyType old_type = old_details.type(); 2801 PropertyType old_type = old_details.type();
2791 Object* new_value = new_descriptors->GetValue(i); 2802 Object* new_value = new_descriptors->GetValue(i);
2792 Object* old_value = old_descriptors->GetValue(i); 2803 Object* old_value = old_descriptors->GetValue(i);
2793 switch (new_type) { 2804 switch (new_type) {
2794 case FIELD: 2805 case FIELD:
(...skipping 2578 matching lines...) Expand 10 before | Expand all | Expand 10 after
5373 new_element_dictionary = CopyFastElementsToDictionary( 5384 new_element_dictionary = CopyFastElementsToDictionary(
5374 handle(object->elements()), length, new_element_dictionary); 5385 handle(object->elements()), length, new_element_dictionary);
5375 } else { 5386 } else {
5376 // No existing elements, use a pre-allocated empty backing store 5387 // No existing elements, use a pre-allocated empty backing store
5377 new_element_dictionary = 5388 new_element_dictionary =
5378 isolate->factory()->empty_slow_element_dictionary(); 5389 isolate->factory()->empty_slow_element_dictionary();
5379 } 5390 }
5380 } 5391 }
5381 5392
5382 Handle<Map> old_map(object->map(), isolate); 5393 Handle<Map> old_map(object->map(), isolate);
5383 int transition_index = old_map->SearchTransition( 5394 int transition_index =
5384 isolate->heap()->frozen_symbol()); 5395 old_map->SearchSpecialTransition(isolate->heap()->frozen_symbol());
5385 if (transition_index != TransitionArray::kNotFound) { 5396 if (transition_index != TransitionArray::kNotFound) {
5386 Handle<Map> transition_map(old_map->GetTransition(transition_index)); 5397 Handle<Map> transition_map(old_map->GetTransition(transition_index));
5387 DCHECK(transition_map->has_dictionary_elements()); 5398 DCHECK(transition_map->has_dictionary_elements());
5388 DCHECK(transition_map->is_frozen()); 5399 DCHECK(transition_map->is_frozen());
5389 DCHECK(!transition_map->is_extensible()); 5400 DCHECK(!transition_map->is_extensible());
5390 JSObject::MigrateToMap(object, transition_map); 5401 JSObject::MigrateToMap(object, transition_map);
5391 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) { 5402 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) {
5392 // Create a new descriptor array with fully-frozen properties 5403 // Create a new descriptor array with fully-frozen properties
5393 Handle<Map> new_map = Map::CopyForFreeze(old_map); 5404 Handle<Map> new_map = Map::CopyForFreeze(old_map);
5394 JSObject::MigrateToMap(object, new_map); 5405 JSObject::MigrateToMap(object, new_map);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
5426 } 5437 }
5427 5438
5428 5439
5429 void JSObject::SetObserved(Handle<JSObject> object) { 5440 void JSObject::SetObserved(Handle<JSObject> object) {
5430 DCHECK(!object->IsJSGlobalProxy()); 5441 DCHECK(!object->IsJSGlobalProxy());
5431 DCHECK(!object->IsJSGlobalObject()); 5442 DCHECK(!object->IsJSGlobalObject());
5432 Isolate* isolate = object->GetIsolate(); 5443 Isolate* isolate = object->GetIsolate();
5433 Handle<Map> new_map; 5444 Handle<Map> new_map;
5434 Handle<Map> old_map(object->map(), isolate); 5445 Handle<Map> old_map(object->map(), isolate);
5435 DCHECK(!old_map->is_observed()); 5446 DCHECK(!old_map->is_observed());
5436 int transition_index = old_map->SearchTransition( 5447 int transition_index =
5437 isolate->heap()->observed_symbol()); 5448 old_map->SearchSpecialTransition(isolate->heap()->observed_symbol());
5438 if (transition_index != TransitionArray::kNotFound) { 5449 if (transition_index != TransitionArray::kNotFound) {
5439 new_map = handle(old_map->GetTransition(transition_index), isolate); 5450 new_map = handle(old_map->GetTransition(transition_index), isolate);
5440 DCHECK(new_map->is_observed()); 5451 DCHECK(new_map->is_observed());
5441 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) { 5452 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) {
5442 new_map = Map::CopyForObserved(old_map); 5453 new_map = Map::CopyForObserved(old_map);
5443 } else { 5454 } else {
5444 new_map = Map::Copy(old_map); 5455 new_map = Map::Copy(old_map);
5445 new_map->set_is_observed(); 5456 new_map->set_is_observed();
5446 } 5457 }
5447 JSObject::MigrateToMap(object, new_map); 5458 JSObject::MigrateToMap(object, new_map);
(...skipping 1146 matching lines...) Expand 10 before | Expand all | Expand 10 after
6594 } 6605 }
6595 } 6606 }
6596 6607
6597 { 6608 {
6598 DisallowHeapAllocation no_gc; 6609 DisallowHeapAllocation no_gc;
6599 descriptors->Append(descriptor); 6610 descriptors->Append(descriptor);
6600 result->InitializeDescriptors(*descriptors); 6611 result->InitializeDescriptors(*descriptors);
6601 } 6612 }
6602 6613
6603 DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1); 6614 DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1);
6604 ConnectTransition(map, result, name, SIMPLE_TRANSITION); 6615 ConnectTransition(map, result, name, SIMPLE_PROPERTY_TRANSITION);
6605 6616
6606 return result; 6617 return result;
6607 } 6618 }
6608 6619
6609 6620
6610 void Map::ConnectTransition(Handle<Map> parent, Handle<Map> child, 6621 void Map::ConnectTransition(Handle<Map> parent, Handle<Map> child,
6611 Handle<Name> name, SimpleTransitionFlag flag) { 6622 Handle<Name> name, SimpleTransitionFlag flag) {
6612 parent->set_owns_descriptors(false); 6623 parent->set_owns_descriptors(false);
6613 if (parent->is_prototype_map()) { 6624 if (parent->is_prototype_map()) {
6614 DCHECK(child->is_prototype_map()); 6625 DCHECK(child->is_prototype_map());
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
6670 if (descriptors->GetDetails(new_descriptor).type() == FIELD) { 6681 if (descriptors->GetDetails(new_descriptor).type() == FIELD) {
6671 unused_property_fields = map->unused_property_fields() - 1; 6682 unused_property_fields = map->unused_property_fields() - 1;
6672 if (unused_property_fields < 0) { 6683 if (unused_property_fields < 0) {
6673 unused_property_fields += JSObject::kFieldsAdded; 6684 unused_property_fields += JSObject::kFieldsAdded;
6674 } 6685 }
6675 } 6686 }
6676 6687
6677 result->set_unused_property_fields(unused_property_fields); 6688 result->set_unused_property_fields(unused_property_fields);
6678 6689
6679 Handle<Name> name = handle(descriptors->GetKey(new_descriptor)); 6690 Handle<Name> name = handle(descriptors->GetKey(new_descriptor));
6680 ConnectTransition(map, result, name, SIMPLE_TRANSITION); 6691 ConnectTransition(map, result, name, SIMPLE_PROPERTY_TRANSITION);
6681 6692
6682 return result; 6693 return result;
6683 } 6694 }
6684 6695
6685 6696
6686 Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind, 6697 Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind,
6687 TransitionFlag flag) { 6698 TransitionFlag flag) {
6688 if (flag == INSERT_TRANSITION) { 6699 if (flag == INSERT_TRANSITION) {
6689 DCHECK(!map->HasElementsTransition() || 6700 DCHECK(!map->HasElementsTransition() ||
6690 ((map->elements_transition_map()->elements_kind() == 6701 ((map->elements_transition_map()->elements_kind() ==
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
6744 new_map = Copy(map); 6755 new_map = Copy(map);
6745 } 6756 }
6746 6757
6747 new_map->set_is_observed(); 6758 new_map->set_is_observed();
6748 if (map->owns_descriptors()) { 6759 if (map->owns_descriptors()) {
6749 new_map->InitializeDescriptors(map->instance_descriptors()); 6760 new_map->InitializeDescriptors(map->instance_descriptors());
6750 } 6761 }
6751 6762
6752 if (map->CanHaveMoreTransitions()) { 6763 if (map->CanHaveMoreTransitions()) {
6753 Handle<Name> name = isolate->factory()->observed_symbol(); 6764 Handle<Name> name = isolate->factory()->observed_symbol();
6754 ConnectTransition(map, new_map, name, FULL_TRANSITION); 6765 ConnectTransition(map, new_map, name, SPECIAL_TRANSITION);
6755 } 6766 }
6756 return new_map; 6767 return new_map;
6757 } 6768 }
6758 6769
6759 6770
6760 Handle<Map> Map::Copy(Handle<Map> map) { 6771 Handle<Map> Map::Copy(Handle<Map> map) {
6761 Handle<DescriptorArray> descriptors(map->instance_descriptors()); 6772 Handle<DescriptorArray> descriptors(map->instance_descriptors());
6762 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); 6773 int number_of_own_descriptors = map->NumberOfOwnDescriptors();
6763 Handle<DescriptorArray> new_descriptors = 6774 Handle<DescriptorArray> new_descriptors =
6764 DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors); 6775 DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors);
6765 return CopyReplaceDescriptors( 6776 return CopyReplaceDescriptors(map, new_descriptors, OMIT_TRANSITION,
6766 map, new_descriptors, OMIT_TRANSITION, MaybeHandle<Name>()); 6777 MaybeHandle<Name>(), SPECIAL_TRANSITION);
6767 } 6778 }
6768 6779
6769 6780
6770 Handle<Map> Map::Create(Isolate* isolate, int inobject_properties) { 6781 Handle<Map> Map::Create(Isolate* isolate, int inobject_properties) {
6771 Handle<Map> copy = Copy(handle(isolate->object_function()->initial_map())); 6782 Handle<Map> copy = Copy(handle(isolate->object_function()->initial_map()));
6772 6783
6773 // Check that we do not overflow the instance size when adding the extra 6784 // Check that we do not overflow the instance size when adding the extra
6774 // inobject properties. If the instance size overflows, we allocate as many 6785 // inobject properties. If the instance size overflows, we allocate as many
6775 // properties as we can as inobject properties. 6786 // properties as we can as inobject properties.
6776 int max_extra_properties = 6787 int max_extra_properties =
(...skipping 14 matching lines...) Expand all
6791 return copy; 6802 return copy;
6792 } 6803 }
6793 6804
6794 6805
6795 Handle<Map> Map::CopyForFreeze(Handle<Map> map) { 6806 Handle<Map> Map::CopyForFreeze(Handle<Map> map) {
6796 int num_descriptors = map->NumberOfOwnDescriptors(); 6807 int num_descriptors = map->NumberOfOwnDescriptors();
6797 Isolate* isolate = map->GetIsolate(); 6808 Isolate* isolate = map->GetIsolate();
6798 Handle<DescriptorArray> new_desc = DescriptorArray::CopyUpToAddAttributes( 6809 Handle<DescriptorArray> new_desc = DescriptorArray::CopyUpToAddAttributes(
6799 handle(map->instance_descriptors(), isolate), num_descriptors, FROZEN); 6810 handle(map->instance_descriptors(), isolate), num_descriptors, FROZEN);
6800 Handle<Map> new_map = CopyReplaceDescriptors( 6811 Handle<Map> new_map = CopyReplaceDescriptors(
6801 map, new_desc, INSERT_TRANSITION, isolate->factory()->frozen_symbol()); 6812 map, new_desc, INSERT_TRANSITION, isolate->factory()->frozen_symbol(),
6813 SPECIAL_TRANSITION);
6802 new_map->freeze(); 6814 new_map->freeze();
6803 new_map->set_is_extensible(false); 6815 new_map->set_is_extensible(false);
6804 new_map->set_elements_kind(DICTIONARY_ELEMENTS); 6816 new_map->set_elements_kind(DICTIONARY_ELEMENTS);
6805 return new_map; 6817 return new_map;
6806 } 6818 }
6807 6819
6808 6820
6809 bool DescriptorArray::CanHoldValue(int descriptor, Object* value) { 6821 bool DescriptorArray::CanHoldValue(int descriptor, Object* value) {
6810 PropertyDetails details = GetDetails(descriptor); 6822 PropertyDetails details = GetDetails(descriptor);
6811 switch (details.type()) { 6823 switch (details.type()) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
6855 Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name, 6867 Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name,
6856 Handle<Object> value, 6868 Handle<Object> value,
6857 PropertyAttributes attributes, 6869 PropertyAttributes attributes,
6858 StoreFromKeyed store_mode) { 6870 StoreFromKeyed store_mode) {
6859 // Dictionary maps can always have additional data properties. 6871 // Dictionary maps can always have additional data properties.
6860 if (map->is_dictionary_map()) return map; 6872 if (map->is_dictionary_map()) return map;
6861 6873
6862 // Migrate to the newest map before storing the property. 6874 // Migrate to the newest map before storing the property.
6863 map = Update(map); 6875 map = Update(map);
6864 6876
6865 int index = map->SearchTransition(*name); 6877 int index = map->SearchTransition(FIELD, *name, attributes);
6866 if (index != TransitionArray::kNotFound) { 6878 if (index != TransitionArray::kNotFound) {
6867 Handle<Map> transition(map->GetTransition(index)); 6879 Handle<Map> transition(map->GetTransition(index));
6868 int descriptor = transition->LastAdded(); 6880 int descriptor = transition->LastAdded();
6869 6881
6870 // TODO(verwaest): Handle attributes better. 6882 DCHECK_EQ(attributes, transition->instance_descriptors()
6871 DescriptorArray* descriptors = transition->instance_descriptors(); 6883 ->GetDetails(descriptor)
6872 if (descriptors->GetDetails(descriptor).attributes() != attributes) { 6884 .attributes());
6873 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES);
6874 }
6875 6885
6876 return Map::PrepareForDataProperty(transition, descriptor, value); 6886 return Map::PrepareForDataProperty(transition, descriptor, value);
6877 } 6887 }
6878 6888
6879 TransitionFlag flag = INSERT_TRANSITION; 6889 TransitionFlag flag = INSERT_TRANSITION;
6880 MaybeHandle<Map> maybe_map; 6890 MaybeHandle<Map> maybe_map;
6881 if (value->IsJSFunction()) { 6891 if (value->IsJSFunction()) {
6882 maybe_map = Map::CopyWithConstant(map, name, value, attributes, flag); 6892 maybe_map = Map::CopyWithConstant(map, name, value, attributes, flag);
6883 } else if (!map->TooManyFastProperties(store_mode)) { 6893 } else if (!map->TooManyFastProperties(store_mode)) {
6884 Isolate* isolate = name->GetIsolate(); 6894 Isolate* isolate = name->GetIsolate();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
6924 return map; 6934 return map;
6925 } 6935 }
6926 6936
6927 // Migrate to the newest map before transitioning to the new property. 6937 // Migrate to the newest map before transitioning to the new property.
6928 map = Update(map); 6938 map = Update(map);
6929 6939
6930 PropertyNormalizationMode mode = map->is_prototype_map() 6940 PropertyNormalizationMode mode = map->is_prototype_map()
6931 ? KEEP_INOBJECT_PROPERTIES 6941 ? KEEP_INOBJECT_PROPERTIES
6932 : CLEAR_INOBJECT_PROPERTIES; 6942 : CLEAR_INOBJECT_PROPERTIES;
6933 6943
6934 int index = map->SearchTransition(*name); 6944 int index = map->SearchTransition(CALLBACKS, *name, attributes);
6935 if (index != TransitionArray::kNotFound) { 6945 if (index != TransitionArray::kNotFound) {
6936 Handle<Map> transition(map->GetTransition(index)); 6946 Handle<Map> transition(map->GetTransition(index));
6937 DescriptorArray* descriptors = transition->instance_descriptors(); 6947 DescriptorArray* descriptors = transition->instance_descriptors();
6938 // Fast path, assume that we're modifying the last added descriptor.
6939 int descriptor = transition->LastAdded(); 6948 int descriptor = transition->LastAdded();
6940 if (descriptors->GetKey(descriptor) != *name) { 6949 DCHECK(descriptors->GetKey(descriptor)->Equals(*name));
6941 // If not, search for the descriptor.
6942 descriptor = descriptors->SearchWithCache(*name, *transition);
6943 }
6944 6950
6945 if (descriptors->GetDetails(descriptor).type() != CALLBACKS) { 6951 DCHECK_EQ(CALLBACKS, descriptors->GetDetails(descriptor).type());
6946 return Map::Normalize(map, mode); 6952 DCHECK_EQ(attributes, descriptors->GetDetails(descriptor).attributes());
6947 }
6948
6949 // TODO(verwaest): Handle attributes better.
6950 if (descriptors->GetDetails(descriptor).attributes() != attributes) {
6951 return Map::Normalize(map, mode);
6952 }
6953 6953
6954 Handle<Object> maybe_pair(descriptors->GetValue(descriptor), isolate); 6954 Handle<Object> maybe_pair(descriptors->GetValue(descriptor), isolate);
6955 if (!maybe_pair->IsAccessorPair()) { 6955 if (!maybe_pair->IsAccessorPair()) {
6956 return Map::Normalize(map, mode); 6956 return Map::Normalize(map, mode);
6957 } 6957 }
6958 6958
6959 Handle<AccessorPair> pair = Handle<AccessorPair>::cast(maybe_pair); 6959 Handle<AccessorPair> pair = Handle<AccessorPair>::cast(maybe_pair);
6960 if (pair->get(component) != *accessor) { 6960 if (pair->get(component) != *accessor) {
6961 return Map::Normalize(map, mode); 6961 return Map::Normalize(map, mode);
6962 } 6962 }
6963 6963
6964 return transition; 6964 return transition;
6965 } 6965 }
6966 6966
6967 Handle<AccessorPair> pair; 6967 Handle<AccessorPair> pair;
6968 DescriptorArray* old_descriptors = map->instance_descriptors(); 6968 DescriptorArray* old_descriptors = map->instance_descriptors();
6969 int descriptor = old_descriptors->SearchWithCache(*name, *map); 6969 int descriptor = old_descriptors->SearchWithCache(*name, *map);
6970 if (descriptor != DescriptorArray::kNotFound) { 6970 if (descriptor != DescriptorArray::kNotFound) {
6971 if (descriptor != map->LastAdded()) {
6972 return Map::Normalize(map, mode);
6973 }
6971 PropertyDetails old_details = old_descriptors->GetDetails(descriptor); 6974 PropertyDetails old_details = old_descriptors->GetDetails(descriptor);
6972 if (old_details.type() != CALLBACKS) { 6975 if (old_details.type() != CALLBACKS) {
6973 return Map::Normalize(map, mode); 6976 return Map::Normalize(map, mode);
6974 } 6977 }
6975 6978
6976 if (old_details.attributes() != attributes) { 6979 if (old_details.attributes() != attributes) {
6977 return Map::Normalize(map, mode); 6980 return Map::Normalize(map, mode);
6978 } 6981 }
6979 6982
6980 Handle<Object> maybe_pair(old_descriptors->GetValue(descriptor), isolate); 6983 Handle<Object> maybe_pair(old_descriptors->GetValue(descriptor), isolate);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
7015 if (flag == INSERT_TRANSITION && 7018 if (flag == INSERT_TRANSITION &&
7016 map->owns_descriptors() && 7019 map->owns_descriptors() &&
7017 map->CanHaveMoreTransitions()) { 7020 map->CanHaveMoreTransitions()) {
7018 return ShareDescriptor(map, descriptors, descriptor); 7021 return ShareDescriptor(map, descriptors, descriptor);
7019 } 7022 }
7020 7023
7021 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( 7024 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo(
7022 descriptors, map->NumberOfOwnDescriptors(), 1); 7025 descriptors, map->NumberOfOwnDescriptors(), 1);
7023 new_descriptors->Append(descriptor); 7026 new_descriptors->Append(descriptor);
7024 7027
7025 return CopyReplaceDescriptors( 7028 return CopyReplaceDescriptors(map, new_descriptors, flag,
7026 map, new_descriptors, flag, descriptor->GetKey(), SIMPLE_TRANSITION); 7029 descriptor->GetKey(),
7030 SIMPLE_PROPERTY_TRANSITION);
7027 } 7031 }
7028 7032
7029 7033
7030 Handle<Map> Map::CopyInsertDescriptor(Handle<Map> map, 7034 Handle<Map> Map::CopyInsertDescriptor(Handle<Map> map,
7031 Descriptor* descriptor, 7035 Descriptor* descriptor,
7032 TransitionFlag flag) { 7036 TransitionFlag flag) {
7033 Handle<DescriptorArray> old_descriptors(map->instance_descriptors()); 7037 Handle<DescriptorArray> old_descriptors(map->instance_descriptors());
7034 7038
7035 // Ensure the key is unique. 7039 // Ensure the key is unique.
7036 descriptor->KeyToUniqueName(); 7040 descriptor->KeyToUniqueName();
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
7110 Handle<Name> key = descriptor->GetKey(); 7114 Handle<Name> key = descriptor->GetKey();
7111 DCHECK(*key == descriptors->GetKey(insertion_index)); 7115 DCHECK(*key == descriptors->GetKey(insertion_index));
7112 7116
7113 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( 7117 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo(
7114 descriptors, map->NumberOfOwnDescriptors()); 7118 descriptors, map->NumberOfOwnDescriptors());
7115 7119
7116 new_descriptors->Replace(insertion_index, descriptor); 7120 new_descriptors->Replace(insertion_index, descriptor);
7117 7121
7118 SimpleTransitionFlag simple_flag = 7122 SimpleTransitionFlag simple_flag =
7119 (insertion_index == descriptors->number_of_descriptors() - 1) 7123 (insertion_index == descriptors->number_of_descriptors() - 1)
7120 ? SIMPLE_TRANSITION 7124 ? SIMPLE_PROPERTY_TRANSITION
7121 : FULL_TRANSITION; 7125 : PROPERTY_TRANSITION;
7122 return CopyReplaceDescriptors(map, new_descriptors, flag, key, simple_flag); 7126 return CopyReplaceDescriptors(map, new_descriptors, flag, key, simple_flag);
7123 } 7127 }
7124 7128
7125 7129
7126 void Map::UpdateCodeCache(Handle<Map> map, 7130 void Map::UpdateCodeCache(Handle<Map> map,
7127 Handle<Name> name, 7131 Handle<Name> name,
7128 Handle<Code> code) { 7132 Handle<Code> code) {
7129 Isolate* isolate = map->GetIsolate(); 7133 Isolate* isolate = map->GetIsolate();
7130 HandleScope scope(isolate); 7134 HandleScope scope(isolate);
7131 // Allocate the code cache if not present. 7135 // Allocate the code cache if not present.
(...skipping 9433 matching lines...) Expand 10 before | Expand all | Expand 10 after
16565 Handle<DependentCode> codes = 16569 Handle<DependentCode> codes =
16566 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), 16570 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()),
16567 DependentCode::kPropertyCellChangedGroup, 16571 DependentCode::kPropertyCellChangedGroup,
16568 info->object_wrapper()); 16572 info->object_wrapper());
16569 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); 16573 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes);
16570 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( 16574 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add(
16571 cell, info->zone()); 16575 cell, info->zone());
16572 } 16576 }
16573 16577
16574 } } // namespace v8::internal 16578 } } // 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