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:
Lois Foltan 2019-02-13 15:50:08 -05:00
parent 29245f8878
commit 9631b06423
19 changed files with 141 additions and 162 deletions

View File

@ -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.)

View File

@ -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.)

View File

@ -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.)

View File

@ -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.)

View File

@ -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());
)
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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

View File

@ -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());

View File

@ -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);
}

View File

@ -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,

View File

@ -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);
}
}
}

View File

@ -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;
}

View File

@ -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, "!!");

View File

@ -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);

View File

@ -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

View File

@ -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
}
}
}

View File

@ -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; }

View File

@ -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); }