提交 b7c54ca2 编写于 作者: J jiangli

Merge

......@@ -334,4 +334,6 @@ a947f40fb536e5b9e0aa210cf26abb430f80887a hs25-b26
09b0d3e9ba6cdf7da07d4010d2d1df14596f6864 hs25-b27
6d88a566d369f6a1f86912cad7d0912686b2fda1 hs25-b28
86db4847f195c0ecceea646431f1ff22d56282e8 jdk8-b86
d4c2667846607042370760e23f64c3ab9350e60d jdk8-b87
01d5f04e64dc2d64625b2db2056f5ed4de918a45 hs25-b29
c4af77d2045476c56fbf3f914b336bb1b7cd18af hs25-b30
......@@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013
HS_MAJOR_VER=25
HS_MINOR_VER=0
HS_BUILD_NUMBER=30
HS_BUILD_NUMBER=31
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
......
......@@ -2097,7 +2097,8 @@ void InterpreterMacroAssembler::get_method_counters(Register method,
call_VM(noreg, CAST_FROM_FN_PTR(address,
InterpreterRuntime::build_method_counters), method);
ld_ptr(method_counters, Rcounters);
br_null_short(Rcounters, Assembler::pn, skip); // No MethodCounters, OutOfMemory
br_null(Rcounters, false, Assembler::pn, skip); // No MethodCounters, OutOfMemory
delayed()->nop();
bind(has_counters);
}
......
......@@ -360,7 +360,7 @@ void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile
const Address mdo_invocation_counter(rax, in_bytes(MethodData::invocation_counter_offset()) +
in_bytes(InvocationCounter::counter_offset()));
__ increment_mask_and_jump(mdo_invocation_counter, increment, mask, rcx, false, Assembler::zero, overflow);
__ jmpb(done);
__ jmp(done);
}
__ bind(no_mdo);
// Increment counter in MethodCounters
......
......@@ -315,7 +315,7 @@ void InterpreterGenerator::generate_counter_incr(
const Address mdo_invocation_counter(rax, in_bytes(MethodData::invocation_counter_offset()) +
in_bytes(InvocationCounter::counter_offset()));
__ increment_mask_and_jump(mdo_invocation_counter, increment, mask, rcx, false, Assembler::zero, overflow);
__ jmpb(done);
__ jmp(done);
}
__ bind(no_mdo);
// Increment counter in MethodCounters
......
......@@ -2180,12 +2180,6 @@ encode %{
$$$emit32$src$$constant;
%}
enc_class Con64(immL src)
%{
// Output immediate
emit_d64($src$$constant);
%}
enc_class Con32F_as_bits(immF src)
%{
// Output Float immediate bits
......@@ -7566,7 +7560,7 @@ instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{
ins_pipe( pipe_cmpxchg );
%}
instruct xaddL_no_res( memory mem, Universe dummy, immL add, rFlagsReg cr) %{
instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{
predicate(n->as_LoadStore()->result_not_used());
match(Set dummy (GetAndAddL mem add));
effect(KILL cr);
......
......@@ -459,7 +459,7 @@ void RangeCheckEliminator::in_block_motion(BlockBegin *block, AccessIndexedList
// Iterate over all different indices
if (_optimistic) {
for (int i=0; i<indices.length(); i++) {
for (int i = 0; i < indices.length(); i++) {
Instruction *index_instruction = indices.at(i);
AccessIndexedInfo *info = _access_indexed_info[index_instruction->id()];
assert(info != NULL, "Info must not be null");
......@@ -531,9 +531,7 @@ void RangeCheckEliminator::in_block_motion(BlockBegin *block, AccessIndexedList
remove_range_check(ai);
}
}
_access_indexed_info[index_instruction->id()] = NULL;
}
indices.clear();
if (list_constant.length() > 1) {
AccessIndexed *first = list_constant.at(0);
......@@ -560,6 +558,13 @@ void RangeCheckEliminator::in_block_motion(BlockBegin *block, AccessIndexedList
}
}
}
// Clear data structures for next array
for (int i = 0; i < indices.length(); i++) {
Instruction *index_instruction = indices.at(i);
_access_indexed_info[index_instruction->id()] = NULL;
}
indices.clear();
}
}
......
......@@ -436,14 +436,19 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
ref_index, CHECK_(nullHandle));
break;
case JVM_REF_invokeVirtual:
case JVM_REF_invokeStatic:
case JVM_REF_invokeSpecial:
case JVM_REF_newInvokeSpecial:
check_property(
tag.is_method(),
"Invalid constant pool index %u in class file %s (not a method)",
ref_index, CHECK_(nullHandle));
break;
case JVM_REF_invokeStatic:
case JVM_REF_invokeSpecial:
check_property(
tag.is_method() || tag.is_interface_method(),
"Invalid constant pool index %u in class file %s (not a method)",
ref_index, CHECK_(nullHandle));
break;
case JVM_REF_invokeInterface:
check_property(
tag.is_interface_method(),
......@@ -3837,7 +3842,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
}
if (TraceClassLoadingPreorder) {
tty->print("[Loading %s", name->as_klass_external_name());
tty->print("[Loading %s", (name != NULL) ? name->as_klass_external_name() : "NoName");
if (cfs->source() != NULL) tty->print(" from %s", cfs->source());
tty->print_cr("]");
}
......
......@@ -268,8 +268,15 @@ ClassDescriptor* ClassDescriptor::parse_generic_signature(
Klass* outer = SystemDictionary::find(
outer_name, class_loader, protection_domain, CHECK_NULL);
if (outer == NULL && !THREAD->is_Compiler_thread()) {
outer = SystemDictionary::resolve_super_or_fail(original_name,
outer_name, class_loader, protection_domain, false, CHECK_NULL);
if (outer_name == ik->super()->name()) {
outer = SystemDictionary::resolve_super_or_fail(original_name, outer_name,
class_loader, protection_domain,
false, CHECK_NULL);
}
else {
outer = SystemDictionary::resolve_or_fail(outer_name, class_loader,
protection_domain, false, CHECK_NULL);
}
}
InstanceKlass* outer_ik;
......
......@@ -2625,6 +2625,15 @@ Metadata* java_lang_invoke_MemberName::vmtarget(oop mname) {
return (Metadata*)mname->address_field(_vmtarget_offset);
}
#if INCLUDE_JVMTI
// Can be executed on VM thread only
void java_lang_invoke_MemberName::adjust_vmtarget(oop mname, Metadata* ref) {
assert((is_instance(mname) && (flags(mname) & (MN_IS_METHOD | MN_IS_CONSTRUCTOR)) > 0), "wrong type");
assert(Thread::current()->is_VM_thread(), "not VM thread");
mname->address_field_put(_vmtarget_offset, (address)ref);
}
#endif // INCLUDE_JVMTI
void java_lang_invoke_MemberName::set_vmtarget(oop mname, Metadata* ref) {
assert(is_instance(mname), "wrong type");
// check the type of the vmtarget
......
......@@ -1036,6 +1036,9 @@ class java_lang_invoke_MemberName: AllStatic {
static Metadata* vmtarget(oop mname);
static void set_vmtarget(oop mname, Metadata* target);
#if INCLUDE_JVMTI
static void adjust_vmtarget(oop mname, Metadata* target);
#endif // INCLUDE_JVMTI
static intptr_t vmindex(oop mname);
static void set_vmindex(oop mname, intptr_t index);
......
......@@ -1014,13 +1014,28 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHand
resolved_method->name(),
resolved_method->signature()));
}
// check if public
if (!sel_method->is_public()) {
ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
Method::name_and_sig_as_C_string(recv_klass(),
sel_method->name(),
sel_method->signature()));
// check access
if (sel_method->method_holder()->is_interface()) {
// Method holder is an interface. Throw Illegal Access Error if sel_method
// is neither public nor private.
if (!(sel_method->is_public() || sel_method->is_private())) {
ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
Method::name_and_sig_as_C_string(recv_klass(),
sel_method->name(),
sel_method->signature()));
}
}
else {
// Method holder is a class. Throw Illegal Access Error if sel_method
// is not public.
if (!sel_method->is_public()) {
ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
Method::name_and_sig_as_C_string(recv_klass(),
sel_method->name(),
sel_method->signature()));
}
}
// check if abstract
if (check_null_and_abstract && sel_method->is_abstract()) {
......
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2012, 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
......
......@@ -2329,6 +2329,12 @@ void InstanceKlass::release_C_heap_structures() {
FreeHeap(jmeths);
}
MemberNameTable* mnt = member_names();
if (mnt != NULL) {
delete mnt;
set_member_names(NULL);
}
int* indices = methods_cached_itable_indices_acquire();
if (indices != (int*)NULL) {
release_set_methods_cached_itable_indices(NULL);
......@@ -2757,6 +2763,17 @@ nmethod* InstanceKlass::lookup_osr_nmethod(Method* const m, int bci, int comp_le
return NULL;
}
void InstanceKlass::add_member_name(Handle mem_name) {
jweak mem_name_wref = JNIHandles::make_weak_global(mem_name);
MutexLocker ml(MemberNameTable_lock);
DEBUG_ONLY(No_Safepoint_Verifier nsv);
if (_member_names == NULL) {
_member_names = new (ResourceObj::C_HEAP, mtClass) MemberNameTable();
}
_member_names->add_member_name(mem_name_wref);
}
// -----------------------------------------------------------------------------------------------------
// Printing
......
......@@ -90,6 +90,7 @@ class DepChange;
class nmethodBucket;
class PreviousVersionNode;
class JvmtiCachedClassFieldMap;
class MemberNameTable;
// This is used in iterators below.
class FieldClosure: public StackObj {
......@@ -246,6 +247,7 @@ class InstanceKlass: public Klass {
int _vtable_len; // length of Java vtable (in words)
int _itable_len; // length of Java itable (in words)
OopMapCache* volatile _oop_map_cache; // OopMapCache for all methods in the klass (allocated lazily)
MemberNameTable* _member_names; // Member names
JNIid* _jni_ids; // First JNI identifier for static fields in this class
jmethodID* _methods_jmethod_ids; // jmethodIDs corresponding to method_idnum, or NULL if none
int* _methods_cached_itable_indices; // itable_index cache for JNI invoke corresponding to methods idnum, or NULL
......@@ -1028,6 +1030,11 @@ public:
// jvm support
jint compute_modifier_flags(TRAPS) const;
// JSR-292 support
MemberNameTable* member_names() { return _member_names; }
void set_member_names(MemberNameTable* member_names) { _member_names = member_names; }
void add_member_name(Handle member_name);
public:
// JVMTI support
jint jvmti_class_status() const;
......
......@@ -3284,6 +3284,16 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass,
// that reference methods of the evolved class.
SystemDictionary::classes_do(adjust_cpool_cache_and_vtable, THREAD);
// JSR-292 support
MemberNameTable* mnt = the_class->member_names();
if (mnt != NULL) {
bool trace_name_printed = false;
mnt->adjust_method_entries(_matching_old_methods,
_matching_new_methods,
_matching_methods_length,
&trace_name_printed);
}
// Fix Resolution Error table also to remove old constant pools
SystemDictionary::delete_resolution_error(old_constants);
......
......@@ -29,6 +29,7 @@
#include "interpreter/oopMapCache.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/oopFactory.hpp"
#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/compilationPolicy.hpp"
#include "runtime/javaCalls.hpp"
......@@ -124,7 +125,9 @@ Handle MethodHandles::new_MemberName(TRAPS) {
return Handle(THREAD, k->allocate_instance(THREAD));
}
oop MethodHandles::init_MemberName(oop mname_oop, oop target_oop) {
oop MethodHandles::init_MemberName(Handle mname, Handle target) {
Thread* thread = Thread::current();
oop target_oop = target();
Klass* target_klass = target_oop->klass();
if (target_klass == SystemDictionary::reflect_Field_klass()) {
oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder()
......@@ -132,24 +135,24 @@ oop MethodHandles::init_MemberName(oop mname_oop, oop target_oop) {
int mods = java_lang_reflect_Field::modifiers(target_oop);
oop type = java_lang_reflect_Field::type(target_oop);
oop name = java_lang_reflect_Field::name(target_oop);
Klass* k = java_lang_Class::as_Klass(clazz);
intptr_t offset = InstanceKlass::cast(k)->field_offset(slot);
return init_field_MemberName(mname_oop, k, accessFlags_from(mods), type, name, offset);
KlassHandle k(thread, java_lang_Class::as_Klass(clazz));
intptr_t offset = InstanceKlass::cast(k())->field_offset(slot);
return init_field_MemberName(mname, k, accessFlags_from(mods), type, name, offset);
} else if (target_klass == SystemDictionary::reflect_Method_klass()) {
oop clazz = java_lang_reflect_Method::clazz(target_oop);
int slot = java_lang_reflect_Method::slot(target_oop);
Klass* k = java_lang_Class::as_Klass(clazz);
if (k != NULL && k->oop_is_instance()) {
Method* m = InstanceKlass::cast(k)->method_with_idnum(slot);
return init_method_MemberName(mname_oop, m, true, k);
KlassHandle k(thread, java_lang_Class::as_Klass(clazz));
if (!k.is_null() && k->oop_is_instance()) {
Method* m = InstanceKlass::cast(k())->method_with_idnum(slot);
return init_method_MemberName(mname, m, true, k);
}
} else if (target_klass == SystemDictionary::reflect_Constructor_klass()) {
oop clazz = java_lang_reflect_Constructor::clazz(target_oop);
int slot = java_lang_reflect_Constructor::slot(target_oop);
Klass* k = java_lang_Class::as_Klass(clazz);
if (k != NULL && k->oop_is_instance()) {
Method* m = InstanceKlass::cast(k)->method_with_idnum(slot);
return init_method_MemberName(mname_oop, m, false, k);
KlassHandle k(thread, java_lang_Class::as_Klass(clazz));
if (!k.is_null() && k->oop_is_instance()) {
Method* m = InstanceKlass::cast(k())->method_with_idnum(slot);
return init_method_MemberName(mname, m, false, k);
}
} else if (target_klass == SystemDictionary::MemberName_klass()) {
// Note: This only works if the MemberName has already been resolved.
......@@ -157,17 +160,18 @@ oop MethodHandles::init_MemberName(oop mname_oop, oop target_oop) {
int flags = java_lang_invoke_MemberName::flags(target_oop);
Metadata* vmtarget=java_lang_invoke_MemberName::vmtarget(target_oop);
intptr_t vmindex = java_lang_invoke_MemberName::vmindex(target_oop);
Klass* k = java_lang_Class::as_Klass(clazz);
KlassHandle k(thread, java_lang_Class::as_Klass(clazz));
int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
if (vmtarget == NULL) return NULL; // not resolved
if ((flags & IS_FIELD) != 0) {
assert(vmtarget->is_klass(), "field vmtarget is Klass*");
int basic_mods = (ref_kind_is_static(ref_kind) ? JVM_ACC_STATIC : 0);
// FIXME: how does k (receiver_limit) contribute?
return init_field_MemberName(mname_oop, (Klass*)vmtarget, accessFlags_from(basic_mods), NULL, NULL, vmindex);
KlassHandle k_vmtarget(thread, (Klass*)vmtarget);
return init_field_MemberName(mname, k_vmtarget, accessFlags_from(basic_mods), NULL, NULL, vmindex);
} else if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) != 0) {
assert(vmtarget->is_method(), "method or constructor vmtarget is Method*");
return init_method_MemberName(mname_oop, (Method*)vmtarget, ref_kind_does_dispatch(ref_kind), k);
return init_method_MemberName(mname, (Method*)vmtarget, ref_kind_does_dispatch(ref_kind), k);
} else {
return NULL;
}
......@@ -175,8 +179,9 @@ oop MethodHandles::init_MemberName(oop mname_oop, oop target_oop) {
return NULL;
}
oop MethodHandles::init_method_MemberName(oop mname_oop, Method* m, bool do_dispatch,
Klass* receiver_limit) {
oop MethodHandles::init_method_MemberName(Handle mname, Method* m, bool do_dispatch,
KlassHandle receiver_limit_h) {
Klass* receiver_limit = receiver_limit_h();
AccessFlags mods = m->access_flags();
int flags = (jushort)( mods.as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS );
int vmindex = Method::nonvirtual_vtable_index; // implies never any dispatch
......@@ -187,6 +192,10 @@ oop MethodHandles::init_method_MemberName(oop mname_oop, Method* m, bool do_disp
flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
} else if (mods.is_static()) {
flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT);
// Get vindex from itable if method holder is an interface.
if (m->method_holder()->is_interface()) {
vmindex = klassItable::compute_itable_index(m);
}
} else if (receiver_limit != mklass &&
!receiver_limit->is_subtype_of(mklass)) {
return NULL; // bad receiver limit
......@@ -213,6 +222,7 @@ oop MethodHandles::init_method_MemberName(oop mname_oop, Method* m, bool do_disp
flags |= CALLER_SENSITIVE;
}
oop mname_oop = mname();
java_lang_invoke_MemberName::set_flags( mname_oop, flags);
java_lang_invoke_MemberName::set_vmtarget(mname_oop, m);
java_lang_invoke_MemberName::set_vmindex( mname_oop, vmindex); // vtable/itable index
......@@ -225,10 +235,11 @@ oop MethodHandles::init_method_MemberName(oop mname_oop, Method* m, bool do_disp
// This is done eagerly, since it is readily available without
// constructing any new objects.
// TO DO: maybe intern mname_oop
return mname_oop;
m->method_holder()->add_member_name(mname);
return mname();
}
Handle MethodHandles::init_method_MemberName(oop mname_oop, CallInfo& info, TRAPS) {
Handle MethodHandles::init_method_MemberName(Handle mname, CallInfo& info, TRAPS) {
Handle empty;
if (info.resolved_appendix().not_null()) {
// The resolved MemberName must not be accompanied by an appendix argument,
......@@ -248,19 +259,20 @@ Handle MethodHandles::init_method_MemberName(oop mname_oop, CallInfo& info, TRAP
} else {
vmindex = info.vtable_index();
}
oop res = init_method_MemberName(mname_oop, m(), (vmindex >= 0), defc());
oop res = init_method_MemberName(mname, m(), (vmindex >= 0), defc());
assert(res == NULL || (java_lang_invoke_MemberName::vmindex(res) == vmindex), "");
return Handle(THREAD, res);
}
oop MethodHandles::init_field_MemberName(oop mname_oop, Klass* field_holder,
oop MethodHandles::init_field_MemberName(Handle mname, KlassHandle field_holder,
AccessFlags mods, oop type, oop name,
intptr_t offset, bool is_setter) {
int flags = (jushort)( mods.as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS );
flags |= IS_FIELD | ((mods.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT);
if (is_setter) flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT);
Metadata* vmtarget = field_holder;
Metadata* vmtarget = field_holder();
int vmindex = offset; // determines the field uniquely when combined with static bit
oop mname_oop = mname();
java_lang_invoke_MemberName::set_flags(mname_oop, flags);
java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget);
java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex);
......@@ -277,10 +289,11 @@ oop MethodHandles::init_field_MemberName(oop mname_oop, Klass* field_holder,
// Although the fieldDescriptor::_index would also identify the field,
// we do not use it, because it is harder to decode.
// TO DO: maybe intern mname_oop
return mname_oop;
InstanceKlass::cast(field_holder())->add_member_name(mname);
return mname();
}
Handle MethodHandles::init_field_MemberName(oop mname_oop, FieldAccessInfo& info, TRAPS) {
Handle MethodHandles::init_field_MemberName(Handle mname, FieldAccessInfo& info, TRAPS) {
return Handle();
#if 0 // FIXME
KlassHandle field_holder = info.klass();
......@@ -679,7 +692,7 @@ Handle MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
return empty;
}
}
return init_method_MemberName(mname(), result, THREAD);
return init_method_MemberName(mname, result, THREAD);
}
case IS_CONSTRUCTOR:
{
......@@ -697,7 +710,7 @@ Handle MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
}
}
assert(result.is_statically_bound(), "");
return init_method_MemberName(mname(), result, THREAD);
return init_method_MemberName(mname, result, THREAD);
}
case IS_FIELD:
{
......@@ -710,7 +723,7 @@ Handle MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
oop name = field_name_or_null(fd.name());
bool is_setter = (ref_kind_is_valid(ref_kind) && ref_kind_is_setter(ref_kind));
mname = Handle(THREAD,
init_field_MemberName(mname(), sel_klass(),
init_field_MemberName(mname, sel_klass,
fd.access_flags(), type, name, fd.offset(), is_setter));
return mname;
}
......@@ -802,16 +815,15 @@ void MethodHandles::expand_MemberName(Handle mname, int suppress, TRAPS) {
THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format");
}
int MethodHandles::find_MemberNames(Klass* k,
int MethodHandles::find_MemberNames(KlassHandle k,
Symbol* name, Symbol* sig,
int mflags, Klass* caller,
int skip, objArrayOop results) {
DEBUG_ONLY(No_Safepoint_Verifier nsv);
// this code contains no safepoints!
int mflags, KlassHandle caller,
int skip, objArrayHandle results) {
// %%% take caller into account!
if (k == NULL || !k->oop_is_instance()) return -1;
Thread* thread = Thread::current();
if (k.is_null() || !k->oop_is_instance()) return -1;
int rfill = 0, rlimit = results->length(), rskip = skip;
// overflow measurement:
......@@ -839,7 +851,7 @@ int MethodHandles::find_MemberNames(Klass* k,
}
if ((match_flags & IS_FIELD) != 0) {
for (FieldStream st(k, local_only, !search_intfc); !st.eos(); st.next()) {
for (FieldStream st(k(), local_only, !search_intfc); !st.eos(); st.next()) {
if (name != NULL && st.name() != name)
continue;
if (sig != NULL && st.signature() != sig)
......@@ -848,15 +860,15 @@ int MethodHandles::find_MemberNames(Klass* k,
if (rskip > 0) {
--rskip;
} else if (rfill < rlimit) {
oop result = results->obj_at(rfill++);
if (!java_lang_invoke_MemberName::is_instance(result))
Handle result(thread, results->obj_at(rfill++));
if (!java_lang_invoke_MemberName::is_instance(result()))
return -99; // caller bug!
oop type = field_signature_type_or_null(st.signature());
oop name = field_name_or_null(st.name());
oop saved = MethodHandles::init_field_MemberName(result, st.klass()(),
oop saved = MethodHandles::init_field_MemberName(result, st.klass(),
st.access_flags(), type, name,
st.offset());
if (saved != result)
if (saved != result())
results->obj_at_put(rfill-1, saved); // show saved instance to user
} else if (++overflow >= overflow_limit) {
match_flags = 0; break; // got tired of looking at overflow
......@@ -889,7 +901,7 @@ int MethodHandles::find_MemberNames(Klass* k,
} else {
// caller will accept either sort; no need to adjust name
}
for (MethodStream st(k, local_only, !search_intfc); !st.eos(); st.next()) {
for (MethodStream st(k(), local_only, !search_intfc); !st.eos(); st.next()) {
Method* m = st.method();
Symbol* m_name = m->name();
if (m_name == clinit_name)
......@@ -902,11 +914,11 @@ int MethodHandles::find_MemberNames(Klass* k,
if (rskip > 0) {
--rskip;
} else if (rfill < rlimit) {
oop result = results->obj_at(rfill++);
if (!java_lang_invoke_MemberName::is_instance(result))
Handle result(thread, results->obj_at(rfill++));
if (!java_lang_invoke_MemberName::is_instance(result()))
return -99; // caller bug!
oop saved = MethodHandles::init_method_MemberName(result, m, true, NULL);
if (saved != result)
if (saved != result())
results->obj_at_put(rfill-1, saved); // show saved instance to user
} else if (++overflow >= overflow_limit) {
match_flags = 0; break; // got tired of looking at overflow
......@@ -917,6 +929,99 @@ int MethodHandles::find_MemberNames(Klass* k,
// return number of elements we at leasted wanted to initialize
return rfill + overflow;
}
//------------------------------------------------------------------------------
// MemberNameTable
//
MemberNameTable::MemberNameTable() : GrowableArray<jweak>(10, true) {
assert_locked_or_safepoint(MemberNameTable_lock);
}
MemberNameTable::~MemberNameTable() {
assert_locked_or_safepoint(MemberNameTable_lock);
int len = this->length();
for (int idx = 0; idx < len; idx++) {
jweak ref = this->at(idx);
JNIHandles::destroy_weak_global(ref);
}
}
// Return entry index if found, return -1 otherwise.
int MemberNameTable::find_member_name(oop mem_name) {
assert_locked_or_safepoint(MemberNameTable_lock);
int len = this->length();
for (int idx = 0; idx < len; idx++) {
jweak ref = this->at(idx);
oop entry = JNIHandles::resolve(ref);
if (entry == mem_name) {
return idx;
}
}
return -1;
}
void MemberNameTable::add_member_name(jweak mem_name_wref) {
assert_locked_or_safepoint(MemberNameTable_lock);
oop mem_name = JNIHandles::resolve(mem_name_wref);
// Each member name may appear just once: add only if not found
if (find_member_name(mem_name) == -1) {
this->append(mem_name_wref);
}
}
#if INCLUDE_JVMTI
oop MemberNameTable::find_member_name_by_method(Method* old_method) {
assert_locked_or_safepoint(MemberNameTable_lock);
oop found = NULL;
int len = this->length();
for (int idx = 0; idx < len; idx++) {
oop mem_name = JNIHandles::resolve(this->at(idx));
if (mem_name == NULL) {
continue;
}
Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(mem_name);
if (method == old_method) {
found = mem_name;
break;
}
}
return found;
}
// It is called at safepoint only
void MemberNameTable::adjust_method_entries(Method** old_methods, Method** new_methods,
int methods_length, bool *trace_name_printed) {
assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
// search the MemberNameTable for uses of either obsolete or EMCP methods
for (int j = 0; j < methods_length; j++) {
Method* old_method = old_methods[j];
Method* new_method = new_methods[j];
oop mem_name = find_member_name_by_method(old_method);
if (mem_name != NULL) {
java_lang_invoke_MemberName::adjust_vmtarget(mem_name, new_method);
if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
if (!(*trace_name_printed)) {
// RC_TRACE_MESG macro has an embedded ResourceMark
RC_TRACE_MESG(("adjust: name=%s",
old_method->method_holder()->external_name()));
*trace_name_printed = true;
}
// RC_TRACE macro has an embedded ResourceMark
RC_TRACE(0x00400000, ("MemberName method update: %s(%s)",
new_method->name()->as_C_string(),
new_method->signature()->as_C_string()));
}
}
}
}
#endif // INCLUDE_JVMTI
//
// Here are the native methods in java.lang.invoke.MethodHandleNatives
// They are the private interface between this JVM and the HotSpot-specific
......@@ -1010,8 +1115,8 @@ JVM_ENTRY(void, MHN_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobje
if (mname_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); }
if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); }
Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
oop target_oop = JNIHandles::resolve_non_null(target_jh);
MethodHandles::init_MemberName(mname(), target_oop);
Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
MethodHandles::init_MemberName(mname, target);
}
JVM_END
......@@ -1118,7 +1223,7 @@ JVM_ENTRY(jobject, MHN_getMemberVMInfo(JNIEnv *env, jobject igcls, jobject mname
x = ((Klass*) vmtarget)->java_mirror();
} else if (vmtarget->is_method()) {
Handle mname2 = MethodHandles::new_MemberName(CHECK_NULL);
x = MethodHandles::init_method_MemberName(mname2(), (Method*)vmtarget, false, NULL);
x = MethodHandles::init_method_MemberName(mname2, (Method*)vmtarget, false, NULL);
}
result->obj_at_put(1, x);
return JNIHandles::make_local(env, result());
......@@ -1161,8 +1266,8 @@ JVM_ENTRY(jint, MHN_getMembers(JNIEnv *env, jobject igcls,
// %%% TO DO
}
int res = MethodHandles::find_MemberNames(k(), name, sig, mflags,
caller(), skip, results());
int res = MethodHandles::find_MemberNames(k, name, sig, mflags,
caller, skip, results);
// TO DO: expand at least some of the MemberNames, to avoid massive callbacks
return res;
}
......
......@@ -54,23 +54,23 @@ class MethodHandles: AllStatic {
static Handle resolve_MemberName(Handle mname, TRAPS); // compute vmtarget/vmindex from name/type
static void expand_MemberName(Handle mname, int suppress, TRAPS); // expand defc/name/type if missing
static Handle new_MemberName(TRAPS); // must be followed by init_MemberName
static oop init_MemberName(oop mname_oop, oop target_oop); // compute vmtarget/vmindex from target
static oop init_method_MemberName(oop mname_oop, Method* m, bool do_dispatch,
Klass* receiver_limit);
static oop init_field_MemberName(oop mname_oop, Klass* field_holder,
static oop init_MemberName(Handle mname_h, Handle target_h); // compute vmtarget/vmindex from target
static oop init_method_MemberName(Handle mname_h, Method* m, bool do_dispatch,
KlassHandle receiver_limit_h);
static oop init_field_MemberName(Handle mname_h, KlassHandle field_holder_h,
AccessFlags mods, oop type, oop name,
intptr_t offset, bool is_setter = false);
static Handle init_method_MemberName(oop mname_oop, CallInfo& info, TRAPS);
static Handle init_field_MemberName(oop mname_oop, FieldAccessInfo& info, TRAPS);
static Handle init_method_MemberName(Handle mname_h, CallInfo& info, TRAPS);
static Handle init_field_MemberName(Handle mname_h, FieldAccessInfo& info, TRAPS);
static int method_ref_kind(Method* m, bool do_dispatch_if_possible = true);
static int find_MemberNames(Klass* k, Symbol* name, Symbol* sig,
int mflags, Klass* caller,
int skip, objArrayOop results);
static int find_MemberNames(KlassHandle k, Symbol* name, Symbol* sig,
int mflags, KlassHandle caller,
int skip, objArrayHandle results);
// bit values for suppress argument to expand_MemberName:
enum { _suppress_defc = 1, _suppress_name = 2, _suppress_type = 4 };
// Generate MethodHandles adapters.
static void generate_adapters();
static void generate_adapters();
// Called from MethodHandlesAdapterGenerator.
static address generate_method_handle_interpreter_entry(MacroAssembler* _masm, vmIntrinsics::ID iid);
......@@ -230,4 +230,27 @@ public:
void generate();
};
//------------------------------------------------------------------------------
// MemberNameTable
//
class MemberNameTable : public GrowableArray<jweak> {
public:
MemberNameTable();
~MemberNameTable();
void add_member_name(jweak mem_name_ref);
private:
int find_member_name(oop mem_name);
#if INCLUDE_JVMTI
public:
// RedefineClasses() API support:
// If a MemberName refers to old_method then update it
// to refer to new_method.
void adjust_method_entries(Method** old_methods, Method** new_methods,
int methods_length, bool *trace_name_printed);
private:
oop find_member_name_by_method(Method* old_method);
#endif // INCLUDE_JVMTI
};
#endif // SHARE_VM_PRIMS_METHODHANDLES_HPP
......@@ -1901,7 +1901,7 @@ bool Arguments::check_vm_args_consistency() {
// Divide by bucket size to prevent a large size from causing rollover when
// calculating amount of memory needed to be allocated for the String table.
status = status && verify_interval(StringTableSize, defaultStringTableSize,
status = status && verify_interval(StringTableSize, minimumStringTableSize,
(max_uintx / StringTable::bucket_size()), "StringTable size");
if (MinHeapFreeRatio > MaxHeapFreeRatio) {
......
......@@ -46,6 +46,7 @@ Mutex* VMStatistic_lock = NULL;
Mutex* JNIGlobalHandle_lock = NULL;
Mutex* JNIHandleBlockFreeList_lock = NULL;
Mutex* JNICachedItableIndex_lock = NULL;
Mutex* MemberNameTable_lock = NULL;
Mutex* JmethodIdCreation_lock = NULL;
Mutex* JfieldIdCreation_lock = NULL;
Monitor* JNICritical_lock = NULL;
......@@ -252,6 +253,7 @@ void mutex_init() {
def(Heap_lock , Monitor, nonleaf+1, false);
def(JfieldIdCreation_lock , Mutex , nonleaf+1, true ); // jfieldID, Used in VM_Operation
def(JNICachedItableIndex_lock , Mutex , nonleaf+1, false); // Used to cache an itable index during JNI invoke
def(MemberNameTable_lock , Mutex , nonleaf+1, false); // Used to protect MemberNameTable
def(CompiledIC_lock , Mutex , nonleaf+2, false); // locks VtableStubs_lock, InlineCacheBuffer_lock
def(CompileTaskAlloc_lock , Mutex , nonleaf+2, true );
......
......@@ -51,6 +51,7 @@ extern Mutex* VMStatistic_lock; // a lock used to guard statist
extern Mutex* JNIGlobalHandle_lock; // a lock on creating JNI global handles
extern Mutex* JNIHandleBlockFreeList_lock; // a lock on the JNI handle block free list
extern Mutex* JNICachedItableIndex_lock; // a lock on caching an itable index during JNI invoke
extern Mutex* MemberNameTable_lock; // a lock on the MemberNameTable updates
extern Mutex* JmethodIdCreation_lock; // a lock on creating JNI method identifiers
extern Mutex* JfieldIdCreation_lock; // a lock on creating JNI static field identifiers
extern Monitor* JNICritical_lock; // a lock used while entering and exiting JNI critical regions, allows GC to sometimes get in
......
......@@ -2126,7 +2126,7 @@ JVM_ENTRY(jint, jmm_DumpHeap0(JNIEnv *env, jstring outputfile, jboolean live))
THROW_MSG_(vmSymbols::java_lang_NullPointerException(),
"Output file name cannot be null.", -1);
}
char* name = java_lang_String::as_utf8_string(on);
char* name = java_lang_String::as_platform_dependent_str(on, CHECK_(-1));
if (name == NULL) {
THROW_MSG_(vmSymbols::java_lang_NullPointerException(),
"Output file name cannot be null.", -1);
......
......@@ -133,7 +133,7 @@ typedef struct _memType2Name {
// This class aggregates malloc'd records by memory type
class MallocMem : public _ValueObj {
class MallocMem VALUE_OBJ_CLASS_SPEC {
private:
MEMFLAGS _type;
......@@ -211,7 +211,7 @@ class ArenaMem : public MallocMem {
};
// This class aggregates virtual memory by its memory type
class VMMem : public _ValueObj {
class VMMem VALUE_OBJ_CLASS_SPEC {
private:
MEMFLAGS _type;
......@@ -296,7 +296,7 @@ class BaselineComparisonReporter;
* aggregates memory usage by callsites when detail tracking
* is on.
*/
class MemBaseline : public _ValueObj {
class MemBaseline VALUE_OBJ_CLASS_SPEC {
friend class BaselineReporter;
friend class BaselineComparisonReporter;
......
......@@ -89,7 +89,7 @@ class SequenceGenerator : AllStatic {
* the memory pointer either points to a malloc'd
* memory block, or a mmap'd memory block
*/
class MemPointer : public _ValueObj {
class MemPointer VALUE_OBJ_CLASS_SPEC {
public:
MemPointer(): _addr(0) { }
MemPointer(address addr): _addr(addr) { }
......
......@@ -308,7 +308,7 @@ class VMRecordIterator : public MemPointerArrayIterator {
}
};
class StagingArea : public _ValueObj {
class StagingArea VALUE_OBJ_CLASS_SPEC {
private:
MemPointerArray* _malloc_data;
MemPointerArray* _vm_data;
......
......@@ -32,7 +32,7 @@
// Maximum MAX_GENERATIONS generation data can be tracked.
#define MAX_GENERATIONS 512
class GenerationData : public _ValueObj {
class GenerationData VALUE_OBJ_CLASS_SPEC {
private:
int _number_of_classes;
MemRecorder* _recorder_list;
......
......@@ -328,9 +328,10 @@ const int max_method_code_size = 64*K - 1; // JVM spec, 2nd ed. section 4.8.1 (
//----------------------------------------------------------------------------------------------------
// Minimum StringTableSize value
// Default and minimum StringTableSize values
const int defaultStringTableSize=1009;
const int defaultStringTableSize = NOT_LP64(1009) LP64_ONLY(60013);
const int minimumStringTableSize=1009;
//----------------------------------------------------------------------------------------------------
......
/*
* Copyright (c) 2013, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8011901
* @summary instruct xaddL_no_res shouldn't allow 64 bit constants.
* @run main/othervm -XX:-BackgroundCompilation Test8011901
*
*/
import java.lang.reflect.*;
import sun.misc.*;
public class Test8011901 {
private long ctl;
private static final sun.misc.Unsafe U;
private static final long CTL;
static {
try {
Field unsafe = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
unsafe.setAccessible(true);
U = (sun.misc.Unsafe) unsafe.get(null);
CTL = U.objectFieldOffset(Test8011901.class.getDeclaredField("ctl"));
} catch (Exception e) {
throw new Error(e);
}
}
public static void main(String[] args) {
for(int c = 0; c < 20000; c++) {
new Test8011901().makeTest();
}
System.out.println("Test Passed");
}
public static final long EXPECTED = 1L << 42;
public void makeTest() {
U.getAndAddLong(this, CTL, EXPECTED);
if (ctl != EXPECTED) {
throw new RuntimeException("Test failed. Expected: " + EXPECTED + ", but got = " + ctl);
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册