# HG changeset patch # User ccheung # Date 1382649639 14400 # Node ID b3a4d4279fa3f77f6db55d990a513256286ec03f # Parent 2036c97e3af0d9bb73a3528872b3456a91052623# Parent b658cfe3585725fcefaf3b8da108d68175ee3703 Merge diff -r 2036c97e3af0 -r b3a4d4279fa3 agent/src/os/linux/ps_core.c --- a/agent/src/os/linux/ps_core.c Mon Oct 21 22:36:43 2013 -0400 +++ b/agent/src/os/linux/ps_core.c Thu Oct 24 17:20:39 2013 -0400 @@ -719,7 +719,7 @@ ELF_PHDR* phbuf; ELF_PHDR* lib_php = NULL; - int page_size=sysconf(_SC_PAGE_SIZE); + int page_size = sysconf(_SC_PAGE_SIZE); if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL) { return false; @@ -736,26 +736,29 @@ if (existing_map == NULL){ if (add_map_info(ph, lib_fd, lib_php->p_offset, - target_vaddr, lib_php->p_filesz) == NULL) { + target_vaddr, lib_php->p_memsz) == NULL) { goto err; } } else { + // Coredump stores value of p_memsz elf field + // rounded up to page boundary. + if ((existing_map->memsz != page_size) && (existing_map->fd != lib_fd) && - (existing_map->memsz != lib_php->p_filesz)){ + (ROUNDUP(existing_map->memsz, page_size) != ROUNDUP(lib_php->p_memsz, page_size))) { - print_debug("address conflict @ 0x%lx (size = %ld, flags = %d\n)", - target_vaddr, lib_php->p_filesz, lib_php->p_flags); + print_debug("address conflict @ 0x%lx (existing map size = %ld, size = %ld, flags = %d)\n", + target_vaddr, existing_map->memsz, lib_php->p_memsz, lib_php->p_flags); goto err; } /* replace PT_LOAD segment with library segment */ print_debug("overwrote with new address mapping (memsz %ld -> %ld)\n", - existing_map->memsz, lib_php->p_filesz); + existing_map->memsz, ROUNDUP(lib_php->p_memsz, page_size)); existing_map->fd = lib_fd; existing_map->offset = lib_php->p_offset; - existing_map->memsz = lib_php->p_filesz; + existing_map->memsz = ROUNDUP(lib_php->p_memsz, page_size); } } diff -r 2036c97e3af0 -r b3a4d4279fa3 agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java --- a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java Mon Oct 21 22:36:43 2013 -0400 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java Thu Oct 24 17:20:39 2013 -0400 @@ -51,6 +51,7 @@ private static int HAS_GENERIC_SIGNATURE; private static int HAS_METHOD_ANNOTATIONS; private static int HAS_PARAMETER_ANNOTATIONS; + private static int HAS_METHOD_PARAMETERS; private static int HAS_DEFAULT_ANNOTATIONS; private static int HAS_TYPE_ANNOTATIONS; @@ -70,6 +71,7 @@ HAS_GENERIC_SIGNATURE = db.lookupIntConstant("ConstMethod::_has_generic_signature").intValue(); HAS_METHOD_ANNOTATIONS = db.lookupIntConstant("ConstMethod::_has_method_annotations").intValue(); HAS_PARAMETER_ANNOTATIONS = db.lookupIntConstant("ConstMethod::_has_parameter_annotations").intValue(); + HAS_METHOD_PARAMETERS = db.lookupIntConstant("ConstMethod::_has_method_parameters").intValue(); HAS_DEFAULT_ANNOTATIONS = db.lookupIntConstant("ConstMethod::_has_default_annotations").intValue(); HAS_TYPE_ANNOTATIONS = db.lookupIntConstant("ConstMethod::_has_type_annotations").intValue(); @@ -85,6 +87,9 @@ // start of byte code bytecodeOffset = type.getSize(); + type = db.lookupType("MethodParametersElement"); + methodParametersElementSize = type.getSize(); + type = db.lookupType("CheckedExceptionElement"); checkedExceptionElementSize = type.getSize(); @@ -113,7 +118,7 @@ // start of bytecode private static long bytecodeOffset; - + private static long methodParametersElementSize; private static long checkedExceptionElementSize; private static long localVariableTableElementSize; private static long exceptionTableElementSize; @@ -387,6 +392,10 @@ return ret; } + private boolean hasMethodParameters() { + return (getFlags() & HAS_METHOD_PARAMETERS) != 0; + } + private boolean hasGenericSignature() { return (getFlags() & HAS_GENERIC_SIGNATURE) != 0; } @@ -442,11 +451,41 @@ return offsetOfLastU2Element(); } - private long offsetOfCheckedExceptionsLength() { + private long offsetOfMethodParametersLength() { + if (Assert.ASSERTS_ENABLED) { + Assert.that(hasMethodParameters(), "should only be called if table is present"); + } return hasGenericSignature() ? offsetOfLastU2Element() - sizeofShort : offsetOfLastU2Element(); } + private int getMethodParametersLength() { + if (hasMethodParameters()) + return (int) getAddress().getCIntegerAt(offsetOfMethodParametersLength(), 2, true); + else + return 0; + } + + // Offset of start of checked exceptions + private long offsetOfMethodParameters() { + long offset = offsetOfMethodParametersLength(); + long length = getMethodParametersLength(); + if (Assert.ASSERTS_ENABLED) { + Assert.that(length > 0, "should only be called if method parameter information is present"); + } + offset -= length * methodParametersElementSize; + return offset; + } + + private long offsetOfCheckedExceptionsLength() { + if (hasMethodParameters()) + return offsetOfMethodParameters() - sizeofShort; + else { + return hasGenericSignature() ? offsetOfLastU2Element() - sizeofShort : + offsetOfLastU2Element(); + } + } + private int getCheckedExceptionsLength() { if (hasCheckedExceptions()) { return (int) getAddress().getCIntegerAt(offsetOfCheckedExceptionsLength(), 2, true); @@ -496,6 +535,8 @@ return offsetOfExceptionTable() - sizeofShort; } else if (hasCheckedExceptions()) { return offsetOfCheckedExceptions() - sizeofShort; + } else if (hasMethodParameters()) { + return offsetOfMethodParameters() - sizeofShort; } else { return hasGenericSignature() ? offsetOfLastU2Element() - sizeofShort : offsetOfLastU2Element(); @@ -526,6 +567,8 @@ } if (hasCheckedExceptions()) { return offsetOfCheckedExceptions() - sizeofShort; + } else if (hasMethodParameters()) { + return offsetOfMethodParameters() - sizeofShort; } else { return hasGenericSignature() ? offsetOfLastU2Element() - sizeofShort : offsetOfLastU2Element(); diff -r 2036c97e3af0 -r b3a4d4279fa3 agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java Mon Oct 21 22:36:43 2013 -0400 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java Thu Oct 24 17:20:39 2013 -0400 @@ -51,8 +51,7 @@ public static void main(String[] args) { ClassLoaderStats cls = new ClassLoaderStats(); - cls.start(args); - cls.stop(); + cls.execute(args); } private static class ClassData { diff -r 2036c97e3af0 -r b3a4d4279fa3 agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java Mon Oct 21 22:36:43 2013 -0400 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java Thu Oct 24 17:20:39 2013 -0400 @@ -54,8 +54,7 @@ public static void main(String[] args) { FinalizerInfo finfo = new FinalizerInfo(); - finfo.start(args); - finfo.stop(); + finfo.execute(args); } public void run() { diff -r 2036c97e3af0 -r b3a4d4279fa3 agent/src/share/classes/sun/jvm/hotspot/tools/FlagDumper.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/FlagDumper.java Mon Oct 21 22:36:43 2013 -0400 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/FlagDumper.java Thu Oct 24 17:20:39 2013 -0400 @@ -54,7 +54,6 @@ public static void main(String[] args) { FlagDumper fd = new FlagDumper(); - fd.start(args); - fd.stop(); + fd.execute(args); } } diff -r 2036c97e3af0 -r b3a4d4279fa3 agent/src/share/classes/sun/jvm/hotspot/tools/HeapDumper.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/HeapDumper.java Mon Oct 21 22:36:43 2013 -0400 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/HeapDumper.java Thu Oct 24 17:20:39 2013 -0400 @@ -80,8 +80,7 @@ } HeapDumper dumper = new HeapDumper(file); - dumper.start(args); - dumper.stop(); + dumper.execute(args); } } diff -r 2036c97e3af0 -r b3a4d4279fa3 agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java Mon Oct 21 22:36:43 2013 -0400 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java Thu Oct 24 17:20:39 2013 -0400 @@ -46,8 +46,7 @@ public static void main(String[] args) { HeapSummary hs = new HeapSummary(); - hs.start(args); - hs.stop(); + hs.execute(args); } public void run() { diff -r 2036c97e3af0 -r b3a4d4279fa3 agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java Mon Oct 21 22:36:43 2013 -0400 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java Thu Oct 24 17:20:39 2013 -0400 @@ -134,8 +134,7 @@ } JInfo jinfo = new JInfo(mode); - jinfo.start(args); - jinfo.stop(); + jinfo.execute(args); } private void printVMFlags() { diff -r 2036c97e3af0 -r b3a4d4279fa3 agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java Mon Oct 21 22:36:43 2013 -0400 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java Thu Oct 24 17:20:39 2013 -0400 @@ -136,7 +136,9 @@ mode = MODE_HEAP_GRAPH_GXL; } else { System.err.println("unknown heap format:" + format); - return; + + // Exit with error status + System.exit(1); } } else { copyArgs = false; @@ -153,8 +155,7 @@ } JMap jmap = new JMap(mode); - jmap.start(args); - jmap.stop(); + jmap.execute(args); } public boolean writeHeapHprofBin(String fileName) { diff -r 2036c97e3af0 -r b3a4d4279fa3 agent/src/share/classes/sun/jvm/hotspot/tools/JSnap.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/JSnap.java Mon Oct 21 22:36:43 2013 -0400 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/JSnap.java Thu Oct 24 17:20:39 2013 -0400 @@ -64,7 +64,6 @@ public static void main(String[] args) { JSnap js = new JSnap(); - js.start(args); - js.stop(); + js.execute(args); } } diff -r 2036c97e3af0 -r b3a4d4279fa3 agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java Mon Oct 21 22:36:43 2013 -0400 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java Thu Oct 24 17:20:39 2013 -0400 @@ -89,8 +89,7 @@ } JStack jstack = new JStack(mixedMode, concurrentLocks); - jstack.start(args); - jstack.stop(); + jstack.execute(args); } private boolean mixedMode; diff -r 2036c97e3af0 -r b3a4d4279fa3 agent/src/share/classes/sun/jvm/hotspot/tools/ObjectHistogram.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/ObjectHistogram.java Mon Oct 21 22:36:43 2013 -0400 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/ObjectHistogram.java Thu Oct 24 17:20:39 2013 -0400 @@ -61,7 +61,6 @@ public static void main(String[] args) { ObjectHistogram oh = new ObjectHistogram(); - oh.start(args); - oh.stop(); + oh.execute(args); } } diff -r 2036c97e3af0 -r b3a4d4279fa3 agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java Mon Oct 21 22:36:43 2013 -0400 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java Thu Oct 24 17:20:39 2013 -0400 @@ -69,7 +69,6 @@ public static void main(String[] args) throws Exception { PMap t = new PMap(); - t.start(args); - t.stop(); + t.execute(args); } } diff -r 2036c97e3af0 -r b3a4d4279fa3 agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java Mon Oct 21 22:36:43 2013 -0400 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java Thu Oct 24 17:20:39 2013 -0400 @@ -182,8 +182,7 @@ public static void main(String[] args) throws Exception { PStack t = new PStack(); - t.start(args); - t.stop(); + t.execute(args); } // -- Internals only below this point diff -r 2036c97e3af0 -r b3a4d4279fa3 agent/src/share/classes/sun/jvm/hotspot/tools/StackTrace.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/StackTrace.java Mon Oct 21 22:36:43 2013 -0400 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/StackTrace.java Thu Oct 24 17:20:39 2013 -0400 @@ -137,8 +137,7 @@ public static void main(String[] args) { StackTrace st = new StackTrace(); - st.start(args); - st.stop(); + st.execute(args); } private boolean verbose; diff -r 2036c97e3af0 -r b3a4d4279fa3 agent/src/share/classes/sun/jvm/hotspot/tools/SysPropsDumper.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/SysPropsDumper.java Mon Oct 21 22:36:43 2013 -0400 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/SysPropsDumper.java Thu Oct 24 17:20:39 2013 -0400 @@ -58,7 +58,6 @@ public static void main(String[] args) { SysPropsDumper pd = new SysPropsDumper(); - pd.start(args); - pd.stop(); + pd.execute(args); } } diff -r 2036c97e3af0 -r b3a4d4279fa3 agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java Mon Oct 21 22:36:43 2013 -0400 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java Thu Oct 24 17:20:39 2013 -0400 @@ -26,6 +26,7 @@ import java.io.PrintStream; import java.util.Hashtable; + import sun.jvm.hotspot.*; import sun.jvm.hotspot.runtime.*; import sun.jvm.hotspot.debugger.*; @@ -105,26 +106,44 @@ public static void main(String[] args) { obj = new ; - obj.start(args); + obj.execute(args); } */ - protected void stop() { + protected void execute(String[] args) { + int returnStatus = 1; + + try { + returnStatus = start(args); + } finally { + stop(); + } + + // Exit with 0 or 1 + System.exit(returnStatus); + } + + public void stop() { if (agent != null) { agent.detach(); } } - protected void start(String[] args) { + private int start(String[] args) { + if ((args.length < 1) || (args.length > 2)) { usage(); - return; + return 1; } // Attempt to handle -h or -help or some invalid flag - if (args[0].startsWith("-")) { + if (args[0].startsWith("-h")) { usage(); + return 0; + } else if (args[0].startsWith("-")) { + usage(); + return 1; } PrintStream err = System.err; @@ -154,6 +173,7 @@ default: usage(); + return 1; } agent = new HotSpotAgent(); @@ -191,15 +211,16 @@ break; } if (e.getMessage() != null) { - err.print(e.getMessage()); + err.println(e.getMessage()); e.printStackTrace(); } err.println(); - return; + return 1; } err.println("Debugger attached successfully."); startInternal(); + return 0; } // When using an existing JVMDebugger. diff -r 2036c97e3af0 -r b3a4d4279fa3 agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java Mon Oct 21 22:36:43 2013 -0400 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java Thu Oct 24 17:20:39 2013 -0400 @@ -177,7 +177,6 @@ public static void main(String[] args) { ClassDump cd = new ClassDump(); - cd.start(args); - cd.stop(); + cd.execute(args); } } diff -r 2036c97e3af0 -r b3a4d4279fa3 agent/src/share/classes/sun/jvm/hotspot/tools/soql/JSDB.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/soql/JSDB.java Mon Oct 21 22:36:43 2013 -0400 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/soql/JSDB.java Thu Oct 24 17:20:39 2013 -0400 @@ -42,8 +42,7 @@ public static void main(String[] args) { JSDB jsdb = new JSDB(); - jsdb.start(args); - jsdb.stop(); + jsdb.execute(args); } public void run() { diff -r 2036c97e3af0 -r b3a4d4279fa3 agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java Mon Oct 21 22:36:43 2013 -0400 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java Thu Oct 24 17:20:39 2013 -0400 @@ -40,8 +40,7 @@ public class SOQL extends Tool { public static void main(String[] args) { SOQL soql = new SOQL(); - soql.start(args); - soql.stop(); + soql.execute(args); } public SOQL() { diff -r 2036c97e3af0 -r b3a4d4279fa3 make/windows/makefiles/trace.make --- a/make/windows/makefiles/trace.make Mon Oct 21 22:36:43 2013 -0400 +++ b/make/windows/makefiles/trace.make Thu Oct 24 17:20:39 2013 -0400 @@ -40,8 +40,7 @@ traceEventIds.hpp \ traceTypes.hpp - -!if "$(OPENJDK)" != "true" +!if EXISTS($(TraceAltSrcDir)) TraceGeneratedNames = $(TraceGeneratedNames) \ traceRequestables.hpp \ traceEventControl.hpp \ @@ -56,7 +55,7 @@ $(TraceOutDir)/traceEventIds.hpp \ $(TraceOutDir)/traceTypes.hpp -!if "$(OPENJDK)" != "true" +!if EXISTS($(TraceAltSrcDir)) TraceGeneratedFiles = $(TraceGeneratedFiles) \ $(TraceOutDir)/traceRequestables.hpp \ $(TraceOutDir)/traceEventControl.hpp \ @@ -68,7 +67,7 @@ XML_DEPS = $(TraceSrcDir)/trace.xml $(TraceSrcDir)/tracetypes.xml \ $(TraceSrcDir)/trace.dtd $(TraceSrcDir)/xinclude.mod -!if "$(OPENJDK)" != "true" +!if EXISTS($(TraceAltSrcDir)) XML_DEPS = $(XML_DEPS) $(TraceAltSrcDir)/traceevents.xml !endif @@ -87,7 +86,7 @@ @echo Generating $@ @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceSrcDir)/traceTypes.xsl -OUT $(TraceOutDir)/traceTypes.hpp -!if "$(OPENJDK)" == "true" +!if !EXISTS($(TraceAltSrcDir)) $(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS) @echo Generating OpenJDK $@ diff -r 2036c97e3af0 -r b3a4d4279fa3 src/share/vm/ci/ciEnv.cpp --- a/src/share/vm/ci/ciEnv.cpp Mon Oct 21 22:36:43 2013 -0400 +++ b/src/share/vm/ci/ciEnv.cpp Thu Oct 24 17:20:39 2013 -0400 @@ -483,8 +483,7 @@ { // We have to lock the cpool to keep the oop from being resolved // while we are accessing it. - oop cplock = cpool->lock(); - ObjectLocker ol(cplock, THREAD, cplock != NULL); + MonitorLockerEx ml(cpool->lock()); constantTag tag = cpool->tag_at(index); if (tag.is_klass()) { // The klass has been inserted into the constant pool diff -r 2036c97e3af0 -r b3a4d4279fa3 src/share/vm/interpreter/linkResolver.cpp --- a/src/share/vm/interpreter/linkResolver.cpp Mon Oct 21 22:36:43 2013 -0400 +++ b/src/share/vm/interpreter/linkResolver.cpp Thu Oct 24 17:20:39 2013 -0400 @@ -1,6 +1,5 @@ /* * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 1997, 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 @@ -265,7 +264,7 @@ void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { Method* result_oop = klass->uncached_lookup_method(name, signature); result = methodHandle(THREAD, result_oop); - while (!result.is_null() && result->is_static()) { + 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)); } @@ -419,18 +418,28 @@ AccessFlags flags = sel_method->access_flags(); - // Special case: arrays always override "clone". JVMS 2.15. + // Special case #1: 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 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'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 need to change "protected" to "public". - assert(flags.is_protected(), "clone not protected?"); + assert(flags.is_protected(), "clone or finalize not protected?"); jint new_flags = flags.as_int(); new_flags = new_flags & (~JVM_ACC_PROTECTED); new_flags = new_flags | JVM_ACC_PUBLIC; diff -r 2036c97e3af0 -r b3a4d4279fa3 src/share/vm/oops/constantPool.cpp --- a/src/share/vm/oops/constantPool.cpp Mon Oct 21 22:36:43 2013 -0400 +++ b/src/share/vm/oops/constantPool.cpp Thu Oct 24 17:20:39 2013 -0400 @@ -40,7 +40,6 @@ #include "runtime/init.hpp" #include "runtime/javaCalls.hpp" #include "runtime/signature.hpp" -#include "runtime/synchronizer.hpp" #include "runtime/vframe.hpp" ConstantPool* ConstantPool::allocate(ClassLoaderData* loader_data, int length, TRAPS) { @@ -70,6 +69,7 @@ // only set to non-zero if constant pool is merged by RedefineClasses set_version(0); + set_lock(new Monitor(Monitor::nonleaf + 2, "A constant pool lock")); // initialize tag array int length = tags->length(); @@ -95,6 +95,9 @@ void ConstantPool::release_C_heap_structures() { // walk constant pool and decrement symbol reference counts unreference_symbols(); + + delete _lock; + set_lock(NULL); } objArrayOop ConstantPool::resolved_references() const { @@ -151,6 +154,9 @@ ClassLoaderData* loader_data = pool_holder()->class_loader_data(); set_resolved_references(loader_data->add_handle(refs_handle)); } + + // Also need to recreate the mutex. Make sure this matches the constructor + set_lock(new Monitor(Monitor::nonleaf + 2, "A constant pool lock")); } } @@ -161,23 +167,7 @@ set_resolved_reference_length( resolved_references() != NULL ? resolved_references()->length() : 0); set_resolved_references(NULL); -} - -oop ConstantPool::lock() { - if (_pool_holder) { - // We re-use the _pool_holder's init_lock to reduce footprint. - // Notes on deadlocks: - // [1] This lock is a Java oop, so it can be recursively locked by - // the same thread without self-deadlocks. - // [2] Deadlock will happen if there is circular dependency between - // the of two Java classes. However, in this case, - // the deadlock would have happened long before we reach - // ConstantPool::lock(), so reusing init_lock does not - // increase the possibility of deadlock. - return _pool_holder->init_lock(); - } else { - return NULL; - } + set_lock(NULL); } int ConstantPool::cp_to_object_index(int cp_index) { @@ -211,9 +201,7 @@ Symbol* name = NULL; Handle loader; - { - oop cplock = this_oop->lock(); - ObjectLocker ol(cplock , THREAD, cplock != NULL); + { MonitorLockerEx ml(this_oop->lock()); if (this_oop->tag_at(which).is_unresolved_klass()) { if (this_oop->tag_at(which).is_unresolved_klass_in_error()) { @@ -260,8 +248,7 @@ bool throw_orig_error = false; { - oop cplock = this_oop->lock(); - ObjectLocker ol(cplock, THREAD, cplock != NULL); + MonitorLockerEx ml(this_oop->lock()); // some other thread has beaten us and has resolved the class. if (this_oop->tag_at(which).is_klass()) { @@ -329,8 +316,7 @@ } return k(); } else { - oop cplock = this_oop->lock(); - ObjectLocker ol(cplock, THREAD, cplock != NULL); + MonitorLockerEx ml(this_oop->lock()); // Only updated constant pool - if it is resolved. do_resolve = this_oop->tag_at(which).is_unresolved_klass(); if (do_resolve) { @@ -600,8 +586,7 @@ int tag, TRAPS) { ResourceMark rm; Symbol* error = PENDING_EXCEPTION->klass()->name(); - oop cplock = this_oop->lock(); - ObjectLocker ol(cplock, THREAD, cplock != NULL); // lock cpool to change tag. + MonitorLockerEx ml(this_oop->lock()); // lock cpool to change tag. int error_tag = (tag == JVM_CONSTANT_MethodHandle) ? JVM_CONSTANT_MethodHandleInError : JVM_CONSTANT_MethodTypeInError; @@ -762,8 +747,7 @@ if (cache_index >= 0) { // Cache the oop here also. Handle result_handle(THREAD, result_oop); - oop cplock = this_oop->lock(); - ObjectLocker ol(cplock, THREAD, cplock != NULL); // don't know if we really need this + MonitorLockerEx ml(this_oop->lock()); // don't know if we really need this oop result = this_oop->resolved_references()->obj_at(cache_index); // Benign race condition: resolved_references may already be filled in while we were trying to lock. // The important thing here is that all threads pick up the same result. diff -r 2036c97e3af0 -r b3a4d4279fa3 src/share/vm/oops/constantPool.hpp --- a/src/share/vm/oops/constantPool.hpp Mon Oct 21 22:36:43 2013 -0400 +++ b/src/share/vm/oops/constantPool.hpp Thu Oct 24 17:20:39 2013 -0400 @@ -111,6 +111,7 @@ int _version; } _saved; + Monitor* _lock; void set_tags(Array* tags) { _tags = tags; } void tag_at_put(int which, jbyte t) { tags()->at_put(which, t); } @@ -843,17 +844,8 @@ void set_resolved_reference_length(int length) { _saved._resolved_reference_length = length; } int resolved_reference_length() const { return _saved._resolved_reference_length; } - - // lock() may return null -- constant pool updates may happen before this lock is - // initialized, because the _pool_holder has not been fully initialized and - // has not been registered into the system dictionary. In this case, no other - // thread can be modifying this constantpool, so no synchronization is - // necessary. - // - // Use cplock() like this: - // oop cplock = cp->lock(); - // ObjectLocker ol(cplock , THREAD, cplock != NULL); - oop lock(); + void set_lock(Monitor* lock) { _lock = lock; } + Monitor* lock() { return _lock; } // Decrease ref counts of symbols that are in the constant pool // when the holder class is unloaded diff -r 2036c97e3af0 -r b3a4d4279fa3 src/share/vm/oops/cpCache.cpp --- a/src/share/vm/oops/cpCache.cpp Mon Oct 21 22:36:43 2013 -0400 +++ b/src/share/vm/oops/cpCache.cpp Thu Oct 24 17:20:39 2013 -0400 @@ -284,8 +284,7 @@ // the lock, so that when the losing writer returns, he can use the linked // cache entry. - oop cplock = cpool->lock(); - ObjectLocker ol(cplock, Thread::current(), cplock != NULL); + MonitorLockerEx ml(cpool->lock()); if (!is_f1_null()) { return; } diff -r 2036c97e3af0 -r b3a4d4279fa3 src/share/vm/oops/instanceKlass.cpp --- a/src/share/vm/oops/instanceKlass.cpp Mon Oct 21 22:36:43 2013 -0400 +++ b/src/share/vm/oops/instanceKlass.cpp Thu Oct 24 17:20:39 2013 -0400 @@ -498,13 +498,27 @@ oop InstanceKlass::init_lock() const { // return the init lock from the mirror - return java_lang_Class::init_lock(java_mirror()); + oop lock = java_lang_Class::init_lock(java_mirror()); + assert((oop)lock != NULL || !is_not_initialized(), // initialized or in_error state + "only fully initialized state can have a null lock"); + return lock; +} + +// Set the initialization lock to null so the object can be GC'ed. Any racing +// threads to get this lock will see a null lock and will not lock. +// That's okay because they all check for initialized state after getting +// the lock and return. +void InstanceKlass::fence_and_clear_init_lock() { + // make sure previous stores are all done, notably the init_state. + OrderAccess::storestore(); + java_lang_Class::set_init_lock(java_mirror(), NULL); + assert(!is_not_initialized(), "class must be initialized now"); } void InstanceKlass::eager_initialize_impl(instanceKlassHandle this_oop) { EXCEPTION_MARK; oop init_lock = this_oop->init_lock(); - ObjectLocker ol(init_lock, THREAD); + ObjectLocker ol(init_lock, THREAD, init_lock != NULL); // abort if someone beat us to the initialization if (!this_oop->is_not_initialized()) return; // note: not equivalent to is_initialized() @@ -523,6 +537,7 @@ } else { // linking successfull, mark class as initialized this_oop->set_init_state (fully_initialized); + this_oop->fence_and_clear_init_lock(); // trace if (TraceClassInitialization) { ResourceMark rm(THREAD); @@ -649,7 +664,7 @@ // verification & rewriting { oop init_lock = this_oop->init_lock(); - ObjectLocker ol(init_lock, THREAD); + ObjectLocker ol(init_lock, THREAD, init_lock != NULL); // rewritten will have been set if loader constraint error found // on an earlier link attempt // don't verify or rewrite if already rewritten @@ -772,7 +787,7 @@ // Step 1 { oop init_lock = this_oop->init_lock(); - ObjectLocker ol(init_lock, THREAD); + ObjectLocker ol(init_lock, THREAD, init_lock != NULL); Thread *self = THREAD; // it's passed the current thread @@ -920,8 +935,9 @@ void InstanceKlass::set_initialization_state_and_notify_impl(instanceKlassHandle this_oop, ClassState state, TRAPS) { oop init_lock = this_oop->init_lock(); - ObjectLocker ol(init_lock, THREAD); + ObjectLocker ol(init_lock, THREAD, init_lock != NULL); this_oop->set_init_state(state); + this_oop->fence_and_clear_init_lock(); ol.notify_all(CHECK); } diff -r 2036c97e3af0 -r b3a4d4279fa3 src/share/vm/oops/instanceKlass.hpp --- a/src/share/vm/oops/instanceKlass.hpp Mon Oct 21 22:36:43 2013 -0400 +++ b/src/share/vm/oops/instanceKlass.hpp Thu Oct 24 17:20:39 2013 -0400 @@ -1023,6 +1023,7 @@ // It has to be an object not a Mutex because it's held through java calls. oop init_lock() const; private: + void fence_and_clear_init_lock(); // Static methods that are used to implement member methods where an exposed this pointer // is needed due to possible GCs diff -r 2036c97e3af0 -r b3a4d4279fa3 src/share/vm/prims/jvmtiEnv.cpp --- a/src/share/vm/prims/jvmtiEnv.cpp Mon Oct 21 22:36:43 2013 -0400 +++ b/src/share/vm/prims/jvmtiEnv.cpp Thu Oct 24 17:20:39 2013 -0400 @@ -259,8 +259,7 @@ // bytes to the InstanceKlass here because they have not been // validated and we're not at a safepoint. constantPoolHandle constants(current_thread, ikh->constants()); - oop cplock = constants->lock(); - ObjectLocker ol(cplock, current_thread, cplock != NULL); // lock constant pool while we query it + MonitorLockerEx ml(constants->lock()); // lock constant pool while we query it JvmtiClassFileReconstituter reconstituter(ikh); if (reconstituter.get_error() != JVMTI_ERROR_NONE) { @@ -2418,8 +2417,7 @@ instanceKlassHandle ikh(thread, k_oop); constantPoolHandle constants(thread, ikh->constants()); - oop cplock = constants->lock(); - ObjectLocker ol(cplock, thread, cplock != NULL); // lock constant pool while we query it + MonitorLockerEx ml(constants->lock()); // lock constant pool while we query it JvmtiConstantPoolReconstituter reconstituter(ikh); if (reconstituter.get_error() != JVMTI_ERROR_NONE) { diff -r 2036c97e3af0 -r b3a4d4279fa3 src/share/vm/runtime/vmStructs.cpp --- a/src/share/vm/runtime/vmStructs.cpp Mon Oct 21 22:36:43 2013 -0400 +++ b/src/share/vm/runtime/vmStructs.cpp Thu Oct 24 17:20:39 2013 -0400 @@ -1464,6 +1464,7 @@ declare_toplevel_type(CheckedExceptionElement) \ declare_toplevel_type(LocalVariableTableElement) \ declare_toplevel_type(ExceptionTableElement) \ + declare_toplevel_type(MethodParametersElement) \ \ declare_toplevel_type(ClassLoaderData) \ declare_toplevel_type(ClassLoaderDataGraph) \ @@ -2336,6 +2337,7 @@ declare_constant(ConstMethod::_has_localvariable_table) \ declare_constant(ConstMethod::_has_exception_table) \ declare_constant(ConstMethod::_has_generic_signature) \ + declare_constant(ConstMethod::_has_method_parameters) \ declare_constant(ConstMethod::_has_method_annotations) \ declare_constant(ConstMethod::_has_parameter_annotations) \ declare_constant(ConstMethod::_has_default_annotations) \ diff -r 2036c97e3af0 -r b3a4d4279fa3 src/share/vm/services/diagnosticCommand.cpp --- a/src/share/vm/services/diagnosticCommand.cpp Mon Oct 21 22:36:43 2013 -0400 +++ b/src/share/vm/services/diagnosticCommand.cpp Thu Oct 24 17:20:39 2013 -0400 @@ -505,7 +505,11 @@ _jdp_pause ("jdp.pause", - "set com.sun.management.jdp.pause", "INT", false) + "set com.sun.management.jdp.pause", "INT", false), + + _jdp_name + ("jdp.name", + "set com.sun.management.jdp.name", "STRING", false) { _dcmdparser.add_dcmd_option(&_config_file); @@ -527,6 +531,7 @@ _dcmdparser.add_dcmd_option(&_jdp_source_addr); _dcmdparser.add_dcmd_option(&_jdp_ttl); _dcmdparser.add_dcmd_option(&_jdp_pause); + _dcmdparser.add_dcmd_option(&_jdp_name); } @@ -596,6 +601,7 @@ PUT_OPTION(_jdp_source_addr); PUT_OPTION(_jdp_ttl); PUT_OPTION(_jdp_pause); + PUT_OPTION(_jdp_name); #undef PUT_OPTION diff -r 2036c97e3af0 -r b3a4d4279fa3 src/share/vm/services/diagnosticCommand.hpp --- a/src/share/vm/services/diagnosticCommand.hpp Mon Oct 21 22:36:43 2013 -0400 +++ b/src/share/vm/services/diagnosticCommand.hpp Thu Oct 24 17:20:39 2013 -0400 @@ -302,6 +302,7 @@ DCmdArgument _jdp_source_addr; DCmdArgument _jdp_ttl; DCmdArgument _jdp_pause; + DCmdArgument _jdp_name; public: JMXStartRemoteDCmd(outputStream *output, bool heap_allocated); diff -r 2036c97e3af0 -r b3a4d4279fa3 src/share/vm/trace/traceEventClasses.xsl --- a/src/share/vm/trace/traceEventClasses.xsl Mon Oct 21 22:36:43 2013 -0400 +++ b/src/share/vm/trace/traceEventClasses.xsl Thu Oct 24 17:20:39 2013 -0400 @@ -23,8 +23,8 @@ --> + - diff -r 2036c97e3af0 -r b3a4d4279fa3 src/share/vm/trace/traceEventIds.xsl --- a/src/share/vm/trace/traceEventIds.xsl Mon Oct 21 22:36:43 2013 -0400 +++ b/src/share/vm/trace/traceEventIds.xsl Thu Oct 24 17:20:39 2013 -0400 @@ -23,8 +23,8 @@ --> + - diff -r 2036c97e3af0 -r b3a4d4279fa3 src/share/vm/trace/traceTypes.xsl --- a/src/share/vm/trace/traceTypes.xsl Mon Oct 21 22:36:43 2013 -0400 +++ b/src/share/vm/trace/traceTypes.xsl Thu Oct 24 17:20:39 2013 -0400 @@ -23,8 +23,8 @@ --> + - diff -r 2036c97e3af0 -r b3a4d4279fa3 test/runtime/8024804/RegisterNatives.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/8024804/RegisterNatives.java Thu Oct 24 17:20:39 2013 -0400 @@ -0,0 +1,46 @@ +/* + * 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 8024804 + * @summary registerNatives() interface resolution should receive IAE + * @run main RegisterNatives + */ +public class RegisterNatives { + interface I { void registerNatives(); } + interface J extends I {} + static class B implements J { public void registerNatives() { System.out.println("B"); } } + public static void main(String... args) { + System.out.println("Regression test for JDK-8024804, crash when InterfaceMethodref resolves to Object.registerNatives\n"); + J val = new B(); + 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 - no IAE resulted\n"); + System.exit(1); + } +} diff -r 2036c97e3af0 -r b3a4d4279fa3 test/runtime/8026394/InterfaceObjectTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/8026394/InterfaceObjectTest.java Thu Oct 24 17:20:39 2013 -0400 @@ -0,0 +1,69 @@ +/* + * 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 8026394 + * @summary clone() and finalize() interface resolution should not receive IAE + * @run main InterfaceObjectTest + */ +interface IClone extends Cloneable { + void finalize() throws Throwable; + Object clone(); +} + +interface ICloneExtend extends IClone { } + +public class InterfaceObjectTest implements ICloneExtend { + + public Object clone() { + System.out.println("In InterfaceObjectTest's clone() method\n"); + return null; + } + + public void finalize() throws Throwable { + try { + System.out.println("In InterfaceObjectTest's finalize() method\n"); + } catch (Throwable t) { + throw new AssertionError(t); + } + } + + public static void tryIt(ICloneExtend o1) { + try { + Object o2 = o1.clone(); + o1.finalize(); + } catch (Throwable t) { + if (t instanceof IllegalAccessError) { + System.out.println("TEST FAILS - IAE resulted\n"); + System.exit(1); + } + } + } + + public static void main(String[] args) { + InterfaceObjectTest o1 = new InterfaceObjectTest(); + tryIt(o1); + System.out.println("TEST PASSES - no IAE resulted\n"); + } +} diff -r 2036c97e3af0 -r b3a4d4279fa3 test/runtime/CommandLine/PrintGCApplicationConcurrentTime.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/CommandLine/PrintGCApplicationConcurrentTime.java Thu Oct 24 17:20:39 2013 -0400 @@ -0,0 +1,34 @@ +/* + * 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 8026041 + * @run main/othervm -XX:+PrintGCApplicationConcurrentTime -Xcomp PrintGCApplicationConcurrentTime + */ + +public class PrintGCApplicationConcurrentTime { + + public static void main(String args[]) throws Exception { + } +} diff -r 2036c97e3af0 -r b3a4d4279fa3 test/testlibrary/com/oracle/java/testlibrary/JDKToolLauncher.java --- a/test/testlibrary/com/oracle/java/testlibrary/JDKToolLauncher.java Mon Oct 21 22:36:43 2013 -0400 +++ b/test/testlibrary/com/oracle/java/testlibrary/JDKToolLauncher.java Thu Oct 24 17:20:39 2013 -0400 @@ -100,7 +100,7 @@ * @return The JDKToolLauncher instance */ public JDKToolLauncher addVMArg(String arg) { - vmArgs.add("-J" + arg); + vmArgs.add(arg); return this; } @@ -124,7 +124,10 @@ public String[] getCommand() { List command = new ArrayList(); command.add(executable); - command.addAll(vmArgs); + // Add -J in front of all vmArgs + for (String arg : vmArgs) { + command.add("-J" + arg); + } command.addAll(toolArgs); return command.toArray(new String[command.size()]); }