Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8252024: [lworld] Lock ordering issue when printing nmethod labels #302

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -129,10 +129,6 @@ int ciInlineKlass::oop_count() const {
GUARDED_VM_ENTRY(return get_InlineKlass()->nonstatic_oop_count();)
}

Array<SigEntry>* ciInlineKlass::extended_sig() const {
GUARDED_VM_ENTRY(return get_InlineKlass()->extended_sig();)
}

address ciInlineKlass::pack_handler() const {
GUARDED_VM_ENTRY(return get_InlineKlass()->pack_handler();)
}
@@ -87,7 +87,6 @@ class ciInlineKlass : public ciInstanceKlass {
ciInstance* default_instance() const;
bool contains_oops() const;
int oop_count() const;
Array<SigEntry>* extended_sig() const;
address pack_handler() const;
address unpack_handler() const;
InlineKlass* get_InlineKlass() const;
@@ -3177,103 +3177,86 @@ void nmethod::print_nmethod_labels(outputStream* stream, address block_begin, bo
}

// Print the arguments for the 3 types of verified entry points
{
const CompiledEntrySignature* ces = _nmethod_to_print_ces;
const GrowableArray<SigEntry>* sig_cc;
const VMRegPair* regs;
if (block_begin == verified_entry_point()) {
sig_cc = &ces->sig_cc();
regs = ces->regs_cc();
} else if (block_begin == verified_inline_entry_point()) {
sig_cc = &ces->sig();
regs = ces->regs();
} else if (block_begin == verified_inline_ro_entry_point()) {
sig_cc = &ces->sig_cc_ro();
regs = ces->regs_cc_ro();
} else {
return;
}
const CompiledEntrySignature* ces = _nmethod_to_print_ces;
const GrowableArray<SigEntry>* sig_cc;
const VMRegPair* regs;
if (block_begin == verified_entry_point()) {
sig_cc = &ces->sig_cc();
regs = ces->regs_cc();
} else if (block_begin == verified_inline_entry_point()) {
sig_cc = &ces->sig();
regs = ces->regs();
} else if (block_begin == verified_inline_ro_entry_point()) {
sig_cc = &ces->sig_cc_ro();
regs = ces->regs_cc_ro();
} else {
return;
}

ResourceMark rm;
int sizeargs = 0;
BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, 256);
TempNewSymbol sig = SigEntry::create_symbol(sig_cc);
for (SignatureStream ss(sig); !ss.at_return_type(); ss.next()) {
BasicType t = ss.type();
sig_bt[sizeargs++] = t;
if (type2size[t] == 2) {
sig_bt[sizeargs++] = T_VOID;
} else {
assert(type2size[t] == 1, "size is 1 or 2");
bool has_this = !m->is_static();
if (ces->has_inline_recv() && block_begin == verified_entry_point()) {
// <this> argument is scalarized for verified_entry_point()
has_this = false;
}
const char* spname = "sp"; // make arch-specific?
int stack_slot_offset = this->frame_size() * wordSize;
int tab1 = 14, tab2 = 24;
int sig_index = 0;
int arg_index = has_this ? -1 : 0;
bool did_old_sp = false;
for (ExtendedSignature sig = ExtendedSignature(sig_cc, SigEntryFilter()); !sig.at_end(); ++sig) {
bool at_this = (arg_index == -1);
bool at_old_sp = false;
BasicType t = (*sig)._bt;
if (at_this) {
stream->print(" # this: ");
} else {
stream->print(" # parm%d: ", arg_index);
}
stream->move_to(tab1);
VMReg fst = regs[sig_index].first();
VMReg snd = regs[sig_index].second();
if (fst->is_reg()) {
stream->print("%s", fst->name());
if (snd->is_valid()) {
stream->print(":%s", snd->name());
}
} else if (fst->is_stack()) {
int offset = fst->reg2stack() * VMRegImpl::stack_slot_size + stack_slot_offset;
if (offset == stack_slot_offset) at_old_sp = true;
stream->print("[%s+0x%x]", spname, offset);
} else {
stream->print("reg%d:%d??", (int)(intptr_t)fst, (int)(intptr_t)snd);
}
bool has_this = !m->is_static();
if (ces->has_inline_recv() && block_begin == verified_entry_point()) {
// <this> argument is scalarized for verified_entry_point()
has_this = false;
}
const char* spname = "sp"; // make arch-specific?
int stack_slot_offset = this->frame_size() * wordSize;
int tab1 = 14, tab2 = 24;
int sig_index = 0;
int arg_index = has_this ? -1 : 0;
bool did_old_sp = false;
for (SignatureStream ss(sig); !ss.at_return_type(); ) {
bool at_this = (arg_index == -1);
bool at_old_sp = false;
BasicType t = ss.type();
assert(t == sig_bt[sig_index], "sigs in sync");
if (at_this) {
stream->print(" # this: ");
} else {
stream->print(" # parm%d: ", arg_index);
}
stream->move_to(tab1);
VMReg fst = regs[sig_index].first();
VMReg snd = regs[sig_index].second();
if (fst->is_reg()) {
stream->print("%s", fst->name());
if (snd->is_valid()) {
stream->print(":%s", snd->name());
}
} else if (fst->is_stack()) {
int offset = fst->reg2stack() * VMRegImpl::stack_slot_size + stack_slot_offset;
if (offset == stack_slot_offset) at_old_sp = true;
stream->print("[%s+0x%x]", spname, offset);
} else {
stream->print("reg%d:%d??", (int)(intptr_t)fst, (int)(intptr_t)snd);
}
stream->print(" ");
stream->move_to(tab2);
stream->print("= ");
if (at_this) {
m->method_holder()->print_value_on(stream);
} else {
bool did_name = false;
if (ss.is_reference()) {
Symbol* name = ss.as_symbol();
name->print_value_on(stream);
did_name = true;
}
if (!did_name)
stream->print("%s", type2name(t));
}
if (at_old_sp) {
stream->print(" (%s of caller)", spname);
did_old_sp = true;
stream->print(" ");
stream->move_to(tab2);
stream->print("= ");
if (at_this) {
m->method_holder()->print_value_on(stream);
} else {
bool did_name = false;
if (is_reference_type(t)) {
Symbol* name = (*sig)._symbol;
name->print_value_on(stream);
did_name = true;
}
stream->cr();
sig_index += type2size[t];
arg_index += 1;
ss.next();
}
if (!did_old_sp) {
stream->print(" # ");
stream->move_to(tab1);
stream->print("[%s+0x%x]", spname, stack_slot_offset);
if (!did_name)
stream->print("%s", type2name(t));
}
if (at_old_sp) {
stream->print(" (%s of caller)", spname);
stream->cr();
did_old_sp = true;
}
stream->cr();
sig_index += type2size[t];
arg_index += 1;
}
if (!did_old_sp) {
stream->print(" # ");
stream->move_to(tab1);
stream->print("[%s+0x%x]", spname, stack_slot_offset);
stream->print(" (%s of caller)", spname);
stream->cr();
}
}

@@ -237,7 +237,7 @@ Klass* InlineKlass::array_klass_impl(bool or_null, TRAPS) {
// types is an argument: drop all T_INLINE_TYPE/T_VOID from the list).
int InlineKlass::collect_fields(GrowableArray<SigEntry>* sig, int base_off) {
int count = 0;
SigEntry::add_entry(sig, T_INLINE_TYPE, base_off);
SigEntry::add_entry(sig, T_INLINE_TYPE, name(), base_off);
for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
if (fs.access_flags().is_static()) continue;
int offset = base_off + fs.offset() - (base_off > 0 ? first_field_offset() : 0);
@@ -250,12 +250,12 @@ int InlineKlass::collect_fields(GrowableArray<SigEntry>* sig, int base_off) {
if (bt == T_INLINE_TYPE) {
bt = T_OBJECT;
}
SigEntry::add_entry(sig, bt, offset);
SigEntry::add_entry(sig, bt, fs.signature(), offset);
count += type2size[bt];
}
}
int offset = base_off + size_helper()*HeapWordSize - (base_off > 0 ? first_field_offset() : 0);
SigEntry::add_entry(sig, T_VOID, offset);
SigEntry::add_entry(sig, T_VOID, name(), offset);
if (base_off == 0) {
sig->sort(SigEntry::compare);
}
@@ -445,8 +445,7 @@ void LateInlineCallGenerator::do_late_inline() {
// Make enough space in the expression stack to transfer
// the incoming arguments and return value.
map->ensure_stack(jvms, jvms->method()->max_stack());
const TypeTuple *domain_sig = call->_tf->domain_sig();
ExtendedSignature sig_cc = ExtendedSignature(method()->get_sig_cc(), SigEntryFilter());
const TypeTuple* domain_sig = call->_tf->domain_sig();
uint nargs = method()->arg_size();
assert(domain_sig->cnt() - TypeFunc::Parms == nargs, "inconsistent signature");

@@ -457,7 +456,7 @@ void LateInlineCallGenerator::do_late_inline() {
// Inline type arguments are not passed by reference: we get an argument per
// field of the inline type. Build InlineTypeNodes from the inline type arguments.
GraphKit arg_kit(jvms, &gvn);
InlineTypeNode* vt = InlineTypeNode::make_from_multi(&arg_kit, call, sig_cc, t->inline_klass(), j, true);
InlineTypeNode* vt = InlineTypeNode::make_from_multi(&arg_kit, call, t->inline_klass(), j, true);
map->set_control(arg_kit.control());
map->set_argument(jvms, i1, vt);
} else {
@@ -1812,15 +1812,14 @@ void GraphKit::set_arguments_for_java_call(CallJavaNode* call, bool is_late_inli
}
// Add the call arguments
const TypeTuple* domain = call->tf()->domain_sig();
ExtendedSignature sig_cc = ExtendedSignature(call->method()->get_sig_cc(), SigEntryFilter());
uint nargs = domain->cnt();
for (uint i = TypeFunc::Parms, idx = TypeFunc::Parms; i < nargs; i++) {
Node* arg = argument(i-TypeFunc::Parms);
const Type* t = domain->field_at(i);
if (call->method()->has_scalarized_args() && t->is_inlinetypeptr() && !t->maybe_null() && t->inline_klass()->can_be_passed_as_fields()) {
// We don't pass inline type arguments by reference but instead pass each field of the inline type
InlineTypeNode* vt = arg->as_InlineType();
vt->pass_fields(this, call, sig_cc, idx);
vt->pass_fields(this, call, idx);
// If an inline type argument is passed as fields, attach the Method* to the call site
// to be able to access the extended signature later via attached_method_before_pc().
// For example, see CompiledMethod::preserve_callee_argument_oops().
@@ -1892,12 +1891,8 @@ Node* GraphKit::set_results_for_java_call(CallJavaNode* call, bool separate_io_p
// Return of multiple values (inline type fields): we create a
// InlineType node, each field is a projection from the call.
ciInlineKlass* vk = call->method()->return_type()->as_inline_klass();
const Array<SigEntry>* sig_array = vk->extended_sig();
GrowableArray<SigEntry> sig = GrowableArray<SigEntry>(sig_array->length());
sig.appendAll(sig_array);
ExtendedSignature sig_cc = ExtendedSignature(&sig, SigEntryFilter());
uint base_input = TypeFunc::Parms + 1;
ret = InlineTypeNode::make_from_multi(this, call, sig_cc, vk, base_input, false);
ret = InlineTypeNode::make_from_multi(this, call, vk, base_input, false);
} else {
ret = _gvn.transform(new ProjNode(call, TypeFunc::Parms));
}
@@ -604,9 +604,9 @@ InlineTypeNode* InlineTypeNode::make_from_flattened(GraphKit* kit, ciInlineKlass
return kit->gvn().transform(vt)->as_InlineType();
}

InlineTypeNode* InlineTypeNode::make_from_multi(GraphKit* kit, MultiNode* multi, ExtendedSignature& sig, ciInlineKlass* vk, uint& base_input, bool in) {
InlineTypeNode* InlineTypeNode::make_from_multi(GraphKit* kit, MultiNode* multi, ciInlineKlass* vk, uint& base_input, bool in) {
InlineTypeNode* vt = make_uninitialized(kit->gvn(), vk);
vt->initialize_fields(kit, multi, sig, base_input, in);
vt->initialize_fields(kit, multi, base_input, in);
return kit->gvn().transform(vt)->as_InlineType();
}

@@ -713,7 +713,7 @@ Node* InlineTypeNode::tagged_klass(ciInlineKlass* vk, PhaseGVN& gvn) {
return gvn.makecon(TypeRawPtr::make((address)bits));
}

void InlineTypeNode::pass_fields(GraphKit* kit, Node* n, ExtendedSignature& sig, uint& base_input) {
void InlineTypeNode::pass_fields(GraphKit* kit, Node* n, uint& base_input) {
for (uint i = 0; i < field_count(); i++) {
int offset = field_offset(i);
ciType* type = field_type(i);
@@ -722,7 +722,7 @@ void InlineTypeNode::pass_fields(GraphKit* kit, Node* n, ExtendedSignature& sig,
if (field_is_flattened(i)) {
// Flattened inline type field
InlineTypeNode* vt = arg->as_InlineType();
vt->pass_fields(kit, n, sig, base_input);
vt->pass_fields(kit, n, base_input);
} else {
if (arg->is_InlineType()) {
// Non-flattened inline type field
@@ -740,15 +740,15 @@ void InlineTypeNode::pass_fields(GraphKit* kit, Node* n, ExtendedSignature& sig,
}
}

void InlineTypeNode::initialize_fields(GraphKit* kit, MultiNode* multi, ExtendedSignature& sig, uint& base_input, bool in) {
void InlineTypeNode::initialize_fields(GraphKit* kit, MultiNode* multi, uint& base_input, bool in) {
PhaseGVN& gvn = kit->gvn();
for (uint i = 0; i < field_count(); ++i) {
ciType* type = field_type(i);
Node* parm = NULL;
if (field_is_flattened(i)) {
// Flattened inline type field
InlineTypeNode* vt = make_uninitialized(gvn, type->as_inline_klass());
vt->initialize_fields(kit, multi, sig, base_input, in);
vt->initialize_fields(kit, multi, base_input, in);
parm = gvn.transform(vt);
} else {
if (multi->is_Start()) {
@@ -126,7 +126,7 @@ class InlineTypeNode : public InlineTypeBaseNode {
// Create and initialize by loading the field values from a flattened field or array
static InlineTypeNode* make_from_flattened(GraphKit* kit, ciInlineKlass* vk, Node* obj, Node* ptr, ciInstanceKlass* holder = NULL, int holder_offset = 0, DecoratorSet decorators = IN_HEAP | MO_UNORDERED);
// Create and initialize with the inputs or outputs of a MultiNode (method entry or call)
static InlineTypeNode* make_from_multi(GraphKit* kit, MultiNode* multi, ExtendedSignature& sig, ciInlineKlass* vk, uint& base_input, bool in);
static InlineTypeNode* make_from_multi(GraphKit* kit, MultiNode* multi, ciInlineKlass* vk, uint& base_input, bool in);

InlineTypeNode* make_larval(GraphKit* kit, bool allocate) const;
InlineTypeNode* finish_larval(GraphKit* kit) const;
@@ -139,9 +139,9 @@ class InlineTypeNode : public InlineTypeBaseNode {
}
static Node* tagged_klass(ciInlineKlass* vk, PhaseGVN& gvn);
// Pass inline type as fields at a call or return
void pass_fields(GraphKit* kit, Node* n, ExtendedSignature& sig, uint& base_input);
void pass_fields(GraphKit* kit, Node* n, uint& base_input);
// Initialize the inline type fields with the inputs or outputs of a MultiNode
void initialize_fields(GraphKit* kit, MultiNode* multi, ExtendedSignature& sig, uint& base_input, bool in);
void initialize_fields(GraphKit* kit, MultiNode* multi, uint& base_input, bool in);

// Allocation optimizations
void remove_redundant_allocations(PhaseIterGVN* igvn, PhaseIdealLoop* phase);
@@ -862,7 +862,6 @@ JVMState* Compile::build_start_state(StartNode* start, const TypeFunc* tf) {
}
PhaseGVN& gvn = *initial_gvn();
uint i = 0;
ExtendedSignature sig_cc = ExtendedSignature(method()->get_sig_cc(), SigEntryFilter());
for (uint j = 0; i < (uint)arg_size; i++) {
const Type* t = tf->domain_sig()->field_at(i);
Node* parm = NULL;
@@ -874,7 +873,7 @@ JVMState* Compile::build_start_state(StartNode* start, const TypeFunc* tf) {
Node* old_mem = map->memory();
// Use immutable memory for inline type loads and restore it below
kit.set_all_memory(C->immutable_memory());
parm = InlineTypeNode::make_from_multi(&kit, start, sig_cc, t->inline_klass(), j, true);
parm = InlineTypeNode::make_from_multi(&kit, start, t->inline_klass(), j, true);
map->set_control(kit.control());
map->set_memory(old_mem);
} else {
@@ -931,12 +930,8 @@ void Compile::return_values(JVMState* jvms) {
} else {
ret->init_req(TypeFunc::Parms, vt->tagged_klass(kit.gvn()));
}
const Array<SigEntry>* sig_array = vt->type()->inline_klass()->extended_sig();
GrowableArray<SigEntry> sig = GrowableArray<SigEntry>(sig_array->length());
sig.appendAll(sig_array);
ExtendedSignature sig_cc = ExtendedSignature(&sig, SigEntryFilter());
uint idx = TypeFunc::Parms+1;
vt->pass_fields(&kit, ret, sig_cc, idx);
uint idx = TypeFunc::Parms + 1;
vt->pass_fields(&kit, ret, idx);
} else {
ret->add_req(res);
// Note: The second dummy edge is not needed by a ReturnNode.