From b42bb5de4ac24eb4a0b6f9339c78c8559a01b7e4 Mon Sep 17 00:00:00 2001 From: twisti Date: Mon, 18 Apr 2011 01:33:28 -0700 Subject: [PATCH] 7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space Reviewed-by: kvn, jrose --- src/share/vm/ci/ciMethod.hpp | 6 +- src/share/vm/memory/genOopClosures.hpp | 4 +- src/share/vm/prims/methodHandleWalk.cpp | 6 +- src/share/vm/prims/methodHandles.cpp | 211 ++++++++++++------------ src/share/vm/prims/methodHandles.hpp | 16 +- src/share/vm/runtime/sharedRuntime.cpp | 8 +- 6 files changed, 120 insertions(+), 131 deletions(-) diff --git a/src/share/vm/ci/ciMethod.hpp b/src/share/vm/ci/ciMethod.hpp index 745806c0c..840fb5da0 100644 --- a/src/share/vm/ci/ciMethod.hpp +++ b/src/share/vm/ci/ciMethod.hpp @@ -276,9 +276,9 @@ class ciMethod : public ciObject { void print_short_name(outputStream* st = tty); methodOop get_method_handle_target() { - klassOop receiver_limit_oop = NULL; - int flags = 0; - return MethodHandles::decode_method(get_oop(), receiver_limit_oop, flags); + KlassHandle receiver_limit; int flags = 0; + methodHandle m = MethodHandles::decode_method(get_oop(), receiver_limit, flags); + return m(); } }; diff --git a/src/share/vm/memory/genOopClosures.hpp b/src/share/vm/memory/genOopClosures.hpp index 77ae7efba..6d5257c4f 100644 --- a/src/share/vm/memory/genOopClosures.hpp +++ b/src/share/vm/memory/genOopClosures.hpp @@ -1,5 +1,5 @@ /* - * 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. * * This code is free software; you can redistribute it and/or modify it @@ -175,7 +175,7 @@ class VerifyOopClosure: public OopClosure { protected: template inline void do_oop_work(T* 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: virtual void do_oop(oop* p); diff --git a/src/share/vm/prims/methodHandleWalk.cpp b/src/share/vm/prims/methodHandleWalk.cpp index 3570d2db4..936d1e739 100644 --- a/src/share/vm/prims/methodHandleWalk.cpp +++ b/src/share/vm/prims/methodHandleWalk.cpp @@ -82,10 +82,8 @@ void MethodHandleChain::set_method_handle(Handle mh, TRAPS) { void MethodHandleChain::set_last_method(oop target, TRAPS) { _is_last = true; - klassOop receiver_limit_oop = NULL; - int flags = 0; - methodOop m = MethodHandles::decode_method(target, receiver_limit_oop, flags); - _last_method = methodHandle(THREAD, m); + KlassHandle receiver_limit; int flags = 0; + _last_method = MethodHandles::decode_method(target, receiver_limit, flags); if ((flags & MethodHandles::_dmf_has_receiver) == 0) _last_invoke = Bytecodes::_invokestatic; else if ((flags & MethodHandles::_dmf_does_dispatch) == 0) diff --git a/src/share/vm/prims/methodHandles.cpp b/src/share/vm/prims/methodHandles.cpp index eb0ba3df1..12a483f23 100644 --- a/src/share/vm/prims/methodHandles.cpp +++ b/src/share/vm/prims/methodHandles.cpp @@ -153,9 +153,9 @@ void MethodHandles::set_enabled(bool z) { // and local, like parse a data structure. For speed, such methods work on plain // oops, not handles. Trapping methods uniformly operate on handles. -methodOop MethodHandles::decode_vmtarget(oop vmtarget, int vmindex, oop mtype, - klassOop& receiver_limit_result, int& decode_flags_result) { - if (vmtarget == NULL) return NULL; +methodHandle MethodHandles::decode_vmtarget(oop vmtarget, int vmindex, oop mtype, + KlassHandle& receiver_limit_result, int& decode_flags_result) { + if (vmtarget == NULL) return methodHandle(); assert(methodOopDesc::nonvirtual_vtable_index < 0, "encoding"); if (vmindex < 0) { // 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, // MemberName and DirectMethodHandle have the same linkage to the JVM internals. // (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); int vmindex = java_lang_invoke_DirectMethodHandle::vmindex(mh); oop mtype = java_lang_invoke_DirectMethodHandle::type(mh); 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(mh->klass() != SystemDictionary::AdapterMethodHandle_klass(), ""); for (oop bmh = mh;;) { // Bound MHs can be stacked to bind several arguments. 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; klassOop tk = target->klass(); if (tk == SystemDictionary::BoundMethodHandle_klass()) { @@ -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(), ""); for (oop amh = mh;;) { // Adapter MHs can be stacked to convert several arguments. int conv_op = adapter_conversion_op(java_lang_invoke_AdapterMethodHandle::conversion(amh)); decode_flags_result |= (_dmf_adapter_lsb << conv_op) & _DMF_ADAPTER_MASK; oop target = java_lang_invoke_MethodHandle::vmtarget(amh); - if (target == NULL) return NULL; + if (target == NULL) return methodHandle(); klassOop tk = target->klass(); if (tk == SystemDictionary::AdapterMethodHandle_klass()) { amh = target; @@ -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) { - if (mh == NULL) return NULL; +methodHandle MethodHandles::decode_MethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result) { + if (mh == NULL) return methodHandle(); klassOop mhk = mh->klass(); assert(java_lang_invoke_MethodHandle::is_subclass(mhk), "must be a MethodHandle"); if (mhk == SystemDictionary::DirectMethodHandle_klass()) { @@ -270,7 +270,7 @@ methodOop MethodHandles::decode_MethodHandle(oop mh, klassOop& receiver_limit_re return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result); } else { 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) // A trusted party is handing us a cookie to determine a method. // 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; - receiver_limit_result = NULL; + receiver_limit_result = KlassHandle(); klassOop xk = x->klass(); if (xk == Universe::methodKlassObj()) { return decode_methodOop((methodOop) x, decode_flags_result); @@ -329,7 +329,7 @@ methodOop MethodHandles::decode_method(oop x, klassOop& receiver_limit_result, i assert(!x->is_method(), "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) { int offset = instanceKlass::cast(k)->offset_from_fields(slot); init_MemberName(mname_oop, k, accessFlags_from(mods), offset); } else { - int decode_flags = 0; klassOop receiver_limit = NULL; - methodOop m = MethodHandles::decode_method(target_oop, - receiver_limit, decode_flags); + KlassHandle receiver_limit; int decode_flags = 0; + methodHandle m = MethodHandles::decode_method(target_oop, receiver_limit, decode_flags); 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 } -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); - 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); int vmindex = java_lang_invoke_MemberName::vmindex(mname); - if (vmindex == VM_INDEX_UNINITIALIZED) return NULL; // not resolved - methodOop m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit_result, decode_flags_result); + if (vmindex == VM_INDEX_UNINITIALIZED) return empty; // not resolved + methodHandle m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit_result, decode_flags_result); oop clazz = java_lang_invoke_MemberName::clazz(mname); if (clazz != NULL && java_lang_Class::is_instance(clazz)) { klassOop klass = java_lang_Class::as_klassOop(clazz); @@ -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 -Symbol* MethodHandles::convert_to_signature(oop type_str, - bool polymorphic, - TRAPS) { +Symbol* MethodHandles::convert_to_signature(oop type_str, bool polymorphic, TRAPS) { if (java_lang_invoke_MethodType::is_instance(type_str)) { return java_lang_invoke_MethodType::as_signature(type_str, polymorphic, CHECK_NULL); } else if (java_lang_Class::is_instance(type_str)) { @@ -474,48 +472,48 @@ void MethodHandles::resolve_MemberName(Handle mname, TRAPS) { #endif if (java_lang_invoke_MemberName::vmindex(mname()) != VM_INDEX_UNINITIALIZED) return; // already resolved - oop defc_oop = java_lang_invoke_MemberName::clazz(mname()); - oop name_str = java_lang_invoke_MemberName::name(mname()); - oop type_str = java_lang_invoke_MemberName::type(mname()); - int flags = java_lang_invoke_MemberName::flags(mname()); + Handle defc_oop(THREAD, java_lang_invoke_MemberName::clazz(mname())); + Handle name_str(THREAD, java_lang_invoke_MemberName::name( mname())); + Handle type_str(THREAD, java_lang_invoke_MemberName::type( 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"); } - klassOop defc_klassOop = java_lang_Class::as_klassOop(defc_oop); - defc_oop = NULL; // safety - if (defc_klassOop == NULL) return; // a primitive; no resolution possible - if (!Klass::cast(defc_klassOop)->oop_is_instance()) { - if (!Klass::cast(defc_klassOop)->oop_is_array()) return; - defc_klassOop = SystemDictionary::Object_klass(); + + instanceKlassHandle defc; + { + klassOop defc_klassOop = java_lang_Class::as_klassOop(defc_oop()); + if (defc_klassOop == NULL) return; // a primitive; no resolution possible + 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()) { 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 - 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 - name_str = NULL; // safety Handle polymorphic_method_type; bool polymorphic_signature = false; if ((flags & ALL_KINDS) == IS_METHOD && (defc() == SystemDictionary::MethodHandle_klass() && - methodOopDesc::is_method_handle_invoke_name(name))) + methodOopDesc::is_method_handle_invoke_name(name))) { polymorphic_signature = true; + } // convert the external string or reflective type to an internal signature - TempNewSymbol type = convert_to_signature(type_str, polymorphic_signature, CHECK); - if (java_lang_invoke_MethodType::is_instance(type_str) && polymorphic_signature) { - polymorphic_method_type = Handle(THREAD, type_str); //preserve exactly + TempNewSymbol type = convert_to_signature(type_str(), polymorphic_signature, CHECK); + if (java_lang_invoke_MethodType::is_instance(type_str()) && polymorphic_signature) { + polymorphic_method_type = type_str; // preserve exactly } - if (type == NULL) return; // no such signature exists in the VM - type_str = NULL; // safety // Time to do the lookup. switch (flags & ALL_KINDS) { @@ -560,8 +558,8 @@ void MethodHandles::resolve_MemberName(Handle mname, TRAPS) { java_lang_invoke_MemberName::set_vmtarget(mname(), vmtarget); java_lang_invoke_MemberName::set_vmindex(mname(), vmindex); java_lang_invoke_MemberName::set_modifiers(mname(), mods); - DEBUG_ONLY(int junk; klassOop junk2); - assert(decode_MemberName(mname(), junk2, junk) == result.resolved_method()(), + DEBUG_ONLY(KlassHandle junk1; int junk2); + assert(decode_MemberName(mname(), junk1, junk2) == result.resolved_method(), "properly stored for later decoding"); return; } @@ -589,8 +587,8 @@ void MethodHandles::resolve_MemberName(Handle mname, TRAPS) { java_lang_invoke_MemberName::set_vmtarget(mname(), vmtarget); java_lang_invoke_MemberName::set_vmindex(mname(), vmindex); java_lang_invoke_MemberName::set_modifiers(mname(), mods); - DEBUG_ONLY(int junk; klassOop junk2); - assert(decode_MemberName(mname(), junk2, junk) == result.resolved_method()(), + DEBUG_ONLY(KlassHandle junk1; int junk2); + assert(decode_MemberName(mname(), junk1, junk2) == result.resolved_method(), "properly stored for later decoding"); return; } @@ -677,16 +675,14 @@ void MethodHandles::expand_MemberName(Handle mname, int suppress, TRAPS) { case IS_METHOD: case IS_CONSTRUCTOR: { - klassOop receiver_limit = NULL; - int decode_flags = 0; - methodHandle m(THREAD, decode_vmtarget(vmtarget, vmindex, NULL, - receiver_limit, decode_flags)); + KlassHandle receiver_limit; int decode_flags = 0; + methodHandle m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit, decode_flags); if (m.is_null()) break; if (!have_defc) { klassOop defc = m->method_holder(); - if (receiver_limit != NULL && receiver_limit != defc - && Klass::cast(receiver_limit)->is_subtype_of(defc)) - defc = receiver_limit; + if (receiver_limit.not_null() && receiver_limit() != defc + && Klass::cast(receiver_limit())->is_subtype_of(defc)) + defc = receiver_limit(); java_lang_invoke_MemberName::set_clazz(mname(), Klass::cast(defc)->java_mirror()); } if (!have_name) { @@ -884,10 +880,9 @@ oop MethodHandles::encode_target(Handle mh, int format, TRAPS) { // - AMH can have methodOop for static invoke with bound receiver // - DMH can have methodOop for static invoke (on variable receiver) // - DMH can have klassOop for dispatched (non-static) invoke - klassOop receiver_limit = NULL; - int decode_flags = 0; - methodOop m = decode_MethodHandle(mh(), receiver_limit, decode_flags); - if (m == NULL) return NULL; + KlassHandle receiver_limit; int decode_flags = 0; + methodHandle m = decode_MethodHandle(mh(), receiver_limit, decode_flags); + if (m.is_null()) return NULL; switch (format) { case ETF_REFLECT_METHOD: // same as jni_ToReflectedMethod: @@ -903,10 +898,10 @@ oop MethodHandles::encode_target(Handle mh, int format, TRAPS) { if (SystemDictionary::MemberName_klass() == NULL) break; instanceKlassHandle mname_klass(THREAD, SystemDictionary::MemberName_klass()); 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); 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); return mname(); } @@ -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 // bits, and will use the same calling sequence code. - int vmindex = methodOopDesc::garbage_vtable_index; - oop vmtarget = NULL; + int vmindex = methodOopDesc::garbage_vtable_index; + Handle vmtarget; instanceKlass::cast(m->method_holder())->link_class(CHECK); @@ -1478,7 +1473,7 @@ void MethodHandles::init_DirectMethodHandle(Handle mh, methodHandle m, bool do_d } else if (!do_dispatch || m->can_be_statically_bound()) { // We are simulating an invokestatic or invokespecial instruction. // 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: vmindex = methodOopDesc::nonvirtual_vtable_index; assert(vmindex < 0, "(>=0) == do_dispatch"); @@ -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. Klass* k = Klass::cast(m->method_holder()); if (k->should_be_initialized()) { - k->initialize(CHECK); + k->initialize(CHECK); // possible safepoint } } } else { @@ -1504,10 +1499,10 @@ void MethodHandles::init_DirectMethodHandle(Handle mh, methodHandle m, bool do_d if (me == NULL) { THROW(vmSymbols::java_lang_InternalError()); } - java_lang_invoke_DirectMethodHandle::set_vmtarget(mh(), vmtarget); - java_lang_invoke_DirectMethodHandle::set_vmindex(mh(), vmindex); - DEBUG_ONLY(int flags; klassOop rlimit); - assert(MethodHandles::decode_method(mh(), rlimit, flags) == m(), + java_lang_invoke_DirectMethodHandle::set_vmtarget(mh(), vmtarget()); + java_lang_invoke_DirectMethodHandle::set_vmindex( mh(), vmindex); + DEBUG_ONLY(KlassHandle rlimit; int flags); + assert(MethodHandles::decode_method(mh(), rlimit, flags) == m, "properly stored for later decoding"); DEBUG_ONLY(bool actual_do_dispatch = ((flags & _dmf_does_dispatch) != 0)); assert(!(actual_do_dispatch && !do_dispatch), @@ -1523,10 +1518,13 @@ void MethodHandles::verify_BoundMethodHandle_with_receiver(Handle mh, methodHandle m, TRAPS) { // Verify type. - oop receiver = java_lang_invoke_BoundMethodHandle::argument(mh()); - Handle mtype(THREAD, java_lang_invoke_MethodHandle::type(mh())); 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); int receiver_pos = m->size_of_parameters() - 1; @@ -1573,8 +1571,8 @@ void MethodHandles::init_BoundMethodHandle_with_receiver(Handle mh, java_lang_invoke_BoundMethodHandle::set_vmtarget(mh(), m()); - DEBUG_ONLY(int junk; klassOop junk2); - assert(MethodHandles::decode_method(mh(), junk2, junk) == m(), "properly stored for later decoding"); + DEBUG_ONLY(KlassHandle junk1; int junk2); + 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"); // Done! @@ -1682,8 +1680,11 @@ void MethodHandles::init_BoundMethodHandle(Handle mh, Handle target, int argnum, } // Get bound type and required slots. - oop ptype_oop = java_lang_invoke_MethodType::ptype(java_lang_invoke_MethodHandle::type(target()), argnum); - BasicType ptype = java_lang_Class::as_BasicType(ptype_oop); + BasicType ptype; + { + 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]; // 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, if (OptimizeMethodHandles && target->klass() == SystemDictionary::DirectMethodHandle_klass() && (argnum == 0 || java_lang_invoke_DirectMethodHandle::vmindex(target()) < 0)) { - int decode_flags = 0; klassOop receiver_limit_oop = NULL; - methodHandle m(THREAD, decode_method(target(), receiver_limit_oop, decode_flags)); + KlassHandle receiver_limit; int decode_flags = 0; + methodHandle m = decode_method(target(), receiver_limit, decode_flags); 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. assert(java_lang_invoke_BoundMethodHandle::vmslots(mh()) == m_vmslots, "type w/ m sig"); if (argnum == 0 && (decode_flags & _dmf_has_receiver) != 0) { - KlassHandle receiver_limit(THREAD, receiver_limit_oop); init_BoundMethodHandle_with_receiver(mh, m, receiver_limit, decode_flags, CHECK); @@ -2019,7 +2019,6 @@ void MethodHandles::verify_AdapterMethodHandle(Handle mh, 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()); jint conversion = java_lang_invoke_AdapterMethodHandle::conversion(mh()); jint conv_op = adapter_conversion_op(conversion); @@ -2215,18 +2214,14 @@ JVM_ENTRY(void, MHN_init_DMH(JNIEnv *env, jobject igcls, jobject mh_jh, // which method are we really talking about? if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } - oop target_oop = JNIHandles::resolve_non_null(target_jh); - if (java_lang_invoke_MemberName::is_instance(target_oop) && - java_lang_invoke_MemberName::vmindex(target_oop) == VM_INDEX_UNINITIALIZED) { - Handle mname(THREAD, target_oop); - MethodHandles::resolve_MemberName(mname, CHECK); - target_oop = mname(); // in case of GC + Handle target(THREAD, JNIHandles::resolve_non_null(target_jh)); + if (java_lang_invoke_MemberName::is_instance(target()) && + java_lang_invoke_MemberName::vmindex(target()) == VM_INDEX_UNINITIALIZED) { + MethodHandles::resolve_MemberName(target, CHECK); } - int decode_flags = 0; klassOop receiver_limit = NULL; - methodHandle m(THREAD, - MethodHandles::decode_method(target_oop, - receiver_limit, decode_flags)); + KlassHandle receiver_limit; int decode_flags = 0; + methodHandle m = MethodHandles::decode_method(target(), receiver_limit, decode_flags); 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 @@ -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?) Untested("init_BMH of non-MH"); if (argnum != 0) { THROW(vmSymbols::java_lang_InternalError()); } - int decode_flags = 0; klassOop receiver_limit_oop = NULL; - methodHandle m(THREAD, - MethodHandles::decode_method(target(), - receiver_limit_oop, - decode_flags)); - KlassHandle receiver_limit(THREAD, receiver_limit_oop); + KlassHandle receiver_limit; int decode_flags = 0; + methodHandle m = MethodHandles::decode_method(target(), receiver_limit, decode_flags); MethodHandles::init_BoundMethodHandle_with_receiver(mh, m, receiver_limit, decode_flags, @@ -2424,12 +2415,12 @@ JVM_ENTRY(jint, MHN_getNamedCon(JNIEnv *env, jobject igcls, jint which, jobjectA #ifndef PRODUCT if (which >= 0 && which < con_value_count) { int con = con_values[which]; - objArrayOop box = (objArrayOop) JNIHandles::resolve(box_jh); - if (box != NULL && box->klass() == Universe::objectArrayKlassObj() && box->length() > 0) { + objArrayHandle box(THREAD, (objArrayOop) JNIHandles::resolve(box_jh)); + if (box.not_null() && box->klass() == Universe::objectArrayKlassObj() && box->length() > 0) { const char* str = &con_names[0]; for (int i = 0; i < which; i++) 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); } return con; @@ -2486,10 +2477,10 @@ JVM_ENTRY(jint, MHN_getMembers(JNIEnv *env, jobject igcls, jclass clazz_jh, jstring name_jh, jstring sig_jh, int mflags, jclass caller_jh, jint skip, jobjectArray results_jh)) { 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); - if (results == NULL || !results->is_objArray()) return -1; + objArrayHandle results(THREAD, (objArrayOop) JNIHandles::resolve(results_jh)); + if (results.is_null() || !results->is_objArray()) return -1; TempNewSymbol name = NULL; TempNewSymbol sig = NULL; @@ -2502,20 +2493,20 @@ JVM_ENTRY(jint, MHN_getMembers(JNIEnv *env, jobject igcls, if (sig == NULL) return 0; // a match is not possible } - klassOop caller = NULL; + KlassHandle caller; if (caller_jh != NULL) { oop caller_oop = JNIHandles::resolve_non_null(caller_jh); 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 // %%% TO DO } - int res = MethodHandles::find_MemberNames(k_oop, 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; } diff --git a/src/share/vm/prims/methodHandles.hpp b/src/share/vm/prims/methodHandles.hpp index 08e0b5377..d104783d4 100644 --- a/src/share/vm/prims/methodHandles.hpp +++ b/src/share/vm/prims/methodHandles.hpp @@ -265,13 +265,13 @@ class MethodHandles: AllStatic { static inline address from_interpreted_entry(EntryKind ek); // helpers for decode_method. - 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 methodOop decode_MemberName(oop mname, klassOop& receiver_limit_result, int& decode_flags_result); - static methodOop decode_MethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result); - static methodOop decode_DirectMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result); - static methodOop decode_BoundMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result); - static methodOop decode_AdapterMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result); + static methodOop decode_methodOop(methodOop m, int& decode_flags_result); + static methodHandle decode_vmtarget(oop vmtarget, int vmindex, oop mtype, KlassHandle& receiver_limit_result, int& decode_flags_result); + static methodHandle decode_MemberName(oop mname, KlassHandle& receiver_limit_result, int& decode_flags_result); + static methodHandle decode_MethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result); + static methodHandle decode_DirectMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result); + static methodHandle decode_BoundMethodHandle(oop mh, KlassHandle& 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. // The result is *not* reported as a multiple of stack_move_unit(); @@ -317,7 +317,7 @@ class MethodHandles: AllStatic { _dmf_adapter_lsb = 0x20, _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 { // format of query to getConstant: GC_JVM_PUSH_LIMIT = 0, diff --git a/src/share/vm/runtime/sharedRuntime.cpp b/src/share/vm/runtime/sharedRuntime.cpp index 820678701..f60b2f070 100644 --- a/src/share/vm/runtime/sharedRuntime.cpp +++ b/src/share/vm/runtime/sharedRuntime.cpp @@ -1721,14 +1721,14 @@ char* SharedRuntime::generate_wrong_method_type_message(JavaThread* thread, targetArity = ArgumentCount(target->signature()).size(); } } - klassOop kignore; int dmf_flags = 0; - methodOop actual_method = MethodHandles::decode_method(actual, kignore, dmf_flags); + KlassHandle kignore; int dmf_flags = 0; + methodHandle actual_method = MethodHandles::decode_method(actual, kignore, dmf_flags); if ((dmf_flags & ~(MethodHandles::_dmf_has_receiver | MethodHandles::_dmf_does_dispatch | 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); - if (actual_method != NULL) { + if (actual_method.not_null()) { mhName = actual_method->signature()->as_C_string(); mhArity = ArgumentCount(actual_method->signature()).size(); if (!actual_method->is_static()) mhArity += 1; -- GitLab