8073705: more performance issues in class redefinition
Optimize the method pointer adjustments for prev klass versions and MNT Reviewed-by: dcubed, coleenp
This commit is contained in:
parent
8cb760c280
commit
f7c143cbb2
@ -2831,33 +2831,6 @@ bool java_lang_invoke_MemberName::is_method(oop mname) {
|
||||
return (flags(mname) & (MN_IS_METHOD | MN_IS_CONSTRUCTOR)) > 0;
|
||||
}
|
||||
|
||||
#if INCLUDE_JVMTI
|
||||
// Can be executed on VM thread only
|
||||
void java_lang_invoke_MemberName::adjust_vmtarget(oop mname, Method* old_method,
|
||||
Method* new_method, bool* trace_name_printed) {
|
||||
assert(is_method(mname), "wrong type");
|
||||
assert(Thread::current()->is_VM_thread(), "not VM thread");
|
||||
|
||||
Method* target = (Method*)mname->address_field(_vmtarget_offset);
|
||||
if (target == old_method) {
|
||||
mname->address_field_put(_vmtarget_offset, (address)new_method);
|
||||
|
||||
if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
|
||||
if (!(*trace_name_printed)) {
|
||||
// RC_TRACE_MESG macro has an embedded ResourceMark
|
||||
RC_TRACE_MESG(("adjust: name=%s",
|
||||
old_method->method_holder()->external_name()));
|
||||
*trace_name_printed = true;
|
||||
}
|
||||
// RC_TRACE macro has an embedded ResourceMark
|
||||
RC_TRACE(0x00400000, ("MemberName method update: %s(%s)",
|
||||
new_method->name()->as_C_string(),
|
||||
new_method->signature()->as_C_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // INCLUDE_JVMTI
|
||||
|
||||
void java_lang_invoke_MemberName::set_vmtarget(oop mname, Metadata* ref) {
|
||||
assert(is_instance(mname), "wrong type");
|
||||
// check the type of the vmtarget
|
||||
|
@ -1092,10 +1092,6 @@ class java_lang_invoke_MemberName: AllStatic {
|
||||
|
||||
static Metadata* vmtarget(oop mname);
|
||||
static void set_vmtarget(oop mname, Metadata* target);
|
||||
#if INCLUDE_JVMTI
|
||||
static void adjust_vmtarget(oop mname, Method* old_method, Method* new_method,
|
||||
bool* trace_name_printed);
|
||||
#endif // INCLUDE_JVMTI
|
||||
|
||||
static intptr_t vmindex(oop mname);
|
||||
static void set_vmindex(oop mname, intptr_t index);
|
||||
|
@ -604,44 +604,6 @@ void ConstantPoolCache::initialize(const intArray& inverse_index_map,
|
||||
|
||||
#if INCLUDE_JVMTI
|
||||
// RedefineClasses() API support:
|
||||
// If any entry of this ConstantPoolCache points to any of
|
||||
// old_methods, replace it with the corresponding new_method.
|
||||
void ConstantPoolCache::adjust_method_entries(Method** old_methods, Method** new_methods,
|
||||
int methods_length, bool * trace_name_printed) {
|
||||
|
||||
if (methods_length == 0) {
|
||||
// nothing to do if there are no methods
|
||||
return;
|
||||
}
|
||||
|
||||
// get shorthand for the interesting class
|
||||
Klass* old_holder = old_methods[0]->method_holder();
|
||||
|
||||
for (int i = 0; i < length(); i++) {
|
||||
if (entry_at(i)->get_interesting_method_entry(old_holder) == NULL) {
|
||||
// skip uninteresting methods
|
||||
continue;
|
||||
}
|
||||
|
||||
// The ConstantPoolCache contains entries for several different
|
||||
// things, but we only care about methods. In fact, we only care
|
||||
// about methods in the same class as the one that contains the
|
||||
// old_methods. At this point, we have an interesting entry.
|
||||
|
||||
for (int j = 0; j < methods_length; j++) {
|
||||
Method* old_method = old_methods[j];
|
||||
Method* new_method = new_methods[j];
|
||||
|
||||
if (entry_at(i)->adjust_method_entry(old_method, new_method,
|
||||
trace_name_printed)) {
|
||||
// current old_method matched this entry and we updated it so
|
||||
// break out and get to the next interesting entry if there one
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If any entry of this ConstantPoolCache points to any of
|
||||
// old_methods, replace it with the corresponding new_method.
|
||||
void ConstantPoolCache::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) {
|
||||
|
@ -477,8 +477,6 @@ class ConstantPoolCache: public MetaspaceObj {
|
||||
// trace_name_printed is set to true if the current call has
|
||||
// printed the klass name so that other routines in the adjust_*
|
||||
// group don't print the klass name.
|
||||
void adjust_method_entries(Method** old_methods, Method** new_methods,
|
||||
int methods_length, bool* trace_name_printed);
|
||||
void adjust_method_entries(InstanceKlass* holder, bool* trace_name_printed);
|
||||
bool check_no_old_or_obsolete_entries();
|
||||
void dump_cache();
|
||||
|
@ -3433,10 +3433,7 @@ void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) {
|
||||
pv_node = pv_node->previous_versions()) {
|
||||
cp_cache = pv_node->constants()->cache();
|
||||
if (cp_cache != NULL) {
|
||||
cp_cache->adjust_method_entries(_matching_old_methods,
|
||||
_matching_new_methods,
|
||||
_matching_methods_length,
|
||||
&trace_name_printed);
|
||||
cp_cache->adjust_method_entries(pv_node, &trace_name_printed);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4085,10 +4082,7 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass,
|
||||
MemberNameTable* mnt = the_class->member_names();
|
||||
if (mnt != NULL) {
|
||||
bool trace_name_printed = false;
|
||||
mnt->adjust_method_entries(_matching_old_methods,
|
||||
_matching_new_methods,
|
||||
_matching_methods_length,
|
||||
&trace_name_printed);
|
||||
mnt->adjust_method_entries(the_class(), &trace_name_printed);
|
||||
}
|
||||
|
||||
// Fix Resolution Error table also to remove old constant pools
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "oops/objArrayOop.inline.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
#include "prims/jvmtiRedefineClassesTrace.hpp"
|
||||
#include "runtime/compilationPolicy.hpp"
|
||||
#include "runtime/javaCalls.hpp"
|
||||
#include "runtime/reflection.hpp"
|
||||
@ -965,21 +966,41 @@ void MemberNameTable::add_member_name(jweak mem_name_wref) {
|
||||
|
||||
#if INCLUDE_JVMTI
|
||||
// It is called at safepoint only for RedefineClasses
|
||||
void MemberNameTable::adjust_method_entries(Method** old_methods, Method** new_methods,
|
||||
int methods_length, bool *trace_name_printed) {
|
||||
void MemberNameTable::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
|
||||
// For each redefined method
|
||||
for (int j = 0; j < methods_length; j++) {
|
||||
Method* old_method = old_methods[j];
|
||||
Method* new_method = new_methods[j];
|
||||
for (int idx = 0; idx < length(); idx++) {
|
||||
oop mem_name = JNIHandles::resolve(this->at(idx));
|
||||
if (mem_name == NULL) {
|
||||
continue;
|
||||
}
|
||||
Method* old_method = (Method*)java_lang_invoke_MemberName::vmtarget(mem_name);
|
||||
|
||||
// search the MemberNameTable for uses of either obsolete or EMCP methods
|
||||
for (int idx = 0; idx < length(); idx++) {
|
||||
oop mem_name = JNIHandles::resolve(this->at(idx));
|
||||
if (mem_name != NULL) {
|
||||
java_lang_invoke_MemberName::adjust_vmtarget(mem_name, old_method, new_method,
|
||||
trace_name_printed);
|
||||
if (old_method == NULL || !old_method->is_old()) {
|
||||
continue; // skip uninteresting entries
|
||||
}
|
||||
if (old_method->is_deleted()) {
|
||||
// skip entries with deleted methods
|
||||
continue;
|
||||
}
|
||||
Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum());
|
||||
|
||||
assert(new_method != NULL, "method_with_idnum() should not be NULL");
|
||||
assert(old_method != new_method, "sanity check");
|
||||
|
||||
java_lang_invoke_MemberName::set_vmtarget(mem_name, new_method);
|
||||
|
||||
if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
|
||||
if (!(*trace_name_printed)) {
|
||||
// RC_TRACE_MESG macro has an embedded ResourceMark
|
||||
RC_TRACE_MESG(("adjust: name=%s",
|
||||
old_method->method_holder()->external_name()));
|
||||
*trace_name_printed = true;
|
||||
}
|
||||
// RC_TRACE macro has an embedded ResourceMark
|
||||
RC_TRACE(0x00400000, ("MemberName method update: %s(%s)",
|
||||
new_method->name()->as_C_string(),
|
||||
new_method->signature()->as_C_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -238,10 +238,8 @@ class MemberNameTable : public GrowableArray<jweak> {
|
||||
|
||||
#if INCLUDE_JVMTI
|
||||
// RedefineClasses() API support:
|
||||
// If a MemberName refers to old_method then update it
|
||||
// to refer to new_method.
|
||||
void adjust_method_entries(Method** old_methods, Method** new_methods,
|
||||
int methods_length, bool *trace_name_printed);
|
||||
// If a MemberName refers to old_method then update it to refer to new_method.
|
||||
void adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed);
|
||||
#endif // INCLUDE_JVMTI
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user