< prev index next >
src/hotspot/share/interpreter/linkResolver.hpp
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
@@ -53,11 +53,11 @@
methodHandle _selected_method; // dynamic (actual) target method
CallKind _call_kind; // kind of call (static(=bytecode static/special +
// others inferred), vtable, itable)
int _call_index; // vtable or itable index of selected class method (if any)
Handle _resolved_appendix; // extra argument in constant pool (if CPCE::has_appendix)
- Handle _resolved_method_type; // MethodType (for invokedynamic and invokehandle call sites)
+ bool _has_local_sig; // use signature from call site, which differs from that of the method itself
Handle _resolved_method_name; // Object holding the ResolvedMethodName
void set_static(Klass* resolved_klass, const methodHandle& resolved_method, TRAPS);
void set_interface(Klass* resolved_klass, Klass* selected_klass,
const methodHandle& resolved_method,
@@ -66,21 +66,22 @@
void set_virtual(Klass* resolved_klass, Klass* selected_klass,
const methodHandle& resolved_method,
const methodHandle& selected_method,
int vtable_index, TRAPS);
void set_handle(const methodHandle& resolved_method,
- Handle resolved_appendix, Handle resolved_method_type, TRAPS);
+ Handle resolved_appendix, bool has_local_sig, TRAPS);
void set_handle(Klass* resolved_klass,
const methodHandle& resolved_method,
- Handle resolved_appendix, Handle resolved_method_type, TRAPS);
+ Handle resolved_appendix, bool has_local_sig, TRAPS);
void set_common(Klass* resolved_klass, Klass* selected_klass,
const methodHandle& resolved_method,
const methodHandle& selected_method,
CallKind kind,
int index, TRAPS);
friend class LinkResolver;
+ friend class BootstrapInfo;
public:
CallInfo() {
#ifndef PRODUCT
_call_kind = CallInfo::unknown_kind;
@@ -96,11 +97,11 @@
Klass* resolved_klass() const { return _resolved_klass; }
Klass* selected_klass() const { return _selected_klass; }
methodHandle resolved_method() const { return _resolved_method; }
methodHandle selected_method() const { return _selected_method; }
Handle resolved_appendix() const { return _resolved_appendix; }
- Handle resolved_method_type() const { return _resolved_method_type; }
+ bool has_local_signature() const { return _has_local_sig; }
Handle resolved_method_name() const { return _resolved_method_name; }
// Materialize a java.lang.invoke.ResolvedMethodName for this resolved_method
void set_resolved_method_name(TRAPS);
BasicType result_type() const { return selected_method()->result_type(); }
@@ -129,10 +130,121 @@
#endif //ASSERT
void verify() PRODUCT_RETURN;
void print() PRODUCT_RETURN;
};
+// Condensed information from constant pool to use to invoke a bootstrap method.
+class BootstrapInfo : public StackObj {
+ constantPoolHandle _pool; // constant pool containing the bootstrap specifier
+ const int _bss_index; // index of bootstrap specifier in CP (condy or indy)
+ const int _indy_index; // internal index of indy call site, or -1 if a condy call
+ const bool _is_method_call; // are we resolving a method (indy) or a value (condy)?
+ const int _argc; // number of static arguments
+ Symbol* _name; // extracted from JVM_CONSTANT_NameAndType
+ Symbol* _signature;
+
+ // pre-bootstrap resolution state:
+ Handle _bsm; // resolved bootstrap method
+ Handle _name_arg; // resolved String
+ Handle _type_arg; // resolved Class or MethodType
+ typeArrayHandle _arg_indexes; // int[] array of static arguments, as CP indexes
+ objArrayHandle _arg_values; // Object[] array of static arguments; null for unresolved
+
+ // post-bootstrap resolution state:
+ bool _is_resolved; // set true when any of the next fields are set
+ Handle _resolved_value; // bind this as condy constant
+ methodHandle _resolved_method; // bind this as indy behavior
+ Handle _resolved_appendix; // extra opaque static argument for _resolved_method
+
+ int nat_ref_index() const { return _pool->bootstrap_name_and_type_ref_index_at(_bss_index); }
+
+ public:
+ BootstrapInfo(const constantPoolHandle& pool, int bss_index, int indy_index = 0);
+
+ // accessors
+ const constantPoolHandle& pool() const{ return _pool; }
+ int bss_index() const { return _bss_index; }
+ int indy_index() const { return _indy_index; }
+ int argc() const { return _argc; }
+ bool is_method_call() const { return _is_method_call; }
+ Symbol* name() const { return _name; }
+ Symbol* signature() const { return _signature; }
+
+ // accessors to lazy state
+ Handle bsm() const { return _bsm; }
+ Handle name_arg() const { return _name_arg; }
+ Handle type_arg() const { return _type_arg; }
+ typeArrayHandle arg_indexes() const { return _arg_indexes; }
+ objArrayHandle arg_values() const { return _arg_values; }
+ bool is_resolved() const { return _is_resolved; }
+ Handle resolved_value() const { assert(!is_method_call(), ""); return _resolved_value; }
+ methodHandle resolved_method() const { assert(is_method_call(), ""); return _resolved_method; }
+ Handle resolved_appendix() const { assert(is_method_call(), ""); return _resolved_appendix; }
+
+ // derived accessors
+ InstanceKlass* caller() const { return _pool->pool_holder(); }
+ oop caller_mirror() const { return caller()->java_mirror(); }
+ int decode_indy_index() const { return ConstantPool::decode_invokedynamic_index(_indy_index); }
+ int name_index() const { return _pool->name_ref_index_at(nat_ref_index()); }
+ int signature_index() const { return _pool->signature_ref_index_at(nat_ref_index()); }
+ int bsms_attr_index() const { return _pool->bootstrap_methods_attribute_index(_bss_index); }
+ int bsm_index() const { return _pool->bootstrap_method_ref_index_at(_bss_index); }
+ //int argc() is eagerly cached in _argc
+ int arg_index(int i) const { return _pool->bootstrap_argument_index_at(_bss_index, i); }
+ oop arg_value(int i) const; // pull oop from _arg_values, safely, NULL if not present
+
+ enum BSMMode { _unknown, _metadata, _bsci, _expression };
+ BSMMode bsm_mode() const;
+
+ // CP cache entry for call site (indy only)
+ ConstantPoolCacheEntry* invokedynamic_cp_cache_entry() const {
+ assert(is_method_call(), "");
+ return _pool->invokedynamic_cp_cache_entry_at(_indy_index);
+ }
+
+ // If there is evidence this call site was already linked, set the
+ // existing linkage data into result, or throw previouos exception.
+ // Return true if either action is taken, else false.
+ bool resolve_previously_linked_invokedynamic(CallInfo& result, TRAPS);
+ bool save_and_throw_indy_exc(TRAPS);
+ void resolve_newly_linked_invokedynamic(CallInfo& result, TRAPS);
+
+ // argument location and resolution
+ // Null returns from these are real, actual null condy constants.
+ // They never produce Universe::the_null_sentinel.
+ oop find_arg_oop(int i, Handle if_not_present, TRAPS) {
+ // Don't pass if_not_present as null unless you are OK with confusing
+ // "not present" with "present but null".
+ bool found_it = false;
+ oop result = _pool->find_cached_constant_at(arg_index(i), found_it, THREAD);
+ return (found_it ? result : if_not_present()); // OK to execute during exception
+ }
+ oop resolve_arg_oop(int i, TRAPS) {
+ return _pool->resolve_possibly_cached_constant_at(arg_index(i), THREAD);
+ }
+
+ // pre-bootstrap resolution actions:
+ Handle resolve_bsm(TRAPS); // lazily compute _bsm and return it
+ void resolve_metadata(TRAPS); // lazily compute _name/_type
+ void resolve_args(ConstantPool::BootstrapArgumentReferenceMode resolving, TRAPS); // compute arguments
+
+ // setters for post-bootstrap results:
+ void set_resolved_value(Handle value) {
+ assert(!is_resolved() && !is_method_call(), "");
+ _is_resolved = true;
+ _resolved_value = value;
+ }
+ void set_resolved_method(methodHandle method, Handle appendix) {
+ assert(!is_resolved() && is_method_call(), "");
+ _is_resolved = true;
+ _resolved_method = method;
+ _resolved_appendix = appendix;
+ }
+
+ void print() { print_msg_on(tty); }
+ void print_msg_on(outputStream* st, const char* msg = NULL);
+};
// Condensed information from constant pool to use to resolve the method or field.
// resolved_klass = specified class (i.e., static receiver class)
// current_klass = sending method holder (i.e., class containing the method
// containing the call being resolved)
@@ -205,12 +317,11 @@
bool checkpolymorphism,
bool in_imethod_resolve);
static Method* lookup_method_in_interfaces(const LinkInfo& link_info);
static methodHandle lookup_polymorphic_method(const LinkInfo& link_info,
- Handle *appendix_result_or_null,
- Handle *method_type_result, TRAPS);
+ Handle *appendix_result_or_null, TRAPS);
JVMCI_ONLY(public:) // Needed for CompilerToVM.resolveMethod()
// Not Linktime so doesn't take LinkInfo
static methodHandle lookup_instance_method_in_klasses (Klass* klass, Symbol* name, Symbol* signature,
Klass::PrivateLookupMode private_mode, TRAPS);
JVMCI_ONLY(private:)
@@ -313,13 +424,12 @@
static void resolve_interface_call(CallInfo& result, Handle recv, Klass* recv_klass,
const LinkInfo& link_info,
bool check_null_and_abstract, TRAPS);
static void resolve_handle_call (CallInfo& result,
const LinkInfo& link_info, TRAPS);
- static void resolve_dynamic_call (CallInfo& result, int pool_index, Handle bootstrap_specifier,
- Symbol* method_name, Symbol* method_signature,
- Klass* current_klass, TRAPS);
+ static void resolve_dynamic_call (CallInfo& result,
+ BootstrapInfo& bootstrap_specifier, TRAPS);
// same as above for compile-time resolution; but returns null handle instead of throwing
// an exception on error also, does not initialize klass (i.e., no side effects)
static methodHandle resolve_virtual_call_or_null (Klass* receiver_klass,
const LinkInfo& link_info);
< prev index next >