mirror of
https://github.com/openjdk/jdk.git
synced 2026-07-19 23:48:50 +00:00
8217998: Remove method_type field associated with the appendix field of an indy or method handle call
Removed the unused method_type field associated with the appendix field of an indy or method handle call. Reviewed-by: acorn, coleenp, dlong
This commit is contained in:
parent
29245f8878
commit
9631b06423
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -3230,7 +3230,6 @@ void TemplateTable::prepare_invoke(int byte_no,
|
||||
// since the parameter_size includes it.
|
||||
__ push(r19);
|
||||
__ mov(r19, index);
|
||||
assert(ConstantPoolCacheEntry::_indy_resolved_references_appendix_offset == 0, "appendix expected at index+0");
|
||||
__ load_resolved_reference_at_index(index, r19);
|
||||
__ pop(r19);
|
||||
__ push(index); // push appendix (MethodType, CallSite, etc.)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2019, 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
|
||||
@ -3645,7 +3645,6 @@ void TemplateTable::prepare_invoke(int byte_no,
|
||||
Label L_no_push;
|
||||
__ tbz(flags, ConstantPoolCacheEntry::has_appendix_shift, L_no_push);
|
||||
__ mov(temp, index);
|
||||
assert(ConstantPoolCacheEntry::_indy_resolved_references_appendix_offset == 0, "appendix expected at index+0");
|
||||
__ load_resolved_reference_at_index(index, temp);
|
||||
__ verify_oop(index);
|
||||
__ push_ptr(index); // push appendix (MethodType, CallSite, etc.)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2019, 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
|
||||
@ -2992,7 +2992,6 @@ void TemplateTable::prepare_invoke(int byte_no,
|
||||
// Push the appendix as a trailing parameter.
|
||||
// This must be done before we get the receiver,
|
||||
// since the parameter_size includes it.
|
||||
assert(ConstantPoolCacheEntry::_indy_resolved_references_appendix_offset == 0, "appendix expected at index+0");
|
||||
__ load_resolved_reference_at_index(temp, index, /*tmp*/recv);
|
||||
__ verify_oop(temp);
|
||||
__ push_ptr(temp); // push appendix (MethodType, CallSite, etc.)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2019, 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
|
||||
@ -3643,7 +3643,6 @@ void TemplateTable::prepare_invoke(int byte_no,
|
||||
// since the parameter_size includes it.
|
||||
__ push(rbx);
|
||||
__ mov(rbx, index);
|
||||
assert(ConstantPoolCacheEntry::_indy_resolved_references_appendix_offset == 0, "appendix expected at index+0");
|
||||
__ load_resolved_reference_at_index(index, rbx);
|
||||
__ pop(rbx);
|
||||
__ push(index); // push appendix (MethodType, CallSite, etc.)
|
||||
|
||||
@ -334,15 +334,91 @@ ciMethod* ciBytecodeStream::get_method(bool& will_link, ciSignature* *declared_s
|
||||
ciMethod* m = env->get_method_by_index(cpool, get_method_index(), cur_bc(), _holder);
|
||||
will_link = m->is_loaded();
|
||||
|
||||
// Use the MethodType stored in the CP cache to create a signature
|
||||
// Use the signature stored in the CP cache to create a signature
|
||||
// with correct types (in respect to class loaders).
|
||||
if (has_method_type()) {
|
||||
ciSymbol* sig_sym = env->get_symbol(cpool->symbol_at(get_method_signature_index(cpool)));
|
||||
ciKlass* pool_holder = env->get_klass(cpool->pool_holder());
|
||||
ciMethodType* method_type = get_method_type();
|
||||
ciSignature* declared_signature = new (env->arena()) ciSignature(pool_holder, sig_sym, method_type);
|
||||
(*declared_signature_result) = declared_signature;
|
||||
//
|
||||
// In classic Java (before Java 7) there is never the slightest
|
||||
// difference between the signature at the call site and that of the
|
||||
// method. Such a difference would have been a type error in the
|
||||
// JVM.
|
||||
//
|
||||
// Now there are a few circumstances where the signature of a call
|
||||
// site (which controls the outgoing stacked arguments) can differ
|
||||
// from the signature of the method (which controls the receipt of
|
||||
// those arguments at the method entry point).
|
||||
//
|
||||
// A. The signatures can differ if the callee is a static method and
|
||||
// the caller thinks it is calling a non-static method (VH.get).
|
||||
// This requires the method signature to have an explicit leading
|
||||
// argument for the implicit 'this', not present at the call site.
|
||||
//
|
||||
// B. The call site can have less specific parameter types than the
|
||||
// method, allowing loosely-typed code to handle strongly-typed
|
||||
// methods. This happens with linkToStatic and related linker
|
||||
// commands. Obviously the loosely-typed code has to ensure that
|
||||
// the strongly typed method's invariants are respected, and this is
|
||||
// done by issuing dynamic casts.
|
||||
//
|
||||
// C. The call site can have more specific parameter types than the
|
||||
// method, allowing loosely-typed methods to handle strongly-typed
|
||||
// requests.
|
||||
//
|
||||
// D. There are corresponding effects with return values, such as
|
||||
// boolean method returning an int to an int-receiving call site,
|
||||
// even though the method thought it returned just a boolean.
|
||||
//
|
||||
// E. The calling sequence at a particular call site may add an
|
||||
// "appendix" argument not mentioned in the call site signature. It
|
||||
// is expected by the method signature, though, and this adds to the
|
||||
// method's arity, even after 'this' parameter effects (A) are
|
||||
// discounted. Appendixes are used by invokehandle and
|
||||
// invokedynamic instructions.
|
||||
//
|
||||
// F. A linker method (linkToStatic, etc.) can also take an extra
|
||||
// argument, a MemberName which routes the call to a concrete
|
||||
// strongly-typed method. In this case the linker method may also
|
||||
// differ in any of the ways A-D. The eventual method will ignore
|
||||
// the presence of the extra argument.
|
||||
//
|
||||
// None of these changes to calling sequences requires an argument
|
||||
// to be moved or reformatted in any way. This works because all
|
||||
// references look alike to the JVM, as do all primitives (except
|
||||
// float/long/double). Another required property of the JVM is
|
||||
// that, if a trailing argument is added or dropped, the placement
|
||||
// of other arguments does not change. This allows cases E and F to
|
||||
// work smoothly, against without any moving or reformatting,
|
||||
// despite the arity change.
|
||||
//
|
||||
if (has_local_signature()) {
|
||||
Symbol* local_signature = cpool->symbol_at(get_method_signature_index(cpool));
|
||||
ciSymbol* sig_sym = env->get_symbol(local_signature);
|
||||
ciKlass* pool_holder = env->get_klass(cpool->pool_holder());
|
||||
ciSignature* call_site_sig = new (env->arena()) ciSignature(pool_holder, cpool, sig_sym);
|
||||
// Examples of how the call site signature can differ from the method's own signature:
|
||||
//
|
||||
// meth = static jboolean java.lang.invoke.VarHandleGuards.guard_LII_Z(jobject, jobject, jint, jint, jobject)
|
||||
// msig = (Ljava/lang/invoke/VarHandle;Ljava/lang/Object;IILjava/lang/invoke/VarHandle$AccessDescriptor;)Z
|
||||
// call = (Ljava/util/concurrent/locks/AbstractQueuedSynchronizer;II)Z
|
||||
//
|
||||
// meth = static jobject java.lang.invoke.LambdaForm$MH/0x0000000800066840.linkToTargetMethod(jobject, jobject)
|
||||
// msig = (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
|
||||
// call = (Ljava/lang/String;)Ljava/util/function/Predicate;
|
||||
//
|
||||
(*declared_signature_result) = call_site_sig;
|
||||
|
||||
} else {
|
||||
// We can just use the method's own signature. It may differ from the call site, but not by much.
|
||||
//
|
||||
// Examples of how the call site signature can differ from the method's signature:
|
||||
//
|
||||
// meth = static final native jint java.lang.invoke.MethodHandle.linkToStatic(jobject, jobject, jint, jint, jobject)
|
||||
// msig = (Ljava/lang/Object;Ljava/lang/Object;IILjava/lang/invoke/MemberName;)I
|
||||
// call = (Ljava/lang/invoke/VarHandle;Ljava/lang/Object;IILjava/lang/invoke/MemberName;)Z
|
||||
//
|
||||
// meth = final native jint java.lang.invoke.MethodHandle.invokeBasic(jobject, jobject, jint, jint)
|
||||
// msig = (Ljava/lang/Object;Ljava/lang/Object;II)I
|
||||
// call = (Ljava/lang/invoke/VarHandle;Ljava/lang/Object;II)Z
|
||||
//
|
||||
(*declared_signature_result) = m->signature();
|
||||
}
|
||||
return m;
|
||||
@ -372,27 +448,14 @@ ciObject* ciBytecodeStream::get_appendix() {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// ciBytecodeStream::has_method_type
|
||||
// ciBytecodeStream::has_local_signature
|
||||
//
|
||||
// Returns true if there is a MethodType argument stored in the
|
||||
// constant pool cache at the current bci.
|
||||
bool ciBytecodeStream::has_method_type() {
|
||||
// Returns true if the method stored in the constant
|
||||
// pool cache at the current bci has a local signature.
|
||||
bool ciBytecodeStream::has_local_signature() {
|
||||
GUARDED_VM_ENTRY(
|
||||
constantPoolHandle cpool(_method->get_Method()->constants());
|
||||
return ConstantPool::has_method_type_at_if_loaded(cpool, get_method_index());
|
||||
)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// ciBytecodeStream::get_method_type
|
||||
//
|
||||
// Return the MethodType stored in the constant pool cache at
|
||||
// the current bci.
|
||||
ciMethodType* ciBytecodeStream::get_method_type() {
|
||||
GUARDED_VM_ENTRY(
|
||||
constantPoolHandle cpool(_method->get_Method()->constants());
|
||||
oop method_type_oop = ConstantPool::method_type_at_if_loaded(cpool, get_method_index());
|
||||
return CURRENT_ENV->get_object(method_type_oop)->as_method_type();
|
||||
return ConstantPool::has_local_signature_at_if_loaded(cpool, get_method_index());
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -245,8 +245,7 @@ public:
|
||||
ciMethod* get_method(bool& will_link, ciSignature* *declared_signature_result);
|
||||
bool has_appendix();
|
||||
ciObject* get_appendix();
|
||||
bool has_method_type();
|
||||
ciMethodType* get_method_type();
|
||||
bool has_local_signature();
|
||||
ciKlass* get_declared_method_holder();
|
||||
int get_method_holder_index();
|
||||
int get_method_signature_index(const constantPoolHandle& cpool);
|
||||
|
||||
@ -2459,7 +2459,6 @@ methodHandle SystemDictionary::find_method_handle_invoker(Klass* klass,
|
||||
Symbol* signature,
|
||||
Klass* accessing_klass,
|
||||
Handle *appendix_result,
|
||||
Handle *method_type_result,
|
||||
TRAPS) {
|
||||
methodHandle empty;
|
||||
assert(THREAD->can_call_java() ,"");
|
||||
@ -2492,7 +2491,6 @@ methodHandle SystemDictionary::find_method_handle_invoker(Klass* klass,
|
||||
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);
|
||||
}
|
||||
|
||||
@ -2811,7 +2809,6 @@ methodHandle SystemDictionary::find_dynamic_call_site_invoker(Klass* caller,
|
||||
Symbol* name,
|
||||
Symbol* type,
|
||||
Handle *appendix_result,
|
||||
Handle *method_type_result,
|
||||
TRAPS) {
|
||||
methodHandle empty;
|
||||
Handle bsm, info;
|
||||
@ -2853,7 +2850,6 @@ methodHandle SystemDictionary::find_dynamic_call_site_invoker(Klass* caller,
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@ -481,7 +481,6 @@ public:
|
||||
Symbol* signature,
|
||||
Klass* accessing_klass,
|
||||
Handle *appendix_result,
|
||||
Handle *method_type_result,
|
||||
TRAPS);
|
||||
// for a given signature, find the internal MethodHandle method (linkTo* or invokeBasic)
|
||||
// (does not ask Java, since this is a low-level intrinsic defined by the JVM)
|
||||
@ -544,7 +543,6 @@ public:
|
||||
Symbol* name,
|
||||
Symbol* type,
|
||||
Handle *appendix_result,
|
||||
Handle *method_type_result,
|
||||
TRAPS);
|
||||
|
||||
// Record the error when the first attempt to resolve a reference from a constant
|
||||
|
||||
@ -977,9 +977,6 @@ void InterpreterRuntime::resolve_invokedynamic(JavaThread* thread) {
|
||||
LastFrameAccessor last_frame(thread);
|
||||
const Bytecodes::Code bytecode = Bytecodes::_invokedynamic;
|
||||
|
||||
//TO DO: consider passing BCI to Java.
|
||||
// int caller_bci = last_frame.method()->bci_from(last_frame.bcp());
|
||||
|
||||
// resolve method
|
||||
CallInfo info;
|
||||
constantPoolHandle pool(thread, last_frame.method()->constants());
|
||||
|
||||
@ -94,26 +94,21 @@ void CallInfo::set_virtual(Klass* resolved_klass,
|
||||
}
|
||||
|
||||
void CallInfo::set_handle(const methodHandle& resolved_method,
|
||||
Handle resolved_appendix,
|
||||
Handle resolved_method_type, TRAPS) {
|
||||
set_handle(SystemDictionary::MethodHandle_klass(), resolved_method, resolved_appendix, resolved_method_type, CHECK);
|
||||
Handle resolved_appendix, TRAPS) {
|
||||
set_handle(SystemDictionary::MethodHandle_klass(), resolved_method, resolved_appendix, CHECK);
|
||||
}
|
||||
|
||||
void CallInfo::set_handle(Klass* resolved_klass,
|
||||
const methodHandle& resolved_method,
|
||||
Handle resolved_appendix,
|
||||
Handle resolved_method_type, TRAPS) {
|
||||
if (resolved_method.is_null()) {
|
||||
THROW_MSG(vmSymbols::java_lang_InternalError(), "resolved method is null");
|
||||
}
|
||||
Handle resolved_appendix, TRAPS) {
|
||||
guarantee(resolved_method.not_null(), "resolved method is null");
|
||||
assert(resolved_method->intrinsic_id() == vmIntrinsics::_invokeBasic ||
|
||||
resolved_method->is_compiled_lambda_form(),
|
||||
"linkMethod must return one of these");
|
||||
int vtable_index = Method::nonvirtual_vtable_index;
|
||||
assert(!resolved_method->has_vtable_index(), "");
|
||||
set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, CallInfo::direct_call, vtable_index, CHECK);
|
||||
_resolved_appendix = resolved_appendix;
|
||||
_resolved_method_type = resolved_method_type;
|
||||
_resolved_appendix = resolved_appendix;
|
||||
}
|
||||
|
||||
void CallInfo::set_common(Klass* resolved_klass,
|
||||
@ -452,7 +447,6 @@ Method* LinkResolver::lookup_method_in_interfaces(const LinkInfo& cp_info) {
|
||||
methodHandle LinkResolver::lookup_polymorphic_method(
|
||||
const LinkInfo& link_info,
|
||||
Handle *appendix_result_or_null,
|
||||
Handle *method_type_result,
|
||||
TRAPS) {
|
||||
Klass* klass = link_info.resolved_klass();
|
||||
Symbol* name = link_info.name();
|
||||
@ -520,7 +514,6 @@ methodHandle LinkResolver::lookup_polymorphic_method(
|
||||
full_signature,
|
||||
link_info.current_klass(),
|
||||
&appendix,
|
||||
&method_type,
|
||||
CHECK_NULL);
|
||||
if (TraceMethodHandles) {
|
||||
ttyLocker ttyl;
|
||||
@ -552,7 +545,6 @@ methodHandle LinkResolver::lookup_polymorphic_method(
|
||||
|
||||
assert(appendix_result_or_null != NULL, "");
|
||||
(*appendix_result_or_null) = appendix;
|
||||
(*method_type_result) = method_type;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -760,7 +752,7 @@ methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
|
||||
|
||||
if (resolved_method.is_null()) {
|
||||
// JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
|
||||
resolved_method = lookup_polymorphic_method(link_info, (Handle*)NULL, (Handle*)NULL, THREAD);
|
||||
resolved_method = lookup_polymorphic_method(link_info, (Handle*)NULL, THREAD);
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
nested_exception = Handle(THREAD, PENDING_EXCEPTION);
|
||||
CLEAR_PENDING_EXCEPTION;
|
||||
@ -1697,10 +1689,8 @@ void LinkResolver::resolve_handle_call(CallInfo& result,
|
||||
resolved_klass == SystemDictionary::VarHandle_klass(), "");
|
||||
assert(MethodHandles::is_signature_polymorphic_name(link_info.name()), "");
|
||||
Handle resolved_appendix;
|
||||
Handle resolved_method_type;
|
||||
methodHandle resolved_method = lookup_polymorphic_method(link_info,
|
||||
&resolved_appendix, &resolved_method_type, CHECK);
|
||||
result.set_handle(resolved_klass, resolved_method, resolved_appendix, resolved_method_type, CHECK);
|
||||
methodHandle resolved_method = lookup_polymorphic_method(link_info, &resolved_appendix, CHECK);
|
||||
result.set_handle(resolved_klass, resolved_method, resolved_appendix, CHECK);
|
||||
}
|
||||
|
||||
void LinkResolver::resolve_invokedynamic(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) {
|
||||
@ -1737,8 +1727,7 @@ void LinkResolver::resolve_invokedynamic(CallInfo& result, const constantPoolHan
|
||||
if (!cpce->is_f1_null()) {
|
||||
methodHandle method( THREAD, cpce->f1_as_method());
|
||||
Handle appendix( THREAD, cpce->appendix_if_resolved(pool));
|
||||
Handle method_type(THREAD, cpce->method_type_if_resolved(pool));
|
||||
result.set_handle(method, appendix, method_type, THREAD);
|
||||
result.set_handle(method, appendix, THREAD);
|
||||
Exceptions::wrap_dynamic_exception(CHECK);
|
||||
return;
|
||||
}
|
||||
@ -1766,8 +1755,7 @@ void LinkResolver::resolve_invokedynamic(CallInfo& result, const constantPoolHan
|
||||
if (!cpce->is_f1_null()) {
|
||||
methodHandle method( THREAD, cpce->f1_as_method());
|
||||
Handle appendix( THREAD, cpce->appendix_if_resolved(pool));
|
||||
Handle method_type(THREAD, cpce->method_type_if_resolved(pool));
|
||||
result.set_handle(method, appendix, method_type, THREAD);
|
||||
result.set_handle(method, appendix, THREAD);
|
||||
Exceptions::wrap_dynamic_exception(CHECK);
|
||||
} else {
|
||||
assert(cpce->indy_resolution_failed(), "Resolution failure flag not set");
|
||||
@ -1788,17 +1776,15 @@ void LinkResolver::resolve_dynamic_call(CallInfo& result,
|
||||
// JSR 292: this must resolve to an implicitly generated method MH.linkToCallSite(*...)
|
||||
// The appendix argument is likely to be a freshly-created CallSite.
|
||||
Handle resolved_appendix;
|
||||
Handle resolved_method_type;
|
||||
methodHandle resolved_method =
|
||||
SystemDictionary::find_dynamic_call_site_invoker(current_klass,
|
||||
pool_index,
|
||||
bootstrap_specifier,
|
||||
method_name, method_signature,
|
||||
&resolved_appendix,
|
||||
&resolved_method_type,
|
||||
THREAD);
|
||||
Exceptions::wrap_dynamic_exception(CHECK);
|
||||
result.set_handle(resolved_method, resolved_appendix, resolved_method_type, THREAD);
|
||||
result.set_handle(resolved_method, resolved_appendix, THREAD);
|
||||
Exceptions::wrap_dynamic_exception(CHECK);
|
||||
}
|
||||
|
||||
|
||||
@ -55,7 +55,6 @@ class CallInfo : public StackObj {
|
||||
// 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)
|
||||
Handle _resolved_method_name; // Object holding the ResolvedMethodName
|
||||
|
||||
void set_static(Klass* resolved_klass, const methodHandle& resolved_method, TRAPS);
|
||||
@ -68,10 +67,10 @@ class CallInfo : public StackObj {
|
||||
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, TRAPS);
|
||||
void set_handle(Klass* resolved_klass,
|
||||
const methodHandle& resolved_method,
|
||||
Handle resolved_appendix, Handle resolved_method_type, TRAPS);
|
||||
Handle resolved_appendix, TRAPS);
|
||||
void set_common(Klass* resolved_klass, Klass* selected_klass,
|
||||
const methodHandle& resolved_method,
|
||||
const methodHandle& selected_method,
|
||||
@ -98,7 +97,6 @@ class CallInfo : public StackObj {
|
||||
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; }
|
||||
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);
|
||||
@ -207,8 +205,7 @@ class LinkResolver: AllStatic {
|
||||
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,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2019, 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
|
||||
@ -221,13 +221,13 @@ void Rewriter::maybe_rewrite_invokehandle(address opc, int cp_index, int cache_i
|
||||
MethodHandles::is_signature_polymorphic_name(SystemDictionary::MethodHandle_klass(),
|
||||
_pool->name_ref_at(cp_index))) {
|
||||
// we may need a resolved_refs entry for the appendix
|
||||
add_invokedynamic_resolved_references_entries(cp_index, cache_index);
|
||||
add_invokedynamic_resolved_references_entry(cp_index, cache_index);
|
||||
status = +1;
|
||||
} else if (_pool->klass_ref_at_noresolve(cp_index) == vmSymbols::java_lang_invoke_VarHandle() &&
|
||||
MethodHandles::is_signature_polymorphic_name(SystemDictionary::VarHandle_klass(),
|
||||
_pool->name_ref_at(cp_index))) {
|
||||
// we may need a resolved_refs entry for the appendix
|
||||
add_invokedynamic_resolved_references_entries(cp_index, cache_index);
|
||||
add_invokedynamic_resolved_references_entry(cp_index, cache_index);
|
||||
status = +1;
|
||||
} else {
|
||||
status = -1;
|
||||
@ -259,7 +259,7 @@ void Rewriter::rewrite_invokedynamic(address bcp, int offset, bool reverse) {
|
||||
if (!reverse) {
|
||||
int cp_index = Bytes::get_Java_u2(p);
|
||||
int cache_index = add_invokedynamic_cp_cache_entry(cp_index);
|
||||
int resolved_index = add_invokedynamic_resolved_references_entries(cp_index, cache_index);
|
||||
int resolved_index = add_invokedynamic_resolved_references_entry(cp_index, cache_index);
|
||||
// Replace the trailing four bytes with a CPC index for the dynamic
|
||||
// call site. Unlike other CPC entries, there is one per bytecode,
|
||||
// not just one per distinct CP entry. In other words, the
|
||||
@ -307,12 +307,9 @@ void Rewriter::patch_invokedynamic_bytecodes() {
|
||||
// invokedynamic resolved references map also points to cp cache and must
|
||||
// add delta to each.
|
||||
int resolved_index = _patch_invokedynamic_refs->at(i);
|
||||
for (int entry = 0; entry < ConstantPoolCacheEntry::_indy_resolved_references_entries; entry++) {
|
||||
assert(_invokedynamic_references_map.at(resolved_index + entry) == cache_index,
|
||||
assert(_invokedynamic_references_map.at(resolved_index) == cache_index,
|
||||
"should be the same index");
|
||||
_invokedynamic_references_map.at_put(resolved_index+entry,
|
||||
cache_index + delta);
|
||||
}
|
||||
_invokedynamic_references_map.at_put(resolved_index, cache_index + delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,19 +159,12 @@ class Rewriter: public StackObj {
|
||||
return ref_index;
|
||||
}
|
||||
|
||||
// add a new entries to the resolved_references map (for invokedynamic and invokehandle only)
|
||||
int add_invokedynamic_resolved_references_entries(int cp_index, int cache_index) {
|
||||
// add a new entry to the resolved_references map (for invokedynamic and invokehandle only)
|
||||
int add_invokedynamic_resolved_references_entry(int cp_index, int cache_index) {
|
||||
assert(_resolved_reference_limit >= 0, "must add indy refs after first iteration");
|
||||
int ref_index = -1;
|
||||
for (int entry = 0; entry < ConstantPoolCacheEntry::_indy_resolved_references_entries; entry++) {
|
||||
const int index = _resolved_references_map.append(cp_index); // many-to-one
|
||||
assert(index >= _resolved_reference_limit, "");
|
||||
if (entry == 0) {
|
||||
ref_index = index;
|
||||
}
|
||||
assert((index - entry) == ref_index, "entries must be consecutive");
|
||||
_invokedynamic_references_map.at_put_grow(index, cache_index, -1);
|
||||
}
|
||||
int ref_index = _resolved_references_map.append(cp_index); // many-to-one
|
||||
assert(ref_index >= _resolved_reference_limit, "");
|
||||
_invokedynamic_references_map.at_put_grow(ref_index, cache_index, -1);
|
||||
return ref_index;
|
||||
}
|
||||
|
||||
|
||||
@ -1241,7 +1241,6 @@ C2V_VMENTRY(jint, isResolvedInvokeHandleInPool, (JNIEnv*, jobject, jobject jvmci
|
||||
vmassert(MethodHandles::is_signature_polymorphic_method(resolved_method()),"!");
|
||||
vmassert(!MethodHandles::is_signature_polymorphic_static(resolved_method->intrinsic_id()), "!");
|
||||
vmassert(cp_cache_entry->appendix_if_resolved(cp) == NULL, "!");
|
||||
vmassert(cp_cache_entry->method_type_if_resolved(cp) == NULL, "!");
|
||||
|
||||
methodHandle m(LinkResolver::linktime_resolve_virtual_method_or_null(link_info));
|
||||
vmassert(m == resolved_method, "!!");
|
||||
|
||||
@ -594,21 +594,13 @@ oop ConstantPool::appendix_at_if_loaded(const constantPoolHandle& cpool, int whi
|
||||
}
|
||||
|
||||
|
||||
bool ConstantPool::has_method_type_at_if_loaded(const constantPoolHandle& cpool, int which) {
|
||||
bool ConstantPool::has_local_signature_at_if_loaded(const constantPoolHandle& cpool, int which) {
|
||||
if (cpool->cache() == NULL) return false; // nothing to load yet
|
||||
int cache_index = decode_cpcache_index(which, true);
|
||||
ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index);
|
||||
return e->has_method_type();
|
||||
return e->has_local_signature();
|
||||
}
|
||||
|
||||
oop ConstantPool::method_type_at_if_loaded(const constantPoolHandle& cpool, int which) {
|
||||
if (cpool->cache() == NULL) return NULL; // nothing to load yet
|
||||
int cache_index = decode_cpcache_index(which, true);
|
||||
ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index);
|
||||
return e->method_type_if_resolved(cpool);
|
||||
}
|
||||
|
||||
|
||||
Symbol* ConstantPool::impl_name_ref_at(int which, bool uncached) {
|
||||
int name_index = name_ref_index_at(impl_name_and_type_ref_index_at(which, uncached));
|
||||
return symbol_at(name_index);
|
||||
|
||||
@ -797,8 +797,7 @@ class ConstantPool : public Metadata {
|
||||
static Method* method_at_if_loaded (const constantPoolHandle& this_cp, int which);
|
||||
static bool has_appendix_at_if_loaded (const constantPoolHandle& this_cp, int which);
|
||||
static oop appendix_at_if_loaded (const constantPoolHandle& this_cp, int which);
|
||||
static bool has_method_type_at_if_loaded (const constantPoolHandle& this_cp, int which);
|
||||
static oop method_type_at_if_loaded (const constantPoolHandle& this_cp, int which);
|
||||
static bool has_local_signature_at_if_loaded (const constantPoolHandle& this_cp, int which);
|
||||
static Klass* klass_at_if_loaded (const constantPoolHandle& this_cp, int which);
|
||||
|
||||
// Routines currently used for annotations (only called by jvm.cpp) but which might be used in the
|
||||
|
||||
@ -392,23 +392,22 @@ void ConstantPoolCacheEntry::set_method_handle_common(const constantPoolHandle&
|
||||
|
||||
const methodHandle adapter = call_info.resolved_method();
|
||||
const Handle appendix = call_info.resolved_appendix();
|
||||
const Handle method_type = call_info.resolved_method_type();
|
||||
const bool has_appendix = appendix.not_null();
|
||||
const bool has_method_type = method_type.not_null();
|
||||
|
||||
// Write the flags.
|
||||
// MHs and indy are always sig-poly and have a local signature.
|
||||
set_method_flags(as_TosState(adapter->result_type()),
|
||||
((has_appendix ? 1 : 0) << has_appendix_shift ) |
|
||||
((has_method_type ? 1 : 0) << has_method_type_shift) |
|
||||
( 1 << is_final_shift ),
|
||||
((has_appendix ? 1 : 0) << has_appendix_shift ) |
|
||||
( 1 << has_local_signature_shift ) |
|
||||
( 1 << is_final_shift ),
|
||||
adapter->size_of_parameters());
|
||||
|
||||
if (TraceInvokeDynamic) {
|
||||
ttyLocker ttyl;
|
||||
tty->print_cr("set_method_handle bc=%d appendix=" PTR_FORMAT "%s method_type=" PTR_FORMAT "%s method=" PTR_FORMAT " ",
|
||||
tty->print_cr("set_method_handle bc=%d appendix=" PTR_FORMAT "%s method=" PTR_FORMAT " (local signature) ",
|
||||
invoke_code,
|
||||
p2i(appendix()), (has_appendix ? "" : " (unused)"),
|
||||
p2i(method_type()), (has_method_type ? "" : " (unused)"),
|
||||
p2i(appendix()),
|
||||
(has_appendix ? "" : " (unused)"),
|
||||
p2i(adapter()));
|
||||
adapter->print();
|
||||
if (has_appendix) appendix()->print();
|
||||
@ -435,20 +434,12 @@ void ConstantPoolCacheEntry::set_method_handle_common(const constantPoolHandle&
|
||||
|
||||
// Store appendix, if any.
|
||||
if (has_appendix) {
|
||||
const int appendix_index = f2_as_index() + _indy_resolved_references_appendix_offset;
|
||||
const int appendix_index = f2_as_index();
|
||||
assert(appendix_index >= 0 && appendix_index < resolved_references->length(), "oob");
|
||||
assert(resolved_references->obj_at(appendix_index) == NULL, "init just once");
|
||||
resolved_references->obj_at_put(appendix_index, appendix());
|
||||
}
|
||||
|
||||
// Store MethodType, if any.
|
||||
if (has_method_type) {
|
||||
const int method_type_index = f2_as_index() + _indy_resolved_references_method_type_offset;
|
||||
assert(method_type_index >= 0 && method_type_index < resolved_references->length(), "oob");
|
||||
assert(resolved_references->obj_at(method_type_index) == NULL, "init just once");
|
||||
resolved_references->obj_at_put(method_type_index, method_type());
|
||||
}
|
||||
|
||||
release_set_f1(adapter()); // This must be the last one to set (see NOTE above)!
|
||||
|
||||
// The interpreter assembly code does not check byte_2,
|
||||
@ -459,6 +450,9 @@ void ConstantPoolCacheEntry::set_method_handle_common(const constantPoolHandle&
|
||||
ttyLocker ttyl;
|
||||
this->print(tty, 0);
|
||||
}
|
||||
|
||||
assert(has_appendix == this->has_appendix(), "proper storage of appendix flag");
|
||||
assert(this->has_local_signature(), "proper storage of signature flag");
|
||||
}
|
||||
|
||||
bool ConstantPoolCacheEntry::save_and_throw_indy_exc(
|
||||
@ -544,16 +538,7 @@ Method* ConstantPoolCacheEntry::method_if_resolved(const constantPoolHandle& cpo
|
||||
oop ConstantPoolCacheEntry::appendix_if_resolved(const constantPoolHandle& cpool) {
|
||||
if (!has_appendix())
|
||||
return NULL;
|
||||
const int ref_index = f2_as_index() + _indy_resolved_references_appendix_offset;
|
||||
objArrayOop resolved_references = cpool->resolved_references();
|
||||
return resolved_references->obj_at(ref_index);
|
||||
}
|
||||
|
||||
|
||||
oop ConstantPoolCacheEntry::method_type_if_resolved(const constantPoolHandle& cpool) {
|
||||
if (!has_method_type())
|
||||
return NULL;
|
||||
const int ref_index = f2_as_index() + _indy_resolved_references_method_type_offset;
|
||||
const int ref_index = f2_as_index();
|
||||
objArrayOop resolved_references = cpool->resolved_references();
|
||||
return resolved_references->obj_at(ref_index);
|
||||
}
|
||||
@ -701,16 +686,7 @@ void ConstantPoolCache::initialize(const intArray& inverse_index_map,
|
||||
for (int ref = 0; ref < invokedynamic_references_map.length(); ref++) {
|
||||
const int cpci = invokedynamic_references_map.at(ref);
|
||||
if (cpci >= 0) {
|
||||
#ifdef ASSERT
|
||||
// invokedynamic and invokehandle have more entries; check if they
|
||||
// all point to the same constant pool cache entry.
|
||||
for (int entry = 1; entry < ConstantPoolCacheEntry::_indy_resolved_references_entries; entry++) {
|
||||
const int cpci_next = invokedynamic_references_map.at(ref + entry);
|
||||
assert(cpci == cpci_next, "%d == %d", cpci, cpci_next);
|
||||
}
|
||||
#endif
|
||||
entry_at(cpci)->initialize_resolved_reference_index(ref);
|
||||
ref += ConstantPoolCacheEntry::_indy_resolved_references_entries - 1; // skip extra entries
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ class PSPromotionManager;
|
||||
// _f2 [ entry specific ] vtable or res_ref index, or vfinal method ptr
|
||||
// _flags [tos|0|F=1|0|0|0|f|v|0 |0000|field_index] (for field entries)
|
||||
// bit length [ 4 |1| 1 |1|1|1|1|1|1 |1 |-3-|----16-----]
|
||||
// _flags [tos|0|F=0|M|A|I|f|0|vf|indy_rf|000|00000|psize] (for method entries)
|
||||
// _flags [tos|0|F=0|S|A|I|f|0|vf|indy_rf|000|00000|psize] (for method entries)
|
||||
// bit length [ 4 |1| 1 |1|1|1|1|1|1 |-4--|--8--|--8--]
|
||||
|
||||
// --------------------------------
|
||||
@ -114,7 +114,7 @@ class PSPromotionManager;
|
||||
// _f2 = vtable/itable index (or final Method*) for virtual calls only,
|
||||
// unused by non-virtual. The is_vfinal flag indicates this is a
|
||||
// method pointer for a final method, not an index.
|
||||
// _flags = method type info (t section),
|
||||
// _flags = has local signature (MHs and indy),
|
||||
// virtual final bit (vfinal),
|
||||
// parameter size (psize section)
|
||||
//
|
||||
@ -180,7 +180,7 @@ class ConstantPoolCacheEntry {
|
||||
tos_state_shift = BitsPerInt - tos_state_bits, // see verify_tos_state_shift below
|
||||
// misc. option bits; can be any bit position in [16..27]
|
||||
is_field_entry_shift = 26, // (F) is it a field or a method?
|
||||
has_method_type_shift = 25, // (M) does the call site have a MethodType?
|
||||
has_local_signature_shift = 25, // (S) does the call site have a per-site signature (sig-poly methods)?
|
||||
has_appendix_shift = 24, // (A) does the call site have an appendix argument?
|
||||
is_forced_virtual_shift = 23, // (I) is the interface reference forced to virtual mode?
|
||||
is_final_shift = 22, // (f) is the field or method final?
|
||||
@ -291,19 +291,10 @@ class ConstantPoolCacheEntry {
|
||||
bool save_and_throw_indy_exc(const constantPoolHandle& cpool, int cpool_index,
|
||||
int index, constantTag tag, TRAPS);
|
||||
|
||||
// invokedynamic and invokehandle call sites have two entries in the
|
||||
// resolved references array:
|
||||
// appendix (at index+0)
|
||||
// MethodType (at index+1)
|
||||
enum {
|
||||
_indy_resolved_references_appendix_offset = 0,
|
||||
_indy_resolved_references_method_type_offset = 1,
|
||||
_indy_resolved_references_entries
|
||||
};
|
||||
|
||||
// invokedynamic and invokehandle call sites have an "appendix" item in the
|
||||
// resolved references array.
|
||||
Method* method_if_resolved(const constantPoolHandle& cpool);
|
||||
oop appendix_if_resolved(const constantPoolHandle& cpool);
|
||||
oop method_type_if_resolved(const constantPoolHandle& cpool);
|
||||
|
||||
void set_parameter_size(int value);
|
||||
|
||||
@ -356,7 +347,7 @@ class ConstantPoolCacheEntry {
|
||||
bool is_vfinal() const { return (_flags & (1 << is_vfinal_shift)) != 0; }
|
||||
bool indy_resolution_failed() const;
|
||||
bool has_appendix() const;
|
||||
bool has_method_type() const;
|
||||
bool has_local_signature() const;
|
||||
bool is_method_entry() const { return (_flags & (1 << is_field_entry_shift)) == 0; }
|
||||
bool is_field_entry() const { return (_flags & (1 << is_field_entry_shift)) != 0; }
|
||||
bool is_long() const { return flag_state() == ltos; }
|
||||
|
||||
@ -71,8 +71,8 @@ inline bool ConstantPoolCacheEntry::has_appendix() const {
|
||||
return (!is_f1_null()) && (_flags & (1 << has_appendix_shift)) != 0;
|
||||
}
|
||||
|
||||
inline bool ConstantPoolCacheEntry::has_method_type() const {
|
||||
return (!is_f1_null()) && (_flags & (1 << has_method_type_shift)) != 0;
|
||||
inline bool ConstantPoolCacheEntry::has_local_signature() const {
|
||||
return (!is_f1_null()) && (_flags & (1 << has_local_signature_shift)) != 0;
|
||||
}
|
||||
|
||||
inline intx ConstantPoolCacheEntry::flags_ord() const { return (intx)OrderAccess::load_acquire(&_flags); }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user