aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoramurillo <none@none>2013-02-08 08:07:06 -0800
committeramurillo <none@none>2013-02-08 08:07:06 -0800
commitd7be921d0b618870b7f2c32522333a04d1a849c2 (patch)
tree04c0166a721e5a36b83b515dccd92923a52ad237
parentb2c6124e361dfea59047209f662be5a7bb23367a (diff)
parent733167cf79832bb14d1c6dbd981268f6d66272cd (diff)
-rw-r--r--agent/src/os/linux/LinuxDebuggerLocal.c12
-rw-r--r--agent/src/os/linux/libproc.h8
-rw-r--r--agent/src/os/win32/windbg/sawindbg.cpp92
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/amd64/WindbgAMD64Thread.java18
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/x86/WindbgX86Thread.java18
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/memory/AFLBinaryTreeDictionary.java (renamed from agent/src/share/classes/sun/jvm/hotspot/memory/BinaryTreeDictionary.java)10
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java6
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/memory/FreeList.java4
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java2
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/runtime/OSThread.java9
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/runtime/ThreadLocalAllocBuffer.java20
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java9
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/runtime/win32_amd64/Win32AMD64JavaThreadPDAccess.java14
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/runtime/win32_x86/Win32X86JavaThreadPDAccess.java14
-rw-r--r--make/Makefile54
-rw-r--r--make/bsd/makefiles/dtrace.make12
-rw-r--r--make/bsd/makefiles/mapfile-vers-debug1
-rw-r--r--make/bsd/makefiles/mapfile-vers-product1
-rw-r--r--make/bsd/makefiles/minimal1.make2
-rw-r--r--make/excludeSrc.make8
-rw-r--r--make/hotspot_version2
-rw-r--r--make/linux/makefiles/mapfile-vers-debug1
-rw-r--r--make/linux/makefiles/mapfile-vers-product1
-rw-r--r--make/linux/makefiles/minimal1.make2
-rw-r--r--make/solaris/Makefile22
-rw-r--r--make/solaris/makefiles/dtrace.make12
-rw-r--r--make/solaris/makefiles/kernel.make32
-rw-r--r--make/solaris/makefiles/mapfile-vers1
-rw-r--r--make/windows/build.bat5
-rw-r--r--make/windows/create_obj_files.sh7
-rw-r--r--make/windows/makefiles/defs.make17
-rw-r--r--make/windows/makefiles/projectcreator.make59
-rw-r--r--make/windows/makefiles/vm.make6
-rw-r--r--src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp9
-rw-r--r--src/cpu/sparc/vm/c1_Runtime1_sparc.cpp5
-rw-r--r--src/cpu/sparc/vm/c2_globals_sparc.hpp2
-rw-r--r--src/cpu/sparc/vm/cppInterpreter_sparc.cpp5
-rw-r--r--src/cpu/sparc/vm/macroAssembler_sparc.cpp9
-rw-r--r--src/cpu/sparc/vm/macroAssembler_sparc.hpp5
-rw-r--r--src/cpu/sparc/vm/templateInterpreter_sparc.cpp5
-rw-r--r--src/cpu/sparc/vm/templateTable_sparc.cpp5
-rw-r--r--src/cpu/x86/vm/assembler_x86.cpp5
-rw-r--r--src/cpu/x86/vm/assembler_x86.hpp4
-rw-r--r--src/cpu/x86/vm/c1_CodeStubs_x86.cpp9
-rw-r--r--src/cpu/x86/vm/c1_Runtime1_x86.cpp5
-rw-r--r--src/cpu/x86/vm/c2_globals_x86.hpp2
-rw-r--r--src/cpu/x86/vm/cppInterpreter_x86.cpp5
-rw-r--r--src/cpu/x86/vm/macroAssembler_x86.cpp9
-rw-r--r--src/cpu/x86/vm/macroAssembler_x86.hpp5
-rw-r--r--src/cpu/x86/vm/templateInterpreter_x86_32.cpp5
-rw-r--r--src/cpu/x86/vm/templateInterpreter_x86_64.cpp5
-rw-r--r--src/cpu/x86/vm/templateTable_x86_32.cpp5
-rw-r--r--src/cpu/x86/vm/templateTable_x86_64.cpp5
-rw-r--r--src/cpu/zero/vm/assembler_zero.cpp5
-rw-r--r--src/cpu/zero/vm/cppInterpreter_zero.cpp5
-rw-r--r--src/os/linux/vm/os_linux.cpp12
-rw-r--r--src/os/windows/vm/os_windows.cpp200
-rw-r--r--src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp2
-rw-r--r--src/os_cpu/linux_x86/vm/os_linux_x86.cpp2
-rw-r--r--src/os_cpu/windows_x86/vm/os_windows_x86.cpp4
-rw-r--r--src/share/tools/whitebox/sun/hotspot/WhiteBox.java5
-rw-r--r--src/share/vm/adlc/adlparse.cpp54
-rw-r--r--src/share/vm/c1/c1_CodeStubs.hpp5
-rw-r--r--src/share/vm/c1/c1_GraphBuilder.cpp9
-rw-r--r--src/share/vm/c1/c1_Instruction.cpp2
-rw-r--r--src/share/vm/c1/c1_LIRGenerator.cpp21
-rw-r--r--src/share/vm/ci/ciEnv.cpp3
-rw-r--r--src/share/vm/ci/ciInstanceKlass.cpp3
-rw-r--r--src/share/vm/ci/ciMethod.cpp5
-rw-r--r--src/share/vm/ci/ciMethod.hpp2
-rw-r--r--src/share/vm/ci/ciMethodData.cpp1
-rw-r--r--src/share/vm/ci/ciReplay.cpp1
-rw-r--r--src/share/vm/classfile/classFileParser.cpp47
-rw-r--r--src/share/vm/classfile/classLoaderData.cpp9
-rw-r--r--src/share/vm/classfile/classLoaderData.hpp4
-rw-r--r--src/share/vm/classfile/metadataOnStackMark.cpp69
-rw-r--r--src/share/vm/classfile/metadataOnStackMark.hpp45
-rw-r--r--src/share/vm/classfile/stackMapFrame.hpp2
-rw-r--r--src/share/vm/classfile/systemDictionary.cpp83
-rw-r--r--src/share/vm/classfile/systemDictionary.hpp6
-rw-r--r--src/share/vm/classfile/vmSymbols.hpp3
-rw-r--r--src/share/vm/compiler/compileBroker.cpp2
-rw-r--r--src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp14
-rw-r--r--src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp2
-rw-r--r--src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp16
-rw-r--r--src/share/vm/gc_implementation/g1/concurrentMark.cpp280
-rw-r--r--src/share/vm/gc_implementation/g1/concurrentMark.hpp35
-rw-r--r--src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp5
-rw-r--r--src/share/vm/gc_implementation/g1/heapRegion.hpp5
-rw-r--r--src/share/vm/gc_implementation/shared/allocationStats.cpp5
-rw-r--r--src/share/vm/gc_implementation/shared/allocationStats.hpp5
-rw-r--r--src/share/vm/gc_implementation/shared/concurrentGCThread.hpp5
-rw-r--r--src/share/vm/gc_implementation/shared/gSpaceCounters.cpp5
-rw-r--r--src/share/vm/gc_implementation/shared/gSpaceCounters.hpp5
-rw-r--r--src/share/vm/gc_implementation/shared/gcAdaptivePolicyCounters.hpp5
-rw-r--r--src/share/vm/gc_implementation/shared/hSpaceCounters.hpp5
-rw-r--r--src/share/vm/gc_implementation/shared/immutableSpace.cpp5
-rw-r--r--src/share/vm/gc_implementation/shared/isGCActiveMark.hpp5
-rw-r--r--src/share/vm/gc_implementation/shared/markSweep.inline.hpp5
-rw-r--r--src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp5
-rw-r--r--src/share/vm/gc_implementation/shared/mutableSpace.cpp5
-rw-r--r--src/share/vm/gc_implementation/shared/spaceCounters.cpp5
-rw-r--r--src/share/vm/gc_implementation/shared/spaceCounters.hpp5
-rw-r--r--src/share/vm/gc_implementation/shared/vmGCOperations.cpp11
-rw-r--r--src/share/vm/gc_implementation/shared/vmGCOperations.hpp14
-rw-r--r--src/share/vm/interpreter/bytecodeInterpreter.cpp4
-rw-r--r--src/share/vm/interpreter/linkResolver.cpp4
-rw-r--r--src/share/vm/memory/allocation.hpp5
-rw-r--r--src/share/vm/memory/binaryTreeDictionary.cpp52
-rw-r--r--src/share/vm/memory/binaryTreeDictionary.hpp4
-rw-r--r--src/share/vm/memory/cardTableModRefBS.cpp7
-rw-r--r--src/share/vm/memory/cardTableRS.cpp7
-rw-r--r--src/share/vm/memory/collectorPolicy.cpp32
-rw-r--r--src/share/vm/memory/collectorPolicy.hpp19
-rw-r--r--src/share/vm/memory/filemap.cpp13
-rw-r--r--src/share/vm/memory/freeBlockDictionary.cpp10
-rw-r--r--src/share/vm/memory/freeList.cpp9
-rw-r--r--src/share/vm/memory/genCollectedHeap.cpp27
-rw-r--r--src/share/vm/memory/generationSpec.cpp9
-rw-r--r--src/share/vm/memory/heapInspection.cpp284
-rw-r--r--src/share/vm/memory/heapInspection.hpp236
-rw-r--r--src/share/vm/memory/metaspace.cpp12
-rw-r--r--src/share/vm/memory/space.cpp5
-rw-r--r--src/share/vm/memory/space.hpp5
-rw-r--r--src/share/vm/memory/specialized_oop_closures.hpp27
-rw-r--r--src/share/vm/memory/tenuredGeneration.cpp11
-rw-r--r--src/share/vm/memory/tenuredGeneration.hpp9
-rw-r--r--src/share/vm/memory/universe.cpp61
-rw-r--r--src/share/vm/memory/universe.hpp12
-rw-r--r--src/share/vm/oops/annotations.cpp47
-rw-r--r--src/share/vm/oops/annotations.hpp10
-rw-r--r--src/share/vm/oops/arrayKlass.hpp10
-rw-r--r--src/share/vm/oops/constMethod.cpp15
-rw-r--r--src/share/vm/oops/constMethod.hpp13
-rw-r--r--src/share/vm/oops/constantPool.cpp105
-rw-r--r--src/share/vm/oops/constantPool.hpp48
-rw-r--r--src/share/vm/oops/cpCache.cpp5
-rw-r--r--src/share/vm/oops/instanceClassLoaderKlass.cpp17
-rw-r--r--src/share/vm/oops/instanceClassLoaderKlass.hpp5
-rw-r--r--src/share/vm/oops/instanceKlass.cpp70
-rw-r--r--src/share/vm/oops/instanceKlass.hpp29
-rw-r--r--src/share/vm/oops/instanceMirrorKlass.cpp21
-rw-r--r--src/share/vm/oops/instanceMirrorKlass.hpp5
-rw-r--r--src/share/vm/oops/instanceRefKlass.cpp21
-rw-r--r--src/share/vm/oops/instanceRefKlass.hpp5
-rw-r--r--src/share/vm/oops/klass.cpp19
-rw-r--r--src/share/vm/oops/klass.hpp35
-rw-r--r--src/share/vm/oops/klassPS.hpp8
-rw-r--r--src/share/vm/oops/method.cpp42
-rw-r--r--src/share/vm/oops/method.hpp14
-rw-r--r--src/share/vm/oops/methodData.cpp12
-rw-r--r--src/share/vm/oops/methodData.hpp8
-rw-r--r--src/share/vm/oops/objArrayKlass.cpp13
-rw-r--r--src/share/vm/oops/objArrayKlass.hpp5
-rw-r--r--src/share/vm/oops/objArrayKlass.inline.hpp9
-rw-r--r--src/share/vm/oops/oop.hpp15
-rw-r--r--src/share/vm/oops/oop.inline.hpp11
-rw-r--r--src/share/vm/oops/oop.pcgc.inline.hpp5
-rw-r--r--src/share/vm/oops/oop.psgc.inline.hpp5
-rw-r--r--src/share/vm/oops/symbol.cpp1
-rw-r--r--src/share/vm/oops/typeArrayKlass.cpp9
-rw-r--r--src/share/vm/opto/bytecodeInfo.cpp52
-rw-r--r--src/share/vm/opto/callGenerator.cpp6
-rw-r--r--src/share/vm/opto/generateOptoStub.cpp17
-rw-r--r--src/share/vm/opto/parse.hpp3
-rw-r--r--src/share/vm/opto/parse3.cpp5
-rw-r--r--src/share/vm/precompiled/precompiled.hpp5
-rw-r--r--src/share/vm/prims/jni.cpp9
-rw-r--r--src/share/vm/prims/jniCheck.hpp4
-rw-r--r--src/share/vm/prims/jvm.cpp15
-rw-r--r--src/share/vm/prims/jvm.h7
-rw-r--r--src/share/vm/prims/jvmtiCodeBlobEvents.hpp4
-rw-r--r--src/share/vm/prims/jvmtiEnv.cpp6
-rw-r--r--src/share/vm/prims/jvmtiEnvBase.cpp12
-rw-r--r--src/share/vm/prims/jvmtiEnvBase.hpp1
-rw-r--r--src/share/vm/prims/jvmtiExport.cpp11
-rw-r--r--src/share/vm/prims/jvmtiExport.hpp1
-rw-r--r--src/share/vm/prims/jvmtiExtensions.hpp4
-rw-r--r--src/share/vm/prims/jvmtiImpl.cpp6
-rw-r--r--src/share/vm/prims/jvmtiImpl.hpp5
-rw-r--r--src/share/vm/prims/jvmtiRawMonitor.hpp4
-rw-r--r--src/share/vm/prims/jvmtiRedefineClasses.cpp290
-rw-r--r--src/share/vm/prims/jvmtiRedefineClasses.hpp20
-rw-r--r--src/share/vm/prims/jvmtiTagMap.cpp5
-rw-r--r--src/share/vm/prims/jvmtiTagMap.hpp4
-rw-r--r--src/share/vm/prims/nativeLookup.cpp1
-rw-r--r--src/share/vm/prims/unsafe.cpp13
-rw-r--r--src/share/vm/prims/whitebox.cpp76
-rw-r--r--src/share/vm/runtime/arguments.cpp120
-rw-r--r--src/share/vm/runtime/arguments.hpp7
-rw-r--r--src/share/vm/runtime/deoptimization.cpp2
-rw-r--r--src/share/vm/runtime/fprofiler.hpp1
-rw-r--r--src/share/vm/runtime/globals.cpp9
-rw-r--r--src/share/vm/runtime/globals_extension.hpp9
-rw-r--r--src/share/vm/runtime/init.cpp1
-rw-r--r--src/share/vm/runtime/java.cpp5
-rw-r--r--src/share/vm/runtime/os.cpp30
-rw-r--r--src/share/vm/runtime/safepoint.cpp13
-rw-r--r--src/share/vm/runtime/sharedRuntime.cpp9
-rw-r--r--src/share/vm/runtime/sharedRuntime.hpp5
-rw-r--r--src/share/vm/runtime/synchronizer.cpp2
-rw-r--r--src/share/vm/runtime/thread.cpp80
-rw-r--r--src/share/vm/runtime/thread.hpp23
-rw-r--r--src/share/vm/runtime/vframeArray.cpp2
-rw-r--r--src/share/vm/runtime/vmStructs.cpp33
-rw-r--r--src/share/vm/runtime/vmStructs.hpp4
-rw-r--r--src/share/vm/runtime/vm_version.cpp6
-rw-r--r--src/share/vm/services/attachListener.cpp6
-rw-r--r--src/share/vm/services/attachListener.hpp6
-rw-r--r--src/share/vm/services/classLoadingService.cpp1
-rw-r--r--src/share/vm/services/classLoadingService.hpp1
-rw-r--r--src/share/vm/services/diagnosticCommand.cpp115
-rw-r--r--src/share/vm/services/diagnosticCommand.hpp36
-rw-r--r--src/share/vm/services/g1MemoryPool.hpp5
-rw-r--r--src/share/vm/services/heapDumper.cpp5
-rw-r--r--src/share/vm/services/management.cpp1
-rw-r--r--src/share/vm/services/memBaseline.cpp1
-rw-r--r--src/share/vm/services/memPtr.cpp2
-rw-r--r--src/share/vm/services/memPtr.hpp10
-rw-r--r--src/share/vm/services/memRecorder.cpp5
-rw-r--r--src/share/vm/services/memRecorder.hpp6
-rw-r--r--src/share/vm/services/memReporter.hpp1
-rw-r--r--src/share/vm/services/memTrackWorker.cpp11
-rw-r--r--src/share/vm/services/memTrackWorker.hpp1
-rw-r--r--src/share/vm/services/memTracker.cpp50
-rw-r--r--src/share/vm/services/memTracker.hpp26
-rw-r--r--src/share/vm/services/memoryPool.cpp5
-rw-r--r--src/share/vm/services/memoryPool.hpp9
-rw-r--r--src/share/vm/services/memoryService.cpp45
-rw-r--r--src/share/vm/services/psMemoryPool.hpp5
-rw-r--r--src/share/vm/services/runtimeService.cpp1
-rw-r--r--src/share/vm/utilities/macros.hpp22
-rw-r--r--src/share/vm/utilities/top.hpp4
-rw-r--r--src/share/vm/utilities/yieldingWorkgroup.cpp5
-rw-r--r--src/share/vm/utilities/yieldingWorkgroup.hpp5
-rw-r--r--test/TEST.ROOT2
-rw-r--r--test/compiler/8004741/Test8004741.java162
-rw-r--r--test/runtime/7158988/FieldMonitor.java4
-rw-r--r--test/runtime/7158988/TestFieldMonitor.sh75
-rw-r--r--test/runtime/8000968/Test8000968.sh99
-rw-r--r--test/runtime/8007475/StackMapFrameTest.java41
-rw-r--r--test/runtime/NMT/AllocTestType.java72
-rw-r--r--test/runtime/NMT/BaselineWithParameter.java54
-rw-r--r--test/runtime/NMT/CommandLineDetail.java45
-rw-r--r--test/runtime/NMT/CommandLineEmptyArgument.java41
-rw-r--r--test/runtime/NMT/CommandLineInvalidArgument.java41
-rw-r--r--test/runtime/NMT/CommandLineSummary.java45
-rw-r--r--test/runtime/NMT/CommandLineTurnOffNMT.java44
-rw-r--r--test/runtime/NMT/JcmdScale.java67
-rw-r--r--test/runtime/NMT/JcmdWithNMTDisabled.java63
-rw-r--r--test/runtime/NMT/PrintNMTStatistics.java66
-rw-r--r--test/runtime/NMT/PrintNMTStatisticsWithNMTDisabled.java44
-rw-r--r--test/runtime/NMT/ShutdownTwice.java56
-rw-r--r--test/runtime/NMT/SummaryAfterShutdown.java56
-rw-r--r--test/runtime/NMT/SummarySanityCheck.java119
-rw-r--r--test/testlibrary/OutputAnalyzerTest.java108
-rw-r--r--test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java50
-rw-r--r--test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java191
-rw-r--r--test/testlibrary/com/oracle/java/testlibrary/OutputBuffer.java59
-rw-r--r--test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java141
-rw-r--r--test/testlibrary/com/oracle/java/testlibrary/StreamPumper.java76
261 files changed, 4373 insertions, 1939 deletions
diff --git a/agent/src/os/linux/LinuxDebuggerLocal.c b/agent/src/os/linux/LinuxDebuggerLocal.c
index 5b49294e9..1d3c3bbd0 100644
--- a/agent/src/os/linux/LinuxDebuggerLocal.c
+++ b/agent/src/os/linux/LinuxDebuggerLocal.c
@@ -280,7 +280,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLo
return (err == PS_OK)? array : 0;
}
-#if defined(i386) || defined(ia64) || defined(amd64) || defined(sparc) || defined(sparcv9)
+#if defined(i386) || defined(amd64) || defined(sparc) || defined(sparcv9)
JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getThreadIntegerRegisterSet0
(JNIEnv *env, jobject this_obj, jint lwp_id) {
@@ -299,9 +299,6 @@ JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLo
#ifdef i386
#define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG
#endif
-#ifdef ia64
-#define NPRGREG IA64_REG_COUNT
-#endif
#ifdef amd64
#define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG
#endif
@@ -336,13 +333,6 @@ JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLo
#endif /* i386 */
-#if ia64
- regs = (*env)->GetLongArrayElements(env, array, &isCopy);
- for (i = 0; i < NPRGREG; i++ ) {
- regs[i] = 0xDEADDEAD;
- }
-#endif /* ia64 */
-
#ifdef amd64
#define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg
diff --git a/agent/src/os/linux/libproc.h b/agent/src/os/linux/libproc.h
index 5f583631c..4cde0c19d 100644
--- a/agent/src/os/linux/libproc.h
+++ b/agent/src/os/linux/libproc.h
@@ -79,14 +79,6 @@ combination of ptrace and /proc calls.
*************************************************************************************/
-#ifdef ia64
-struct user_regs_struct {
-/* copied from user.h which doesn't define this in a struct */
-
-#define IA64_REG_COUNT (EF_SIZE/8+32) /* integer and fp regs */
-unsigned long regs[IA64_REG_COUNT]; /* integer and fp regs */
-};
-#endif
#if defined(sparc) || defined(sparcv9)
#define user_regs_struct pt_regs
diff --git a/agent/src/os/win32/windbg/sawindbg.cpp b/agent/src/os/win32/windbg/sawindbg.cpp
index c0a1e6696..2ee4a2a02 100644
--- a/agent/src/os/win32/windbg/sawindbg.cpp
+++ b/agent/src/os/win32/windbg/sawindbg.cpp
@@ -27,10 +27,7 @@
#include "sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal.h"
-#ifdef _M_IA64
- #include "sun_jvm_hotspot_debugger_ia64_IA64ThreadContext.h"
- #define NPRGREG sun_jvm_hotspot_debugger_ia64_IA64ThreadContext_NPRGREG
-#elif _M_IX86
+#ifdef _M_IX86
#include "sun_jvm_hotspot_debugger_x86_X86ThreadContext.h"
#define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG
#elif _M_AMD64
@@ -491,92 +488,7 @@ static bool addThreads(JNIEnv* env, jobject obj) {
memset(&context, 0, sizeof(CONTEXT));
#undef REG_INDEX
-#ifdef _M_IA64
- #define REG_INDEX(x) sun_jvm_hotspot_debugger_ia64_IA64ThreadContext_##x
-
- context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG;
- ptrIDebugAdvanced->GetThreadContext(&context, sizeof(CONTEXT));
-
- ptrRegs[REG_INDEX(GR0)] = 0; // always 0
- ptrRegs[REG_INDEX(GR1)] = context.IntGp; // r1
- ptrRegs[REG_INDEX(GR2)] = context.IntT0; // r2-r3
- ptrRegs[REG_INDEX(GR3)] = context.IntT1;
- ptrRegs[REG_INDEX(GR4)] = context.IntS0; // r4-r7
- ptrRegs[REG_INDEX(GR5)] = context.IntS1;
- ptrRegs[REG_INDEX(GR6)] = context.IntS2;
- ptrRegs[REG_INDEX(GR7)] = context.IntS3;
- ptrRegs[REG_INDEX(GR8)] = context.IntV0; // r8
- ptrRegs[REG_INDEX(GR9)] = context.IntT2; // r9-r11
- ptrRegs[REG_INDEX(GR10)] = context.IntT3;
- ptrRegs[REG_INDEX(GR11)] = context.IntT4;
- ptrRegs[REG_INDEX(GR12)] = context.IntSp; // r12 stack pointer
- ptrRegs[REG_INDEX(GR13)] = context.IntTeb; // r13 teb
- ptrRegs[REG_INDEX(GR14)] = context.IntT5; // r14-r31
- ptrRegs[REG_INDEX(GR15)] = context.IntT6;
- ptrRegs[REG_INDEX(GR16)] = context.IntT7;
- ptrRegs[REG_INDEX(GR17)] = context.IntT8;
- ptrRegs[REG_INDEX(GR18)] = context.IntT9;
- ptrRegs[REG_INDEX(GR19)] = context.IntT10;
- ptrRegs[REG_INDEX(GR20)] = context.IntT11;
- ptrRegs[REG_INDEX(GR21)] = context.IntT12;
- ptrRegs[REG_INDEX(GR22)] = context.IntT13;
- ptrRegs[REG_INDEX(GR23)] = context.IntT14;
- ptrRegs[REG_INDEX(GR24)] = context.IntT15;
- ptrRegs[REG_INDEX(GR25)] = context.IntT16;
- ptrRegs[REG_INDEX(GR26)] = context.IntT17;
- ptrRegs[REG_INDEX(GR27)] = context.IntT18;
- ptrRegs[REG_INDEX(GR28)] = context.IntT19;
- ptrRegs[REG_INDEX(GR29)] = context.IntT20;
- ptrRegs[REG_INDEX(GR30)] = context.IntT21;
- ptrRegs[REG_INDEX(GR31)] = context.IntT22;
-
- ptrRegs[REG_INDEX(INT_NATS)] = context.IntNats;
- ptrRegs[REG_INDEX(PREDS)] = context.Preds;
-
- ptrRegs[REG_INDEX(BR_RP)] = context.BrRp;
- ptrRegs[REG_INDEX(BR1)] = context.BrS0; // b1-b5
- ptrRegs[REG_INDEX(BR2)] = context.BrS1;
- ptrRegs[REG_INDEX(BR3)] = context.BrS2;
- ptrRegs[REG_INDEX(BR4)] = context.BrS3;
- ptrRegs[REG_INDEX(BR5)] = context.BrS4;
- ptrRegs[REG_INDEX(BR6)] = context.BrT0; // b6-b7
- ptrRegs[REG_INDEX(BR7)] = context.BrT1;
-
- ptrRegs[REG_INDEX(AP_UNAT)] = context.ApUNAT;
- ptrRegs[REG_INDEX(AP_LC)] = context.ApLC;
- ptrRegs[REG_INDEX(AP_EC)] = context.ApEC;
- ptrRegs[REG_INDEX(AP_CCV)] = context.ApCCV;
- ptrRegs[REG_INDEX(AP_DCR)] = context.ApDCR;
-
- ptrRegs[REG_INDEX(RS_PFS)] = context.RsPFS;
- ptrRegs[REG_INDEX(RS_BSP)] = context.RsBSP;
- ptrRegs[REG_INDEX(RS_BSPSTORE)] = context.RsBSPSTORE;
- ptrRegs[REG_INDEX(RS_RSC)] = context.RsRSC;
- ptrRegs[REG_INDEX(RS_RNAT)] = context.RsRNAT;
-
- ptrRegs[REG_INDEX(ST_IPSR)] = context.StIPSR;
- ptrRegs[REG_INDEX(ST_IIP)] = context.StIIP;
- ptrRegs[REG_INDEX(ST_IFS)] = context.StIFS;
-
- ptrRegs[REG_INDEX(DB_I0)] = context.DbI0;
- ptrRegs[REG_INDEX(DB_I1)] = context.DbI1;
- ptrRegs[REG_INDEX(DB_I2)] = context.DbI2;
- ptrRegs[REG_INDEX(DB_I3)] = context.DbI3;
- ptrRegs[REG_INDEX(DB_I4)] = context.DbI4;
- ptrRegs[REG_INDEX(DB_I5)] = context.DbI5;
- ptrRegs[REG_INDEX(DB_I6)] = context.DbI6;
- ptrRegs[REG_INDEX(DB_I7)] = context.DbI7;
-
- ptrRegs[REG_INDEX(DB_D0)] = context.DbD0;
- ptrRegs[REG_INDEX(DB_D1)] = context.DbD1;
- ptrRegs[REG_INDEX(DB_D2)] = context.DbD2;
- ptrRegs[REG_INDEX(DB_D3)] = context.DbD3;
- ptrRegs[REG_INDEX(DB_D4)] = context.DbD4;
- ptrRegs[REG_INDEX(DB_D5)] = context.DbD5;
- ptrRegs[REG_INDEX(DB_D6)] = context.DbD6;
- ptrRegs[REG_INDEX(DB_D7)] = context.DbD7;
-
-#elif _M_IX86
+#ifdef _M_IX86
#define REG_INDEX(x) sun_jvm_hotspot_debugger_x86_X86ThreadContext_##x
context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
diff --git a/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/amd64/WindbgAMD64Thread.java b/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/amd64/WindbgAMD64Thread.java
index bf30dd0a5..ec5aea35e 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/amd64/WindbgAMD64Thread.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/amd64/WindbgAMD64Thread.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -34,21 +34,11 @@ class WindbgAMD64Thread implements ThreadProxy {
private boolean gotID;
private long id;
- /** The address argument must be the address of the HANDLE of the
- desired thread in the target process. */
+ // The address argument must be the address of the OSThread::_thread_id
WindbgAMD64Thread(WindbgDebugger debugger, Address addr) {
this.debugger = debugger;
- // FIXME: size of data fetched here should be configurable.
- // However, making it so would produce a dependency on the "types"
- // package from the debugger package, which is not desired.
-
- // another hack here is that we use sys thread id instead of handle.
- // windbg can't get details based on handles it seems.
- // I assume that osThread_win32 thread struct has _thread_id (which
- // sys thread id) just after handle field.
-
- this.sysId = (int) addr.addOffsetTo(debugger.getAddressSize()).getCIntegerAt(0, 4, true);
- gotID = false;
+ this.sysId = (long)addr.getCIntegerAt(0, 4, true);
+ gotID = false;
}
WindbgAMD64Thread(WindbgDebugger debugger, long sysId) {
diff --git a/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/x86/WindbgX86Thread.java b/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/x86/WindbgX86Thread.java
index 84d19e03b..e5417972b 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/x86/WindbgX86Thread.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/x86/WindbgX86Thread.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -34,21 +34,11 @@ class WindbgX86Thread implements ThreadProxy {
private boolean gotID;
private long id;
- /** The address argument must be the address of the HANDLE of the
- desired thread in the target process. */
+ // The address argument must be the address of OSThread::_thread_id
WindbgX86Thread(WindbgDebugger debugger, Address addr) {
this.debugger = debugger;
- // FIXME: size of data fetched here should be configurable.
- // However, making it so would produce a dependency on the "types"
- // package from the debugger package, which is not desired.
-
- // another hack here is that we use sys thread id instead of handle.
- // windbg can't get details based on handles it seems.
- // I assume that osThread_win32 thread struct has _thread_id (which
- // sys thread id) just after handle field.
-
- this.sysId = (int) addr.addOffsetTo(debugger.getAddressSize()).getCIntegerAt(0, 4, true);
- gotID = false;
+ this.sysId = (long)addr.getCIntegerAt(0, 4, true);
+ gotID = false;
}
WindbgX86Thread(WindbgDebugger debugger, long sysId) {
diff --git a/agent/src/share/classes/sun/jvm/hotspot/memory/BinaryTreeDictionary.java b/agent/src/share/classes/sun/jvm/hotspot/memory/AFLBinaryTreeDictionary.java
index 802af91bb..5b56cf5f8 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/memory/BinaryTreeDictionary.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/memory/AFLBinaryTreeDictionary.java
@@ -1,6 +1,6 @@
/*
* @(#)BinaryTreeDictionary.java
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -30,7 +30,7 @@ import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.types.*;
import sun.jvm.hotspot.runtime.*;
-public class BinaryTreeDictionary extends VMObject {
+public class AFLBinaryTreeDictionary extends VMObject {
static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
@@ -40,8 +40,8 @@ public class BinaryTreeDictionary extends VMObject {
}
private static synchronized void initialize(TypeDataBase db) {
- Type type = db.lookupType("BinaryTreeDictionary");
- totalSizeField = type.getCIntegerField("_totalSize");
+ Type type = db.lookupType("AFLBinaryTreeDictionary");
+ totalSizeField = type.getCIntegerField("_total_size");
}
// Fields
@@ -53,7 +53,7 @@ public class BinaryTreeDictionary extends VMObject {
}
// Constructor
- public BinaryTreeDictionary(Address addr) {
+ public AFLBinaryTreeDictionary(Address addr) {
super(addr);
}
}
diff --git a/agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java b/agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java
index c2e8200b6..f47f0e811 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -117,9 +117,9 @@ public class CompactibleFreeListSpace extends CompactibleSpace {
}
// large block
- BinaryTreeDictionary bfbd = (BinaryTreeDictionary) VMObjectFactory.newObject(BinaryTreeDictionary.class,
+ AFLBinaryTreeDictionary aflbd = (AFLBinaryTreeDictionary) VMObjectFactory.newObject(AFLBinaryTreeDictionary.class,
dictionaryField.getValue(addr));
- size += bfbd.size();
+ size += aflbd.size();
// linear block in TLAB
diff --git a/agent/src/share/classes/sun/jvm/hotspot/memory/FreeList.java b/agent/src/share/classes/sun/jvm/hotspot/memory/FreeList.java
index 23d7c3d34..2d0024e1d 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/memory/FreeList.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/memory/FreeList.java
@@ -1,7 +1,7 @@
/*
* @(#)FreeList.java
*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -41,7 +41,7 @@ public class FreeList extends VMObject {
}
private static synchronized void initialize(TypeDataBase db) {
- Type type = db.lookupType("FreeList");
+ Type type = db.lookupType("FreeList<FreeChunk>");
sizeField = type.getCIntegerField("_size");
countField = type.getCIntegerField("_count");
headerSize = type.getSize();
diff --git a/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java b/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java
index 59923078d..f944188f4 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java
@@ -467,7 +467,7 @@ public class ObjectHeap {
liveRegions.add(tlab.start());
liveRegions.add(tlab.start());
liveRegions.add(tlab.top());
- liveRegions.add(tlab.end());
+ liveRegions.add(tlab.hardEnd());
}
}
}
diff --git a/agent/src/share/classes/sun/jvm/hotspot/runtime/OSThread.java b/agent/src/share/classes/sun/jvm/hotspot/runtime/OSThread.java
index cdcbf1138..fb17c53d3 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/OSThread.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/OSThread.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -32,6 +32,7 @@ import sun.jvm.hotspot.types.*;
// to the sys_thread_t structure of the classic JVM implementation.
public class OSThread extends VMObject {
private static JIntField interruptedField;
+ private static JIntField threadIdField;
static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
@@ -43,6 +44,7 @@ public class OSThread extends VMObject {
private static synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("OSThread");
interruptedField = type.getJIntField("_interrupted");
+ threadIdField = type.getJIntField("_thread_id");
}
public OSThread(Address addr) {
@@ -52,4 +54,9 @@ public class OSThread extends VMObject {
public boolean interrupted() {
return ((int)interruptedField.getValue(addr)) != 0;
}
+
+ public int threadId() {
+ return (int)threadIdField.getValue(addr);
+ }
+
}
diff --git a/agent/src/share/classes/sun/jvm/hotspot/runtime/ThreadLocalAllocBuffer.java b/agent/src/share/classes/sun/jvm/hotspot/runtime/ThreadLocalAllocBuffer.java
index 381b53ded..738dc94fa 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/ThreadLocalAllocBuffer.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/ThreadLocalAllocBuffer.java
@@ -27,6 +27,7 @@ package sun.jvm.hotspot.runtime;
import java.io.*;
import java.util.*;
import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.types.*;
/** <P> ThreadLocalAllocBuffer: a descriptor for thread-local storage
@@ -62,9 +63,22 @@ public class ThreadLocalAllocBuffer extends VMObject {
super(addr);
}
- public Address start() { return startField.getValue(addr); }
- public Address end() { return endField.getValue(addr); }
- public Address top() { return topField.getValue(addr); }
+ public Address start() { return startField.getValue(addr); }
+ public Address end() { return endField.getValue(addr); }
+ public Address top() { return topField.getValue(addr); }
+ public Address hardEnd() { return end().addOffsetTo(alignmentReserve()); }
+
+ private long alignmentReserve() {
+ return Oop.alignObjectSize(endReserve());
+ }
+
+ private long endReserve() {
+ long minFillerArraySize = Array.baseOffsetInBytes(BasicType.T_INT);
+ long reserveForAllocationPrefetch = VM.getVM().getReserveForAllocationPrefetch();
+ long heapWordSize = VM.getVM().getHeapWordSize();
+
+ return Math.max(minFillerArraySize, reserveForAllocationPrefetch * heapWordSize);
+ }
/** Support for iteration over heap -- not sure how this will
interact with GC in reflective system, but necessary for the
diff --git a/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java b/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java
index 5531980b1..80464a10b 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java
@@ -114,6 +114,7 @@ public class VM {
private int invalidOSREntryBCI;
private ReversePtrs revPtrs;
private VMRegImpl vmregImpl;
+ private int reserveForAllocationPrefetch;
// System.getProperties from debuggee VM
private Properties sysProps;
@@ -293,6 +294,10 @@ public class VM {
vmRelease = CStringUtilities.getString(releaseAddr);
Address vmInternalInfoAddr = vmVersion.getAddressField("_s_internal_vm_info_string").getValue();
vmInternalInfo = CStringUtilities.getString(vmInternalInfoAddr);
+
+ CIntegerType intType = (CIntegerType) db.lookupType("int");
+ CIntegerField reserveForAllocationPrefetchField = vmVersion.getCIntegerField("_reserve_for_allocation_prefetch");
+ reserveForAllocationPrefetch = (int)reserveForAllocationPrefetchField.getCInteger(intType);
} catch (Exception exp) {
throw new RuntimeException("can't determine target's VM version : " + exp.getMessage());
}
@@ -778,6 +783,10 @@ public class VM {
return vmInternalInfo;
}
+ public int getReserveForAllocationPrefetch() {
+ return reserveForAllocationPrefetch;
+ }
+
public boolean isSharingEnabled() {
if (sharingEnabled == null) {
Flag flag = getCommandLineFlag("UseSharedSpaces");
diff --git a/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_amd64/Win32AMD64JavaThreadPDAccess.java b/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_amd64/Win32AMD64JavaThreadPDAccess.java
index e18dd4f80..86255a48f 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_amd64/Win32AMD64JavaThreadPDAccess.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_amd64/Win32AMD64JavaThreadPDAccess.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -43,7 +43,7 @@ public class Win32AMD64JavaThreadPDAccess implements JavaThreadPDAccess {
private static AddressField osThreadField;
// Field from OSThread
- private static Field osThreadThreadHandleField;
+ private static Field osThreadThreadIdField;
// This is currently unneeded but is being kept in case we change
// the currentFrameGuess algorithm
@@ -64,7 +64,7 @@ public class Win32AMD64JavaThreadPDAccess implements JavaThreadPDAccess {
osThreadField = type.getAddressField("_osthread");
type = db.lookupType("OSThread");
- osThreadThreadHandleField = type.getField("_thread_handle");
+ osThreadThreadIdField = type.getField("_thread_id");
}
public Address getLastJavaFP(Address addr) {
@@ -128,10 +128,10 @@ public class Win32AMD64JavaThreadPDAccess implements JavaThreadPDAccess {
// Fetch the OSThread (for now and for simplicity, not making a
// separate "OSThread" class in this package)
Address osThreadAddr = osThreadField.getValue(addr);
- // Get the address of the HANDLE within the OSThread
- Address threadHandleAddr =
- osThreadAddr.addOffsetTo(osThreadThreadHandleField.getOffset());
+ // Get the address of the thread_id within the OSThread
+ Address threadIdAddr =
+ osThreadAddr.addOffsetTo(osThreadThreadIdField.getOffset());
JVMDebugger debugger = VM.getVM().getDebugger();
- return debugger.getThreadForIdentifierAddress(threadHandleAddr);
+ return debugger.getThreadForIdentifierAddress(threadIdAddr);
}
}
diff --git a/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_x86/Win32X86JavaThreadPDAccess.java b/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_x86/Win32X86JavaThreadPDAccess.java
index dff6615a0..435e47623 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_x86/Win32X86JavaThreadPDAccess.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_x86/Win32X86JavaThreadPDAccess.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -42,7 +42,7 @@ public class Win32X86JavaThreadPDAccess implements JavaThreadPDAccess {
private static AddressField osThreadField;
// Field from OSThread
- private static Field osThreadThreadHandleField;
+ private static Field osThreadThreadIdField;
// This is currently unneeded but is being kept in case we change
// the currentFrameGuess algorithm
@@ -63,7 +63,7 @@ public class Win32X86JavaThreadPDAccess implements JavaThreadPDAccess {
osThreadField = type.getAddressField("_osthread");
type = db.lookupType("OSThread");
- osThreadThreadHandleField = type.getField("_thread_handle");
+ osThreadThreadIdField = type.getField("_thread_id");
}
public Address getLastJavaFP(Address addr) {
@@ -127,10 +127,10 @@ public class Win32X86JavaThreadPDAccess implements JavaThreadPDAccess {
// Fetch the OSThread (for now and for simplicity, not making a
// separate "OSThread" class in this package)
Address osThreadAddr = osThreadField.getValue(addr);
- // Get the address of the HANDLE within the OSThread
- Address threadHandleAddr =
- osThreadAddr.addOffsetTo(osThreadThreadHandleField.getOffset());
+ // Get the address of the thread_id within the OSThread
+ Address threadIdAddr =
+ osThreadAddr.addOffsetTo(osThreadThreadIdField.getOffset());
JVMDebugger debugger = VM.getVM().getDebugger();
- return debugger.getThreadForIdentifierAddress(threadHandleAddr);
+ return debugger.getThreadForIdentifierAddress(threadIdAddr);
}
}
diff --git a/make/Makefile b/make/Makefile
index fe5a6b684..a1d8cb9dd 100644
--- a/make/Makefile
+++ b/make/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 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
@@ -87,7 +87,6 @@ endif
# Typical C1/C2 targets made available with this Makefile
C1_VM_TARGETS=product1 fastdebug1 optimized1 jvmg1
C2_VM_TARGETS=product fastdebug optimized jvmg
-KERNEL_VM_TARGETS=productkernel fastdebugkernel optimizedkernel jvmgkernel
ZERO_VM_TARGETS=productzero fastdebugzero optimizedzero jvmgzero
SHARK_VM_TARGETS=productshark fastdebugshark optimizedshark jvmgshark
MINIMAL1_VM_TARGETS=productminimal1 fastdebugminimal1 jvmgminimal1
@@ -161,11 +160,6 @@ $(C2_VM_TARGETS):
$(CD) $(GAMMADIR)/make; \
$(MAKE) BUILD_FLAVOR=$@ VM_TARGET=$@ generic_build2 $(ALT_OUT)
-$(KERNEL_VM_TARGETS):
- $(CD) $(GAMMADIR)/make; \
- $(MAKE) BUILD_FLAVOR=$(@:%kernel=%) VM_TARGET=$@ \
- generic_buildkernel $(ALT_OUT)
-
$(ZERO_VM_TARGETS):
$(CD) $(GAMMADIR)/make; \
$(MAKE) BUILD_FLAVOR=$(@:%zero=%) VM_TARGET=$@ \
@@ -223,24 +217,6 @@ else
$(MAKE_ARGS) $(VM_TARGET)
endif
-generic_buildkernel:
- $(MKDIR) -p $(OUTPUTDIR)
-ifeq ($(OSNAME),windows)
- ifeq ($(ARCH_DATA_MODEL), 32)
- $(CD) $(OUTPUTDIR); \
- $(NMAKE) -f $(ABS_OS_MAKEFILE) \
- Variant=kernel \
- WorkSpace=$(ABS_GAMMADIR) \
- BootStrapDir=$(ABS_BOOTDIR) \
- BuildUser=$(USERNAME) \
- $(MAKE_ARGS) $(VM_TARGET:%kernel=%)
- else
- @$(ECHO) "No kernel ($(VM_TARGET)) for ARCH_DATA_MODEL=$(ARCH_DATA_MODEL)"
- endif
-else
- @$(ECHO) "No kernel ($(VM_TARGET)) for OS_NAME=$(OSNAME)"
-endif
-
generic_buildzero:
$(MKDIR) -p $(OUTPUTDIR)
$(CD) $(OUTPUTDIR); \
@@ -314,12 +290,10 @@ XUSAGE=$(HS_SRC_DIR)/share/vm/Xusage.txt
DOCS_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_docs
C1_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_compiler1
C2_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_compiler2
-KERNEL_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_kernel
ZERO_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_zero
SHARK_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_shark
C1_DIR=$(C1_BASE_DIR)/$(VM_SUBDIR)
C2_DIR=$(C2_BASE_DIR)/$(VM_SUBDIR)
-KERNEL_DIR=$(KERNEL_BASE_DIR)/$(VM_SUBDIR)
ZERO_DIR=$(ZERO_BASE_DIR)/$(VM_SUBDIR)
SHARK_DIR=$(SHARK_BASE_DIR)/$(VM_SUBDIR)
MINIMAL1_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_minimal1
@@ -333,10 +307,6 @@ ifeq ($(JVM_VARIANT_CLIENT), true)
MISC_DIR=$(C1_DIR)
GEN_DIR=$(C1_BASE_DIR)/generated
endif
-ifeq ($(JVM_VARIANT_KERNEL), true)
- MISC_DIR=$(C2_DIR)
- GEN_DIR=$(C2_BASE_DIR)/generated
-endif
ifeq ($(JVM_VARIANT_ZEROSHARK), true)
MISC_DIR=$(SHARK_DIR)
GEN_DIR=$(SHARK_BASE_DIR)/generated
@@ -386,16 +356,6 @@ $(EXPORT_SERVER_DIR)/%.pdb: $(C2_DIR)/%.pdb
$(install-file)
$(EXPORT_SERVER_DIR)/%.map: $(C2_DIR)/%.map
$(install-file)
-
-# Kernel files always come from kernel area
-$(EXPORT_KERNEL_DIR)/%.diz: $(KERNEL_DIR)/%.diz
- $(install-file)
-$(EXPORT_KERNEL_DIR)/%.dll: $(KERNEL_DIR)/%.dll
- $(install-file)
-$(EXPORT_KERNEL_DIR)/%.pdb: $(KERNEL_DIR)/%.pdb
- $(install-file)
-$(EXPORT_KERNEL_DIR)/%.map: $(KERNEL_DIR)/%.map
- $(install-file)
endif
# Minimal JVM files always come from minimal area
@@ -538,7 +498,7 @@ $(EXPORT_DOCS_DIR)/platform/jvmti/%: $(DOCS_DIR)/%
$(install-file)
# Xusage file
-$(EXPORT_SERVER_DIR)/Xusage.txt $(EXPORT_CLIENT_DIR)/Xusage.txt $(EXPORT_KERNEL_DIR)/Xusage.txt $(EXPORT_MINIMAL_DIR)/Xusage.txt: $(XUSAGE)
+$(EXPORT_SERVER_DIR)/Xusage.txt $(EXPORT_CLIENT_DIR)/Xusage.txt $(EXPORT_MINIMAL_DIR)/Xusage.txt: $(XUSAGE)
$(prep-target)
$(RM) $@.temp
$(SED) 's/\(separated by \)[;:]/\1$(PATH_SEP)/g' $< > $@.temp
@@ -551,7 +511,6 @@ clobber clean: clean_build clean_export clean_jdk
clean_build:
$(RM) -r $(C1_DIR)
$(RM) -r $(C2_DIR)
- $(RM) -r $(KERNEL_DIR)
$(RM) -r $(ZERO_DIR)
$(RM) -r $(SHARK_DIR)
$(RM) -r $(MINIMAL1_DIR)
@@ -586,10 +545,6 @@ test_jdk:
$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -server -Xinternalversion
$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -server -version
endif
- ifeq ($(JVM_VARIANT_KERNEL), true)
- $(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -kernel -Xinternalversion
- $(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -kernel -version
- endif
copy_product_jdk::
$(RM) -r $(JDK_IMAGE_DIR)
@@ -665,7 +620,6 @@ target_help:
@$(ECHO) "Other targets are:"
@$(ECHO) " $(C1_VM_TARGETS)"
@$(ECHO) " $(C2_VM_TARGETS)"
- @$(ECHO) " $(KERNEL_VM_TARGETS)"
@$(ECHO) " $(MINIMAL1_VM_TARGETS)"
# Variable help (only common ones used by this workspace)
@@ -761,8 +715,8 @@ endif
include $(GAMMADIR)/make/jprt.gmk
.PHONY: all world clobber clean help $(C1_VM_TARGETS) $(C2_VM_TARGETS) \
- $(KERNEL_VM_TARGETS) $(MINIMAL1_VM_TARGETS) \
- generic_build1 generic_build2 generic_buildkernel generic_buildminimal1 generic_export \
+ $(MINIMAL1_VM_TARGETS) \
+ generic_build1 generic_build2 generic_buildminimal1 generic_export \
export_product export_fastdebug export_debug export_optimized \
export_jdk_product export_jdk_fastdebug export_jdk_debug \
create_jdk copy_jdk update_jdk test_jdk \
diff --git a/make/bsd/makefiles/dtrace.make b/make/bsd/makefiles/dtrace.make
index d325f2082..1c53841b5 100644
--- a/make/bsd/makefiles/dtrace.make
+++ b/make/bsd/makefiles/dtrace.make
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 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
@@ -25,10 +25,9 @@
# Rules to build jvm_db/dtrace, used by vm.make
# We build libjvm_dtrace/libjvm_db/dtrace for COMPILER1 and COMPILER2
-# but not for CORE or KERNEL configurations.
+# but not for CORE configuration.
ifneq ("${TYPE}", "CORE")
-ifneq ("${TYPE}", "KERNEL")
ifeq ($(OS_VENDOR), Darwin)
# we build dtrace for macosx using USDT2 probes
@@ -280,13 +279,6 @@ endif # ifneq ("${dtraceFound}", "")
endif # ifeq ($(OS_VENDOR), Darwin)
-else # KERNEL build
-
-dtraceCheck:
- $(QUIETLY) echo "**NOTICE** Dtrace support disabled for KERNEL builds"
-
-endif # ifneq ("${TYPE}", "KERNEL")
-
else # CORE build
dtraceCheck:
diff --git a/make/bsd/makefiles/mapfile-vers-debug b/make/bsd/makefiles/mapfile-vers-debug
index ef827302c..24144fe9b 100644
--- a/make/bsd/makefiles/mapfile-vers-debug
+++ b/make/bsd/makefiles/mapfile-vers-debug
@@ -188,6 +188,7 @@ SUNWprivate_1.1 {
JVM_IsSilentCompiler;
JVM_IsSupportedJNIVersion;
JVM_IsThreadAlive;
+ JVM_IsVMGeneratedMethodIx;
JVM_LatestUserDefinedLoader;
JVM_Listen;
JVM_LoadClass0;
diff --git a/make/bsd/makefiles/mapfile-vers-product b/make/bsd/makefiles/mapfile-vers-product
index 0d2b04ca7..c165c16e2 100644
--- a/make/bsd/makefiles/mapfile-vers-product
+++ b/make/bsd/makefiles/mapfile-vers-product
@@ -188,6 +188,7 @@ SUNWprivate_1.1 {
JVM_IsSilentCompiler;
JVM_IsSupportedJNIVersion;
JVM_IsThreadAlive;
+ JVM_IsVMGeneratedMethodIx;
JVM_LatestUserDefinedLoader;
JVM_Listen;
JVM_LoadClass0;
diff --git a/make/bsd/makefiles/minimal1.make b/make/bsd/makefiles/minimal1.make
index 9494f78bc..abfbc4c94 100644
--- a/make/bsd/makefiles/minimal1.make
+++ b/make/bsd/makefiles/minimal1.make
@@ -30,7 +30,7 @@ INCLUDE_VM_STRUCTS ?= false
INCLUDE_JNI_CHECK ?= false
INCLUDE_SERVICES ?= false
INCLUDE_MANAGEMENT ?= false
-INCLUDE_ALTERNATE_GCS ?= false
+INCLUDE_ALL_GCS ?= false
INCLUDE_NMT ?= false
INCLUDE_CDS ?= false
diff --git a/make/excludeSrc.make b/make/excludeSrc.make
index 721aea5c7..589c262ca 100644
--- a/make/excludeSrc.make
+++ b/make/excludeSrc.make
@@ -72,12 +72,10 @@ ifeq ($(INCLUDE_CDS), false)
Src_Files_EXCLUDE += metaspaceShared.cpp
endif
-ifeq ($(INCLUDE_ALTERNATE_GCS), false)
- CXXFLAGS += -DINCLUDE_ALTERNATE_GCS=0
- CFLAGS += -DINCLUDE_ALTERNATE_GCS=0
+ifeq ($(INCLUDE_ALL_GCS), false)
+ CXXFLAGS += -DINCLUDE_ALL_GCS=0
+ CFLAGS += -DINCLUDE_ALL_GCS=0
- CXXFLAGS += -DSERIALGC
- CFLAGS += -DSERIALGC
Src_Files_EXCLUDE += \
cmsAdaptiveSizePolicy.cpp cmsCollectorPolicy.cpp \
cmsGCAdaptivePolicyCounters.cpp cmsLockVerifier.cpp cmsPermGen.cpp compactibleFreeListSpace.cpp \
diff --git a/make/hotspot_version b/make/hotspot_version
index c47d3d182..6f09485a3 100644
--- a/make/hotspot_version
+++ b/make/hotspot_version
@@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013
HS_MAJOR_VER=25
HS_MINOR_VER=0
-HS_BUILD_NUMBER=17
+HS_BUILD_NUMBER=18
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
diff --git a/make/linux/makefiles/mapfile-vers-debug b/make/linux/makefiles/mapfile-vers-debug
index ae4e2f9bc..27238f572 100644
--- a/make/linux/makefiles/mapfile-vers-debug
+++ b/make/linux/makefiles/mapfile-vers-debug
@@ -184,6 +184,7 @@ SUNWprivate_1.1 {
JVM_IsSilentCompiler;
JVM_IsSupportedJNIVersion;
JVM_IsThreadAlive;
+ JVM_IsVMGeneratedMethodIx;
JVM_LatestUserDefinedLoader;
JVM_Listen;
JVM_LoadClass0;
diff --git a/make/linux/makefiles/mapfile-vers-product b/make/linux/makefiles/mapfile-vers-product
index 9a3028d2a..04531fa15 100644
--- a/make/linux/makefiles/mapfile-vers-product
+++ b/make/linux/makefiles/mapfile-vers-product
@@ -184,6 +184,7 @@ SUNWprivate_1.1 {
JVM_IsSilentCompiler;
JVM_IsSupportedJNIVersion;
JVM_IsThreadAlive;
+ JVM_IsVMGeneratedMethodIx;
JVM_LatestUserDefinedLoader;
JVM_Listen;
JVM_LoadClass0;
diff --git a/make/linux/makefiles/minimal1.make b/make/linux/makefiles/minimal1.make
index 9494f78bc..abfbc4c94 100644
--- a/make/linux/makefiles/minimal1.make
+++ b/make/linux/makefiles/minimal1.make
@@ -30,7 +30,7 @@ INCLUDE_VM_STRUCTS ?= false
INCLUDE_JNI_CHECK ?= false
INCLUDE_SERVICES ?= false
INCLUDE_MANAGEMENT ?= false
-INCLUDE_ALTERNATE_GCS ?= false
+INCLUDE_ALL_GCS ?= false
INCLUDE_NMT ?= false
INCLUDE_CDS ?= false
diff --git a/make/solaris/Makefile b/make/solaris/Makefile
index 4a47cb937..83e4df665 100644
--- a/make/solaris/Makefile
+++ b/make/solaris/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1998, 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
@@ -157,13 +157,11 @@ SUBDIRS_C1 = $(addprefix $(OSNAME)_$(BUILDARCH)_compiler1/,$(TARGETS))
SUBDIRS_C2 = $(addprefix $(OSNAME)_$(BUILDARCH)_compiler2/,$(TARGETS))
SUBDIRS_TIERED = $(addprefix $(OSNAME)_$(BUILDARCH)_tiered/,$(TARGETS))
SUBDIRS_CORE = $(addprefix $(OSNAME)_$(BUILDARCH)_core/,$(TARGETS))
-SUBDIRS_KERNEL = $(addprefix $(OSNAME)_$(BUILDARCH)_kernel/,$(TARGETS))
TARGETS_C2 = $(TARGETS)
TARGETS_C1 = $(addsuffix 1,$(TARGETS))
TARGETS_TIERED = $(addsuffix tiered,$(TARGETS))
TARGETS_CORE = $(addsuffix core,$(TARGETS))
-TARGETS_KERNEL = $(addsuffix kernel,$(TARGETS))
BUILDTREE_MAKE = $(GAMMADIR)/make/$(OSNAME)/makefiles/buildtree.make
BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OSNAME) ARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH)
@@ -229,10 +227,6 @@ $(SUBDIRS_CORE): $(BUILDTREE_MAKE)
$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
$(BUILDTREE) VARIANT=core
-$(SUBDIRS_KERNEL): $(BUILDTREE_MAKE)
- $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
- $(BUILDTREE) VARIANT=kernel
-
# Define INSTALL=y at command line to automatically copy JVM into JAVA_HOME
$(TARGETS_C2): $(SUBDIRS_C2)
@@ -271,20 +265,10 @@ ifdef INSTALL
cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && $(MAKE) $(MFLAGS) install
endif
-$(TARGETS_KERNEL): $(SUBDIRS_KERNEL)
- cd $(OSNAME)_$(BUILDARCH)_kernel/$(patsubst %kernel,%,$@) && $(MAKE) $(MFLAGS)
-ifeq ($(TEST_IN_BUILD),true)
- cd $(OSNAME)_$(BUILDARCH)_kernel/$(patsubst %kernel,%,$@) && ./test_gamma
-endif
-ifdef INSTALL
- cd $(OSNAME)_$(BUILDARCH)_kernel/$(patsubst %kernel,%,$@) && $(MAKE) $(MFLAGS) install
-endif
-
# Just build the tree, and nothing else:
tree: $(SUBDIRS_C2)
tree1: $(SUBDIRS_C1)
treecore: $(SUBDIRS_CORE)
-treekernel: $(SUBDIRS_KERNEL)
# Doc target. This is the same for all build options.
# Hence create a docs directory beside ...$(ARCH)_[...]
@@ -304,10 +288,10 @@ core: jvmgcore productcore
clean_docs:
rm -rf $(SUBDIR_DOCS)
-clean_compiler1 clean_compiler2 clean_core clean_kernel:
+clean_compiler1 clean_compiler2 clean_core:
rm -rf $(OSNAME)_$(BUILDARCH)_$(subst clean_,,$@)
-clean: clean_compiler2 clean_compiler1 clean_core clean_docs clean_kernel
+clean: clean_compiler2 clean_compiler1 clean_core clean_docs
include $(GAMMADIR)/make/cscope.make
diff --git a/make/solaris/makefiles/dtrace.make b/make/solaris/makefiles/dtrace.make
index 111acdb0d..b57365b93 100644
--- a/make/solaris/makefiles/dtrace.make
+++ b/make/solaris/makefiles/dtrace.make
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 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
@@ -25,10 +25,9 @@
# Rules to build jvm_db/dtrace, used by vm.make
# We build libjvm_dtrace/libjvm_db/dtrace for COMPILER1 and COMPILER2
-# but not for CORE or KERNEL configurations.
+# but not for CORE configuration.
ifneq ("${TYPE}", "CORE")
-ifneq ("${TYPE}", "KERNEL")
ifdef USE_GCC
@@ -362,13 +361,6 @@ endif # ifneq ("${dtraceFound}", "")
endif # ifdef USE_GCC
-else # KERNEL build
-
-dtraceCheck:
- $(QUIETLY) echo "**NOTICE** Dtrace support disabled for KERNEL builds"
-
-endif # ifneq ("${TYPE}", "KERNEL")
-
else # CORE build
dtraceCheck:
diff --git a/make/solaris/makefiles/kernel.make b/make/solaris/makefiles/kernel.make
deleted file mode 100644
index 40728e669..000000000
--- a/make/solaris/makefiles/kernel.make
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# Copyright (c) 2007, 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.
-#
-#
-#
-# Sets make macros for making kernel version of VM.
-# This target on solaris is just tempoarily for debugging the kernel build.
-
-TYPE=KERNEL
-
-VM_SUBDIR = client
-
-CFLAGS += -DKERNEL
diff --git a/make/solaris/makefiles/mapfile-vers b/make/solaris/makefiles/mapfile-vers
index bf2125306..d58807b04 100644
--- a/make/solaris/makefiles/mapfile-vers
+++ b/make/solaris/makefiles/mapfile-vers
@@ -184,6 +184,7 @@ SUNWprivate_1.1 {
JVM_IsSilentCompiler;
JVM_IsSupportedJNIVersion;
JVM_IsThreadAlive;
+ JVM_IsVMGeneratedMethodIx;
JVM_LatestUserDefinedLoader;
JVM_Listen;
JVM_LoadClass0;
diff --git a/make/windows/build.bat b/make/windows/build.bat
index e4eab3abf..5df20dd4f 100644
--- a/make/windows/build.bat
+++ b/make/windows/build.bat
@@ -1,6 +1,6 @@
@echo off
REM
-REM Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+REM Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
REM
REM This code is free software; you can redistribute it and/or modify it
@@ -67,7 +67,6 @@ goto usage
:test1
if "%2" == "core" goto test2
-if "%2" == "kernel" goto test2
if "%2" == "compiler1" goto test2
if "%2" == "compiler2" goto test2
if "%2" == "tiered" goto test2
@@ -109,7 +108,7 @@ echo Usage: build flavor version workspace bootstrap_dir [build_id] [windbg_home
echo.
echo where:
echo flavor is "product", "debug" or "fastdebug",
-echo version is "core", "kernel", "compiler1", "compiler2", or "tiered",
+echo version is "core", "compiler1", "compiler2", or "tiered",
echo workspace is source directory without trailing slash,
echo bootstrap_dir is a full path to a JDK in which bin/java
echo and bin/javac are present and working, and build_id is an
diff --git a/make/windows/create_obj_files.sh b/make/windows/create_obj_files.sh
index 78fabc06d..14a7087f2 100644
--- a/make/windows/create_obj_files.sh
+++ b/make/windows/create_obj_files.sh
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 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
@@ -107,7 +107,6 @@ COMPILER2_PATHS="${COMPILER2_PATHS} ${GENERATED}/adfiles"
# Include dirs per type.
case "${TYPE}" in
"core") Src_Dirs="${CORE_PATHS}" ;;
- "kernel") Src_Dirs="${BASE_PATHS} ${COMPILER1_PATHS}" ;;
"compiler1") Src_Dirs="${CORE_PATHS} ${COMPILER1_PATHS}" ;;
"compiler2") Src_Dirs="${CORE_PATHS} ${COMPILER2_PATHS}" ;;
"tiered") Src_Dirs="${CORE_PATHS} ${COMPILER1_PATHS} ${COMPILER2_PATHS}" ;;
@@ -120,16 +119,12 @@ COMPILER1_SPECIFIC_FILES="c1_*"
SHARK_SPECIFIC_FILES="shark"
ZERO_SPECIFIC_FILES="zero"
-# These files need to be excluded when building the kernel target.
-KERNEL_EXCLUDED_FILES="attachListener.cpp attachListener_windows.cpp metaspaceShared_${Platform_arch_model}.cpp forte.cpp fprofiler.cpp heapDumper.cpp heapInspection.cpp jniCheck.cpp jvmtiCodeBlobEvents.cpp jvmtiExtensions.cpp jvmtiImpl.cpp jvmtiRawMonitor.cpp jvmtiTagMap.cpp jvmtiTrace.cpp vmStructs.cpp g1MemoryPool.cpp psMemoryPool.cpp gcAdaptivePolicyCounters.cpp concurrentGCThread.cpp metaspaceShared.cpp mutableNUMASpace.cpp allocationStats.cpp gSpaceCounters.cpp immutableSpace.cpp mutableSpace.cpp spaceCounters.cpp yieldingWorkgroup.cpp"
-
# Always exclude these.
Src_Files_EXCLUDE="jsig.c jvmtiEnvRecommended.cpp jvmtiEnvStub.cpp"
# Exclude per type.
case "${TYPE}" in
"core") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER1_SPECIFIC_FILES} ${COMPILER2_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES} ciTypeFlow.cpp" ;;
- "kernel") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER2_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES} ${KERNEL_EXCLUDED_FILES} ciTypeFlow.cpp" ;;
"compiler1") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER2_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES} ciTypeFlow.cpp" ;;
"compiler2") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER1_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES}" ;;
"tiered") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES}" ;;
diff --git a/make/windows/makefiles/defs.make b/make/windows/makefiles/defs.make
index e637c0033..5d58e699b 100644
--- a/make/windows/makefiles/defs.make
+++ b/make/windows/makefiles/defs.make
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 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
@@ -157,7 +157,7 @@ endif
MAKE_ARGS += RM="$(RM)"
MAKE_ARGS += ZIPEXE=$(ZIPEXE)
-# On 32 bit windows we build server, client and kernel, on 64 bit just server.
+# On 32 bit windows we build server and client, on 64 bit just server.
ifeq ($(JVM_VARIANTS),)
ifeq ($(ARCH_DATA_MODEL), 32)
JVM_VARIANTS:=client,server
@@ -250,7 +250,6 @@ endif
EXPORT_SERVER_DIR = $(EXPORT_JRE_BIN_DIR)/server
EXPORT_CLIENT_DIR = $(EXPORT_JRE_BIN_DIR)/client
-EXPORT_KERNEL_DIR = $(EXPORT_JRE_BIN_DIR)/kernel
ifeq ($(JVM_VARIANT_SERVER),true)
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
@@ -277,18 +276,6 @@ ifeq ($(JVM_VARIANT_CLIENT),true)
endif
endif
endif
-ifeq ($(JVM_VARIANT_KERNEL),true)
- EXPORT_LIST += $(EXPORT_KERNEL_DIR)/Xusage.txt
- EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.$(LIBRARY_SUFFIX)
- ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
- ifeq ($(ZIP_DEBUGINFO_FILES),1)
- EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.diz
- else
- EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.pdb
- EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.map
- endif
- endif
-endif
EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/wb.jar
diff --git a/make/windows/makefiles/projectcreator.make b/make/windows/makefiles/projectcreator.make
index 5d71de661..68d098d0d 100644
--- a/make/windows/makefiles/projectcreator.make
+++ b/make/windows/makefiles/projectcreator.make
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 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
@@ -167,63 +167,6 @@ $(ProjectCreatorIDEOptionsIgnoreCompiler1:TARGET=core) \
$(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=core)
##################################################
-# JKERNEL specific options
-##################################################
-ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \
- -define_kernel KERNEL \
-$(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=kernel) \
- -ignorePath_kernel src/share/vm/gc_implementation/parallelScavenge \
- -ignorePath_kernel src/share/vm/gc_implementation/parNew \
- -ignorePath_kernel src/share/vm/gc_implementation/concurrentMarkSweep \
- -ignorePath_kernel src/share/vm/gc_implementation/g1 \
- -ignoreFile_kernel attachListener.cpp \
- -ignoreFile_kernel attachListener_windows.cpp \
- -ignoreFile_kernel dump.cpp \
- -ignoreFile_kernel dump_$(Platform_arch_model).cpp \
- -ignoreFile_kernel forte.cpp \
- -ignoreFile_kernel fprofiler.cpp \
- -ignoreFile_kernel heapDumper.cpp \
- -ignoreFile_kernel heapInspection.cpp \
- -ignoreFile_kernel jniCheck.cpp \
- -ignoreFile_kernel jvmtiCodeBlobEvents.cpp \
- -ignoreFile_kernel jvmtiExtensions.cpp \
- -ignoreFile_kernel jvmtiImpl.cpp \
- -ignoreFile_kernel jvmtiRawMonitor.cpp \
- -ignoreFile_kernel jvmtiTagMap.cpp \
- -ignoreFile_kernel jvmtiTrace.cpp \
- -ignoreFile_kernel jvmtiTrace.hpp \
- -ignoreFile_kernel restore.cpp \
- -ignoreFile_kernel serialize.cpp \
- -ignoreFile_kernel vmStructs.cpp \
- -ignoreFile_kernel g1MemoryPool.cpp \
- -ignoreFile_kernel g1MemoryPool.hpp \
- -ignoreFile_kernel psMemoryPool.cpp \
- -ignoreFile_kernel psMemoryPool.hpp \
- -ignoreFile_kernel gcAdaptivePolicyCounters.cpp \
- -ignoreFile_kernel concurrentGCThread.cpp \
- -ignoreFile_kernel mutableNUMASpace.cpp \
- -ignoreFile_kernel ciTypeFlow.cpp \
- -ignoreFile_kernel ciTypeFlow.hpp \
- -ignoreFile_kernel oop.pcgc.inline.hpp \
- -ignoreFile_kernel oop.psgc.inline.hpp \
- -ignoreFile_kernel allocationStats.cpp \
- -ignoreFile_kernel allocationStats.hpp \
- -ignoreFile_kernel concurrentGCThread.hpp \
- -ignoreFile_kernel gSpaceCounters.cpp \
- -ignoreFile_kernel gSpaceCounters.hpp \
- -ignoreFile_kernel gcAdaptivePolicyCounters.hpp \
- -ignoreFile_kernel immutableSpace.cpp \
- -ignoreFile_kernel mutableNUMASpace.hpp \
- -ignoreFile_kernel mutableSpace.cpp \
- -ignoreFile_kernel spaceCounters.cpp \
- -ignoreFile_kernel spaceCounters.hpp \
- -ignoreFile_kernel yieldingWorkgroup.cpp \
- -ignoreFile_kernel yieldingWorkgroup.hpp \
- -ignorePath_kernel vmStructs_ \
- -ignoreFile_kernel $(Platform_arch_model).ad \
- -additionalFile_kernel gcTaskManager.hpp
-
-##################################################
# Client(C1) compiler specific options
##################################################
ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \
diff --git a/make/windows/makefiles/vm.make b/make/windows/makefiles/vm.make
index b1e71de0e..2e501a7b9 100644
--- a/make/windows/makefiles/vm.make
+++ b/make/windows/makefiles/vm.make
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -44,10 +44,6 @@ CXX_FLAGS=$(CXX_FLAGS) /D "ASSERT"
# No need to define anything, CORE is defined as !COMPILER1 && !COMPILER2
!endif
-!if "$(Variant)" == "kernel"
-CXX_FLAGS=$(CXX_FLAGS) /D "KERNEL"
-!endif
-
!if "$(Variant)" == "compiler1"
CXX_FLAGS=$(CXX_FLAGS) /D "COMPILER1"
!endif
diff --git a/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp b/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp
index fa5ce4fa6..6d936b376 100644
--- a/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp
+++ b/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp
@@ -30,10 +30,11 @@
#include "c1/c1_Runtime1.hpp"
#include "nativeInst_sparc.hpp"
#include "runtime/sharedRuntime.hpp"
+#include "utilities/macros.hpp"
#include "vmreg_sparc.inline.hpp"
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
#define __ ce->masm()->
@@ -420,7 +421,7 @@ void ArrayCopyStub::emit_code(LIR_Assembler* ce) {
///////////////////////////////////////////////////////////////////////////////////
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
void G1PreBarrierStub::emit_code(LIR_Assembler* ce) {
// At this point we know that marking is in progress.
@@ -483,7 +484,7 @@ void G1PostBarrierStub::emit_code(LIR_Assembler* ce) {
__ delayed()->nop();
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
///////////////////////////////////////////////////////////////////////////////////
#undef __
diff --git a/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp b/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp
index 017baa61d..b8c838b16 100644
--- a/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp
+++ b/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp
@@ -35,6 +35,7 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/signature.hpp"
#include "runtime/vframeArray.hpp"
+#include "utilities/macros.hpp"
#include "vmreg_sparc.inline.hpp"
// Implementation of StubAssembler
@@ -822,7 +823,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
}
break;
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
case g1_pre_barrier_slow_id:
{ // G4: previous value of memory
BarrierSet* bs = Universe::heap()->barrier_set();
@@ -984,7 +985,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
__ delayed()->restore();
}
break;
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
default:
{ __ set_info("unimplemented entry", dont_gc_arguments);
diff --git a/src/cpu/sparc/vm/c2_globals_sparc.hpp b/src/cpu/sparc/vm/c2_globals_sparc.hpp
index 0dcdea056..c642e915f 100644
--- a/src/cpu/sparc/vm/c2_globals_sparc.hpp
+++ b/src/cpu/sparc/vm/c2_globals_sparc.hpp
@@ -42,7 +42,7 @@ define_pd_global(bool, ProfileInterpreter, false);
#else
define_pd_global(bool, ProfileInterpreter, true);
#endif // CC_INTERP
-define_pd_global(bool, TieredCompilation, trueInTiered);
+define_pd_global(bool, TieredCompilation, false);
define_pd_global(intx, CompileThreshold, 10000);
define_pd_global(intx, BackEdgeThreshold, 140000);
diff --git a/src/cpu/sparc/vm/cppInterpreter_sparc.cpp b/src/cpu/sparc/vm/cppInterpreter_sparc.cpp
index 6066c2019..4918746db 100644
--- a/src/cpu/sparc/vm/cppInterpreter_sparc.cpp
+++ b/src/cpu/sparc/vm/cppInterpreter_sparc.cpp
@@ -45,6 +45,7 @@
#include "runtime/timer.hpp"
#include "runtime/vframeArray.hpp"
#include "utilities/debug.hpp"
+#include "utilities/macros.hpp"
#ifdef SHARK
#include "shark/shark_globals.hpp"
#endif
@@ -551,7 +552,7 @@ address InterpreterGenerator::generate_accessor_entry(void) {
}
address InterpreterGenerator::generate_Reference_get_entry(void) {
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
if (UseG1GC) {
// We need to generate have a routine that generates code to:
// * load the value in the referent field
@@ -563,7 +564,7 @@ address InterpreterGenerator::generate_Reference_get_entry(void) {
// field as live.
Unimplemented();
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
// If G1 is not enabled then attempt to go through the accessor entry point
// Reference.get is an accessor
diff --git a/src/cpu/sparc/vm/macroAssembler_sparc.cpp b/src/cpu/sparc/vm/macroAssembler_sparc.cpp
index 3690a9272..251e42cd6 100644
--- a/src/cpu/sparc/vm/macroAssembler_sparc.cpp
+++ b/src/cpu/sparc/vm/macroAssembler_sparc.cpp
@@ -36,11 +36,12 @@
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
#include "gc_implementation/g1/heapRegion.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
#ifdef PRODUCT
#define BLOCK_COMMENT(str) /* nothing */
@@ -3867,7 +3868,7 @@ void MacroAssembler::bang_stack_size(Register Rsize, Register Rtsp,
}
///////////////////////////////////////////////////////////////////////////////////
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
static address satb_log_enqueue_with_frame = NULL;
static u_char* satb_log_enqueue_with_frame_end = NULL;
@@ -4231,7 +4232,7 @@ void MacroAssembler::g1_write_barrier_post(Register store_addr, Register new_val
bind(filtered);
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
///////////////////////////////////////////////////////////////////////////////////
void MacroAssembler::card_write_barrier_post(Register store_addr, Register new_val, Register tmp) {
diff --git a/src/cpu/sparc/vm/macroAssembler_sparc.hpp b/src/cpu/sparc/vm/macroAssembler_sparc.hpp
index dffef7e79..26605cbfa 100644
--- a/src/cpu/sparc/vm/macroAssembler_sparc.hpp
+++ b/src/cpu/sparc/vm/macroAssembler_sparc.hpp
@@ -26,6 +26,7 @@
#define CPU_SPARC_VM_MACROASSEMBLER_SPARC_HPP
#include "asm/assembler.hpp"
+#include "utilities/macros.hpp"
// <sys/trap.h> promises that the system will not use traps 16-31
#define ST_RESERVED_FOR_USER_0 0x10
@@ -1181,13 +1182,13 @@ public:
void card_write_barrier_post(Register store_addr, Register new_val, Register tmp);
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// General G1 pre-barrier generator.
void g1_write_barrier_pre(Register obj, Register index, int offset, Register pre_val, Register tmp, bool preserve_o_regs);
// General G1 post-barrier generator
void g1_write_barrier_post(Register store_addr, Register new_val, Register tmp);
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
// pushes double TOS element of FPU stack on CPU stack; pops from FPU stack
void push_fTOS();
diff --git a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
index ed46aa9cd..b5cfa00f9 100644
--- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
+++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
@@ -44,6 +44,7 @@
#include "runtime/timer.hpp"
#include "runtime/vframeArray.hpp"
#include "utilities/debug.hpp"
+#include "utilities/macros.hpp"
#ifndef CC_INTERP
#ifndef FAST_DISPATCH
@@ -734,7 +735,7 @@ address InterpreterGenerator::generate_accessor_entry(void) {
// Method entry for java.lang.ref.Reference.get.
address InterpreterGenerator::generate_Reference_get_entry(void) {
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// Code: _aload_0, _getfield, _areturn
// parameter size = 1
//
@@ -805,7 +806,7 @@ address InterpreterGenerator::generate_Reference_get_entry(void) {
(void) generate_normal_entry(false);
return entry;
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
// If G1 is not enabled then attempt to go through the accessor entry point
// Reference.get is an accessor
diff --git a/src/cpu/sparc/vm/templateTable_sparc.cpp b/src/cpu/sparc/vm/templateTable_sparc.cpp
index 931342ded..d32a2493c 100644
--- a/src/cpu/sparc/vm/templateTable_sparc.cpp
+++ b/src/cpu/sparc/vm/templateTable_sparc.cpp
@@ -34,6 +34,7 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/synchronizer.hpp"
+#include "utilities/macros.hpp"
#ifndef CC_INTERP
#define __ _masm->
@@ -53,7 +54,7 @@ static void do_oop_store(InterpreterMacroAssembler* _masm,
assert(tmp != val && tmp != base && tmp != index, "register collision");
assert(index == noreg || offset == 0, "only one offset");
switch (barrier) {
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
case BarrierSet::G1SATBCT:
case BarrierSet::G1SATBCTLogging:
{
@@ -82,7 +83,7 @@ static void do_oop_store(InterpreterMacroAssembler* _masm,
}
}
break;
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
case BarrierSet::CardTableModRef:
case BarrierSet::CardTableExtension:
{
diff --git a/src/cpu/x86/vm/assembler_x86.cpp b/src/cpu/x86/vm/assembler_x86.cpp
index 795461d6a..b94aaa936 100644
--- a/src/cpu/x86/vm/assembler_x86.cpp
+++ b/src/cpu/x86/vm/assembler_x86.cpp
@@ -36,11 +36,12 @@
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
#include "gc_implementation/g1/heapRegion.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
#ifdef PRODUCT
#define BLOCK_COMMENT(str) /* nothing */
diff --git a/src/cpu/x86/vm/assembler_x86.hpp b/src/cpu/x86/vm/assembler_x86.hpp
index 8dad416b0..97a5bfc03 100644
--- a/src/cpu/x86/vm/assembler_x86.hpp
+++ b/src/cpu/x86/vm/assembler_x86.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -543,7 +543,7 @@ class Assembler : public AbstractAssembler {
// of instructions are freely declared without the need for wrapping them an ifdef.
// (Some dangerous instructions are ifdef's out of inappropriate jvm's.)
// In the .cpp file the implementations are wrapped so that they are dropped out
- // of the resulting jvm. This is done mostly to keep the footprint of KERNEL
+ // of the resulting jvm. This is done mostly to keep the footprint of MINIMAL
// to the size it was prior to merging up the 32bit and 64bit assemblers.
//
// This does mean you'll get a linker/runtime error if you use a 64bit only instruction
diff --git a/src/cpu/x86/vm/c1_CodeStubs_x86.cpp b/src/cpu/x86/vm/c1_CodeStubs_x86.cpp
index 53c7cbacd..806bce01b 100644
--- a/src/cpu/x86/vm/c1_CodeStubs_x86.cpp
+++ b/src/cpu/x86/vm/c1_CodeStubs_x86.cpp
@@ -30,10 +30,11 @@
#include "c1/c1_Runtime1.hpp"
#include "nativeInst_x86.hpp"
#include "runtime/sharedRuntime.hpp"
+#include "utilities/macros.hpp"
#include "vmreg_x86.inline.hpp"
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
#define __ ce->masm()->
@@ -482,7 +483,7 @@ void ArrayCopyStub::emit_code(LIR_Assembler* ce) {
}
/////////////////////////////////////////////////////////////////////////////
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
void G1PreBarrierStub::emit_code(LIR_Assembler* ce) {
// At this point we know that marking is in progress.
@@ -528,7 +529,7 @@ void G1PostBarrierStub::emit_code(LIR_Assembler* ce) {
__ jmp(_continuation);
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
/////////////////////////////////////////////////////////////////////////////
#undef __
diff --git a/src/cpu/x86/vm/c1_Runtime1_x86.cpp b/src/cpu/x86/vm/c1_Runtime1_x86.cpp
index e02d5f6af..d3ac75e40 100644
--- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp
+++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp
@@ -36,6 +36,7 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/signature.hpp"
#include "runtime/vframeArray.hpp"
+#include "utilities/macros.hpp"
#include "vmreg_x86.inline.hpp"
@@ -1607,7 +1608,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
}
break;
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
case g1_pre_barrier_slow_id:
{
StubFrame f(sasm, "g1_pre_barrier", dont_gc_arguments);
@@ -1804,7 +1805,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
}
break;
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
default:
{ StubFrame f(sasm, "unimplemented entry", dont_gc_arguments);
diff --git a/src/cpu/x86/vm/c2_globals_x86.hpp b/src/cpu/x86/vm/c2_globals_x86.hpp
index 5ad08b0f1..f63b8c46d 100644
--- a/src/cpu/x86/vm/c2_globals_x86.hpp
+++ b/src/cpu/x86/vm/c2_globals_x86.hpp
@@ -44,7 +44,7 @@ define_pd_global(bool, ProfileInterpreter, false);
#else
define_pd_global(bool, ProfileInterpreter, true);
#endif // CC_INTERP
-define_pd_global(bool, TieredCompilation, trueInTiered);
+define_pd_global(bool, TieredCompilation, false);
define_pd_global(intx, CompileThreshold, 10000);
define_pd_global(intx, BackEdgeThreshold, 100000);
diff --git a/src/cpu/x86/vm/cppInterpreter_x86.cpp b/src/cpu/x86/vm/cppInterpreter_x86.cpp
index 9c3a2f31a..55b29fb2f 100644
--- a/src/cpu/x86/vm/cppInterpreter_x86.cpp
+++ b/src/cpu/x86/vm/cppInterpreter_x86.cpp
@@ -45,6 +45,7 @@
#include "runtime/timer.hpp"
#include "runtime/vframeArray.hpp"
#include "utilities/debug.hpp"
+#include "utilities/macros.hpp"
#ifdef SHARK
#include "shark/shark_globals.hpp"
#endif
@@ -938,7 +939,7 @@ address InterpreterGenerator::generate_accessor_entry(void) {
}
address InterpreterGenerator::generate_Reference_get_entry(void) {
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
if (UseG1GC) {
// We need to generate have a routine that generates code to:
// * load the value in the referent field
@@ -950,7 +951,7 @@ address InterpreterGenerator::generate_Reference_get_entry(void) {
// field as live.
Unimplemented();
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
// If G1 is not enabled then attempt to go through the accessor entry point
// Reference.get is an accessor
diff --git a/src/cpu/x86/vm/macroAssembler_x86.cpp b/src/cpu/x86/vm/macroAssembler_x86.cpp
index e4b221b28..c1e4c96e6 100644
--- a/src/cpu/x86/vm/macroAssembler_x86.cpp
+++ b/src/cpu/x86/vm/macroAssembler_x86.cpp
@@ -37,11 +37,12 @@
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
#include "gc_implementation/g1/heapRegion.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
#ifdef PRODUCT
#define BLOCK_COMMENT(str) /* nothing */
@@ -3207,7 +3208,7 @@ void MacroAssembler::vxorps(XMMRegister dst, XMMRegister nds, AddressLiteral src
//////////////////////////////////////////////////////////////////////////////////
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
void MacroAssembler::g1_write_barrier_pre(Register obj,
Register pre_val,
@@ -3417,7 +3418,7 @@ void MacroAssembler::g1_write_barrier_post(Register store_addr,
bind(done);
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
//////////////////////////////////////////////////////////////////////////////////
diff --git a/src/cpu/x86/vm/macroAssembler_x86.hpp b/src/cpu/x86/vm/macroAssembler_x86.hpp
index e4b89322b..9500f3164 100644
--- a/src/cpu/x86/vm/macroAssembler_x86.hpp
+++ b/src/cpu/x86/vm/macroAssembler_x86.hpp
@@ -26,6 +26,7 @@
#define CPU_X86_VM_MACROASSEMBLER_X86_HPP
#include "asm/assembler.hpp"
+#include "utilities/macros.hpp"
// MacroAssembler extends Assembler by frequently used macros.
@@ -294,7 +295,7 @@ class MacroAssembler: public Assembler {
void store_check(Register obj); // store check for obj - register is destroyed afterwards
void store_check(Register obj, Address dst); // same as above, dst is exact store location (reg. is destroyed)
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
void g1_write_barrier_pre(Register obj,
Register pre_val,
@@ -309,7 +310,7 @@ class MacroAssembler: public Assembler {
Register tmp,
Register tmp2);
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
// split store_check(Register obj) to enhance instruction interleaving
void store_check_part_1(Register obj);
diff --git a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
index aabc3dbba..a562bee3e 100644
--- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
+++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
@@ -44,6 +44,7 @@
#include "runtime/timer.hpp"
#include "runtime/vframeArray.hpp"
#include "utilities/debug.hpp"
+#include "utilities/macros.hpp"
#define __ _masm->
@@ -761,7 +762,7 @@ address InterpreterGenerator::generate_accessor_entry(void) {
// Method entry for java.lang.ref.Reference.get.
address InterpreterGenerator::generate_Reference_get_entry(void) {
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// Code: _aload_0, _getfield, _areturn
// parameter size = 1
//
@@ -844,7 +845,7 @@ address InterpreterGenerator::generate_Reference_get_entry(void) {
return entry;
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
// If G1 is not enabled then attempt to go through the accessor entry point
// Reference.get is an accessor
diff --git a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
index 3e3cc0fc1..26eadba79 100644
--- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
+++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
@@ -44,6 +44,7 @@
#include "runtime/timer.hpp"
#include "runtime/vframeArray.hpp"
#include "utilities/debug.hpp"
+#include "utilities/macros.hpp"
#define __ _masm->
@@ -742,7 +743,7 @@ address InterpreterGenerator::generate_accessor_entry(void) {
// Method entry for java.lang.ref.Reference.get.
address InterpreterGenerator::generate_Reference_get_entry(void) {
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// Code: _aload_0, _getfield, _areturn
// parameter size = 1
//
@@ -821,7 +822,7 @@ address InterpreterGenerator::generate_Reference_get_entry(void) {
return entry;
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
// If G1 is not enabled then attempt to go through the accessor entry point
// Reference.get is an accessor
diff --git a/src/cpu/x86/vm/templateTable_x86_32.cpp b/src/cpu/x86/vm/templateTable_x86_32.cpp
index e2a20531f..371517c05 100644
--- a/src/cpu/x86/vm/templateTable_x86_32.cpp
+++ b/src/cpu/x86/vm/templateTable_x86_32.cpp
@@ -35,6 +35,7 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/synchronizer.hpp"
+#include "utilities/macros.hpp"
#ifndef CC_INTERP
#define __ _masm->
@@ -125,7 +126,7 @@ static void do_oop_store(InterpreterMacroAssembler* _masm,
bool precise) {
assert(val == noreg || val == rax, "parameter is just for looks");
switch (barrier) {
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
case BarrierSet::G1SATBCT:
case BarrierSet::G1SATBCTLogging:
{
@@ -164,7 +165,7 @@ static void do_oop_store(InterpreterMacroAssembler* _masm,
}
break;
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
case BarrierSet::CardTableModRef:
case BarrierSet::CardTableExtension:
{
diff --git a/src/cpu/x86/vm/templateTable_x86_64.cpp b/src/cpu/x86/vm/templateTable_x86_64.cpp
index eedab0b4b..d1e22d259 100644
--- a/src/cpu/x86/vm/templateTable_x86_64.cpp
+++ b/src/cpu/x86/vm/templateTable_x86_64.cpp
@@ -35,6 +35,7 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/synchronizer.hpp"
+#include "utilities/macros.hpp"
#ifndef CC_INTERP
@@ -136,7 +137,7 @@ static void do_oop_store(InterpreterMacroAssembler* _masm,
bool precise) {
assert(val == noreg || val == rax, "parameter is just for looks");
switch (barrier) {
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
case BarrierSet::G1SATBCT:
case BarrierSet::G1SATBCTLogging:
{
@@ -167,7 +168,7 @@ static void do_oop_store(InterpreterMacroAssembler* _masm,
}
break;
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
case BarrierSet::CardTableModRef:
case BarrierSet::CardTableExtension:
{
diff --git a/src/cpu/zero/vm/assembler_zero.cpp b/src/cpu/zero/vm/assembler_zero.cpp
index d70a2adc7..ad1107ed1 100644
--- a/src/cpu/zero/vm/assembler_zero.cpp
+++ b/src/cpu/zero/vm/assembler_zero.cpp
@@ -36,11 +36,12 @@
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
#include "gc_implementation/g1/heapRegion.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
int AbstractAssembler::code_fill_byte() {
return 0;
diff --git a/src/cpu/zero/vm/cppInterpreter_zero.cpp b/src/cpu/zero/vm/cppInterpreter_zero.cpp
index c6f82cd74..a199d037c 100644
--- a/src/cpu/zero/vm/cppInterpreter_zero.cpp
+++ b/src/cpu/zero/vm/cppInterpreter_zero.cpp
@@ -47,6 +47,7 @@
#include "runtime/vframeArray.hpp"
#include "stack_zero.inline.hpp"
#include "utilities/debug.hpp"
+#include "utilities/macros.hpp"
#ifdef SHARK
#include "shark/shark_globals.hpp"
#endif
@@ -791,7 +792,7 @@ address InterpreterGenerator::generate_accessor_entry() {
}
address InterpreterGenerator::generate_Reference_get_entry(void) {
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
if (UseG1GC) {
// We need to generate have a routine that generates code to:
// * load the value in the referent field
@@ -803,7 +804,7 @@ address InterpreterGenerator::generate_Reference_get_entry(void) {
// field as live.
Unimplemented();
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
// If G1 is not enabled then attempt to go through the accessor entry point
// Reference.get is an accessor
diff --git a/src/os/linux/vm/os_linux.cpp b/src/os/linux/vm/os_linux.cpp
index 8ff3c786b..537b48cdb 100644
--- a/src/os/linux/vm/os_linux.cpp
+++ b/src/os/linux/vm/os_linux.cpp
@@ -1155,13 +1155,9 @@ void os::Linux::capture_initial_stack(size_t max_size) {
// for initial thread if its stack size exceeds 6M. Cap it at 2M,
// in case other parts in glibc still assumes 2M max stack size.
// FIXME: alt signal stack is gone, maybe we can relax this constraint?
-#ifndef IA64
- if (stack_size > 2 * K * K) stack_size = 2 * K * K;
-#else
// Problem still exists RH7.2 (IA64 anyway) but 2MB is a little small
- if (stack_size > 4 * K * K) stack_size = 4 * K * K;
-#endif
-
+ if (stack_size > 2 * K * K IA64_ONLY(*2))
+ stack_size = 2 * K * K IA64_ONLY(*2);
// Try to figure out where the stack base (top) is. This is harder.
//
// When an application is started, glibc saves the initial stack pointer in
@@ -4367,16 +4363,12 @@ int os::Linux::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mute
if (is_NPTL()) {
return pthread_cond_timedwait(_cond, _mutex, _abstime);
} else {
-#ifndef IA64
// 6292965: LinuxThreads pthread_cond_timedwait() resets FPU control
// word back to default 64bit precision if condvar is signaled. Java
// wants 53bit precision. Save and restore current value.
int fpu = get_fpu_control_word();
-#endif // IA64
int status = pthread_cond_timedwait(_cond, _mutex, _abstime);
-#ifndef IA64
set_fpu_control_word(fpu);
-#endif // IA64
return status;
}
}
diff --git a/src/os/windows/vm/os_windows.cpp b/src/os/windows/vm/os_windows.cpp
index 98b3077d1..eb16478ab 100644
--- a/src/os/windows/vm/os_windows.cpp
+++ b/src/os/windows/vm/os_windows.cpp
@@ -349,6 +349,33 @@ address os::current_stack_base() {
#ifdef _M_IA64
// IA64 has memory and register stacks
+ //
+ // This is the stack layout you get on NT/IA64 if you specify 1MB stack limit
+ // at thread creation (1MB backing store growing upwards, 1MB memory stack
+ // growing downwards, 2MB summed up)
+ //
+ // ...
+ // ------- top of stack (high address) -----
+ // |
+ // | 1MB
+ // | Backing Store (Register Stack)
+ // |
+ // | / \
+ // | |
+ // | |
+ // | |
+ // ------------------------ stack base -----
+ // | 1MB
+ // | Memory Stack
+ // |
+ // | |
+ // | |
+ // | |
+ // | \ /
+ // |
+ // ----- bottom of stack (low address) -----
+ // ...
+
stack_size = stack_size / 2;
#endif
return stack_bottom + stack_size;
@@ -2005,17 +2032,34 @@ LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo, address handler
JavaThread* thread = JavaThread::current();
// Save pc in thread
#ifdef _M_IA64
- thread->set_saved_exception_pc((address)exceptionInfo->ContextRecord->StIIP);
+ // Do not blow up if no thread info available.
+ if (thread) {
+ // Saving PRECISE pc (with slot information) in thread.
+ uint64_t precise_pc = (uint64_t) exceptionInfo->ExceptionRecord->ExceptionAddress;
+ // Convert precise PC into "Unix" format
+ precise_pc = (precise_pc & 0xFFFFFFFFFFFFFFF0) | ((precise_pc & 0xF) >> 2);
+ thread->set_saved_exception_pc((address)precise_pc);
+ }
// Set pc to handler
exceptionInfo->ContextRecord->StIIP = (DWORD64)handler;
+ // Clear out psr.ri (= Restart Instruction) in order to continue
+ // at the beginning of the target bundle.
+ exceptionInfo->ContextRecord->StIPSR &= 0xFFFFF9FFFFFFFFFF;
+ assert(((DWORD64)handler & 0xF) == 0, "Target address must point to the beginning of a bundle!");
#elif _M_AMD64
- thread->set_saved_exception_pc((address)exceptionInfo->ContextRecord->Rip);
+ // Do not blow up if no thread info available.
+ if (thread) {
+ thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip);
+ }
// Set pc to handler
exceptionInfo->ContextRecord->Rip = (DWORD64)handler;
#else
- thread->set_saved_exception_pc((address)exceptionInfo->ContextRecord->Eip);
+ // Do not blow up if no thread info available.
+ if (thread) {
+ thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Eip);
+ }
// Set pc to handler
- exceptionInfo->ContextRecord->Eip = (LONG)handler;
+ exceptionInfo->ContextRecord->Eip = (DWORD)(DWORD_PTR)handler;
#endif
// Continue the execution
@@ -2040,6 +2084,14 @@ extern "C" void events();
// included or copied here.
#define EXCEPTION_INFO_EXEC_VIOLATION 0x08
+// Handle NAT Bit consumption on IA64.
+#ifdef _M_IA64
+#define EXCEPTION_REG_NAT_CONSUMPTION STATUS_REG_NAT_CONSUMPTION
+#endif
+
+// Windows Vista/2008 heap corruption check
+#define EXCEPTION_HEAP_CORRUPTION 0xC0000374
+
#define def_excpt(val) #val, val
struct siglabel {
@@ -2082,6 +2134,10 @@ struct siglabel exceptlabels[] = {
def_excpt(EXCEPTION_GUARD_PAGE),
def_excpt(EXCEPTION_INVALID_HANDLE),
def_excpt(EXCEPTION_UNCAUGHT_CXX_EXCEPTION),
+ def_excpt(EXCEPTION_HEAP_CORRUPTION),
+#ifdef _M_IA64
+ def_excpt(EXCEPTION_REG_NAT_CONSUMPTION),
+#endif
NULL, 0
};
@@ -2206,7 +2262,14 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH;
DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
#ifdef _M_IA64
- address pc = (address) exceptionInfo->ContextRecord->StIIP;
+ // On Itanium, we need the "precise pc", which has the slot number coded
+ // into the least 4 bits: 0000=slot0, 0100=slot1, 1000=slot2 (Windows format).
+ address pc = (address) exceptionInfo->ExceptionRecord->ExceptionAddress;
+ // Convert the pc to "Unix format", which has the slot number coded
+ // into the least 2 bits: 0000=slot0, 0001=slot1, 0010=slot2
+ // This is needed for IA64 because "relocation" / "implicit null check" / "poll instruction"
+ // information is saved in the Unix format.
+ address pc_unix_format = (address) ((((uint64_t)pc) & 0xFFFFFFFFFFFFFFF0) | ((((uint64_t)pc) & 0xF) >> 2));
#elif _M_AMD64
address pc = (address) exceptionInfo->ContextRecord->Rip;
#else
@@ -2321,29 +2384,40 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
if (exception_code == EXCEPTION_STACK_OVERFLOW) {
if (os::uses_stack_guard_pages()) {
#ifdef _M_IA64
- //
- // If it's a legal stack address continue, Windows will map it in.
- //
+ // Use guard page for register stack.
PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
address addr = (address) exceptionRecord->ExceptionInformation[1];
- if (addr > thread->stack_yellow_zone_base() && addr < thread->stack_base() )
- return EXCEPTION_CONTINUE_EXECUTION;
+ // Check for a register stack overflow on Itanium
+ if (thread->addr_inside_register_stack_red_zone(addr)) {
+ // Fatal red zone violation happens if the Java program
+ // catches a StackOverflow error and does so much processing
+ // that it runs beyond the unprotected yellow guard zone. As
+ // a result, we are out of here.
+ fatal("ERROR: Unrecoverable stack overflow happened. JVM will exit.");
+ } else if(thread->addr_inside_register_stack(addr)) {
+ // Disable the yellow zone which sets the state that
+ // we've got a stack overflow problem.
+ if (thread->stack_yellow_zone_enabled()) {
+ thread->disable_stack_yellow_zone();
+ }
+ // Give us some room to process the exception.
+ thread->disable_register_stack_guard();
+ // Tracing with +Verbose.
+ if (Verbose) {
+ tty->print_cr("SOF Compiled Register Stack overflow at " INTPTR_FORMAT " (SIGSEGV)", pc);
+ tty->print_cr("Register Stack access at " INTPTR_FORMAT, addr);
+ tty->print_cr("Register Stack base " INTPTR_FORMAT, thread->register_stack_base());
+ tty->print_cr("Register Stack [" INTPTR_FORMAT "," INTPTR_FORMAT "]",
+ thread->register_stack_base(),
+ thread->register_stack_base() + thread->stack_size());
+ }
- // The register save area is the same size as the memory stack
- // and starts at the page just above the start of the memory stack.
- // If we get a fault in this area, we've run out of register
- // stack. If we are in java, try throwing a stack overflow exception.
- if (addr > thread->stack_base() &&
- addr <= (thread->stack_base()+thread->stack_size()) ) {
- char buf[256];
- jio_snprintf(buf, sizeof(buf),
- "Register stack overflow, addr:%p, stack_base:%p\n",
- addr, thread->stack_base() );
- tty->print_raw_cr(buf);
- // If not in java code, return and hope for the best.
- return in_java ? Handle_Exception(exceptionInfo,
- SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW))
- : EXCEPTION_CONTINUE_EXECUTION;
+ // Reguard the permanent register stack red zone just to be sure.
+ // We saw Windows silently disabling this without telling us.
+ thread->enable_register_stack_red_zone();
+
+ return Handle_Exception(exceptionInfo,
+ SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW));
}
#endif
if (thread->stack_yellow_zone_enabled()) {
@@ -2418,50 +2492,33 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
{
// Null pointer exception.
#ifdef _M_IA64
- // We catch register stack overflows in compiled code by doing
- // an explicit compare and executing a st8(G0, G0) if the
- // BSP enters into our guard area. We test for the overflow
- // condition and fall into the normal null pointer exception
- // code if BSP hasn't overflowed.
- if ( in_java ) {
- if(thread->register_stack_overflow()) {
- assert((address)exceptionInfo->ContextRecord->IntS3 ==
- thread->register_stack_limit(),
- "GR7 doesn't contain register_stack_limit");
- // Disable the yellow zone which sets the state that
- // we've got a stack overflow problem.
- if (thread->stack_yellow_zone_enabled()) {
- thread->disable_stack_yellow_zone();
+ // Process implicit null checks in compiled code. Note: Implicit null checks
+ // can happen even if "ImplicitNullChecks" is disabled, e.g. in vtable stubs.
+ if (CodeCache::contains((void*) pc_unix_format) && !MacroAssembler::needs_explicit_null_check((intptr_t) addr)) {
+ CodeBlob *cb = CodeCache::find_blob_unsafe(pc_unix_format);
+ // Handle implicit null check in UEP method entry
+ if (cb && (cb->is_frame_complete_at(pc) ||
+ (cb->is_nmethod() && ((nmethod *)cb)->inlinecache_check_contains(pc)))) {
+ if (Verbose) {
+ intptr_t *bundle_start = (intptr_t*) ((intptr_t) pc_unix_format & 0xFFFFFFFFFFFFFFF0);
+ tty->print_cr("trap: null_check at " INTPTR_FORMAT " (SIGSEGV)", pc_unix_format);
+ tty->print_cr(" to addr " INTPTR_FORMAT, addr);
+ tty->print_cr(" bundle is " INTPTR_FORMAT " (high), " INTPTR_FORMAT " (low)",
+ *(bundle_start + 1), *bundle_start);
}
- // Give us some room to process the exception
- thread->disable_register_stack_guard();
- // Update GR7 with the new limit so we can continue running
- // compiled code.
- exceptionInfo->ContextRecord->IntS3 =
- (ULONGLONG)thread->register_stack_limit();
return Handle_Exception(exceptionInfo,
- SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW));
- } else {
- //
- // Check for implicit null
- // We only expect null pointers in the stubs (vtable)
- // the rest are checked explicitly now.
- //
- if (((uintptr_t)addr) < os::vm_page_size() ) {
- // an access to the first page of VM--assume it is a null pointer
- address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
- if (stub != NULL) return Handle_Exception(exceptionInfo, stub);
- }
+ SharedRuntime::continuation_for_implicit_exception(thread, pc_unix_format, SharedRuntime::IMPLICIT_NULL));
}
- } // in_java
+ }
- // IA64 doesn't use implicit null checking yet. So we shouldn't
- // get here.
- tty->print_raw_cr("Access violation, possible null pointer exception");
+ // Implicit null checks were processed above. Hence, we should not reach
+ // here in the usual case => die!
+ if (Verbose) tty->print_raw_cr("Access violation, possible null pointer exception");
report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
exceptionInfo->ContextRecord);
return EXCEPTION_CONTINUE_SEARCH;
-#else /* !IA64 */
+
+#else // !IA64
// Windows 98 reports faulting addresses incorrectly
if (!MacroAssembler::needs_explicit_null_check((intptr_t)addr) ||
@@ -2493,7 +2550,24 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
exceptionInfo->ContextRecord);
return EXCEPTION_CONTINUE_SEARCH;
- }
+ } // /EXCEPTION_ACCESS_VIOLATION
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if defined _M_IA64
+ else if ((exception_code == EXCEPTION_ILLEGAL_INSTRUCTION ||
+ exception_code == EXCEPTION_ILLEGAL_INSTRUCTION_2)) {
+ M37 handle_wrong_method_break(0, NativeJump::HANDLE_WRONG_METHOD, PR0);
+
+ // Compiled method patched to be non entrant? Following conditions must apply:
+ // 1. must be first instruction in bundle
+ // 2. must be a break instruction with appropriate code
+ if((((uint64_t) pc & 0x0F) == 0) &&
+ (((IPF_Bundle*) pc)->get_slot0() == handle_wrong_method_break.bits())) {
+ return Handle_Exception(exceptionInfo,
+ (address)SharedRuntime::get_handle_wrong_method_stub());
+ }
+ } // /EXCEPTION_ILLEGAL_INSTRUCTION
+#endif
+
if (in_java) {
switch (exception_code) {
diff --git a/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp b/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
index fc55e4ec7..9eabc200b 100644
--- a/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
+++ b/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
@@ -372,7 +372,7 @@ frame os::current_frame() {
CAST_FROM_FN_PTR(address, os::current_frame));
if (os::is_first_C_frame(&myframe)) {
// stack is not walkable
- return frame(NULL, NULL, NULL);
+ return frame();
} else {
return os::get_sender_for_C_frame(&myframe);
}
diff --git a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
index 907395bb2..bfb0e960a 100644
--- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
+++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
@@ -189,7 +189,7 @@ frame os::current_frame() {
CAST_FROM_FN_PTR(address, os::current_frame));
if (os::is_first_C_frame(&myframe)) {
// stack is not walkable
- return frame(NULL, NULL, NULL);
+ return frame();
} else {
return os::get_sender_for_C_frame(&myframe);
}
diff --git a/src/os_cpu/windows_x86/vm/os_windows_x86.cpp b/src/os_cpu/windows_x86/vm/os_windows_x86.cpp
index e8bd38dc1..1ef29f99a 100644
--- a/src/os_cpu/windows_x86/vm/os_windows_x86.cpp
+++ b/src/os_cpu/windows_x86/vm/os_windows_x86.cpp
@@ -399,7 +399,7 @@ frame os::current_frame() {
typedef intptr_t* get_fp_func ();
get_fp_func* func = CAST_TO_FN_PTR(get_fp_func*,
StubRoutines::x86::get_previous_fp_entry());
- if (func == NULL) return frame(NULL, NULL, NULL);
+ if (func == NULL) return frame();
intptr_t* fp = (*func)();
#else
intptr_t* fp = _get_previous_fp();
@@ -410,7 +410,7 @@ frame os::current_frame() {
CAST_FROM_FN_PTR(address, os::current_frame));
if (os::is_first_C_frame(&myframe)) {
// stack is not walkable
- return frame(NULL, NULL, NULL);
+ return frame();
} else {
return os::get_sender_for_C_frame(&myframe);
}
diff --git a/src/share/tools/whitebox/sun/hotspot/WhiteBox.java b/src/share/tools/whitebox/sun/hotspot/WhiteBox.java
index 3a8592dec..ecc508589 100644
--- a/src/share/tools/whitebox/sun/hotspot/WhiteBox.java
+++ b/src/share/tools/whitebox/sun/hotspot/WhiteBox.java
@@ -76,4 +76,9 @@ public class WhiteBox {
public native long g1NumFreeRegions();
public native int g1RegionSize();
public native Object[] parseCommandLine(String commandline, DiagnosticCommand[] args);
+
+ // NMT
+ public native boolean NMTAllocTest();
+ public native boolean NMTFreeTestMemory();
+ public native boolean NMTWaitForDataMerge();
}
diff --git a/src/share/vm/adlc/adlparse.cpp b/src/share/vm/adlc/adlparse.cpp
index 6d08eab80..04fb735c3 100644
--- a/src/share/vm/adlc/adlparse.cpp
+++ b/src/share/vm/adlc/adlparse.cpp
@@ -168,7 +168,7 @@ void ADLParser::instr_parse(void) {
// Check for block delimiter
if ( (_curchar != '%')
|| ( next_char(), (_curchar != '{')) ) {
- parse_err(SYNERR, "missing '%{' in instruction definition\n");
+ parse_err(SYNERR, "missing '%%{' in instruction definition\n");
return;
}
next_char(); // Maintain the invariant
@@ -253,7 +253,7 @@ void ADLParser::instr_parse(void) {
} while(_curchar != '%');
next_char();
if (_curchar != '}') {
- parse_err(SYNERR, "missing '%}' in instruction definition\n");
+ parse_err(SYNERR, "missing '%%}' in instruction definition\n");
return;
}
// Check for "Set" form of chain rule
@@ -423,7 +423,7 @@ void ADLParser::oper_parse(void) {
skipws();
// Check for block delimiter
if ((_curchar != '%') || (*(_ptr+1) != '{')) { // If not open block
- parse_err(SYNERR, "missing '%c{' in operand definition\n","%");
+ parse_err(SYNERR, "missing '%%{' in operand definition\n");
return;
}
next_char(); next_char(); // Skip over "%{" symbol
@@ -483,7 +483,7 @@ void ADLParser::oper_parse(void) {
} while(_curchar != '%');
next_char();
if (_curchar != '}') {
- parse_err(SYNERR, "missing '%}' in operand definition\n");
+ parse_err(SYNERR, "missing '%%}' in operand definition\n");
return;
}
// Add operand to tail of operand list
@@ -1324,7 +1324,7 @@ void ADLParser::pipe_parse(void) {
// Check for block delimiter
if ( (_curchar != '%')
|| ( next_char(), (_curchar != '{')) ) {
- parse_err(SYNERR, "missing '%{' in pipeline definition\n");
+ parse_err(SYNERR, "missing '%%{' in pipeline definition\n");
return;
}
next_char(); // Maintain the invariant
@@ -1341,7 +1341,7 @@ void ADLParser::pipe_parse(void) {
skipws();
if ( (_curchar != '%')
|| ( next_char(), (_curchar != '{')) ) {
- parse_err(SYNERR, "expected '%{'\n");
+ parse_err(SYNERR, "expected '%%{'\n");
return;
}
next_char(); skipws();
@@ -1397,7 +1397,7 @@ void ADLParser::pipe_parse(void) {
skipws();
if ( (_curchar != '%')
|| ( next_char(), (_curchar != '{')) ) {
- parse_err(SYNERR, "expected '%{'\n");
+ parse_err(SYNERR, "expected '%%{'\n");
return;
}
next_char(); skipws();
@@ -1586,7 +1586,7 @@ void ADLParser::pipe_parse(void) {
if ( (_curchar != '%')
|| ( next_char(), (_curchar != '}')) ) {
- parse_err(SYNERR, "expected '%}', found \"%c\"\n", _curchar);
+ parse_err(SYNERR, "expected '%%}', found \"%c\"\n", _curchar);
}
next_char(); skipws();
@@ -1612,7 +1612,7 @@ void ADLParser::pipe_parse(void) {
next_char();
if (_curchar != '}') {
- parse_err(SYNERR, "missing \"%}\" in pipeline definition\n");
+ parse_err(SYNERR, "missing \"%%}\" in pipeline definition\n");
return;
}
@@ -1775,7 +1775,7 @@ void ADLParser::pipe_class_parse(PipelineForm &pipeline) {
// Check for block delimiter
if ( (_curchar != '%')
|| ( next_char(), (_curchar != '{')) ) {
- parse_err(SYNERR, "missing \"%{\" in pipe_class definition\n");
+ parse_err(SYNERR, "missing \"%%{\" in pipe_class definition\n");
return;
}
next_char();
@@ -2062,7 +2062,7 @@ void ADLParser::pipe_class_parse(PipelineForm &pipeline) {
next_char();
if (_curchar != '}') {
- parse_err(SYNERR, "missing \"%}\" in pipe_class definition\n");
+ parse_err(SYNERR, "missing \"%%}\" in pipe_class definition\n");
return;
}
@@ -3341,12 +3341,12 @@ Interface *ADLParser::mem_interface_parse(void) {
char *disp = NULL;
if (_curchar != '%') {
- parse_err(SYNERR, "Missing '%{' for 'interface' block.\n");
+ parse_err(SYNERR, "Missing '%%{' for 'interface' block.\n");
return NULL;
}
next_char(); // Skip '%'
if (_curchar != '{') {
- parse_err(SYNERR, "Missing '%{' for 'interface' block.\n");
+ parse_err(SYNERR, "Missing '%%{' for 'interface' block.\n");
return NULL;
}
next_char(); // Skip '{'
@@ -3354,7 +3354,7 @@ Interface *ADLParser::mem_interface_parse(void) {
do {
char *field = get_ident();
if (field == NULL) {
- parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n");
+ parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%%}' ending interface.\n");
return NULL;
}
if ( strcmp(field,"base") == 0 ) {
@@ -3370,13 +3370,13 @@ Interface *ADLParser::mem_interface_parse(void) {
disp = interface_field_parse();
}
else {
- parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n");
+ parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%%}' ending interface.\n");
return NULL;
}
} while( _curchar != '%' );
next_char(); // Skip '%'
if ( _curchar != '}' ) {
- parse_err(SYNERR, "Missing '%}' for 'interface' block.\n");
+ parse_err(SYNERR, "Missing '%%}' for 'interface' block.\n");
return NULL;
}
next_char(); // Skip '}'
@@ -3403,12 +3403,12 @@ Interface *ADLParser::cond_interface_parse(void) {
const char *greater_format = "gt";
if (_curchar != '%') {
- parse_err(SYNERR, "Missing '%{' for 'cond_interface' block.\n");
+ parse_err(SYNERR, "Missing '%%{' for 'cond_interface' block.\n");
return NULL;
}
next_char(); // Skip '%'
if (_curchar != '{') {
- parse_err(SYNERR, "Missing '%{' for 'cond_interface' block.\n");
+ parse_err(SYNERR, "Missing '%%{' for 'cond_interface' block.\n");
return NULL;
}
next_char(); // Skip '{'
@@ -3416,7 +3416,7 @@ Interface *ADLParser::cond_interface_parse(void) {
do {
char *field = get_ident();
if (field == NULL) {
- parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n");
+ parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%%}' ending interface.\n");
return NULL;
}
if ( strcmp(field,"equal") == 0 ) {
@@ -3438,13 +3438,13 @@ Interface *ADLParser::cond_interface_parse(void) {
greater = interface_field_parse(&greater_format);
}
else {
- parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n");
+ parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%%}' ending interface.\n");
return NULL;
}
} while( _curchar != '%' );
next_char(); // Skip '%'
if ( _curchar != '}' ) {
- parse_err(SYNERR, "Missing '%}' for 'interface' block.\n");
+ parse_err(SYNERR, "Missing '%%}' for 'interface' block.\n");
return NULL;
}
next_char(); // Skip '}'
@@ -3543,7 +3543,7 @@ MatchRule *ADLParser::match_parse(FormDict &operands) {
}
else if ((cnstr = find_cpp_block("match constructor")) == NULL ) {
parse_err(SYNERR, "invalid construction of match rule\n"
- "Missing ';' or invalid '%{' and '%}' constructor\n");
+ "Missing ';' or invalid '%%{' and '%%}' constructor\n");
return NULL; // No MatchRule to return
}
if (_AD._adl_debug > 1)
@@ -3646,7 +3646,7 @@ FormatRule* ADLParser::format_parse(void) {
// Check for closing '"' and '%}' in format description
skipws(); // Move to closing '%}'
if ( _curchar != '%' ) {
- parse_err(SYNERR, "non-blank characters between closing '\"' and '%' in format");
+ parse_err(SYNERR, "non-blank characters between closing '\"' and '%%' in format");
return NULL;
}
} // Done with format description inside
@@ -3654,7 +3654,7 @@ FormatRule* ADLParser::format_parse(void) {
skipws();
// Past format description, at '%'
if ( _curchar != '%' || *(_ptr+1) != '}' ) {
- parse_err(SYNERR, "missing '%}' at end of format block");
+ parse_err(SYNERR, "missing '%%}' at end of format block");
return NULL;
}
next_char(); // Move past the '%'
@@ -3785,7 +3785,7 @@ FormatRule* ADLParser::template_parse(void) {
skipws();
// Past format description, at '%'
if ( _curchar != '%' || *(_ptr+1) != '}' ) {
- parse_err(SYNERR, "missing '%}' at end of format block");
+ parse_err(SYNERR, "missing '%%}' at end of format block");
return NULL;
}
next_char(); // Move past the '%'
@@ -3834,7 +3834,7 @@ ExpandRule* ADLParser::expand_parse(InstructForm *instr) {
skipws(); // Skip leading whitespace
if ((_curchar != '%')
|| (next_char(), (_curchar != '{')) ) { // If not open block
- parse_err(SYNERR, "missing '%{' in expand definition\n");
+ parse_err(SYNERR, "missing '%%{' in expand definition\n");
return(NULL);
}
next_char(); // Maintain the invariant
@@ -3933,7 +3933,7 @@ ExpandRule* ADLParser::expand_parse(InstructForm *instr) {
} while(_curchar != '%');
next_char();
if (_curchar != '}') {
- parse_err(SYNERR, "missing '%}' in expand rule definition\n");
+ parse_err(SYNERR, "missing '%%}' in expand rule definition\n");
return(NULL);
}
next_char();
diff --git a/src/share/vm/c1/c1_CodeStubs.hpp b/src/share/vm/c1/c1_CodeStubs.hpp
index 5b46ce1b6..9fbeb29b5 100644
--- a/src/share/vm/c1/c1_CodeStubs.hpp
+++ b/src/share/vm/c1/c1_CodeStubs.hpp
@@ -31,6 +31,7 @@
#include "c1/c1_LIR.hpp"
#include "c1/c1_Runtime1.hpp"
#include "utilities/array.hpp"
+#include "utilities/macros.hpp"
class CodeEmitInfo;
class LIR_Assembler;
@@ -515,7 +516,7 @@ class ArrayCopyStub: public CodeStub {
};
//////////////////////////////////////////////////////////////////////////////////////////
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// Code stubs for Garbage-First barriers.
class G1PreBarrierStub: public CodeStub {
@@ -608,7 +609,7 @@ class G1PostBarrierStub: public CodeStub {
#endif // PRODUCT
};
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
//////////////////////////////////////////////////////////////////////////////////////////
#endif // SHARE_VM_C1_C1_CODESTUBS_HPP
diff --git a/src/share/vm/c1/c1_GraphBuilder.cpp b/src/share/vm/c1/c1_GraphBuilder.cpp
index cbaf83b8f..9491607ad 100644
--- a/src/share/vm/c1/c1_GraphBuilder.cpp
+++ b/src/share/vm/c1/c1_GraphBuilder.cpp
@@ -3667,11 +3667,12 @@ bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, Bytecode
}
// now perform tests that are based on flag settings
- if (callee->force_inline() || callee->should_inline()) {
- // ignore heuristic controls on inlining
- if (callee->force_inline())
- print_inlining(callee, "force inline by annotation");
+ if (callee->force_inline()) {
+ print_inlining(callee, "force inline by annotation");
+ } else if (callee->should_inline()) {
+ print_inlining(callee, "force inline by CompileOracle");
} else {
+ // use heuristic controls on inlining
if (inline_level() > MaxInlineLevel ) INLINE_BAILOUT("inlining too deep");
if (recursive_inline_level(callee) > MaxRecursiveInlineLevel) INLINE_BAILOUT("recursive inlining too deep");
if (callee->code_size_for_inlining() > max_inline_size() ) INLINE_BAILOUT("callee is too large");
diff --git a/src/share/vm/c1/c1_Instruction.cpp b/src/share/vm/c1/c1_Instruction.cpp
index 628091ce3..985cb098e 100644
--- a/src/share/vm/c1/c1_Instruction.cpp
+++ b/src/share/vm/c1/c1_Instruction.cpp
@@ -188,7 +188,7 @@ ciType* LoadIndexed::exact_type() const {
ciType* LoadIndexed::declared_type() const {
ciType* array_type = array()->declared_type();
- if (array_type == NULL) {
+ if (array_type == NULL || !array_type->is_loaded()) {
return NULL;
}
assert(array_type->is_array_klass(), "what else?");
diff --git a/src/share/vm/c1/c1_LIRGenerator.cpp b/src/share/vm/c1/c1_LIRGenerator.cpp
index 65bc34e3d..b46acec14 100644
--- a/src/share/vm/c1/c1_LIRGenerator.cpp
+++ b/src/share/vm/c1/c1_LIRGenerator.cpp
@@ -35,9 +35,10 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "utilities/bitMap.inline.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/heapRegion.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
#ifdef ASSERT
#define __ gen()->lir(__FILE__, __LINE__)->
@@ -1417,12 +1418,12 @@ void LIRGenerator::pre_barrier(LIR_Opr addr_opr, LIR_Opr pre_val,
bool do_load, bool patch, CodeEmitInfo* info) {
// Do the pre-write barrier, if any.
switch (_bs->kind()) {
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
case BarrierSet::G1SATBCT:
case BarrierSet::G1SATBCTLogging:
G1SATBCardTableModRef_pre_barrier(addr_opr, pre_val, do_load, patch, info);
break;
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
case BarrierSet::CardTableModRef:
case BarrierSet::CardTableExtension:
// No pre barriers
@@ -1439,12 +1440,12 @@ void LIRGenerator::pre_barrier(LIR_Opr addr_opr, LIR_Opr pre_val,
void LIRGenerator::post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) {
switch (_bs->kind()) {
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
case BarrierSet::G1SATBCT:
case BarrierSet::G1SATBCTLogging:
G1SATBCardTableModRef_post_barrier(addr, new_val);
break;
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
case BarrierSet::CardTableModRef:
case BarrierSet::CardTableExtension:
CardTableModRef_post_barrier(addr, new_val);
@@ -1459,7 +1460,7 @@ void LIRGenerator::post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) {
}
////////////////////////////////////////////////////////////////////////
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
void LIRGenerator::G1SATBCardTableModRef_pre_barrier(LIR_Opr addr_opr, LIR_Opr pre_val,
bool do_load, bool patch, CodeEmitInfo* info) {
@@ -1575,7 +1576,7 @@ void LIRGenerator::G1SATBCardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_Opr
__ branch_destination(slow->continuation());
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
////////////////////////////////////////////////////////////////////////
void LIRGenerator::CardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) {
@@ -2181,7 +2182,7 @@ void LIRGenerator::do_UnsafeGetObject(UnsafeGetObject* x) {
get_Object_unsafe(value, src.result(), off.result(), type, x->is_volatile());
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// We might be reading the value of the referent field of a
// Reference object in order to attach it back to the live
// object graph. If G1 is enabled then we need to record
@@ -2311,7 +2312,7 @@ void LIRGenerator::do_UnsafeGetObject(UnsafeGetObject* x) {
__ branch_destination(Lcont->label());
}
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
if (x->is_volatile() && os::is_MP()) __ membar_acquire();
}
diff --git a/src/share/vm/ci/ciEnv.cpp b/src/share/vm/ci/ciEnv.cpp
index bb51f88c7..bd18105d9 100644
--- a/src/share/vm/ci/ciEnv.cpp
+++ b/src/share/vm/ci/ciEnv.cpp
@@ -52,6 +52,7 @@
#include "runtime/reflection.hpp"
#include "runtime/sharedRuntime.hpp"
#include "utilities/dtrace.hpp"
+#include "utilities/macros.hpp"
#ifdef COMPILER1
#include "c1/c1_Runtime1.hpp"
#endif
@@ -1168,7 +1169,7 @@ void ciEnv::dump_replay_data() {
void ciEnv::dump_replay_data(outputStream* out) {
ASSERT_IN_VM;
-
+ ResourceMark rm;
#if INCLUDE_JVMTI
out->print_cr("JvmtiExport can_access_local_variables %d", _jvmti_can_access_local_variables);
out->print_cr("JvmtiExport can_hotswap_or_post_breakpoint %d", _jvmti_can_hotswap_or_post_breakpoint);
diff --git a/src/share/vm/ci/ciInstanceKlass.cpp b/src/share/vm/ci/ciInstanceKlass.cpp
index de5e973bf..d74e3693a 100644
--- a/src/share/vm/ci/ciInstanceKlass.cpp
+++ b/src/share/vm/ci/ciInstanceKlass.cpp
@@ -580,6 +580,7 @@ class StaticFinalFieldPrinter : public FieldClosure {
}
void do_field(fieldDescriptor* fd) {
if (fd->is_final() && !fd->has_initial_value()) {
+ ResourceMark rm;
oop mirror = fd->field_holder()->java_mirror();
_out->print("staticfield %s %s %s ", _holder, fd->name()->as_quoted_ascii(), fd->signature()->as_quoted_ascii());
switch (fd->field_type()) {
@@ -643,6 +644,8 @@ class StaticFinalFieldPrinter : public FieldClosure {
void ciInstanceKlass::dump_replay_data(outputStream* out) {
ASSERT_IN_VM;
+ ResourceMark rm;
+
InstanceKlass* ik = get_instanceKlass();
ConstantPool* cp = ik->constants();
diff --git a/src/share/vm/ci/ciMethod.cpp b/src/share/vm/ci/ciMethod.cpp
index 8ad9ecb11..0fa11470c 100644
--- a/src/share/vm/ci/ciMethod.cpp
+++ b/src/share/vm/ci/ciMethod.cpp
@@ -977,7 +977,7 @@ bool ciMethod::can_be_compiled() {
// ciMethod::set_not_compilable
//
// Tell the VM that this method cannot be compiled at all.
-void ciMethod::set_not_compilable() {
+void ciMethod::set_not_compilable(const char* reason) {
check_is_loaded();
VM_ENTRY_MARK;
ciEnv* env = CURRENT_ENV;
@@ -986,7 +986,7 @@ void ciMethod::set_not_compilable() {
} else {
_is_c2_compilable = false;
}
- get_Method()->set_not_compilable(env->comp_level());
+ get_Method()->set_not_compilable(env->comp_level(), true, reason);
}
// ------------------------------------------------------------------
@@ -1178,6 +1178,7 @@ ciMethodBlocks *ciMethod::get_method_blocks() {
void ciMethod::dump_replay_data(outputStream* st) {
ASSERT_IN_VM;
+ ResourceMark rm;
Method* method = get_Method();
Klass* holder = method->method_holder();
st->print_cr("ciMethod %s %s %s %d %d %d %d %d",
diff --git a/src/share/vm/ci/ciMethod.hpp b/src/share/vm/ci/ciMethod.hpp
index 193eb68de..c98f2c0dc 100644
--- a/src/share/vm/ci/ciMethod.hpp
+++ b/src/share/vm/ci/ciMethod.hpp
@@ -252,7 +252,7 @@ class ciMethod : public ciMetadata {
bool has_option(const char *option);
bool can_be_compiled();
bool can_be_osr_compiled(int entry_bci);
- void set_not_compilable();
+ void set_not_compilable(const char* reason = NULL);
bool has_compiled_code();
void log_nmethod_identity(xmlStream* log);
bool is_not_reached(int bci);
diff --git a/src/share/vm/ci/ciMethodData.cpp b/src/share/vm/ci/ciMethodData.cpp
index ee5490be8..c30c6c364 100644
--- a/src/share/vm/ci/ciMethodData.cpp
+++ b/src/share/vm/ci/ciMethodData.cpp
@@ -374,6 +374,7 @@ void ciMethodData::print_impl(outputStream* st) {
void ciMethodData::dump_replay_data(outputStream* out) {
ASSERT_IN_VM;
+ ResourceMark rm;
MethodData* mdo = get_MethodData();
Method* method = mdo->method();
Klass* holder = method->method_holder();
diff --git a/src/share/vm/ci/ciReplay.cpp b/src/share/vm/ci/ciReplay.cpp
index 9b532b8e2..030d93db7 100644
--- a/src/share/vm/ci/ciReplay.cpp
+++ b/src/share/vm/ci/ciReplay.cpp
@@ -30,6 +30,7 @@
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "utilities/copy.hpp"
+#include "utilities/macros.hpp"
#ifndef PRODUCT
diff --git a/src/share/vm/classfile/classFileParser.cpp b/src/share/vm/classfile/classFileParser.cpp
index 557707ba4..d46a1eab8 100644
--- a/src/share/vm/classfile/classFileParser.cpp
+++ b/src/share/vm/classfile/classFileParser.cpp
@@ -1947,6 +1947,8 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
u2** localvariable_type_table_start;
u2 method_parameters_length = 0;
u1* method_parameters_data = NULL;
+ bool method_parameters_seen = false;
+ bool method_parameters_four_byte_flags;
bool parsed_code_attribute = false;
bool parsed_checked_exceptions_attribute = false;
bool parsed_stackmap_attribute = false;
@@ -2157,22 +2159,32 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
method_attribute_length,
cp, CHECK_(nullHandle));
} else if (method_attribute_name == vmSymbols::tag_method_parameters()) {
+ // reject multiple method parameters
+ if (method_parameters_seen) {
+ classfile_parse_error("Multiple MethodParameters attributes in class file %s", CHECK_(nullHandle));
+ }
+ method_parameters_seen = true;
method_parameters_length = cfs->get_u1_fast();
// Track the actual size (note: this is written for clarity; a
// decent compiler will CSE and constant-fold this into a single
// expression)
- u2 actual_size = 1;
- method_parameters_data = cfs->get_u1_buffer();
- actual_size += 2 * method_parameters_length;
- cfs->skip_u2_fast(method_parameters_length);
- actual_size += 4 * method_parameters_length;
- cfs->skip_u4_fast(method_parameters_length);
- // Enforce attribute length
- if (method_attribute_length != actual_size) {
+ // Use the attribute length to figure out the size of flags
+ if (method_attribute_length == (method_parameters_length * 6u) + 1u) {
+ method_parameters_four_byte_flags = true;
+ } else if (method_attribute_length == (method_parameters_length * 4u) + 1u) {
+ method_parameters_four_byte_flags = false;
+ } else {
classfile_parse_error(
- "Invalid MethodParameters method attribute length %u in class file %s",
+ "Invalid MethodParameters method attribute length %u in class file",
method_attribute_length, CHECK_(nullHandle));
}
+ method_parameters_data = cfs->get_u1_buffer();
+ cfs->skip_u2_fast(method_parameters_length);
+ if (method_parameters_four_byte_flags) {
+ cfs->skip_u4_fast(method_parameters_length);
+ } else {
+ cfs->skip_u2_fast(method_parameters_length);
+ }
// ignore this attribute if it cannot be reflected
if (!SystemDictionary::Parameter_klass_loaded())
method_parameters_length = 0;
@@ -2316,15 +2328,16 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
// Copy method parameters
if (method_parameters_length > 0) {
MethodParametersElement* elem = m->constMethod()->method_parameters_start();
- for(int i = 0; i < method_parameters_length; i++) {
- elem[i].name_cp_index =
- Bytes::get_Java_u2(method_parameters_data);
+ for (int i = 0; i < method_parameters_length; i++) {
+ elem[i].name_cp_index = Bytes::get_Java_u2(method_parameters_data);
method_parameters_data += 2;
- u4 flags = Bytes::get_Java_u4(method_parameters_data);
- // This caused an alignment fault on Sparc, if flags was a u4
- elem[i].flags_lo = extract_low_short_from_int(flags);
- elem[i].flags_hi = extract_high_short_from_int(flags);
- method_parameters_data += 4;
+ if (method_parameters_four_byte_flags) {
+ elem[i].flags = Bytes::get_Java_u4(method_parameters_data);
+ method_parameters_data += 4;
+ } else {
+ elem[i].flags = Bytes::get_Java_u2(method_parameters_data);
+ method_parameters_data += 2;
+ }
}
}
diff --git a/src/share/vm/classfile/classLoaderData.cpp b/src/share/vm/classfile/classLoaderData.cpp
index 22cc8cf9b..e74a88d7d 100644
--- a/src/share/vm/classfile/classLoaderData.cpp
+++ b/src/share/vm/classfile/classLoaderData.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -50,11 +50,12 @@
#include "classfile/classLoaderData.hpp"
#include "classfile/classLoaderData.inline.hpp"
#include "classfile/javaClasses.hpp"
+#include "classfile/metadataOnStackMark.hpp"
#include "classfile/systemDictionary.hpp"
#include "code/codeCache.hpp"
#include "memory/metadataFactory.hpp"
#include "memory/metaspaceShared.hpp"
-#include "prims/jvmtiRedefineClasses.hpp"
+#include "memory/oopFactory.hpp"
#include "runtime/jniHandles.hpp"
#include "runtime/mutex.hpp"
#include "runtime/safepoint.hpp"
@@ -723,13 +724,13 @@ void ClassLoaderDataGraph::dump_on(outputStream * const out) {
}
MetaspaceAux::dump(out);
}
+#endif // PRODUCT
void ClassLoaderData::print_value_on(outputStream* out) const {
if (class_loader() == NULL) {
- out->print_cr("NULL class_loader");
+ out->print("NULL class_loader");
} else {
out->print("class loader "PTR_FORMAT, this);
class_loader()->print_value_on(out);
}
}
-#endif // PRODUCT
diff --git a/src/share/vm/classfile/classLoaderData.hpp b/src/share/vm/classfile/classLoaderData.hpp
index 9525658e6..f72645db1 100644
--- a/src/share/vm/classfile/classLoaderData.hpp
+++ b/src/share/vm/classfile/classLoaderData.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -220,7 +220,7 @@ class ClassLoaderData : public CHeapObj<mtClass> {
void set_jmethod_ids(JNIMethodBlock* new_block) { _jmethod_ids = new_block; }
void print_value() { print_value_on(tty); }
- void print_value_on(outputStream* out) const PRODUCT_RETURN;
+ void print_value_on(outputStream* out) const;
void dump(outputStream * const out) PRODUCT_RETURN;
void verify();
const char* loader_name();
diff --git a/src/share/vm/classfile/metadataOnStackMark.cpp b/src/share/vm/classfile/metadataOnStackMark.cpp
new file mode 100644
index 000000000..1f24042f5
--- /dev/null
+++ b/src/share/vm/classfile/metadataOnStackMark.cpp
@@ -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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "classfile/metadataOnStackMark.hpp"
+#include "code/codeCache.hpp"
+#include "compiler/compileBroker.hpp"
+#include "oops/metadata.hpp"
+#include "runtime/synchronizer.hpp"
+#include "runtime/thread.hpp"
+#include "utilities/growableArray.hpp"
+
+
+// Keep track of marked on-stack metadata so it can be cleared.
+GrowableArray<Metadata*>* _marked_objects = NULL;
+NOT_PRODUCT(bool MetadataOnStackMark::_is_active = false;)
+
+// Walk metadata on the stack and mark it so that redefinition doesn't delete
+// it. Class unloading also walks the previous versions and might try to
+// delete it, so this class is used by class unloading also.
+MetadataOnStackMark::MetadataOnStackMark() {
+ assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
+ NOT_PRODUCT(_is_active = true;)
+ if (_marked_objects == NULL) {
+ _marked_objects = new (ResourceObj::C_HEAP, mtClass) GrowableArray<Metadata*>(1000, true);
+ }
+ Threads::metadata_do(Metadata::mark_on_stack);
+ CodeCache::alive_nmethods_do(nmethod::mark_on_stack);
+ CompileBroker::mark_on_stack();
+}
+
+MetadataOnStackMark::~MetadataOnStackMark() {
+ assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
+ // Unmark everything that was marked. Can't do the same walk because
+ // redefine classes messes up the code cache so the set of methods
+ // might not be the same.
+ for (int i = 0; i< _marked_objects->length(); i++) {
+ _marked_objects->at(i)->set_on_stack(false);
+ }
+ _marked_objects->clear(); // reuse growable array for next time.
+ NOT_PRODUCT(_is_active = false;)
+}
+
+// Record which objects are marked so we can unmark the same objects.
+void MetadataOnStackMark::record(Metadata* m) {
+ assert(_is_active, "metadata on stack marking is active");
+ _marked_objects->push(m);
+}
diff --git a/src/share/vm/classfile/metadataOnStackMark.hpp b/src/share/vm/classfile/metadataOnStackMark.hpp
new file mode 100644
index 000000000..5a4fda2f3
--- /dev/null
+++ b/src/share/vm/classfile/metadataOnStackMark.hpp
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef SHARE_VM_CLASSFILE_METADATAONSTACKMARK_HPP
+#define SHARE_VM_CLASSFILE_METADATAONSTACKMARK_HPP
+
+#include "memory/allocation.hpp"
+
+class Metadata;
+
+// Helper class to mark and unmark metadata used on the stack as either handles
+// or executing methods, so that it can't be deleted during class redefinition
+// and class unloading.
+// This is also used for other things that can be deallocated, like class
+// metadata during parsing, relocated methods, and methods in backtraces.
+class MetadataOnStackMark : public StackObj {
+ NOT_PRODUCT(static bool _is_active;)
+ public:
+ MetadataOnStackMark();
+ ~MetadataOnStackMark();
+ static void record(Metadata* m);
+};
+
+#endif // SHARE_VM_CLASSFILE_METADATAONSTACKMARK_HPP
diff --git a/src/share/vm/classfile/stackMapFrame.hpp b/src/share/vm/classfile/stackMapFrame.hpp
index 3329f7a9e..bdeb956ba 100644
--- a/src/share/vm/classfile/stackMapFrame.hpp
+++ b/src/share/vm/classfile/stackMapFrame.hpp
@@ -178,7 +178,7 @@ class StackMapFrame : public ResourceObj {
#ifdef DEBUG
// Put bogus type to indicate it's no longer valid.
if (_stack_mark != -1) {
- for (int i = _stack_mark; i >= _stack_size; --i) {
+ for (int i = _stack_mark - 1; i >= _stack_size; --i) {
_stack[i] = VerificationType::bogus_type();
}
}
diff --git a/src/share/vm/classfile/systemDictionary.cpp b/src/share/vm/classfile/systemDictionary.cpp
index 546016250..a7370fcce 100644
--- a/src/share/vm/classfile/systemDictionary.cpp
+++ b/src/share/vm/classfile/systemDictionary.cpp
@@ -1199,66 +1199,6 @@ instanceKlassHandle SystemDictionary::load_shared_class(
return ik;
}
-#ifdef KERNEL
-// Some classes on the bootstrap class path haven't been installed on the
-// system yet. Call the DownloadManager method to make them appear in the
-// bootstrap class path and try again to load the named class.
-// Note that with delegation class loaders all classes in another loader will
-// first try to call this so it'd better be fast!!
-static instanceKlassHandle download_and_retry_class_load(
- Symbol* class_name,
- TRAPS) {
-
- Klass* dlm = SystemDictionary::DownloadManager_klass();
- instanceKlassHandle nk;
-
- // If download manager class isn't loaded just return.
- if (dlm == NULL) return nk;
-
- { HandleMark hm(THREAD);
- ResourceMark rm(THREAD);
- Handle s = java_lang_String::create_from_symbol(class_name, CHECK_(nk));
- Handle class_string = java_lang_String::externalize_classname(s, CHECK_(nk));
-
- // return value
- JavaValue result(T_OBJECT);
-
- // Call the DownloadManager. We assume that it has a lock because
- // multiple classes could be not found and downloaded at the same time.
- // class sun.misc.DownloadManager;
- // public static String getBootClassPathEntryForClass(String className);
- JavaCalls::call_static(&result,
- KlassHandle(THREAD, dlm),
- vmSymbols::getBootClassPathEntryForClass_name(),
- vmSymbols::string_string_signature(),
- class_string,
- CHECK_(nk));
-
- // Get result.string and add to bootclasspath
- assert(result.get_type() == T_OBJECT, "just checking");
- oop obj = (oop) result.get_jobject();
- if (obj == NULL) { return nk; }
-
- Handle h_obj(THREAD, obj);
- char* new_class_name = java_lang_String::as_platform_dependent_str(h_obj,
- CHECK_(nk));
-
- // lock the loader
- // we use this lock because JVMTI does.
- Handle loader_lock(THREAD, SystemDictionary::system_loader_lock());
-
- ObjectLocker ol(loader_lock, THREAD);
- // add the file to the bootclasspath
- ClassLoader::update_class_path_entry_list(new_class_name, true);
- } // end HandleMark
-
- if (TraceClassLoading) {
- ClassLoader::print_bootclasspath();
- }
- return ClassLoader::load_classfile(class_name, CHECK_(nk));
-}
-#endif // KERNEL
-
instanceKlassHandle SystemDictionary::load_instance_class(Symbol* class_name, Handle class_loader, TRAPS) {
instanceKlassHandle nh = instanceKlassHandle(); // null Handle
@@ -1278,15 +1218,6 @@ instanceKlassHandle SystemDictionary::load_instance_class(Symbol* class_name, Ha
k = ClassLoader::load_classfile(class_name, CHECK_(nh));
}
-#ifdef KERNEL
- // If the VM class loader has failed to load the class, call the
- // DownloadManager class to make it magically appear on the classpath
- // and try again. This is only configured with the Kernel VM.
- if (k.is_null()) {
- k = download_and_retry_class_load(class_name, CHECK_(nh));
- }
-#endif // KERNEL
-
// find_or_define_instance_class may return a different InstanceKlass
if (!k.is_null()) {
k = find_or_define_instance_class(class_name, class_loader, k, CHECK_(nh));
@@ -1822,13 +1753,7 @@ bool SystemDictionary::initialize_wk_klass(WKID id, int init_opt, TRAPS) {
Symbol* symbol = vmSymbols::symbol_at((vmSymbols::SID)sid);
Klass** klassp = &_well_known_klasses[id];
bool must_load = (init_opt < SystemDictionary::Opt);
- bool try_load = true;
- if (init_opt == SystemDictionary::Opt_Kernel) {
-#ifndef KERNEL
- try_load = false;
-#endif //KERNEL
- }
- if ((*klassp) == NULL && try_load) {
+ if ((*klassp) == NULL) {
if (must_load) {
(*klassp) = resolve_or_fail(symbol, true, CHECK_0); // load required class
} else {
@@ -1918,12 +1843,6 @@ void SystemDictionary::initialize_preloaded_classes(TRAPS) {
//_box_klasses[T_OBJECT] = WK_KLASS(object_klass);
//_box_klasses[T_ARRAY] = WK_KLASS(object_klass);
-#ifdef KERNEL
- if (DownloadManager_klass() == NULL) {
- warning("Cannot find sun/jkernel/DownloadManager");
- }
-#endif // KERNEL
-
{ // Compute whether we should use loadClass or loadClassInternal when loading classes.
Method* method = InstanceKlass::cast(ClassLoader_klass())->find_method(vmSymbols::loadClassInternal_name(), vmSymbols::string_class_signature());
_has_loadClassInternal = (method != NULL);
diff --git a/src/share/vm/classfile/systemDictionary.hpp b/src/share/vm/classfile/systemDictionary.hpp
index e2f660ee1..d415c9b1e 100644
--- a/src/share/vm/classfile/systemDictionary.hpp
+++ b/src/share/vm/classfile/systemDictionary.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -168,8 +168,6 @@ class SymbolPropertyTable;
/* It's okay if this turns out to be NULL in non-1.4 JDKs. */ \
do_klass(nio_Buffer_klass, java_nio_Buffer, Opt ) \
\
- do_klass(DownloadManager_klass, sun_jkernel_DownloadManager, Opt_Kernel ) \
- \
do_klass(PostVMInitHook_klass, sun_misc_PostVMInitHook, Opt ) \
\
/* Preload boxing klasses */ \
@@ -211,7 +209,6 @@ class SystemDictionary : AllStatic {
Opt, // preload tried; NULL if not present
Opt_Only_JDK14NewRef, // preload tried; use only with NewReflection
Opt_Only_JDK15, // preload tried; use only with JDK1.5+
- Opt_Kernel, // preload tried only #ifdef KERNEL
OPTION_LIMIT,
CEIL_LG_OPTION_LIMIT = 4 // OPTION_LIMIT <= (1<<CEIL_LG_OPTION_LIMIT)
};
@@ -394,7 +391,6 @@ public:
static Klass* check_klass_Pre( Klass* k) { return check_klass(k); }
static Klass* check_klass_Pre_JSR292(Klass* k) { return EnableInvokeDynamic ? check_klass(k) : k; }
static Klass* check_klass_Opt( Klass* k) { return k; }
- static Klass* check_klass_Opt_Kernel(Klass* k) { return k; } //== Opt
static Klass* check_klass_Opt_Only_JDK15(Klass* k) {
assert(JDK_Version::is_gte_jdk15x_version(), "JDK 1.5 only");
return k;
diff --git a/src/share/vm/classfile/vmSymbols.hpp b/src/share/vm/classfile/vmSymbols.hpp
index ad0d7d9fc..f28f6d488 100644
--- a/src/share/vm/classfile/vmSymbols.hpp
+++ b/src/share/vm/classfile/vmSymbols.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -108,7 +108,6 @@
template(java_lang_Compiler, "java/lang/Compiler") \
template(sun_misc_Signal, "sun/misc/Signal") \
template(java_lang_AssertionStatusDirectives, "java/lang/AssertionStatusDirectives") \
- template(sun_jkernel_DownloadManager, "sun/jkernel/DownloadManager") \
template(getBootClassPathEntryForClass_name, "getBootClassPathEntryForClass") \
template(sun_misc_PostVMInitHook, "sun/misc/PostVMInitHook") \
template(sun_misc_Launcher_ExtClassLoader, "sun/misc/Launcher$ExtClassLoader") \
diff --git a/src/share/vm/compiler/compileBroker.cpp b/src/share/vm/compiler/compileBroker.cpp
index 41883d1b4..6f4e671c1 100644
--- a/src/share/vm/compiler/compileBroker.cpp
+++ b/src/share/vm/compiler/compileBroker.cpp
@@ -1398,7 +1398,7 @@ bool CompileBroker::compilation_is_prohibited(methodHandle method, int osr_bci,
method->print_short_name(tty);
tty->cr();
}
- method->set_not_compilable_quietly();
+ method->set_not_compilable(CompLevel_all, !quietly, "excluded by CompilerOracle");
}
return false;
diff --git a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
index 78d956ff1..cb8b73743 100644
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
@@ -102,7 +102,7 @@ CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs,
// temporarily disabled).
switch (dictionaryChoice) {
case FreeBlockDictionary<FreeChunk>::dictionaryBinaryTree:
- _dictionary = new BinaryTreeDictionary<FreeChunk, AdaptiveFreeList>(mr);
+ _dictionary = new AFLBinaryTreeDictionary(mr);
break;
case FreeBlockDictionary<FreeChunk>::dictionarySplayTree:
case FreeBlockDictionary<FreeChunk>::dictionarySkipList:
@@ -122,7 +122,8 @@ CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs,
// moved to its new location before the klass is moved.
// Set the _refillSize for the linear allocation blocks
if (!use_adaptive_freelists) {
- FreeChunk* fc = _dictionary->get_chunk(mr.word_size());
+ FreeChunk* fc = _dictionary->get_chunk(mr.word_size(),
+ FreeBlockDictionary<FreeChunk>::atLeast);
// The small linAB initially has all the space and will allocate
// a chunk of any size.
HeapWord* addr = (HeapWord*) fc;
@@ -1647,7 +1648,8 @@ CompactibleFreeListSpace::getChunkFromIndexedFreeListHelper(size_t size,
FreeChunk*
CompactibleFreeListSpace::getChunkFromDictionary(size_t size) {
assert_locked();
- FreeChunk* fc = _dictionary->get_chunk(size);
+ FreeChunk* fc = _dictionary->get_chunk(size,
+ FreeBlockDictionary<FreeChunk>::atLeast);
if (fc == NULL) {
return NULL;
}
@@ -1664,7 +1666,8 @@ CompactibleFreeListSpace::getChunkFromDictionary(size_t size) {
FreeChunk*
CompactibleFreeListSpace::getChunkFromDictionaryExact(size_t size) {
assert_locked();
- FreeChunk* fc = _dictionary->get_chunk(size);
+ FreeChunk* fc = _dictionary->get_chunk(size,
+ FreeBlockDictionary<FreeChunk>::atLeast);
if (fc == NULL) {
return fc;
}
@@ -1677,7 +1680,8 @@ CompactibleFreeListSpace::getChunkFromDictionaryExact(size_t size) {
if (fc->size() < size + MinChunkSize) {
// Return the chunk to the dictionary and go get a bigger one.
returnChunkToDictionary(fc);
- fc = _dictionary->get_chunk(size + MinChunkSize);
+ fc = _dictionary->get_chunk(size + MinChunkSize,
+ FreeBlockDictionary<FreeChunk>::atLeast);
if (fc == NULL) {
return NULL;
}
diff --git a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp
index 1b3d93ed2..23c95897c 100644
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp
@@ -131,7 +131,7 @@ class CompactibleFreeListSpace: public CompactibleSpace {
LinearAllocBlock _smallLinearAllocBlock;
FreeBlockDictionary<FreeChunk>::DictionaryChoice _dictionaryChoice;
- FreeBlockDictionary<FreeChunk>* _dictionary; // ptr to dictionary for large size blocks
+ AFLBinaryTreeDictionary* _dictionary; // ptr to dictionary for large size blocks
AdaptiveFreeList<FreeChunk> _indexedFreeList[IndexSetSize];
// indexed array for small size blocks
diff --git a/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp b/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp
index a67e19d89..1a46ed3f5 100644
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -25,8 +25,6 @@
#ifndef SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_VMSTRUCTS_CMS_HPP
#define SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_VMSTRUCTS_CMS_HPP
-typedef BinaryTreeDictionary<FreeChunk, AdaptiveFreeList> AFLBinaryTreeDictionary;
-
#define VM_STRUCTS_CMS(nonstatic_field, \
volatile_nonstatic_field, \
static_field) \
@@ -34,14 +32,15 @@ typedef BinaryTreeDictionary<FreeChunk, AdaptiveFreeList> AFLBinaryTreeDictionar
nonstatic_field(CompactibleFreeListSpace, _bt, BlockOffsetArrayNonContigSpace) \
\
nonstatic_field(CMSBitMap, _bmWordSize, size_t) \
- nonstatic_field(CMSBitMap, _shifter, const int) \
- nonstatic_field(CMSBitMap, _bm, BitMap) \
- nonstatic_field(CMSBitMap, _virtual_space, VirtualSpace) \
+ nonstatic_field(CMSBitMap, _shifter, const int) \
+ nonstatic_field(CMSBitMap, _bm, BitMap) \
+ nonstatic_field(CMSBitMap, _virtual_space, VirtualSpace) \
nonstatic_field(CMSCollector, _markBitMap, CMSBitMap) \
nonstatic_field(ConcurrentMarkSweepGeneration, _cmsSpace, CompactibleFreeListSpace*) \
static_field(ConcurrentMarkSweepThread, _collector, CMSCollector*) \
nonstatic_field(LinearAllocBlock, _word_size, size_t) \
nonstatic_field(AFLBinaryTreeDictionary, _total_size, size_t) \
+ nonstatic_field(CompactibleFreeListSpace, _dictionary, AFLBinaryTreeDictionary*) \
nonstatic_field(CompactibleFreeListSpace, _indexedFreeList[0], FreeList<FreeChunk>) \
nonstatic_field(CompactibleFreeListSpace, _smallLinearAllocBlock, LinearAllocBlock)
@@ -62,10 +61,9 @@ typedef BinaryTreeDictionary<FreeChunk, AdaptiveFreeList> AFLBinaryTreeDictionar
declare_toplevel_type(SurrogateLockerThread*) \
declare_toplevel_type(CompactibleFreeListSpace*) \
declare_toplevel_type(CMSCollector*) \
- declare_toplevel_type(AFLBinaryTreeDictionary*) \
+ declare_toplevel_type(AFLBinaryTreeDictionary) \
declare_toplevel_type(LinearAllocBlock) \
- declare_toplevel_type(FreeBlockDictionary<FreeChunk>) \
- declare_type(AFLBinaryTreeDictionary, FreeBlockDictionary<FreeChunk>)
+ declare_toplevel_type(FreeBlockDictionary<FreeChunk>)
#define VM_INT_CONSTANTS_CMS(declare_constant) \
declare_constant(Generation::ConcurrentMarkSweep) \
diff --git a/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/src/share/vm/gc_implementation/g1/concurrentMark.cpp
index 3199cbf5a..28c733c15 100644
--- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp
@@ -571,19 +571,14 @@ ConcurrentMark::ConcurrentMark(G1CollectedHeap* g1h, ReservedSpace heap_rs) :
_sleep_factor = 0.0;
_marking_task_overhead = 1.0;
} else {
- if (ConcGCThreads > 0) {
- // notice that ConcGCThreads overwrites G1MarkingOverheadPercent
+ if (!FLAG_IS_DEFAULT(ConcGCThreads) && ConcGCThreads > 0) {
+ // Note: ConcGCThreads has precedence over G1MarkingOverheadPercent
// if both are set
-
- _parallel_marking_threads = (uint) ConcGCThreads;
- _max_parallel_marking_threads = _parallel_marking_threads;
_sleep_factor = 0.0;
_marking_task_overhead = 1.0;
} else if (G1MarkingOverheadPercent > 0) {
- // we will calculate the number of parallel marking threads
- // based on a target overhead with respect to the soft real-time
- // goal
-
+ // We will calculate the number of parallel marking threads based
+ // on a target overhead with respect to the soft real-time goal
double marking_overhead = (double) G1MarkingOverheadPercent / 100.0;
double overall_cm_overhead =
(double) MaxGCPauseMillis * marking_overhead /
@@ -596,17 +591,22 @@ ConcurrentMark::ConcurrentMark(G1CollectedHeap* g1h, ReservedSpace heap_rs) :
double sleep_factor =
(1.0 - marking_task_overhead) / marking_task_overhead;
- _parallel_marking_threads = (uint) marking_thread_num;
- _max_parallel_marking_threads = _parallel_marking_threads;
+ FLAG_SET_ERGO(uintx, ConcGCThreads, (uint) marking_thread_num);
_sleep_factor = sleep_factor;
_marking_task_overhead = marking_task_overhead;
} else {
- _parallel_marking_threads = scale_parallel_threads((uint)ParallelGCThreads);
- _max_parallel_marking_threads = _parallel_marking_threads;
+ // Calculate the number of parallel marking threads by scaling
+ // the number of parallel GC threads.
+ uint marking_thread_num = scale_parallel_threads((uint) ParallelGCThreads);
+ FLAG_SET_ERGO(uintx, ConcGCThreads, marking_thread_num);
_sleep_factor = 0.0;
_marking_task_overhead = 1.0;
}
+ assert(ConcGCThreads > 0, "Should have been set");
+ _parallel_marking_threads = (uint) ConcGCThreads;
+ _max_parallel_marking_threads = _parallel_marking_threads;
+
if (parallel_marking_threads() > 1) {
_cleanup_task_overhead = 1.0;
} else {
@@ -1190,7 +1190,7 @@ void ConcurrentMark::scanRootRegions() {
uint active_workers = MAX2(1U, parallel_marking_threads());
CMRootRegionScanTask task(this);
- if (parallel_marking_threads() > 0) {
+ if (use_parallel_marking_threads()) {
_parallel_workers->set_active_workers((int) active_workers);
_parallel_workers->run_task(&task);
} else {
@@ -1226,7 +1226,7 @@ void ConcurrentMark::markFromRoots() {
set_phase(active_workers, true /* concurrent */);
CMConcurrentMarkingTask markingTask(this, cmThread());
- if (parallel_marking_threads() > 0) {
+ if (use_parallel_marking_threads()) {
_parallel_workers->set_active_workers((int)active_workers);
// Don't set _n_par_threads because it affects MT in proceess_strong_roots()
// and the decisions on that MT processing is made elsewhere.
@@ -2167,7 +2167,8 @@ void ConcurrentMark::completeCleanup() {
assert(tmp_free_list.is_empty(), "post-condition");
}
-// Support closures for reference procssing in G1
+// Supporting Object and Oop closures for reference discovery
+// and processing in during marking
bool G1CMIsAliveClosure::do_object_b(oop obj) {
HeapWord* addr = (HeapWord*)obj;
@@ -2175,73 +2176,26 @@ bool G1CMIsAliveClosure::do_object_b(oop obj) {
(!_g1->is_in_g1_reserved(addr) || !_g1->is_obj_ill(obj));
}
-class G1CMKeepAliveClosure: public ExtendedOopClosure {
- G1CollectedHeap* _g1;
- ConcurrentMark* _cm;
- public:
- G1CMKeepAliveClosure(G1CollectedHeap* g1, ConcurrentMark* cm) :
- _g1(g1), _cm(cm) {
- assert(Thread::current()->is_VM_thread(), "otherwise fix worker id");
- }
-
- virtual void do_oop(narrowOop* p) { do_oop_work(p); }
- virtual void do_oop( oop* p) { do_oop_work(p); }
-
- template <class T> void do_oop_work(T* p) {
- oop obj = oopDesc::load_decode_heap_oop(p);
- HeapWord* addr = (HeapWord*)obj;
-
- if (_cm->verbose_high()) {
- gclog_or_tty->print_cr("\t[0] we're looking at location "
- "*"PTR_FORMAT" = "PTR_FORMAT,
- p, (void*) obj);
- }
-
- if (_g1->is_in_g1_reserved(addr) && _g1->is_obj_ill(obj)) {
- _cm->mark_and_count(obj);
- _cm->mark_stack_push(obj);
- }
- }
-};
-
-class G1CMDrainMarkingStackClosure: public VoidClosure {
- ConcurrentMark* _cm;
- CMMarkStack* _markStack;
- G1CMKeepAliveClosure* _oopClosure;
- public:
- G1CMDrainMarkingStackClosure(ConcurrentMark* cm, CMMarkStack* markStack,
- G1CMKeepAliveClosure* oopClosure) :
- _cm(cm),
- _markStack(markStack),
- _oopClosure(oopClosure) { }
-
- void do_void() {
- _markStack->drain(_oopClosure, _cm->nextMarkBitMap(), false);
- }
-};
-
-// 'Keep Alive' closure used by parallel reference processing.
-// An instance of this closure is used in the parallel reference processing
-// code rather than an instance of G1CMKeepAliveClosure. We could have used
-// the G1CMKeepAliveClosure as it is MT-safe. Also reference objects are
-// placed on to discovered ref lists once so we can mark and push with no
-// need to check whether the object has already been marked. Using the
-// G1CMKeepAliveClosure would mean, however, having all the worker threads
-// operating on the global mark stack. This means that an individual
-// worker would be doing lock-free pushes while it processes its own
-// discovered ref list followed by drain call. If the discovered ref lists
-// are unbalanced then this could cause interference with the other
-// workers. Using a CMTask (and its embedded local data structures)
-// avoids that potential interference.
-class G1CMParKeepAliveAndDrainClosure: public OopClosure {
+// 'Keep Alive' oop closure used by both serial parallel reference processing.
+// Uses the CMTask associated with a worker thread (for serial reference
+// processing the CMTask for worker 0 is used) to preserve (mark) and
+// trace referent objects.
+//
+// Using the CMTask and embedded local queues avoids having the worker
+// threads operating on the global mark stack. This reduces the risk
+// of overflowing the stack - which we would rather avoid at this late
+// state. Also using the tasks' local queues removes the potential
+// of the workers interfering with each other that could occur if
+// operating on the global stack.
+
+class G1CMKeepAliveAndDrainClosure: public OopClosure {
ConcurrentMark* _cm;
CMTask* _task;
int _ref_counter_limit;
int _ref_counter;
public:
- G1CMParKeepAliveAndDrainClosure(ConcurrentMark* cm, CMTask* task) :
- _cm(cm), _task(task),
- _ref_counter_limit(G1RefProcDrainInterval) {
+ G1CMKeepAliveAndDrainClosure(ConcurrentMark* cm, CMTask* task) :
+ _cm(cm), _task(task), _ref_counter_limit(G1RefProcDrainInterval) {
assert(_ref_counter_limit > 0, "sanity");
_ref_counter = _ref_counter_limit;
}
@@ -2262,18 +2216,22 @@ class G1CMParKeepAliveAndDrainClosure: public OopClosure {
_ref_counter--;
if (_ref_counter == 0) {
- // We have dealt with _ref_counter_limit references, pushing them and objects
- // reachable from them on to the local stack (and possibly the global stack).
- // Call do_marking_step() to process these entries. We call the routine in a
- // loop, which we'll exit if there's nothing more to do (i.e. we're done
- // with the entries that we've pushed as a result of the deal_with_reference
- // calls above) or we overflow.
- // Note: CMTask::do_marking_step() can set the CMTask::has_aborted() flag
- // while there may still be some work to do. (See the comment at the
- // beginning of CMTask::do_marking_step() for those conditions - one of which
- // is reaching the specified time target.) It is only when
- // CMTask::do_marking_step() returns without setting the has_aborted() flag
- // that the marking has completed.
+ // We have dealt with _ref_counter_limit references, pushing them
+ // and objects reachable from them on to the local stack (and
+ // possibly the global stack). Call CMTask::do_marking_step() to
+ // process these entries.
+ //
+ // We call CMTask::do_marking_step() in a loop, which we'll exit if
+ // there's nothing more to do (i.e. we're done with the entries that
+ // were pushed as a result of the CMTask::deal_with_reference() calls
+ // above) or we overflow.
+ //
+ // Note: CMTask::do_marking_step() can set the CMTask::has_aborted()
+ // flag while there may still be some work to do. (See the comment at
+ // the beginning of CMTask::do_marking_step() for those conditions -
+ // one of which is reaching the specified time target.) It is only
+ // when CMTask::do_marking_step() returns without setting the
+ // has_aborted() flag that the marking step has completed.
do {
double mark_step_duration_ms = G1ConcMarkStepDurationMillis;
_task->do_marking_step(mark_step_duration_ms,
@@ -2290,36 +2248,59 @@ class G1CMParKeepAliveAndDrainClosure: public OopClosure {
}
};
-class G1CMParDrainMarkingStackClosure: public VoidClosure {
+// 'Drain' oop closure used by both serial and parallel reference processing.
+// Uses the CMTask associated with a given worker thread (for serial
+// reference processing the CMtask for worker 0 is used). Calls the
+// do_marking_step routine, with an unbelievably large timeout value,
+// to drain the marking data structures of the remaining entries
+// added by the 'keep alive' oop closure above.
+
+class G1CMDrainMarkingStackClosure: public VoidClosure {
ConcurrentMark* _cm;
- CMTask* _task;
+ CMTask* _task;
+ bool _do_stealing;
+ bool _do_termination;
public:
- G1CMParDrainMarkingStackClosure(ConcurrentMark* cm, CMTask* task) :
- _cm(cm), _task(task) { }
+ G1CMDrainMarkingStackClosure(ConcurrentMark* cm, CMTask* task, bool is_par) :
+ _cm(cm), _task(task) {
+ assert(is_par || _task->worker_id() == 0,
+ "Only task for worker 0 should be used if ref processing is single threaded");
+ // We only allow stealing and only enter the termination protocol
+ // in CMTask::do_marking_step() if this closure is being instantiated
+ // for parallel reference processing.
+ _do_stealing = _do_termination = is_par;
+ }
void do_void() {
do {
if (_cm->verbose_high()) {
- gclog_or_tty->print_cr("\t[%u] Drain: Calling do marking_step",
- _task->worker_id());
+ gclog_or_tty->print_cr("\t[%u] Drain: Calling do_marking_step - "
+ "stealing: %s, termination: %s",
+ _task->worker_id(),
+ BOOL_TO_STR(_do_stealing),
+ BOOL_TO_STR(_do_termination));
}
- // We call CMTask::do_marking_step() to completely drain the local and
- // global marking stacks. The routine is called in a loop, which we'll
- // exit if there's nothing more to do (i.e. we'completely drained the
- // entries that were pushed as a result of applying the
- // G1CMParKeepAliveAndDrainClosure to the entries on the discovered ref
- // lists above) or we overflow the global marking stack.
- // Note: CMTask::do_marking_step() can set the CMTask::has_aborted() flag
- // while there may still be some work to do. (See the comment at the
- // beginning of CMTask::do_marking_step() for those conditions - one of which
- // is reaching the specified time target.) It is only when
- // CMTask::do_marking_step() returns without setting the has_aborted() flag
- // that the marking has completed.
+ // We call CMTask::do_marking_step() to completely drain the local
+ // and global marking stacks of entries pushed by the 'keep alive'
+ // oop closure (an instance of G1CMKeepAliveAndDrainClosure above).
+ //
+ // CMTask::do_marking_step() is called in a loop, which we'll exit
+ // if there's nothing more to do (i.e. we'completely drained the
+ // entries that were pushed as a a result of applying the 'keep alive'
+ // closure to the entries on the discovered ref lists) or we overflow
+ // the global marking stack.
+ //
+ // Note: CMTask::do_marking_step() can set the CMTask::has_aborted()
+ // flag while there may still be some work to do. (See the comment at
+ // the beginning of CMTask::do_marking_step() for those conditions -
+ // one of which is reaching the specified time target.) It is only
+ // when CMTask::do_marking_step() returns without setting the
+ // has_aborted() flag that the marking step has completed.
_task->do_marking_step(1000000000.0 /* something very large */,
- true /* do_stealing */,
- true /* do_termination */);
+ _do_stealing,
+ _do_termination);
} while (_task->has_aborted() && !_cm->has_overflown());
}
};
@@ -2352,19 +2333,23 @@ class G1CMRefProcTaskProxy: public AbstractGangTask {
ProcessTask& _proc_task;
G1CollectedHeap* _g1h;
ConcurrentMark* _cm;
+ bool _processing_is_mt;
public:
G1CMRefProcTaskProxy(ProcessTask& proc_task,
G1CollectedHeap* g1h,
ConcurrentMark* cm) :
AbstractGangTask("Process reference objects in parallel"),
- _proc_task(proc_task), _g1h(g1h), _cm(cm) { }
+ _proc_task(proc_task), _g1h(g1h), _cm(cm) {
+ ReferenceProcessor* rp = _g1h->ref_processor_cm();
+ _processing_is_mt = rp->processing_is_mt();
+ }
virtual void work(uint worker_id) {
CMTask* marking_task = _cm->task(worker_id);
G1CMIsAliveClosure g1_is_alive(_g1h);
- G1CMParKeepAliveAndDrainClosure g1_par_keep_alive(_cm, marking_task);
- G1CMParDrainMarkingStackClosure g1_par_drain(_cm, marking_task);
+ G1CMKeepAliveAndDrainClosure g1_par_keep_alive(_cm, marking_task);
+ G1CMDrainMarkingStackClosure g1_par_drain(_cm, marking_task, _processing_is_mt);
_proc_task.work(worker_id, g1_is_alive, g1_par_keep_alive, g1_par_drain);
}
@@ -2372,6 +2357,7 @@ public:
void G1CMRefProcTaskExecutor::execute(ProcessTask& proc_task) {
assert(_workers != NULL, "Need parallel worker threads.");
+ assert(_g1h->ref_processor_cm()->processing_is_mt(), "processing is not MT");
G1CMRefProcTaskProxy proc_task_proxy(proc_task, _g1h, _cm);
@@ -2399,6 +2385,7 @@ public:
void G1CMRefProcTaskExecutor::execute(EnqueueTask& enq_task) {
assert(_workers != NULL, "Need parallel worker threads.");
+ assert(_g1h->ref_processor_cm()->processing_is_mt(), "processing is not MT");
G1CMRefEnqueueTaskProxy enq_task_proxy(enq_task);
@@ -2429,59 +2416,58 @@ void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) {
// See the comment in G1CollectedHeap::ref_processing_init()
// about how reference processing currently works in G1.
- // Process weak references.
+ // Set the soft reference policy
rp->setup_policy(clear_all_soft_refs);
assert(_markStack.isEmpty(), "mark stack should be empty");
- G1CMKeepAliveClosure g1_keep_alive(g1h, this);
- G1CMDrainMarkingStackClosure
- g1_drain_mark_stack(this, &_markStack, &g1_keep_alive);
+ // Non-MT instances 'Keep Alive' and 'Complete GC' oop closures.
+ G1CMKeepAliveAndDrainClosure g1_keep_alive(this, task(0));
+ G1CMDrainMarkingStackClosure g1_drain_mark_stack(this, task(0), false);
+
+ // We need at least one active thread. If reference processing is
+ // not multi-threaded we use the current (ConcurrentMarkThread) thread,
+ // otherwise we use the work gang from the G1CollectedHeap and we
+ // utilize all the worker threads we can.
+ uint active_workers = (rp->processing_is_mt() && g1h->workers() != NULL
+ ? g1h->workers()->active_workers()
+ : 1U);
- // We use the work gang from the G1CollectedHeap and we utilize all
- // the worker threads.
- uint active_workers = g1h->workers() ? g1h->workers()->active_workers() : 1U;
active_workers = MAX2(MIN2(active_workers, _max_worker_id), 1U);
G1CMRefProcTaskExecutor par_task_executor(g1h, this,
g1h->workers(), active_workers);
- if (rp->processing_is_mt()) {
- // Set the degree of MT here. If the discovery is done MT, there
- // may have been a different number of threads doing the discovery
- // and a different number of discovered lists may have Ref objects.
- // That is OK as long as the Reference lists are balanced (see
- // balance_all_queues() and balance_queues()).
- rp->set_active_mt_degree(active_workers);
+ AbstractRefProcTaskExecutor* executor = (rp->processing_is_mt()
+ ? &par_task_executor
+ : NULL);
- rp->process_discovered_references(&g1_is_alive,
+ // Set the degree of MT processing here. If the discovery was done MT,
+ // the number of threads involved during discovery could differ from
+ // the number of active workers. This is OK as long as the discovered
+ // Reference lists are balanced (see balance_all_queues() and balance_queues()).
+ rp->set_active_mt_degree(active_workers);
+
+ // Process the weak references.
+ rp->process_discovered_references(&g1_is_alive,
&g1_keep_alive,
&g1_drain_mark_stack,
- &par_task_executor);
+ executor);
- // The work routines of the parallel keep_alive and drain_marking_stack
- // will set the has_overflown flag if we overflow the global marking
- // stack.
- } else {
- rp->process_discovered_references(&g1_is_alive,
- &g1_keep_alive,
- &g1_drain_mark_stack,
- NULL);
- }
+ // The do_oop work routines of the keep_alive and drain_marking_stack
+ // oop closures will set the has_overflown flag if we overflow the
+ // global marking stack.
assert(_markStack.overflow() || _markStack.isEmpty(),
"mark stack should be empty (unless it overflowed)");
if (_markStack.overflow()) {
- // Should have been done already when we tried to push an
+ // This should have been done already when we tried to push an
// entry on to the global mark stack. But let's do it again.
set_has_overflown();
}
- if (rp->processing_is_mt()) {
- assert(rp->num_q() == active_workers, "why not");
- rp->enqueue_discovered_references(&par_task_executor);
- } else {
- rp->enqueue_discovered_references();
- }
+ assert(rp->num_q() == active_workers, "why not");
+
+ rp->enqueue_discovered_references(executor);
rp->verify_no_references_recorded();
assert(!rp->discovery_enabled(), "Post condition");
@@ -3242,7 +3228,9 @@ void ConcurrentMark::print_summary_info() {
}
void ConcurrentMark::print_worker_threads_on(outputStream* st) const {
- _parallel_workers->print_worker_threads_on(st);
+ if (use_parallel_marking_threads()) {
+ _parallel_workers->print_worker_threads_on(st);
+ }
}
// We take a break if someone is trying to stop the world.
diff --git a/src/share/vm/gc_implementation/g1/concurrentMark.hpp b/src/share/vm/gc_implementation/g1/concurrentMark.hpp
index 34c5601e0..6ec27c7d9 100644
--- a/src/share/vm/gc_implementation/g1/concurrentMark.hpp
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.hpp
@@ -371,8 +371,8 @@ class ConcurrentMark: public CHeapObj<mtGC> {
friend class CalcLiveObjectsClosure;
friend class G1CMRefProcTaskProxy;
friend class G1CMRefProcTaskExecutor;
- friend class G1CMParKeepAliveAndDrainClosure;
- friend class G1CMParDrainMarkingStackClosure;
+ friend class G1CMKeepAliveAndDrainClosure;
+ friend class G1CMDrainMarkingStackClosure;
protected:
ConcurrentMarkThread* _cmThread; // the thread doing the work
@@ -499,17 +499,26 @@ protected:
}
// accessor methods
- uint parallel_marking_threads() { return _parallel_marking_threads; }
- uint max_parallel_marking_threads() { return _max_parallel_marking_threads;}
- double sleep_factor() { return _sleep_factor; }
- double marking_task_overhead() { return _marking_task_overhead;}
- double cleanup_sleep_factor() { return _cleanup_sleep_factor; }
- double cleanup_task_overhead() { return _cleanup_task_overhead;}
-
- HeapWord* finger() { return _finger; }
- bool concurrent() { return _concurrent; }
- uint active_tasks() { return _active_tasks; }
- ParallelTaskTerminator* terminator() { return &_terminator; }
+ uint parallel_marking_threads() const { return _parallel_marking_threads; }
+ uint max_parallel_marking_threads() const { return _max_parallel_marking_threads;}
+ double sleep_factor() { return _sleep_factor; }
+ double marking_task_overhead() { return _marking_task_overhead;}
+ double cleanup_sleep_factor() { return _cleanup_sleep_factor; }
+ double cleanup_task_overhead() { return _cleanup_task_overhead;}
+
+ bool use_parallel_marking_threads() const {
+ assert(parallel_marking_threads() <=
+ max_parallel_marking_threads(), "sanity");
+ assert((_parallel_workers == NULL && parallel_marking_threads() == 0) ||
+ parallel_marking_threads() > 0,
+ "parallel workers not set up correctly");
+ return _parallel_workers != NULL;
+ }
+
+ HeapWord* finger() { return _finger; }
+ bool concurrent() { return _concurrent; }
+ uint active_tasks() { return _active_tasks; }
+ ParallelTaskTerminator* terminator() { return &_terminator; }
// It claims the next available region to be scanned by a marking
// task/thread. It might return NULL if the next region is empty or
diff --git a/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp
index dde3ba4be..6f887583c 100644
--- a/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp
+++ b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp
@@ -28,8 +28,9 @@
#include "memory/cardTableModRefBS.hpp"
#include "memory/memRegion.hpp"
#include "oops/oop.inline.hpp"
+#include "utilities/macros.hpp"
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
class DirtyCardQueueSet;
@@ -120,6 +121,6 @@ class G1SATBCardTableLoggingModRefBS: public G1SATBCardTableModRefBS {
};
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1SATBCARDTABLEMODREFBS_HPP
diff --git a/src/share/vm/gc_implementation/g1/heapRegion.hpp b/src/share/vm/gc_implementation/g1/heapRegion.hpp
index 4f1c5493f..7c79195d3 100644
--- a/src/share/vm/gc_implementation/g1/heapRegion.hpp
+++ b/src/share/vm/gc_implementation/g1/heapRegion.hpp
@@ -32,8 +32,9 @@
#include "gc_implementation/shared/spaceDecorator.hpp"
#include "memory/space.inline.hpp"
#include "memory/watermark.hpp"
+#include "utilities/macros.hpp"
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// A HeapRegion is the smallest piece of a G1CollectedHeap that
// can be collected independently.
@@ -837,6 +838,6 @@ class HeapRegionClosure : public StackObj {
bool complete() { return _complete; }
};
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGION_HPP
diff --git a/src/share/vm/gc_implementation/shared/allocationStats.cpp b/src/share/vm/gc_implementation/shared/allocationStats.cpp
index c24fc3bbf..7cc37fd94 100644
--- a/src/share/vm/gc_implementation/shared/allocationStats.cpp
+++ b/src/share/vm/gc_implementation/shared/allocationStats.cpp
@@ -23,10 +23,11 @@
*/
#include "precompiled.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/shared/allocationStats.hpp"
#include "utilities/ostream.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
// Technically this should be derived from machine speed, and
// ideally it would be dynamically adjusted.
diff --git a/src/share/vm/gc_implementation/shared/allocationStats.hpp b/src/share/vm/gc_implementation/shared/allocationStats.hpp
index df1ee1ea2..cf7cd3ae0 100644
--- a/src/share/vm/gc_implementation/shared/allocationStats.hpp
+++ b/src/share/vm/gc_implementation/shared/allocationStats.hpp
@@ -25,11 +25,12 @@
#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_ALLOCATIONSTATS_HPP
#define SHARE_VM_GC_IMPLEMENTATION_SHARED_ALLOCATIONSTATS_HPP
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/shared/gcUtil.hpp"
#include "memory/allocation.hpp"
#include "utilities/globalDefinitions.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
class AllocationStats VALUE_OBJ_CLASS_SPEC {
// A duration threshold (in ms) used to filter
diff --git a/src/share/vm/gc_implementation/shared/concurrentGCThread.hpp b/src/share/vm/gc_implementation/shared/concurrentGCThread.hpp
index 77d041d70..6530d23b6 100644
--- a/src/share/vm/gc_implementation/shared/concurrentGCThread.hpp
+++ b/src/share/vm/gc_implementation/shared/concurrentGCThread.hpp
@@ -25,9 +25,10 @@
#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_CONCURRENTGCTHREAD_HPP
#define SHARE_VM_GC_IMPLEMENTATION_SHARED_CONCURRENTGCTHREAD_HPP
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "runtime/thread.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
class VoidClosure;
diff --git a/src/share/vm/gc_implementation/shared/gSpaceCounters.cpp b/src/share/vm/gc_implementation/shared/gSpaceCounters.cpp
index 4a8f85ab2..506322de5 100644
--- a/src/share/vm/gc_implementation/shared/gSpaceCounters.cpp
+++ b/src/share/vm/gc_implementation/shared/gSpaceCounters.cpp
@@ -23,11 +23,12 @@
*/
#include "precompiled.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/shared/gSpaceCounters.hpp"
#include "memory/generation.hpp"
#include "memory/resourceArea.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
GSpaceCounters::GSpaceCounters(const char* name, int ordinal, size_t max_size,
Generation* g, GenerationCounters* gc,
diff --git a/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp b/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp
index 745dac741..c54e773c3 100644
--- a/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp
+++ b/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp
@@ -25,11 +25,12 @@
#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_GSPACECOUNTERS_HPP
#define SHARE_VM_GC_IMPLEMENTATION_SHARED_GSPACECOUNTERS_HPP
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/shared/generationCounters.hpp"
#include "memory/generation.hpp"
#include "runtime/perfData.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
// A GSpaceCounter is a holder class for performance counters
// that track a space;
diff --git a/src/share/vm/gc_implementation/shared/gcAdaptivePolicyCounters.hpp b/src/share/vm/gc_implementation/shared/gcAdaptivePolicyCounters.hpp
index c1758a2fc..5024ab9e7 100644
--- a/src/share/vm/gc_implementation/shared/gcAdaptivePolicyCounters.hpp
+++ b/src/share/vm/gc_implementation/shared/gcAdaptivePolicyCounters.hpp
@@ -25,10 +25,11 @@
#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_GCADAPTIVEPOLICYCOUNTERS_HPP
#define SHARE_VM_GC_IMPLEMENTATION_SHARED_GCADAPTIVEPOLICYCOUNTERS_HPP
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/shared/adaptiveSizePolicy.hpp"
#include "gc_implementation/shared/gcPolicyCounters.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
// This class keeps statistical information and computes the
// size of the heap.
diff --git a/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp b/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp
index f3b956ee6..034d319b0 100644
--- a/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp
+++ b/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp
@@ -25,11 +25,12 @@
#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_HSPACECOUNTERS_HPP
#define SHARE_VM_GC_IMPLEMENTATION_SHARED_HSPACECOUNTERS_HPP
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/shared/generationCounters.hpp"
#include "memory/generation.hpp"
#include "runtime/perfData.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
// A HSpaceCounter is a holder class for performance counters
// that track a collections (logical spaces) in a heap;
diff --git a/src/share/vm/gc_implementation/shared/immutableSpace.cpp b/src/share/vm/gc_implementation/shared/immutableSpace.cpp
index 30eb04df6..c844a3e59 100644
--- a/src/share/vm/gc_implementation/shared/immutableSpace.cpp
+++ b/src/share/vm/gc_implementation/shared/immutableSpace.cpp
@@ -23,11 +23,12 @@
*/
#include "precompiled.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/shared/immutableSpace.hpp"
#include "memory/universe.hpp"
#include "oops/oop.inline.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
void ImmutableSpace::initialize(MemRegion mr) {
HeapWord* bottom = mr.start();
diff --git a/src/share/vm/gc_implementation/shared/isGCActiveMark.hpp b/src/share/vm/gc_implementation/shared/isGCActiveMark.hpp
index 4d3641724..c56cbafeb 100644
--- a/src/share/vm/gc_implementation/shared/isGCActiveMark.hpp
+++ b/src/share/vm/gc_implementation/shared/isGCActiveMark.hpp
@@ -25,9 +25,10 @@
#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_ISGCACTIVEMARK_HPP
#define SHARE_VM_GC_IMPLEMENTATION_SHARED_ISGCACTIVEMARK_HPP
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
// This class provides a method for block structured setting of the
// _is_gc_active state without requiring accessors in CollectedHeap
diff --git a/src/share/vm/gc_implementation/shared/markSweep.inline.hpp b/src/share/vm/gc_implementation/shared/markSweep.inline.hpp
index 3a3cbdd8c..975229195 100644
--- a/src/share/vm/gc_implementation/shared/markSweep.inline.hpp
+++ b/src/share/vm/gc_implementation/shared/markSweep.inline.hpp
@@ -28,9 +28,10 @@
#include "gc_implementation/shared/markSweep.hpp"
#include "gc_interface/collectedHeap.hpp"
#include "utilities/stack.inline.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
inline void MarkSweep::mark_object(oop obj) {
// some marks may contain information we need to preserve so we store them away
diff --git a/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp b/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp
index 8b8f8d65e..5621c077c 100644
--- a/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp
+++ b/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp
@@ -25,10 +25,11 @@
#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_MUTABLENUMASPACE_HPP
#define SHARE_VM_GC_IMPLEMENTATION_SHARED_MUTABLENUMASPACE_HPP
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/shared/gcUtil.hpp"
#include "gc_implementation/shared/mutableSpace.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
/*
* The NUMA-aware allocator (MutableNUMASpace) is basically a modification
diff --git a/src/share/vm/gc_implementation/shared/mutableSpace.cpp b/src/share/vm/gc_implementation/shared/mutableSpace.cpp
index e573e02df..d50edac13 100644
--- a/src/share/vm/gc_implementation/shared/mutableSpace.cpp
+++ b/src/share/vm/gc_implementation/shared/mutableSpace.cpp
@@ -23,13 +23,14 @@
*/
#include "precompiled.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/shared/mutableSpace.hpp"
#include "gc_implementation/shared/spaceDecorator.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/safepoint.hpp"
#include "runtime/thread.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
MutableSpace::MutableSpace(size_t alignment): ImmutableSpace(), _top(NULL), _alignment(alignment) {
assert(MutableSpace::alignment() >= 0 &&
diff --git a/src/share/vm/gc_implementation/shared/spaceCounters.cpp b/src/share/vm/gc_implementation/shared/spaceCounters.cpp
index 48dddd85b..f606e99e9 100644
--- a/src/share/vm/gc_implementation/shared/spaceCounters.cpp
+++ b/src/share/vm/gc_implementation/shared/spaceCounters.cpp
@@ -23,10 +23,11 @@
*/
#include "precompiled.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/shared/spaceCounters.hpp"
#include "memory/resourceArea.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
SpaceCounters::SpaceCounters(const char* name, int ordinal, size_t max_size,
MutableSpace* m, GenerationCounters* gc) :
diff --git a/src/share/vm/gc_implementation/shared/spaceCounters.hpp b/src/share/vm/gc_implementation/shared/spaceCounters.hpp
index 6b13e5acf..17302d420 100644
--- a/src/share/vm/gc_implementation/shared/spaceCounters.hpp
+++ b/src/share/vm/gc_implementation/shared/spaceCounters.hpp
@@ -25,12 +25,13 @@
#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_SPACECOUNTERS_HPP
#define SHARE_VM_GC_IMPLEMENTATION_SHARED_SPACECOUNTERS_HPP
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/shared/generationCounters.hpp"
#include "gc_implementation/shared/immutableSpace.hpp"
#include "gc_implementation/shared/mutableSpace.hpp"
#include "runtime/perfData.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
// A SpaceCounter is a holder class for performance counters
// that track a space;
diff --git a/src/share/vm/gc_implementation/shared/vmGCOperations.cpp b/src/share/vm/gc_implementation/shared/vmGCOperations.cpp
index ee1be4a64..756ed28f0 100644
--- a/src/share/vm/gc_implementation/shared/vmGCOperations.cpp
+++ b/src/share/vm/gc_implementation/shared/vmGCOperations.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -36,9 +36,10 @@
#include "runtime/interfaceSupport.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/preserveException.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
#ifndef USDT2
HS_DTRACE_PROBE_DECL1(hotspot, gc__begin, bool);
@@ -167,7 +168,9 @@ void VM_GC_HeapInspection::doit() {
ch->collect_as_vm_thread(GCCause::_heap_inspection);
}
}
- HeapInspection::heap_inspection(_out, _need_prologue /* need_prologue */);
+ HeapInspection inspect(_csv_format, _print_help, _print_class_stats,
+ _columns);
+ inspect.heap_inspection(_out, _need_prologue /* need_prologue */);
}
diff --git a/src/share/vm/gc_implementation/shared/vmGCOperations.hpp b/src/share/vm/gc_implementation/shared/vmGCOperations.hpp
index 285ef97e3..2a416f228 100644
--- a/src/share/vm/gc_implementation/shared/vmGCOperations.hpp
+++ b/src/share/vm/gc_implementation/shared/vmGCOperations.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -130,6 +130,10 @@ class VM_GC_HeapInspection: public VM_GC_Operation {
outputStream* _out;
bool _full_gc;
bool _need_prologue;
+ bool _csv_format; // "comma separated values" format for spreadsheet.
+ bool _print_help;
+ bool _print_class_stats;
+ const char* _columns;
public:
VM_GC_HeapInspection(outputStream* out, bool request_full_gc,
bool need_prologue) :
@@ -140,6 +144,10 @@ class VM_GC_HeapInspection: public VM_GC_Operation {
_out = out;
_full_gc = request_full_gc;
_need_prologue = need_prologue;
+ _csv_format = false;
+ _print_help = false;
+ _print_class_stats = false;
+ _columns = NULL;
}
~VM_GC_HeapInspection() {}
@@ -147,6 +155,10 @@ class VM_GC_HeapInspection: public VM_GC_Operation {
virtual bool skip_operation() const;
virtual bool doit_prologue();
virtual void doit();
+ void set_csv_format(bool value) {_csv_format = value;}
+ void set_print_help(bool value) {_print_help = value;}
+ void set_print_class_stats(bool value) {_print_class_stats = value;}
+ void set_columns(const char* value) {_columns = value;}
};
diff --git a/src/share/vm/interpreter/bytecodeInterpreter.cpp b/src/share/vm/interpreter/bytecodeInterpreter.cpp
index 0d139fdf7..55ef63ee9 100644
--- a/src/share/vm/interpreter/bytecodeInterpreter.cpp
+++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp
@@ -3099,9 +3099,9 @@ BytecodeInterpreter::print() {
tty->print_cr("&native_fresult: " INTPTR_FORMAT, (uintptr_t) &this->_native_fresult);
tty->print_cr("native_lresult: " INTPTR_FORMAT, (uintptr_t) this->_native_lresult);
#endif
-#if defined(IA64) && !defined(ZERO)
+#if !defined(ZERO)
tty->print_cr("last_Java_fp: " INTPTR_FORMAT, (uintptr_t) this->_last_Java_fp);
-#endif // IA64 && !ZERO
+#endif // !ZERO
tty->print_cr("self_link: " INTPTR_FORMAT, (uintptr_t) this->_self_link);
}
diff --git a/src/share/vm/interpreter/linkResolver.cpp b/src/share/vm/interpreter/linkResolver.cpp
index 959388fc6..efb2a164f 100644
--- a/src/share/vm/interpreter/linkResolver.cpp
+++ b/src/share/vm/interpreter/linkResolver.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1241,7 +1241,7 @@ void LinkResolver::resolve_handle_call(CallInfo& result, KlassHandle resolved_kl
void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
assert(EnableInvokeDynamic, "");
- pool->set_invokedynamic(); // mark header to flag active call sites
+ pool->set_has_invokedynamic(); // mark header to flag active call sites
//resolve_pool(<resolved_klass>, method_name, method_signature, current_klass, pool, index, CHECK);
Symbol* method_name = pool->name_ref_at(index);
diff --git a/src/share/vm/memory/allocation.hpp b/src/share/vm/memory/allocation.hpp
index 3cade72c2..e1e266ec5 100644
--- a/src/share/vm/memory/allocation.hpp
+++ b/src/share/vm/memory/allocation.hpp
@@ -145,9 +145,10 @@ enum MemoryType {
mtChunk = 0x0B00, // chunk that holds content of arenas
mtJavaHeap = 0x0C00, // Java heap
mtClassShared = 0x0D00, // class data sharing
- mt_number_of_types = 0x000D, // number of memory types (mtDontTrack
+ mtTest = 0x0E00, // Test type for verifying NMT
+ mt_number_of_types = 0x000E, // number of memory types (mtDontTrack
// is not included as validate type)
- mtDontTrack = 0x0E00, // memory we do not or cannot track
+ mtDontTrack = 0x0F00, // memory we do not or cannot track
mt_masks = 0x7F00,
// object type mask
diff --git a/src/share/vm/memory/binaryTreeDictionary.cpp b/src/share/vm/memory/binaryTreeDictionary.cpp
index 725a71925..8ed2b61a9 100644
--- a/src/share/vm/memory/binaryTreeDictionary.cpp
+++ b/src/share/vm/memory/binaryTreeDictionary.cpp
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "utilities/macros.hpp"
#include "gc_implementation/shared/allocationStats.hpp"
#include "memory/binaryTreeDictionary.hpp"
#include "memory/freeList.hpp"
@@ -31,12 +32,13 @@
#include "memory/metachunk.hpp"
#include "runtime/globals.hpp"
#include "utilities/ostream.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/adaptiveFreeList.hpp"
#include "gc_implementation/concurrentMarkSweep/freeChunk.hpp"
#include "gc_implementation/shared/spaceDecorator.hpp"
#include "gc_implementation/concurrentMarkSweep/freeChunk.hpp"
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
////////////////////////////////////////////////////////////////////////////////
// A binary tree based search structure for free blocks.
@@ -118,7 +120,7 @@ TreeList<Chunk_t, FreeList_t>::as_TreeList(HeapWord* addr, size_t size) {
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// Specialize for AdaptiveFreeList which tries to avoid
// splitting a chunk of a size that is under populated in favor of
// an over populated size. The general get_better_list() just returns
@@ -160,7 +162,7 @@ TreeList<FreeChunk, AdaptiveFreeList>::get_better_list(
}
return curTL;
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
template <class Chunk_t, template <class> class FreeList_t>
TreeList<Chunk_t, FreeList_t>*
@@ -871,9 +873,9 @@ size_t BinaryTreeDictionary<Chunk_t, FreeList_t>::total_nodes_in_tree(TreeList<C
template <class Chunk_t, template <class> class FreeList_t>
void BinaryTreeDictionary<Chunk_t, FreeList_t>::dict_census_update(size_t size, bool split, bool birth){}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
template <>
-void BinaryTreeDictionary<FreeChunk, AdaptiveFreeList>::dict_census_update(size_t size, bool split, bool birth){
+void AFLBinaryTreeDictionary::dict_census_update(size_t size, bool split, bool birth){
TreeList<FreeChunk, AdaptiveFreeList>* nd = find_list(size);
if (nd) {
if (split) {
@@ -900,7 +902,7 @@ void BinaryTreeDictionary<FreeChunk, AdaptiveFreeList>::dict_census_update(size_
// This is a birth associated with a LinAB. The chunk
// for the LinAB is not in the dictionary.
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
template <class Chunk_t, template <class> class FreeList_t>
bool BinaryTreeDictionary<Chunk_t, FreeList_t>::coal_dict_over_populated(size_t size) {
@@ -909,9 +911,9 @@ bool BinaryTreeDictionary<Chunk_t, FreeList_t>::coal_dict_over_populated(size_t
return true;
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
template <>
-bool BinaryTreeDictionary<FreeChunk, AdaptiveFreeList>::coal_dict_over_populated(size_t size) {
+bool AFLBinaryTreeDictionary::coal_dict_over_populated(size_t size) {
if (FLSAlwaysCoalesceLarge) return true;
TreeList<FreeChunk, AdaptiveFreeList>* list_of_size = find_list(size);
@@ -919,7 +921,7 @@ bool BinaryTreeDictionary<FreeChunk, AdaptiveFreeList>::coal_dict_over_populated
return list_of_size == NULL || list_of_size->coal_desired() <= 0 ||
list_of_size->count() > list_of_size->coal_desired();
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
// Closures for walking the binary tree.
// do_list() walks the free list in a node applying the closure
@@ -979,7 +981,7 @@ class BeginSweepClosure : public AscendTreeCensusClosure<Chunk_t, FreeList_t> {
void do_list(FreeList<Chunk_t>* fl) {}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
void do_list(AdaptiveFreeList<Chunk_t>* fl) {
double coalSurplusPercent = _percentage;
fl->compute_desired(_inter_sweep_current, _inter_sweep_estimate, _intra_sweep_estimate);
@@ -987,7 +989,7 @@ class BeginSweepClosure : public AscendTreeCensusClosure<Chunk_t, FreeList_t> {
fl->set_before_sweep(fl->count());
fl->set_bfr_surp(fl->surplus());
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
};
// Used to search the tree until a condition is met.
@@ -1134,13 +1136,13 @@ class setTreeSurplusClosure : public AscendTreeCensusClosure<Chunk_t, FreeList_t
setTreeSurplusClosure(double v) { percentage = v; }
void do_list(FreeList<Chunk_t>* fl) {}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
void do_list(AdaptiveFreeList<Chunk_t>* fl) {
double splitSurplusPercent = percentage;
fl->set_surplus(fl->count() -
(ssize_t)((double)fl->desired() * splitSurplusPercent));
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
};
template <class Chunk_t, template <class> class FreeList_t>
@@ -1157,7 +1159,7 @@ class setTreeHintsClosure : public DescendTreeCensusClosure<Chunk_t, FreeList_t>
setTreeHintsClosure(size_t v) { hint = v; }
void do_list(FreeList<Chunk_t>* fl) {}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
void do_list(AdaptiveFreeList<Chunk_t>* fl) {
fl->set_hint(hint);
assert(fl->hint() == 0 || fl->hint() > fl->size(),
@@ -1166,7 +1168,7 @@ class setTreeHintsClosure : public DescendTreeCensusClosure<Chunk_t, FreeList_t>
hint = fl->size();
}
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
};
template <class Chunk_t, template <class> class FreeList_t>
@@ -1180,7 +1182,7 @@ template <class Chunk_t, template <class> class FreeList_t>
class clearTreeCensusClosure : public AscendTreeCensusClosure<Chunk_t, FreeList_t> {
void do_list(FreeList<Chunk_t>* fl) {}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
void do_list(AdaptiveFreeList<Chunk_t>* fl) {
fl->set_prev_sweep(fl->count());
fl->set_coal_births(0);
@@ -1188,7 +1190,7 @@ class clearTreeCensusClosure : public AscendTreeCensusClosure<Chunk_t, FreeList_
fl->set_split_births(0);
fl->set_split_deaths(0);
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
};
template <class Chunk_t, template <class> class FreeList_t>
@@ -1252,7 +1254,7 @@ class PrintTreeCensusClosure : public AscendTreeCensusClosure<Chunk_t, FreeList_
total()->set_count( total()->count() + fl->count() );
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
void do_list(AdaptiveFreeList<Chunk_t>* fl) {
if (++_print_line >= 40) {
FreeList_t<Chunk_t>::print_labels_on(gclog_or_tty, "size");
@@ -1271,7 +1273,7 @@ class PrintTreeCensusClosure : public AscendTreeCensusClosure<Chunk_t, FreeList_
total()->set_split_births(total()->split_births() + fl->split_births());
total()->set_split_deaths(total()->split_deaths() + fl->split_deaths());
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
};
template <class Chunk_t, template <class> class FreeList_t>
@@ -1286,9 +1288,9 @@ void BinaryTreeDictionary<Chunk_t, FreeList_t>::print_dict_census(void) const {
FreeList_t<Chunk_t>::print_labels_on(gclog_or_tty, " ");
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
template <>
-void BinaryTreeDictionary<FreeChunk, AdaptiveFreeList>::print_dict_census(void) const {
+void AFLBinaryTreeDictionary::print_dict_census(void) const {
gclog_or_tty->print("\nBinaryTree\n");
AdaptiveFreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size");
@@ -1308,7 +1310,7 @@ void BinaryTreeDictionary<FreeChunk, AdaptiveFreeList>::print_dict_census(void)
(double)(total->desired() - total->count())
/(total->desired() != 0 ? (double)total->desired() : 1.0));
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
template <class Chunk_t, template <class> class FreeList_t>
class PrintFreeListsClosure : public AscendTreeCensusClosure<Chunk_t, FreeList_t> {
@@ -1414,10 +1416,10 @@ template class BinaryTreeDictionary<Metachunk, FreeList>;
template class TreeChunk<Metachunk, FreeList>;
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// Explicitly instantiate these types for FreeChunk.
template class TreeList<FreeChunk, AdaptiveFreeList>;
template class BinaryTreeDictionary<FreeChunk, AdaptiveFreeList>;
template class TreeChunk<FreeChunk, AdaptiveFreeList>;
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
diff --git a/src/share/vm/memory/binaryTreeDictionary.hpp b/src/share/vm/memory/binaryTreeDictionary.hpp
index 757eb4fda..460a4ea29 100644
--- a/src/share/vm/memory/binaryTreeDictionary.hpp
+++ b/src/share/vm/memory/binaryTreeDictionary.hpp
@@ -43,6 +43,10 @@ template <class Chunk_t, template <class> class FreeList_t> class AscendTreeCens
template <class Chunk_t, template <class> class FreeList_t> class DescendTreeCensusClosure;
template <class Chunk_t, template <class> class FreeList_t> class DescendTreeSearchClosure;
+class FreeChunk;
+template <class> class AdaptiveFreeList;
+typedef BinaryTreeDictionary<FreeChunk, AdaptiveFreeList> AFLBinaryTreeDictionary;
+
template <class Chunk_t, template <class> class FreeList_t>
class TreeList : public FreeList_t<Chunk_t> {
friend class TreeChunk<Chunk_t, FreeList_t>;
diff --git a/src/share/vm/memory/cardTableModRefBS.cpp b/src/share/vm/memory/cardTableModRefBS.cpp
index bd0c79ed4..d3fa82d85 100644
--- a/src/share/vm/memory/cardTableModRefBS.cpp
+++ b/src/share/vm/memory/cardTableModRefBS.cpp
@@ -34,6 +34,7 @@
#include "runtime/mutexLocker.hpp"
#include "runtime/virtualspace.hpp"
#include "services/memTracker.hpp"
+#include "utilities/macros.hpp"
#ifdef COMPILER1
#include "c1/c1_LIR.hpp"
#include "c1/c1_LIRGenerator.hpp"
@@ -499,13 +500,13 @@ void CardTableModRefBS::non_clean_card_iterate_possibly_parallel(Space* sp,
int n_threads = SharedHeap::heap()->n_par_threads();
bool is_par = n_threads > 0;
if (is_par) {
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
assert(SharedHeap::heap()->n_par_threads() ==
SharedHeap::heap()->workers()->active_workers(), "Mismatch");
non_clean_card_iterate_parallel_work(sp, mr, cl, ct, n_threads);
-#else // SERIALGC
+#else // INCLUDE_ALL_GCS
fatal("Parallel gc not supported here.");
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
} else {
// We do not call the non_clean_card_iterate_serial() version below because
// we want to clear the cards (which non_clean_card_iterate_serial() does not
diff --git a/src/share/vm/memory/cardTableRS.cpp b/src/share/vm/memory/cardTableRS.cpp
index d16b3ec0b..d92de4816 100644
--- a/src/share/vm/memory/cardTableRS.cpp
+++ b/src/share/vm/memory/cardTableRS.cpp
@@ -31,10 +31,11 @@
#include "oops/oop.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/os.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/concurrentMark.hpp"
#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
CardTableRS::CardTableRS(MemRegion whole_heap,
int max_covered_regions) :
@@ -42,7 +43,7 @@ CardTableRS::CardTableRS(MemRegion whole_heap,
_cur_youngergen_card_val(youngergenP1_card),
_regions_to_iterate(max_covered_regions - 1)
{
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
if (UseG1GC) {
_ct_bs = new G1SATBCardTableLoggingModRefBS(whole_heap,
max_covered_regions);
diff --git a/src/share/vm/memory/collectorPolicy.cpp b/src/share/vm/memory/collectorPolicy.cpp
index b13d97611..2645cec46 100644
--- a/src/share/vm/memory/collectorPolicy.cpp
+++ b/src/share/vm/memory/collectorPolicy.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -39,10 +39,11 @@
#include "runtime/java.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/vmThread.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp"
#include "gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
// CollectorPolicy methods.
@@ -235,6 +236,18 @@ void TwoGenerationCollectorPolicy::initialize_flags() {
if (NewSize + OldSize > MaxHeapSize) {
MaxHeapSize = NewSize + OldSize;
}
+
+ if (FLAG_IS_CMDLINE(OldSize) && FLAG_IS_DEFAULT(NewSize)) {
+ // NewRatio will be used later to set the young generation size so we use
+ // it to calculate how big the heap should be based on the requested OldSize
+ // and NewRatio.
+ assert(NewRatio > 0, "NewRatio should have been set up earlier");
+ size_t calculated_heapsize = (OldSize / NewRatio) * (NewRatio + 1);
+
+ calculated_heapsize = align_size_up(calculated_heapsize, max_alignment());
+ MaxHeapSize = calculated_heapsize;
+ InitialHeapSize = calculated_heapsize;
+ }
MaxHeapSize = align_size_up(MaxHeapSize, max_alignment());
always_do_update_barrier = UseConcMarkSweepGC;
@@ -384,14 +397,15 @@ void GenCollectorPolicy::initialize_size_info() {
// keeping it simple also seems a worthwhile goal.
bool TwoGenerationCollectorPolicy::adjust_gen0_sizes(size_t* gen0_size_ptr,
size_t* gen1_size_ptr,
- size_t heap_size,
- size_t min_gen0_size) {
+ const size_t heap_size,
+ const size_t min_gen1_size) {
bool result = false;
+
if ((*gen1_size_ptr + *gen0_size_ptr) > heap_size) {
- if (((*gen0_size_ptr + OldSize) > heap_size) &&
- (heap_size - min_gen0_size) >= min_alignment()) {
- // Adjust gen0 down to accomodate OldSize
- *gen0_size_ptr = heap_size - min_gen0_size;
+ if ((heap_size < (*gen0_size_ptr + min_gen1_size)) &&
+ (heap_size >= min_gen1_size + min_alignment())) {
+ // Adjust gen0 down to accommodate min_gen1_size
+ *gen0_size_ptr = heap_size - min_gen1_size;
*gen0_size_ptr =
MAX2((uintx)align_size_down(*gen0_size_ptr, min_alignment()),
min_alignment());
diff --git a/src/share/vm/memory/collectorPolicy.hpp b/src/share/vm/memory/collectorPolicy.hpp
index a079f71b9..4acf7ba78 100644
--- a/src/share/vm/memory/collectorPolicy.hpp
+++ b/src/share/vm/memory/collectorPolicy.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -29,6 +29,7 @@
#include "memory/barrierSet.hpp"
#include "memory/generationSpec.hpp"
#include "memory/genRemSet.hpp"
+#include "utilities/macros.hpp"
// This class (or more correctly, subtypes of this class)
// are used to define global garbage collector attributes.
@@ -48,10 +49,10 @@
class GenCollectorPolicy;
class TwoGenerationCollectorPolicy;
class AdaptiveSizePolicy;
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
class ConcurrentMarkSweepPolicy;
class G1CollectorPolicy;
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
class GCPolicyCounters;
class MarkSweepPolicy;
@@ -134,21 +135,21 @@ class CollectorPolicy : public CHeapObj<mtGC> {
virtual GenCollectorPolicy* as_generation_policy() { return NULL; }
virtual TwoGenerationCollectorPolicy* as_two_generation_policy() { return NULL; }
virtual MarkSweepPolicy* as_mark_sweep_policy() { return NULL; }
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
virtual ConcurrentMarkSweepPolicy* as_concurrent_mark_sweep_policy() { return NULL; }
virtual G1CollectorPolicy* as_g1_policy() { return NULL; }
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
// Note that these are not virtual.
bool is_generation_policy() { return as_generation_policy() != NULL; }
bool is_two_generation_policy() { return as_two_generation_policy() != NULL; }
bool is_mark_sweep_policy() { return as_mark_sweep_policy() != NULL; }
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
bool is_concurrent_mark_sweep_policy() { return as_concurrent_mark_sweep_policy() != NULL; }
bool is_g1_policy() { return as_g1_policy() != NULL; }
-#else // SERIALGC
+#else // INCLUDE_ALL_GCS
bool is_concurrent_mark_sweep_policy() { return false; }
bool is_g1_policy() { return false; }
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
virtual BarrierSet::Name barrier_set_name() = 0;
@@ -321,7 +322,7 @@ class TwoGenerationCollectorPolicy : public GenCollectorPolicy {
// Returns true is gen0 sizes were adjusted
bool adjust_gen0_sizes(size_t* gen0_size_ptr, size_t* gen1_size_ptr,
- size_t heap_size, size_t min_gen1_size);
+ const size_t heap_size, const size_t min_gen1_size);
};
class MarkSweepPolicy : public TwoGenerationCollectorPolicy {
diff --git a/src/share/vm/memory/filemap.cpp b/src/share/vm/memory/filemap.cpp
index fe0958073..fec0957f1 100644
--- a/src/share/vm/memory/filemap.cpp
+++ b/src/share/vm/memory/filemap.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -210,13 +210,14 @@ void FileMapInfo::open_for_write() {
tty->print_cr(" %s", _full_path);
}
- // Remove the existing file in case another process has it open.
+#ifdef _WINDOWS // On Windows, need WRITE permission to remove the file.
+ chmod(_full_path, _S_IREAD | _S_IWRITE);
+#endif
+
+ // Use remove() to delete the existing file because, on Unix, this will
+ // allow processes that have it open continued access to the file.
remove(_full_path);
-#ifdef _WINDOWS // if 0444 is used on Windows, then remove() will fail.
- int fd = open(_full_path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0744);
-#else
int fd = open(_full_path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0444);
-#endif
if (fd < 0) {
fail_stop("Unable to create shared archive file %s.", _full_path);
}
diff --git a/src/share/vm/memory/freeBlockDictionary.cpp b/src/share/vm/memory/freeBlockDictionary.cpp
index 918a80f1f..713036ea5 100644
--- a/src/share/vm/memory/freeBlockDictionary.cpp
+++ b/src/share/vm/memory/freeBlockDictionary.cpp
@@ -23,13 +23,15 @@
*/
#include "precompiled.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/freeChunk.hpp"
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
#include "memory/freeBlockDictionary.hpp"
#include "memory/metablock.hpp"
#include "memory/metachunk.hpp"
#include "runtime/thread.inline.hpp"
+#include "utilities/macros.hpp"
#ifndef PRODUCT
template <class Chunk> Mutex* FreeBlockDictionary<Chunk>::par_lock() const {
@@ -56,7 +58,7 @@ template <class Chunk> void FreeBlockDictionary<Chunk>::verify_par_locked() cons
template class FreeBlockDictionary<Metablock>;
template class FreeBlockDictionary<Metachunk>;
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// Explicitly instantiate for FreeChunk
template class FreeBlockDictionary<FreeChunk>;
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
diff --git a/src/share/vm/memory/freeList.cpp b/src/share/vm/memory/freeList.cpp
index f5cd80545..05e4ef0a2 100644
--- a/src/share/vm/memory/freeList.cpp
+++ b/src/share/vm/memory/freeList.cpp
@@ -31,10 +31,11 @@
#include "runtime/globals.hpp"
#include "runtime/mutex.hpp"
#include "runtime/vmThread.hpp"
+#include "utilities/macros.hpp"
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/freeChunk.hpp"
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
// Free list. A FreeList is used to access a linked list of chunks
// of space in the heap. The head and tail are maintained so that
@@ -341,6 +342,6 @@ void FreeList<Chunk_t>::print_on(outputStream* st, const char* c) const {
template class FreeList<Metablock>;
template class FreeList<Metachunk>;
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
template class FreeList<FreeChunk>;
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
diff --git a/src/share/vm/memory/genCollectedHeap.cpp b/src/share/vm/memory/genCollectedHeap.cpp
index 13778b06d..9d65cc157 100644
--- a/src/share/vm/memory/genCollectedHeap.cpp
+++ b/src/share/vm/memory/genCollectedHeap.cpp
@@ -51,10 +51,11 @@
#include "services/memoryService.hpp"
#include "utilities/vmError.hpp"
#include "utilities/workgroup.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
#include "gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
GenCollectedHeap* GenCollectedHeap::_gch;
NOT_PRODUCT(size_t GenCollectedHeap::_skip_header_HeapWords = 0;)
@@ -141,14 +142,14 @@ jint GenCollectedHeap::initialize() {
}
clear_incremental_collection_failed();
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// If we are running CMS, create the collector responsible
// for collecting the CMS generations.
if (collector_policy()->is_concurrent_mark_sweep_policy()) {
bool success = create_cms_collector();
if (!success) return JNI_ENOMEM;
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
return JNI_OK;
}
@@ -686,12 +687,12 @@ size_t GenCollectedHeap::unsafe_max_alloc() {
void GenCollectedHeap::collect(GCCause::Cause cause) {
if (should_do_concurrent_full_gc(cause)) {
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// mostly concurrent full collection
collect_mostly_concurrent(cause);
-#else // SERIALGC
+#else // INCLUDE_ALL_GCS
ShouldNotReachHere();
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
} else {
#ifdef ASSERT
if (cause == GCCause::_scavenge_alot) {
@@ -736,7 +737,7 @@ void GenCollectedHeap::collect_locked(GCCause::Cause cause, int max_level) {
}
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
bool GenCollectedHeap::create_cms_collector() {
assert(((_gens[1]->kind() == Generation::ConcurrentMarkSweep) ||
@@ -772,7 +773,7 @@ void GenCollectedHeap::collect_mostly_concurrent(GCCause::Cause cause) {
VMThread::execute(&op);
}
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
void GenCollectedHeap::do_full_collection(bool clear_all_soft_refs) {
do_full_collection(clear_all_soft_refs, _n_gens - 1);
@@ -1116,22 +1117,22 @@ void GenCollectedHeap::gc_threads_do(ThreadClosure* tc) const {
if (workers() != NULL) {
workers()->threads_do(tc);
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
if (UseConcMarkSweepGC) {
ConcurrentMarkSweepThread::threads_do(tc);
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
}
void GenCollectedHeap::print_gc_threads_on(outputStream* st) const {
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
if (UseParNewGC) {
workers()->print_worker_threads_on(st);
}
if (UseConcMarkSweepGC) {
ConcurrentMarkSweepThread::print_all_on(st);
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
}
void GenCollectedHeap::print_tracing_info() const {
diff --git a/src/share/vm/memory/generationSpec.cpp b/src/share/vm/memory/generationSpec.cpp
index 30c79ea6f..d97a56fbb 100644
--- a/src/share/vm/memory/generationSpec.cpp
+++ b/src/share/vm/memory/generationSpec.cpp
@@ -30,11 +30,12 @@
#include "memory/generationSpec.hpp"
#include "memory/tenuredGeneration.hpp"
#include "runtime/java.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/parNew/asParNewGeneration.hpp"
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp"
#include "gc_implementation/parNew/parNewGeneration.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
Generation* GenerationSpec::init(ReservedSpace rs, int level,
GenRemSet* remset) {
@@ -45,7 +46,7 @@ Generation* GenerationSpec::init(ReservedSpace rs, int level,
case Generation::MarkSweepCompact:
return new TenuredGeneration(rs, init_size(), level, remset);
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
case Generation::ParNew:
return new ParNewGeneration(rs, init_size(), level);
@@ -94,7 +95,7 @@ Generation* GenerationSpec::init(ReservedSpace rs, int level,
return g;
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
default:
guarantee(false, "unrecognized GenerationName");
diff --git a/src/share/vm/memory/heapInspection.cpp b/src/share/vm/memory/heapInspection.cpp
index 71674fcb2..a51ea1d15 100644
--- a/src/share/vm/memory/heapInspection.cpp
+++ b/src/share/vm/memory/heapInspection.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -23,15 +23,17 @@
*/
#include "precompiled.hpp"
+#include "classfile/classLoaderData.hpp"
#include "gc_interface/collectedHeap.hpp"
#include "memory/genCollectedHeap.hpp"
#include "memory/heapInspection.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/os.hpp"
#include "utilities/globalDefinitions.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
// HeapInspection
@@ -41,12 +43,24 @@ int KlassInfoEntry::compare(KlassInfoEntry* e1, KlassInfoEntry* e2) {
} else if(e1->_instance_words < e2->_instance_words) {
return 1;
}
- return 0;
+ // Sort alphabetically, note 'Z' < '[' < 'a', but it's better to group
+ // the array classes before all the instance classes.
+ ResourceMark rm;
+ const char* name1 = e1->klass()->external_name();
+ const char* name2 = e2->klass()->external_name();
+ bool d1 = (name1[0] == '[');
+ bool d2 = (name2[0] == '[');
+ if (d1 && !d2) {
+ return -1;
+ } else if (d2 && !d1) {
+ return 1;
+ } else {
+ return strcmp(name1, name2);
+ }
}
-void KlassInfoEntry::print_on(outputStream* st) const {
- ResourceMark rm;
- const char* name;;
+const char* KlassInfoEntry::name() const {
+ const char* name;
if (_klass->name() != NULL) {
name = _klass->external_name();
} else {
@@ -60,11 +74,17 @@ void KlassInfoEntry::print_on(outputStream* st) const {
if (_klass == Universe::longArrayKlassObj()) name = "<longArrayKlass>"; else
name = "<no name>";
}
+ return name;
+}
+
+void KlassInfoEntry::print_on(outputStream* st) const {
+ ResourceMark rm;
+
// simplify the formatting (ILP32 vs LP64) - always cast the numbers to 64-bit
st->print_cr(INT64_FORMAT_W(13) " " UINT64_FORMAT_W(13) " %s",
(jlong) _instance_count,
(julong) _instance_words * HeapWordSize,
- name);
+ name());
}
KlassInfoEntry* KlassInfoBucket::lookup(Klass* const k) {
@@ -101,7 +121,14 @@ void KlassInfoBucket::empty() {
}
}
-KlassInfoTable::KlassInfoTable(int size, HeapWord* ref) {
+void KlassInfoTable::AllClassesFinder::do_klass(Klass* k) {
+ // This has the SIDE EFFECT of creating a KlassInfoEntry
+ // for <k>, if one doesn't exist yet.
+ _table->lookup(k);
+}
+
+KlassInfoTable::KlassInfoTable(int size, HeapWord* ref,
+ bool need_class_stats) {
_size = 0;
_ref = ref;
_buckets = NEW_C_HEAP_ARRAY(KlassInfoBucket, size, mtInternal);
@@ -110,6 +137,10 @@ KlassInfoTable::KlassInfoTable(int size, HeapWord* ref) {
for (int index = 0; index < _size; index++) {
_buckets[index].initialize();
}
+ if (need_class_stats) {
+ AllClassesFinder finder(this);
+ ClassLoaderDataGraph::classes_do(&finder);
+ }
}
}
@@ -165,7 +196,8 @@ int KlassInfoHisto::sort_helper(KlassInfoEntry** e1, KlassInfoEntry** e2) {
return (*e1)->compare(*e1,*e2);
}
-KlassInfoHisto::KlassInfoHisto(const char* title, int estimatedCount) :
+KlassInfoHisto::KlassInfoHisto(KlassInfoTable* cit, const char* title, int estimatedCount) :
+ _cit(cit),
_title(title) {
_elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<KlassInfoEntry*>(estimatedCount,true);
}
@@ -196,9 +228,205 @@ void KlassInfoHisto::print_elements(outputStream* st) const {
total, totalw * HeapWordSize);
}
-void KlassInfoHisto::print_on(outputStream* st) const {
- st->print_cr("%s",title());
- print_elements(st);
+#define MAKE_COL_NAME(field, name, help) #name,
+#define MAKE_COL_HELP(field, name, help) help,
+
+static const char *name_table[] = {
+ HEAP_INSPECTION_COLUMNS_DO(MAKE_COL_NAME)
+};
+
+static const char *help_table[] = {
+ HEAP_INSPECTION_COLUMNS_DO(MAKE_COL_HELP)
+};
+
+bool KlassInfoHisto::is_selected(const char *col_name) {
+ if (_selected_columns == NULL) {
+ return true;
+ }
+ if (strcmp(_selected_columns, col_name) == 0) {
+ return true;
+ }
+
+ const char *start = strstr(_selected_columns, col_name);
+ if (start == NULL) {
+ return false;
+ }
+
+ // The following must be true, because _selected_columns != col_name
+ if (start > _selected_columns && start[-1] != ',') {
+ return false;
+ }
+ char x = start[strlen(col_name)];
+ if (x != ',' && x != '\0') {
+ return false;
+ }
+
+ return true;
+}
+
+void KlassInfoHisto::print_title(outputStream* st, bool csv_format,
+ bool selected[], int width_table[],
+ const char *name_table[]) {
+ if (csv_format) {
+ st->print("Index,Super");
+ for (int c=0; c<KlassSizeStats::_num_columns; c++) {
+ if (selected[c]) {st->print(",%s", name_table[c]);}
+ }
+ st->print(",ClassName");
+ } else {
+ st->print("Index Super");
+ for (int c=0; c<KlassSizeStats::_num_columns; c++) {
+ if (selected[c]) {st->print(str_fmt(width_table[c]), name_table[c]);}
+ }
+ st->print(" ClassName");
+ }
+
+ if (is_selected("ClassLoader")) {
+ st->print(",ClassLoader");
+ }
+ st->cr();
+}
+
+void KlassInfoHisto::print_class_stats(outputStream* st,
+ bool csv_format, const char *columns) {
+ ResourceMark rm;
+ KlassSizeStats sz, sz_sum;
+ int i;
+ julong *col_table = (julong*)(&sz);
+ julong *colsum_table = (julong*)(&sz_sum);
+ int width_table[KlassSizeStats::_num_columns];
+ bool selected[KlassSizeStats::_num_columns];
+
+ _selected_columns = columns;
+
+ memset(&sz_sum, 0, sizeof(sz_sum));
+ for (int c=0; c<KlassSizeStats::_num_columns; c++) {
+ selected[c] = is_selected(name_table[c]);
+ }
+
+ for(i=0; i < elements()->length(); i++) {
+ elements()->at(i)->set_index(i+1);
+ }
+
+ for (int pass=1; pass<=2; pass++) {
+ if (pass == 2) {
+ print_title(st, csv_format, selected, width_table, name_table);
+ }
+ for(i=0; i < elements()->length(); i++) {
+ KlassInfoEntry* e = (KlassInfoEntry*)elements()->at(i);
+ const Klass* k = e->klass();
+
+ memset(&sz, 0, sizeof(sz));
+ sz._inst_count = e->count();
+ sz._inst_bytes = HeapWordSize * e->words();
+ k->collect_statistics(&sz);
+ sz._total_bytes = sz._ro_bytes + sz._rw_bytes;
+
+ if (pass == 1) {
+ for (int c=0; c<KlassSizeStats::_num_columns; c++) {
+ colsum_table[c] += col_table[c];
+ }
+ } else {
+ int super_index = -1;
+ if (k->oop_is_instance()) {
+ Klass* super = ((InstanceKlass*)k)->java_super();
+ if (super) {
+ KlassInfoEntry* super_e = _cit->lookup(super);
+ if (super_e) {
+ super_index = super_e->index();
+ }
+ }
+ }
+
+ if (csv_format) {
+ st->print("%d,%d", e->index(), super_index);
+ for (int c=0; c<KlassSizeStats::_num_columns; c++) {
+ if (selected[c]) {st->print("," JULONG_FORMAT, col_table[c]);}
+ }
+ st->print(",%s",e->name());
+ } else {
+ st->print("%5d %5d", e->index(), super_index);
+ for (int c=0; c<KlassSizeStats::_num_columns; c++) {
+ if (selected[c]) {print_julong(st, width_table[c], col_table[c]);}
+ }
+ st->print(" %s", e->name());
+ }
+ if (is_selected("ClassLoader")) {
+ ClassLoaderData* loader_data = k->class_loader_data();
+ st->print(",");
+ loader_data->print_value_on(st);
+ }
+ st->cr();
+ }
+ }
+
+ if (pass == 1) {
+ for (int c=0; c<KlassSizeStats::_num_columns; c++) {
+ width_table[c] = col_width(colsum_table[c], name_table[c]);
+ }
+ }
+ }
+
+ sz_sum._inst_size = 0;
+
+ if (csv_format) {
+ st->print(",");
+ for (int c=0; c<KlassSizeStats::_num_columns; c++) {
+ if (selected[c]) {st->print("," JULONG_FORMAT, colsum_table[c]);}
+ }
+ } else {
+ st->print(" ");
+ for (int c=0; c<KlassSizeStats::_num_columns; c++) {
+ if (selected[c]) {print_julong(st, width_table[c], colsum_table[c]);}
+ }
+ st->print(" Total");
+ if (sz_sum._total_bytes > 0) {
+ st->cr();
+ st->print(" ");
+ for (int c=0; c<KlassSizeStats::_num_columns; c++) {
+ if (selected[c]) {
+ switch (c) {
+ case KlassSizeStats::_index_inst_size:
+ case KlassSizeStats::_index_inst_count:
+ case KlassSizeStats::_index_method_count:
+ st->print(str_fmt(width_table[c]), "-");
+ break;
+ default:
+ {
+ double perc = (double)(100) * (double)(colsum_table[c]) / (double)sz_sum._total_bytes;
+ st->print(perc_fmt(width_table[c]), perc);
+ }
+ }
+ }
+ }
+ }
+ }
+ st->cr();
+
+ if (!csv_format) {
+ print_title(st, csv_format, selected, width_table, name_table);
+ }
+}
+
+julong KlassInfoHisto::annotations_bytes(Array<AnnotationArray*>* p) const {
+ julong bytes = 0;
+ if (p != NULL) {
+ for (int i = 0; i < p->length(); i++) {
+ bytes += count_bytes_array(p->at(i));
+ }
+ bytes += count_bytes_array(p);
+ }
+ return bytes;
+}
+
+void KlassInfoHisto::print_histo_on(outputStream* st, bool print_stats,
+ bool csv_format, const char *columns) {
+ if (print_stats) {
+ print_class_stats(st, csv_format, columns);
+ } else {
+ st->print_cr("%s",title());
+ print_elements(st);
+ }
}
class HistoClosure : public KlassInfoClosure {
@@ -236,8 +464,26 @@ void HeapInspection::heap_inspection(outputStream* st, bool need_prologue) {
CollectedHeap* heap = Universe::heap();
bool is_shared_heap = false;
+ if (_print_help) {
+ for (int c=0; c<KlassSizeStats::_num_columns; c++) {
+ st->print("%s:\n\t", name_table[c]);
+ const int max_col = 60;
+ int col = 0;
+ for (const char *p = help_table[c]; *p; p++,col++) {
+ if (col >= max_col && *p == ' ') {
+ st->print("\n\t");
+ col = 0;
+ } else {
+ st->print("%c", *p);
+ }
+ }
+ st->print_cr(".\n");
+ }
+ return;
+ }
+
// Collect klass instance info
- KlassInfoTable cit(KlassInfoTable::cit_size, ref);
+ KlassInfoTable cit(KlassInfoTable::cit_size, ref, _print_class_stats);
if (!cit.allocation_failed()) {
// Iterate over objects in the heap
RecordInstanceClosure ric(&cit);
@@ -252,14 +498,14 @@ void HeapInspection::heap_inspection(outputStream* st, bool need_prologue) {
missed_count);
}
// Sort and print klass instance info
- KlassInfoHisto histo("\n"
- " num #instances #bytes class name\n"
- "----------------------------------------------",
- KlassInfoHisto::histo_initial_size);
+ const char *title = "\n"
+ " num #instances #bytes class name\n"
+ "----------------------------------------------";
+ KlassInfoHisto histo(&cit, title, KlassInfoHisto::histo_initial_size);
HistoClosure hc(&histo);
cit.iterate(&hc);
histo.sort();
- histo.print_on(st);
+ histo.print_histo_on(st, _print_class_stats, _csv_format, _columns);
} else {
st->print_cr("WARNING: Ran out of C-heap; histogram not generated");
}
diff --git a/src/share/vm/memory/heapInspection.hpp b/src/share/vm/memory/heapInspection.hpp
index 72e675850..c080cb842 100644
--- a/src/share/vm/memory/heapInspection.hpp
+++ b/src/share/vm/memory/heapInspection.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -27,6 +27,8 @@
#include "memory/allocation.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/annotations.hpp"
+#include "utilities/macros.hpp"
#if INCLUDE_SERVICES
@@ -44,16 +46,144 @@
// to KlassInfoEntry's and is used to sort
// the entries.
+#define HEAP_INSPECTION_COLUMNS_DO(f) \
+ f(inst_size, InstSize, \
+ "Size of each object instance of the Java class") \
+ f(inst_count, InstCount, \
+ "Number of object instances of the Java class") \
+ f(inst_bytes, InstBytes, \
+ "This is usually (InstSize * InstNum). The only exception is " \
+ "java.lang.Class, whose InstBytes also includes the slots " \
+ "used to store static fields. InstBytes is not counted in " \
+ "ROAll, RWAll or Total") \
+ f(mirror_bytes, Mirror, \
+ "Size of the Klass::java_mirror() object") \
+ f(klass_bytes, KlassBytes, \
+ "Size of the InstanceKlass or ArrayKlass for this class. " \
+ "Note that this includes VTab, ITab, OopMap") \
+ f(secondary_supers_bytes, K_secondary_supers, \
+ "Number of bytes used by the Klass::secondary_supers() array") \
+ f(vtab_bytes, VTab, \
+ "Size of the embedded vtable in InstanceKlass") \
+ f(itab_bytes, ITab, \
+ "Size of the embedded itable in InstanceKlass") \
+ f(nonstatic_oopmap_bytes, OopMap, \
+ "Size of the embedded nonstatic_oop_map in InstanceKlass") \
+ f(methods_array_bytes, IK_methods, \
+ "Number of bytes used by the InstanceKlass::methods() array") \
+ f(method_ordering_bytes, IK_method_ordering, \
+ "Number of bytes used by the InstanceKlass::method_ordering() array") \
+ f(local_interfaces_bytes, IK_local_interfaces, \
+ "Number of bytes used by the InstanceKlass::local_interfaces() array") \
+ f(transitive_interfaces_bytes, IK_transitive_interfaces, \
+ "Number of bytes used by the InstanceKlass::transitive_interfaces() array") \
+ f(fields_bytes, IK_fields, \
+ "Number of bytes used by the InstanceKlass::fields() array") \
+ f(inner_classes_bytes, IK_inner_classes, \
+ "Number of bytes used by the InstanceKlass::inner_classes() array") \
+ f(signers_bytes, IK_signers, \
+ "Number of bytes used by the InstanceKlass::singers() array") \
+ f(class_annotations_bytes, class_annotations, \
+ "Size of class annotations") \
+ f(fields_annotations_bytes, fields_annotations, \
+ "Size of field annotations") \
+ f(methods_annotations_bytes, methods_annotations, \
+ "Size of method annotations") \
+ f(methods_parameter_annotations_bytes, methods_parameter_annotations, \
+ "Size of method parameter annotations") \
+ f(methods_default_annotations_bytes, methods_default_annotations, \
+ "Size of methods default annotations") \
+ f(type_annotations_bytes, type_annotations, \
+ "Size of type annotations") \
+ f(annotations_bytes, annotations, \
+ "Size of all annotations") \
+ f(cp_bytes, Cp, \
+ "Size of InstanceKlass::constants()") \
+ f(cp_tags_bytes, CpTags, \
+ "Size of InstanceKlass::constants()->tags()") \
+ f(cp_cache_bytes, CpCache, \
+ "Size of InstanceKlass::constants()->cache()") \
+ f(cp_operands_bytes, CpOperands, \
+ "Size of InstanceKlass::constants()->operands()") \
+ f(cp_refmap_bytes, CpRefMap, \
+ "Size of InstanceKlass::constants()->reference_map()") \
+ f(cp_all_bytes, CpAll, \
+ "Sum of Cp + CpTags + CpCache + CpOperands + CpRefMap") \
+ f(method_count, MethodCount, \
+ "Number of methods in this class") \
+ f(method_bytes, MethodBytes, \
+ "Size of the Method object") \
+ f(const_method_bytes, ConstMethod, \
+ "Size of the ConstMethod object") \
+ f(method_data_bytes, MethodData, \
+ "Size of the MethodData object") \
+ f(stackmap_bytes, StackMap, \
+ "Size of the stackmap_data") \
+ f(bytecode_bytes, Bytecodes, \
+ "Of the MethodBytes column, how much are the space taken up by bytecodes") \
+ f(method_all_bytes, MethodAll, \
+ "Sum of MethodBytes + Constmethod + Stackmap + Methoddata") \
+ f(ro_bytes, ROAll, \
+ "Size of all class meta data that could (potentially) be placed " \
+ "in read-only memory. (This could change with CDS design)") \
+ f(rw_bytes, RWAll, \
+ "Size of all class meta data that must be placed in read/write " \
+ "memory. (This could change with CDS design) ") \
+ f(total_bytes, Total, \
+ "ROAll + RWAll. Note that this does NOT include InstBytes.")
+
+// Size statistics for a Klass - filled in by Klass::collect_statistics()
+class KlassSizeStats {
+public:
+#define COUNT_KLASS_SIZE_STATS_FIELD(field, name, help) _index_ ## field,
+#define DECLARE_KLASS_SIZE_STATS_FIELD(field, name, help) julong _ ## field;
+
+ enum {
+ HEAP_INSPECTION_COLUMNS_DO(COUNT_KLASS_SIZE_STATS_FIELD)
+ _num_columns
+ };
+
+ HEAP_INSPECTION_COLUMNS_DO(DECLARE_KLASS_SIZE_STATS_FIELD)
+
+ static int count(oop x) {
+ return (HeapWordSize * ((x) ? (x)->size() : 0));
+ }
+
+ static int count_array(objArrayOop x) {
+ return (HeapWordSize * ((x) ? (x)->size() : 0));
+ }
+
+ template <class T> static int count(T* x) {
+ return (HeapWordSize * ((x) ? (x)->size() : 0));
+ }
+
+ template <class T> static int count_array(T* x) {
+ if (x == NULL) {
+ return 0;
+ }
+ if (x->length() == 0) {
+ // This is a shared array, e.g., Universe::the_empty_int_array(). Don't
+ // count it to avoid double-counting.
+ return 0;
+ }
+ return HeapWordSize * x->size();
+ }
+};
+
+
+
+
class KlassInfoEntry: public CHeapObj<mtInternal> {
private:
KlassInfoEntry* _next;
Klass* _klass;
long _instance_count;
size_t _instance_words;
+ long _index;
public:
KlassInfoEntry(Klass* k, KlassInfoEntry* next) :
- _klass(k), _instance_count(0), _instance_words(0), _next(next)
+ _klass(k), _instance_count(0), _instance_words(0), _next(next), _index(-1)
{}
KlassInfoEntry* next() { return _next; }
bool is_equal(Klass* k) { return k == _klass; }
@@ -62,8 +192,11 @@ class KlassInfoEntry: public CHeapObj<mtInternal> {
void set_count(long ct) { _instance_count = ct; }
size_t words() { return _instance_words; }
void set_words(size_t wds) { _instance_words = wds; }
+ void set_index(long index) { _index = index; }
+ long index() { return _index; }
int compare(KlassInfoEntry* e1, KlassInfoEntry* e2);
void print_on(outputStream* st) const;
+ const char* name() const;
};
class KlassInfoClosure: public StackObj {
@@ -95,45 +228,132 @@ class KlassInfoTable: public StackObj {
KlassInfoBucket* _buckets;
uint hash(Klass* p);
- KlassInfoEntry* lookup(Klass* const k);
+ KlassInfoEntry* lookup(Klass* const k); // allocates if not found!
+
+ class AllClassesFinder : public KlassClosure {
+ KlassInfoTable *_table;
+ public:
+ AllClassesFinder(KlassInfoTable* table) : _table(table) {}
+ virtual void do_klass(Klass* k);
+ };
public:
// Table size
enum {
cit_size = 20011
};
- KlassInfoTable(int size, HeapWord* ref);
+ KlassInfoTable(int size, HeapWord* ref, bool need_class_stats);
~KlassInfoTable();
bool record_instance(const oop obj);
void iterate(KlassInfoClosure* cic);
bool allocation_failed() { return _buckets == NULL; }
+
+ friend class KlassInfoHisto;
};
class KlassInfoHisto : public StackObj {
private:
+ KlassInfoTable *_cit;
GrowableArray<KlassInfoEntry*>* _elements;
GrowableArray<KlassInfoEntry*>* elements() const { return _elements; }
const char* _title;
const char* title() const { return _title; }
static int sort_helper(KlassInfoEntry** e1, KlassInfoEntry** e2);
void print_elements(outputStream* st) const;
+ void print_class_stats(outputStream* st, bool csv_format, const char *columns);
+ julong annotations_bytes(Array<AnnotationArray*>* p) const;
+ const char *_selected_columns;
+ bool is_selected(const char *col_name);
+ void print_title(outputStream* st, bool csv_format,
+ bool selected_columns_table[], int width_table[],
+ const char *name_table[]);
+
+ template <class T> static int count_bytes(T* x) {
+ return (HeapWordSize * ((x) ? (x)->size() : 0));
+ }
+
+ template <class T> static int count_bytes_array(T* x) {
+ if (x == NULL) {
+ return 0;
+ }
+ if (x->length() == 0) {
+ // This is a shared array, e.g., Universe::the_empty_int_array(). Don't
+ // count it to avoid double-counting.
+ return 0;
+ }
+ return HeapWordSize * x->size();
+ }
+
+ // returns a format string to print a julong with the given width. E.g,
+ // printf(num_fmt(6), julong(10)) would print out the number 10 with 4
+ // leading spaces.
+ static void print_julong(outputStream* st, int width, julong n) {
+ int num_spaces = width - julong_width(n);
+ if (num_spaces > 0) {
+ st->print(str_fmt(num_spaces), "");
+ }
+ st->print(JULONG_FORMAT, n);
+ }
+
+ static char* perc_fmt(int width) {
+ static char buf[32];
+ jio_snprintf(buf, sizeof(buf), "%%%d.1f%%%%", width-1);
+ return buf;
+ }
+
+ static char* str_fmt(int width) {
+ static char buf[32];
+ jio_snprintf(buf, sizeof(buf), "%%%ds", width);
+ return buf;
+ }
+
+ static int julong_width(julong n) {
+ if (n == 0) {
+ return 1;
+ }
+ int w = 0;
+ while (n > 0) {
+ n /= 10;
+ w += 1;
+ }
+ return w;
+ }
+
+ static int col_width(julong n, const char *name) {
+ int w = julong_width(n);
+ int min = (int)(strlen(name));
+ if (w < min) {
+ w = min;
+ }
+ // add a leading space for separation.
+ return w + 1;
+ }
+
public:
enum {
histo_initial_size = 1000
};
- KlassInfoHisto(const char* title,
+ KlassInfoHisto(KlassInfoTable* cit, const char* title,
int estimatedCount);
~KlassInfoHisto();
void add(KlassInfoEntry* cie);
- void print_on(outputStream* st) const;
+ void print_histo_on(outputStream* st, bool print_class_stats, bool csv_format, const char *columns);
void sort();
};
#endif // INCLUDE_SERVICES
-class HeapInspection : public AllStatic {
+class HeapInspection : public StackObj {
+ bool _csv_format; // "comma separated values" format for spreadsheet.
+ bool _print_help;
+ bool _print_class_stats;
+ const char* _columns;
public:
- static void heap_inspection(outputStream* st, bool need_prologue) NOT_SERVICES_RETURN;
+ HeapInspection(bool csv_format, bool print_help,
+ bool print_class_stats, const char *columns) :
+ _csv_format(csv_format), _print_help(print_help),
+ _print_class_stats(print_class_stats), _columns(columns) {}
+ void heap_inspection(outputStream* st, bool need_prologue) NOT_SERVICES_RETURN;
static void find_instances_at_safepoint(Klass* k, GrowableArray<oop>* result) NOT_SERVICES_RETURN;
};
diff --git a/src/share/vm/memory/metaspace.cpp b/src/share/vm/memory/metaspace.cpp
index f54803a19..c629e175f 100644
--- a/src/share/vm/memory/metaspace.cpp
+++ b/src/share/vm/memory/metaspace.cpp
@@ -1737,10 +1737,10 @@ void SpaceManager::get_initial_chunk_sizes(Metaspace::MetaspaceType type,
*class_chunk_word_size = ClassSmallChunk;
break;
}
- assert(chunk_word_size != 0 && class_chunk_word_size != 0,
+ assert(*chunk_word_size != 0 && *class_chunk_word_size != 0,
err_msg("Initial chunks sizes bad: data " SIZE_FORMAT
" class " SIZE_FORMAT,
- chunk_word_size, class_chunk_word_size));
+ *chunk_word_size, *class_chunk_word_size));
}
size_t SpaceManager::sum_free_in_chunks_in_use() const {
@@ -2040,7 +2040,7 @@ SpaceManager::~SpaceManager() {
align_size_up(humongous_chunks->word_size(),
HumongousChunkGranularity),
err_msg("Humongous chunk size is wrong: word size " SIZE_FORMAT
- " granularity " SIZE_FORMAT,
+ " granularity %d",
humongous_chunks->word_size(), HumongousChunkGranularity));
Metachunk* next_humongous_chunks = humongous_chunks->next();
chunk_manager->humongous_dictionary()->return_chunk(humongous_chunks);
@@ -2264,7 +2264,8 @@ void SpaceManager::verify_allocation_total() {
}
MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
assert(allocation_total() == sum_used_in_chunks_in_use(),
- err_msg("allocation total is not consistent %d vs %d",
+ err_msg("allocation total is not consistent " SIZE_FORMAT
+ " vs " SIZE_FORMAT,
allocation_total(), sum_used_in_chunks_in_use()));
}
@@ -2578,7 +2579,8 @@ void Metaspace::global_initialize() {
// argument passed in is at the top of the compressed space
void Metaspace::initialize_class_space(ReservedSpace rs) {
// The reserved space size may be bigger because of alignment, esp with UseLargePages
- assert(rs.size() >= ClassMetaspaceSize, err_msg("%d != %d", rs.size(), ClassMetaspaceSize));
+ assert(rs.size() >= ClassMetaspaceSize,
+ err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), ClassMetaspaceSize));
_class_space_list = new VirtualSpaceList(rs);
}
diff --git a/src/share/vm/memory/space.cpp b/src/share/vm/memory/space.cpp
index ca3882df0..7eb462ecc 100644
--- a/src/share/vm/memory/space.cpp
+++ b/src/share/vm/memory/space.cpp
@@ -40,6 +40,7 @@
#include "runtime/safepoint.hpp"
#include "utilities/copy.hpp"
#include "utilities/globalDefinitions.hpp"
+#include "utilities/macros.hpp"
void SpaceMemRegionOopsIterClosure::do_oop(oop* p) { SpaceMemRegionOopsIterClosure::do_oop_work(p); }
void SpaceMemRegionOopsIterClosure::do_oop(narrowOop* p) { SpaceMemRegionOopsIterClosure::do_oop_work(p); }
@@ -658,7 +659,7 @@ void ContiguousSpace::object_iterate_mem(MemRegion mr, UpwardsObjectClosure* cl)
}
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#define ContigSpace_PAR_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \
\
void ContiguousSpace::par_oop_iterate(MemRegion mr, OopClosureType* blk) {\
@@ -673,7 +674,7 @@ void ContiguousSpace::object_iterate_mem(MemRegion mr, UpwardsObjectClosure* cl)
ALL_PAR_OOP_ITERATE_CLOSURES(ContigSpace_PAR_OOP_ITERATE_DEFN)
#undef ContigSpace_PAR_OOP_ITERATE_DEFN
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
void ContiguousSpace::oop_iterate(ExtendedOopClosure* blk) {
if (is_empty()) return;
diff --git a/src/share/vm/memory/space.hpp b/src/share/vm/memory/space.hpp
index 1dade4a26..a434b0a33 100644
--- a/src/share/vm/memory/space.hpp
+++ b/src/share/vm/memory/space.hpp
@@ -34,6 +34,7 @@
#include "oops/markOop.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/prefetch.hpp"
+#include "utilities/macros.hpp"
#include "utilities/workgroup.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
@@ -884,14 +885,14 @@ class ContiguousSpace: public CompactibleSpace {
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// In support of parallel oop_iterate.
#define ContigSpace_PAR_OOP_ITERATE_DECL(OopClosureType, nv_suffix) \
void par_oop_iterate(MemRegion mr, OopClosureType* blk);
ALL_PAR_OOP_ITERATE_CLOSURES(ContigSpace_PAR_OOP_ITERATE_DECL)
#undef ContigSpace_PAR_OOP_ITERATE_DECL
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
// Compaction support
virtual void reset_after_compaction() {
diff --git a/src/share/vm/memory/specialized_oop_closures.hpp b/src/share/vm/memory/specialized_oop_closures.hpp
index a13660d40..2aed587f0 100644
--- a/src/share/vm/memory/specialized_oop_closures.hpp
+++ b/src/share/vm/memory/specialized_oop_closures.hpp
@@ -26,9 +26,10 @@
#define SHARE_VM_MEMORY_SPECIALIZED_OOP_CLOSURES_HPP
#include "runtime/atomic.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/g1_specialized_oop_closures.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
// The following OopClosure types get specialized versions of
// "oop_oop_iterate" that invoke the closures' do_oop methods
@@ -80,20 +81,20 @@ class NoHeaderExtendedOopClosure;
f(FastScanClosure,_nv) \
f(FilteringClosure,_nv)
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_P(f) \
f(ParScanWithBarrierClosure,_nv) \
f(ParScanWithoutBarrierClosure,_nv)
-#else // SERIALGC
+#else // INCLUDE_ALL_GCS
#define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_P(f)
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
#define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_1(f) \
f(NoHeaderExtendedOopClosure,_nv) \
SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_S(f) \
SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_P(f)
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(f) \
f(MarkRefsIntoAndScanClosure,_nv) \
f(Par_MarkRefsIntoAndScanClosure,_nv) \
@@ -104,9 +105,9 @@ class NoHeaderExtendedOopClosure;
f(CMSKeepAliveClosure,_nv) \
f(CMSInnerParMarkAndPushClosure,_nv) \
FURTHER_SPECIALIZED_OOP_OOP_ITERATE_CLOSURES(f)
-#else // SERIALGC
+#else // INCLUDE_ALL_GCS
#define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(f)
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
// We separate these out, because sometime the general one has
@@ -120,7 +121,7 @@ class NoHeaderExtendedOopClosure;
#define ALL_OOP_OOP_ITERATE_CLOSURES_2(f) \
SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(f)
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// This macro applies an argument macro to all OopClosures for which we
// want specialized bodies of a family of methods related to
// "par_oop_iterate". The arguments to f are the same as above.
@@ -136,7 +137,7 @@ class NoHeaderExtendedOopClosure;
#define ALL_PAR_OOP_ITERATE_CLOSURES(f) \
f(ExtendedOopClosure,_v) \
SPECIALIZED_PAR_OOP_ITERATE_CLOSURES(f)
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
// This macro applies an argument macro to all OopClosures for which we
// want specialized bodies of a family of methods related to
@@ -155,14 +156,14 @@ class NoHeaderExtendedOopClosure;
f(ScanClosure,_nv) \
f(FastScanClosure,_nv)
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#define SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG_P(f) \
f(ParScanWithBarrierClosure,_nv) \
f(ParScanWithoutBarrierClosure,_nv) \
FURTHER_SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(f)
-#else // SERIALGC
+#else // INCLUDE_ALL_GCS
#define SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG_P(f)
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
#define SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG(f) \
SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG_S(f) \
diff --git a/src/share/vm/memory/tenuredGeneration.cpp b/src/share/vm/memory/tenuredGeneration.cpp
index f47ea307d..1e15d6550 100644
--- a/src/share/vm/memory/tenuredGeneration.cpp
+++ b/src/share/vm/memory/tenuredGeneration.cpp
@@ -33,6 +33,7 @@
#include "memory/tenuredGeneration.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/java.hpp"
+#include "utilities/macros.hpp"
TenuredGeneration::TenuredGeneration(ReservedSpace rs,
size_t initial_byte_size, int level,
@@ -61,7 +62,7 @@ TenuredGeneration::TenuredGeneration(ReservedSpace rs,
_space_counters = new CSpaceCounters(gen_name, 0,
_virtual_space.reserved_size(),
_the_space, _gen_counters);
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
if (UseParNewGC) {
typedef ParGCAllocBufferWithBOT* ParGCAllocBufferWithBOTPtr;
_alloc_buffers = NEW_C_HEAP_ARRAY(ParGCAllocBufferWithBOTPtr,
@@ -77,7 +78,7 @@ TenuredGeneration::TenuredGeneration(ReservedSpace rs,
} else {
_alloc_buffers = NULL;
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
}
@@ -339,7 +340,7 @@ void TenuredGeneration::update_counters() {
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
oop TenuredGeneration::par_promote(int thread_num,
oop old, markOop m, size_t word_sz) {
@@ -423,10 +424,10 @@ void TenuredGeneration::verify_alloc_buffers_clean() {
}
}
-#else // SERIALGC
+#else // INCLUDE_ALL_GCS
void TenuredGeneration::retire_alloc_buffers_before_full_gc() {}
void TenuredGeneration::verify_alloc_buffers_clean() {}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
bool TenuredGeneration::promotion_attempt_is_safe(size_t max_promotion_in_bytes) const {
size_t available = max_contiguous_available();
diff --git a/src/share/vm/memory/tenuredGeneration.hpp b/src/share/vm/memory/tenuredGeneration.hpp
index 3a1541e79..b948a1b0b 100644
--- a/src/share/vm/memory/tenuredGeneration.hpp
+++ b/src/share/vm/memory/tenuredGeneration.hpp
@@ -29,6 +29,7 @@
#include "gc_implementation/shared/gcStats.hpp"
#include "gc_implementation/shared/generationCounters.hpp"
#include "memory/generation.hpp"
+#include "utilities/macros.hpp"
// TenuredGeneration models the heap containing old (promoted/tenured) objects.
@@ -45,11 +46,11 @@ class TenuredGeneration: public OneContigSpaceCardGeneration {
size_t _capacity_at_prologue;
size_t _used_at_prologue;
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// To support parallel promotion: an array of parallel allocation
// buffers, one per thread, initially NULL.
ParGCAllocBufferWithBOT** _alloc_buffers;
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
// Retire all alloc buffers before a full GC, so that they will be
// re-allocated at the start of the next young GC.
@@ -93,14 +94,14 @@ class TenuredGeneration: public OneContigSpaceCardGeneration {
size_t size,
bool is_tlab);
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// Overrides.
virtual oop par_promote(int thread_num,
oop obj, markOop m, size_t word_sz);
virtual void par_promote_alloc_undo(int thread_num,
HeapWord* obj, size_t word_sz);
virtual void par_promote_alloc_done(int thread_num);
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
// Performance Counter support
void update_counters();
diff --git a/src/share/vm/memory/universe.cpp b/src/share/vm/memory/universe.cpp
index c9199228c..a7a6c24bf 100644
--- a/src/share/vm/memory/universe.cpp
+++ b/src/share/vm/memory/universe.cpp
@@ -70,13 +70,14 @@
#include "utilities/events.hpp"
#include "utilities/hashtable.inline.hpp"
#include "utilities/preserveException.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp"
#include "gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1CollectorPolicy.hpp"
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
// Known objects
Klass* Universe::_boolArrayKlassObj = NULL;
@@ -144,6 +145,7 @@ NarrowPtrStruct Universe::_narrow_oop = { NULL, 0, true };
NarrowPtrStruct Universe::_narrow_klass = { NULL, 0, true };
address Universe::_narrow_ptrs_base;
+size_t Universe::_class_metaspace_size;
void Universe::basic_type_classes_do(void f(Klass*)) {
f(boolArrayKlassObj());
@@ -689,8 +691,15 @@ char* Universe::preferred_heap_base(size_t heap_size, NARROW_OOP_MODE mode) {
// Return specified base for the first request.
if (!FLAG_IS_DEFAULT(HeapBaseMinAddress) && (mode == UnscaledNarrowOop)) {
base = HeapBaseMinAddress;
- } else if (total_size <= OopEncodingHeapMax && (mode != HeapBasedNarrowOop)) {
- if (total_size <= NarrowOopHeapMax && (mode == UnscaledNarrowOop) &&
+
+ // If the total size and the metaspace size are small enough to allow
+ // UnscaledNarrowOop then just use UnscaledNarrowOop.
+ } else if ((total_size <= OopEncodingHeapMax) && (mode != HeapBasedNarrowOop) &&
+ (!UseCompressedKlassPointers ||
+ (((OopEncodingHeapMax - heap_size) + Universe::class_metaspace_size()) <= KlassEncodingMetaspaceMax))) {
+ // We don't need to check the metaspace size here because it is always smaller
+ // than total_size.
+ if ((total_size <= NarrowOopHeapMax) && (mode == UnscaledNarrowOop) &&
(Universe::narrow_oop_shift() == 0)) {
// Use 32-bits oops without encoding and
// place heap's top on the 4Gb boundary
@@ -706,14 +715,24 @@ char* Universe::preferred_heap_base(size_t heap_size, NARROW_OOP_MODE mode) {
base = (OopEncodingHeapMax - heap_size);
}
}
+
+ // See if ZeroBaseNarrowOop encoding will work for a heap based at
+ // (KlassEncodingMetaspaceMax - class_metaspace_size()).
+ } else if (UseCompressedKlassPointers && (mode != HeapBasedNarrowOop) &&
+ (Universe::class_metaspace_size() + HeapBaseMinAddress <= KlassEncodingMetaspaceMax) &&
+ (KlassEncodingMetaspaceMax + heap_size - Universe::class_metaspace_size() <= OopEncodingHeapMax)) {
+ base = (KlassEncodingMetaspaceMax - Universe::class_metaspace_size());
} else {
- // Can't reserve below 32Gb.
+ // UnscaledNarrowOop encoding didn't work, and no base was found for ZeroBasedOops or
+ // HeapBasedNarrowOop encoding was requested. So, can't reserve below 32Gb.
Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
}
+
// Set narrow_oop_base and narrow_oop_use_implicit_null_checks
// used in ReservedHeapSpace() constructors.
// The final values will be set in initialize_heap() below.
- if (base != 0 && (base + heap_size) <= OopEncodingHeapMax) {
+ if ((base != 0) && ((base + heap_size) <= OopEncodingHeapMax) &&
+ (!UseCompressedKlassPointers || (base + Universe::class_metaspace_size()) <= KlassEncodingMetaspaceMax)) {
// Use zero based compressed oops
Universe::set_narrow_oop_base(NULL);
// Don't need guard page for implicit checks in indexed
@@ -740,20 +759,20 @@ char* Universe::preferred_heap_base(size_t heap_size, NARROW_OOP_MODE mode) {
jint Universe::initialize_heap() {
if (UseParallelGC) {
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
Universe::_collectedHeap = new ParallelScavengeHeap();
-#else // SERIALGC
+#else // INCLUDE_ALL_GCS
fatal("UseParallelGC not supported in this VM.");
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
} else if (UseG1GC) {
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
G1CollectorPolicy* g1p = new G1CollectorPolicy();
G1CollectedHeap* g1h = new G1CollectedHeap(g1p);
Universe::_collectedHeap = g1h;
-#else // SERIALGC
+#else // INCLUDE_ALL_GCS
fatal("UseG1GC not supported in java kernel vm.");
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
} else {
GenCollectorPolicy *gc_policy;
@@ -761,15 +780,15 @@ jint Universe::initialize_heap() {
if (UseSerialGC) {
gc_policy = new MarkSweepPolicy();
} else if (UseConcMarkSweepGC) {
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
if (UseAdaptiveSizePolicy) {
gc_policy = new ASConcurrentMarkSweepPolicy();
} else {
gc_policy = new ConcurrentMarkSweepPolicy();
}
-#else // SERIALGC
+#else // INCLUDE_ALL_GCS
fatal("UseConcMarkSweepGC not supported in this VM.");
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
} else { // default old generation
gc_policy = new MarkSweepPolicy();
}
@@ -796,7 +815,9 @@ jint Universe::initialize_heap() {
tty->print("heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB",
Universe::heap()->base(), Universe::heap()->reserved_region().byte_size()/M);
}
- if ((uint64_t)Universe::heap()->reserved_region().end() > OopEncodingHeapMax) {
+ if (((uint64_t)Universe::heap()->reserved_region().end() > OopEncodingHeapMax) ||
+ (UseCompressedKlassPointers &&
+ ((uint64_t)Universe::heap()->base() + Universe::class_metaspace_size() > KlassEncodingMetaspaceMax))) {
// Can't reserve heap below 32Gb.
// keep the Universe::narrow_oop_base() set in Universe::reserve_heap()
Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
@@ -862,8 +883,8 @@ ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) {
// be compressed the same as instances.
// Need to round class space size up because it's below the heap and
// the actual alignment depends on its size.
- size_t metaspace_size = align_size_up(ClassMetaspaceSize, alignment);
- size_t total_reserved = align_size_up(heap_size + metaspace_size, alignment);
+ Universe::set_class_metaspace_size(align_size_up(ClassMetaspaceSize, alignment));
+ size_t total_reserved = align_size_up(heap_size + Universe::class_metaspace_size(), alignment);
char* addr = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop);
ReservedHeapSpace total_rs(total_reserved, alignment, UseLargePages, addr);
@@ -904,8 +925,8 @@ ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) {
// compressed oops is greater than the one used for compressed klass
// ptrs, a metadata space on top of the heap could become
// unreachable.
- ReservedSpace class_rs = total_rs.first_part(metaspace_size);
- ReservedSpace heap_rs = total_rs.last_part(metaspace_size, alignment);
+ ReservedSpace class_rs = total_rs.first_part(Universe::class_metaspace_size());
+ ReservedSpace heap_rs = total_rs.last_part(Universe::class_metaspace_size(), alignment);
Metaspace::initialize_class_space(class_rs);
if (UseCompressedOops) {
diff --git a/src/share/vm/memory/universe.hpp b/src/share/vm/memory/universe.hpp
index ca7b09c7b..2bf0b653f 100644
--- a/src/share/vm/memory/universe.hpp
+++ b/src/share/vm/memory/universe.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -211,6 +211,9 @@ class Universe: AllStatic {
static struct NarrowPtrStruct _narrow_klass;
static address _narrow_ptrs_base;
+ // Aligned size of the metaspace.
+ static size_t _class_metaspace_size;
+
// array of dummy objects used with +FullGCAlot
debug_only(static objArrayOop _fullgc_alot_dummy_array;)
// index of next entry to clear
@@ -278,6 +281,13 @@ class Universe: AllStatic {
static bool reserve_metaspace_helper(bool with_base = false);
static ReservedHeapSpace reserve_heap_metaspace(size_t heap_size, size_t alignment, bool& contiguous);
+ static size_t class_metaspace_size() {
+ return _class_metaspace_size;
+ }
+ static void set_class_metaspace_size(size_t metaspace_size) {
+ _class_metaspace_size = metaspace_size;
+ }
+
// Debugging
static int _verify_count; // number of verifies done
// True during call to verify(). Should only be set/cleared in verify().
diff --git a/src/share/vm/oops/annotations.cpp b/src/share/vm/oops/annotations.cpp
index 72c5737f0..9e5d6ef37 100644
--- a/src/share/vm/oops/annotations.cpp
+++ b/src/share/vm/oops/annotations.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "classfile/classLoaderData.hpp"
+#include "memory/heapInspection.hpp"
#include "memory/metadataFactory.hpp"
#include "memory/oopFactory.hpp"
#include "oops/annotations.hpp"
@@ -114,6 +115,50 @@ void Annotations::print_value_on(outputStream* st) const {
st->print("Anotations(" INTPTR_FORMAT ")", this);
}
+#if INCLUDE_SERVICES
+// Size Statistics
+
+julong Annotations::count_bytes(Array<AnnotationArray*>* p) {
+ julong bytes = 0;
+ if (p != NULL) {
+ for (int i = 0; i < p->length(); i++) {
+ bytes += KlassSizeStats::count_array(p->at(i));
+ }
+ bytes += KlassSizeStats::count_array(p);
+ }
+ return bytes;
+}
+
+void Annotations::collect_statistics(KlassSizeStats *sz) const {
+ sz->_annotations_bytes = sz->count(this);
+ sz->_class_annotations_bytes = sz->count(class_annotations());
+ sz->_fields_annotations_bytes = count_bytes(fields_annotations());
+ sz->_methods_annotations_bytes = count_bytes(methods_annotations());
+ sz->_methods_parameter_annotations_bytes =
+ count_bytes(methods_parameter_annotations());
+ sz->_methods_default_annotations_bytes =
+ count_bytes(methods_default_annotations());
+
+ const Annotations* type_anno = type_annotations();
+ if (type_anno != NULL) {
+ sz->_type_annotations_bytes = sz->count(type_anno);
+ sz->_type_annotations_bytes += sz->count(type_anno->class_annotations());
+ sz->_type_annotations_bytes += count_bytes(type_anno->fields_annotations());
+ sz->_type_annotations_bytes += count_bytes(type_anno->methods_annotations());
+ }
+
+ sz->_annotations_bytes +=
+ sz->_class_annotations_bytes +
+ sz->_fields_annotations_bytes +
+ sz->_methods_annotations_bytes +
+ sz->_methods_parameter_annotations_bytes +
+ sz->_methods_default_annotations_bytes +
+ sz->_type_annotations_bytes;
+
+ sz->_ro_bytes += sz->_annotations_bytes;
+}
+#endif // INCLUDE_SERVICES
+
#define BULLET " - "
#ifndef PRODUCT
diff --git a/src/share/vm/oops/annotations.hpp b/src/share/vm/oops/annotations.hpp
index 07d05467b..82d701ac5 100644
--- a/src/share/vm/oops/annotations.hpp
+++ b/src/share/vm/oops/annotations.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -34,6 +34,7 @@
class ClassLoaderData;
class outputStream;
+class KlassSizeStats;
typedef Array<u1> AnnotationArray;
@@ -82,7 +83,12 @@ class Annotations: public MetaspaceObj {
Array<AnnotationArray*>* mda, TRAPS);
void deallocate_contents(ClassLoaderData* loader_data);
DEBUG_ONLY(bool on_stack() { return false; }) // for template
+
+ // Sizing (in words)
static int size() { return sizeof(Annotations) / wordSize; }
+#if INCLUDE_SERVICES
+ void collect_statistics(KlassSizeStats *sz) const;
+#endif
// Constructor to initialize to null
Annotations() : _class_annotations(NULL),
@@ -142,7 +148,7 @@ class Annotations: public MetaspaceObj {
void set_methods_annotations_of(instanceKlassHandle ik,
int idnum, AnnotationArray* anno,
Array<AnnotationArray*>** md_p, TRAPS);
-
+ static julong count_bytes(Array<AnnotationArray*>* p);
public:
const char* internal_name() const { return "{constant pool}"; }
#ifndef PRODUCT
diff --git a/src/share/vm/oops/arrayKlass.hpp b/src/share/vm/oops/arrayKlass.hpp
index 38a5340e3..f37a4d500 100644
--- a/src/share/vm/oops/arrayKlass.hpp
+++ b/src/share/vm/oops/arrayKlass.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -106,6 +106,14 @@ class ArrayKlass: public Klass {
static int header_size() { return sizeof(ArrayKlass)/HeapWordSize; }
static int static_size(int header_size);
+#if INCLUDE_SERVICES
+ virtual void collect_statistics(KlassSizeStats *sz) const {
+ Klass::collect_statistics(sz);
+ // Do nothing for now, but remember to modify if you add new
+ // stuff to ArrayKlass.
+ }
+#endif
+
// Java vtable
klassVtable* vtable() const; // return new klassVtable
int vtable_length() const { return _vtable_len; }
diff --git a/src/share/vm/oops/constMethod.cpp b/src/share/vm/oops/constMethod.cpp
index 79c10c0e6..3358d225e 100644
--- a/src/share/vm/oops/constMethod.cpp
+++ b/src/share/vm/oops/constMethod.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "interpreter/interpreter.hpp"
#include "memory/gcLocker.hpp"
+#include "memory/heapInspection.hpp"
#include "memory/metadataFactory.hpp"
#include "oops/constMethod.hpp"
#include "oops/method.hpp"
@@ -330,6 +331,18 @@ void ConstMethod::print_value_on(outputStream* st) const {
method()->print_value_on(st);
}
+#if INCLUDE_SERVICES
+// Size Statistics
+void ConstMethod::collect_statistics(KlassSizeStats *sz) const {
+ int n1, n2, n3;
+ sz->_const_method_bytes += (n1 = sz->count(this));
+ sz->_bytecode_bytes += (n2 = code_size());
+ sz->_stackmap_bytes += (n3 = sz->count_array(stackmap_data()));
+
+ sz->_method_all_bytes += n1 + n3; // note: n2 is part of n3
+ sz->_ro_bytes += n1 + n3;
+}
+#endif // INCLUDE_SERVICES
// Verification
diff --git a/src/share/vm/oops/constMethod.hpp b/src/share/vm/oops/constMethod.hpp
index 8b5939821..12a36c244 100644
--- a/src/share/vm/oops/constMethod.hpp
+++ b/src/share/vm/oops/constMethod.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -122,14 +122,10 @@ class ExceptionTableElement VALUE_OBJ_CLASS_SPEC {
class MethodParametersElement VALUE_OBJ_CLASS_SPEC {
public:
u2 name_cp_index;
- // This has to happen, otherwise it will cause SIGBUS from a
- // misaligned u4 on some architectures (ie SPARC)
- // because MethodParametersElements are only aligned mod 2
- // within the ConstMethod container u2 flags_hi;
- u2 flags_hi;
- u2 flags_lo;
+ u2 flags;
};
+class KlassSizeStats;
class ConstMethod : public MetaspaceObj {
friend class VMStructs;
@@ -320,6 +316,9 @@ public:
int size() const { return _constMethod_size;}
void set_constMethod_size(int size) { _constMethod_size = size; }
+#if INCLUDE_SERVICES
+ void collect_statistics(KlassSizeStats *sz) const;
+#endif
// code size
int code_size() const { return _code_size; }
diff --git a/src/share/vm/oops/constantPool.cpp b/src/share/vm/oops/constantPool.cpp
index 770510c78..1c21420c2 100644
--- a/src/share/vm/oops/constantPool.cpp
+++ b/src/share/vm/oops/constantPool.cpp
@@ -25,16 +25,17 @@
#include "precompiled.hpp"
#include "classfile/classLoaderData.hpp"
#include "classfile/javaClasses.hpp"
+#include "classfile/metadataOnStackMark.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "interpreter/linkResolver.hpp"
+#include "memory/heapInspection.hpp"
#include "memory/metadataFactory.hpp"
#include "memory/oopFactory.hpp"
#include "oops/constantPool.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/objArrayKlass.hpp"
-#include "prims/jvmtiRedefineClasses.hpp"
#include "runtime/fieldType.hpp"
#include "runtime/init.hpp"
#include "runtime/javaCalls.hpp"
@@ -65,11 +66,10 @@ ConstantPool::ConstantPool(Array<u1>* tags) {
set_operands(NULL);
set_pool_holder(NULL);
set_flags(0);
+
// 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"));
- // all fields are initialized; needed for GC
- set_on_stack(false);
// initialize tag array
int length = tags->length();
@@ -100,18 +100,6 @@ void ConstantPool::release_C_heap_structures() {
set_lock(NULL);
}
-void ConstantPool::set_flag_at(FlagBit fb) {
- const int MAX_STATE_CHANGES = 2;
- for (int i = MAX_STATE_CHANGES + 10; i > 0; i--) {
- int oflags = _flags;
- int nflags = oflags | (1 << (int)fb);
- if (Atomic::cmpxchg(nflags, &_flags, oflags) == oflags)
- return;
- }
- assert(false, "failed to cmpxchg flags");
- _flags |= (1 << (int)fb); // better than nothing
-}
-
objArrayOop ConstantPool::resolved_references() const {
return (objArrayOop)JNIHandles::resolve(_resolved_references);
}
@@ -1111,32 +1099,9 @@ bool ConstantPool::compare_entry_to(int index1, constantPoolHandle cp2,
} // end compare_entry_to()
-// Copy this constant pool's entries at start_i to end_i (inclusive)
-// to the constant pool to_cp's entries starting at to_i. A total of
-// (end_i - start_i) + 1 entries are copied.
-void ConstantPool::copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int end_i,
- constantPoolHandle to_cp, int to_i, TRAPS) {
-
- int dest_i = to_i; // leave original alone for debug purposes
-
- for (int src_i = start_i; src_i <= end_i; /* see loop bottom */ ) {
- copy_entry_to(from_cp, src_i, to_cp, dest_i, CHECK);
-
- switch (from_cp->tag_at(src_i).value()) {
- case JVM_CONSTANT_Double:
- case JVM_CONSTANT_Long:
- // double and long take two constant pool entries
- src_i += 2;
- dest_i += 2;
- break;
-
- default:
- // all others take one constant pool entry
- src_i++;
- dest_i++;
- break;
- }
- }
+void ConstantPool::copy_operands(constantPoolHandle from_cp,
+ constantPoolHandle to_cp,
+ TRAPS) {
int from_oplen = operand_array_length(from_cp->operands());
int old_oplen = operand_array_length(to_cp->operands());
@@ -1164,7 +1129,7 @@ void ConstantPool::copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int
(len = old_off) * sizeof(u2));
fillp += len;
// first part of src
- Copy::conjoint_memory_atomic(to_cp->operands()->adr_at(0),
+ Copy::conjoint_memory_atomic(from_cp->operands()->adr_at(0),
new_operands->adr_at(fillp),
(len = from_off) * sizeof(u2));
fillp += len;
@@ -1174,7 +1139,7 @@ void ConstantPool::copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int
(len = old_len - old_off) * sizeof(u2));
fillp += len;
// second part of src
- Copy::conjoint_memory_atomic(to_cp->operands()->adr_at(from_off),
+ Copy::conjoint_memory_atomic(from_cp->operands()->adr_at(from_off),
new_operands->adr_at(fillp),
(len = from_len - from_off) * sizeof(u2));
fillp += len;
@@ -1192,8 +1157,39 @@ void ConstantPool::copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int
to_cp->set_operands(new_operands);
}
}
+} // end copy_operands()
-} // end copy_cp_to()
+
+// Copy this constant pool's entries at start_i to end_i (inclusive)
+// to the constant pool to_cp's entries starting at to_i. A total of
+// (end_i - start_i) + 1 entries are copied.
+void ConstantPool::copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int end_i,
+ constantPoolHandle to_cp, int to_i, TRAPS) {
+
+
+ int dest_i = to_i; // leave original alone for debug purposes
+
+ for (int src_i = start_i; src_i <= end_i; /* see loop bottom */ ) {
+ copy_entry_to(from_cp, src_i, to_cp, dest_i, CHECK);
+
+ switch (from_cp->tag_at(src_i).value()) {
+ case JVM_CONSTANT_Double:
+ case JVM_CONSTANT_Long:
+ // double and long take two constant pool entries
+ src_i += 2;
+ dest_i += 2;
+ break;
+
+ default:
+ // all others take one constant pool entry
+ src_i++;
+ dest_i++;
+ break;
+ }
+ }
+ copy_operands(from_cp, to_cp, CHECK);
+
+} // end copy_cp_to_impl()
// Copy this constant pool's entry at from_i to the constant pool
@@ -1755,7 +1751,11 @@ int ConstantPool::copy_cpool_bytes(int cpool_size,
void ConstantPool::set_on_stack(const bool value) {
- _on_stack = value;
+ if (value) {
+ _flags |= _on_stack;
+ } else {
+ _flags &= ~_on_stack;
+ }
if (value) MetadataOnStackMark::record(this);
}
@@ -1827,6 +1827,7 @@ void ConstantPool::print_on(outputStream* st) const {
if (has_pseudo_string()) st->print(" has_pseudo_string");
if (has_invokedynamic()) st->print(" has_invokedynamic");
if (has_preresolution()) st->print(" has_preresolution");
+ if (on_stack()) st->print(" on_stack");
st->cr();
}
if (pool_holder() != NULL) {
@@ -1954,6 +1955,20 @@ void ConstantPool::print_value_on(outputStream* st) const {
}
}
+#if INCLUDE_SERVICES
+// Size Statistics
+void ConstantPool::collect_statistics(KlassSizeStats *sz) const {
+ sz->_cp_all_bytes += (sz->_cp_bytes = sz->count(this));
+ sz->_cp_all_bytes += (sz->_cp_tags_bytes = sz->count_array(tags()));
+ sz->_cp_all_bytes += (sz->_cp_cache_bytes = sz->count(cache()));
+ sz->_cp_all_bytes += (sz->_cp_operands_bytes = sz->count_array(operands()));
+ sz->_cp_all_bytes += (sz->_cp_refmap_bytes = sz->count_array(reference_map()));
+
+ sz->_ro_bytes += sz->_cp_operands_bytes + sz->_cp_tags_bytes +
+ sz->_cp_refmap_bytes;
+ sz->_rw_bytes += sz->_cp_bytes + sz->_cp_cache_bytes;
+}
+#endif // INCLUDE_SERVICES
// Verification
diff --git a/src/share/vm/oops/constantPool.hpp b/src/share/vm/oops/constantPool.hpp
index 655460215..92ae90f20 100644
--- a/src/share/vm/oops/constantPool.hpp
+++ b/src/share/vm/oops/constantPool.hpp
@@ -80,6 +80,7 @@ class CPSlot VALUE_OBJ_CLASS_SPEC {
}
};
+class KlassSizeStats;
class ConstantPool : public Metadata {
friend class VMStructs;
friend class BytecodeInterpreter; // Directly extracts an oop in the pool for fast instanceof/checkcast
@@ -95,10 +96,15 @@ class ConstantPool : public Metadata {
jobject _resolved_references;
Array<u2>* _reference_map;
- int _flags; // a few header bits to describe contents for GC
- int _length; // number of elements in the array
+ enum {
+ _has_invokedynamic = 1, // Flags
+ _has_pseudo_string = 2,
+ _has_preresolution = 4,
+ _on_stack = 8
+ };
- bool _on_stack; // Redefined method still executing refers to this constant pool.
+ int _flags; // old fashioned bit twiddling
+ int _length; // number of elements in the array
union {
// set for CDS to restore resolved references
@@ -115,17 +121,8 @@ class ConstantPool : public Metadata {
void set_operands(Array<u2>* operands) { _operands = operands; }
- enum FlagBit {
- FB_has_invokedynamic = 1,
- FB_has_pseudo_string = 2,
- FB_has_preresolution = 3
- };
-
- int flags() const { return _flags; }
- void set_flags(int f) { _flags = f; }
- bool flag_at(FlagBit fb) const { return (_flags & (1 << (int)fb)) != 0; }
- void set_flag_at(FlagBit fb);
- // no clear_flag_at function; they only increase
+ int flags() const { return _flags; }
+ void set_flags(int f) { _flags = f; }
private:
intptr_t* base() const { return (intptr_t*) (((char*) this) + sizeof(ConstantPool)); }
@@ -178,18 +175,20 @@ class ConstantPool : public Metadata {
Array<u1>* tags() const { return _tags; }
Array<u2>* operands() const { return _operands; }
- bool has_pseudo_string() const { return flag_at(FB_has_pseudo_string); }
- bool has_invokedynamic() const { return flag_at(FB_has_invokedynamic); }
- bool has_preresolution() const { return flag_at(FB_has_preresolution); }
- void set_pseudo_string() { set_flag_at(FB_has_pseudo_string); }
- void set_invokedynamic() { set_flag_at(FB_has_invokedynamic); }
- void set_preresolution() { set_flag_at(FB_has_preresolution); }
+ bool has_invokedynamic() const { return (_flags & _has_invokedynamic) != 0; }
+ void set_has_invokedynamic() { _flags |= _has_invokedynamic; }
+
+ bool has_pseudo_string() const { return (_flags & _has_pseudo_string) != 0; }
+ void set_has_pseudo_string() { _flags |= _has_pseudo_string; }
+
+ bool has_preresolution() const { return (_flags & _has_preresolution) != 0; }
+ void set_has_preresolution() { _flags |= _has_preresolution; }
// Redefine classes support. If a method refering to this constant pool
// is on the executing stack, or as a handle in vm code, this constant pool
// can't be removed from the set of previous versions saved in the instance
// class.
- bool on_stack() const { return _on_stack; }
+ bool on_stack() const { return (_flags &_on_stack) != 0; }
void set_on_stack(const bool value);
// Klass holding pool
@@ -457,7 +456,7 @@ class ConstantPool : public Metadata {
void pseudo_string_at_put(int which, int obj_index, oop x) {
assert(EnableInvokeDynamic, "");
- set_pseudo_string(); // mark header
+ set_has_pseudo_string(); // mark header
assert(tag_at(which).is_string(), "Corrupted constant pool");
string_at_put(which, obj_index, x); // this works just fine
}
@@ -686,9 +685,13 @@ class ConstantPool : public Metadata {
return 0 <= index && index < length();
}
+ // Sizing (in words)
static int header_size() { return sizeof(ConstantPool)/HeapWordSize; }
static int size(int length) { return align_object_size(header_size() + length); }
int size() const { return size(length()); }
+#if INCLUDE_SERVICES
+ void collect_statistics(KlassSizeStats *sz) const;
+#endif
friend class ClassFileParser;
friend class SystemDictionary;
@@ -783,6 +786,7 @@ class ConstantPool : public Metadata {
}
static void copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int end_i, constantPoolHandle to_cp, int to_i, TRAPS);
static void copy_entry_to(constantPoolHandle from_cp, int from_i, constantPoolHandle to_cp, int to_i, TRAPS);
+ static void copy_operands(constantPoolHandle from_cp, constantPoolHandle to_cp, TRAPS);
int find_matching_entry(int pattern_i, constantPoolHandle search_cp, TRAPS);
int version() const { return _saved._version; }
void set_version(int version) { _saved._version = version; }
diff --git a/src/share/vm/oops/cpCache.cpp b/src/share/vm/oops/cpCache.cpp
index 06c70cd02..7d6d36b68 100644
--- a/src/share/vm/oops/cpCache.cpp
+++ b/src/share/vm/oops/cpCache.cpp
@@ -33,9 +33,10 @@
#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/handles.inline.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
# include "gc_implementation/parallelScavenge/psPromotionManager.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
// Implememtation of ConstantPoolCacheEntry
diff --git a/src/share/vm/oops/instanceClassLoaderKlass.cpp b/src/share/vm/oops/instanceClassLoaderKlass.cpp
index def7d10e5..507206fc8 100644
--- a/src/share/vm/oops/instanceClassLoaderKlass.cpp
+++ b/src/share/vm/oops/instanceClassLoaderKlass.cpp
@@ -36,12 +36,13 @@
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
#include "runtime/handles.inline.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/parNew/parOopClosures.inline.hpp"
#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
#include "oops/oop.pcgc.inline.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
#define if_do_metadata_checked(closure, nv_suffix) \
/* Make sure the non-virtual and the virtual versions match. */ \
@@ -73,7 +74,7 @@ oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) {
return size; \
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#define InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
\
int InstanceClassLoaderKlass:: \
@@ -83,7 +84,7 @@ oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) {
int size = InstanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure); \
return size; \
}
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
#define InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix) \
@@ -111,10 +112,10 @@ oop_oop_iterate##nv_suffix##_m(oop obj,
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN)
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN_m)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN_m)
@@ -129,7 +130,7 @@ void InstanceClassLoaderKlass::oop_follow_contents(oop obj) {
}
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
void InstanceClassLoaderKlass::oop_follow_contents(ParCompactionManager* cm,
oop obj) {
InstanceKlass::oop_follow_contents(cm, obj);
@@ -155,5 +156,5 @@ int InstanceClassLoaderKlass::oop_update_pointers(ParCompactionManager* cm, oop
}
return size_helper();
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
diff --git a/src/share/vm/oops/instanceClassLoaderKlass.hpp b/src/share/vm/oops/instanceClassLoaderKlass.hpp
index c9f7f026a..d93f2a5c3 100644
--- a/src/share/vm/oops/instanceClassLoaderKlass.hpp
+++ b/src/share/vm/oops/instanceClassLoaderKlass.hpp
@@ -26,6 +26,7 @@
#define SHARE_VM_OOPS_INSTANCECLASSLOADERKLASS_HPP
#include "oops/instanceKlass.hpp"
+#include "utilities/macros.hpp"
// An InstanceClassLoaderKlass is a specialization of the InstanceKlass. It does
// not add any field. It is added to walk the dependencies for the class loader
@@ -61,13 +62,13 @@ public:
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DECL)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DECL)
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#define InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix) \
int oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* blk);
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
// Garbage collection
void oop_follow_contents(oop obj);
diff --git a/src/share/vm/oops/instanceKlass.cpp b/src/share/vm/oops/instanceKlass.cpp
index b0b7038e3..4af6e3206 100644
--- a/src/share/vm/oops/instanceKlass.cpp
+++ b/src/share/vm/oops/instanceKlass.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,7 @@
#include "interpreter/rewriter.hpp"
#include "jvmtifiles/jvmti.h"
#include "memory/genOopClosures.inline.hpp"
+#include "memory/heapInspection.hpp"
#include "memory/metadataFactory.hpp"
#include "memory/oopFactory.hpp"
#include "oops/fieldStreams.hpp"
@@ -55,7 +56,8 @@
#include "runtime/thread.inline.hpp"
#include "services/threadService.hpp"
#include "utilities/dtrace.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1OopClosures.inline.hpp"
@@ -66,7 +68,7 @@
#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
#include "oops/oop.pcgc.inline.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
#ifdef COMPILER1
#include "c1/c1_Compiler.hpp"
#endif
@@ -2042,7 +2044,7 @@ void InstanceKlass::oop_follow_contents(oop obj) {
assert_is_in_closed_subset)
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
void InstanceKlass::oop_follow_contents(ParCompactionManager* cm,
oop obj) {
assert(obj != NULL, "can't follow the content of NULL object");
@@ -2054,7 +2056,7 @@ void InstanceKlass::oop_follow_contents(ParCompactionManager* cm,
PSParallelCompact::mark_and_push(cm, p), \
assert_is_in)
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
// closure's do_metadata() method dictates whether the given closure should be
// applied to the klass ptr in the object header.
@@ -2082,7 +2084,7 @@ int InstanceKlass::oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure)
return size_helper(); \
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#define InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
\
int InstanceKlass::oop_oop_iterate_backwards##nv_suffix(oop obj, \
@@ -2100,7 +2102,7 @@ int InstanceKlass::oop_oop_iterate_backwards##nv_suffix(oop obj,
assert_is_in_closed_subset) \
return size_helper(); \
}
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
#define InstanceKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix) \
\
@@ -2124,10 +2126,10 @@ ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_DEFN)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_DEFN)
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_DEFN_m)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_DEFN_m)
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
int InstanceKlass::oop_adjust_pointers(oop obj) {
int size = size_helper();
@@ -2139,7 +2141,7 @@ int InstanceKlass::oop_adjust_pointers(oop obj) {
return size;
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
void InstanceKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
InstanceKlass_OOP_MAP_REVERSE_ITERATE( \
obj, \
@@ -2159,7 +2161,7 @@ int InstanceKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
return size;
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
void InstanceKlass::clean_implementors_list(BoolObjectClosure* is_alive) {
assert(is_loader_alive(is_alive), "this klass should be live");
@@ -2960,6 +2962,52 @@ const char* InstanceKlass::internal_name() const {
return external_name();
}
+#if INCLUDE_SERVICES
+// Size Statistics
+void InstanceKlass::collect_statistics(KlassSizeStats *sz) const {
+ Klass::collect_statistics(sz);
+
+ sz->_inst_size = HeapWordSize * size_helper();
+ sz->_vtab_bytes = HeapWordSize * align_object_offset(vtable_length());
+ sz->_itab_bytes = HeapWordSize * align_object_offset(itable_length());
+ sz->_nonstatic_oopmap_bytes = HeapWordSize *
+ ((is_interface() || is_anonymous()) ?
+ align_object_offset(nonstatic_oop_map_size()) :
+ nonstatic_oop_map_size());
+
+ int n = 0;
+ n += (sz->_methods_array_bytes = sz->count_array(methods()));
+ n += (sz->_method_ordering_bytes = sz->count_array(method_ordering()));
+ n += (sz->_local_interfaces_bytes = sz->count_array(local_interfaces()));
+ n += (sz->_transitive_interfaces_bytes = sz->count_array(transitive_interfaces()));
+ n += (sz->_signers_bytes = sz->count_array(signers()));
+ n += (sz->_fields_bytes = sz->count_array(fields()));
+ n += (sz->_inner_classes_bytes = sz->count_array(inner_classes()));
+ sz->_ro_bytes += n;
+
+ const ConstantPool* cp = constants();
+ if (cp) {
+ cp->collect_statistics(sz);
+ }
+
+ const Annotations* anno = annotations();
+ if (anno) {
+ anno->collect_statistics(sz);
+ }
+
+ const Array<Method*>* methods_array = methods();
+ if (methods()) {
+ for (int i = 0; i < methods_array->length(); i++) {
+ Method* method = methods_array->at(i);
+ if (method) {
+ sz->_method_count ++;
+ method->collect_statistics(sz);
+ }
+ }
+ }
+}
+#endif // INCLUDE_SERVICES
+
// Verification
class VerifyFieldClosure: public OopClosure {
diff --git a/src/share/vm/oops/instanceKlass.hpp b/src/share/vm/oops/instanceKlass.hpp
index 97b3dd233..025da1282 100644
--- a/src/share/vm/oops/instanceKlass.hpp
+++ b/src/share/vm/oops/instanceKlass.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,7 @@
#include "runtime/os.hpp"
#include "utilities/accessFlags.hpp"
#include "utilities/bitMap.inline.hpp"
+#include "utilities/macros.hpp"
// An InstanceKlass is the VM level representation of a Java class.
// It contains all information needed for at class at execution runtime.
@@ -256,6 +257,16 @@ class InstanceKlass: public Klass {
// JVMTI fields can be moved to their own structure - see 6315920
unsigned char * _cached_class_file_bytes; // JVMTI: cached class file, before retransformable agent modified it in CFLH
jint _cached_class_file_len; // JVMTI: length of above
+
+ volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change
+
+ // Class states are defined as ClassState (see above).
+ // Place the _init_state here to utilize the unused 2-byte after
+ // _idnum_allocated_count.
+ u1 _init_state; // state of class
+ u1 _reference_type; // reference type
+
+
JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map; // JVMTI: used during heap iteration
// Method array.
@@ -281,15 +292,6 @@ class InstanceKlass: public Klass {
// ...
Array<u2>* _fields;
- volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change
-
- // Class states are defined as ClassState (see above).
- // Place the _init_state here to utilize the unused 2-byte after
- // _idnum_allocated_count.
- u1 _init_state; // state of class
-
- u1 _reference_type; // reference type
-
// embedded Java vtable follows here
// embedded Java itables follows here
// embedded static fields follows here
@@ -826,6 +828,9 @@ class InstanceKlass: public Klass {
is_interface(),
is_anonymous());
}
+#if INCLUDE_SERVICES
+ virtual void collect_statistics(KlassSizeStats *sz) const;
+#endif
static int vtable_start_offset() { return header_size(); }
static int vtable_length_offset() { return offset_of(InstanceKlass, _vtable_len) / HeapWordSize; }
@@ -932,13 +937,13 @@ class InstanceKlass: public Klass {
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_DECL)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_DECL)
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#define InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix) \
int oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* blk);
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
u2 idnum_allocated_count() const { return _idnum_allocated_count; }
private:
diff --git a/src/share/vm/oops/instanceMirrorKlass.cpp b/src/share/vm/oops/instanceMirrorKlass.cpp
index 4e63075c4..3eabba70a 100644
--- a/src/share/vm/oops/instanceMirrorKlass.cpp
+++ b/src/share/vm/oops/instanceMirrorKlass.cpp
@@ -35,7 +35,8 @@
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
#include "runtime/handles.inline.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1OopClosures.inline.hpp"
@@ -45,7 +46,7 @@
#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
#include "oops/oop.pcgc.inline.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
int InstanceMirrorKlass::_offset_of_static_fields = 0;
@@ -168,7 +169,7 @@ void InstanceMirrorKlass::oop_follow_contents(oop obj) {
assert_is_in_closed_subset)
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
void InstanceMirrorKlass::oop_follow_contents(ParCompactionManager* cm,
oop obj) {
InstanceKlass::oop_follow_contents(cm, obj);
@@ -189,7 +190,7 @@ void InstanceMirrorKlass::oop_follow_contents(ParCompactionManager* cm,
PSParallelCompact::mark_and_push(cm, p), \
assert_is_in)
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
int InstanceMirrorKlass::oop_adjust_pointers(oop obj) {
int size = oop_size(obj);
@@ -262,7 +263,7 @@ oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) {
} \
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#define InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
\
int InstanceMirrorKlass:: \
@@ -278,7 +279,7 @@ oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) {
InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(oop, nv_suffix); \
} \
}
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
#define InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix) \
@@ -310,14 +311,14 @@ oop_oop_iterate##nv_suffix##_m(oop obj,
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN)
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m)
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
void InstanceMirrorKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
// Note that we don't have to follow the mirror -> klass pointer, since all
// klasses that are dirty will be scavenged when we iterate over the
@@ -353,7 +354,7 @@ int InstanceMirrorKlass::oop_update_pointers(ParCompactionManager* cm, oop obj)
assert_nothing)
return size;
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
int InstanceMirrorKlass::instance_size(KlassHandle k) {
if (k() != NULL && k->oop_is_instance()) {
diff --git a/src/share/vm/oops/instanceMirrorKlass.hpp b/src/share/vm/oops/instanceMirrorKlass.hpp
index db1d8de25..38f2dc817 100644
--- a/src/share/vm/oops/instanceMirrorKlass.hpp
+++ b/src/share/vm/oops/instanceMirrorKlass.hpp
@@ -28,6 +28,7 @@
#include "classfile/systemDictionary.hpp"
#include "oops/instanceKlass.hpp"
#include "runtime/handles.hpp"
+#include "utilities/macros.hpp"
// An InstanceMirrorKlass is a specialized InstanceKlass for
// java.lang.Class instances. These instances are special because
@@ -107,13 +108,13 @@ class InstanceMirrorKlass: public InstanceKlass {
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DECL)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DECL)
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#define InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix) \
int oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* blk);
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
};
#endif // SHARE_VM_OOPS_INSTANCEMIRRORKLASS_HPP
diff --git a/src/share/vm/oops/instanceRefKlass.cpp b/src/share/vm/oops/instanceRefKlass.cpp
index 1784609e3..cb5f89655 100644
--- a/src/share/vm/oops/instanceRefKlass.cpp
+++ b/src/share/vm/oops/instanceRefKlass.cpp
@@ -33,7 +33,8 @@
#include "oops/instanceRefKlass.hpp"
#include "oops/oop.inline.hpp"
#include "utilities/preserveException.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1OopClosures.inline.hpp"
#include "gc_implementation/g1/g1RemSet.inline.hpp"
@@ -42,7 +43,7 @@
#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
#include "oops/oop.pcgc.inline.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
template <class T>
void specialized_oop_follow_contents(InstanceRefKlass* ref, oop obj) {
@@ -120,7 +121,7 @@ void InstanceRefKlass::oop_follow_contents(oop obj) {
}
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
template <class T>
void specialized_oop_follow_contents(InstanceRefKlass* ref,
ParCompactionManager* cm,
@@ -194,7 +195,7 @@ void InstanceRefKlass::oop_follow_contents(ParCompactionManager* cm,
specialized_oop_follow_contents<oop>(this, cm, obj);
}
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
#ifdef ASSERT
template <class T> void trace_reference_gc(const char *s, oop obj,
@@ -317,7 +318,7 @@ oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) {
} \
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#define InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
\
int InstanceRefKlass:: \
@@ -333,7 +334,7 @@ oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) {
InstanceRefKlass_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, contains); \
} \
}
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
#define InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix) \
@@ -354,14 +355,14 @@ oop_oop_iterate##nv_suffix##_m(oop obj,
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_DEFN)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_DEFN)
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m)
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
template <class T>
void specialized_oop_push_contents(InstanceRefKlass *ref,
PSPromotionManager* pm, oop obj) {
@@ -444,7 +445,7 @@ int InstanceRefKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
}
return size_helper();
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
void InstanceRefKlass::update_nonstatic_oop_maps(Klass* k) {
// Clear the nonstatic oop-map entries corresponding to referent
diff --git a/src/share/vm/oops/instanceRefKlass.hpp b/src/share/vm/oops/instanceRefKlass.hpp
index fd565ecd8..d8771608f 100644
--- a/src/share/vm/oops/instanceRefKlass.hpp
+++ b/src/share/vm/oops/instanceRefKlass.hpp
@@ -26,6 +26,7 @@
#define SHARE_VM_OOPS_INSTANCEREFKLASS_HPP
#include "oops/instanceKlass.hpp"
+#include "utilities/macros.hpp"
// An InstanceRefKlass is a specialized InstanceKlass for Java
// classes that are subclasses of java/lang/ref/Reference.
@@ -83,13 +84,13 @@ class InstanceRefKlass: public InstanceKlass {
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_DECL)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_DECL)
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#define InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix) \
int oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* blk);
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
static void release_and_notify_pending_list_lock(BasicLock *pending_list_basic_lock);
static void acquire_pending_list_lock(BasicLock *pending_list_basic_lock);
diff --git a/src/share/vm/oops/klass.cpp b/src/share/vm/oops/klass.cpp
index 21bfb6bda..341f60c3f 100644
--- a/src/share/vm/oops/klass.cpp
+++ b/src/share/vm/oops/klass.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
#include "classfile/vmSymbols.hpp"
#include "gc_implementation/shared/markSweep.inline.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
+#include "memory/heapInspection.hpp"
#include "memory/metadataFactory.hpp"
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
@@ -37,11 +38,12 @@
#include "oops/oop.inline2.hpp"
#include "runtime/atomic.hpp"
#include "utilities/stack.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
#include "gc_implementation/parallelScavenge/psPromotionManager.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
void Klass::set_name(Symbol* n) {
_name = n;
@@ -624,6 +626,17 @@ void Klass::oop_print_value_on(oop obj, outputStream* st) {
obj->print_address_on(st);
}
+#if INCLUDE_SERVICES
+// Size Statistics
+void Klass::collect_statistics(KlassSizeStats *sz) const {
+ sz->_klass_bytes = sz->count(this);
+ sz->_mirror_bytes = sz->count(java_mirror());
+ sz->_secondary_supers_bytes = sz->count_array(secondary_supers());
+
+ sz->_ro_bytes += sz->_secondary_supers_bytes;
+ sz->_rw_bytes += sz->_klass_bytes + sz->_mirror_bytes;
+}
+#endif // INCLUDE_SERVICES
// Verification
diff --git a/src/share/vm/oops/klass.hpp b/src/share/vm/oops/klass.hpp
index be5d0c529..803f4da27 100644
--- a/src/share/vm/oops/klass.hpp
+++ b/src/share/vm/oops/klass.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,11 +35,12 @@
#include "runtime/orderAccess.hpp"
#include "trace/traceMacros.hpp"
#include "utilities/accessFlags.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp"
#include "gc_implementation/g1/g1OopClosures.hpp"
#include "gc_implementation/parNew/parOopClosures.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
//
// A Klass provides:
@@ -75,11 +76,11 @@
// [class_loader_data]
// [modifier_flags]
// [access_flags ]
-// [verify_count ] - not in product
-// [alloc_count ]
// [last_biased_lock_bulk_revocation_time] (64 bits)
// [prototype_header]
// [biased_lock_revocation_count]
+// [verify_count ] - not in product
+// [alloc_count ]
// [_modified_oops]
// [_accumulated_modified_oops]
// [trace_id]
@@ -91,6 +92,7 @@ template <class T> class GrowableArray;
class ClassLoaderData;
class klassVtable;
class ParCompactionManager;
+class KlassSizeStats;
class Klass : public Metadata {
friend class VMStructs;
@@ -164,18 +166,18 @@ class Klass : public Metadata {
jint _modifier_flags; // Processed access flags, for use by Class.getModifiers.
AccessFlags _access_flags; // Access flags. The class/interface distinction is stored here.
-#ifndef PRODUCT
- int _verify_count; // to avoid redundant verifies
-#endif
-
- juint _alloc_count; // allocation profiling support
-
// Biased locking implementation and statistics
// (the 64-bit chunk goes first, to avoid some fragmentation)
jlong _last_biased_lock_bulk_revocation_time;
markOop _prototype_header; // Used when biased locking is both enabled and disabled for this type
jint _biased_lock_revocation_count;
+#ifndef PRODUCT
+ int _verify_count; // to avoid redundant verifies
+#endif
+
+ juint _alloc_count; // allocation profiling support
+
TRACE_DEFINE_KLASS_TRACE_ID;
// Remembered sets support for the oops in the klasses.
@@ -477,6 +479,9 @@ class Klass : public Metadata {
// Size of klass in word size.
virtual int size() const = 0;
+#if INCLUDE_SERVICES
+ virtual void collect_statistics(KlassSizeStats *sz) const;
+#endif
// Returns the Java name for a class (Resource allocated)
// For arrays, this returns the name of the element with a leading '['.
@@ -625,13 +630,13 @@ class Klass : public Metadata {
return oop_oop_iterate(obj, blk);
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// In case we don't have a specialized backward scanner use forward
// iteration.
virtual int oop_oop_iterate_backwards_v(oop obj, ExtendedOopClosure* blk) {
return oop_oop_iterate_v(obj, blk);
}
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
// Iterates "blk" over all the oops in "obj" (of type "this") within "mr".
// (I don't see why the _m should be required, but without it the Solaris
@@ -663,7 +668,7 @@ class Klass : public Metadata {
SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_1(Klass_OOP_OOP_ITERATE_DECL)
SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(Klass_OOP_OOP_ITERATE_DECL)
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#define Klass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix) \
virtual int oop_oop_iterate_backwards##nv_suffix(oop obj, \
OopClosureType* blk) { \
@@ -673,7 +678,7 @@ class Klass : public Metadata {
SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_1(Klass_OOP_OOP_ITERATE_BACKWARDS_DECL)
SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(Klass_OOP_OOP_ITERATE_BACKWARDS_DECL)
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
virtual void array_klasses_do(void f(Klass* k)) {}
virtual void with_array_klasses_do(void f(Klass* k));
diff --git a/src/share/vm/oops/klassPS.hpp b/src/share/vm/oops/klassPS.hpp
index 0aa7a580d..5fb17b6e8 100644
--- a/src/share/vm/oops/klassPS.hpp
+++ b/src/share/vm/oops/klassPS.hpp
@@ -27,7 +27,9 @@
// Expands to Parallel Scavenge and Parallel Old declarations
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+
+#if INCLUDE_ALL_GCS
#define PARALLEL_GC_DECLS \
virtual void oop_push_contents(PSPromotionManager* pm, oop obj); \
/* Parallel Old GC support \
@@ -44,9 +46,9 @@
virtual void oop_push_contents(PSPromotionManager* pm, oop obj) = 0; \
virtual void oop_follow_contents(ParCompactionManager* cm, oop obj) = 0; \
virtual int oop_update_pointers(ParCompactionManager* cm, oop obj) = 0;
-#else // SERIALGC
+#else // INCLUDE_ALL_GCS
#define PARALLEL_GC_DECLS
#define PARALLEL_GC_DECLS_PV
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
#endif // SHARE_VM_OOPS_KLASSPS_HPP
diff --git a/src/share/vm/oops/method.cpp b/src/share/vm/oops/method.cpp
index 936090f50..110148a72 100644
--- a/src/share/vm/oops/method.cpp
+++ b/src/share/vm/oops/method.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "classfile/metadataOnStackMark.hpp"
#include "classfile/systemDictionary.hpp"
#include "code/debugInfoRec.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
@@ -33,6 +34,7 @@
#include "interpreter/oopMapCache.hpp"
#include "memory/gcLocker.hpp"
#include "memory/generation.hpp"
+#include "memory/heapInspection.hpp"
#include "memory/metadataFactory.hpp"
#include "memory/oopFactory.hpp"
#include "oops/constMethod.hpp"
@@ -41,7 +43,6 @@
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
#include "prims/jvmtiExport.hpp"
-#include "prims/jvmtiRedefineClasses.hpp"
#include "prims/methodHandles.hpp"
#include "prims/nativeLookup.hpp"
#include "runtime/arguments.hpp"
@@ -699,7 +700,7 @@ void Method::set_signature_handler(address handler) {
}
-void Method::print_made_not_compilable(int comp_level, bool is_osr, bool report) {
+void Method::print_made_not_compilable(int comp_level, bool is_osr, bool report, const char* reason) {
if (PrintCompilation && report) {
ttyLocker ttyl;
tty->print("made not %scompilable on ", is_osr ? "OSR " : "");
@@ -713,14 +714,21 @@ void Method::print_made_not_compilable(int comp_level, bool is_osr, bool report)
}
this->print_short_name(tty);
int size = this->code_size();
- if (size > 0)
+ if (size > 0) {
tty->print(" (%d bytes)", size);
+ }
+ if (reason != NULL) {
+ tty->print(" %s", reason);
+ }
tty->cr();
}
if ((TraceDeoptimization || LogCompilation) && (xtty != NULL)) {
ttyLocker ttyl;
xtty->begin_elem("make_not_%scompilable thread='" UINTX_FORMAT "'",
is_osr ? "osr_" : "", os::current_thread_id());
+ if (reason != NULL) {
+ xtty->print(" reason=\'%s\'", reason);
+ }
xtty->method(this);
xtty->stamp();
xtty->end_elem();
@@ -742,8 +750,8 @@ bool Method::is_not_compilable(int comp_level) const {
}
// call this when compiler finds that this method is not compilable
-void Method::set_not_compilable(int comp_level, bool report) {
- print_made_not_compilable(comp_level, /*is_osr*/ false, report);
+void Method::set_not_compilable(int comp_level, bool report, const char* reason) {
+ print_made_not_compilable(comp_level, /*is_osr*/ false, report, reason);
if (comp_level == CompLevel_all) {
set_not_c1_compilable();
set_not_c2_compilable();
@@ -768,8 +776,8 @@ bool Method::is_not_osr_compilable(int comp_level) const {
return false;
}
-void Method::set_not_osr_compilable(int comp_level, bool report) {
- print_made_not_compilable(comp_level, /*is_osr*/ true, report);
+void Method::set_not_osr_compilable(int comp_level, bool report, const char* reason) {
+ print_made_not_compilable(comp_level, /*is_osr*/ true, report, reason);
if (comp_level == CompLevel_all) {
set_not_c1_osr_compilable();
set_not_c2_osr_compilable();
@@ -1027,7 +1035,7 @@ methodHandle Method::make_method_handle_intrinsic(vmIntrinsics::ID iid,
cp->set_pool_holder(InstanceKlass::cast(holder()));
cp->symbol_at_put(_imcp_invoke_name, name);
cp->symbol_at_put(_imcp_invoke_signature, signature);
- cp->set_preresolution();
+ cp->set_has_preresolution();
// decide on access bits: public or not?
int flags_bits = (JVM_ACC_NATIVE | JVM_ACC_SYNTHETIC | JVM_ACC_FINAL);
@@ -1954,6 +1962,22 @@ void Method::print_value_on(outputStream* st) const {
if (WizardMode && code() != NULL) st->print(" ((nmethod*)%p)", code());
}
+#if INCLUDE_SERVICES
+// Size Statistics
+void Method::collect_statistics(KlassSizeStats *sz) const {
+ int mysize = sz->count(this);
+ sz->_method_bytes += mysize;
+ sz->_method_all_bytes += mysize;
+ sz->_rw_bytes += mysize;
+
+ if (constMethod()) {
+ constMethod()->collect_statistics(sz);
+ }
+ if (method_data()) {
+ method_data()->collect_statistics(sz);
+ }
+}
+#endif // INCLUDE_SERVICES
// Verification
diff --git a/src/share/vm/oops/method.hpp b/src/share/vm/oops/method.hpp
index 72a4faf11..339380f67 100644
--- a/src/share/vm/oops/method.hpp
+++ b/src/share/vm/oops/method.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -101,6 +101,7 @@ class LocalVariableTableElement;
class AdapterHandlerEntry;
class MethodData;
class ConstMethod;
+class KlassSizeStats;
class Method : public Metadata {
friend class VMStructs;
@@ -127,8 +128,8 @@ class Method : public Metadata {
InvocationCounter _backedge_counter; // Incremented before each backedge taken - used to trigger frequencey-based optimizations
#ifdef TIERED
- jlong _prev_time; // Previous time the rate was acquired
float _rate; // Events (invocation and backedge counter increments) per millisecond
+ jlong _prev_time; // Previous time the rate was acquired
#endif
#ifndef PRODUCT
@@ -593,6 +594,9 @@ class Method : public Metadata {
static int header_size() { return sizeof(Method)/HeapWordSize; }
static int size(bool is_native);
int size() const { return method_size(); }
+#if INCLUDE_SERVICES
+ void collect_statistics(KlassSizeStats *sz) const;
+#endif
// interpreter support
static ByteSize const_offset() { return byte_offset_of(Method, _constMethod ); }
@@ -760,18 +764,18 @@ class Method : public Metadata {
// whether it is not compilable for another reason like having a
// breakpoint set in it.
bool is_not_compilable(int comp_level = CompLevel_any) const;
- void set_not_compilable(int comp_level = CompLevel_all, bool report = true);
+ void set_not_compilable(int comp_level = CompLevel_all, bool report = true, const char* reason = NULL);
void set_not_compilable_quietly(int comp_level = CompLevel_all) {
set_not_compilable(comp_level, false);
}
bool is_not_osr_compilable(int comp_level = CompLevel_any) const;
- void set_not_osr_compilable(int comp_level = CompLevel_all, bool report = true);
+ void set_not_osr_compilable(int comp_level = CompLevel_all, bool report = true, const char* reason = NULL);
void set_not_osr_compilable_quietly(int comp_level = CompLevel_all) {
set_not_osr_compilable(comp_level, false);
}
private:
- void print_made_not_compilable(int comp_level, bool is_osr, bool report);
+ void print_made_not_compilable(int comp_level, bool is_osr, bool report, const char* reason);
public:
bool is_not_c1_compilable() const { return access_flags().is_not_c1_compilable(); }
diff --git a/src/share/vm/oops/methodData.cpp b/src/share/vm/oops/methodData.cpp
index 71d9649c2..c7a200f9e 100644
--- a/src/share/vm/oops/methodData.cpp
+++ b/src/share/vm/oops/methodData.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -27,6 +27,7 @@
#include "interpreter/bytecode.hpp"
#include "interpreter/bytecodeStream.hpp"
#include "interpreter/linkResolver.hpp"
+#include "memory/heapInspection.hpp"
#include "oops/methodData.hpp"
#include "prims/jvmtiRedefineClasses.hpp"
#include "runtime/compilationPolicy.hpp"
@@ -859,6 +860,15 @@ void MethodData::print_data_on(outputStream* st) const {
}
#endif
+#if INCLUDE_SERVICES
+// Size Statistics
+void MethodData::collect_statistics(KlassSizeStats *sz) const {
+ int n = sz->count(this);
+ sz->_method_data_bytes += n;
+ sz->_method_all_bytes += n;
+ sz->_rw_bytes += n;
+}
+#endif // INCLUDE_SERVICES
// Verification
diff --git a/src/share/vm/oops/methodData.hpp b/src/share/vm/oops/methodData.hpp
index 133278878..2f45870f3 100644
--- a/src/share/vm/oops/methodData.hpp
+++ b/src/share/vm/oops/methodData.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -32,6 +32,7 @@
#include "runtime/orderAccess.hpp"
class BytecodeStream;
+class KlassSizeStats;
// The MethodData object collects counts and other profile information
// during zeroth-tier (interpretive) and first-tier execution.
@@ -1289,6 +1290,9 @@ public:
// My size
int size_in_bytes() const { return _size; }
int size() const { return align_object_size(align_size_up(_size, BytesPerWord)/BytesPerWord); }
+#if INCLUDE_SERVICES
+ void collect_statistics(KlassSizeStats *sz) const;
+#endif
int creation_mileage() const { return _creation_mileage; }
void set_creation_mileage(int x) { _creation_mileage = x; }
@@ -1465,7 +1469,7 @@ public:
void inc_decompile_count() {
_nof_decompiles += 1;
if (decompile_count() > (uint)PerMethodRecompilationCutoff) {
- method()->set_not_compilable(CompLevel_full_optimization);
+ method()->set_not_compilable(CompLevel_full_optimization, true, "decompile_count > PerMethodRecompilationCutoff");
}
}
diff --git a/src/share/vm/oops/objArrayKlass.cpp b/src/share/vm/oops/objArrayKlass.cpp
index 434fb74ab..f04020639 100644
--- a/src/share/vm/oops/objArrayKlass.cpp
+++ b/src/share/vm/oops/objArrayKlass.cpp
@@ -43,7 +43,8 @@
#include "runtime/handles.inline.hpp"
#include "runtime/mutexLocker.hpp"
#include "utilities/copy.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1OopClosures.inline.hpp"
@@ -54,7 +55,7 @@
#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
#include "oops/oop.pcgc.inline.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
ObjArrayKlass* ObjArrayKlass::allocate(ClassLoaderData* loader_data, int n, KlassHandle klass_handle, Symbol* name, TRAPS) {
assert(ObjArrayKlass::header_size() <= InstanceKlass::header_size(),
@@ -461,7 +462,7 @@ void ObjArrayKlass::oop_follow_contents(oop obj) {
}
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
void ObjArrayKlass::oop_follow_contents(ParCompactionManager* cm,
oop obj) {
assert(obj->is_array(), "obj must be array");
@@ -472,7 +473,7 @@ void ObjArrayKlass::oop_follow_contents(ParCompactionManager* cm,
objarray_follow_contents<oop>(cm, obj, 0);
}
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
#define if_do_metadata_checked(closure, nv_suffix) \
/* Make sure the non-virtual and the virtual versions match. */ \
@@ -573,7 +574,7 @@ int ObjArrayKlass::oop_adjust_pointers(oop obj) {
return size;
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
void ObjArrayKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
assert(obj->is_objArray(), "obj must be obj array");
ObjArrayKlass_OOP_ITERATE( \
@@ -591,7 +592,7 @@ int ObjArrayKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
ObjArrayKlass_OOP_ITERATE(a, p, PSParallelCompact::adjust_pointer(p))
return size;
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
// JVM support
diff --git a/src/share/vm/oops/objArrayKlass.hpp b/src/share/vm/oops/objArrayKlass.hpp
index 2234aa831..74aa4f8d7 100644
--- a/src/share/vm/oops/objArrayKlass.hpp
+++ b/src/share/vm/oops/objArrayKlass.hpp
@@ -28,6 +28,7 @@
#include "classfile/classLoaderData.hpp"
#include "memory/specialized_oop_closures.hpp"
#include "oops/arrayKlass.hpp"
+#include "utilities/macros.hpp"
// ObjArrayKlass is the klass for objArrays
@@ -111,11 +112,11 @@ class ObjArrayKlass : public ArrayKlass {
// Parallel Scavenge and Parallel Old
PARALLEL_GC_DECLS
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
inline void oop_follow_contents(ParCompactionManager* cm, oop obj, int index);
template <class T> inline void
objarray_follow_contents(ParCompactionManager* cm, oop obj, int index);
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
// Iterators
int oop_oop_iterate(oop obj, ExtendedOopClosure* blk) {
diff --git a/src/share/vm/oops/objArrayKlass.inline.hpp b/src/share/vm/oops/objArrayKlass.inline.hpp
index 4a948d82e..23e809a7e 100644
--- a/src/share/vm/oops/objArrayKlass.inline.hpp
+++ b/src/share/vm/oops/objArrayKlass.inline.hpp
@@ -27,10 +27,11 @@
#include "gc_implementation/shared/markSweep.inline.hpp"
#include "oops/objArrayKlass.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/parallelScavenge/psCompactionManager.inline.hpp"
#include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
void ObjArrayKlass::oop_follow_contents(oop obj, int index) {
if (UseCompressedOops) {
@@ -63,7 +64,7 @@ void ObjArrayKlass::objarray_follow_contents(oop obj, int index) {
}
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
void ObjArrayKlass::oop_follow_contents(ParCompactionManager* cm, oop obj,
int index) {
if (UseCompressedOops) {
@@ -96,6 +97,6 @@ void ObjArrayKlass::objarray_follow_contents(ParCompactionManager* cm, oop obj,
cm->push_objarray(a, end_index); // Push the continuation.
}
}
-#endif // #ifndef SERIALGC
+#endif // INCLUDE_ALL_GCS
#endif // SHARE_VM_OOPS_OBJARRAYKLASS_INLINE_HPP
diff --git a/src/share/vm/oops/oop.hpp b/src/share/vm/oops/oop.hpp
index 7cb04ff4c..94e68ed32 100644
--- a/src/share/vm/oops/oop.hpp
+++ b/src/share/vm/oops/oop.hpp
@@ -29,6 +29,7 @@
#include "memory/memRegion.hpp"
#include "memory/specialized_oop_closures.hpp"
#include "oops/metadata.hpp"
+#include "utilities/macros.hpp"
#include "utilities/top.hpp"
// oopDesc is the top baseclass for objects classes. The {name}Desc classes describe
@@ -298,7 +299,7 @@ class oopDesc {
// reference field in "this".
void follow_contents(void);
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// Parallel Scavenge
void push_contents(PSPromotionManager* pm);
@@ -306,7 +307,7 @@ class oopDesc {
void update_contents(ParCompactionManager* cm);
void follow_contents(ParCompactionManager* cm);
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
bool is_scavengable() const;
@@ -316,13 +317,13 @@ class oopDesc {
void forward_to(oop p);
bool cas_forward_to(oop p, markOop compare);
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// Like "forward_to", but inserts the forwarding pointer atomically.
// Exactly one thread succeeds in inserting the forwarding pointer, and
// this call returns "NULL" for that thread; any other thread has the
// value of the forwarding pointer returned and does not modify "this".
oop forward_to_atomic(oop p);
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
oop forwardee() const;
@@ -334,10 +335,10 @@ class oopDesc {
// return the size of this oop. This is used by the MarkSweep collector.
int adjust_pointers();
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// Parallel old
void update_header(ParCompactionManager* cm);
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
// mark-sweep support
void follow_body(int begin, int end);
@@ -354,7 +355,7 @@ class oopDesc {
ALL_OOP_OOP_ITERATE_CLOSURES_1(OOP_ITERATE_DECL)
ALL_OOP_OOP_ITERATE_CLOSURES_2(OOP_ITERATE_DECL)
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#define OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix) \
int oop_iterate_backwards(OopClosureType* blk);
diff --git a/src/share/vm/oops/oop.inline.hpp b/src/share/vm/oops/oop.inline.hpp
index c09761747..3c71e15f8 100644
--- a/src/share/vm/oops/oop.inline.hpp
+++ b/src/share/vm/oops/oop.inline.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -40,6 +40,7 @@
#include "oops/oop.hpp"
#include "runtime/atomic.hpp"
#include "runtime/os.hpp"
+#include "utilities/macros.hpp"
#ifdef TARGET_ARCH_x86
# include "bytes_x86.hpp"
#endif
@@ -227,12 +228,12 @@ inline oop oopDesc::decode_heap_oop(oop v) { return v; }
// might not be the same as oop.
inline narrowOop oopDesc::encode_klass_not_null(Klass* v) {
- assert(!is_null(v), "oop value can never be zero");
+ assert(!is_null(v), "klass value can never be zero");
assert(check_klass_alignment(v), "Address not aligned");
address base = Universe::narrow_klass_base();
int shift = Universe::narrow_klass_shift();
uint64_t pd = (uint64_t)(pointer_delta((void*)v, (void*)base, 1));
- assert(OopEncodingHeapMax > pd, "change encoding max if new encoding");
+ assert(KlassEncodingMetaspaceMax > pd, "change encoding max if new encoding");
uint64_t result = pd >> shift;
assert((result & CONST64(0xffffffff00000000)) == 0, "narrow klass pointer overflow");
assert(decode_klass(result) == v, "reversibility");
@@ -760,7 +761,7 @@ inline int oopDesc::oop_iterate_no_header(OopClosure* blk, MemRegion mr) {
ALL_OOP_OOP_ITERATE_CLOSURES_1(OOP_ITERATE_DEFN)
ALL_OOP_OOP_ITERATE_CLOSURES_2(OOP_ITERATE_DEFN)
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#define OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
\
inline int oopDesc::oop_iterate_backwards(OopClosureType* blk) { \
@@ -770,6 +771,6 @@ inline int oopDesc::oop_iterate_backwards(OopClosureType* blk) { \
ALL_OOP_OOP_ITERATE_CLOSURES_1(OOP_ITERATE_BACKWARDS_DEFN)
ALL_OOP_OOP_ITERATE_CLOSURES_2(OOP_ITERATE_BACKWARDS_DEFN)
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
#endif // SHARE_VM_OOPS_OOP_INLINE_HPP
diff --git a/src/share/vm/oops/oop.pcgc.inline.hpp b/src/share/vm/oops/oop.pcgc.inline.hpp
index 050678185..d8e40477f 100644
--- a/src/share/vm/oops/oop.pcgc.inline.hpp
+++ b/src/share/vm/oops/oop.pcgc.inline.hpp
@@ -25,14 +25,15 @@
#ifndef SHARE_VM_OOPS_OOP_PCGC_INLINE_HPP
#define SHARE_VM_OOPS_OOP_PCGC_INLINE_HPP
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/parNew/parNewGeneration.hpp"
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
#include "gc_implementation/parallelScavenge/psCompactionManager.hpp"
#include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
inline void oopDesc::update_contents(ParCompactionManager* cm) {
// The klass field must be updated before anything else
diff --git a/src/share/vm/oops/oop.psgc.inline.hpp b/src/share/vm/oops/oop.psgc.inline.hpp
index 4d8c3d63d..ea184f363 100644
--- a/src/share/vm/oops/oop.psgc.inline.hpp
+++ b/src/share/vm/oops/oop.psgc.inline.hpp
@@ -25,11 +25,12 @@
#ifndef SHARE_VM_OOPS_OOP_PSGC_INLINE_HPP
#define SHARE_VM_OOPS_OOP_PSGC_INLINE_HPP
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
// ParallelScavengeHeap methods
diff --git a/src/share/vm/oops/symbol.cpp b/src/share/vm/oops/symbol.cpp
index f2253dbcc..546018992 100644
--- a/src/share/vm/oops/symbol.cpp
+++ b/src/share/vm/oops/symbol.cpp
@@ -152,6 +152,7 @@ char* Symbol::as_C_string_flexible_buffer(Thread* t,
}
void Symbol::print_symbol_on(outputStream* st) const {
+ ResourceMark rm;
st = st ? st : tty;
st->print("%s", as_quoted_ascii());
}
diff --git a/src/share/vm/oops/typeArrayKlass.cpp b/src/share/vm/oops/typeArrayKlass.cpp
index 9b6ec260c..56863a024 100644
--- a/src/share/vm/oops/typeArrayKlass.cpp
+++ b/src/share/vm/oops/typeArrayKlass.cpp
@@ -39,6 +39,7 @@
#include "oops/typeArrayKlass.hpp"
#include "oops/typeArrayOop.hpp"
#include "runtime/handles.inline.hpp"
+#include "utilities/macros.hpp"
bool TypeArrayKlass::compute_is_subtype_of(Klass* k) {
if (!k->oop_is_typeArray()) {
@@ -208,13 +209,13 @@ void TypeArrayKlass::oop_follow_contents(oop obj) {
// know that Universe::TypeArrayKlass never moves.
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
void TypeArrayKlass::oop_follow_contents(ParCompactionManager* cm, oop obj) {
assert(obj->is_typeArray(),"must be a type array");
// Performance tweak: We skip iterating over the klass pointer since we
// know that Universe::TypeArrayKlass never moves.
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
int TypeArrayKlass::oop_adjust_pointers(oop obj) {
assert(obj->is_typeArray(),"must be a type array");
@@ -240,7 +241,7 @@ int TypeArrayKlass::oop_oop_iterate_m(oop obj, ExtendedOopClosure* blk, MemRegio
return t->object_size();
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
void TypeArrayKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
ShouldNotReachHere();
assert(obj->is_typeArray(),"must be a type array");
@@ -251,7 +252,7 @@ TypeArrayKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
assert(obj->is_typeArray(),"must be a type array");
return typeArrayOop(obj)->object_size();
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
void TypeArrayKlass::initialize(TRAPS) {
// Nothing to do. Having this function is handy since objArrayKlasses can be
diff --git a/src/share/vm/opto/bytecodeInfo.cpp b/src/share/vm/opto/bytecodeInfo.cpp
index 5b80bd75c..3da308c27 100644
--- a/src/share/vm/opto/bytecodeInfo.cpp
+++ b/src/share/vm/opto/bytecodeInfo.cpp
@@ -420,14 +420,24 @@ const char* InlineTree::check_can_parse(ciMethod* callee) {
}
//------------------------------print_inlining---------------------------------
-// Really, the failure_msg can be a success message also.
-void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci, const char* failure_msg) const {
- C->print_inlining(callee_method, inline_level(), caller_bci, failure_msg ? failure_msg : "inline");
- if (callee_method == NULL) tty->print(" callee not monotonic or profiled");
- if (Verbose && callee_method) {
- const InlineTree *top = this;
- while( top->caller_tree() != NULL ) { top = top->caller_tree(); }
- //tty->print(" bcs: %d+%d invoked: %d", top->count_inline_bcs(), callee_method->code_size(), callee_method->interpreter_invocation_count());
+void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci,
+ const char* msg, bool success) const {
+ assert(msg != NULL, "just checking");
+ if (C->log() != NULL) {
+ if (success) {
+ C->log()->inline_success(msg);
+ } else {
+ C->log()->inline_fail(msg);
+ }
+ }
+ if (PrintInlining) {
+ C->print_inlining(callee_method, inline_level(), caller_bci, msg);
+ if (callee_method == NULL) tty->print(" callee not monotonic or profiled");
+ if (Verbose && callee_method) {
+ const InlineTree *top = this;
+ while( top->caller_tree() != NULL ) { top = top->caller_tree(); }
+ //tty->print(" bcs: %d+%d invoked: %d", top->count_inline_bcs(), callee_method->code_size(), callee_method->interpreter_invocation_count());
+ }
}
}
@@ -451,23 +461,23 @@ WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms,
// Do some initial checks.
if (!pass_initial_checks(caller_method, caller_bci, callee_method)) {
- if (PrintInlining) print_inlining(callee_method, caller_bci, "failed initial checks");
+ print_inlining(callee_method, caller_bci, "failed initial checks",
+ false /* !success */);
return NULL;
}
// Do some parse checks.
failure_msg = check_can_parse(callee_method);
if (failure_msg != NULL) {
- if (PrintInlining) print_inlining(callee_method, caller_bci, failure_msg);
+ print_inlining(callee_method, caller_bci, failure_msg,
+ false /* !success */);
return NULL;
}
// Check if inlining policy says no.
WarmCallInfo wci = *(initial_wci);
- failure_msg = try_to_inline(callee_method, caller_method, caller_bci, profile, &wci, should_delay);
- if (failure_msg != NULL && C->log() != NULL) {
- C->log()->inline_fail(failure_msg);
- }
+ failure_msg = try_to_inline(callee_method, caller_method, caller_bci, profile,
+ &wci, should_delay);
#ifndef PRODUCT
if (UseOldInlining && InlineWarmCalls
@@ -487,7 +497,7 @@ WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms,
wci = *(WarmCallInfo::always_hot());
else
wci = *(WarmCallInfo::always_cold());
- }
+ }
if (!InlineWarmCalls) {
if (!wci.is_cold() && !wci.is_hot()) {
// Do not inline the warm calls.
@@ -496,11 +506,10 @@ WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms,
}
if (!wci.is_cold()) {
- // In -UseOldInlining, the failure_msg may also be a success message.
- if (failure_msg == NULL) failure_msg = "inline (hot)";
-
// Inline!
- if (PrintInlining) print_inlining(callee_method, caller_bci, failure_msg);
+ print_inlining(callee_method, caller_bci,
+ failure_msg ? failure_msg : "inline (hot)",
+ true /* success */);
if (UseOldInlining)
build_inline_tree_for_callee(callee_method, jvms, caller_bci);
if (InlineWarmCalls && !wci.is_hot())
@@ -509,8 +518,9 @@ WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms,
}
// Do not inline
- if (failure_msg == NULL) failure_msg = "too cold to inline";
- if (PrintInlining) print_inlining(callee_method, caller_bci, failure_msg);
+ print_inlining(callee_method, caller_bci,
+ failure_msg ? failure_msg : "too cold to inline",
+ false /* !success */ );
return NULL;
}
diff --git a/src/share/vm/opto/callGenerator.cpp b/src/share/vm/opto/callGenerator.cpp
index 89a7c46f6..8cac8ee76 100644
--- a/src/share/vm/opto/callGenerator.cpp
+++ b/src/share/vm/opto/callGenerator.cpp
@@ -305,11 +305,13 @@ class LateInlineCallGenerator : public DirectCallGenerator {
void LateInlineCallGenerator::do_late_inline() {
// Can't inline it
if (call_node() == NULL || call_node()->outcnt() == 0 ||
- call_node()->in(0) == NULL || call_node()->in(0)->is_top())
+ call_node()->in(0) == NULL || call_node()->in(0)->is_top()) {
return;
+ }
+ const TypeTuple *r = call_node()->tf()->domain();
for (int i1 = 0; i1 < method()->arg_size(); i1++) {
- if (call_node()->in(TypeFunc::Parms + i1)->is_top()) {
+ if (call_node()->in(TypeFunc::Parms + i1)->is_top() && r->field_at(TypeFunc::Parms + i1) != Type::HALF) {
assert(Compile::current()->inlining_incrementally(), "shouldn't happen during parsing");
return;
}
diff --git a/src/share/vm/opto/generateOptoStub.cpp b/src/share/vm/opto/generateOptoStub.cpp
index 56fc759f2..c5ebd5ad5 100644
--- a/src/share/vm/opto/generateOptoStub.cpp
+++ b/src/share/vm/opto/generateOptoStub.cpp
@@ -88,12 +88,12 @@ void GraphKit::gen_stub(address C_function,
thread,
in_bytes(JavaThread::frame_anchor_offset()) +
in_bytes(JavaFrameAnchor::last_Java_pc_offset()));
-#if defined(SPARC) || defined(IA64)
+#if defined(SPARC)
Node* adr_flags = basic_plus_adr(top(),
thread,
in_bytes(JavaThread::frame_anchor_offset()) +
in_bytes(JavaFrameAnchor::flags_offset()));
-#endif /* defined(SPARC) || defined(IA64) */
+#endif /* defined(SPARC) */
// Drop in the last_Java_sp. last_Java_fp is not touched.
@@ -102,10 +102,8 @@ void GraphKit::gen_stub(address C_function,
// users will look at the other fields.
//
Node *adr_sp = basic_plus_adr(top(), thread, in_bytes(JavaThread::last_Java_sp_offset()));
-#ifndef IA64
Node *last_sp = basic_plus_adr(top(), frameptr(), (intptr_t) STACK_BIAS);
store_to_memory(NULL, adr_sp, last_sp, T_ADDRESS, NoAlias);
-#endif
// Set _thread_in_native
// The order of stores into TLS is critical! Setting _thread_in_native MUST
@@ -210,19 +208,12 @@ void GraphKit::gen_stub(address C_function,
//-----------------------------
// Clear last_Java_sp
-#ifdef IA64
- if( os::is_MP() ) insert_mem_bar(Op_MemBarRelease);
-#endif
-
store_to_memory(NULL, adr_sp, null(), T_ADDRESS, NoAlias);
-#ifdef IA64
- if (os::is_MP() && UseMembar) insert_mem_bar(new MemBarVolatileNode());
-#endif // def IA64
// Clear last_Java_pc and (optionally)_flags
store_to_memory(NULL, adr_last_Java_pc, null(), T_ADDRESS, NoAlias);
-#if defined(SPARC) || defined(IA64)
+#if defined(SPARC)
store_to_memory(NULL, adr_flags, intcon(0), T_INT, NoAlias);
-#endif /* defined(SPARC) || defined(IA64) */
+#endif /* defined(SPARC) */
#ifdef IA64
Node* adr_last_Java_fp = basic_plus_adr(top(), thread, in_bytes(JavaThread::last_Java_fp_offset()));
if( os::is_MP() ) insert_mem_bar(Op_MemBarRelease);
diff --git a/src/share/vm/opto/parse.hpp b/src/share/vm/opto/parse.hpp
index c880832a4..2cf487f8a 100644
--- a/src/share/vm/opto/parse.hpp
+++ b/src/share/vm/opto/parse.hpp
@@ -73,7 +73,8 @@ protected:
const char* try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result, bool& should_delay);
const char* should_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const;
const char* should_not_inline(ciMethod* callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const;
- void print_inlining(ciMethod *callee_method, int caller_bci, const char *failure_msg) const;
+ void print_inlining(ciMethod* callee_method, int caller_bci,
+ const char* msg, bool success) const;
InlineTree *caller_tree() const { return _caller_tree; }
InlineTree* callee_at(int bci, ciMethod* m) const;
diff --git a/src/share/vm/opto/parse3.cpp b/src/share/vm/opto/parse3.cpp
index ac6f4ec8f..9de92a2ae 100644
--- a/src/share/vm/opto/parse3.cpp
+++ b/src/share/vm/opto/parse3.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -487,7 +487,8 @@ void Parse::do_multianewarray() {
fun, NULL, TypeRawPtr::BOTTOM,
makecon(TypeKlassPtr::make(array_klass)),
length[0], length[1], length[2],
- length[3], length[4]);
+ (ndimensions > 2) ? length[3] : NULL,
+ (ndimensions > 3) ? length[4] : NULL);
} else {
// Create a java array for dimension sizes
Node* dims = NULL;
diff --git a/src/share/vm/precompiled/precompiled.hpp b/src/share/vm/precompiled/precompiled.hpp
index 1bbc5599b..118fe9c1b 100644
--- a/src/share/vm/precompiled/precompiled.hpp
+++ b/src/share/vm/precompiled/precompiled.hpp
@@ -24,6 +24,7 @@
// Precompiled headers are turned off for Sun Studion,
// or if the user passes USE_PRECOMPILED_HEADER=0 to the makefiles.
+
#ifndef DONT_USE_PRECOMPILED_HEADER
# include "asm/assembler.hpp"
@@ -285,7 +286,7 @@
# include "c1/c1_ValueType.hpp"
# include "c1/c1_globals.hpp"
#endif // COMPILER1
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
# include "gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp"
# include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
# include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp"
@@ -314,6 +315,6 @@
# include "gc_implementation/shared/gcAdaptivePolicyCounters.hpp"
# include "gc_implementation/shared/gcPolicyCounters.hpp"
# include "gc_implementation/shared/parGCAllocBuffer.hpp"
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
#endif // !DONT_USE_PRECOMPILED_HEADER
diff --git a/src/share/vm/prims/jni.cpp b/src/share/vm/prims/jni.cpp
index ddbde753f..f45568a7c 100644
--- a/src/share/vm/prims/jni.cpp
+++ b/src/share/vm/prims/jni.cpp
@@ -32,9 +32,10 @@
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "interpreter/linkResolver.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
#include "memory/allocation.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/gcLocker.inline.hpp"
@@ -2641,7 +2642,7 @@ JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID
o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
}
jobject ret = JNIHandles::make_local(env, o->obj_field(offset));
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// If G1 is enabled and we are accessing the value of the referent
// field in a reference object then we need to register a non-null
// referent with the SATB barrier.
@@ -2660,7 +2661,7 @@ JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID
G1SATBCardTableModRefBS::enqueue(referent);
}
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
#ifndef USDT2
DTRACE_PROBE1(hotspot_jni, GetObjectField__return, ret);
#else /* USDT2 */
diff --git a/src/share/vm/prims/jniCheck.hpp b/src/share/vm/prims/jniCheck.hpp
index e5f5071b3..169ab7be3 100644
--- a/src/share/vm/prims/jniCheck.hpp
+++ b/src/share/vm/prims/jniCheck.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -25,9 +25,7 @@
#ifndef SHARE_VM_PRIMS_JNICHECK_HPP
#define SHARE_VM_PRIMS_JNICHECK_HPP
-#ifndef KERNEL
#include "runtime/thread.hpp"
-#endif
extern "C" {
// Report a JNI failure caught by -Xcheck:jni. Perform a core dump.
diff --git a/src/share/vm/prims/jvm.cpp b/src/share/vm/prims/jvm.cpp
index f5d126368..84ab5f048 100644
--- a/src/share/vm/prims/jvm.cpp
+++ b/src/share/vm/prims/jvm.cpp
@@ -1620,7 +1620,7 @@ JVM_ENTRY(jobjectArray, JVM_GetMethodParameters(JNIEnv *env, jobject method))
// For a 0 index, give a NULL symbol
Symbol* const sym = 0 != params[i].name_cp_index ?
mh->constants()->symbol_at(params[i].name_cp_index) : NULL;
- int flags = build_int_from_shorts(params[i].flags_lo, params[i].flags_hi);
+ int flags = params[i].flags;
oop param = Reflection::new_parameter(reflected_method, i, sym,
flags, CHECK_NULL);
result->obj_at_put(i, param);
@@ -2302,6 +2302,15 @@ JVM_QUICK_ENTRY(jboolean, JVM_IsConstructorIx(JNIEnv *env, jclass cls, int metho
JVM_END
+JVM_QUICK_ENTRY(jboolean, JVM_IsVMGeneratedMethodIx(JNIEnv *env, jclass cls, int method_index))
+ JVMWrapper("JVM_IsVMGeneratedMethodIx");
+ ResourceMark rm(THREAD);
+ Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
+ k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);
+ Method* method = InstanceKlass::cast(k)->methods()->at(method_index);
+ return method->is_overpass();
+JVM_END
+
JVM_ENTRY(const char*, JVM_GetMethodIxNameUTF(JNIEnv *env, jclass cls, jint method_index))
JVMWrapper("JVM_GetMethodIxIxUTF");
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
@@ -4519,10 +4528,6 @@ JVM_ENTRY(void, JVM_GetVersionInfo(JNIEnv* env, jvm_version_info* info, size_t i
// consider to expose this new capability in the sun.rt.jvmCapabilities jvmstat
// counter defined in runtimeService.cpp.
info->is_attachable = AttachListener::is_attach_supported();
-#ifdef KERNEL
- info->is_kernel_jvm = 1; // true;
-#else // KERNEL
info->is_kernel_jvm = 0; // false;
-#endif // KERNEL
}
JVM_END
diff --git a/src/share/vm/prims/jvm.h b/src/share/vm/prims/jvm.h
index c081f872a..dea46d126 100644
--- a/src/share/vm/prims/jvm.h
+++ b/src/share/vm/prims/jvm.h
@@ -860,6 +860,13 @@ JNIEXPORT jboolean JNICALL
JVM_IsConstructorIx(JNIEnv *env, jclass cb, int index);
/*
+ * Is the given method generated by the VM.
+ * The method is identified by method_index.
+ */
+JNIEXPORT jboolean JNICALL
+JVM_IsVMGeneratedMethodIx(JNIEnv *env, jclass cb, int index);
+
+/*
* Returns the name of a given method in UTF format.
* The result remains valid until JVM_ReleaseUTF is called.
*
diff --git a/src/share/vm/prims/jvmtiCodeBlobEvents.hpp b/src/share/vm/prims/jvmtiCodeBlobEvents.hpp
index 92adaaf80..00da7ca6c 100644
--- a/src/share/vm/prims/jvmtiCodeBlobEvents.hpp
+++ b/src/share/vm/prims/jvmtiCodeBlobEvents.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -25,9 +25,7 @@
#ifndef SHARE_VM_PRIMS_JVMTICODEBLOBEVENTS_HPP
#define SHARE_VM_PRIMS_JVMTICODEBLOBEVENTS_HPP
-#ifndef JVMTI_KERNEL
#include "jvmtifiles/jvmti.h"
-#endif
// forward declaration
class JvmtiEnv;
diff --git a/src/share/vm/prims/jvmtiEnv.cpp b/src/share/vm/prims/jvmtiEnv.cpp
index cb3b3db1e..318fe4e0b 100644
--- a/src/share/vm/prims/jvmtiEnv.cpp
+++ b/src/share/vm/prims/jvmtiEnv.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -647,8 +647,6 @@ JvmtiEnv::GetJLocationFormat(jvmtiJlocationFormat* format_ptr) {
return JVMTI_ERROR_NONE;
} /* end GetJLocationFormat */
-#ifndef JVMTI_KERNEL
-
//
// Thread functions
//
@@ -3436,5 +3434,3 @@ JvmtiEnv::SetSystemProperty(const char* property, const char* value_ptr) {
}
return err;
} /* end SetSystemProperty */
-
-#endif // !JVMTI_KERNEL
diff --git a/src/share/vm/prims/jvmtiEnvBase.cpp b/src/share/vm/prims/jvmtiEnvBase.cpp
index eed312681..563876341 100644
--- a/src/share/vm/prims/jvmtiEnvBase.cpp
+++ b/src/share/vm/prims/jvmtiEnvBase.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -74,10 +74,8 @@ JvmtiEnvBase::globally_initialize() {
JvmtiManageCapabilities::initialize();
-#ifndef JVMTI_KERNEL
// register extension functions and events
JvmtiExtensions::register_extensions();
-#endif // !JVMTI_KERNEL
#ifdef JVMTI_TRACE
JvmtiTrace::initialize();
@@ -236,14 +234,12 @@ JvmtiEnvBase::env_dispose() {
// Same situation as with events (see above)
set_native_method_prefixes(0, NULL);
-#ifndef JVMTI_KERNEL
JvmtiTagMap* tag_map_to_deallocate = _tag_map;
set_tag_map(NULL);
// A tag map can be big, deallocate it now
if (tag_map_to_deallocate != NULL) {
delete tag_map_to_deallocate;
}
-#endif // !JVMTI_KERNEL
_needs_clean_up = true;
}
@@ -255,14 +251,12 @@ JvmtiEnvBase::~JvmtiEnvBase() {
// There is a small window of time during which the tag map of a
// disposed environment could have been reallocated.
// Make sure it is gone.
-#ifndef JVMTI_KERNEL
JvmtiTagMap* tag_map_to_deallocate = _tag_map;
set_tag_map(NULL);
// A tag map can be big, deallocate it now
if (tag_map_to_deallocate != NULL) {
delete tag_map_to_deallocate;
}
-#endif // !JVMTI_KERNEL
_magic = BAD_MAGIC;
}
@@ -593,8 +587,6 @@ JvmtiEnvBase::get_jni_class_non_null(Klass* k) {
return (jclass)jni_reference(k->java_mirror());
}
-#ifndef JVMTI_KERNEL
-
//
// Field Information
//
@@ -1482,5 +1474,3 @@ JvmtiMonitorClosure::do_monitor(ObjectMonitor* mon) {
}
}
}
-
-#endif // !JVMTI_KERNEL
diff --git a/src/share/vm/prims/jvmtiEnvBase.hpp b/src/share/vm/prims/jvmtiEnvBase.hpp
index d7b7d7cf6..929dcf222 100644
--- a/src/share/vm/prims/jvmtiEnvBase.hpp
+++ b/src/share/vm/prims/jvmtiEnvBase.hpp
@@ -35,6 +35,7 @@
#include "runtime/thread.hpp"
#include "runtime/vm_operations.hpp"
#include "utilities/growableArray.hpp"
+#include "utilities/macros.hpp"
//
// Forward Declarations
diff --git a/src/share/vm/prims/jvmtiExport.cpp b/src/share/vm/prims/jvmtiExport.cpp
index cb5a1f454..ab66dca33 100644
--- a/src/share/vm/prims/jvmtiExport.cpp
+++ b/src/share/vm/prims/jvmtiExport.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -50,9 +50,10 @@
#include "runtime/vframe.hpp"
#include "services/attachListener.hpp"
#include "services/serviceUtil.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/parallelScavenge/psMarkSweep.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
#ifdef JVMTI_TRACE
#define EVT_TRACE(evt,out) if ((JvmtiTrace::event_trace_flags(evt) & JvmtiTrace::SHOW_EVENT_SENT) != 0) { SafeResourceMark rm; tty->print_cr out; }
@@ -677,7 +678,6 @@ void JvmtiExport::report_unsupported(bool on) {
}
-#ifndef JVMTI_KERNEL
static inline Klass* oop_to_klass(oop obj) {
Klass* k = obj->klass();
@@ -2178,7 +2178,6 @@ extern "C" {
typedef jint (JNICALL *OnAttachEntry_t)(JavaVM*, char *, void *);
}
-#ifndef SERVICES_KERNEL
jint JvmtiExport::load_agent_library(AttachOperation* op, outputStream* st) {
char ebuf[1024];
char buffer[JVM_MAXPATHLEN];
@@ -2259,7 +2258,6 @@ jint JvmtiExport::load_agent_library(AttachOperation* op, outputStream* st) {
}
return result;
}
-#endif // SERVICES_KERNEL
////////////////////////////////////////////////////////////////////////////////////////////////
@@ -2457,4 +2455,3 @@ JvmtiGCMarker::~JvmtiGCMarker() {
JvmtiExport::post_garbage_collection_finish();
}
}
-#endif // JVMTI_KERNEL
diff --git a/src/share/vm/prims/jvmtiExport.hpp b/src/share/vm/prims/jvmtiExport.hpp
index 1100d5269..a1e0e0bd4 100644
--- a/src/share/vm/prims/jvmtiExport.hpp
+++ b/src/share/vm/prims/jvmtiExport.hpp
@@ -34,6 +34,7 @@
#include "runtime/handles.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/growableArray.hpp"
+#include "utilities/macros.hpp"
// Must be included after jvmti.h.
#include "code/jvmticmlr.h"
diff --git a/src/share/vm/prims/jvmtiExtensions.hpp b/src/share/vm/prims/jvmtiExtensions.hpp
index a5e343331..f85003f6b 100644
--- a/src/share/vm/prims/jvmtiExtensions.hpp
+++ b/src/share/vm/prims/jvmtiExtensions.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -25,11 +25,9 @@
#ifndef SHARE_VM_PRIMS_JVMTIEXTENSIONS_HPP
#define SHARE_VM_PRIMS_JVMTIEXTENSIONS_HPP
-#ifndef JVMTI_KERNEL
#include "jvmtifiles/jvmti.h"
#include "jvmtifiles/jvmtiEnv.hpp"
#include "memory/allocation.hpp"
-#endif
// JvmtiExtensions
//
diff --git a/src/share/vm/prims/jvmtiImpl.cpp b/src/share/vm/prims/jvmtiImpl.cpp
index bb7714d49..4a1747e1b 100644
--- a/src/share/vm/prims/jvmtiImpl.cpp
+++ b/src/share/vm/prims/jvmtiImpl.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -905,8 +905,6 @@ void JvmtiSuspendControl::print() {
#endif
}
-#ifndef KERNEL
-
JvmtiDeferredEvent JvmtiDeferredEvent::compiled_method_load_event(
nmethod* nm) {
JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_LOAD);
@@ -1098,5 +1096,3 @@ void JvmtiDeferredEventQueue::process_pending_events() {
}
}
}
-
-#endif // ndef KERNEL
diff --git a/src/share/vm/prims/jvmtiImpl.hpp b/src/share/vm/prims/jvmtiImpl.hpp
index d785930be..204bd83f1 100644
--- a/src/share/vm/prims/jvmtiImpl.hpp
+++ b/src/share/vm/prims/jvmtiImpl.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -25,8 +25,6 @@
#ifndef SHARE_VM_PRIMS_JVMTIIMPL_HPP
#define SHARE_VM_PRIMS_JVMTIIMPL_HPP
-#ifndef JVMTI_KERNEL
-
#include "classfile/systemDictionary.hpp"
#include "jvmtifiles/jvmti.h"
#include "oops/objArrayOop.hpp"
@@ -435,7 +433,6 @@ public:
static void print();
};
-#endif // !JVMTI_KERNEL
/**
* When a thread (such as the compiler thread or VM thread) cannot post a
diff --git a/src/share/vm/prims/jvmtiRawMonitor.hpp b/src/share/vm/prims/jvmtiRawMonitor.hpp
index e5b25fa3a..8c182f318 100644
--- a/src/share/vm/prims/jvmtiRawMonitor.hpp
+++ b/src/share/vm/prims/jvmtiRawMonitor.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -25,10 +25,8 @@
#ifndef SHARE_VM_PRIMS_JVMTIRAWMONITOR_HPP
#define SHARE_VM_PRIMS_JVMTIRAWMONITOR_HPP
-#ifndef JVMTI_KERNEL
#include "runtime/objectMonitor.hpp"
#include "utilities/growableArray.hpp"
-#endif
//
// class JvmtiRawMonitor
diff --git a/src/share/vm/prims/jvmtiRedefineClasses.cpp b/src/share/vm/prims/jvmtiRedefineClasses.cpp
index 7e68f2b10..ce1ec56ef 100644
--- a/src/share/vm/prims/jvmtiRedefineClasses.cpp
+++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "classfile/metadataOnStackMark.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/verifier.hpp"
#include "code/codeCache.hpp"
@@ -115,43 +116,6 @@ bool VM_RedefineClasses::doit_prologue() {
return true;
}
-// Keep track of marked on-stack metadata so it can be cleared.
-GrowableArray<Metadata*>* _marked_objects = NULL;
-NOT_PRODUCT(bool MetadataOnStackMark::_is_active = false;)
-
-// Walk metadata on the stack and mark it so that redefinition doesn't delete
-// it. Class unloading also walks the previous versions and might try to
-// delete it, so this class is used by class unloading also.
-MetadataOnStackMark::MetadataOnStackMark() {
- assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
- NOT_PRODUCT(_is_active = true;)
- if (_marked_objects == NULL) {
- _marked_objects = new (ResourceObj::C_HEAP, mtClass) GrowableArray<Metadata*>(1000, true);
- }
- Threads::metadata_do(Metadata::mark_on_stack);
- CodeCache::alive_nmethods_do(nmethod::mark_on_stack);
- CompileBroker::mark_on_stack();
-}
-
-MetadataOnStackMark::~MetadataOnStackMark() {
- assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
- // Unmark everything that was marked. Can't do the same walk because
- // redefine classes messes up the code cache so the set of methods
- // might not be the same.
- for (int i = 0; i< _marked_objects->length(); i++) {
- _marked_objects->at(i)->set_on_stack(false);
- }
- _marked_objects->clear(); // reuse growable array for next time.
- NOT_PRODUCT(_is_active = false;)
-}
-
-// Record which objects are marked so we can unmark the same objects.
-void MetadataOnStackMark::record(Metadata* m) {
- assert(_is_active, "metadata on stack marking is active");
- _marked_objects->push(m);
-}
-
-
void VM_RedefineClasses::doit() {
Thread *thread = Thread::current();
@@ -314,76 +278,23 @@ void VM_RedefineClasses::append_entry(constantPoolHandle scratch_cp,
case JVM_CONSTANT_NameAndType:
{
int name_ref_i = scratch_cp->name_ref_index_at(scratch_i);
- int new_name_ref_i = 0;
- bool match = (name_ref_i < *merge_cp_length_p) &&
- scratch_cp->compare_entry_to(name_ref_i, *merge_cp_p, name_ref_i,
- THREAD);
- if (!match) {
- // forward reference in *merge_cp_p or not a direct match
-
- int found_i = scratch_cp->find_matching_entry(name_ref_i, *merge_cp_p,
- THREAD);
- if (found_i != 0) {
- guarantee(found_i != name_ref_i,
- "compare_entry_to() and find_matching_entry() do not agree");
-
- // Found a matching entry somewhere else in *merge_cp_p so
- // just need a mapping entry.
- new_name_ref_i = found_i;
- map_index(scratch_cp, name_ref_i, found_i);
- } else {
- // no match found so we have to append this entry to *merge_cp_p
- append_entry(scratch_cp, name_ref_i, merge_cp_p, merge_cp_length_p,
- THREAD);
- // The above call to append_entry() can only append one entry
- // so the post call query of *merge_cp_length_p is only for
- // the sake of consistency.
- new_name_ref_i = *merge_cp_length_p - 1;
- }
- }
+ int new_name_ref_i = find_or_append_indirect_entry(scratch_cp, name_ref_i, merge_cp_p,
+ merge_cp_length_p, THREAD);
int signature_ref_i = scratch_cp->signature_ref_index_at(scratch_i);
- int new_signature_ref_i = 0;
- match = (signature_ref_i < *merge_cp_length_p) &&
- scratch_cp->compare_entry_to(signature_ref_i, *merge_cp_p,
- signature_ref_i, THREAD);
- if (!match) {
- // forward reference in *merge_cp_p or not a direct match
-
- int found_i = scratch_cp->find_matching_entry(signature_ref_i,
- *merge_cp_p, THREAD);
- if (found_i != 0) {
- guarantee(found_i != signature_ref_i,
- "compare_entry_to() and find_matching_entry() do not agree");
-
- // Found a matching entry somewhere else in *merge_cp_p so
- // just need a mapping entry.
- new_signature_ref_i = found_i;
- map_index(scratch_cp, signature_ref_i, found_i);
- } else {
- // no match found so we have to append this entry to *merge_cp_p
- append_entry(scratch_cp, signature_ref_i, merge_cp_p,
- merge_cp_length_p, THREAD);
- // The above call to append_entry() can only append one entry
- // so the post call query of *merge_cp_length_p is only for
- // the sake of consistency.
- new_signature_ref_i = *merge_cp_length_p - 1;
- }
- }
+ int new_signature_ref_i = find_or_append_indirect_entry(scratch_cp, signature_ref_i,
+ merge_cp_p, merge_cp_length_p,
+ THREAD);
// If the referenced entries already exist in *merge_cp_p, then
// both new_name_ref_i and new_signature_ref_i will both be 0.
// In that case, all we are appending is the current entry.
- if (new_name_ref_i == 0) {
- new_name_ref_i = name_ref_i;
- } else {
+ if (new_name_ref_i != name_ref_i) {
RC_TRACE(0x00080000,
("NameAndType entry@%d name_ref_index change: %d to %d",
*merge_cp_length_p, name_ref_i, new_name_ref_i));
}
- if (new_signature_ref_i == 0) {
- new_signature_ref_i = signature_ref_i;
- } else {
+ if (new_signature_ref_i != signature_ref_i) {
RC_TRACE(0x00080000,
("NameAndType entry@%d signature_ref_index change: %d to %d",
*merge_cp_length_p, signature_ref_i, new_signature_ref_i));
@@ -405,76 +316,12 @@ void VM_RedefineClasses::append_entry(constantPoolHandle scratch_cp,
case JVM_CONSTANT_Methodref:
{
int klass_ref_i = scratch_cp->uncached_klass_ref_index_at(scratch_i);
- int new_klass_ref_i = 0;
- bool match = (klass_ref_i < *merge_cp_length_p) &&
- scratch_cp->compare_entry_to(klass_ref_i, *merge_cp_p, klass_ref_i,
- THREAD);
- if (!match) {
- // forward reference in *merge_cp_p or not a direct match
-
- int found_i = scratch_cp->find_matching_entry(klass_ref_i, *merge_cp_p,
- THREAD);
- if (found_i != 0) {
- guarantee(found_i != klass_ref_i,
- "compare_entry_to() and find_matching_entry() do not agree");
-
- // Found a matching entry somewhere else in *merge_cp_p so
- // just need a mapping entry.
- new_klass_ref_i = found_i;
- map_index(scratch_cp, klass_ref_i, found_i);
- } else {
- // no match found so we have to append this entry to *merge_cp_p
- append_entry(scratch_cp, klass_ref_i, merge_cp_p, merge_cp_length_p,
- THREAD);
- // The above call to append_entry() can only append one entry
- // so the post call query of *merge_cp_length_p is only for
- // the sake of consistency. Without the optimization where we
- // use JVM_CONSTANT_UnresolvedClass, then up to two entries
- // could be appended.
- new_klass_ref_i = *merge_cp_length_p - 1;
- }
- }
+ int new_klass_ref_i = find_or_append_indirect_entry(scratch_cp, klass_ref_i,
+ merge_cp_p, merge_cp_length_p, THREAD);
- int name_and_type_ref_i =
- scratch_cp->uncached_name_and_type_ref_index_at(scratch_i);
- int new_name_and_type_ref_i = 0;
- match = (name_and_type_ref_i < *merge_cp_length_p) &&
- scratch_cp->compare_entry_to(name_and_type_ref_i, *merge_cp_p,
- name_and_type_ref_i, THREAD);
- if (!match) {
- // forward reference in *merge_cp_p or not a direct match
-
- int found_i = scratch_cp->find_matching_entry(name_and_type_ref_i,
- *merge_cp_p, THREAD);
- if (found_i != 0) {
- guarantee(found_i != name_and_type_ref_i,
- "compare_entry_to() and find_matching_entry() do not agree");
-
- // Found a matching entry somewhere else in *merge_cp_p so
- // just need a mapping entry.
- new_name_and_type_ref_i = found_i;
- map_index(scratch_cp, name_and_type_ref_i, found_i);
- } else {
- // no match found so we have to append this entry to *merge_cp_p
- append_entry(scratch_cp, name_and_type_ref_i, merge_cp_p,
- merge_cp_length_p, THREAD);
- // The above call to append_entry() can append more than
- // one entry so the post call query of *merge_cp_length_p
- // is required in order to get the right index for the
- // JVM_CONSTANT_NameAndType entry.
- new_name_and_type_ref_i = *merge_cp_length_p - 1;
- }
- }
-
- // If the referenced entries already exist in *merge_cp_p, then
- // both new_klass_ref_i and new_name_and_type_ref_i will both be
- // 0. In that case, all we are appending is the current entry.
- if (new_klass_ref_i == 0) {
- new_klass_ref_i = klass_ref_i;
- }
- if (new_name_and_type_ref_i == 0) {
- new_name_and_type_ref_i = name_and_type_ref_i;
- }
+ int name_and_type_ref_i = scratch_cp->uncached_name_and_type_ref_index_at(scratch_i);
+ int new_name_and_type_ref_i = find_or_append_indirect_entry(scratch_cp, name_and_type_ref_i,
+ merge_cp_p, merge_cp_length_p, THREAD);
const char *entry_name;
switch (scratch_cp->tag_at(scratch_i).value()) {
@@ -517,6 +364,72 @@ void VM_RedefineClasses::append_entry(constantPoolHandle scratch_cp,
(*merge_cp_length_p)++;
} break;
+ // this is an indirect CP entry so it needs special handling
+ case JVM_CONSTANT_MethodType:
+ {
+ int ref_i = scratch_cp->method_type_index_at(scratch_i);
+ int new_ref_i = find_or_append_indirect_entry(scratch_cp, ref_i, merge_cp_p,
+ merge_cp_length_p, THREAD);
+ if (new_ref_i != ref_i) {
+ RC_TRACE(0x00080000,
+ ("MethodType entry@%d ref_index change: %d to %d",
+ *merge_cp_length_p, ref_i, new_ref_i));
+ }
+ (*merge_cp_p)->method_type_index_at_put(*merge_cp_length_p, new_ref_i);
+ if (scratch_i != *merge_cp_length_p) {
+ // The new entry in *merge_cp_p is at a different index than
+ // the new entry in scratch_cp so we need to map the index values.
+ map_index(scratch_cp, scratch_i, *merge_cp_length_p);
+ }
+ (*merge_cp_length_p)++;
+ } break;
+
+ // this is an indirect CP entry so it needs special handling
+ case JVM_CONSTANT_MethodHandle:
+ {
+ int ref_kind = scratch_cp->method_handle_ref_kind_at(scratch_i);
+ int ref_i = scratch_cp->method_handle_index_at(scratch_i);
+ int new_ref_i = find_or_append_indirect_entry(scratch_cp, ref_i, merge_cp_p,
+ merge_cp_length_p, THREAD);
+ if (new_ref_i != ref_i) {
+ RC_TRACE(0x00080000,
+ ("MethodHandle entry@%d ref_index change: %d to %d",
+ *merge_cp_length_p, ref_i, new_ref_i));
+ }
+ (*merge_cp_p)->method_handle_index_at_put(*merge_cp_length_p, ref_kind, new_ref_i);
+ if (scratch_i != *merge_cp_length_p) {
+ // The new entry in *merge_cp_p is at a different index than
+ // the new entry in scratch_cp so we need to map the index values.
+ map_index(scratch_cp, scratch_i, *merge_cp_length_p);
+ }
+ (*merge_cp_length_p)++;
+ } break;
+
+ // this is an indirect CP entry so it needs special handling
+ case JVM_CONSTANT_InvokeDynamic:
+ {
+ // TBD: cross-checks and possible extra appends into CP and bsm operands
+ // are needed as well. This issue is tracked by a separate bug 8007037.
+ int bss_idx = scratch_cp->invoke_dynamic_bootstrap_specifier_index(scratch_i);
+
+ int ref_i = scratch_cp->invoke_dynamic_name_and_type_ref_index_at(scratch_i);
+ int new_ref_i = find_or_append_indirect_entry(scratch_cp, ref_i, merge_cp_p,
+ merge_cp_length_p, THREAD);
+ if (new_ref_i != ref_i) {
+ RC_TRACE(0x00080000,
+ ("InvokeDynamic entry@%d name_and_type ref_index change: %d to %d",
+ *merge_cp_length_p, ref_i, new_ref_i));
+ }
+
+ (*merge_cp_p)->invoke_dynamic_at_put(*merge_cp_length_p, bss_idx, new_ref_i);
+ if (scratch_i != *merge_cp_length_p) {
+ // The new entry in *merge_cp_p is at a different index than
+ // the new entry in scratch_cp so we need to map the index values.
+ map_index(scratch_cp, scratch_i, *merge_cp_length_p);
+ }
+ (*merge_cp_length_p)++;
+ } break;
+
// At this stage, Class or UnresolvedClass could be here, but not
// ClassIndex
case JVM_CONSTANT_ClassIndex: // fall through
@@ -543,6 +456,35 @@ void VM_RedefineClasses::append_entry(constantPoolHandle scratch_cp,
} // end append_entry()
+int VM_RedefineClasses::find_or_append_indirect_entry(constantPoolHandle scratch_cp,
+ int ref_i, constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS) {
+
+ int new_ref_i = ref_i;
+ bool match = (ref_i < *merge_cp_length_p) &&
+ scratch_cp->compare_entry_to(ref_i, *merge_cp_p, ref_i, THREAD);
+
+ if (!match) {
+ // forward reference in *merge_cp_p or not a direct match
+ int found_i = scratch_cp->find_matching_entry(ref_i, *merge_cp_p, THREAD);
+ if (found_i != 0) {
+ guarantee(found_i != ref_i, "compare_entry_to() and find_matching_entry() do not agree");
+ // Found a matching entry somewhere else in *merge_cp_p so just need a mapping entry.
+ new_ref_i = found_i;
+ map_index(scratch_cp, ref_i, found_i);
+ } else {
+ // no match found so we have to append this entry to *merge_cp_p
+ append_entry(scratch_cp, ref_i, merge_cp_p, merge_cp_length_p, THREAD);
+ // The above call to append_entry() can only append one entry
+ // so the post call query of *merge_cp_length_p is only for
+ // the sake of consistency.
+ new_ref_i = *merge_cp_length_p - 1;
+ }
+ }
+
+ return new_ref_i;
+} // end find_or_append_indirect_entry()
+
+
void VM_RedefineClasses::swap_all_method_annotations(int i, int j, instanceKlassHandle scratch_class, TRAPS) {
AnnotationArray* save;
@@ -1158,6 +1100,8 @@ bool VM_RedefineClasses::merge_constant_pools(constantPoolHandle old_cp,
}
} // end for each old_cp entry
+ ConstantPool::copy_operands(old_cp, *merge_cp_p, CHECK_0);
+
// We don't need to sanity check that *merge_cp_length_p is within
// *merge_cp_p bounds since we have the minimum on-entry check above.
(*merge_cp_length_p) = old_i;
@@ -1341,8 +1285,12 @@ jvmtiError VM_RedefineClasses::merge_cp_and_rewrite(
_index_map_count = 0;
_index_map_p = new intArray(scratch_cp->length(), -1);
+ // reference to the cp holder is needed for copy_operands()
+ merge_cp->set_pool_holder(scratch_class());
bool result = merge_constant_pools(old_cp, scratch_cp, &merge_cp,
&merge_cp_length, THREAD);
+ merge_cp->set_pool_holder(NULL);
+
if (!result) {
// The merge can fail due to memory allocation failure or due
// to robustness checks.
@@ -1594,6 +1542,7 @@ void VM_RedefineClasses::rewrite_cp_refs_in_method(methodHandle method,
case Bytecodes::_getfield : // fall through
case Bytecodes::_getstatic : // fall through
case Bytecodes::_instanceof : // fall through
+ case Bytecodes::_invokedynamic : // fall through
case Bytecodes::_invokeinterface: // fall through
case Bytecodes::_invokespecial : // fall through
case Bytecodes::_invokestatic : // fall through
@@ -2416,13 +2365,14 @@ void VM_RedefineClasses::set_new_constant_pool(
assert(version != 0, "sanity check");
smaller_cp->set_version(version);
+ // attach klass to new constant pool
+ // reference to the cp holder is needed for copy_operands()
+ smaller_cp->set_pool_holder(scratch_class());
+
scratch_cp->copy_cp_to(1, scratch_cp_length - 1, smaller_cp, 1, THREAD);
scratch_cp = smaller_cp;
// attach new constant pool to klass
- scratch_cp->set_pool_holder(scratch_class());
-
- // attach klass to new constant pool
scratch_class->set_constants(scratch_cp());
int i; // for portability
@@ -3140,11 +3090,9 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass,
Klass* the_class_oop = java_lang_Class::as_Klass(the_class_mirror);
instanceKlassHandle the_class = instanceKlassHandle(THREAD, the_class_oop);
-#ifndef JVMTI_KERNEL
// Remove all breakpoints in methods of this class
JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints();
jvmti_breakpoints.clearall_in_class_at_safepoint(the_class_oop);
-#endif // !JVMTI_KERNEL
if (the_class_oop == Universe::reflect_invoke_cache()->klass()) {
// We are redefining java.lang.reflect.Method. Method.invoke() is
diff --git a/src/share/vm/prims/jvmtiRedefineClasses.hpp b/src/share/vm/prims/jvmtiRedefineClasses.hpp
index 7164413c8..d348ed2c7 100644
--- a/src/share/vm/prims/jvmtiRedefineClasses.hpp
+++ b/src/share/vm/prims/jvmtiRedefineClasses.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -421,10 +421,11 @@ class VM_RedefineClasses: public VM_Operation {
// and in all direct and indirect subclasses.
void increment_class_counter(InstanceKlass *ik, TRAPS);
- // Support for constant pool merging (these routines are in alpha
- // order):
+ // Support for constant pool merging (these routines are in alpha order):
void append_entry(constantPoolHandle scratch_cp, int scratch_i,
constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS);
+ int find_or_append_indirect_entry(constantPoolHandle scratch_cp, int scratch_i,
+ constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS);
int find_new_index(int old_index);
bool is_unresolved_class_mismatch(constantPoolHandle cp1, int index1,
constantPoolHandle cp2, int index2);
@@ -487,17 +488,4 @@ class VM_RedefineClasses: public VM_Operation {
// and redefine implementation
static bool is_modifiable_class(oop klass_mirror);
};
-
-
-// Helper class to mark and unmark metadata used on the stack as either handles
-// or executing methods, so that it can't be deleted during class redefinition
-// and class unloading.
-class MetadataOnStackMark : public StackObj {
- NOT_PRODUCT(static bool _is_active;)
- public:
- MetadataOnStackMark() NOT_JVMTI_RETURN;
- ~MetadataOnStackMark() NOT_JVMTI_RETURN;
- static void record(Metadata* m) NOT_JVMTI_RETURN;
-};
-
#endif // SHARE_VM_PRIMS_JVMTIREDEFINECLASSES_HPP
diff --git a/src/share/vm/prims/jvmtiTagMap.cpp b/src/share/vm/prims/jvmtiTagMap.cpp
index 3dbc70adf..5d72029d2 100644
--- a/src/share/vm/prims/jvmtiTagMap.cpp
+++ b/src/share/vm/prims/jvmtiTagMap.cpp
@@ -45,9 +45,10 @@
#include "runtime/vmThread.hpp"
#include "runtime/vm_operations.hpp"
#include "services/serviceUtil.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
// JvmtiTagHashmapEntry
//
diff --git a/src/share/vm/prims/jvmtiTagMap.hpp b/src/share/vm/prims/jvmtiTagMap.hpp
index 6435f6251..89e394780 100644
--- a/src/share/vm/prims/jvmtiTagMap.hpp
+++ b/src/share/vm/prims/jvmtiTagMap.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -27,14 +27,12 @@
#ifndef SHARE_VM_PRIMS_JVMTITAGMAP_HPP
#define SHARE_VM_PRIMS_JVMTITAGMAP_HPP
-#ifndef JVMTI_KERNEL
#include "gc_interface/collectedHeap.hpp"
#include "jvmtifiles/jvmti.h"
#include "jvmtifiles/jvmtiEnv.hpp"
#include "memory/allocation.hpp"
#include "memory/genCollectedHeap.hpp"
#include "memory/universe.hpp"
-#endif
// forward references
class JvmtiTagHashmap;
diff --git a/src/share/vm/prims/nativeLookup.cpp b/src/share/vm/prims/nativeLookup.cpp
index 5fdd070aa..6162ae850 100644
--- a/src/share/vm/prims/nativeLookup.cpp
+++ b/src/share/vm/prims/nativeLookup.cpp
@@ -40,6 +40,7 @@
#include "runtime/javaCalls.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/signature.hpp"
+#include "utilities/macros.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
#endif
diff --git a/src/share/vm/prims/unsafe.cpp b/src/share/vm/prims/unsafe.cpp
index e56277b65..18252c154 100644
--- a/src/share/vm/prims/unsafe.cpp
+++ b/src/share/vm/prims/unsafe.cpp
@@ -24,9 +24,10 @@
#include "precompiled.hpp"
#include "classfile/vmSymbols.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
#include "memory/allocation.inline.hpp"
#include "prims/jni.h"
#include "prims/jvm.h"
@@ -189,7 +190,7 @@ UNSAFE_ENTRY(jobject, Unsafe_GetObject140(JNIEnv *env, jobject unsafe, jobject o
if (obj == NULL) THROW_0(vmSymbols::java_lang_NullPointerException());
GET_OOP_FIELD(obj, offset, v)
jobject ret = JNIHandles::make_local(env, v);
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// We could be accessing the referent field in a reference
// object. If G1 is enabled then we need to register a non-null
// referent with the SATB barrier.
@@ -212,7 +213,7 @@ UNSAFE_ENTRY(jobject, Unsafe_GetObject140(JNIEnv *env, jobject unsafe, jobject o
G1SATBCardTableModRefBS::enqueue(referent);
}
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
return ret;
UNSAFE_END
@@ -247,7 +248,7 @@ UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj,
UnsafeWrapper("Unsafe_GetObject");
GET_OOP_FIELD(obj, offset, v)
jobject ret = JNIHandles::make_local(env, v);
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// We could be accessing the referent field in a reference
// object. If G1 is enabled then we need to register non-null
// referent with the SATB barrier.
@@ -270,7 +271,7 @@ UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj,
G1SATBCardTableModRefBS::enqueue(referent);
}
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
return ret;
UNSAFE_END
diff --git a/src/share/vm/prims/whitebox.cpp b/src/share/vm/prims/whitebox.cpp
index 6c60be19f..7bbec834e 100644
--- a/src/share/vm/prims/whitebox.cpp
+++ b/src/share/vm/prims/whitebox.cpp
@@ -36,12 +36,17 @@
#include "runtime/interfaceSupport.hpp"
#include "runtime/os.hpp"
#include "utilities/debug.hpp"
+#include "utilities/macros.hpp"
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/concurrentMark.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/heapRegionRemSet.hpp"
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
+
+#ifdef INCLUDE_NMT
+#include "services/memTracker.hpp"
+#endif // INCLUDE_NMT
bool WhiteBox::_used = false;
@@ -85,7 +90,7 @@ WB_ENTRY(jboolean, WB_IsClassAlive(JNIEnv* env, jobject target, jstring name))
return closure.found();
WB_END
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
WB_ENTRY(jboolean, WB_G1IsHumongous(JNIEnv* env, jobject o, jobject obj))
G1CollectedHeap* g1 = G1CollectedHeap::heap();
oop result = JNIHandles::resolve(obj);
@@ -108,7 +113,61 @@ WB_END
WB_ENTRY(jint, WB_G1RegionSize(JNIEnv* env, jobject o))
return (jint)HeapRegion::GrainBytes;
WB_END
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
+
+#ifdef INCLUDE_NMT
+// Keep track of the 3 allocations in NMTAllocTest so we can free them later
+// on and verify that they're not visible anymore
+static void* nmtMtTest1 = NULL, *nmtMtTest2 = NULL, *nmtMtTest3 = NULL;
+
+// Alloc memory using the test memory type so that we can use that to see if
+// NMT picks it up correctly
+WB_ENTRY(jboolean, WB_NMTAllocTest(JNIEnv* env))
+ void *mem;
+
+ if (!MemTracker::is_on() || MemTracker::shutdown_in_progress()) {
+ return false;
+ }
+
+ // Allocate 2 * 128k + 256k + 1024k and free the 1024k one to make sure we track
+ // everything correctly. Total should be 512k held alive.
+ nmtMtTest1 = os::malloc(128 * 1024, mtTest);
+ mem = os::malloc(1024 * 1024, mtTest);
+ nmtMtTest2 = os::malloc(256 * 1024, mtTest);
+ os::free(mem, mtTest);
+ nmtMtTest3 = os::malloc(128 * 1024, mtTest);
+
+ return true;
+WB_END
+
+// Free the memory allocated by NMTAllocTest
+WB_ENTRY(jboolean, WB_NMTFreeTestMemory(JNIEnv* env))
+
+ if (nmtMtTest1 == NULL || nmtMtTest2 == NULL || nmtMtTest3 == NULL) {
+ return false;
+ }
+
+ os::free(nmtMtTest1, mtTest);
+ nmtMtTest1 = NULL;
+ os::free(nmtMtTest2, mtTest);
+ nmtMtTest2 = NULL;
+ os::free(nmtMtTest3, mtTest);
+ nmtMtTest3 = NULL;
+
+ return true;
+WB_END
+
+// Block until the current generation of NMT data to be merged, used to reliably test the NMT feature
+WB_ENTRY(jboolean, WB_NMTWaitForDataMerge(JNIEnv* env))
+
+ if (!MemTracker::is_on() || MemTracker::shutdown_in_progress()) {
+ return false;
+ }
+
+ return MemTracker::wbtest_wait_for_data_merge();
+WB_END
+
+#endif // INCLUDE_NMT
//Some convenience methods to deal with objects from java
int WhiteBox::offset_for_field(const char* field_name, oop object,
@@ -171,12 +230,17 @@ static JNINativeMethod methods[] = {
CC "(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;",
(void*) &WB_ParseCommandLine
},
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
{CC"g1InConcurrentMark", CC"()Z", (void*)&WB_G1InConcurrentMark},
{CC"g1IsHumongous", CC"(Ljava/lang/Object;)Z", (void*)&WB_G1IsHumongous },
{CC"g1NumFreeRegions", CC"()J", (void*)&WB_G1NumFreeRegions },
{CC"g1RegionSize", CC"()I", (void*)&WB_G1RegionSize },
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
+#ifdef INCLUDE_NMT
+ {CC"NMTAllocTest", CC"()Z", (void*)&WB_NMTAllocTest },
+ {CC"NMTFreeTestMemory", CC"()Z", (void*)&WB_NMTFreeTestMemory },
+ {CC"NMTWaitForDataMerge",CC"()Z", (void*)&WB_NMTWaitForDataMerge},
+#endif // INCLUDE_NMT
};
#undef CC
diff --git a/src/share/vm/runtime/arguments.cpp b/src/share/vm/runtime/arguments.cpp
index 9b5d7f912..de596c1a8 100644
--- a/src/share/vm/runtime/arguments.cpp
+++ b/src/share/vm/runtime/arguments.cpp
@@ -38,6 +38,7 @@
#include "services/management.hpp"
#include "services/memTracker.hpp"
#include "utilities/defaultStream.hpp"
+#include "utilities/macros.hpp"
#include "utilities/taskqueue.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
@@ -51,9 +52,9 @@
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
#endif
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
// Note: This is a special bug reporting site for the JVM
#define DEFAULT_VENDOR_URL_BUG "http://bugreport.sun.com/bugreport/crash.jsp"
@@ -827,7 +828,8 @@ bool Arguments::process_argument(const char* arg,
return true;
}
- const char * const argname = *arg == '+' || *arg == '-' ? arg + 1 : arg;
+ bool has_plus_minus = (*arg == '+' || *arg == '-');
+ const char* const argname = has_plus_minus ? arg + 1 : arg;
if (is_newly_obsolete(arg, &since)) {
char version[256];
since.to_string(version, sizeof(version));
@@ -838,13 +840,29 @@ bool Arguments::process_argument(const char* arg,
// For locked flags, report a custom error message if available.
// Otherwise, report the standard unrecognized VM option.
- Flag* locked_flag = Flag::find_flag((char*)argname, strlen(argname), true);
- if (locked_flag != NULL) {
+ size_t arg_len;
+ const char* equal_sign = strchr(argname, '=');
+ if (equal_sign == NULL) {
+ arg_len = strlen(argname);
+ } else {
+ arg_len = equal_sign - argname;
+ }
+
+ Flag* found_flag = Flag::find_flag((char*)argname, arg_len, true);
+ if (found_flag != NULL) {
char locked_message_buf[BUFLEN];
- locked_flag->get_locked_message(locked_message_buf, BUFLEN);
+ found_flag->get_locked_message(locked_message_buf, BUFLEN);
if (strlen(locked_message_buf) == 0) {
- jio_fprintf(defaultStream::error_stream(),
- "Unrecognized VM option '%s'\n", argname);
+ if (found_flag->is_bool() && !has_plus_minus) {
+ jio_fprintf(defaultStream::error_stream(),
+ "Missing +/- setting for VM option '%s'\n", argname);
+ } else if (!found_flag->is_bool() && has_plus_minus) {
+ jio_fprintf(defaultStream::error_stream(),
+ "Unexpected +/- setting in VM option '%s'\n", argname);
+ } else {
+ jio_fprintf(defaultStream::error_stream(),
+ "Improperly specified VM option '%s'\n", argname);
+ }
} else {
jio_fprintf(defaultStream::error_stream(), "%s", locked_message_buf);
}
@@ -1072,7 +1090,7 @@ void Arguments::set_tiered_flags() {
}
}
-#if INCLUDE_ALTERNATE_GCS
+#if INCLUDE_ALL_GCS
static void disable_adaptive_size_policy(const char* collector_name) {
if (UseAdaptiveSizePolicy) {
if (FLAG_IS_CMDLINE(UseAdaptiveSizePolicy)) {
@@ -1284,7 +1302,7 @@ void Arguments::set_cms_and_parnew_gc_flags() {
tty->print_cr("ConcGCThreads: %u", ConcGCThreads);
}
}
-#endif // INCLUDE_ALTERNATE_GCS
+#endif // INCLUDE_ALL_GCS
void set_object_alignment() {
// Object alignment.
@@ -1301,10 +1319,10 @@ void set_object_alignment() {
// Oop encoding heap max
OopEncodingHeapMax = (uint64_t(max_juint) + 1) << LogMinObjAlignmentInBytes;
-#if INCLUDE_ALTERNATE_GCS
+#if INCLUDE_ALL_GCS
// Set CMS global values
CompactibleFreeListSpace::set_cms_values();
-#endif // INCLUDE_ALTERNATE_GCS
+#endif // INCLUDE_ALL_GCS
}
bool verify_object_alignment() {
@@ -1429,13 +1447,18 @@ void Arguments::set_ergonomics_flags() {
}
// Set the ClassMetaspaceSize to something that will not need to be
// expanded, since it cannot be expanded.
- if (UseCompressedKlassPointers && FLAG_IS_DEFAULT(ClassMetaspaceSize)) {
- // 100,000 classes seems like a good size, so 100M assumes around 1K
- // per klass. The vtable and oopMap is embedded so we don't have a fixed
- // size per klass. Eventually, this will be parameterized because it
- // would also be useful to determine the optimal size of the
- // systemDictionary.
- FLAG_SET_ERGO(uintx, ClassMetaspaceSize, 100*M);
+ if (UseCompressedKlassPointers) {
+ if (ClassMetaspaceSize > KlassEncodingMetaspaceMax) {
+ warning("Class metaspace size is too large for UseCompressedKlassPointers");
+ FLAG_SET_DEFAULT(UseCompressedKlassPointers, false);
+ } else if (FLAG_IS_DEFAULT(ClassMetaspaceSize)) {
+ // 100,000 classes seems like a good size, so 100M assumes around 1K
+ // per klass. The vtable and oopMap is embedded so we don't have a fixed
+ // size per klass. Eventually, this will be parameterized because it
+ // would also be useful to determine the optimal size of the
+ // systemDictionary.
+ FLAG_SET_ERGO(uintx, ClassMetaspaceSize, 100*M);
+ }
}
}
// Also checks that certain machines are slower with compressed oops
@@ -1976,7 +1999,7 @@ bool Arguments::check_vm_args_consistency() {
status = status && verify_min_value(ParGCArrayScanChunk, 1, "ParGCArrayScanChunk");
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
if (UseG1GC) {
status = status && verify_percentage(InitiatingHeapOccupancyPercent,
"InitiatingHeapOccupancyPercent");
@@ -1985,7 +2008,7 @@ bool Arguments::check_vm_args_consistency() {
status = status && verify_min_value((intx)G1ConcMarkStepDurationMillis, 1,
"G1ConcMarkStepDurationMillis");
}
-#endif
+#endif // INCLUDE_ALL_GCS
status = status && verify_interval(RefDiscoveryPolicy,
ReferenceProcessor::DiscoveryPolicyMin,
@@ -2472,10 +2495,7 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
// -Xshare:dump
} else if (match_option(option, "-Xshare:dump", &tail)) {
-#if defined(KERNEL)
- vm_exit_during_initialization(
- "Dumping a shared archive is not supported on the Kernel JVM.", NULL);
-#elif !INCLUDE_CDS
+#if !INCLUDE_CDS
vm_exit_during_initialization(
"Dumping a shared archive is not supported in this VM.", NULL);
#else
@@ -3157,7 +3177,7 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
UNSUPPORTED_OPTION(UseLargePages, "-XX:+UseLargePages");
#endif
-#if !INCLUDE_ALTERNATE_GCS
+#if !INCLUDE_ALL_GCS
if (UseParallelGC) {
warning("Parallel GC is not supported in this VM. Using Serial GC.");
}
@@ -3170,7 +3190,7 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
if (UseParNewGC) {
warning("Par New GC is not supported in this VM. Using Serial GC.");
}
-#endif // INCLUDE_ALTERNATE_GCS
+#endif // INCLUDE_ALL_GCS
#ifndef PRODUCT
if (TraceBytecodesAt != 0) {
@@ -3217,9 +3237,9 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
// Set object alignment values.
set_object_alignment();
-#ifdef SERIALGC
+#if !INCLUDE_ALL_GCS
force_serial_gc();
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
#if !INCLUDE_CDS
no_shared_spaces();
#endif // INCLUDE_CDS
@@ -3247,7 +3267,7 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
// Set heap size based on available physical memory
set_heap_size();
-#if INCLUDE_ALTERNATE_GCS
+#if INCLUDE_ALL_GCS
// Set per-collector flags
if (UseParallelGC || UseParallelOldGC) {
set_parallel_gc_flags();
@@ -3259,11 +3279,9 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
set_g1_gc_flags();
}
check_deprecated_gcs();
-#endif // INCLUDE_ALTERNATE_GCS
-
-#ifdef SERIALGC
+#else // INCLUDE_ALL_GCS
assert(verify_serial_gc_flags(), "SerialGC unset");
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
// Set bytecode rewriting flags
set_bytecode_flags();
@@ -3357,7 +3375,7 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
}
jint Arguments::adjust_after_os() {
-#if INCLUDE_ALTERNATE_GCS
+#if INCLUDE_ALL_GCS
if (UseParallelGC || UseParallelOldGC) {
if (UseNUMA) {
if (FLAG_IS_DEFAULT(MinHeapDeltaBytes)) {
@@ -3368,7 +3386,7 @@ jint Arguments::adjust_after_os() {
UseNUMAInterleaving = true;
}
}
-#endif
+#endif // INCLUDE_ALL_GCS
return JNI_OK;
}
@@ -3463,36 +3481,6 @@ void Arguments::PropertyList_unique_add(SystemProperty** plist, const char* k, c
PropertyList_add(plist, k, v);
}
-#ifdef KERNEL
-char *Arguments::get_kernel_properties() {
- // Find properties starting with kernel and append them to string
- // We need to find out how long they are first because the URL's that they
- // might point to could get long.
- int length = 0;
- SystemProperty* prop;
- for (prop = _system_properties; prop != NULL; prop = prop->next()) {
- if (strncmp(prop->key(), "kernel.", 7 ) == 0) {
- length += (strlen(prop->key()) + strlen(prop->value()) + 5); // "-D ="
- }
- }
- // Add one for null terminator.
- char *props = AllocateHeap(length + 1, mtInternal);
- if (length != 0) {
- int pos = 0;
- for (prop = _system_properties; prop != NULL; prop = prop->next()) {
- if (strncmp(prop->key(), "kernel.", 7 ) == 0) {
- jio_snprintf(&props[pos], length-pos,
- "-D%s=%s ", prop->key(), prop->value());
- pos = strlen(props);
- }
- }
- }
- // null terminate props in case of null
- props[length] = '\0';
- return props;
-}
-#endif // KERNEL
-
// Copies src into buf, replacing "%%" with "%" and "%p" with pid
// Returns true if all of the source pointed by src has been copied over to
// the destination buffer pointed by buf. Otherwise, returns false.
diff --git a/src/share/vm/runtime/arguments.hpp b/src/share/vm/runtime/arguments.hpp
index 71e6e3001..c116e2028 100644
--- a/src/share/vm/runtime/arguments.hpp
+++ b/src/share/vm/runtime/arguments.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -540,11 +540,6 @@ class Arguments : AllStatic {
// Utility: copies src into buf, replacing "%%" with "%" and "%p" with pid.
static bool copy_expand_pid(const char* src, size_t srclen, char* buf, size_t buflen);
-
-#ifdef KERNEL
- // For java kernel vm, return property string for kernel properties.
- static char *get_kernel_properties();
-#endif // KERNEL
};
#endif // SHARE_VM_RUNTIME_ARGUMENTS_HPP
diff --git a/src/share/vm/runtime/deoptimization.cpp b/src/share/vm/runtime/deoptimization.cpp
index 63df5aa5f..8f735b7d6 100644
--- a/src/share/vm/runtime/deoptimization.cpp
+++ b/src/share/vm/runtime/deoptimization.cpp
@@ -1559,7 +1559,7 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint tra
if (trap_method() == nm->method()) {
make_not_compilable = true;
} else {
- trap_method->set_not_compilable(CompLevel_full_optimization);
+ trap_method->set_not_compilable(CompLevel_full_optimization, true, "overflow_recompile_count > PerBytecodeRecompilationCutoff");
// But give grace to the enclosing nm->method().
}
}
diff --git a/src/share/vm/runtime/fprofiler.hpp b/src/share/vm/runtime/fprofiler.hpp
index c06a50563..429b32e7f 100644
--- a/src/share/vm/runtime/fprofiler.hpp
+++ b/src/share/vm/runtime/fprofiler.hpp
@@ -25,6 +25,7 @@
#ifndef SHARE_VM_RUNTIME_FPROFILER_HPP
#define SHARE_VM_RUNTIME_FPROFILER_HPP
+#include "utilities/macros.hpp"
#include "runtime/timer.hpp"
// a simple flat profiler for Java
diff --git a/src/share/vm/runtime/globals.cpp b/src/share/vm/runtime/globals.cpp
index 569a3f4be..dd32cb375 100644
--- a/src/share/vm/runtime/globals.cpp
+++ b/src/share/vm/runtime/globals.cpp
@@ -29,10 +29,11 @@
#include "runtime/globals.hpp"
#include "runtime/globals_extension.hpp"
#include "utilities/ostream.hpp"
+#include "utilities/macros.hpp"
#include "utilities/top.hpp"
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/g1_globals.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
#ifdef COMPILER1
#include "c1/c1_globals.hpp"
#endif
@@ -256,9 +257,9 @@ void Flag::print_as_flag(outputStream* st) {
static Flag flagTable[] = {
RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_EXPERIMENTAL_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT, RUNTIME_MANAGEABLE_FLAG_STRUCT, RUNTIME_PRODUCT_RW_FLAG_STRUCT, RUNTIME_LP64_PRODUCT_FLAG_STRUCT)
RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT)
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
G1_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_EXPERIMENTAL_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT, RUNTIME_MANAGEABLE_FLAG_STRUCT, RUNTIME_PRODUCT_RW_FLAG_STRUCT)
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
#ifdef COMPILER1
C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, C1_PD_DEVELOP_FLAG_STRUCT, C1_PRODUCT_FLAG_STRUCT, C1_PD_PRODUCT_FLAG_STRUCT, C1_NOTPRODUCT_FLAG_STRUCT)
#endif
diff --git a/src/share/vm/runtime/globals_extension.hpp b/src/share/vm/runtime/globals_extension.hpp
index 4d8666821..00d06fe27 100644
--- a/src/share/vm/runtime/globals_extension.hpp
+++ b/src/share/vm/runtime/globals_extension.hpp
@@ -26,6 +26,7 @@
#define SHARE_VM_RUNTIME_GLOBALS_EXTENSION_HPP
#include "runtime/globals.hpp"
+#include "utilities/macros.hpp"
#include "utilities/top.hpp"
// Construct enum of Flag_<cmdline-arg> constants.
@@ -94,9 +95,9 @@
typedef enum {
RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, RUNTIME_PD_DEVELOP_FLAG_MEMBER, RUNTIME_PRODUCT_FLAG_MEMBER, RUNTIME_PD_PRODUCT_FLAG_MEMBER, RUNTIME_DIAGNOSTIC_FLAG_MEMBER, RUNTIME_EXPERIMENTAL_FLAG_MEMBER, RUNTIME_NOTPRODUCT_FLAG_MEMBER, RUNTIME_MANAGEABLE_FLAG_MEMBER, RUNTIME_PRODUCT_RW_FLAG_MEMBER, RUNTIME_LP64_PRODUCT_FLAG_MEMBER)
RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, RUNTIME_PD_DEVELOP_FLAG_MEMBER, RUNTIME_PRODUCT_FLAG_MEMBER, RUNTIME_PD_PRODUCT_FLAG_MEMBER, RUNTIME_DIAGNOSTIC_FLAG_MEMBER, RUNTIME_NOTPRODUCT_FLAG_MEMBER)
-#if INCLUDE_ALTERNATE_GCS
+#if INCLUDE_ALL_GCS
G1_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, RUNTIME_PD_DEVELOP_FLAG_MEMBER, RUNTIME_PRODUCT_FLAG_MEMBER, RUNTIME_PD_PRODUCT_FLAG_MEMBER, RUNTIME_DIAGNOSTIC_FLAG_MEMBER, RUNTIME_EXPERIMENTAL_FLAG_MEMBER, RUNTIME_NOTPRODUCT_FLAG_MEMBER, RUNTIME_MANAGEABLE_FLAG_MEMBER, RUNTIME_PRODUCT_RW_FLAG_MEMBER)
-#endif // INCLUDE_ALTERNATE_GCS
+#endif // INCLUDE_ALL_GCS
#ifdef COMPILER1
C1_FLAGS(C1_DEVELOP_FLAG_MEMBER, C1_PD_DEVELOP_FLAG_MEMBER, C1_PRODUCT_FLAG_MEMBER, C1_PD_PRODUCT_FLAG_MEMBER, C1_NOTPRODUCT_FLAG_MEMBER)
#endif
@@ -187,7 +188,7 @@ typedef enum {
RUNTIME_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE,
RUNTIME_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE)
-#if INCLUDE_ALTERNATE_GCS
+#if INCLUDE_ALL_GCS
G1_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE,
RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE,
RUNTIME_PRODUCT_FLAG_MEMBER_WITH_TYPE,
@@ -197,7 +198,7 @@ typedef enum {
RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE,
RUNTIME_MANAGEABLE_FLAG_MEMBER_WITH_TYPE,
RUNTIME_PRODUCT_RW_FLAG_MEMBER_WITH_TYPE)
-#endif // INCLUDE_ALTERNATE_GCS
+#endif // INCLUDE_ALL_GCS
#ifdef COMPILER1
C1_FLAGS(C1_DEVELOP_FLAG_MEMBER_WITH_TYPE,
C1_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE,
diff --git a/src/share/vm/runtime/init.cpp b/src/share/vm/runtime/init.cpp
index 541cb0867..7ef17204b 100644
--- a/src/share/vm/runtime/init.cpp
+++ b/src/share/vm/runtime/init.cpp
@@ -34,6 +34,7 @@
#include "runtime/init.hpp"
#include "runtime/safepoint.hpp"
#include "runtime/sharedRuntime.hpp"
+#include "utilities/macros.hpp"
// Initialization done by VM thread in vm_init_globals()
void check_ThreadShadow();
diff --git a/src/share/vm/runtime/java.cpp b/src/share/vm/runtime/java.cpp
index fd9050d9c..f9be22344 100644
--- a/src/share/vm/runtime/java.cpp
+++ b/src/share/vm/runtime/java.cpp
@@ -64,6 +64,7 @@
#include "utilities/dtrace.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/histogram.hpp"
+#include "utilities/macros.hpp"
#include "utilities/vmError.hpp"
#ifdef TARGET_ARCH_x86
# include "vm_version_x86.hpp"
@@ -80,11 +81,11 @@
#ifdef TARGET_ARCH_ppc
# include "vm_version_ppc.hpp"
#endif
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
#ifdef COMPILER1
#include "c1/c1_Compiler.hpp"
#include "c1/c1_Runtime1.hpp"
diff --git a/src/share/vm/runtime/os.cpp b/src/share/vm/runtime/os.cpp
index 649ce4fcc..b40906803 100644
--- a/src/share/vm/runtime/os.cpp
+++ b/src/share/vm/runtime/os.cpp
@@ -985,15 +985,28 @@ void os::print_location(outputStream* st, intptr_t x, bool verbose) {
// if C stack is walkable beyond current frame. The check for fp() is not
// necessary on Sparc, but it's harmless.
bool os::is_first_C_frame(frame* fr) {
-#ifdef IA64
- // In order to walk native frames on Itanium, we need to access the unwind
- // table, which is inside ELF. We don't want to parse ELF after fatal error,
- // so return true for IA64. If we need to support C stack walking on IA64,
- // this function needs to be moved to CPU specific files, as fp() on IA64
- // is register stack, which grows towards higher memory address.
+#if defined(IA64) && !defined(_WIN32)
+ // On IA64 we have to check if the callers bsp is still valid
+ // (i.e. within the register stack bounds).
+ // Notice: this only works for threads created by the VM and only if
+ // we walk the current stack!!! If we want to be able to walk
+ // arbitrary other threads, we'll have to somehow store the thread
+ // object in the frame.
+ Thread *thread = Thread::current();
+ if ((address)fr->fp() <=
+ thread->register_stack_base() HPUX_ONLY(+ 0x0) LINUX_ONLY(+ 0x50)) {
+ // This check is a little hacky, because on Linux the first C
+ // frame's ('start_thread') register stack frame starts at
+ // "register_stack_base + 0x48" while on HPUX, the first C frame's
+ // ('__pthread_bound_body') register stack frame seems to really
+ // start at "register_stack_base".
+ return true;
+ } else {
+ return false;
+ }
+#elif defined(IA64) && defined(_WIN32)
return true;
-#endif
-
+#else
// Load up sp, fp, sender sp and sender fp, check for reasonable values.
// Check usp first, because if that's bad the other accessors may fault
// on some architectures. Ditto ufp second, etc.
@@ -1023,6 +1036,7 @@ bool os::is_first_C_frame(frame* fr) {
if (old_fp - ufp > 64 * K) return true;
return false;
+#endif
}
#ifdef ASSERT
diff --git a/src/share/vm/runtime/safepoint.cpp b/src/share/vm/runtime/safepoint.cpp
index bf2d38c20..37ee19a8f 100644
--- a/src/share/vm/runtime/safepoint.cpp
+++ b/src/share/vm/runtime/safepoint.cpp
@@ -52,6 +52,7 @@
#include "services/memTracker.hpp"
#include "services/runtimeService.hpp"
#include "utilities/events.hpp"
+#include "utilities/macros.hpp"
#ifdef TARGET_ARCH_x86
# include "nativeInst_x86.hpp"
# include "vmreg_x86.inline.hpp"
@@ -72,10 +73,10 @@
# include "nativeInst_ppc.hpp"
# include "vmreg_ppc.inline.hpp"
#endif
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
#include "gc_implementation/shared/concurrentGCThread.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
#ifdef COMPILER1
#include "c1/c1_globals.hpp"
#endif
@@ -103,7 +104,7 @@ void SafepointSynchronize::begin() {
_ts_of_current_safepoint = tty->time_stamp().seconds();
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
if (UseConcMarkSweepGC) {
// In the future we should investigate whether CMS can use the
// more-general mechanism below. DLD (01/05).
@@ -111,7 +112,7 @@ void SafepointSynchronize::begin() {
} else if (UseG1GC) {
ConcurrentGCThread::safepoint_synchronize();
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
// By getting the Threads_lock, we assure that no threads are about to start or
// exit. It is released again in SafepointSynchronize::end().
@@ -480,14 +481,14 @@ void SafepointSynchronize::end() {
Threads_lock->unlock();
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// If there are any concurrent GC threads resume them.
if (UseConcMarkSweepGC) {
ConcurrentMarkSweepThread::desynchronize(false);
} else if (UseG1GC) {
ConcurrentGCThread::safepoint_desynchronize();
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
// record this time so VMThread can keep track how much time has elasped
// since last safepoint.
_end_of_last_safepoint = os::javaTimeMillis();
diff --git a/src/share/vm/runtime/sharedRuntime.cpp b/src/share/vm/runtime/sharedRuntime.cpp
index 7d2b816fe..09a0b65b9 100644
--- a/src/share/vm/runtime/sharedRuntime.cpp
+++ b/src/share/vm/runtime/sharedRuntime.cpp
@@ -56,6 +56,7 @@
#include "utilities/dtrace.hpp"
#include "utilities/events.hpp"
#include "utilities/hashtable.inline.hpp"
+#include "utilities/macros.hpp"
#include "utilities/xmlstream.hpp"
#ifdef TARGET_ARCH_x86
# include "nativeInst_x86.hpp"
@@ -212,7 +213,7 @@ void SharedRuntime::print_ic_miss_histogram() {
}
#endif // PRODUCT
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// G1 write-barrier pre: executed before a pointer store.
JRT_LEAF(void, SharedRuntime::g1_wb_pre(oopDesc* orig, JavaThread *thread))
@@ -230,7 +231,7 @@ JRT_LEAF(void, SharedRuntime::g1_wb_post(void* card_addr, JavaThread* thread))
thread->dirty_card_queue().enqueue(card_addr);
JRT_END
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
JRT_LEAF(jlong, SharedRuntime::lmul(jlong y, jlong x))
@@ -2816,10 +2817,6 @@ VMRegPair *SharedRuntime::find_callee_arguments(Symbol* sig, bool has_receiver,
JRT_LEAF(intptr_t*, SharedRuntime::OSR_migration_begin( JavaThread *thread) )
-#ifdef IA64
- ShouldNotReachHere(); // NYI
-#endif /* IA64 */
-
//
// This code is dependent on the memory layout of the interpreter local
// array and the monitors. On all of our platforms the layout is identical
diff --git a/src/share/vm/runtime/sharedRuntime.hpp b/src/share/vm/runtime/sharedRuntime.hpp
index 54448890e..e6867645a 100644
--- a/src/share/vm/runtime/sharedRuntime.hpp
+++ b/src/share/vm/runtime/sharedRuntime.hpp
@@ -32,6 +32,7 @@
#include "memory/resourceArea.hpp"
#include "runtime/threadLocalStorage.hpp"
#include "utilities/hashtable.hpp"
+#include "utilities/macros.hpp"
class AdapterHandlerEntry;
class AdapterHandlerTable;
@@ -168,11 +169,11 @@ class SharedRuntime: AllStatic {
static address raw_exception_handler_for_return_address(JavaThread* thread, address return_address);
static address exception_handler_for_return_address(JavaThread* thread, address return_address);
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// G1 write barriers
static void g1_wb_pre(oopDesc* orig, JavaThread *thread);
static void g1_wb_post(void* card_addr, JavaThread* thread);
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
// exception handling and implicit exceptions
static address compute_compiled_exc_handler(nmethod* nm, address ret_pc, Handle& exception,
diff --git a/src/share/vm/runtime/synchronizer.cpp b/src/share/vm/runtime/synchronizer.cpp
index 667066e7f..bdf416275 100644
--- a/src/share/vm/runtime/synchronizer.cpp
+++ b/src/share/vm/runtime/synchronizer.cpp
@@ -53,7 +53,7 @@
# include "os_bsd.inline.hpp"
#endif
-#if defined(__GNUC__) && !defined(IA64)
+#if defined(__GNUC__)
// Need to inhibit inlining for older versions of GCC to avoid build-time failures
#define ATTR __attribute__((noinline))
#else
diff --git a/src/share/vm/runtime/thread.cpp b/src/share/vm/runtime/thread.cpp
index ff6adde6e..e0cf75b03 100644
--- a/src/share/vm/runtime/thread.cpp
+++ b/src/share/vm/runtime/thread.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -82,6 +82,7 @@
#include "utilities/dtrace.hpp"
#include "utilities/events.hpp"
#include "utilities/preserveException.hpp"
+#include "utilities/macros.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
#endif
@@ -94,11 +95,11 @@
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
#endif
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
#include "gc_implementation/g1/concurrentMarkThread.inline.hpp"
#include "gc_implementation/parallelScavenge/pcTasks.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
#ifdef COMPILER1
#include "c1/c1_Compiler.hpp"
#endif
@@ -1482,17 +1483,17 @@ void JavaThread::initialize() {
pd_initialize();
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
SATBMarkQueueSet JavaThread::_satb_mark_queue_set;
DirtyCardQueueSet JavaThread::_dirty_card_queue_set;
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
JavaThread::JavaThread(bool is_attaching_via_jni) :
Thread()
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
, _satb_mark_queue(&_satb_mark_queue_set),
_dirty_card_queue(&_dirty_card_queue_set)
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
{
initialize();
if (is_attaching_via_jni) {
@@ -1500,7 +1501,7 @@ JavaThread::JavaThread(bool is_attaching_via_jni) :
} else {
_jni_attach_state = _not_attaching_via_jni;
}
- assert(_deferred_card_mark.is_empty(), "Default MemRegion ctor");
+ assert(deferred_card_mark().is_empty(), "Default MemRegion ctor");
_safepoint_visible = false;
}
@@ -1547,10 +1548,10 @@ static void compiler_thread_entry(JavaThread* thread, TRAPS);
JavaThread::JavaThread(ThreadFunction entry_point, size_t stack_sz) :
Thread()
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
, _satb_mark_queue(&_satb_mark_queue_set),
_dirty_card_queue(&_dirty_card_queue_set)
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
{
if (TraceThreadEvents) {
tty->print_cr("creating thread %p", this);
@@ -1896,19 +1897,26 @@ void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
JvmtiExport::cleanup_thread(this);
}
-#ifndef SERIALGC
- // We must flush G1-related buffers before removing a thread from
+ // We must flush any deferred card marks before removing a thread from
// the list of active threads.
+ Universe::heap()->flush_deferred_store_barrier(this);
+ assert(deferred_card_mark().is_empty(), "Should have been flushed");
+
+#if INCLUDE_ALL_GCS
+ // We must flush the G1-related buffers before removing a thread
+ // from the list of active threads. We must do this after any deferred
+ // card marks have been flushed (above) so that any entries that are
+ // added to the thread's dirty card queue as a result are not lost.
if (UseG1GC) {
flush_barrier_queues();
}
-#endif
+#endif // INCLUDE_ALL_GCS
// Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread
Threads::remove(this);
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// Flush G1-related queues.
void JavaThread::flush_barrier_queues() {
satb_mark_queue().flush();
@@ -1936,7 +1944,7 @@ void JavaThread::initialize_queues() {
// active field set to true.
assert(dirty_queue.is_active(), "dirty card queue should be active");
}
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
void JavaThread::cleanup_failed_attach_current_thread() {
if (get_thread_profiler() != NULL) {
@@ -1964,11 +1972,11 @@ void JavaThread::cleanup_failed_attach_current_thread() {
tlab().make_parsable(true); // retire TLAB, if any
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
if (UseG1GC) {
flush_barrier_queues();
}
-#endif
+#endif // INCLUDE_ALL_GCS
Threads::remove(this);
delete this;
@@ -3600,7 +3608,7 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION));
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// Support for ConcurrentMarkSweep. This should be cleaned up
// and better encapsulated. The ugly nested if test would go away
// once things are properly refactored. XXX YSR
@@ -3614,7 +3622,7 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION));
}
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
// Always call even when there are not JVMTI environments yet, since environments
// may be attached late and JVMTI must track phases of VM execution
@@ -3739,28 +3747,6 @@ static OnLoadEntry_t lookup_on_load(AgentLibrary* agent, const char *on_load_sym
name)) {
library = os::dll_load(buffer, ebuf, sizeof ebuf);
}
-#ifdef KERNEL
- // Download instrument dll
- if (library == NULL && strcmp(name, "instrument") == 0) {
- char *props = Arguments::get_kernel_properties();
- char *home = Arguments::get_java_home();
- const char *fmt = "%s/bin/java %s -Dkernel.background.download=false"
- " sun.jkernel.DownloadManager -download client_jvm";
- size_t length = strlen(props) + strlen(home) + strlen(fmt) + 1;
- char *cmd = NEW_C_HEAP_ARRAY(char, length, mtThread);
- jio_snprintf(cmd, length, fmt, home, props);
- int status = os::fork_and_exec(cmd);
- FreeHeap(props);
- if (status == -1) {
- warning(cmd);
- vm_exit_during_initialization("fork_and_exec failed: %s",
- strerror(errno));
- }
- FREE_C_HEAP_ARRAY(char, cmd, mtThread);
- // when this comes back the instrument.dll should be where it belongs.
- library = os::dll_load(buffer, ebuf, sizeof ebuf);
- }
-#endif // KERNEL
if (library == NULL) { // Try the local directory
char ns[1] = {0};
if (os::dll_build_name(buffer, sizeof(buffer), ns, name)) {
@@ -4209,7 +4195,7 @@ void Threads::possibly_parallel_oops_do(OopClosure* f, CLDToOopClosure* cld_f, C
}
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// Used by ParallelScavenge
void Threads::create_thread_roots_tasks(GCTaskQueue* q) {
ALL_JAVA_THREADS(p) {
@@ -4225,7 +4211,7 @@ void Threads::create_thread_roots_marking_tasks(GCTaskQueue* q) {
}
q->enqueue(new ThreadRootsMarkingTask(VMThread::vm_thread()));
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
void Threads::nmethods_do(CodeBlobClosure* cf) {
ALL_JAVA_THREADS(p) {
@@ -4333,13 +4319,13 @@ void Threads::print_on(outputStream* st, bool print_stacks, bool internal_format
);
st->cr();
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// Dump concurrent locks
ConcurrentLocksDump concurrent_locks;
if (print_concurrent_locks) {
concurrent_locks.dump_at_safepoint();
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
ALL_JAVA_THREADS(p) {
ResourceMark rm;
@@ -4352,11 +4338,11 @@ void Threads::print_on(outputStream* st, bool print_stacks, bool internal_format
}
}
st->cr();
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
if (print_concurrent_locks) {
concurrent_locks.print_locks_on(p, st);
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
}
VMThread::vm_thread()->print_on(st);
diff --git a/src/share/vm/runtime/thread.hpp b/src/share/vm/runtime/thread.hpp
index 627000c72..98f8d2545 100644
--- a/src/share/vm/runtime/thread.hpp
+++ b/src/share/vm/runtime/thread.hpp
@@ -41,6 +41,7 @@
#include "runtime/stubRoutines.hpp"
#include "runtime/threadLocalStorage.hpp"
#include "runtime/unhandledOops.hpp"
+#include "utilities/macros.hpp"
#if INCLUDE_NMT
#include "services/memRecorder.hpp"
@@ -49,10 +50,10 @@
#include "trace/tracing.hpp"
#include "utilities/exceptions.hpp"
#include "utilities/top.hpp"
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/dirtyCardQueue.hpp"
#include "gc_implementation/g1/satbQueue.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
#ifdef ZERO
#ifdef TARGET_ARCH_zero
# include "stack_zero.hpp"
@@ -929,7 +930,7 @@ class JavaThread: public Thread {
} _jmp_ring[ jump_ring_buffer_size ];
#endif /* PRODUCT */
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// Support for G1 barriers
ObjPtrQueue _satb_mark_queue; // Thread-local log for SATB barrier.
@@ -941,7 +942,7 @@ class JavaThread: public Thread {
static DirtyCardQueueSet _dirty_card_queue_set;
void flush_barrier_queues();
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
friend class VMThread;
friend class ThreadWaitTransition;
@@ -1345,10 +1346,10 @@ class JavaThread: public Thread {
return byte_offset_of(JavaThread, _should_post_on_exceptions_flag);
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
static ByteSize satb_mark_queue_offset() { return byte_offset_of(JavaThread, _satb_mark_queue); }
static ByteSize dirty_card_queue_offset() { return byte_offset_of(JavaThread, _dirty_card_queue); }
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
// Returns the jni environment for this thread
JNIEnv* jni_environment() { return &_jni_environment; }
@@ -1637,7 +1638,7 @@ public:
_stack_size_at_create = value;
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// SATB marking queue support
ObjPtrQueue& satb_mark_queue() { return _satb_mark_queue; }
static SATBMarkQueueSet& satb_mark_queue_set() {
@@ -1649,7 +1650,7 @@ public:
static DirtyCardQueueSet& dirty_card_queue_set() {
return _dirty_card_queue_set;
}
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
// This method initializes the SATB and dirty card queues before a
// JavaThread is added to the Java thread list. Right now, we don't
@@ -1668,11 +1669,11 @@ public:
// might happen between the JavaThread constructor being called and the
// thread being added to the Java thread list (an example of this is
// when the structure for the DestroyJavaVM thread is created).
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
void initialize_queues();
-#else // !SERIALGC
+#else // INCLUDE_ALL_GCS
void initialize_queues() { }
-#endif // !SERIALGC
+#endif // INCLUDE_ALL_GCS
// Machine dependent stuff
#ifdef TARGET_OS_ARCH_linux_x86
diff --git a/src/share/vm/runtime/vframeArray.cpp b/src/share/vm/runtime/vframeArray.cpp
index 2c9aa0f3a..d00e9f009 100644
--- a/src/share/vm/runtime/vframeArray.cpp
+++ b/src/share/vm/runtime/vframeArray.cpp
@@ -233,8 +233,6 @@ void vframeArrayElement::unpack_on_stack(int caller_actual_parameters,
// Force early return from top frame after deoptimization
#ifndef CC_INTERP
pc = Interpreter::remove_activation_early_entry(state->earlyret_tos());
-#else
- // TBD: Need to implement ForceEarlyReturn for CC_INTERP (ia64)
#endif
} else {
// Possibly override the previous pc computation of the top (youngest) frame
diff --git a/src/share/vm/runtime/vmStructs.cpp b/src/share/vm/runtime/vmStructs.cpp
index a1fe3f2aa..86169fcfc 100644
--- a/src/share/vm/runtime/vmStructs.cpp
+++ b/src/share/vm/runtime/vmStructs.cpp
@@ -101,6 +101,7 @@
#include "utilities/array.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/hashtable.hpp"
+#include "utilities/macros.hpp"
#ifdef TARGET_ARCH_x86
# include "vmStructs_x86.hpp"
#endif
@@ -146,7 +147,7 @@
#ifdef TARGET_OS_ARCH_bsd_zero
# include "vmStructs_bsd_zero.hpp"
#endif
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp"
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
@@ -161,7 +162,7 @@
#include "gc_implementation/parallelScavenge/psYoungGen.hpp"
#include "gc_implementation/parallelScavenge/vmStructs_parallelgc.hpp"
#include "gc_implementation/g1/vmStructs_g1.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
#ifdef COMPILER2
#include "opto/addnode.hpp"
#include "opto/block.hpp"
@@ -1161,6 +1162,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
static_field(Abstract_VM_Version, _vm_major_version, int) \
static_field(Abstract_VM_Version, _vm_minor_version, int) \
static_field(Abstract_VM_Version, _vm_build_number, int) \
+ static_field(Abstract_VM_Version, _reserve_for_allocation_prefetch, int) \
\
static_field(JDK_Version, _current, JDK_Version) \
nonstatic_field(JDK_Version, _partially_initialized, bool) \
@@ -2087,8 +2089,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
declare_toplevel_type(FreeBlockDictionary<Metablock>*) \
declare_toplevel_type(FreeList<Metablock>*) \
declare_toplevel_type(FreeList<Metablock>) \
- declare_toplevel_type(MetablockTreeDictionary*) \
- declare_type(MetablockTreeDictionary, FreeBlockDictionary<Metablock>)
+ declare_type(MetablockTreeDictionary, FreeBlockDictionary<Metablock>)
//--------------------------------------------------------------------------------
@@ -2786,7 +2787,7 @@ VMStructEntry VMStructs::localHotSpotVMStructs[] = {
GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY,
GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY)
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
VM_STRUCTS_PARALLELGC(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_STATIC_VM_STRUCT_ENTRY)
@@ -2796,7 +2797,7 @@ VMStructEntry VMStructs::localHotSpotVMStructs[] = {
VM_STRUCTS_G1(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_STATIC_VM_STRUCT_ENTRY)
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
VM_STRUCTS_CPU(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_STATIC_VM_STRUCT_ENTRY,
@@ -2830,7 +2831,7 @@ VMTypeEntry VMStructs::localHotSpotVMTypes[] = {
GENERATE_C2_VM_TYPE_ENTRY,
GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY)
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
VM_TYPES_PARALLELGC(GENERATE_VM_TYPE_ENTRY,
GENERATE_TOPLEVEL_VM_TYPE_ENTRY)
@@ -2841,7 +2842,7 @@ VMTypeEntry VMStructs::localHotSpotVMTypes[] = {
VM_TYPES_G1(GENERATE_VM_TYPE_ENTRY,
GENERATE_TOPLEVEL_VM_TYPE_ENTRY)
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
VM_TYPES_CPU(GENERATE_VM_TYPE_ENTRY,
GENERATE_TOPLEVEL_VM_TYPE_ENTRY,
@@ -2872,11 +2873,11 @@ VMIntConstantEntry VMStructs::localHotSpotVMIntConstants[] = {
GENERATE_C2_VM_INT_CONSTANT_ENTRY,
GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY)
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
VM_INT_CONSTANTS_CMS(GENERATE_VM_INT_CONSTANT_ENTRY)
VM_INT_CONSTANTS_PARNEW(GENERATE_VM_INT_CONSTANT_ENTRY)
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
VM_INT_CONSTANTS_CPU(GENERATE_VM_INT_CONSTANT_ENTRY,
GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY,
@@ -2930,7 +2931,7 @@ VMStructs::init() {
CHECK_NO_OP,
CHECK_NO_OP);
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
VM_STRUCTS_PARALLELGC(CHECK_NONSTATIC_VM_STRUCT_ENTRY,
CHECK_STATIC_VM_STRUCT_ENTRY);
@@ -2940,7 +2941,7 @@ VMStructs::init() {
VM_STRUCTS_G1(CHECK_NONSTATIC_VM_STRUCT_ENTRY,
CHECK_STATIC_VM_STRUCT_ENTRY);
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
VM_STRUCTS_CPU(CHECK_NONSTATIC_VM_STRUCT_ENTRY,
CHECK_STATIC_VM_STRUCT_ENTRY,
@@ -2969,7 +2970,7 @@ VMStructs::init() {
CHECK_C2_VM_TYPE_ENTRY,
CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY);
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
VM_TYPES_PARALLELGC(CHECK_VM_TYPE_ENTRY,
CHECK_SINGLE_ARG_VM_TYPE_NO_OP);
@@ -2980,7 +2981,7 @@ VMStructs::init() {
VM_TYPES_G1(CHECK_VM_TYPE_ENTRY,
CHECK_SINGLE_ARG_VM_TYPE_NO_OP);
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
VM_TYPES_CPU(CHECK_VM_TYPE_ENTRY,
CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
@@ -3035,7 +3036,7 @@ VMStructs::init() {
ENSURE_C2_FIELD_TYPE_PRESENT,
CHECK_NO_OP,
CHECK_NO_OP));
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
debug_only(VM_STRUCTS_PARALLELGC(ENSURE_FIELD_TYPE_PRESENT,
ENSURE_FIELD_TYPE_PRESENT));
debug_only(VM_STRUCTS_CMS(ENSURE_FIELD_TYPE_PRESENT,
@@ -3043,7 +3044,7 @@ VMStructs::init() {
ENSURE_FIELD_TYPE_PRESENT));
debug_only(VM_STRUCTS_G1(ENSURE_FIELD_TYPE_PRESENT,
ENSURE_FIELD_TYPE_PRESENT));
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
debug_only(VM_STRUCTS_CPU(ENSURE_FIELD_TYPE_PRESENT,
ENSURE_FIELD_TYPE_PRESENT,
CHECK_NO_OP,
diff --git a/src/share/vm/runtime/vmStructs.hpp b/src/share/vm/runtime/vmStructs.hpp
index b1070a406..5c4c93a1f 100644
--- a/src/share/vm/runtime/vmStructs.hpp
+++ b/src/share/vm/runtime/vmStructs.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -25,9 +25,7 @@
#ifndef SHARE_VM_RUNTIME_VMSTRUCTS_HPP
#define SHARE_VM_RUNTIME_VMSTRUCTS_HPP
-#ifndef VM_STRUCTS_KERNEL
#include "utilities/debug.hpp"
-#endif
#ifdef COMPILER1
#include "c1/c1_Runtime1.hpp"
#endif
diff --git a/src/share/vm/runtime/vm_version.cpp b/src/share/vm/runtime/vm_version.cpp
index 2d105a97b..ef03c76f6 100644
--- a/src/share/vm/runtime/vm_version.cpp
+++ b/src/share/vm/runtime/vm_version.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -111,9 +111,6 @@ void Abstract_VM_Version::initialize() {
#endif
#ifndef VMTYPE
- #ifdef KERNEL
- #define VMTYPE "Kernel"
- #else // KERNEL
#ifdef TIERED
#define VMTYPE "Server"
#else // TIERED
@@ -128,7 +125,6 @@ void Abstract_VM_Version::initialize() {
COMPILER2_PRESENT("Server")
#endif // ZERO
#endif // TIERED
- #endif // KERNEL
#endif
#ifndef HOTSPOT_VM_DISTRO
diff --git a/src/share/vm/services/attachListener.cpp b/src/share/vm/services/attachListener.cpp
index 80dfd7eff..da93859bb 100644
--- a/src/share/vm/services/attachListener.cpp
+++ b/src/share/vm/services/attachListener.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -170,7 +170,6 @@ static jint jcmd(AttachOperation* op, outputStream* out) {
return JNI_OK;
}
-#ifndef SERVICES_KERNEL // Heap dumping not supported
// Implementation of "dumpheap" command.
// See also: HeapDumpDCmd class
//
@@ -212,7 +211,6 @@ jint dump_heap(AttachOperation* op, outputStream* out) {
}
return JNI_OK;
}
-#endif // SERVICES_KERNEL
// Implementation of "inspectheap" command
// See also: ClassHistogramDCmd class
@@ -382,9 +380,7 @@ static jint print_flag(AttachOperation* op, outputStream* out) {
static AttachOperationFunctionInfo funcs[] = {
{ "agentProperties", get_agent_properties },
{ "datadump", data_dump },
-#ifndef SERVICES_KERNEL
{ "dumpheap", dump_heap },
-#endif // SERVICES_KERNEL
{ "load", JvmtiExport::load_agent_library },
{ "properties", get_system_properties },
{ "threaddump", thread_dump },
diff --git a/src/share/vm/services/attachListener.hpp b/src/share/vm/services/attachListener.hpp
index 1916e8cac..2e7cff395 100644
--- a/src/share/vm/services/attachListener.hpp
+++ b/src/share/vm/services/attachListener.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -28,6 +28,7 @@
#include "memory/allocation.hpp"
#include "utilities/debug.hpp"
#include "utilities/ostream.hpp"
+#include "utilities/macros.hpp"
// The AttachListener thread services a queue of operations that are enqueued
// by client tools. Each operation is identified by a name and has up to 3
@@ -38,8 +39,6 @@
// complets the result value and any result data is returned to the client
// tool.
-#ifndef SERVICES_KERNEL
-
class AttachOperation;
typedef jint (*AttachOperationFunction)(AttachOperation* op, outputStream* out);
@@ -48,7 +47,6 @@ struct AttachOperationFunctionInfo {
const char* name;
AttachOperationFunction func;
};
-#endif // SERVICES_KERNEL
class AttachListener: AllStatic {
public:
diff --git a/src/share/vm/services/classLoadingService.cpp b/src/share/vm/services/classLoadingService.cpp
index 04dfca892..b06890808 100644
--- a/src/share/vm/services/classLoadingService.cpp
+++ b/src/share/vm/services/classLoadingService.cpp
@@ -31,6 +31,7 @@
#include "services/classLoadingService.hpp"
#include "services/memoryService.hpp"
#include "utilities/dtrace.hpp"
+#include "utilities/macros.hpp"
#ifdef DTRACE_ENABLED
diff --git a/src/share/vm/services/classLoadingService.hpp b/src/share/vm/services/classLoadingService.hpp
index 1ea177f83..a7f2c4c25 100644
--- a/src/share/vm/services/classLoadingService.hpp
+++ b/src/share/vm/services/classLoadingService.hpp
@@ -28,6 +28,7 @@
#include "runtime/handles.hpp"
#include "runtime/perfData.hpp"
#include "utilities/growableArray.hpp"
+#include "utilities/macros.hpp"
class InstanceKlass;
diff --git a/src/share/vm/services/diagnosticCommand.cpp b/src/share/vm/services/diagnosticCommand.cpp
index 52a098a26..5499d9ad2 100644
--- a/src/share/vm/services/diagnosticCommand.cpp
+++ b/src/share/vm/services/diagnosticCommand.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -30,6 +30,7 @@
#include "services/diagnosticFramework.hpp"
#include "services/heapDumper.hpp"
#include "services/management.hpp"
+#include "utilities/macros.hpp"
void DCmdRegistrant::register_dcmds(){
// Registration of the diagnostic commands
@@ -43,12 +44,12 @@ void DCmdRegistrant::register_dcmds(){
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMUptimeDCmd>(true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SystemGCDCmd>(true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RunFinalizationDCmd>(true, false));
-#if INCLUDE_SERVICES // Heap dumping supported
+#if INCLUDE_SERVICES // Heap dumping/inspection supported
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapDumpDCmd>(true, false));
-#endif // INCLUDE_SERVICES
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHistogramDCmd>(true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassStatsDCmd>(true, false));
+#endif // INCLUDE_SERVICES
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(true, false));
-
//Enhanced JMX Agent Support
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStartRemoteDCmd>(true,false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStartLocalDCmd>(true,false));
@@ -252,7 +253,7 @@ void RunFinalizationDCmd::execute(TRAPS) {
vmSymbols::void_method_signature(), CHECK);
}
-#if INCLUDE_SERVICES // Heap dumping supported
+#if INCLUDE_SERVICES // Heap dumping/inspection supported
HeapDumpDCmd::HeapDumpDCmd(outputStream* output, bool heap) :
DCmdWithParser(output, heap),
_filename("filename","Name of the dump file", "STRING",true),
@@ -292,7 +293,6 @@ int HeapDumpDCmd::num_arguments() {
return 0;
}
}
-#endif // INCLUDE_SERVICES
ClassHistogramDCmd::ClassHistogramDCmd(outputStream* output, bool heap) :
DCmdWithParser(output, heap),
@@ -319,6 +319,65 @@ int ClassHistogramDCmd::num_arguments() {
}
}
+#define DEFAULT_COLUMNS "InstBytes,KlassBytes,CpAll,annotations,MethodCount,Bytecodes,MethodAll,ROAll,RWAll,Total"
+ClassStatsDCmd::ClassStatsDCmd(outputStream* output, bool heap) :
+ DCmdWithParser(output, heap),
+ _csv("-csv", "Print in CSV (comma-separated values) format for spreadsheets",
+ "BOOLEAN", false, "false"),
+ _all("-all", "Show all columns",
+ "BOOLEAN", false, "false"),
+ _help("-help", "Show meaning of all the columns",
+ "BOOLEAN", false, "false"),
+ _columns("columns", "Comma-separated list of all the columns to show. "
+ "If not specified, the following columns are shown: " DEFAULT_COLUMNS,
+ "STRING", false) {
+ _dcmdparser.add_dcmd_option(&_all);
+ _dcmdparser.add_dcmd_option(&_csv);
+ _dcmdparser.add_dcmd_option(&_help);
+ _dcmdparser.add_dcmd_argument(&_columns);
+}
+
+void ClassStatsDCmd::execute(TRAPS) {
+ if (!UnlockDiagnosticVMOptions) {
+ output()->print_cr("GC.class_stats command requires -XX:+UnlockDiagnosticVMOptions");
+ return;
+ }
+
+ VM_GC_HeapInspection heapop(output(),
+ true, /* request_full_gc */
+ true /* need_prologue */);
+ heapop.set_csv_format(_csv.value());
+ heapop.set_print_help(_help.value());
+ heapop.set_print_class_stats(true);
+ if (_all.value()) {
+ if (_columns.has_value()) {
+ output()->print_cr("Cannot specify -all and individual columns at the same time");
+ return;
+ } else {
+ heapop.set_columns(NULL);
+ }
+ } else {
+ if (_columns.has_value()) {
+ heapop.set_columns(_columns.value());
+ } else {
+ heapop.set_columns(DEFAULT_COLUMNS);
+ }
+ }
+ VMThread::execute(&heapop);
+}
+
+int ClassStatsDCmd::num_arguments() {
+ ResourceMark rm;
+ ClassStatsDCmd* dcmd = new ClassStatsDCmd(NULL, false);
+ if (dcmd != NULL) {
+ DCmdMark mark(dcmd);
+ return dcmd->_dcmdparser.num_arguments();
+ } else {
+ return 0;
+ }
+}
+#endif // INCLUDE_SERVICES
+
ThreadDumpDCmd::ThreadDumpDCmd(outputStream* output, bool heap) :
DCmdWithParser(output, heap),
_locks("-l", "print java.util.concurrent locks", "BOOLEAN", false, "false") {
@@ -406,7 +465,32 @@ JMXStartRemoteDCmd::JMXStartRemoteDCmd(outputStream *output, bool heap_allocated
_jmxremote_ssl_config_file
("jmxremote.ssl.config.file",
- "set com.sun.management.jmxremote.ssl_config_file", "STRING", false)
+ "set com.sun.management.jmxremote.ssl_config_file", "STRING", false),
+
+// JDP Protocol support
+ _jmxremote_autodiscovery
+ ("jmxremote.autodiscovery",
+ "set com.sun.management.jmxremote.autodiscovery", "STRING", false),
+
+ _jdp_port
+ ("jdp.port",
+ "set com.sun.management.jdp.port", "INT", false),
+
+ _jdp_address
+ ("jdp.address",
+ "set com.sun.management.jdp.address", "STRING", false),
+
+ _jdp_source_addr
+ ("jdp.source_addr",
+ "set com.sun.management.jdp.source_addr", "STRING", false),
+
+ _jdp_ttl
+ ("jdp.ttl",
+ "set com.sun.management.jdp.ttl", "INT", false),
+
+ _jdp_pause
+ ("jdp.pause",
+ "set com.sun.management.jdp.pause", "INT", false)
{
_dcmdparser.add_dcmd_option(&_config_file);
@@ -422,6 +506,12 @@ JMXStartRemoteDCmd::JMXStartRemoteDCmd(outputStream *output, bool heap_allocated
_dcmdparser.add_dcmd_option(&_jmxremote_ssl_enabled_protocols);
_dcmdparser.add_dcmd_option(&_jmxremote_ssl_need_client_auth);
_dcmdparser.add_dcmd_option(&_jmxremote_ssl_config_file);
+ _dcmdparser.add_dcmd_option(&_jmxremote_autodiscovery);
+ _dcmdparser.add_dcmd_option(&_jdp_port);
+ _dcmdparser.add_dcmd_option(&_jdp_address);
+ _dcmdparser.add_dcmd_option(&_jdp_source_addr);
+ _dcmdparser.add_dcmd_option(&_jdp_ttl);
+ _dcmdparser.add_dcmd_option(&_jdp_pause);
}
@@ -436,7 +526,6 @@ int JMXStartRemoteDCmd::num_arguments() {
}
}
-
void JMXStartRemoteDCmd::execute(TRAPS) {
ResourceMark rm(THREAD);
HandleMark hm(THREAD);
@@ -466,7 +555,9 @@ void JMXStartRemoteDCmd::execute(TRAPS) {
// file.
#define PUT_OPTION(a) \
if ( (a).is_set() ){ \
- options.print("%scom.sun.management.%s=%s", comma, (a).name(), (a).value()); \
+ options.print(\
+ ( *((a).type()) == 'I' ) ? "%scom.sun.management.%s=%d" : "%scom.sun.management.%s=%s",\
+ comma, (a).name(), (a).value()); \
comma[0] = ','; \
}
@@ -483,6 +574,12 @@ void JMXStartRemoteDCmd::execute(TRAPS) {
PUT_OPTION(_jmxremote_ssl_enabled_protocols);
PUT_OPTION(_jmxremote_ssl_need_client_auth);
PUT_OPTION(_jmxremote_ssl_config_file);
+ PUT_OPTION(_jmxremote_autodiscovery);
+ PUT_OPTION(_jdp_port);
+ PUT_OPTION(_jdp_address);
+ PUT_OPTION(_jdp_source_addr);
+ PUT_OPTION(_jdp_ttl);
+ PUT_OPTION(_jdp_pause);
#undef PUT_OPTION
diff --git a/src/share/vm/services/diagnosticCommand.hpp b/src/share/vm/services/diagnosticCommand.hpp
index 99d75a92f..ac5d5809d 100644
--- a/src/share/vm/services/diagnosticCommand.hpp
+++ b/src/share/vm/services/diagnosticCommand.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -35,6 +35,7 @@
#include "services/diagnosticCommand.hpp"
#include "services/diagnosticFramework.hpp"
#include "services/diagnosticCommand_ext.hpp"
+#include "utilities/macros.hpp"
class HelpDCmd : public DCmdWithParser {
protected:
@@ -178,7 +179,7 @@ public:
};
#endif // INCLUDE_SERVICES
-// See also: inspeactheap in attachListener.cpp
+// See also: inspectheap in attachListener.cpp
class ClassHistogramDCmd : public DCmdWithParser {
protected:
DCmdArgument<bool> _all;
@@ -197,6 +198,27 @@ public:
virtual void execute(TRAPS);
};
+class ClassStatsDCmd : public DCmdWithParser {
+protected:
+ DCmdArgument<bool> _all;
+ DCmdArgument<bool> _csv;
+ DCmdArgument<bool> _help;
+ DCmdArgument<char*> _columns;
+public:
+ ClassStatsDCmd(outputStream* output, bool heap);
+ static const char* name() {
+ return "GC.class_stats";
+ }
+ static const char* description() {
+ return "Provide statistics about Java class meta data. Requires -XX:+UnlockDiagnosticVMOptions.";
+ }
+ static const char* impact() {
+ return "High: Depends on Java heap size and content.";
+ }
+ static int num_arguments();
+ virtual void execute(TRAPS);
+};
+
// See also: thread_dump in attachListener.cpp
class ThreadDumpDCmd : public DCmdWithParser {
protected:
@@ -236,6 +258,16 @@ class JMXStartRemoteDCmd : public DCmdWithParser {
DCmdArgument<char *> _jmxremote_ssl_need_client_auth;
DCmdArgument<char *> _jmxremote_ssl_config_file;
+ // JDP support
+ // Keep autodiscovery char* not bool to pass true/false
+ // as property value to java level.
+ DCmdArgument<char *> _jmxremote_autodiscovery;
+ DCmdArgument<jlong> _jdp_port;
+ DCmdArgument<char *> _jdp_address;
+ DCmdArgument<char *> _jdp_source_addr;
+ DCmdArgument<jlong> _jdp_ttl;
+ DCmdArgument<jlong> _jdp_pause;
+
public:
JMXStartRemoteDCmd(outputStream *output, bool heap_allocated);
diff --git a/src/share/vm/services/g1MemoryPool.hpp b/src/share/vm/services/g1MemoryPool.hpp
index c84ecb2d5..abe67e2f9 100644
--- a/src/share/vm/services/g1MemoryPool.hpp
+++ b/src/share/vm/services/g1MemoryPool.hpp
@@ -25,11 +25,12 @@
#ifndef SHARE_VM_SERVICES_G1MEMORYPOOL_HPP
#define SHARE_VM_SERVICES_G1MEMORYPOOL_HPP
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/g1MonitoringSupport.hpp"
#include "services/memoryPool.hpp"
#include "services/memoryUsage.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
// This file contains the three classes that represent the memory
// pools of the G1 spaces: G1EdenPool, G1SurvivorPool, and
diff --git a/src/share/vm/services/heapDumper.cpp b/src/share/vm/services/heapDumper.cpp
index 65ee27f45..fa1bf273e 100644
--- a/src/share/vm/services/heapDumper.cpp
+++ b/src/share/vm/services/heapDumper.cpp
@@ -40,9 +40,10 @@
#include "services/heapDumper.hpp"
#include "services/threadService.hpp"
#include "utilities/ostream.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
/*
* HPROF binary format - description copied from:
diff --git a/src/share/vm/services/management.cpp b/src/share/vm/services/management.cpp
index a5b68d9b6..549622e92 100644
--- a/src/share/vm/services/management.cpp
+++ b/src/share/vm/services/management.cpp
@@ -53,6 +53,7 @@
#include "services/memoryService.hpp"
#include "services/runtimeService.hpp"
#include "services/threadService.hpp"
+#include "utilities/macros.hpp"
PerfVariable* Management::_begin_vm_creation_time = NULL;
PerfVariable* Management::_end_vm_creation_time = NULL;
diff --git a/src/share/vm/services/memBaseline.cpp b/src/share/vm/services/memBaseline.cpp
index 9d9832e86..681b4d7d9 100644
--- a/src/share/vm/services/memBaseline.cpp
+++ b/src/share/vm/services/memBaseline.cpp
@@ -40,6 +40,7 @@ MemType2Name MemBaseline::MemType2NameMap[NUMBER_OF_MEMORY_TYPE] = {
{mtNMT, "Memory Tracking"},
{mtChunk, "Pooled Free Chunks"},
{mtClassShared,"Shared spaces for classes"},
+ {mtTest, "Test"},
{mtNone, "Unknown"} // It can happen when type tagging records are lagging
// behind
};
diff --git a/src/share/vm/services/memPtr.cpp b/src/share/vm/services/memPtr.cpp
index 5d0fbf5bf..3e124e2bd 100644
--- a/src/share/vm/services/memPtr.cpp
+++ b/src/share/vm/services/memPtr.cpp
@@ -27,8 +27,8 @@
#include "services/memTracker.hpp"
volatile jint SequenceGenerator::_seq_number = 1;
+volatile unsigned long SequenceGenerator::_generation = 1;
NOT_PRODUCT(jint SequenceGenerator::_max_seq_number = 1;)
-DEBUG_ONLY(volatile unsigned long SequenceGenerator::_generation = 0;)
jint SequenceGenerator::next() {
jint seq = Atomic::add(1, &_seq_number);
diff --git a/src/share/vm/services/memPtr.hpp b/src/share/vm/services/memPtr.hpp
index a27c3eb4a..e1c852ac7 100644
--- a/src/share/vm/services/memPtr.hpp
+++ b/src/share/vm/services/memPtr.hpp
@@ -47,16 +47,16 @@ class SequenceGenerator : AllStatic {
static void reset() {
assert(SafepointSynchronize::is_at_safepoint(), "Safepoint required");
_seq_number = 1;
- DEBUG_ONLY(_generation ++;)
+ _generation ++;
};
- DEBUG_ONLY(static unsigned long current_generation() { return (unsigned long)_generation; })
+ static unsigned long current_generation() { return _generation; }
NOT_PRODUCT(static jint max_seq_num() { return _max_seq_number; })
private:
- static volatile jint _seq_number;
- NOT_PRODUCT(static jint _max_seq_number; )
- DEBUG_ONLY(static volatile unsigned long _generation; )
+ static volatile jint _seq_number;
+ static volatile unsigned long _generation;
+ NOT_PRODUCT(static jint _max_seq_number; )
};
/*
diff --git a/src/share/vm/services/memRecorder.cpp b/src/share/vm/services/memRecorder.cpp
index 93703269e..776ad223c 100644
--- a/src/share/vm/services/memRecorder.cpp
+++ b/src/share/vm/services/memRecorder.cpp
@@ -55,7 +55,7 @@ volatile jint MemRecorder::_instance_count = 0;
MemRecorder::MemRecorder() {
assert(MemTracker::is_on(), "Native memory tracking is off");
Atomic::inc(&_instance_count);
- debug_only(set_generation();)
+ set_generation();
if (MemTracker::track_callsite()) {
_pointer_records = new (std::nothrow)FixedSizeMemPointerArray<SeqMemPointerRecordEx,
@@ -151,11 +151,12 @@ SequencedRecordIterator MemRecorder::pointer_itr() {
}
-#ifdef ASSERT
void MemRecorder::set_generation() {
_generation = SequenceGenerator::current_generation();
}
+#ifdef ASSERT
+
void MemRecorder::check_dup_seq(jint seq) const {
MemPointerArrayIteratorImpl itr(_pointer_records);
MemPointerRecord* rc = (MemPointerRecord*)itr.current();
diff --git a/src/share/vm/services/memRecorder.hpp b/src/share/vm/services/memRecorder.hpp
index e4c322d65..9d6bf2b7e 100644
--- a/src/share/vm/services/memRecorder.hpp
+++ b/src/share/vm/services/memRecorder.hpp
@@ -213,7 +213,7 @@ class MemRecorder : public CHeapObj<mtNMT|otNMTRecorder> {
// used for linked list
MemRecorder* _next;
// active recorder can only record a certain generation data
- debug_only(unsigned long _generation;)
+ unsigned long _generation;
protected:
_NOINLINE_ MemRecorder();
@@ -251,6 +251,8 @@ class MemRecorder : public CHeapObj<mtNMT|otNMTRecorder> {
SequencedRecordIterator pointer_itr();
+ // return the generation of this recorder which it belongs to
+ unsigned long get_generation() const { return _generation; }
protected:
// number of MemRecorder instance
static volatile jint _instance_count;
@@ -263,7 +265,7 @@ class MemRecorder : public CHeapObj<mtNMT|otNMTRecorder> {
static int sort_record_fn(const void* e1, const void* e2);
debug_only(void check_dup_seq(jint seq) const;)
- debug_only(void set_generation();)
+ void set_generation();
};
#endif // SHARE_VM_SERVICES_MEM_RECORDER_HPP
diff --git a/src/share/vm/services/memReporter.hpp b/src/share/vm/services/memReporter.hpp
index 38f1e60bd..86d4b52ef 100644
--- a/src/share/vm/services/memReporter.hpp
+++ b/src/share/vm/services/memReporter.hpp
@@ -29,6 +29,7 @@
#include "services/memBaseline.hpp"
#include "services/memTracker.hpp"
#include "utilities/ostream.hpp"
+#include "utilities/macros.hpp"
#if INCLUDE_NMT
diff --git a/src/share/vm/services/memTrackWorker.cpp b/src/share/vm/services/memTrackWorker.cpp
index 19b375d40..8c38d1a37 100644
--- a/src/share/vm/services/memTrackWorker.cpp
+++ b/src/share/vm/services/memTrackWorker.cpp
@@ -91,6 +91,8 @@ void MemTrackWorker::run() {
MemSnapshot* snapshot = MemTracker::get_snapshot();
assert(snapshot != NULL, "Worker should not be started");
MemRecorder* rec;
+ unsigned long processing_generation = 0;
+ bool worker_idle = false;
while (!MemTracker::shutdown_in_progress()) {
NOT_PRODUCT(_last_gen_in_use = generations_in_use();)
@@ -100,6 +102,12 @@ void MemTrackWorker::run() {
rec = _gen[_head].next_recorder();
}
if (rec != NULL) {
+ if (rec->get_generation() != processing_generation || worker_idle) {
+ processing_generation = rec->get_generation();
+ worker_idle = false;
+ MemTracker::set_current_processing_generation(processing_generation);
+ }
+
// merge the recorder into staging area
if (!snapshot->merge(rec)) {
MemTracker::shutdown(MemTracker::NMT_out_of_memory);
@@ -129,6 +137,9 @@ void MemTrackWorker::run() {
MemTracker::shutdown(MemTracker::NMT_out_of_memory);
}
} else {
+ // worker thread is idle
+ worker_idle = true;
+ MemTracker::report_worker_idle();
snapshot->wait(1000);
ThreadCritical tc;
// check if more data arrived
diff --git a/src/share/vm/services/memTrackWorker.hpp b/src/share/vm/services/memTrackWorker.hpp
index 9a2d52802..be80e294d 100644
--- a/src/share/vm/services/memTrackWorker.hpp
+++ b/src/share/vm/services/memTrackWorker.hpp
@@ -107,6 +107,7 @@ class MemTrackWorker : public NamedThread {
NOT_PRODUCT(int _merge_count;)
NOT_PRODUCT(int _last_gen_in_use;)
+ // how many generations are queued
inline int generations_in_use() const {
return (_tail >= _head ? (_tail - _head + 1) : (MAX_GENERATIONS - (_head - _tail) + 1));
}
diff --git a/src/share/vm/services/memTracker.cpp b/src/share/vm/services/memTracker.cpp
index c8032d8fd..4c110d584 100644
--- a/src/share/vm/services/memTracker.cpp
+++ b/src/share/vm/services/memTracker.cpp
@@ -29,6 +29,7 @@
#include "runtime/mutexLocker.hpp"
#include "runtime/safepoint.hpp"
#include "runtime/threadCritical.hpp"
+#include "runtime/vm_operations.hpp"
#include "services/memPtr.hpp"
#include "services/memReporter.hpp"
#include "services/memTracker.hpp"
@@ -65,6 +66,8 @@ volatile MemTracker::NMTStates MemTracker::_state = NMT_uninited;
MemTracker::ShutdownReason MemTracker::_reason = NMT_shutdown_none;
int MemTracker::_thread_count = 255;
volatile jint MemTracker::_pooled_recorder_count = 0;
+volatile unsigned long MemTracker::_processing_generation = 0;
+volatile bool MemTracker::_worker_thread_idle = false;
debug_only(intx MemTracker::_main_thread_tid = 0;)
NOT_PRODUCT(volatile jint MemTracker::_pending_recorder_count = 0;)
@@ -279,7 +282,7 @@ MemRecorder* MemTracker::get_new_or_pooled_instance() {
}
cur_head->set_next(NULL);
Atomic::dec(&_pooled_recorder_count);
- debug_only(cur_head->set_generation();)
+ cur_head->set_generation();
return cur_head;
}
}
@@ -570,6 +573,51 @@ bool MemTracker::print_memory_usage(BaselineOutputer& out, size_t unit, bool sum
return false;
}
+// Whitebox API for blocking until the current generation of NMT data has been merged
+bool MemTracker::wbtest_wait_for_data_merge() {
+ // NMT can't be shutdown while we're holding _query_lock
+ MutexLockerEx lock(_query_lock, true);
+ assert(_worker_thread != NULL, "Invalid query");
+ // the generation at query time, so NMT will spin till this generation is processed
+ unsigned long generation_at_query_time = SequenceGenerator::current_generation();
+ unsigned long current_processing_generation = _processing_generation;
+ // if generation counter overflown
+ bool generation_overflown = (generation_at_query_time < current_processing_generation);
+ long generations_to_wrap = MAX_UNSIGNED_LONG - current_processing_generation;
+ // spin
+ while (!shutdown_in_progress()) {
+ if (!generation_overflown) {
+ if (current_processing_generation > generation_at_query_time) {
+ return true;
+ }
+ } else {
+ assert(generations_to_wrap >= 0, "Sanity check");
+ long current_generations_to_wrap = MAX_UNSIGNED_LONG - current_processing_generation;
+ assert(current_generations_to_wrap >= 0, "Sanity check");
+ // to overflow an unsigned long should take long time, so to_wrap check should be sufficient
+ if (current_generations_to_wrap > generations_to_wrap &&
+ current_processing_generation > generation_at_query_time) {
+ return true;
+ }
+ }
+
+ // if worker thread is idle, but generation is not advancing, that means
+ // there is not safepoint to let NMT advance generation, force one.
+ if (_worker_thread_idle) {
+ VM_ForceSafepoint vfs;
+ VMThread::execute(&vfs);
+ }
+ MemSnapshot* snapshot = get_snapshot();
+ if (snapshot == NULL) {
+ return false;
+ }
+ snapshot->wait(1000);
+ current_processing_generation = _processing_generation;
+ }
+ // We end up here if NMT is shutting down before our data has been merged
+ return false;
+}
+
// compare memory usage between current snapshot and baseline
bool MemTracker::compare_memory_usage(BaselineOutputer& out, size_t unit, bool summary_only) {
MutexLockerEx lock(_query_lock, true);
diff --git a/src/share/vm/services/memTracker.hpp b/src/share/vm/services/memTracker.hpp
index 538195c0c..764b29505 100644
--- a/src/share/vm/services/memTracker.hpp
+++ b/src/share/vm/services/memTracker.hpp
@@ -91,9 +91,10 @@ class MemTracker : AllStatic {
static bool compare_memory_usage(BaselineOutputer& out, size_t unit,
bool summary_only = true) { }
+ static bool wbtest_wait_for_data_merge() { }
+
static inline void sync() { }
static inline void thread_exiting(JavaThread* thread) { }
-
};
@@ -111,6 +112,10 @@ class MemTracker : AllStatic {
extern bool NMT_track_callsite;
+#ifndef MAX_UNSIGNED_LONG
+#define MAX_UNSIGNED_LONG (unsigned long)(-1)
+#endif
+
#ifdef ASSERT
#define DEBUG_CALLER_PC (NMT_track_callsite ? os::get_caller_pc(2) : 0)
#else
@@ -380,6 +385,11 @@ class MemTracker : AllStatic {
static bool compare_memory_usage(BaselineOutputer& out, size_t unit,
bool summary_only = true);
+ // the version for whitebox testing support, it ensures that all memory
+ // activities before this method call, are reflected in the snapshot
+ // database.
+ static bool wbtest_wait_for_data_merge();
+
// sync is called within global safepoint to synchronize nmt data
static void sync();
@@ -432,6 +442,15 @@ class MemTracker : AllStatic {
static void create_record_in_recorder(address addr, MEMFLAGS type,
size_t size, address pc, JavaThread* thread);
+ static void set_current_processing_generation(unsigned long generation) {
+ _worker_thread_idle = false;
+ _processing_generation = generation;
+ }
+
+ static void report_worker_idle() {
+ _worker_thread_idle = true;
+ }
+
private:
// global memory snapshot
static MemSnapshot* _snapshot;
@@ -483,6 +502,11 @@ class MemTracker : AllStatic {
static volatile enum NMTStates _state;
// the reason for shutting down nmt
static enum ShutdownReason _reason;
+ // the generation that NMT is processing
+ static volatile unsigned long _processing_generation;
+ // although NMT is still procesing current generation, but
+ // there is not more recorder to process, set idle state
+ static volatile bool _worker_thread_idle;
};
#endif // !INCLUDE_NMT
diff --git a/src/share/vm/services/memoryPool.cpp b/src/share/vm/services/memoryPool.cpp
index dc608c492..e2895b1f8 100644
--- a/src/share/vm/services/memoryPool.cpp
+++ b/src/share/vm/services/memoryPool.cpp
@@ -32,6 +32,7 @@
#include "services/management.hpp"
#include "services/memoryManager.hpp"
#include "services/memoryPool.hpp"
+#include "utilities/macros.hpp"
MemoryPool::MemoryPool(const char* name,
PoolType type,
@@ -208,7 +209,7 @@ MemoryUsage SurvivorContiguousSpacePool::get_memory_usage() {
return MemoryUsage(initial_size(), used, committed, maxSize);
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
CompactibleFreeListSpacePool::CompactibleFreeListSpacePool(CompactibleFreeListSpace* space,
const char* name,
PoolType type,
@@ -225,7 +226,7 @@ MemoryUsage CompactibleFreeListSpacePool::get_memory_usage() {
return MemoryUsage(initial_size(), used, committed, maxSize);
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
GenerationPool::GenerationPool(Generation* gen,
const char* name,
diff --git a/src/share/vm/services/memoryPool.hpp b/src/share/vm/services/memoryPool.hpp
index c97fdbfa7..826061853 100644
--- a/src/share/vm/services/memoryPool.hpp
+++ b/src/share/vm/services/memoryPool.hpp
@@ -30,9 +30,10 @@
#include "memory/heap.hpp"
#include "memory/space.hpp"
#include "services/memoryUsage.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
// A memory pool represents the memory area that the VM manages.
// The Java virtual machine has at least one memory pool
@@ -185,7 +186,7 @@ public:
}
};
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
class CompactibleFreeListSpacePool : public CollectedMemoryPool {
private:
CompactibleFreeListSpace* _space;
@@ -199,7 +200,7 @@ public:
MemoryUsage get_memory_usage();
size_t used_in_bytes() { return _space->used(); }
};
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
class GenerationPool : public CollectedMemoryPool {
diff --git a/src/share/vm/services/memoryService.cpp b/src/share/vm/services/memoryService.cpp
index 03af9b998..0040f9d96 100644
--- a/src/share/vm/services/memoryService.cpp
+++ b/src/share/vm/services/memoryService.cpp
@@ -43,7 +43,8 @@
#include "services/memoryPool.hpp"
#include "services/memoryService.hpp"
#include "utilities/growableArray.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/parNew/parNewGeneration.hpp"
@@ -52,7 +53,7 @@
#include "gc_implementation/parallelScavenge/psYoungGen.hpp"
#include "services/g1MemoryPool.hpp"
#include "services/psMemoryPool.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
GrowableArray<MemoryPool*>* MemoryService::_pools_list =
new (ResourceObj::C_HEAP, mtInternal) GrowableArray<MemoryPool*>(init_pools_list_size, true);
@@ -83,7 +84,7 @@ void MemoryService::set_universe_heap(CollectedHeap* heap) {
add_gen_collected_heap_info(GenCollectedHeap::heap());
break;
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
case CollectedHeap::ParallelScavengeHeap : {
add_parallel_scavenge_heap_info(ParallelScavengeHeap::heap());
break;
@@ -92,7 +93,7 @@ void MemoryService::set_universe_heap(CollectedHeap* heap) {
add_g1_heap_info(G1CollectedHeap::heap());
break;
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
default: {
guarantee(false, "Unrecognized kind of heap");
}
@@ -130,22 +131,22 @@ void MemoryService::add_gen_collected_heap_info(GenCollectedHeap* heap) {
case Generation::DefNew:
_minor_gc_manager = MemoryManager::get_copy_memory_manager();
break;
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
case Generation::ParNew:
case Generation::ASParNew:
_minor_gc_manager = MemoryManager::get_parnew_memory_manager();
break;
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
default:
guarantee(false, "Unrecognized generation spec");
break;
}
if (policy->is_mark_sweep_policy()) {
_major_gc_manager = MemoryManager::get_msc_memory_manager();
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
} else if (policy->is_concurrent_mark_sweep_policy()) {
_major_gc_manager = MemoryManager::get_cms_memory_manager();
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
} else {
guarantee(false, "Unknown two-gen policy");
}
@@ -159,7 +160,7 @@ void MemoryService::add_gen_collected_heap_info(GenCollectedHeap* heap) {
add_generation_memory_pool(heap->get_gen(major), _major_gc_manager);
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
// Add memory pools for ParallelScavengeHeap
// This function currently only supports two generations collected heap.
// The collector for ParallelScavengeHeap will have two memory managers.
@@ -185,7 +186,7 @@ void MemoryService::add_g1_heap_info(G1CollectedHeap* g1h) {
add_g1YoungGen_memory_pool(g1h, _major_gc_manager, _minor_gc_manager);
add_g1OldGen_memory_pool(g1h, _major_gc_manager);
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
MemoryPool* MemoryService::add_gen(Generation* gen,
const char* name,
@@ -222,7 +223,7 @@ MemoryPool* MemoryService::add_survivor_spaces(DefNewGeneration* gen,
return (MemoryPool*) pool;
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
MemoryPool* MemoryService::add_cms_space(CompactibleFreeListSpace* space,
const char* name,
bool is_heap,
@@ -233,7 +234,7 @@ MemoryPool* MemoryService::add_cms_space(CompactibleFreeListSpace* space,
_pools_list->append(pool);
return (MemoryPool*) pool;
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
// Add memory pool(s) for one generation
void MemoryService::add_generation_memory_pool(Generation* gen,
@@ -261,7 +262,7 @@ void MemoryService::add_generation_memory_pool(Generation* gen,
break;
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
case Generation::ParNew:
case Generation::ASParNew:
{
@@ -282,7 +283,7 @@ void MemoryService::add_generation_memory_pool(Generation* gen,
break;
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
case Generation::MarkSweepCompact: {
assert(major_mgr != NULL && minor_mgr == NULL, "Should have only one manager");
@@ -293,7 +294,7 @@ void MemoryService::add_generation_memory_pool(Generation* gen,
break;
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
case Generation::ConcurrentMarkSweep:
case Generation::ASConcurrentMarkSweep:
{
@@ -306,7 +307,7 @@ void MemoryService::add_generation_memory_pool(Generation* gen,
true /* support_usage_threshold */);
break;
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
default:
assert(false, "should not reach here");
@@ -326,7 +327,7 @@ void MemoryService::add_generation_memory_pool(Generation* gen,
}
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
void MemoryService::add_psYoung_memory_pool(PSYoungGen* gen, MemoryManager* major_mgr, MemoryManager* minor_mgr) {
assert(major_mgr != NULL && minor_mgr != NULL, "Should have two managers");
@@ -384,7 +385,7 @@ void MemoryService::add_g1OldGen_memory_pool(G1CollectedHeap* g1h,
mgr->add_pool(old_gen);
_pools_list->append(old_gen);
}
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
void MemoryService::add_code_heap_memory_pool(CodeHeap* heap) {
_code_heap_pool = new CodeHeapPool(heap,
@@ -534,17 +535,17 @@ Handle MemoryService::create_MemoryUsage_obj(MemoryUsage usage, TRAPS) {
TraceMemoryManagerStats::TraceMemoryManagerStats(Generation::Name kind, GCCause::Cause cause) {
switch (kind) {
case Generation::DefNew:
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
case Generation::ParNew:
case Generation::ASParNew:
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
_fullGC=false;
break;
case Generation::MarkSweepCompact:
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
case Generation::ConcurrentMarkSweep:
case Generation::ASConcurrentMarkSweep:
-#endif // SERIALGC
+#endif // INCLUDE_ALL_GCS
_fullGC=true;
break;
default:
diff --git a/src/share/vm/services/psMemoryPool.hpp b/src/share/vm/services/psMemoryPool.hpp
index 2fd193f70..080b49161 100644
--- a/src/share/vm/services/psMemoryPool.hpp
+++ b/src/share/vm/services/psMemoryPool.hpp
@@ -25,7 +25,8 @@
#ifndef SHARE_VM_SERVICES_PSMEMORYPOOL_HPP
#define SHARE_VM_SERVICES_PSMEMORYPOOL_HPP
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "gc_implementation/parallelScavenge/psOldGen.hpp"
#include "gc_implementation/parallelScavenge/psYoungGen.hpp"
#include "gc_implementation/shared/mutableSpace.hpp"
@@ -34,7 +35,7 @@
#include "memory/space.hpp"
#include "services/memoryPool.hpp"
#include "services/memoryUsage.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
class PSGenerationPool : public CollectedMemoryPool {
private:
diff --git a/src/share/vm/services/runtimeService.cpp b/src/share/vm/services/runtimeService.cpp
index bba6a95af..49997dfc5 100644
--- a/src/share/vm/services/runtimeService.cpp
+++ b/src/share/vm/services/runtimeService.cpp
@@ -29,6 +29,7 @@
#include "services/runtimeService.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/exceptions.hpp"
+#include "utilities/macros.hpp"
#ifndef USDT2
HS_DTRACE_PROBE_DECL(hs_private, safepoint__begin);
diff --git a/src/share/vm/utilities/macros.hpp b/src/share/vm/utilities/macros.hpp
index 64e331d90..a97e9e7d0 100644
--- a/src/share/vm/utilities/macros.hpp
+++ b/src/share/vm/utilities/macros.hpp
@@ -130,23 +130,23 @@
#endif // INCLUDE_MANAGEMENT
/*
- * When INCLUDE_ALTERNATE_GCS is false the only garbage collectors
+ * When INCLUDE_ALL_GCS is false the only garbage collectors
* included in the JVM are defaultNewGeneration and markCompact.
*
- * When INCLUDE_ALTERNATE_GCS is true all garbage collectors are
+ * When INCLUDE_ALL_GCS is true all garbage collectors are
* included in the JVM.
*/
-#ifndef INCLUDE_ALTERNATE_GCS
-#define INCLUDE_ALTERNATE_GCS 1
-#endif // INCLUDE_ALTERNATE_GCS
+#ifndef INCLUDE_ALL_GCS
+#define INCLUDE_ALL_GCS 1
+#endif // INCLUDE_ALL_GCS
-#if INCLUDE_ALTERNATE_GCS
-#define NOT_ALTERNATE_GCS_RETURN /* next token must be ; */
-#define NOT_ALTERNATE_GCS_RETURN_(code) /* next token must be ; */
+#if INCLUDE_ALL_GCS
+#define NOT_ALL_GCS_RETURN /* next token must be ; */
+#define NOT_ALL_GCS_RETURN_(code) /* next token must be ; */
#else
-#define NOT_ALTERNATE_GCS_RETURN {}
-#define NOT_ALTERNATE_GCS_RETURN_(code) { return code; }
-#endif // INCLUDE_ALTERNATE_GCS
+#define NOT_ALL_GCS_RETURN {}
+#define NOT_ALL_GCS_RETURN_(code) { return code; }
+#endif // INCLUDE_ALL_GCS
#ifndef INCLUDE_NMT
#define INCLUDE_NMT 1
diff --git a/src/share/vm/utilities/top.hpp b/src/share/vm/utilities/top.hpp
index 034148a50..b1abbc2f6 100644
--- a/src/share/vm/utilities/top.hpp
+++ b/src/share/vm/utilities/top.hpp
@@ -33,9 +33,9 @@
#include "utilities/macros.hpp"
#include "utilities/ostream.hpp"
#include "utilities/sizes.hpp"
-#ifndef SERIALGC
+#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/g1_globals.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
#ifdef COMPILER1
#include "c1/c1_globals.hpp"
#endif
diff --git a/src/share/vm/utilities/yieldingWorkgroup.cpp b/src/share/vm/utilities/yieldingWorkgroup.cpp
index 7e594232a..e344aea4b 100644
--- a/src/share/vm/utilities/yieldingWorkgroup.cpp
+++ b/src/share/vm/utilities/yieldingWorkgroup.cpp
@@ -23,9 +23,10 @@
*/
#include "precompiled.hpp"
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "utilities/yieldingWorkgroup.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
// Forward declaration of classes declared here.
diff --git a/src/share/vm/utilities/yieldingWorkgroup.hpp b/src/share/vm/utilities/yieldingWorkgroup.hpp
index f9646f91f..5a626ce7f 100644
--- a/src/share/vm/utilities/yieldingWorkgroup.hpp
+++ b/src/share/vm/utilities/yieldingWorkgroup.hpp
@@ -25,9 +25,10 @@
#ifndef SHARE_VM_UTILITIES_YIELDINGWORKGROUP_HPP
#define SHARE_VM_UTILITIES_YIELDINGWORKGROUP_HPP
-#ifndef SERIALGC
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
#include "utilities/workgroup.hpp"
-#endif
+#endif // INCLUDE_ALL_GCS
// Forward declarations
diff --git a/test/TEST.ROOT b/test/TEST.ROOT
index 24014f682..629bb54dd 100644
--- a/test/TEST.ROOT
+++ b/test/TEST.ROOT
@@ -28,4 +28,4 @@
# DO NOT EDIT without first contacting hotspot-regtest@sun.com
# The list of keywords supported in this test suite
-keys=cte_test
+keys=cte_test jcmd nmt regression
diff --git a/test/compiler/8004741/Test8004741.java b/test/compiler/8004741/Test8004741.java
index 95e63b9c0..baacc3476 100644
--- a/test/compiler/8004741/Test8004741.java
+++ b/test/compiler/8004741/Test8004741.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -25,70 +25,160 @@
* @test Test8004741.java
* @bug 8004741
* @summary Missing compiled exception handle table entry for multidimensional array allocation
+ * @run main/othervm -Xmx64m -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:+StressCompiledExceptionHandlers -XX:+SafepointALot -XX:GuaranteedSafepointInterval=100 Test8004741
* @run main/othervm -Xmx64m -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:+StressCompiledExceptionHandlers Test8004741
- *
*/
import java.util.*;
public class Test8004741 extends Thread {
+ static int passed = 0;
+
+ /**
+ * Loop forever allocating 2-d arrays.
+ * Catches and rethrows all exceptions; in the case of ThreadDeath, increments passed.
+ * Note that passed is incremented here because this is the exception handler with
+ * the smallest scope; we only want to declare success in the case where it is highly
+ * likely that the test condition
+ * (exception in 2-d array alloc interrupted by ThreadDeath)
+ * actually occurs.
+ */
static int[][] test(int a, int b) throws Exception {
- int[][] ar = null;
+ int[][] ar;
try {
ar = new int[a][b];
- } catch (Error e) {
- System.out.println("test got Error");
- passed = true;
- throw(e);
- } catch (Exception e) {
- System.out.println("test got Exception");
+ } catch (ThreadDeath e) {
+ System.out.println("test got ThreadDeath");
+ passed++;
throw(e);
}
return ar;
}
- static boolean passed = false;
+ /* Cookbook wait-notify to track progress of test thread. */
+ Object progressLock = new Object();
+ private static final int NOT_STARTED = 0;
+ private static final int RUNNING = 1;
+ private static final int STOPPING = 2;
- public void run() {
- System.out.println("test started");
- try {
- while(true) {
- test(2,20000);
+ int progressState = NOT_STARTED;
+
+ void toState(int state) {
+ synchronized (progressLock) {
+ progressState = state;
+ progressLock.notify();
+ }
+ }
+
+ void waitFor(int state) {
+ synchronized (progressLock) {
+ while (progressState < state) {
+ try {
+ progressLock.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ System.out.println("unexpected InterruptedException");
+ fail();
}
- } catch (ThreadDeath e) {
- System.out.println("test got ThreadDeath");
- passed = true;
- } catch (Error e) {
- e.printStackTrace();
- System.out.println("test got Error");
- } catch (Exception e) {
- e.printStackTrace();
- System.out.println("test got Exception");
}
+ if (progressState > state) {
+ System.out.println("unexpected test state change, expected " +
+ state + " but saw " + progressState);
+ fail();
+ }
+ }
}
- public static void main(String[] args) throws Exception {
- for (int n = 0; n < 11000; n++) {
- test(2, 20);
+ /**
+ * Loops running test until some sort of an exception or error,
+ * expects to see ThreadDeath.
+ */
+ public void run() {
+ try {
+ // Print before state change, so that other thread is most likely
+ // to see this thread executing calls to test() in a loop.
+ System.out.println("thread running");
+ toState(RUNNING);
+ while (true) {
+ // (2,2) (2,10) (2,100) were observed to tickle the bug;
+ test(2, 100);
+ }
+ } catch (ThreadDeath e) {
+ // nothing to say, passing was incremented by the test.
+ } catch (Throwable e) {
+ e.printStackTrace();
+ System.out.println("unexpected Throwable " + e);
+ fail();
}
+ toState(STOPPING);
+ }
- // First test exception catch
+ /**
+ * Runs a single trial of the test in a thread.
+ * No single trial is definitive, since the ThreadDeath
+ * exception might not land in the tested region of code.
+ */
+ public static void threadTest() throws InterruptedException {
Test8004741 t = new Test8004741();
-
- passed = false;
t.start();
- Thread.sleep(1000);
+ t.waitFor(RUNNING);
+ Thread.sleep(100);
+ System.out.println("stopping thread");
t.stop();
-
- Thread.sleep(5000);
+ t.waitFor(STOPPING);
t.join();
- if (passed) {
+ }
+
+ public static void main(String[] args) throws Exception {
+ // Warm up "test"
+ // t will never be started.
+ for (int n = 0; n < 11000; n++) {
+ test(2, 100);
+ }
+
+ // Will this sleep help ensure that the compiler is run?
+ Thread.sleep(500);
+ passed = 0;
+
+ try {
+ test(-1, 100);
+ System.out.println("Missing NegativeArraySizeException #1");
+ fail();
+ } catch ( java.lang.NegativeArraySizeException e ) {
+ System.out.println("Saw expected NegativeArraySizeException #1");
+ }
+
+ try {
+ test(100, -1);
+ fail();
+ System.out.println("Missing NegativeArraySizeException #2");
+ fail();
+ } catch ( java.lang.NegativeArraySizeException e ) {
+ System.out.println("Saw expected NegativeArraySizeException #2");
+ }
+
+ /* Test repetitions. If the test succeeds-mostly, it succeeds,
+ * as long as it does not crash (the outcome if the exception range
+ * table entry for the array allocation is missing).
+ */
+ int N = 12;
+ for (int n = 0; n < N; n++) {
+ threadTest();
+ }
+
+ if (passed > N/2) {
+ System.out.println("Saw " + passed + " out of " + N + " possible ThreadDeath hits");
System.out.println("PASSED");
} else {
- System.out.println("FAILED");
- System.exit(97);
+ System.out.println("Too few ThreadDeath hits; expected at least " + N/2 +
+ " but saw only " + passed);
+ fail();
}
}
+ static void fail() {
+ System.out.println("FAILED");
+ System.exit(97);
+ }
};
diff --git a/test/runtime/7158988/FieldMonitor.java b/test/runtime/7158988/FieldMonitor.java
index 584d39d20..5421f6262 100644
--- a/test/runtime/7158988/FieldMonitor.java
+++ b/test/runtime/7158988/FieldMonitor.java
@@ -24,8 +24,10 @@
/*
* @test FieldMonitor.java
* @bug 7158988
+ * @key regression
* @summary verify jvm does not crash while debugging
- * @run shell TestFieldMonitor.sh
+ * @run compile TestPostFieldModification.java
+ * @run main/othervm FieldMonitor
* @author axel.siebenborn@sap.com
*/
import java.io.BufferedReader;
diff --git a/test/runtime/7158988/TestFieldMonitor.sh b/test/runtime/7158988/TestFieldMonitor.sh
deleted file mode 100644
index aa18c1609..000000000
--- a/test/runtime/7158988/TestFieldMonitor.sh
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/bin/sh
-
-if [ "${TESTSRC}" = "" ]
-then TESTSRC=.
-fi
-
-if [ "${TESTJAVA}" = "" ]
-then
- PARENT=`dirname \`which java\``
- TESTJAVA=`dirname ${PARENT}`
- echo "TESTJAVA not set, selecting " ${TESTJAVA}
- echo "If this is incorrect, try setting the variable manually."
-fi
-
-if [ "${TESTCLASSES}" = "" ]
-then
- echo "TESTCLASSES not set. Test cannot execute. Failed."
- exit 1
-fi
-
-# set platform-dependent variables
-OS=`uname -s`
-case "$OS" in
- SunOS | Linux | Darwin)
- NULL=/dev/null
- PS=":"
- FS="/"
- ;;
- Windows_95 | Windows_98 | Windows_ME )
- NULL=NUL
- PS=";"
- FS="\\"
- echo "Test skipped, only for WinNT"
- exit 0
- ;;
- Windows_NT )
- NULL=NUL
- PS=";"
- FS="\\"
- ;;
- CYGWIN_NT* )
- NULL=/dev/null
- PS=";"
- FS="/"
- ;;
- CYGWIN_* )
- NULL=/dev/null
- PS=";"
- FS="/"
- echo "Test skipped, only for WinNT"
- exit 0
- ;;
- * )
- echo "Unrecognized system!"
- exit 1;
- ;;
-esac
-
-#CLASSPATH=.${PS}${TESTCLASSES} ; export CLASSPATH
-
-cp ${TESTSRC}${FS}*.java .
-
-${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -fullversion
-
-${TESTJAVA}${FS}bin${FS}javac -classpath .${PS}$TESTJAVA${FS}lib${FS}tools.jar *.java
-
-${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -classpath .${PS}$TESTJAVA${FS}lib${FS}tools.jar FieldMonitor > test.out
-
-grep "A fatal error has been detected" test.out > ${NULL}
-if [ $? = 0 ]; then
- cat test.out
- STATUS=1
-fi
-
-exit $STATUS
diff --git a/test/runtime/8000968/Test8000968.sh b/test/runtime/8000968/Test8000968.sh
new file mode 100644
index 000000000..cd7183476
--- /dev/null
+++ b/test/runtime/8000968/Test8000968.sh
@@ -0,0 +1,99 @@
+#
+# 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 Test8000968.sh
+# @bug 8000968
+# @summary NPG: UseCompressedKlassPointers asserts with ObjectAlignmentInBytes=32
+# @run shell Test8000968.sh
+#
+
+if [ "${TESTJAVA}" = "" ]
+then
+ PARENT=`dirname \`which java\``
+ TESTJAVA=`dirname ${PARENT}`
+ printf "TESTJAVA not set, selecting " ${TESTJAVA}
+ printf " If this is incorrect, try setting the variable manually.\n"
+fi
+
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+ Windows_* )
+ FS="\\"
+ NULL=NUL
+ ;;
+ * )
+ FS="/"
+ NULL=/dev/null
+ ;;
+esac
+
+JAVA=${TESTJAVA}${FS}bin${FS}java
+
+#
+# See if platform has 64 bit java.
+#
+${JAVA} ${TESTVMOPTS} -d64 -version 2>&1 | grep -i "does not support" > ${NULL}
+if [ "$?" != "1" ]
+then
+ printf "Platform is 32 bit, does not support -XX:ObjectAlignmentInBytes= option.\n"
+ printf "Passed.\n"
+ exit 0
+fi
+
+#
+# Test -XX:ObjectAlignmentInBytes with -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops.
+#
+${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=16 -version 2>&1 > ${NULL}
+if [ "$?" != "0" ]
+then
+ printf "FAILED: -XX:ObjectAlignmentInBytes=16 option did not work.\n"
+ exit 1
+fi
+
+${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=32 -version 2>&1 > ${NULL}
+if [ "$?" != "0" ]
+then
+ printf "FAILED: -XX:ObjectAlignmentInBytes=32 option did not work.\n"
+ exit 1
+fi
+
+${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=64 -version 2>&1 > ${NULL}
+if [ "$?" != "0" ]
+then
+ printf "FAILED: -XX:ObjectAlignmentInBytes=64 option did not work.\n"
+ exit 1
+fi
+
+${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=128 -version 2>&1 > ${NULL}
+if [ "$?" != "0" ]
+then
+ printf "FAILED: -XX:ObjectAlignmentInBytes=128 option did not work.\n"
+ exit 1
+fi
+
+
+printf "Passed.\n"
+exit 0
diff --git a/test/runtime/8007475/StackMapFrameTest.java b/test/runtime/8007475/StackMapFrameTest.java
new file mode 100644
index 000000000..b927ae76d
--- /dev/null
+++ b/test/runtime/8007475/StackMapFrameTest.java
@@ -0,0 +1,41 @@
+/*
+ * 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 8007475
+ * @summary Test memory stomp in stack map test
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseMallocOnly StackMapFrameTest
+ */
+public class StackMapFrameTest {
+
+ public static void foo() {
+ Object o = new Object();
+ }
+
+ public static void main(String args[]) {
+ for (int i = 0; i < 25000; i++) {
+ foo();
+ }
+ }
+}
diff --git a/test/runtime/NMT/AllocTestType.java b/test/runtime/NMT/AllocTestType.java
new file mode 100644
index 000000000..764488444
--- /dev/null
+++ b/test/runtime/NMT/AllocTestType.java
@@ -0,0 +1,72 @@
+/*
+ * 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
+ * @summary Test consistency of NMT by leaking a few select allocations of the Test type and then verify visibility with jcmd
+ * @key nmt jcmd
+ * @library /testlibrary
+ * @run compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI AllocTestType.java
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail AllocTestType
+ */
+
+import com.oracle.java.testlibrary.*;
+import sun.hotspot.WhiteBox;
+
+public class AllocTestType {
+
+ public static void main(String args[]) throws Exception {
+ OutputAnalyzer output;
+
+ // Grab my own PID
+ String pid = Integer.toString(ProcessTools.getProcessId());
+ ProcessBuilder pb = new ProcessBuilder();
+
+ // Use WB API to alloc with the mtTest type
+ if (!WhiteBox.getWhiteBox().NMTAllocTest()) {
+ throw new Exception("Call to WB API NMTAllocTest() failed");
+ }
+
+ // Use WB API to ensure that all data has been merged before we continue
+ if (!WhiteBox.getWhiteBox().NMTWaitForDataMerge()) {
+ throw new Exception("Call to WB API NMTWaitForDataMerge() failed");
+ }
+
+ // Run 'jcmd <pid> VM.native_memory summary'
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary"});
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Test (reserved=512KB, committed=512KB)");
+
+ // Free the memory allocated by NMTAllocTest
+ if (!WhiteBox.getWhiteBox().NMTFreeTestMemory()) {
+ throw new Exception("Call to WB API NMTFreeTestMemory() failed");
+ }
+
+ // Use WB API to ensure that all data has been merged before we continue
+ if (!WhiteBox.getWhiteBox().NMTWaitForDataMerge()) {
+ throw new Exception("Call to WB API NMTWaitForDataMerge() failed");
+ }
+ output = new OutputAnalyzer(pb.start());
+ output.shouldNotContain("Test (reserved=");
+ }
+}
diff --git a/test/runtime/NMT/BaselineWithParameter.java b/test/runtime/NMT/BaselineWithParameter.java
new file mode 100644
index 000000000..594bd7165
--- /dev/null
+++ b/test/runtime/NMT/BaselineWithParameter.java
@@ -0,0 +1,54 @@
+/*
+ * 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 8004802
+ * @key nmt jcmd regression
+ * @summary Regression test for invoking a jcmd with baseline=false, result was that the target VM crashed
+ * @library /testlibrary
+ * @run main/othervm -XX:NativeMemoryTracking=detail BaselineWithParameter
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class BaselineWithParameter {
+
+ public static void main(String args[]) throws Exception {
+ // Grab my own PID
+ String pid = Integer.toString(ProcessTools.getProcessId());
+ OutputAnalyzer output;
+
+ ProcessBuilder pb = new ProcessBuilder();
+
+ // Run 'jcmd <pid> VM.native_memory baseline=false'
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "baseline=false"});
+ pb.start();
+
+ // Run 'jcmd <pid> VM.native_memory summary=false'
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary=false"});
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("No command to execute");
+
+ }
+}
diff --git a/test/runtime/NMT/CommandLineDetail.java b/test/runtime/NMT/CommandLineDetail.java
new file mode 100644
index 000000000..d993316ba
--- /dev/null
+++ b/test/runtime/NMT/CommandLineDetail.java
@@ -0,0 +1,45 @@
+/*
+ * 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
+ * @key nmt
+ * @summary Running with NMT detail should not result in an error or warning
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class CommandLineDetail {
+
+ public static void main(String args[]) throws Exception {
+
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:NativeMemoryTracking=detail",
+ "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldNotContain("error");
+ output.shouldNotContain("warning");
+ output.shouldHaveExitValue(0);
+ }
+}
diff --git a/test/runtime/NMT/CommandLineEmptyArgument.java b/test/runtime/NMT/CommandLineEmptyArgument.java
new file mode 100644
index 000000000..956cdd260
--- /dev/null
+++ b/test/runtime/NMT/CommandLineEmptyArgument.java
@@ -0,0 +1,41 @@
+/*
+ * 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
+ * @key nmt
+ * @summary Empty argument to NMT should result in an informative error message
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class CommandLineEmptyArgument {
+
+ public static void main(String args[]) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:NativeMemoryTracking=");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Syntax error, expecting -XX:NativeMemoryTracking=[off|summary|detail]");
+ output.shouldHaveExitValue(1);
+ }
+}
diff --git a/test/runtime/NMT/CommandLineInvalidArgument.java b/test/runtime/NMT/CommandLineInvalidArgument.java
new file mode 100644
index 000000000..79cc2de94
--- /dev/null
+++ b/test/runtime/NMT/CommandLineInvalidArgument.java
@@ -0,0 +1,41 @@
+/*
+ * 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
+ * @key nmt
+ * @summary Invalid argument to NMT should result in an informative error message
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class CommandLineInvalidArgument {
+
+ public static void main(String args[]) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:NativeMemoryTracking=apa");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Syntax error, expecting -XX:NativeMemoryTracking=[off|summary|detail]");
+ output.shouldHaveExitValue(1);
+ }
+}
diff --git a/test/runtime/NMT/CommandLineSummary.java b/test/runtime/NMT/CommandLineSummary.java
new file mode 100644
index 000000000..b8415d1bd
--- /dev/null
+++ b/test/runtime/NMT/CommandLineSummary.java
@@ -0,0 +1,45 @@
+/*
+ * 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
+ * @key nmt
+ * @summary Running with NMT summary should not result in an error or warning
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class CommandLineSummary {
+
+ public static void main(String args[]) throws Exception {
+
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:NativeMemoryTracking=summary",
+ "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldNotContain("error");
+ output.shouldNotContain("warning");
+ output.shouldHaveExitValue(0);
+ }
+}
diff --git a/test/runtime/NMT/CommandLineTurnOffNMT.java b/test/runtime/NMT/CommandLineTurnOffNMT.java
new file mode 100644
index 000000000..e8d950cba
--- /dev/null
+++ b/test/runtime/NMT/CommandLineTurnOffNMT.java
@@ -0,0 +1,44 @@
+/*
+ * 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
+ * @key nmt
+ * @summary Turning off NMT should not result in an error or warning
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class CommandLineTurnOffNMT {
+
+ public static void main(String args[]) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:NativeMemoryTracking=off",
+ "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldNotContain("error");
+ output.shouldNotContain("warning");
+ output.shouldHaveExitValue(0);
+ }
+}
diff --git a/test/runtime/NMT/JcmdScale.java b/test/runtime/NMT/JcmdScale.java
new file mode 100644
index 000000000..e57d27b59
--- /dev/null
+++ b/test/runtime/NMT/JcmdScale.java
@@ -0,0 +1,67 @@
+/*
+ * 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
+ * @key nmt jcmd
+ * @summary Test the NMT scale parameter
+ * @library /testlibrary
+ * @run main/othervm -XX:NativeMemoryTracking=summary JcmdScale
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class JcmdScale {
+
+ public static void main(String args[]) throws Exception {
+ ProcessBuilder pb = new ProcessBuilder();
+ OutputAnalyzer output;
+ // Grab my own PID
+ String pid = Integer.toString(ProcessTools.getProcessId());
+
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "scale=KB"});
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("KB, committed=");
+
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "scale=MB"});
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("MB, committed=");
+
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "scale=GB"});
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("GB, committed=");
+
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "scale=apa"});
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Incorrect scale value: apa");
+
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary", "scale=GB"});
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("GB, committed=");
+
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary", "scale=apa"});
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Incorrect scale value: apa");
+
+ }
+}
diff --git a/test/runtime/NMT/JcmdWithNMTDisabled.java b/test/runtime/NMT/JcmdWithNMTDisabled.java
new file mode 100644
index 000000000..7b58a8413
--- /dev/null
+++ b/test/runtime/NMT/JcmdWithNMTDisabled.java
@@ -0,0 +1,63 @@
+/*
+ * 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
+ * @key nmt jcmd
+ * @summary Verify that jcmd correctly reports that NMT is not enabled
+ * @library /testlibrary
+ * First run without enabling NMT
+ * @run main/othervm JcmdWithNMTDisabled
+ * Then run with explicitly disabling NMT, should not be any difference
+ * @run main/othervm -XX:NativeMemoryTracking=off JcmdWithNMTDisabled
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class JcmdWithNMTDisabled {
+ static ProcessBuilder pb = new ProcessBuilder();
+ static String pid;
+
+ public static void main(String args[]) throws Exception {
+ // Grab my own PID
+ pid = Integer.toString(ProcessTools.getProcessId());
+
+ jcmdCommand("summary");
+ jcmdCommand("detail");
+ jcmdCommand("baseline");
+ jcmdCommand("summary.diff");
+ jcmdCommand("detail.diff");
+ jcmdCommand("scale=GB");
+ jcmdCommand("shutdown");
+ }
+
+ // Helper method for invoking different jcmd calls, all should fail with the same message saying NMT is not enabled
+ public static void jcmdCommand(String command) throws Exception {
+
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", command});
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+ // Verify that jcmd reports that NMT is not enabled
+ output.shouldContain("Native memory tracking is not enabled");
+ }
+}
diff --git a/test/runtime/NMT/PrintNMTStatistics.java b/test/runtime/NMT/PrintNMTStatistics.java
new file mode 100644
index 000000000..307ab948a
--- /dev/null
+++ b/test/runtime/NMT/PrintNMTStatistics.java
@@ -0,0 +1,66 @@
+/*
+ * 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
+ * @key nmt regression
+ * @bug 8005936
+ * @summary Make sure PrintNMTStatistics works on normal JVM exit
+ * @library /testlibrary
+ * @run compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI PrintNMTStatistics.java
+ */
+
+import com.oracle.java.testlibrary.*;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import sun.hotspot.WhiteBox;
+
+public class PrintNMTStatistics {
+
+ public static void main(String args[]) throws Exception {
+
+ // We start a new java process running with an argument and use WB API to ensure
+ // we have data for NMT on VM exit
+ if (args.length > 0) {
+ // Use WB API to ensure that all data has been merged before we continue
+ if (!WhiteBox.getWhiteBox().NMTWaitForDataMerge()) {
+ throw new Exception("Call to WB API NMTWaitForDataMerge() failed");
+ }
+ return;
+ }
+
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:NativeMemoryTracking=summary",
+ "+XX:+PrintNMTStatistics",
+ "PrintNMTStatistics",
+ "test");
+
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Java Heap (reserved=");
+ output.shouldNotContain("error");
+ output.shouldNotContain("warning");
+ output.shouldHaveExitValue(0);
+ }
+}
diff --git a/test/runtime/NMT/PrintNMTStatisticsWithNMTDisabled.java b/test/runtime/NMT/PrintNMTStatisticsWithNMTDisabled.java
new file mode 100644
index 000000000..1c25f284d
--- /dev/null
+++ b/test/runtime/NMT/PrintNMTStatisticsWithNMTDisabled.java
@@ -0,0 +1,44 @@
+/*
+ * 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
+ * @key nmt
+ * @summary Trying to enable PrintNMTStatistics should result in a warning
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class PrintNMTStatisticsWithNMTDisabled {
+
+ public static void main(String args[]) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:+PrintNMTStatistics",
+ "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("warning: PrintNMTStatistics is disabled, because native memory tracking is not enabled");
+ output.shouldHaveExitValue(0);
+ }
+}
diff --git a/test/runtime/NMT/ShutdownTwice.java b/test/runtime/NMT/ShutdownTwice.java
new file mode 100644
index 000000000..1bb327aed
--- /dev/null
+++ b/test/runtime/NMT/ShutdownTwice.java
@@ -0,0 +1,56 @@
+/*
+ * 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
+ * @key nmt jcmd
+ * @summary Run shutdown twice
+ * @library /testlibrary
+ * @run main/othervm -XX:NativeMemoryTracking=detail ShutdownTwice
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class ShutdownTwice {
+
+ public static void main(String args[]) throws Exception {
+ // Grab my own PID
+ String pid = Integer.toString(ProcessTools.getProcessId());
+ OutputAnalyzer output;
+
+ ProcessBuilder pb = new ProcessBuilder();
+
+ // Run 'jcmd <pid> VM.native_memory shutdown'
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "shutdown"});
+ output = new OutputAnalyzer(pb.start());
+
+ // Verify that jcmd reports that NMT is shutting down
+ output.shouldContain("Shutdown is in progress, it will take a few moments to completely shutdown");
+
+ // Run shutdown again
+ output = new OutputAnalyzer(pb.start());
+
+ // Verify that jcmd reports that NMT has been shutdown already
+ output.shouldContain("Native memory tracking has been shutdown by user");
+ }
+}
diff --git a/test/runtime/NMT/SummaryAfterShutdown.java b/test/runtime/NMT/SummaryAfterShutdown.java
new file mode 100644
index 000000000..96061f3f0
--- /dev/null
+++ b/test/runtime/NMT/SummaryAfterShutdown.java
@@ -0,0 +1,56 @@
+/*
+ * 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
+ * @key nmt jcmd
+ * @summary Verify that jcmd correctly reports that NMT is not enabled after a shutdown
+ * @library /testlibrary
+ * @run main/othervm -XX:NativeMemoryTracking=detail SummaryAfterShutdown
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class SummaryAfterShutdown {
+
+ public static void main(String args[]) throws Exception {
+ OutputAnalyzer output;
+ // Grab my own PID
+ String pid = Integer.toString(ProcessTools.getProcessId());
+ ProcessBuilder pb = new ProcessBuilder();
+
+ // Run 'jcmd <pid> VM.native_memory shutdown'
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "shutdown"});
+ output = new OutputAnalyzer(pb.start());
+
+ // Verify that jcmd reports that NMT is shutting down
+ output.shouldContain("Shutdown is in progress, it will take a few moments to completely shutdown");
+
+ // Run 'jcmd <pid> VM.native_memory summary'
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary"});
+ output = new OutputAnalyzer(pb.start());
+
+ // Verify that jcmd reports that NMT has been shutdown
+ output.shouldContain("Native memory tracking has been shutdown by user");
+ }
+}
diff --git a/test/runtime/NMT/SummarySanityCheck.java b/test/runtime/NMT/SummarySanityCheck.java
new file mode 100644
index 000000000..cf81d5b35
--- /dev/null
+++ b/test/runtime/NMT/SummarySanityCheck.java
@@ -0,0 +1,119 @@
+/*
+ * 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
+ * @key nmt jcmd
+ * @summary Sanity check the output of NMT
+ * @library /testlibrary
+ * @run compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI SummarySanityCheck.java
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:NativeMemoryTracking=summary -XX:+WhiteBoxAPI SummarySanityCheck
+ */
+
+import com.oracle.java.testlibrary.*;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import sun.hotspot.WhiteBox;
+
+public class SummarySanityCheck {
+
+ private static String jcmdout;
+ public static void main(String args[]) throws Exception {
+ // Grab my own PID
+ String pid = Integer.toString(ProcessTools.getProcessId());
+
+ // Use WB API to ensure that all data has been merged before we continue
+ if (!WhiteBox.getWhiteBox().NMTWaitForDataMerge()) {
+ throw new Exception("Call to WB API NMTWaitForDataMerge() failed");
+ }
+
+ ProcessBuilder pb = new ProcessBuilder();
+
+ // Run 'jcmd <pid> VM.native_memory summary scale=KB'
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary", "scale=KB"});
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+ jcmdout = output.getOutput();
+ // Split by '-' to get the 'groups'
+ String[] lines = jcmdout.split("\n");
+
+ if (lines.length == 0) {
+ throwTestException("Failed to parse jcmd output");
+ }
+
+ int totalCommitted = 0, totalReserved = 0;
+ int totalCommittedSum = 0, totalReservedSum = 0;
+
+ // Match '- <mtType> (reserved=<reserved>KB, committed=<committed>KB)
+ Pattern mtTypePattern = Pattern.compile("-\\s+(?<typename>[\\w\\s]+)\\(reserved=(?<reserved>\\d+)KB,\\scommitted=(?<committed>\\d+)KB\\)");
+ // Match 'Total: reserved=<reserved>KB, committed=<committed>KB'
+ Pattern totalMemoryPattern = Pattern.compile("Total\\:\\s\\sreserved=(?<reserved>\\d+)KB,\\s\\scommitted=(?<committed>\\d+)KB");
+
+ for (int i = 0; i < lines.length; i++) {
+ if (lines[i].startsWith("Total")) {
+ Matcher totalMemoryMatcher = totalMemoryPattern.matcher(lines[i]);
+
+ if (totalMemoryMatcher.matches() && totalMemoryMatcher.groupCount() == 2) {
+ totalCommitted = Integer.parseInt(totalMemoryMatcher.group("committed"));
+ totalReserved = Integer.parseInt(totalMemoryMatcher.group("reserved"));
+ } else {
+ throwTestException("Failed to match the expected groups in 'Total' memory part");
+ }
+ } else if (lines[i].startsWith("-")) {
+ Matcher typeMatcher = mtTypePattern.matcher(lines[i]);
+ if (typeMatcher.matches()) {
+ int typeCommitted = Integer.parseInt(typeMatcher.group("committed"));
+ int typeReserved = Integer.parseInt(typeMatcher.group("reserved"));
+
+ // Make sure reserved is always less or equals
+ if (typeCommitted > typeReserved) {
+ throwTestException("Committed (" + typeCommitted + ") was more than Reserved ("
+ + typeReserved + ") for mtType: " + typeMatcher.group("typename"));
+ }
+
+ // Add to total and compare them in the end
+ totalCommittedSum += typeCommitted;
+ totalReservedSum += typeReserved;
+ } else {
+ throwTestException("Failed to match the group on line " + i);
+ }
+ }
+ }
+
+ // See if they add up correctly, rounding is a problem so make sure we're within +/- 8KB
+ int committedDiff = totalCommitted - totalCommittedSum;
+ if (committedDiff > 8 || committedDiff < -8) {
+ throwTestException("Total committed (" + totalCommitted + ") did not match the summarized committed (" + totalCommittedSum + ")" );
+ }
+
+ int reservedDiff = totalReserved - totalReservedSum;
+ if (reservedDiff > 8 || reservedDiff < -8) {
+ throwTestException("Total reserved (" + totalReserved + ") did not match the summarized reserved (" + totalReservedSum + ")" );
+ }
+ }
+
+ private static void throwTestException(String reason) throws Exception {
+ throw new Exception(reason + " . Stdout is :\n" + jcmdout);
+ }
+}
diff --git a/test/testlibrary/OutputAnalyzerTest.java b/test/testlibrary/OutputAnalyzerTest.java
new file mode 100644
index 000000000..cc48fd3ff
--- /dev/null
+++ b/test/testlibrary/OutputAnalyzerTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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
+ * @summary Test the OutputAnalyzer utility class
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+public class OutputAnalyzerTest {
+
+ public static void main(String args[]) throws Exception {
+
+ String stdout = "aaaaaa";
+ String stderr = "bbbbbb";
+
+ OutputAnalyzer output = new OutputAnalyzer(stdout, stderr);
+
+ if (!stdout.equals(output.getStdout())) {
+ throw new Exception("getStdout() returned '" + output.getStdout() + "', expected '" + stdout + "'");
+ }
+
+ if (!stderr.equals(output.getStderr())) {
+ throw new Exception("getStderr() returned '" + output.getStderr() + "', expected '" + stderr + "'");
+ }
+
+ try {
+ output.shouldContain(stdout);
+ output.stdoutShouldContain(stdout);
+ output.shouldContain(stderr);
+ output.stderrShouldContain(stderr);
+ } catch (RuntimeException e) {
+ throw new Exception("shouldContain() failed", e);
+ }
+
+ try {
+ output.shouldContain("cccc");
+ throw new Exception("shouldContain() failed to throw exception");
+ } catch (RuntimeException e) {
+ // expected
+ }
+
+ try {
+ output.stdoutShouldContain(stderr);
+ throw new Exception("stdoutShouldContain() failed to throw exception");
+ } catch (RuntimeException e) {
+ // expected
+ }
+
+ try {
+ output.stderrShouldContain(stdout);
+ throw new Exception("stdoutShouldContain() failed to throw exception");
+ } catch (RuntimeException e) {
+ // expected
+ }
+
+ try {
+ output.shouldNotContain("cccc");
+ output.stdoutShouldNotContain("cccc");
+ output.stderrShouldNotContain("cccc");
+ } catch (RuntimeException e) {
+ throw new Exception("shouldNotContain() failed", e);
+ }
+
+ try {
+ output.shouldNotContain(stdout);
+ throw new Exception("shouldContain() failed to throw exception");
+ } catch (RuntimeException e) {
+ // expected
+ }
+
+ try {
+ output.stdoutShouldNotContain(stdout);
+ throw new Exception("shouldContain() failed to throw exception");
+ } catch (RuntimeException e) {
+ // expected
+ }
+
+ try {
+ output.stderrShouldNotContain(stderr);
+ throw new Exception("shouldContain() failed to throw exception");
+ } catch (RuntimeException e) {
+ // expected
+ }
+ }
+}
diff --git a/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java b/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java
new file mode 100644
index 000000000..91ad6a8c8
--- /dev/null
+++ b/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+package com.oracle.java.testlibrary;
+
+import java.io.File;
+
+public final class JDKToolFinder {
+
+ private JDKToolFinder() {
+ }
+
+ /**
+ * Returns the full path to an executable in jdk/bin based on System property
+ * test.jdk (set by jtreg test suite)
+ *
+ * @return Full path to an executable in jdk/bin
+ */
+ public static String getJDKTool(String tool) {
+ String binPath = System.getProperty("test.jdk");
+ if (binPath == null) {
+ throw new RuntimeException("System property 'test.jdk' not set. This property is normally set by jtreg. "
+ + "When running test separately, set this property using '-Dtest.jdk=/path/to/jdk'.");
+ }
+
+ binPath += File.separatorChar + "bin" + File.separatorChar + tool;
+
+ return binPath;
+ }
+}
diff --git a/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java b/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java
new file mode 100644
index 000000000..469d0c24a
--- /dev/null
+++ b/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java
@@ -0,0 +1,191 @@
+/*
+ * 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.
+ */
+
+package com.oracle.java.testlibrary;
+
+import java.io.IOException;
+
+public final class OutputAnalyzer {
+
+ private final String stdout;
+ private final String stderr;
+ private final int exitValue;
+
+ /**
+ * Create an OutputAnalyzer, a utility class for verifying output and exit
+ * value from a Process
+ *
+ * @param process Process to analyze
+ * @throws IOException If an I/O error occurs.
+ */
+ public OutputAnalyzer(Process process) throws IOException {
+ OutputBuffer output = ProcessTools.getOutput(process);
+ exitValue = process.exitValue();
+ this.stdout = output.getStdout();
+ this.stderr = output.getStderr();
+ }
+
+ /**
+ * Create an OutputAnalyzer, a utility class for verifying output
+ *
+ * @param buf String buffer to analyze
+ */
+ public OutputAnalyzer(String buf) {
+ this(buf, buf);
+ }
+
+ /**
+ * Create an OutputAnalyzer, a utility class for verifying output
+ *
+ * @param stdout stdout buffer to analyze
+ * @param stderr stderr buffer to analyze
+ */
+ public OutputAnalyzer(String stdout, String stderr) {
+ this.stdout = stdout;
+ this.stderr = stderr;
+ exitValue = -1;
+ }
+
+ /**
+ * Verify that the stdout and stderr contents of output buffer contains the string
+ *
+ * @param expectedString String that buffer should contain
+ * @throws RuntimeException If the string was not found
+ */
+ public void shouldContain(String expectedString) {
+ if (!stdout.contains(expectedString) && !stderr.contains(expectedString)) {
+ throw new RuntimeException("'" + expectedString + "' missing from stdout/stderr: [" + stdout + stderr + "]\n");
+ }
+ }
+
+ /**
+ * Verify that the stdout contents of output buffer contains the string
+ *
+ * @param expectedString String that buffer should contain
+ * @throws RuntimeException If the string was not found
+ */
+ public void stdoutShouldContain(String expectedString) {
+ if (!stdout.contains(expectedString)) {
+ throw new RuntimeException("'" + expectedString + "' missing from stdout: [" + stdout + "]\n");
+ }
+ }
+
+ /**
+ * Verify that the stderr contents of output buffer contains the string
+ *
+ * @param expectedString String that buffer should contain
+ * @throws RuntimeException If the string was not found
+ */
+ public void stderrShouldContain(String expectedString) {
+ if (!stderr.contains(expectedString)) {
+ throw new RuntimeException("'" + expectedString + "' missing from stderr: [" + stderr + "]\n");
+ }
+ }
+
+ /**
+ * Verify that the stdout and stderr contents of output buffer does not contain the string
+ *
+ * @param expectedString String that the buffer should not contain
+ * @throws RuntimeException If the string was found
+ */
+ public void shouldNotContain(String notExpectedString) {
+ if (stdout.contains(notExpectedString)) {
+ throw new RuntimeException("'" + notExpectedString + "' found in stdout: [" + stdout + "]\n");
+ }
+ if (stderr.contains(notExpectedString)) {
+ throw new RuntimeException("'" + notExpectedString + "' found in stderr: [" + stderr + "]\n");
+ }
+ }
+
+ /**
+ * Verify that the stdout contents of output buffer does not contain the string
+ *
+ * @param expectedString String that the buffer should not contain
+ * @throws RuntimeException If the string was found
+ */
+ public void stdoutShouldNotContain(String notExpectedString) {
+ if (stdout.contains(notExpectedString)) {
+ throw new RuntimeException("'" + notExpectedString + "' found in stdout: [" + stdout + "]\n");
+ }
+ }
+
+ /**
+ * Verify that the stderr contents of output buffer does not contain the string
+ *
+ * @param expectedString String that the buffer should not contain
+ * @throws RuntimeException If the string was found
+ */
+ public void stderrShouldNotContain(String notExpectedString) {
+ if (stderr.contains(notExpectedString)) {
+ throw new RuntimeException("'" + notExpectedString + "' found in stderr: [" + stderr + "]\n");
+ }
+ }
+
+ /**
+ * Verifiy the exit value of the process
+ *
+ * @param expectedExitValue Expected exit value from process
+ * @throws RuntimeException If the exit value from the process did not match the expected value
+ */
+ public void shouldHaveExitValue(int expectedExitValue) {
+ if (getExitValue() != expectedExitValue) {
+ throw new RuntimeException("Exit value " + getExitValue() + " , expected to get " + expectedExitValue);
+ }
+ }
+
+ /**
+ * Get the contents of the output buffer (stdout and stderr)
+ *
+ * @return Content of the output buffer
+ */
+ public String getOutput() {
+ return stdout + stderr;
+ }
+
+ /**
+ * Get the contents of the stdout buffer
+ *
+ * @return Content of the stdout buffer
+ */
+ public String getStdout() {
+ return stdout;
+ }
+
+ /**
+ * Get the contents of the stderr buffer
+ *
+ * @return Content of the stderr buffer
+ */
+ public String getStderr() {
+ return stderr;
+ }
+
+ /**
+ * Get the process exit value
+ *
+ * @return Process exit value
+ */
+ public int getExitValue() {
+ return exitValue;
+ }
+}
diff --git a/test/testlibrary/com/oracle/java/testlibrary/OutputBuffer.java b/test/testlibrary/com/oracle/java/testlibrary/OutputBuffer.java
new file mode 100644
index 000000000..b98d05650
--- /dev/null
+++ b/test/testlibrary/com/oracle/java/testlibrary/OutputBuffer.java
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+package com.oracle.java.testlibrary;
+
+public class OutputBuffer {
+ private final String stdout;
+ private final String stderr;
+
+ /**
+ * Create an OutputBuffer, a class for storing and managing stdout and stderr
+ * results separately
+ *
+ * @param stdout stdout result
+ * @param stderr stderr result
+ */
+ public OutputBuffer(String stdout, String stderr) {
+ this.stdout = stdout;
+ this.stderr = stderr;
+ }
+
+ /**
+ * Returns the stdout result
+ *
+ * @return stdout result
+ */
+ public String getStdout() {
+ return stdout;
+ }
+
+ /**
+ * Returns the stderr result
+ *
+ * @return stderr result
+ */
+ public String getStderr() {
+ return stderr;
+ }
+}
diff --git a/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java b/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java
new file mode 100644
index 000000000..42203d17f
--- /dev/null
+++ b/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java
@@ -0,0 +1,141 @@
+/*
+ * 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.
+ */
+
+package com.oracle.java.testlibrary;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+
+import sun.management.VMManagement;
+
+public final class ProcessTools {
+
+ private ProcessTools() {
+ }
+
+ /**
+ * Pumps stdout and stderr from running the process into a String.
+ *
+ * @param processHandler ProcessHandler to run.
+ * @return Output from process.
+ * @throws IOException If an I/O error occurs.
+ */
+ public static OutputBuffer getOutput(ProcessBuilder processBuilder) throws IOException {
+ return getOutput(processBuilder.start());
+ }
+
+ /**
+ * Pumps stdout and stderr the running process into a String.
+ *
+ * @param process Process to pump.
+ * @return Output from process.
+ * @throws IOException If an I/O error occurs.
+ */
+ public static OutputBuffer getOutput(Process process) throws IOException {
+ ByteArrayOutputStream stderrBuffer = new ByteArrayOutputStream();
+ ByteArrayOutputStream stdoutBuffer = new ByteArrayOutputStream();
+ StreamPumper outPumper = new StreamPumper(process.getInputStream(), stdoutBuffer);
+ StreamPumper errPumper = new StreamPumper(process.getErrorStream(), stderrBuffer);
+ Thread outPumperThread = new Thread(outPumper);
+ Thread errPumperThread = new Thread(errPumper);
+
+ outPumperThread.setDaemon(true);
+ errPumperThread.setDaemon(true);
+
+ outPumperThread.start();
+ errPumperThread.start();
+
+ try {
+ process.waitFor();
+ outPumperThread.join();
+ errPumperThread.join();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ return null;
+ }
+
+ return new OutputBuffer(stdoutBuffer.toString(), stderrBuffer.toString());
+ }
+
+ /**
+ * Get the process id of the current running Java process
+ *
+ * @return Process id
+ */
+ public static int getProcessId() throws Exception {
+
+ // Get the current process id using a reflection hack
+ RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
+ Field jvm = runtime.getClass().getDeclaredField("jvm");
+
+ jvm.setAccessible(true);
+ VMManagement mgmt = (sun.management.VMManagement) jvm.get(runtime);
+
+ Method pid_method = mgmt.getClass().getDeclaredMethod("getProcessId");
+
+ pid_method.setAccessible(true);
+
+ int pid = (Integer) pid_method.invoke(mgmt);
+
+ return pid;
+ }
+
+ /**
+ * Get platform specific VM arguments (e.g. -d64 on 64bit Solaris)
+ *
+ * @return String[] with platform specific arguments, empty if there are none
+ */
+ public static String[] getPlatformSpecificVMArgs() {
+ String osName = System.getProperty("os.name");
+ String dataModel = System.getProperty("sun.arch.data.model");
+
+ if (osName.equals("SunOS") && dataModel.equals("64")) {
+ return new String[] { "-d64" };
+ }
+
+ return new String[] {};
+ }
+
+ /**
+ * Create ProcessBuilder using the java launcher from the jdk to be tested and
+ * with any platform specific arguments prepended
+ */
+ public static ProcessBuilder createJavaProcessBuilder(String... command) throws Exception {
+ String javapath = JDKToolFinder.getJDKTool("java");
+
+ ArrayList<String> args = new ArrayList<>();
+ args.add(javapath);
+ Collections.addAll(args, getPlatformSpecificVMArgs());
+ Collections.addAll(args, command);
+
+ return new ProcessBuilder(args.toArray(new String[args.size()]));
+
+ }
+
+}
diff --git a/test/testlibrary/com/oracle/java/testlibrary/StreamPumper.java b/test/testlibrary/com/oracle/java/testlibrary/StreamPumper.java
new file mode 100644
index 000000000..4631bce61
--- /dev/null
+++ b/test/testlibrary/com/oracle/java/testlibrary/StreamPumper.java
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+package com.oracle.java.testlibrary;
+
+import java.io.OutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+
+public final class StreamPumper implements Runnable {
+
+ private static final int BUF_SIZE = 256;
+
+ private final OutputStream out;
+ private final InputStream in;
+
+ /**
+ * Create a StreamPumper that reads from in and writes to out.
+ *
+ * @param in The stream to read from.
+ * @param out The stream to write to.
+ */
+ public StreamPumper(InputStream in, OutputStream out) {
+ this.in = in;
+ this.out = out;
+ }
+
+ /**
+ * Implements Thread.run(). Continuously read from <code>in</code> and write
+ * to <code>out</code> until <code>in</code> has reached end of stream. Abort
+ * on interruption. Abort on IOExceptions.
+ */
+ @Override
+ public void run() {
+ int length;
+ InputStream localIn = in;
+ OutputStream localOut = out;
+ byte[] buffer = new byte[BUF_SIZE];
+
+ try {
+ while (!Thread.interrupted() && (length = localIn.read(buffer)) > 0) {
+ localOut.write(buffer, 0, length);
+ }
+ } catch (IOException e) {
+ // Just abort if something like this happens.
+ e.printStackTrace();
+ } finally {
+ try {
+ localOut.flush();
+ in.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+}