提交 138a1f59 编写于 作者: S sspitsyn

8073705: more performance issues in class redefinition

Summary: Optimize the method pointer adjustments for prev klass versions and MNT
Reviewed-by: dcubed, coleenp
上级 7943b396
...@@ -2801,33 +2801,6 @@ bool java_lang_invoke_MemberName::is_method(oop mname) { ...@@ -2801,33 +2801,6 @@ bool java_lang_invoke_MemberName::is_method(oop mname) {
return (flags(mname) & (MN_IS_METHOD | MN_IS_CONSTRUCTOR)) > 0; 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) { void java_lang_invoke_MemberName::set_vmtarget(oop mname, Metadata* ref) {
assert(is_instance(mname), "wrong type"); assert(is_instance(mname), "wrong type");
// check the type of the vmtarget // check the type of the vmtarget
......
...@@ -1096,10 +1096,6 @@ class java_lang_invoke_MemberName: AllStatic { ...@@ -1096,10 +1096,6 @@ class java_lang_invoke_MemberName: AllStatic {
static Metadata* vmtarget(oop mname); static Metadata* vmtarget(oop mname);
static void set_vmtarget(oop mname, Metadata* target); 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 intptr_t vmindex(oop mname);
static void set_vmindex(oop mname, intptr_t index); static void set_vmindex(oop mname, intptr_t index);
......
...@@ -602,44 +602,6 @@ void ConstantPoolCache::initialize(const intArray& inverse_index_map, ...@@ -602,44 +602,6 @@ void ConstantPoolCache::initialize(const intArray& inverse_index_map,
#if INCLUDE_JVMTI #if INCLUDE_JVMTI
// RedefineClasses() API support: // 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 // If any entry of this ConstantPoolCache points to any of
// old_methods, replace it with the corresponding new_method. // old_methods, replace it with the corresponding new_method.
void ConstantPoolCache::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) { void ConstantPoolCache::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) {
......
...@@ -476,8 +476,6 @@ class ConstantPoolCache: public MetaspaceObj { ...@@ -476,8 +476,6 @@ class ConstantPoolCache: public MetaspaceObj {
// trace_name_printed is set to true if the current call has // trace_name_printed is set to true if the current call has
// printed the klass name so that other routines in the adjust_* // printed the klass name so that other routines in the adjust_*
// group don't print the klass name. // 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); void adjust_method_entries(InstanceKlass* holder, bool* trace_name_printed);
bool check_no_old_or_obsolete_entries(); bool check_no_old_or_obsolete_entries();
void dump_cache(); void dump_cache();
......
...@@ -3433,10 +3433,7 @@ void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) { ...@@ -3433,10 +3433,7 @@ void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) {
other_cp = pv_node->prev_constant_pool(); other_cp = pv_node->prev_constant_pool();
cp_cache = other_cp->cache(); cp_cache = other_cp->cache();
if (cp_cache != NULL) { if (cp_cache != NULL) {
cp_cache->adjust_method_entries(_matching_old_methods, cp_cache->adjust_method_entries(other_cp->pool_holder(), &trace_name_printed);
_matching_new_methods,
_matching_methods_length,
&trace_name_printed);
} }
} }
} }
...@@ -4071,10 +4068,7 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass, ...@@ -4071,10 +4068,7 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass,
MemberNameTable* mnt = the_class->member_names(); MemberNameTable* mnt = the_class->member_names();
if (mnt != NULL) { if (mnt != NULL) {
bool trace_name_printed = false; bool trace_name_printed = false;
mnt->adjust_method_entries(_matching_old_methods, mnt->adjust_method_entries(the_class(), &trace_name_printed);
_matching_new_methods,
_matching_methods_length,
&trace_name_printed);
} }
// Fix Resolution Error table also to remove old constant pools // Fix Resolution Error table also to remove old constant pools
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "memory/allocation.inline.hpp" #include "memory/allocation.inline.hpp"
#include "memory/oopFactory.hpp" #include "memory/oopFactory.hpp"
#include "prims/methodHandles.hpp" #include "prims/methodHandles.hpp"
#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "runtime/compilationPolicy.hpp" #include "runtime/compilationPolicy.hpp"
#include "runtime/javaCalls.hpp" #include "runtime/javaCalls.hpp"
#include "runtime/reflection.hpp" #include "runtime/reflection.hpp"
...@@ -955,21 +956,41 @@ void MemberNameTable::add_member_name(jweak mem_name_wref) { ...@@ -955,21 +956,41 @@ void MemberNameTable::add_member_name(jweak mem_name_wref) {
#if INCLUDE_JVMTI #if INCLUDE_JVMTI
// It is called at safepoint only for RedefineClasses // It is called at safepoint only for RedefineClasses
void MemberNameTable::adjust_method_entries(Method** old_methods, Method** new_methods, void MemberNameTable::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) {
int methods_length, bool *trace_name_printed) {
assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint"); assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
// For each redefined method // For each redefined method
for (int j = 0; j < methods_length; j++) {
Method* old_method = old_methods[j];
Method* new_method = new_methods[j];
// search the MemberNameTable for uses of either obsolete or EMCP methods
for (int idx = 0; idx < length(); idx++) { for (int idx = 0; idx < length(); idx++) {
oop mem_name = JNIHandles::resolve(this->at(idx)); oop mem_name = JNIHandles::resolve(this->at(idx));
if (mem_name != NULL) { if (mem_name == NULL) {
java_lang_invoke_MemberName::adjust_vmtarget(mem_name, old_method, new_method, continue;
trace_name_printed); }
Method* old_method = (Method*)java_lang_invoke_MemberName::vmtarget(mem_name);
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()));
} }
} }
} }
......
...@@ -240,10 +240,8 @@ class MemberNameTable : public GrowableArray<jweak> { ...@@ -240,10 +240,8 @@ class MemberNameTable : public GrowableArray<jweak> {
#if INCLUDE_JVMTI #if INCLUDE_JVMTI
// RedefineClasses() API support: // RedefineClasses() API support:
// If a MemberName refers to old_method then update it // If a MemberName refers to old_method then update it to refer to new_method.
// to refer to new_method. void adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed);
void adjust_method_entries(Method** old_methods, Method** new_methods,
int methods_length, bool *trace_name_printed);
#endif // INCLUDE_JVMTI #endif // INCLUDE_JVMTI
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册