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

Side by Side Diff: src/objects.cc

Issue 259993004: Fix and cleanup Map::GeneralizeRepresentation(). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix representation check on target map. Created 6 years, 7 months 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/property.h » ('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 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 2407 matching lines...) Expand 10 before | Expand all | Expand 10 after
2418 Map* Map::FindRootMap() { 2418 Map* Map::FindRootMap() {
2419 Map* result = this; 2419 Map* result = this;
2420 while (true) { 2420 while (true) {
2421 Object* back = result->GetBackPointer(); 2421 Object* back = result->GetBackPointer();
2422 if (back->IsUndefined()) return result; 2422 if (back->IsUndefined()) return result;
2423 result = Map::cast(back); 2423 result = Map::cast(back);
2424 } 2424 }
2425 } 2425 }
2426 2426
2427 2427
2428 // Returns NULL if the updated map is incompatible.
2429 Map* Map::FindUpdatedMap(int verbatim,
2430 int length,
2431 DescriptorArray* descriptors) {
2432 DisallowHeapAllocation no_allocation;
2433
2434 // This can only be called on roots of transition trees.
2435 ASSERT(GetBackPointer()->IsUndefined());
2436
2437 Map* current = this;
2438
2439 for (int i = verbatim; i < length; i++) {
2440 if (!current->HasTransitionArray()) break;
2441 Name* name = descriptors->GetKey(i);
2442 TransitionArray* transitions = current->transitions();
2443 int transition = transitions->Search(name);
2444 if (transition == TransitionArray::kNotFound) break;
2445 current = transitions->GetTarget(transition);
2446 PropertyDetails details = descriptors->GetDetails(i);
2447 PropertyDetails target_details =
2448 current->instance_descriptors()->GetDetails(i);
2449 if (details.attributes() != target_details.attributes()) return NULL;
2450 if (details.type() == CALLBACKS) {
2451 if (target_details.type() != CALLBACKS) return NULL;
2452 if (descriptors->GetValue(i) !=
2453 current->instance_descriptors()->GetValue(i)) {
2454 return NULL;
2455 }
2456 } else if (target_details.type() == CALLBACKS) {
2457 return NULL;
2458 }
2459 }
2460
2461 return current;
2462 }
2463
2464
2465 Map* Map::FindLastMatchMap(int verbatim, 2428 Map* Map::FindLastMatchMap(int verbatim,
2466 int length, 2429 int length,
2467 DescriptorArray* descriptors) { 2430 DescriptorArray* descriptors) {
2468 DisallowHeapAllocation no_allocation; 2431 DisallowHeapAllocation no_allocation;
2469 2432
2470 // This can only be called on roots of transition trees. 2433 // This can only be called on roots of transition trees.
2471 ASSERT(GetBackPointer()->IsUndefined()); 2434 ASSERT(GetBackPointer()->IsUndefined());
2472 2435
2473 Map* current = this; 2436 Map* current = this;
2474 2437
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2545 } 2508 }
2546 return HeapType::Any(isolate); 2509 return HeapType::Any(isolate);
2547 } 2510 }
2548 2511
2549 2512
2550 // static 2513 // static
2551 void Map::GeneralizeFieldType(Handle<Map> map, 2514 void Map::GeneralizeFieldType(Handle<Map> map,
2552 int modify_index, 2515 int modify_index,
2553 Handle<HeapType> new_field_type) { 2516 Handle<HeapType> new_field_type) {
2554 Isolate* isolate = map->GetIsolate(); 2517 Isolate* isolate = map->GetIsolate();
2555 Handle<Map> field_owner(map->FindFieldOwner(modify_index), isolate);
2556 Handle<DescriptorArray> descriptors(
2557 field_owner->instance_descriptors(), isolate);
2558 2518
2559 // Check if we actually need to generalize the field type at all. 2519 // Check if we actually need to generalize the field type at all.
2560 Handle<HeapType> old_field_type( 2520 Handle<HeapType> old_field_type(
2561 descriptors->GetFieldType(modify_index), isolate); 2521 map->instance_descriptors()->GetFieldType(modify_index), isolate);
2562 if (new_field_type->NowIs(old_field_type)) { 2522 if (new_field_type->NowIs(old_field_type)) {
2563 ASSERT(Map::GeneralizeFieldType(old_field_type, 2523 ASSERT(Map::GeneralizeFieldType(old_field_type,
2564 new_field_type, 2524 new_field_type,
2565 isolate)->NowIs(old_field_type)); 2525 isolate)->NowIs(old_field_type));
2566 return; 2526 return;
2567 } 2527 }
2568 2528
2529 // Determine the field owner.
2530 Handle<Map> field_owner(map->FindFieldOwner(modify_index), isolate);
2531 Handle<DescriptorArray> descriptors(
2532 field_owner->instance_descriptors(), isolate);
2533 ASSERT_EQ(*old_field_type, descriptors->GetFieldType(modify_index));
2534
2569 // Determine the generalized new field type. 2535 // Determine the generalized new field type.
2570 new_field_type = Map::GeneralizeFieldType( 2536 new_field_type = Map::GeneralizeFieldType(
2571 old_field_type, new_field_type, isolate); 2537 old_field_type, new_field_type, isolate);
2572 2538
2573 PropertyDetails details = descriptors->GetDetails(modify_index); 2539 PropertyDetails details = descriptors->GetDetails(modify_index);
2574 FieldDescriptor d(handle(descriptors->GetKey(modify_index), isolate), 2540 FieldDescriptor d(handle(descriptors->GetKey(modify_index), isolate),
2575 descriptors->GetFieldIndex(modify_index), 2541 descriptors->GetFieldIndex(modify_index),
2576 new_field_type, 2542 new_field_type,
2577 details.attributes(), 2543 details.attributes(),
2578 details.representation()); 2544 details.representation());
(...skipping 12 matching lines...) Expand all
2591 } 2557 }
2592 2558
2593 2559
2594 // Generalize the representation of the descriptor at |modify_index|. 2560 // Generalize the representation of the descriptor at |modify_index|.
2595 // This method rewrites the transition tree to reflect the new change. To avoid 2561 // This method rewrites the transition tree to reflect the new change. To avoid
2596 // high degrees over polymorphism, and to stabilize quickly, on every rewrite 2562 // high degrees over polymorphism, and to stabilize quickly, on every rewrite
2597 // the new type is deduced by merging the current type with any potential new 2563 // the new type is deduced by merging the current type with any potential new
2598 // (partial) version of the type in the transition tree. 2564 // (partial) version of the type in the transition tree.
2599 // To do this, on each rewrite: 2565 // To do this, on each rewrite:
2600 // - Search the root of the transition tree using FindRootMap. 2566 // - Search the root of the transition tree using FindRootMap.
2601 // - Find |updated|, the newest matching version of this map using 2567 // - Find |target_map|, the newest matching version of this map using the keys
2602 // FindUpdatedMap. This uses the keys in the own map's descriptor array to 2568 // in the |old_map|'s descriptor array to walk the transition tree.
2603 // walk the transition tree. 2569 // - Merge/generalize the descriptor array of the |old_map| and |target_map|.
2604 // - Merge/generalize the descriptor array of the current map and |updated|. 2570 // - Generalize the |modify_index| descriptor using |new_representation| and
2605 // - Generalize the |modify_index| descriptor using |new_representation|. 2571 // |new_field_type|.
2606 // - Walk the tree again starting from the root towards |updated|. Stop at 2572 // - Walk the tree again starting from the root towards |target_map|. Stop at
2607 // |split_map|, the first map who's descriptor array does not match the merged 2573 // |split_map|, the first map who's descriptor array does not match the merged
2608 // descriptor array. 2574 // descriptor array.
2609 // - If |updated| == |split_map|, |updated| is in the expected state. Return it. 2575 // - If |target_map| == |split_map|, |target_map| is in the expected state.
2610 // - Otherwise, invalidate the outdated transition target from |updated|, and 2576 // Return it.
2577 // - Otherwise, invalidate the outdated transition target from |target_map|, and
2611 // replace its transition tree with a new branch for the updated descriptors. 2578 // replace its transition tree with a new branch for the updated descriptors.
2612 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map, 2579 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
2613 int modify_index, 2580 int modify_index,
2614 Representation new_representation, 2581 Representation new_representation,
2615 Handle<HeapType> new_field_type, 2582 Handle<HeapType> new_field_type,
2616 StoreMode store_mode) { 2583 StoreMode store_mode) {
2617 Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors()); 2584 Isolate* isolate = old_map->GetIsolate();
2585
2586 Handle<DescriptorArray> old_descriptors(
2587 old_map->instance_descriptors(), isolate);
2588 int old_nof = old_map->NumberOfOwnDescriptors();
2618 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); 2589 PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
2619 Representation old_representation = old_details.representation(); 2590 Representation old_representation = old_details.representation();
2620 2591
2621 // It's fine to transition from None to anything but double without any 2592 // It's fine to transition from None to anything but double without any
2622 // modification to the object, because the default uninitialized value for 2593 // modification to the object, because the default uninitialized value for
2623 // representation None can be overwritten by both smi and tagged values. 2594 // representation None can be overwritten by both smi and tagged values.
2624 // Doubles, however, would require a box allocation. 2595 // Doubles, however, would require a box allocation.
2625 if (old_representation.IsNone() && 2596 if (old_representation.IsNone() &&
2626 !new_representation.IsNone() && 2597 !new_representation.IsNone() &&
2627 !new_representation.IsDouble()) { 2598 !new_representation.IsDouble()) {
2628 ASSERT(old_details.type() == FIELD); 2599 ASSERT(old_details.type() == FIELD);
2629 ASSERT(old_descriptors->GetFieldType(modify_index)->NowIs( 2600 ASSERT(old_descriptors->GetFieldType(modify_index)->NowIs(
2630 HeapType::None())); 2601 HeapType::None()));
2631 if (FLAG_trace_generalization) { 2602 if (FLAG_trace_generalization) {
2632 old_map->PrintGeneralization( 2603 old_map->PrintGeneralization(
2633 stdout, "uninitialized field", 2604 stdout, "uninitialized field",
2634 modify_index, old_map->NumberOfOwnDescriptors(), 2605 modify_index, old_map->NumberOfOwnDescriptors(),
2635 old_map->NumberOfOwnDescriptors(), false, 2606 old_map->NumberOfOwnDescriptors(), false,
2636 old_representation, new_representation, 2607 old_representation, new_representation,
2637 old_descriptors->GetFieldType(modify_index), *new_field_type); 2608 old_descriptors->GetFieldType(modify_index), *new_field_type);
2638 } 2609 }
2639 old_descriptors->SetRepresentation(modify_index, new_representation); 2610 old_descriptors->SetRepresentation(modify_index, new_representation);
2640 old_descriptors->SetValue(modify_index, *new_field_type); 2611 old_descriptors->SetValue(modify_index, *new_field_type);
2641 return old_map; 2612 return old_map;
2642 } 2613 }
2643 2614
2644 if (new_representation.Equals(old_representation) &&
2645 old_details.type() == FIELD) {
2646 Map::GeneralizeFieldType(old_map, modify_index, new_field_type);
2647 return old_map;
2648 }
2649
2650 Handle<Map> root_map(old_map->FindRootMap());
2651
2652 // Check the state of the root map. 2615 // Check the state of the root map.
2616 Handle<Map> root_map(old_map->FindRootMap(), isolate);
2653 if (!old_map->EquivalentToForTransition(*root_map)) { 2617 if (!old_map->EquivalentToForTransition(*root_map)) {
2654 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, 2618 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
2655 old_details.attributes(), "not equivalent"); 2619 old_details.attributes(), "not equivalent");
2656 } 2620 }
2657 2621 int root_nof = root_map->NumberOfOwnDescriptors();
2658 int verbatim = root_map->NumberOfOwnDescriptors(); 2622 if (modify_index < root_nof) {
2659 2623 PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
2660 if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) { 2624 if ((old_details.type() != FIELD && store_mode == FORCE_FIELD) ||
2661 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, 2625 (old_details.type() == FIELD &&
2662 old_details.attributes(), "root modification"); 2626 (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) ||
2663 } 2627 !new_representation.fits_into(old_details.representation())))) {
2664 2628 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
2665 int descriptors = old_map->NumberOfOwnDescriptors(); 2629 old_details.attributes(), "root modification");
2666 Map* raw_updated = root_map->FindUpdatedMap( 2630 }
2667 verbatim, descriptors, *old_descriptors); 2631 }
2668 if (raw_updated == NULL) { 2632
2669 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, 2633 Handle<Map> target_map = root_map;
2670 old_details.attributes(), "incompatible"); 2634 for (int i = root_nof; i < old_nof; ++i) {
2671 } 2635 int j = target_map->SearchTransition(old_descriptors->GetKey(i));
2672 2636 if (j == TransitionArray::kNotFound) break;
2673 Handle<Map> updated(raw_updated); 2637 Handle<Map> tmp_map(target_map->GetTransition(j), isolate);
2674 Handle<DescriptorArray> updated_descriptors(updated->instance_descriptors()); 2638 Handle<DescriptorArray> tmp_descriptors = handle(
2675 2639 tmp_map->instance_descriptors(), isolate);
2676 int valid = updated->NumberOfOwnDescriptors(); 2640
2677 2641 // Check if target map is incompatible.
2678 // Directly change the map if the target map is more general. Ensure that the 2642 PropertyDetails old_details = old_descriptors->GetDetails(i);
2679 // target type of the modify_index is a FIELD, unless we are migrating. 2643 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i);
2680 if (updated_descriptors->IsMoreGeneralThan( 2644 PropertyType old_type = old_details.type();
2681 verbatim, valid, descriptors, *old_descriptors) && 2645 PropertyType tmp_type = tmp_details.type();
2682 (store_mode == ALLOW_AS_CONSTANT || 2646 if (tmp_details.attributes() != old_details.attributes() ||
2683 updated_descriptors->GetDetails(modify_index).type() == FIELD)) { 2647 ((tmp_type == CALLBACKS || old_type == CALLBACKS) &&
2684 Representation updated_representation = 2648 (tmp_type != old_type ||
2685 updated_descriptors->GetDetails(modify_index).representation(); 2649 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i)))) {
2686 if (new_representation.fits_into(updated_representation)) return updated; 2650 return CopyGeneralizeAllRepresentations(
2687 } 2651 old_map, modify_index, store_mode,
2688 2652 old_details.attributes(), "incompatible");
2689 Handle<DescriptorArray> new_descriptors = DescriptorArray::Merge( 2653 }
2690 updated, verbatim, valid, descriptors, modify_index, 2654 Representation old_representation = old_details.representation();
2691 store_mode, old_map); 2655 Representation tmp_representation = tmp_details.representation();
2692 ASSERT(store_mode == ALLOW_AS_CONSTANT || 2656 if (!old_representation.fits_into(tmp_representation) ||
2657 (!new_representation.fits_into(tmp_representation) &&
2658 modify_index == i)) {
2659 break;
2660 }
2661 if (tmp_type == FIELD) {
2662 // Generalize the field type as necessary.
2663 Handle<HeapType> old_field_type = (old_type == FIELD)
2664 ? handle(old_descriptors->GetFieldType(i), isolate)
2665 : old_descriptors->GetValue(i)->OptimalType(
2666 isolate, tmp_representation);
2667 if (modify_index == i) {
2668 old_field_type = GeneralizeFieldType(
2669 new_field_type, old_field_type, isolate);
2670 }
2671 GeneralizeFieldType(tmp_map, i, old_field_type);
2672 } else if (tmp_type == CONSTANT) {
2673 if (old_type != CONSTANT ||
2674 old_descriptors->GetConstant(i) != tmp_descriptors->GetConstant(i)) {
2675 break;
2676 }
2677 } else {
2678 ASSERT_EQ(tmp_type, old_type);
2679 ASSERT_EQ(tmp_descriptors->GetValue(i), old_descriptors->GetValue(i));
2680 }
2681 target_map = tmp_map;
2682 }
2683
2684 // Directly change the map if the target map is more general.
2685 Handle<DescriptorArray> target_descriptors(
2686 target_map->instance_descriptors(), isolate);
2687 int target_nof = target_map->NumberOfOwnDescriptors();
2688 if (target_nof == old_nof &&
2689 (store_mode != FORCE_FIELD ||
2690 target_descriptors->GetDetails(modify_index).type() == FIELD)) {
2691 ASSERT(modify_index < target_nof);
2692 ASSERT(new_representation.fits_into(
2693 target_descriptors->GetDetails(modify_index).representation()));
2694 ASSERT(target_descriptors->GetDetails(modify_index).type() != FIELD ||
2695 new_field_type->NowIs(
2696 target_descriptors->GetFieldType(modify_index)));
2697 return target_map;
2698 }
2699
2700 // Find the last compatible target map in the transition tree.
2701 for (int i = target_nof; i < old_nof; ++i) {
2702 int j = target_map->SearchTransition(old_descriptors->GetKey(i));
2703 if (j == TransitionArray::kNotFound) break;
2704 Handle<Map> tmp_map(target_map->GetTransition(j), isolate);
2705 Handle<DescriptorArray> tmp_descriptors(
2706 tmp_map->instance_descriptors(), isolate);
2707
2708 // Check if target map is compatible.
2709 PropertyDetails old_details = old_descriptors->GetDetails(i);
2710 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i);
2711 if (tmp_details.attributes() != old_details.attributes() ||
2712 ((tmp_details.type() == CALLBACKS || old_details.type() == CALLBACKS) &&
2713 (tmp_details.type() != old_details.type() ||
2714 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i)))) {
2715 return CopyGeneralizeAllRepresentations(
2716 old_map, modify_index, store_mode,
2717 old_details.attributes(), "incompatible");
2718 }
2719 target_map = tmp_map;
2720 }
2721 target_nof = target_map->NumberOfOwnDescriptors();
2722 target_descriptors = handle(target_map->instance_descriptors(), isolate);
2723
2724 // Allocate a new descriptor array large enough to hold the required
2725 // descriptors, with minimally the exact same size as the old descriptor
2726 // array.
2727 int new_slack = Max(
2728 old_nof, old_descriptors->number_of_descriptors()) - old_nof;
2729 Handle<DescriptorArray> new_descriptors = DescriptorArray::Allocate(
2730 isolate, old_nof, new_slack);
2731 ASSERT(new_descriptors->length() > target_descriptors->length() ||
2732 new_descriptors->NumberOfSlackDescriptors() > 0 ||
2733 new_descriptors->number_of_descriptors() ==
2734 old_descriptors->number_of_descriptors());
2735 ASSERT(new_descriptors->number_of_descriptors() == old_nof);
2736
2737 // 0 -> |root_nof|
2738 int current_offset = 0;
2739 for (int i = 0; i < root_nof; ++i) {
2740 PropertyDetails old_details = old_descriptors->GetDetails(i);
2741 if (old_details.type() == FIELD) current_offset++;
2742 Descriptor d(handle(old_descriptors->GetKey(i), isolate),
2743 handle(old_descriptors->GetValue(i), isolate),
2744 old_details);
2745 new_descriptors->Set(i, &d);
2746 }
2747
2748 // |root_nof| -> |target_nof|
2749 for (int i = root_nof; i < target_nof; ++i) {
2750 Handle<Name> target_key(target_descriptors->GetKey(i), isolate);
2751 PropertyDetails old_details = old_descriptors->GetDetails(i);
2752 PropertyDetails target_details = target_descriptors->GetDetails(i);
2753 target_details = target_details.CopyWithRepresentation(
2754 old_details.representation().generalize(
2755 target_details.representation()));
2756 if (modify_index == i) {
2757 target_details = target_details.CopyWithRepresentation(
2758 new_representation.generalize(target_details.representation()));
2759 }
2760 if (old_details.type() == FIELD ||
2761 target_details.type() == FIELD ||
2762 (modify_index == i && store_mode == FORCE_FIELD) ||
2763 (target_descriptors->GetValue(i) != old_descriptors->GetValue(i))) {
2764 Handle<HeapType> old_field_type = (old_details.type() == FIELD)
2765 ? handle(old_descriptors->GetFieldType(i), isolate)
2766 : old_descriptors->GetValue(i)->OptimalType(
2767 isolate, target_details.representation());
2768 Handle<HeapType> target_field_type = (target_details.type() == FIELD)
2769 ? handle(target_descriptors->GetFieldType(i), isolate)
2770 : target_descriptors->GetValue(i)->OptimalType(
2771 isolate, target_details.representation());
2772 target_field_type = GeneralizeFieldType(
2773 target_field_type, old_field_type, isolate);
2774 if (modify_index == i) {
2775 target_field_type = GeneralizeFieldType(
2776 target_field_type, new_field_type, isolate);
2777 }
2778 FieldDescriptor d(target_key,
2779 current_offset++,
2780 target_field_type,
2781 target_details.attributes(),
2782 target_details.representation());
2783 new_descriptors->Set(i, &d);
2784 } else {
2785 ASSERT_NE(FIELD, target_details.type());
2786 Descriptor d(target_key,
2787 handle(target_descriptors->GetValue(i), isolate),
2788 target_details);
2789 new_descriptors->Set(i, &d);
2790 }
2791 }
2792
2793 // |target_nof| -> |old_nof|
2794 for (int i = target_nof; i < old_nof; ++i) {
2795 PropertyDetails old_details = old_descriptors->GetDetails(i);
2796 Handle<Name> old_key(old_descriptors->GetKey(i), isolate);
2797 if (modify_index == i) {
2798 old_details = old_details.CopyWithRepresentation(
2799 new_representation.generalize(old_details.representation()));
2800 }
2801 if (old_details.type() == FIELD) {
2802 Handle<HeapType> old_field_type(
2803 old_descriptors->GetFieldType(i), isolate);
2804 if (modify_index == i) {
2805 old_field_type = GeneralizeFieldType(
2806 old_field_type, new_field_type, isolate);
2807 }
2808 FieldDescriptor d(old_key,
2809 current_offset++,
2810 old_field_type,
2811 old_details.attributes(),
2812 old_details.representation());
2813 new_descriptors->Set(i, &d);
2814 } else {
2815 ASSERT(old_details.type() == CONSTANT || old_details.type() == CALLBACKS);
2816 if (modify_index == i && store_mode == FORCE_FIELD) {
2817 FieldDescriptor d(old_key,
2818 current_offset++,
2819 GeneralizeFieldType(
2820 old_descriptors->GetValue(i)->OptimalType(
2821 isolate, old_details.representation()),
2822 new_field_type, isolate),
2823 old_details.attributes(),
2824 old_details.representation());
2825 new_descriptors->Set(i, &d);
2826 } else {
2827 ASSERT_NE(FIELD, old_details.type());
2828 Descriptor d(old_key,
2829 handle(old_descriptors->GetValue(i), isolate),
2830 old_details);
2831 new_descriptors->Set(i, &d);
2832 }
2833 }
2834 }
2835
2836 new_descriptors->Sort();
2837
2838 ASSERT(store_mode != FORCE_FIELD ||
2693 new_descriptors->GetDetails(modify_index).type() == FIELD); 2839 new_descriptors->GetDetails(modify_index).type() == FIELD);
2694 2840
2695 Isolate* isolate = new_descriptors->GetIsolate();
2696 old_representation =
2697 new_descriptors->GetDetails(modify_index).representation();
2698 Representation updated_representation =
2699 new_representation.generalize(old_representation);
2700 if (!updated_representation.Equals(old_representation)) {
2701 new_descriptors->SetRepresentation(modify_index, updated_representation);
2702 }
2703 if (new_descriptors->GetDetails(modify_index).type() == FIELD) {
2704 Handle<HeapType> field_type(
2705 new_descriptors->GetFieldType(modify_index), isolate);
2706 new_field_type = Map::GeneralizeFieldType(
2707 field_type, new_field_type, isolate);
2708 new_descriptors->SetValue(modify_index, *new_field_type);
2709 }
2710
2711 Handle<Map> split_map(root_map->FindLastMatchMap( 2841 Handle<Map> split_map(root_map->FindLastMatchMap(
2712 verbatim, descriptors, *new_descriptors)); 2842 root_nof, old_nof, *new_descriptors), isolate);
2713 2843 int split_nof = split_map->NumberOfOwnDescriptors();
2714 int split_descriptors = split_map->NumberOfOwnDescriptors(); 2844 ASSERT_NE(old_nof, split_nof);
2715 // This is shadowed by |updated_descriptors| being more general than 2845
2716 // |old_descriptors|.
2717 ASSERT(descriptors != split_descriptors);
2718
2719 int descriptor = split_descriptors;
2720 split_map->DeprecateTarget( 2846 split_map->DeprecateTarget(
2721 old_descriptors->GetKey(descriptor), *new_descriptors); 2847 old_descriptors->GetKey(split_nof), *new_descriptors);
2722 2848
2723 if (FLAG_trace_generalization) { 2849 if (FLAG_trace_generalization) {
2724 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); 2850 PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
2725 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); 2851 PropertyDetails new_details = new_descriptors->GetDetails(modify_index);
2726 Handle<HeapType> old_field_type = (old_details.type() == FIELD) 2852 Handle<HeapType> old_field_type = (old_details.type() == FIELD)
2727 ? handle(old_descriptors->GetFieldType(modify_index), isolate) 2853 ? handle(old_descriptors->GetFieldType(modify_index), isolate)
2728 : HeapType::Constant(handle(old_descriptors->GetValue(modify_index), 2854 : HeapType::Constant(handle(old_descriptors->GetValue(modify_index),
2729 isolate), isolate); 2855 isolate), isolate);
2730 Handle<HeapType> new_field_type = (new_details.type() == FIELD) 2856 Handle<HeapType> new_field_type = (new_details.type() == FIELD)
2731 ? handle(new_descriptors->GetFieldType(modify_index), isolate) 2857 ? handle(new_descriptors->GetFieldType(modify_index), isolate)
2732 : HeapType::Constant(handle(new_descriptors->GetValue(modify_index), 2858 : HeapType::Constant(handle(new_descriptors->GetValue(modify_index),
2733 isolate), isolate); 2859 isolate), isolate);
2734 old_map->PrintGeneralization( 2860 old_map->PrintGeneralization(
2735 stdout, "", modify_index, descriptor, descriptors, 2861 stdout, "", modify_index, split_nof, old_nof,
2736 old_details.type() == CONSTANT && store_mode == FORCE_FIELD, 2862 old_details.type() == CONSTANT && store_mode == FORCE_FIELD,
2737 old_details.representation(), new_details.representation(), 2863 old_details.representation(), new_details.representation(),
2738 *old_field_type, *new_field_type); 2864 *old_field_type, *new_field_type);
2739 } 2865 }
2740 2866
2741 // Add missing transitions. 2867 // Add missing transitions.
2742 Handle<Map> new_map = split_map; 2868 Handle<Map> new_map = split_map;
2743 for (; descriptor < descriptors; descriptor++) { 2869 for (int i = split_nof; i < old_nof; ++i) {
2744 new_map = CopyInstallDescriptors(new_map, descriptor, new_descriptors); 2870 new_map = CopyInstallDescriptors(new_map, i, new_descriptors);
2745 } 2871 }
2746
2747 new_map->set_owns_descriptors(true); 2872 new_map->set_owns_descriptors(true);
2748 return new_map; 2873 return new_map;
2749 } 2874 }
2750 2875
2751 2876
2752 // Generalize the representation of all FIELD descriptors. 2877 // Generalize the representation of all FIELD descriptors.
2753 Handle<Map> Map::GeneralizeAllFieldRepresentations( 2878 Handle<Map> Map::GeneralizeAllFieldRepresentations(
2754 Handle<Map> map) { 2879 Handle<Map> map) {
2755 Handle<DescriptorArray> descriptors(map->instance_descriptors()); 2880 Handle<DescriptorArray> descriptors(map->instance_descriptors());
2756 for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) { 2881 for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) {
(...skipping 5633 matching lines...) Expand 10 before | Expand all | Expand 10 after
8390 const WhitenessWitness& witness) { 8515 const WhitenessWitness& witness) {
8391 Object* value = src->GetValue(index); 8516 Object* value = src->GetValue(index);
8392 PropertyDetails details = src->GetDetails(index); 8517 PropertyDetails details = src->GetDetails(index);
8393 Descriptor desc(handle(src->GetKey(index)), 8518 Descriptor desc(handle(src->GetKey(index)),
8394 handle(value, src->GetIsolate()), 8519 handle(value, src->GetIsolate()),
8395 details); 8520 details);
8396 Set(index, &desc, witness); 8521 Set(index, &desc, witness);
8397 } 8522 }
8398 8523
8399 8524
8400 // Creates a new descriptor array by merging the descriptor array of |right_map|
8401 // into the (at least partly) updated descriptor array of |left_map|.
8402 // The method merges two descriptor array in three parts. Both descriptor arrays
8403 // are identical up to |verbatim|. They also overlap in keys up to |valid|.
8404 // Between |verbatim| and |valid|, the resulting descriptor type as well as the
8405 // representation are generalized from both |left_map| and |right_map|. Beyond
8406 // |valid|, the descriptors are copied verbatim from |right_map| up to
8407 // |new_size|.
8408 // In case of incompatible types, the type and representation of |right_map| is
8409 // used.
8410 Handle<DescriptorArray> DescriptorArray::Merge(Handle<Map> left_map,
8411 int verbatim,
8412 int valid,
8413 int new_size,
8414 int modify_index,
8415 StoreMode store_mode,
8416 Handle<Map> right_map) {
8417 ASSERT(verbatim <= valid);
8418 ASSERT(valid <= new_size);
8419
8420 // Allocate a new descriptor array large enough to hold the required
8421 // descriptors, with minimally the exact same size as this descriptor array.
8422 Isolate* isolate = left_map->GetIsolate();
8423 Handle<DescriptorArray> left(left_map->instance_descriptors());
8424 Handle<DescriptorArray> right(right_map->instance_descriptors());
8425 Handle<DescriptorArray> result = DescriptorArray::Allocate(
8426 isolate,
8427 new_size,
8428 Max(new_size, right->number_of_descriptors()) - new_size);
8429 ASSERT(result->length() > left->length() ||
8430 result->NumberOfSlackDescriptors() > 0 ||
8431 result->number_of_descriptors() == right->number_of_descriptors());
8432 ASSERT(result->number_of_descriptors() == new_size);
8433
8434 int descriptor;
8435
8436 // 0 -> |verbatim|
8437 int current_offset = 0;
8438 for (descriptor = 0; descriptor < verbatim; descriptor++) {
8439 if (left->GetDetails(descriptor).type() == FIELD) current_offset++;
8440 Descriptor d(handle(right->GetKey(descriptor)),
8441 handle(right->GetValue(descriptor), right->GetIsolate()),
8442 right->GetDetails(descriptor));
8443 result->Set(descriptor, &d);
8444 }
8445
8446 // |verbatim| -> |valid|
8447 for (; descriptor < valid; descriptor++) {
8448 PropertyDetails left_details = left->GetDetails(descriptor);
8449 PropertyDetails right_details = right->GetDetails(descriptor);
8450 if (left_details.type() == FIELD || right_details.type() == FIELD ||
8451 (store_mode == FORCE_FIELD && descriptor == modify_index) ||
8452 (left_details.type() == CONSTANT &&
8453 right_details.type() == CONSTANT &&
8454 left->GetValue(descriptor) != right->GetValue(descriptor))) {
8455 ASSERT(left_details.type() == CONSTANT || left_details.type() == FIELD);
8456 ASSERT(right_details.type() == CONSTANT || right_details.type() == FIELD);
8457 Representation representation = left_details.representation().generalize(
8458 right_details.representation());
8459 Handle<HeapType> left_type = (left_details.type() == FIELD)
8460 ? handle(left->GetFieldType(descriptor), isolate)
8461 : left->GetValue(descriptor)->OptimalType(isolate, representation);
8462 Handle<HeapType> right_type = (right_details.type() == FIELD)
8463 ? handle(right->GetFieldType(descriptor), isolate)
8464 : right->GetValue(descriptor)->OptimalType(isolate, representation);
8465 Handle<HeapType> field_type = Map::GeneralizeFieldType(
8466 left_type, right_type, isolate);
8467 FieldDescriptor d(handle(left->GetKey(descriptor), isolate),
8468 current_offset++,
8469 field_type,
8470 right_details.attributes(),
8471 representation);
8472 result->Set(descriptor, &d);
8473 } else {
8474 Descriptor d(handle(right->GetKey(descriptor), isolate),
8475 handle(right->GetValue(descriptor), isolate),
8476 right_details);
8477 result->Set(descriptor, &d);
8478 }
8479 }
8480
8481 // |valid| -> |new_size|
8482 for (; descriptor < new_size; descriptor++) {
8483 PropertyDetails right_details = right->GetDetails(descriptor);
8484 if (right_details.type() == FIELD) {
8485 FieldDescriptor d(handle(right->GetKey(descriptor), isolate),
8486 current_offset++,
8487 handle(right->GetFieldType(descriptor), isolate),
8488 right_details.attributes(),
8489 right_details.representation());
8490 result->Set(descriptor, &d);
8491 } else if (store_mode == FORCE_FIELD && descriptor == modify_index) {
8492 ASSERT_EQ(CONSTANT, right_details.type());
8493 Representation field_representation = right_details.representation();
8494 Handle<HeapType> field_type = right->GetValue(descriptor)->OptimalType(
8495 isolate, field_representation);
8496 FieldDescriptor d(handle(right->GetKey(descriptor), isolate),
8497 current_offset++,
8498 field_type,
8499 right_details.attributes(),
8500 field_representation);
8501 result->Set(descriptor, &d);
8502 } else {
8503 Descriptor d(handle(right->GetKey(descriptor), isolate),
8504 handle(right->GetValue(descriptor), isolate),
8505 right_details);
8506 result->Set(descriptor, &d);
8507 }
8508 }
8509
8510 result->Sort();
8511 return result;
8512 }
8513
8514
8515 // Checks whether a merge of |other| into |this| would return a copy of |this|.
8516 bool DescriptorArray::IsMoreGeneralThan(int verbatim,
8517 int valid,
8518 int new_size,
8519 DescriptorArray* other) {
8520 ASSERT(verbatim <= valid);
8521 ASSERT(valid <= new_size);
8522 if (valid != new_size) return false;
8523
8524 for (int descriptor = verbatim; descriptor < valid; descriptor++) {
8525 PropertyDetails details = GetDetails(descriptor);
8526 PropertyDetails other_details = other->GetDetails(descriptor);
8527 if (!other_details.representation().fits_into(details.representation())) {
8528 return false;
8529 }
8530 if (details.type() == CONSTANT) {
8531 if (other_details.type() != CONSTANT) return false;
8532 if (GetValue(descriptor) != other->GetValue(descriptor)) return false;
8533 } else if (details.type() == FIELD && other_details.type() == FIELD) {
8534 if (!other->GetFieldType(descriptor)->NowIs(GetFieldType(descriptor))) {
8535 return false;
8536 }
8537 }
8538 }
8539
8540 return true;
8541 }
8542
8543
8544 // We need the whiteness witness since sort will reshuffle the entries in the 8525 // We need the whiteness witness since sort will reshuffle the entries in the
8545 // descriptor array. If the descriptor array were to be black, the shuffling 8526 // descriptor array. If the descriptor array were to be black, the shuffling
8546 // would move a slot that was already recorded as pointing into an evacuation 8527 // would move a slot that was already recorded as pointing into an evacuation
8547 // candidate. This would result in missing updates upon evacuation. 8528 // candidate. This would result in missing updates upon evacuation.
8548 void DescriptorArray::Sort() { 8529 void DescriptorArray::Sort() {
8549 // In-place heap sort. 8530 // In-place heap sort.
8550 int len = number_of_descriptors(); 8531 int len = number_of_descriptors();
8551 // Reset sorting since the descriptor array might contain invalid pointers. 8532 // Reset sorting since the descriptor array might contain invalid pointers.
8552 for (int i = 0; i < len; ++i) SetSortedKey(i, i); 8533 for (int i = 0; i < len; ++i) SetSortedKey(i, i);
8553 // Bottom-up max-heap construction. 8534 // Bottom-up max-heap construction.
(...skipping 8788 matching lines...) Expand 10 before | Expand all | Expand 10 after
17342 #define ERROR_MESSAGES_TEXTS(C, T) T, 17323 #define ERROR_MESSAGES_TEXTS(C, T) T,
17343 static const char* error_messages_[] = { 17324 static const char* error_messages_[] = {
17344 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 17325 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
17345 }; 17326 };
17346 #undef ERROR_MESSAGES_TEXTS 17327 #undef ERROR_MESSAGES_TEXTS
17347 return error_messages_[reason]; 17328 return error_messages_[reason];
17348 } 17329 }
17349 17330
17350 17331
17351 } } // namespace v8::internal 17332 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/property.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698