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

Side by Side Diff: src/objects.cc

Issue 715313003: Avoid fast short-cut in Map::GeneralizeRepresentation() for literals with non-simple transitions. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
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 | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | test/mjsunit/regress/regress-3687.js » ('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 2336 matching lines...) Expand 10 before | Expand all | Expand 10 after
2347 if (back->IsUndefined()) break; 2347 if (back->IsUndefined()) break;
2348 Map* parent = Map::cast(back); 2348 Map* parent = Map::cast(back);
2349 if (parent->NumberOfOwnDescriptors() <= descriptor) break; 2349 if (parent->NumberOfOwnDescriptors() <= descriptor) break;
2350 result = parent; 2350 result = parent;
2351 } 2351 }
2352 return result; 2352 return result;
2353 } 2353 }
2354 2354
2355 2355
2356 void Map::UpdateFieldType(int descriptor, Handle<Name> name, 2356 void Map::UpdateFieldType(int descriptor, Handle<Name> name,
2357 Representation new_representation,
2357 Handle<HeapType> new_type) { 2358 Handle<HeapType> new_type) {
2358 DisallowHeapAllocation no_allocation; 2359 DisallowHeapAllocation no_allocation;
2359 PropertyDetails details = instance_descriptors()->GetDetails(descriptor); 2360 PropertyDetails details = instance_descriptors()->GetDetails(descriptor);
2360 if (details.type() != FIELD) return; 2361 if (details.type() != FIELD) return;
2361 if (HasTransitionArray()) { 2362 if (HasTransitionArray()) {
2362 TransitionArray* transitions = this->transitions(); 2363 TransitionArray* transitions = this->transitions();
2363 for (int i = 0; i < transitions->number_of_transitions(); ++i) { 2364 for (int i = 0; i < transitions->number_of_transitions(); ++i) {
2364 transitions->GetTarget(i)->UpdateFieldType(descriptor, name, new_type); 2365 transitions->GetTarget(i)
2366 ->UpdateFieldType(descriptor, name, new_representation, new_type);
2365 } 2367 }
2366 } 2368 }
2369 // It is allowed to change representation here only from None to something.
2370 DCHECK(details.representation().Equals(new_representation) ||
2371 details.representation().IsNone());
2372
2367 // Skip if already updated the shared descriptor. 2373 // Skip if already updated the shared descriptor.
2368 if (instance_descriptors()->GetFieldType(descriptor) == *new_type) return; 2374 if (instance_descriptors()->GetFieldType(descriptor) == *new_type) return;
2369 FieldDescriptor d(name, instance_descriptors()->GetFieldIndex(descriptor), 2375 FieldDescriptor d(name, instance_descriptors()->GetFieldIndex(descriptor),
2370 new_type, details.attributes(), details.representation()); 2376 new_type, details.attributes(), new_representation);
2371 instance_descriptors()->Replace(descriptor, &d); 2377 instance_descriptors()->Replace(descriptor, &d);
2372 } 2378 }
2373 2379
2374 2380
2375 // static 2381 // static
2376 Handle<HeapType> Map::GeneralizeFieldType(Handle<HeapType> type1, 2382 Handle<HeapType> Map::GeneralizeFieldType(Handle<HeapType> type1,
2377 Handle<HeapType> type2, 2383 Handle<HeapType> type2,
2378 Isolate* isolate) { 2384 Isolate* isolate) {
2379 static const int kMaxClassesPerFieldType = 5; 2385 static const int kMaxClassesPerFieldType = 5;
2380 if (type1->NowIs(type2)) return type2; 2386 if (type1->NowIs(type2)) return type2;
2381 if (type2->NowIs(type1)) return type1; 2387 if (type2->NowIs(type1)) return type1;
2382 if (type1->NowStable() && type2->NowStable()) { 2388 if (type1->NowStable() && type2->NowStable()) {
2383 Handle<HeapType> type = HeapType::Union(type1, type2, isolate); 2389 Handle<HeapType> type = HeapType::Union(type1, type2, isolate);
2384 if (type->NumClasses() <= kMaxClassesPerFieldType) { 2390 if (type->NumClasses() <= kMaxClassesPerFieldType) {
2385 DCHECK(type->NowStable()); 2391 DCHECK(type->NowStable());
2386 DCHECK(type1->NowIs(type)); 2392 DCHECK(type1->NowIs(type));
2387 DCHECK(type2->NowIs(type)); 2393 DCHECK(type2->NowIs(type));
2388 return type; 2394 return type;
2389 } 2395 }
2390 } 2396 }
2391 return HeapType::Any(isolate); 2397 return HeapType::Any(isolate);
2392 } 2398 }
2393 2399
2394 2400
2395 // static 2401 // static
2396 void Map::GeneralizeFieldType(Handle<Map> map, 2402 void Map::GeneralizeFieldType(Handle<Map> map, int modify_index,
2397 int modify_index, 2403 Representation new_representation,
2398 Handle<HeapType> new_field_type) { 2404 Handle<HeapType> new_field_type) {
2399 Isolate* isolate = map->GetIsolate(); 2405 Isolate* isolate = map->GetIsolate();
2400 2406
2401 // Check if we actually need to generalize the field type at all. 2407 // Check if we actually need to generalize the field type at all.
2402 Handle<HeapType> old_field_type( 2408 Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate);
2403 map->instance_descriptors()->GetFieldType(modify_index), isolate); 2409 Representation old_representation =
2404 if (new_field_type->NowIs(old_field_type)) { 2410 old_descriptors->GetDetails(modify_index).representation();
2411 Handle<HeapType> old_field_type(old_descriptors->GetFieldType(modify_index),
2412 isolate);
2413
2414 if (old_representation.Equals(new_representation) &&
2415 new_field_type->NowIs(old_field_type)) {
2405 DCHECK(Map::GeneralizeFieldType(old_field_type, 2416 DCHECK(Map::GeneralizeFieldType(old_field_type,
2406 new_field_type, 2417 new_field_type,
2407 isolate)->NowIs(old_field_type)); 2418 isolate)->NowIs(old_field_type));
2408 return; 2419 return;
2409 } 2420 }
2410 2421
2411 // Determine the field owner. 2422 // Determine the field owner.
2412 Handle<Map> field_owner(map->FindFieldOwner(modify_index), isolate); 2423 Handle<Map> field_owner(map->FindFieldOwner(modify_index), isolate);
2413 Handle<DescriptorArray> descriptors( 2424 Handle<DescriptorArray> descriptors(
2414 field_owner->instance_descriptors(), isolate); 2425 field_owner->instance_descriptors(), isolate);
2415 DCHECK_EQ(*old_field_type, descriptors->GetFieldType(modify_index)); 2426 DCHECK_EQ(*old_field_type, descriptors->GetFieldType(modify_index));
2416 2427
2417 // Determine the generalized new field type. 2428 // Determine the generalized new field type.
2418 new_field_type = Map::GeneralizeFieldType( 2429 new_field_type = Map::GeneralizeFieldType(
2419 old_field_type, new_field_type, isolate); 2430 old_field_type, new_field_type, isolate);
2420 2431
2421 PropertyDetails details = descriptors->GetDetails(modify_index); 2432 PropertyDetails details = descriptors->GetDetails(modify_index);
2422 Handle<Name> name(descriptors->GetKey(modify_index)); 2433 Handle<Name> name(descriptors->GetKey(modify_index));
2423 field_owner->UpdateFieldType(modify_index, name, new_field_type); 2434 field_owner->UpdateFieldType(modify_index, name, new_representation,
2435 new_field_type);
2424 field_owner->dependent_code()->DeoptimizeDependentCodeGroup( 2436 field_owner->dependent_code()->DeoptimizeDependentCodeGroup(
2425 isolate, DependentCode::kFieldTypeGroup); 2437 isolate, DependentCode::kFieldTypeGroup);
2426 2438
2427 if (FLAG_trace_generalization) { 2439 if (FLAG_trace_generalization) {
2428 map->PrintGeneralization( 2440 map->PrintGeneralization(
2429 stdout, "field type generalization", 2441 stdout, "field type generalization",
2430 modify_index, map->NumberOfOwnDescriptors(), 2442 modify_index, map->NumberOfOwnDescriptors(),
2431 map->NumberOfOwnDescriptors(), false, 2443 map->NumberOfOwnDescriptors(), false,
2432 details.representation(), details.representation(), 2444 details.representation(), details.representation(),
2433 *old_field_type, *new_field_type); 2445 *old_field_type, *new_field_type);
(...skipping 30 matching lines...) Expand all
2464 Handle<DescriptorArray> old_descriptors( 2476 Handle<DescriptorArray> old_descriptors(
2465 old_map->instance_descriptors(), isolate); 2477 old_map->instance_descriptors(), isolate);
2466 int old_nof = old_map->NumberOfOwnDescriptors(); 2478 int old_nof = old_map->NumberOfOwnDescriptors();
2467 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); 2479 PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
2468 Representation old_representation = old_details.representation(); 2480 Representation old_representation = old_details.representation();
2469 2481
2470 // It's fine to transition from None to anything but double without any 2482 // It's fine to transition from None to anything but double without any
2471 // modification to the object, because the default uninitialized value for 2483 // modification to the object, because the default uninitialized value for
2472 // representation None can be overwritten by both smi and tagged values. 2484 // representation None can be overwritten by both smi and tagged values.
2473 // Doubles, however, would require a box allocation. 2485 // Doubles, however, would require a box allocation.
2474 if (old_representation.IsNone() && 2486 if (old_representation.IsNone() && !new_representation.IsNone() &&
2475 !new_representation.IsNone() &&
2476 !new_representation.IsDouble()) { 2487 !new_representation.IsDouble()) {
2477 DCHECK(old_details.type() == FIELD); 2488 DCHECK(old_details.type() == FIELD);
2478 DCHECK(old_descriptors->GetFieldType(modify_index)->NowIs(
2479 HeapType::None()));
2480 if (FLAG_trace_generalization) { 2489 if (FLAG_trace_generalization) {
2481 old_map->PrintGeneralization( 2490 old_map->PrintGeneralization(
2482 stdout, "uninitialized field", 2491 stdout, "uninitialized field",
2483 modify_index, old_map->NumberOfOwnDescriptors(), 2492 modify_index, old_map->NumberOfOwnDescriptors(),
2484 old_map->NumberOfOwnDescriptors(), false, 2493 old_map->NumberOfOwnDescriptors(), false,
2485 old_representation, new_representation, 2494 old_representation, new_representation,
2486 old_descriptors->GetFieldType(modify_index), *new_field_type); 2495 old_descriptors->GetFieldType(modify_index), *new_field_type);
2487 } 2496 }
2488 old_descriptors->SetRepresentation(modify_index, new_representation); 2497 Handle<Map> field_owner(old_map->FindFieldOwner(modify_index), isolate);
2489 old_descriptors->SetValue(modify_index, *new_field_type); 2498
2499 GeneralizeFieldType(field_owner, modify_index, new_representation,
2500 new_field_type);
2501 DCHECK(old_descriptors->GetDetails(modify_index).representation().Equals(
2502 new_representation));
2503 DCHECK(old_descriptors->GetFieldType(modify_index)->NowIs(new_field_type));
2490 return old_map; 2504 return old_map;
2491 } 2505 }
2492 2506
2493 // Check the state of the root map. 2507 // Check the state of the root map.
2494 Handle<Map> root_map(old_map->FindRootMap(), isolate); 2508 Handle<Map> root_map(old_map->FindRootMap(), isolate);
2495 if (!old_map->EquivalentToForTransition(*root_map)) { 2509 if (!old_map->EquivalentToForTransition(*root_map)) {
2496 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, 2510 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
2497 "GenAll_NotEquivalent"); 2511 "GenAll_NotEquivalent");
2498 } 2512 }
2499 int root_nof = root_map->NumberOfOwnDescriptors(); 2513 int root_nof = root_map->NumberOfOwnDescriptors();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2540 if (tmp_type == FIELD) { 2554 if (tmp_type == FIELD) {
2541 // Generalize the field type as necessary. 2555 // Generalize the field type as necessary.
2542 Handle<HeapType> old_field_type = (old_type == FIELD) 2556 Handle<HeapType> old_field_type = (old_type == FIELD)
2543 ? handle(old_descriptors->GetFieldType(i), isolate) 2557 ? handle(old_descriptors->GetFieldType(i), isolate)
2544 : old_descriptors->GetValue(i)->OptimalType( 2558 : old_descriptors->GetValue(i)->OptimalType(
2545 isolate, tmp_representation); 2559 isolate, tmp_representation);
2546 if (modify_index == i) { 2560 if (modify_index == i) {
2547 old_field_type = GeneralizeFieldType( 2561 old_field_type = GeneralizeFieldType(
2548 new_field_type, old_field_type, isolate); 2562 new_field_type, old_field_type, isolate);
2549 } 2563 }
2550 GeneralizeFieldType(tmp_map, i, old_field_type); 2564 GeneralizeFieldType(tmp_map, i, tmp_representation, old_field_type);
2551 } else if (tmp_type == CONSTANT) { 2565 } else if (tmp_type == CONSTANT) {
2552 if (old_type != CONSTANT || 2566 if (old_type != CONSTANT ||
2553 old_descriptors->GetConstant(i) != tmp_descriptors->GetConstant(i)) { 2567 old_descriptors->GetConstant(i) != tmp_descriptors->GetConstant(i)) {
2554 break; 2568 break;
2555 } 2569 }
2556 } else { 2570 } else {
2557 DCHECK_EQ(tmp_type, old_type); 2571 DCHECK_EQ(tmp_type, old_type);
2558 DCHECK_EQ(tmp_descriptors->GetValue(i), old_descriptors->GetValue(i)); 2572 DCHECK_EQ(tmp_descriptors->GetValue(i), old_descriptors->GetValue(i));
2559 } 2573 }
2560 target_map = tmp_map; 2574 target_map = tmp_map;
(...skipping 14211 matching lines...) Expand 10 before | Expand all | Expand 10 after
16772 Handle<DependentCode> codes = 16786 Handle<DependentCode> codes =
16773 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), 16787 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()),
16774 DependentCode::kPropertyCellChangedGroup, 16788 DependentCode::kPropertyCellChangedGroup,
16775 info->object_wrapper()); 16789 info->object_wrapper());
16776 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); 16790 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes);
16777 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( 16791 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add(
16778 cell, info->zone()); 16792 cell, info->zone());
16779 } 16793 }
16780 16794
16781 } } // namespace v8::internal 16795 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | test/mjsunit/regress/regress-3687.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698