7090904: JSR 292: JRuby junit test crashes in PSScavengeRootsClosure::do_oop
Reviewed-by: kvn, never, jrose
This commit is contained in:
parent
b030a36386
commit
ae64d0bc30
@ -1609,6 +1609,12 @@ int AbstractInterpreter::layout_activation(methodOop method,
|
|||||||
// and sender_sp is fp+8
|
// and sender_sp is fp+8
|
||||||
intptr_t* locals = interpreter_frame->sender_sp() + max_locals - 1;
|
intptr_t* locals = interpreter_frame->sender_sp() + max_locals - 1;
|
||||||
|
|
||||||
|
#ifdef ASSERT
|
||||||
|
if (caller->is_interpreted_frame()) {
|
||||||
|
assert(locals < caller->fp() + frame::interpreter_frame_initial_sp_offset, "bad placement");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
interpreter_frame->interpreter_frame_set_locals(locals);
|
interpreter_frame->interpreter_frame_set_locals(locals);
|
||||||
BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin();
|
BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin();
|
||||||
BasicObjectLock* monbot = montop - moncount;
|
BasicObjectLock* monbot = montop - moncount;
|
||||||
|
@ -1622,6 +1622,12 @@ int AbstractInterpreter::layout_activation(methodOop method,
|
|||||||
// sender_sp is fp+16 XXX
|
// sender_sp is fp+16 XXX
|
||||||
intptr_t* locals = interpreter_frame->sender_sp() + max_locals - 1;
|
intptr_t* locals = interpreter_frame->sender_sp() + max_locals - 1;
|
||||||
|
|
||||||
|
#ifdef ASSERT
|
||||||
|
if (caller->is_interpreted_frame()) {
|
||||||
|
assert(locals < caller->fp() + frame::interpreter_frame_initial_sp_offset, "bad placement");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
interpreter_frame->interpreter_frame_set_locals(locals);
|
interpreter_frame->interpreter_frame_set_locals(locals);
|
||||||
BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin();
|
BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin();
|
||||||
BasicObjectLock* monbot = montop - moncount;
|
BasicObjectLock* monbot = montop - moncount;
|
||||||
|
@ -241,7 +241,7 @@ bool BytecodePrinter::check_index(int i, int& cp_index, outputStream* st) {
|
|||||||
st->print_cr(" not secondary entry?", i);
|
st->print_cr(" not secondary entry?", i);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
i = cache->entry_at(i)->main_entry_index();
|
i = cache->entry_at(i)->main_entry_index() + constantPoolOopDesc::CPCACHE_INDEX_TAG;
|
||||||
goto check_cache_index;
|
goto check_cache_index;
|
||||||
} else {
|
} else {
|
||||||
st->print_cr(" not in cache[*]?", i);
|
st->print_cr(" not in cache[*]?", i);
|
||||||
|
@ -362,8 +362,6 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
|
|||||||
intptr_t* frame_sizes = NEW_C_HEAP_ARRAY(intptr_t, number_of_frames);
|
intptr_t* frame_sizes = NEW_C_HEAP_ARRAY(intptr_t, number_of_frames);
|
||||||
// +1 because we always have an interpreter return address for the final slot.
|
// +1 because we always have an interpreter return address for the final slot.
|
||||||
address* frame_pcs = NEW_C_HEAP_ARRAY(address, number_of_frames + 1);
|
address* frame_pcs = NEW_C_HEAP_ARRAY(address, number_of_frames + 1);
|
||||||
int callee_parameters = 0;
|
|
||||||
int callee_locals = 0;
|
|
||||||
int popframe_extra_args = 0;
|
int popframe_extra_args = 0;
|
||||||
// Create an interpreter return address for the stub to use as its return
|
// Create an interpreter return address for the stub to use as its return
|
||||||
// address so the skeletal frames are perfectly walkable
|
// address so the skeletal frames are perfectly walkable
|
||||||
@ -387,14 +385,20 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
|
|||||||
// handles are used. If the caller is interpreted get the real
|
// handles are used. If the caller is interpreted get the real
|
||||||
// value so that the proper amount of space can be added to it's
|
// value so that the proper amount of space can be added to it's
|
||||||
// frame.
|
// frame.
|
||||||
int caller_actual_parameters = callee_parameters;
|
bool caller_was_method_handle = false;
|
||||||
if (deopt_sender.is_interpreted_frame()) {
|
if (deopt_sender.is_interpreted_frame()) {
|
||||||
methodHandle method = deopt_sender.interpreter_frame_method();
|
methodHandle method = deopt_sender.interpreter_frame_method();
|
||||||
Bytecode_invoke cur = Bytecode_invoke_check(method,
|
Bytecode_invoke cur = Bytecode_invoke_check(method,
|
||||||
deopt_sender.interpreter_frame_bci());
|
deopt_sender.interpreter_frame_bci());
|
||||||
Symbol* signature = method->constants()->signature_ref_at(cur.index());
|
if (cur.code() == Bytecodes::_invokedynamic ||
|
||||||
ArgumentSizeComputer asc(signature);
|
(cur.code() == Bytecodes::_invokevirtual &&
|
||||||
caller_actual_parameters = asc.size() + (cur.has_receiver() ? 1 : 0);
|
method->constants()->klass_ref_at_noresolve(cur.index()) == vmSymbols::java_lang_invoke_MethodHandle() &&
|
||||||
|
methodOopDesc::is_method_handle_invoke_name(cur.name()))) {
|
||||||
|
// Method handle invokes may involve fairly arbitrary chains of
|
||||||
|
// calls so it's impossible to know how much actual space the
|
||||||
|
// caller has for locals.
|
||||||
|
caller_was_method_handle = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -411,14 +415,15 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
|
|||||||
// in the frame_sizes/frame_pcs so the assembly code can do a trivial walk.
|
// in the frame_sizes/frame_pcs so the assembly code can do a trivial walk.
|
||||||
// so things look a little strange in this loop.
|
// so things look a little strange in this loop.
|
||||||
//
|
//
|
||||||
|
int callee_parameters = 0;
|
||||||
|
int callee_locals = 0;
|
||||||
for (int index = 0; index < array->frames(); index++ ) {
|
for (int index = 0; index < array->frames(); index++ ) {
|
||||||
// frame[number_of_frames - 1 ] = on_stack_size(youngest)
|
// frame[number_of_frames - 1 ] = on_stack_size(youngest)
|
||||||
// frame[number_of_frames - 2 ] = on_stack_size(sender(youngest))
|
// frame[number_of_frames - 2 ] = on_stack_size(sender(youngest))
|
||||||
// frame[number_of_frames - 3 ] = on_stack_size(sender(sender(youngest)))
|
// frame[number_of_frames - 3 ] = on_stack_size(sender(sender(youngest)))
|
||||||
int caller_parms = callee_parameters;
|
int caller_parms = callee_parameters;
|
||||||
if (index == array->frames() - 1) {
|
if ((index == array->frames() - 1) && caller_was_method_handle) {
|
||||||
// Use the value from the interpreted caller
|
caller_parms = 0;
|
||||||
caller_parms = caller_actual_parameters;
|
|
||||||
}
|
}
|
||||||
frame_sizes[number_of_frames - 1 - index] = BytesPerWord * array->element(index)->on_stack_size(caller_parms,
|
frame_sizes[number_of_frames - 1 - index] = BytesPerWord * array->element(index)->on_stack_size(caller_parms,
|
||||||
callee_parameters,
|
callee_parameters,
|
||||||
@ -460,13 +465,13 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
|
|||||||
// QQQ I'd rather see this pushed down into last_frame_adjust
|
// QQQ I'd rather see this pushed down into last_frame_adjust
|
||||||
// and have it take the sender (aka caller).
|
// and have it take the sender (aka caller).
|
||||||
|
|
||||||
if (deopt_sender.is_compiled_frame()) {
|
if (deopt_sender.is_compiled_frame() || caller_was_method_handle) {
|
||||||
caller_adjustment = last_frame_adjust(0, callee_locals);
|
caller_adjustment = last_frame_adjust(0, callee_locals);
|
||||||
} else if (callee_locals > caller_actual_parameters) {
|
} else if (callee_locals > callee_parameters) {
|
||||||
// The caller frame may need extending to accommodate
|
// The caller frame may need extending to accommodate
|
||||||
// non-parameter locals of the first unpacked interpreted frame.
|
// non-parameter locals of the first unpacked interpreted frame.
|
||||||
// Compute that adjustment.
|
// Compute that adjustment.
|
||||||
caller_adjustment = last_frame_adjust(caller_actual_parameters, callee_locals);
|
caller_adjustment = last_frame_adjust(callee_parameters, callee_locals);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the sender is deoptimized the we must retrieve the address of the handler
|
// If the sender is deoptimized the we must retrieve the address of the handler
|
||||||
@ -481,7 +486,7 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
|
|||||||
|
|
||||||
UnrollBlock* info = new UnrollBlock(array->frame_size() * BytesPerWord,
|
UnrollBlock* info = new UnrollBlock(array->frame_size() * BytesPerWord,
|
||||||
caller_adjustment * BytesPerWord,
|
caller_adjustment * BytesPerWord,
|
||||||
caller_actual_parameters,
|
caller_was_method_handle ? 0 : callee_parameters,
|
||||||
number_of_frames,
|
number_of_frames,
|
||||||
frame_sizes,
|
frame_sizes,
|
||||||
frame_pcs,
|
frame_pcs,
|
||||||
|
@ -1338,7 +1338,11 @@ void frame::describe(FrameValues& values, int frame_no) {
|
|||||||
// Label values common to most frames
|
// Label values common to most frames
|
||||||
values.describe(-1, unextended_sp(), err_msg("unextended_sp for #%d", frame_no));
|
values.describe(-1, unextended_sp(), err_msg("unextended_sp for #%d", frame_no));
|
||||||
values.describe(-1, sp(), err_msg("sp for #%d", frame_no));
|
values.describe(-1, sp(), err_msg("sp for #%d", frame_no));
|
||||||
values.describe(-1, fp(), err_msg("fp for #%d", frame_no));
|
if (is_compiled_frame()) {
|
||||||
|
values.describe(-1, sp() + _cb->frame_size(), err_msg("computed fp for #%d", frame_no));
|
||||||
|
} else {
|
||||||
|
values.describe(-1, fp(), err_msg("fp for #%d", frame_no));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (is_interpreted_frame()) {
|
if (is_interpreted_frame()) {
|
||||||
methodOop m = interpreter_frame_method();
|
methodOop m = interpreter_frame_method();
|
||||||
@ -1450,9 +1454,8 @@ void FrameValues::validate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FrameValues::print() {
|
void FrameValues::print(JavaThread* thread) {
|
||||||
_values.sort(compare);
|
_values.sort(compare);
|
||||||
JavaThread* thread = JavaThread::current();
|
|
||||||
|
|
||||||
// Sometimes values like the fp can be invalid values if the
|
// Sometimes values like the fp can be invalid values if the
|
||||||
// register map wasn't updated during the walk. Trim out values
|
// register map wasn't updated during the walk. Trim out values
|
||||||
@ -1460,12 +1463,22 @@ void FrameValues::print() {
|
|||||||
int min_index = 0;
|
int min_index = 0;
|
||||||
int max_index = _values.length() - 1;
|
int max_index = _values.length() - 1;
|
||||||
intptr_t* v0 = _values.at(min_index).location;
|
intptr_t* v0 = _values.at(min_index).location;
|
||||||
while (!thread->is_in_stack((address)v0)) {
|
|
||||||
v0 = _values.at(++min_index).location;
|
|
||||||
}
|
|
||||||
intptr_t* v1 = _values.at(max_index).location;
|
intptr_t* v1 = _values.at(max_index).location;
|
||||||
while (!thread->is_in_stack((address)v1)) {
|
|
||||||
v1 = _values.at(--max_index).location;
|
if (thread == Thread::current()) {
|
||||||
|
while (!thread->is_in_stack((address)v0)) {
|
||||||
|
v0 = _values.at(++min_index).location;
|
||||||
|
}
|
||||||
|
while (!thread->is_in_stack((address)v1)) {
|
||||||
|
v1 = _values.at(--max_index).location;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (!thread->on_local_stack((address)v0)) {
|
||||||
|
v0 = _values.at(++min_index).location;
|
||||||
|
}
|
||||||
|
while (!thread->on_local_stack((address)v1)) {
|
||||||
|
v1 = _values.at(--max_index).location;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
intptr_t* min = MIN2(v0, v1);
|
intptr_t* min = MIN2(v0, v1);
|
||||||
intptr_t* max = MAX2(v0, v1);
|
intptr_t* max = MAX2(v0, v1);
|
||||||
|
@ -516,7 +516,7 @@ class FrameValues {
|
|||||||
void describe(int owner, intptr_t* location, const char* description, int priority = 0);
|
void describe(int owner, intptr_t* location, const char* description, int priority = 0);
|
||||||
|
|
||||||
void validate();
|
void validate();
|
||||||
void print();
|
void print(JavaThread* thread);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -2947,7 +2947,7 @@ void JavaThread::print_frame_layout(int depth, bool validate_only) {
|
|||||||
values.validate();
|
values.validate();
|
||||||
} else {
|
} else {
|
||||||
tty->print_cr("[Describe stack layout]");
|
tty->print_cr("[Describe stack layout]");
|
||||||
values.print();
|
values.print(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user