mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-11 14:11:36 +00:00
Merge
This commit is contained in:
commit
2ad60b9910
@ -4680,7 +4680,7 @@ encode %{
|
||||
Label retaddr;
|
||||
__ adr(rscratch2, retaddr);
|
||||
__ lea(rscratch1, RuntimeAddress(entry));
|
||||
// Leave a breadcrumb for JavaThread::pd_last_frame().
|
||||
// Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc()
|
||||
__ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize)));
|
||||
__ blrt(rscratch1, gpcnt, fpcnt, rtype);
|
||||
__ bind(retaddr);
|
||||
|
||||
@ -78,7 +78,7 @@ int StubAssembler::call_RT(Register oop_result1, Register metadata_result, addre
|
||||
}
|
||||
pop(r0, sp);
|
||||
#endif
|
||||
reset_last_Java_frame(true, true);
|
||||
reset_last_Java_frame(true);
|
||||
maybe_isb();
|
||||
|
||||
// check for pending exceptions
|
||||
@ -547,7 +547,7 @@ OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) {
|
||||
__ bind(L);
|
||||
}
|
||||
#endif
|
||||
__ reset_last_Java_frame(true, false);
|
||||
__ reset_last_Java_frame(true);
|
||||
__ maybe_isb();
|
||||
|
||||
// check for pending exceptions
|
||||
|
||||
@ -336,13 +336,16 @@ frame frame::sender_for_entry_frame(RegisterMap* map) const {
|
||||
JavaFrameAnchor* jfa = entry_frame_call_wrapper()->anchor();
|
||||
assert(!entry_frame_is_first(), "next Java fp must be non zero");
|
||||
assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack");
|
||||
// Since we are walking the stack now this nested anchor is obviously walkable
|
||||
// even if it wasn't when it was stacked.
|
||||
if (!jfa->walkable()) {
|
||||
// Capture _last_Java_pc (if needed) and mark anchor walkable.
|
||||
jfa->capture_last_Java_pc();
|
||||
}
|
||||
map->clear();
|
||||
assert(map->include_argument_oops(), "should be set by clear");
|
||||
if (jfa->last_Java_pc() != NULL ) {
|
||||
frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc());
|
||||
return fr;
|
||||
}
|
||||
frame fr(jfa->last_Java_sp(), jfa->last_Java_fp());
|
||||
vmassert(jfa->last_Java_pc() != NULL, "not walkable");
|
||||
frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc());
|
||||
return fr;
|
||||
}
|
||||
|
||||
@ -769,3 +772,21 @@ frame::frame(void* sp, void* fp, void* pc) {
|
||||
init((intptr_t*)sp, (intptr_t*)fp, (address)pc);
|
||||
}
|
||||
#endif
|
||||
|
||||
void JavaFrameAnchor::make_walkable(JavaThread* thread) {
|
||||
// last frame set?
|
||||
if (last_Java_sp() == NULL) return;
|
||||
// already walkable?
|
||||
if (walkable()) return;
|
||||
vmassert(Thread::current() == (Thread*)thread, "not current thread");
|
||||
vmassert(last_Java_sp() != NULL, "not called from Java code?");
|
||||
vmassert(last_Java_pc() == NULL, "already walkable");
|
||||
capture_last_Java_pc();
|
||||
vmassert(walkable(), "something went wrong");
|
||||
}
|
||||
|
||||
void JavaFrameAnchor::capture_last_Java_pc() {
|
||||
vmassert(_last_Java_sp != NULL, "no last frame set");
|
||||
vmassert(_last_Java_pc == NULL, "already walkable");
|
||||
_last_Java_pc = (address)_last_Java_sp[-1];
|
||||
}
|
||||
|
||||
@ -201,7 +201,7 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
||||
// #endif
|
||||
MacroAssembler::null_check(reg, offset);
|
||||
// #ifdef ASSERT
|
||||
// reset_last_Java_frame(true, false);
|
||||
// reset_last_Java_frame(true);
|
||||
// #endif
|
||||
}
|
||||
|
||||
|
||||
@ -64,10 +64,9 @@ public:
|
||||
_last_Java_sp = src->_last_Java_sp;
|
||||
}
|
||||
|
||||
// Always walkable
|
||||
bool walkable(void) { return true; }
|
||||
// Never any thing to do since we are always walkable and can find address of return addresses
|
||||
void make_walkable(JavaThread* thread) { }
|
||||
bool walkable(void) { return _last_Java_sp != NULL && _last_Java_pc != NULL; }
|
||||
void make_walkable(JavaThread* thread);
|
||||
void capture_last_Java_pc(void);
|
||||
|
||||
intptr_t* last_Java_sp(void) const { return _last_Java_sp; }
|
||||
|
||||
|
||||
@ -274,19 +274,18 @@ void MacroAssembler::serialize_memory(Register thread, Register tmp) {
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::reset_last_Java_frame(bool clear_fp,
|
||||
bool clear_pc) {
|
||||
void MacroAssembler::reset_last_Java_frame(bool clear_fp) {
|
||||
// we must set sp to zero to clear frame
|
||||
str(zr, Address(rthread, JavaThread::last_Java_sp_offset()));
|
||||
|
||||
// must clear fp, so that compiled frames are not confused; it is
|
||||
// possible that we need it only for debugging
|
||||
if (clear_fp) {
|
||||
str(zr, Address(rthread, JavaThread::last_Java_fp_offset()));
|
||||
}
|
||||
|
||||
if (clear_pc) {
|
||||
str(zr, Address(rthread, JavaThread::last_Java_pc_offset()));
|
||||
}
|
||||
// Always clear the pc because it could have been set by make_walkable()
|
||||
str(zr, Address(rthread, JavaThread::last_Java_pc_offset()));
|
||||
}
|
||||
|
||||
// Calls to C land
|
||||
@ -632,7 +631,7 @@ void MacroAssembler::call_VM_base(Register oop_result,
|
||||
|
||||
// reset last Java frame
|
||||
// Only interpreter should have to clear fp
|
||||
reset_last_Java_frame(true, true);
|
||||
reset_last_Java_frame(true);
|
||||
|
||||
// C++ interp handles this in the interpreter
|
||||
check_and_handle_popframe(java_thread);
|
||||
@ -875,7 +874,7 @@ void MacroAssembler:: notify(int type) {
|
||||
if (type == bytecode_start) {
|
||||
// set_last_Java_frame(esp, rfp, (address)NULL);
|
||||
Assembler:: notify(type);
|
||||
// reset_last_Java_frame(true, false);
|
||||
// reset_last_Java_frame(true);
|
||||
}
|
||||
else
|
||||
Assembler:: notify(type);
|
||||
|
||||
@ -757,10 +757,10 @@ public:
|
||||
Register last_java_pc,
|
||||
Register scratch);
|
||||
|
||||
void reset_last_Java_frame(Register thread, bool clearfp, bool clear_pc);
|
||||
void reset_last_Java_frame(Register thread);
|
||||
|
||||
// thread in the default location (r15_thread on 64bit)
|
||||
void reset_last_Java_frame(bool clear_fp, bool clear_pc);
|
||||
// thread in the default location (rthread)
|
||||
void reset_last_Java_frame(bool clear_fp);
|
||||
|
||||
// Stores
|
||||
void store_check(Register obj); // store check for obj - register is destroyed afterwards
|
||||
|
||||
@ -2030,7 +2030,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
__ bind(dtrace_method_exit_done);
|
||||
}
|
||||
|
||||
__ reset_last_Java_frame(false, true);
|
||||
__ reset_last_Java_frame(false);
|
||||
|
||||
// Unpack oop result
|
||||
if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
|
||||
@ -2370,7 +2370,7 @@ void SharedRuntime::generate_deopt_blob() {
|
||||
__ bind(retaddr);
|
||||
oop_maps->add_gc_map( __ pc()-start, map->deep_copy());
|
||||
|
||||
__ reset_last_Java_frame(false, false);
|
||||
__ reset_last_Java_frame(false);
|
||||
|
||||
__ b(after_fetch_unroll_info_call);
|
||||
} // EnableJVMCI
|
||||
@ -2465,7 +2465,7 @@ void SharedRuntime::generate_deopt_blob() {
|
||||
// find any register it might need.
|
||||
oop_maps->add_gc_map(__ pc() - start, map);
|
||||
|
||||
__ reset_last_Java_frame(false, true);
|
||||
__ reset_last_Java_frame(false);
|
||||
|
||||
#if INCLUDE_JVMCI
|
||||
if (EnableJVMCI) {
|
||||
@ -2606,7 +2606,7 @@ void SharedRuntime::generate_deopt_blob() {
|
||||
new OopMap( frame_size_in_words, 0 ));
|
||||
|
||||
// Clear fp AND pc
|
||||
__ reset_last_Java_frame(true, true);
|
||||
__ reset_last_Java_frame(true);
|
||||
|
||||
// Collect return values
|
||||
__ ldrd(v0, Address(sp, RegisterSaver::v0_offset_in_bytes()));
|
||||
@ -2709,7 +2709,7 @@ void SharedRuntime::generate_uncommon_trap_blob() {
|
||||
|
||||
oop_maps->add_gc_map(__ pc() - start, map);
|
||||
|
||||
__ reset_last_Java_frame(false, true);
|
||||
__ reset_last_Java_frame(false);
|
||||
|
||||
// move UnrollBlock* into r4
|
||||
__ mov(r4, r0);
|
||||
@ -2828,7 +2828,7 @@ void SharedRuntime::generate_uncommon_trap_blob() {
|
||||
oop_maps->add_gc_map(the_pc - start, new OopMap(SimpleRuntimeFrame::framesize, 0));
|
||||
|
||||
// Clear fp AND pc
|
||||
__ reset_last_Java_frame(true, true);
|
||||
__ reset_last_Java_frame(true);
|
||||
|
||||
// Pop self-frame.
|
||||
__ leave(); // Epilog
|
||||
@ -2906,7 +2906,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t
|
||||
|
||||
Label noException;
|
||||
|
||||
__ reset_last_Java_frame(false, true);
|
||||
__ reset_last_Java_frame(false);
|
||||
|
||||
__ maybe_isb();
|
||||
__ membar(Assembler::LoadLoad | Assembler::LoadStore);
|
||||
@ -2985,7 +2985,7 @@ RuntimeStub* SharedRuntime::generate_resolve_blob(address destination, const cha
|
||||
// r0 contains the address we are going to jump to assuming no exception got installed
|
||||
|
||||
// clear last_Java_sp
|
||||
__ reset_last_Java_frame(false, true);
|
||||
__ reset_last_Java_frame(false);
|
||||
// check for pending exceptions
|
||||
Label pending;
|
||||
__ ldr(rscratch1, Address(rthread, Thread::pending_exception_offset()));
|
||||
@ -3116,7 +3116,7 @@ void OptoRuntime::generate_exception_blob() {
|
||||
|
||||
oop_maps->add_gc_map(the_pc - start, new OopMap(SimpleRuntimeFrame::framesize, 0));
|
||||
|
||||
__ reset_last_Java_frame(false, true);
|
||||
__ reset_last_Java_frame(false);
|
||||
|
||||
// Restore callee-saved registers
|
||||
|
||||
|
||||
@ -3801,7 +3801,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
|
||||
oop_maps->add_gc_map(the_pc - start, map);
|
||||
|
||||
__ reset_last_Java_frame(true, true);
|
||||
__ reset_last_Java_frame(true);
|
||||
__ maybe_isb();
|
||||
|
||||
__ leave();
|
||||
|
||||
@ -1353,7 +1353,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||
__ stlrw(rscratch1, rscratch2);
|
||||
|
||||
// reset_last_Java_frame
|
||||
__ reset_last_Java_frame(true, true);
|
||||
__ reset_last_Java_frame(true);
|
||||
|
||||
// reset handle block
|
||||
__ ldr(t, Address(rthread, JavaThread::active_handles_offset()));
|
||||
|
||||
@ -98,7 +98,7 @@ int StubAssembler::call_RT(Register oop_result1, Register metadata_result, addre
|
||||
}
|
||||
pop(rax);
|
||||
#endif
|
||||
reset_last_Java_frame(thread, true, align_stack);
|
||||
reset_last_Java_frame(thread, true);
|
||||
|
||||
// discard thread and arguments
|
||||
NOT_LP64(addptr(rsp, num_rt_args()*BytesPerWord));
|
||||
@ -872,7 +872,7 @@ OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) {
|
||||
}
|
||||
__ pop(rax);
|
||||
#endif
|
||||
__ reset_last_Java_frame(thread, true, false);
|
||||
__ reset_last_Java_frame(thread, true);
|
||||
#ifndef _LP64
|
||||
__ pop(rcx); // discard thread arg
|
||||
__ pop(rcx); // discard dummy
|
||||
|
||||
@ -337,13 +337,16 @@ frame frame::sender_for_entry_frame(RegisterMap* map) const {
|
||||
JavaFrameAnchor* jfa = entry_frame_call_wrapper()->anchor();
|
||||
assert(!entry_frame_is_first(), "next Java fp must be non zero");
|
||||
assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack");
|
||||
// Since we are walking the stack now this nested anchor is obviously walkable
|
||||
// even if it wasn't when it was stacked.
|
||||
if (!jfa->walkable()) {
|
||||
// Capture _last_Java_pc (if needed) and mark anchor walkable.
|
||||
jfa->capture_last_Java_pc();
|
||||
}
|
||||
map->clear();
|
||||
assert(map->include_argument_oops(), "should be set by clear");
|
||||
if (jfa->last_Java_pc() != NULL ) {
|
||||
frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc());
|
||||
return fr;
|
||||
}
|
||||
frame fr(jfa->last_Java_sp(), jfa->last_Java_fp());
|
||||
vmassert(jfa->last_Java_pc() != NULL, "not walkable");
|
||||
frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc());
|
||||
return fr;
|
||||
}
|
||||
|
||||
@ -666,3 +669,21 @@ frame::frame(void* sp, void* fp, void* pc) {
|
||||
init((intptr_t*)sp, (intptr_t*)fp, (address)pc);
|
||||
}
|
||||
#endif
|
||||
|
||||
void JavaFrameAnchor::make_walkable(JavaThread* thread) {
|
||||
// last frame set?
|
||||
if (last_Java_sp() == NULL) return;
|
||||
// already walkable?
|
||||
if (walkable()) return;
|
||||
vmassert(Thread::current() == (Thread*)thread, "not current thread");
|
||||
vmassert(last_Java_sp() != NULL, "not called from Java code?");
|
||||
vmassert(last_Java_pc() == NULL, "already walkable");
|
||||
capture_last_Java_pc();
|
||||
vmassert(walkable(), "something went wrong");
|
||||
}
|
||||
|
||||
void JavaFrameAnchor::capture_last_Java_pc() {
|
||||
vmassert(_last_Java_sp != NULL, "no last frame set");
|
||||
vmassert(_last_Java_pc == NULL, "already walkable");
|
||||
_last_Java_pc = (address)_last_Java_sp[-1];
|
||||
}
|
||||
|
||||
@ -101,6 +101,7 @@ inline frame::frame(intptr_t* sp, intptr_t* fp) {
|
||||
// call a specialized frame constructor instead of this one.
|
||||
// Then we could use the assert below. However this assert is of somewhat dubious
|
||||
// value.
|
||||
// UPDATE: this constructor is only used by trace_method_handle_stub() now.
|
||||
// assert(_pc != NULL, "no pc?");
|
||||
|
||||
_cb = CodeCache::find_blob(_pc);
|
||||
|
||||
@ -62,10 +62,9 @@ public:
|
||||
_last_Java_sp = src->_last_Java_sp;
|
||||
}
|
||||
|
||||
// Always walkable
|
||||
bool walkable(void) { return true; }
|
||||
// Never any thing to do since we are always walkable and can find address of return addresses
|
||||
void make_walkable(JavaThread* thread) { }
|
||||
bool walkable(void) { return _last_Java_sp != NULL && _last_Java_pc != NULL; }
|
||||
void make_walkable(JavaThread* thread);
|
||||
void capture_last_Java_pc(void);
|
||||
|
||||
intptr_t* last_Java_sp(void) const { return _last_Java_sp; }
|
||||
|
||||
|
||||
@ -752,8 +752,7 @@ void MacroAssembler::pushptr(AddressLiteral src) {
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::reset_last_Java_frame(bool clear_fp,
|
||||
bool clear_pc) {
|
||||
void MacroAssembler::reset_last_Java_frame(bool clear_fp) {
|
||||
// we must set sp to zero to clear frame
|
||||
movptr(Address(r15_thread, JavaThread::last_Java_sp_offset()), NULL_WORD);
|
||||
// must clear fp, so that compiled frames are not confused; it is
|
||||
@ -762,9 +761,8 @@ void MacroAssembler::reset_last_Java_frame(bool clear_fp,
|
||||
movptr(Address(r15_thread, JavaThread::last_Java_fp_offset()), NULL_WORD);
|
||||
}
|
||||
|
||||
if (clear_pc) {
|
||||
movptr(Address(r15_thread, JavaThread::last_Java_pc_offset()), NULL_WORD);
|
||||
}
|
||||
// Always clear the pc because it could have been set by make_walkable()
|
||||
movptr(Address(r15_thread, JavaThread::last_Java_pc_offset()), NULL_WORD);
|
||||
}
|
||||
|
||||
void MacroAssembler::set_last_Java_frame(Register last_java_sp,
|
||||
@ -2531,7 +2529,7 @@ void MacroAssembler::call_VM_base(Register oop_result,
|
||||
}
|
||||
// reset last Java frame
|
||||
// Only interpreter should have to clear fp
|
||||
reset_last_Java_frame(java_thread, true, false);
|
||||
reset_last_Java_frame(java_thread, true);
|
||||
|
||||
// C++ interp handles this in the interpreter
|
||||
check_and_handle_popframe(java_thread);
|
||||
@ -3642,8 +3640,7 @@ void MacroAssembler::push_IU_state() {
|
||||
pusha();
|
||||
}
|
||||
|
||||
void MacroAssembler::reset_last_Java_frame(Register java_thread, bool clear_fp, bool clear_pc) {
|
||||
// determine java_thread register
|
||||
void MacroAssembler::reset_last_Java_frame(Register java_thread, bool clear_fp) { // determine java_thread register
|
||||
if (!java_thread->is_valid()) {
|
||||
java_thread = rdi;
|
||||
get_thread(java_thread);
|
||||
@ -3654,8 +3651,8 @@ void MacroAssembler::reset_last_Java_frame(Register java_thread, bool clear_fp,
|
||||
movptr(Address(java_thread, JavaThread::last_Java_fp_offset()), NULL_WORD);
|
||||
}
|
||||
|
||||
if (clear_pc)
|
||||
movptr(Address(java_thread, JavaThread::last_Java_pc_offset()), NULL_WORD);
|
||||
// Always clear the pc because it could have been set by make_walkable()
|
||||
movptr(Address(java_thread, JavaThread::last_Java_pc_offset()), NULL_WORD);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -288,10 +288,10 @@ class MacroAssembler: public Assembler {
|
||||
Register last_java_fp,
|
||||
address last_java_pc);
|
||||
|
||||
void reset_last_Java_frame(Register thread, bool clear_fp, bool clear_pc);
|
||||
void reset_last_Java_frame(Register thread, bool clear_fp);
|
||||
|
||||
// thread in the default location (r15_thread on 64bit)
|
||||
void reset_last_Java_frame(bool clear_fp, bool clear_pc);
|
||||
void reset_last_Java_frame(bool clear_fp);
|
||||
|
||||
// Stores
|
||||
void store_check(Register obj); // store check for obj - register is destroyed afterwards
|
||||
|
||||
@ -117,7 +117,7 @@ void OptoRuntime::generate_exception_blob() {
|
||||
// No registers to map, rbp is known implicitly
|
||||
oop_maps->add_gc_map( __ pc() - start, new OopMap( framesize, 0 ));
|
||||
__ get_thread(rcx);
|
||||
__ reset_last_Java_frame(rcx, false, false);
|
||||
__ reset_last_Java_frame(rcx, false);
|
||||
|
||||
// Restore callee-saved registers
|
||||
__ movptr(rbp, Address(rsp, rbp_off * wordSize));
|
||||
|
||||
@ -1330,7 +1330,7 @@ static void check_needs_gc_for_critical_native(MacroAssembler* masm,
|
||||
__ increment(rsp, wordSize);
|
||||
|
||||
__ get_thread(thread);
|
||||
__ reset_last_Java_frame(thread, false, true);
|
||||
__ reset_last_Java_frame(thread, false);
|
||||
|
||||
save_or_restore_arguments(masm, stack_slots, total_in_args,
|
||||
arg_save_area, NULL, in_regs, in_sig_bt);
|
||||
@ -2224,7 +2224,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
|
||||
// We can finally stop using that last_Java_frame we setup ages ago
|
||||
|
||||
__ reset_last_Java_frame(thread, false, true);
|
||||
__ reset_last_Java_frame(thread, false);
|
||||
|
||||
// Unpack oop result
|
||||
if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
|
||||
@ -2553,7 +2553,7 @@ void SharedRuntime::generate_deopt_blob() {
|
||||
__ pop(rcx);
|
||||
|
||||
__ get_thread(rcx);
|
||||
__ reset_last_Java_frame(rcx, false, false);
|
||||
__ reset_last_Java_frame(rcx, false);
|
||||
|
||||
// Load UnrollBlock into EDI
|
||||
__ mov(rdi, rax);
|
||||
@ -2702,7 +2702,7 @@ void SharedRuntime::generate_deopt_blob() {
|
||||
__ push(rax);
|
||||
|
||||
__ get_thread(rcx);
|
||||
__ reset_last_Java_frame(rcx, false, false);
|
||||
__ reset_last_Java_frame(rcx, false);
|
||||
|
||||
// Collect return values
|
||||
__ movptr(rax,Address(rsp, (RegisterSaver::raxOffset() + additional_words + 1)*wordSize));
|
||||
@ -2806,7 +2806,7 @@ void SharedRuntime::generate_uncommon_trap_blob() {
|
||||
|
||||
__ get_thread(rcx);
|
||||
|
||||
__ reset_last_Java_frame(rcx, false, false);
|
||||
__ reset_last_Java_frame(rcx, false);
|
||||
|
||||
// Load UnrollBlock into EDI
|
||||
__ movptr(rdi, rax);
|
||||
@ -2912,7 +2912,7 @@ void SharedRuntime::generate_uncommon_trap_blob() {
|
||||
oop_maps->add_gc_map( __ pc()-start, new OopMap( framesize, 0 ) );
|
||||
|
||||
__ get_thread(rdi);
|
||||
__ reset_last_Java_frame(rdi, true, false);
|
||||
__ reset_last_Java_frame(rdi, true);
|
||||
|
||||
// Pop self-frame.
|
||||
__ leave(); // Epilog!
|
||||
@ -3007,7 +3007,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t
|
||||
|
||||
// Clear last_Java_sp again
|
||||
__ get_thread(java_thread);
|
||||
__ reset_last_Java_frame(java_thread, false, false);
|
||||
__ reset_last_Java_frame(java_thread, false);
|
||||
|
||||
__ cmpptr(Address(java_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
|
||||
__ jcc(Assembler::equal, noException);
|
||||
@ -3082,7 +3082,7 @@ RuntimeStub* SharedRuntime::generate_resolve_blob(address destination, const cha
|
||||
__ addptr(rsp, wordSize);
|
||||
|
||||
// clear last_Java_sp
|
||||
__ reset_last_Java_frame(thread, true, false);
|
||||
__ reset_last_Java_frame(thread, true);
|
||||
// check for pending exceptions
|
||||
Label pending;
|
||||
__ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
|
||||
|
||||
@ -1461,7 +1461,7 @@ static void check_needs_gc_for_critical_native(MacroAssembler* masm,
|
||||
__ mov(rsp, r12); // restore sp
|
||||
__ reinit_heapbase();
|
||||
|
||||
__ reset_last_Java_frame(false, true);
|
||||
__ reset_last_Java_frame(false);
|
||||
|
||||
save_or_restore_arguments(masm, stack_slots, total_in_args,
|
||||
arg_save_area, NULL, in_regs, in_sig_bt);
|
||||
@ -2577,7 +2577,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
restore_native_result(masm, ret_type, stack_slots);
|
||||
}
|
||||
|
||||
__ reset_last_Java_frame(false, true);
|
||||
__ reset_last_Java_frame(false);
|
||||
|
||||
// Unpack oop result
|
||||
if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
|
||||
@ -2849,7 +2849,7 @@ void SharedRuntime::generate_deopt_blob() {
|
||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap)));
|
||||
oop_maps->add_gc_map( __ pc()-start, map->deep_copy());
|
||||
|
||||
__ reset_last_Java_frame(false, false);
|
||||
__ reset_last_Java_frame(false);
|
||||
|
||||
__ jmp(after_fetch_unroll_info_call);
|
||||
} // EnableJVMCI
|
||||
@ -2939,7 +2939,7 @@ void SharedRuntime::generate_deopt_blob() {
|
||||
// find any register it might need.
|
||||
oop_maps->add_gc_map(__ pc() - start, map);
|
||||
|
||||
__ reset_last_Java_frame(false, false);
|
||||
__ reset_last_Java_frame(false);
|
||||
|
||||
#if INCLUDE_JVMCI
|
||||
if (EnableJVMCI) {
|
||||
@ -3087,7 +3087,7 @@ void SharedRuntime::generate_deopt_blob() {
|
||||
new OopMap( frame_size_in_words, 0 ));
|
||||
|
||||
// Clear fp AND pc
|
||||
__ reset_last_Java_frame(true, true);
|
||||
__ reset_last_Java_frame(true);
|
||||
|
||||
// Collect return values
|
||||
__ movdbl(xmm0, Address(rsp, RegisterSaver::xmm0_offset_in_bytes()));
|
||||
@ -3164,7 +3164,7 @@ void SharedRuntime::generate_uncommon_trap_blob() {
|
||||
|
||||
oop_maps->add_gc_map(__ pc() - start, map);
|
||||
|
||||
__ reset_last_Java_frame(false, false);
|
||||
__ reset_last_Java_frame(false);
|
||||
|
||||
// Load UnrollBlock* into rdi
|
||||
__ mov(rdi, rax);
|
||||
@ -3281,7 +3281,7 @@ void SharedRuntime::generate_uncommon_trap_blob() {
|
||||
oop_maps->add_gc_map(the_pc - start, new OopMap(SimpleRuntimeFrame::framesize, 0));
|
||||
|
||||
// Clear fp AND pc
|
||||
__ reset_last_Java_frame(true, true);
|
||||
__ reset_last_Java_frame(true);
|
||||
|
||||
// Pop self-frame.
|
||||
__ leave(); // Epilog
|
||||
@ -3364,7 +3364,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t
|
||||
|
||||
Label noException;
|
||||
|
||||
__ reset_last_Java_frame(false, false);
|
||||
__ reset_last_Java_frame(false);
|
||||
|
||||
__ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
|
||||
__ jcc(Assembler::equal, noException);
|
||||
@ -3434,7 +3434,7 @@ RuntimeStub* SharedRuntime::generate_resolve_blob(address destination, const cha
|
||||
// rax contains the address we are going to jump to assuming no exception got installed
|
||||
|
||||
// clear last_Java_sp
|
||||
__ reset_last_Java_frame(false, false);
|
||||
__ reset_last_Java_frame(false);
|
||||
// check for pending exceptions
|
||||
Label pending;
|
||||
__ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
|
||||
@ -3809,7 +3809,7 @@ void OptoRuntime::generate_exception_blob() {
|
||||
|
||||
oop_maps->add_gc_map(the_pc - start, new OopMap(SimpleRuntimeFrame::framesize, 0));
|
||||
|
||||
__ reset_last_Java_frame(false, true);
|
||||
__ reset_last_Java_frame(false);
|
||||
|
||||
// Restore callee-saved registers
|
||||
|
||||
|
||||
@ -3766,7 +3766,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
// however can use the register value directly if it is callee saved.
|
||||
__ get_thread(java_thread);
|
||||
|
||||
__ reset_last_Java_frame(java_thread, true, false);
|
||||
__ reset_last_Java_frame(java_thread, true);
|
||||
|
||||
__ leave(); // required for proper stackwalking of RuntimeStub frame
|
||||
|
||||
|
||||
@ -5018,7 +5018,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
|
||||
oop_maps->add_gc_map(the_pc - start, map);
|
||||
|
||||
__ reset_last_Java_frame(true, true);
|
||||
__ reset_last_Java_frame(true);
|
||||
|
||||
__ leave(); // required for proper stackwalking of RuntimeStub frame
|
||||
|
||||
|
||||
@ -1167,7 +1167,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||
__ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_Java);
|
||||
|
||||
// reset_last_Java_frame
|
||||
__ reset_last_Java_frame(thread, true, true);
|
||||
__ reset_last_Java_frame(thread, true);
|
||||
|
||||
// reset handle block
|
||||
__ movptr(t, Address(thread, JavaThread::active_handles_offset()));
|
||||
@ -1659,7 +1659,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() {
|
||||
__ set_last_Java_frame(noreg, rbp, __ pc());
|
||||
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::popframe_move_outgoing_args), r15_thread, c_rarg1, c_rarg2);
|
||||
#endif
|
||||
__ reset_last_Java_frame(thread, true, true);
|
||||
__ reset_last_Java_frame(thread, true);
|
||||
|
||||
// Restore the last_sp and null it out
|
||||
__ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
|
||||
@ -986,7 +986,7 @@ void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
|
||||
emit_opcode(cbuf, 0x58 | RBP_enc);
|
||||
|
||||
if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
|
||||
__ reserved_stack_check();
|
||||
__ reserved_stack_check();
|
||||
}
|
||||
|
||||
if (do_polling() && C->is_method_compilation()) {
|
||||
@ -7355,7 +7355,7 @@ instruct compareAndSwapB(rRegI res,
|
||||
"movzbl $res, $res" %}
|
||||
opcode(0x0F, 0xB0);
|
||||
ins_encode(lock_prefix,
|
||||
REX_reg_mem(newval, mem_ptr),
|
||||
REX_breg_mem(newval, mem_ptr),
|
||||
OpcP, OpcS,
|
||||
reg_mem(newval, mem_ptr),
|
||||
REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
|
||||
@ -7380,7 +7380,7 @@ instruct compareAndSwapS(rRegI res,
|
||||
opcode(0x0F, 0xB1);
|
||||
ins_encode(lock_prefix,
|
||||
SizePrefix,
|
||||
REX_reg_mem(newval, mem_ptr),
|
||||
REX_reg_mem(newval, mem_ptr),
|
||||
OpcP, OpcS,
|
||||
reg_mem(newval, mem_ptr),
|
||||
REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
|
||||
@ -7424,7 +7424,7 @@ instruct compareAndExchangeB(
|
||||
"If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
|
||||
opcode(0x0F, 0xB0);
|
||||
ins_encode(lock_prefix,
|
||||
REX_reg_mem(newval, mem_ptr),
|
||||
REX_breg_mem(newval, mem_ptr),
|
||||
OpcP, OpcS,
|
||||
reg_mem(newval, mem_ptr) // lock cmpxchg
|
||||
);
|
||||
|
||||
@ -45,7 +45,7 @@ bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava)
|
||||
|
||||
// If we have a last_Java_frame, then we should use it even if
|
||||
// isInJava == true. It should be more reliable than ucontext info.
|
||||
if (jt->has_last_Java_frame()) {
|
||||
if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) {
|
||||
*fr_addr = jt->pd_last_frame();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -32,12 +32,8 @@
|
||||
|
||||
frame pd_last_frame() {
|
||||
assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
|
||||
if (_anchor.last_Java_pc() != NULL) {
|
||||
return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
|
||||
} else {
|
||||
// This will pick up pc from sp
|
||||
return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp());
|
||||
}
|
||||
vmassert(_anchor.last_Java_pc() != NULL, "not walkable");
|
||||
return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
@ -47,7 +47,7 @@ bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava)
|
||||
|
||||
// If we have a last_Java_frame, then we should use it even if
|
||||
// isInJava == true. It should be more reliable than ucontext info.
|
||||
if (jt->has_last_Java_frame()) {
|
||||
if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) {
|
||||
*fr_addr = jt->pd_last_frame();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -43,12 +43,7 @@
|
||||
|
||||
frame pd_last_frame() {
|
||||
assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
|
||||
if (_anchor.last_Java_pc() != NULL) {
|
||||
return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
|
||||
} else {
|
||||
// This will pick up pc from sp
|
||||
return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp());
|
||||
}
|
||||
return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
@ -46,7 +46,7 @@ bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava)
|
||||
|
||||
// If we have a last_Java_frame, then we should use it even if
|
||||
// isInJava == true. It should be more reliable than ucontext info.
|
||||
if (jt->has_last_Java_frame()) {
|
||||
if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) {
|
||||
*fr_addr = jt->pd_last_frame();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -32,12 +32,8 @@
|
||||
|
||||
frame pd_last_frame() {
|
||||
assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
|
||||
if (_anchor.last_Java_pc() != NULL) {
|
||||
return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
|
||||
} else {
|
||||
// This will pick up pc from sp
|
||||
return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp());
|
||||
}
|
||||
vmassert(_anchor.last_Java_pc() != NULL, "not walkable");
|
||||
return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
@ -274,8 +274,14 @@ bool os::Solaris::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_
|
||||
// stack overflow handling
|
||||
return false;
|
||||
} else {
|
||||
*fr = os::fetch_frame_from_ucontext(thread, uc);
|
||||
*fr = frame(fr->sender_sp(), fr->sp());
|
||||
// Returned frame will be the caller of the method that faults on the stack bang.
|
||||
// Register window not yet rotated (happens at SAVE after stack bang), so there is no new
|
||||
// frame to go with the faulting PC. Using caller SP that is still in SP, and caller PC
|
||||
// that was written to O7 at call.
|
||||
intptr_t* sp = os::Solaris::ucontext_get_sp(uc);
|
||||
address pc = (address)uc->uc_mcontext.gregs[REG_O7];
|
||||
*fr = frame(sp, frame::unpatchable, pc);
|
||||
|
||||
if (!fr->is_java_frame()) {
|
||||
assert(fr->safe_for_sender(thread), "Safety check");
|
||||
*fr = fr->java_sender();
|
||||
|
||||
@ -45,9 +45,8 @@ bool JavaThread::pd_get_top_frame(frame* fr_addr,
|
||||
assert(this->is_Java_thread(), "must be JavaThread");
|
||||
JavaThread* jt = (JavaThread *)this;
|
||||
|
||||
// last_Java_frame is always walkable and safe use it if we have it
|
||||
|
||||
if (jt->has_last_Java_frame()) {
|
||||
// There is small window where last_Java_frame is not walkable or safe
|
||||
if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) {
|
||||
*fr_addr = jt->pd_last_frame();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -30,12 +30,8 @@
|
||||
|
||||
frame pd_last_frame() {
|
||||
assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
|
||||
if (_anchor.last_Java_pc() != NULL) {
|
||||
return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
|
||||
} else {
|
||||
// This will pick up pc from sp
|
||||
return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp());
|
||||
}
|
||||
vmassert(_anchor.last_Java_pc() != NULL, "not walkable");
|
||||
return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
@ -48,7 +48,7 @@ bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava)
|
||||
|
||||
// If we have a last_Java_frame, then we should use it even if
|
||||
// isInJava == true. It should be more reliable than CONTEXT info.
|
||||
if (jt->has_last_Java_frame()) {
|
||||
if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) {
|
||||
*fr_addr = jt->pd_last_frame();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -32,12 +32,8 @@
|
||||
|
||||
frame pd_last_frame() {
|
||||
assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
|
||||
if (_anchor.last_Java_pc() != NULL) {
|
||||
return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
|
||||
} else {
|
||||
// This will pick up pc from sp
|
||||
return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp());
|
||||
}
|
||||
vmassert(_anchor.last_Java_pc() != NULL, "not walkable");
|
||||
return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
@ -342,7 +342,7 @@ methodHandle JVMCIEnv::get_method_by_index_impl(const constantPoolHandle& cpool,
|
||||
Symbol* sig_sym = cpool->signature_ref_at(index);
|
||||
|
||||
if (cpool->has_preresolution()
|
||||
|| (holder() == SystemDictionary::MethodHandle_klass() &&
|
||||
|| ((holder() == SystemDictionary::MethodHandle_klass() || holder() == SystemDictionary::VarHandle_klass()) &&
|
||||
MethodHandles::is_signature_polymorphic_name(holder(), name_sym))) {
|
||||
// Short-circuit lookups for JSR 292-related call sites.
|
||||
// That is, do not rely only on name-based lookups, because they may fail
|
||||
|
||||
@ -54,6 +54,7 @@
|
||||
#include "runtime/compilationPolicy.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
#include "runtime/init.hpp"
|
||||
#include "runtime/orderAccess.inline.hpp"
|
||||
#include "runtime/relocator.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
@ -1015,7 +1016,14 @@ address Method::make_adapters(methodHandle mh, TRAPS) {
|
||||
// so making them eagerly shouldn't be too expensive.
|
||||
AdapterHandlerEntry* adapter = AdapterHandlerLibrary::get_adapter(mh);
|
||||
if (adapter == NULL ) {
|
||||
THROW_MSG_NULL(vmSymbols::java_lang_VirtualMachineError(), "Out of space in CodeCache for adapters");
|
||||
if (!is_init_completed()) {
|
||||
// Don't throw exceptions during VM initialization because java.lang.* classes
|
||||
// might not have been initialized, causing problems when constructing the
|
||||
// Java exception object.
|
||||
vm_exit_during_initialization("Out of space in CodeCache for adapters");
|
||||
} else {
|
||||
THROW_MSG_NULL(vmSymbols::java_lang_VirtualMachineError(), "Out of space in CodeCache for adapters");
|
||||
}
|
||||
}
|
||||
|
||||
if (mh->is_shared()) {
|
||||
|
||||
@ -24,10 +24,12 @@
|
||||
package compiler.profiling.spectrapredefineclass;
|
||||
|
||||
import com.sun.tools.attach.VirtualMachine;
|
||||
import jdk.test.lib.Utils;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.instrument.Instrumentation;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.ProtectionDomain;
|
||||
|
||||
class A {
|
||||
@ -67,8 +69,7 @@ class Test {
|
||||
}
|
||||
|
||||
public class Agent implements ClassFileTransformer {
|
||||
|
||||
|
||||
public static final String AGENT_JAR = Paths.get(Utils.TEST_CLASSES, "agent.jar").toString();
|
||||
static public boolean m2(A a) {
|
||||
boolean res = false;
|
||||
if (a.getClass() == B.class) {
|
||||
@ -95,7 +96,7 @@ public class Agent implements ClassFileTransformer {
|
||||
// Redefine class
|
||||
try {
|
||||
VirtualMachine vm = VirtualMachine.attach(pid);
|
||||
vm.loadAgent(System.getProperty("test.classes",".") + "/agent.jar", "");
|
||||
vm.loadAgent(AGENT_JAR, "");
|
||||
vm.detach();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* java.instrument
|
||||
* java.management
|
||||
* @build compiler.profiling.spectrapredefineclass_classloaders.Agent
|
||||
* @build compiler.profiling.spectrapredefineclass.Agent
|
||||
* @run driver ClassFileInstaller compiler.profiling.spectrapredefineclass.Agent
|
||||
* @run driver compiler.profiling.spectrapredefineclass.Launcher
|
||||
* @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation
|
||||
@ -39,23 +39,33 @@
|
||||
|
||||
package compiler.profiling.spectrapredefineclass;
|
||||
|
||||
import jdk.test.lib.JDKToolFinder;
|
||||
import jdk.test.lib.JDKToolLauncher;
|
||||
import jdk.test.lib.OutputAnalyzer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
public class Launcher {
|
||||
private static final String MANIFEST = "MANIFEST.MF";
|
||||
public static void main(String[] args) throws Exception {
|
||||
try (PrintWriter pw = new PrintWriter(MANIFEST)) {
|
||||
pw.println("Agent-Class: " + Agent.class.getName());
|
||||
pw.println("Can-Retransform-Classes: true");
|
||||
}
|
||||
|
||||
PrintWriter pw = new PrintWriter("MANIFEST.MF");
|
||||
pw.println("Agent-Class: " + Launcher.class.getPackage().getName() +".Agent");
|
||||
pw.println("Can-Retransform-Classes: true");
|
||||
pw.close();
|
||||
JDKToolLauncher jar = JDKToolLauncher.create("jar")
|
||||
.addToolArg("cmf")
|
||||
.addToolArg(MANIFEST)
|
||||
.addToolArg(Agent.AGENT_JAR)
|
||||
.addToolArg(Agent.class.getName().replace('.', File.separatorChar) + ".class");
|
||||
|
||||
ProcessBuilder pb = new ProcessBuilder();
|
||||
pb.command(new String[] { JDKToolFinder.getJDKTool("jar"), "cmf", "MANIFEST.MF",
|
||||
System.getProperty("test.classes",".") + "/agent.jar",
|
||||
"compiler/profiling/spectrapredefineclass/Agent.class".replace('/', File.separatorChar)});
|
||||
pb.start().waitFor();
|
||||
ProcessBuilder pb = new ProcessBuilder(jar.getCommand());
|
||||
try {
|
||||
OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
||||
output.shouldHaveExitValue(0);
|
||||
} catch (IOException ex) {
|
||||
throw new Error("TESTBUG: jar failed.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
package compiler.profiling.spectrapredefineclass_classloaders;
|
||||
|
||||
import com.sun.tools.attach.VirtualMachine;
|
||||
import jdk.test.lib.Utils;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.instrument.Instrumentation;
|
||||
@ -32,14 +33,16 @@ import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.ProtectionDomain;
|
||||
|
||||
public class Agent implements ClassFileTransformer {
|
||||
public static final String AGENT_JAR = Paths.get(Utils.TEST_CLASSES, "agent.jar").toString();
|
||||
public static ClassLoader newClassLoader() {
|
||||
try {
|
||||
return new URLClassLoader(new URL[] {
|
||||
Paths.get(System.getProperty("test.classes",".")).toUri().toURL(),
|
||||
Paths.get(Utils.TEST_CLASSES).toUri().toURL(),
|
||||
}, null);
|
||||
} catch (MalformedURLException e){
|
||||
throw new RuntimeException("Unexpected URL conversion failure", e);
|
||||
@ -76,7 +79,7 @@ public class Agent implements ClassFileTransformer {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
try {
|
||||
VirtualMachine vm = VirtualMachine.attach(pid);
|
||||
vm.loadAgent(System.getProperty("test.classes",".") + "/agent.jar", "");
|
||||
vm.loadAgent(AGENT_JAR, "");
|
||||
vm.detach();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
|
||||
@ -39,26 +39,36 @@
|
||||
* -XX:ReservedCodeCacheSize=3M
|
||||
* compiler.profiling.spectrapredefineclass_classloaders.Agent
|
||||
*/
|
||||
|
||||
package compiler.profiling.spectrapredefineclass_classloaders;
|
||||
|
||||
import jdk.test.lib.JDKToolFinder;
|
||||
import jdk.test.lib.JDKToolLauncher;
|
||||
import jdk.test.lib.OutputAnalyzer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
public class Launcher {
|
||||
public static void main(String[] args) throws Exception {
|
||||
private static final String MANIFEST = "MANIFEST.MF";
|
||||
public static void main(String[] args) throws Exception {
|
||||
try (PrintWriter pw = new PrintWriter(MANIFEST)) {
|
||||
pw.println("Agent-Class: " + Agent.class.getName());
|
||||
pw.println("Can-Retransform-Classes: true");
|
||||
}
|
||||
|
||||
PrintWriter pw = new PrintWriter("MANIFEST.MF");
|
||||
JDKToolLauncher jar = JDKToolLauncher.create("jar")
|
||||
.addToolArg("cmf")
|
||||
.addToolArg(MANIFEST)
|
||||
.addToolArg(Agent.AGENT_JAR)
|
||||
.addToolArg(Agent.class.getName().replace('.', File.separatorChar) + ".class");
|
||||
|
||||
pw.println("Agent-Class: " + Launcher.class.getPackage().getName() + ".Agent");
|
||||
pw.println("Can-Retransform-Classes: true");
|
||||
pw.close();
|
||||
|
||||
ProcessBuilder pb = new ProcessBuilder();
|
||||
pb.command(new String[]{JDKToolFinder.getJDKTool("jar"), "cmf", "MANIFEST.MF",
|
||||
System.getProperty("test.classes", ".") + "/agent.jar",
|
||||
"compiler/profiling/spectrapredefineclass/Agent.class".replace('/', File.separatorChar)});
|
||||
pb.start().waitFor();
|
||||
ProcessBuilder pb = new ProcessBuilder(jar.getCommand());
|
||||
try {
|
||||
OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
||||
output.shouldHaveExitValue(0);
|
||||
} catch (IOException ex) {
|
||||
throw new Error("TESTBUG: jar failed.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8026949
|
||||
* @bug 8026949 8164091
|
||||
* @summary Test ensures correct VM output during startup
|
||||
* @library /test/lib
|
||||
* @modules java.base/jdk.internal.misc
|
||||
@ -45,7 +45,14 @@ public class StartupOutput {
|
||||
pb = ProcessTools.createJavaProcessBuilder("-Xint", "-XX:+DisplayVMOutputToStdout", "-version");
|
||||
out = new OutputAnalyzer(pb.start());
|
||||
out.shouldNotContain("no space to run compilers");
|
||||
|
||||
out.shouldHaveExitValue(0);
|
||||
|
||||
pb = ProcessTools.createJavaProcessBuilder("-Xint", "-XX:ReservedCodeCacheSize=1770K", "-XX:InitialCodeCacheSize=4K", "-version");
|
||||
out = new OutputAnalyzer(pb.start());
|
||||
// The VM should not crash but may return an error message because we don't have enough space for adapters
|
||||
int exitCode = out.getExitValue();
|
||||
if (exitCode != 1 && exitCode != 0) {
|
||||
throw new Exception("VM crashed with exit code " + exitCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user