JDK-8148871 : Possible wrong expression stack depth at deopt point
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 9,10,11
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2016-02-02
  • Updated: 2022-02-01
  • Resolved: 2018-03-01
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.
JDK 11
11 b04Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
While running test/compiler/jvmci/code/SimpleDebugInfoTest.java with -vmoptions:" -XX:+DeoptimizeALot -XX:CompileThreshold=100 -esa -XX:+VerifyStack" I got the following error.

Wrong number of expression stack elements during deoptimization
  Error occurred while verifying frame 0 (0..0, 0 is topmost)
  Fabricated interpreter frame had 2 expression stack elements
  Interpreter oop map had 3 expression stack elements
  try_next_mask = 1
  next_mask_expression_stack_size = 0
  callee_size_of_parameters = 0
  callee_max_locals = 0
  top_frame_expression_stack_adjustment = 1
  exec_mode = 0
  cur_invoke_parameter_size = 0
  Thread = 0x00007f57343ca000, thread ID = 9537
  Interpreted frames:
    sun.reflect.generics.parser.SignatureParser.parsePackageNameAndSimpleClassTypeSignature()Lsun/reflect/generics/tree/SimpleClassTypeSignature; (bci 95)
 - sp: 0x00007f56eddf84a0
 - thread: "MainThread" #12 prio=5 os_prio=0 tid=0x00007f57343ca000 nid=0x2541 runnable [0x00007f56eddf7000]
   java.lang.Thread.State: RUNNABLE
   JavaThread state: _thread_in_Java
Thread: 0x00007f57343ca000  [0x2541] State: _running _has_called_back 0 _at_poll_safepoint 0
   JavaThread state: _thread_in_Java
 - frame size: 34
 - interpreter_frame -> sp: 0x00007f56eddf8538
# To suppress the following error report, specify this argument
# after -XX: or in .hotspotrc:  SuppressErrorAt=/deoptimization.cpp:762
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (/home/tkrodrig/ws/hs-comp/hotspot/src/share/vm/runtime/deoptimization.cpp:762), pid=9511, tid=9537
#  guarantee(false) failed: wrong number of expression stack elements during deopt
#
# JRE version: Java(TM) SE Runtime Environment (9.0) (fastdebug build 9-internal+0-2016-02-01-191105.tkrodrig.hs-comp)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 9-internal+0-2016-02-01-191105.tkrodrig.hs-comp, mixed mode, tiered, jvmci, compressed oops, g1 gc, linux-amd64)
# Core dump will be written. Default location: Core dumps may be processed with "/usr/share/apport/apport %p %s %c %P" (or dumping to /home/tkrodrig/ws/hs-comp/hotspot/test/JTwork/scratch/core.9511)
#
# An error report file with more information is saved as:
# /home/tkrodrig/ws/hs-comp/hotspot/test/JTwork/scratch/hs_err_pid9511.log
 Locks owned:
Mutex: [0x00007f5734015750/0x0000000000000001] tty_lock - owner: 0x00007f57343ca000
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
#
Current thread is 9537

Here is the scope desc from a failing run:
ScopeDesc(pc=0x00007f2fa167f23e offset=237e):
   sun.reflect.generics.parser.SignatureParser::parsePackageNameAndSimpleClassTypeSignature@95 (line 343)
   Locals
    - l0: stack[152],oop
    - l1: reg r8 [16],oop
    - l2: empty
   Expression stack
    - @0: reg r8 [16],oop
    - @1: 0

and the bytecode leading up to bci 95.

      92: aload_1
      93: iconst_0
      94: iconst_0
      95: anewarray     #62                 // class sun/reflect/generics/tree/TypeArgument

It certainly seems like it should have 3 elements on the stack.  But maybe this is a case where the assertion needs to be adjusted.
Comments
URL: http://hg.openjdk.java.net/jdk/jdk/rev/41e570d862b4 User: jwilhelm Date: 2018-03-09 01:13:15 +0000
09-03-2018

URL: http://hg.openjdk.java.net/jdk/hs/rev/41e570d862b4 User: thartmann Date: 2018-03-01 08:03:36 +0000
01-03-2018

Thanks Tom, I'll run some testing and will send the RFR tomorrow.
27-02-2018

Thanks for tracking down. The fix looks good.
27-02-2018

I finally found some time to look into this and came up with a simple regression test: http://cr.openjdk.java.net/~thartmann/8148871/webrev.00/raw_files/new/test/hotspot/jtreg/compiler/interpreter/TestVerifyStackAfterDeopt.java The test() method is compiled to: 0 fast_aload_0 1 iconst_0 2 anewarray java/lang/Object 5 invokevirtual 3 <Test.m([Ljava/lang/Object;)V> 8 return C1 emits a slow call to Runtime1::new_object_array() for the anewarray bytecode in case the TLAB is full. With -XX:+DeoptimizeALot, the runtime deoptimizes the caller frame. We then crash in Deoptimization::unpack_frames() because the VerifyStack code expects 2 expression stack elements at the next instruction whereas the interpreter frame / scope descriptor have only one: Wrong number of expression stack elements during deoptimization Error occurred while verifying frame 0 (0..0, 0 is topmost) Fabricated interpreter frame had 1 expression stack elements Interpreter oop map had 2 expression stack elements try_next_mask = 1 next_mask_expression_stack_size = 0 callee_size_of_parameters = 0 callee_max_locals = 0 top_frame_expression_stack_adjustment = 1 exec_mode = 0 cur_invoke_parameter_size = 0 Thread = 0x00007f28b401b000, thread ID = 9569 Interpreted frames: Test.test()V (bci 2) - sp: 0x00007f28bcf43800 - thread: "main" #1 prio=5 os_prio=0 tid=0x00007f28b401b000 nid=0x2561 runnable [0x00007f28bcf42000] java.lang.Thread.State: RUNNABLE JavaThread state: _thread_in_Java Thread: 0x00007f28b401b000 [0x2561] State: _running _has_called_back 0 _at_poll_safepoint 0 JavaThread state: _thread_in_Java - frame size: 8 - interpreter_frame -> sp: 0x00007f28bcf437e0 Here's the ScopeDesc which only has one expression stack element (the 'this' oop for the subsequent call to m()): ScopeDesc(pc=0x00007f28a573ddb6 offset=156): Test::test@2 (line 10) Locals - l0: reg r8 [16],oop Expression stack - @0: reg r8 [16],oop The problem is that the code uses the interpreter oop map to get the stack size of the next instruction ('next_mask_expression_stack_size'). However, for calls, the oop map contains the state *after* the instruction, i.e., after the invokevirtual call: 0 vars = 'r' stack = '' monitors = '' aload_0 1 vars = 'r' stack = 'r' monitors = '' iconst_0 2 vars = 'r' stack = 'rv' monitors = '' anewarray 5 vars = 'r' stack = 'rr' monitors = '' invokevirtual([Ljava/lang/Object;)V 8 vars = 'r' stack = '' monitors = '' return With next_mask_expression_stack_size = 0, the result of 'next_mask_expression_stack_size - top_frame_expression_stack_adjustment' is negative and verification fails. The fix is to add a special case for invoke bytecodes and use the parameter size instead of the oop map in that case: http://cr.openjdk.java.net/~thartmann/8148871/webrev.00/
27-02-2018

9-defer-request: Crash in fastdebug that appears only if VerifyStack develop flag is enabled. The flag is disabled by default.
31-08-2016

9-defer-SQE-ok: agreed on deferral reason
31-08-2016

ILW = crash in fastdebug; single test with -XX:+VerifyStack option only; none = MLH = P4
07-06-2016