From 81e730e5f11a4ad2d0ba90edf2530d5f00989af9 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Mon, 25 Jan 2021 20:02:56 +0000 Subject: [PATCH] 8259276: C2: Empty expression stack when reexecuting tableswitch/lookupswitch instructions after deoptimization Reviewed-by: dlong, kvn, thartmann --- src/hotspot/share/opto/graphKit.cpp | 12 +++++++++--- src/hotspot/share/opto/parse2.cpp | 12 ++++++++---- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp index 14c3807d2e2..31668b880c2 100644 --- a/src/hotspot/share/opto/graphKit.cpp +++ b/src/hotspot/share/opto/graphKit.cpp @@ -823,8 +823,7 @@ bool GraphKit::dead_locals_are_killed() { #endif //ASSERT -// Helper function for enforcing certain bytecodes to reexecute if -// deoptimization happens +// Helper function for enforcing certain bytecodes to reexecute if deoptimization happens. static bool should_reexecute_implied_by_bytecode(JVMState *jvms, bool is_anewarray) { ciMethod* cur_method = jvms->method(); int cur_bci = jvms->bci(); @@ -839,8 +838,9 @@ static bool should_reexecute_implied_by_bytecode(JVMState *jvms, bool is_anewarr // is limited by dimensions and guarded by flag so in some cases // multianewarray() runtime calls will be generated and // the bytecode should not be reexecutes (stack will not be reset). - } else + } else { return false; + } } // Helper function for adding JVMState and debug information to node @@ -894,6 +894,12 @@ void GraphKit::add_safepoint_edges(SafePointNode* call, bool must_throw) { // deoptimization happens. We set the reexecute state for them here if (out_jvms->is_reexecute_undefined() && //don't change if already specified should_reexecute_implied_by_bytecode(out_jvms, call->is_AllocateArray())) { +#ifdef ASSERT + int inputs = 0, not_used; // initialized by GraphKit::compute_stack_effects() + assert(method() == youngest_jvms->method(), "sanity"); + assert(compute_stack_effects(inputs, not_used), "unknown bytecode: %s", Bytecodes::name(java_bc())); + assert(out_jvms->sp() >= (uint)inputs, "not enough operands for reexecution"); +#endif // ASSERT out_jvms->set_should_reexecute(true); //NOTE: youngest_jvms not changed } diff --git a/src/hotspot/share/opto/parse2.cpp b/src/hotspot/share/opto/parse2.cpp index c006de2ae5a..9d89184db10 100644 --- a/src/hotspot/share/opto/parse2.cpp +++ b/src/hotspot/share/opto/parse2.cpp @@ -419,7 +419,6 @@ static void merge_ranges(SwitchRange* ranges, int& rp) { //-------------------------------do_tableswitch-------------------------------- void Parse::do_tableswitch() { - Node* lookup = pop(); // Get information about tableswitch int default_dest = iter().get_dest_table(0); int lo_index = iter().get_int_table(1); @@ -429,6 +428,7 @@ void Parse::do_tableswitch() { if (len < 1) { // If this is a backward branch, add safepoint maybe_add_safepoint(default_dest); + pop(); // the effect of the instruction execution on the operand stack merge(default_dest); return; } @@ -485,22 +485,24 @@ void Parse::do_tableswitch() { } // Safepoint in case if backward branch observed - if( makes_backward_branch && UseLoopSafepoints ) + if (makes_backward_branch && UseLoopSafepoints) { add_safepoint(); + } + Node* lookup = pop(); // lookup value jump_switch_ranges(lookup, &ranges[0], &ranges[rp]); } //------------------------------do_lookupswitch-------------------------------- void Parse::do_lookupswitch() { - Node *lookup = pop(); // lookup value // Get information about lookupswitch int default_dest = iter().get_dest_table(0); int len = iter().get_int_table(1); if (len < 1) { // If this is a backward branch, add safepoint maybe_add_safepoint(default_dest); + pop(); // the effect of the instruction execution on the operand stack merge(default_dest); return; } @@ -577,9 +579,11 @@ void Parse::do_lookupswitch() { } // Safepoint in case backward branch observed - if (makes_backward_branch && UseLoopSafepoints) + if (makes_backward_branch && UseLoopSafepoints) { add_safepoint(); + } + Node *lookup = pop(); // lookup value jump_switch_ranges(lookup, &ranges[0], &ranges[rp]); }