JDK-8049252 : VerifyStack logic in Deoptimization::unpack_frames does not expect to see invoke bc at the top frame during normal deoptimization
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 6,7,8,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2014-07-03
  • Updated: 2016-02-03
  • Resolved: 2014-07-29
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
8u40Fixed 9 b28Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
While working on JDK-6848902 I've added -XX:+VerifyStack to arguments of compiler/6589834/Test_ia32.java test (it was suggested in comments in that test) and it seems like issue described in comment for original bug was never fixed (https://bugs.openjdk.java.net/browse/JDK-6589834?focusedCommentId=12388050&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-12388050) and stack verification is still failing:

Wrong number of expression stack elements during deoptimization
  Error occurred while verifying frame 0 (0..1, 0 is topmost)
  Fabricated interpreter frame had 3 expression stack elements
  Interpreter oop map had 2 expression stack elements
  try_next_mask = 0
  next_mask_expression_stack_size = -1
  callee_size_of_parameters = 0
  callee_max_locals = 0
  top_frame_expression_stack_adjustment = 0
  exec_mode = 0
  cur_invoke_parameter_size = 1
  Thread = 0x00007faea41b0000, thread ID = 7273
  Interpreted frames:
    Test_ia32.f([LTest_ia32;)I (bci 3)
    Test_ia32.run()V (bci 10)
 - sp: 0x00007fae8a54f7c0
 - thread: "Thread-4" #13 prio=5 os_prio=0 tid=0x00007faea41b0000 nid=0x1c69 runnable [0x00007fae8a54f000]
   java.lang.Thread.State: RUNNABLE
   JavaThread state: _thread_in_Java
Thread: 0x00007faea41b0000  [0x1c69] State: _running _has_called_back 0 _at_poll_safepoint 0
   JavaThread state: _thread_in_Java
 - frame size: 8
 - interpreter_frame -> sp: 0x00007fae8a54f738
 - interpreter_frame -> sp: 0x00007fae8a54f7a0
Fix: add missing el->should_reexecute() check in assert. src/share/vm/runtime/deoptimization.cpp @@ -661,7 +661,7 @@ (iframe->interpreter_frame_expression_stack_size() == (next_mask_expression_stack_size - top_frame_expression_stack_adjustment))) || (is_top_frame && (exec_mode == Unpack_exception) && iframe->interpreter_frame_expression_stack_size() == 0) || - (is_top_frame && (exec_mode == Unpack_uncommon_trap || exec_mode == Unpack_reexecute) && + (is_top_frame && (exec_mode == Unpack_uncommon_trap || exec_mode == Unpack_reexecute || el->should_reexecute()) && (iframe->interpreter_frame_expression_stack_size() == mask.expression_stack_size() + cur_invoke_parameter_size)) )) {

I think, something wrong with the assert. The intrinsic code for clone() set reexecution flag: bool LibraryCallKit::inline_native_clone(bool is_virtual) { PhiNode* result_val; // Set the reexecute bit for the interpreter to reexecute // the bytecode that invokes Object.clone if deoptimization happens. { PreserveReexecuteState preexecs(this); jvms()->set_should_reexecute(true); So we have to keep the receiver on the stack to reexecute the call in Interpreter: 0 iconst_1 1 iconst_2 2 fast_aload_0 3 invokevirtual 10 <[LTest_ia32;.clone()Ljava/lang/Object;> OptoAssembly show that we have correctly 3 values on stack (RBP points to array): 13f call,static wrapper for: _new_array_Java # Reflector::f @ bci:3 L[0]=_ STK[0]=#1 STK[1]=#2 STK[2]=RBP # Reflector::run @ bci:33 L[0]=rsp + #0 L[1]=_ L[2]=_ L[3]=_ # OopMap{rbp=Oop [0]=Oop [8]=NarrowOop off=324} But the next condition in the assert does not list 'Unpack_deopt' which we have in this case: (is_top_frame && (exec_mode == Unpack_uncommon_trap || exec_mode == Unpack_reexecute) && (iframe->interpreter_frame_expression_stack_size() == mask.expression_stack_size() + cur_invoke_parameter_size))

The trick was to use the latest jdk9 b24 as JAVA_HOME. Now I can reproduce it with debug VM I built.

Vladimir, issue could be reproduced with both original and modified tests, but for original test (before 6848902) -XX:+VerifyStack should be explicitly specified. So following commands should be done for original test: cp $HS/test/compiler/6589834/*.java ./ $JAVA_HOME/bin/javac Test_ia32.java $JAVA_HOME/bin/java -XX:+VerifyStack Test_ia32 And for modified test: cp $HS/test/compiler/6589834/*.java ./ cp -r $HS/test/testlibrary/whitebox/sun ./ cp -r $HS/test/testlibrary/whitebox/sun ./ $JAVA_HOME/bin/javac *.java $JAVA_HOME/bin/java -Xbootclasspath/a:. -XX:+WhiteBoxAPI -XX:+VerifyStack -XX:CompileOnly=InlinedArrayCloneTestCase Test_ia32

Filipp, to reproduce the problem should I use the test with your 6848902 fix or original? If it is modified test, then how I can run it standalone (not by jtreg)? It seems, I can't reproduce it with original test. Are any other conditions to reproduce the failure?

[~kvn], do you know anything about this one?

To reproduce execute compiler/6589834/Test_ia32.java test with -XX:+VerifyStack option.