# HG changeset patch # User ehelin # Date 1386861224 -3600 # Node ID e3995ab443937d1bd542c9f405a2f2ac6ea63163 # Parent 9fbabcbb875b1c14726c0bd2e0942ebf826b73cd# Parent fa76dce60db72ecbf37448126500302d1e98e36b Merge diff -r fa76dce60db7 -r e3995ab44393 agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java --- a/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java Mon Dec 09 10:03:39 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java Thu Dec 12 16:13:44 2013 +0100 @@ -364,7 +364,7 @@ } catch (AddressException e) { // This is okay at the top of these regions - } + } catch (UnknownOopException e) { // This is okay at the top of these regions } @@ -373,7 +373,7 @@ visitor.epilogue(); } - private void addLiveRegions(List input, List output) { + private void addLiveRegions(String name, List input, List output) { for (Iterator itr = input.iterator(); itr.hasNext();) { MemRegion reg = (MemRegion) itr.next(); Address top = reg.end(); @@ -386,6 +386,9 @@ } output.add(top); output.add(bottom); + if (DEBUG) { + System.err.println("Live region: " + name + ": " + bottom + ", " + top); + } } } @@ -395,7 +398,7 @@ } public void doSpace(Space s) { - addLiveRegions(s.getLiveRegions(), liveRegions); + addLiveRegions(s.toString(), s.getLiveRegions(), liveRegions); } private List liveRegions; } @@ -426,11 +429,11 @@ ParallelScavengeHeap psh = (ParallelScavengeHeap) heap; PSYoungGen youngGen = psh.youngGen(); // Add eden space - addLiveRegions(youngGen.edenSpace().getLiveRegions(), liveRegions); + addLiveRegions("eden", youngGen.edenSpace().getLiveRegions(), liveRegions); // Add from-space but not to-space - addLiveRegions(youngGen.fromSpace().getLiveRegions(), liveRegions); + addLiveRegions("from", youngGen.fromSpace().getLiveRegions(), liveRegions); PSOldGen oldGen = psh.oldGen(); - addLiveRegions(oldGen.objectSpace().getLiveRegions(), liveRegions); + addLiveRegions("old ", oldGen.objectSpace().getLiveRegions(), liveRegions); } else if (heap instanceof G1CollectedHeap) { G1CollectedHeap g1h = (G1CollectedHeap) heap; g1h.heapRegionIterate(lrc); @@ -451,23 +454,27 @@ if (VM.getVM().getUseTLAB()) { for (JavaThread thread = VM.getVM().getThreads().first(); thread != null; thread = thread.next()) { - if (thread.isJavaThread()) { - ThreadLocalAllocBuffer tlab = thread.tlab(); - if (tlab.start() != null) { - if ((tlab.top() == null) || (tlab.end() == null)) { - System.err.print("Warning: skipping invalid TLAB for thread "); + ThreadLocalAllocBuffer tlab = thread.tlab(); + if (tlab.start() != null) { + if ((tlab.top() == null) || (tlab.end() == null)) { + System.err.print("Warning: skipping invalid TLAB for thread "); + thread.printThreadIDOn(System.err); + System.err.println(); + } else { + if (DEBUG) { + System.err.print("TLAB for " + thread.getThreadName() + ", #"); thread.printThreadIDOn(System.err); - System.err.println(); - } else { - // Go from: - // - below start() to start() - // - start() to top() - // - end() and above - liveRegions.add(tlab.start()); - liveRegions.add(tlab.start()); - liveRegions.add(tlab.top()); - liveRegions.add(tlab.hardEnd()); + System.err.print(": "); + tlab.printOn(System.err); } + // Go from: + // - below start() to start() + // - start() to top() + // - end() and above + liveRegions.add(tlab.start()); + liveRegions.add(tlab.start()); + liveRegions.add(tlab.top()); + liveRegions.add(tlab.hardEnd()); } } } @@ -480,6 +487,15 @@ Assert.that(liveRegions.size() % 2 == 0, "Must have even number of region boundaries"); } + if (DEBUG) { + System.err.println("liveRegions:"); + for (int i = 0; i < liveRegions.size(); i += 2) { + Address bottom = (Address) liveRegions.get(i); + Address top = (Address) liveRegions.get(i+1); + System.err.println(" " + bottom + " - " + top); + } + } + return liveRegions; } diff -r fa76dce60db7 -r e3995ab44393 agent/src/share/classes/sun/jvm/hotspot/runtime/ThreadLocalAllocBuffer.java --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/ThreadLocalAllocBuffer.java Mon Dec 09 10:03:39 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/ThreadLocalAllocBuffer.java Thu Dec 12 16:13:44 2013 +0100 @@ -109,6 +109,6 @@ public void printOn(PrintStream tty) { tty.println(" [" + start() + "," + - top() + "," + end() + ")"); + top() + "," + end() + ",{" + hardEnd() + "})"); } } diff -r fa76dce60db7 -r e3995ab44393 src/cpu/x86/vm/frame_x86.cpp --- a/src/cpu/x86/vm/frame_x86.cpp Mon Dec 09 10:03:39 2013 +0100 +++ b/src/cpu/x86/vm/frame_x86.cpp Thu Dec 12 16:13:44 2013 +0100 @@ -94,13 +94,6 @@ // other generic buffer blobs are more problematic so we just assume they are // ok. adapter blobs never have a frame complete and are never ok. - // check for a valid frame_size, otherwise we are unlikely to get a valid sender_pc - - if (!Interpreter::contains(_pc) && _cb->frame_size() <= 0) { - //assert(0, "Invalid frame_size"); - return false; - } - if (!_cb->is_frame_complete_at(_pc)) { if (_cb->is_nmethod() || _cb->is_adapter_blob() || _cb->is_runtime_stub()) { return false; @@ -144,6 +137,11 @@ // must be some sort of compiled/runtime frame // fp does not have to be safe (although it could be check for c1?) + // check for a valid frame_size, otherwise we are unlikely to get a valid sender_pc + if (_cb->frame_size() <= 0) { + return false; + } + sender_sp = _unextended_sp + _cb->frame_size(); // On Intel the return_address is always the word on the stack sender_pc = (address) *(sender_sp-1); diff -r fa76dce60db7 -r e3995ab44393 src/share/vm/interpreter/linkResolver.cpp --- a/src/share/vm/interpreter/linkResolver.cpp Mon Dec 09 10:03:39 2013 +0100 +++ b/src/share/vm/interpreter/linkResolver.cpp Thu Dec 12 16:13:44 2013 +0100 @@ -242,8 +242,20 @@ // 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, bool checkpolymorphism, TRAPS) { +void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, bool in_imethod_resolve, TRAPS) { Method* result_oop = klass->uncached_lookup_method(name, signature); + + // JDK 8, JVMS 5.4.3.4: Interface method resolution should + // ignore static and non-public methods of java.lang.Object, + // like clone, finalize, registerNatives. + if (in_imethod_resolve && + result_oop != NULL && + klass->is_interface() && + (result_oop->is_static() || !result_oop->is_public()) && + result_oop->method_holder() == SystemDictionary::Object_klass()) { + result_oop = NULL; + } + if (result_oop == NULL) { Array* default_methods = InstanceKlass::cast(klass())->default_methods(); if (default_methods != NULL) { @@ -420,28 +432,18 @@ AccessFlags flags = sel_method->access_flags(); - // Special case #1: arrays always override "clone". JVMS 2.15. + // Special case: arrays always override "clone". JVMS 2.15. // If the resolved klass is an array class, and the declaring class // is java.lang.Object and the method is "clone", set the flags // to public. - // Special case #2: If the resolved klass is an interface, and - // the declaring class is java.lang.Object, and the method is - // "clone" or "finalize", set the flags to public. If the - // resolved interface does not contain "clone" or "finalize" - // methods, the method/interface method resolution looks to - // the interface's super class, java.lang.Object. With JDK 8 - // interface accessability check requirement, special casing - // this scenario is necessary to avoid an IAE. // - // We'll check for each method name first and then java.lang.Object - // to best short-circuit out of these tests. - if (((sel_method->name() == vmSymbols::clone_name() && - (resolved_klass->oop_is_array() || resolved_klass->is_interface())) || - (sel_method->name() == vmSymbols::finalize_method_name() && - resolved_klass->is_interface())) && - sel_klass() == SystemDictionary::Object_klass()) { + // We'll check for the method name first, as that's most likely + // to be false (so we'll short-circuit out of these tests). + if (sel_method->name() == vmSymbols::clone_name() && + sel_klass() == SystemDictionary::Object_klass() && + resolved_klass->oop_is_array()) { // We need to change "protected" to "public". - assert(flags.is_protected(), "clone or finalize not protected?"); + assert(flags.is_protected(), "clone not protected?"); jint new_flags = flags.as_int(); new_flags = new_flags & (~JVM_ACC_PROTECTED); new_flags = new_flags | JVM_ACC_PUBLIC; @@ -531,7 +533,7 @@ } // 2. lookup method in resolved klass and its super klasses - lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, true, CHECK); + lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, true, false, CHECK); if (resolved_method.is_null()) { // not found in the class hierarchy // 3. lookup method in all the interfaces implemented by the resolved klass @@ -628,7 +630,7 @@ // lookup method in this interface or its super, java.lang.Object // JDK8: also look for static methods - lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, CHECK); + lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, true, CHECK); if (resolved_method.is_null()) { // lookup method in all the super-interfaces @@ -943,8 +945,17 @@ Klass *klass_to_check = !InstanceKlass::cast(current_klass())->is_anonymous() ? current_klass() : InstanceKlass::cast(current_klass())->host_klass(); + // As of the fix for 4486457 we disable verification for all of the + // dynamically-generated bytecodes associated with the 1.4 + // reflection implementation, not just those associated with + // sun/reflect/SerializationConstructorAccessor. + bool is_reflect = JDK_Version::is_gte_jdk14x_version() && + UseNewReflection && + klass_to_check->is_subclass_of( + SystemDictionary::reflect_MagicAccessorImpl_klass()); - if (!InstanceKlass::cast(klass_to_check)->is_same_or_direct_interface(resolved_klass())) { + if (!is_reflect && + !InstanceKlass::cast(klass_to_check)->is_same_or_direct_interface(resolved_klass())) { ResourceMark rm(THREAD); char buf[200]; jio_snprintf(buf, sizeof(buf), diff -r fa76dce60db7 -r e3995ab44393 src/share/vm/interpreter/linkResolver.hpp --- a/src/share/vm/interpreter/linkResolver.hpp Mon Dec 09 10:03:39 2013 +0100 +++ b/src/share/vm/interpreter/linkResolver.hpp Thu Dec 12 16:13:44 2013 +0100 @@ -124,7 +124,7 @@ friend class klassItable; private: - static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, TRAPS); + 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, diff -r fa76dce60db7 -r e3995ab44393 src/share/vm/runtime/reflection.cpp --- a/src/share/vm/runtime/reflection.cpp Mon Dec 09 10:03:39 2013 +0100 +++ b/src/share/vm/runtime/reflection.cpp Thu Dec 12 16:13:44 2013 +0100 @@ -537,15 +537,26 @@ return true; } + Klass* host_class = current_class; + while (host_class->oop_is_instance() && + InstanceKlass::cast(host_class)->is_anonymous()) { + Klass* next_host_class = InstanceKlass::cast(host_class)->host_klass(); + if (next_host_class == NULL) break; + host_class = next_host_class; + } + if (host_class == field_class) { + return true; + } + if (access.is_protected()) { if (!protected_restriction) { - // See if current_class is a subclass of field_class - if (current_class->is_subclass_of(field_class)) { + // See if current_class (or outermost host class) is a subclass of field_class + if (host_class->is_subclass_of(field_class)) { if (access.is_static() || // static fields are ok, see 6622385 current_class == resolved_class || field_class == resolved_class || - current_class->is_subclass_of(resolved_class) || - resolved_class->is_subclass_of(current_class)) { + host_class->is_subclass_of(resolved_class) || + resolved_class->is_subclass_of(host_class)) { return true; } } diff -r fa76dce60db7 -r e3995ab44393 test/runtime/8024804/RegisterNatives.java --- a/test/runtime/8024804/RegisterNatives.java Mon Dec 09 10:03:39 2013 +0100 +++ b/test/runtime/8024804/RegisterNatives.java Thu Dec 12 16:13:44 2013 +0100 @@ -22,10 +22,10 @@ */ /* - * @ignore 8028741 * @test * @bug 8024804 - * @summary registerNatives() interface resolution should receive IAE + * @bug 8028741 + * @summary interface method resolution should skip finding j.l.Object's registerNatives() and succeed in selecting class B's registerNatives() * @run main RegisterNatives */ public class RegisterNatives { @@ -38,10 +38,10 @@ try { val.registerNatives(); } catch (IllegalAccessError e) { - System.out.println("TEST PASSES - according to current JVM spec, IAE expected\n"); - return; + System.out.println("TEST FAILS - JDK 8 JVMS, static and non-public methods of j.l.Object should be ignored during interface method resolution\n"); + e.printStackTrace(); + throw e; } - System.out.println("TEST FAILS - no IAE resulted\n"); - System.exit(1); + System.out.println("TEST PASSES - no IAE resulted\n"); } }