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

Side by Side Diff: src/objects.cc

Issue 259003002: Revert "Fix and cleanup Map::GeneralizeRepresentation()." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: 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
2428 Map* Map::FindLastMatchMap(int verbatim, 2465 Map* Map::FindLastMatchMap(int verbatim,
2429 int length, 2466 int length,
2430 DescriptorArray* descriptors) { 2467 DescriptorArray* descriptors) {
2431 DisallowHeapAllocation no_allocation; 2468 DisallowHeapAllocation no_allocation;
2432 2469
2433 // This can only be called on roots of transition trees. 2470 // This can only be called on roots of transition trees.
2434 ASSERT(GetBackPointer()->IsUndefined()); 2471 ASSERT(GetBackPointer()->IsUndefined());
2435 2472
2436 Map* current = this; 2473 Map* current = this;
2437 2474
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2508 } 2545 }
2509 return HeapType::Any(isolate); 2546 return HeapType::Any(isolate);
2510 } 2547 }
2511 2548
2512 2549
2513 // static 2550 // static
2514 void Map::GeneralizeFieldType(Handle<Map> map, 2551 void Map::GeneralizeFieldType(Handle<Map> map,
2515 int modify_index, 2552 int modify_index,
2516 Handle<HeapType> new_field_type) { 2553 Handle<HeapType> new_field_type) {
2517 Isolate* isolate = map->GetIsolate(); 2554 Isolate* isolate = map->GetIsolate();
2555 Handle<Map> field_owner(map->FindFieldOwner(modify_index), isolate);
2556 Handle<DescriptorArray> descriptors(
2557 field_owner->instance_descriptors(), isolate);
2518 2558
2519 // Check if we actually need to generalize the field type at all. 2559 // Check if we actually need to generalize the field type at all.
2520 Handle<HeapType> old_field_type( 2560 Handle<HeapType> old_field_type(
2521 map->instance_descriptors()->GetFieldType(modify_index), isolate); 2561 descriptors->GetFieldType(modify_index), isolate);
2522 if (new_field_type->NowIs(old_field_type)) { 2562 if (new_field_type->NowIs(old_field_type)) {
2523 ASSERT(Map::GeneralizeFieldType(old_field_type, 2563 ASSERT(Map::GeneralizeFieldType(old_field_type,
2524 new_field_type, 2564 new_field_type,
2525 isolate)->NowIs(old_field_type)); 2565 isolate)->NowIs(old_field_type));
2526 return; 2566 return;
2527 } 2567 }
2528 2568
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
2535 // Determine the generalized new field type. 2569 // Determine the generalized new field type.
2536 new_field_type = Map::GeneralizeFieldType( 2570 new_field_type = Map::GeneralizeFieldType(
2537 old_field_type, new_field_type, isolate); 2571 old_field_type, new_field_type, isolate);
2538 2572
2539 PropertyDetails details = descriptors->GetDetails(modify_index); 2573 PropertyDetails details = descriptors->GetDetails(modify_index);
2540 FieldDescriptor d(handle(descriptors->GetKey(modify_index), isolate), 2574 FieldDescriptor d(handle(descriptors->GetKey(modify_index), isolate),
2541 descriptors->GetFieldIndex(modify_index), 2575 descriptors->GetFieldIndex(modify_index),
2542 new_field_type, 2576 new_field_type,
2543 details.attributes(), 2577 details.attributes(),
2544 details.representation()); 2578 details.representation());
(...skipping 12 matching lines...) Expand all
2557 } 2591 }
2558 2592
2559 2593
2560 // Generalize the representation of the descriptor at |modify_index|. 2594 // Generalize the representation of the descriptor at |modify_index|.
2561 // This method rewrites the transition tree to reflect the new change. To avoid 2595 // This method rewrites the transition tree to reflect the new change. To avoid
2562 // high degrees over polymorphism, and to stabilize quickly, on every rewrite 2596 // high degrees over polymorphism, and to stabilize quickly, on every rewrite
2563 // the new type is deduced by merging the current type with any potential new 2597 // the new type is deduced by merging the current type with any potential new
2564 // (partial) version of the type in the transition tree. 2598 // (partial) version of the type in the transition tree.
2565 // To do this, on each rewrite: 2599 // To do this, on each rewrite:
2566 // - Search the root of the transition tree using FindRootMap. 2600 // - Search the root of the transition tree using FindRootMap.
2567 // - Find |target_map|, the newest matching version of this map using the keys 2601 // - Find |updated|, the newest matching version of this map using
2568 // in the |old_map|'s descriptor array to walk the transition tree. 2602 // FindUpdatedMap. This uses the keys in the own map's descriptor array to
2569 // - Merge/generalize the descriptor array of the |old_map| and |target_map|. 2603 // walk the transition tree.
2570 // - Generalize the |modify_index| descriptor using |new_representation| and 2604 // - Merge/generalize the descriptor array of the current map and |updated|.
2571 // |new_field_type|. 2605 // - Generalize the |modify_index| descriptor using |new_representation|.
2572 // - Walk the tree again starting from the root towards |target_map|. Stop at 2606 // - Walk the tree again starting from the root towards |updated|. Stop at
2573 // |split_map|, the first map who's descriptor array does not match the merged 2607 // |split_map|, the first map who's descriptor array does not match the merged
2574 // descriptor array. 2608 // descriptor array.
2575 // - If |target_map| == |split_map|, |target_map| is in the expected state. 2609 // - If |updated| == |split_map|, |updated| is in the expected state. Return it.
2576 // Return it. 2610 // - Otherwise, invalidate the outdated transition target from |updated|, and
2577 // - Otherwise, invalidate the outdated transition target from |target_map|, and
2578 // replace its transition tree with a new branch for the updated descriptors. 2611 // replace its transition tree with a new branch for the updated descriptors.
2579 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map, 2612 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
2580 int modify_index, 2613 int modify_index,
2581 Representation new_representation, 2614 Representation new_representation,
2582 Handle<HeapType> new_field_type, 2615 Handle<HeapType> new_field_type,
2583 StoreMode store_mode) { 2616 StoreMode store_mode) {
2584 Isolate* isolate = old_map->GetIsolate(); 2617 Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors());
2585
2586 Handle<DescriptorArray> old_descriptors(
2587 old_map->instance_descriptors(), isolate);
2588 int old_nof = old_map->NumberOfOwnDescriptors();
2589 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); 2618 PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
2590 Representation old_representation = old_details.representation(); 2619 Representation old_representation = old_details.representation();
2591 2620
2592 // It's fine to transition from None to anything but double without any 2621 // It's fine to transition from None to anything but double without any
2593 // modification to the object, because the default uninitialized value for 2622 // modification to the object, because the default uninitialized value for
2594 // representation None can be overwritten by both smi and tagged values. 2623 // representation None can be overwritten by both smi and tagged values.
2595 // Doubles, however, would require a box allocation. 2624 // Doubles, however, would require a box allocation.
2596 if (old_representation.IsNone() && 2625 if (old_representation.IsNone() &&
2597 !new_representation.IsNone() && 2626 !new_representation.IsNone() &&
2598 !new_representation.IsDouble()) { 2627 !new_representation.IsDouble()) {
2599 ASSERT(old_details.type() == FIELD); 2628 ASSERT(old_details.type() == FIELD);
2600 ASSERT(old_descriptors->GetFieldType(modify_index)->NowIs( 2629 ASSERT(old_descriptors->GetFieldType(modify_index)->NowIs(
2601 HeapType::None())); 2630 HeapType::None()));
2602 if (FLAG_trace_generalization) { 2631 if (FLAG_trace_generalization) {
2603 old_map->PrintGeneralization( 2632 old_map->PrintGeneralization(
2604 stdout, "uninitialized field", 2633 stdout, "uninitialized field",
2605 modify_index, old_map->NumberOfOwnDescriptors(), 2634 modify_index, old_map->NumberOfOwnDescriptors(),
2606 old_map->NumberOfOwnDescriptors(), false, 2635 old_map->NumberOfOwnDescriptors(), false,
2607 old_representation, new_representation, 2636 old_representation, new_representation,
2608 old_descriptors->GetFieldType(modify_index), *new_field_type); 2637 old_descriptors->GetFieldType(modify_index), *new_field_type);
2609 } 2638 }
2610 old_descriptors->SetRepresentation(modify_index, new_representation); 2639 old_descriptors->SetRepresentation(modify_index, new_representation);
2611 old_descriptors->SetValue(modify_index, *new_field_type); 2640 old_descriptors->SetValue(modify_index, *new_field_type);
2612 return old_map; 2641 return old_map;
2613 } 2642 }
2614 2643
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
2615 // Check the state of the root map. 2652 // Check the state of the root map.
2616 Handle<Map> root_map(old_map->FindRootMap(), isolate);
2617 if (!old_map->EquivalentToForTransition(*root_map)) { 2653 if (!old_map->EquivalentToForTransition(*root_map)) {
2618 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, 2654 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
2619 old_details.attributes(), "not equivalent"); 2655 old_details.attributes(), "not equivalent");
2620 } 2656 }
2621 int root_nof = root_map->NumberOfOwnDescriptors(); 2657
2622 if (modify_index < root_nof) { 2658 int verbatim = root_map->NumberOfOwnDescriptors();
2623 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); 2659
2624 if ((old_details.type() != FIELD && store_mode == FORCE_FIELD) || 2660 if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) {
2625 (old_details.type() == FIELD && 2661 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
2626 (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) || 2662 old_details.attributes(), "root modification");
2627 !new_representation.fits_into(old_details.representation())))) {
2628 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
2629 old_details.attributes(), "root modification");
2630 }
2631 } 2663 }
2632 2664
2633 Handle<Map> target_map = root_map; 2665 int descriptors = old_map->NumberOfOwnDescriptors();
2634 for (int i = root_nof; i < old_nof; ++i) { 2666 Map* raw_updated = root_map->FindUpdatedMap(
2635 int j = target_map->SearchTransition(old_descriptors->GetKey(i)); 2667 verbatim, descriptors, *old_descriptors);
2636 if (j == TransitionArray::kNotFound) break; 2668 if (raw_updated == NULL) {
2637 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); 2669 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
2638 Handle<DescriptorArray> tmp_descriptors = handle( 2670 old_details.attributes(), "incompatible");
2639 tmp_map->instance_descriptors(), isolate);
2640
2641 // Check if target map is incompatible.
2642 PropertyDetails old_details = old_descriptors->GetDetails(i);
2643 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i);
2644 PropertyType old_type = old_details.type();
2645 PropertyType tmp_type = tmp_details.type();
2646 if (tmp_details.attributes() != old_details.attributes() ||
2647 ((tmp_type == CALLBACKS || old_type == CALLBACKS) &&
2648 (tmp_type != old_type ||
2649 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i)))) {
2650 return CopyGeneralizeAllRepresentations(
2651 old_map, modify_index, store_mode,
2652 old_details.attributes(), "incompatible");
2653 }
2654 Representation old_representation = old_details.representation();
2655 Representation tmp_representation = tmp_details.representation();
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 } 2671 }
2683 2672
2684 // Directly change the map if the target map is more general. 2673 Handle<Map> updated(raw_updated);
2685 Handle<DescriptorArray> target_descriptors( 2674 Handle<DescriptorArray> updated_descriptors(updated->instance_descriptors());
2686 target_map->instance_descriptors(), isolate); 2675
2687 int target_nof = target_map->NumberOfOwnDescriptors(); 2676 int valid = updated->NumberOfOwnDescriptors();
2688 if (target_nof == old_nof && 2677
2689 (store_mode != FORCE_FIELD || 2678 // Directly change the map if the target map is more general. Ensure that the
2690 target_descriptors->GetDetails(modify_index).type() == FIELD)) { 2679 // target type of the modify_index is a FIELD, unless we are migrating.
2691 ASSERT(modify_index < target_nof); 2680 if (updated_descriptors->IsMoreGeneralThan(
2692 ASSERT(new_representation.fits_into( 2681 verbatim, valid, descriptors, *old_descriptors) &&
2693 target_descriptors->GetDetails(modify_index).representation())); 2682 (store_mode == ALLOW_AS_CONSTANT ||
2694 ASSERT(target_descriptors->GetDetails(modify_index).type() != FIELD || 2683 updated_descriptors->GetDetails(modify_index).type() == FIELD)) {
2695 new_field_type->NowIs( 2684 Representation updated_representation =
2696 target_descriptors->GetFieldType(modify_index))); 2685 updated_descriptors->GetDetails(modify_index).representation();
2697 return target_map; 2686 if (new_representation.fits_into(updated_representation)) return updated;
2698 } 2687 }
2699 2688
2700 // Find the last compatible target map in the transition tree. 2689 Handle<DescriptorArray> new_descriptors = DescriptorArray::Merge(
2701 for (int i = target_nof; i < old_nof; ++i) { 2690 updated, verbatim, valid, descriptors, modify_index,
2702 int j = target_map->SearchTransition(old_descriptors->GetKey(i)); 2691 store_mode, old_map);
2703 if (j == TransitionArray::kNotFound) break; 2692 ASSERT(store_mode == ALLOW_AS_CONSTANT ||
2704 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); 2693 new_descriptors->GetDetails(modify_index).type() == FIELD);
2705 Handle<DescriptorArray> tmp_descriptors(
2706 tmp_map->instance_descriptors(), isolate);
2707 2694
2708 // Check if target map is compatible. 2695 Isolate* isolate = new_descriptors->GetIsolate();
2709 PropertyDetails old_details = old_descriptors->GetDetails(i); 2696 old_representation =
2710 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); 2697 new_descriptors->GetDetails(modify_index).representation();
2711 if (tmp_details.attributes() != old_details.attributes() || 2698 Representation updated_representation =
2712 ((tmp_details.type() == CALLBACKS || old_details.type() == CALLBACKS) && 2699 new_representation.generalize(old_representation);
2713 (tmp_details.type() != old_details.type() || 2700 if (!updated_representation.Equals(old_representation)) {
2714 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i)))) { 2701 new_descriptors->SetRepresentation(modify_index, updated_representation);
2715 return CopyGeneralizeAllRepresentations(
2716 old_map, modify_index, store_mode,
2717 old_details.attributes(), "incompatible");
2718 }
2719 target_map = tmp_map;
2720 } 2702 }
2721 target_nof = target_map->NumberOfOwnDescriptors(); 2703 if (new_descriptors->GetDetails(modify_index).type() == FIELD) {
2722 target_descriptors = handle(target_map->instance_descriptors(), isolate); 2704 Handle<HeapType> field_type(
2723 2705 new_descriptors->GetFieldType(modify_index), isolate);
2724 // Allocate a new descriptor array large enough to hold the required 2706 new_field_type = Map::GeneralizeFieldType(
2725 // descriptors, with minimally the exact same size as the old descriptor 2707 field_type, new_field_type, isolate);
2726 // array. 2708 new_descriptors->SetValue(modify_index, *new_field_type);
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 } 2709 }
2747 2710
2748 // |root_nof| -> |target_nof| 2711 Handle<Map> split_map(root_map->FindLastMatchMap(
2749 for (int i = root_nof; i < target_nof; ++i) { 2712 verbatim, descriptors, *new_descriptors));
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 2713
2793 // |target_nof| -> |old_nof| 2714 int split_descriptors = split_map->NumberOfOwnDescriptors();
2794 for (int i = target_nof; i < old_nof; ++i) { 2715 // This is shadowed by |updated_descriptors| being more general than
2795 PropertyDetails old_details = old_descriptors->GetDetails(i); 2716 // |old_descriptors|.
2796 Handle<Name> old_key(old_descriptors->GetKey(i), isolate); 2717 ASSERT(descriptors != split_descriptors);
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 2718
2836 new_descriptors->Sort(); 2719 int descriptor = split_descriptors;
2837
2838 ASSERT(store_mode != FORCE_FIELD ||
2839 new_descriptors->GetDetails(modify_index).type() == FIELD);
2840
2841 Handle<Map> split_map(root_map->FindLastMatchMap(
2842 root_nof, old_nof, *new_descriptors), isolate);
2843 int split_nof = split_map->NumberOfOwnDescriptors();
2844 ASSERT_NE(old_nof, split_nof);
2845
2846 split_map->DeprecateTarget( 2720 split_map->DeprecateTarget(
2847 old_descriptors->GetKey(split_nof), *new_descriptors); 2721 old_descriptors->GetKey(descriptor), *new_descriptors);
2848 2722
2849 if (FLAG_trace_generalization) { 2723 if (FLAG_trace_generalization) {
2850 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); 2724 PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
2851 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); 2725 PropertyDetails new_details = new_descriptors->GetDetails(modify_index);
2852 Handle<HeapType> old_field_type = (old_details.type() == FIELD) 2726 Handle<HeapType> old_field_type = (old_details.type() == FIELD)
2853 ? handle(old_descriptors->GetFieldType(modify_index), isolate) 2727 ? handle(old_descriptors->GetFieldType(modify_index), isolate)
2854 : HeapType::Constant(handle(old_descriptors->GetValue(modify_index), 2728 : HeapType::Constant(handle(old_descriptors->GetValue(modify_index),
2855 isolate), isolate); 2729 isolate), isolate);
2856 Handle<HeapType> new_field_type = (new_details.type() == FIELD) 2730 Handle<HeapType> new_field_type = (new_details.type() == FIELD)
2857 ? handle(new_descriptors->GetFieldType(modify_index), isolate) 2731 ? handle(new_descriptors->GetFieldType(modify_index), isolate)
2858 : HeapType::Constant(handle(new_descriptors->GetValue(modify_index), 2732 : HeapType::Constant(handle(new_descriptors->GetValue(modify_index),
2859 isolate), isolate); 2733 isolate), isolate);
2860 old_map->PrintGeneralization( 2734 old_map->PrintGeneralization(
2861 stdout, "", modify_index, split_nof, old_nof, 2735 stdout, "", modify_index, descriptor, descriptors,
2862 old_details.type() == CONSTANT && store_mode == FORCE_FIELD, 2736 old_details.type() == CONSTANT && store_mode == FORCE_FIELD,
2863 old_details.representation(), new_details.representation(), 2737 old_details.representation(), new_details.representation(),
2864 *old_field_type, *new_field_type); 2738 *old_field_type, *new_field_type);
2865 } 2739 }
2866 2740
2867 // Add missing transitions. 2741 // Add missing transitions.
2868 Handle<Map> new_map = split_map; 2742 Handle<Map> new_map = split_map;
2869 for (int i = split_nof; i < old_nof; ++i) { 2743 for (; descriptor < descriptors; descriptor++) {
2870 new_map = CopyInstallDescriptors(new_map, i, new_descriptors); 2744 new_map = CopyInstallDescriptors(new_map, descriptor, new_descriptors);
2871 } 2745 }
2746
2872 new_map->set_owns_descriptors(true); 2747 new_map->set_owns_descriptors(true);
2873 return new_map; 2748 return new_map;
2874 } 2749 }
2875 2750
2876 2751
2877 // Generalize the representation of all FIELD descriptors. 2752 // Generalize the representation of all FIELD descriptors.
2878 Handle<Map> Map::GeneralizeAllFieldRepresentations( 2753 Handle<Map> Map::GeneralizeAllFieldRepresentations(
2879 Handle<Map> map) { 2754 Handle<Map> map) {
2880 Handle<DescriptorArray> descriptors(map->instance_descriptors()); 2755 Handle<DescriptorArray> descriptors(map->instance_descriptors());
2881 for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) { 2756 for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) {
(...skipping 5633 matching lines...) Expand 10 before | Expand all | Expand 10 after
8515 const WhitenessWitness& witness) { 8390 const WhitenessWitness& witness) {
8516 Object* value = src->GetValue(index); 8391 Object* value = src->GetValue(index);
8517 PropertyDetails details = src->GetDetails(index); 8392 PropertyDetails details = src->GetDetails(index);
8518 Descriptor desc(handle(src->GetKey(index)), 8393 Descriptor desc(handle(src->GetKey(index)),
8519 handle(value, src->GetIsolate()), 8394 handle(value, src->GetIsolate()),
8520 details); 8395 details);
8521 Set(index, &desc, witness); 8396 Set(index, &desc, witness);
8522 } 8397 }
8523 8398
8524 8399
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
8525 // We need the whiteness witness since sort will reshuffle the entries in the 8544 // We need the whiteness witness since sort will reshuffle the entries in the
8526 // descriptor array. If the descriptor array were to be black, the shuffling 8545 // descriptor array. If the descriptor array were to be black, the shuffling
8527 // would move a slot that was already recorded as pointing into an evacuation 8546 // would move a slot that was already recorded as pointing into an evacuation
8528 // candidate. This would result in missing updates upon evacuation. 8547 // candidate. This would result in missing updates upon evacuation.
8529 void DescriptorArray::Sort() { 8548 void DescriptorArray::Sort() {
8530 // In-place heap sort. 8549 // In-place heap sort.
8531 int len = number_of_descriptors(); 8550 int len = number_of_descriptors();
8532 // Reset sorting since the descriptor array might contain invalid pointers. 8551 // Reset sorting since the descriptor array might contain invalid pointers.
8533 for (int i = 0; i < len; ++i) SetSortedKey(i, i); 8552 for (int i = 0; i < len; ++i) SetSortedKey(i, i);
8534 // Bottom-up max-heap construction. 8553 // Bottom-up max-heap construction.
(...skipping 8788 matching lines...) Expand 10 before | Expand all | Expand 10 after
17323 #define ERROR_MESSAGES_TEXTS(C, T) T, 17342 #define ERROR_MESSAGES_TEXTS(C, T) T,
17324 static const char* error_messages_[] = { 17343 static const char* error_messages_[] = {
17325 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 17344 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
17326 }; 17345 };
17327 #undef ERROR_MESSAGES_TEXTS 17346 #undef ERROR_MESSAGES_TEXTS
17328 return error_messages_[reason]; 17347 return error_messages_[reason];
17329 } 17348 }
17330 17349
17331 17350
17332 } } // namespace v8::internal 17351 } } // 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