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

Side by Side Diff: src/hydrogen-instructions.cc

Issue 11365174: A change in the way we place TransitionElementKinds in the tree. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Now includes optimization of codegen for transition elementskind instruction Created 8 years 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/hydrogen-instructions.h ('k') | src/ia32/lithium-codegen-ia32.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 615 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 PrintChangesTo(stream); 626 PrintChangesTo(stream);
627 PrintTypeTo(stream); 627 PrintTypeTo(stream);
628 } 628 }
629 629
630 630
631 void HInstruction::PrintMnemonicTo(StringStream* stream) { 631 void HInstruction::PrintMnemonicTo(StringStream* stream) {
632 stream->Add("%s ", Mnemonic()); 632 stream->Add("%s ", Mnemonic());
633 } 633 }
634 634
635 635
636 bool HInstruction::IsDefinedAfterInSameBlock(HValue* other) const {
637 // Is the current instruction defined after other and in
638 // the same block?
639 if (block() != other->block()) {
640 return false;
641 }
642
643 HInstruction* cur = previous();
644 while (cur != NULL) {
645 if (cur == other) break;
646 cur = cur->previous();
647 }
648
649 return cur == other;
650 }
651
652
636 void HInstruction::Unlink() { 653 void HInstruction::Unlink() {
637 ASSERT(IsLinked()); 654 ASSERT(IsLinked());
638 ASSERT(!IsControlInstruction()); // Must never move control instructions. 655 ASSERT(!IsControlInstruction()); // Must never move control instructions.
639 ASSERT(!IsBlockEntry()); // Doesn't make sense to delete these. 656 ASSERT(!IsBlockEntry()); // Doesn't make sense to delete these.
640 ASSERT(previous_ != NULL); 657 ASSERT(previous_ != NULL);
641 previous_->next_ = next_; 658 previous_->next_ = next_;
642 if (next_ == NULL) { 659 if (next_ == NULL) {
643 ASSERT(block()->last() == this); 660 ASSERT(block()->last() == this);
644 block()->set_last(previous_); 661 block()->set_last(previous_);
645 } else { 662 } else {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 #ifdef DEBUG 718 #ifdef DEBUG
702 void HInstruction::Verify() { 719 void HInstruction::Verify() {
703 // Verify that input operands are defined before use. 720 // Verify that input operands are defined before use.
704 HBasicBlock* cur_block = block(); 721 HBasicBlock* cur_block = block();
705 for (int i = 0; i < OperandCount(); ++i) { 722 for (int i = 0; i < OperandCount(); ++i) {
706 HValue* other_operand = OperandAt(i); 723 HValue* other_operand = OperandAt(i);
707 if (other_operand == NULL) continue; 724 if (other_operand == NULL) continue;
708 HBasicBlock* other_block = other_operand->block(); 725 HBasicBlock* other_block = other_operand->block();
709 if (cur_block == other_block) { 726 if (cur_block == other_block) {
710 if (!other_operand->IsPhi()) { 727 if (!other_operand->IsPhi()) {
711 HInstruction* cur = this->previous(); 728 // We must be defined after other operand in the same block!
712 while (cur != NULL) { 729 ASSERT(IsDefinedAfterInSameBlock(other_operand));
713 if (cur == other_operand) break;
714 cur = cur->previous();
715 }
716 // Must reach other operand in the same block!
717 ASSERT(cur == other_operand);
718 } 730 }
719 } else { 731 } else {
720 // If the following assert fires, you may have forgotten an 732 // If the following assert fires, you may have forgotten an
721 // AddInstruction. 733 // AddInstruction.
722 ASSERT(other_block->Dominates(cur_block)); 734 ASSERT(other_block->Dominates(cur_block));
723 } 735 }
724 } 736 }
725 737
726 // Verify that instructions that may have side-effects are followed 738 // Verify that instructions that may have side-effects are followed
727 // by a simulate instruction. 739 // by a simulate instruction.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 stream->Add(")"); 832 stream->Add(")");
821 } 833 }
822 834
823 835
824 void HUnaryControlInstruction::PrintDataTo(StringStream* stream) { 836 void HUnaryControlInstruction::PrintDataTo(StringStream* stream) {
825 value()->PrintNameTo(stream); 837 value()->PrintNameTo(stream);
826 HControlInstruction::PrintDataTo(stream); 838 HControlInstruction::PrintDataTo(stream);
827 } 839 }
828 840
829 841
842 void HFastLiteral::PrintDataTo(StringStream* stream) {
843 if (TransitionRequested()) {
844 stream->Add(" (Transition to %s requested)",
845 ElementsKindToString(TransitionTo()));
846 }
847 }
848
849
830 void HIsNilAndBranch::PrintDataTo(StringStream* stream) { 850 void HIsNilAndBranch::PrintDataTo(StringStream* stream) {
831 value()->PrintNameTo(stream); 851 value()->PrintNameTo(stream);
832 stream->Add(kind() == kStrictEquality ? " === " : " == "); 852 stream->Add(kind() == kStrictEquality ? " === " : " == ");
833 stream->Add(nil() == kNullValue ? "null" : "undefined"); 853 stream->Add(nil() == kNullValue ? "null" : "undefined");
834 HControlInstruction::PrintDataTo(stream); 854 HControlInstruction::PrintDataTo(stream);
835 } 855 }
836 856
837 857
838 void HReturn::PrintDataTo(StringStream* stream) { 858 void HReturn::PrintDataTo(StringStream* stream) {
839 value()->PrintNameTo(stream); 859 value()->PrintNameTo(stream);
(...skipping 926 matching lines...) Expand 10 before | Expand all | Expand 10 after
1766 : new(zone) Range(); 1786 : new(zone) Range();
1767 result->Shl(c->Integer32Value()); 1787 result->Shl(c->Integer32Value());
1768 result->set_can_be_minus_zero(false); 1788 result->set_can_be_minus_zero(false);
1769 return result; 1789 return result;
1770 } 1790 }
1771 } 1791 }
1772 return HValue::InferRange(zone); 1792 return HValue::InferRange(zone);
1773 } 1793 }
1774 1794
1775 1795
1796 HLoadKeyed::HLoadKeyed(HValue* obj,
1797 HValue* key,
1798 HValue* dependency,
1799 ElementsKind elements_kind,
1800 Zone* zone)
1801 : HArrayInstruction(obj, key, zone), bit_field_(0) {
1802 bit_field_ = ElementsKindField::encode(elements_kind);
1803 SetOperandAt(2, dependency);
1804
1805 if (is_external()) {
1806 SetInitialized();
1807
1808 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
1809 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
1810 set_representation(Representation::Double());
1811 } else {
1812 set_representation(Representation::Integer32());
1813 }
1814
1815 SetGVNFlag(kDependsOnSpecializedArrayElements);
1816 // Native code could change the specialized array.
1817 SetGVNFlag(kDependsOnCalls);
1818 } else {
1819 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) ||
1820 IsFastDoubleElementsKind(elements_kind));
1821
1822 // We don't yet know what it depends on yet, so set both flags
1823 SetGVNFlag(kDependsOnArrayElements);
1824 SetGVNFlag(kDependsOnDoubleArrayElements);
1825 if (!FLAG_use_place_elements_transitions) {
1826 PerformDeferredInitialization();
1827 }
1828 }
1829
1830 SetFlag(kUseGVN);
1831 }
1832
1833
1834 void HLoadKeyed::PerformDeferredInitialization(ElementsKind new_elements_kind) {
1835 ASSERT(!is_external());
1836 ASSERT(!Initialized());
1837 SetInitialized();
1838
1839 if (new_elements_kind != elements_kind()) {
1840 bit_field_ = ElementsKindField::encode(new_elements_kind);
1841 }
1842
1843 ClearGVNFlag(kDependsOnArrayElements);
1844 ClearGVNFlag(kDependsOnDoubleArrayElements);
1845
1846 if (IsFastSmiOrObjectElementsKind(elements_kind())) {
1847 if (IsFastSmiElementsKind(elements_kind()) &&
1848 IsFastPackedElementsKind(elements_kind())) {
1849 set_type(HType::Smi());
1850 }
1851
1852 set_representation(Representation::Tagged());
1853 SetGVNFlag(kDependsOnArrayElements);
1854 } else {
1855 set_representation(Representation::Double());
1856 SetGVNFlag(kDependsOnDoubleArrayElements);
1857 }
1858 }
1859
1860
1776 Range* HLoadKeyed::InferRange(Zone* zone) { 1861 Range* HLoadKeyed::InferRange(Zone* zone) {
1777 switch (elements_kind()) { 1862 switch (elements_kind()) {
1778 case EXTERNAL_PIXEL_ELEMENTS: 1863 case EXTERNAL_PIXEL_ELEMENTS:
1779 return new(zone) Range(0, 255); 1864 return new(zone) Range(0, 255);
1780 case EXTERNAL_BYTE_ELEMENTS: 1865 case EXTERNAL_BYTE_ELEMENTS:
1781 return new(zone) Range(-128, 127); 1866 return new(zone) Range(-128, 127);
1782 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 1867 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
1783 return new(zone) Range(0, 255); 1868 return new(zone) Range(0, 255);
1784 case EXTERNAL_SHORT_ELEMENTS: 1869 case EXTERNAL_SHORT_ELEMENTS:
1785 return new(zone) Range(-32768, 32767); 1870 return new(zone) Range(-32768, 32767);
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
2075 2160
2076 if (names_cache->enumerable() == object()) { 2161 if (names_cache->enumerable() == object()) {
2077 HForInCacheArray* index_cache = 2162 HForInCacheArray* index_cache =
2078 names_cache->index_cache(); 2163 names_cache->index_cache();
2079 HCheckMapValue* map_check = 2164 HCheckMapValue* map_check =
2080 new(block()->zone()) HCheckMapValue(object(), names_cache->map()); 2165 new(block()->zone()) HCheckMapValue(object(), names_cache->map());
2081 HInstruction* index = new(block()->zone()) HLoadKeyed( 2166 HInstruction* index = new(block()->zone()) HLoadKeyed(
2082 index_cache, 2167 index_cache,
2083 key_load->key(), 2168 key_load->key(),
2084 key_load->key(), 2169 key_load->key(),
2085 key_load->elements_kind()); 2170 key_load->elements_kind(),
2171 block()->zone());
2086 map_check->InsertBefore(this); 2172 map_check->InsertBefore(this);
2087 index->InsertBefore(this); 2173 index->InsertBefore(this);
2088 HLoadFieldByIndex* load = new(block()->zone()) HLoadFieldByIndex( 2174 HLoadFieldByIndex* load = new(block()->zone()) HLoadFieldByIndex(
2089 object(), index); 2175 object(), index);
2090 load->InsertBefore(this); 2176 load->InsertBefore(this);
2091 return load; 2177 return load;
2092 } 2178 }
2093 } 2179 }
2094 } 2180 }
2095 2181
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
2438 visited->Add(id()); 2524 visited->Add(id());
2439 // Propagate to the left argument. If the left argument cannot be -0, then 2525 // Propagate to the left argument. If the left argument cannot be -0, then
2440 // the result of the sub operation cannot be either. 2526 // the result of the sub operation cannot be either.
2441 if (range() == NULL || range()->CanBeMinusZero()) { 2527 if (range() == NULL || range()->CanBeMinusZero()) {
2442 return left(); 2528 return left();
2443 } 2529 }
2444 return NULL; 2530 return NULL;
2445 } 2531 }
2446 2532
2447 2533
2534 // Determines whether the given array or object literal boilerplate satisfies
2535 // all limits to be considered for fast deep-copying and computes the total
2536 // size of all objects that are part of the graph.
2537 bool HFastLiteral::IsFastLiteral(Handle<JSObject> boilerplate,
2538 int max_depth,
2539 int* max_properties,
2540 int* total_size) {
2541 ASSERT(max_depth >= 0 && *max_properties >= 0);
2542 if (max_depth == 0) return false;
2543
2544 Handle<FixedArrayBase> elements(boilerplate->elements());
2545 if (elements->length() > 0 &&
2546 elements->map() != boilerplate->GetHeap()->fixed_cow_array_map()) {
2547 if (boilerplate->HasFastDoubleElements()) {
2548 *total_size += FixedDoubleArray::SizeFor(elements->length());
2549 } else if (boilerplate->HasFastObjectElements()) {
2550 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements);
2551 int length = elements->length();
2552 for (int i = 0; i < length; i++) {
2553 if ((*max_properties)-- == 0) return false;
2554 Handle<Object> value(fast_elements->get(i));
2555 if (value->IsJSObject()) {
2556 Handle<JSObject> value_object = Handle<JSObject>::cast(value);
2557 if (!IsFastLiteral(value_object,
2558 max_depth - 1,
2559 max_properties,
2560 total_size)) {
2561 return false;
2562 }
2563 }
2564 }
2565 *total_size += FixedArray::SizeFor(length);
2566 } else {
2567 return false;
2568 }
2569 }
2570
2571 Handle<FixedArray> properties(boilerplate->properties());
2572 if (properties->length() > 0) {
2573 return false;
2574 } else {
2575 int nof = boilerplate->map()->inobject_properties();
2576 for (int i = 0; i < nof; i++) {
2577 if ((*max_properties)-- == 0) return false;
2578 Handle<Object> value(boilerplate->InObjectPropertyAt(i));
2579 if (value->IsJSObject()) {
2580 Handle<JSObject> value_object = Handle<JSObject>::cast(value);
2581 if (!IsFastLiteral(value_object,
2582 max_depth - 1,
2583 max_properties,
2584 total_size)) {
2585 return false;
2586 }
2587 }
2588 }
2589 }
2590
2591 *total_size += boilerplate->map()->instance_size();
2592 return true;
2593 }
2594
2595
2596 HStoreKeyed::HStoreKeyed(HValue* obj, HValue* key, HValue* val,
2597 ElementsKind elements_kind,
2598 Zone* zone)
2599 : HArrayInstruction(obj, key, zone),
2600 elements_kind_(elements_kind),
2601 index_offset_(0),
2602 is_dehoisted_(false) {
2603 SetOperandAt(2, val);
2604
2605 if (is_external()) {
2606 SetInitialized();
2607
2608 SetGVNFlag(kChangesSpecializedArrayElements);
2609 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating.
2610 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS &&
2611 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) {
2612 SetFlag(kTruncatingToInt32);
2613 }
2614 } else {
2615 // We don't know what we'll have later.
2616 // Initialize for the worst case
2617 SetGVNFlag(kChangesDoubleArrayElements);
2618 SetFlag(kDeoptimizeOnUndefined);
2619 SetGVNFlag(kChangesArrayElements);
2620
2621 if (!FLAG_use_place_elements_transitions) {
2622 PerformDeferredInitialization();
2623 }
2624 }
2625 }
2626
2627
2628 void HStoreKeyed::PerformDeferredInitialization(
2629 ElementsKind new_elements_kind) {
2630 ASSERT(!is_external());
2631 ASSERT(!Initialized());
2632 SetInitialized();
2633
2634 if (new_elements_kind != elements_kind_) {
2635 elements_kind_ = new_elements_kind;
2636 }
2637
2638 // Adjust flags appropriately
2639 if (IsFastDoubleElementsKind(elements_kind())) {
2640 ClearGVNFlag(kChangesArrayElements);
2641 } else {
2642 ClearGVNFlag(kChangesDoubleArrayElements);
2643 ClearFlag(kDeoptimizeOnUndefined);
2644 }
2645 }
2646
2647
2448 bool HStoreKeyed::NeedsCanonicalization() { 2648 bool HStoreKeyed::NeedsCanonicalization() {
2449 // If value is an integer or comes from the result of a keyed load 2649 // If value is an integer or comes from the result of a keyed load
2450 // then it will be a non-hole value: no need for canonicalization. 2650 // then it will be a non-hole value: no need for canonicalization.
2451 if (value()->IsLoadKeyed() || 2651 if (value()->IsLoadKeyed() ||
2452 (value()->IsChange() && HChange::cast(value())->from().IsInteger32())) { 2652 (value()->IsChange() && HChange::cast(value())->from().IsInteger32())) {
2453 return false; 2653 return false;
2454 } 2654 }
2455 return true; 2655 return true;
2456 } 2656 }
2457 2657
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
2732 all_uses_require = use_rep; 2932 all_uses_require = use_rep;
2733 } 2933 }
2734 if (all_uses_require_the_same) { 2934 if (all_uses_require_the_same) {
2735 return all_uses_require; 2935 return all_uses_require;
2736 } 2936 }
2737 2937
2738 return Representation::None(); 2938 return Representation::None();
2739 } 2939 }
2740 2940
2741 2941
2942 HTransitionElementsKind::HTransitionElementsKind(HValue* object,
2943 Handle<Map> original_map,
2944 Handle<Map> transitioned_map,
2945 Isolate* isolate,
2946 bool calculatePessimisticHoleyAndFamily)
2947
2948 : original_map_(original_map),
2949 transitioned_map_(transitioned_map),
2950 pessimistic_holey_(Handle<Map>::null()),
2951 family_(Handle<Map>::null()),
2952 special_case_(false) {
2953 SetOperandAt(0, object);
2954 SetFlag(kUseGVN);
2955 SetGVNFlag(kChangesElementsKind);
2956 if (original_map->has_fast_double_elements()) {
2957 SetGVNFlag(kChangesElementsPointer);
2958 SetGVNFlag(kChangesNewSpacePromotion);
2959 }
2960 if (transitioned_map->has_fast_double_elements()) {
2961 SetGVNFlag(kChangesElementsPointer);
2962 SetGVNFlag(kChangesNewSpacePromotion);
2963 }
2964 set_representation(Representation::Tagged());
2965
2966 if (calculatePessimisticHoleyAndFamily) {
2967 Handle<Map> map_to = transitioned_map_;
2968
2969 // When transition records are created, we have the chance to create map
2970 // transitions we might need later. Transitions are unified during
2971 // optimization, and we may need to transition from a packed fastmap to a
2972 // holey version of same. But we can't create those transitions during
2973 // optimization. Do it now, recognizing that when the handle disappears
2974 // these maps may be collected if they didn't make it into usage in the
2975 // optimized graph.
2976 if (pessimistic_holey_.is_null()) {
2977 if (IsFastPackedElementsKind(map_to->elements_kind())) {
2978 ElementsKind holey_kind = GetHoleyElementsKind(map_to->elements_kind());
2979 // The transition might already exist
2980 Handle<Map> holey_map_handle(FindClosestElementsTransition(*map_to,
2981 holey_kind));
2982 ASSERT(!holey_map_handle.is_null());
2983 if (holey_map_handle->elements_kind() != holey_kind) {
2984 MaybeObject* holey_map = map_to->AddMissingElementsTransitions(
2985 holey_kind);
2986 holey_map->ToHandle<Map>(&pessimistic_holey_, isolate);
2987 } else {
2988 pessimistic_holey_ = holey_map_handle;
2989 }
2990 } else {
2991 pessimistic_holey_ = map_to;
2992 }
2993 }
2994
2995 if (family_.is_null()) {
2996 // fill in map_family_
2997 // Walk up to the base map from the map_to();
2998 Handle<Map> end_map(FindClosestElementsTransition(*map_to,
2999 TERMINAL_FAST_ELEMENTS_KIND));
3000 ASSERT(!end_map.is_null());
3001 family_ = end_map;
3002 }
3003
3004 ASSERT(!pessimistic_holey_.is_null());
3005 ASSERT(!family_.is_null());
3006 }
3007 }
3008
3009 void HArrayInstruction::PrintElementPlacementTo(StringStream* stream) {
3010 stream->Add("SITE: block%d %d: ", block()->block_id(),
3011 id());
3012 PrintTo(stream);
3013 stream->Add("\n");
3014
3015 stream->Add(" HOISTABLE: %s\n", hoistable() ? "true" : "false");
3016 stream->Add(" ELEMENTS_KIND: %s\n", ElementsKindToString(GetElementsKind()));
3017
3018 // Print score
3019 // stream->Add(" SCORE: (+%d,%d,-%d)\n", score_[0], score_[1], score_[2]);
3020
3021 // Find the def point for the instruction
3022 HValue *element = elements();
3023 ASSERT(element != NULL);
3024 // Now get the item from the elements
3025 ASSERT(element->IsLoadElements());
3026 HValue *elements_value = HLoadElements::cast(element)->value();
3027 stream->Add(" OBJECT: ");
3028 elements_value->PrintNameTo(stream);
3029 stream->Add(" ");
3030 elements_value->PrintTo(stream);
3031 stream->Add(" %s\n", elements_value->IsPhi() ? "PHI" : "");
3032 stream->Add(" TRANSITIONS:\n");
3033 ElementsKind transitionElementsKind = FAST_SMI_ELEMENTS;
3034 for (int i = 0; i < transitions(); i++) {
3035 HTransitionElementsKind* b = transition(i);
3036 stream->Add(" %s", ElementsKindToString(
3037 b->original_map()->elements_kind()));
3038 stream->Add("(0x%p)-> ", *(b->original_map()));
3039 transitionElementsKind = b->transitioned_map()->elements_kind();
3040 stream->Add("%s", ElementsKindToString(transitionElementsKind));
3041 stream->Add("(0x%p)\n", *(b->transitioned_map()));
3042 }
3043 }
3044
3045
3046 void HArrayInstruction::AddTransitions(const ZoneList<HTransitionElementsKind*>&
3047 transition_list) {
3048 ASSERT(transition_list.length() > 0);
3049 #ifdef DEBUG
3050 Map* first_to_map = *(transition_list[0]->transitioned_map());
3051 #endif
3052
3053 // Doesn't check for duplicates.
3054 // The "to" map values should be the same for the whole group
3055 for (int i = 0; i < transition_list.length(); i++) {
3056 transitions_->Add(transition_list[i], zone_);
3057 ASSERT(first_to_map ==
3058 *(transition_list[i]->transitioned_map()));
3059 }
3060 }
3061
3062
3063 Handle<Map> HArrayInstruction::map_family() {
3064 Handle<Map> family = Handle<Map>::null();
3065 if (transitions()) {
3066 family = transition(0)->family();
3067 }
3068
3069 #ifdef DEBUG
3070 for (int i = 1; i < transitions(); i++) {
3071 HTransitionElementsKind* tr = transition(i);
3072 ASSERT(*(tr->family()) == *family);
3073 }
3074 #endif
3075 return family;
3076 }
3077
3078
2742 // Node-specific verification code is only included in debug mode. 3079 // Node-specific verification code is only included in debug mode.
2743 #ifdef DEBUG 3080 #ifdef DEBUG
2744 3081
2745 void HPhi::Verify() { 3082 void HPhi::Verify() {
2746 ASSERT(OperandCount() == block()->predecessors()->length()); 3083 ASSERT(OperandCount() == block()->predecessors()->length());
2747 for (int i = 0; i < OperandCount(); ++i) { 3084 for (int i = 0; i < OperandCount(); ++i) {
2748 HValue* value = OperandAt(i); 3085 HValue* value = OperandAt(i);
2749 HBasicBlock* defining_block = value->block(); 3086 HBasicBlock* defining_block = value->block();
2750 HBasicBlock* predecessor_block = block()->predecessors()->at(i); 3087 HBasicBlock* predecessor_block = block()->predecessors()->at(i);
2751 ASSERT(defining_block == predecessor_block || 3088 ASSERT(defining_block == predecessor_block ||
(...skipping 21 matching lines...) Expand all
2773 3110
2774 3111
2775 void HCheckFunction::Verify() { 3112 void HCheckFunction::Verify() {
2776 HInstruction::Verify(); 3113 HInstruction::Verify();
2777 ASSERT(HasNoUses()); 3114 ASSERT(HasNoUses());
2778 } 3115 }
2779 3116
2780 #endif 3117 #endif
2781 3118
2782 } } // namespace v8::internal 3119 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen-instructions.h ('k') | src/ia32/lithium-codegen-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698