mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-18 10:04:42 +02:00
8273456: Do not hold ttyLock around stack walking
Reviewed-by: dholmes, eosterlund
This commit is contained in:
parent
695b434b44
commit
461a467f91
5 changed files with 81 additions and 72 deletions
|
@ -2383,22 +2383,19 @@ WB_ENTRY(void, WB_CheckThreadObjOfTerminatingThread(JNIEnv* env, jobject wb, job
|
|||
WB_END
|
||||
|
||||
WB_ENTRY(void, WB_VerifyFrames(JNIEnv* env, jobject wb, jboolean log, jboolean update_map))
|
||||
intx tty_token = -1;
|
||||
if (log) {
|
||||
tty_token = ttyLocker::hold_tty();
|
||||
tty->print_cr("[WhiteBox::VerifyFrames] Walking Frames");
|
||||
}
|
||||
ResourceMark rm; // for verify
|
||||
stringStream st;
|
||||
for (StackFrameStream fst(JavaThread::current(), update_map, true); !fst.is_done(); fst.next()) {
|
||||
frame* current_frame = fst.current();
|
||||
if (log) {
|
||||
current_frame->print_value();
|
||||
current_frame->print_value_on(&st, NULL);
|
||||
}
|
||||
current_frame->verify(fst.register_map());
|
||||
}
|
||||
if (log) {
|
||||
tty->print_cr("[WhiteBox::VerifyFrames] Walking Frames");
|
||||
tty->print_raw(st.as_string());
|
||||
tty->print_cr("[WhiteBox::VerifyFrames] Done");
|
||||
ttyLocker::release_tty(tty_token);
|
||||
}
|
||||
WB_END
|
||||
|
||||
|
|
|
@ -143,14 +143,16 @@ int Deoptimization::UnrollBlock::size_of_frames() const {
|
|||
|
||||
|
||||
void Deoptimization::UnrollBlock::print() {
|
||||
ttyLocker ttyl;
|
||||
tty->print_cr("UnrollBlock");
|
||||
tty->print_cr(" size_of_deoptimized_frame = %d", _size_of_deoptimized_frame);
|
||||
tty->print( " frame_sizes: ");
|
||||
ResourceMark rm;
|
||||
stringStream st;
|
||||
st.print_cr("UnrollBlock");
|
||||
st.print_cr(" size_of_deoptimized_frame = %d", _size_of_deoptimized_frame);
|
||||
st.print( " frame_sizes: ");
|
||||
for (int index = 0; index < number_of_frames(); index++) {
|
||||
tty->print(INTX_FORMAT " ", frame_sizes()[index]);
|
||||
st.print(INTX_FORMAT " ", frame_sizes()[index]);
|
||||
}
|
||||
tty->cr();
|
||||
st.cr();
|
||||
tty->print_raw(st.as_string());
|
||||
}
|
||||
|
||||
|
||||
|
@ -179,6 +181,38 @@ JRT_BLOCK_ENTRY(Deoptimization::UnrollBlock*, Deoptimization::fetch_unroll_info(
|
|||
JRT_END
|
||||
|
||||
#if COMPILER2_OR_JVMCI
|
||||
#ifndef PRODUCT
|
||||
// print information about reallocated objects
|
||||
static void print_objects(JavaThread* deoptee_thread,
|
||||
GrowableArray<ScopeValue*>* objects, bool realloc_failures) {
|
||||
ResourceMark rm;
|
||||
stringStream st; // change to logStream with logging
|
||||
st.print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, p2i(deoptee_thread));
|
||||
fieldDescriptor fd;
|
||||
|
||||
for (int i = 0; i < objects->length(); i++) {
|
||||
ObjectValue* sv = (ObjectValue*) objects->at(i);
|
||||
Klass* k = java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()());
|
||||
Handle obj = sv->value();
|
||||
|
||||
st.print(" object <" INTPTR_FORMAT "> of type ", p2i(sv->value()()));
|
||||
k->print_value_on(&st);
|
||||
assert(obj.not_null() || realloc_failures, "reallocation was missed");
|
||||
if (obj.is_null()) {
|
||||
st.print(" allocation failed");
|
||||
} else {
|
||||
st.print(" allocated (%d bytes)", obj->size() * HeapWordSize);
|
||||
}
|
||||
st.cr();
|
||||
|
||||
if (Verbose && !obj.is_null()) {
|
||||
k->oop_print_on(obj(), &st);
|
||||
}
|
||||
}
|
||||
tty->print_raw(st.as_string());
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool rematerialize_objects(JavaThread* thread, int exec_mode, CompiledMethod* compiled_method,
|
||||
frame& deoptee, RegisterMap& map, GrowableArray<compiledVFrame*>* chunk,
|
||||
bool& deoptimized_objects) {
|
||||
|
@ -210,7 +244,6 @@ static bool rematerialize_objects(JavaThread* thread, int exec_mode, CompiledMet
|
|||
return_value = Handle(thread, result);
|
||||
assert(Universe::heap()->is_in_or_null(result), "must be heap pointer");
|
||||
if (TraceDeoptimization) {
|
||||
ttyLocker ttyl;
|
||||
tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, p2i(result), p2i(thread));
|
||||
}
|
||||
}
|
||||
|
@ -231,9 +264,7 @@ static bool rematerialize_objects(JavaThread* thread, int exec_mode, CompiledMet
|
|||
Deoptimization::reassign_fields(&deoptee, &map, objects, realloc_failures, skip_internal);
|
||||
#ifndef PRODUCT
|
||||
if (TraceDeoptimization) {
|
||||
ttyLocker ttyl;
|
||||
tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, p2i(deoptee_thread));
|
||||
Deoptimization::print_objects(objects, realloc_failures);
|
||||
print_objects(deoptee_thread, objects, realloc_failures);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -263,29 +294,31 @@ static void restore_eliminated_locks(JavaThread* thread, GrowableArray<compiledV
|
|||
deoptimized_objects = deoptimized_objects || relocked;
|
||||
#ifndef PRODUCT
|
||||
if (PrintDeoptimizationDetails) {
|
||||
ttyLocker ttyl;
|
||||
ResourceMark rm;
|
||||
stringStream st;
|
||||
for (int j = 0; j < monitors->length(); j++) {
|
||||
MonitorInfo* mi = monitors->at(j);
|
||||
if (mi->eliminated()) {
|
||||
if (first) {
|
||||
first = false;
|
||||
tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, p2i(thread));
|
||||
st.print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, p2i(thread));
|
||||
}
|
||||
if (exec_mode == Deoptimization::Unpack_none) {
|
||||
ObjectMonitor* monitor = deoptee_thread->current_waiting_monitor();
|
||||
if (monitor != NULL && monitor->object() == mi->owner()) {
|
||||
tty->print_cr(" object <" INTPTR_FORMAT "> DEFERRED relocking after wait", p2i(mi->owner()));
|
||||
st.print_cr(" object <" INTPTR_FORMAT "> DEFERRED relocking after wait", p2i(mi->owner()));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (mi->owner_is_scalar_replaced()) {
|
||||
Klass* k = java_lang_Class::as_Klass(mi->owner_klass());
|
||||
tty->print_cr(" failed reallocation for klass %s", k->external_name());
|
||||
st.print_cr(" failed reallocation for klass %s", k->external_name());
|
||||
} else {
|
||||
tty->print_cr(" object <" INTPTR_FORMAT "> locked", p2i(mi->owner()));
|
||||
st.print_cr(" object <" INTPTR_FORMAT "> locked", p2i(mi->owner()));
|
||||
}
|
||||
}
|
||||
}
|
||||
tty->print_raw(st.as_string());
|
||||
}
|
||||
#endif // !PRODUCT
|
||||
}
|
||||
|
@ -604,7 +637,6 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
|
|||
|
||||
if (array->frames() > 1) {
|
||||
if (VerifyStack && TraceDeoptimization) {
|
||||
ttyLocker ttyl;
|
||||
tty->print_cr("Deoptimizing method containing inlining");
|
||||
}
|
||||
}
|
||||
|
@ -698,7 +730,6 @@ JRT_LEAF(BasicType, Deoptimization::unpack_frames(JavaThread* thread, int exec_m
|
|||
|
||||
#ifndef PRODUCT
|
||||
if (TraceDeoptimization) {
|
||||
ttyLocker ttyl;
|
||||
tty->print_cr("DEOPT UNPACKING thread " INTPTR_FORMAT " vframeArray " INTPTR_FORMAT " mode %d",
|
||||
p2i(thread), p2i(array), exec_mode);
|
||||
}
|
||||
|
@ -820,8 +851,6 @@ JRT_LEAF(BasicType, Deoptimization::unpack_frames(JavaThread* thread, int exec_m
|
|||
(iframe->interpreter_frame_expression_stack_size() == mask.expression_stack_size() + cur_invoke_parameter_size))
|
||||
)) {
|
||||
{
|
||||
ttyLocker ttyl;
|
||||
|
||||
// Print out some information that will help us debug the problem
|
||||
tty->print_cr("Wrong number of expression stack elements during deoptimization");
|
||||
tty->print_cr(" Error occurred while verifying frame %d (0..%d, 0 is topmost)", i, cur_array->frames() - 1);
|
||||
|
@ -842,7 +871,7 @@ JRT_LEAF(BasicType, Deoptimization::unpack_frames(JavaThread* thread, int exec_m
|
|||
tty->print_cr(" %s (bci %d)", el->method()->name_and_sig_as_C_string(), el->bci());
|
||||
}
|
||||
cur_array->print_on_2(tty);
|
||||
} // release tty lock before calling guarantee
|
||||
}
|
||||
guarantee(false, "wrong number of expression stack elements during deopt");
|
||||
}
|
||||
VerifyOopClosure verify;
|
||||
|
@ -1461,34 +1490,6 @@ bool Deoptimization::relock_objects(JavaThread* thread, GrowableArray<MonitorInf
|
|||
}
|
||||
return relocked_objects;
|
||||
}
|
||||
|
||||
|
||||
#ifndef PRODUCT
|
||||
// print information about reallocated objects
|
||||
void Deoptimization::print_objects(GrowableArray<ScopeValue*>* objects, bool realloc_failures) {
|
||||
fieldDescriptor fd;
|
||||
|
||||
for (int i = 0; i < objects->length(); i++) {
|
||||
ObjectValue* sv = (ObjectValue*) objects->at(i);
|
||||
Klass* k = java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()());
|
||||
Handle obj = sv->value();
|
||||
|
||||
tty->print(" object <" INTPTR_FORMAT "> of type ", p2i(sv->value()()));
|
||||
k->print_value();
|
||||
assert(obj.not_null() || realloc_failures, "reallocation was missed");
|
||||
if (obj.is_null()) {
|
||||
tty->print(" allocation failed");
|
||||
} else {
|
||||
tty->print(" allocated (%d bytes)", obj->size() * HeapWordSize);
|
||||
}
|
||||
tty->cr();
|
||||
|
||||
if (Verbose && !obj.is_null()) {
|
||||
k->oop_print_on(obj(), tty);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // COMPILER2_OR_JVMCI
|
||||
|
||||
vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk, bool realloc_failures) {
|
||||
|
@ -1496,14 +1497,15 @@ vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, Re
|
|||
|
||||
#ifndef PRODUCT
|
||||
if (PrintDeoptimizationDetails) {
|
||||
ttyLocker ttyl;
|
||||
tty->print("DEOPT PACKING thread " INTPTR_FORMAT " ", p2i(thread));
|
||||
fr.print_on(tty);
|
||||
tty->print_cr(" Virtual frames (innermost first):");
|
||||
ResourceMark rm;
|
||||
stringStream st;
|
||||
st.print("DEOPT PACKING thread " INTPTR_FORMAT " ", p2i(thread));
|
||||
fr.print_on(&st);
|
||||
st.print_cr(" Virtual frames (innermost first):");
|
||||
for (int index = 0; index < chunk->length(); index++) {
|
||||
compiledVFrame* vf = chunk->at(index);
|
||||
tty->print(" %2d - ", index);
|
||||
vf->print_value();
|
||||
st.print(" %2d - ", index);
|
||||
vf->print_value_on(&st);
|
||||
int bci = chunk->at(index)->raw_bci();
|
||||
const char* code_name;
|
||||
if (bci == SynchronizationEntryBCI) {
|
||||
|
@ -1512,13 +1514,14 @@ vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, Re
|
|||
Bytecodes::Code code = vf->method()->code_at(bci);
|
||||
code_name = Bytecodes::name(code);
|
||||
}
|
||||
tty->print(" - %s", code_name);
|
||||
tty->print_cr(" @ bci %d ", bci);
|
||||
st.print(" - %s", code_name);
|
||||
st.print_cr(" @ bci %d ", bci);
|
||||
if (Verbose) {
|
||||
vf->print();
|
||||
tty->cr();
|
||||
vf->print_on(&st);
|
||||
st.cr();
|
||||
}
|
||||
}
|
||||
tty->print_raw(st.as_string());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1541,7 +1544,6 @@ vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, Re
|
|||
|
||||
#ifndef PRODUCT
|
||||
if (PrintDeoptimizationDetails) {
|
||||
ttyLocker ttyl;
|
||||
tty->print_cr(" Created vframeArray " INTPTR_FORMAT, p2i(array));
|
||||
}
|
||||
#endif // PRODUCT
|
||||
|
@ -1849,7 +1851,6 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* current, jint tr
|
|||
bool is_receiver_constraint_failure = COMPILER2_PRESENT(VerifyReceiverTypes &&) (reason == Deoptimization::Reason_receiver_constraint);
|
||||
|
||||
if (TraceDeoptimization || is_receiver_constraint_failure) {
|
||||
ttyLocker ttyl;
|
||||
tty->print_cr(" bci=%d pc=" INTPTR_FORMAT ", relative_pc=" INTPTR_FORMAT ", method=%s" JVMCI_ONLY(", debug_id=%d"), trap_scope->bci(), p2i(fr.pc()), fr.pc() - nm->code_begin(), trap_scope->method()->name_and_sig_as_C_string()
|
||||
#if INCLUDE_JVMCI
|
||||
, debug_id
|
||||
|
|
|
@ -182,7 +182,6 @@ class Deoptimization : AllStatic {
|
|||
static bool relock_objects(JavaThread* thread, GrowableArray<MonitorInfo*>* monitors,
|
||||
JavaThread* deoptee_thread, frame& fr, int exec_mode, bool realloc_failures);
|
||||
static void pop_frames_failed_reallocs(JavaThread* thread, vframeArray* array);
|
||||
NOT_PRODUCT(static void print_objects(GrowableArray<ScopeValue*>* objects, bool realloc_failures);)
|
||||
#endif // COMPILER2_OR_JVMCI
|
||||
|
||||
public:
|
||||
|
|
|
@ -45,10 +45,10 @@ class Mutex : public CHeapObj<mtSynchronizer> {
|
|||
// Special low level locks are given names and ranges avoid overlap.
|
||||
enum lock_types {
|
||||
event,
|
||||
service = event + 3,
|
||||
tty = event + 3,
|
||||
service = tty + 3,
|
||||
stackwatermark = service + 3,
|
||||
tty = stackwatermark + 3,
|
||||
special = tty + 3,
|
||||
special = stackwatermark + 3,
|
||||
oopstorage = special + 3,
|
||||
leaf = oopstorage + 2,
|
||||
safepoint = leaf + 10,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2021, 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
|
||||
|
@ -33,6 +33,18 @@
|
|||
* compiler.uncommontrap.TestDeoptOOM
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8273456
|
||||
* @summary Test that ttyLock isn't held when taking StackWatermark_lock
|
||||
* @requires !vm.graal.enabled & vm.gc.Z
|
||||
* @run main/othervm -XX:-BackgroundCompilation -Xmx128M -XX:+IgnoreUnrecognizedVMOptions -XX:+VerifyStack
|
||||
* -XX:CompileCommand=exclude,compiler.uncommontrap.TestDeoptOOM::main
|
||||
* -XX:CompileCommand=exclude,compiler.uncommontrap.TestDeoptOOM::m9_1
|
||||
* -XX:+UseZGC -XX:+LogCompilation -XX:+PrintDeoptimizationDetails -XX:+TraceDeoptimization -XX:+Verbose
|
||||
* compiler.uncommontrap.TestDeoptOOM
|
||||
*/
|
||||
|
||||
package compiler.uncommontrap;
|
||||
|
||||
public class TestDeoptOOM {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue