From ec5d05699e7e3946478b4d5823e9663835c46306 Mon Sep 17 00:00:00 2001 From: Fredrik Arvidsson Date: Wed, 16 Oct 2013 09:20:23 +0200 Subject: [PATCH 01/11] 8025638: jmap returns 0 instead of 1 when it fails Re-factored some code handling return values and fails/errors during tool execution. Reviewed-by: sla, kevinw --- .../jvm/hotspot/tools/ClassLoaderStats.java | 3 +- .../sun/jvm/hotspot/tools/FinalizerInfo.java | 3 +- .../sun/jvm/hotspot/tools/FlagDumper.java | 3 +- .../sun/jvm/hotspot/tools/HeapDumper.java | 3 +- .../sun/jvm/hotspot/tools/HeapSummary.java | 3 +- .../classes/sun/jvm/hotspot/tools/JInfo.java | 3 +- .../classes/sun/jvm/hotspot/tools/JMap.java | 7 ++-- .../classes/sun/jvm/hotspot/tools/JSnap.java | 3 +- .../classes/sun/jvm/hotspot/tools/JStack.java | 3 +- .../jvm/hotspot/tools/ObjectHistogram.java | 3 +- .../classes/sun/jvm/hotspot/tools/PMap.java | 3 +- .../classes/sun/jvm/hotspot/tools/PStack.java | 3 +- .../sun/jvm/hotspot/tools/StackTrace.java | 3 +- .../sun/jvm/hotspot/tools/SysPropsDumper.java | 3 +- .../classes/sun/jvm/hotspot/tools/Tool.java | 35 +++++++++++++++---- .../jvm/hotspot/tools/jcore/ClassDump.java | 3 +- .../sun/jvm/hotspot/tools/soql/JSDB.java | 3 +- .../sun/jvm/hotspot/tools/soql/SOQL.java | 3 +- 18 files changed, 48 insertions(+), 42 deletions(-) diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java index eeda376b1d6..d2ea2db855d 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java @@ -51,8 +51,7 @@ public class ClassLoaderStats extends Tool { public static void main(String[] args) { ClassLoaderStats cls = new ClassLoaderStats(); - cls.start(args); - cls.stop(); + cls.execute(args); } private static class ClassData { diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java index ed707b9ee8a..2a8ca2cfb7a 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java @@ -54,8 +54,7 @@ public class FinalizerInfo extends Tool { public static void main(String[] args) { FinalizerInfo finfo = new FinalizerInfo(); - finfo.start(args); - finfo.stop(); + finfo.execute(args); } public void run() { diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FlagDumper.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FlagDumper.java index c8db6d6b044..37fa4c83c26 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FlagDumper.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FlagDumper.java @@ -54,7 +54,6 @@ public class FlagDumper extends Tool { public static void main(String[] args) { FlagDumper fd = new FlagDumper(); - fd.start(args); - fd.stop(); + fd.execute(args); } } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapDumper.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapDumper.java index c5af0ed005d..e2da202acb9 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapDumper.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapDumper.java @@ -80,8 +80,7 @@ public class HeapDumper extends Tool { } HeapDumper dumper = new HeapDumper(file); - dumper.start(args); - dumper.stop(); + dumper.execute(args); } } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java index daab682aaef..f87457c3c3e 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java @@ -46,8 +46,7 @@ public class HeapSummary extends Tool { public static void main(String[] args) { HeapSummary hs = new HeapSummary(); - hs.start(args); - hs.stop(); + hs.execute(args); } public void run() { diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java index f2452420744..6f9cd0f41d2 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java @@ -134,8 +134,7 @@ public class JInfo extends Tool { } JInfo jinfo = new JInfo(mode); - jinfo.start(args); - jinfo.stop(); + jinfo.execute(args); } private void printVMFlags() { diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java index f6f3c0741c0..847eac19468 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java @@ -136,7 +136,9 @@ public class JMap extends Tool { 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 @@ public class JMap extends Tool { } JMap jmap = new JMap(mode); - jmap.start(args); - jmap.stop(); + jmap.execute(args); } public boolean writeHeapHprofBin(String fileName) { diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JSnap.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JSnap.java index 9301f1059fd..c2e5ed52f84 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JSnap.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JSnap.java @@ -64,7 +64,6 @@ public class JSnap extends Tool { public static void main(String[] args) { JSnap js = new JSnap(); - js.start(args); - js.stop(); + js.execute(args); } } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java index 7cbe8f4d945..52fb6654e70 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java @@ -89,8 +89,7 @@ public class JStack extends Tool { } JStack jstack = new JStack(mixedMode, concurrentLocks); - jstack.start(args); - jstack.stop(); + jstack.execute(args); } private boolean mixedMode; diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ObjectHistogram.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ObjectHistogram.java index 168202eec2c..6c6c555badf 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ObjectHistogram.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ObjectHistogram.java @@ -61,7 +61,6 @@ public class ObjectHistogram extends Tool { public static void main(String[] args) { ObjectHistogram oh = new ObjectHistogram(); - oh.start(args); - oh.stop(); + oh.execute(args); } } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java index 2a234130991..e18aa76cfa6 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java @@ -69,7 +69,6 @@ public class PMap extends Tool { public static void main(String[] args) throws Exception { PMap t = new PMap(); - t.start(args); - t.stop(); + t.execute(args); } } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java index 7f10612b317..c4e7b5c7b74 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java @@ -182,8 +182,7 @@ public class PStack extends Tool { 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 --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/StackTrace.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/StackTrace.java index eb0cc88d116..bbb0b081b2d 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/StackTrace.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/StackTrace.java @@ -137,8 +137,7 @@ public class StackTrace extends Tool { public static void main(String[] args) { StackTrace st = new StackTrace(); - st.start(args); - st.stop(); + st.execute(args); } private boolean verbose; diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/SysPropsDumper.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/SysPropsDumper.java index d601fef4401..01465574006 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/SysPropsDumper.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/SysPropsDumper.java @@ -58,7 +58,6 @@ public class SysPropsDumper extends Tool { public static void main(String[] args) { SysPropsDumper pd = new SysPropsDumper(); - pd.start(args); - pd.stop(); + pd.execute(args); } } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java index 3021801c9dd..19cfb349da8 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java @@ -26,6 +26,7 @@ package sun.jvm.hotspot.tools; 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 abstract class Tool implements Runnable { 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 @@ public abstract class Tool implements Runnable { default: usage(); + return 1; } agent = new HotSpotAgent(); @@ -191,15 +211,16 @@ public abstract class Tool implements Runnable { 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 --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java index afd7f9865b5..98300c1d6c4 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java @@ -177,7 +177,6 @@ public class ClassDump extends Tool { public static void main(String[] args) { ClassDump cd = new ClassDump(); - cd.start(args); - cd.stop(); + cd.execute(args); } } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/JSDB.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/JSDB.java index 09874af178e..db6dc339394 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/JSDB.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/JSDB.java @@ -42,8 +42,7 @@ public class JSDB extends Tool { public static void main(String[] args) { JSDB jsdb = new JSDB(); - jsdb.start(args); - jsdb.stop(); + jsdb.execute(args); } public void run() { diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java index b3054b90bd0..67f5ed1e920 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java @@ -40,8 +40,7 @@ import sun.jvm.hotspot.utilities.soql.*; 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() { From 56bf9f42e0c203f3cddeaa1c4fcba55c76ec21bc Mon Sep 17 00:00:00 2001 From: Volker Simonis Date: Wed, 16 Oct 2013 15:06:39 +0200 Subject: [PATCH 02/11] 8026703: Wrongly placed element in Event-Based JVM Tracing .xsl files Reviewed-by: sla, kamg --- hotspot/src/share/vm/trace/traceEventClasses.xsl | 2 +- hotspot/src/share/vm/trace/traceEventIds.xsl | 2 +- hotspot/src/share/vm/trace/traceTypes.xsl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/trace/traceEventClasses.xsl b/hotspot/src/share/vm/trace/traceEventClasses.xsl index 70ac9c03759..d9d2cf276ed 100644 --- a/hotspot/src/share/vm/trace/traceEventClasses.xsl +++ b/hotspot/src/share/vm/trace/traceEventClasses.xsl @@ -23,8 +23,8 @@ --> - + diff --git a/hotspot/src/share/vm/trace/traceEventIds.xsl b/hotspot/src/share/vm/trace/traceEventIds.xsl index 737377cadd7..6a7e95474c0 100644 --- a/hotspot/src/share/vm/trace/traceEventIds.xsl +++ b/hotspot/src/share/vm/trace/traceEventIds.xsl @@ -23,8 +23,8 @@ --> - + diff --git a/hotspot/src/share/vm/trace/traceTypes.xsl b/hotspot/src/share/vm/trace/traceTypes.xsl index b06b604cedd..278720d1c1a 100644 --- a/hotspot/src/share/vm/trace/traceTypes.xsl +++ b/hotspot/src/share/vm/trace/traceTypes.xsl @@ -23,8 +23,8 @@ --> - + From 21627fb02f9a69d5e408ca3016bfdb8fe6c158f1 Mon Sep 17 00:00:00 2001 From: Lois Foltan Date: Wed, 16 Oct 2013 14:32:05 -0400 Subject: [PATCH 03/11] 8024804: Crash when InterfaceMethodref resolves to Object.registerNatives Added check for NULL prior to continuation of method look up to avoid runtime crash during look up of Object's superclass' methods. Reviewed-by: coleenp, hseigel --- .../src/share/vm/interpreter/linkResolver.cpp | 2 +- .../test/runtime/8024804/RegisterNatives.java | 46 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 hotspot/test/runtime/8024804/RegisterNatives.java diff --git a/hotspot/src/share/vm/interpreter/linkResolver.cpp b/hotspot/src/share/vm/interpreter/linkResolver.cpp index 6705feb6ccc..88c45c63c25 100644 --- a/hotspot/src/share/vm/interpreter/linkResolver.cpp +++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp @@ -248,7 +248,7 @@ void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle kl 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)); } diff --git a/hotspot/test/runtime/8024804/RegisterNatives.java b/hotspot/test/runtime/8024804/RegisterNatives.java new file mode 100644 index 00000000000..8a5772a88b9 --- /dev/null +++ b/hotspot/test/runtime/8024804/RegisterNatives.java @@ -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); + } +} From d6f90baf178aa6d51b62505c2515ddcc40f676bd Mon Sep 17 00:00:00 2001 From: Dmitry Samersoff Date: Thu, 17 Oct 2013 16:08:01 +0400 Subject: [PATCH 04/11] 8025812: tmtools/jmap/heap_config tests fail on Linux-ia32 because it Cant attach to the core file Coredump store memsz elf field rounded up to page Reviewed-by: dholmes, sla --- hotspot/agent/src/os/linux/ps_core.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/hotspot/agent/src/os/linux/ps_core.c b/hotspot/agent/src/os/linux/ps_core.c index ab3866d5997..268fc2ad162 100644 --- a/hotspot/agent/src/os/linux/ps_core.c +++ b/hotspot/agent/src/os/linux/ps_core.c @@ -719,7 +719,7 @@ static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* li 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 @@ static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* li 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); } } From 2be8957d814aaa7852508862dfdf63d69e75c750 Mon Sep 17 00:00:00 2001 From: Eric Mccorkle Date: Thu, 17 Oct 2013 16:45:08 +0400 Subject: [PATCH 05/11] 8005810: Update Hotspot Serviceability Agent for Method Parameter Reflection and Generic Type Signature Data Hotspot was updated to store method parameter reflection and generic type signature data at runtime. Serviceability agent support was updated for this data Reviewed-by: coleenp, minqi, sla --- .../sun/jvm/hotspot/oops/ConstMethod.java | 47 ++++++++++++++++++- hotspot/src/share/vm/runtime/vmStructs.cpp | 2 + 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java index 3d0a370cd66..585581fefe4 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java @@ -51,6 +51,7 @@ public class ConstMethod extends VMObject { 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 @@ public class ConstMethod extends VMObject { 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 @@ public class ConstMethod extends VMObject { // 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 @@ public class ConstMethod extends VMObject { // 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 @@ public class ConstMethod extends VMObject { return ret; } + private boolean hasMethodParameters() { + return (getFlags() & HAS_METHOD_PARAMETERS) != 0; + } + private boolean hasGenericSignature() { return (getFlags() & HAS_GENERIC_SIGNATURE) != 0; } @@ -442,11 +451,41 @@ public class ConstMethod extends VMObject { 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 @@ public class ConstMethod extends VMObject { 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 @@ public class ConstMethod extends VMObject { } if (hasCheckedExceptions()) { return offsetOfCheckedExceptions() - sizeofShort; + } else if (hasMethodParameters()) { + return offsetOfMethodParameters() - sizeofShort; } else { return hasGenericSignature() ? offsetOfLastU2Element() - sizeofShort : offsetOfLastU2Element(); diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index 199dbac0b24..d7f748c6eca 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -1465,6 +1465,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_toplevel_type(CheckedExceptionElement) \ declare_toplevel_type(LocalVariableTableElement) \ declare_toplevel_type(ExceptionTableElement) \ + declare_toplevel_type(MethodParametersElement) \ \ declare_toplevel_type(ClassLoaderData) \ declare_toplevel_type(ClassLoaderDataGraph) \ @@ -2337,6 +2338,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; 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) \ From 00982daf400aa747b87db8f0f4a684214c82a4c9 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Thu, 17 Oct 2013 16:11:26 +0200 Subject: [PATCH 06/11] 8026792: HOTSPOT: licensee reports a JDK8 build failure after 8005849/8005008 fixes integrated Reviewed-by: dholmes, sla --- hotspot/make/windows/makefiles/trace.make | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/hotspot/make/windows/makefiles/trace.make b/hotspot/make/windows/makefiles/trace.make index 02948c0a8d0..58fee24653c 100644 --- a/hotspot/make/windows/makefiles/trace.make +++ b/hotspot/make/windows/makefiles/trace.make @@ -40,8 +40,7 @@ TraceGeneratedNames = \ traceEventIds.hpp \ traceTypes.hpp - -!if "$(OPENJDK)" != "true" +!if EXISTS($(TraceAltSrcDir)) TraceGeneratedNames = $(TraceGeneratedNames) \ traceRequestables.hpp \ traceEventControl.hpp \ @@ -56,7 +55,7 @@ TraceGeneratedFiles = \ $(TraceOutDir)/traceEventIds.hpp \ $(TraceOutDir)/traceTypes.hpp -!if "$(OPENJDK)" != "true" +!if EXISTS($(TraceAltSrcDir)) TraceGeneratedFiles = $(TraceGeneratedFiles) \ $(TraceOutDir)/traceRequestables.hpp \ $(TraceOutDir)/traceEventControl.hpp \ @@ -68,7 +67,7 @@ XSLT = $(QUIETLY) $(REMOTE) $(RUN_JAVA) -classpath $(JvmtiOutDir) jvmtiGen 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 @@ $(TraceOutDir)/traceTypes.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceType @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 $@ From f6a5cb56ecbc588ca0dd28bd15a4634efb9fa725 Mon Sep 17 00:00:00 2001 From: Dmitry Samersoff Date: Sat, 19 Oct 2013 21:29:57 +0400 Subject: [PATCH 07/11] 8026930: In ManagementAgent.start it should be possible to set the jdp.name parameter (hotspot part) Pass one more property from Agent to JdpController Reviewed-by: jbachorik, sla --- hotspot/src/share/vm/services/diagnosticCommand.cpp | 8 +++++++- hotspot/src/share/vm/services/diagnosticCommand.hpp | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/services/diagnosticCommand.cpp b/hotspot/src/share/vm/services/diagnosticCommand.cpp index 79c922a8586..8e6b547128f 100644 --- a/hotspot/src/share/vm/services/diagnosticCommand.cpp +++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp @@ -505,7 +505,11 @@ JMXStartRemoteDCmd::JMXStartRemoteDCmd(outputStream *output, bool heap_allocated _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 @@ JMXStartRemoteDCmd::JMXStartRemoteDCmd(outputStream *output, bool heap_allocated _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 @@ void JMXStartRemoteDCmd::execute(DCmdSource source, TRAPS) { PUT_OPTION(_jdp_source_addr); PUT_OPTION(_jdp_ttl); PUT_OPTION(_jdp_pause); + PUT_OPTION(_jdp_name); #undef PUT_OPTION diff --git a/hotspot/src/share/vm/services/diagnosticCommand.hpp b/hotspot/src/share/vm/services/diagnosticCommand.hpp index 9c7216177bf..5485b119dec 100644 --- a/hotspot/src/share/vm/services/diagnosticCommand.hpp +++ b/hotspot/src/share/vm/services/diagnosticCommand.hpp @@ -302,6 +302,7 @@ class JMXStartRemoteDCmd : public DCmdWithParser { DCmdArgument _jdp_source_addr; DCmdArgument _jdp_ttl; DCmdArgument _jdp_pause; + DCmdArgument _jdp_name; public: JMXStartRemoteDCmd(outputStream *output, bool heap_allocated); From 033c5b68eacea66f823502649d3b34fbfdb36d67 Mon Sep 17 00:00:00 2001 From: Lois Foltan Date: Tue, 22 Oct 2013 14:47:59 -0400 Subject: [PATCH 08/11] 8026394: Eclipse fails with JDK8 build 111 If the resolved interface does not itself contain "clone" or "finalize" methods, the method/interface method resolution looks to the interface's super class, java.lang.Object. With the JDK 8 interface method accessability check requirement, since these two methods are declared within Object as protected, they must be special cased in LinkResolver::check_method_accessability() in order to avoid an IAE. Reviewed-by: acorn, dholmes --- .../src/share/vm/interpreter/linkResolver.cpp | 25 ++++--- .../runtime/8026394/InterfaceObjectTest.java | 69 +++++++++++++++++++ 2 files changed, 86 insertions(+), 8 deletions(-) create mode 100644 hotspot/test/runtime/8026394/InterfaceObjectTest.java diff --git a/hotspot/src/share/vm/interpreter/linkResolver.cpp b/hotspot/src/share/vm/interpreter/linkResolver.cpp index 3ce8cf90a8a..f88dd153394 100644 --- a/hotspot/src/share/vm/interpreter/linkResolver.cpp +++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp @@ -1,5 +1,4 @@ /* - * 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. * @@ -419,18 +418,28 @@ void LinkResolver::check_method_accessability(KlassHandle ref_klass, 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 --git a/hotspot/test/runtime/8026394/InterfaceObjectTest.java b/hotspot/test/runtime/8026394/InterfaceObjectTest.java new file mode 100644 index 00000000000..03ae6300bc1 --- /dev/null +++ b/hotspot/test/runtime/8026394/InterfaceObjectTest.java @@ -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"); + } +} From 4ac64cd06d945f868ef2978591031049c2c08b3f Mon Sep 17 00:00:00 2001 From: Mikhailo Seledtsov Date: Tue, 22 Oct 2013 15:54:50 -0400 Subject: [PATCH 09/11] 8026809: [TESTBUG] Create regression test for JDK-8026041 Created simple regression test for the bug Reviewed-by: hseigel, lfoltan, zgu --- .../PrintGCApplicationConcurrentTime.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 hotspot/test/runtime/CommandLine/PrintGCApplicationConcurrentTime.java diff --git a/hotspot/test/runtime/CommandLine/PrintGCApplicationConcurrentTime.java b/hotspot/test/runtime/CommandLine/PrintGCApplicationConcurrentTime.java new file mode 100644 index 00000000000..e6cf34962a4 --- /dev/null +++ b/hotspot/test/runtime/CommandLine/PrintGCApplicationConcurrentTime.java @@ -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 { + } +} From 0e4eda601c3d2fd64dc12b6b3a53e1518ca001d9 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Tue, 22 Oct 2013 14:29:02 -0700 Subject: [PATCH 10/11] 8014910: deadlock between JVM/TI ClassPrepare event handler and CompilerThread Revert changes in JDK-8008962 Reviewed-by: coleenp, sspitsyn --- hotspot/src/share/vm/ci/ciEnv.cpp | 3 +- hotspot/src/share/vm/oops/constantPool.cpp | 42 +++++++-------------- hotspot/src/share/vm/oops/constantPool.hpp | 14 ++----- hotspot/src/share/vm/oops/cpCache.cpp | 3 +- hotspot/src/share/vm/oops/instanceKlass.cpp | 26 ++++++++++--- hotspot/src/share/vm/oops/instanceKlass.hpp | 1 + hotspot/src/share/vm/prims/jvmtiEnv.cpp | 6 +-- 7 files changed, 42 insertions(+), 53 deletions(-) diff --git a/hotspot/src/share/vm/ci/ciEnv.cpp b/hotspot/src/share/vm/ci/ciEnv.cpp index 9cdd475a352..7e61a849b0f 100644 --- a/hotspot/src/share/vm/ci/ciEnv.cpp +++ b/hotspot/src/share/vm/ci/ciEnv.cpp @@ -483,8 +483,7 @@ ciKlass* ciEnv::get_klass_by_index_impl(constantPoolHandle cpool, { // 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 --git a/hotspot/src/share/vm/oops/constantPool.cpp b/hotspot/src/share/vm/oops/constantPool.cpp index 73cebb4258f..16b53a69929 100644 --- a/hotspot/src/share/vm/oops/constantPool.cpp +++ b/hotspot/src/share/vm/oops/constantPool.cpp @@ -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 @@ ConstantPool::ConstantPool(Array* tags) { // 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::deallocate_contents(ClassLoaderData* loader_data) { 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 @@ void ConstantPool::restore_unshareable_info(TRAPS) { 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 @@ void ConstantPool::remove_unshareable_info() { 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 @@ Klass* ConstantPool::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS 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 @@ Klass* ConstantPool::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS 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 @@ Klass* ConstantPool::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS } 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 @@ void ConstantPool::save_and_throw_exception(constantPoolHandle this_oop, int whi 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 @@ oop ConstantPool::resolve_constant_at_impl(constantPoolHandle this_oop, int inde 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 --git a/hotspot/src/share/vm/oops/constantPool.hpp b/hotspot/src/share/vm/oops/constantPool.hpp index 47a51a835e2..497df53d778 100644 --- a/hotspot/src/share/vm/oops/constantPool.hpp +++ b/hotspot/src/share/vm/oops/constantPool.hpp @@ -111,6 +111,7 @@ class ConstantPool : public Metadata { 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 @@ class ConstantPool : public Metadata { 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 --git a/hotspot/src/share/vm/oops/cpCache.cpp b/hotspot/src/share/vm/oops/cpCache.cpp index eabd1e059b0..215cf7796f0 100644 --- a/hotspot/src/share/vm/oops/cpCache.cpp +++ b/hotspot/src/share/vm/oops/cpCache.cpp @@ -284,8 +284,7 @@ void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool, // 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 --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index 971039ab943..a8fa7b3ee0e 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -498,13 +498,27 @@ objArrayOop InstanceKlass::signers() const { 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 @@ void InstanceKlass::eager_initialize_impl(instanceKlassHandle this_oop) { } 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 @@ bool InstanceKlass::link_class_impl( // 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 @@ void InstanceKlass::initialize_impl(instanceKlassHandle this_oop, TRAPS) { // 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(ClassState state, TRAPS) 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 --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp index 914cb1dc06a..283caa0a703 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.hpp +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp @@ -1023,6 +1023,7 @@ public: // 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 --git a/hotspot/src/share/vm/prims/jvmtiEnv.cpp b/hotspot/src/share/vm/prims/jvmtiEnv.cpp index f24c80f4339..318fe4e0b7e 100644 --- a/hotspot/src/share/vm/prims/jvmtiEnv.cpp +++ b/hotspot/src/share/vm/prims/jvmtiEnv.cpp @@ -259,8 +259,7 @@ JvmtiEnv::RetransformClasses(jint class_count, const jclass* classes) { // 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 @@ JvmtiEnv::GetConstantPool(oop k_mirror, jint* constant_pool_count_ptr, jint* con 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) { From e731a6d078e676a783d0e4b65b726381e1db718c Mon Sep 17 00:00:00 2001 From: Fredrik Arvidsson Date: Wed, 23 Oct 2013 10:24:28 +0200 Subject: [PATCH 11/11] 8026808: serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java failed with unexpected exit value Fixes a bug with vmArgs when using JDKToolLauncher Reviewed-by: sla, dholmes --- .../com/oracle/java/testlibrary/JDKToolLauncher.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolLauncher.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolLauncher.java index 7871bd2ce2f..4534a8fe2f6 100644 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolLauncher.java +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolLauncher.java @@ -100,7 +100,7 @@ public class JDKToolLauncher { * @return The JDKToolLauncher instance */ public JDKToolLauncher addVMArg(String arg) { - vmArgs.add("-J" + arg); + vmArgs.add(arg); return this; } @@ -124,7 +124,10 @@ public class JDKToolLauncher { 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()]); }