提交 b42bb5de 编写于 作者: T twisti

7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space

Reviewed-by: kvn, jrose
上级 0f11ba0c
...@@ -276,9 +276,9 @@ class ciMethod : public ciObject { ...@@ -276,9 +276,9 @@ class ciMethod : public ciObject {
void print_short_name(outputStream* st = tty); void print_short_name(outputStream* st = tty);
methodOop get_method_handle_target() { methodOop get_method_handle_target() {
klassOop receiver_limit_oop = NULL; KlassHandle receiver_limit; int flags = 0;
int flags = 0; methodHandle m = MethodHandles::decode_method(get_oop(), receiver_limit, flags);
return MethodHandles::decode_method(get_oop(), receiver_limit_oop, flags); return m();
} }
}; };
......
/* /*
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -175,7 +175,7 @@ class VerifyOopClosure: public OopClosure { ...@@ -175,7 +175,7 @@ class VerifyOopClosure: public OopClosure {
protected: protected:
template <class T> inline void do_oop_work(T* p) { template <class T> inline void do_oop_work(T* p) {
oop obj = oopDesc::load_decode_heap_oop(p); oop obj = oopDesc::load_decode_heap_oop(p);
guarantee(obj->is_oop_or_null(), "invalid oop"); guarantee(obj->is_oop_or_null(), err_msg("invalid oop: " INTPTR_FORMAT, obj));
} }
public: public:
virtual void do_oop(oop* p); virtual void do_oop(oop* p);
......
...@@ -82,10 +82,8 @@ void MethodHandleChain::set_method_handle(Handle mh, TRAPS) { ...@@ -82,10 +82,8 @@ void MethodHandleChain::set_method_handle(Handle mh, TRAPS) {
void MethodHandleChain::set_last_method(oop target, TRAPS) { void MethodHandleChain::set_last_method(oop target, TRAPS) {
_is_last = true; _is_last = true;
klassOop receiver_limit_oop = NULL; KlassHandle receiver_limit; int flags = 0;
int flags = 0; _last_method = MethodHandles::decode_method(target, receiver_limit, flags);
methodOop m = MethodHandles::decode_method(target, receiver_limit_oop, flags);
_last_method = methodHandle(THREAD, m);
if ((flags & MethodHandles::_dmf_has_receiver) == 0) if ((flags & MethodHandles::_dmf_has_receiver) == 0)
_last_invoke = Bytecodes::_invokestatic; _last_invoke = Bytecodes::_invokestatic;
else if ((flags & MethodHandles::_dmf_does_dispatch) == 0) else if ((flags & MethodHandles::_dmf_does_dispatch) == 0)
......
...@@ -153,9 +153,9 @@ void MethodHandles::set_enabled(bool z) { ...@@ -153,9 +153,9 @@ void MethodHandles::set_enabled(bool z) {
// and local, like parse a data structure. For speed, such methods work on plain // and local, like parse a data structure. For speed, such methods work on plain
// oops, not handles. Trapping methods uniformly operate on handles. // oops, not handles. Trapping methods uniformly operate on handles.
methodOop MethodHandles::decode_vmtarget(oop vmtarget, int vmindex, oop mtype, methodHandle MethodHandles::decode_vmtarget(oop vmtarget, int vmindex, oop mtype,
klassOop& receiver_limit_result, int& decode_flags_result) { KlassHandle& receiver_limit_result, int& decode_flags_result) {
if (vmtarget == NULL) return NULL; if (vmtarget == NULL) return methodHandle();
assert(methodOopDesc::nonvirtual_vtable_index < 0, "encoding"); assert(methodOopDesc::nonvirtual_vtable_index < 0, "encoding");
if (vmindex < 0) { if (vmindex < 0) {
// this DMH performs no dispatch; it is directly bound to a methodOop // this DMH performs no dispatch; it is directly bound to a methodOop
...@@ -198,20 +198,20 @@ methodOop MethodHandles::decode_vmtarget(oop vmtarget, int vmindex, oop mtype, ...@@ -198,20 +198,20 @@ methodOop MethodHandles::decode_vmtarget(oop vmtarget, int vmindex, oop mtype,
// MemberName and DirectMethodHandle have the same linkage to the JVM internals. // MemberName and DirectMethodHandle have the same linkage to the JVM internals.
// (MemberName is the non-operational name used for queries and setup.) // (MemberName is the non-operational name used for queries and setup.)
methodOop MethodHandles::decode_DirectMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) { methodHandle MethodHandles::decode_DirectMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result) {
oop vmtarget = java_lang_invoke_DirectMethodHandle::vmtarget(mh); oop vmtarget = java_lang_invoke_DirectMethodHandle::vmtarget(mh);
int vmindex = java_lang_invoke_DirectMethodHandle::vmindex(mh); int vmindex = java_lang_invoke_DirectMethodHandle::vmindex(mh);
oop mtype = java_lang_invoke_DirectMethodHandle::type(mh); oop mtype = java_lang_invoke_DirectMethodHandle::type(mh);
return decode_vmtarget(vmtarget, vmindex, mtype, receiver_limit_result, decode_flags_result); return decode_vmtarget(vmtarget, vmindex, mtype, receiver_limit_result, decode_flags_result);
} }
methodOop MethodHandles::decode_BoundMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) { methodHandle MethodHandles::decode_BoundMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result) {
assert(java_lang_invoke_BoundMethodHandle::is_instance(mh), ""); assert(java_lang_invoke_BoundMethodHandle::is_instance(mh), "");
assert(mh->klass() != SystemDictionary::AdapterMethodHandle_klass(), ""); assert(mh->klass() != SystemDictionary::AdapterMethodHandle_klass(), "");
for (oop bmh = mh;;) { for (oop bmh = mh;;) {
// Bound MHs can be stacked to bind several arguments. // Bound MHs can be stacked to bind several arguments.
oop target = java_lang_invoke_MethodHandle::vmtarget(bmh); oop target = java_lang_invoke_MethodHandle::vmtarget(bmh);
if (target == NULL) return NULL; if (target == NULL) return methodHandle();
decode_flags_result |= MethodHandles::_dmf_binds_argument; decode_flags_result |= MethodHandles::_dmf_binds_argument;
klassOop tk = target->klass(); klassOop tk = target->klass();
if (tk == SystemDictionary::BoundMethodHandle_klass()) { if (tk == SystemDictionary::BoundMethodHandle_klass()) {
...@@ -236,14 +236,14 @@ methodOop MethodHandles::decode_BoundMethodHandle(oop mh, klassOop& receiver_lim ...@@ -236,14 +236,14 @@ methodOop MethodHandles::decode_BoundMethodHandle(oop mh, klassOop& receiver_lim
} }
} }
methodOop MethodHandles::decode_AdapterMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) { methodHandle MethodHandles::decode_AdapterMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result) {
assert(mh->klass() == SystemDictionary::AdapterMethodHandle_klass(), ""); assert(mh->klass() == SystemDictionary::AdapterMethodHandle_klass(), "");
for (oop amh = mh;;) { for (oop amh = mh;;) {
// Adapter MHs can be stacked to convert several arguments. // Adapter MHs can be stacked to convert several arguments.
int conv_op = adapter_conversion_op(java_lang_invoke_AdapterMethodHandle::conversion(amh)); int conv_op = adapter_conversion_op(java_lang_invoke_AdapterMethodHandle::conversion(amh));
decode_flags_result |= (_dmf_adapter_lsb << conv_op) & _DMF_ADAPTER_MASK; decode_flags_result |= (_dmf_adapter_lsb << conv_op) & _DMF_ADAPTER_MASK;
oop target = java_lang_invoke_MethodHandle::vmtarget(amh); oop target = java_lang_invoke_MethodHandle::vmtarget(amh);
if (target == NULL) return NULL; if (target == NULL) return methodHandle();
klassOop tk = target->klass(); klassOop tk = target->klass();
if (tk == SystemDictionary::AdapterMethodHandle_klass()) { if (tk == SystemDictionary::AdapterMethodHandle_klass()) {
amh = target; amh = target;
...@@ -255,8 +255,8 @@ methodOop MethodHandles::decode_AdapterMethodHandle(oop mh, klassOop& receiver_l ...@@ -255,8 +255,8 @@ methodOop MethodHandles::decode_AdapterMethodHandle(oop mh, klassOop& receiver_l
} }
} }
methodOop MethodHandles::decode_MethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) { methodHandle MethodHandles::decode_MethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result) {
if (mh == NULL) return NULL; if (mh == NULL) return methodHandle();
klassOop mhk = mh->klass(); klassOop mhk = mh->klass();
assert(java_lang_invoke_MethodHandle::is_subclass(mhk), "must be a MethodHandle"); assert(java_lang_invoke_MethodHandle::is_subclass(mhk), "must be a MethodHandle");
if (mhk == SystemDictionary::DirectMethodHandle_klass()) { if (mhk == SystemDictionary::DirectMethodHandle_klass()) {
...@@ -270,7 +270,7 @@ methodOop MethodHandles::decode_MethodHandle(oop mh, klassOop& receiver_limit_re ...@@ -270,7 +270,7 @@ methodOop MethodHandles::decode_MethodHandle(oop mh, klassOop& receiver_limit_re
return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result); return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result);
} else { } else {
assert(false, "cannot parse this MH"); assert(false, "cannot parse this MH");
return NULL; // random MH? return methodHandle(); // random MH?
} }
} }
...@@ -299,9 +299,9 @@ methodOop MethodHandles::decode_methodOop(methodOop m, int& decode_flags_result) ...@@ -299,9 +299,9 @@ methodOop MethodHandles::decode_methodOop(methodOop m, int& decode_flags_result)
// A trusted party is handing us a cookie to determine a method. // A trusted party is handing us a cookie to determine a method.
// Let's boil it down to the method oop they really want. // Let's boil it down to the method oop they really want.
methodOop MethodHandles::decode_method(oop x, klassOop& receiver_limit_result, int& decode_flags_result) { methodHandle MethodHandles::decode_method(oop x, KlassHandle& receiver_limit_result, int& decode_flags_result) {
decode_flags_result = 0; decode_flags_result = 0;
receiver_limit_result = NULL; receiver_limit_result = KlassHandle();
klassOop xk = x->klass(); klassOop xk = x->klass();
if (xk == Universe::methodKlassObj()) { if (xk == Universe::methodKlassObj()) {
return decode_methodOop((methodOop) x, decode_flags_result); return decode_methodOop((methodOop) x, decode_flags_result);
...@@ -329,7 +329,7 @@ methodOop MethodHandles::decode_method(oop x, klassOop& receiver_limit_result, i ...@@ -329,7 +329,7 @@ methodOop MethodHandles::decode_method(oop x, klassOop& receiver_limit_result, i
assert(!x->is_method(), "already checked"); assert(!x->is_method(), "already checked");
assert(!java_lang_invoke_MemberName::is_instance(x), "already checked"); assert(!java_lang_invoke_MemberName::is_instance(x), "already checked");
} }
return NULL; return methodHandle();
} }
...@@ -389,11 +389,10 @@ void MethodHandles::init_MemberName(oop mname_oop, oop target_oop) { ...@@ -389,11 +389,10 @@ void MethodHandles::init_MemberName(oop mname_oop, oop target_oop) {
int offset = instanceKlass::cast(k)->offset_from_fields(slot); int offset = instanceKlass::cast(k)->offset_from_fields(slot);
init_MemberName(mname_oop, k, accessFlags_from(mods), offset); init_MemberName(mname_oop, k, accessFlags_from(mods), offset);
} else { } else {
int decode_flags = 0; klassOop receiver_limit = NULL; KlassHandle receiver_limit; int decode_flags = 0;
methodOop m = MethodHandles::decode_method(target_oop, methodHandle m = MethodHandles::decode_method(target_oop, receiver_limit, decode_flags);
receiver_limit, decode_flags);
bool do_dispatch = ((decode_flags & MethodHandles::_dmf_does_dispatch) != 0); bool do_dispatch = ((decode_flags & MethodHandles::_dmf_does_dispatch) != 0);
init_MemberName(mname_oop, m, do_dispatch); init_MemberName(mname_oop, m(), do_dispatch);
} }
} }
...@@ -423,13 +422,14 @@ void MethodHandles::init_MemberName(oop mname_oop, klassOop field_holder, Access ...@@ -423,13 +422,14 @@ void MethodHandles::init_MemberName(oop mname_oop, klassOop field_holder, Access
} }
methodOop MethodHandles::decode_MemberName(oop mname, klassOop& receiver_limit_result, int& decode_flags_result) { methodHandle MethodHandles::decode_MemberName(oop mname, KlassHandle& receiver_limit_result, int& decode_flags_result) {
methodHandle empty;
int flags = java_lang_invoke_MemberName::flags(mname); int flags = java_lang_invoke_MemberName::flags(mname);
if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) == 0) return NULL; // not invocable if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) == 0) return empty; // not invocable
oop vmtarget = java_lang_invoke_MemberName::vmtarget(mname); oop vmtarget = java_lang_invoke_MemberName::vmtarget(mname);
int vmindex = java_lang_invoke_MemberName::vmindex(mname); int vmindex = java_lang_invoke_MemberName::vmindex(mname);
if (vmindex == VM_INDEX_UNINITIALIZED) return NULL; // not resolved if (vmindex == VM_INDEX_UNINITIALIZED) return empty; // not resolved
methodOop m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit_result, decode_flags_result); methodHandle m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit_result, decode_flags_result);
oop clazz = java_lang_invoke_MemberName::clazz(mname); oop clazz = java_lang_invoke_MemberName::clazz(mname);
if (clazz != NULL && java_lang_Class::is_instance(clazz)) { if (clazz != NULL && java_lang_Class::is_instance(clazz)) {
klassOop klass = java_lang_Class::as_klassOop(clazz); klassOop klass = java_lang_Class::as_klassOop(clazz);
...@@ -439,9 +439,7 @@ methodOop MethodHandles::decode_MemberName(oop mname, klassOop& receiver_limit_r ...@@ -439,9 +439,7 @@ methodOop MethodHandles::decode_MemberName(oop mname, klassOop& receiver_limit_r
} }
// convert the external string or reflective type to an internal signature // convert the external string or reflective type to an internal signature
Symbol* MethodHandles::convert_to_signature(oop type_str, Symbol* MethodHandles::convert_to_signature(oop type_str, bool polymorphic, TRAPS) {
bool polymorphic,
TRAPS) {
if (java_lang_invoke_MethodType::is_instance(type_str)) { if (java_lang_invoke_MethodType::is_instance(type_str)) {
return java_lang_invoke_MethodType::as_signature(type_str, polymorphic, CHECK_NULL); return java_lang_invoke_MethodType::as_signature(type_str, polymorphic, CHECK_NULL);
} else if (java_lang_Class::is_instance(type_str)) { } else if (java_lang_Class::is_instance(type_str)) {
...@@ -474,48 +472,48 @@ void MethodHandles::resolve_MemberName(Handle mname, TRAPS) { ...@@ -474,48 +472,48 @@ void MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
#endif #endif
if (java_lang_invoke_MemberName::vmindex(mname()) != VM_INDEX_UNINITIALIZED) if (java_lang_invoke_MemberName::vmindex(mname()) != VM_INDEX_UNINITIALIZED)
return; // already resolved return; // already resolved
oop defc_oop = java_lang_invoke_MemberName::clazz(mname()); Handle defc_oop(THREAD, java_lang_invoke_MemberName::clazz(mname()));
oop name_str = java_lang_invoke_MemberName::name(mname()); Handle name_str(THREAD, java_lang_invoke_MemberName::name( mname()));
oop type_str = java_lang_invoke_MemberName::type(mname()); Handle type_str(THREAD, java_lang_invoke_MemberName::type( mname()));
int flags = java_lang_invoke_MemberName::flags(mname()); int flags = java_lang_invoke_MemberName::flags(mname());
if (defc_oop == NULL || name_str == NULL || type_str == NULL) { if (defc_oop.is_null() || name_str.is_null() || type_str.is_null()) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to resolve"); THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to resolve");
} }
klassOop defc_klassOop = java_lang_Class::as_klassOop(defc_oop);
defc_oop = NULL; // safety instanceKlassHandle defc;
if (defc_klassOop == NULL) return; // a primitive; no resolution possible {
if (!Klass::cast(defc_klassOop)->oop_is_instance()) { klassOop defc_klassOop = java_lang_Class::as_klassOop(defc_oop());
if (!Klass::cast(defc_klassOop)->oop_is_array()) return; if (defc_klassOop == NULL) return; // a primitive; no resolution possible
defc_klassOop = SystemDictionary::Object_klass(); if (!Klass::cast(defc_klassOop)->oop_is_instance()) {
if (!Klass::cast(defc_klassOop)->oop_is_array()) return;
defc_klassOop = SystemDictionary::Object_klass();
}
defc = instanceKlassHandle(THREAD, defc_klassOop);
} }
instanceKlassHandle defc(THREAD, defc_klassOop);
defc_klassOop = NULL; // safety
if (defc.is_null()) { if (defc.is_null()) {
THROW_MSG(vmSymbols::java_lang_InternalError(), "primitive class"); THROW_MSG(vmSymbols::java_lang_InternalError(), "primitive class");
} }
defc->link_class(CHECK); defc->link_class(CHECK); // possible safepoint
// convert the external string name to an internal symbol // convert the external string name to an internal symbol
TempNewSymbol name = java_lang_String::as_symbol_or_null(name_str); TempNewSymbol name = java_lang_String::as_symbol_or_null(name_str());
if (name == NULL) return; // no such name if (name == NULL) return; // no such name
name_str = NULL; // safety
Handle polymorphic_method_type; Handle polymorphic_method_type;
bool polymorphic_signature = false; bool polymorphic_signature = false;
if ((flags & ALL_KINDS) == IS_METHOD && if ((flags & ALL_KINDS) == IS_METHOD &&
(defc() == SystemDictionary::MethodHandle_klass() && (defc() == SystemDictionary::MethodHandle_klass() &&
methodOopDesc::is_method_handle_invoke_name(name))) methodOopDesc::is_method_handle_invoke_name(name))) {
polymorphic_signature = true; polymorphic_signature = true;
}
// convert the external string or reflective type to an internal signature // convert the external string or reflective type to an internal signature
TempNewSymbol type = convert_to_signature(type_str, polymorphic_signature, CHECK); TempNewSymbol type = convert_to_signature(type_str(), polymorphic_signature, CHECK);
if (java_lang_invoke_MethodType::is_instance(type_str) && polymorphic_signature) { if (java_lang_invoke_MethodType::is_instance(type_str()) && polymorphic_signature) {
polymorphic_method_type = Handle(THREAD, type_str); //preserve exactly polymorphic_method_type = type_str; // preserve exactly
} }
if (type == NULL) return; // no such signature exists in the VM if (type == NULL) return; // no such signature exists in the VM
type_str = NULL; // safety
// Time to do the lookup. // Time to do the lookup.
switch (flags & ALL_KINDS) { switch (flags & ALL_KINDS) {
...@@ -560,8 +558,8 @@ void MethodHandles::resolve_MemberName(Handle mname, TRAPS) { ...@@ -560,8 +558,8 @@ void MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
java_lang_invoke_MemberName::set_vmtarget(mname(), vmtarget); java_lang_invoke_MemberName::set_vmtarget(mname(), vmtarget);
java_lang_invoke_MemberName::set_vmindex(mname(), vmindex); java_lang_invoke_MemberName::set_vmindex(mname(), vmindex);
java_lang_invoke_MemberName::set_modifiers(mname(), mods); java_lang_invoke_MemberName::set_modifiers(mname(), mods);
DEBUG_ONLY(int junk; klassOop junk2); DEBUG_ONLY(KlassHandle junk1; int junk2);
assert(decode_MemberName(mname(), junk2, junk) == result.resolved_method()(), assert(decode_MemberName(mname(), junk1, junk2) == result.resolved_method(),
"properly stored for later decoding"); "properly stored for later decoding");
return; return;
} }
...@@ -589,8 +587,8 @@ void MethodHandles::resolve_MemberName(Handle mname, TRAPS) { ...@@ -589,8 +587,8 @@ void MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
java_lang_invoke_MemberName::set_vmtarget(mname(), vmtarget); java_lang_invoke_MemberName::set_vmtarget(mname(), vmtarget);
java_lang_invoke_MemberName::set_vmindex(mname(), vmindex); java_lang_invoke_MemberName::set_vmindex(mname(), vmindex);
java_lang_invoke_MemberName::set_modifiers(mname(), mods); java_lang_invoke_MemberName::set_modifiers(mname(), mods);
DEBUG_ONLY(int junk; klassOop junk2); DEBUG_ONLY(KlassHandle junk1; int junk2);
assert(decode_MemberName(mname(), junk2, junk) == result.resolved_method()(), assert(decode_MemberName(mname(), junk1, junk2) == result.resolved_method(),
"properly stored for later decoding"); "properly stored for later decoding");
return; return;
} }
...@@ -677,16 +675,14 @@ void MethodHandles::expand_MemberName(Handle mname, int suppress, TRAPS) { ...@@ -677,16 +675,14 @@ void MethodHandles::expand_MemberName(Handle mname, int suppress, TRAPS) {
case IS_METHOD: case IS_METHOD:
case IS_CONSTRUCTOR: case IS_CONSTRUCTOR:
{ {
klassOop receiver_limit = NULL; KlassHandle receiver_limit; int decode_flags = 0;
int decode_flags = 0; methodHandle m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit, decode_flags);
methodHandle m(THREAD, decode_vmtarget(vmtarget, vmindex, NULL,
receiver_limit, decode_flags));
if (m.is_null()) break; if (m.is_null()) break;
if (!have_defc) { if (!have_defc) {
klassOop defc = m->method_holder(); klassOop defc = m->method_holder();
if (receiver_limit != NULL && receiver_limit != defc if (receiver_limit.not_null() && receiver_limit() != defc
&& Klass::cast(receiver_limit)->is_subtype_of(defc)) && Klass::cast(receiver_limit())->is_subtype_of(defc))
defc = receiver_limit; defc = receiver_limit();
java_lang_invoke_MemberName::set_clazz(mname(), Klass::cast(defc)->java_mirror()); java_lang_invoke_MemberName::set_clazz(mname(), Klass::cast(defc)->java_mirror());
} }
if (!have_name) { if (!have_name) {
...@@ -884,10 +880,9 @@ oop MethodHandles::encode_target(Handle mh, int format, TRAPS) { ...@@ -884,10 +880,9 @@ oop MethodHandles::encode_target(Handle mh, int format, TRAPS) {
// - AMH can have methodOop for static invoke with bound receiver // - AMH can have methodOop for static invoke with bound receiver
// - DMH can have methodOop for static invoke (on variable receiver) // - DMH can have methodOop for static invoke (on variable receiver)
// - DMH can have klassOop for dispatched (non-static) invoke // - DMH can have klassOop for dispatched (non-static) invoke
klassOop receiver_limit = NULL; KlassHandle receiver_limit; int decode_flags = 0;
int decode_flags = 0; methodHandle m = decode_MethodHandle(mh(), receiver_limit, decode_flags);
methodOop m = decode_MethodHandle(mh(), receiver_limit, decode_flags); if (m.is_null()) return NULL;
if (m == NULL) return NULL;
switch (format) { switch (format) {
case ETF_REFLECT_METHOD: case ETF_REFLECT_METHOD:
// same as jni_ToReflectedMethod: // same as jni_ToReflectedMethod:
...@@ -903,10 +898,10 @@ oop MethodHandles::encode_target(Handle mh, int format, TRAPS) { ...@@ -903,10 +898,10 @@ oop MethodHandles::encode_target(Handle mh, int format, TRAPS) {
if (SystemDictionary::MemberName_klass() == NULL) break; if (SystemDictionary::MemberName_klass() == NULL) break;
instanceKlassHandle mname_klass(THREAD, SystemDictionary::MemberName_klass()); instanceKlassHandle mname_klass(THREAD, SystemDictionary::MemberName_klass());
mname_klass->initialize(CHECK_NULL); mname_klass->initialize(CHECK_NULL);
Handle mname = mname_klass->allocate_instance_handle(CHECK_NULL); Handle mname = mname_klass->allocate_instance_handle(CHECK_NULL); // possible safepoint
java_lang_invoke_MemberName::set_vmindex(mname(), VM_INDEX_UNINITIALIZED); java_lang_invoke_MemberName::set_vmindex(mname(), VM_INDEX_UNINITIALIZED);
bool do_dispatch = ((decode_flags & MethodHandles::_dmf_does_dispatch) != 0); bool do_dispatch = ((decode_flags & MethodHandles::_dmf_does_dispatch) != 0);
init_MemberName(mname(), m, do_dispatch); init_MemberName(mname(), m(), do_dispatch);
expand_MemberName(mname, 0, CHECK_NULL); expand_MemberName(mname, 0, CHECK_NULL);
return mname(); return mname();
} }
...@@ -1459,8 +1454,8 @@ void MethodHandles::init_DirectMethodHandle(Handle mh, methodHandle m, bool do_d ...@@ -1459,8 +1454,8 @@ void MethodHandles::init_DirectMethodHandle(Handle mh, methodHandle m, bool do_d
// that links the interpreter calls to the method. We need the same // that links the interpreter calls to the method. We need the same
// bits, and will use the same calling sequence code. // bits, and will use the same calling sequence code.
int vmindex = methodOopDesc::garbage_vtable_index; int vmindex = methodOopDesc::garbage_vtable_index;
oop vmtarget = NULL; Handle vmtarget;
instanceKlass::cast(m->method_holder())->link_class(CHECK); instanceKlass::cast(m->method_holder())->link_class(CHECK);
...@@ -1478,7 +1473,7 @@ void MethodHandles::init_DirectMethodHandle(Handle mh, methodHandle m, bool do_d ...@@ -1478,7 +1473,7 @@ void MethodHandles::init_DirectMethodHandle(Handle mh, methodHandle m, bool do_d
} else if (!do_dispatch || m->can_be_statically_bound()) { } else if (!do_dispatch || m->can_be_statically_bound()) {
// We are simulating an invokestatic or invokespecial instruction. // We are simulating an invokestatic or invokespecial instruction.
// Set up the method pointer, just like ConstantPoolCacheEntry::set_method(). // Set up the method pointer, just like ConstantPoolCacheEntry::set_method().
vmtarget = m(); vmtarget = m;
// this does not help dispatch, but it will make it possible to parse this MH: // this does not help dispatch, but it will make it possible to parse this MH:
vmindex = methodOopDesc::nonvirtual_vtable_index; vmindex = methodOopDesc::nonvirtual_vtable_index;
assert(vmindex < 0, "(>=0) == do_dispatch"); assert(vmindex < 0, "(>=0) == do_dispatch");
...@@ -1490,7 +1485,7 @@ void MethodHandles::init_DirectMethodHandle(Handle mh, methodHandle m, bool do_d ...@@ -1490,7 +1485,7 @@ void MethodHandles::init_DirectMethodHandle(Handle mh, methodHandle m, bool do_d
// For a DMH, it is done now, when the handle is created. // For a DMH, it is done now, when the handle is created.
Klass* k = Klass::cast(m->method_holder()); Klass* k = Klass::cast(m->method_holder());
if (k->should_be_initialized()) { if (k->should_be_initialized()) {
k->initialize(CHECK); k->initialize(CHECK); // possible safepoint
} }
} }
} else { } else {
...@@ -1504,10 +1499,10 @@ void MethodHandles::init_DirectMethodHandle(Handle mh, methodHandle m, bool do_d ...@@ -1504,10 +1499,10 @@ void MethodHandles::init_DirectMethodHandle(Handle mh, methodHandle m, bool do_d
if (me == NULL) { THROW(vmSymbols::java_lang_InternalError()); } if (me == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
java_lang_invoke_DirectMethodHandle::set_vmtarget(mh(), vmtarget); java_lang_invoke_DirectMethodHandle::set_vmtarget(mh(), vmtarget());
java_lang_invoke_DirectMethodHandle::set_vmindex(mh(), vmindex); java_lang_invoke_DirectMethodHandle::set_vmindex( mh(), vmindex);
DEBUG_ONLY(int flags; klassOop rlimit); DEBUG_ONLY(KlassHandle rlimit; int flags);
assert(MethodHandles::decode_method(mh(), rlimit, flags) == m(), assert(MethodHandles::decode_method(mh(), rlimit, flags) == m,
"properly stored for later decoding"); "properly stored for later decoding");
DEBUG_ONLY(bool actual_do_dispatch = ((flags & _dmf_does_dispatch) != 0)); DEBUG_ONLY(bool actual_do_dispatch = ((flags & _dmf_does_dispatch) != 0));
assert(!(actual_do_dispatch && !do_dispatch), assert(!(actual_do_dispatch && !do_dispatch),
...@@ -1523,10 +1518,13 @@ void MethodHandles::verify_BoundMethodHandle_with_receiver(Handle mh, ...@@ -1523,10 +1518,13 @@ void MethodHandles::verify_BoundMethodHandle_with_receiver(Handle mh,
methodHandle m, methodHandle m,
TRAPS) { TRAPS) {
// Verify type. // Verify type.
oop receiver = java_lang_invoke_BoundMethodHandle::argument(mh());
Handle mtype(THREAD, java_lang_invoke_MethodHandle::type(mh()));
KlassHandle bound_recv_type; KlassHandle bound_recv_type;
if (receiver != NULL) bound_recv_type = KlassHandle(THREAD, receiver->klass()); {
oop receiver = java_lang_invoke_BoundMethodHandle::argument(mh());
if (receiver != NULL)
bound_recv_type = KlassHandle(THREAD, receiver->klass());
}
Handle mtype(THREAD, java_lang_invoke_MethodHandle::type(mh()));
verify_method_type(m, mtype, true, bound_recv_type, CHECK); verify_method_type(m, mtype, true, bound_recv_type, CHECK);
int receiver_pos = m->size_of_parameters() - 1; int receiver_pos = m->size_of_parameters() - 1;
...@@ -1573,8 +1571,8 @@ void MethodHandles::init_BoundMethodHandle_with_receiver(Handle mh, ...@@ -1573,8 +1571,8 @@ void MethodHandles::init_BoundMethodHandle_with_receiver(Handle mh,
java_lang_invoke_BoundMethodHandle::set_vmtarget(mh(), m()); java_lang_invoke_BoundMethodHandle::set_vmtarget(mh(), m());
DEBUG_ONLY(int junk; klassOop junk2); DEBUG_ONLY(KlassHandle junk1; int junk2);
assert(MethodHandles::decode_method(mh(), junk2, junk) == m(), "properly stored for later decoding"); assert(MethodHandles::decode_method(mh(), junk1, junk2) == m, "properly stored for later decoding");
assert(decode_MethodHandle_stack_pushes(mh()) == 1, "BMH pushes one stack slot"); assert(decode_MethodHandle_stack_pushes(mh()) == 1, "BMH pushes one stack slot");
// Done! // Done!
...@@ -1682,8 +1680,11 @@ void MethodHandles::init_BoundMethodHandle(Handle mh, Handle target, int argnum, ...@@ -1682,8 +1680,11 @@ void MethodHandles::init_BoundMethodHandle(Handle mh, Handle target, int argnum,
} }
// Get bound type and required slots. // Get bound type and required slots.
oop ptype_oop = java_lang_invoke_MethodType::ptype(java_lang_invoke_MethodHandle::type(target()), argnum); BasicType ptype;
BasicType ptype = java_lang_Class::as_BasicType(ptype_oop); {
oop ptype_oop = java_lang_invoke_MethodType::ptype(java_lang_invoke_MethodHandle::type(target()), argnum);
ptype = java_lang_Class::as_BasicType(ptype_oop);
}
int slots_pushed = type2size[ptype]; int slots_pushed = type2size[ptype];
// If (a) the target is a direct non-dispatched method handle, // If (a) the target is a direct non-dispatched method handle,
...@@ -1694,13 +1695,12 @@ void MethodHandles::init_BoundMethodHandle(Handle mh, Handle target, int argnum, ...@@ -1694,13 +1695,12 @@ void MethodHandles::init_BoundMethodHandle(Handle mh, Handle target, int argnum,
if (OptimizeMethodHandles && if (OptimizeMethodHandles &&
target->klass() == SystemDictionary::DirectMethodHandle_klass() && target->klass() == SystemDictionary::DirectMethodHandle_klass() &&
(argnum == 0 || java_lang_invoke_DirectMethodHandle::vmindex(target()) < 0)) { (argnum == 0 || java_lang_invoke_DirectMethodHandle::vmindex(target()) < 0)) {
int decode_flags = 0; klassOop receiver_limit_oop = NULL; KlassHandle receiver_limit; int decode_flags = 0;
methodHandle m(THREAD, decode_method(target(), receiver_limit_oop, decode_flags)); methodHandle m = decode_method(target(), receiver_limit, decode_flags);
if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "DMH failed to decode"); } if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "DMH failed to decode"); }
DEBUG_ONLY(int m_vmslots = m->size_of_parameters() - slots_pushed); // pos. of 1st arg. DEBUG_ONLY(int m_vmslots = m->size_of_parameters() - slots_pushed); // pos. of 1st arg.
assert(java_lang_invoke_BoundMethodHandle::vmslots(mh()) == m_vmslots, "type w/ m sig"); assert(java_lang_invoke_BoundMethodHandle::vmslots(mh()) == m_vmslots, "type w/ m sig");
if (argnum == 0 && (decode_flags & _dmf_has_receiver) != 0) { if (argnum == 0 && (decode_flags & _dmf_has_receiver) != 0) {
KlassHandle receiver_limit(THREAD, receiver_limit_oop);
init_BoundMethodHandle_with_receiver(mh, m, init_BoundMethodHandle_with_receiver(mh, m,
receiver_limit, decode_flags, receiver_limit, decode_flags,
CHECK); CHECK);
...@@ -2019,7 +2019,6 @@ void MethodHandles::verify_AdapterMethodHandle(Handle mh, int argnum, TRAPS) { ...@@ -2019,7 +2019,6 @@ void MethodHandles::verify_AdapterMethodHandle(Handle mh, int argnum, TRAPS) {
} }
void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnum, TRAPS) { void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnum, TRAPS) {
oop argument = java_lang_invoke_AdapterMethodHandle::argument(mh());
int argslot = java_lang_invoke_AdapterMethodHandle::vmargslot(mh()); int argslot = java_lang_invoke_AdapterMethodHandle::vmargslot(mh());
jint conversion = java_lang_invoke_AdapterMethodHandle::conversion(mh()); jint conversion = java_lang_invoke_AdapterMethodHandle::conversion(mh());
jint conv_op = adapter_conversion_op(conversion); jint conv_op = adapter_conversion_op(conversion);
...@@ -2215,18 +2214,14 @@ JVM_ENTRY(void, MHN_init_DMH(JNIEnv *env, jobject igcls, jobject mh_jh, ...@@ -2215,18 +2214,14 @@ JVM_ENTRY(void, MHN_init_DMH(JNIEnv *env, jobject igcls, jobject mh_jh,
// which method are we really talking about? // which method are we really talking about?
if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
oop target_oop = JNIHandles::resolve_non_null(target_jh); Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
if (java_lang_invoke_MemberName::is_instance(target_oop) && if (java_lang_invoke_MemberName::is_instance(target()) &&
java_lang_invoke_MemberName::vmindex(target_oop) == VM_INDEX_UNINITIALIZED) { java_lang_invoke_MemberName::vmindex(target()) == VM_INDEX_UNINITIALIZED) {
Handle mname(THREAD, target_oop); MethodHandles::resolve_MemberName(target, CHECK);
MethodHandles::resolve_MemberName(mname, CHECK);
target_oop = mname(); // in case of GC
} }
int decode_flags = 0; klassOop receiver_limit = NULL; KlassHandle receiver_limit; int decode_flags = 0;
methodHandle m(THREAD, methodHandle m = MethodHandles::decode_method(target(), receiver_limit, decode_flags);
MethodHandles::decode_method(target_oop,
receiver_limit, decode_flags));
if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "no such method"); } if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "no such method"); }
// The trusted Java code that calls this method should already have performed // The trusted Java code that calls this method should already have performed
...@@ -2284,12 +2279,8 @@ JVM_ENTRY(void, MHN_init_BMH(JNIEnv *env, jobject igcls, jobject mh_jh, ...@@ -2284,12 +2279,8 @@ JVM_ENTRY(void, MHN_init_BMH(JNIEnv *env, jobject igcls, jobject mh_jh,
// Target object is a reflective method. (%%% Do we need this alternate path?) // Target object is a reflective method. (%%% Do we need this alternate path?)
Untested("init_BMH of non-MH"); Untested("init_BMH of non-MH");
if (argnum != 0) { THROW(vmSymbols::java_lang_InternalError()); } if (argnum != 0) { THROW(vmSymbols::java_lang_InternalError()); }
int decode_flags = 0; klassOop receiver_limit_oop = NULL; KlassHandle receiver_limit; int decode_flags = 0;
methodHandle m(THREAD, methodHandle m = MethodHandles::decode_method(target(), receiver_limit, decode_flags);
MethodHandles::decode_method(target(),
receiver_limit_oop,
decode_flags));
KlassHandle receiver_limit(THREAD, receiver_limit_oop);
MethodHandles::init_BoundMethodHandle_with_receiver(mh, m, MethodHandles::init_BoundMethodHandle_with_receiver(mh, m,
receiver_limit, receiver_limit,
decode_flags, decode_flags,
...@@ -2424,12 +2415,12 @@ JVM_ENTRY(jint, MHN_getNamedCon(JNIEnv *env, jobject igcls, jint which, jobjectA ...@@ -2424,12 +2415,12 @@ JVM_ENTRY(jint, MHN_getNamedCon(JNIEnv *env, jobject igcls, jint which, jobjectA
#ifndef PRODUCT #ifndef PRODUCT
if (which >= 0 && which < con_value_count) { if (which >= 0 && which < con_value_count) {
int con = con_values[which]; int con = con_values[which];
objArrayOop box = (objArrayOop) JNIHandles::resolve(box_jh); objArrayHandle box(THREAD, (objArrayOop) JNIHandles::resolve(box_jh));
if (box != NULL && box->klass() == Universe::objectArrayKlassObj() && box->length() > 0) { if (box.not_null() && box->klass() == Universe::objectArrayKlassObj() && box->length() > 0) {
const char* str = &con_names[0]; const char* str = &con_names[0];
for (int i = 0; i < which; i++) for (int i = 0; i < which; i++)
str += strlen(str) + 1; // skip name and null str += strlen(str) + 1; // skip name and null
oop name = java_lang_String::create_oop_from_str(str, CHECK_0); oop name = java_lang_String::create_oop_from_str(str, CHECK_0); // possible safepoint
box->obj_at_put(0, name); box->obj_at_put(0, name);
} }
return con; return con;
...@@ -2486,10 +2477,10 @@ JVM_ENTRY(jint, MHN_getMembers(JNIEnv *env, jobject igcls, ...@@ -2486,10 +2477,10 @@ JVM_ENTRY(jint, MHN_getMembers(JNIEnv *env, jobject igcls,
jclass clazz_jh, jstring name_jh, jstring sig_jh, jclass clazz_jh, jstring name_jh, jstring sig_jh,
int mflags, jclass caller_jh, jint skip, jobjectArray results_jh)) { int mflags, jclass caller_jh, jint skip, jobjectArray results_jh)) {
if (clazz_jh == NULL || results_jh == NULL) return -1; if (clazz_jh == NULL || results_jh == NULL) return -1;
klassOop k_oop = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz_jh)); KlassHandle k(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz_jh)));
objArrayOop results = (objArrayOop) JNIHandles::resolve(results_jh); objArrayHandle results(THREAD, (objArrayOop) JNIHandles::resolve(results_jh));
if (results == NULL || !results->is_objArray()) return -1; if (results.is_null() || !results->is_objArray()) return -1;
TempNewSymbol name = NULL; TempNewSymbol name = NULL;
TempNewSymbol sig = NULL; TempNewSymbol sig = NULL;
...@@ -2502,20 +2493,20 @@ JVM_ENTRY(jint, MHN_getMembers(JNIEnv *env, jobject igcls, ...@@ -2502,20 +2493,20 @@ JVM_ENTRY(jint, MHN_getMembers(JNIEnv *env, jobject igcls,
if (sig == NULL) return 0; // a match is not possible if (sig == NULL) return 0; // a match is not possible
} }
klassOop caller = NULL; KlassHandle caller;
if (caller_jh != NULL) { if (caller_jh != NULL) {
oop caller_oop = JNIHandles::resolve_non_null(caller_jh); oop caller_oop = JNIHandles::resolve_non_null(caller_jh);
if (!java_lang_Class::is_instance(caller_oop)) return -1; if (!java_lang_Class::is_instance(caller_oop)) return -1;
caller = java_lang_Class::as_klassOop(caller_oop); caller = KlassHandle(THREAD, java_lang_Class::as_klassOop(caller_oop));
} }
if (name != NULL && sig != NULL && results != NULL) { if (name != NULL && sig != NULL && results.not_null()) {
// try a direct resolve // try a direct resolve
// %%% TO DO // %%% TO DO
} }
int res = MethodHandles::find_MemberNames(k_oop, name, sig, mflags, int res = MethodHandles::find_MemberNames(k(), name, sig, mflags,
caller, skip, results); caller(), skip, results());
// TO DO: expand at least some of the MemberNames, to avoid massive callbacks // TO DO: expand at least some of the MemberNames, to avoid massive callbacks
return res; return res;
} }
......
...@@ -265,13 +265,13 @@ class MethodHandles: AllStatic { ...@@ -265,13 +265,13 @@ class MethodHandles: AllStatic {
static inline address from_interpreted_entry(EntryKind ek); static inline address from_interpreted_entry(EntryKind ek);
// helpers for decode_method. // helpers for decode_method.
static methodOop decode_methodOop(methodOop m, int& decode_flags_result); static methodOop decode_methodOop(methodOop m, int& decode_flags_result);
static methodOop decode_vmtarget(oop vmtarget, int vmindex, oop mtype, klassOop& receiver_limit_result, int& decode_flags_result); static methodHandle decode_vmtarget(oop vmtarget, int vmindex, oop mtype, KlassHandle& receiver_limit_result, int& decode_flags_result);
static methodOop decode_MemberName(oop mname, klassOop& receiver_limit_result, int& decode_flags_result); static methodHandle decode_MemberName(oop mname, KlassHandle& receiver_limit_result, int& decode_flags_result);
static methodOop decode_MethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result); static methodHandle decode_MethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result);
static methodOop decode_DirectMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result); static methodHandle decode_DirectMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result);
static methodOop decode_BoundMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result); static methodHandle decode_BoundMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result);
static methodOop decode_AdapterMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result); static methodHandle decode_AdapterMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result);
// Find out how many stack slots an mh pushes or pops. // Find out how many stack slots an mh pushes or pops.
// The result is *not* reported as a multiple of stack_move_unit(); // The result is *not* reported as a multiple of stack_move_unit();
...@@ -317,7 +317,7 @@ class MethodHandles: AllStatic { ...@@ -317,7 +317,7 @@ class MethodHandles: AllStatic {
_dmf_adapter_lsb = 0x20, _dmf_adapter_lsb = 0x20,
_DMF_ADAPTER_MASK = (_dmf_adapter_lsb << CONV_OP_LIMIT) - _dmf_adapter_lsb _DMF_ADAPTER_MASK = (_dmf_adapter_lsb << CONV_OP_LIMIT) - _dmf_adapter_lsb
}; };
static methodOop decode_method(oop x, klassOop& receiver_limit_result, int& decode_flags_result); static methodHandle decode_method(oop x, KlassHandle& receiver_limit_result, int& decode_flags_result);
enum { enum {
// format of query to getConstant: // format of query to getConstant:
GC_JVM_PUSH_LIMIT = 0, GC_JVM_PUSH_LIMIT = 0,
......
...@@ -1721,14 +1721,14 @@ char* SharedRuntime::generate_wrong_method_type_message(JavaThread* thread, ...@@ -1721,14 +1721,14 @@ char* SharedRuntime::generate_wrong_method_type_message(JavaThread* thread,
targetArity = ArgumentCount(target->signature()).size(); targetArity = ArgumentCount(target->signature()).size();
} }
} }
klassOop kignore; int dmf_flags = 0; KlassHandle kignore; int dmf_flags = 0;
methodOop actual_method = MethodHandles::decode_method(actual, kignore, dmf_flags); methodHandle actual_method = MethodHandles::decode_method(actual, kignore, dmf_flags);
if ((dmf_flags & ~(MethodHandles::_dmf_has_receiver | if ((dmf_flags & ~(MethodHandles::_dmf_has_receiver |
MethodHandles::_dmf_does_dispatch | MethodHandles::_dmf_does_dispatch |
MethodHandles::_dmf_from_interface)) != 0) MethodHandles::_dmf_from_interface)) != 0)
actual_method = NULL; // MH does extra binds, drops, etc. actual_method = methodHandle(); // MH does extra binds, drops, etc.
bool has_receiver = ((dmf_flags & MethodHandles::_dmf_has_receiver) != 0); bool has_receiver = ((dmf_flags & MethodHandles::_dmf_has_receiver) != 0);
if (actual_method != NULL) { if (actual_method.not_null()) {
mhName = actual_method->signature()->as_C_string(); mhName = actual_method->signature()->as_C_string();
mhArity = ArgumentCount(actual_method->signature()).size(); mhArity = ArgumentCount(actual_method->signature()).size();
if (!actual_method->is_static()) mhArity += 1; if (!actual_method->is_static()) mhArity += 1;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册