OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <sstream> | 5 #include <sstream> |
6 | 6 |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
10 #include "src/allocation-site-scopes.h" | 10 #include "src/allocation-site-scopes.h" |
(...skipping 2336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |