Merge
This commit is contained in:
commit
023bafb08f
@ -709,24 +709,23 @@ Method* ciEnv::lookup_method(InstanceKlass* accessor,
|
||||
KlassHandle h_holder(THREAD, holder);
|
||||
LinkResolver::check_klass_accessability(h_accessor, h_holder, KILL_COMPILE_ON_FATAL_(NULL));
|
||||
methodHandle dest_method;
|
||||
LinkInfo link_info(h_holder, name, sig, h_accessor, /*check_access*/true);
|
||||
switch (bc) {
|
||||
case Bytecodes::_invokestatic:
|
||||
dest_method =
|
||||
LinkResolver::resolve_static_call_or_null(h_holder, name, sig, h_accessor);
|
||||
LinkResolver::resolve_static_call_or_null(link_info);
|
||||
break;
|
||||
case Bytecodes::_invokespecial:
|
||||
dest_method =
|
||||
LinkResolver::resolve_special_call_or_null(h_holder, name, sig, h_accessor);
|
||||
LinkResolver::resolve_special_call_or_null(link_info);
|
||||
break;
|
||||
case Bytecodes::_invokeinterface:
|
||||
dest_method =
|
||||
LinkResolver::linktime_resolve_interface_method_or_null(h_holder, name, sig,
|
||||
h_accessor, true);
|
||||
LinkResolver::linktime_resolve_interface_method_or_null(link_info);
|
||||
break;
|
||||
case Bytecodes::_invokevirtual:
|
||||
dest_method =
|
||||
LinkResolver::linktime_resolve_virtual_method_or_null(h_holder, name, sig,
|
||||
h_accessor, true);
|
||||
LinkResolver::linktime_resolve_virtual_method_or_null(link_info);
|
||||
break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
|
@ -352,11 +352,11 @@ bool ciField::will_link(ciInstanceKlass* accessing_klass,
|
||||
}
|
||||
}
|
||||
|
||||
LinkInfo link_info(_holder->get_instanceKlass(),
|
||||
_name->get_symbol(), _signature->get_symbol(),
|
||||
accessing_klass->get_Klass());
|
||||
fieldDescriptor result;
|
||||
LinkResolver::resolve_field(result, _holder->get_instanceKlass(),
|
||||
_name->get_symbol(), _signature->get_symbol(),
|
||||
accessing_klass->get_Klass(), bc, true, false,
|
||||
KILL_COMPILE_ON_FATAL_(false));
|
||||
LinkResolver::resolve_field(result, link_info, bc, false, KILL_COMPILE_ON_FATAL_(false));
|
||||
|
||||
// update the hit-cache, unless there is a problem with memory scoping:
|
||||
if (accessing_klass->is_shared() || !is_shared()) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2015, 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
|
||||
@ -786,6 +786,7 @@ ciMethod* ciMethod::resolve_invoke(ciKlass* caller, ciKlass* exact_receiver, boo
|
||||
Symbol* h_name = name()->get_symbol();
|
||||
Symbol* h_signature = signature()->get_symbol();
|
||||
|
||||
LinkInfo link_info(h_resolved, h_name, h_signature, caller_klass, check_access);
|
||||
methodHandle m;
|
||||
// Only do exact lookup if receiver klass has been linked. Otherwise,
|
||||
// the vtable has not been setup, and the LinkResolver will fail.
|
||||
@ -793,9 +794,9 @@ ciMethod* ciMethod::resolve_invoke(ciKlass* caller, ciKlass* exact_receiver, boo
|
||||
||
|
||||
InstanceKlass::cast(h_recv())->is_linked() && !exact_receiver->is_interface()) {
|
||||
if (holder()->is_interface()) {
|
||||
m = LinkResolver::resolve_interface_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass, check_access);
|
||||
m = LinkResolver::resolve_interface_call_or_null(h_recv, link_info);
|
||||
} else {
|
||||
m = LinkResolver::resolve_virtual_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass, check_access);
|
||||
m = LinkResolver::resolve_virtual_call_or_null(h_recv, link_info);
|
||||
}
|
||||
}
|
||||
|
||||
@ -839,7 +840,8 @@ int ciMethod::resolve_vtable_index(ciKlass* caller, ciKlass* receiver) {
|
||||
Symbol* h_name = name()->get_symbol();
|
||||
Symbol* h_signature = signature()->get_symbol();
|
||||
|
||||
vtable_index = LinkResolver::resolve_virtual_vtable_index(h_recv, h_recv, h_name, h_signature, caller_klass);
|
||||
LinkInfo link_info(h_recv, h_name, h_signature, caller_klass);
|
||||
vtable_index = LinkResolver::resolve_virtual_vtable_index(h_recv, link_info);
|
||||
if (vtable_index == Method::nonvirtual_vtable_index) {
|
||||
// A statically bound method. Return "no such index".
|
||||
vtable_index = Method::invalid_vtable_index;
|
||||
@ -1285,10 +1287,8 @@ bool ciMethod::check_call(int refinfo_index, bool is_static) const {
|
||||
EXCEPTION_MARK;
|
||||
HandleMark hm(THREAD);
|
||||
constantPoolHandle pool (THREAD, get_Method()->constants());
|
||||
methodHandle spec_method;
|
||||
KlassHandle spec_klass;
|
||||
Bytecodes::Code code = (is_static ? Bytecodes::_invokestatic : Bytecodes::_invokevirtual);
|
||||
LinkResolver::resolve_method_statically(spec_method, spec_klass, code, pool, refinfo_index, THREAD);
|
||||
methodHandle spec_method = LinkResolver::resolve_method_statically(code, pool, refinfo_index, THREAD);
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
CLEAR_PENDING_EXCEPTION;
|
||||
return false;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2015, 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
|
||||
@ -147,13 +147,10 @@ BasicType Bytecode_member_ref::result_type() const {
|
||||
|
||||
|
||||
methodHandle Bytecode_invoke::static_target(TRAPS) {
|
||||
methodHandle m;
|
||||
KlassHandle resolved_klass;
|
||||
constantPoolHandle constants(THREAD, this->constants());
|
||||
|
||||
Bytecodes::Code bc = invoke_code();
|
||||
LinkResolver::resolve_method_statically(m, resolved_klass, bc, constants, index(), CHECK_(methodHandle()));
|
||||
return m;
|
||||
return LinkResolver::resolve_method_statically(bc, constants, index(), THREAD);
|
||||
}
|
||||
|
||||
Handle Bytecode_invoke::appendix(TRAPS) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2015, 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
|
||||
@ -36,7 +36,7 @@
|
||||
// that method. If the info is invalid, the link has not been resolved
|
||||
// successfully.
|
||||
|
||||
class CallInfo VALUE_OBJ_CLASS_SPEC {
|
||||
class CallInfo : public StackObj {
|
||||
public:
|
||||
// Ways that a method call might be selected (or not) based on receiver type.
|
||||
// Note that an invokevirtual instruction might be linked with no_dispatch,
|
||||
@ -58,11 +58,22 @@ class CallInfo VALUE_OBJ_CLASS_SPEC {
|
||||
Handle _resolved_appendix; // extra argument in constant pool (if CPCE::has_appendix)
|
||||
Handle _resolved_method_type; // MethodType (for invokedynamic and invokehandle call sites)
|
||||
|
||||
void set_static( KlassHandle resolved_klass, methodHandle resolved_method , TRAPS);
|
||||
void set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int itable_index , TRAPS);
|
||||
void set_virtual( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index , TRAPS);
|
||||
void set_handle( methodHandle resolved_method, Handle resolved_appendix, Handle resolved_method_type, TRAPS);
|
||||
void set_common( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, CallKind kind, int index, TRAPS);
|
||||
void set_static(KlassHandle resolved_klass, const methodHandle& resolved_method, TRAPS);
|
||||
void set_interface(KlassHandle resolved_klass, KlassHandle selected_klass,
|
||||
const methodHandle& resolved_method,
|
||||
const methodHandle& selected_method,
|
||||
int itable_index, TRAPS);
|
||||
void set_virtual(KlassHandle resolved_klass, KlassHandle 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);
|
||||
void set_common(KlassHandle resolved_klass, KlassHandle selected_klass,
|
||||
const methodHandle& resolved_method,
|
||||
const methodHandle& selected_method,
|
||||
CallKind kind,
|
||||
int index, TRAPS);
|
||||
|
||||
friend class LinkResolver;
|
||||
|
||||
@ -113,6 +124,37 @@ class CallInfo VALUE_OBJ_CLASS_SPEC {
|
||||
void print() PRODUCT_RETURN;
|
||||
};
|
||||
|
||||
|
||||
// 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)
|
||||
class LinkInfo : public StackObj {
|
||||
Symbol* _name; // extracted from JVM_CONSTANT_NameAndType
|
||||
Symbol* _signature;
|
||||
KlassHandle _resolved_klass; // class that the constant pool entry points to
|
||||
KlassHandle _current_klass; // class that owns the constant pool
|
||||
bool _check_access;
|
||||
public:
|
||||
LinkInfo(constantPoolHandle pool, int index, TRAPS);
|
||||
// Condensed information from other call sites within the vm.
|
||||
LinkInfo(KlassHandle resolved_klass, Symbol* name, Symbol* signature,
|
||||
KlassHandle current_klass, bool check_access = true) :
|
||||
_resolved_klass(resolved_klass),
|
||||
_name(name), _signature(signature), _current_klass(current_klass),
|
||||
_check_access(check_access) {}
|
||||
|
||||
// accessors
|
||||
Symbol* name() const { return _name; }
|
||||
Symbol* signature() const { return _signature; }
|
||||
KlassHandle resolved_klass() const { return _resolved_klass; }
|
||||
KlassHandle current_klass() const { return _current_klass; }
|
||||
bool check_access() const { return _check_access; }
|
||||
char* method_string() const;
|
||||
|
||||
void print() PRODUCT_RETURN;
|
||||
};
|
||||
|
||||
// Link information for getfield/putfield & getstatic/putstatic bytecodes
|
||||
// is represented using a fieldDescriptor.
|
||||
|
||||
@ -124,85 +166,136 @@ class LinkResolver: AllStatic {
|
||||
friend class klassItable;
|
||||
|
||||
private:
|
||||
static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, bool in_imethod_resolve, TRAPS);
|
||||
static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
|
||||
static void lookup_method_in_interfaces (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
|
||||
static void lookup_polymorphic_method (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature,
|
||||
KlassHandle current_klass, Handle *appendix_result_or_null, Handle *method_type_result, TRAPS);
|
||||
|
||||
static void resolve_klass (KlassHandle& result, constantPoolHandle pool, int index, TRAPS);
|
||||
static methodHandle lookup_method_in_klasses(const LinkInfo& link_info,
|
||||
bool checkpolymorphism,
|
||||
bool in_imethod_resolve, TRAPS);
|
||||
static methodHandle lookup_method_in_interfaces(const LinkInfo& link_info, TRAPS);
|
||||
static methodHandle lookup_polymorphic_method(const LinkInfo& link_info,
|
||||
Handle *appendix_result_or_null,
|
||||
Handle *method_type_result, TRAPS);
|
||||
// Not Linktime so doesn't take LinkInfo
|
||||
static methodHandle lookup_instance_method_in_klasses (
|
||||
KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
|
||||
|
||||
static void resolve_pool (KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS);
|
||||
// Similar loader constraint checking functions that throw
|
||||
// LinkageError with descriptive message.
|
||||
static void check_method_loader_constraints(const LinkInfo& link_info,
|
||||
const methodHandle& resolved_method,
|
||||
const char* method_type, TRAPS);
|
||||
static void check_field_loader_constraints(Symbol* field, Symbol* sig,
|
||||
KlassHandle current_klass,
|
||||
KlassHandle sel_klass, TRAPS);
|
||||
|
||||
static void resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool nostatics, TRAPS);
|
||||
static void resolve_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool require_methodref, TRAPS);
|
||||
static methodHandle resolve_interface_method(const LinkInfo& link_info, bool nostatics, TRAPS);
|
||||
static methodHandle resolve_method (const LinkInfo& link_info, bool require_methodref, TRAPS);
|
||||
|
||||
static void linktime_resolve_static_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
|
||||
static void linktime_resolve_special_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
|
||||
static void linktime_resolve_virtual_method (methodHandle &resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature,KlassHandle current_klass, bool check_access, TRAPS);
|
||||
static void linktime_resolve_interface_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
|
||||
static methodHandle linktime_resolve_static_method (const LinkInfo& link_info, TRAPS);
|
||||
static methodHandle linktime_resolve_special_method (const LinkInfo& link_info, TRAPS);
|
||||
static methodHandle linktime_resolve_virtual_method (const LinkInfo& link_info, TRAPS);
|
||||
static methodHandle linktime_resolve_interface_method (const LinkInfo& link_info, TRAPS);
|
||||
|
||||
static void runtime_resolve_special_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, KlassHandle current_klass, bool check_access, TRAPS);
|
||||
static void runtime_resolve_virtual_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS);
|
||||
static void runtime_resolve_interface_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS);
|
||||
static void runtime_resolve_special_method (CallInfo& result,
|
||||
const methodHandle& resolved_method,
|
||||
KlassHandle resolved_klass,
|
||||
KlassHandle current_klass,
|
||||
bool check_access, TRAPS);
|
||||
static void runtime_resolve_virtual_method (CallInfo& result,
|
||||
const methodHandle& resolved_method,
|
||||
KlassHandle resolved_klass,
|
||||
Handle recv,
|
||||
KlassHandle recv_klass,
|
||||
bool check_null_and_abstract, TRAPS);
|
||||
static void runtime_resolve_interface_method (CallInfo& result,
|
||||
const methodHandle& resolved_method,
|
||||
KlassHandle resolved_klass,
|
||||
Handle recv,
|
||||
KlassHandle recv_klass,
|
||||
bool check_null_and_abstract, TRAPS);
|
||||
|
||||
static void check_field_accessability (KlassHandle ref_klass, KlassHandle resolved_klass, KlassHandle sel_klass, fieldDescriptor& fd, TRAPS);
|
||||
static void check_method_accessability (KlassHandle ref_klass, KlassHandle resolved_klass, KlassHandle sel_klass, methodHandle sel_method, TRAPS);
|
||||
static void check_field_accessability(KlassHandle ref_klass,
|
||||
KlassHandle resolved_klass,
|
||||
KlassHandle sel_klass,
|
||||
const fieldDescriptor& fd, TRAPS);
|
||||
static void check_method_accessability(KlassHandle ref_klass,
|
||||
KlassHandle resolved_klass,
|
||||
KlassHandle sel_klass,
|
||||
const methodHandle& sel_method, TRAPS);
|
||||
|
||||
// runtime resolving from constant pool
|
||||
static void resolve_invokestatic (CallInfo& result,
|
||||
constantPoolHandle pool, int index, TRAPS);
|
||||
static void resolve_invokespecial (CallInfo& result,
|
||||
constantPoolHandle pool, int index, TRAPS);
|
||||
static void resolve_invokevirtual (CallInfo& result, Handle recv,
|
||||
constantPoolHandle pool, int index, TRAPS);
|
||||
static void resolve_invokeinterface(CallInfo& result, Handle recv,
|
||||
constantPoolHandle pool, int index, TRAPS);
|
||||
static void resolve_invokedynamic (CallInfo& result,
|
||||
constantPoolHandle pool, int index, TRAPS);
|
||||
static void resolve_invokehandle (CallInfo& result,
|
||||
constantPoolHandle pool, int index, TRAPS);
|
||||
public:
|
||||
// constant pool resolving
|
||||
static void check_klass_accessability(KlassHandle ref_klass, KlassHandle sel_klass, TRAPS);
|
||||
|
||||
// static resolving calls (will not run any Java code); used only from Bytecode_invoke::static_target
|
||||
static void resolve_method_statically(methodHandle& method_result, KlassHandle& klass_result,
|
||||
Bytecodes::Code code, constantPoolHandle pool, int index, TRAPS);
|
||||
// static resolving calls (will not run any Java code);
|
||||
// used only from Bytecode_invoke::static_target
|
||||
static methodHandle resolve_method_statically(Bytecodes::Code code,
|
||||
constantPoolHandle pool,
|
||||
int index, TRAPS);
|
||||
|
||||
// runtime/static resolving for fields
|
||||
static void resolve_field_access(fieldDescriptor& result, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS);
|
||||
static void resolve_field(fieldDescriptor& result, KlassHandle resolved_klass, Symbol* field_name, Symbol* field_signature,
|
||||
KlassHandle current_klass, Bytecodes::Code access_kind, bool check_access, bool initialize_class, TRAPS);
|
||||
static void resolve_field_access(fieldDescriptor& result,
|
||||
constantPoolHandle pool,
|
||||
int index, Bytecodes::Code byte, TRAPS);
|
||||
static void resolve_field(fieldDescriptor& result, const LinkInfo& link_info,
|
||||
Bytecodes::Code access_kind,
|
||||
bool initialize_class, TRAPS);
|
||||
|
||||
// source of access_kind codes:
|
||||
static Bytecodes::Code field_access_kind(bool is_static, bool is_put) {
|
||||
return (is_static
|
||||
? (is_put ? Bytecodes::_putstatic : Bytecodes::_getstatic)
|
||||
: (is_put ? Bytecodes::_putfield : Bytecodes::_getfield ));
|
||||
}
|
||||
static void resolve_static_call (CallInfo& result,
|
||||
const LinkInfo& link_info,
|
||||
bool initialize_klass, TRAPS);
|
||||
static void resolve_special_call (CallInfo& result,
|
||||
const LinkInfo& link_info,
|
||||
TRAPS);
|
||||
static void resolve_virtual_call (CallInfo& result, Handle recv, KlassHandle recv_klass,
|
||||
const LinkInfo& link_info,
|
||||
bool check_null_and_abstract, TRAPS);
|
||||
static void resolve_interface_call(CallInfo& result, Handle recv, KlassHandle 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, Handle bootstrap_specifier,
|
||||
Symbol* method_name, Symbol* method_signature,
|
||||
KlassHandle current_klass, TRAPS);
|
||||
|
||||
// runtime resolving:
|
||||
// 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)
|
||||
static void resolve_static_call (CallInfo& result, KlassHandle& resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool initialize_klass, TRAPS);
|
||||
static void resolve_special_call (CallInfo& result, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
|
||||
static void resolve_virtual_call (CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool check_null_and_abstract, TRAPS);
|
||||
static void resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool check_null_and_abstract, TRAPS);
|
||||
static void resolve_handle_call (CallInfo& result, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, TRAPS);
|
||||
static void resolve_dynamic_call (CallInfo& result, Handle bootstrap_specifier, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, 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 (KlassHandle receiver_klass,
|
||||
const LinkInfo& link_info);
|
||||
static methodHandle resolve_interface_call_or_null(KlassHandle receiver_klass,
|
||||
const LinkInfo& link_info);
|
||||
static methodHandle resolve_static_call_or_null (const LinkInfo& link_info);
|
||||
static methodHandle resolve_special_call_or_null (const LinkInfo& link_info);
|
||||
|
||||
// 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 (KlassHandle receiver_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access = true);
|
||||
static methodHandle resolve_interface_call_or_null(KlassHandle receiver_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access = true);
|
||||
static methodHandle resolve_static_call_or_null (KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access = true);
|
||||
static methodHandle resolve_special_call_or_null (KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access = true);
|
||||
static int vtable_index_of_interface_method(KlassHandle klass, methodHandle resolved_method);
|
||||
static int vtable_index_of_interface_method(KlassHandle klass, const methodHandle& resolved_method);
|
||||
|
||||
// same as above for compile-time resolution; returns vtable_index if current_klass if linked
|
||||
static int resolve_virtual_vtable_index (KlassHandle receiver_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass);
|
||||
static int resolve_virtual_vtable_index (KlassHandle receiver_klass,
|
||||
const LinkInfo& link_info);
|
||||
|
||||
// static resolving for compiler (does not throw exceptions, returns null handle if unsuccessful)
|
||||
static methodHandle linktime_resolve_virtual_method_or_null (KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access);
|
||||
static methodHandle linktime_resolve_interface_method_or_null(KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access);
|
||||
static methodHandle linktime_resolve_virtual_method_or_null (const LinkInfo& link_info);
|
||||
static methodHandle linktime_resolve_interface_method_or_null(const LinkInfo& link_info);
|
||||
|
||||
// runtime resolving from constant pool
|
||||
static void resolve_invokestatic (CallInfo& result, constantPoolHandle pool, int index, TRAPS);
|
||||
static void resolve_invokespecial (CallInfo& result, constantPoolHandle pool, int index, TRAPS);
|
||||
static void resolve_invokevirtual (CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS);
|
||||
static void resolve_invokeinterface(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS);
|
||||
static void resolve_invokedynamic (CallInfo& result, constantPoolHandle pool, int index, TRAPS);
|
||||
static void resolve_invokehandle (CallInfo& result, constantPoolHandle pool, int index, TRAPS);
|
||||
|
||||
static void resolve_invoke (CallInfo& result, Handle recv, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS);
|
||||
static void resolve_invoke(CallInfo& result, Handle recv,
|
||||
constantPoolHandle pool, int index,
|
||||
Bytecodes::Code byte, TRAPS);
|
||||
private:
|
||||
static void trace_method_resolution(const char* prefix, KlassHandle klass,
|
||||
KlassHandle resolved_klass,
|
||||
const methodHandle& method) PRODUCT_RETURN;
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_INTERPRETER_LINKRESOLVER_HPP
|
||||
|
@ -1136,7 +1136,7 @@ void klassItable::initialize_itable_for_interface(int method_table_offset, Klass
|
||||
if (m->has_itable_index()) {
|
||||
// This search must match the runtime resolution, i.e. selection search for invokeinterface
|
||||
// to correctly enforce loader constraints for interface method inheritance
|
||||
LinkResolver::lookup_instance_method_in_klasses(target, _klass, m->name(), m->signature(), CHECK);
|
||||
target = LinkResolver::lookup_instance_method_in_klasses(_klass, m->name(), m->signature(), CHECK);
|
||||
}
|
||||
if (target == NULL || !target->is_public() || target->is_abstract()) {
|
||||
// Entry does not resolve. Leave it empty for AbstractMethodError.
|
||||
|
@ -677,24 +677,24 @@ Handle MethodHandles::resolve_MemberName(Handle mname, KlassHandle caller, TRAPS
|
||||
case IS_METHOD:
|
||||
{
|
||||
CallInfo result;
|
||||
LinkInfo link_info(defc, name, type, caller, caller.not_null());
|
||||
{
|
||||
assert(!HAS_PENDING_EXCEPTION, "");
|
||||
if (ref_kind == JVM_REF_invokeStatic) {
|
||||
LinkResolver::resolve_static_call(result,
|
||||
defc, name, type, caller, caller.not_null(), false, THREAD);
|
||||
link_info, false, THREAD);
|
||||
} else if (ref_kind == JVM_REF_invokeInterface) {
|
||||
LinkResolver::resolve_interface_call(result, Handle(), defc,
|
||||
defc, name, type, caller, caller.not_null(), false, THREAD);
|
||||
link_info, false, THREAD);
|
||||
} else if (mh_invoke_id != vmIntrinsics::_none) {
|
||||
assert(!is_signature_polymorphic_static(mh_invoke_id), "");
|
||||
LinkResolver::resolve_handle_call(result,
|
||||
defc, name, type, caller, THREAD);
|
||||
LinkResolver::resolve_handle_call(result, link_info, THREAD);
|
||||
} else if (ref_kind == JVM_REF_invokeSpecial) {
|
||||
LinkResolver::resolve_special_call(result,
|
||||
defc, name, type, caller, caller.not_null(), THREAD);
|
||||
link_info, THREAD);
|
||||
} else if (ref_kind == JVM_REF_invokeVirtual) {
|
||||
LinkResolver::resolve_virtual_call(result, Handle(), defc,
|
||||
defc, name, type, caller, caller.not_null(), false, THREAD);
|
||||
link_info, false, THREAD);
|
||||
} else {
|
||||
assert(false, err_msg("ref_kind=%d", ref_kind));
|
||||
}
|
||||
@ -714,11 +714,11 @@ Handle MethodHandles::resolve_MemberName(Handle mname, KlassHandle caller, TRAPS
|
||||
case IS_CONSTRUCTOR:
|
||||
{
|
||||
CallInfo result;
|
||||
LinkInfo link_info(defc, name, type, caller, caller.not_null());
|
||||
{
|
||||
assert(!HAS_PENDING_EXCEPTION, "");
|
||||
if (name == vmSymbols::object_initializer_name()) {
|
||||
LinkResolver::resolve_special_call(result,
|
||||
defc, name, type, caller, caller.not_null(), THREAD);
|
||||
LinkResolver::resolve_special_call(result, link_info, THREAD);
|
||||
} else {
|
||||
break; // will throw after end of switch
|
||||
}
|
||||
@ -735,7 +735,8 @@ Handle MethodHandles::resolve_MemberName(Handle mname, KlassHandle caller, TRAPS
|
||||
fieldDescriptor result; // find_field initializes fd if found
|
||||
{
|
||||
assert(!HAS_PENDING_EXCEPTION, "");
|
||||
LinkResolver::resolve_field(result, defc, name, type, caller, Bytecodes::_nop, false, false, THREAD);
|
||||
LinkInfo link_info(defc, name, type, caller, /*check_access*/false);
|
||||
LinkResolver::resolve_field(result, link_info, Bytecodes::_nop, false, THREAD);
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
return empty;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2015, 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
|
||||
@ -179,9 +179,9 @@ void JavaCalls::call_virtual(JavaValue* result, KlassHandle spec_klass, Symbol*
|
||||
CallInfo callinfo;
|
||||
Handle receiver = args->receiver();
|
||||
KlassHandle recvrKlass(THREAD, receiver.is_null() ? (Klass*)NULL : receiver->klass());
|
||||
LinkInfo link_info(spec_klass, name, signature, KlassHandle(), /*check_access*/false);
|
||||
LinkResolver::resolve_virtual_call(
|
||||
callinfo, receiver, recvrKlass, spec_klass, name, signature,
|
||||
KlassHandle(), false, true, CHECK);
|
||||
callinfo, receiver, recvrKlass, link_info, true, CHECK);
|
||||
methodHandle method = callinfo.selected_method();
|
||||
assert(method.not_null(), "should have thrown exception");
|
||||
|
||||
@ -216,7 +216,8 @@ void JavaCalls::call_virtual(JavaValue* result, Handle receiver, KlassHandle spe
|
||||
|
||||
void JavaCalls::call_special(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
|
||||
CallInfo callinfo;
|
||||
LinkResolver::resolve_special_call(callinfo, klass, name, signature, KlassHandle(), false, CHECK);
|
||||
LinkInfo link_info(klass, name, signature, KlassHandle(), /*check_access*/false);
|
||||
LinkResolver::resolve_special_call(callinfo, link_info, CHECK);
|
||||
methodHandle method = callinfo.selected_method();
|
||||
assert(method.not_null(), "should have thrown exception");
|
||||
|
||||
@ -250,7 +251,8 @@ void JavaCalls::call_special(JavaValue* result, Handle receiver, KlassHandle kla
|
||||
|
||||
void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
|
||||
CallInfo callinfo;
|
||||
LinkResolver::resolve_static_call(callinfo, klass, name, signature, KlassHandle(), false, true, CHECK);
|
||||
LinkInfo link_info(klass, name, signature, KlassHandle(), /*check_access*/false);
|
||||
LinkResolver::resolve_static_call(callinfo, link_info, true, CHECK);
|
||||
methodHandle method = callinfo.selected_method();
|
||||
assert(method.not_null(), "should have thrown exception");
|
||||
|
||||
|
@ -831,9 +831,9 @@ methodHandle Reflection::resolve_interface_call(instanceKlassHandle klass, metho
|
||||
CallInfo info;
|
||||
Symbol* signature = method->signature();
|
||||
Symbol* name = method->name();
|
||||
LinkResolver::resolve_interface_call(info, receiver, recv_klass, klass,
|
||||
name, signature,
|
||||
KlassHandle(), false, true,
|
||||
LinkResolver::resolve_interface_call(info, receiver, recv_klass,
|
||||
LinkInfo(klass, name, signature, KlassHandle(), false),
|
||||
true,
|
||||
CHECK_(methodHandle()));
|
||||
return info.selected_method();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user