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();