--- a/hotspot/agent/src/os/linux/Makefile Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/agent/src/os/linux/Makefile Fri Feb 17 06:34:49 2012 -0800
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -40,7 +40,7 @@
LIBS = -lthread_db
-CFLAGS = -c -fPIC -g -D_GNU_SOURCE -D$(ARCH) $(INCLUDES)
+CFLAGS = -c -fPIC -g -D_GNU_SOURCE -D$(ARCH) $(INCLUDES) -D_FILE_OFFSET_BITS=64
LIBSA = $(ARCH)/libsaproc.so
--- a/hotspot/agent/src/os/linux/libproc_impl.c Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/agent/src/os/linux/libproc_impl.c Fri Feb 17 06:34:49 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -50,10 +50,6 @@
char alt_path[PATH_MAX + 1];
init_alt_root();
- fd = open(name, O_RDONLY);
- if (fd >= 0) {
- return fd;
- }
if (alt_root_len > 0) {
strcpy(alt_path, alt_root);
@@ -73,6 +69,11 @@
return fd;
}
}
+ } else {
+ fd = open(name, O_RDONLY);
+ if (fd >= 0) {
+ return fd;
+ }
}
return -1;
--- a/hotspot/make/jprt.properties Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/make/jprt.properties Fri Feb 17 06:34:49 2012 -0800
@@ -38,7 +38,9 @@
# This tells jprt what default release we want to build
-jprt.tools.default.release=${jprt.submit.release}
+jprt.hotspot.default.release=jdk7
+
+jprt.tools.default.release=${jprt.submit.option.release?${jprt.submit.option.release}:${jprt.hotspot.default.release}}
# Disable syncing the source after builds and tests are done.
@@ -52,126 +54,46 @@
# Define the Solaris platforms we want for the various releases
jprt.my.solaris.sparc.jdk8=solaris_sparc_5.10
jprt.my.solaris.sparc.jdk7=solaris_sparc_5.10
-jprt.my.solaris.sparc.jdk7b107=solaris_sparc_5.10
-jprt.my.solaris.sparc.jdk7temp=solaris_sparc_5.10
-jprt.my.solaris.sparc.jdk6=solaris_sparc_5.8
-jprt.my.solaris.sparc.jdk6perf=solaris_sparc_5.8
-jprt.my.solaris.sparc.jdk6u10=solaris_sparc_5.8
-jprt.my.solaris.sparc.jdk6u14=solaris_sparc_5.8
-jprt.my.solaris.sparc.jdk6u18=solaris_sparc_5.8
-jprt.my.solaris.sparc.jdk6u20=solaris_sparc_5.8
-jprt.my.solaris.sparc.ejdk7=${jprt.my.solaris.sparc.jdk7}
-jprt.my.solaris.sparc.ejdk6=${jprt.my.solaris.sparc.jdk6}
jprt.my.solaris.sparc=${jprt.my.solaris.sparc.${jprt.tools.default.release}}
jprt.my.solaris.sparcv9.jdk8=solaris_sparcv9_5.10
jprt.my.solaris.sparcv9.jdk7=solaris_sparcv9_5.10
-jprt.my.solaris.sparcv9.jdk7b107=solaris_sparcv9_5.10
-jprt.my.solaris.sparcv9.jdk7temp=solaris_sparcv9_5.10
-jprt.my.solaris.sparcv9.jdk6=solaris_sparcv9_5.8
-jprt.my.solaris.sparcv9.jdk6perf=solaris_sparcv9_5.8
-jprt.my.solaris.sparcv9.jdk6u10=solaris_sparcv9_5.8
-jprt.my.solaris.sparcv9.jdk6u14=solaris_sparcv9_5.8
-jprt.my.solaris.sparcv9.jdk6u18=solaris_sparcv9_5.8
-jprt.my.solaris.sparcv9.jdk6u20=solaris_sparcv9_5.8
-jprt.my.solaris.sparcv9.ejdk7=${jprt.my.solaris.sparcv9.jdk7}
-jprt.my.solaris.sparcv9.ejdk6=${jprt.my.solaris.sparcv9.jdk6}
jprt.my.solaris.sparcv9=${jprt.my.solaris.sparcv9.${jprt.tools.default.release}}
jprt.my.solaris.i586.jdk8=solaris_i586_5.10
jprt.my.solaris.i586.jdk7=solaris_i586_5.10
-jprt.my.solaris.i586.jdk7b107=solaris_i586_5.10
-jprt.my.solaris.i586.jdk7temp=solaris_i586_5.10
-jprt.my.solaris.i586.jdk6=solaris_i586_5.8
-jprt.my.solaris.i586.jdk6perf=solaris_i586_5.8
-jprt.my.solaris.i586.jdk6u10=solaris_i586_5.8
-jprt.my.solaris.i586.jdk6u14=solaris_i586_5.8
-jprt.my.solaris.i586.jdk6u18=solaris_i586_5.8
-jprt.my.solaris.i586.jdk6u20=solaris_i586_5.8
-jprt.my.solaris.i586.ejdk7=${jprt.my.solaris.i586.jdk7}
-jprt.my.solaris.i586.ejdk6=${jprt.my.solaris.i586.jdk6}
jprt.my.solaris.i586=${jprt.my.solaris.i586.${jprt.tools.default.release}}
jprt.my.solaris.x64.jdk8=solaris_x64_5.10
jprt.my.solaris.x64.jdk7=solaris_x64_5.10
-jprt.my.solaris.x64.jdk7b107=solaris_x64_5.10
-jprt.my.solaris.x64.jdk7temp=solaris_x64_5.10
-jprt.my.solaris.x64.jdk6=solaris_x64_5.10
-jprt.my.solaris.x64.jdk6perf=solaris_x64_5.10
-jprt.my.solaris.x64.jdk6u10=solaris_x64_5.10
-jprt.my.solaris.x64.jdk6u14=solaris_x64_5.10
-jprt.my.solaris.x64.jdk6u18=solaris_x64_5.10
-jprt.my.solaris.x64.jdk6u20=solaris_x64_5.10
-jprt.my.solaris.x64.ejdk7=${jprt.my.solaris.x64.jdk7}
-jprt.my.solaris.x64.ejdk6=${jprt.my.solaris.x64.jdk6}
jprt.my.solaris.x64=${jprt.my.solaris.x64.${jprt.tools.default.release}}
jprt.my.linux.i586.jdk8=linux_i586_2.6
jprt.my.linux.i586.jdk7=linux_i586_2.6
-jprt.my.linux.i586.jdk7b107=linux_i586_2.6
-jprt.my.linux.i586.jdk7temp=linux_i586_2.6
-jprt.my.linux.i586.jdk6=linux_i586_2.4
-jprt.my.linux.i586.jdk6perf=linux_i586_2.4
-jprt.my.linux.i586.jdk6u10=linux_i586_2.4
-jprt.my.linux.i586.jdk6u14=linux_i586_2.4
-jprt.my.linux.i586.jdk6u18=linux_i586_2.4
-jprt.my.linux.i586.jdk6u20=linux_i586_2.4
-jprt.my.linux.i586.ejdk7=linux_i586_2.6
-jprt.my.linux.i586.ejdk6=linux_i586_2.6
jprt.my.linux.i586=${jprt.my.linux.i586.${jprt.tools.default.release}}
jprt.my.linux.x64.jdk8=linux_x64_2.6
jprt.my.linux.x64.jdk7=linux_x64_2.6
-jprt.my.linux.x64.jdk7b107=linux_x64_2.6
-jprt.my.linux.x64.jdk7temp=linux_x64_2.6
-jprt.my.linux.x64.jdk6=linux_x64_2.4
-jprt.my.linux.x64.jdk6perf=linux_x64_2.4
-jprt.my.linux.x64.jdk6u10=linux_x64_2.4
-jprt.my.linux.x64.jdk6u14=linux_x64_2.4
-jprt.my.linux.x64.jdk6u18=linux_x64_2.4
-jprt.my.linux.x64.jdk6u20=linux_x64_2.4
-jprt.my.linux.x64.ejdk7=${jprt.my.linux.x64.jdk7}
-jprt.my.linux.x64.ejdk6=${jprt.my.linux.x64.jdk6}
jprt.my.linux.x64=${jprt.my.linux.x64.${jprt.tools.default.release}}
jprt.my.linux.ppc.jdk8=linux_ppc_2.6
jprt.my.linux.ppc.jdk7=linux_ppc_2.6
-jprt.my.linux.ppc.jdk7b107=linux_ppc_2.6
-jprt.my.linux.ppc.jdk7temp=linux_ppc_2.6
-jprt.my.linux.ppc.ejdk6=linux_ppc_2.6
-jprt.my.linux.ppc.ejdk7=linux_ppc_2.6
jprt.my.linux.ppc=${jprt.my.linux.ppc.${jprt.tools.default.release}}
jprt.my.linux.ppcv2.jdk8=linux_ppcv2_2.6
jprt.my.linux.ppcv2.jdk7=linux_ppcv2_2.6
-jprt.my.linux.ppcv2.jdk7b107=linux_ppcv2_2.6
-jprt.my.linux.ppcv2.jdk7temp=linux_ppcv2_2.6
-jprt.my.linux.ppcv2.ejdk6=linux_ppcv2_2.6
-jprt.my.linux.ppcv2.ejdk7=linux_ppcv2_2.6
jprt.my.linux.ppcv2=${jprt.my.linux.ppcv2.${jprt.tools.default.release}}
jprt.my.linux.ppcsflt.jdk8=linux_ppcsflt_2.6
jprt.my.linux.ppcsflt.jdk7=linux_ppcsflt_2.6
-jprt.my.linux.ppcsflt.jdk7b107=linux_ppcsflt_2.6
-jprt.my.linux.ppcsflt.jdk7temp=linux_ppcsflt_2.6
-jprt.my.linux.ppcsflt.ejdk6=linux_ppcsflt_2.6
-jprt.my.linux.ppcsflt.ejdk7=linux_ppcsflt_2.6
jprt.my.linux.ppcsflt=${jprt.my.linux.ppcsflt.${jprt.tools.default.release}}
jprt.my.linux.armvfp.jdk8=linux_armvfp_2.6
jprt.my.linux.armvfp.jdk7=linux_armvfp_2.6
-jprt.my.linux.armvfp.jdk7b107=linux_armvfp_2.6
-jprt.my.linux.armvfp.jdk7temp=linux_armvfp_2.6
-jprt.my.linux.armvfp.ejdk6=linux_armvfp_2.6
-jprt.my.linux.armvfp.ejdk7=linux_armvfp_2.6
jprt.my.linux.armvfp=${jprt.my.linux.armvfp.${jprt.tools.default.release}}
jprt.my.linux.armsflt.jdk8=linux_armsflt_2.6
jprt.my.linux.armsflt.jdk7=linux_armsflt_2.6
-jprt.my.linux.armsflt.jdk7b107=linux_armsflt_2.6
-jprt.my.linux.armsflt.jdk7temp=linux_armsflt_2.6
-jprt.my.linux.armsflt.ejdk6=linux_armsflt_2.6
-jprt.my.linux.armsflt.ejdk7=linux_armsflt_2.6
jprt.my.linux.armsflt=${jprt.my.linux.armsflt.${jprt.tools.default.release}}
jprt.my.macosx.x64.jdk8=macosx_x64_10.7
@@ -180,30 +102,10 @@
jprt.my.windows.i586.jdk8=windows_i586_5.1
jprt.my.windows.i586.jdk7=windows_i586_5.1
-jprt.my.windows.i586.jdk7b107=windows_i586_5.0
-jprt.my.windows.i586.jdk7temp=windows_i586_5.0
-jprt.my.windows.i586.jdk6=windows_i586_5.0
-jprt.my.windows.i586.jdk6perf=windows_i586_5.0
-jprt.my.windows.i586.jdk6u10=windows_i586_5.0
-jprt.my.windows.i586.jdk6u14=windows_i586_5.0
-jprt.my.windows.i586.jdk6u18=windows_i586_5.0
-jprt.my.windows.i586.jdk6u20=windows_i586_5.0
-jprt.my.windows.i586.ejdk7=${jprt.my.windows.i586.jdk7}
-jprt.my.windows.i586.ejdk6=${jprt.my.windows.i586.jdk6}
jprt.my.windows.i586=${jprt.my.windows.i586.${jprt.tools.default.release}}
jprt.my.windows.x64.jdk8=windows_x64_5.2
jprt.my.windows.x64.jdk7=windows_x64_5.2
-jprt.my.windows.x64.jdk7b107=windows_x64_5.2
-jprt.my.windows.x64.jdk7temp=windows_x64_5.2
-jprt.my.windows.x64.jdk6=windows_x64_5.2
-jprt.my.windows.x64.jdk6perf=windows_x64_5.2
-jprt.my.windows.x64.jdk6u10=windows_x64_5.2
-jprt.my.windows.x64.jdk6u14=windows_x64_5.2
-jprt.my.windows.x64.jdk6u18=windows_x64_5.2
-jprt.my.windows.x64.jdk6u20=windows_x64_5.2
-jprt.my.windows.x64.ejdk7=${jprt.my.windows.x64.jdk7}
-jprt.my.windows.x64.ejdk6=${jprt.my.windows.x64.jdk6}
jprt.my.windows.x64=${jprt.my.windows.x64.${jprt.tools.default.release}}
# Standard list of jprt build targets for this source tree
@@ -539,16 +441,6 @@
jprt.test.targets.jdk8=${jprt.test.targets.standard}
jprt.test.targets.jdk7=${jprt.test.targets.standard}
-jprt.test.targets.jdk7temp=${jprt.test.targets.standard}
-jprt.test.targets.jdk7b105=${jprt.test.targets.standard}
-jprt.test.targets.jdk6=${jprt.test.targets.standard}
-jprt.test.targets.jdk6perf=${jprt.test.targets.standard}
-jprt.test.targets.jdk6u10=${jprt.test.targets.standard}
-jprt.test.targets.jdk6u14=${jprt.test.targets.standard}
-jprt.test.targets.jdk6u18=${jprt.test.targets.standard}
-jprt.test.targets.jdk6u20=${jprt.test.targets.standard}
-jprt.test.targets.ejdk6=${jprt.test.targets.embedded}
-jprt.test.targets.ejdk7=${jprt.test.targets.embedded}
jprt.test.targets=${jprt.test.targets.${jprt.tools.default.release}}
# The default test/Makefile targets that should be run
@@ -593,15 +485,5 @@
jprt.make.rule.test.targets.jdk8=${jprt.make.rule.test.targets.standard}
jprt.make.rule.test.targets.jdk7=${jprt.make.rule.test.targets.standard}
-jprt.make.rule.test.targets.jdk7temp=${jprt.make.rule.test.targets.standard}
-jprt.make.rule.test.targets.jdk7b107=${jprt.make.rule.test.targets.standard}
-jprt.make.rule.test.targets.jdk6=${jprt.make.rule.test.targets.standard}
-jprt.make.rule.test.targets.jdk6perf=${jprt.make.rule.test.targets.standard}
-jprt.make.rule.test.targets.jdk6u10=${jprt.make.rule.test.targets.standard}
-jprt.make.rule.test.targets.jdk6u14=${jprt.make.rule.test.targets.standard}
-jprt.make.rule.test.targets.jdk6u18=${jprt.make.rule.test.targets.standard}
-jprt.make.rule.test.targets.jdk6u20=${jprt.make.rule.test.targets.standard}
-jprt.make.rule.test.targets.ejdk6=${jprt.make.rule.test.targets.embedded}
-jprt.make.rule.test.targets.ejdk7=${jprt.make.rule.test.targets.embedded}
jprt.make.rule.test.targets=${jprt.make.rule.test.targets.${jprt.tools.default.release}}
--- a/hotspot/make/linux/makefiles/saproc.make Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/make/linux/makefiles/saproc.make Fri Feb 17 06:34:49 2012 -0800
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,7 @@
fi
@echo Making SA debugger back-end...
$(QUIETLY) $(CC) -D$(BUILDARCH) -D_GNU_SOURCE \
+ -D_FILE_OFFSET_BITS=64 \
$(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \
-I$(SASRCDIR) \
-I$(GENERATED) \
--- a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp Fri Feb 17 06:34:49 2012 -0800
@@ -56,14 +56,15 @@
// Stack slots are 2X larger in LP64 than in the 32 bit VM.
define_pd_global(intx, ThreadStackSize, 1024);
define_pd_global(intx, VMThreadStackSize, 1024);
+define_pd_global(intx, StackShadowPages, 10 DEBUG_ONLY(+1));
#else
define_pd_global(intx, ThreadStackSize, 512);
define_pd_global(intx, VMThreadStackSize, 512);
+define_pd_global(intx, StackShadowPages, 3 DEBUG_ONLY(+1));
#endif
define_pd_global(intx, StackYellowPages, 2);
define_pd_global(intx, StackRedPages, 1);
-define_pd_global(intx, StackShadowPages, 3 DEBUG_ONLY(+1));
define_pd_global(intx, PreInflateSpin, 40); // Determined by running design center
--- a/hotspot/src/cpu/x86/vm/globals_x86.hpp Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp Fri Feb 17 06:34:49 2012 -0800
@@ -60,7 +60,7 @@
#ifdef AMD64
// Very large C++ stack frames using solaris-amd64 optimized builds
// due to lack of optimization caused by C++ compiler bugs
-define_pd_global(intx, StackShadowPages, SOLARIS_ONLY(20) NOT_SOLARIS(6) DEBUG_ONLY(+2));
+define_pd_global(intx, StackShadowPages, NOT_WIN64(20) WIN64_ONLY(6) DEBUG_ONLY(+2));
#else
define_pd_global(intx, StackShadowPages, 3 DEBUG_ONLY(+5));
#endif // AMD64
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.hpp Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.hpp Fri Feb 17 06:34:49 2012 -0800
@@ -249,13 +249,18 @@
enum {
// AMD
- CPU_FAMILY_AMD_11H = 17,
+ CPU_FAMILY_AMD_11H = 0x11,
// Intel
CPU_FAMILY_INTEL_CORE = 6,
- CPU_MODEL_NEHALEM_EP = 26,
- CPU_MODEL_WESTMERE_EP = 44,
-// CPU_MODEL_IVYBRIDGE_EP = ??, TODO - get real value
- CPU_MODEL_SANDYBRIDGE_EP = 45
+ CPU_MODEL_NEHALEM = 0x1e,
+ CPU_MODEL_NEHALEM_EP = 0x1a,
+ CPU_MODEL_NEHALEM_EX = 0x2e,
+ CPU_MODEL_WESTMERE = 0x25,
+ CPU_MODEL_WESTMERE_EP = 0x2c,
+ CPU_MODEL_WESTMERE_EX = 0x2f,
+ CPU_MODEL_SANDYBRIDGE = 0x2a,
+ CPU_MODEL_SANDYBRIDGE_EP = 0x2d,
+ CPU_MODEL_IVYBRIDGE_EP = 0x3a
} cpuExtendedFamily;
// cpuid information block. All info derived from executing cpuid with
@@ -325,7 +330,7 @@
uint32_t proc_name_4, proc_name_5, proc_name_6, proc_name_7;
uint32_t proc_name_8, proc_name_9, proc_name_10,proc_name_11;
- // cpuid function 0x80000005 //AMD L1, Intel reserved
+ // cpuid function 0x80000005 // AMD L1, Intel reserved
uint32_t ext_cpuid5_eax; // unused currently
uint32_t ext_cpuid5_ebx; // reserved
ExtCpuid5Ex ext_cpuid5_ecx; // L1 data cache info (AMD)
@@ -547,15 +552,15 @@
static bool is_intel_tsc_synched_at_init() {
if (is_intel_family_core()) {
uint32_t ext_model = extended_cpu_model();
- if (ext_model == CPU_MODEL_NEHALEM_EP ||
- ext_model == CPU_MODEL_WESTMERE_EP ||
-// TODO ext_model == CPU_MODEL_IVYBRIDGE_EP ||
- ext_model == CPU_MODEL_SANDYBRIDGE_EP) {
- // 2-socket invtsc support. EX versions with 4 sockets are not
- // guaranteed to synchronize tscs at initialization via a double
- // handshake. The tscs can be explicitly set in software. Code
- // that uses tsc values must be prepared for them to arbitrarily
- // jump backward or forward.
+ if (ext_model == CPU_MODEL_NEHALEM_EP ||
+ ext_model == CPU_MODEL_WESTMERE_EP ||
+ ext_model == CPU_MODEL_SANDYBRIDGE_EP ||
+ ext_model == CPU_MODEL_IVYBRIDGE_EP) {
+ // <= 2-socket invariant tsc support. EX versions are usually used
+ // in > 2-socket systems and likely don't synchronize tscs at
+ // initialization.
+ // Code that uses tsc values must be prepared for them to arbitrarily
+ // jump forward or backward.
return true;
}
}
--- a/hotspot/src/os/bsd/vm/decoder_machO.hpp Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/src/os/bsd/vm/decoder_machO.hpp Fri Feb 17 06:34:49 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,8 +29,9 @@
#include "utilities/decoder.hpp"
-// Just a placehold for now
-class MachODecoder: public NullDecoder {
+// Just a placehold for now, a real implementation should derive
+// from AbstractDecoder
+class MachODecoder : public NullDecoder {
public:
MachODecoder() { }
~MachODecoder() { }
--- a/hotspot/src/os/windows/vm/decoder_windows.hpp Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/src/os/windows/vm/decoder_windows.hpp Fri Feb 17 06:34:49 2012 -0800
@@ -36,7 +36,7 @@
typedef BOOL (WINAPI *pfn_SymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64);
typedef DWORD (WINAPI *pfn_UndecorateSymbolName)(const char*, char*, DWORD, DWORD);
-class WindowsDecoder: public NullDecoder {
+class WindowsDecoder : public AbstractDecoder {
public:
WindowsDecoder();
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Fri Feb 17 06:34:49 2012 -0800
@@ -284,6 +284,7 @@
template(run_method_name, "run") \
template(exit_method_name, "exit") \
template(add_method_name, "add") \
+ template(remove_method_name, "remove") \
template(parent_name, "parent") \
template(threads_name, "threads") \
template(groups_name, "groups") \
--- a/hotspot/src/share/vm/prims/jvmtiTagMap.cpp Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/src/share/vm/prims/jvmtiTagMap.cpp Fri Feb 17 06:34:49 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -2999,7 +2999,8 @@
char type = field->field_type();
if (!is_primitive_field_type(type)) {
oop fld_o = o->obj_field(field->field_offset());
- if (fld_o != NULL) {
+ // ignore any objects that aren't visible to profiler
+ if (fld_o != NULL && ServiceUtil::visible_oop(fld_o)) {
// reflection code may have a reference to a klassOop.
// - see sun.reflect.UnsafeStaticFieldAccessorImpl and sun.misc.Unsafe
if (fld_o->is_klass()) {
--- a/hotspot/src/share/vm/runtime/arguments.cpp Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Fri Feb 17 06:34:49 2012 -0800
@@ -1370,12 +1370,9 @@
// by ergonomics.
if (MaxHeapSize <= max_heap_for_compressed_oops()) {
#if !defined(COMPILER1) || defined(TIERED)
-// disable UseCompressedOops by default on MacOS X until 7118647 is fixed
-#ifndef __APPLE__
if (FLAG_IS_DEFAULT(UseCompressedOops)) {
FLAG_SET_ERGO(bool, UseCompressedOops, true);
}
-#endif // !__APPLE__
#endif
#ifdef _WIN64
if (UseLargePages && UseCompressedOops) {
--- a/hotspot/src/share/vm/runtime/dtraceJSDT.cpp Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/src/share/vm/runtime/dtraceJSDT.cpp Fri Feb 17 06:34:49 2012 -0800
@@ -82,7 +82,7 @@
int handle = pd_activate((void*)probes,
module_name, providers_count, providers);
- if (handle <= 0) {
+ if (handle < 0) {
delete probes;
THROW_MSG_0(vmSymbols::java_lang_RuntimeException(),
"Unable to register DTrace probes (internal error).");
--- a/hotspot/src/share/vm/runtime/thread.cpp Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/src/share/vm/runtime/thread.cpp Fri Feb 17 06:34:49 2012 -0800
@@ -3220,11 +3220,6 @@
return status;
}
- // Must be run after init_ft which initializes ft_enabled
- if (TRACE_INITIALIZE() != JNI_OK) {
- vm_exit_during_initialization("Failed to initialize tracing backend");
- }
-
// Should be done after the heap is fully created
main_thread->cache_global_variables();
@@ -3366,6 +3361,7 @@
initialize_class(vmSymbols::java_lang_ArithmeticException(), CHECK_0);
initialize_class(vmSymbols::java_lang_StackOverflowError(), CHECK_0);
initialize_class(vmSymbols::java_lang_IllegalMonitorStateException(), CHECK_0);
+ initialize_class(vmSymbols::java_lang_IllegalArgumentException(), CHECK_0);
} else {
warning("java.lang.OutOfMemoryError has not been initialized");
warning("java.lang.NullPointerException has not been initialized");
@@ -3373,6 +3369,7 @@
warning("java.lang.ArrayStoreException has not been initialized");
warning("java.lang.ArithmeticException has not been initialized");
warning("java.lang.StackOverflowError has not been initialized");
+ warning("java.lang.IllegalArgumentException has not been initialized");
}
}
@@ -3402,6 +3399,11 @@
quicken_jni_functions();
+ // Must be run after init_ft which initializes ft_enabled
+ if (TRACE_INITIALIZE() != JNI_OK) {
+ vm_exit_during_initialization("Failed to initialize tracing backend");
+ }
+
// Set flag that basic initialization has completed. Used by exceptions and various
// debug stuff, that does not work until all basic classes have been initialized.
set_init_completed();
--- a/hotspot/src/share/vm/runtime/virtualspace.cpp Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/src/share/vm/runtime/virtualspace.cpp Fri Feb 17 06:34:49 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -455,7 +455,7 @@
void ReservedSpace::protect_noaccess_prefix(const size_t size) {
assert( (_noaccess_prefix != 0) == (UseCompressedOops && _base != NULL &&
- (size_t(_base + _size) > OopEncodingHeapMax) &&
+ (Universe::narrow_oop_base() != NULL) &&
Universe::narrow_oop_use_implicit_null_checks()),
"noaccess_prefix should be used only with non zero based compressed oops");
--- a/hotspot/src/share/vm/services/diagnosticArgument.cpp Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/src/share/vm/services/diagnosticArgument.cpp Fri Feb 17 06:34:49 2012 -0800
@@ -28,9 +28,16 @@
#include "services/diagnosticArgument.hpp"
void GenDCmdArgument::read_value(const char* str, size_t len, TRAPS) {
- if (is_set()) {
+ /* NOTE:Some argument types doesn't require a value,
+ * for instance boolean arguments: "enableFeatureX". is
+ * equivalent to "enableFeatureX=true". In these cases,
+ * str will be null. This is perfectly valid.
+ * All argument types must perform null checks on str.
+ */
+
+ if (is_set() && !allow_multiple()) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
- "Duplicates in diagnostic command arguments");
+ "Duplicates in diagnostic command arguments\n");
}
parse_value(str, len, CHECK);
set_is_set(true);
@@ -38,9 +45,9 @@
template <> void DCmdArgument<jlong>::parse_value(const char* str,
size_t len, TRAPS) {
- if (sscanf(str, INT64_FORMAT, &_value) != 1) {
+ if (str == NULL || sscanf(str, INT64_FORMAT, &_value) != 1) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
- "Integer parsing error in diagnostic command arguments");
+ "Integer parsing error in diagnostic command arguments\n");
}
}
@@ -89,16 +96,20 @@
template <> void DCmdArgument<char*>::parse_value(const char* str,
size_t len, TRAPS) {
- _value = NEW_C_HEAP_ARRAY(char, len+1);
- strncpy(_value, str, len);
- _value[len] = 0;
+ if (str == NULL) {
+ _value = NULL;
+ } else {
+ _value = NEW_C_HEAP_ARRAY(char, len+1);
+ strncpy(_value, str, len);
+ _value[len] = 0;
+ }
}
template <> void DCmdArgument<char*>::init_value(TRAPS) {
- if (has_default()) {
+ if (has_default() && _default_string != NULL) {
this->parse_value(_default_string, strlen(_default_string), THREAD);
if (HAS_PENDING_EXCEPTION) {
- fatal("Default string must be parsable");
+ fatal("Default string must be parsable");
}
} else {
set_value(NULL);
@@ -111,3 +122,153 @@
set_value(NULL);
}
}
+
+template <> void DCmdArgument<NanoTimeArgument>::parse_value(const char* str,
+ size_t len, TRAPS) {
+ if (str == NULL) {
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+ "Integer parsing error nanotime value: syntax error");
+ }
+
+ int argc = sscanf(str, INT64_FORMAT , &_value._time);
+ if (argc != 1) {
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+ "Integer parsing error nanotime value: syntax error");
+ }
+ size_t idx = 0;
+ while(idx < len && isdigit(str[idx])) {
+ idx++;
+ }
+ if (idx == len) {
+ // only accept missing unit if the value is 0
+ if (_value._time != 0) {
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+ "Integer parsing error nanotime value: unit required");
+ } else {
+ _value._nanotime = 0;
+ strcpy(_value._unit, "ns");
+ return;
+ }
+ } else if(len - idx > 2) {
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+ "Integer parsing error nanotime value: illegal unit");
+ } else {
+ strncpy(_value._unit, &str[idx], len - idx);
+ /*Write an extra null termination. This is safe because _value._unit
+ * is declared as char[3], and length is checked to be not larger than
+ * two above. Also, this is necessary, since length might be 1, and the
+ * default value already in the string is ns, which is two chars.
+ */
+ _value._unit[len-idx] = '\0';
+ }
+
+ if (strcmp(_value._unit, "ns") == 0) {
+ _value._nanotime = _value._time;
+ } else if (strcmp(_value._unit, "us") == 0) {
+ _value._nanotime = _value._time * 1000;
+ } else if (strcmp(_value._unit, "ms") == 0) {
+ _value._nanotime = _value._time * 1000 * 1000;
+ } else if (strcmp(_value._unit, "s") == 0) {
+ _value._nanotime = _value._time * 1000 * 1000 * 1000;
+ } else if (strcmp(_value._unit, "m") == 0) {
+ _value._nanotime = _value._time * 60 * 1000 * 1000 * 1000;
+ } else if (strcmp(_value._unit, "h") == 0) {
+ _value._nanotime = _value._time * 60 * 60 * 1000 * 1000 * 1000;
+ } else if (strcmp(_value._unit, "d") == 0) {
+ _value._nanotime = _value._time * 24 * 60 * 60 * 1000 * 1000 * 1000;
+ } else {
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+ "Integer parsing error nanotime value: illegal unit");
+ }
+}
+
+template <> void DCmdArgument<NanoTimeArgument>::init_value(TRAPS) {
+ if (has_default()) {
+ this->parse_value(_default_string, strlen(_default_string), THREAD);
+ if (HAS_PENDING_EXCEPTION) {
+ fatal("Default string must be parsable");
+ }
+ } else {
+ _value._time = 0;
+ _value._nanotime = 0;
+ strcmp(_value._unit, "ns");
+ }
+}
+
+template <> void DCmdArgument<NanoTimeArgument>::destroy_value() { }
+
+// WARNING StringArrayArgument can only be used as an option, it cannot be
+// used as an argument with the DCmdParser
+
+template <> void DCmdArgument<StringArrayArgument*>::parse_value(const char* str,
+ size_t len, TRAPS) {
+ _value->add(str,len);
+}
+
+template <> void DCmdArgument<StringArrayArgument*>::init_value(TRAPS) {
+ _value = new StringArrayArgument();
+ _allow_multiple = true;
+ if (has_default()) {
+ fatal("StringArrayArgument cannot have default value");
+ }
+}
+
+template <> void DCmdArgument<StringArrayArgument*>::destroy_value() {
+ if (_value != NULL) {
+ delete _value;
+ set_value(NULL);
+ }
+}
+
+template <> void DCmdArgument<MemorySizeArgument>::parse_value(const char* str,
+ size_t len, TRAPS) {
+ if (str == NULL) {
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+ "Integer parsing error nanotime value: syntax error");
+ }
+
+ if (*str == '-') {
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+ "Parsing error memory size value: negative values not allowed");
+ }
+ int res = sscanf(str, UINT64_FORMAT "%c", &_value._val, &_value._multiplier);
+ if (res == 2) {
+ switch (_value._multiplier) {
+ case 'k': case 'K':
+ _value._size = _value._val * 1024;
+ break;
+ case 'm': case 'M':
+ _value._size = _value._val * 1024 * 1024;
+ break;
+ case 'g': case 'G':
+ _value._size = _value._val * 1024 * 1024 * 1024;
+ break;
+ default:
+ _value._size = _value._val;
+ _value._multiplier = ' ';
+ //default case should be to break with no error, since user
+ //can write size in bytes, or might have a delimiter and next arg
+ break;
+ }
+ } else if (res == 1) {
+ _value._size = _value._val;
+ } else {
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+ "Parsing error memory size value: invalid value");
+ }
+}
+
+template <> void DCmdArgument<MemorySizeArgument>::init_value(TRAPS) {
+ if (has_default()) {
+ this->parse_value(_default_string, strlen(_default_string), THREAD);
+ if (HAS_PENDING_EXCEPTION) {
+ fatal("Default string must be parsable");
+ }
+ } else {
+ _value._size = 0;
+ _value._val = 0;
+ _value._multiplier = ' ';
+ }
+}
+
+template <> void DCmdArgument<MemorySizeArgument>::destroy_value() { }
--- a/hotspot/src/share/vm/services/diagnosticArgument.hpp Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/src/share/vm/services/diagnosticArgument.hpp Fri Feb 17 06:34:49 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,49 @@
#include "runtime/thread.hpp"
#include "utilities/exceptions.hpp"
+class StringArrayArgument : public CHeapObj {
+private:
+ GrowableArray<char*>* _array;
+public:
+ StringArrayArgument() {
+ _array = new(ResourceObj::C_HEAP)GrowableArray<char *>(32, true);
+ assert(_array != NULL, "Sanity check");
+ }
+ void add(const char* str, size_t len) {
+ if (str != NULL) {
+ char* ptr = NEW_C_HEAP_ARRAY(char, len+1);
+ strncpy(ptr, str, len);
+ ptr[len] = 0;
+ _array->append(ptr);
+ }
+ }
+ GrowableArray<char*>* array() {
+ return _array;
+ }
+ ~StringArrayArgument() {
+ for (int i=0; i<_array->length(); i++) {
+ if(_array->at(i) != NULL) { // Safety check
+ FREE_C_HEAP_ARRAY(char, _array->at(i));
+ }
+ }
+ delete _array;
+ }
+};
+
+class NanoTimeArgument {
+public:
+ jlong _nanotime;
+ jlong _time;
+ char _unit[3];
+};
+
+class MemorySizeArgument {
+public:
+ u8 _size;
+ u8 _val;
+ char _multiplier;
+};
+
class GenDCmdArgument : public ResourceObj {
protected:
GenDCmdArgument* _next;
@@ -40,6 +83,7 @@
const char* _default_string;
bool _is_set;
bool _is_mandatory;
+ bool _allow_multiple;
GenDCmdArgument(const char* name, const char* description, const char* type,
const char* default_string, bool mandatory) {
_name = name;
@@ -48,6 +92,7 @@
_default_string = default_string;
_is_mandatory = mandatory;
_is_set = false;
+ _allow_multiple = false;
};
public:
const char* name() { return _name; }
@@ -56,6 +101,7 @@
const char* default_string() { return _default_string; }
bool is_set() { return _is_set; }
void set_is_set(bool b) { _is_set = b; }
+ bool allow_multiple() { return _allow_multiple; }
bool is_mandatory() { return _is_mandatory; }
bool has_value() { return _is_set || _default_string != NULL; }
bool has_default() { return _default_string != NULL; }
--- a/hotspot/src/share/vm/services/diagnosticFramework.cpp Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/src/share/vm/services/diagnosticFramework.cpp Fri Feb 17 06:34:49 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -61,7 +61,7 @@
bool DCmdArgIter::next(TRAPS) {
if (_len == 0) return false;
// skipping spaces
- while (_cursor < _len - 1 && isspace(_buffer[_cursor])) {
+ while (_cursor < _len - 1 && _buffer[_cursor] == _delim) {
_cursor++;
}
// handling end of command line
--- a/hotspot/src/share/vm/services/diagnosticFramework.hpp Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/src/share/vm/services/diagnosticFramework.hpp Fri Feb 17 06:34:49 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -195,6 +195,7 @@
DCmdParser() {
_options = NULL;
_arguments_list = NULL;
+ _delim = ' ';
}
void add_dcmd_option(GenDCmdArgument* arg);
void add_dcmd_argument(GenDCmdArgument* arg);
--- a/hotspot/src/share/vm/services/gcNotifier.cpp Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/src/share/vm/services/gcNotifier.cpp Fri Feb 17 06:34:49 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -180,17 +180,43 @@
}
void GCNotifier::sendNotification(TRAPS) {
+ GCNotifier::sendNotificationInternal(THREAD);
+ // Clearing pending exception to avoid premature termination of
+ // the service thread
+ if (HAS_PENDING_EXCEPTION) {
+ CLEAR_PENDING_EXCEPTION;
+ }
+}
+
+class NotificationMark : public StackObj {
+ // This class is used in GCNotifier::sendNotificationInternal to ensure that
+ // the GCNotificationRequest object is properly cleaned up, whatever path
+ // is used to exit the method.
+ GCNotificationRequest* _request;
+public:
+ NotificationMark(GCNotificationRequest* r) {
+ _request = r;
+ }
+ ~NotificationMark() {
+ assert(_request != NULL, "Sanity check");
+ delete _request;
+ }
+};
+
+void GCNotifier::sendNotificationInternal(TRAPS) {
ResourceMark rm(THREAD);
+ HandleMark hm(THREAD);
GCNotificationRequest *request = getRequest();
- if(request != NULL) {
- Handle objGcInfo = createGcInfo(request->gcManager,request->gcStatInfo,THREAD);
+ if (request != NULL) {
+ NotificationMark nm(request);
+ Handle objGcInfo = createGcInfo(request->gcManager, request->gcStatInfo, THREAD);
Handle objName = java_lang_String::create_from_platform_dependent_str(request->gcManager->name(), CHECK);
Handle objAction = java_lang_String::create_from_platform_dependent_str(request->gcAction, CHECK);
Handle objCause = java_lang_String::create_from_platform_dependent_str(request->gcCause, CHECK);
klassOop k = Management::sun_management_GarbageCollectorImpl_klass(CHECK);
- instanceKlassHandle gc_mbean_klass (THREAD, k);
+ instanceKlassHandle gc_mbean_klass(THREAD, k);
instanceOop gc_mbean = request->gcManager->get_memory_manager_instance(THREAD);
instanceHandle gc_mbean_h(THREAD, gc_mbean);
@@ -213,11 +239,6 @@
vmSymbols::createGCNotification_signature(),
&args,
CHECK);
- if (HAS_PENDING_EXCEPTION) {
- CLEAR_PENDING_EXCEPTION;
- }
-
- delete request;
}
}
--- a/hotspot/src/share/vm/services/gcNotifier.hpp Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/src/share/vm/services/gcNotifier.hpp Fri Feb 17 06:34:49 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -60,6 +60,7 @@
static GCNotificationRequest *last_request;
static void addRequest(GCNotificationRequest *request);
static GCNotificationRequest *getRequest();
+ static void sendNotificationInternal(TRAPS);
public:
static void pushNotification(GCMemoryManager *manager, const char *action, const char *cause);
static bool has_event();
--- a/hotspot/src/share/vm/utilities/decoder.cpp Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/src/share/vm/utilities/decoder.cpp Fri Feb 17 06:34:49 2012 -0800
@@ -25,7 +25,9 @@
#include "precompiled.hpp"
#include "prims/jvm.h"
#include "runtime/mutexLocker.hpp"
+#include "runtime/os.hpp"
#include "utilities/decoder.hpp"
+#include "utilities/vmError.hpp"
#if defined(_WINDOWS)
#include "decoder_windows.hpp"
@@ -35,74 +37,94 @@
#include "decoder_elf.hpp"
#endif
-NullDecoder* Decoder::_decoder = NULL;
-NullDecoder Decoder::_do_nothing_decoder;
-Mutex* Decoder::_decoder_lock = new Mutex(Mutex::safepoint,
- "DecoderLock");
+AbstractDecoder* Decoder::_shared_decoder = NULL;
+AbstractDecoder* Decoder::_error_handler_decoder = NULL;
+NullDecoder Decoder::_do_nothing_decoder;
+Mutex* Decoder::_shared_decoder_lock = new Mutex(Mutex::native,
+ "SharedDecoderLock");
-// _decoder_lock should already acquired before enter this method
-NullDecoder* Decoder::get_decoder() {
- assert(_decoder_lock != NULL && _decoder_lock->owned_by_self(),
+AbstractDecoder* Decoder::get_shared_instance() {
+ assert(_shared_decoder_lock != NULL && _shared_decoder_lock->owned_by_self(),
"Require DecoderLock to enter");
- if (_decoder != NULL) {
- return _decoder;
+ if (_shared_decoder == NULL) {
+ _shared_decoder = create_decoder();
}
+ return _shared_decoder;
+}
- // Decoder is a secondary service. Although, it is good to have,
- // but we can live without it.
+AbstractDecoder* Decoder::get_error_handler_instance() {
+ if (_error_handler_decoder == NULL) {
+ _error_handler_decoder = create_decoder();
+ }
+ return _error_handler_decoder;
+}
+
+
+AbstractDecoder* Decoder::create_decoder() {
+ AbstractDecoder* decoder;
#if defined(_WINDOWS)
- _decoder = new (std::nothrow) WindowsDecoder();
+ decoder = new (std::nothrow) WindowsDecoder();
#elif defined (__APPLE__)
- _decoder = new (std::nothrow)MachODecoder();
+ decoder = new (std::nothrow)MachODecoder();
#else
- _decoder = new (std::nothrow)ElfDecoder();
+ decoder = new (std::nothrow)ElfDecoder();
#endif
- if (_decoder == NULL || _decoder->has_error()) {
- if (_decoder != NULL) {
- delete _decoder;
+ if (decoder == NULL || decoder->has_error()) {
+ if (decoder != NULL) {
+ delete decoder;
}
- _decoder = &_do_nothing_decoder;
+ decoder = &_do_nothing_decoder;
}
- return _decoder;
+ return decoder;
}
bool Decoder::decode(address addr, char* buf, int buflen, int* offset, const char* modulepath) {
- assert(_decoder_lock != NULL, "Just check");
- MutexLockerEx locker(_decoder_lock, true);
- NullDecoder* decoder = get_decoder();
+ assert(_shared_decoder_lock != NULL, "Just check");
+ bool error_handling_thread = os::current_thread_id() == VMError::first_error_tid;
+ MutexLockerEx locker(error_handling_thread ? NULL : _shared_decoder_lock, true);
+ AbstractDecoder* decoder = error_handling_thread ?
+ get_error_handler_instance(): get_shared_instance();
assert(decoder != NULL, "null decoder");
return decoder->decode(addr, buf, buflen, offset, modulepath);
}
bool Decoder::demangle(const char* symbol, char* buf, int buflen) {
- assert(_decoder_lock != NULL, "Just check");
- MutexLockerEx locker(_decoder_lock, true);
- NullDecoder* decoder = get_decoder();
+ assert(_shared_decoder_lock != NULL, "Just check");
+ bool error_handling_thread = os::current_thread_id() == VMError::first_error_tid;
+ MutexLockerEx locker(error_handling_thread ? NULL : _shared_decoder_lock, true);
+ AbstractDecoder* decoder = error_handling_thread ?
+ get_error_handler_instance(): get_shared_instance();
assert(decoder != NULL, "null decoder");
return decoder->demangle(symbol, buf, buflen);
}
bool Decoder::can_decode_C_frame_in_vm() {
- assert(_decoder_lock != NULL, "Just check");
- MutexLockerEx locker(_decoder_lock, true);
- NullDecoder* decoder = get_decoder();
+ assert(_shared_decoder_lock != NULL, "Just check");
+ bool error_handling_thread = os::current_thread_id() == VMError::first_error_tid;
+ MutexLockerEx locker(error_handling_thread ? NULL : _shared_decoder_lock, true);
+ AbstractDecoder* decoder = error_handling_thread ?
+ get_error_handler_instance(): get_shared_instance();
assert(decoder != NULL, "null decoder");
return decoder->can_decode_C_frame_in_vm();
}
-// shutdown real decoder and replace it with
-// _do_nothing_decoder
+/*
+ * Shutdown shared decoder and replace it with
+ * _do_nothing_decoder. Do nothing with error handler
+ * instance, since the JVM is going down.
+ */
void Decoder::shutdown() {
- assert(_decoder_lock != NULL, "Just check");
- MutexLockerEx locker(_decoder_lock, true);
+ assert(_shared_decoder_lock != NULL, "Just check");
+ MutexLockerEx locker(_shared_decoder_lock, true);
- if (_decoder != NULL && _decoder != &_do_nothing_decoder) {
- delete _decoder;
+ if (_shared_decoder != NULL &&
+ _shared_decoder != &_do_nothing_decoder) {
+ delete _shared_decoder;
}
- _decoder = &_do_nothing_decoder;
+ _shared_decoder = &_do_nothing_decoder;
}
--- a/hotspot/src/share/vm/utilities/decoder.hpp Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/src/share/vm/utilities/decoder.hpp Fri Feb 17 06:34:49 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,7 @@
#include "memory/allocation.hpp"
#include "runtime/mutex.hpp"
-class NullDecoder: public CHeapObj {
+class AbstractDecoder : public CHeapObj {
public:
// status code for decoding native C frame
enum decoder_status {
@@ -43,6 +43,34 @@
helper_init_error // SymInitialize failed (Windows only)
};
+ // decode an pc address to corresponding function name and an offset from the beginning of
+ // the function
+ virtual bool decode(address pc, char* buf, int buflen, int* offset,
+ const char* modulepath = NULL) = 0;
+ // demangle a C++ symbol
+ virtual bool demangle(const char* symbol, char* buf, int buflen) = 0;
+ // if the decoder can decode symbols in vm
+ virtual bool can_decode_C_frame_in_vm() const = 0;
+
+ virtual decoder_status status() const {
+ return _decoder_status;
+ }
+
+ virtual bool has_error() const {
+ return is_error(_decoder_status);
+ }
+
+ static bool is_error(decoder_status status) {
+ return (status > 0);
+ }
+
+protected:
+ decoder_status _decoder_status;
+};
+
+// Do nothing decoder
+class NullDecoder : public AbstractDecoder {
+public:
NullDecoder() {
_decoder_status = not_available;
}
@@ -61,40 +89,34 @@
virtual bool can_decode_C_frame_in_vm() const {
return false;
}
-
- virtual decoder_status status() const {
- return _decoder_status;
- }
-
- virtual bool has_error() const {
- return is_error(_decoder_status);
- }
-
- static bool is_error(decoder_status status) {
- return (status > 0);
- }
-
-protected:
- decoder_status _decoder_status;
};
-class Decoder: AllStatic {
+class Decoder : AllStatic {
public:
static bool decode(address pc, char* buf, int buflen, int* offset, const char* modulepath = NULL);
static bool demangle(const char* symbol, char* buf, int buflen);
static bool can_decode_C_frame_in_vm();
+ // shutdown shared instance
static void shutdown();
protected:
- static NullDecoder* get_decoder();
+ // shared decoder instance, _shared_instance_lock is needed
+ static AbstractDecoder* get_shared_instance();
+ // a private instance for error handler. Error handler can be
+ // triggered almost everywhere, including signal handler, where
+ // no lock can be taken. So the shared decoder can not be used
+ // in this scenario.
+ static AbstractDecoder* get_error_handler_instance();
+ static AbstractDecoder* create_decoder();
private:
- static NullDecoder* _decoder;
- static NullDecoder _do_nothing_decoder;
+ static AbstractDecoder* _shared_decoder;
+ static AbstractDecoder* _error_handler_decoder;
+ static NullDecoder _do_nothing_decoder;
protected:
- static Mutex* _decoder_lock;
+ static Mutex* _shared_decoder_lock;
};
#endif // SHARE_VM_UTILITIES_DECODER_HPP
--- a/hotspot/src/share/vm/utilities/decoder_elf.hpp Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/src/share/vm/utilities/decoder_elf.hpp Fri Feb 17 06:34:49 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@
#include "utilities/decoder.hpp"
#include "utilities/elfFile.hpp"
-class ElfDecoder: public NullDecoder {
+class ElfDecoder : public AbstractDecoder {
public:
ElfDecoder() {
--- a/hotspot/src/share/vm/utilities/preserveException.cpp Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/src/share/vm/utilities/preserveException.cpp Fri Feb 17 06:34:49 2012 -0800
@@ -32,9 +32,9 @@
thread = Thread::current();
_thread = thread;
_preserved_exception_oop = Handle(thread, _thread->pending_exception());
- _thread->clear_pending_exception(); // Needed to avoid infinite recursion
_preserved_exception_line = _thread->exception_line();
_preserved_exception_file = _thread->exception_file();
+ _thread->clear_pending_exception(); // Needed to avoid infinite recursion
}
--- a/hotspot/src/share/vm/utilities/vmError.hpp Fri Feb 17 13:23:29 2012 +0100
+++ b/hotspot/src/share/vm/utilities/vmError.hpp Fri Feb 17 06:34:49 2012 -0800
@@ -27,11 +27,12 @@
#include "utilities/globalDefinitions.hpp"
-
+class Decoder;
class VM_ReportJavaOutOfMemory;
class VMError : public StackObj {
friend class VM_ReportJavaOutOfMemory;
+ friend class Decoder;
enum ErrorType {
internal_error = 0xe0000000,