mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-23 20:44:41 +02:00
Merge
This commit is contained in:
commit
3b4f167e54
332 changed files with 5475 additions and 3385 deletions
|
@ -89,6 +89,27 @@ void VM_Version::initialize() {
|
|||
_supports_cx8 = has_v9();
|
||||
_supports_atomic_getset4 = true; // swap instruction
|
||||
|
||||
// There are Fujitsu Sparc64 CPUs which support blk_init as well so
|
||||
// we have to take this check out of the 'is_niagara()' block below.
|
||||
if (has_blk_init()) {
|
||||
// When using CMS or G1, we cannot use memset() in BOT updates
|
||||
// because the sun4v/CMT version in libc_psr uses BIS which
|
||||
// exposes "phantom zeros" to concurrent readers. See 6948537.
|
||||
if (FLAG_IS_DEFAULT(UseMemSetInBOT) && (UseConcMarkSweepGC || UseG1GC)) {
|
||||
FLAG_SET_DEFAULT(UseMemSetInBOT, false);
|
||||
}
|
||||
// Issue a stern warning if the user has explicitly set
|
||||
// UseMemSetInBOT (it is known to cause issues), but allow
|
||||
// use for experimentation and debugging.
|
||||
if (UseConcMarkSweepGC || UseG1GC) {
|
||||
if (UseMemSetInBOT) {
|
||||
assert(!FLAG_IS_DEFAULT(UseMemSetInBOT), "Error");
|
||||
warning("Experimental flag -XX:+UseMemSetInBOT is known to cause instability"
|
||||
" on sun4v; please understand that you are using at your own risk!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_niagara()) {
|
||||
// Indirect branch is the same cost as direct
|
||||
if (FLAG_IS_DEFAULT(UseInlineCaches)) {
|
||||
|
@ -98,12 +119,6 @@ void VM_Version::initialize() {
|
|||
if (FLAG_IS_DEFAULT(OptoLoopAlignment)) {
|
||||
FLAG_SET_DEFAULT(OptoLoopAlignment, 4);
|
||||
}
|
||||
// When using CMS or G1, we cannot use memset() in BOT updates
|
||||
// because the sun4v/CMT version in libc_psr uses BIS which
|
||||
// exposes "phantom zeros" to concurrent readers. See 6948537.
|
||||
if (FLAG_IS_DEFAULT(UseMemSetInBOT) && (UseConcMarkSweepGC || UseG1GC)) {
|
||||
FLAG_SET_DEFAULT(UseMemSetInBOT, false);
|
||||
}
|
||||
#ifdef _LP64
|
||||
// 32-bit oops don't make sense for the 64-bit VM on sparc
|
||||
// since the 32-bit VM has the same registers and smaller objects.
|
||||
|
|
|
@ -94,7 +94,13 @@ protected:
|
|||
static bool is_M_family(int features) { return (features & M_family_m) != 0; }
|
||||
static bool is_T_family(int features) { return (features & T_family_m) != 0; }
|
||||
static bool is_niagara() { return is_T_family(_features); }
|
||||
DEBUG_ONLY( static bool is_niagara(int features) { return (features & sun4v_m) != 0; } )
|
||||
#ifdef ASSERT
|
||||
static bool is_niagara(int features) {
|
||||
// 'sun4v_m' may be defined on both Sun/Oracle Sparc CPUs as well as
|
||||
// on Fujitsu Sparc64 CPUs, but only Sun/Oracle Sparcs can be 'niagaras'.
|
||||
return (features & sun4v_m) != 0 && (features & sparc64_family_m) == 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Returns true if it is niagara1 (T1).
|
||||
static bool is_T1_model(int features) { return is_T_family(features) && ((features & T1_model_m) != 0); }
|
||||
|
|
|
@ -1719,10 +1719,12 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
|||
|
||||
BarrierSet* bs = Universe::heap()->barrier_set();
|
||||
CardTableModRefBS* ct = (CardTableModRefBS*)bs;
|
||||
assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
|
||||
|
||||
Label done;
|
||||
Label runtime;
|
||||
|
||||
// At this point we know new_value is non-NULL and the new_value crosses regsion.
|
||||
// At this point we know new_value is non-NULL and the new_value crosses regions.
|
||||
// Must check to see if card is already dirty
|
||||
|
||||
const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread);
|
||||
|
@ -1735,26 +1737,17 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
|||
__ push(rax);
|
||||
__ push(rcx);
|
||||
|
||||
NOT_LP64(__ get_thread(thread);)
|
||||
ExternalAddress cardtable((address)ct->byte_map_base);
|
||||
assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
|
||||
|
||||
const Register cardtable = rax;
|
||||
const Register card_addr = rcx;
|
||||
#ifdef _LP64
|
||||
const Register tmp = rscratch1;
|
||||
f.load_argument(0, card_addr);
|
||||
__ shrq(card_addr, CardTableModRefBS::card_shift);
|
||||
__ lea(tmp, cardtable);
|
||||
// get the address of the card
|
||||
__ addq(card_addr, tmp);
|
||||
#else
|
||||
const Register card_index = rcx;
|
||||
f.load_argument(0, card_index);
|
||||
__ shrl(card_index, CardTableModRefBS::card_shift);
|
||||
|
||||
Address index(noreg, card_index, Address::times_1);
|
||||
__ leal(card_addr, __ as_Address(ArrayAddress(cardtable, index)));
|
||||
#endif
|
||||
f.load_argument(0, card_addr);
|
||||
__ shrptr(card_addr, CardTableModRefBS::card_shift);
|
||||
// Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT
|
||||
// a valid address and therefore is not properly handled by the relocation code.
|
||||
__ movptr(cardtable, (intptr_t)ct->byte_map_base);
|
||||
__ addptr(card_addr, cardtable);
|
||||
|
||||
NOT_LP64(__ get_thread(thread);)
|
||||
|
||||
__ cmpb(Address(card_addr, 0), (int)G1SATBCardTableModRefBS::g1_young_card_val());
|
||||
__ jcc(Assembler::equal, done);
|
||||
|
|
|
@ -3354,6 +3354,8 @@ void MacroAssembler::g1_write_barrier_post(Register store_addr,
|
|||
|
||||
BarrierSet* bs = Universe::heap()->barrier_set();
|
||||
CardTableModRefBS* ct = (CardTableModRefBS*)bs;
|
||||
assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
|
||||
|
||||
Label done;
|
||||
Label runtime;
|
||||
|
||||
|
@ -3371,28 +3373,16 @@ void MacroAssembler::g1_write_barrier_post(Register store_addr,
|
|||
|
||||
// storing region crossing non-NULL, is card already dirty?
|
||||
|
||||
ExternalAddress cardtable((address) ct->byte_map_base);
|
||||
assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
|
||||
#ifdef _LP64
|
||||
const Register card_addr = tmp;
|
||||
const Register cardtable = tmp2;
|
||||
|
||||
movq(card_addr, store_addr);
|
||||
shrq(card_addr, CardTableModRefBS::card_shift);
|
||||
movptr(card_addr, store_addr);
|
||||
shrptr(card_addr, CardTableModRefBS::card_shift);
|
||||
// Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT
|
||||
// a valid address and therefore is not properly handled by the relocation code.
|
||||
movptr(cardtable, (intptr_t)ct->byte_map_base);
|
||||
addptr(card_addr, cardtable);
|
||||
|
||||
lea(tmp2, cardtable);
|
||||
|
||||
// get the address of the card
|
||||
addq(card_addr, tmp2);
|
||||
#else
|
||||
const Register card_index = tmp;
|
||||
|
||||
movl(card_index, store_addr);
|
||||
shrl(card_index, CardTableModRefBS::card_shift);
|
||||
|
||||
Address index(noreg, card_index, Address::times_1);
|
||||
const Register card_addr = tmp;
|
||||
lea(card_addr, as_Address(ArrayAddress(cardtable, index)));
|
||||
#endif
|
||||
cmpb(Address(card_addr, 0), (int)G1SATBCardTableModRefBS::g1_young_card_val());
|
||||
jcc(Assembler::equal, done);
|
||||
|
||||
|
@ -3416,7 +3406,7 @@ void MacroAssembler::g1_write_barrier_post(Register store_addr,
|
|||
movq(Address(tmp2, 0), card_addr);
|
||||
#else
|
||||
addl(tmp2, queue_index);
|
||||
movl(Address(tmp2, 0), card_index);
|
||||
movl(Address(tmp2, 0), card_addr);
|
||||
#endif
|
||||
jmp(done);
|
||||
|
||||
|
@ -3468,25 +3458,19 @@ void MacroAssembler::store_check_part_2(Register obj) {
|
|||
|
||||
// The calculation for byte_map_base is as follows:
|
||||
// byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift);
|
||||
// So this essentially converts an address to a displacement and
|
||||
// it will never need to be relocated. On 64bit however the value may be too
|
||||
// large for a 32bit displacement
|
||||
|
||||
// So this essentially converts an address to a displacement and it will
|
||||
// never need to be relocated. On 64bit however the value may be too
|
||||
// large for a 32bit displacement.
|
||||
intptr_t disp = (intptr_t) ct->byte_map_base;
|
||||
if (is_simm32(disp)) {
|
||||
Address cardtable(noreg, obj, Address::times_1, disp);
|
||||
movb(cardtable, 0);
|
||||
} else {
|
||||
// By doing it as an ExternalAddress disp could be converted to a rip-relative
|
||||
// displacement and done in a single instruction given favorable mapping and
|
||||
// a smarter version of as_Address. Worst case it is two instructions which
|
||||
// is no worse off then loading disp into a register and doing as a simple
|
||||
// Address() as above.
|
||||
// We can't do as ExternalAddress as the only style since if disp == 0 we'll
|
||||
// assert since NULL isn't acceptable in a reloci (see 6644928). In any case
|
||||
// in some cases we'll get a single instruction version.
|
||||
|
||||
ExternalAddress cardtable((address)disp);
|
||||
// By doing it as an ExternalAddress 'disp' could be converted to a rip-relative
|
||||
// displacement and done in a single instruction given favorable mapping and a
|
||||
// smarter version of as_Address. However, 'ExternalAddress' generates a relocation
|
||||
// entry and that entry is not properly handled by the relocation code.
|
||||
AddressLiteral cardtable((address)ct->byte_map_base, relocInfo::none);
|
||||
Address index(noreg, obj, Address::times_1);
|
||||
movb(as_Address(ArrayAddress(cardtable, index)), 0);
|
||||
}
|
||||
|
|
|
@ -625,13 +625,13 @@ static GrowableArray<EmptyVtableSlot*>* find_empty_vtable_slots(
|
|||
while (super != NULL) {
|
||||
for (int i = 0; i < super->methods()->length(); ++i) {
|
||||
Method* m = super->methods()->at(i);
|
||||
if (m->is_overpass()) {
|
||||
if (m->is_overpass() || m->is_static()) {
|
||||
// m is a method that would have been a miranda if not for the
|
||||
// default method processing that occurred on behalf of our superclass,
|
||||
// so it's a method we want to re-examine in this new context. That is,
|
||||
// unless we have a real implementation of it in the current class.
|
||||
Method* impl = klass->lookup_method(m->name(), m->signature());
|
||||
if (impl == NULL || impl->is_overpass()) {
|
||||
if (impl == NULL || impl->is_overpass() || impl->is_static()) {
|
||||
if (!already_in_vtable_slots(slots, m)) {
|
||||
slots->append(new EmptyVtableSlot(m));
|
||||
}
|
||||
|
@ -648,7 +648,7 @@ static GrowableArray<EmptyVtableSlot*>* find_empty_vtable_slots(
|
|||
// so it's a method we want to re-examine in this new context. That is,
|
||||
// unless we have a real implementation of it in the current class.
|
||||
Method* impl = klass->lookup_method(m->name(), m->signature());
|
||||
if (impl == NULL || impl->is_overpass()) {
|
||||
if (impl == NULL || impl->is_overpass() || impl->is_static()) {
|
||||
if (!already_in_vtable_slots(slots, m)) {
|
||||
slots->append(new EmptyVtableSlot(m));
|
||||
}
|
||||
|
|
|
@ -66,29 +66,10 @@ void MarkSweep::AdjustKlassClosure::do_klass(Klass* klass) {
|
|||
klass->oops_do(&MarkSweep::adjust_pointer_closure);
|
||||
}
|
||||
|
||||
void MarkSweep::follow_klass(Klass* klass) {
|
||||
ClassLoaderData* cld = klass->class_loader_data();
|
||||
// The actual processing of the klass is done when we
|
||||
// traverse the list of Klasses in the class loader data.
|
||||
MarkSweep::follow_class_loader(cld);
|
||||
}
|
||||
|
||||
void MarkSweep::adjust_klass(Klass* klass) {
|
||||
ClassLoaderData* cld = klass->class_loader_data();
|
||||
// The actual processing of the klass is done when we
|
||||
// traverse the list of Klasses in the class loader data.
|
||||
MarkSweep::adjust_class_loader(cld);
|
||||
}
|
||||
|
||||
void MarkSweep::follow_class_loader(ClassLoaderData* cld) {
|
||||
cld->oops_do(&MarkSweep::mark_and_push_closure, &MarkSweep::follow_klass_closure, true);
|
||||
}
|
||||
|
||||
void MarkSweep::adjust_class_loader(ClassLoaderData* cld) {
|
||||
cld->oops_do(&MarkSweep::adjust_pointer_closure, &MarkSweep::adjust_klass_closure, true);
|
||||
}
|
||||
|
||||
|
||||
void MarkSweep::follow_stack() {
|
||||
do {
|
||||
while (!_marking_stack.is_empty()) {
|
||||
|
|
|
@ -172,10 +172,8 @@ class MarkSweep : AllStatic {
|
|||
static void follow_stack(); // Empty marking stack.
|
||||
|
||||
static void follow_klass(Klass* klass);
|
||||
static void adjust_klass(Klass* klass);
|
||||
|
||||
static void follow_class_loader(ClassLoaderData* cld);
|
||||
static void adjust_class_loader(ClassLoaderData* cld);
|
||||
|
||||
static void preserve_mark(oop p, markOop mark);
|
||||
// Save the mark word so it can be restored later
|
||||
|
|
|
@ -44,6 +44,11 @@ inline void MarkSweep::mark_object(oop obj) {
|
|||
}
|
||||
}
|
||||
|
||||
inline void MarkSweep::follow_klass(Klass* klass) {
|
||||
oop op = klass->klass_holder();
|
||||
MarkSweep::mark_and_push(&op);
|
||||
}
|
||||
|
||||
template <class T> inline void MarkSweep::follow_root(T* p) {
|
||||
assert(!Universe::heap()->is_in_reserved(p),
|
||||
"roots shouldn't be things within the heap");
|
||||
|
|
|
@ -242,7 +242,7 @@ void LinkResolver::resolve_klass(KlassHandle& result, constantPoolHandle pool, i
|
|||
|
||||
// Look up method in klasses, including static methods
|
||||
// Then look up local default methods
|
||||
void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
|
||||
void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, TRAPS) {
|
||||
Method* result_oop = klass->uncached_lookup_method(name, signature);
|
||||
if (result_oop == NULL) {
|
||||
Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods();
|
||||
|
@ -251,7 +251,7 @@ void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle kl
|
|||
}
|
||||
}
|
||||
|
||||
if (EnableInvokeDynamic && result_oop != NULL) {
|
||||
if (checkpolymorphism && EnableInvokeDynamic && result_oop != NULL) {
|
||||
vmIntrinsics::ID iid = result_oop->intrinsic_id();
|
||||
if (MethodHandles::is_signature_polymorphic(iid)) {
|
||||
// Do not link directly to these. The VM must produce a synthetic one using lookup_polymorphic_method.
|
||||
|
@ -267,8 +267,8 @@ void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, Klass
|
|||
Method* result_oop = klass->uncached_lookup_method(name, signature);
|
||||
result = methodHandle(THREAD, result_oop);
|
||||
while (!result.is_null() && result->is_static() && result->method_holder()->super() != NULL) {
|
||||
klass = KlassHandle(THREAD, result->method_holder()->super());
|
||||
result = methodHandle(THREAD, klass->uncached_lookup_method(name, signature));
|
||||
KlassHandle super_klass = KlassHandle(THREAD, result->method_holder()->super());
|
||||
result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature));
|
||||
}
|
||||
|
||||
if (result.is_null()) {
|
||||
|
@ -503,11 +503,14 @@ void LinkResolver::resolve_method_statically(methodHandle& resolved_method, Klas
|
|||
}
|
||||
|
||||
if (code == Bytecodes::_invokeinterface) {
|
||||
resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
|
||||
resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
|
||||
} else if (code == Bytecodes::_invokevirtual) {
|
||||
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
|
||||
} else {
|
||||
} else if (!resolved_klass->is_interface()) {
|
||||
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK);
|
||||
} else {
|
||||
bool nostatics = (code == Bytecodes::_invokestatic) ? false : true;
|
||||
resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, nostatics, CHECK);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -528,7 +531,7 @@ void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle res
|
|||
}
|
||||
|
||||
// 2. lookup method in resolved klass and its super klasses
|
||||
lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK);
|
||||
lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, true, CHECK);
|
||||
|
||||
if (resolved_method.is_null()) { // not found in the class hierarchy
|
||||
// 3. lookup method in all the interfaces implemented by the resolved klass
|
||||
|
@ -612,7 +615,8 @@ void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
|
|||
Symbol* method_name,
|
||||
Symbol* method_signature,
|
||||
KlassHandle current_klass,
|
||||
bool check_access, TRAPS) {
|
||||
bool check_access,
|
||||
bool nostatics, TRAPS) {
|
||||
|
||||
// check if klass is interface
|
||||
if (!resolved_klass->is_interface()) {
|
||||
|
@ -623,7 +627,8 @@ void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
|
|||
}
|
||||
|
||||
// lookup method in this interface or its super, java.lang.Object
|
||||
lookup_instance_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK);
|
||||
// JDK8: also look for static methods
|
||||
lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, CHECK);
|
||||
|
||||
if (resolved_method.is_null()) {
|
||||
// lookup method in all the super-interfaces
|
||||
|
@ -638,6 +643,16 @@ void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
|
|||
}
|
||||
}
|
||||
|
||||
if (nostatics && resolved_method->is_static()) {
|
||||
ResourceMark rm(THREAD);
|
||||
char buf[200];
|
||||
jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
|
||||
resolved_method->name(),
|
||||
resolved_method->signature()));
|
||||
THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
|
||||
}
|
||||
|
||||
|
||||
if (check_access) {
|
||||
// JDK8 adds non-public interface methods, and accessability check requirement
|
||||
assert(current_klass.not_null() , "current_klass should not be null");
|
||||
|
@ -864,7 +879,11 @@ void LinkResolver::linktime_resolve_static_method(methodHandle& resolved_method,
|
|||
Symbol* method_name, Symbol* method_signature,
|
||||
KlassHandle current_klass, bool check_access, TRAPS) {
|
||||
|
||||
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
|
||||
if (!resolved_klass->is_interface()) {
|
||||
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
|
||||
} else {
|
||||
resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
|
||||
}
|
||||
assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
|
||||
|
||||
// check if static
|
||||
|
@ -898,7 +917,11 @@ void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method
|
|||
// and the selected method is recalculated relative to the direct superclass
|
||||
// superinterface.method, which explicitly does not check shadowing
|
||||
|
||||
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
|
||||
if (!resolved_klass->is_interface()) {
|
||||
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
|
||||
} else {
|
||||
resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, true, CHECK);
|
||||
}
|
||||
|
||||
// check if method name is <init>, that it is found in same klass as static type
|
||||
if (resolved_method->name() == vmSymbols::object_initializer_name() &&
|
||||
|
@ -1219,7 +1242,7 @@ void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, KlassHa
|
|||
void LinkResolver::linktime_resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name,
|
||||
Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) {
|
||||
// normal interface method resolution
|
||||
resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
|
||||
resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, true, CHECK);
|
||||
|
||||
assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
|
||||
assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
|
||||
|
|
|
@ -124,7 +124,7 @@ class LinkResolver: AllStatic {
|
|||
friend class klassItable;
|
||||
|
||||
private:
|
||||
static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
|
||||
static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, 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,
|
||||
|
@ -134,7 +134,7 @@ class LinkResolver: AllStatic {
|
|||
|
||||
static void resolve_pool (KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS);
|
||||
|
||||
static void resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, 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 void linktime_resolve_static_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
|
||||
|
|
|
@ -1431,6 +1431,17 @@ Method* InstanceKlass::find_method(Symbol* name, Symbol* signature) const {
|
|||
return InstanceKlass::find_method(methods(), name, signature);
|
||||
}
|
||||
|
||||
// find_instance_method looks up the name/signature in the local methods array
|
||||
// and skips over static methods
|
||||
Method* InstanceKlass::find_instance_method(
|
||||
Array<Method*>* methods, Symbol* name, Symbol* signature) {
|
||||
Method* meth = InstanceKlass::find_method(methods, name, signature);
|
||||
if (meth != NULL && meth->is_static()) {
|
||||
meth = NULL;
|
||||
}
|
||||
return meth;
|
||||
}
|
||||
|
||||
// find_method looks up the name/signature in the local methods array
|
||||
Method* InstanceKlass::find_method(
|
||||
Array<Method*>* methods, Symbol* name, Symbol* signature) {
|
||||
|
@ -2173,7 +2184,6 @@ int InstanceKlass::oop_adjust_pointers(oop obj) {
|
|||
obj, \
|
||||
MarkSweep::adjust_pointer(p), \
|
||||
assert_is_in)
|
||||
MarkSweep::adjust_klass(obj->klass());
|
||||
return size;
|
||||
}
|
||||
|
||||
|
|
|
@ -515,6 +515,7 @@ class InstanceKlass: public Klass {
|
|||
// find a local method (returns NULL if not found)
|
||||
Method* find_method(Symbol* name, Symbol* signature) const;
|
||||
static Method* find_method(Array<Method*>* methods, Symbol* name, Symbol* signature);
|
||||
static Method* find_instance_method(Array<Method*>* methods, Symbol* name, Symbol* signature);
|
||||
|
||||
// find a local method index in default_methods (returns -1 if not found)
|
||||
static int find_method_index(Array<Method*>* methods, Symbol* name, Symbol* signature);
|
||||
|
|
|
@ -155,7 +155,13 @@ void InstanceMirrorKlass::oop_follow_contents(oop obj) {
|
|||
// Follow the klass field in the mirror.
|
||||
Klass* klass = java_lang_Class::as_Klass(obj);
|
||||
if (klass != NULL) {
|
||||
MarkSweep::follow_klass(klass);
|
||||
// For anonymous classes we need to handle the class loader data,
|
||||
// otherwise it won't be claimed and can be unloaded.
|
||||
if (klass->oop_is_instance() && InstanceKlass::cast(klass)->is_anonymous()) {
|
||||
MarkSweep::follow_class_loader(klass->class_loader_data());
|
||||
} else {
|
||||
MarkSweep::follow_klass(klass);
|
||||
}
|
||||
} else {
|
||||
// If klass is NULL then this a mirror for a primitive type.
|
||||
// We don't have to follow them, since they are handled as strong
|
||||
|
@ -196,17 +202,6 @@ int InstanceMirrorKlass::oop_adjust_pointers(oop obj) {
|
|||
int size = oop_size(obj);
|
||||
InstanceKlass::oop_adjust_pointers(obj);
|
||||
|
||||
// Follow the klass field in the mirror.
|
||||
Klass* klass = java_lang_Class::as_Klass(obj);
|
||||
if (klass != NULL) {
|
||||
MarkSweep::adjust_klass(klass);
|
||||
} else {
|
||||
// If klass is NULL then this a mirror for a primitive type.
|
||||
// We don't have to follow them, since they are handled as strong
|
||||
// roots in Universe::oops_do.
|
||||
assert(java_lang_Class::is_primitive(obj), "Sanity check");
|
||||
}
|
||||
|
||||
InstanceMirrorKlass_OOP_ITERATE( \
|
||||
start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \
|
||||
MarkSweep::adjust_pointer(p), \
|
||||
|
|
|
@ -665,6 +665,11 @@ bool klassVtable::is_miranda_entry_at(int i) {
|
|||
|
||||
// check if a method is a miranda method, given a class's methods table,
|
||||
// its default_method table and its super
|
||||
// Miranda methods are calculated twice:
|
||||
// first: before vtable size calculation: including abstract and default
|
||||
// This is seen by default method creation
|
||||
// Second: recalculated during vtable initialization: only abstract
|
||||
// This is seen by link resolution and selection.
|
||||
// "miranda" means not static, not defined by this class.
|
||||
// private methods in interfaces do not belong in the miranda list.
|
||||
// the caller must make sure that the method belongs to an interface implemented by the class
|
||||
|
@ -678,7 +683,8 @@ bool klassVtable::is_miranda(Method* m, Array<Method*>* class_methods,
|
|||
}
|
||||
Symbol* name = m->name();
|
||||
Symbol* signature = m->signature();
|
||||
if (InstanceKlass::find_method(class_methods, name, signature) == NULL) {
|
||||
|
||||
if (InstanceKlass::find_instance_method(class_methods, name, signature) == NULL) {
|
||||
// did not find it in the method table of the current class
|
||||
if ((default_methods == NULL) ||
|
||||
InstanceKlass::find_method(default_methods, name, signature) == NULL) {
|
||||
|
@ -688,6 +694,12 @@ bool klassVtable::is_miranda(Method* m, Array<Method*>* class_methods,
|
|||
}
|
||||
|
||||
Method* mo = InstanceKlass::cast(super)->lookup_method(name, signature);
|
||||
while (mo != NULL && mo->access_flags().is_static()
|
||||
&& mo->method_holder() != NULL
|
||||
&& mo->method_holder()->super() != NULL)
|
||||
{
|
||||
mo = mo->method_holder()->super()->uncached_lookup_method(name, signature);
|
||||
}
|
||||
if (mo == NULL || mo->access_flags().is_private() ) {
|
||||
// super class hierarchy does not implement it or protection is different
|
||||
return true;
|
||||
|
|
|
@ -569,7 +569,6 @@ int ObjArrayKlass::oop_adjust_pointers(oop obj) {
|
|||
// Get size before changing pointers.
|
||||
// Don't call size() or oop_size() since that is a virtual call.
|
||||
int size = a->object_size();
|
||||
MarkSweep::adjust_klass(a->klass());
|
||||
ObjArrayKlass_OOP_ITERATE(a, p, MarkSweep::adjust_pointer(p))
|
||||
return size;
|
||||
}
|
||||
|
|
|
@ -647,7 +647,7 @@
|
|||
diagnostic(bool, OptimizeExpensiveOps, true, \
|
||||
"Find best control for expensive operations") \
|
||||
\
|
||||
product(bool, UseMathExactIntrinsics, true, \
|
||||
experimental(bool, UseMathExactIntrinsics, false, \
|
||||
"Enables intrinsification of various java.lang.Math functions") \
|
||||
\
|
||||
experimental(bool, ReplaceInParentMaps, false, \
|
||||
|
|
|
@ -269,11 +269,20 @@ class VM_GetCurrentLocation : public VM_Operation {
|
|||
void doit() {
|
||||
ResourceMark rmark; // _thread != Thread::current()
|
||||
RegisterMap rm(_thread, false);
|
||||
javaVFrame* vf = _thread->last_java_vframe(&rm);
|
||||
assert(vf != NULL, "must have last java frame");
|
||||
Method* method = vf->method();
|
||||
_method_id = method->jmethod_id();
|
||||
_bci = vf->bci();
|
||||
// There can be a race condition between a VM_Operation reaching a safepoint
|
||||
// and the target thread exiting from Java execution.
|
||||
// We must recheck the last Java frame still exists.
|
||||
if (_thread->has_last_Java_frame()) {
|
||||
javaVFrame* vf = _thread->last_java_vframe(&rm);
|
||||
assert(vf != NULL, "must have last java frame");
|
||||
Method* method = vf->method();
|
||||
_method_id = method->jmethod_id();
|
||||
_bci = vf->bci();
|
||||
} else {
|
||||
// Clear current location as the target thread has no Java frames anymore.
|
||||
_method_id = (jmethodID)NULL;
|
||||
_bci = 0;
|
||||
}
|
||||
}
|
||||
void get_current_location(jmethodID *method_id, int *bci) {
|
||||
*method_id = _method_id;
|
||||
|
|
|
@ -299,7 +299,7 @@ public:
|
|||
static inline bool is_breakpoint(address bcp);
|
||||
|
||||
static void oops_do(OopClosure* f);
|
||||
static void metadata_do(void f(Metadata*));
|
||||
static void metadata_do(void f(Metadata*)) NOT_JVMTI_RETURN;
|
||||
static void gc_epilogue();
|
||||
};
|
||||
|
||||
|
|
|
@ -2281,18 +2281,6 @@ bool Arguments::check_vm_args_consistency() {
|
|||
status = status && verify_percentage(MarkSweepDeadRatio, "MarkSweepDeadRatio");
|
||||
|
||||
status = status && verify_min_value(MarkSweepAlwaysCompactCount, 1, "MarkSweepAlwaysCompactCount");
|
||||
#ifdef SPARC
|
||||
if (UseConcMarkSweepGC || UseG1GC) {
|
||||
// Issue a stern warning if the user has explicitly set
|
||||
// UseMemSetInBOT (it is known to cause issues), but allow
|
||||
// use for experimentation and debugging.
|
||||
if (VM_Version::is_sun4v() && UseMemSetInBOT) {
|
||||
assert(!FLAG_IS_DEFAULT(UseMemSetInBOT), "Error");
|
||||
warning("Experimental flag -XX:+UseMemSetInBOT is known to cause instability"
|
||||
" on sun4v; please understand that you are using at your own risk!");
|
||||
}
|
||||
}
|
||||
#endif // SPARC
|
||||
|
||||
if (PrintNMTStatistics) {
|
||||
#if INCLUDE_NMT
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue