提交 e97a0e05 编写于 作者: S sspitsyn

8008511: JSR 292: MemberName vmtarget refs to methods must be updated at class redefinition

Summary: Lazily create and maintain the MemberNameTable to be able to update MemberName's
Reviewed-by: coleenp, jrose, dholmes
Contributed-by: serguei.spitsyn@oracle.com
上级 71b856e4
......@@ -2625,6 +2625,15 @@ Metadata* java_lang_invoke_MemberName::vmtarget(oop mname) {
return (Metadata*)mname->address_field(_vmtarget_offset);
}
#if INCLUDE_JVMTI
// Can be executed on VM thread only
void java_lang_invoke_MemberName::adjust_vmtarget(oop mname, Metadata* ref) {
assert((is_instance(mname) && (flags(mname) & (MN_IS_METHOD | MN_IS_CONSTRUCTOR)) > 0), "wrong type");
assert(Thread::current()->is_VM_thread(), "not VM thread");
mname->address_field_put(_vmtarget_offset, (address)ref);
}
#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
......
......@@ -1036,6 +1036,9 @@ 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, Metadata* target);
#endif // INCLUDE_JVMTI
static intptr_t vmindex(oop mname);
static void set_vmindex(oop mname, intptr_t index);
......
......@@ -2329,6 +2329,12 @@ void InstanceKlass::release_C_heap_structures() {
FreeHeap(jmeths);
}
MemberNameTable* mnt = member_names();
if (mnt != NULL) {
delete mnt;
set_member_names(NULL);
}
int* indices = methods_cached_itable_indices_acquire();
if (indices != (int*)NULL) {
release_set_methods_cached_itable_indices(NULL);
......@@ -2757,6 +2763,17 @@ nmethod* InstanceKlass::lookup_osr_nmethod(Method* const m, int bci, int comp_le
return NULL;
}
void InstanceKlass::add_member_name(Handle mem_name) {
jweak mem_name_wref = JNIHandles::make_weak_global(mem_name);
MutexLocker ml(MemberNameTable_lock);
DEBUG_ONLY(No_Safepoint_Verifier nsv);
if (_member_names == NULL) {
_member_names = new (ResourceObj::C_HEAP, mtClass) MemberNameTable();
}
_member_names->add_member_name(mem_name_wref);
}
// -----------------------------------------------------------------------------------------------------
// Printing
......
......@@ -90,6 +90,7 @@ class DepChange;
class nmethodBucket;
class PreviousVersionNode;
class JvmtiCachedClassFieldMap;
class MemberNameTable;
// This is used in iterators below.
class FieldClosure: public StackObj {
......@@ -246,6 +247,7 @@ class InstanceKlass: public Klass {
int _vtable_len; // length of Java vtable (in words)
int _itable_len; // length of Java itable (in words)
OopMapCache* volatile _oop_map_cache; // OopMapCache for all methods in the klass (allocated lazily)
MemberNameTable* _member_names; // Member names
JNIid* _jni_ids; // First JNI identifier for static fields in this class
jmethodID* _methods_jmethod_ids; // jmethodIDs corresponding to method_idnum, or NULL if none
int* _methods_cached_itable_indices; // itable_index cache for JNI invoke corresponding to methods idnum, or NULL
......@@ -1028,6 +1030,11 @@ public:
// jvm support
jint compute_modifier_flags(TRAPS) const;
// JSR-292 support
MemberNameTable* member_names() { return _member_names; }
void set_member_names(MemberNameTable* member_names) { _member_names = member_names; }
void add_member_name(Handle member_name);
public:
// JVMTI support
jint jvmti_class_status() const;
......
......@@ -3284,6 +3284,16 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass,
// that reference methods of the evolved class.
SystemDictionary::classes_do(adjust_cpool_cache_and_vtable, THREAD);
// JSR-292 support
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);
}
// Fix Resolution Error table also to remove old constant pools
SystemDictionary::delete_resolution_error(old_constants);
......
......@@ -29,6 +29,7 @@
#include "interpreter/oopMapCache.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/oopFactory.hpp"
#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/compilationPolicy.hpp"
#include "runtime/javaCalls.hpp"
......@@ -124,7 +125,9 @@ Handle MethodHandles::new_MemberName(TRAPS) {
return Handle(THREAD, k->allocate_instance(THREAD));
}
oop MethodHandles::init_MemberName(oop mname_oop, oop target_oop) {
oop MethodHandles::init_MemberName(Handle mname, Handle target) {
Thread* thread = Thread::current();
oop target_oop = target();
Klass* target_klass = target_oop->klass();
if (target_klass == SystemDictionary::reflect_Field_klass()) {
oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder()
......@@ -132,24 +135,24 @@ oop MethodHandles::init_MemberName(oop mname_oop, oop target_oop) {
int mods = java_lang_reflect_Field::modifiers(target_oop);
oop type = java_lang_reflect_Field::type(target_oop);
oop name = java_lang_reflect_Field::name(target_oop);
Klass* k = java_lang_Class::as_Klass(clazz);
intptr_t offset = InstanceKlass::cast(k)->field_offset(slot);
return init_field_MemberName(mname_oop, k, accessFlags_from(mods), type, name, offset);
KlassHandle k(thread, java_lang_Class::as_Klass(clazz));
intptr_t offset = InstanceKlass::cast(k())->field_offset(slot);
return init_field_MemberName(mname, k, accessFlags_from(mods), type, name, offset);
} else if (target_klass == SystemDictionary::reflect_Method_klass()) {
oop clazz = java_lang_reflect_Method::clazz(target_oop);
int slot = java_lang_reflect_Method::slot(target_oop);
Klass* k = java_lang_Class::as_Klass(clazz);
if (k != NULL && k->oop_is_instance()) {
Method* m = InstanceKlass::cast(k)->method_with_idnum(slot);
return init_method_MemberName(mname_oop, m, true, k);
KlassHandle k(thread, java_lang_Class::as_Klass(clazz));
if (!k.is_null() && k->oop_is_instance()) {
Method* m = InstanceKlass::cast(k())->method_with_idnum(slot);
return init_method_MemberName(mname, m, true, k);
}
} else if (target_klass == SystemDictionary::reflect_Constructor_klass()) {
oop clazz = java_lang_reflect_Constructor::clazz(target_oop);
int slot = java_lang_reflect_Constructor::slot(target_oop);
Klass* k = java_lang_Class::as_Klass(clazz);
if (k != NULL && k->oop_is_instance()) {
Method* m = InstanceKlass::cast(k)->method_with_idnum(slot);
return init_method_MemberName(mname_oop, m, false, k);
KlassHandle k(thread, java_lang_Class::as_Klass(clazz));
if (!k.is_null() && k->oop_is_instance()) {
Method* m = InstanceKlass::cast(k())->method_with_idnum(slot);
return init_method_MemberName(mname, m, false, k);
}
} else if (target_klass == SystemDictionary::MemberName_klass()) {
// Note: This only works if the MemberName has already been resolved.
......@@ -157,17 +160,18 @@ oop MethodHandles::init_MemberName(oop mname_oop, oop target_oop) {
int flags = java_lang_invoke_MemberName::flags(target_oop);
Metadata* vmtarget=java_lang_invoke_MemberName::vmtarget(target_oop);
intptr_t vmindex = java_lang_invoke_MemberName::vmindex(target_oop);
Klass* k = java_lang_Class::as_Klass(clazz);
KlassHandle k(thread, java_lang_Class::as_Klass(clazz));
int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
if (vmtarget == NULL) return NULL; // not resolved
if ((flags & IS_FIELD) != 0) {
assert(vmtarget->is_klass(), "field vmtarget is Klass*");
int basic_mods = (ref_kind_is_static(ref_kind) ? JVM_ACC_STATIC : 0);
// FIXME: how does k (receiver_limit) contribute?
return init_field_MemberName(mname_oop, (Klass*)vmtarget, accessFlags_from(basic_mods), NULL, NULL, vmindex);
KlassHandle k_vmtarget(thread, (Klass*)vmtarget);
return init_field_MemberName(mname, k_vmtarget, accessFlags_from(basic_mods), NULL, NULL, vmindex);
} else if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) != 0) {
assert(vmtarget->is_method(), "method or constructor vmtarget is Method*");
return init_method_MemberName(mname_oop, (Method*)vmtarget, ref_kind_does_dispatch(ref_kind), k);
return init_method_MemberName(mname, (Method*)vmtarget, ref_kind_does_dispatch(ref_kind), k);
} else {
return NULL;
}
......@@ -175,8 +179,9 @@ oop MethodHandles::init_MemberName(oop mname_oop, oop target_oop) {
return NULL;
}
oop MethodHandles::init_method_MemberName(oop mname_oop, Method* m, bool do_dispatch,
Klass* receiver_limit) {
oop MethodHandles::init_method_MemberName(Handle mname, Method* m, bool do_dispatch,
KlassHandle receiver_limit_h) {
Klass* receiver_limit = receiver_limit_h();
AccessFlags mods = m->access_flags();
int flags = (jushort)( mods.as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS );
int vmindex = Method::nonvirtual_vtable_index; // implies never any dispatch
......@@ -218,6 +223,7 @@ oop MethodHandles::init_method_MemberName(oop mname_oop, Method* m, bool do_disp
flags |= CALLER_SENSITIVE;
}
oop mname_oop = mname();
java_lang_invoke_MemberName::set_flags( mname_oop, flags);
java_lang_invoke_MemberName::set_vmtarget(mname_oop, m);
java_lang_invoke_MemberName::set_vmindex( mname_oop, vmindex); // vtable/itable index
......@@ -230,10 +236,11 @@ oop MethodHandles::init_method_MemberName(oop mname_oop, Method* m, bool do_disp
// This is done eagerly, since it is readily available without
// constructing any new objects.
// TO DO: maybe intern mname_oop
return mname_oop;
m->method_holder()->add_member_name(mname);
return mname();
}
Handle MethodHandles::init_method_MemberName(oop mname_oop, CallInfo& info, TRAPS) {
Handle MethodHandles::init_method_MemberName(Handle mname, CallInfo& info, TRAPS) {
Handle empty;
if (info.resolved_appendix().not_null()) {
// The resolved MemberName must not be accompanied by an appendix argument,
......@@ -253,19 +260,20 @@ Handle MethodHandles::init_method_MemberName(oop mname_oop, CallInfo& info, TRAP
} else {
vmindex = info.vtable_index();
}
oop res = init_method_MemberName(mname_oop, m(), (vmindex >= 0), defc());
oop res = init_method_MemberName(mname, m(), (vmindex >= 0), defc());
assert(res == NULL || (java_lang_invoke_MemberName::vmindex(res) == vmindex), "");
return Handle(THREAD, res);
}
oop MethodHandles::init_field_MemberName(oop mname_oop, Klass* field_holder,
oop MethodHandles::init_field_MemberName(Handle mname, KlassHandle field_holder,
AccessFlags mods, oop type, oop name,
intptr_t offset, bool is_setter) {
int flags = (jushort)( mods.as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS );
flags |= IS_FIELD | ((mods.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT);
if (is_setter) flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT);
Metadata* vmtarget = field_holder;
Metadata* vmtarget = field_holder();
int vmindex = offset; // determines the field uniquely when combined with static bit
oop mname_oop = mname();
java_lang_invoke_MemberName::set_flags(mname_oop, flags);
java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget);
java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex);
......@@ -282,10 +290,11 @@ oop MethodHandles::init_field_MemberName(oop mname_oop, Klass* field_holder,
// Although the fieldDescriptor::_index would also identify the field,
// we do not use it, because it is harder to decode.
// TO DO: maybe intern mname_oop
return mname_oop;
InstanceKlass::cast(field_holder())->add_member_name(mname);
return mname();
}
Handle MethodHandles::init_field_MemberName(oop mname_oop, FieldAccessInfo& info, TRAPS) {
Handle MethodHandles::init_field_MemberName(Handle mname, FieldAccessInfo& info, TRAPS) {
return Handle();
#if 0 // FIXME
KlassHandle field_holder = info.klass();
......@@ -684,7 +693,7 @@ Handle MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
return empty;
}
}
return init_method_MemberName(mname(), result, THREAD);
return init_method_MemberName(mname, result, THREAD);
}
case IS_CONSTRUCTOR:
{
......@@ -702,7 +711,7 @@ Handle MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
}
}
assert(result.is_statically_bound(), "");
return init_method_MemberName(mname(), result, THREAD);
return init_method_MemberName(mname, result, THREAD);
}
case IS_FIELD:
{
......@@ -715,7 +724,7 @@ Handle MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
oop name = field_name_or_null(fd.name());
bool is_setter = (ref_kind_is_valid(ref_kind) && ref_kind_is_setter(ref_kind));
mname = Handle(THREAD,
init_field_MemberName(mname(), sel_klass(),
init_field_MemberName(mname, sel_klass,
fd.access_flags(), type, name, fd.offset(), is_setter));
return mname;
}
......@@ -807,16 +816,15 @@ void MethodHandles::expand_MemberName(Handle mname, int suppress, TRAPS) {
THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format");
}
int MethodHandles::find_MemberNames(Klass* k,
int MethodHandles::find_MemberNames(KlassHandle k,
Symbol* name, Symbol* sig,
int mflags, Klass* caller,
int skip, objArrayOop results) {
DEBUG_ONLY(No_Safepoint_Verifier nsv);
// this code contains no safepoints!
int mflags, KlassHandle caller,
int skip, objArrayHandle results) {
// %%% take caller into account!
if (k == NULL || !k->oop_is_instance()) return -1;
Thread* thread = Thread::current();
if (k.is_null() || !k->oop_is_instance()) return -1;
int rfill = 0, rlimit = results->length(), rskip = skip;
// overflow measurement:
......@@ -844,7 +852,7 @@ int MethodHandles::find_MemberNames(Klass* k,
}
if ((match_flags & IS_FIELD) != 0) {
for (FieldStream st(k, local_only, !search_intfc); !st.eos(); st.next()) {
for (FieldStream st(k(), local_only, !search_intfc); !st.eos(); st.next()) {
if (name != NULL && st.name() != name)
continue;
if (sig != NULL && st.signature() != sig)
......@@ -853,15 +861,15 @@ int MethodHandles::find_MemberNames(Klass* k,
if (rskip > 0) {
--rskip;
} else if (rfill < rlimit) {
oop result = results->obj_at(rfill++);
if (!java_lang_invoke_MemberName::is_instance(result))
Handle result(thread, results->obj_at(rfill++));
if (!java_lang_invoke_MemberName::is_instance(result()))
return -99; // caller bug!
oop type = field_signature_type_or_null(st.signature());
oop name = field_name_or_null(st.name());
oop saved = MethodHandles::init_field_MemberName(result, st.klass()(),
oop saved = MethodHandles::init_field_MemberName(result, st.klass(),
st.access_flags(), type, name,
st.offset());
if (saved != result)
if (saved != result())
results->obj_at_put(rfill-1, saved); // show saved instance to user
} else if (++overflow >= overflow_limit) {
match_flags = 0; break; // got tired of looking at overflow
......@@ -894,7 +902,7 @@ int MethodHandles::find_MemberNames(Klass* k,
} else {
// caller will accept either sort; no need to adjust name
}
for (MethodStream st(k, local_only, !search_intfc); !st.eos(); st.next()) {
for (MethodStream st(k(), local_only, !search_intfc); !st.eos(); st.next()) {
Method* m = st.method();
Symbol* m_name = m->name();
if (m_name == clinit_name)
......@@ -907,11 +915,11 @@ int MethodHandles::find_MemberNames(Klass* k,
if (rskip > 0) {
--rskip;
} else if (rfill < rlimit) {
oop result = results->obj_at(rfill++);
if (!java_lang_invoke_MemberName::is_instance(result))
Handle result(thread, results->obj_at(rfill++));
if (!java_lang_invoke_MemberName::is_instance(result()))
return -99; // caller bug!
oop saved = MethodHandles::init_method_MemberName(result, m, true, NULL);
if (saved != result)
if (saved != result())
results->obj_at_put(rfill-1, saved); // show saved instance to user
} else if (++overflow >= overflow_limit) {
match_flags = 0; break; // got tired of looking at overflow
......@@ -922,6 +930,99 @@ int MethodHandles::find_MemberNames(Klass* k,
// return number of elements we at leasted wanted to initialize
return rfill + overflow;
}
//------------------------------------------------------------------------------
// MemberNameTable
//
MemberNameTable::MemberNameTable() : GrowableArray<jweak>(10, true) {
assert_locked_or_safepoint(MemberNameTable_lock);
}
MemberNameTable::~MemberNameTable() {
assert_locked_or_safepoint(MemberNameTable_lock);
int len = this->length();
for (int idx = 0; idx < len; idx++) {
jweak ref = this->at(idx);
JNIHandles::destroy_weak_global(ref);
}
}
// Return entry index if found, return -1 otherwise.
int MemberNameTable::find_member_name(oop mem_name) {
assert_locked_or_safepoint(MemberNameTable_lock);
int len = this->length();
for (int idx = 0; idx < len; idx++) {
jweak ref = this->at(idx);
oop entry = JNIHandles::resolve(ref);
if (entry == mem_name) {
return idx;
}
}
return -1;
}
void MemberNameTable::add_member_name(jweak mem_name_wref) {
assert_locked_or_safepoint(MemberNameTable_lock);
oop mem_name = JNIHandles::resolve(mem_name_wref);
// Each member name may appear just once: add only if not found
if (find_member_name(mem_name) == -1) {
this->append(mem_name_wref);
}
}
#if INCLUDE_JVMTI
oop MemberNameTable::find_member_name_by_method(Method* old_method) {
assert_locked_or_safepoint(MemberNameTable_lock);
oop found = NULL;
int len = this->length();
for (int idx = 0; idx < len; idx++) {
oop mem_name = JNIHandles::resolve(this->at(idx));
if (mem_name == NULL) {
continue;
}
Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(mem_name);
if (method == old_method) {
found = mem_name;
break;
}
}
return found;
}
// It is called at safepoint only
void MemberNameTable::adjust_method_entries(Method** old_methods, Method** new_methods,
int methods_length, bool *trace_name_printed) {
assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
// search the MemberNameTable for uses of either obsolete or EMCP methods
for (int j = 0; j < methods_length; j++) {
Method* old_method = old_methods[j];
Method* new_method = new_methods[j];
oop mem_name = find_member_name_by_method(old_method);
if (mem_name != NULL) {
java_lang_invoke_MemberName::adjust_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()));
}
}
}
}
#endif // INCLUDE_JVMTI
//
// Here are the native methods in java.lang.invoke.MethodHandleNatives
// They are the private interface between this JVM and the HotSpot-specific
......@@ -1015,8 +1116,8 @@ JVM_ENTRY(void, MHN_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobje
if (mname_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); }
if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); }
Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
oop target_oop = JNIHandles::resolve_non_null(target_jh);
MethodHandles::init_MemberName(mname(), target_oop);
Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
MethodHandles::init_MemberName(mname, target);
}
JVM_END
......@@ -1123,7 +1224,7 @@ JVM_ENTRY(jobject, MHN_getMemberVMInfo(JNIEnv *env, jobject igcls, jobject mname
x = ((Klass*) vmtarget)->java_mirror();
} else if (vmtarget->is_method()) {
Handle mname2 = MethodHandles::new_MemberName(CHECK_NULL);
x = MethodHandles::init_method_MemberName(mname2(), (Method*)vmtarget, false, NULL);
x = MethodHandles::init_method_MemberName(mname2, (Method*)vmtarget, false, NULL);
}
result->obj_at_put(1, x);
return JNIHandles::make_local(env, result());
......@@ -1166,8 +1267,8 @@ JVM_ENTRY(jint, MHN_getMembers(JNIEnv *env, jobject igcls,
// %%% TO DO
}
int res = MethodHandles::find_MemberNames(k(), name, sig, mflags,
caller(), skip, results());
int res = MethodHandles::find_MemberNames(k, name, sig, mflags,
caller, skip, results);
// TO DO: expand at least some of the MemberNames, to avoid massive callbacks
return res;
}
......
......@@ -54,18 +54,18 @@ class MethodHandles: AllStatic {
static Handle resolve_MemberName(Handle mname, TRAPS); // compute vmtarget/vmindex from name/type
static void expand_MemberName(Handle mname, int suppress, TRAPS); // expand defc/name/type if missing
static Handle new_MemberName(TRAPS); // must be followed by init_MemberName
static oop init_MemberName(oop mname_oop, oop target_oop); // compute vmtarget/vmindex from target
static oop init_method_MemberName(oop mname_oop, Method* m, bool do_dispatch,
Klass* receiver_limit);
static oop init_field_MemberName(oop mname_oop, Klass* field_holder,
static oop init_MemberName(Handle mname_h, Handle target_h); // compute vmtarget/vmindex from target
static oop init_method_MemberName(Handle mname_h, Method* m, bool do_dispatch,
KlassHandle receiver_limit_h);
static oop init_field_MemberName(Handle mname_h, KlassHandle field_holder_h,
AccessFlags mods, oop type, oop name,
intptr_t offset, bool is_setter = false);
static Handle init_method_MemberName(oop mname_oop, CallInfo& info, TRAPS);
static Handle init_field_MemberName(oop mname_oop, FieldAccessInfo& info, TRAPS);
static Handle init_method_MemberName(Handle mname_h, CallInfo& info, TRAPS);
static Handle init_field_MemberName(Handle mname_h, FieldAccessInfo& info, TRAPS);
static int method_ref_kind(Method* m, bool do_dispatch_if_possible = true);
static int find_MemberNames(Klass* k, Symbol* name, Symbol* sig,
int mflags, Klass* caller,
int skip, objArrayOop results);
static int find_MemberNames(KlassHandle k, Symbol* name, Symbol* sig,
int mflags, KlassHandle caller,
int skip, objArrayHandle results);
// bit values for suppress argument to expand_MemberName:
enum { _suppress_defc = 1, _suppress_name = 2, _suppress_type = 4 };
......@@ -230,4 +230,27 @@ public:
void generate();
};
//------------------------------------------------------------------------------
// MemberNameTable
//
class MemberNameTable : public GrowableArray<jweak> {
public:
MemberNameTable();
~MemberNameTable();
void add_member_name(jweak mem_name_ref);
private:
int find_member_name(oop mem_name);
#if INCLUDE_JVMTI
public:
// 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);
private:
oop find_member_name_by_method(Method* old_method);
#endif // INCLUDE_JVMTI
};
#endif // SHARE_VM_PRIMS_METHODHANDLES_HPP
......@@ -46,6 +46,7 @@ Mutex* VMStatistic_lock = NULL;
Mutex* JNIGlobalHandle_lock = NULL;
Mutex* JNIHandleBlockFreeList_lock = NULL;
Mutex* JNICachedItableIndex_lock = NULL;
Mutex* MemberNameTable_lock = NULL;
Mutex* JmethodIdCreation_lock = NULL;
Mutex* JfieldIdCreation_lock = NULL;
Monitor* JNICritical_lock = NULL;
......@@ -252,6 +253,7 @@ void mutex_init() {
def(Heap_lock , Monitor, nonleaf+1, false);
def(JfieldIdCreation_lock , Mutex , nonleaf+1, true ); // jfieldID, Used in VM_Operation
def(JNICachedItableIndex_lock , Mutex , nonleaf+1, false); // Used to cache an itable index during JNI invoke
def(MemberNameTable_lock , Mutex , nonleaf+1, false); // Used to protect MemberNameTable
def(CompiledIC_lock , Mutex , nonleaf+2, false); // locks VtableStubs_lock, InlineCacheBuffer_lock
def(CompileTaskAlloc_lock , Mutex , nonleaf+2, true );
......
......@@ -51,6 +51,7 @@ extern Mutex* VMStatistic_lock; // a lock used to guard statist
extern Mutex* JNIGlobalHandle_lock; // a lock on creating JNI global handles
extern Mutex* JNIHandleBlockFreeList_lock; // a lock on the JNI handle block free list
extern Mutex* JNICachedItableIndex_lock; // a lock on caching an itable index during JNI invoke
extern Mutex* MemberNameTable_lock; // a lock on the MemberNameTable updates
extern Mutex* JmethodIdCreation_lock; // a lock on creating JNI method identifiers
extern Mutex* JfieldIdCreation_lock; // a lock on creating JNI static field identifiers
extern Monitor* JNICritical_lock; // a lock used while entering and exiting JNI critical regions, allows GC to sometimes get in
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册