Max stack is badly calculated with COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES on specific methods
When instrumenting certain Java 11 classes and methods, max stack depth is badly calculated using COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES
.
Consequently, the JVM crashes due to internal verification error when the faulty class objects are collected during GC (in GenerateOopMap).
On the faulty methods, the max stack value calculated with COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES is typically 2 less than the correct max stack value (using javac as the reference). When forcing COMPUTE_MAX_STACK_AND_LOCAL, max_stack is calculated correctly.
We have observed the issue with these methods:
- java.util.ServiceLoader.loadProvider
- sun.reflect.annotation.AnnotationParser.parseAnnotation2
Specifically, loadProvider bytecode contains invokedynamic, which may be a hint (however, parseAnnotation2 does not).
For parseAnnotation2, ASM calculated stack of 2 is clearly wrong, since the function contains a sequence of 4 aloads. javac calculated stack is 4.
The issue reproduced with different Java 9-11 versions on Linux.
Attached relevant class files and disassembly (from openjdk-11.0.3+7 on Ubuntu 16.04):
java_util_ServiceLoader_loadProvider.disasm.txt (correct stack = 6, ASM result = 4)
ServiceLoader.class
sun_reflect_annotation_AnnotationParser_parseAnnotation2_disasm.txt (correct stack = 4, ASM result = 2)
AnnotationParser.class