8271140: Fix native frame handling in vframeStream::asJavaVFrame()

Reviewed-by: dnsimon, kvn, never
This commit is contained in:
Andreas Woess 2021-07-26 19:47:34 +00:00 committed by Tom Rodriguez
parent b8f79a7ff7
commit 3aadae2077
2 changed files with 63 additions and 41 deletions

View File

@ -574,23 +574,24 @@ void vframeStreamCommon::skip_prefixed_method_and_wrappers() {
javaVFrame* vframeStreamCommon::asJavaVFrame() {
javaVFrame* result = NULL;
if (_mode == compiled_mode) {
assert(_frame.is_compiled_frame() || _frame.is_native_frame(), "expected compiled Java frame");
// lazy update to register map
bool update_map = true;
RegisterMap map(_thread, update_map);
frame f = _prev_frame.sender(&map);
assert(f.is_compiled_frame() || f.is_native_frame(), "expected compiled Java frame");
compiledVFrame* cvf = compiledVFrame::cast(vframe::new_vframe(&f, &map, _thread));
assert(cvf->cb() == cb(), "wrong code blob");
if (cvf->scope() == NULL) {
// native nmethods have no scope
assert(f.is_native_frame(), "expected native frame");
compiledVFrame* cvf;
if (_frame.is_native_frame()) {
cvf = compiledVFrame::cast(vframe::new_vframe(&_frame, &_reg_map, _thread));
assert(cvf->cb() == cb(), "wrong code blob");
} else {
assert(_frame.is_compiled_frame(), "expected compiled Java frame");
// lazy update to register map
bool update_map = true;
RegisterMap map(_thread, update_map);
frame f = _prev_frame.sender(&map);
assert(f.is_compiled_frame(), "expected compiled Java frame");
cvf = compiledVFrame::cast(vframe::new_vframe(&f, &map, _thread));
assert(cvf->cb() == cb(), "wrong code blob");
// get the same scope as this stream
cvf = cvf->at_scope(_decode_offset, _vframe_id);

View File

@ -25,11 +25,7 @@
* @test
* @bug 8269592
*
* @requires vm.jvmci & vm.compMode == "Xmixed"
* @requires vm.opt.final.EliminateAllocations == true
*
* @comment no "-Xcomp -XX:-TieredCompilation" combination allowed until JDK-8140018 is resolved
* @requires vm.opt.TieredCompilation == null | vm.opt.TieredCompilation == true
* @requires vm.jvmci
*
* @library / /test/lib
* @library ../common/patches
@ -46,21 +42,25 @@
* @run main/othervm -Xbatch -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
* -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
* -XX:+DoEscapeAnalysis -XX:-UseCounterDecay
* compiler.jvmci.compilerToVM.IterateFramesNative
* @run main/othervm -Xcomp -Xbootclasspath/a:.
* -XX:CompileOnly=compiler.jvmci.compilerToVM.IterateFramesNative::callerNative
* -XX:CompileOnly=jdk.vm.ci.hotspot.CompilerToVM::iterateFrames
* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
* -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
* -Dcompiler.jvmci.compilerToVM.IterateFramesNative.checkCompiled=true
* compiler.jvmci.compilerToVM.IterateFramesNative
*/
package compiler.jvmci.compilerToVM;
import compiler.jvmci.common.CTVMUtilities;
import compiler.testlibrary.CompilerUtils;
import compiler.whitebox.CompilerWhiteBoxTest;
import jdk.test.lib.Asserts;
import jdk.vm.ci.code.stack.InspectedFrame;
import jdk.vm.ci.code.stack.InspectedFrameVisitor;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
import jdk.vm.ci.hotspot.HotSpotStackFrameReference;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jtreg.SkippedException;
import sun.hotspot.WhiteBox;
import java.lang.reflect.Method;
@ -68,38 +68,38 @@ import java.util.concurrent.atomic.AtomicInteger;
public class IterateFramesNative {
private static final WhiteBox WB;
private static final int COMPILE_THRESHOLD;
private static final Method NATIVE_METHOD;
private static final Method ITERATE_FRAMES_METHOD;
private static final ResolvedJavaMethod NATIVE_METHOD_RESOLVED;
private static final ResolvedJavaMethod NATIVE_CALLBACK_METHOD_RESOLVED;
private static final boolean CHECK_COMPILED;
static {
Method nativeMethod;
Method nativeCallbackMethod;
WB = WhiteBox.getWhiteBox();
try {
nativeMethod = IterateFramesNative.class.getDeclaredMethod("callerNative",
NATIVE_METHOD = IterateFramesNative.class.getDeclaredMethod("callerNative",
Runnable.class);
nativeCallbackMethod = IterateFramesNative.class.getDeclaredMethod("testNativeFrameCallback",
Helper.class, int.class);
ITERATE_FRAMES_METHOD = CompilerToVMHelper.CompilerToVMClass().getDeclaredMethod(
"iterateFrames",
ResolvedJavaMethod[].class,
ResolvedJavaMethod[].class,
int.class,
InspectedFrameVisitor.class);
} catch (NoSuchMethodException e) {
throw new Error("Can't get executable for test method", e);
}
NATIVE_METHOD_RESOLVED = CTVMUtilities.getResolvedMethod(nativeMethod);
NATIVE_METHOD_RESOLVED = CTVMUtilities.getResolvedMethod(NATIVE_METHOD);
NATIVE_CALLBACK_METHOD_RESOLVED = CTVMUtilities.getResolvedMethod(nativeCallbackMethod);
COMPILE_THRESHOLD = WB.getBooleanVMFlag("TieredCompilation")
? CompilerWhiteBoxTest.THRESHOLD
: CompilerWhiteBoxTest.THRESHOLD * 2;
CHECK_COMPILED = Boolean.getBoolean(
"compiler.jvmci.compilerToVM.IterateFramesNative.checkCompiled");
loadNativeLibrary();
}
public static void main(String[] args) {
int levels[] = CompilerUtils.getAvailableCompilationLevels();
// we need compilation level 4 to use EscapeAnalysis
if (levels.length < 1 || levels[levels.length - 1] != 4) {
throw new SkippedException("Test needs compilation level 4");
}
new IterateFramesNative().test();
}
@ -116,17 +116,38 @@ public class IterateFramesNative {
System.loadLibrary("IterateFramesNative");
}
public static native void callerNative(Runnable runnable);
private void testNativeFrame(String str, int iteration) {
Helper innerHelper = new Helper("foo");
Helper innerHelper = new Helper(str);
callerNative(() -> testNativeFrameCallback(innerHelper, iteration));
Asserts.assertEQ(innerHelper.string, NATIVE_METHOD_RESOLVED.getName(),
"Native frame not found?: " + NATIVE_METHOD_RESOLVED.getName());
if (CHECK_COMPILED) {
Asserts.assertTrue(WB.isMethodCompiled(ITERATE_FRAMES_METHOD),
"Expected native method to be compiled: " + ITERATE_FRAMES_METHOD);
Asserts.assertTrue(WB.isMethodCompiled(NATIVE_METHOD),
"Expected native method to be compiled: " + NATIVE_METHOD);
}
}
public static native void callerNative(Runnable runnable);
private void testNativeFrameCallback(Helper helper, int iteration) {
HotSpotStackFrameReference initialFrame = CompilerToVMHelper.iterateFrames(
null,
null,
0,
f -> {
HotSpotStackFrameReference frame = (HotSpotStackFrameReference) f;
Asserts.assertNotNull(frame, "got null frame for native method");
return frame;
});
Asserts.assertNotNull(initialFrame, "frame must not be null");
Asserts.assertEQ(initialFrame.getMethod().getName(), "iterateFrames",
"Expected initial frame method to be CompilerToVM.iterateFrames");
AtomicInteger frameCounter = new AtomicInteger();
ResolvedJavaMethod[] methods = new ResolvedJavaMethod[] {NATIVE_METHOD_RESOLVED, NATIVE_CALLBACK_METHOD_RESOLVED};
CompilerToVMHelper.iterateFrames(