--- a/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c Thu Feb 07 18:40:45 2013 -0800
@@ -280,7 +280,7 @@
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 @@
#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 @@
#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
--- a/hotspot/agent/src/os/linux/libproc.h Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/agent/src/os/linux/libproc.h Thu Feb 07 18:40:45 2013 -0800
@@ -79,14 +79,6 @@
*************************************************************************************/
-#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
--- a/hotspot/agent/src/os/win32/windbg/sawindbg.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/agent/src/os/win32/windbg/sawindbg.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
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;
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/amd64/WindbgAMD64Thread.java Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/amd64/WindbgAMD64Thread.java Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
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) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/x86/WindbgX86Thread.java Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/x86/WindbgX86Thread.java Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
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) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/AFLBinaryTreeDictionary.java Thu Feb 07 18:40:45 2013 -0800
@@ -0,0 +1,59 @@
+/*
+ * @(#)BinaryTreeDictionary.java
+ * 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
+ * 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 sun.jvm.hotspot.memory;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.runtime.*;
+
+public class AFLBinaryTreeDictionary extends VMObject {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) {
+ Type type = db.lookupType("AFLBinaryTreeDictionary");
+ totalSizeField = type.getCIntegerField("_total_size");
+ }
+
+ // Fields
+ private static CIntegerField totalSizeField;
+
+ // Accessors
+ public long size() {
+ return totalSizeField.getValue(addr);
+ }
+
+ // Constructor
+ public AFLBinaryTreeDictionary(Address addr) {
+ super(addr);
+ }
+}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/BinaryTreeDictionary.java Thu Feb 07 15:51:25 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * @(#)BinaryTreeDictionary.java
- * Copyright (c) 2000, 2008, 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 sun.jvm.hotspot.memory;
-
-import java.util.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.types.*;
-import sun.jvm.hotspot.runtime.*;
-
-public class BinaryTreeDictionary extends VMObject {
- static {
- VM.registerVMInitializedObserver(new Observer() {
- public void update(Observable o, Object data) {
- initialize(VM.getVM().getTypeDataBase());
- }
- });
- }
-
- private static synchronized void initialize(TypeDataBase db) {
- Type type = db.lookupType("BinaryTreeDictionary");
- totalSizeField = type.getCIntegerField("_totalSize");
- }
-
- // Fields
- private static CIntegerField totalSizeField;
-
- // Accessors
- public long size() {
- return totalSizeField.getValue(addr);
- }
-
- // Constructor
- public BinaryTreeDictionary(Address addr) {
- super(addr);
- }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
}
// 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
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/FreeList.java Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/FreeList.java Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
}
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();
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/OSThread.java Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/OSThread.java Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
// 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 @@
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 boolean interrupted() {
return ((int)interruptedField.getValue(addr)) != 0;
}
+
+ public int threadId() {
+ return (int)threadIdField.getValue(addr);
+ }
+
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_amd64/Win32AMD64JavaThreadPDAccess.java Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_amd64/Win32AMD64JavaThreadPDAccess.java Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
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 @@
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 @@
// 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);
}
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_x86/Win32X86JavaThreadPDAccess.java Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_x86/Win32X86JavaThreadPDAccess.java Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
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 @@
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 @@
// 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);
}
}
--- a/hotspot/make/Makefile Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/make/Makefile Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
# 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 @@
$(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 @@
$(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 @@
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 @@
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 @@
$(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 @@
$(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 @@
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 @@
$(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 @@
@$(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 @@
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 \
--- a/hotspot/make/bsd/makefiles/dtrace.make Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/make/bsd/makefiles/dtrace.make Thu Feb 07 18:40:45 2013 -0800
@@ -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 # 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:
--- a/hotspot/make/bsd/makefiles/mapfile-vers-debug Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/make/bsd/makefiles/mapfile-vers-debug Thu Feb 07 18:40:45 2013 -0800
@@ -188,6 +188,7 @@
JVM_IsSilentCompiler;
JVM_IsSupportedJNIVersion;
JVM_IsThreadAlive;
+ JVM_IsVMGeneratedMethodIx;
JVM_LatestUserDefinedLoader;
JVM_Listen;
JVM_LoadClass0;
--- a/hotspot/make/bsd/makefiles/mapfile-vers-product Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/make/bsd/makefiles/mapfile-vers-product Thu Feb 07 18:40:45 2013 -0800
@@ -188,6 +188,7 @@
JVM_IsSilentCompiler;
JVM_IsSupportedJNIVersion;
JVM_IsThreadAlive;
+ JVM_IsVMGeneratedMethodIx;
JVM_LatestUserDefinedLoader;
JVM_Listen;
JVM_LoadClass0;
--- a/hotspot/make/linux/makefiles/mapfile-vers-debug Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/make/linux/makefiles/mapfile-vers-debug Thu Feb 07 18:40:45 2013 -0800
@@ -184,6 +184,7 @@
JVM_IsSilentCompiler;
JVM_IsSupportedJNIVersion;
JVM_IsThreadAlive;
+ JVM_IsVMGeneratedMethodIx;
JVM_LatestUserDefinedLoader;
JVM_Listen;
JVM_LoadClass0;
--- a/hotspot/make/linux/makefiles/mapfile-vers-product Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/make/linux/makefiles/mapfile-vers-product Thu Feb 07 18:40:45 2013 -0800
@@ -184,6 +184,7 @@
JVM_IsSilentCompiler;
JVM_IsSupportedJNIVersion;
JVM_IsThreadAlive;
+ JVM_IsVMGeneratedMethodIx;
JVM_LatestUserDefinedLoader;
JVM_Listen;
JVM_LoadClass0;
--- a/hotspot/make/solaris/Makefile Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/make/solaris/Makefile Thu Feb 07 18:40:45 2013 -0800
@@ -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_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 @@
$(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 @@
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 @@
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
--- a/hotspot/make/solaris/makefiles/dtrace.make Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/make/solaris/makefiles/dtrace.make Thu Feb 07 18:40:45 2013 -0800
@@ -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 # ifdef USE_GCC
-else # KERNEL build
-
-dtraceCheck:
- $(QUIETLY) echo "**NOTICE** Dtrace support disabled for KERNEL builds"
-
-endif # ifneq ("${TYPE}", "KERNEL")
-
else # CORE build
dtraceCheck:
--- a/hotspot/make/solaris/makefiles/kernel.make Thu Feb 07 15:51:25 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -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
--- a/hotspot/make/solaris/makefiles/mapfile-vers Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/make/solaris/makefiles/mapfile-vers Thu Feb 07 18:40:45 2013 -0800
@@ -184,6 +184,7 @@
JVM_IsSilentCompiler;
JVM_IsSupportedJNIVersion;
JVM_IsThreadAlive;
+ JVM_IsVMGeneratedMethodIx;
JVM_LatestUserDefinedLoader;
JVM_Listen;
JVM_LoadClass0;
--- a/hotspot/make/windows/build.bat Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/make/windows/build.bat Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
: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.
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
--- a/hotspot/make/windows/create_obj_files.sh Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/make/windows/create_obj_files.sh Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
# 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 @@
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}" ;;
--- a/hotspot/make/windows/makefiles/defs.make Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/make/windows/makefiles/defs.make Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
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 @@
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 @@
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
--- a/hotspot/make/windows/makefiles/projectcreator.make Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/make/windows/makefiles/projectcreator.make Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
$(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) \
--- a/hotspot/make/windows/makefiles/vm.make Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/make/windows/makefiles/vm.make Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
# 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
--- a/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -42,7 +42,7 @@
#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);
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
// 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
--- a/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -44,7 +44,7 @@
#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);
--- a/hotspot/src/os/linux/vm/os_linux.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -1155,13 +1155,9 @@
// 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 @@
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;
}
}
--- a/hotspot/src/os/windows/vm/os_windows.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -349,6 +349,33 @@
#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 @@
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 @@
// 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 @@
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 @@
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 @@
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;
-
- // 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;
+ // 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());
+ }
+
+ // 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 @@
{
// 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 @@
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) {
--- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -372,7 +372,7 @@
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);
}
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -189,7 +189,7 @@
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);
}
--- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -399,7 +399,7 @@
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 @@
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);
}
--- a/hotspot/src/share/tools/whitebox/sun/hotspot/WhiteBox.java Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/tools/whitebox/sun/hotspot/WhiteBox.java Thu Feb 07 18:40:45 2013 -0800
@@ -76,4 +76,9 @@
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();
}
--- a/hotspot/src/share/vm/adlc/adlparse.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/adlc/adlparse.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -168,7 +168,7 @@
// 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 @@
} 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 @@
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 @@
} 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 @@
// 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 @@
skipws();
if ( (_curchar != '%')
|| ( next_char(), (_curchar != '{')) ) {
- parse_err(SYNERR, "expected '%{'\n");
+ parse_err(SYNERR, "expected '%%{'\n");
return;
}
next_char(); skipws();
@@ -1397,7 +1397,7 @@
skipws();
if ( (_curchar != '%')
|| ( next_char(), (_curchar != '{')) ) {
- parse_err(SYNERR, "expected '%{'\n");
+ parse_err(SYNERR, "expected '%%{'\n");
return;
}
next_char(); skipws();
@@ -1586,7 +1586,7 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
// 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 @@
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 @@
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 @@
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 @@
} 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();
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -3667,11 +3667,12 @@
}
// 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");
--- a/hotspot/src/share/vm/c1/c1_Instruction.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/c1/c1_Instruction.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -188,7 +188,7 @@
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?");
--- a/hotspot/src/share/vm/ci/ciEnv.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -1168,7 +1168,7 @@
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);
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -580,6 +580,7 @@
}
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 @@
void ciInstanceKlass::dump_replay_data(outputStream* out) {
ASSERT_IN_VM;
+ ResourceMark rm;
+
InstanceKlass* ik = get_instanceKlass();
ConstantPool* cp = ik->constants();
--- a/hotspot/src/share/vm/ci/ciMethod.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -977,7 +977,7 @@
// 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 @@
} 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 @@
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",
--- a/hotspot/src/share/vm/ci/ciMethod.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/ci/ciMethod.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -252,7 +252,7 @@
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);
--- a/hotspot/src/share/vm/ci/ciMethodData.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/ci/ciMethodData.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -374,6 +374,7 @@
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();
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -1947,6 +1947,8 @@
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,21 +2159,31 @@
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;
+ // 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",
+ method_attribute_length, CHECK_(nullHandle));
+ }
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) {
- classfile_parse_error(
- "Invalid MethodParameters method attribute length %u in class file %s",
- method_attribute_length, CHECK_(nullHandle));
+ 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())
@@ -2316,15 +2328,16 @@
// 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;
+ }
}
}
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
}
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
--- a/hotspot/src/share/vm/classfile/classLoaderData.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
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();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/classfile/metadataOnStackMark.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/classfile/metadataOnStackMark.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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
--- a/hotspot/src/share/vm/classfile/stackMapFrame.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/classfile/stackMapFrame.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -178,7 +178,7 @@
#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();
}
}
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -1199,66 +1199,6 @@
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 @@
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 @@
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 @@
//_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);
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
/* 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 @@
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 @@
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;
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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") \
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -1398,7 +1398,7 @@
method->print_short_name(tty);
tty->cr();
}
- method->set_not_compilable_quietly();
+ method->set_not_compilable(CompLevel_all, !quietly, "excluded by CompilerOracle");
}
return false;
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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
@@ -32,9 +32,9 @@
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*) \
--- a/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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
@@ -167,7 +167,9 @@
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 */);
}
--- a/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
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 @@
_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 @@
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;}
};
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -3099,9 +3099,9 @@
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);
}
--- a/hotspot/src/share/vm/interpreter/linkResolver.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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_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);
--- a/hotspot/src/share/vm/memory/allocation.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/memory/allocation.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -145,9 +145,10 @@
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
--- a/hotspot/src/share/vm/memory/filemap.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/memory/filemap.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
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);
}
--- a/hotspot/src/share/vm/memory/heapInspection.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/memory/heapInspection.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "classfile/classLoaderData.hpp"
#include "gc_interface/collectedHeap.hpp"
#include "memory/genCollectedHeap.hpp"
#include "memory/heapInspection.hpp"
@@ -41,12 +42,24 @@
} 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 +73,17 @@
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 +120,14 @@
}
}
-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 +136,10 @@
for (int index = 0; index < _size; index++) {
_buckets[index].initialize();
}
+ if (need_class_stats) {
+ AllClassesFinder finder(this);
+ ClassLoaderDataGraph::classes_do(&finder);
+ }
}
}
@@ -165,7 +195,8 @@
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 +227,205 @@
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 +463,26 @@
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 +497,14 @@
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");
}
--- a/hotspot/src/share/vm/memory/heapInspection.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/memory/heapInspection.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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,7 @@
#include "memory/allocation.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/annotations.hpp"
#if INCLUDE_SERVICES
@@ -44,16 +45,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 +191,11 @@
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 +227,132 @@
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;
};
--- a/hotspot/src/share/vm/memory/universe.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/memory/universe.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -144,6 +144,7 @@
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 +690,15 @@
// 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 +714,24 @@
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
@@ -796,7 +814,9 @@
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 +882,8 @@
// 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 +924,8 @@
// 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) {
--- a/hotspot/src/share/vm/memory/universe.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/memory/universe.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
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 @@
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().
--- a/hotspot/src/share/vm/oops/annotations.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/oops/annotations.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
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
--- a/hotspot/src/share/vm/oops/annotations.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/oops/annotations.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
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 @@
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
--- a/hotspot/src/share/vm/oops/arrayKlass.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/oops/arrayKlass.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
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; }
--- a/hotspot/src/share/vm/oops/constMethod.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/oops/constMethod.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
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
--- a/hotspot/src/share/vm/oops/constMethod.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/oops/constMethod.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 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 @@
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; }
--- a/hotspot/src/share/vm/oops/constantPool.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/oops/constantPool.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
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 @@
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 @@
} // 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 @@
(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 @@
(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 @@
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 @@
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 @@
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 @@
}
}
+#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
--- a/hotspot/src/share/vm/oops/constantPool.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/oops/constantPool.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -80,6 +80,7 @@
}
};
+class KlassSizeStats;
class ConstantPool : public Metadata {
friend class VMStructs;
friend class BytecodeInterpreter; // Directly extracts an oop in the pool for fast instanceof/checkcast
@@ -95,11 +96,16 @@
jobject _resolved_references;
Array<u2>* _reference_map;
- int _flags; // a few header bits to describe contents for GC
+ enum {
+ _has_invokedynamic = 1, // Flags
+ _has_pseudo_string = 2,
+ _has_preresolution = 4,
+ _on_stack = 8
+ };
+
+ int _flags; // old fashioned bit twiddling
int _length; // number of elements in the array
- bool _on_stack; // Redefined method still executing refers to this constant pool.
-
union {
// set for CDS to restore resolved references
int _resolved_reference_length;
@@ -115,17 +121,8 @@
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 @@
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 @@
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 @@
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 @@
}
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; }
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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"
@@ -2960,6 +2961,52 @@
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 {
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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
@@ -256,6 +256,16 @@
// 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 +291,6 @@
// ...
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 +827,9 @@
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; }
--- a/hotspot/src/share/vm/oops/klass.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/oops/klass.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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"
@@ -624,6 +625,17 @@
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
--- a/hotspot/src/share/vm/oops/klass.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/oops/klass.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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
@@ -75,11 +75,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 +91,7 @@
class ClassLoaderData;
class klassVtable;
class ParCompactionManager;
+class KlassSizeStats;
class Klass : public Metadata {
friend class VMStructs;
@@ -164,18 +165,18 @@
jint _modifier_flags; // Processed access flags, for use by Class.getModifiers.
AccessFlags _access_flags; // Access flags. The class/interface distinction is stored here.
+ // 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
- // 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;
-
TRACE_DEFINE_KLASS_TRACE_ID;
// Remembered sets support for the oops in the klasses.
@@ -477,6 +478,9 @@
// 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 '['.
--- a/hotspot/src/share/vm/oops/method.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/oops/method.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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::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 @@
}
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 @@
}
// 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 @@
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 @@
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 @@
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
--- a/hotspot/src/share/vm/oops/method.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/oops/method.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 AdapterHandlerEntry;
class MethodData;
class ConstMethod;
+class KlassSizeStats;
class Method : public Metadata {
friend class VMStructs;
@@ -127,8 +128,8 @@
InvocationCounter _backedge_counter; // Incremented before each backedge taken - used to trigger frequencey-based optimizations
#ifdef TIERED
+ float _rate; // Events (invocation and backedge counter increments) per millisecond
jlong _prev_time; // Previous time the rate was acquired
- float _rate; // Events (invocation and backedge counter increments) per millisecond
#endif
#ifndef PRODUCT
@@ -593,6 +594,9 @@
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 @@
// 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(); }
--- a/hotspot/src/share/vm/oops/methodData.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/oops/methodData.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
}
#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
--- a/hotspot/src/share/vm/oops/methodData.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/oops/methodData.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
// 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 @@
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");
}
}
--- a/hotspot/src/share/vm/oops/oop.inline.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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
@@ -227,12 +227,12 @@
// 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");
--- a/hotspot/src/share/vm/oops/symbol.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/oops/symbol.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -152,6 +152,7 @@
}
void Symbol::print_symbol_on(outputStream* st) const {
+ ResourceMark rm;
st = st ? st : tty;
st->print("%s", as_quoted_ascii());
}
--- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -420,14 +420,24 @@
}
//------------------------------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 @@
// 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 @@
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 @@
}
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 @@
}
// 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;
}
--- a/hotspot/src/share/vm/opto/callGenerator.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/opto/callGenerator.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -305,11 +305,13 @@
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;
}
--- a/hotspot/src/share/vm/opto/generateOptoStub.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/opto/generateOptoStub.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -88,12 +88,12 @@
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 @@
// 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 @@
//-----------------------------
// 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);
--- a/hotspot/src/share/vm/opto/parse.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/opto/parse.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -73,7 +73,8 @@
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;
--- a/hotspot/src/share/vm/opto/parse3.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/opto/parse3.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
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;
--- a/hotspot/src/share/vm/prims/jniCheck.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/prims/jniCheck.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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.
--- a/hotspot/src/share/vm/prims/jvm.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/prims/jvm.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -1620,7 +1620,7 @@
// 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_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 @@
// 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
--- a/hotspot/src/share/vm/prims/jvm.h Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/prims/jvm.h Thu Feb 07 18:40:45 2013 -0800
@@ -860,6 +860,13 @@
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.
*
--- a/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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;
--- a/hotspot/src/share/vm/prims/jvmtiEnv.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/prims/jvmtiEnv.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
return JVMTI_ERROR_NONE;
} /* end GetJLocationFormat */
-#ifndef JVMTI_KERNEL
-
//
// Thread functions
//
@@ -3436,5 +3434,3 @@
}
return err;
} /* end SetSystemProperty */
-
-#endif // !JVMTI_KERNEL
--- a/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
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 @@
// 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 @@
// 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 @@
return (jclass)jni_reference(k->java_mirror());
}
-#ifndef JVMTI_KERNEL
-
//
// Field Information
//
@@ -1482,5 +1474,3 @@
}
}
}
-
-#endif // !JVMTI_KERNEL
--- a/hotspot/src/share/vm/prims/jvmtiExport.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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
@@ -677,7 +677,6 @@
}
-#ifndef JVMTI_KERNEL
static inline Klass* oop_to_klass(oop obj) {
Klass* k = obj->klass();
@@ -2178,7 +2177,6 @@
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 +2257,6 @@
}
return result;
}
-#endif // SERVICES_KERNEL
////////////////////////////////////////////////////////////////////////////////////////////////
@@ -2457,4 +2454,3 @@
JvmtiExport::post_garbage_collection_finish();
}
}
-#endif // JVMTI_KERNEL
--- a/hotspot/src/share/vm/prims/jvmtiExtensions.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/prims/jvmtiExtensions.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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
//
--- a/hotspot/src/share/vm/prims/jvmtiImpl.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/prims/jvmtiImpl.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
#endif
}
-#ifndef KERNEL
-
JvmtiDeferredEvent JvmtiDeferredEvent::compiled_method_load_event(
nmethod* nm) {
JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_LOAD);
@@ -1098,5 +1096,3 @@
}
}
}
-
-#endif // ndef KERNEL
--- a/hotspot/src/share/vm/prims/jvmtiImpl.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/prims/jvmtiImpl.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
static void print();
};
-#endif // !JVMTI_KERNEL
/**
* When a thread (such as the compiler thread or VM thread) cannot post a
--- a/hotspot/src/share/vm/prims/jvmtiRawMonitor.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/prims/jvmtiRawMonitor.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
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 @@
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 @@
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 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 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 = 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 @@
(*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 @@
} // 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 @@
}
} // 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 @@
_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 @@
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 @@
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 @@
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
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
// 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 @@
// 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
--- a/hotspot/src/share/vm/prims/jvmtiTagMap.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/prims/jvmtiTagMap.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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;
--- a/hotspot/src/share/vm/prims/whitebox.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/prims/whitebox.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -43,6 +43,10 @@
#include "gc_implementation/g1/heapRegionRemSet.hpp"
#endif // !SERIALGC
+#ifdef INCLUDE_NMT
+#include "services/memTracker.hpp"
+#endif // INCLUDE_NMT
+
bool WhiteBox::_used = false;
WB_ENTRY(jlong, WB_GetObjectAddress(JNIEnv* env, jobject o, jobject obj))
@@ -110,6 +114,60 @@
WB_END
#endif // !SERIALGC
+#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,
Symbol* signature_symbol) {
@@ -177,6 +235,11 @@
{CC"g1NumFreeRegions", CC"()J", (void*)&WB_G1NumFreeRegions },
{CC"g1RegionSize", CC"()I", (void*)&WB_G1RegionSize },
#endif // !SERIALGC
+#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
--- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -827,7 +827,8 @@
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 +839,29 @@
// 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);
}
@@ -1429,13 +1446,18 @@
}
// 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
@@ -2472,10 +2494,7 @@
// -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
@@ -3463,36 +3482,6 @@
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.
--- a/hotspot/src/share/vm/runtime/arguments.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/runtime/arguments.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
// 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
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -1559,7 +1559,7 @@
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().
}
}
--- a/hotspot/src/share/vm/runtime/os.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/runtime/os.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -985,15 +985,28 @@
// 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 @@
if (old_fp - ufp > 64 * K) return true;
return false;
+#endif
}
#ifdef ASSERT
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -2816,10 +2816,6 @@
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
--- a/hotspot/src/share/vm/runtime/synchronizer.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/runtime/synchronizer.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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
--- a/hotspot/src/share/vm/runtime/thread.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/runtime/thread.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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
@@ -3746,28 +3746,6 @@
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)) {
--- a/hotspot/src/share/vm/runtime/vframeArray.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/runtime/vframeArray.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -233,8 +233,6 @@
// 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
--- a/hotspot/src/share/vm/runtime/vmStructs.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/runtime/vmStructs.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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
--- a/hotspot/src/share/vm/runtime/vm_version.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/runtime/vm_version.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
#endif
#ifndef VMTYPE
- #ifdef KERNEL
- #define VMTYPE "Kernel"
- #else // KERNEL
#ifdef TIERED
#define VMTYPE "Server"
#else // TIERED
@@ -128,7 +125,6 @@
COMPILER2_PRESENT("Server")
#endif // ZERO
#endif // TIERED
- #endif // KERNEL
#endif
#ifndef HOTSPOT_VM_DISTRO
--- a/hotspot/src/share/vm/services/attachListener.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/services/attachListener.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
return JNI_OK;
}
-#ifndef SERVICES_KERNEL // Heap dumping not supported
// Implementation of "dumpheap" command.
// See also: HeapDumpDCmd class
//
@@ -212,7 +211,6 @@
}
return JNI_OK;
}
-#endif // SERVICES_KERNEL
// Implementation of "inspectheap" command
// See also: ClassHistogramDCmd class
@@ -382,9 +380,7 @@
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 },
--- a/hotspot/src/share/vm/services/attachListener.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/services/attachListener.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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
@@ -38,8 +38,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 +46,6 @@
const char* name;
AttachOperationFunction func;
};
-#endif // SERVICES_KERNEL
class AttachListener: AllStatic {
public:
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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
@@ -43,12 +43,12 @@
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));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHistogramDCmd>(true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassStatsDCmd>(true, false));
#endif // INCLUDE_SERVICES
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHistogramDCmd>(true, false));
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 +252,7 @@
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 +292,6 @@
return 0;
}
}
-#endif // INCLUDE_SERVICES
ClassHistogramDCmd::ClassHistogramDCmd(outputStream* output, bool heap) :
DCmdWithParser(output, heap),
@@ -319,6 +318,65 @@
}
}
+#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 +464,32 @@
_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 +505,12 @@
_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 +525,6 @@
}
}
-
void JMXStartRemoteDCmd::execute(TRAPS) {
ResourceMark rm(THREAD);
HandleMark hm(THREAD);
@@ -466,7 +554,9 @@
// 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 +573,12 @@
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
--- a/hotspot/src/share/vm/services/diagnosticCommand.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/services/diagnosticCommand.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -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
@@ -178,7 +178,7 @@
};
#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 +197,27 @@
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 +257,16 @@
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);
--- a/hotspot/src/share/vm/services/memBaseline.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/services/memBaseline.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -40,6 +40,7 @@
{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
};
--- a/hotspot/src/share/vm/services/memPtr.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/services/memPtr.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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);
--- a/hotspot/src/share/vm/services/memPtr.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/services/memPtr.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -47,16 +47,16 @@
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; )
};
/*
--- a/hotspot/src/share/vm/services/memRecorder.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/services/memRecorder.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -55,7 +55,7 @@
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 @@
}
-#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();
--- a/hotspot/src/share/vm/services/memRecorder.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/services/memRecorder.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -213,7 +213,7 @@
// 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 @@
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 @@
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
--- a/hotspot/src/share/vm/services/memTrackWorker.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/services/memTrackWorker.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -91,6 +91,8 @@
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 @@
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 @@
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
--- a/hotspot/src/share/vm/services/memTrackWorker.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/services/memTrackWorker.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -107,6 +107,7 @@
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));
}
--- a/hotspot/src/share/vm/services/memTracker.cpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/services/memTracker.cpp Thu Feb 07 18:40:45 2013 -0800
@@ -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 @@
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 @@
}
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 @@
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);
--- a/hotspot/src/share/vm/services/memTracker.hpp Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/src/share/vm/services/memTracker.hpp Thu Feb 07 18:40:45 2013 -0800
@@ -91,9 +91,10 @@
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 @@
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 @@
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 @@
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 @@
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
--- a/hotspot/test/TEST.ROOT Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/test/TEST.ROOT Thu Feb 07 18:40:45 2013 -0800
@@ -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
--- a/hotspot/test/compiler/8004741/Test8004741.java Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/test/compiler/8004741/Test8004741.java Thu Feb 07 18:40:45 2013 -0800
@@ -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;
+
+ int progressState = NOT_STARTED;
- public void run() {
- System.out.println("test started");
- try {
- while(true) {
- test(2,20000);
+ 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();
+ }
+ }
+ }
+
+ /**
+ * 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);
+ }
+
+ /**
+ * 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();
+ t.start();
+ t.waitFor(RUNNING);
+ Thread.sleep(100);
+ System.out.println("stopping thread");
+ t.stop();
+ t.waitFor(STOPPING);
+ t.join();
}
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, 20);
+ 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");
}
- // First test exception catch
- Test8004741 t = new Test8004741();
+ try {
+ test(100, -1);
+ fail();
+ System.out.println("Missing NegativeArraySizeException #2");
+ fail();
+ } catch ( java.lang.NegativeArraySizeException e ) {
+ System.out.println("Saw expected NegativeArraySizeException #2");
+ }
- passed = false;
- t.start();
- Thread.sleep(1000);
- t.stop();
+ /* 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();
+ }
- Thread.sleep(5000);
- t.join();
- if (passed) {
+ 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);
+ }
};
--- a/hotspot/test/runtime/7158988/FieldMonitor.java Thu Feb 07 15:51:25 2013 +0100
+++ b/hotspot/test/runtime/7158988/FieldMonitor.java Thu Feb 07 18:40:45 2013 -0800
@@ -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;
--- a/hotspot/test/runtime/7158988/TestFieldMonitor.sh Thu Feb 07 15:51:25 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/8000968/Test8000968.sh Thu Feb 07 18:40:45 2013 -0800
@@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/8007475/StackMapFrameTest.java Thu Feb 07 18:40:45 2013 -0800
@@ -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();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/NMT/AllocTestType.java Thu Feb 07 18:40:45 2013 -0800
@@ -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=");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/NMT/BaselineWithParameter.java Thu Feb 07 18:40:45 2013 -0800
@@ -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");
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/NMT/CommandLineDetail.java Thu Feb 07 18:40:45 2013 -0800
@@ -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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/NMT/CommandLineEmptyArgument.java Thu Feb 07 18:40:45 2013 -0800
@@ -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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/NMT/CommandLineInvalidArgument.java Thu Feb 07 18:40:45 2013 -0800
@@ -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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/NMT/CommandLineSummary.java Thu Feb 07 18:40:45 2013 -0800
@@ -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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/NMT/CommandLineTurnOffNMT.java Thu Feb 07 18:40:45 2013 -0800
@@ -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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/NMT/JcmdScale.java Thu Feb 07 18:40:45 2013 -0800
@@ -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");
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/NMT/JcmdWithNMTDisabled.java Thu Feb 07 18:40:45 2013 -0800
@@ -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");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/NMT/PrintNMTStatistics.java Thu Feb 07 18:40:45 2013 -0800
@@ -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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/NMT/PrintNMTStatisticsWithNMTDisabled.java Thu Feb 07 18:40:45 2013 -0800
@@ -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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/NMT/ShutdownTwice.java Thu Feb 07 18:40:45 2013 -0800
@@ -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");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/NMT/SummaryAfterShutdown.java Thu Feb 07 18:40:45 2013 -0800
@@ -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");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/NMT/SummarySanityCheck.java Thu Feb 07 18:40:45 2013 -0800
@@ -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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/OutputAnalyzerTest.java Thu Feb 07 18:40:45 2013 -0800
@@ -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
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java Thu Feb 07 18:40:45 2013 -0800
@@ -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;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java Thu Feb 07 18:40:45 2013 -0800
@@ -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;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputBuffer.java Thu Feb 07 18:40:45 2013 -0800
@@ -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;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java Thu Feb 07 18:40:45 2013 -0800
@@ -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()]));
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/StreamPumper.java Thu Feb 07 18:40:45 2013 -0800
@@ -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();
+ }
+ }
+ }
+}