< prev index next > src/hotspot/share/interpreter/linkResolver.cpp
Print this page
void LinkResolver::resolve_field_access(fieldDescriptor& fd,
const constantPoolHandle& pool,
int index,
const methodHandle& method,
Bytecodes::Code byte,
! bool initialize_class, TRAPS) {
LinkInfo link_info(pool, index, method, byte, CHECK);
! resolve_field(fd, link_info, byte, initialize_class, CHECK);
}
void LinkResolver::resolve_field(fieldDescriptor& fd,
const LinkInfo& link_info,
! Bytecodes::Code byte, bool initialize_class,
TRAPS) {
assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
byte == Bytecodes::_getfield || byte == Bytecodes::_putfield ||
byte == Bytecodes::_nofast_getfield || byte == Bytecodes::_nofast_putfield ||
(byte == Bytecodes::_nop && !link_info.check_access()), "bad field access bytecode");
void LinkResolver::resolve_field_access(fieldDescriptor& fd,
const constantPoolHandle& pool,
int index,
const methodHandle& method,
Bytecodes::Code byte,
! StaticMode static_mode, TRAPS) {
LinkInfo link_info(pool, index, method, byte, CHECK);
! resolve_field(fd, link_info, byte, static_mode, CHECK);
}
void LinkResolver::resolve_field(fieldDescriptor& fd,
const LinkInfo& link_info,
! Bytecodes::Code byte, StaticMode static_mode,
TRAPS) {
assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
byte == Bytecodes::_getfield || byte == Bytecodes::_putfield ||
byte == Bytecodes::_nofast_getfield || byte == Bytecodes::_nofast_putfield ||
(byte == Bytecodes::_nop && !link_info.check_access()), "bad field access bytecode");
// note 1: the klass which declared the field must be initialized (i.e, sel_klass)
// according to the newest JVM spec (5.5, p.170) - was bug (gri 7/28/99)
//
// note 2: we don't want to force initialization if we are just checking
// if the field access is legal; e.g., during compilation
! if (is_static && initialize_class) {
! sel_klass->initialize(CHECK);
}
}
if (link_info.check_loader_constraints() && (sel_klass != current_klass) && (current_klass != nullptr)) {
check_field_loader_constraints(field, sig, current_klass, sel_klass, CHECK);
// note 1: the klass which declared the field must be initialized (i.e, sel_klass)
// according to the newest JVM spec (5.5, p.170) - was bug (gri 7/28/99)
//
// note 2: we don't want to force initialization if we are just checking
// if the field access is legal; e.g., during compilation
! if (is_static) {
! if (static_mode == StaticMode::initialize_klass) {
+ sel_klass->initialize(CHECK);
+ } else if (static_mode == StaticMode::initialize_klass_preemptable) {
+ sel_klass->initialize_preemptable(CHECK);
+ }
}
}
if (link_info.check_loader_constraints() && (sel_klass != current_klass) && (current_klass != nullptr)) {
check_field_loader_constraints(field, sig, current_klass, sel_klass, CHECK);
// recv_klass the receiver klass
void LinkResolver::resolve_static_call(CallInfo& result,
const LinkInfo& link_info,
! bool initialize_class, TRAPS) {
Method* resolved_method = linktime_resolve_static_method(link_info, CHECK);
// The resolved class can change as a result of this resolution.
Klass* resolved_klass = resolved_method->method_holder();
// Initialize klass (this should only happen if everything is ok)
! if (initialize_class && resolved_klass->should_be_initialized()) {
! resolved_klass->initialize(CHECK);
// Use updated LinkInfo to reresolve with resolved method holder
LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(),
link_info.current_klass(),
link_info.check_access() ? LinkInfo::AccessCheck::required : LinkInfo::AccessCheck::skip,
link_info.check_loader_constraints() ? LinkInfo::LoaderConstraintCheck::required : LinkInfo::LoaderConstraintCheck::skip);
// recv_klass the receiver klass
void LinkResolver::resolve_static_call(CallInfo& result,
const LinkInfo& link_info,
! StaticMode static_mode, TRAPS) {
Method* resolved_method = linktime_resolve_static_method(link_info, CHECK);
// The resolved class can change as a result of this resolution.
Klass* resolved_klass = resolved_method->method_holder();
// Initialize klass (this should only happen if everything is ok)
! if (static_mode != StaticMode::dont_initialize_klass && resolved_klass->should_be_initialized()) {
! if (static_mode == StaticMode::initialize_klass) {
+ resolved_klass->initialize(CHECK);
+ } else if (static_mode == StaticMode::initialize_klass_preemptable) {
+ resolved_klass->initialize_preemptable(CHECK);
+ }
// Use updated LinkInfo to reresolve with resolved method holder
LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(),
link_info.current_klass(),
link_info.check_access() ? LinkInfo::AccessCheck::required : LinkInfo::AccessCheck::skip,
link_info.check_loader_constraints() ? LinkInfo::LoaderConstraintCheck::required : LinkInfo::LoaderConstraintCheck::skip);
}
Method* LinkResolver::resolve_static_call_or_null(const LinkInfo& link_info) {
EXCEPTION_MARK;
CallInfo info;
! resolve_static_call(info, link_info, /*initialize_class*/false, THREAD);
if (HAS_PENDING_EXCEPTION) {
CLEAR_PENDING_EXCEPTION;
return nullptr;
}
return info.selected_method();
}
Method* LinkResolver::resolve_static_call_or_null(const LinkInfo& link_info) {
EXCEPTION_MARK;
CallInfo info;
! resolve_static_call(info, link_info, StaticMode::dont_initialize_klass, THREAD);
if (HAS_PENDING_EXCEPTION) {
CLEAR_PENDING_EXCEPTION;
return nullptr;
}
return info.selected_method();
//------------------------------------------------------------------------------------------------------------------------
// ConstantPool entries
! void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, const constantPoolHandle& pool, int index, Bytecodes::Code byte, TRAPS) {
switch (byte) {
! case Bytecodes::_invokestatic : resolve_invokestatic (result, pool, index, CHECK); break;
! case Bytecodes::_invokespecial : resolve_invokespecial (result, recv, pool, index, CHECK); break;
! case Bytecodes::_invokevirtual : resolve_invokevirtual (result, recv, pool, index, CHECK); break;
! case Bytecodes::_invokehandle : resolve_invokehandle (result, pool, index, CHECK); break;
! case Bytecodes::_invokedynamic : resolve_invokedynamic (result, pool, index, CHECK); break;
! case Bytecodes::_invokeinterface: resolve_invokeinterface(result, recv, pool, index, CHECK); break;
! default : break;
}
return;
}
void LinkResolver::resolve_invoke(CallInfo& result, Handle& recv,
//------------------------------------------------------------------------------------------------------------------------
// ConstantPool entries
! void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, const constantPoolHandle& pool, int index, Bytecodes::Code byte, StaticMode static_mode, TRAPS) {
switch (byte) {
! case Bytecodes::_invokestatic : resolve_invokestatic (result, pool, index, static_mode, CHECK); break;
! case Bytecodes::_invokespecial : resolve_invokespecial (result, recv, pool, index, CHECK); break;
! case Bytecodes::_invokevirtual : resolve_invokevirtual (result, recv, pool, index, CHECK); break;
! case Bytecodes::_invokehandle : resolve_invokehandle (result, pool, index, CHECK); break;
! case Bytecodes::_invokedynamic : resolve_invokedynamic (result, pool, index, CHECK); break;
! case Bytecodes::_invokeinterface: resolve_invokeinterface(result, recv, pool, index, CHECK); break;
! default : break;
}
return;
}
void LinkResolver::resolve_invoke(CallInfo& result, Handle& recv,
case Bytecodes::_invokeinterface:
resolve_interface_call(result, recv, recv->klass(), link_info,
/*check_null_and_abstract=*/true, CHECK);
break;
case Bytecodes::_invokestatic:
! resolve_static_call(result, link_info, /*initialize_class=*/false, CHECK);
break;
case Bytecodes::_invokespecial:
resolve_special_call(result, recv, link_info, CHECK);
break;
default:
fatal("bad call: %s", Bytecodes::name(byte));
break;
}
}
! void LinkResolver::resolve_invokestatic(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) {
LinkInfo link_info(pool, index, Bytecodes::_invokestatic, CHECK);
! resolve_static_call(result, link_info, /*initialize_class*/true, CHECK);
}
void LinkResolver::resolve_invokespecial(CallInfo& result, Handle recv,
const constantPoolHandle& pool, int index, TRAPS) {
case Bytecodes::_invokeinterface:
resolve_interface_call(result, recv, recv->klass(), link_info,
/*check_null_and_abstract=*/true, CHECK);
break;
case Bytecodes::_invokestatic:
! resolve_static_call(result, link_info, StaticMode::dont_initialize_klass, CHECK);
break;
case Bytecodes::_invokespecial:
resolve_special_call(result, recv, link_info, CHECK);
break;
default:
fatal("bad call: %s", Bytecodes::name(byte));
break;
}
}
! void LinkResolver::resolve_invokestatic(CallInfo& result, const constantPoolHandle& pool, int index, StaticMode static_mode, TRAPS) {
LinkInfo link_info(pool, index, Bytecodes::_invokestatic, CHECK);
! resolve_static_call(result, link_info, static_mode, CHECK);
}
void LinkResolver::resolve_invokespecial(CallInfo& result, Handle recv,
const constantPoolHandle& pool, int index, TRAPS) {
< prev index next >