< prev index next >
src/hotspot/share/classfile/systemDictionary.cpp
Print this page
rev 52749 : Bootstrap method consolidation
* clean up and simplify JDK support code for BSM invocation
* simplify JVM bootstrap handshake: use BootstrapCallInfo only
* remove unused JVM paths and data fields
* move bootstrap argument processing from MethodHandleNatives to ConstantPool
* remove ConstantGroup; merge argument access into BootstrapCallInfo
* adjust BSM argument access: remove copyArguments, add argumentRef API
* add metadata-free BSM modes, including symbolic arguments from CP
*** 2510,2520 ****
methodHandle SystemDictionary::find_method_handle_invoker(Klass* klass,
Symbol* name,
Symbol* signature,
Klass* accessing_klass,
Handle *appendix_result,
- Handle *method_type_result,
TRAPS) {
methodHandle empty;
assert(THREAD->can_call_java() ,"");
Handle method_type =
SystemDictionary::find_method_handle_type(signature, accessing_klass, CHECK_(empty));
--- 2510,2519 ----
*** 2543,2553 ****
SystemDictionary::MethodHandleNatives_klass(),
vmSymbols::linkMethod_name(),
vmSymbols::linkMethod_signature(),
&args, CHECK_(empty));
Handle mname(THREAD, (oop) result.get_jobject());
- (*method_type_result) = method_type;
return unpack_method_and_appendix(mname, accessing_klass, appendix_box, appendix_result, THREAD);
}
// Decide if we can globally cache a lookup of this class, to be returned to any client that asks.
// We must ensure that all class loaders everywhere will reach this class, for any client.
--- 2542,2551 ----
*** 2584,2593 ****
--- 2582,2592 ----
Handle SystemDictionary::find_java_mirror_for_type(Symbol* signature,
Klass* accessing_klass,
Handle class_loader,
Handle protection_domain,
SignatureStream::FailureMode failure_mode,
+ bool check_access,
TRAPS) {
Handle empty;
assert(accessing_klass == NULL || (class_loader.is_null() && protection_domain.is_null()),
"one or the other, or perhaps neither");
*** 2624,2634 ****
return Handle(); // report failure this way
}
Handle mirror(THREAD, constant_type_klass->java_mirror());
// Check accessibility, emulating ConstantPool::verify_constant_pool_resolve.
! if (accessing_klass != NULL) {
Klass* sel_klass = constant_type_klass;
bool fold_type_to_class = true;
LinkResolver::check_klass_accessability(accessing_klass, sel_klass,
fold_type_to_class, CHECK_(empty));
}
--- 2623,2633 ----
return Handle(); // report failure this way
}
Handle mirror(THREAD, constant_type_klass->java_mirror());
// Check accessibility, emulating ConstantPool::verify_constant_pool_resolve.
! if (check_access && accessing_klass != NULL) {
Klass* sel_klass = constant_type_klass;
bool fold_type_to_class = true;
LinkResolver::check_klass_accessability(accessing_klass, sel_klass,
fold_type_to_class, CHECK_(empty));
}
*** 2732,2762 ****
// report back to the caller with the MethodType
return method_type;
}
- Handle SystemDictionary::find_field_handle_type(Symbol* signature,
- Klass* accessing_klass,
- TRAPS) {
- Handle empty;
- ResourceMark rm(THREAD);
- SignatureStream ss(signature, /*is_method=*/ false);
- if (!ss.is_done()) {
- Handle class_loader, protection_domain;
- if (accessing_klass != NULL) {
- class_loader = Handle(THREAD, accessing_klass->class_loader());
- protection_domain = Handle(THREAD, accessing_klass->protection_domain());
- }
- oop mirror = ss.as_java_mirror(class_loader, protection_domain, SignatureStream::NCDFError, CHECK_(empty));
- ss.next();
- if (ss.is_done()) {
- return Handle(THREAD, mirror);
- }
- }
- return empty;
- }
-
// Ask Java code to find or construct a method handle constant.
Handle SystemDictionary::link_method_handle_constant(Klass* caller,
int ref_kind, //e.g., JVM_REF_invokeVirtual
Klass* callee,
Symbol* name,
--- 2731,2740 ----
*** 2804,2915 ****
vmSymbols::linkMethodHandleConstant_signature(),
&args, CHECK_(empty));
return Handle(THREAD, (oop) result.get_jobject());
}
! // Ask Java to compute a constant by invoking a BSM given a Dynamic_info CP entry
! Handle SystemDictionary::link_dynamic_constant(Klass* caller,
! int condy_index,
! Handle bootstrap_specifier,
! Symbol* name,
! Symbol* type,
! TRAPS) {
! Handle empty;
! Handle bsm, info;
! if (java_lang_invoke_MethodHandle::is_instance(bootstrap_specifier())) {
! bsm = bootstrap_specifier;
! } else {
! assert(bootstrap_specifier->is_objArray(), "");
! objArrayOop args = (objArrayOop) bootstrap_specifier();
! assert(args->length() == 2, "");
! bsm = Handle(THREAD, args->obj_at(0));
! info = Handle(THREAD, args->obj_at(1));
! }
! guarantee(java_lang_invoke_MethodHandle::is_instance(bsm()),
! "caller must supply a valid BSM");
!
! // This should not happen. JDK code should take care of that.
! if (caller == NULL) {
! THROW_MSG_(vmSymbols::java_lang_InternalError(), "bad dynamic constant", empty);
}
!
! Handle constant_name = java_lang_String::create_from_symbol(name, CHECK_(empty));
!
! // Resolve the constant type in the context of the caller class
! Handle type_mirror = find_java_mirror_for_type(type, caller, SignatureStream::NCDFError,
! CHECK_(empty));
!
! // call java.lang.invoke.MethodHandleNatives::linkConstantDyanmic(caller, condy_index, bsm, type, info)
! JavaCallArguments args;
! args.push_oop(Handle(THREAD, caller->java_mirror()));
! args.push_int(condy_index);
! args.push_oop(bsm);
! args.push_oop(constant_name);
! args.push_oop(type_mirror);
! args.push_oop(info);
JavaValue result(T_OBJECT);
JavaCalls::call_static(&result,
SystemDictionary::MethodHandleNatives_klass(),
! vmSymbols::linkDynamicConstant_name(),
! vmSymbols::linkDynamicConstant_signature(),
! &args, CHECK_(empty));
!
! return Handle(THREAD, (oop) result.get_jobject());
! }
!
! // Ask Java code to find or construct a java.lang.invoke.CallSite for the given
! // name and signature, as interpreted relative to the given class loader.
! methodHandle SystemDictionary::find_dynamic_call_site_invoker(Klass* caller,
! int indy_index,
! Handle bootstrap_specifier,
! Symbol* name,
! Symbol* type,
! Handle *appendix_result,
! Handle *method_type_result,
! TRAPS) {
! methodHandle empty;
! Handle bsm, info;
! if (java_lang_invoke_MethodHandle::is_instance(bootstrap_specifier())) {
! bsm = bootstrap_specifier;
} else {
! objArrayOop args = (objArrayOop) bootstrap_specifier();
! assert(args->length() == 2, "");
! bsm = Handle(THREAD, args->obj_at(0));
! info = Handle(THREAD, args->obj_at(1));
}
- guarantee(java_lang_invoke_MethodHandle::is_instance(bsm()),
- "caller must supply a valid BSM");
-
- Handle method_name = java_lang_String::create_from_symbol(name, CHECK_(empty));
- Handle method_type = find_method_handle_type(type, caller, CHECK_(empty));
! // This should not happen. JDK code should take care of that.
! if (caller == NULL || method_type.is_null()) {
! THROW_MSG_(vmSymbols::java_lang_InternalError(), "bad invokedynamic", empty);
}
-
- objArrayHandle appendix_box = oopFactory::new_objArray_handle(SystemDictionary::Object_klass(), 1, CHECK_(empty));
- assert(appendix_box->obj_at(0) == NULL, "");
-
- // call java.lang.invoke.MethodHandleNatives::linkCallSite(caller, indy_index, bsm, name, mtype, info, &appendix)
- JavaCallArguments args;
- args.push_oop(Handle(THREAD, caller->java_mirror()));
- args.push_int(indy_index);
- args.push_oop(bsm);
- args.push_oop(method_name);
- args.push_oop(method_type);
- args.push_oop(info);
- args.push_oop(appendix_box);
- JavaValue result(T_OBJECT);
- JavaCalls::call_static(&result,
- SystemDictionary::MethodHandleNatives_klass(),
- vmSymbols::linkCallSite_name(),
- vmSymbols::linkCallSite_signature(),
- &args, CHECK_(empty));
- Handle mname(THREAD, (oop) result.get_jobject());
- (*method_type_result) = method_type;
- return unpack_method_and_appendix(mname, caller, appendix_box, appendix_result, THREAD);
}
// Protection domain cache table handling
ProtectionDomainCacheEntry* SystemDictionary::cache_get(Handle protection_domain) {
--- 2782,2875 ----
vmSymbols::linkMethodHandleConstant_signature(),
&args, CHECK_(empty));
return Handle(THREAD, (oop) result.get_jobject());
}
! // Ask Java to run a bootstrap method, in order to create a dynamic call site
! // while linking an invokedynamic op, or compute a constant for Dynamic_info CP entry
! // with linkage results being stored back into the bootstrap specifier.
! void SystemDictionary::invoke_bootstrap_method(BootstrapInfo& bootstrap_specifier, TRAPS) {
! ResourceMark rm;
! bootstrap_specifier.resolve_bsm(CHECK);
! bootstrap_specifier.resolve_metadata(CHECK);
! BootstrapInfo::BSMMode bsm_mode = bootstrap_specifier.bsm_mode();
! ConstantPool::BootstrapArgumentReferenceMode arg_mode = ConstantPool::R_IFPRESENT;
! if (bsm_mode == BootstrapInfo::_metadata ||
! (bsm_mode == BootstrapInfo::_expression &&
! bootstrap_specifier.name() == vmSymbols::invoke_name()))
! // We know the BSM is going to immediately use all the arguments.
! arg_mode = ConstantPool::R_FORCE;
! // Otherwise, it can't hurt to pre-pack the object array with present arguments.
! bootstrap_specifier.resolve_args(arg_mode, CHECK);
! if (arg_mode != ConstantPool::R_FORCE) {
! // If we are going tentative, also grab the symbolic reference data.
! bootstrap_specifier.resolve_args(ConstantPool::R_SYMREF, CHECK);
! }
!
! Handle caller(THREAD, bootstrap_specifier.caller_mirror());
! typeArrayOop index_info_oop = oopFactory::new_intArray(2, CHECK);
! typeArrayHandle index_info(THREAD, index_info_oop);
! index_info->int_at_put(0, bootstrap_specifier.argc());
! index_info->int_at_put(1, bootstrap_specifier.bss_index());
!
! bool has_appendix = bootstrap_specifier.is_method_call();
! objArrayHandle appendix_box;
! if (has_appendix) {
! // Some method calls may require an appendix argument. Arrange to receive it.
! objArrayOop appendix_box_oop = oopFactory::new_objArray(SystemDictionary::Object_klass(), 1, CHECK);
! appendix_box = objArrayHandle(THREAD, appendix_box_oop);
! assert(appendix_box->obj_at(0) == NULL, "");
}
! Handle request;
! if (bootstrap_specifier.indy_index() != 0) {
! // request is call-site specific
! request = Handle(THREAD, SystemDictionary::CallSite_klass()->java_mirror());
! }
!
! Handle cpool = reflect_ConstantPool::create_from_pool(bootstrap_specifier.pool()(), CHECK);
! Handle arg_indexes(THREAD, bootstrap_specifier.arg_indexes()());
! Handle arg_values(THREAD, bootstrap_specifier.arg_values()());
!
! // call java.lang.invoke.MethodHandleNatives::bootstrapMethodHelper(cpool, bss_index, indy_index, argc, bsm, name, type, argIndexes, argValues, request, &appendix)
! JavaCallArguments args(11);
! args.push_oop(cpool);
! args.push_int(bootstrap_specifier.bss_index());
! args.push_int(bootstrap_specifier.indy_index());
! args.push_int(bootstrap_specifier.argc());
! args.push_oop(bootstrap_specifier.bsm());
! args.push_oop(bootstrap_specifier.name_arg());
! args.push_oop(bootstrap_specifier.type_arg());
! args.push_oop(bootstrap_specifier.arg_indexes());
! args.push_oop(bootstrap_specifier.arg_values());
! args.push_oop(request);
! args.push_oop(appendix_box);
JavaValue result(T_OBJECT);
JavaCalls::call_static(&result,
SystemDictionary::MethodHandleNatives_klass(),
! vmSymbols::bootstrapMethodHelper_name(),
! vmSymbols::bootstrapMethodHelper_signature(),
! &args, CHECK);
! if (has_appendix) {
! Handle appendix;
! Handle mname(THREAD, (oop) result.get_jobject());
! methodHandle method = unpack_method_and_appendix(mname,
! bootstrap_specifier.caller(),
! appendix_box,
! &appendix, CHECK);
! bootstrap_specifier.set_resolved_method(method, appendix);
} else {
! Handle value(THREAD, (oop) result.get_jobject());
! bootstrap_specifier.set_resolved_value(value);
}
! // sanity check
! if (!bootstrap_specifier.is_resolved() ||
! (bootstrap_specifier.is_method_call() &&
! bootstrap_specifier.resolved_method().is_null())) {
! // Could be a guarantee but throw IE instead, in case it is JDK bug.
! THROW_MSG(vmSymbols::java_lang_InternalError(), "bootstrap method call failed");
}
}
// Protection domain cache table handling
ProtectionDomainCacheEntry* SystemDictionary::cache_get(Handle protection_domain) {
< prev index next >