Mercurial > hg > graal-compiler
comparison src/share/vm/opto/graphKit.cpp @ 14500:fdad2932c73f
8031752: Failed speculative optimizations should be reattempted when root of compilation is different
Summary: support for speculative traps that keep track of the root of the compilation in which a trap occurs.
Reviewed-by: kvn, twisti
author | roland |
---|---|
date | Tue, 25 Feb 2014 18:16:24 +0100 |
parents | 45467c53f178 |
children | 484a359ff649 |
comparison
equal
deleted
inserted
replaced
14498:04e7587c97dc | 14500:fdad2932c73f |
---|---|
610 // create the stack trace. | 610 // create the stack trace. |
611 | 611 |
612 // Usual case: Bail to interpreter. | 612 // Usual case: Bail to interpreter. |
613 // Reserve the right to recompile if we haven't seen anything yet. | 613 // Reserve the right to recompile if we haven't seen anything yet. |
614 | 614 |
615 assert(!Deoptimization::reason_is_speculate(reason), "unsupported"); | |
615 Deoptimization::DeoptAction action = Deoptimization::Action_maybe_recompile; | 616 Deoptimization::DeoptAction action = Deoptimization::Action_maybe_recompile; |
616 if (treat_throw_as_hot | 617 if (treat_throw_as_hot |
617 && (method()->method_data()->trap_recompiled_at(bci()) | 618 && (method()->method_data()->trap_recompiled_at(bci(), NULL) |
618 || C->too_many_traps(reason))) { | 619 || C->too_many_traps(reason))) { |
619 // We cannot afford to take more traps here. Suffer in the interpreter. | 620 // We cannot afford to take more traps here. Suffer in the interpreter. |
620 if (C->log() != NULL) | 621 if (C->log() != NULL) |
621 C->log()->elem("hot_throw preallocated='0' reason='%s' mcount='%d'", | 622 C->log()->elem("hot_throw preallocated='0' reason='%s' mcount='%d'", |
622 Deoptimization::trap_reason_name(reason), | 623 Deoptimization::trap_reason_name(reason), |
2143 * Record profiling data from receiver profiling at an invoke with the | 2144 * Record profiling data from receiver profiling at an invoke with the |
2144 * type system so that it can propagate it (speculation) | 2145 * type system so that it can propagate it (speculation) |
2145 * | 2146 * |
2146 * @param n receiver node | 2147 * @param n receiver node |
2147 * | 2148 * |
2148 * @return node with improved type | 2149 * @return node with improved type |
2149 */ | 2150 */ |
2150 Node* GraphKit::record_profiled_receiver_for_speculation(Node* n) { | 2151 Node* GraphKit::record_profiled_receiver_for_speculation(Node* n) { |
2151 if (!UseTypeSpeculation) { | 2152 if (!UseTypeSpeculation) { |
2152 return n; | 2153 return n; |
2153 } | 2154 } |
2737 //------------------------maybe_cast_profiled_receiver------------------------- | 2738 //------------------------maybe_cast_profiled_receiver------------------------- |
2738 // If the profile has seen exactly one type, narrow to exactly that type. | 2739 // If the profile has seen exactly one type, narrow to exactly that type. |
2739 // Subsequent type checks will always fold up. | 2740 // Subsequent type checks will always fold up. |
2740 Node* GraphKit::maybe_cast_profiled_receiver(Node* not_null_obj, | 2741 Node* GraphKit::maybe_cast_profiled_receiver(Node* not_null_obj, |
2741 ciKlass* require_klass, | 2742 ciKlass* require_klass, |
2742 ciKlass* spec_klass, | 2743 ciKlass* spec_klass, |
2743 bool safe_for_replace) { | 2744 bool safe_for_replace) { |
2744 if (!UseTypeProfile || !TypeProfileCasts) return NULL; | 2745 if (!UseTypeProfile || !TypeProfileCasts) return NULL; |
2745 | 2746 |
2747 Deoptimization::DeoptReason reason = spec_klass == NULL ? Deoptimization::Reason_class_check : Deoptimization::Reason_speculate_class_check; | |
2748 | |
2746 // Make sure we haven't already deoptimized from this tactic. | 2749 // Make sure we haven't already deoptimized from this tactic. |
2747 if (too_many_traps(Deoptimization::Reason_class_check)) | 2750 if (too_many_traps(reason)) |
2748 return NULL; | 2751 return NULL; |
2749 | 2752 |
2750 // (No, this isn't a call, but it's enough like a virtual call | 2753 // (No, this isn't a call, but it's enough like a virtual call |
2751 // to use the same ciMethod accessor to get the profile info...) | 2754 // to use the same ciMethod accessor to get the profile info...) |
2752 // If we have a speculative type use it instead of profiling (which | 2755 // If we have a speculative type use it instead of profiling (which |
2764 Node* exact_obj = not_null_obj; // will get updated in place... | 2767 Node* exact_obj = not_null_obj; // will get updated in place... |
2765 Node* slow_ctl = type_check_receiver(exact_obj, exact_kls, 1.0, | 2768 Node* slow_ctl = type_check_receiver(exact_obj, exact_kls, 1.0, |
2766 &exact_obj); | 2769 &exact_obj); |
2767 { PreserveJVMState pjvms(this); | 2770 { PreserveJVMState pjvms(this); |
2768 set_control(slow_ctl); | 2771 set_control(slow_ctl); |
2769 uncommon_trap(Deoptimization::Reason_class_check, | 2772 uncommon_trap(reason, |
2770 Deoptimization::Action_maybe_recompile); | 2773 Deoptimization::Action_maybe_recompile); |
2771 } | 2774 } |
2772 if (safe_for_replace) { | 2775 if (safe_for_replace) { |
2773 replace_in_map(not_null_obj, exact_obj); | 2776 replace_in_map(not_null_obj, exact_obj); |
2774 } | 2777 } |
2791 Node* GraphKit::maybe_cast_profiled_obj(Node* obj, | 2794 Node* GraphKit::maybe_cast_profiled_obj(Node* obj, |
2792 ciKlass* type, | 2795 ciKlass* type, |
2793 bool not_null) { | 2796 bool not_null) { |
2794 // type == NULL if profiling tells us this object is always null | 2797 // type == NULL if profiling tells us this object is always null |
2795 if (type != NULL) { | 2798 if (type != NULL) { |
2796 if (!too_many_traps(Deoptimization::Reason_null_check) && | 2799 Deoptimization::DeoptReason class_reason = Deoptimization::Reason_speculate_class_check; |
2797 !too_many_traps(Deoptimization::Reason_class_check)) { | 2800 Deoptimization::DeoptReason null_reason = Deoptimization::Reason_null_check; |
2801 if (!too_many_traps(null_reason) && | |
2802 !too_many_traps(class_reason)) { | |
2798 Node* not_null_obj = NULL; | 2803 Node* not_null_obj = NULL; |
2799 // not_null is true if we know the object is not null and | 2804 // not_null is true if we know the object is not null and |
2800 // there's no need for a null check | 2805 // there's no need for a null check |
2801 if (!not_null) { | 2806 if (!not_null) { |
2802 Node* null_ctl = top(); | 2807 Node* null_ctl = top(); |
2811 Node* slow_ctl = type_check_receiver(exact_obj, exact_kls, 1.0, | 2816 Node* slow_ctl = type_check_receiver(exact_obj, exact_kls, 1.0, |
2812 &exact_obj); | 2817 &exact_obj); |
2813 { | 2818 { |
2814 PreserveJVMState pjvms(this); | 2819 PreserveJVMState pjvms(this); |
2815 set_control(slow_ctl); | 2820 set_control(slow_ctl); |
2816 uncommon_trap(Deoptimization::Reason_class_check, | 2821 uncommon_trap(class_reason, |
2817 Deoptimization::Action_maybe_recompile); | 2822 Deoptimization::Action_maybe_recompile); |
2818 } | 2823 } |
2819 replace_in_map(not_null_obj, exact_obj); | 2824 replace_in_map(not_null_obj, exact_obj); |
2820 obj = exact_obj; | 2825 obj = exact_obj; |
2821 } | 2826 } |
2880 known_statically = (static_res == SSC_always_true || static_res == SSC_always_false); | 2885 known_statically = (static_res == SSC_always_true || static_res == SSC_always_false); |
2881 } | 2886 } |
2882 } | 2887 } |
2883 | 2888 |
2884 if (known_statically && UseTypeSpeculation) { | 2889 if (known_statically && UseTypeSpeculation) { |
2885 // If we know the type check always succeed then we don't use the | 2890 // If we know the type check always succeeds then we don't use the |
2886 // profiling data at this bytecode. Don't lose it, feed it to the | 2891 // profiling data at this bytecode. Don't lose it, feed it to the |
2887 // type system as a speculative type. | 2892 // type system as a speculative type. |
2888 not_null_obj = record_profiled_receiver_for_speculation(not_null_obj); | 2893 not_null_obj = record_profiled_receiver_for_speculation(not_null_obj); |
2889 } else { | 2894 } else { |
2890 const TypeOopPtr* obj_type = _gvn.type(obj)->is_oopptr(); | 2895 const TypeOopPtr* obj_type = _gvn.type(obj)->is_oopptr(); |