8246378: [Windows] assert on MethodHandle logging code
Reviewed-by: iklam, vlivanov
This commit is contained in:
parent
98a5d5a6ee
commit
e7c7469cf5
@ -33,7 +33,6 @@
|
||||
// Implementation of the platform-specific part of StubRoutines - for
|
||||
// a description of how to extend it, see the stubRoutines.hpp file.
|
||||
|
||||
address StubRoutines::aarch64::_get_previous_fp_entry = NULL;
|
||||
address StubRoutines::aarch64::_get_previous_sp_entry = NULL;
|
||||
|
||||
address StubRoutines::aarch64::_f2i_fixup = NULL;
|
||||
|
@ -43,7 +43,6 @@ class aarch64 {
|
||||
friend class StubGenerator;
|
||||
|
||||
private:
|
||||
static address _get_previous_fp_entry;
|
||||
static address _get_previous_sp_entry;
|
||||
|
||||
static address _f2i_fixup;
|
||||
@ -77,11 +76,6 @@ class aarch64 {
|
||||
|
||||
public:
|
||||
|
||||
static address get_previous_fp_entry()
|
||||
{
|
||||
return _get_previous_fp_entry;
|
||||
}
|
||||
|
||||
static address get_previous_sp_entry()
|
||||
{
|
||||
return _get_previous_sp_entry;
|
||||
|
@ -528,6 +528,12 @@ void trace_method_handle_stub(const char* adaptername,
|
||||
}
|
||||
tty->cr();
|
||||
|
||||
// Note: We want to allow trace_method_handle from any call site.
|
||||
// While trace_method_handle creates a frame, it may be entered
|
||||
// without a PC on the stack top (e.g. not just after a call).
|
||||
// Walking that frame could lead to failures due to that invalid PC.
|
||||
// => carefully detect that frame when doing the stack walking
|
||||
|
||||
{
|
||||
// dumping last frame with frame::describe
|
||||
|
||||
@ -536,43 +542,38 @@ void trace_method_handle_stub(const char* adaptername,
|
||||
PRESERVE_EXCEPTION_MARK; // may not be needed but safer and inexpensive here
|
||||
FrameValues values;
|
||||
|
||||
// Note: We want to allow trace_method_handle from any call site.
|
||||
// While trace_method_handle creates a frame, it may be entered
|
||||
// without a PC on the stack top (e.g. not just after a call).
|
||||
// Walking that frame could lead to failures due to that invalid PC.
|
||||
// => carefully detect that frame when doing the stack walking
|
||||
|
||||
// Current C frame
|
||||
frame cur_frame = os::current_frame();
|
||||
|
||||
// Robust search of trace_calling_frame (independant of inlining).
|
||||
// Assumes saved_regs comes from a pusha in the trace_calling_frame.
|
||||
assert(cur_frame.sp() < saved_regs, "registers not saved on stack ?");
|
||||
frame trace_calling_frame = os::get_sender_for_C_frame(&cur_frame);
|
||||
while (trace_calling_frame.fp() < saved_regs) {
|
||||
trace_calling_frame = os::get_sender_for_C_frame(&trace_calling_frame);
|
||||
}
|
||||
if (cur_frame.fp() != 0) { // not walkable
|
||||
|
||||
// safely create a frame and call frame::describe
|
||||
intptr_t *dump_sp = trace_calling_frame.sender_sp();
|
||||
intptr_t *dump_fp = trace_calling_frame.link();
|
||||
// Robust search of trace_calling_frame (independent of inlining).
|
||||
// Assumes saved_regs comes from a pusha in the trace_calling_frame.
|
||||
assert(cur_frame.sp() < saved_regs, "registers not saved on stack ?");
|
||||
frame trace_calling_frame = os::get_sender_for_C_frame(&cur_frame);
|
||||
while (trace_calling_frame.fp() < saved_regs) {
|
||||
trace_calling_frame = os::get_sender_for_C_frame(&trace_calling_frame);
|
||||
}
|
||||
|
||||
bool walkable = has_mh; // whether the traced frame shoud be walkable
|
||||
// safely create a frame and call frame::describe
|
||||
intptr_t *dump_sp = trace_calling_frame.sender_sp();
|
||||
intptr_t *dump_fp = trace_calling_frame.link();
|
||||
|
||||
if (walkable) {
|
||||
// The previous definition of walkable may have to be refined
|
||||
// if new call sites cause the next frame constructor to start
|
||||
// failing. Alternatively, frame constructors could be
|
||||
// modified to support the current or future non walkable
|
||||
// frames (but this is more intrusive and is not considered as
|
||||
// part of this RFE, which will instead use a simpler output).
|
||||
frame dump_frame = frame(dump_sp, dump_fp);
|
||||
dump_frame.describe(values, 1);
|
||||
} else {
|
||||
// Stack may not be walkable (invalid PC above FP):
|
||||
// Add descriptions without building a Java frame to avoid issues
|
||||
values.describe(-1, dump_fp, "fp for #1 <not parsed, cannot trust pc>");
|
||||
values.describe(-1, dump_sp, "sp for #1");
|
||||
if (has_mh) {
|
||||
// The previous definition of walkable may have to be refined
|
||||
// if new call sites cause the next frame constructor to start
|
||||
// failing. Alternatively, frame constructors could be
|
||||
// modified to support the current or future non walkable
|
||||
// frames (but this is more intrusive and is not considered as
|
||||
// part of this RFE, which will instead use a simpler output).
|
||||
frame dump_frame = frame(dump_sp, dump_fp);
|
||||
dump_frame.describe(values, 1);
|
||||
} else {
|
||||
// Stack may not be walkable (invalid PC above FP):
|
||||
// Add descriptions without building a Java frame to avoid issues
|
||||
values.describe(-1, dump_fp, "fp for #1 <not parsed, cannot trust pc>");
|
||||
values.describe(-1, dump_sp, "sp for #1");
|
||||
}
|
||||
}
|
||||
values.describe(-1, entry_sp, "raw top of stack");
|
||||
|
||||
|
@ -566,26 +566,6 @@ class StubGenerator: public StubCodeGenerator {
|
||||
return start;
|
||||
}
|
||||
|
||||
// Support for intptr_t get_previous_fp()
|
||||
//
|
||||
// This routine is used to find the previous frame pointer for the
|
||||
// caller (current_frame_guess). This is used as part of debugging
|
||||
// ps() is seemingly lost trying to find frames.
|
||||
// This code assumes that caller current_frame_guess) has a frame.
|
||||
address generate_get_previous_fp() {
|
||||
StubCodeMark mark(this, "StubRoutines", "get_previous_fp");
|
||||
const Address old_fp(rbp, 0);
|
||||
const Address older_fp(rax, 0);
|
||||
address start = __ pc();
|
||||
|
||||
__ enter();
|
||||
__ movptr(rax, old_fp); // callers fp
|
||||
__ movptr(rax, older_fp); // the frame for ps()
|
||||
__ pop(rbp);
|
||||
__ ret(0);
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
// Support for intptr_t get_previous_sp()
|
||||
//
|
||||
@ -6717,7 +6697,6 @@ address generate_avx_ghash_processBlocks() {
|
||||
StubRoutines::_fence_entry = generate_orderaccess_fence();
|
||||
|
||||
// platform dependent
|
||||
StubRoutines::x86::_get_previous_fp_entry = generate_get_previous_fp();
|
||||
StubRoutines::x86::_get_previous_sp_entry = generate_get_previous_sp();
|
||||
|
||||
StubRoutines::x86::_verify_mxcsr_entry = generate_verify_mxcsr();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -42,7 +42,6 @@ class x86 {
|
||||
|
||||
#ifdef _LP64
|
||||
private:
|
||||
static address _get_previous_fp_entry;
|
||||
static address _get_previous_sp_entry;
|
||||
|
||||
static address _f2i_fixup;
|
||||
@ -57,10 +56,6 @@ class x86 {
|
||||
|
||||
public:
|
||||
|
||||
static address get_previous_fp_entry() {
|
||||
return _get_previous_fp_entry;
|
||||
}
|
||||
|
||||
static address get_previous_sp_entry() {
|
||||
return _get_previous_sp_entry;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -31,7 +31,6 @@
|
||||
// Implementation of the platform-specific part of StubRoutines - for
|
||||
// a description of how to extend it, see the stubRoutines.hpp file.
|
||||
|
||||
address StubRoutines::x86::_get_previous_fp_entry = NULL;
|
||||
address StubRoutines::x86::_get_previous_sp_entry = NULL;
|
||||
|
||||
address StubRoutines::x86::_f2i_fixup = NULL;
|
||||
|
@ -142,32 +142,14 @@ bool os::win32::get_frame_at_stack_banging_point(JavaThread* thread,
|
||||
return true;
|
||||
}
|
||||
|
||||
// By default, gcc always saves frame pointer rfp on this stack. This
|
||||
// may get turned off by -fomit-frame-pointer.
|
||||
frame os::get_sender_for_C_frame(frame* fr) {
|
||||
return frame(fr->link(), fr->link(), fr->sender_pc());
|
||||
ShouldNotReachHere();
|
||||
return frame();
|
||||
}
|
||||
|
||||
frame os::current_frame() {
|
||||
typedef intptr_t* get_fp_func ();
|
||||
get_fp_func* func = CAST_TO_FN_PTR(get_fp_func*,
|
||||
StubRoutines::aarch64::get_previous_fp_entry());
|
||||
if (func == NULL) return frame();
|
||||
intptr_t* fp = (*func)();
|
||||
if (fp == NULL) {
|
||||
return frame();
|
||||
}
|
||||
|
||||
frame myframe((intptr_t*)os::current_stack_pointer(),
|
||||
(intptr_t*)fp,
|
||||
CAST_FROM_FN_PTR(address, os::current_frame));
|
||||
if (os::is_first_C_frame(&myframe)) {
|
||||
|
||||
// stack is not walkable
|
||||
return frame();
|
||||
} else {
|
||||
return os::get_sender_for_C_frame(&myframe);
|
||||
}
|
||||
return frame(); // cannot walk Windows frames this way. See os::get_native_stack
|
||||
// and os::platform_print_native_stack
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -323,13 +323,6 @@ frame os::fetch_frame_from_context(const void* ucVoid) {
|
||||
return frame(sp, fp, epc);
|
||||
}
|
||||
|
||||
// VC++ does not save frame pointer on stack in optimized build. It
|
||||
// can be turned off by /Oy-. If we really want to walk C frames,
|
||||
// we can use the StackWalk() API.
|
||||
frame os::get_sender_for_C_frame(frame* fr) {
|
||||
return frame(fr->sender_sp(), fr->link(), fr->sender_pc());
|
||||
}
|
||||
|
||||
#ifndef AMD64
|
||||
// Ignore "C4172: returning address of local variable or temporary" on 32bit
|
||||
PRAGMA_DIAG_PUSH
|
||||
@ -390,49 +383,18 @@ bool os::win32::get_frame_at_stack_banging_point(JavaThread* thread,
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef AMD64
|
||||
intptr_t* _get_previous_fp() {
|
||||
intptr_t **frameptr;
|
||||
__asm {
|
||||
mov frameptr, ebp
|
||||
};
|
||||
// ebp (frameptr) is for this frame (_get_previous_fp). We want the ebp for the
|
||||
// caller of os::current_frame*(), so go up two frames. However, for
|
||||
// optimized builds, _get_previous_fp() will be inlined, so only go
|
||||
// up 1 frame in that case.
|
||||
#ifdef _NMT_NOINLINE_
|
||||
return **(intptr_t***)frameptr;
|
||||
#else
|
||||
return *frameptr;
|
||||
#endif
|
||||
|
||||
// VC++ does not save frame pointer on stack in optimized build. It
|
||||
// can be turned off by /Oy-. If we really want to walk C frames,
|
||||
// we can use the StackWalk() API.
|
||||
frame os::get_sender_for_C_frame(frame* fr) {
|
||||
ShouldNotReachHere();
|
||||
return frame();
|
||||
}
|
||||
#endif // !AMD64
|
||||
|
||||
frame os::current_frame() {
|
||||
|
||||
#ifdef AMD64
|
||||
// apparently _asm not supported on windows amd64
|
||||
typedef intptr_t* get_fp_func ();
|
||||
get_fp_func* func = CAST_TO_FN_PTR(get_fp_func*,
|
||||
StubRoutines::x86::get_previous_fp_entry());
|
||||
if (func == NULL) return frame();
|
||||
intptr_t* fp = (*func)();
|
||||
if (fp == NULL) {
|
||||
return frame();
|
||||
}
|
||||
#else
|
||||
intptr_t* fp = _get_previous_fp();
|
||||
#endif // AMD64
|
||||
|
||||
frame myframe((intptr_t*)os::current_stack_pointer(),
|
||||
(intptr_t*)fp,
|
||||
CAST_FROM_FN_PTR(address, os::current_frame));
|
||||
if (os::is_first_C_frame(&myframe)) {
|
||||
// stack is not walkable
|
||||
return frame();
|
||||
} else {
|
||||
return os::get_sender_for_C_frame(&myframe);
|
||||
}
|
||||
return frame(); // cannot walk Windows frames this way. See os::get_native_stack
|
||||
// and os::platform_print_native_stack
|
||||
}
|
||||
|
||||
void os::print_context(outputStream *st, const void *context) {
|
||||
|
@ -1170,9 +1170,13 @@ void os::print_location(outputStream* st, intptr_t x, bool verbose) {
|
||||
}
|
||||
|
||||
// Looks like all platforms can use the same function to check if C
|
||||
// stack is walkable beyond current frame. The check for fp() is not
|
||||
// necessary on Sparc, but it's harmless.
|
||||
// stack is walkable beyond current frame.
|
||||
bool os::is_first_C_frame(frame* fr) {
|
||||
|
||||
#ifdef _WINDOWS
|
||||
return true; // native stack isn't walkable on windows this way.
|
||||
#endif
|
||||
|
||||
// Load up sp, fp, sender sp and sender fp, check for reasonable values.
|
||||
// Check usp first, because if that's bad the other accessors may fault
|
||||
// on some architectures. Ditto ufp second, etc.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -31,7 +31,7 @@
|
||||
* java.instrument
|
||||
* @requires vm.jvmti
|
||||
* @run main RedefineClassHelper
|
||||
* @run main/othervm -Xmx256m -XX:MaxMetaspaceSize=64m -javaagent:redefineagent.jar -Xlog:all=trace:file=all.log RedefineClasses
|
||||
* @run main/othervm -Xmx256m -XX:MaxMetaspaceSize=64m -javaagent:redefineagent.jar -XX:+Verbose -Xlog:all=trace:file=all.log RedefineClasses
|
||||
*/
|
||||
|
||||
// package access top-level class to avoid problem with RedefineClassHelper
|
||||
|
@ -26,10 +26,11 @@
|
||||
* @bug 8244946
|
||||
* @summary Run simple test with -XX:+Verbose and -Xlog:methodhandles.
|
||||
*
|
||||
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+Verbose -Xlog:methodhandles TestMethodHandlesVerbose
|
||||
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+Verbose -Xlog:methodhandles TestMethodHandlesVerbose a b
|
||||
*/
|
||||
|
||||
public class TestMethodHandlesVerbose {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(args[0] + args[1]);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user