src/share/vm/interpreter/linkResolver.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/interpreter/linkResolver.cpp Thu Jun 2 10:38:19 2016
--- new/src/share/vm/interpreter/linkResolver.cpp Thu Jun 2 10:38:18 2016
*** 221,239 ****
--- 221,240 ----
#endif
//------------------------------------------------------------------------------------------------------------------------
// Implementation of LinkInfo
! LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, methodHandle current_method, TRAPS) {
// resolve klass
Klass* result = pool->klass_ref_at(index, CHECK);
_resolved_klass = KlassHandle(THREAD, result);
// Get name, signature, and static klass
_name = pool->name_ref_at(index);
_signature = pool->signature_ref_at(index);
_current_klass = KlassHandle(THREAD, pool->pool_holder());
+ _current_method = current_method;
// Coming from the constant pool always checks access
_check_access = true;
}
*** 570,584 ****
--- 571,585 ----
if (code == Bytecodes::_invokedynamic) {
resolved_klass = SystemDictionary::MethodHandle_klass();
Symbol* method_name = vmSymbols::invoke_name();
Symbol* method_signature = pool->signature_ref_at(index);
KlassHandle current_klass(THREAD, pool->pool_holder());
! LinkInfo link_info(resolved_klass, method_name, method_signature, current_klass, NULL);
return resolve_method(link_info, /*require_methodref*/false, THREAD);
}
! LinkInfo link_info(pool, index, NULL, CHECK_NULL);
resolved_klass = link_info.resolved_klass();
if (pool->has_preresolution()
|| (resolved_klass() == SystemDictionary::MethodHandle_klass() &&
MethodHandles::is_signature_polymorphic_name(resolved_klass(), link_info.name()))) {
*** 855,866 ****
--- 856,867 ----
);
return;
}
}
! void LinkResolver::resolve_field_access(fieldDescriptor& fd, const constantPoolHandle& pool, int index, const methodHandle& method, Bytecodes::Code byte, TRAPS) {
! LinkInfo link_info(pool, index, method, CHECK);
resolve_field(fd, link_info, byte, true, CHECK);
}
void LinkResolver::resolve_field(fieldDescriptor& fd,
const LinkInfo& link_info,
*** 905,918 ****
--- 906,930 ----
char msg[200];
jio_snprintf(msg, sizeof(msg), "Expected %s field %s.%s", is_static ? "static" : "non-static", resolved_klass()->external_name(), fd.name()->as_C_string());
THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg);
}
// Final fields can only be accessed from its own class.
if (is_put && fd.access_flags().is_final() && sel_klass() != current_klass()) {
+ // A final field can be modified only
+ // (1) by methods declared in the class declaring the field and
+ // (2) by the <clinit> method (in case of a static field)
+ // or by the <init> method (in case of an instance field).
+ if (is_put && fd.access_flags().is_final()) {
+ methodHandle m = link_info.current_method();
+ assert(!m.is_null(), "information about the current method must be available for 'put' bytecodes");
+ Symbol* method_name = m->name();
+ if (sel_klass() != current_klass() ||
+ (byte == Bytecodes::_putstatic && fd.is_static() && method_name != vmSymbols::class_initializer_name()) ||
+ ((byte == Bytecodes::_putfield || byte == Bytecodes::_nofast_putfield) && !fd.is_static() && method_name != vmSymbols::object_initializer_name())
+ ) {
THROW(vmSymbols::java_lang_IllegalAccessError());
}
+ }
// initialize resolved_klass if necessary
// 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)
//
*** 954,964 ****
--- 966,976 ----
// 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_klass as method_holder?)
LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(),
! link_info.current_klass(), NULL, link_info.check_access());
resolved_method = linktime_resolve_static_method(new_info, CHECK);
}
assert(save_resolved_method == resolved_method(), "does this change?");
// setup result
*** 1480,1490 ****
--- 1492,1502 ----
const methodHandle& attached_method,
Bytecodes::Code byte, TRAPS) {
KlassHandle defc = attached_method->method_holder();
Symbol* name = attached_method->name();
Symbol* type = attached_method->signature();
! LinkInfo link_info(defc, name, type, KlassHandle(), NULL, /*check_access=*/false);
switch(byte) {
case Bytecodes::_invokevirtual:
resolve_virtual_call(result, recv, recv->klass(), link_info,
/*check_null_and_abstract=*/true, CHECK);
break;
*** 1502,1542 ****
--- 1514,1554 ----
fatal("bad call: %s", Bytecodes::name(byte));
}
}
void LinkResolver::resolve_invokestatic(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) {
! LinkInfo link_info(pool, index, NULL, CHECK);
resolve_static_call(result, link_info, /*initialize_class*/true, CHECK);
}
void LinkResolver::resolve_invokespecial(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) {
! LinkInfo link_info(pool, index, NULL, CHECK);
resolve_special_call(result, link_info, CHECK);
}
void LinkResolver::resolve_invokevirtual(CallInfo& result, Handle recv,
const constantPoolHandle& pool, int index,
TRAPS) {
! LinkInfo link_info(pool, index, NULL, CHECK);
KlassHandle recvrKlass (THREAD, recv.is_null() ? (Klass*)NULL : recv->klass());
resolve_virtual_call(result, recv, recvrKlass, link_info, /*check_null_or_abstract*/true, CHECK);
}
void LinkResolver::resolve_invokeinterface(CallInfo& result, Handle recv, const constantPoolHandle& pool, int index, TRAPS) {
! LinkInfo link_info(pool, index, NULL, CHECK);
KlassHandle recvrKlass (THREAD, recv.is_null() ? (Klass*)NULL : recv->klass());
resolve_interface_call(result, recv, recvrKlass, link_info, true, CHECK);
}
void LinkResolver::resolve_invokehandle(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) {
// This guy is reached from InterpreterRuntime::resolve_invokehandle.
! LinkInfo link_info(pool, index, NULL, CHECK);
if (TraceMethodHandles) {
ResourceMark rm(THREAD);
tty->print_cr("resolve_invokehandle %s %s", link_info.name()->as_C_string(),
link_info.signature()->as_C_string());
}
src/share/vm/interpreter/linkResolver.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File