提交 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) {
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
......
......@@ -1096,10 +1096,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);
......
......@@ -602,44 +602,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) {
......
......@@ -476,8 +476,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) {
other_cp = pv_node->prev_constant_pool();
cp_cache = other_cp->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(other_cp->pool_holder(), &trace_name_printed);
}
}
}
......@@ -4071,10 +4068,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
......
......@@ -30,6 +30,7 @@
#include "memory/allocation.inline.hpp"
#include "memory/oopFactory.hpp"
#include "prims/methodHandles.hpp"
#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "runtime/compilationPolicy.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/reflection.hpp"
......@@ -955,21 +956,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];
// 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);
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);
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> {
#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
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册