Skip to content

Commit

Permalink
8273456: Do not hold ttyLock around stack walking
Browse files Browse the repository at this point in the history
8273629: compiler/uncommontrap/TestDeoptOOM.java fails with release VMs

Reviewed-by: lucy, phh
Backport-of: 461a467f91ba19ae35d7833b7d3e74f62f52e19c
  • Loading branch information
GoeLin committed Oct 26, 2023
1 parent 2c75188 commit 93127b4
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 69 deletions.
11 changes: 4 additions & 7 deletions src/hotspot/share/prims/whitebox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2318,22 +2318,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

Expand Down
121 changes: 61 additions & 60 deletions src/hotspot/share/runtime/deoptimization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,14 +144,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());
}


Expand Down Expand Up @@ -180,6 +182,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) {
Expand Down Expand Up @@ -211,7 +245,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));
}
}
Expand All @@ -232,9 +265,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
}
Expand Down Expand Up @@ -264,29 +295,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
}
Expand Down Expand Up @@ -612,7 +645,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");
}
}
Expand Down Expand Up @@ -721,7 +753,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);
}
Expand Down Expand Up @@ -844,8 +875,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);
Expand All @@ -870,7 +899,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;
Expand Down Expand Up @@ -1499,49 +1528,22 @@ 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) {
Events::log_deopt_message(thread, "DEOPT PACKING pc=" INTPTR_FORMAT " sp=" INTPTR_FORMAT, p2i(fr.pc()), p2i(fr.sp()));

#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) {
Expand All @@ -1550,13 +1552,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

Expand All @@ -1579,7 +1582,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
Expand Down Expand Up @@ -1980,7 +1982,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
Expand Down
1 change: 0 additions & 1 deletion src/hotspot/share/runtime/deoptimization.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,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:
Expand Down
15 changes: 14 additions & 1 deletion test/hotspot/jtreg/compiler/uncommontrap/TestDeoptOOM.java
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -33,6 +33,19 @@
* 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:+UnlockDiagnosticVMOptions
* -XX:+UseZGC -XX:+LogCompilation -XX:+PrintDeoptimizationDetails -XX:+TraceDeoptimization -XX:+Verbose
* compiler.uncommontrap.TestDeoptOOM
*/

package compiler.uncommontrap;

public class TestDeoptOOM {
Expand Down

1 comment on commit 93127b4

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.