# HG changeset patch # User amurillo # Date 1360339626 28800 # Node ID 412d722168bc23f8e6d98995202728678561417f # Parent da53cb17186ad534a4453849992657b5f6dadafe# Parent 1135141fb97edf7a1cbc7596662fbdee605342ff Merge diff -r da53cb17186a -r 412d722168bc agent/src/os/linux/LinuxDebuggerLocal.c --- a/agent/src/os/linux/LinuxDebuggerLocal.c Thu Feb 07 12:32:50 2013 -0800 +++ b/agent/src/os/linux/LinuxDebuggerLocal.c Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc agent/src/os/linux/libproc.h --- a/agent/src/os/linux/libproc.h Thu Feb 07 12:32:50 2013 -0800 +++ b/agent/src/os/linux/libproc.h Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc agent/src/os/win32/windbg/sawindbg.cpp --- a/agent/src/os/win32/windbg/sawindbg.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/agent/src/os/win32/windbg/sawindbg.cpp Fri Feb 08 08:07:06 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; diff -r da53cb17186a -r 412d722168bc agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/amd64/WindbgAMD64Thread.java --- a/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/amd64/WindbgAMD64Thread.java Thu Feb 07 12:32:50 2013 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/amd64/WindbgAMD64Thread.java Fri Feb 08 08:07:06 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) { diff -r da53cb17186a -r 412d722168bc agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/x86/WindbgX86Thread.java --- a/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/x86/WindbgX86Thread.java Thu Feb 07 12:32:50 2013 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/x86/WindbgX86Thread.java Fri Feb 08 08:07:06 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) { diff -r da53cb17186a -r 412d722168bc agent/src/share/classes/sun/jvm/hotspot/memory/AFLBinaryTreeDictionary.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/agent/src/share/classes/sun/jvm/hotspot/memory/AFLBinaryTreeDictionary.java Fri Feb 08 08:07:06 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); + } +} diff -r da53cb17186a -r 412d722168bc agent/src/share/classes/sun/jvm/hotspot/memory/BinaryTreeDictionary.java --- a/agent/src/share/classes/sun/jvm/hotspot/memory/BinaryTreeDictionary.java Thu Feb 07 12:32:50 2013 -0800 +++ /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); - } -} diff -r da53cb17186a -r 412d722168bc agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java --- a/agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java Thu Feb 07 12:32:50 2013 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc agent/src/share/classes/sun/jvm/hotspot/memory/FreeList.java --- a/agent/src/share/classes/sun/jvm/hotspot/memory/FreeList.java Thu Feb 07 12:32:50 2013 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/memory/FreeList.java Fri Feb 08 08:07:06 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"); sizeField = type.getCIntegerField("_size"); countField = type.getCIntegerField("_count"); headerSize = type.getSize(); diff -r da53cb17186a -r 412d722168bc agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java --- a/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java Thu Feb 07 12:32:50 2013 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java Fri Feb 08 08:07:06 2013 -0800 @@ -467,7 +467,7 @@ liveRegions.add(tlab.start()); liveRegions.add(tlab.start()); liveRegions.add(tlab.top()); - liveRegions.add(tlab.end()); + liveRegions.add(tlab.hardEnd()); } } } diff -r da53cb17186a -r 412d722168bc agent/src/share/classes/sun/jvm/hotspot/runtime/OSThread.java --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/OSThread.java Thu Feb 07 12:32:50 2013 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/OSThread.java Fri Feb 08 08:07:06 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); + } + } diff -r da53cb17186a -r 412d722168bc agent/src/share/classes/sun/jvm/hotspot/runtime/ThreadLocalAllocBuffer.java --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/ThreadLocalAllocBuffer.java Thu Feb 07 12:32:50 2013 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/ThreadLocalAllocBuffer.java Fri Feb 08 08:07:06 2013 -0800 @@ -27,6 +27,7 @@ import java.io.*; import java.util.*; import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.oops.*; import sun.jvm.hotspot.types.*; /**

ThreadLocalAllocBuffer: a descriptor for thread-local storage @@ -62,9 +63,22 @@ super(addr); } - public Address start() { return startField.getValue(addr); } - public Address end() { return endField.getValue(addr); } - public Address top() { return topField.getValue(addr); } + public Address start() { return startField.getValue(addr); } + public Address end() { return endField.getValue(addr); } + public Address top() { return topField.getValue(addr); } + public Address hardEnd() { return end().addOffsetTo(alignmentReserve()); } + + private long alignmentReserve() { + return Oop.alignObjectSize(endReserve()); + } + + private long endReserve() { + long minFillerArraySize = Array.baseOffsetInBytes(BasicType.T_INT); + long reserveForAllocationPrefetch = VM.getVM().getReserveForAllocationPrefetch(); + long heapWordSize = VM.getVM().getHeapWordSize(); + + return Math.max(minFillerArraySize, reserveForAllocationPrefetch * heapWordSize); + } /** Support for iteration over heap -- not sure how this will interact with GC in reflective system, but necessary for the diff -r da53cb17186a -r 412d722168bc agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Thu Feb 07 12:32:50 2013 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Fri Feb 08 08:07:06 2013 -0800 @@ -114,6 +114,7 @@ private int invalidOSREntryBCI; private ReversePtrs revPtrs; private VMRegImpl vmregImpl; + private int reserveForAllocationPrefetch; // System.getProperties from debuggee VM private Properties sysProps; @@ -293,6 +294,10 @@ vmRelease = CStringUtilities.getString(releaseAddr); Address vmInternalInfoAddr = vmVersion.getAddressField("_s_internal_vm_info_string").getValue(); vmInternalInfo = CStringUtilities.getString(vmInternalInfoAddr); + + CIntegerType intType = (CIntegerType) db.lookupType("int"); + CIntegerField reserveForAllocationPrefetchField = vmVersion.getCIntegerField("_reserve_for_allocation_prefetch"); + reserveForAllocationPrefetch = (int)reserveForAllocationPrefetchField.getCInteger(intType); } catch (Exception exp) { throw new RuntimeException("can't determine target's VM version : " + exp.getMessage()); } @@ -778,6 +783,10 @@ return vmInternalInfo; } + public int getReserveForAllocationPrefetch() { + return reserveForAllocationPrefetch; + } + public boolean isSharingEnabled() { if (sharingEnabled == null) { Flag flag = getCommandLineFlag("UseSharedSpaces"); diff -r da53cb17186a -r 412d722168bc agent/src/share/classes/sun/jvm/hotspot/runtime/win32_amd64/Win32AMD64JavaThreadPDAccess.java --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_amd64/Win32AMD64JavaThreadPDAccess.java Thu Feb 07 12:32:50 2013 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_amd64/Win32AMD64JavaThreadPDAccess.java Fri Feb 08 08:07:06 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); } } diff -r da53cb17186a -r 412d722168bc agent/src/share/classes/sun/jvm/hotspot/runtime/win32_x86/Win32X86JavaThreadPDAccess.java --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_x86/Win32X86JavaThreadPDAccess.java Thu Feb 07 12:32:50 2013 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_x86/Win32X86JavaThreadPDAccess.java Fri Feb 08 08:07:06 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); } } diff -r da53cb17186a -r 412d722168bc make/Makefile --- a/make/Makefile Thu Feb 07 12:32:50 2013 -0800 +++ b/make/Makefile Fri Feb 08 08:07:06 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 \ diff -r da53cb17186a -r 412d722168bc make/bsd/makefiles/dtrace.make --- a/make/bsd/makefiles/dtrace.make Thu Feb 07 12:32:50 2013 -0800 +++ b/make/bsd/makefiles/dtrace.make Fri Feb 08 08:07:06 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: diff -r da53cb17186a -r 412d722168bc make/bsd/makefiles/mapfile-vers-debug --- a/make/bsd/makefiles/mapfile-vers-debug Thu Feb 07 12:32:50 2013 -0800 +++ b/make/bsd/makefiles/mapfile-vers-debug Fri Feb 08 08:07:06 2013 -0800 @@ -188,6 +188,7 @@ JVM_IsSilentCompiler; JVM_IsSupportedJNIVersion; JVM_IsThreadAlive; + JVM_IsVMGeneratedMethodIx; JVM_LatestUserDefinedLoader; JVM_Listen; JVM_LoadClass0; diff -r da53cb17186a -r 412d722168bc make/bsd/makefiles/mapfile-vers-product --- a/make/bsd/makefiles/mapfile-vers-product Thu Feb 07 12:32:50 2013 -0800 +++ b/make/bsd/makefiles/mapfile-vers-product Fri Feb 08 08:07:06 2013 -0800 @@ -188,6 +188,7 @@ JVM_IsSilentCompiler; JVM_IsSupportedJNIVersion; JVM_IsThreadAlive; + JVM_IsVMGeneratedMethodIx; JVM_LatestUserDefinedLoader; JVM_Listen; JVM_LoadClass0; diff -r da53cb17186a -r 412d722168bc make/bsd/makefiles/minimal1.make --- a/make/bsd/makefiles/minimal1.make Thu Feb 07 12:32:50 2013 -0800 +++ b/make/bsd/makefiles/minimal1.make Fri Feb 08 08:07:06 2013 -0800 @@ -30,7 +30,7 @@ INCLUDE_JNI_CHECK ?= false INCLUDE_SERVICES ?= false INCLUDE_MANAGEMENT ?= false -INCLUDE_ALTERNATE_GCS ?= false +INCLUDE_ALL_GCS ?= false INCLUDE_NMT ?= false INCLUDE_CDS ?= false diff -r da53cb17186a -r 412d722168bc make/excludeSrc.make --- a/make/excludeSrc.make Thu Feb 07 12:32:50 2013 -0800 +++ b/make/excludeSrc.make Fri Feb 08 08:07:06 2013 -0800 @@ -72,12 +72,10 @@ Src_Files_EXCLUDE += metaspaceShared.cpp endif -ifeq ($(INCLUDE_ALTERNATE_GCS), false) - CXXFLAGS += -DINCLUDE_ALTERNATE_GCS=0 - CFLAGS += -DINCLUDE_ALTERNATE_GCS=0 +ifeq ($(INCLUDE_ALL_GCS), false) + CXXFLAGS += -DINCLUDE_ALL_GCS=0 + CFLAGS += -DINCLUDE_ALL_GCS=0 - CXXFLAGS += -DSERIALGC - CFLAGS += -DSERIALGC Src_Files_EXCLUDE += \ cmsAdaptiveSizePolicy.cpp cmsCollectorPolicy.cpp \ cmsGCAdaptivePolicyCounters.cpp cmsLockVerifier.cpp cmsPermGen.cpp compactibleFreeListSpace.cpp \ diff -r da53cb17186a -r 412d722168bc make/hotspot_version --- a/make/hotspot_version Thu Feb 07 12:32:50 2013 -0800 +++ b/make/hotspot_version Fri Feb 08 08:07:06 2013 -0800 @@ -35,7 +35,7 @@ HS_MAJOR_VER=25 HS_MINOR_VER=0 -HS_BUILD_NUMBER=17 +HS_BUILD_NUMBER=18 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 diff -r da53cb17186a -r 412d722168bc make/linux/makefiles/mapfile-vers-debug --- a/make/linux/makefiles/mapfile-vers-debug Thu Feb 07 12:32:50 2013 -0800 +++ b/make/linux/makefiles/mapfile-vers-debug Fri Feb 08 08:07:06 2013 -0800 @@ -184,6 +184,7 @@ JVM_IsSilentCompiler; JVM_IsSupportedJNIVersion; JVM_IsThreadAlive; + JVM_IsVMGeneratedMethodIx; JVM_LatestUserDefinedLoader; JVM_Listen; JVM_LoadClass0; diff -r da53cb17186a -r 412d722168bc make/linux/makefiles/mapfile-vers-product --- a/make/linux/makefiles/mapfile-vers-product Thu Feb 07 12:32:50 2013 -0800 +++ b/make/linux/makefiles/mapfile-vers-product Fri Feb 08 08:07:06 2013 -0800 @@ -184,6 +184,7 @@ JVM_IsSilentCompiler; JVM_IsSupportedJNIVersion; JVM_IsThreadAlive; + JVM_IsVMGeneratedMethodIx; JVM_LatestUserDefinedLoader; JVM_Listen; JVM_LoadClass0; diff -r da53cb17186a -r 412d722168bc make/linux/makefiles/minimal1.make --- a/make/linux/makefiles/minimal1.make Thu Feb 07 12:32:50 2013 -0800 +++ b/make/linux/makefiles/minimal1.make Fri Feb 08 08:07:06 2013 -0800 @@ -30,7 +30,7 @@ INCLUDE_JNI_CHECK ?= false INCLUDE_SERVICES ?= false INCLUDE_MANAGEMENT ?= false -INCLUDE_ALTERNATE_GCS ?= false +INCLUDE_ALL_GCS ?= false INCLUDE_NMT ?= false INCLUDE_CDS ?= false diff -r da53cb17186a -r 412d722168bc make/solaris/Makefile --- a/make/solaris/Makefile Thu Feb 07 12:32:50 2013 -0800 +++ b/make/solaris/Makefile Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc make/solaris/makefiles/dtrace.make --- a/make/solaris/makefiles/dtrace.make Thu Feb 07 12:32:50 2013 -0800 +++ b/make/solaris/makefiles/dtrace.make Fri Feb 08 08:07:06 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: diff -r da53cb17186a -r 412d722168bc make/solaris/makefiles/kernel.make --- a/make/solaris/makefiles/kernel.make Thu Feb 07 12:32:50 2013 -0800 +++ /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 diff -r da53cb17186a -r 412d722168bc make/solaris/makefiles/mapfile-vers --- a/make/solaris/makefiles/mapfile-vers Thu Feb 07 12:32:50 2013 -0800 +++ b/make/solaris/makefiles/mapfile-vers Fri Feb 08 08:07:06 2013 -0800 @@ -184,6 +184,7 @@ JVM_IsSilentCompiler; JVM_IsSupportedJNIVersion; JVM_IsThreadAlive; + JVM_IsVMGeneratedMethodIx; JVM_LatestUserDefinedLoader; JVM_Listen; JVM_LoadClass0; diff -r da53cb17186a -r 412d722168bc make/windows/build.bat --- a/make/windows/build.bat Thu Feb 07 12:32:50 2013 -0800 +++ b/make/windows/build.bat Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc make/windows/create_obj_files.sh --- a/make/windows/create_obj_files.sh Thu Feb 07 12:32:50 2013 -0800 +++ b/make/windows/create_obj_files.sh Fri Feb 08 08:07:06 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}" ;; diff -r da53cb17186a -r 412d722168bc make/windows/makefiles/defs.make --- a/make/windows/makefiles/defs.make Thu Feb 07 12:32:50 2013 -0800 +++ b/make/windows/makefiles/defs.make Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc make/windows/makefiles/projectcreator.make --- a/make/windows/makefiles/projectcreator.make Thu Feb 07 12:32:50 2013 -0800 +++ b/make/windows/makefiles/projectcreator.make Fri Feb 08 08:07:06 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) \ diff -r da53cb17186a -r 412d722168bc make/windows/makefiles/vm.make --- a/make/windows/makefiles/vm.make Thu Feb 07 12:32:50 2013 -0800 +++ b/make/windows/makefiles/vm.make Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp --- a/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -30,10 +30,11 @@ #include "c1/c1_Runtime1.hpp" #include "nativeInst_sparc.hpp" #include "runtime/sharedRuntime.hpp" +#include "utilities/macros.hpp" #include "vmreg_sparc.inline.hpp" -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" -#endif +#endif // INCLUDE_ALL_GCS #define __ ce->masm()-> @@ -420,7 +421,7 @@ /////////////////////////////////////////////////////////////////////////////////// -#ifndef SERIALGC +#if INCLUDE_ALL_GCS void G1PreBarrierStub::emit_code(LIR_Assembler* ce) { // At this point we know that marking is in progress. @@ -483,7 +484,7 @@ __ delayed()->nop(); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS /////////////////////////////////////////////////////////////////////////////////// #undef __ diff -r da53cb17186a -r 412d722168bc src/cpu/sparc/vm/c1_Runtime1_sparc.cpp --- a/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -35,6 +35,7 @@ #include "runtime/sharedRuntime.hpp" #include "runtime/signature.hpp" #include "runtime/vframeArray.hpp" +#include "utilities/macros.hpp" #include "vmreg_sparc.inline.hpp" // Implementation of StubAssembler @@ -822,7 +823,7 @@ } break; -#ifndef SERIALGC +#if INCLUDE_ALL_GCS case g1_pre_barrier_slow_id: { // G4: previous value of memory BarrierSet* bs = Universe::heap()->barrier_set(); @@ -984,7 +985,7 @@ __ delayed()->restore(); } break; -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS default: { __ set_info("unimplemented entry", dont_gc_arguments); diff -r da53cb17186a -r 412d722168bc src/cpu/sparc/vm/c2_globals_sparc.hpp --- a/src/cpu/sparc/vm/c2_globals_sparc.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/cpu/sparc/vm/c2_globals_sparc.hpp Fri Feb 08 08:07:06 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); diff -r da53cb17186a -r 412d722168bc src/cpu/sparc/vm/cppInterpreter_sparc.cpp --- a/src/cpu/sparc/vm/cppInterpreter_sparc.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/cpu/sparc/vm/cppInterpreter_sparc.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -45,6 +45,7 @@ #include "runtime/timer.hpp" #include "runtime/vframeArray.hpp" #include "utilities/debug.hpp" +#include "utilities/macros.hpp" #ifdef SHARK #include "shark/shark_globals.hpp" #endif @@ -551,7 +552,7 @@ } address InterpreterGenerator::generate_Reference_get_entry(void) { -#ifndef SERIALGC +#if INCLUDE_ALL_GCS if (UseG1GC) { // We need to generate have a routine that generates code to: // * load the value in the referent field @@ -563,7 +564,7 @@ // field as live. Unimplemented(); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS // If G1 is not enabled then attempt to go through the accessor entry point // Reference.get is an accessor diff -r da53cb17186a -r 412d722168bc src/cpu/sparc/vm/macroAssembler_sparc.cpp --- a/src/cpu/sparc/vm/macroAssembler_sparc.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/cpu/sparc/vm/macroAssembler_sparc.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -36,11 +36,12 @@ #include "runtime/os.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/stubRoutines.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" #include "gc_implementation/g1/heapRegion.hpp" -#endif +#endif // INCLUDE_ALL_GCS #ifdef PRODUCT #define BLOCK_COMMENT(str) /* nothing */ @@ -3867,7 +3868,7 @@ } /////////////////////////////////////////////////////////////////////////////////// -#ifndef SERIALGC +#if INCLUDE_ALL_GCS static address satb_log_enqueue_with_frame = NULL; static u_char* satb_log_enqueue_with_frame_end = NULL; @@ -4231,7 +4232,7 @@ bind(filtered); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS /////////////////////////////////////////////////////////////////////////////////// void MacroAssembler::card_write_barrier_post(Register store_addr, Register new_val, Register tmp) { diff -r da53cb17186a -r 412d722168bc src/cpu/sparc/vm/macroAssembler_sparc.hpp --- a/src/cpu/sparc/vm/macroAssembler_sparc.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/cpu/sparc/vm/macroAssembler_sparc.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -26,6 +26,7 @@ #define CPU_SPARC_VM_MACROASSEMBLER_SPARC_HPP #include "asm/assembler.hpp" +#include "utilities/macros.hpp" // promises that the system will not use traps 16-31 #define ST_RESERVED_FOR_USER_0 0x10 @@ -1181,13 +1182,13 @@ void card_write_barrier_post(Register store_addr, Register new_val, Register tmp); -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // General G1 pre-barrier generator. void g1_write_barrier_pre(Register obj, Register index, int offset, Register pre_val, Register tmp, bool preserve_o_regs); // General G1 post-barrier generator void g1_write_barrier_post(Register store_addr, Register new_val, Register tmp); -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS // pushes double TOS element of FPU stack on CPU stack; pops from FPU stack void push_fTOS(); diff -r da53cb17186a -r 412d722168bc src/cpu/sparc/vm/templateInterpreter_sparc.cpp --- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -44,6 +44,7 @@ #include "runtime/timer.hpp" #include "runtime/vframeArray.hpp" #include "utilities/debug.hpp" +#include "utilities/macros.hpp" #ifndef CC_INTERP #ifndef FAST_DISPATCH @@ -734,7 +735,7 @@ // Method entry for java.lang.ref.Reference.get. address InterpreterGenerator::generate_Reference_get_entry(void) { -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // Code: _aload_0, _getfield, _areturn // parameter size = 1 // @@ -805,7 +806,7 @@ (void) generate_normal_entry(false); return entry; } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS // If G1 is not enabled then attempt to go through the accessor entry point // Reference.get is an accessor diff -r da53cb17186a -r 412d722168bc src/cpu/sparc/vm/templateTable_sparc.cpp --- a/src/cpu/sparc/vm/templateTable_sparc.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/cpu/sparc/vm/templateTable_sparc.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -34,6 +34,7 @@ #include "runtime/sharedRuntime.hpp" #include "runtime/stubRoutines.hpp" #include "runtime/synchronizer.hpp" +#include "utilities/macros.hpp" #ifndef CC_INTERP #define __ _masm-> @@ -53,7 +54,7 @@ assert(tmp != val && tmp != base && tmp != index, "register collision"); assert(index == noreg || offset == 0, "only one offset"); switch (barrier) { -#ifndef SERIALGC +#if INCLUDE_ALL_GCS case BarrierSet::G1SATBCT: case BarrierSet::G1SATBCTLogging: { @@ -82,7 +83,7 @@ } } break; -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS case BarrierSet::CardTableModRef: case BarrierSet::CardTableExtension: { diff -r da53cb17186a -r 412d722168bc src/cpu/x86/vm/assembler_x86.cpp --- a/src/cpu/x86/vm/assembler_x86.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/cpu/x86/vm/assembler_x86.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -36,11 +36,12 @@ #include "runtime/os.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/stubRoutines.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" #include "gc_implementation/g1/heapRegion.hpp" -#endif +#endif // INCLUDE_ALL_GCS #ifdef PRODUCT #define BLOCK_COMMENT(str) /* nothing */ diff -r da53cb17186a -r 412d722168bc src/cpu/x86/vm/assembler_x86.hpp --- a/src/cpu/x86/vm/assembler_x86.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/cpu/x86/vm/assembler_x86.hpp Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc src/cpu/x86/vm/c1_CodeStubs_x86.cpp --- a/src/cpu/x86/vm/c1_CodeStubs_x86.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/cpu/x86/vm/c1_CodeStubs_x86.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -30,10 +30,11 @@ #include "c1/c1_Runtime1.hpp" #include "nativeInst_x86.hpp" #include "runtime/sharedRuntime.hpp" +#include "utilities/macros.hpp" #include "vmreg_x86.inline.hpp" -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" -#endif +#endif // INCLUDE_ALL_GCS #define __ ce->masm()-> @@ -482,7 +483,7 @@ } ///////////////////////////////////////////////////////////////////////////// -#ifndef SERIALGC +#if INCLUDE_ALL_GCS void G1PreBarrierStub::emit_code(LIR_Assembler* ce) { // At this point we know that marking is in progress. @@ -528,7 +529,7 @@ __ jmp(_continuation); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS ///////////////////////////////////////////////////////////////////////////// #undef __ diff -r da53cb17186a -r 412d722168bc src/cpu/x86/vm/c1_Runtime1_x86.cpp --- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -36,6 +36,7 @@ #include "runtime/sharedRuntime.hpp" #include "runtime/signature.hpp" #include "runtime/vframeArray.hpp" +#include "utilities/macros.hpp" #include "vmreg_x86.inline.hpp" @@ -1607,7 +1608,7 @@ } break; -#ifndef SERIALGC +#if INCLUDE_ALL_GCS case g1_pre_barrier_slow_id: { StubFrame f(sasm, "g1_pre_barrier", dont_gc_arguments); @@ -1804,7 +1805,7 @@ } break; -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS default: { StubFrame f(sasm, "unimplemented entry", dont_gc_arguments); diff -r da53cb17186a -r 412d722168bc src/cpu/x86/vm/c2_globals_x86.hpp --- a/src/cpu/x86/vm/c2_globals_x86.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/cpu/x86/vm/c2_globals_x86.hpp Fri Feb 08 08:07:06 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); diff -r da53cb17186a -r 412d722168bc src/cpu/x86/vm/cppInterpreter_x86.cpp --- a/src/cpu/x86/vm/cppInterpreter_x86.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/cpu/x86/vm/cppInterpreter_x86.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -45,6 +45,7 @@ #include "runtime/timer.hpp" #include "runtime/vframeArray.hpp" #include "utilities/debug.hpp" +#include "utilities/macros.hpp" #ifdef SHARK #include "shark/shark_globals.hpp" #endif @@ -938,7 +939,7 @@ } address InterpreterGenerator::generate_Reference_get_entry(void) { -#ifndef SERIALGC +#if INCLUDE_ALL_GCS if (UseG1GC) { // We need to generate have a routine that generates code to: // * load the value in the referent field @@ -950,7 +951,7 @@ // field as live. Unimplemented(); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS // If G1 is not enabled then attempt to go through the accessor entry point // Reference.get is an accessor diff -r da53cb17186a -r 412d722168bc src/cpu/x86/vm/macroAssembler_x86.cpp --- a/src/cpu/x86/vm/macroAssembler_x86.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/cpu/x86/vm/macroAssembler_x86.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -37,11 +37,12 @@ #include "runtime/os.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/stubRoutines.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" #include "gc_implementation/g1/heapRegion.hpp" -#endif +#endif // INCLUDE_ALL_GCS #ifdef PRODUCT #define BLOCK_COMMENT(str) /* nothing */ @@ -3207,7 +3208,7 @@ ////////////////////////////////////////////////////////////////////////////////// -#ifndef SERIALGC +#if INCLUDE_ALL_GCS void MacroAssembler::g1_write_barrier_pre(Register obj, Register pre_val, @@ -3417,7 +3418,7 @@ bind(done); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS ////////////////////////////////////////////////////////////////////////////////// diff -r da53cb17186a -r 412d722168bc src/cpu/x86/vm/macroAssembler_x86.hpp --- a/src/cpu/x86/vm/macroAssembler_x86.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/cpu/x86/vm/macroAssembler_x86.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -26,6 +26,7 @@ #define CPU_X86_VM_MACROASSEMBLER_X86_HPP #include "asm/assembler.hpp" +#include "utilities/macros.hpp" // MacroAssembler extends Assembler by frequently used macros. @@ -294,7 +295,7 @@ void store_check(Register obj); // store check for obj - register is destroyed afterwards void store_check(Register obj, Address dst); // same as above, dst is exact store location (reg. is destroyed) -#ifndef SERIALGC +#if INCLUDE_ALL_GCS void g1_write_barrier_pre(Register obj, Register pre_val, @@ -309,7 +310,7 @@ Register tmp, Register tmp2); -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS // split store_check(Register obj) to enhance instruction interleaving void store_check_part_1(Register obj); diff -r da53cb17186a -r 412d722168bc src/cpu/x86/vm/templateInterpreter_x86_32.cpp --- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -44,6 +44,7 @@ #include "runtime/timer.hpp" #include "runtime/vframeArray.hpp" #include "utilities/debug.hpp" +#include "utilities/macros.hpp" #define __ _masm-> @@ -761,7 +762,7 @@ // Method entry for java.lang.ref.Reference.get. address InterpreterGenerator::generate_Reference_get_entry(void) { -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // Code: _aload_0, _getfield, _areturn // parameter size = 1 // @@ -844,7 +845,7 @@ return entry; } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS // If G1 is not enabled then attempt to go through the accessor entry point // Reference.get is an accessor diff -r da53cb17186a -r 412d722168bc src/cpu/x86/vm/templateInterpreter_x86_64.cpp --- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -44,6 +44,7 @@ #include "runtime/timer.hpp" #include "runtime/vframeArray.hpp" #include "utilities/debug.hpp" +#include "utilities/macros.hpp" #define __ _masm-> @@ -742,7 +743,7 @@ // Method entry for java.lang.ref.Reference.get. address InterpreterGenerator::generate_Reference_get_entry(void) { -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // Code: _aload_0, _getfield, _areturn // parameter size = 1 // @@ -821,7 +822,7 @@ return entry; } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS // If G1 is not enabled then attempt to go through the accessor entry point // Reference.get is an accessor diff -r da53cb17186a -r 412d722168bc src/cpu/x86/vm/templateTable_x86_32.cpp --- a/src/cpu/x86/vm/templateTable_x86_32.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -35,6 +35,7 @@ #include "runtime/sharedRuntime.hpp" #include "runtime/stubRoutines.hpp" #include "runtime/synchronizer.hpp" +#include "utilities/macros.hpp" #ifndef CC_INTERP #define __ _masm-> @@ -125,7 +126,7 @@ bool precise) { assert(val == noreg || val == rax, "parameter is just for looks"); switch (barrier) { -#ifndef SERIALGC +#if INCLUDE_ALL_GCS case BarrierSet::G1SATBCT: case BarrierSet::G1SATBCTLogging: { @@ -164,7 +165,7 @@ } break; -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS case BarrierSet::CardTableModRef: case BarrierSet::CardTableExtension: { diff -r da53cb17186a -r 412d722168bc src/cpu/x86/vm/templateTable_x86_64.cpp --- a/src/cpu/x86/vm/templateTable_x86_64.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -35,6 +35,7 @@ #include "runtime/sharedRuntime.hpp" #include "runtime/stubRoutines.hpp" #include "runtime/synchronizer.hpp" +#include "utilities/macros.hpp" #ifndef CC_INTERP @@ -136,7 +137,7 @@ bool precise) { assert(val == noreg || val == rax, "parameter is just for looks"); switch (barrier) { -#ifndef SERIALGC +#if INCLUDE_ALL_GCS case BarrierSet::G1SATBCT: case BarrierSet::G1SATBCTLogging: { @@ -167,7 +168,7 @@ } break; -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS case BarrierSet::CardTableModRef: case BarrierSet::CardTableExtension: { diff -r da53cb17186a -r 412d722168bc src/cpu/zero/vm/assembler_zero.cpp --- a/src/cpu/zero/vm/assembler_zero.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/cpu/zero/vm/assembler_zero.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -36,11 +36,12 @@ #include "runtime/os.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/stubRoutines.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" #include "gc_implementation/g1/heapRegion.hpp" -#endif +#endif // INCLUDE_ALL_GCS int AbstractAssembler::code_fill_byte() { return 0; diff -r da53cb17186a -r 412d722168bc src/cpu/zero/vm/cppInterpreter_zero.cpp --- a/src/cpu/zero/vm/cppInterpreter_zero.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/cpu/zero/vm/cppInterpreter_zero.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -47,6 +47,7 @@ #include "runtime/vframeArray.hpp" #include "stack_zero.inline.hpp" #include "utilities/debug.hpp" +#include "utilities/macros.hpp" #ifdef SHARK #include "shark/shark_globals.hpp" #endif @@ -791,7 +792,7 @@ } address InterpreterGenerator::generate_Reference_get_entry(void) { -#ifndef SERIALGC +#if INCLUDE_ALL_GCS if (UseG1GC) { // We need to generate have a routine that generates code to: // * load the value in the referent field @@ -803,7 +804,7 @@ // field as live. Unimplemented(); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS // If G1 is not enabled then attempt to go through the accessor entry point // Reference.get is an accessor diff -r da53cb17186a -r 412d722168bc src/os/linux/vm/os_linux.cpp --- a/src/os/linux/vm/os_linux.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/os/linux/vm/os_linux.cpp Fri Feb 08 08:07:06 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; } } diff -r da53cb17186a -r 412d722168bc src/os/windows/vm/os_windows.cpp --- a/src/os/windows/vm/os_windows.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/os/windows/vm/os_windows.cpp Fri Feb 08 08:07:06 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) { diff -r da53cb17186a -r 412d722168bc src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp --- a/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Fri Feb 08 08:07:06 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); } diff -r da53cb17186a -r 412d722168bc src/os_cpu/linux_x86/vm/os_linux_x86.cpp --- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Fri Feb 08 08:07:06 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); } diff -r da53cb17186a -r 412d722168bc src/os_cpu/windows_x86/vm/os_windows_x86.cpp --- a/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Fri Feb 08 08:07:06 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); } diff -r da53cb17186a -r 412d722168bc src/share/tools/whitebox/sun/hotspot/WhiteBox.java --- a/src/share/tools/whitebox/sun/hotspot/WhiteBox.java Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/tools/whitebox/sun/hotspot/WhiteBox.java Fri Feb 08 08:07:06 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(); } diff -r da53cb17186a -r 412d722168bc src/share/vm/adlc/adlparse.cpp --- a/src/share/vm/adlc/adlparse.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/adlc/adlparse.cpp Fri Feb 08 08:07:06 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(); diff -r da53cb17186a -r 412d722168bc src/share/vm/c1/c1_CodeStubs.hpp --- a/src/share/vm/c1/c1_CodeStubs.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/c1/c1_CodeStubs.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -31,6 +31,7 @@ #include "c1/c1_LIR.hpp" #include "c1/c1_Runtime1.hpp" #include "utilities/array.hpp" +#include "utilities/macros.hpp" class CodeEmitInfo; class LIR_Assembler; @@ -515,7 +516,7 @@ }; ////////////////////////////////////////////////////////////////////////////////////////// -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // Code stubs for Garbage-First barriers. class G1PreBarrierStub: public CodeStub { @@ -608,7 +609,7 @@ #endif // PRODUCT }; -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS ////////////////////////////////////////////////////////////////////////////////////////// #endif // SHARE_VM_C1_C1_CODESTUBS_HPP diff -r da53cb17186a -r 412d722168bc src/share/vm/c1/c1_GraphBuilder.cpp --- a/src/share/vm/c1/c1_GraphBuilder.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Fri Feb 08 08:07:06 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"); diff -r da53cb17186a -r 412d722168bc src/share/vm/c1/c1_Instruction.cpp --- a/src/share/vm/c1/c1_Instruction.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/c1/c1_Instruction.cpp Fri Feb 08 08:07:06 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?"); diff -r da53cb17186a -r 412d722168bc src/share/vm/c1/c1_LIRGenerator.cpp --- a/src/share/vm/c1/c1_LIRGenerator.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/c1/c1_LIRGenerator.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -35,9 +35,10 @@ #include "runtime/sharedRuntime.hpp" #include "runtime/stubRoutines.hpp" #include "utilities/bitMap.inline.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/g1/heapRegion.hpp" -#endif +#endif // INCLUDE_ALL_GCS #ifdef ASSERT #define __ gen()->lir(__FILE__, __LINE__)-> @@ -1417,12 +1418,12 @@ bool do_load, bool patch, CodeEmitInfo* info) { // Do the pre-write barrier, if any. switch (_bs->kind()) { -#ifndef SERIALGC +#if INCLUDE_ALL_GCS case BarrierSet::G1SATBCT: case BarrierSet::G1SATBCTLogging: G1SATBCardTableModRef_pre_barrier(addr_opr, pre_val, do_load, patch, info); break; -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS case BarrierSet::CardTableModRef: case BarrierSet::CardTableExtension: // No pre barriers @@ -1439,12 +1440,12 @@ void LIRGenerator::post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) { switch (_bs->kind()) { -#ifndef SERIALGC +#if INCLUDE_ALL_GCS case BarrierSet::G1SATBCT: case BarrierSet::G1SATBCTLogging: G1SATBCardTableModRef_post_barrier(addr, new_val); break; -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS case BarrierSet::CardTableModRef: case BarrierSet::CardTableExtension: CardTableModRef_post_barrier(addr, new_val); @@ -1459,7 +1460,7 @@ } //////////////////////////////////////////////////////////////////////// -#ifndef SERIALGC +#if INCLUDE_ALL_GCS void LIRGenerator::G1SATBCardTableModRef_pre_barrier(LIR_Opr addr_opr, LIR_Opr pre_val, bool do_load, bool patch, CodeEmitInfo* info) { @@ -1575,7 +1576,7 @@ __ branch_destination(slow->continuation()); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS //////////////////////////////////////////////////////////////////////// void LIRGenerator::CardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) { @@ -2181,7 +2182,7 @@ get_Object_unsafe(value, src.result(), off.result(), type, x->is_volatile()); -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // We might be reading the value of the referent field of a // Reference object in order to attach it back to the live // object graph. If G1 is enabled then we need to record @@ -2311,7 +2312,7 @@ __ branch_destination(Lcont->label()); } } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS if (x->is_volatile() && os::is_MP()) __ membar_acquire(); } diff -r da53cb17186a -r 412d722168bc src/share/vm/ci/ciEnv.cpp --- a/src/share/vm/ci/ciEnv.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/ci/ciEnv.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -52,6 +52,7 @@ #include "runtime/reflection.hpp" #include "runtime/sharedRuntime.hpp" #include "utilities/dtrace.hpp" +#include "utilities/macros.hpp" #ifdef COMPILER1 #include "c1/c1_Runtime1.hpp" #endif @@ -1168,7 +1169,7 @@ void ciEnv::dump_replay_data(outputStream* out) { ASSERT_IN_VM; - + ResourceMark rm; #if INCLUDE_JVMTI out->print_cr("JvmtiExport can_access_local_variables %d", _jvmti_can_access_local_variables); out->print_cr("JvmtiExport can_hotswap_or_post_breakpoint %d", _jvmti_can_hotswap_or_post_breakpoint); diff -r da53cb17186a -r 412d722168bc src/share/vm/ci/ciInstanceKlass.cpp --- a/src/share/vm/ci/ciInstanceKlass.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/ci/ciInstanceKlass.cpp Fri Feb 08 08:07:06 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(); diff -r da53cb17186a -r 412d722168bc src/share/vm/ci/ciMethod.cpp --- a/src/share/vm/ci/ciMethod.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/ci/ciMethod.cpp Fri Feb 08 08:07:06 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", diff -r da53cb17186a -r 412d722168bc src/share/vm/ci/ciMethod.hpp --- a/src/share/vm/ci/ciMethod.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/ci/ciMethod.hpp Fri Feb 08 08:07:06 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); diff -r da53cb17186a -r 412d722168bc src/share/vm/ci/ciMethodData.cpp --- a/src/share/vm/ci/ciMethodData.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/ci/ciMethodData.cpp Fri Feb 08 08:07:06 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(); diff -r da53cb17186a -r 412d722168bc src/share/vm/ci/ciReplay.cpp --- a/src/share/vm/ci/ciReplay.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/ci/ciReplay.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -30,6 +30,7 @@ #include "memory/oopFactory.hpp" #include "memory/resourceArea.hpp" #include "utilities/copy.hpp" +#include "utilities/macros.hpp" #ifndef PRODUCT diff -r da53cb17186a -r 412d722168bc src/share/vm/classfile/classFileParser.cpp --- a/src/share/vm/classfile/classFileParser.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/classfile/classFileParser.cpp Fri Feb 08 08:07:06 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; + } } } diff -r da53cb17186a -r 412d722168bc src/share/vm/classfile/classLoaderData.cpp --- a/src/share/vm/classfile/classLoaderData.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/classfile/classLoaderData.cpp Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc src/share/vm/classfile/classLoaderData.hpp --- a/src/share/vm/classfile/classLoaderData.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/classfile/classLoaderData.hpp Fri Feb 08 08:07:06 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(); diff -r da53cb17186a -r 412d722168bc src/share/vm/classfile/metadataOnStackMark.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/classfile/metadataOnStackMark.cpp Fri Feb 08 08:07:06 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* _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(1000, true); + } + Threads::metadata_do(Metadata::mark_on_stack); + CodeCache::alive_nmethods_do(nmethod::mark_on_stack); + CompileBroker::mark_on_stack(); +} + +MetadataOnStackMark::~MetadataOnStackMark() { + assert(SafepointSynchronize::is_at_safepoint(), "sanity check"); + // Unmark everything that was marked. Can't do the same walk because + // redefine classes messes up the code cache so the set of methods + // might not be the same. + for (int i = 0; i< _marked_objects->length(); i++) { + _marked_objects->at(i)->set_on_stack(false); + } + _marked_objects->clear(); // reuse growable array for next time. + NOT_PRODUCT(_is_active = false;) +} + +// Record which objects are marked so we can unmark the same objects. +void MetadataOnStackMark::record(Metadata* m) { + assert(_is_active, "metadata on stack marking is active"); + _marked_objects->push(m); +} diff -r da53cb17186a -r 412d722168bc src/share/vm/classfile/metadataOnStackMark.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/classfile/metadataOnStackMark.hpp Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc src/share/vm/classfile/stackMapFrame.hpp --- a/src/share/vm/classfile/stackMapFrame.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/classfile/stackMapFrame.hpp Fri Feb 08 08:07:06 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(); } } diff -r da53cb17186a -r 412d722168bc src/share/vm/classfile/systemDictionary.cpp --- a/src/share/vm/classfile/systemDictionary.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/classfile/systemDictionary.cpp Fri Feb 08 08:07:06 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); diff -r da53cb17186a -r 412d722168bc src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/classfile/systemDictionary.hpp Fri Feb 08 08:07:06 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<print_short_name(tty); tty->cr(); } - method->set_not_compilable_quietly(); + method->set_not_compilable(CompLevel_all, !quietly, "excluded by CompilerOracle"); } return false; diff -r da53cb17186a -r 412d722168bc src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -102,7 +102,7 @@ // temporarily disabled). switch (dictionaryChoice) { case FreeBlockDictionary::dictionaryBinaryTree: - _dictionary = new BinaryTreeDictionary(mr); + _dictionary = new AFLBinaryTreeDictionary(mr); break; case FreeBlockDictionary::dictionarySplayTree: case FreeBlockDictionary::dictionarySkipList: @@ -122,7 +122,8 @@ // moved to its new location before the klass is moved. // Set the _refillSize for the linear allocation blocks if (!use_adaptive_freelists) { - FreeChunk* fc = _dictionary->get_chunk(mr.word_size()); + FreeChunk* fc = _dictionary->get_chunk(mr.word_size(), + FreeBlockDictionary::atLeast); // The small linAB initially has all the space and will allocate // a chunk of any size. HeapWord* addr = (HeapWord*) fc; @@ -1647,7 +1648,8 @@ FreeChunk* CompactibleFreeListSpace::getChunkFromDictionary(size_t size) { assert_locked(); - FreeChunk* fc = _dictionary->get_chunk(size); + FreeChunk* fc = _dictionary->get_chunk(size, + FreeBlockDictionary::atLeast); if (fc == NULL) { return NULL; } @@ -1664,7 +1666,8 @@ FreeChunk* CompactibleFreeListSpace::getChunkFromDictionaryExact(size_t size) { assert_locked(); - FreeChunk* fc = _dictionary->get_chunk(size); + FreeChunk* fc = _dictionary->get_chunk(size, + FreeBlockDictionary::atLeast); if (fc == NULL) { return fc; } @@ -1677,7 +1680,8 @@ if (fc->size() < size + MinChunkSize) { // Return the chunk to the dictionary and go get a bigger one. returnChunkToDictionary(fc); - fc = _dictionary->get_chunk(size + MinChunkSize); + fc = _dictionary->get_chunk(size + MinChunkSize, + FreeBlockDictionary::atLeast); if (fc == NULL) { return NULL; } diff -r da53cb17186a -r 412d722168bc src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -131,7 +131,7 @@ LinearAllocBlock _smallLinearAllocBlock; FreeBlockDictionary::DictionaryChoice _dictionaryChoice; - FreeBlockDictionary* _dictionary; // ptr to dictionary for large size blocks + AFLBinaryTreeDictionary* _dictionary; // ptr to dictionary for large size blocks AdaptiveFreeList _indexedFreeList[IndexSetSize]; // indexed array for small size blocks diff -r da53cb17186a -r 412d722168bc src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp Fri Feb 08 08:07:06 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 @@ -25,8 +25,6 @@ #ifndef SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_VMSTRUCTS_CMS_HPP #define SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_VMSTRUCTS_CMS_HPP -typedef BinaryTreeDictionary AFLBinaryTreeDictionary; - #define VM_STRUCTS_CMS(nonstatic_field, \ volatile_nonstatic_field, \ static_field) \ @@ -34,14 +32,15 @@ nonstatic_field(CompactibleFreeListSpace, _bt, BlockOffsetArrayNonContigSpace) \ \ nonstatic_field(CMSBitMap, _bmWordSize, size_t) \ - nonstatic_field(CMSBitMap, _shifter, const int) \ - nonstatic_field(CMSBitMap, _bm, BitMap) \ - nonstatic_field(CMSBitMap, _virtual_space, VirtualSpace) \ + nonstatic_field(CMSBitMap, _shifter, const int) \ + nonstatic_field(CMSBitMap, _bm, BitMap) \ + nonstatic_field(CMSBitMap, _virtual_space, VirtualSpace) \ nonstatic_field(CMSCollector, _markBitMap, CMSBitMap) \ nonstatic_field(ConcurrentMarkSweepGeneration, _cmsSpace, CompactibleFreeListSpace*) \ static_field(ConcurrentMarkSweepThread, _collector, CMSCollector*) \ nonstatic_field(LinearAllocBlock, _word_size, size_t) \ nonstatic_field(AFLBinaryTreeDictionary, _total_size, size_t) \ + nonstatic_field(CompactibleFreeListSpace, _dictionary, AFLBinaryTreeDictionary*) \ nonstatic_field(CompactibleFreeListSpace, _indexedFreeList[0], FreeList) \ nonstatic_field(CompactibleFreeListSpace, _smallLinearAllocBlock, LinearAllocBlock) @@ -62,10 +61,9 @@ declare_toplevel_type(SurrogateLockerThread*) \ declare_toplevel_type(CompactibleFreeListSpace*) \ declare_toplevel_type(CMSCollector*) \ - declare_toplevel_type(AFLBinaryTreeDictionary*) \ + declare_toplevel_type(AFLBinaryTreeDictionary) \ declare_toplevel_type(LinearAllocBlock) \ - declare_toplevel_type(FreeBlockDictionary) \ - declare_type(AFLBinaryTreeDictionary, FreeBlockDictionary) + declare_toplevel_type(FreeBlockDictionary) #define VM_INT_CONSTANTS_CMS(declare_constant) \ declare_constant(Generation::ConcurrentMarkSweep) \ diff -r da53cb17186a -r 412d722168bc src/share/vm/gc_implementation/g1/concurrentMark.cpp --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -571,19 +571,14 @@ _sleep_factor = 0.0; _marking_task_overhead = 1.0; } else { - if (ConcGCThreads > 0) { - // notice that ConcGCThreads overwrites G1MarkingOverheadPercent + if (!FLAG_IS_DEFAULT(ConcGCThreads) && ConcGCThreads > 0) { + // Note: ConcGCThreads has precedence over G1MarkingOverheadPercent // if both are set - - _parallel_marking_threads = (uint) ConcGCThreads; - _max_parallel_marking_threads = _parallel_marking_threads; _sleep_factor = 0.0; _marking_task_overhead = 1.0; } else if (G1MarkingOverheadPercent > 0) { - // we will calculate the number of parallel marking threads - // based on a target overhead with respect to the soft real-time - // goal - + // We will calculate the number of parallel marking threads based + // on a target overhead with respect to the soft real-time goal double marking_overhead = (double) G1MarkingOverheadPercent / 100.0; double overall_cm_overhead = (double) MaxGCPauseMillis * marking_overhead / @@ -596,17 +591,22 @@ double sleep_factor = (1.0 - marking_task_overhead) / marking_task_overhead; - _parallel_marking_threads = (uint) marking_thread_num; - _max_parallel_marking_threads = _parallel_marking_threads; + FLAG_SET_ERGO(uintx, ConcGCThreads, (uint) marking_thread_num); _sleep_factor = sleep_factor; _marking_task_overhead = marking_task_overhead; } else { - _parallel_marking_threads = scale_parallel_threads((uint)ParallelGCThreads); - _max_parallel_marking_threads = _parallel_marking_threads; + // Calculate the number of parallel marking threads by scaling + // the number of parallel GC threads. + uint marking_thread_num = scale_parallel_threads((uint) ParallelGCThreads); + FLAG_SET_ERGO(uintx, ConcGCThreads, marking_thread_num); _sleep_factor = 0.0; _marking_task_overhead = 1.0; } + assert(ConcGCThreads > 0, "Should have been set"); + _parallel_marking_threads = (uint) ConcGCThreads; + _max_parallel_marking_threads = _parallel_marking_threads; + if (parallel_marking_threads() > 1) { _cleanup_task_overhead = 1.0; } else { @@ -1190,7 +1190,7 @@ uint active_workers = MAX2(1U, parallel_marking_threads()); CMRootRegionScanTask task(this); - if (parallel_marking_threads() > 0) { + if (use_parallel_marking_threads()) { _parallel_workers->set_active_workers((int) active_workers); _parallel_workers->run_task(&task); } else { @@ -1226,7 +1226,7 @@ set_phase(active_workers, true /* concurrent */); CMConcurrentMarkingTask markingTask(this, cmThread()); - if (parallel_marking_threads() > 0) { + if (use_parallel_marking_threads()) { _parallel_workers->set_active_workers((int)active_workers); // Don't set _n_par_threads because it affects MT in proceess_strong_roots() // and the decisions on that MT processing is made elsewhere. @@ -2167,7 +2167,8 @@ assert(tmp_free_list.is_empty(), "post-condition"); } -// Support closures for reference procssing in G1 +// Supporting Object and Oop closures for reference discovery +// and processing in during marking bool G1CMIsAliveClosure::do_object_b(oop obj) { HeapWord* addr = (HeapWord*)obj; @@ -2175,73 +2176,26 @@ (!_g1->is_in_g1_reserved(addr) || !_g1->is_obj_ill(obj)); } -class G1CMKeepAliveClosure: public ExtendedOopClosure { - G1CollectedHeap* _g1; - ConcurrentMark* _cm; - public: - G1CMKeepAliveClosure(G1CollectedHeap* g1, ConcurrentMark* cm) : - _g1(g1), _cm(cm) { - assert(Thread::current()->is_VM_thread(), "otherwise fix worker id"); - } - - virtual void do_oop(narrowOop* p) { do_oop_work(p); } - virtual void do_oop( oop* p) { do_oop_work(p); } - - template void do_oop_work(T* p) { - oop obj = oopDesc::load_decode_heap_oop(p); - HeapWord* addr = (HeapWord*)obj; - - if (_cm->verbose_high()) { - gclog_or_tty->print_cr("\t[0] we're looking at location " - "*"PTR_FORMAT" = "PTR_FORMAT, - p, (void*) obj); - } - - if (_g1->is_in_g1_reserved(addr) && _g1->is_obj_ill(obj)) { - _cm->mark_and_count(obj); - _cm->mark_stack_push(obj); - } - } -}; - -class G1CMDrainMarkingStackClosure: public VoidClosure { - ConcurrentMark* _cm; - CMMarkStack* _markStack; - G1CMKeepAliveClosure* _oopClosure; - public: - G1CMDrainMarkingStackClosure(ConcurrentMark* cm, CMMarkStack* markStack, - G1CMKeepAliveClosure* oopClosure) : - _cm(cm), - _markStack(markStack), - _oopClosure(oopClosure) { } - - void do_void() { - _markStack->drain(_oopClosure, _cm->nextMarkBitMap(), false); - } -}; - -// 'Keep Alive' closure used by parallel reference processing. -// An instance of this closure is used in the parallel reference processing -// code rather than an instance of G1CMKeepAliveClosure. We could have used -// the G1CMKeepAliveClosure as it is MT-safe. Also reference objects are -// placed on to discovered ref lists once so we can mark and push with no -// need to check whether the object has already been marked. Using the -// G1CMKeepAliveClosure would mean, however, having all the worker threads -// operating on the global mark stack. This means that an individual -// worker would be doing lock-free pushes while it processes its own -// discovered ref list followed by drain call. If the discovered ref lists -// are unbalanced then this could cause interference with the other -// workers. Using a CMTask (and its embedded local data structures) -// avoids that potential interference. -class G1CMParKeepAliveAndDrainClosure: public OopClosure { +// 'Keep Alive' oop closure used by both serial parallel reference processing. +// Uses the CMTask associated with a worker thread (for serial reference +// processing the CMTask for worker 0 is used) to preserve (mark) and +// trace referent objects. +// +// Using the CMTask and embedded local queues avoids having the worker +// threads operating on the global mark stack. This reduces the risk +// of overflowing the stack - which we would rather avoid at this late +// state. Also using the tasks' local queues removes the potential +// of the workers interfering with each other that could occur if +// operating on the global stack. + +class G1CMKeepAliveAndDrainClosure: public OopClosure { ConcurrentMark* _cm; CMTask* _task; int _ref_counter_limit; int _ref_counter; public: - G1CMParKeepAliveAndDrainClosure(ConcurrentMark* cm, CMTask* task) : - _cm(cm), _task(task), - _ref_counter_limit(G1RefProcDrainInterval) { + G1CMKeepAliveAndDrainClosure(ConcurrentMark* cm, CMTask* task) : + _cm(cm), _task(task), _ref_counter_limit(G1RefProcDrainInterval) { assert(_ref_counter_limit > 0, "sanity"); _ref_counter = _ref_counter_limit; } @@ -2262,18 +2216,22 @@ _ref_counter--; if (_ref_counter == 0) { - // We have dealt with _ref_counter_limit references, pushing them and objects - // reachable from them on to the local stack (and possibly the global stack). - // Call do_marking_step() to process these entries. We call the routine in a - // loop, which we'll exit if there's nothing more to do (i.e. we're done - // with the entries that we've pushed as a result of the deal_with_reference - // calls above) or we overflow. - // Note: CMTask::do_marking_step() can set the CMTask::has_aborted() flag - // while there may still be some work to do. (See the comment at the - // beginning of CMTask::do_marking_step() for those conditions - one of which - // is reaching the specified time target.) It is only when - // CMTask::do_marking_step() returns without setting the has_aborted() flag - // that the marking has completed. + // We have dealt with _ref_counter_limit references, pushing them + // and objects reachable from them on to the local stack (and + // possibly the global stack). Call CMTask::do_marking_step() to + // process these entries. + // + // We call CMTask::do_marking_step() in a loop, which we'll exit if + // there's nothing more to do (i.e. we're done with the entries that + // were pushed as a result of the CMTask::deal_with_reference() calls + // above) or we overflow. + // + // Note: CMTask::do_marking_step() can set the CMTask::has_aborted() + // flag while there may still be some work to do. (See the comment at + // the beginning of CMTask::do_marking_step() for those conditions - + // one of which is reaching the specified time target.) It is only + // when CMTask::do_marking_step() returns without setting the + // has_aborted() flag that the marking step has completed. do { double mark_step_duration_ms = G1ConcMarkStepDurationMillis; _task->do_marking_step(mark_step_duration_ms, @@ -2290,36 +2248,59 @@ } }; -class G1CMParDrainMarkingStackClosure: public VoidClosure { +// 'Drain' oop closure used by both serial and parallel reference processing. +// Uses the CMTask associated with a given worker thread (for serial +// reference processing the CMtask for worker 0 is used). Calls the +// do_marking_step routine, with an unbelievably large timeout value, +// to drain the marking data structures of the remaining entries +// added by the 'keep alive' oop closure above. + +class G1CMDrainMarkingStackClosure: public VoidClosure { ConcurrentMark* _cm; - CMTask* _task; + CMTask* _task; + bool _do_stealing; + bool _do_termination; public: - G1CMParDrainMarkingStackClosure(ConcurrentMark* cm, CMTask* task) : - _cm(cm), _task(task) { } + G1CMDrainMarkingStackClosure(ConcurrentMark* cm, CMTask* task, bool is_par) : + _cm(cm), _task(task) { + assert(is_par || _task->worker_id() == 0, + "Only task for worker 0 should be used if ref processing is single threaded"); + // We only allow stealing and only enter the termination protocol + // in CMTask::do_marking_step() if this closure is being instantiated + // for parallel reference processing. + _do_stealing = _do_termination = is_par; + } void do_void() { do { if (_cm->verbose_high()) { - gclog_or_tty->print_cr("\t[%u] Drain: Calling do marking_step", - _task->worker_id()); + gclog_or_tty->print_cr("\t[%u] Drain: Calling do_marking_step - " + "stealing: %s, termination: %s", + _task->worker_id(), + BOOL_TO_STR(_do_stealing), + BOOL_TO_STR(_do_termination)); } - // We call CMTask::do_marking_step() to completely drain the local and - // global marking stacks. The routine is called in a loop, which we'll - // exit if there's nothing more to do (i.e. we'completely drained the - // entries that were pushed as a result of applying the - // G1CMParKeepAliveAndDrainClosure to the entries on the discovered ref - // lists above) or we overflow the global marking stack. - // Note: CMTask::do_marking_step() can set the CMTask::has_aborted() flag - // while there may still be some work to do. (See the comment at the - // beginning of CMTask::do_marking_step() for those conditions - one of which - // is reaching the specified time target.) It is only when - // CMTask::do_marking_step() returns without setting the has_aborted() flag - // that the marking has completed. + // We call CMTask::do_marking_step() to completely drain the local + // and global marking stacks of entries pushed by the 'keep alive' + // oop closure (an instance of G1CMKeepAliveAndDrainClosure above). + // + // CMTask::do_marking_step() is called in a loop, which we'll exit + // if there's nothing more to do (i.e. we'completely drained the + // entries that were pushed as a a result of applying the 'keep alive' + // closure to the entries on the discovered ref lists) or we overflow + // the global marking stack. + // + // Note: CMTask::do_marking_step() can set the CMTask::has_aborted() + // flag while there may still be some work to do. (See the comment at + // the beginning of CMTask::do_marking_step() for those conditions - + // one of which is reaching the specified time target.) It is only + // when CMTask::do_marking_step() returns without setting the + // has_aborted() flag that the marking step has completed. _task->do_marking_step(1000000000.0 /* something very large */, - true /* do_stealing */, - true /* do_termination */); + _do_stealing, + _do_termination); } while (_task->has_aborted() && !_cm->has_overflown()); } }; @@ -2352,19 +2333,23 @@ ProcessTask& _proc_task; G1CollectedHeap* _g1h; ConcurrentMark* _cm; + bool _processing_is_mt; public: G1CMRefProcTaskProxy(ProcessTask& proc_task, G1CollectedHeap* g1h, ConcurrentMark* cm) : AbstractGangTask("Process reference objects in parallel"), - _proc_task(proc_task), _g1h(g1h), _cm(cm) { } + _proc_task(proc_task), _g1h(g1h), _cm(cm) { + ReferenceProcessor* rp = _g1h->ref_processor_cm(); + _processing_is_mt = rp->processing_is_mt(); + } virtual void work(uint worker_id) { CMTask* marking_task = _cm->task(worker_id); G1CMIsAliveClosure g1_is_alive(_g1h); - G1CMParKeepAliveAndDrainClosure g1_par_keep_alive(_cm, marking_task); - G1CMParDrainMarkingStackClosure g1_par_drain(_cm, marking_task); + G1CMKeepAliveAndDrainClosure g1_par_keep_alive(_cm, marking_task); + G1CMDrainMarkingStackClosure g1_par_drain(_cm, marking_task, _processing_is_mt); _proc_task.work(worker_id, g1_is_alive, g1_par_keep_alive, g1_par_drain); } @@ -2372,6 +2357,7 @@ void G1CMRefProcTaskExecutor::execute(ProcessTask& proc_task) { assert(_workers != NULL, "Need parallel worker threads."); + assert(_g1h->ref_processor_cm()->processing_is_mt(), "processing is not MT"); G1CMRefProcTaskProxy proc_task_proxy(proc_task, _g1h, _cm); @@ -2399,6 +2385,7 @@ void G1CMRefProcTaskExecutor::execute(EnqueueTask& enq_task) { assert(_workers != NULL, "Need parallel worker threads."); + assert(_g1h->ref_processor_cm()->processing_is_mt(), "processing is not MT"); G1CMRefEnqueueTaskProxy enq_task_proxy(enq_task); @@ -2429,59 +2416,58 @@ // See the comment in G1CollectedHeap::ref_processing_init() // about how reference processing currently works in G1. - // Process weak references. + // Set the soft reference policy rp->setup_policy(clear_all_soft_refs); assert(_markStack.isEmpty(), "mark stack should be empty"); - G1CMKeepAliveClosure g1_keep_alive(g1h, this); - G1CMDrainMarkingStackClosure - g1_drain_mark_stack(this, &_markStack, &g1_keep_alive); - - // We use the work gang from the G1CollectedHeap and we utilize all - // the worker threads. - uint active_workers = g1h->workers() ? g1h->workers()->active_workers() : 1U; + // Non-MT instances 'Keep Alive' and 'Complete GC' oop closures. + G1CMKeepAliveAndDrainClosure g1_keep_alive(this, task(0)); + G1CMDrainMarkingStackClosure g1_drain_mark_stack(this, task(0), false); + + // We need at least one active thread. If reference processing is + // not multi-threaded we use the current (ConcurrentMarkThread) thread, + // otherwise we use the work gang from the G1CollectedHeap and we + // utilize all the worker threads we can. + uint active_workers = (rp->processing_is_mt() && g1h->workers() != NULL + ? g1h->workers()->active_workers() + : 1U); + active_workers = MAX2(MIN2(active_workers, _max_worker_id), 1U); G1CMRefProcTaskExecutor par_task_executor(g1h, this, g1h->workers(), active_workers); - if (rp->processing_is_mt()) { - // Set the degree of MT here. If the discovery is done MT, there - // may have been a different number of threads doing the discovery - // and a different number of discovered lists may have Ref objects. - // That is OK as long as the Reference lists are balanced (see - // balance_all_queues() and balance_queues()). - rp->set_active_mt_degree(active_workers); - - rp->process_discovered_references(&g1_is_alive, + AbstractRefProcTaskExecutor* executor = (rp->processing_is_mt() + ? &par_task_executor + : NULL); + + // Set the degree of MT processing here. If the discovery was done MT, + // the number of threads involved during discovery could differ from + // the number of active workers. This is OK as long as the discovered + // Reference lists are balanced (see balance_all_queues() and balance_queues()). + rp->set_active_mt_degree(active_workers); + + // Process the weak references. + rp->process_discovered_references(&g1_is_alive, &g1_keep_alive, &g1_drain_mark_stack, - &par_task_executor); - - // The work routines of the parallel keep_alive and drain_marking_stack - // will set the has_overflown flag if we overflow the global marking - // stack. - } else { - rp->process_discovered_references(&g1_is_alive, - &g1_keep_alive, - &g1_drain_mark_stack, - NULL); - } + executor); + + // The do_oop work routines of the keep_alive and drain_marking_stack + // oop closures will set the has_overflown flag if we overflow the + // global marking stack. assert(_markStack.overflow() || _markStack.isEmpty(), "mark stack should be empty (unless it overflowed)"); if (_markStack.overflow()) { - // Should have been done already when we tried to push an + // This should have been done already when we tried to push an // entry on to the global mark stack. But let's do it again. set_has_overflown(); } - if (rp->processing_is_mt()) { - assert(rp->num_q() == active_workers, "why not"); - rp->enqueue_discovered_references(&par_task_executor); - } else { - rp->enqueue_discovered_references(); - } + assert(rp->num_q() == active_workers, "why not"); + + rp->enqueue_discovered_references(executor); rp->verify_no_references_recorded(); assert(!rp->discovery_enabled(), "Post condition"); @@ -3242,7 +3228,9 @@ } void ConcurrentMark::print_worker_threads_on(outputStream* st) const { - _parallel_workers->print_worker_threads_on(st); + if (use_parallel_marking_threads()) { + _parallel_workers->print_worker_threads_on(st); + } } // We take a break if someone is trying to stop the world. diff -r da53cb17186a -r 412d722168bc src/share/vm/gc_implementation/g1/concurrentMark.hpp --- a/src/share/vm/gc_implementation/g1/concurrentMark.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -371,8 +371,8 @@ friend class CalcLiveObjectsClosure; friend class G1CMRefProcTaskProxy; friend class G1CMRefProcTaskExecutor; - friend class G1CMParKeepAliveAndDrainClosure; - friend class G1CMParDrainMarkingStackClosure; + friend class G1CMKeepAliveAndDrainClosure; + friend class G1CMDrainMarkingStackClosure; protected: ConcurrentMarkThread* _cmThread; // the thread doing the work @@ -499,17 +499,26 @@ } // accessor methods - uint parallel_marking_threads() { return _parallel_marking_threads; } - uint max_parallel_marking_threads() { return _max_parallel_marking_threads;} - double sleep_factor() { return _sleep_factor; } - double marking_task_overhead() { return _marking_task_overhead;} - double cleanup_sleep_factor() { return _cleanup_sleep_factor; } - double cleanup_task_overhead() { return _cleanup_task_overhead;} + uint parallel_marking_threads() const { return _parallel_marking_threads; } + uint max_parallel_marking_threads() const { return _max_parallel_marking_threads;} + double sleep_factor() { return _sleep_factor; } + double marking_task_overhead() { return _marking_task_overhead;} + double cleanup_sleep_factor() { return _cleanup_sleep_factor; } + double cleanup_task_overhead() { return _cleanup_task_overhead;} - HeapWord* finger() { return _finger; } - bool concurrent() { return _concurrent; } - uint active_tasks() { return _active_tasks; } - ParallelTaskTerminator* terminator() { return &_terminator; } + bool use_parallel_marking_threads() const { + assert(parallel_marking_threads() <= + max_parallel_marking_threads(), "sanity"); + assert((_parallel_workers == NULL && parallel_marking_threads() == 0) || + parallel_marking_threads() > 0, + "parallel workers not set up correctly"); + return _parallel_workers != NULL; + } + + HeapWord* finger() { return _finger; } + bool concurrent() { return _concurrent; } + uint active_tasks() { return _active_tasks; } + ParallelTaskTerminator* terminator() { return &_terminator; } // It claims the next available region to be scanned by a marking // task/thread. It might return NULL if the next region is empty or diff -r da53cb17186a -r 412d722168bc src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp --- a/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -28,8 +28,9 @@ #include "memory/cardTableModRefBS.hpp" #include "memory/memRegion.hpp" #include "oops/oop.inline.hpp" +#include "utilities/macros.hpp" -#ifndef SERIALGC +#if INCLUDE_ALL_GCS class DirtyCardQueueSet; @@ -120,6 +121,6 @@ }; -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1SATBCARDTABLEMODREFBS_HPP diff -r da53cb17186a -r 412d722168bc src/share/vm/gc_implementation/g1/heapRegion.hpp --- a/src/share/vm/gc_implementation/g1/heapRegion.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/gc_implementation/g1/heapRegion.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -32,8 +32,9 @@ #include "gc_implementation/shared/spaceDecorator.hpp" #include "memory/space.inline.hpp" #include "memory/watermark.hpp" +#include "utilities/macros.hpp" -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // A HeapRegion is the smallest piece of a G1CollectedHeap that // can be collected independently. @@ -837,6 +838,6 @@ bool complete() { return _complete; } }; -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS #endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGION_HPP diff -r da53cb17186a -r 412d722168bc src/share/vm/gc_implementation/shared/allocationStats.cpp --- a/src/share/vm/gc_implementation/shared/allocationStats.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/allocationStats.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -23,10 +23,11 @@ */ #include "precompiled.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/shared/allocationStats.hpp" #include "utilities/ostream.hpp" -#endif +#endif // INCLUDE_ALL_GCS // Technically this should be derived from machine speed, and // ideally it would be dynamically adjusted. diff -r da53cb17186a -r 412d722168bc src/share/vm/gc_implementation/shared/allocationStats.hpp --- a/src/share/vm/gc_implementation/shared/allocationStats.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/allocationStats.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -25,11 +25,12 @@ #ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_ALLOCATIONSTATS_HPP #define SHARE_VM_GC_IMPLEMENTATION_SHARED_ALLOCATIONSTATS_HPP -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/shared/gcUtil.hpp" #include "memory/allocation.hpp" #include "utilities/globalDefinitions.hpp" -#endif +#endif // INCLUDE_ALL_GCS class AllocationStats VALUE_OBJ_CLASS_SPEC { // A duration threshold (in ms) used to filter diff -r da53cb17186a -r 412d722168bc src/share/vm/gc_implementation/shared/concurrentGCThread.hpp --- a/src/share/vm/gc_implementation/shared/concurrentGCThread.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/concurrentGCThread.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -25,9 +25,10 @@ #ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_CONCURRENTGCTHREAD_HPP #define SHARE_VM_GC_IMPLEMENTATION_SHARED_CONCURRENTGCTHREAD_HPP -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "runtime/thread.hpp" -#endif +#endif // INCLUDE_ALL_GCS class VoidClosure; diff -r da53cb17186a -r 412d722168bc src/share/vm/gc_implementation/shared/gSpaceCounters.cpp --- a/src/share/vm/gc_implementation/shared/gSpaceCounters.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/gSpaceCounters.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -23,11 +23,12 @@ */ #include "precompiled.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/shared/gSpaceCounters.hpp" #include "memory/generation.hpp" #include "memory/resourceArea.hpp" -#endif +#endif // INCLUDE_ALL_GCS GSpaceCounters::GSpaceCounters(const char* name, int ordinal, size_t max_size, Generation* g, GenerationCounters* gc, diff -r da53cb17186a -r 412d722168bc src/share/vm/gc_implementation/shared/gSpaceCounters.hpp --- a/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -25,11 +25,12 @@ #ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_GSPACECOUNTERS_HPP #define SHARE_VM_GC_IMPLEMENTATION_SHARED_GSPACECOUNTERS_HPP -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/shared/generationCounters.hpp" #include "memory/generation.hpp" #include "runtime/perfData.hpp" -#endif +#endif // INCLUDE_ALL_GCS // A GSpaceCounter is a holder class for performance counters // that track a space; diff -r da53cb17186a -r 412d722168bc src/share/vm/gc_implementation/shared/gcAdaptivePolicyCounters.hpp --- a/src/share/vm/gc_implementation/shared/gcAdaptivePolicyCounters.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/gcAdaptivePolicyCounters.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -25,10 +25,11 @@ #ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_GCADAPTIVEPOLICYCOUNTERS_HPP #define SHARE_VM_GC_IMPLEMENTATION_SHARED_GCADAPTIVEPOLICYCOUNTERS_HPP -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/shared/adaptiveSizePolicy.hpp" #include "gc_implementation/shared/gcPolicyCounters.hpp" -#endif +#endif // INCLUDE_ALL_GCS // This class keeps statistical information and computes the // size of the heap. diff -r da53cb17186a -r 412d722168bc src/share/vm/gc_implementation/shared/hSpaceCounters.hpp --- a/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -25,11 +25,12 @@ #ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_HSPACECOUNTERS_HPP #define SHARE_VM_GC_IMPLEMENTATION_SHARED_HSPACECOUNTERS_HPP -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/shared/generationCounters.hpp" #include "memory/generation.hpp" #include "runtime/perfData.hpp" -#endif +#endif // INCLUDE_ALL_GCS // A HSpaceCounter is a holder class for performance counters // that track a collections (logical spaces) in a heap; diff -r da53cb17186a -r 412d722168bc src/share/vm/gc_implementation/shared/immutableSpace.cpp --- a/src/share/vm/gc_implementation/shared/immutableSpace.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/immutableSpace.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -23,11 +23,12 @@ */ #include "precompiled.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/shared/immutableSpace.hpp" #include "memory/universe.hpp" #include "oops/oop.inline.hpp" -#endif +#endif // INCLUDE_ALL_GCS void ImmutableSpace::initialize(MemRegion mr) { HeapWord* bottom = mr.start(); diff -r da53cb17186a -r 412d722168bc src/share/vm/gc_implementation/shared/isGCActiveMark.hpp --- a/src/share/vm/gc_implementation/shared/isGCActiveMark.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/isGCActiveMark.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -25,9 +25,10 @@ #ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_ISGCACTIVEMARK_HPP #define SHARE_VM_GC_IMPLEMENTATION_SHARED_ISGCACTIVEMARK_HPP -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" -#endif +#endif // INCLUDE_ALL_GCS // This class provides a method for block structured setting of the // _is_gc_active state without requiring accessors in CollectedHeap diff -r da53cb17186a -r 412d722168bc src/share/vm/gc_implementation/shared/markSweep.inline.hpp --- a/src/share/vm/gc_implementation/shared/markSweep.inline.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/markSweep.inline.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -28,9 +28,10 @@ #include "gc_implementation/shared/markSweep.hpp" #include "gc_interface/collectedHeap.hpp" #include "utilities/stack.inline.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/parallelScavenge/psParallelCompact.hpp" -#endif +#endif // INCLUDE_ALL_GCS inline void MarkSweep::mark_object(oop obj) { // some marks may contain information we need to preserve so we store them away diff -r da53cb17186a -r 412d722168bc src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp --- a/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -25,10 +25,11 @@ #ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_MUTABLENUMASPACE_HPP #define SHARE_VM_GC_IMPLEMENTATION_SHARED_MUTABLENUMASPACE_HPP -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/shared/gcUtil.hpp" #include "gc_implementation/shared/mutableSpace.hpp" -#endif +#endif // INCLUDE_ALL_GCS /* * The NUMA-aware allocator (MutableNUMASpace) is basically a modification diff -r da53cb17186a -r 412d722168bc src/share/vm/gc_implementation/shared/mutableSpace.cpp --- a/src/share/vm/gc_implementation/shared/mutableSpace.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/mutableSpace.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -23,13 +23,14 @@ */ #include "precompiled.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/shared/mutableSpace.hpp" #include "gc_implementation/shared/spaceDecorator.hpp" #include "oops/oop.inline.hpp" #include "runtime/safepoint.hpp" #include "runtime/thread.hpp" -#endif +#endif // INCLUDE_ALL_GCS MutableSpace::MutableSpace(size_t alignment): ImmutableSpace(), _top(NULL), _alignment(alignment) { assert(MutableSpace::alignment() >= 0 && diff -r da53cb17186a -r 412d722168bc src/share/vm/gc_implementation/shared/spaceCounters.cpp --- a/src/share/vm/gc_implementation/shared/spaceCounters.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/spaceCounters.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -23,10 +23,11 @@ */ #include "precompiled.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/shared/spaceCounters.hpp" #include "memory/resourceArea.hpp" -#endif +#endif // INCLUDE_ALL_GCS SpaceCounters::SpaceCounters(const char* name, int ordinal, size_t max_size, MutableSpace* m, GenerationCounters* gc) : diff -r da53cb17186a -r 412d722168bc src/share/vm/gc_implementation/shared/spaceCounters.hpp --- a/src/share/vm/gc_implementation/shared/spaceCounters.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/spaceCounters.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -25,12 +25,13 @@ #ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_SPACECOUNTERS_HPP #define SHARE_VM_GC_IMPLEMENTATION_SHARED_SPACECOUNTERS_HPP -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/shared/generationCounters.hpp" #include "gc_implementation/shared/immutableSpace.hpp" #include "gc_implementation/shared/mutableSpace.hpp" #include "runtime/perfData.hpp" -#endif +#endif // INCLUDE_ALL_GCS // A SpaceCounter is a holder class for performance counters // that track a space; diff -r da53cb17186a -r 412d722168bc src/share/vm/gc_implementation/shared/vmGCOperations.cpp --- a/src/share/vm/gc_implementation/shared/vmGCOperations.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/vmGCOperations.cpp Fri Feb 08 08:07:06 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 @@ -36,9 +36,10 @@ #include "runtime/interfaceSupport.hpp" #include "utilities/dtrace.hpp" #include "utilities/preserveException.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" -#endif +#endif // INCLUDE_ALL_GCS #ifndef USDT2 HS_DTRACE_PROBE_DECL1(hotspot, gc__begin, bool); @@ -167,7 +168,9 @@ ch->collect_as_vm_thread(GCCause::_heap_inspection); } } - HeapInspection::heap_inspection(_out, _need_prologue /* need_prologue */); + HeapInspection inspect(_csv_format, _print_help, _print_class_stats, + _columns); + inspect.heap_inspection(_out, _need_prologue /* need_prologue */); } diff -r da53cb17186a -r 412d722168bc src/share/vm/gc_implementation/shared/vmGCOperations.hpp --- a/src/share/vm/gc_implementation/shared/vmGCOperations.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/vmGCOperations.hpp Fri Feb 08 08:07:06 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;} }; diff -r da53cb17186a -r 412d722168bc src/share/vm/interpreter/bytecodeInterpreter.cpp --- a/src/share/vm/interpreter/bytecodeInterpreter.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp Fri Feb 08 08:07:06 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); } diff -r da53cb17186a -r 412d722168bc src/share/vm/interpreter/linkResolver.cpp --- a/src/share/vm/interpreter/linkResolver.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/interpreter/linkResolver.cpp Fri Feb 08 08:07:06 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(, method_name, method_signature, current_klass, pool, index, CHECK); Symbol* method_name = pool->name_ref_at(index); diff -r da53cb17186a -r 412d722168bc src/share/vm/memory/allocation.hpp --- a/src/share/vm/memory/allocation.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/memory/allocation.hpp Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc src/share/vm/memory/binaryTreeDictionary.cpp --- a/src/share/vm/memory/binaryTreeDictionary.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/memory/binaryTreeDictionary.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "utilities/macros.hpp" #include "gc_implementation/shared/allocationStats.hpp" #include "memory/binaryTreeDictionary.hpp" #include "memory/freeList.hpp" @@ -31,12 +32,13 @@ #include "memory/metachunk.hpp" #include "runtime/globals.hpp" #include "utilities/ostream.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/concurrentMarkSweep/adaptiveFreeList.hpp" #include "gc_implementation/concurrentMarkSweep/freeChunk.hpp" #include "gc_implementation/shared/spaceDecorator.hpp" #include "gc_implementation/concurrentMarkSweep/freeChunk.hpp" -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS //////////////////////////////////////////////////////////////////////////////// // A binary tree based search structure for free blocks. @@ -118,7 +120,7 @@ } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // Specialize for AdaptiveFreeList which tries to avoid // splitting a chunk of a size that is under populated in favor of // an over populated size. The general get_better_list() just returns @@ -160,7 +162,7 @@ } return curTL; } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS template class FreeList_t> TreeList* @@ -871,9 +873,9 @@ template class FreeList_t> void BinaryTreeDictionary::dict_census_update(size_t size, bool split, bool birth){} -#ifndef SERIALGC +#if INCLUDE_ALL_GCS template <> -void BinaryTreeDictionary::dict_census_update(size_t size, bool split, bool birth){ +void AFLBinaryTreeDictionary::dict_census_update(size_t size, bool split, bool birth){ TreeList* nd = find_list(size); if (nd) { if (split) { @@ -900,7 +902,7 @@ // This is a birth associated with a LinAB. The chunk // for the LinAB is not in the dictionary. } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS template class FreeList_t> bool BinaryTreeDictionary::coal_dict_over_populated(size_t size) { @@ -909,9 +911,9 @@ return true; } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS template <> -bool BinaryTreeDictionary::coal_dict_over_populated(size_t size) { +bool AFLBinaryTreeDictionary::coal_dict_over_populated(size_t size) { if (FLSAlwaysCoalesceLarge) return true; TreeList* list_of_size = find_list(size); @@ -919,7 +921,7 @@ return list_of_size == NULL || list_of_size->coal_desired() <= 0 || list_of_size->count() > list_of_size->coal_desired(); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS // Closures for walking the binary tree. // do_list() walks the free list in a node applying the closure @@ -979,7 +981,7 @@ void do_list(FreeList* fl) {} -#ifndef SERIALGC +#if INCLUDE_ALL_GCS void do_list(AdaptiveFreeList* fl) { double coalSurplusPercent = _percentage; fl->compute_desired(_inter_sweep_current, _inter_sweep_estimate, _intra_sweep_estimate); @@ -987,7 +989,7 @@ fl->set_before_sweep(fl->count()); fl->set_bfr_surp(fl->surplus()); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS }; // Used to search the tree until a condition is met. @@ -1134,13 +1136,13 @@ setTreeSurplusClosure(double v) { percentage = v; } void do_list(FreeList* fl) {} -#ifndef SERIALGC +#if INCLUDE_ALL_GCS void do_list(AdaptiveFreeList* fl) { double splitSurplusPercent = percentage; fl->set_surplus(fl->count() - (ssize_t)((double)fl->desired() * splitSurplusPercent)); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS }; template class FreeList_t> @@ -1157,7 +1159,7 @@ setTreeHintsClosure(size_t v) { hint = v; } void do_list(FreeList* fl) {} -#ifndef SERIALGC +#if INCLUDE_ALL_GCS void do_list(AdaptiveFreeList* fl) { fl->set_hint(hint); assert(fl->hint() == 0 || fl->hint() > fl->size(), @@ -1166,7 +1168,7 @@ hint = fl->size(); } } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS }; template class FreeList_t> @@ -1180,7 +1182,7 @@ class clearTreeCensusClosure : public AscendTreeCensusClosure { void do_list(FreeList* fl) {} -#ifndef SERIALGC +#if INCLUDE_ALL_GCS void do_list(AdaptiveFreeList* fl) { fl->set_prev_sweep(fl->count()); fl->set_coal_births(0); @@ -1188,7 +1190,7 @@ fl->set_split_births(0); fl->set_split_deaths(0); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS }; template class FreeList_t> @@ -1252,7 +1254,7 @@ total()->set_count( total()->count() + fl->count() ); } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS void do_list(AdaptiveFreeList* fl) { if (++_print_line >= 40) { FreeList_t::print_labels_on(gclog_or_tty, "size"); @@ -1271,7 +1273,7 @@ total()->set_split_births(total()->split_births() + fl->split_births()); total()->set_split_deaths(total()->split_deaths() + fl->split_deaths()); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS }; template class FreeList_t> @@ -1286,9 +1288,9 @@ FreeList_t::print_labels_on(gclog_or_tty, " "); } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS template <> -void BinaryTreeDictionary::print_dict_census(void) const { +void AFLBinaryTreeDictionary::print_dict_census(void) const { gclog_or_tty->print("\nBinaryTree\n"); AdaptiveFreeList::print_labels_on(gclog_or_tty, "size"); @@ -1308,7 +1310,7 @@ (double)(total->desired() - total->count()) /(total->desired() != 0 ? (double)total->desired() : 1.0)); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS template class FreeList_t> class PrintFreeListsClosure : public AscendTreeCensusClosure { @@ -1414,10 +1416,10 @@ template class TreeChunk; -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // Explicitly instantiate these types for FreeChunk. template class TreeList; template class BinaryTreeDictionary; template class TreeChunk; -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS diff -r da53cb17186a -r 412d722168bc src/share/vm/memory/binaryTreeDictionary.hpp --- a/src/share/vm/memory/binaryTreeDictionary.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/memory/binaryTreeDictionary.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -43,6 +43,10 @@ template class FreeList_t> class DescendTreeCensusClosure; template class FreeList_t> class DescendTreeSearchClosure; +class FreeChunk; +template class AdaptiveFreeList; +typedef BinaryTreeDictionary AFLBinaryTreeDictionary; + template class FreeList_t> class TreeList : public FreeList_t { friend class TreeChunk; diff -r da53cb17186a -r 412d722168bc src/share/vm/memory/cardTableModRefBS.cpp --- a/src/share/vm/memory/cardTableModRefBS.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/memory/cardTableModRefBS.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -34,6 +34,7 @@ #include "runtime/mutexLocker.hpp" #include "runtime/virtualspace.hpp" #include "services/memTracker.hpp" +#include "utilities/macros.hpp" #ifdef COMPILER1 #include "c1/c1_LIR.hpp" #include "c1/c1_LIRGenerator.hpp" @@ -499,13 +500,13 @@ int n_threads = SharedHeap::heap()->n_par_threads(); bool is_par = n_threads > 0; if (is_par) { -#ifndef SERIALGC +#if INCLUDE_ALL_GCS assert(SharedHeap::heap()->n_par_threads() == SharedHeap::heap()->workers()->active_workers(), "Mismatch"); non_clean_card_iterate_parallel_work(sp, mr, cl, ct, n_threads); -#else // SERIALGC +#else // INCLUDE_ALL_GCS fatal("Parallel gc not supported here."); -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS } else { // We do not call the non_clean_card_iterate_serial() version below because // we want to clear the cards (which non_clean_card_iterate_serial() does not diff -r da53cb17186a -r 412d722168bc src/share/vm/memory/cardTableRS.cpp --- a/src/share/vm/memory/cardTableRS.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/memory/cardTableRS.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -31,10 +31,11 @@ #include "oops/oop.inline.hpp" #include "runtime/java.hpp" #include "runtime/os.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/g1/concurrentMark.hpp" #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" -#endif +#endif // INCLUDE_ALL_GCS CardTableRS::CardTableRS(MemRegion whole_heap, int max_covered_regions) : @@ -42,7 +43,7 @@ _cur_youngergen_card_val(youngergenP1_card), _regions_to_iterate(max_covered_regions - 1) { -#ifndef SERIALGC +#if INCLUDE_ALL_GCS if (UseG1GC) { _ct_bs = new G1SATBCardTableLoggingModRefBS(whole_heap, max_covered_regions); diff -r da53cb17186a -r 412d722168bc src/share/vm/memory/collectorPolicy.cpp --- a/src/share/vm/memory/collectorPolicy.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/memory/collectorPolicy.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,10 +39,11 @@ #include "runtime/java.hpp" #include "runtime/thread.inline.hpp" #include "runtime/vmThread.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp" #include "gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.hpp" -#endif +#endif // INCLUDE_ALL_GCS // CollectorPolicy methods. @@ -235,6 +236,18 @@ if (NewSize + OldSize > MaxHeapSize) { MaxHeapSize = NewSize + OldSize; } + + if (FLAG_IS_CMDLINE(OldSize) && FLAG_IS_DEFAULT(NewSize)) { + // NewRatio will be used later to set the young generation size so we use + // it to calculate how big the heap should be based on the requested OldSize + // and NewRatio. + assert(NewRatio > 0, "NewRatio should have been set up earlier"); + size_t calculated_heapsize = (OldSize / NewRatio) * (NewRatio + 1); + + calculated_heapsize = align_size_up(calculated_heapsize, max_alignment()); + MaxHeapSize = calculated_heapsize; + InitialHeapSize = calculated_heapsize; + } MaxHeapSize = align_size_up(MaxHeapSize, max_alignment()); always_do_update_barrier = UseConcMarkSweepGC; @@ -384,14 +397,15 @@ // keeping it simple also seems a worthwhile goal. bool TwoGenerationCollectorPolicy::adjust_gen0_sizes(size_t* gen0_size_ptr, size_t* gen1_size_ptr, - size_t heap_size, - size_t min_gen0_size) { + const size_t heap_size, + const size_t min_gen1_size) { bool result = false; + if ((*gen1_size_ptr + *gen0_size_ptr) > heap_size) { - if (((*gen0_size_ptr + OldSize) > heap_size) && - (heap_size - min_gen0_size) >= min_alignment()) { - // Adjust gen0 down to accomodate OldSize - *gen0_size_ptr = heap_size - min_gen0_size; + if ((heap_size < (*gen0_size_ptr + min_gen1_size)) && + (heap_size >= min_gen1_size + min_alignment())) { + // Adjust gen0 down to accommodate min_gen1_size + *gen0_size_ptr = heap_size - min_gen1_size; *gen0_size_ptr = MAX2((uintx)align_size_down(*gen0_size_ptr, min_alignment()), min_alignment()); diff -r da53cb17186a -r 412d722168bc src/share/vm/memory/collectorPolicy.hpp --- a/src/share/vm/memory/collectorPolicy.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/memory/collectorPolicy.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ #include "memory/barrierSet.hpp" #include "memory/generationSpec.hpp" #include "memory/genRemSet.hpp" +#include "utilities/macros.hpp" // This class (or more correctly, subtypes of this class) // are used to define global garbage collector attributes. @@ -48,10 +49,10 @@ class GenCollectorPolicy; class TwoGenerationCollectorPolicy; class AdaptiveSizePolicy; -#ifndef SERIALGC +#if INCLUDE_ALL_GCS class ConcurrentMarkSweepPolicy; class G1CollectorPolicy; -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS class GCPolicyCounters; class MarkSweepPolicy; @@ -134,21 +135,21 @@ virtual GenCollectorPolicy* as_generation_policy() { return NULL; } virtual TwoGenerationCollectorPolicy* as_two_generation_policy() { return NULL; } virtual MarkSweepPolicy* as_mark_sweep_policy() { return NULL; } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS virtual ConcurrentMarkSweepPolicy* as_concurrent_mark_sweep_policy() { return NULL; } virtual G1CollectorPolicy* as_g1_policy() { return NULL; } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS // Note that these are not virtual. bool is_generation_policy() { return as_generation_policy() != NULL; } bool is_two_generation_policy() { return as_two_generation_policy() != NULL; } bool is_mark_sweep_policy() { return as_mark_sweep_policy() != NULL; } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS bool is_concurrent_mark_sweep_policy() { return as_concurrent_mark_sweep_policy() != NULL; } bool is_g1_policy() { return as_g1_policy() != NULL; } -#else // SERIALGC +#else // INCLUDE_ALL_GCS bool is_concurrent_mark_sweep_policy() { return false; } bool is_g1_policy() { return false; } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS virtual BarrierSet::Name barrier_set_name() = 0; @@ -321,7 +322,7 @@ // Returns true is gen0 sizes were adjusted bool adjust_gen0_sizes(size_t* gen0_size_ptr, size_t* gen1_size_ptr, - size_t heap_size, size_t min_gen1_size); + const size_t heap_size, const size_t min_gen1_size); }; class MarkSweepPolicy : public TwoGenerationCollectorPolicy { diff -r da53cb17186a -r 412d722168bc src/share/vm/memory/filemap.cpp --- a/src/share/vm/memory/filemap.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/memory/filemap.cpp Fri Feb 08 08:07:06 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); } diff -r da53cb17186a -r 412d722168bc src/share/vm/memory/freeBlockDictionary.cpp --- a/src/share/vm/memory/freeBlockDictionary.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/memory/freeBlockDictionary.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -23,13 +23,15 @@ */ #include "precompiled.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/concurrentMarkSweep/freeChunk.hpp" -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS #include "memory/freeBlockDictionary.hpp" #include "memory/metablock.hpp" #include "memory/metachunk.hpp" #include "runtime/thread.inline.hpp" +#include "utilities/macros.hpp" #ifndef PRODUCT template Mutex* FreeBlockDictionary::par_lock() const { @@ -56,7 +58,7 @@ template class FreeBlockDictionary; template class FreeBlockDictionary; -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // Explicitly instantiate for FreeChunk template class FreeBlockDictionary; -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS diff -r da53cb17186a -r 412d722168bc src/share/vm/memory/freeList.cpp --- a/src/share/vm/memory/freeList.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/memory/freeList.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -31,10 +31,11 @@ #include "runtime/globals.hpp" #include "runtime/mutex.hpp" #include "runtime/vmThread.hpp" +#include "utilities/macros.hpp" -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #include "gc_implementation/concurrentMarkSweep/freeChunk.hpp" -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS // Free list. A FreeList is used to access a linked list of chunks // of space in the heap. The head and tail are maintained so that @@ -341,6 +342,6 @@ template class FreeList; template class FreeList; -#ifndef SERIALGC +#if INCLUDE_ALL_GCS template class FreeList; -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS diff -r da53cb17186a -r 412d722168bc src/share/vm/memory/genCollectedHeap.cpp --- a/src/share/vm/memory/genCollectedHeap.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/memory/genCollectedHeap.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -51,10 +51,11 @@ #include "services/memoryService.hpp" #include "utilities/vmError.hpp" #include "utilities/workgroup.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp" #include "gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp" -#endif +#endif // INCLUDE_ALL_GCS GenCollectedHeap* GenCollectedHeap::_gch; NOT_PRODUCT(size_t GenCollectedHeap::_skip_header_HeapWords = 0;) @@ -141,14 +142,14 @@ } clear_incremental_collection_failed(); -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // If we are running CMS, create the collector responsible // for collecting the CMS generations. if (collector_policy()->is_concurrent_mark_sweep_policy()) { bool success = create_cms_collector(); if (!success) return JNI_ENOMEM; } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS return JNI_OK; } @@ -686,12 +687,12 @@ void GenCollectedHeap::collect(GCCause::Cause cause) { if (should_do_concurrent_full_gc(cause)) { -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // mostly concurrent full collection collect_mostly_concurrent(cause); -#else // SERIALGC +#else // INCLUDE_ALL_GCS ShouldNotReachHere(); -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS } else { #ifdef ASSERT if (cause == GCCause::_scavenge_alot) { @@ -736,7 +737,7 @@ } } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS bool GenCollectedHeap::create_cms_collector() { assert(((_gens[1]->kind() == Generation::ConcurrentMarkSweep) || @@ -772,7 +773,7 @@ VMThread::execute(&op); } } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS void GenCollectedHeap::do_full_collection(bool clear_all_soft_refs) { do_full_collection(clear_all_soft_refs, _n_gens - 1); @@ -1116,22 +1117,22 @@ if (workers() != NULL) { workers()->threads_do(tc); } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS if (UseConcMarkSweepGC) { ConcurrentMarkSweepThread::threads_do(tc); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS } void GenCollectedHeap::print_gc_threads_on(outputStream* st) const { -#ifndef SERIALGC +#if INCLUDE_ALL_GCS if (UseParNewGC) { workers()->print_worker_threads_on(st); } if (UseConcMarkSweepGC) { ConcurrentMarkSweepThread::print_all_on(st); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS } void GenCollectedHeap::print_tracing_info() const { diff -r da53cb17186a -r 412d722168bc src/share/vm/memory/generationSpec.cpp --- a/src/share/vm/memory/generationSpec.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/memory/generationSpec.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -30,11 +30,12 @@ #include "memory/generationSpec.hpp" #include "memory/tenuredGeneration.hpp" #include "runtime/java.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/parNew/asParNewGeneration.hpp" #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp" #include "gc_implementation/parNew/parNewGeneration.hpp" -#endif +#endif // INCLUDE_ALL_GCS Generation* GenerationSpec::init(ReservedSpace rs, int level, GenRemSet* remset) { @@ -45,7 +46,7 @@ case Generation::MarkSweepCompact: return new TenuredGeneration(rs, init_size(), level, remset); -#ifndef SERIALGC +#if INCLUDE_ALL_GCS case Generation::ParNew: return new ParNewGeneration(rs, init_size(), level); @@ -94,7 +95,7 @@ return g; } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS default: guarantee(false, "unrecognized GenerationName"); diff -r da53cb17186a -r 412d722168bc src/share/vm/memory/heapInspection.cpp --- a/src/share/vm/memory/heapInspection.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/memory/heapInspection.cpp Fri Feb 08 08:07:06 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,15 +23,17 @@ */ #include "precompiled.hpp" +#include "classfile/classLoaderData.hpp" #include "gc_interface/collectedHeap.hpp" #include "memory/genCollectedHeap.hpp" #include "memory/heapInspection.hpp" #include "memory/resourceArea.hpp" #include "runtime/os.hpp" #include "utilities/globalDefinitions.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" -#endif +#endif // INCLUDE_ALL_GCS // HeapInspection @@ -41,12 +43,24 @@ } else if(e1->_instance_words < e2->_instance_words) { return 1; } - return 0; + // Sort alphabetically, note 'Z' < '[' < 'a', but it's better to group + // the array classes before all the instance classes. + ResourceMark rm; + const char* name1 = e1->klass()->external_name(); + const char* name2 = e2->klass()->external_name(); + bool d1 = (name1[0] == '['); + bool d2 = (name2[0] == '['); + if (d1 && !d2) { + return -1; + } else if (d2 && !d1) { + return 1; + } else { + return strcmp(name1, name2); + } } -void KlassInfoEntry::print_on(outputStream* st) const { - ResourceMark rm; - const char* name;; +const char* KlassInfoEntry::name() const { + const char* name; if (_klass->name() != NULL) { name = _klass->external_name(); } else { @@ -60,11 +74,17 @@ if (_klass == Universe::longArrayKlassObj()) name = ""; else name = ""; } + return name; +} + +void KlassInfoEntry::print_on(outputStream* st) const { + ResourceMark rm; + // simplify the formatting (ILP32 vs LP64) - always cast the numbers to 64-bit st->print_cr(INT64_FORMAT_W(13) " " UINT64_FORMAT_W(13) " %s", (jlong) _instance_count, (julong) _instance_words * HeapWordSize, - name); + name()); } KlassInfoEntry* KlassInfoBucket::lookup(Klass* const k) { @@ -101,7 +121,14 @@ } } -KlassInfoTable::KlassInfoTable(int size, HeapWord* ref) { +void KlassInfoTable::AllClassesFinder::do_klass(Klass* k) { + // This has the SIDE EFFECT of creating a KlassInfoEntry + // for , if one doesn't exist yet. + _table->lookup(k); +} + +KlassInfoTable::KlassInfoTable(int size, HeapWord* ref, + bool need_class_stats) { _size = 0; _ref = ref; _buckets = NEW_C_HEAP_ARRAY(KlassInfoBucket, size, mtInternal); @@ -110,6 +137,10 @@ for (int index = 0; index < _size; index++) { _buckets[index].initialize(); } + if (need_class_stats) { + AllClassesFinder finder(this); + ClassLoaderDataGraph::classes_do(&finder); + } } } @@ -165,7 +196,8 @@ 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(estimatedCount,true); } @@ -196,9 +228,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; cprint(",%s", name_table[c]);} + } + st->print(",ClassName"); + } else { + st->print("Index Super"); + for (int c=0; cprint(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; clength(); 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; coop_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; cprint("," JULONG_FORMAT, col_table[c]);} + } + st->print(",%s",e->name()); + } else { + st->print("%5d %5d", e->index(), super_index); + for (int c=0; cprint(" %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; cprint(","); + for (int c=0; cprint("," JULONG_FORMAT, colsum_table[c]);} + } + } else { + st->print(" "); + for (int c=0; cprint(" Total"); + if (sz_sum._total_bytes > 0) { + st->cr(); + st->print(" "); + for (int c=0; cprint(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* p) const { + julong bytes = 0; + if (p != NULL) { + for (int i = 0; i < p->length(); i++) { + bytes += count_bytes_array(p->at(i)); + } + bytes += count_bytes_array(p); + } + return bytes; +} + +void KlassInfoHisto::print_histo_on(outputStream* st, bool print_stats, + bool csv_format, const char *columns) { + if (print_stats) { + print_class_stats(st, csv_format, columns); + } else { + st->print_cr("%s",title()); + print_elements(st); + } } class HistoClosure : public KlassInfoClosure { @@ -236,8 +464,26 @@ CollectedHeap* heap = Universe::heap(); bool is_shared_heap = false; + if (_print_help) { + for (int c=0; cprint("%s:\n\t", name_table[c]); + const int max_col = 60; + int col = 0; + for (const char *p = help_table[c]; *p; p++,col++) { + if (col >= max_col && *p == ' ') { + st->print("\n\t"); + col = 0; + } else { + st->print("%c", *p); + } + } + st->print_cr(".\n"); + } + return; + } + // Collect klass instance info - KlassInfoTable cit(KlassInfoTable::cit_size, ref); + KlassInfoTable cit(KlassInfoTable::cit_size, ref, _print_class_stats); if (!cit.allocation_failed()) { // Iterate over objects in the heap RecordInstanceClosure ric(&cit); @@ -252,14 +498,14 @@ missed_count); } // Sort and print klass instance info - KlassInfoHisto histo("\n" - " num #instances #bytes class name\n" - "----------------------------------------------", - KlassInfoHisto::histo_initial_size); + const char *title = "\n" + " num #instances #bytes class name\n" + "----------------------------------------------"; + KlassInfoHisto histo(&cit, title, KlassInfoHisto::histo_initial_size); HistoClosure hc(&histo); cit.iterate(&hc); histo.sort(); - histo.print_on(st); + histo.print_histo_on(st, _print_class_stats, _csv_format, _columns); } else { st->print_cr("WARNING: Ran out of C-heap; histogram not generated"); } diff -r da53cb17186a -r 412d722168bc src/share/vm/memory/heapInspection.hpp --- a/src/share/vm/memory/heapInspection.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/memory/heapInspection.hpp Fri Feb 08 08:07:06 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,8 @@ #include "memory/allocation.inline.hpp" #include "oops/oop.inline.hpp" +#include "oops/annotations.hpp" +#include "utilities/macros.hpp" #if INCLUDE_SERVICES @@ -44,16 +46,144 @@ // to KlassInfoEntry's and is used to sort // the entries. +#define HEAP_INSPECTION_COLUMNS_DO(f) \ + f(inst_size, InstSize, \ + "Size of each object instance of the Java class") \ + f(inst_count, InstCount, \ + "Number of object instances of the Java class") \ + f(inst_bytes, InstBytes, \ + "This is usually (InstSize * InstNum). The only exception is " \ + "java.lang.Class, whose InstBytes also includes the slots " \ + "used to store static fields. InstBytes is not counted in " \ + "ROAll, RWAll or Total") \ + f(mirror_bytes, Mirror, \ + "Size of the Klass::java_mirror() object") \ + f(klass_bytes, KlassBytes, \ + "Size of the InstanceKlass or ArrayKlass for this class. " \ + "Note that this includes VTab, ITab, OopMap") \ + f(secondary_supers_bytes, K_secondary_supers, \ + "Number of bytes used by the Klass::secondary_supers() array") \ + f(vtab_bytes, VTab, \ + "Size of the embedded vtable in InstanceKlass") \ + f(itab_bytes, ITab, \ + "Size of the embedded itable in InstanceKlass") \ + f(nonstatic_oopmap_bytes, OopMap, \ + "Size of the embedded nonstatic_oop_map in InstanceKlass") \ + f(methods_array_bytes, IK_methods, \ + "Number of bytes used by the InstanceKlass::methods() array") \ + f(method_ordering_bytes, IK_method_ordering, \ + "Number of bytes used by the InstanceKlass::method_ordering() array") \ + f(local_interfaces_bytes, IK_local_interfaces, \ + "Number of bytes used by the InstanceKlass::local_interfaces() array") \ + f(transitive_interfaces_bytes, IK_transitive_interfaces, \ + "Number of bytes used by the InstanceKlass::transitive_interfaces() array") \ + f(fields_bytes, IK_fields, \ + "Number of bytes used by the InstanceKlass::fields() array") \ + f(inner_classes_bytes, IK_inner_classes, \ + "Number of bytes used by the InstanceKlass::inner_classes() array") \ + f(signers_bytes, IK_signers, \ + "Number of bytes used by the InstanceKlass::singers() array") \ + f(class_annotations_bytes, class_annotations, \ + "Size of class annotations") \ + f(fields_annotations_bytes, fields_annotations, \ + "Size of field annotations") \ + f(methods_annotations_bytes, methods_annotations, \ + "Size of method annotations") \ + f(methods_parameter_annotations_bytes, methods_parameter_annotations, \ + "Size of method parameter annotations") \ + f(methods_default_annotations_bytes, methods_default_annotations, \ + "Size of methods default annotations") \ + f(type_annotations_bytes, type_annotations, \ + "Size of type annotations") \ + f(annotations_bytes, annotations, \ + "Size of all annotations") \ + f(cp_bytes, Cp, \ + "Size of InstanceKlass::constants()") \ + f(cp_tags_bytes, CpTags, \ + "Size of InstanceKlass::constants()->tags()") \ + f(cp_cache_bytes, CpCache, \ + "Size of InstanceKlass::constants()->cache()") \ + f(cp_operands_bytes, CpOperands, \ + "Size of InstanceKlass::constants()->operands()") \ + f(cp_refmap_bytes, CpRefMap, \ + "Size of InstanceKlass::constants()->reference_map()") \ + f(cp_all_bytes, CpAll, \ + "Sum of Cp + CpTags + CpCache + CpOperands + CpRefMap") \ + f(method_count, MethodCount, \ + "Number of methods in this class") \ + f(method_bytes, MethodBytes, \ + "Size of the Method object") \ + f(const_method_bytes, ConstMethod, \ + "Size of the ConstMethod object") \ + f(method_data_bytes, MethodData, \ + "Size of the MethodData object") \ + f(stackmap_bytes, StackMap, \ + "Size of the stackmap_data") \ + f(bytecode_bytes, Bytecodes, \ + "Of the MethodBytes column, how much are the space taken up by bytecodes") \ + f(method_all_bytes, MethodAll, \ + "Sum of MethodBytes + Constmethod + Stackmap + Methoddata") \ + f(ro_bytes, ROAll, \ + "Size of all class meta data that could (potentially) be placed " \ + "in read-only memory. (This could change with CDS design)") \ + f(rw_bytes, RWAll, \ + "Size of all class meta data that must be placed in read/write " \ + "memory. (This could change with CDS design) ") \ + f(total_bytes, Total, \ + "ROAll + RWAll. Note that this does NOT include InstBytes.") + +// Size statistics for a Klass - filled in by Klass::collect_statistics() +class KlassSizeStats { +public: +#define COUNT_KLASS_SIZE_STATS_FIELD(field, name, help) _index_ ## field, +#define DECLARE_KLASS_SIZE_STATS_FIELD(field, name, help) julong _ ## field; + + enum { + HEAP_INSPECTION_COLUMNS_DO(COUNT_KLASS_SIZE_STATS_FIELD) + _num_columns + }; + + HEAP_INSPECTION_COLUMNS_DO(DECLARE_KLASS_SIZE_STATS_FIELD) + + static int count(oop x) { + return (HeapWordSize * ((x) ? (x)->size() : 0)); + } + + static int count_array(objArrayOop x) { + return (HeapWordSize * ((x) ? (x)->size() : 0)); + } + + template static int count(T* x) { + return (HeapWordSize * ((x) ? (x)->size() : 0)); + } + + template 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 { private: KlassInfoEntry* _next; Klass* _klass; long _instance_count; size_t _instance_words; + long _index; public: KlassInfoEntry(Klass* k, KlassInfoEntry* next) : - _klass(k), _instance_count(0), _instance_words(0), _next(next) + _klass(k), _instance_count(0), _instance_words(0), _next(next), _index(-1) {} KlassInfoEntry* next() { return _next; } bool is_equal(Klass* k) { return k == _klass; } @@ -62,8 +192,11 @@ void set_count(long ct) { _instance_count = ct; } size_t words() { return _instance_words; } void set_words(size_t wds) { _instance_words = wds; } + void set_index(long index) { _index = index; } + long index() { return _index; } int compare(KlassInfoEntry* e1, KlassInfoEntry* e2); void print_on(outputStream* st) const; + const char* name() const; }; class KlassInfoClosure: public StackObj { @@ -95,45 +228,132 @@ 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* _elements; GrowableArray* 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* 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 static int count_bytes(T* x) { + return (HeapWordSize * ((x) ? (x)->size() : 0)); + } + + template 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* result) NOT_SERVICES_RETURN; }; diff -r da53cb17186a -r 412d722168bc src/share/vm/memory/metaspace.cpp --- a/src/share/vm/memory/metaspace.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/memory/metaspace.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -1737,10 +1737,10 @@ *class_chunk_word_size = ClassSmallChunk; break; } - assert(chunk_word_size != 0 && class_chunk_word_size != 0, + assert(*chunk_word_size != 0 && *class_chunk_word_size != 0, err_msg("Initial chunks sizes bad: data " SIZE_FORMAT " class " SIZE_FORMAT, - chunk_word_size, class_chunk_word_size)); + *chunk_word_size, *class_chunk_word_size)); } size_t SpaceManager::sum_free_in_chunks_in_use() const { @@ -2040,7 +2040,7 @@ align_size_up(humongous_chunks->word_size(), HumongousChunkGranularity), err_msg("Humongous chunk size is wrong: word size " SIZE_FORMAT - " granularity " SIZE_FORMAT, + " granularity %d", humongous_chunks->word_size(), HumongousChunkGranularity)); Metachunk* next_humongous_chunks = humongous_chunks->next(); chunk_manager->humongous_dictionary()->return_chunk(humongous_chunks); @@ -2264,7 +2264,8 @@ } MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); assert(allocation_total() == sum_used_in_chunks_in_use(), - err_msg("allocation total is not consistent %d vs %d", + err_msg("allocation total is not consistent " SIZE_FORMAT + " vs " SIZE_FORMAT, allocation_total(), sum_used_in_chunks_in_use())); } @@ -2578,7 +2579,8 @@ // argument passed in is at the top of the compressed space void Metaspace::initialize_class_space(ReservedSpace rs) { // The reserved space size may be bigger because of alignment, esp with UseLargePages - assert(rs.size() >= ClassMetaspaceSize, err_msg("%d != %d", rs.size(), ClassMetaspaceSize)); + assert(rs.size() >= ClassMetaspaceSize, + err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), ClassMetaspaceSize)); _class_space_list = new VirtualSpaceList(rs); } diff -r da53cb17186a -r 412d722168bc src/share/vm/memory/space.cpp --- a/src/share/vm/memory/space.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/memory/space.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -40,6 +40,7 @@ #include "runtime/safepoint.hpp" #include "utilities/copy.hpp" #include "utilities/globalDefinitions.hpp" +#include "utilities/macros.hpp" void SpaceMemRegionOopsIterClosure::do_oop(oop* p) { SpaceMemRegionOopsIterClosure::do_oop_work(p); } void SpaceMemRegionOopsIterClosure::do_oop(narrowOop* p) { SpaceMemRegionOopsIterClosure::do_oop_work(p); } @@ -658,7 +659,7 @@ } } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #define ContigSpace_PAR_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \ \ void ContiguousSpace::par_oop_iterate(MemRegion mr, OopClosureType* blk) {\ @@ -673,7 +674,7 @@ ALL_PAR_OOP_ITERATE_CLOSURES(ContigSpace_PAR_OOP_ITERATE_DEFN) #undef ContigSpace_PAR_OOP_ITERATE_DEFN -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS void ContiguousSpace::oop_iterate(ExtendedOopClosure* blk) { if (is_empty()) return; diff -r da53cb17186a -r 412d722168bc src/share/vm/memory/space.hpp --- a/src/share/vm/memory/space.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/memory/space.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -34,6 +34,7 @@ #include "oops/markOop.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/prefetch.hpp" +#include "utilities/macros.hpp" #include "utilities/workgroup.hpp" #ifdef TARGET_OS_FAMILY_linux # include "os_linux.inline.hpp" @@ -884,14 +885,14 @@ } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // In support of parallel oop_iterate. #define ContigSpace_PAR_OOP_ITERATE_DECL(OopClosureType, nv_suffix) \ void par_oop_iterate(MemRegion mr, OopClosureType* blk); ALL_PAR_OOP_ITERATE_CLOSURES(ContigSpace_PAR_OOP_ITERATE_DECL) #undef ContigSpace_PAR_OOP_ITERATE_DECL -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS // Compaction support virtual void reset_after_compaction() { diff -r da53cb17186a -r 412d722168bc src/share/vm/memory/specialized_oop_closures.hpp --- a/src/share/vm/memory/specialized_oop_closures.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/memory/specialized_oop_closures.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -26,9 +26,10 @@ #define SHARE_VM_MEMORY_SPECIALIZED_OOP_CLOSURES_HPP #include "runtime/atomic.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/g1/g1_specialized_oop_closures.hpp" -#endif +#endif // INCLUDE_ALL_GCS // The following OopClosure types get specialized versions of // "oop_oop_iterate" that invoke the closures' do_oop methods @@ -80,20 +81,20 @@ f(FastScanClosure,_nv) \ f(FilteringClosure,_nv) -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_P(f) \ f(ParScanWithBarrierClosure,_nv) \ f(ParScanWithoutBarrierClosure,_nv) -#else // SERIALGC +#else // INCLUDE_ALL_GCS #define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_P(f) -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS #define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_1(f) \ f(NoHeaderExtendedOopClosure,_nv) \ SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_S(f) \ SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_P(f) -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(f) \ f(MarkRefsIntoAndScanClosure,_nv) \ f(Par_MarkRefsIntoAndScanClosure,_nv) \ @@ -104,9 +105,9 @@ f(CMSKeepAliveClosure,_nv) \ f(CMSInnerParMarkAndPushClosure,_nv) \ FURTHER_SPECIALIZED_OOP_OOP_ITERATE_CLOSURES(f) -#else // SERIALGC +#else // INCLUDE_ALL_GCS #define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(f) -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS // We separate these out, because sometime the general one has @@ -120,7 +121,7 @@ #define ALL_OOP_OOP_ITERATE_CLOSURES_2(f) \ SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(f) -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // This macro applies an argument macro to all OopClosures for which we // want specialized bodies of a family of methods related to // "par_oop_iterate". The arguments to f are the same as above. @@ -136,7 +137,7 @@ #define ALL_PAR_OOP_ITERATE_CLOSURES(f) \ f(ExtendedOopClosure,_v) \ SPECIALIZED_PAR_OOP_ITERATE_CLOSURES(f) -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS // This macro applies an argument macro to all OopClosures for which we // want specialized bodies of a family of methods related to @@ -155,14 +156,14 @@ f(ScanClosure,_nv) \ f(FastScanClosure,_nv) -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #define SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG_P(f) \ f(ParScanWithBarrierClosure,_nv) \ f(ParScanWithoutBarrierClosure,_nv) \ FURTHER_SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(f) -#else // SERIALGC +#else // INCLUDE_ALL_GCS #define SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG_P(f) -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS #define SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG(f) \ SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG_S(f) \ diff -r da53cb17186a -r 412d722168bc src/share/vm/memory/tenuredGeneration.cpp --- a/src/share/vm/memory/tenuredGeneration.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/memory/tenuredGeneration.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -33,6 +33,7 @@ #include "memory/tenuredGeneration.hpp" #include "oops/oop.inline.hpp" #include "runtime/java.hpp" +#include "utilities/macros.hpp" TenuredGeneration::TenuredGeneration(ReservedSpace rs, size_t initial_byte_size, int level, @@ -61,7 +62,7 @@ _space_counters = new CSpaceCounters(gen_name, 0, _virtual_space.reserved_size(), _the_space, _gen_counters); -#ifndef SERIALGC +#if INCLUDE_ALL_GCS if (UseParNewGC) { typedef ParGCAllocBufferWithBOT* ParGCAllocBufferWithBOTPtr; _alloc_buffers = NEW_C_HEAP_ARRAY(ParGCAllocBufferWithBOTPtr, @@ -77,7 +78,7 @@ } else { _alloc_buffers = NULL; } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS } @@ -339,7 +340,7 @@ } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS oop TenuredGeneration::par_promote(int thread_num, oop old, markOop m, size_t word_sz) { @@ -423,10 +424,10 @@ } } -#else // SERIALGC +#else // INCLUDE_ALL_GCS void TenuredGeneration::retire_alloc_buffers_before_full_gc() {} void TenuredGeneration::verify_alloc_buffers_clean() {} -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS bool TenuredGeneration::promotion_attempt_is_safe(size_t max_promotion_in_bytes) const { size_t available = max_contiguous_available(); diff -r da53cb17186a -r 412d722168bc src/share/vm/memory/tenuredGeneration.hpp --- a/src/share/vm/memory/tenuredGeneration.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/memory/tenuredGeneration.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -29,6 +29,7 @@ #include "gc_implementation/shared/gcStats.hpp" #include "gc_implementation/shared/generationCounters.hpp" #include "memory/generation.hpp" +#include "utilities/macros.hpp" // TenuredGeneration models the heap containing old (promoted/tenured) objects. @@ -45,11 +46,11 @@ size_t _capacity_at_prologue; size_t _used_at_prologue; -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // To support parallel promotion: an array of parallel allocation // buffers, one per thread, initially NULL. ParGCAllocBufferWithBOT** _alloc_buffers; -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS // Retire all alloc buffers before a full GC, so that they will be // re-allocated at the start of the next young GC. @@ -93,14 +94,14 @@ size_t size, bool is_tlab); -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // Overrides. virtual oop par_promote(int thread_num, oop obj, markOop m, size_t word_sz); virtual void par_promote_alloc_undo(int thread_num, HeapWord* obj, size_t word_sz); virtual void par_promote_alloc_done(int thread_num); -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS // Performance Counter support void update_counters(); diff -r da53cb17186a -r 412d722168bc src/share/vm/memory/universe.cpp --- a/src/share/vm/memory/universe.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/memory/universe.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -70,13 +70,14 @@ #include "utilities/events.hpp" #include "utilities/hashtable.inline.hpp" #include "utilities/preserveException.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp" #include "gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.hpp" #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1CollectorPolicy.hpp" #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" -#endif +#endif // INCLUDE_ALL_GCS // Known objects Klass* Universe::_boolArrayKlassObj = NULL; @@ -144,6 +145,7 @@ NarrowPtrStruct Universe::_narrow_klass = { NULL, 0, true }; address Universe::_narrow_ptrs_base; +size_t Universe::_class_metaspace_size; void Universe::basic_type_classes_do(void f(Klass*)) { f(boolArrayKlassObj()); @@ -689,8 +691,15 @@ // Return specified base for the first request. if (!FLAG_IS_DEFAULT(HeapBaseMinAddress) && (mode == UnscaledNarrowOop)) { base = HeapBaseMinAddress; - } else if (total_size <= OopEncodingHeapMax && (mode != HeapBasedNarrowOop)) { - if (total_size <= NarrowOopHeapMax && (mode == UnscaledNarrowOop) && + + // If the total size and the metaspace size are small enough to allow + // UnscaledNarrowOop then just use UnscaledNarrowOop. + } else if ((total_size <= OopEncodingHeapMax) && (mode != HeapBasedNarrowOop) && + (!UseCompressedKlassPointers || + (((OopEncodingHeapMax - heap_size) + Universe::class_metaspace_size()) <= KlassEncodingMetaspaceMax))) { + // We don't need to check the metaspace size here because it is always smaller + // than total_size. + if ((total_size <= NarrowOopHeapMax) && (mode == UnscaledNarrowOop) && (Universe::narrow_oop_shift() == 0)) { // Use 32-bits oops without encoding and // place heap's top on the 4Gb boundary @@ -706,14 +715,24 @@ base = (OopEncodingHeapMax - heap_size); } } + + // See if ZeroBaseNarrowOop encoding will work for a heap based at + // (KlassEncodingMetaspaceMax - class_metaspace_size()). + } else if (UseCompressedKlassPointers && (mode != HeapBasedNarrowOop) && + (Universe::class_metaspace_size() + HeapBaseMinAddress <= KlassEncodingMetaspaceMax) && + (KlassEncodingMetaspaceMax + heap_size - Universe::class_metaspace_size() <= OopEncodingHeapMax)) { + base = (KlassEncodingMetaspaceMax - Universe::class_metaspace_size()); } else { - // Can't reserve below 32Gb. + // UnscaledNarrowOop encoding didn't work, and no base was found for ZeroBasedOops or + // HeapBasedNarrowOop encoding was requested. So, can't reserve below 32Gb. Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes); } + // Set narrow_oop_base and narrow_oop_use_implicit_null_checks // used in ReservedHeapSpace() constructors. // The final values will be set in initialize_heap() below. - if (base != 0 && (base + heap_size) <= OopEncodingHeapMax) { + if ((base != 0) && ((base + heap_size) <= OopEncodingHeapMax) && + (!UseCompressedKlassPointers || (base + Universe::class_metaspace_size()) <= KlassEncodingMetaspaceMax)) { // Use zero based compressed oops Universe::set_narrow_oop_base(NULL); // Don't need guard page for implicit checks in indexed @@ -740,20 +759,20 @@ jint Universe::initialize_heap() { if (UseParallelGC) { -#ifndef SERIALGC +#if INCLUDE_ALL_GCS Universe::_collectedHeap = new ParallelScavengeHeap(); -#else // SERIALGC +#else // INCLUDE_ALL_GCS fatal("UseParallelGC not supported in this VM."); -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS } else if (UseG1GC) { -#ifndef SERIALGC +#if INCLUDE_ALL_GCS G1CollectorPolicy* g1p = new G1CollectorPolicy(); G1CollectedHeap* g1h = new G1CollectedHeap(g1p); Universe::_collectedHeap = g1h; -#else // SERIALGC +#else // INCLUDE_ALL_GCS fatal("UseG1GC not supported in java kernel vm."); -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS } else { GenCollectorPolicy *gc_policy; @@ -761,15 +780,15 @@ if (UseSerialGC) { gc_policy = new MarkSweepPolicy(); } else if (UseConcMarkSweepGC) { -#ifndef SERIALGC +#if INCLUDE_ALL_GCS if (UseAdaptiveSizePolicy) { gc_policy = new ASConcurrentMarkSweepPolicy(); } else { gc_policy = new ConcurrentMarkSweepPolicy(); } -#else // SERIALGC +#else // INCLUDE_ALL_GCS fatal("UseConcMarkSweepGC not supported in this VM."); -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS } else { // default old generation gc_policy = new MarkSweepPolicy(); } @@ -796,7 +815,9 @@ tty->print("heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB", Universe::heap()->base(), Universe::heap()->reserved_region().byte_size()/M); } - if ((uint64_t)Universe::heap()->reserved_region().end() > OopEncodingHeapMax) { + if (((uint64_t)Universe::heap()->reserved_region().end() > OopEncodingHeapMax) || + (UseCompressedKlassPointers && + ((uint64_t)Universe::heap()->base() + Universe::class_metaspace_size() > KlassEncodingMetaspaceMax))) { // Can't reserve heap below 32Gb. // keep the Universe::narrow_oop_base() set in Universe::reserve_heap() Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes); @@ -862,8 +883,8 @@ // be compressed the same as instances. // Need to round class space size up because it's below the heap and // the actual alignment depends on its size. - size_t metaspace_size = align_size_up(ClassMetaspaceSize, alignment); - size_t total_reserved = align_size_up(heap_size + metaspace_size, alignment); + Universe::set_class_metaspace_size(align_size_up(ClassMetaspaceSize, alignment)); + size_t total_reserved = align_size_up(heap_size + Universe::class_metaspace_size(), alignment); char* addr = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop); ReservedHeapSpace total_rs(total_reserved, alignment, UseLargePages, addr); @@ -904,8 +925,8 @@ // compressed oops is greater than the one used for compressed klass // ptrs, a metadata space on top of the heap could become // unreachable. - ReservedSpace class_rs = total_rs.first_part(metaspace_size); - ReservedSpace heap_rs = total_rs.last_part(metaspace_size, alignment); + ReservedSpace class_rs = total_rs.first_part(Universe::class_metaspace_size()); + ReservedSpace heap_rs = total_rs.last_part(Universe::class_metaspace_size(), alignment); Metaspace::initialize_class_space(class_rs); if (UseCompressedOops) { diff -r da53cb17186a -r 412d722168bc src/share/vm/memory/universe.hpp --- a/src/share/vm/memory/universe.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/memory/universe.hpp Fri Feb 08 08:07:06 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(). diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/annotations.cpp --- a/src/share/vm/oops/annotations.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/annotations.cpp Fri Feb 08 08:07:06 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* p) { + julong bytes = 0; + if (p != NULL) { + for (int i = 0; i < p->length(); i++) { + bytes += KlassSizeStats::count_array(p->at(i)); + } + bytes += KlassSizeStats::count_array(p); + } + return bytes; +} + +void Annotations::collect_statistics(KlassSizeStats *sz) const { + sz->_annotations_bytes = sz->count(this); + sz->_class_annotations_bytes = sz->count(class_annotations()); + sz->_fields_annotations_bytes = count_bytes(fields_annotations()); + sz->_methods_annotations_bytes = count_bytes(methods_annotations()); + sz->_methods_parameter_annotations_bytes = + count_bytes(methods_parameter_annotations()); + sz->_methods_default_annotations_bytes = + count_bytes(methods_default_annotations()); + + const Annotations* type_anno = type_annotations(); + if (type_anno != NULL) { + sz->_type_annotations_bytes = sz->count(type_anno); + sz->_type_annotations_bytes += sz->count(type_anno->class_annotations()); + sz->_type_annotations_bytes += count_bytes(type_anno->fields_annotations()); + sz->_type_annotations_bytes += count_bytes(type_anno->methods_annotations()); + } + + sz->_annotations_bytes += + sz->_class_annotations_bytes + + sz->_fields_annotations_bytes + + sz->_methods_annotations_bytes + + sz->_methods_parameter_annotations_bytes + + sz->_methods_default_annotations_bytes + + sz->_type_annotations_bytes; + + sz->_ro_bytes += sz->_annotations_bytes; +} +#endif // INCLUDE_SERVICES + #define BULLET " - " #ifndef PRODUCT diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/annotations.hpp --- a/src/share/vm/oops/annotations.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/annotations.hpp Fri Feb 08 08:07:06 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 AnnotationArray; @@ -82,7 +83,12 @@ Array* 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** md_p, TRAPS); - + static julong count_bytes(Array* p); public: const char* internal_name() const { return "{constant pool}"; } #ifndef PRODUCT diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/arrayKlass.hpp --- a/src/share/vm/oops/arrayKlass.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/arrayKlass.hpp Fri Feb 08 08:07:06 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; } diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/constMethod.cpp --- a/src/share/vm/oops/constMethod.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/constMethod.cpp Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/constMethod.hpp --- a/src/share/vm/oops/constMethod.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/constMethod.hpp Fri Feb 08 08:07:06 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; } diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/constantPool.cpp --- a/src/share/vm/oops/constantPool.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/constantPool.cpp Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/constantPool.hpp --- a/src/share/vm/oops/constantPool.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/constantPool.hpp Fri Feb 08 08:07:06 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* _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* 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* tags() const { return _tags; } Array* 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; } diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/cpCache.cpp --- a/src/share/vm/oops/cpCache.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/cpCache.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -33,9 +33,10 @@ #include "prims/jvmtiRedefineClassesTrace.hpp" #include "prims/methodHandles.hpp" #include "runtime/handles.inline.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS # include "gc_implementation/parallelScavenge/psPromotionManager.hpp" -#endif +#endif // INCLUDE_ALL_GCS // Implememtation of ConstantPoolCacheEntry diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/instanceClassLoaderKlass.cpp --- a/src/share/vm/oops/instanceClassLoaderKlass.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/instanceClassLoaderKlass.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -36,12 +36,13 @@ #include "oops/oop.inline.hpp" #include "oops/symbol.hpp" #include "runtime/handles.inline.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/parNew/parOopClosures.inline.hpp" #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" #include "oops/oop.pcgc.inline.hpp" -#endif +#endif // INCLUDE_ALL_GCS #define if_do_metadata_checked(closure, nv_suffix) \ /* Make sure the non-virtual and the virtual versions match. */ \ @@ -73,7 +74,7 @@ return size; \ } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #define InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \ \ int InstanceClassLoaderKlass:: \ @@ -83,7 +84,7 @@ int size = InstanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure); \ return size; \ } -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS #define InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix) \ @@ -111,10 +112,10 @@ ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN) ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN) -#ifndef SERIALGC +#if INCLUDE_ALL_GCS ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN) ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN) -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN_m) ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN_m) @@ -129,7 +130,7 @@ } } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS void InstanceClassLoaderKlass::oop_follow_contents(ParCompactionManager* cm, oop obj) { InstanceKlass::oop_follow_contents(cm, obj); @@ -155,5 +156,5 @@ } return size_helper(); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/instanceClassLoaderKlass.hpp --- a/src/share/vm/oops/instanceClassLoaderKlass.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/instanceClassLoaderKlass.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -26,6 +26,7 @@ #define SHARE_VM_OOPS_INSTANCECLASSLOADERKLASS_HPP #include "oops/instanceKlass.hpp" +#include "utilities/macros.hpp" // An InstanceClassLoaderKlass is a specialization of the InstanceKlass. It does // not add any field. It is added to walk the dependencies for the class loader @@ -61,13 +62,13 @@ ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DECL) ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DECL) -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #define InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix) \ int oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* blk); ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DECL) ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARDS_DECL) -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS // Garbage collection void oop_follow_contents(oop obj); diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/instanceKlass.cpp --- a/src/share/vm/oops/instanceKlass.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/instanceKlass.cpp Fri Feb 08 08:07:06 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" @@ -55,7 +56,8 @@ #include "runtime/thread.inline.hpp" #include "services/threadService.hpp" #include "utilities/dtrace.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp" #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1OopClosures.inline.hpp" @@ -66,7 +68,7 @@ #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" #include "oops/oop.pcgc.inline.hpp" -#endif +#endif // INCLUDE_ALL_GCS #ifdef COMPILER1 #include "c1/c1_Compiler.hpp" #endif @@ -2042,7 +2044,7 @@ assert_is_in_closed_subset) } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS void InstanceKlass::oop_follow_contents(ParCompactionManager* cm, oop obj) { assert(obj != NULL, "can't follow the content of NULL object"); @@ -2054,7 +2056,7 @@ PSParallelCompact::mark_and_push(cm, p), \ assert_is_in) } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS // closure's do_metadata() method dictates whether the given closure should be // applied to the klass ptr in the object header. @@ -2082,7 +2084,7 @@ return size_helper(); \ } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #define InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \ \ int InstanceKlass::oop_oop_iterate_backwards##nv_suffix(oop obj, \ @@ -2100,7 +2102,7 @@ assert_is_in_closed_subset) \ return size_helper(); \ } -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS #define InstanceKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix) \ \ @@ -2124,10 +2126,10 @@ ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_DEFN) ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_DEFN_m) ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_DEFN_m) -#ifndef SERIALGC +#if INCLUDE_ALL_GCS ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN) ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN) -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS int InstanceKlass::oop_adjust_pointers(oop obj) { int size = size_helper(); @@ -2139,7 +2141,7 @@ return size; } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS void InstanceKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { InstanceKlass_OOP_MAP_REVERSE_ITERATE( \ obj, \ @@ -2159,7 +2161,7 @@ return size; } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS void InstanceKlass::clean_implementors_list(BoolObjectClosure* is_alive) { assert(is_loader_alive(is_alive), "this klass should be live"); @@ -2960,6 +2962,52 @@ 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* methods_array = methods(); + if (methods()) { + for (int i = 0; i < methods_array->length(); i++) { + Method* method = methods_array->at(i); + if (method) { + sz->_method_count ++; + method->collect_statistics(sz); + } + } + } +} +#endif // INCLUDE_SERVICES + // Verification class VerifyFieldClosure: public OopClosure { diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/instanceKlass.hpp --- a/src/share/vm/oops/instanceKlass.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/instanceKlass.hpp Fri Feb 08 08:07:06 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 @@ -36,6 +36,7 @@ #include "runtime/os.hpp" #include "utilities/accessFlags.hpp" #include "utilities/bitMap.inline.hpp" +#include "utilities/macros.hpp" // An InstanceKlass is the VM level representation of a Java class. // It contains all information needed for at class at execution runtime. @@ -256,6 +257,16 @@ // JVMTI fields can be moved to their own structure - see 6315920 unsigned char * _cached_class_file_bytes; // JVMTI: cached class file, before retransformable agent modified it in CFLH jint _cached_class_file_len; // JVMTI: length of above + + volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change + + // Class states are defined as ClassState (see above). + // Place the _init_state here to utilize the unused 2-byte after + // _idnum_allocated_count. + u1 _init_state; // state of class + u1 _reference_type; // reference type + + JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map; // JVMTI: used during heap iteration // Method array. @@ -281,15 +292,6 @@ // ... Array* _fields; - volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change - - // Class states are defined as ClassState (see above). - // Place the _init_state here to utilize the unused 2-byte after - // _idnum_allocated_count. - u1 _init_state; // state of class - - u1 _reference_type; // reference type - // embedded Java vtable follows here // embedded Java itables follows here // embedded static fields follows here @@ -826,6 +828,9 @@ is_interface(), is_anonymous()); } +#if INCLUDE_SERVICES + virtual void collect_statistics(KlassSizeStats *sz) const; +#endif static int vtable_start_offset() { return header_size(); } static int vtable_length_offset() { return offset_of(InstanceKlass, _vtable_len) / HeapWordSize; } @@ -932,13 +937,13 @@ ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_DECL) ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_DECL) -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #define InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix) \ int oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* blk); ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DECL) ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DECL) -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS u2 idnum_allocated_count() const { return _idnum_allocated_count; } private: diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/instanceMirrorKlass.cpp --- a/src/share/vm/oops/instanceMirrorKlass.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/instanceMirrorKlass.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -35,7 +35,8 @@ #include "oops/oop.inline.hpp" #include "oops/symbol.hpp" #include "runtime/handles.inline.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp" #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1OopClosures.inline.hpp" @@ -45,7 +46,7 @@ #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" #include "oops/oop.pcgc.inline.hpp" -#endif +#endif // INCLUDE_ALL_GCS int InstanceMirrorKlass::_offset_of_static_fields = 0; @@ -168,7 +169,7 @@ assert_is_in_closed_subset) } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS void InstanceMirrorKlass::oop_follow_contents(ParCompactionManager* cm, oop obj) { InstanceKlass::oop_follow_contents(cm, obj); @@ -189,7 +190,7 @@ PSParallelCompact::mark_and_push(cm, p), \ assert_is_in) } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS int InstanceMirrorKlass::oop_adjust_pointers(oop obj) { int size = oop_size(obj); @@ -262,7 +263,7 @@ } \ } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #define InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \ \ int InstanceMirrorKlass:: \ @@ -278,7 +279,7 @@ InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(oop, nv_suffix); \ } \ } -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS #define InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix) \ @@ -310,14 +311,14 @@ ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN) ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN) -#ifndef SERIALGC +#if INCLUDE_ALL_GCS ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN) ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN) -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m) ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m) -#ifndef SERIALGC +#if INCLUDE_ALL_GCS void InstanceMirrorKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { // Note that we don't have to follow the mirror -> klass pointer, since all // klasses that are dirty will be scavenged when we iterate over the @@ -353,7 +354,7 @@ assert_nothing) return size; } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS int InstanceMirrorKlass::instance_size(KlassHandle k) { if (k() != NULL && k->oop_is_instance()) { diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/instanceMirrorKlass.hpp --- a/src/share/vm/oops/instanceMirrorKlass.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/instanceMirrorKlass.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -28,6 +28,7 @@ #include "classfile/systemDictionary.hpp" #include "oops/instanceKlass.hpp" #include "runtime/handles.hpp" +#include "utilities/macros.hpp" // An InstanceMirrorKlass is a specialized InstanceKlass for // java.lang.Class instances. These instances are special because @@ -107,13 +108,13 @@ ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DECL) ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DECL) -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #define InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix) \ int oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* blk); ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DECL) ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DECL) -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS }; #endif // SHARE_VM_OOPS_INSTANCEMIRRORKLASS_HPP diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/instanceRefKlass.cpp --- a/src/share/vm/oops/instanceRefKlass.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/instanceRefKlass.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -33,7 +33,8 @@ #include "oops/instanceRefKlass.hpp" #include "oops/oop.inline.hpp" #include "utilities/preserveException.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1OopClosures.inline.hpp" #include "gc_implementation/g1/g1RemSet.inline.hpp" @@ -42,7 +43,7 @@ #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" #include "oops/oop.pcgc.inline.hpp" -#endif +#endif // INCLUDE_ALL_GCS template void specialized_oop_follow_contents(InstanceRefKlass* ref, oop obj) { @@ -120,7 +121,7 @@ } } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS template void specialized_oop_follow_contents(InstanceRefKlass* ref, ParCompactionManager* cm, @@ -194,7 +195,7 @@ specialized_oop_follow_contents(this, cm, obj); } } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS #ifdef ASSERT template void trace_reference_gc(const char *s, oop obj, @@ -317,7 +318,7 @@ } \ } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #define InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \ \ int InstanceRefKlass:: \ @@ -333,7 +334,7 @@ InstanceRefKlass_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, contains); \ } \ } -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS #define InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix) \ @@ -354,14 +355,14 @@ ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_DEFN) ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_DEFN) -#ifndef SERIALGC +#if INCLUDE_ALL_GCS ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN) ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN) -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m) ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m) -#ifndef SERIALGC +#if INCLUDE_ALL_GCS template void specialized_oop_push_contents(InstanceRefKlass *ref, PSPromotionManager* pm, oop obj) { @@ -444,7 +445,7 @@ } return size_helper(); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS void InstanceRefKlass::update_nonstatic_oop_maps(Klass* k) { // Clear the nonstatic oop-map entries corresponding to referent diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/instanceRefKlass.hpp --- a/src/share/vm/oops/instanceRefKlass.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/instanceRefKlass.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -26,6 +26,7 @@ #define SHARE_VM_OOPS_INSTANCEREFKLASS_HPP #include "oops/instanceKlass.hpp" +#include "utilities/macros.hpp" // An InstanceRefKlass is a specialized InstanceKlass for Java // classes that are subclasses of java/lang/ref/Reference. @@ -83,13 +84,13 @@ ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_DECL) ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_DECL) -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #define InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix) \ int oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* blk); ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DECL) ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DECL) -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS static void release_and_notify_pending_list_lock(BasicLock *pending_list_basic_lock); static void acquire_pending_list_lock(BasicLock *pending_list_basic_lock); diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/klass.cpp --- a/src/share/vm/oops/klass.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/klass.cpp Fri Feb 08 08:07:06 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" @@ -37,11 +38,12 @@ #include "oops/oop.inline2.hpp" #include "runtime/atomic.hpp" #include "utilities/stack.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/parallelScavenge/psParallelCompact.hpp" #include "gc_implementation/parallelScavenge/psPromotionManager.hpp" #include "gc_implementation/parallelScavenge/psScavenge.hpp" -#endif +#endif // INCLUDE_ALL_GCS void Klass::set_name(Symbol* n) { _name = n; @@ -624,6 +626,17 @@ obj->print_address_on(st); } +#if INCLUDE_SERVICES +// Size Statistics +void Klass::collect_statistics(KlassSizeStats *sz) const { + sz->_klass_bytes = sz->count(this); + sz->_mirror_bytes = sz->count(java_mirror()); + sz->_secondary_supers_bytes = sz->count_array(secondary_supers()); + + sz->_ro_bytes += sz->_secondary_supers_bytes; + sz->_rw_bytes += sz->_klass_bytes + sz->_mirror_bytes; +} +#endif // INCLUDE_SERVICES // Verification diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/klass.hpp --- a/src/share/vm/oops/klass.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/klass.hpp Fri Feb 08 08:07:06 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 @@ -35,11 +35,12 @@ #include "runtime/orderAccess.hpp" #include "trace/traceMacros.hpp" #include "utilities/accessFlags.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp" #include "gc_implementation/g1/g1OopClosures.hpp" #include "gc_implementation/parNew/parOopClosures.hpp" -#endif +#endif // INCLUDE_ALL_GCS // // A Klass provides: @@ -75,11 +76,11 @@ // [class_loader_data] // [modifier_flags] // [access_flags ] -// [verify_count ] - not in product -// [alloc_count ] // [last_biased_lock_bulk_revocation_time] (64 bits) // [prototype_header] // [biased_lock_revocation_count] +// [verify_count ] - not in product +// [alloc_count ] // [_modified_oops] // [_accumulated_modified_oops] // [trace_id] @@ -91,6 +92,7 @@ class ClassLoaderData; class klassVtable; class ParCompactionManager; +class KlassSizeStats; class Klass : public Metadata { friend class VMStructs; @@ -164,18 +166,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 +479,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 '['. @@ -625,13 +630,13 @@ return oop_oop_iterate(obj, blk); } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // In case we don't have a specialized backward scanner use forward // iteration. virtual int oop_oop_iterate_backwards_v(oop obj, ExtendedOopClosure* blk) { return oop_oop_iterate_v(obj, blk); } -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS // Iterates "blk" over all the oops in "obj" (of type "this") within "mr". // (I don't see why the _m should be required, but without it the Solaris @@ -663,7 +668,7 @@ SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_1(Klass_OOP_OOP_ITERATE_DECL) SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(Klass_OOP_OOP_ITERATE_DECL) -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #define Klass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix) \ virtual int oop_oop_iterate_backwards##nv_suffix(oop obj, \ OopClosureType* blk) { \ @@ -673,7 +678,7 @@ SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_1(Klass_OOP_OOP_ITERATE_BACKWARDS_DECL) SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(Klass_OOP_OOP_ITERATE_BACKWARDS_DECL) -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS virtual void array_klasses_do(void f(Klass* k)) {} virtual void with_array_klasses_do(void f(Klass* k)); diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/klassPS.hpp --- a/src/share/vm/oops/klassPS.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/klassPS.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -27,7 +27,9 @@ // Expands to Parallel Scavenge and Parallel Old declarations -#ifndef SERIALGC +#include "utilities/macros.hpp" + +#if INCLUDE_ALL_GCS #define PARALLEL_GC_DECLS \ virtual void oop_push_contents(PSPromotionManager* pm, oop obj); \ /* Parallel Old GC support \ @@ -44,9 +46,9 @@ virtual void oop_push_contents(PSPromotionManager* pm, oop obj) = 0; \ virtual void oop_follow_contents(ParCompactionManager* cm, oop obj) = 0; \ virtual int oop_update_pointers(ParCompactionManager* cm, oop obj) = 0; -#else // SERIALGC +#else // INCLUDE_ALL_GCS #define PARALLEL_GC_DECLS #define PARALLEL_GC_DECLS_PV -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS #endif // SHARE_VM_OOPS_KLASSPS_HPP diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/method.cpp --- a/src/share/vm/oops/method.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/method.cpp Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/method.hpp --- a/src/share/vm/oops/method.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/method.hpp Fri Feb 08 08:07:06 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(); } diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/methodData.cpp --- a/src/share/vm/oops/methodData.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/methodData.cpp Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/methodData.hpp --- a/src/share/vm/oops/methodData.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/methodData.hpp Fri Feb 08 08:07:06 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"); } } diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/objArrayKlass.cpp --- a/src/share/vm/oops/objArrayKlass.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/objArrayKlass.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -43,7 +43,8 @@ #include "runtime/handles.inline.hpp" #include "runtime/mutexLocker.hpp" #include "utilities/copy.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp" #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1OopClosures.inline.hpp" @@ -54,7 +55,7 @@ #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" #include "oops/oop.pcgc.inline.hpp" -#endif +#endif // INCLUDE_ALL_GCS ObjArrayKlass* ObjArrayKlass::allocate(ClassLoaderData* loader_data, int n, KlassHandle klass_handle, Symbol* name, TRAPS) { assert(ObjArrayKlass::header_size() <= InstanceKlass::header_size(), @@ -461,7 +462,7 @@ } } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS void ObjArrayKlass::oop_follow_contents(ParCompactionManager* cm, oop obj) { assert(obj->is_array(), "obj must be array"); @@ -472,7 +473,7 @@ objarray_follow_contents(cm, obj, 0); } } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS #define if_do_metadata_checked(closure, nv_suffix) \ /* Make sure the non-virtual and the virtual versions match. */ \ @@ -573,7 +574,7 @@ return size; } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS void ObjArrayKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { assert(obj->is_objArray(), "obj must be obj array"); ObjArrayKlass_OOP_ITERATE( \ @@ -591,7 +592,7 @@ ObjArrayKlass_OOP_ITERATE(a, p, PSParallelCompact::adjust_pointer(p)) return size; } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS // JVM support diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/objArrayKlass.hpp --- a/src/share/vm/oops/objArrayKlass.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/objArrayKlass.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -28,6 +28,7 @@ #include "classfile/classLoaderData.hpp" #include "memory/specialized_oop_closures.hpp" #include "oops/arrayKlass.hpp" +#include "utilities/macros.hpp" // ObjArrayKlass is the klass for objArrays @@ -111,11 +112,11 @@ // Parallel Scavenge and Parallel Old PARALLEL_GC_DECLS -#ifndef SERIALGC +#if INCLUDE_ALL_GCS inline void oop_follow_contents(ParCompactionManager* cm, oop obj, int index); template inline void objarray_follow_contents(ParCompactionManager* cm, oop obj, int index); -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS // Iterators int oop_oop_iterate(oop obj, ExtendedOopClosure* blk) { diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/objArrayKlass.inline.hpp --- a/src/share/vm/oops/objArrayKlass.inline.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/objArrayKlass.inline.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -27,10 +27,11 @@ #include "gc_implementation/shared/markSweep.inline.hpp" #include "oops/objArrayKlass.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/parallelScavenge/psCompactionManager.inline.hpp" #include "gc_implementation/parallelScavenge/psParallelCompact.hpp" -#endif +#endif // INCLUDE_ALL_GCS void ObjArrayKlass::oop_follow_contents(oop obj, int index) { if (UseCompressedOops) { @@ -63,7 +64,7 @@ } } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS void ObjArrayKlass::oop_follow_contents(ParCompactionManager* cm, oop obj, int index) { if (UseCompressedOops) { @@ -96,6 +97,6 @@ cm->push_objarray(a, end_index); // Push the continuation. } } -#endif // #ifndef SERIALGC +#endif // INCLUDE_ALL_GCS #endif // SHARE_VM_OOPS_OBJARRAYKLASS_INLINE_HPP diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/oop.hpp --- a/src/share/vm/oops/oop.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/oop.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -29,6 +29,7 @@ #include "memory/memRegion.hpp" #include "memory/specialized_oop_closures.hpp" #include "oops/metadata.hpp" +#include "utilities/macros.hpp" #include "utilities/top.hpp" // oopDesc is the top baseclass for objects classes. The {name}Desc classes describe @@ -298,7 +299,7 @@ // reference field in "this". void follow_contents(void); -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // Parallel Scavenge void push_contents(PSPromotionManager* pm); @@ -306,7 +307,7 @@ void update_contents(ParCompactionManager* cm); void follow_contents(ParCompactionManager* cm); -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS bool is_scavengable() const; @@ -316,13 +317,13 @@ void forward_to(oop p); bool cas_forward_to(oop p, markOop compare); -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // Like "forward_to", but inserts the forwarding pointer atomically. // Exactly one thread succeeds in inserting the forwarding pointer, and // this call returns "NULL" for that thread; any other thread has the // value of the forwarding pointer returned and does not modify "this". oop forward_to_atomic(oop p); -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS oop forwardee() const; @@ -334,10 +335,10 @@ // return the size of this oop. This is used by the MarkSweep collector. int adjust_pointers(); -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // Parallel old void update_header(ParCompactionManager* cm); -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS // mark-sweep support void follow_body(int begin, int end); @@ -354,7 +355,7 @@ ALL_OOP_OOP_ITERATE_CLOSURES_1(OOP_ITERATE_DECL) ALL_OOP_OOP_ITERATE_CLOSURES_2(OOP_ITERATE_DECL) -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #define OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix) \ int oop_iterate_backwards(OopClosureType* blk); diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/oop.inline.hpp --- a/src/share/vm/oops/oop.inline.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/oop.inline.hpp Fri Feb 08 08:07:06 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 @@ -40,6 +40,7 @@ #include "oops/oop.hpp" #include "runtime/atomic.hpp" #include "runtime/os.hpp" +#include "utilities/macros.hpp" #ifdef TARGET_ARCH_x86 # include "bytes_x86.hpp" #endif @@ -227,12 +228,12 @@ // might not be the same as oop. inline narrowOop oopDesc::encode_klass_not_null(Klass* v) { - assert(!is_null(v), "oop value can never be zero"); + assert(!is_null(v), "klass value can never be zero"); assert(check_klass_alignment(v), "Address not aligned"); address base = Universe::narrow_klass_base(); int shift = Universe::narrow_klass_shift(); uint64_t pd = (uint64_t)(pointer_delta((void*)v, (void*)base, 1)); - assert(OopEncodingHeapMax > pd, "change encoding max if new encoding"); + assert(KlassEncodingMetaspaceMax > pd, "change encoding max if new encoding"); uint64_t result = pd >> shift; assert((result & CONST64(0xffffffff00000000)) == 0, "narrow klass pointer overflow"); assert(decode_klass(result) == v, "reversibility"); @@ -760,7 +761,7 @@ ALL_OOP_OOP_ITERATE_CLOSURES_1(OOP_ITERATE_DEFN) ALL_OOP_OOP_ITERATE_CLOSURES_2(OOP_ITERATE_DEFN) -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #define OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \ \ inline int oopDesc::oop_iterate_backwards(OopClosureType* blk) { \ @@ -770,6 +771,6 @@ ALL_OOP_OOP_ITERATE_CLOSURES_1(OOP_ITERATE_BACKWARDS_DEFN) ALL_OOP_OOP_ITERATE_CLOSURES_2(OOP_ITERATE_BACKWARDS_DEFN) -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS #endif // SHARE_VM_OOPS_OOP_INLINE_HPP diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/oop.pcgc.inline.hpp --- a/src/share/vm/oops/oop.pcgc.inline.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/oop.pcgc.inline.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -25,14 +25,15 @@ #ifndef SHARE_VM_OOPS_OOP_PCGC_INLINE_HPP #define SHARE_VM_OOPS_OOP_PCGC_INLINE_HPP -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/parNew/parNewGeneration.hpp" #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" #include "gc_implementation/parallelScavenge/psCompactionManager.hpp" #include "gc_implementation/parallelScavenge/psParallelCompact.hpp" #include "gc_implementation/parallelScavenge/psScavenge.hpp" #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" -#endif +#endif // INCLUDE_ALL_GCS inline void oopDesc::update_contents(ParCompactionManager* cm) { // The klass field must be updated before anything else diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/oop.psgc.inline.hpp --- a/src/share/vm/oops/oop.psgc.inline.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/oop.psgc.inline.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -25,11 +25,12 @@ #ifndef SHARE_VM_OOPS_OOP_PSGC_INLINE_HPP #define SHARE_VM_OOPS_OOP_PSGC_INLINE_HPP -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" #include "gc_implementation/parallelScavenge/psScavenge.hpp" #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" -#endif +#endif // INCLUDE_ALL_GCS // ParallelScavengeHeap methods diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/symbol.cpp --- a/src/share/vm/oops/symbol.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/symbol.cpp Fri Feb 08 08:07:06 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()); } diff -r da53cb17186a -r 412d722168bc src/share/vm/oops/typeArrayKlass.cpp --- a/src/share/vm/oops/typeArrayKlass.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/oops/typeArrayKlass.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -39,6 +39,7 @@ #include "oops/typeArrayKlass.hpp" #include "oops/typeArrayOop.hpp" #include "runtime/handles.inline.hpp" +#include "utilities/macros.hpp" bool TypeArrayKlass::compute_is_subtype_of(Klass* k) { if (!k->oop_is_typeArray()) { @@ -208,13 +209,13 @@ // know that Universe::TypeArrayKlass never moves. } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS void TypeArrayKlass::oop_follow_contents(ParCompactionManager* cm, oop obj) { assert(obj->is_typeArray(),"must be a type array"); // Performance tweak: We skip iterating over the klass pointer since we // know that Universe::TypeArrayKlass never moves. } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS int TypeArrayKlass::oop_adjust_pointers(oop obj) { assert(obj->is_typeArray(),"must be a type array"); @@ -240,7 +241,7 @@ return t->object_size(); } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS void TypeArrayKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { ShouldNotReachHere(); assert(obj->is_typeArray(),"must be a type array"); @@ -251,7 +252,7 @@ assert(obj->is_typeArray(),"must be a type array"); return typeArrayOop(obj)->object_size(); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS void TypeArrayKlass::initialize(TRAPS) { // Nothing to do. Having this function is handy since objArrayKlasses can be diff -r da53cb17186a -r 412d722168bc src/share/vm/opto/bytecodeInfo.cpp --- a/src/share/vm/opto/bytecodeInfo.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/opto/bytecodeInfo.cpp Fri Feb 08 08:07:06 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; } diff -r da53cb17186a -r 412d722168bc src/share/vm/opto/callGenerator.cpp --- a/src/share/vm/opto/callGenerator.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/opto/callGenerator.cpp Fri Feb 08 08:07:06 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; } diff -r da53cb17186a -r 412d722168bc src/share/vm/opto/generateOptoStub.cpp --- a/src/share/vm/opto/generateOptoStub.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/opto/generateOptoStub.cpp Fri Feb 08 08:07:06 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); diff -r da53cb17186a -r 412d722168bc src/share/vm/opto/parse.hpp --- a/src/share/vm/opto/parse.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/opto/parse.hpp Fri Feb 08 08:07:06 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; diff -r da53cb17186a -r 412d722168bc src/share/vm/opto/parse3.cpp --- a/src/share/vm/opto/parse3.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/opto/parse3.cpp Fri Feb 08 08:07:06 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; diff -r da53cb17186a -r 412d722168bc src/share/vm/precompiled/precompiled.hpp --- a/src/share/vm/precompiled/precompiled.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/precompiled/precompiled.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -24,6 +24,7 @@ // Precompiled headers are turned off for Sun Studion, // or if the user passes USE_PRECOMPILED_HEADER=0 to the makefiles. + #ifndef DONT_USE_PRECOMPILED_HEADER # include "asm/assembler.hpp" @@ -285,7 +286,7 @@ # include "c1/c1_ValueType.hpp" # include "c1/c1_globals.hpp" #endif // COMPILER1 -#ifndef SERIALGC +#if INCLUDE_ALL_GCS # include "gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp" # include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp" # include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp" @@ -314,6 +315,6 @@ # include "gc_implementation/shared/gcAdaptivePolicyCounters.hpp" # include "gc_implementation/shared/gcPolicyCounters.hpp" # include "gc_implementation/shared/parGCAllocBuffer.hpp" -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS #endif // !DONT_USE_PRECOMPILED_HEADER diff -r da53cb17186a -r 412d722168bc src/share/vm/prims/jni.cpp --- a/src/share/vm/prims/jni.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/prims/jni.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -32,9 +32,10 @@ #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "interpreter/linkResolver.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS #include "memory/allocation.hpp" #include "memory/allocation.inline.hpp" #include "memory/gcLocker.inline.hpp" @@ -2641,7 +2642,7 @@ o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false); } jobject ret = JNIHandles::make_local(env, o->obj_field(offset)); -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // If G1 is enabled and we are accessing the value of the referent // field in a reference object then we need to register a non-null // referent with the SATB barrier. @@ -2660,7 +2661,7 @@ G1SATBCardTableModRefBS::enqueue(referent); } } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS #ifndef USDT2 DTRACE_PROBE1(hotspot_jni, GetObjectField__return, ret); #else /* USDT2 */ diff -r da53cb17186a -r 412d722168bc src/share/vm/prims/jniCheck.hpp --- a/src/share/vm/prims/jniCheck.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/prims/jniCheck.hpp Fri Feb 08 08:07:06 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. diff -r da53cb17186a -r 412d722168bc src/share/vm/prims/jvm.cpp --- a/src/share/vm/prims/jvm.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/prims/jvm.cpp Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc src/share/vm/prims/jvm.h --- a/src/share/vm/prims/jvm.h Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/prims/jvm.h Fri Feb 08 08:07:06 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. * diff -r da53cb17186a -r 412d722168bc src/share/vm/prims/jvmtiCodeBlobEvents.hpp --- a/src/share/vm/prims/jvmtiCodeBlobEvents.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/prims/jvmtiCodeBlobEvents.hpp Fri Feb 08 08:07:06 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; diff -r da53cb17186a -r 412d722168bc src/share/vm/prims/jvmtiEnv.cpp --- a/src/share/vm/prims/jvmtiEnv.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/prims/jvmtiEnv.cpp Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc src/share/vm/prims/jvmtiEnvBase.cpp --- a/src/share/vm/prims/jvmtiEnvBase.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/prims/jvmtiEnvBase.cpp Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc src/share/vm/prims/jvmtiEnvBase.hpp --- a/src/share/vm/prims/jvmtiEnvBase.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/prims/jvmtiEnvBase.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -35,6 +35,7 @@ #include "runtime/thread.hpp" #include "runtime/vm_operations.hpp" #include "utilities/growableArray.hpp" +#include "utilities/macros.hpp" // // Forward Declarations diff -r da53cb17186a -r 412d722168bc src/share/vm/prims/jvmtiExport.cpp --- a/src/share/vm/prims/jvmtiExport.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/prims/jvmtiExport.cpp Fri Feb 08 08:07:06 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 @@ -50,9 +50,10 @@ #include "runtime/vframe.hpp" #include "services/attachListener.hpp" #include "services/serviceUtil.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/parallelScavenge/psMarkSweep.hpp" -#endif +#endif // INCLUDE_ALL_GCS #ifdef JVMTI_TRACE #define EVT_TRACE(evt,out) if ((JvmtiTrace::event_trace_flags(evt) & JvmtiTrace::SHOW_EVENT_SENT) != 0) { SafeResourceMark rm; tty->print_cr out; } @@ -677,7 +678,6 @@ } -#ifndef JVMTI_KERNEL static inline Klass* oop_to_klass(oop obj) { Klass* k = obj->klass(); @@ -2178,7 +2178,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 +2258,6 @@ } return result; } -#endif // SERVICES_KERNEL //////////////////////////////////////////////////////////////////////////////////////////////// @@ -2457,4 +2455,3 @@ JvmtiExport::post_garbage_collection_finish(); } } -#endif // JVMTI_KERNEL diff -r da53cb17186a -r 412d722168bc src/share/vm/prims/jvmtiExport.hpp --- a/src/share/vm/prims/jvmtiExport.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/prims/jvmtiExport.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -34,6 +34,7 @@ #include "runtime/handles.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/growableArray.hpp" +#include "utilities/macros.hpp" // Must be included after jvmti.h. #include "code/jvmticmlr.h" diff -r da53cb17186a -r 412d722168bc src/share/vm/prims/jvmtiExtensions.hpp --- a/src/share/vm/prims/jvmtiExtensions.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/prims/jvmtiExtensions.hpp Fri Feb 08 08:07:06 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 // diff -r da53cb17186a -r 412d722168bc src/share/vm/prims/jvmtiImpl.cpp --- a/src/share/vm/prims/jvmtiImpl.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/prims/jvmtiImpl.cpp Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc src/share/vm/prims/jvmtiImpl.hpp --- a/src/share/vm/prims/jvmtiImpl.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/prims/jvmtiImpl.hpp Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc src/share/vm/prims/jvmtiRawMonitor.hpp --- a/src/share/vm/prims/jvmtiRawMonitor.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/prims/jvmtiRawMonitor.hpp Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc src/share/vm/prims/jvmtiRedefineClasses.cpp --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Feb 08 08:07:06 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* _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(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 diff -r da53cb17186a -r 412d722168bc src/share/vm/prims/jvmtiRedefineClasses.hpp --- a/src/share/vm/prims/jvmtiRedefineClasses.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/prims/jvmtiRedefineClasses.hpp Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc src/share/vm/prims/jvmtiTagMap.cpp --- a/src/share/vm/prims/jvmtiTagMap.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/prims/jvmtiTagMap.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -45,9 +45,10 @@ #include "runtime/vmThread.hpp" #include "runtime/vm_operations.hpp" #include "services/serviceUtil.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" -#endif +#endif // INCLUDE_ALL_GCS // JvmtiTagHashmapEntry // diff -r da53cb17186a -r 412d722168bc src/share/vm/prims/jvmtiTagMap.hpp --- a/src/share/vm/prims/jvmtiTagMap.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/prims/jvmtiTagMap.hpp Fri Feb 08 08:07:06 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; diff -r da53cb17186a -r 412d722168bc src/share/vm/prims/nativeLookup.cpp --- a/src/share/vm/prims/nativeLookup.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/prims/nativeLookup.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -40,6 +40,7 @@ #include "runtime/javaCalls.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/signature.hpp" +#include "utilities/macros.hpp" #ifdef TARGET_OS_FAMILY_linux # include "os_linux.inline.hpp" #endif diff -r da53cb17186a -r 412d722168bc src/share/vm/prims/unsafe.cpp --- a/src/share/vm/prims/unsafe.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/prims/unsafe.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -24,9 +24,10 @@ #include "precompiled.hpp" #include "classfile/vmSymbols.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS #include "memory/allocation.inline.hpp" #include "prims/jni.h" #include "prims/jvm.h" @@ -189,7 +190,7 @@ if (obj == NULL) THROW_0(vmSymbols::java_lang_NullPointerException()); GET_OOP_FIELD(obj, offset, v) jobject ret = JNIHandles::make_local(env, v); -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // We could be accessing the referent field in a reference // object. If G1 is enabled then we need to register a non-null // referent with the SATB barrier. @@ -212,7 +213,7 @@ G1SATBCardTableModRefBS::enqueue(referent); } } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS return ret; UNSAFE_END @@ -247,7 +248,7 @@ UnsafeWrapper("Unsafe_GetObject"); GET_OOP_FIELD(obj, offset, v) jobject ret = JNIHandles::make_local(env, v); -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // We could be accessing the referent field in a reference // object. If G1 is enabled then we need to register non-null // referent with the SATB barrier. @@ -270,7 +271,7 @@ G1SATBCardTableModRefBS::enqueue(referent); } } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS return ret; UNSAFE_END diff -r da53cb17186a -r 412d722168bc src/share/vm/prims/whitebox.cpp --- a/src/share/vm/prims/whitebox.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/prims/whitebox.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -36,12 +36,17 @@ #include "runtime/interfaceSupport.hpp" #include "runtime/os.hpp" #include "utilities/debug.hpp" +#include "utilities/macros.hpp" -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #include "gc_implementation/g1/concurrentMark.hpp" #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/heapRegionRemSet.hpp" -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS + +#ifdef INCLUDE_NMT +#include "services/memTracker.hpp" +#endif // INCLUDE_NMT bool WhiteBox::_used = false; @@ -85,7 +90,7 @@ return closure.found(); WB_END -#ifndef SERIALGC +#if INCLUDE_ALL_GCS WB_ENTRY(jboolean, WB_G1IsHumongous(JNIEnv* env, jobject o, jobject obj)) G1CollectedHeap* g1 = G1CollectedHeap::heap(); oop result = JNIHandles::resolve(obj); @@ -108,7 +113,61 @@ WB_ENTRY(jint, WB_G1RegionSize(JNIEnv* env, jobject o)) return (jint)HeapRegion::GrainBytes; WB_END -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS + +#ifdef INCLUDE_NMT +// Keep track of the 3 allocations in NMTAllocTest so we can free them later +// on and verify that they're not visible anymore +static void* nmtMtTest1 = NULL, *nmtMtTest2 = NULL, *nmtMtTest3 = NULL; + +// Alloc memory using the test memory type so that we can use that to see if +// NMT picks it up correctly +WB_ENTRY(jboolean, WB_NMTAllocTest(JNIEnv* env)) + void *mem; + + if (!MemTracker::is_on() || MemTracker::shutdown_in_progress()) { + return false; + } + + // Allocate 2 * 128k + 256k + 1024k and free the 1024k one to make sure we track + // everything correctly. Total should be 512k held alive. + nmtMtTest1 = os::malloc(128 * 1024, mtTest); + mem = os::malloc(1024 * 1024, mtTest); + nmtMtTest2 = os::malloc(256 * 1024, mtTest); + os::free(mem, mtTest); + nmtMtTest3 = os::malloc(128 * 1024, mtTest); + + return true; +WB_END + +// Free the memory allocated by NMTAllocTest +WB_ENTRY(jboolean, WB_NMTFreeTestMemory(JNIEnv* env)) + + if (nmtMtTest1 == NULL || nmtMtTest2 == NULL || nmtMtTest3 == NULL) { + return false; + } + + os::free(nmtMtTest1, mtTest); + nmtMtTest1 = NULL; + os::free(nmtMtTest2, mtTest); + nmtMtTest2 = NULL; + os::free(nmtMtTest3, mtTest); + nmtMtTest3 = NULL; + + return true; +WB_END + +// Block until the current generation of NMT data to be merged, used to reliably test the NMT feature +WB_ENTRY(jboolean, WB_NMTWaitForDataMerge(JNIEnv* env)) + + if (!MemTracker::is_on() || MemTracker::shutdown_in_progress()) { + return false; + } + + return MemTracker::wbtest_wait_for_data_merge(); +WB_END + +#endif // INCLUDE_NMT //Some convenience methods to deal with objects from java int WhiteBox::offset_for_field(const char* field_name, oop object, @@ -171,12 +230,17 @@ CC "(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;", (void*) &WB_ParseCommandLine }, -#ifndef SERIALGC +#if INCLUDE_ALL_GCS {CC"g1InConcurrentMark", CC"()Z", (void*)&WB_G1InConcurrentMark}, {CC"g1IsHumongous", CC"(Ljava/lang/Object;)Z", (void*)&WB_G1IsHumongous }, {CC"g1NumFreeRegions", CC"()J", (void*)&WB_G1NumFreeRegions }, {CC"g1RegionSize", CC"()I", (void*)&WB_G1RegionSize }, -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS +#ifdef INCLUDE_NMT + {CC"NMTAllocTest", CC"()Z", (void*)&WB_NMTAllocTest }, + {CC"NMTFreeTestMemory", CC"()Z", (void*)&WB_NMTFreeTestMemory }, + {CC"NMTWaitForDataMerge",CC"()Z", (void*)&WB_NMTWaitForDataMerge}, +#endif // INCLUDE_NMT }; #undef CC diff -r da53cb17186a -r 412d722168bc src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/runtime/arguments.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -38,6 +38,7 @@ #include "services/management.hpp" #include "services/memTracker.hpp" #include "utilities/defaultStream.hpp" +#include "utilities/macros.hpp" #include "utilities/taskqueue.hpp" #ifdef TARGET_OS_FAMILY_linux # include "os_linux.inline.hpp" @@ -51,9 +52,9 @@ #ifdef TARGET_OS_FAMILY_bsd # include "os_bsd.inline.hpp" #endif -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp" -#endif +#endif // INCLUDE_ALL_GCS // Note: This is a special bug reporting site for the JVM #define DEFAULT_VENDOR_URL_BUG "http://bugreport.sun.com/bugreport/crash.jsp" @@ -827,7 +828,8 @@ return true; } - const char * const argname = *arg == '+' || *arg == '-' ? arg + 1 : arg; + bool has_plus_minus = (*arg == '+' || *arg == '-'); + const char* const argname = has_plus_minus ? arg + 1 : arg; if (is_newly_obsolete(arg, &since)) { char version[256]; since.to_string(version, sizeof(version)); @@ -838,13 +840,29 @@ // For locked flags, report a custom error message if available. // Otherwise, report the standard unrecognized VM option. - Flag* locked_flag = Flag::find_flag((char*)argname, strlen(argname), true); - if (locked_flag != NULL) { + size_t arg_len; + const char* equal_sign = strchr(argname, '='); + if (equal_sign == NULL) { + arg_len = strlen(argname); + } else { + arg_len = equal_sign - argname; + } + + Flag* found_flag = Flag::find_flag((char*)argname, arg_len, true); + if (found_flag != NULL) { char locked_message_buf[BUFLEN]; - locked_flag->get_locked_message(locked_message_buf, BUFLEN); + found_flag->get_locked_message(locked_message_buf, BUFLEN); if (strlen(locked_message_buf) == 0) { - jio_fprintf(defaultStream::error_stream(), - "Unrecognized VM option '%s'\n", argname); + if (found_flag->is_bool() && !has_plus_minus) { + jio_fprintf(defaultStream::error_stream(), + "Missing +/- setting for VM option '%s'\n", argname); + } else if (!found_flag->is_bool() && has_plus_minus) { + jio_fprintf(defaultStream::error_stream(), + "Unexpected +/- setting in VM option '%s'\n", argname); + } else { + jio_fprintf(defaultStream::error_stream(), + "Improperly specified VM option '%s'\n", argname); + } } else { jio_fprintf(defaultStream::error_stream(), "%s", locked_message_buf); } @@ -1072,7 +1090,7 @@ } } -#if INCLUDE_ALTERNATE_GCS +#if INCLUDE_ALL_GCS static void disable_adaptive_size_policy(const char* collector_name) { if (UseAdaptiveSizePolicy) { if (FLAG_IS_CMDLINE(UseAdaptiveSizePolicy)) { @@ -1284,7 +1302,7 @@ tty->print_cr("ConcGCThreads: %u", ConcGCThreads); } } -#endif // INCLUDE_ALTERNATE_GCS +#endif // INCLUDE_ALL_GCS void set_object_alignment() { // Object alignment. @@ -1301,10 +1319,10 @@ // Oop encoding heap max OopEncodingHeapMax = (uint64_t(max_juint) + 1) << LogMinObjAlignmentInBytes; -#if INCLUDE_ALTERNATE_GCS +#if INCLUDE_ALL_GCS // Set CMS global values CompactibleFreeListSpace::set_cms_values(); -#endif // INCLUDE_ALTERNATE_GCS +#endif // INCLUDE_ALL_GCS } bool verify_object_alignment() { @@ -1429,13 +1447,18 @@ } // Set the ClassMetaspaceSize to something that will not need to be // expanded, since it cannot be expanded. - if (UseCompressedKlassPointers && FLAG_IS_DEFAULT(ClassMetaspaceSize)) { - // 100,000 classes seems like a good size, so 100M assumes around 1K - // per klass. The vtable and oopMap is embedded so we don't have a fixed - // size per klass. Eventually, this will be parameterized because it - // would also be useful to determine the optimal size of the - // systemDictionary. - FLAG_SET_ERGO(uintx, ClassMetaspaceSize, 100*M); + if (UseCompressedKlassPointers) { + if (ClassMetaspaceSize > KlassEncodingMetaspaceMax) { + warning("Class metaspace size is too large for UseCompressedKlassPointers"); + FLAG_SET_DEFAULT(UseCompressedKlassPointers, false); + } else if (FLAG_IS_DEFAULT(ClassMetaspaceSize)) { + // 100,000 classes seems like a good size, so 100M assumes around 1K + // per klass. The vtable and oopMap is embedded so we don't have a fixed + // size per klass. Eventually, this will be parameterized because it + // would also be useful to determine the optimal size of the + // systemDictionary. + FLAG_SET_ERGO(uintx, ClassMetaspaceSize, 100*M); + } } } // Also checks that certain machines are slower with compressed oops @@ -1976,7 +1999,7 @@ status = status && verify_min_value(ParGCArrayScanChunk, 1, "ParGCArrayScanChunk"); -#ifndef SERIALGC +#if INCLUDE_ALL_GCS if (UseG1GC) { status = status && verify_percentage(InitiatingHeapOccupancyPercent, "InitiatingHeapOccupancyPercent"); @@ -1985,7 +2008,7 @@ status = status && verify_min_value((intx)G1ConcMarkStepDurationMillis, 1, "G1ConcMarkStepDurationMillis"); } -#endif +#endif // INCLUDE_ALL_GCS status = status && verify_interval(RefDiscoveryPolicy, ReferenceProcessor::DiscoveryPolicyMin, @@ -2472,10 +2495,7 @@ // -Xshare:dump } else if (match_option(option, "-Xshare:dump", &tail)) { -#if defined(KERNEL) - vm_exit_during_initialization( - "Dumping a shared archive is not supported on the Kernel JVM.", NULL); -#elif !INCLUDE_CDS +#if !INCLUDE_CDS vm_exit_during_initialization( "Dumping a shared archive is not supported in this VM.", NULL); #else @@ -3157,7 +3177,7 @@ UNSUPPORTED_OPTION(UseLargePages, "-XX:+UseLargePages"); #endif -#if !INCLUDE_ALTERNATE_GCS +#if !INCLUDE_ALL_GCS if (UseParallelGC) { warning("Parallel GC is not supported in this VM. Using Serial GC."); } @@ -3170,7 +3190,7 @@ if (UseParNewGC) { warning("Par New GC is not supported in this VM. Using Serial GC."); } -#endif // INCLUDE_ALTERNATE_GCS +#endif // INCLUDE_ALL_GCS #ifndef PRODUCT if (TraceBytecodesAt != 0) { @@ -3217,9 +3237,9 @@ // Set object alignment values. set_object_alignment(); -#ifdef SERIALGC +#if !INCLUDE_ALL_GCS force_serial_gc(); -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS #if !INCLUDE_CDS no_shared_spaces(); #endif // INCLUDE_CDS @@ -3247,7 +3267,7 @@ // Set heap size based on available physical memory set_heap_size(); -#if INCLUDE_ALTERNATE_GCS +#if INCLUDE_ALL_GCS // Set per-collector flags if (UseParallelGC || UseParallelOldGC) { set_parallel_gc_flags(); @@ -3259,11 +3279,9 @@ set_g1_gc_flags(); } check_deprecated_gcs(); -#endif // INCLUDE_ALTERNATE_GCS - -#ifdef SERIALGC +#else // INCLUDE_ALL_GCS assert(verify_serial_gc_flags(), "SerialGC unset"); -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS // Set bytecode rewriting flags set_bytecode_flags(); @@ -3357,7 +3375,7 @@ } jint Arguments::adjust_after_os() { -#if INCLUDE_ALTERNATE_GCS +#if INCLUDE_ALL_GCS if (UseParallelGC || UseParallelOldGC) { if (UseNUMA) { if (FLAG_IS_DEFAULT(MinHeapDeltaBytes)) { @@ -3368,7 +3386,7 @@ UseNUMAInterleaving = true; } } -#endif +#endif // INCLUDE_ALL_GCS return JNI_OK; } @@ -3463,36 +3481,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. diff -r da53cb17186a -r 412d722168bc src/share/vm/runtime/arguments.hpp --- a/src/share/vm/runtime/arguments.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/runtime/arguments.hpp Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc src/share/vm/runtime/deoptimization.cpp --- a/src/share/vm/runtime/deoptimization.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/runtime/deoptimization.cpp Fri Feb 08 08:07:06 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(). } } diff -r da53cb17186a -r 412d722168bc src/share/vm/runtime/fprofiler.hpp --- a/src/share/vm/runtime/fprofiler.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/runtime/fprofiler.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -25,6 +25,7 @@ #ifndef SHARE_VM_RUNTIME_FPROFILER_HPP #define SHARE_VM_RUNTIME_FPROFILER_HPP +#include "utilities/macros.hpp" #include "runtime/timer.hpp" // a simple flat profiler for Java diff -r da53cb17186a -r 412d722168bc src/share/vm/runtime/globals.cpp --- a/src/share/vm/runtime/globals.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/runtime/globals.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -29,10 +29,11 @@ #include "runtime/globals.hpp" #include "runtime/globals_extension.hpp" #include "utilities/ostream.hpp" +#include "utilities/macros.hpp" #include "utilities/top.hpp" -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #include "gc_implementation/g1/g1_globals.hpp" -#endif +#endif // INCLUDE_ALL_GCS #ifdef COMPILER1 #include "c1/c1_globals.hpp" #endif @@ -256,9 +257,9 @@ static Flag flagTable[] = { RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_EXPERIMENTAL_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT, RUNTIME_MANAGEABLE_FLAG_STRUCT, RUNTIME_PRODUCT_RW_FLAG_STRUCT, RUNTIME_LP64_PRODUCT_FLAG_STRUCT) RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT) -#ifndef SERIALGC +#if INCLUDE_ALL_GCS G1_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_EXPERIMENTAL_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT, RUNTIME_MANAGEABLE_FLAG_STRUCT, RUNTIME_PRODUCT_RW_FLAG_STRUCT) -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS #ifdef COMPILER1 C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, C1_PD_DEVELOP_FLAG_STRUCT, C1_PRODUCT_FLAG_STRUCT, C1_PD_PRODUCT_FLAG_STRUCT, C1_NOTPRODUCT_FLAG_STRUCT) #endif diff -r da53cb17186a -r 412d722168bc src/share/vm/runtime/globals_extension.hpp --- a/src/share/vm/runtime/globals_extension.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/runtime/globals_extension.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -26,6 +26,7 @@ #define SHARE_VM_RUNTIME_GLOBALS_EXTENSION_HPP #include "runtime/globals.hpp" +#include "utilities/macros.hpp" #include "utilities/top.hpp" // Construct enum of Flag_ constants. @@ -94,9 +95,9 @@ typedef enum { RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, RUNTIME_PD_DEVELOP_FLAG_MEMBER, RUNTIME_PRODUCT_FLAG_MEMBER, RUNTIME_PD_PRODUCT_FLAG_MEMBER, RUNTIME_DIAGNOSTIC_FLAG_MEMBER, RUNTIME_EXPERIMENTAL_FLAG_MEMBER, RUNTIME_NOTPRODUCT_FLAG_MEMBER, RUNTIME_MANAGEABLE_FLAG_MEMBER, RUNTIME_PRODUCT_RW_FLAG_MEMBER, RUNTIME_LP64_PRODUCT_FLAG_MEMBER) RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, RUNTIME_PD_DEVELOP_FLAG_MEMBER, RUNTIME_PRODUCT_FLAG_MEMBER, RUNTIME_PD_PRODUCT_FLAG_MEMBER, RUNTIME_DIAGNOSTIC_FLAG_MEMBER, RUNTIME_NOTPRODUCT_FLAG_MEMBER) -#if INCLUDE_ALTERNATE_GCS +#if INCLUDE_ALL_GCS G1_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, RUNTIME_PD_DEVELOP_FLAG_MEMBER, RUNTIME_PRODUCT_FLAG_MEMBER, RUNTIME_PD_PRODUCT_FLAG_MEMBER, RUNTIME_DIAGNOSTIC_FLAG_MEMBER, RUNTIME_EXPERIMENTAL_FLAG_MEMBER, RUNTIME_NOTPRODUCT_FLAG_MEMBER, RUNTIME_MANAGEABLE_FLAG_MEMBER, RUNTIME_PRODUCT_RW_FLAG_MEMBER) -#endif // INCLUDE_ALTERNATE_GCS +#endif // INCLUDE_ALL_GCS #ifdef COMPILER1 C1_FLAGS(C1_DEVELOP_FLAG_MEMBER, C1_PD_DEVELOP_FLAG_MEMBER, C1_PRODUCT_FLAG_MEMBER, C1_PD_PRODUCT_FLAG_MEMBER, C1_NOTPRODUCT_FLAG_MEMBER) #endif @@ -187,7 +188,7 @@ RUNTIME_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE, RUNTIME_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE, RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE) -#if INCLUDE_ALTERNATE_GCS +#if INCLUDE_ALL_GCS G1_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE, RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE, RUNTIME_PRODUCT_FLAG_MEMBER_WITH_TYPE, @@ -197,7 +198,7 @@ RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE, RUNTIME_MANAGEABLE_FLAG_MEMBER_WITH_TYPE, RUNTIME_PRODUCT_RW_FLAG_MEMBER_WITH_TYPE) -#endif // INCLUDE_ALTERNATE_GCS +#endif // INCLUDE_ALL_GCS #ifdef COMPILER1 C1_FLAGS(C1_DEVELOP_FLAG_MEMBER_WITH_TYPE, C1_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE, diff -r da53cb17186a -r 412d722168bc src/share/vm/runtime/init.cpp --- a/src/share/vm/runtime/init.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/runtime/init.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -34,6 +34,7 @@ #include "runtime/init.hpp" #include "runtime/safepoint.hpp" #include "runtime/sharedRuntime.hpp" +#include "utilities/macros.hpp" // Initialization done by VM thread in vm_init_globals() void check_ThreadShadow(); diff -r da53cb17186a -r 412d722168bc src/share/vm/runtime/java.cpp --- a/src/share/vm/runtime/java.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/runtime/java.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -64,6 +64,7 @@ #include "utilities/dtrace.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/histogram.hpp" +#include "utilities/macros.hpp" #include "utilities/vmError.hpp" #ifdef TARGET_ARCH_x86 # include "vm_version_x86.hpp" @@ -80,11 +81,11 @@ #ifdef TARGET_ARCH_ppc # include "vm_version_ppc.hpp" #endif -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp" #include "gc_implementation/parallelScavenge/psScavenge.hpp" #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" -#endif +#endif // INCLUDE_ALL_GCS #ifdef COMPILER1 #include "c1/c1_Compiler.hpp" #include "c1/c1_Runtime1.hpp" diff -r da53cb17186a -r 412d722168bc src/share/vm/runtime/os.cpp --- a/src/share/vm/runtime/os.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/runtime/os.cpp Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc src/share/vm/runtime/safepoint.cpp --- a/src/share/vm/runtime/safepoint.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/runtime/safepoint.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -52,6 +52,7 @@ #include "services/memTracker.hpp" #include "services/runtimeService.hpp" #include "utilities/events.hpp" +#include "utilities/macros.hpp" #ifdef TARGET_ARCH_x86 # include "nativeInst_x86.hpp" # include "vmreg_x86.inline.hpp" @@ -72,10 +73,10 @@ # include "nativeInst_ppc.hpp" # include "vmreg_ppc.inline.hpp" #endif -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp" #include "gc_implementation/shared/concurrentGCThread.hpp" -#endif +#endif // INCLUDE_ALL_GCS #ifdef COMPILER1 #include "c1/c1_globals.hpp" #endif @@ -103,7 +104,7 @@ _ts_of_current_safepoint = tty->time_stamp().seconds(); } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS if (UseConcMarkSweepGC) { // In the future we should investigate whether CMS can use the // more-general mechanism below. DLD (01/05). @@ -111,7 +112,7 @@ } else if (UseG1GC) { ConcurrentGCThread::safepoint_synchronize(); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS // By getting the Threads_lock, we assure that no threads are about to start or // exit. It is released again in SafepointSynchronize::end(). @@ -480,14 +481,14 @@ Threads_lock->unlock(); } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // If there are any concurrent GC threads resume them. if (UseConcMarkSweepGC) { ConcurrentMarkSweepThread::desynchronize(false); } else if (UseG1GC) { ConcurrentGCThread::safepoint_desynchronize(); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS // record this time so VMThread can keep track how much time has elasped // since last safepoint. _end_of_last_safepoint = os::javaTimeMillis(); diff -r da53cb17186a -r 412d722168bc src/share/vm/runtime/sharedRuntime.cpp --- a/src/share/vm/runtime/sharedRuntime.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/runtime/sharedRuntime.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -56,6 +56,7 @@ #include "utilities/dtrace.hpp" #include "utilities/events.hpp" #include "utilities/hashtable.inline.hpp" +#include "utilities/macros.hpp" #include "utilities/xmlstream.hpp" #ifdef TARGET_ARCH_x86 # include "nativeInst_x86.hpp" @@ -212,7 +213,7 @@ } #endif // PRODUCT -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // G1 write-barrier pre: executed before a pointer store. JRT_LEAF(void, SharedRuntime::g1_wb_pre(oopDesc* orig, JavaThread *thread)) @@ -230,7 +231,7 @@ thread->dirty_card_queue().enqueue(card_addr); JRT_END -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS JRT_LEAF(jlong, SharedRuntime::lmul(jlong y, jlong x)) @@ -2816,10 +2817,6 @@ JRT_LEAF(intptr_t*, SharedRuntime::OSR_migration_begin( JavaThread *thread) ) -#ifdef IA64 - ShouldNotReachHere(); // NYI -#endif /* IA64 */ - // // This code is dependent on the memory layout of the interpreter local // array and the monitors. On all of our platforms the layout is identical diff -r da53cb17186a -r 412d722168bc src/share/vm/runtime/sharedRuntime.hpp --- a/src/share/vm/runtime/sharedRuntime.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/runtime/sharedRuntime.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -32,6 +32,7 @@ #include "memory/resourceArea.hpp" #include "runtime/threadLocalStorage.hpp" #include "utilities/hashtable.hpp" +#include "utilities/macros.hpp" class AdapterHandlerEntry; class AdapterHandlerTable; @@ -168,11 +169,11 @@ static address raw_exception_handler_for_return_address(JavaThread* thread, address return_address); static address exception_handler_for_return_address(JavaThread* thread, address return_address); -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // G1 write barriers static void g1_wb_pre(oopDesc* orig, JavaThread *thread); static void g1_wb_post(void* card_addr, JavaThread* thread); -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS // exception handling and implicit exceptions static address compute_compiled_exc_handler(nmethod* nm, address ret_pc, Handle& exception, diff -r da53cb17186a -r 412d722168bc src/share/vm/runtime/synchronizer.cpp --- a/src/share/vm/runtime/synchronizer.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/runtime/synchronizer.cpp Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc src/share/vm/runtime/thread.cpp --- a/src/share/vm/runtime/thread.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/runtime/thread.cpp Fri Feb 08 08:07:06 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 @@ -82,6 +82,7 @@ #include "utilities/dtrace.hpp" #include "utilities/events.hpp" #include "utilities/preserveException.hpp" +#include "utilities/macros.hpp" #ifdef TARGET_OS_FAMILY_linux # include "os_linux.inline.hpp" #endif @@ -94,11 +95,11 @@ #ifdef TARGET_OS_FAMILY_bsd # include "os_bsd.inline.hpp" #endif -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp" #include "gc_implementation/g1/concurrentMarkThread.inline.hpp" #include "gc_implementation/parallelScavenge/pcTasks.hpp" -#endif +#endif // INCLUDE_ALL_GCS #ifdef COMPILER1 #include "c1/c1_Compiler.hpp" #endif @@ -1482,17 +1483,17 @@ pd_initialize(); } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS SATBMarkQueueSet JavaThread::_satb_mark_queue_set; DirtyCardQueueSet JavaThread::_dirty_card_queue_set; -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS JavaThread::JavaThread(bool is_attaching_via_jni) : Thread() -#ifndef SERIALGC +#if INCLUDE_ALL_GCS , _satb_mark_queue(&_satb_mark_queue_set), _dirty_card_queue(&_dirty_card_queue_set) -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS { initialize(); if (is_attaching_via_jni) { @@ -1500,7 +1501,7 @@ } else { _jni_attach_state = _not_attaching_via_jni; } - assert(_deferred_card_mark.is_empty(), "Default MemRegion ctor"); + assert(deferred_card_mark().is_empty(), "Default MemRegion ctor"); _safepoint_visible = false; } @@ -1547,10 +1548,10 @@ JavaThread::JavaThread(ThreadFunction entry_point, size_t stack_sz) : Thread() -#ifndef SERIALGC +#if INCLUDE_ALL_GCS , _satb_mark_queue(&_satb_mark_queue_set), _dirty_card_queue(&_dirty_card_queue_set) -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS { if (TraceThreadEvents) { tty->print_cr("creating thread %p", this); @@ -1896,19 +1897,26 @@ JvmtiExport::cleanup_thread(this); } -#ifndef SERIALGC - // We must flush G1-related buffers before removing a thread from + // We must flush any deferred card marks before removing a thread from // the list of active threads. + Universe::heap()->flush_deferred_store_barrier(this); + assert(deferred_card_mark().is_empty(), "Should have been flushed"); + +#if INCLUDE_ALL_GCS + // We must flush the G1-related buffers before removing a thread + // from the list of active threads. We must do this after any deferred + // card marks have been flushed (above) so that any entries that are + // added to the thread's dirty card queue as a result are not lost. if (UseG1GC) { flush_barrier_queues(); } -#endif +#endif // INCLUDE_ALL_GCS // Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread Threads::remove(this); } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // Flush G1-related queues. void JavaThread::flush_barrier_queues() { satb_mark_queue().flush(); @@ -1936,7 +1944,7 @@ // active field set to true. assert(dirty_queue.is_active(), "dirty card queue should be active"); } -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS void JavaThread::cleanup_failed_attach_current_thread() { if (get_thread_profiler() != NULL) { @@ -1964,11 +1972,11 @@ tlab().make_parsable(true); // retire TLAB, if any } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS if (UseG1GC) { flush_barrier_queues(); } -#endif +#endif // INCLUDE_ALL_GCS Threads::remove(this); delete this; @@ -3600,7 +3608,7 @@ vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION)); } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // Support for ConcurrentMarkSweep. This should be cleaned up // and better encapsulated. The ugly nested if test would go away // once things are properly refactored. XXX YSR @@ -3614,7 +3622,7 @@ vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION)); } } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS // Always call even when there are not JVMTI environments yet, since environments // may be attached late and JVMTI must track phases of VM execution @@ -3739,28 +3747,6 @@ name)) { library = os::dll_load(buffer, ebuf, sizeof ebuf); } -#ifdef KERNEL - // Download instrument dll - if (library == NULL && strcmp(name, "instrument") == 0) { - char *props = Arguments::get_kernel_properties(); - char *home = Arguments::get_java_home(); - const char *fmt = "%s/bin/java %s -Dkernel.background.download=false" - " sun.jkernel.DownloadManager -download client_jvm"; - size_t length = strlen(props) + strlen(home) + strlen(fmt) + 1; - char *cmd = NEW_C_HEAP_ARRAY(char, length, mtThread); - jio_snprintf(cmd, length, fmt, home, props); - int status = os::fork_and_exec(cmd); - FreeHeap(props); - if (status == -1) { - warning(cmd); - vm_exit_during_initialization("fork_and_exec failed: %s", - strerror(errno)); - } - FREE_C_HEAP_ARRAY(char, cmd, mtThread); - // when this comes back the instrument.dll should be where it belongs. - library = os::dll_load(buffer, ebuf, sizeof ebuf); - } -#endif // KERNEL if (library == NULL) { // Try the local directory char ns[1] = {0}; if (os::dll_build_name(buffer, sizeof(buffer), ns, name)) { @@ -4209,7 +4195,7 @@ } } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // Used by ParallelScavenge void Threads::create_thread_roots_tasks(GCTaskQueue* q) { ALL_JAVA_THREADS(p) { @@ -4225,7 +4211,7 @@ } q->enqueue(new ThreadRootsMarkingTask(VMThread::vm_thread())); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS void Threads::nmethods_do(CodeBlobClosure* cf) { ALL_JAVA_THREADS(p) { @@ -4333,13 +4319,13 @@ ); st->cr(); -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // Dump concurrent locks ConcurrentLocksDump concurrent_locks; if (print_concurrent_locks) { concurrent_locks.dump_at_safepoint(); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS ALL_JAVA_THREADS(p) { ResourceMark rm; @@ -4352,11 +4338,11 @@ } } st->cr(); -#ifndef SERIALGC +#if INCLUDE_ALL_GCS if (print_concurrent_locks) { concurrent_locks.print_locks_on(p, st); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS } VMThread::vm_thread()->print_on(st); diff -r da53cb17186a -r 412d722168bc src/share/vm/runtime/thread.hpp --- a/src/share/vm/runtime/thread.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/runtime/thread.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -41,6 +41,7 @@ #include "runtime/stubRoutines.hpp" #include "runtime/threadLocalStorage.hpp" #include "runtime/unhandledOops.hpp" +#include "utilities/macros.hpp" #if INCLUDE_NMT #include "services/memRecorder.hpp" @@ -49,10 +50,10 @@ #include "trace/tracing.hpp" #include "utilities/exceptions.hpp" #include "utilities/top.hpp" -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #include "gc_implementation/g1/dirtyCardQueue.hpp" #include "gc_implementation/g1/satbQueue.hpp" -#endif +#endif // INCLUDE_ALL_GCS #ifdef ZERO #ifdef TARGET_ARCH_zero # include "stack_zero.hpp" @@ -929,7 +930,7 @@ } _jmp_ring[ jump_ring_buffer_size ]; #endif /* PRODUCT */ -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // Support for G1 barriers ObjPtrQueue _satb_mark_queue; // Thread-local log for SATB barrier. @@ -941,7 +942,7 @@ static DirtyCardQueueSet _dirty_card_queue_set; void flush_barrier_queues(); -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS friend class VMThread; friend class ThreadWaitTransition; @@ -1345,10 +1346,10 @@ return byte_offset_of(JavaThread, _should_post_on_exceptions_flag); } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS static ByteSize satb_mark_queue_offset() { return byte_offset_of(JavaThread, _satb_mark_queue); } static ByteSize dirty_card_queue_offset() { return byte_offset_of(JavaThread, _dirty_card_queue); } -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS // Returns the jni environment for this thread JNIEnv* jni_environment() { return &_jni_environment; } @@ -1637,7 +1638,7 @@ _stack_size_at_create = value; } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // SATB marking queue support ObjPtrQueue& satb_mark_queue() { return _satb_mark_queue; } static SATBMarkQueueSet& satb_mark_queue_set() { @@ -1649,7 +1650,7 @@ static DirtyCardQueueSet& dirty_card_queue_set() { return _dirty_card_queue_set; } -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS // This method initializes the SATB and dirty card queues before a // JavaThread is added to the Java thread list. Right now, we don't @@ -1668,11 +1669,11 @@ // might happen between the JavaThread constructor being called and the // thread being added to the Java thread list (an example of this is // when the structure for the DestroyJavaVM thread is created). -#ifndef SERIALGC +#if INCLUDE_ALL_GCS void initialize_queues(); -#else // !SERIALGC +#else // INCLUDE_ALL_GCS void initialize_queues() { } -#endif // !SERIALGC +#endif // INCLUDE_ALL_GCS // Machine dependent stuff #ifdef TARGET_OS_ARCH_linux_x86 diff -r da53cb17186a -r 412d722168bc src/share/vm/runtime/vframeArray.cpp --- a/src/share/vm/runtime/vframeArray.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/runtime/vframeArray.cpp Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc src/share/vm/runtime/vmStructs.cpp --- a/src/share/vm/runtime/vmStructs.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/runtime/vmStructs.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -101,6 +101,7 @@ #include "utilities/array.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/hashtable.hpp" +#include "utilities/macros.hpp" #ifdef TARGET_ARCH_x86 # include "vmStructs_x86.hpp" #endif @@ -146,7 +147,7 @@ #ifdef TARGET_OS_ARCH_bsd_zero # include "vmStructs_bsd_zero.hpp" #endif -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp" #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp" #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp" @@ -161,7 +162,7 @@ #include "gc_implementation/parallelScavenge/psYoungGen.hpp" #include "gc_implementation/parallelScavenge/vmStructs_parallelgc.hpp" #include "gc_implementation/g1/vmStructs_g1.hpp" -#endif +#endif // INCLUDE_ALL_GCS #ifdef COMPILER2 #include "opto/addnode.hpp" #include "opto/block.hpp" @@ -1161,6 +1162,7 @@ static_field(Abstract_VM_Version, _vm_major_version, int) \ static_field(Abstract_VM_Version, _vm_minor_version, int) \ static_field(Abstract_VM_Version, _vm_build_number, int) \ + static_field(Abstract_VM_Version, _reserve_for_allocation_prefetch, int) \ \ static_field(JDK_Version, _current, JDK_Version) \ nonstatic_field(JDK_Version, _partially_initialized, bool) \ @@ -2087,8 +2089,7 @@ declare_toplevel_type(FreeBlockDictionary*) \ declare_toplevel_type(FreeList*) \ declare_toplevel_type(FreeList) \ - declare_toplevel_type(MetablockTreeDictionary*) \ - declare_type(MetablockTreeDictionary, FreeBlockDictionary) + declare_type(MetablockTreeDictionary, FreeBlockDictionary) //-------------------------------------------------------------------------------- @@ -2786,7 +2787,7 @@ GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY, GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY) -#ifndef SERIALGC +#if INCLUDE_ALL_GCS VM_STRUCTS_PARALLELGC(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, GENERATE_STATIC_VM_STRUCT_ENTRY) @@ -2796,7 +2797,7 @@ VM_STRUCTS_G1(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, GENERATE_STATIC_VM_STRUCT_ENTRY) -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS VM_STRUCTS_CPU(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, GENERATE_STATIC_VM_STRUCT_ENTRY, @@ -2830,7 +2831,7 @@ GENERATE_C2_VM_TYPE_ENTRY, GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY) -#ifndef SERIALGC +#if INCLUDE_ALL_GCS VM_TYPES_PARALLELGC(GENERATE_VM_TYPE_ENTRY, GENERATE_TOPLEVEL_VM_TYPE_ENTRY) @@ -2841,7 +2842,7 @@ VM_TYPES_G1(GENERATE_VM_TYPE_ENTRY, GENERATE_TOPLEVEL_VM_TYPE_ENTRY) -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS VM_TYPES_CPU(GENERATE_VM_TYPE_ENTRY, GENERATE_TOPLEVEL_VM_TYPE_ENTRY, @@ -2872,11 +2873,11 @@ GENERATE_C2_VM_INT_CONSTANT_ENTRY, GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY) -#ifndef SERIALGC +#if INCLUDE_ALL_GCS VM_INT_CONSTANTS_CMS(GENERATE_VM_INT_CONSTANT_ENTRY) VM_INT_CONSTANTS_PARNEW(GENERATE_VM_INT_CONSTANT_ENTRY) -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS VM_INT_CONSTANTS_CPU(GENERATE_VM_INT_CONSTANT_ENTRY, GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY, @@ -2930,7 +2931,7 @@ CHECK_NO_OP, CHECK_NO_OP); -#ifndef SERIALGC +#if INCLUDE_ALL_GCS VM_STRUCTS_PARALLELGC(CHECK_NONSTATIC_VM_STRUCT_ENTRY, CHECK_STATIC_VM_STRUCT_ENTRY); @@ -2940,7 +2941,7 @@ VM_STRUCTS_G1(CHECK_NONSTATIC_VM_STRUCT_ENTRY, CHECK_STATIC_VM_STRUCT_ENTRY); -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS VM_STRUCTS_CPU(CHECK_NONSTATIC_VM_STRUCT_ENTRY, CHECK_STATIC_VM_STRUCT_ENTRY, @@ -2969,7 +2970,7 @@ CHECK_C2_VM_TYPE_ENTRY, CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY); -#ifndef SERIALGC +#if INCLUDE_ALL_GCS VM_TYPES_PARALLELGC(CHECK_VM_TYPE_ENTRY, CHECK_SINGLE_ARG_VM_TYPE_NO_OP); @@ -2980,7 +2981,7 @@ VM_TYPES_G1(CHECK_VM_TYPE_ENTRY, CHECK_SINGLE_ARG_VM_TYPE_NO_OP); -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS VM_TYPES_CPU(CHECK_VM_TYPE_ENTRY, CHECK_SINGLE_ARG_VM_TYPE_NO_OP, @@ -3035,7 +3036,7 @@ ENSURE_C2_FIELD_TYPE_PRESENT, CHECK_NO_OP, CHECK_NO_OP)); -#ifndef SERIALGC +#if INCLUDE_ALL_GCS debug_only(VM_STRUCTS_PARALLELGC(ENSURE_FIELD_TYPE_PRESENT, ENSURE_FIELD_TYPE_PRESENT)); debug_only(VM_STRUCTS_CMS(ENSURE_FIELD_TYPE_PRESENT, @@ -3043,7 +3044,7 @@ ENSURE_FIELD_TYPE_PRESENT)); debug_only(VM_STRUCTS_G1(ENSURE_FIELD_TYPE_PRESENT, ENSURE_FIELD_TYPE_PRESENT)); -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS debug_only(VM_STRUCTS_CPU(ENSURE_FIELD_TYPE_PRESENT, ENSURE_FIELD_TYPE_PRESENT, CHECK_NO_OP, diff -r da53cb17186a -r 412d722168bc src/share/vm/runtime/vmStructs.hpp --- a/src/share/vm/runtime/vmStructs.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/runtime/vmStructs.hpp Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc src/share/vm/runtime/vm_version.cpp --- a/src/share/vm/runtime/vm_version.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/runtime/vm_version.cpp Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc src/share/vm/services/attachListener.cpp --- a/src/share/vm/services/attachListener.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/services/attachListener.cpp Fri Feb 08 08:07:06 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 }, diff -r da53cb17186a -r 412d722168bc src/share/vm/services/attachListener.hpp --- a/src/share/vm/services/attachListener.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/services/attachListener.hpp Fri Feb 08 08:07:06 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 @@ -28,6 +28,7 @@ #include "memory/allocation.hpp" #include "utilities/debug.hpp" #include "utilities/ostream.hpp" +#include "utilities/macros.hpp" // The AttachListener thread services a queue of operations that are enqueued // by client tools. Each operation is identified by a name and has up to 3 @@ -38,8 +39,6 @@ // complets the result value and any result data is returned to the client // tool. -#ifndef SERVICES_KERNEL - class AttachOperation; typedef jint (*AttachOperationFunction)(AttachOperation* op, outputStream* out); @@ -48,7 +47,6 @@ const char* name; AttachOperationFunction func; }; -#endif // SERVICES_KERNEL class AttachListener: AllStatic { public: diff -r da53cb17186a -r 412d722168bc src/share/vm/services/classLoadingService.cpp --- a/src/share/vm/services/classLoadingService.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/services/classLoadingService.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -31,6 +31,7 @@ #include "services/classLoadingService.hpp" #include "services/memoryService.hpp" #include "utilities/dtrace.hpp" +#include "utilities/macros.hpp" #ifdef DTRACE_ENABLED diff -r da53cb17186a -r 412d722168bc src/share/vm/services/classLoadingService.hpp --- a/src/share/vm/services/classLoadingService.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/services/classLoadingService.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -28,6 +28,7 @@ #include "runtime/handles.hpp" #include "runtime/perfData.hpp" #include "utilities/growableArray.hpp" +#include "utilities/macros.hpp" class InstanceKlass; diff -r da53cb17186a -r 412d722168bc src/share/vm/services/diagnosticCommand.cpp --- a/src/share/vm/services/diagnosticCommand.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/services/diagnosticCommand.cpp Fri Feb 08 08:07:06 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 @@ -30,6 +30,7 @@ #include "services/diagnosticFramework.hpp" #include "services/heapDumper.hpp" #include "services/management.hpp" +#include "utilities/macros.hpp" void DCmdRegistrant::register_dcmds(){ // Registration of the diagnostic commands @@ -43,12 +44,12 @@ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); -#if INCLUDE_SERVICES // Heap dumping supported +#if INCLUDE_SERVICES // Heap dumping/inspection supported DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); #endif // INCLUDE_SERVICES - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); - //Enhanced JMX Agent Support DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true,false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true,false)); @@ -252,7 +253,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 +293,6 @@ return 0; } } -#endif // INCLUDE_SERVICES ClassHistogramDCmd::ClassHistogramDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap), @@ -319,6 +319,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 +465,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 +506,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 +526,6 @@ } } - void JMXStartRemoteDCmd::execute(TRAPS) { ResourceMark rm(THREAD); HandleMark hm(THREAD); @@ -466,7 +555,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 +574,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 diff -r da53cb17186a -r 412d722168bc src/share/vm/services/diagnosticCommand.hpp --- a/src/share/vm/services/diagnosticCommand.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/services/diagnosticCommand.hpp Fri Feb 08 08:07:06 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 @@ -35,6 +35,7 @@ #include "services/diagnosticCommand.hpp" #include "services/diagnosticFramework.hpp" #include "services/diagnosticCommand_ext.hpp" +#include "utilities/macros.hpp" class HelpDCmd : public DCmdWithParser { protected: @@ -178,7 +179,7 @@ }; #endif // INCLUDE_SERVICES -// See also: inspeactheap in attachListener.cpp +// See also: inspectheap in attachListener.cpp class ClassHistogramDCmd : public DCmdWithParser { protected: DCmdArgument _all; @@ -197,6 +198,27 @@ virtual void execute(TRAPS); }; +class ClassStatsDCmd : public DCmdWithParser { +protected: + DCmdArgument _all; + DCmdArgument _csv; + DCmdArgument _help; + DCmdArgument _columns; +public: + ClassStatsDCmd(outputStream* output, bool heap); + static const char* name() { + return "GC.class_stats"; + } + static const char* description() { + return "Provide statistics about Java class meta data. Requires -XX:+UnlockDiagnosticVMOptions."; + } + static const char* impact() { + return "High: Depends on Java heap size and content."; + } + static int num_arguments(); + virtual void execute(TRAPS); +}; + // See also: thread_dump in attachListener.cpp class ThreadDumpDCmd : public DCmdWithParser { protected: @@ -236,6 +258,16 @@ DCmdArgument _jmxremote_ssl_need_client_auth; DCmdArgument _jmxremote_ssl_config_file; + // JDP support + // Keep autodiscovery char* not bool to pass true/false + // as property value to java level. + DCmdArgument _jmxremote_autodiscovery; + DCmdArgument _jdp_port; + DCmdArgument _jdp_address; + DCmdArgument _jdp_source_addr; + DCmdArgument _jdp_ttl; + DCmdArgument _jdp_pause; + public: JMXStartRemoteDCmd(outputStream *output, bool heap_allocated); diff -r da53cb17186a -r 412d722168bc src/share/vm/services/g1MemoryPool.hpp --- a/src/share/vm/services/g1MemoryPool.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/services/g1MemoryPool.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -25,11 +25,12 @@ #ifndef SHARE_VM_SERVICES_G1MEMORYPOOL_HPP #define SHARE_VM_SERVICES_G1MEMORYPOOL_HPP -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/g1/g1MonitoringSupport.hpp" #include "services/memoryPool.hpp" #include "services/memoryUsage.hpp" -#endif +#endif // INCLUDE_ALL_GCS // This file contains the three classes that represent the memory // pools of the G1 spaces: G1EdenPool, G1SurvivorPool, and diff -r da53cb17186a -r 412d722168bc src/share/vm/services/heapDumper.cpp --- a/src/share/vm/services/heapDumper.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/services/heapDumper.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -40,9 +40,10 @@ #include "services/heapDumper.hpp" #include "services/threadService.hpp" #include "utilities/ostream.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" -#endif +#endif // INCLUDE_ALL_GCS /* * HPROF binary format - description copied from: diff -r da53cb17186a -r 412d722168bc src/share/vm/services/management.cpp --- a/src/share/vm/services/management.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/services/management.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -53,6 +53,7 @@ #include "services/memoryService.hpp" #include "services/runtimeService.hpp" #include "services/threadService.hpp" +#include "utilities/macros.hpp" PerfVariable* Management::_begin_vm_creation_time = NULL; PerfVariable* Management::_end_vm_creation_time = NULL; diff -r da53cb17186a -r 412d722168bc src/share/vm/services/memBaseline.cpp --- a/src/share/vm/services/memBaseline.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/services/memBaseline.cpp Fri Feb 08 08:07:06 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 }; diff -r da53cb17186a -r 412d722168bc src/share/vm/services/memPtr.cpp --- a/src/share/vm/services/memPtr.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/services/memPtr.cpp Fri Feb 08 08:07:06 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); diff -r da53cb17186a -r 412d722168bc src/share/vm/services/memPtr.hpp --- a/src/share/vm/services/memPtr.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/services/memPtr.hpp Fri Feb 08 08:07:06 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; ) }; /* diff -r da53cb17186a -r 412d722168bc src/share/vm/services/memRecorder.cpp --- a/src/share/vm/services/memRecorder.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/services/memRecorder.cpp Fri Feb 08 08:07:06 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)FixedSizeMemPointerArrayget_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 diff -r da53cb17186a -r 412d722168bc src/share/vm/services/memTrackWorker.hpp --- a/src/share/vm/services/memTrackWorker.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/services/memTrackWorker.hpp Fri Feb 08 08:07:06 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)); } diff -r da53cb17186a -r 412d722168bc src/share/vm/services/memTracker.cpp --- a/src/share/vm/services/memTracker.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/services/memTracker.cpp Fri Feb 08 08:07:06 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); diff -r da53cb17186a -r 412d722168bc src/share/vm/services/memTracker.hpp --- a/src/share/vm/services/memTracker.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/services/memTracker.hpp Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc src/share/vm/services/memoryPool.cpp --- a/src/share/vm/services/memoryPool.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/services/memoryPool.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -32,6 +32,7 @@ #include "services/management.hpp" #include "services/memoryManager.hpp" #include "services/memoryPool.hpp" +#include "utilities/macros.hpp" MemoryPool::MemoryPool(const char* name, PoolType type, @@ -208,7 +209,7 @@ return MemoryUsage(initial_size(), used, committed, maxSize); } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS CompactibleFreeListSpacePool::CompactibleFreeListSpacePool(CompactibleFreeListSpace* space, const char* name, PoolType type, @@ -225,7 +226,7 @@ return MemoryUsage(initial_size(), used, committed, maxSize); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS GenerationPool::GenerationPool(Generation* gen, const char* name, diff -r da53cb17186a -r 412d722168bc src/share/vm/services/memoryPool.hpp --- a/src/share/vm/services/memoryPool.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/services/memoryPool.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -30,9 +30,10 @@ #include "memory/heap.hpp" #include "memory/space.hpp" #include "services/memoryUsage.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp" -#endif +#endif // INCLUDE_ALL_GCS // A memory pool represents the memory area that the VM manages. // The Java virtual machine has at least one memory pool @@ -185,7 +186,7 @@ } }; -#ifndef SERIALGC +#if INCLUDE_ALL_GCS class CompactibleFreeListSpacePool : public CollectedMemoryPool { private: CompactibleFreeListSpace* _space; @@ -199,7 +200,7 @@ MemoryUsage get_memory_usage(); size_t used_in_bytes() { return _space->used(); } }; -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS class GenerationPool : public CollectedMemoryPool { diff -r da53cb17186a -r 412d722168bc src/share/vm/services/memoryService.cpp --- a/src/share/vm/services/memoryService.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/services/memoryService.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -43,7 +43,8 @@ #include "services/memoryPool.hpp" #include "services/memoryService.hpp" #include "utilities/growableArray.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp" #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/parNew/parNewGeneration.hpp" @@ -52,7 +53,7 @@ #include "gc_implementation/parallelScavenge/psYoungGen.hpp" #include "services/g1MemoryPool.hpp" #include "services/psMemoryPool.hpp" -#endif +#endif // INCLUDE_ALL_GCS GrowableArray* MemoryService::_pools_list = new (ResourceObj::C_HEAP, mtInternal) GrowableArray(init_pools_list_size, true); @@ -83,7 +84,7 @@ add_gen_collected_heap_info(GenCollectedHeap::heap()); break; } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS case CollectedHeap::ParallelScavengeHeap : { add_parallel_scavenge_heap_info(ParallelScavengeHeap::heap()); break; @@ -92,7 +93,7 @@ add_g1_heap_info(G1CollectedHeap::heap()); break; } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS default: { guarantee(false, "Unrecognized kind of heap"); } @@ -130,22 +131,22 @@ case Generation::DefNew: _minor_gc_manager = MemoryManager::get_copy_memory_manager(); break; -#ifndef SERIALGC +#if INCLUDE_ALL_GCS case Generation::ParNew: case Generation::ASParNew: _minor_gc_manager = MemoryManager::get_parnew_memory_manager(); break; -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS default: guarantee(false, "Unrecognized generation spec"); break; } if (policy->is_mark_sweep_policy()) { _major_gc_manager = MemoryManager::get_msc_memory_manager(); -#ifndef SERIALGC +#if INCLUDE_ALL_GCS } else if (policy->is_concurrent_mark_sweep_policy()) { _major_gc_manager = MemoryManager::get_cms_memory_manager(); -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS } else { guarantee(false, "Unknown two-gen policy"); } @@ -159,7 +160,7 @@ add_generation_memory_pool(heap->get_gen(major), _major_gc_manager); } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS // Add memory pools for ParallelScavengeHeap // This function currently only supports two generations collected heap. // The collector for ParallelScavengeHeap will have two memory managers. @@ -185,7 +186,7 @@ add_g1YoungGen_memory_pool(g1h, _major_gc_manager, _minor_gc_manager); add_g1OldGen_memory_pool(g1h, _major_gc_manager); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS MemoryPool* MemoryService::add_gen(Generation* gen, const char* name, @@ -222,7 +223,7 @@ return (MemoryPool*) pool; } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS MemoryPool* MemoryService::add_cms_space(CompactibleFreeListSpace* space, const char* name, bool is_heap, @@ -233,7 +234,7 @@ _pools_list->append(pool); return (MemoryPool*) pool; } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS // Add memory pool(s) for one generation void MemoryService::add_generation_memory_pool(Generation* gen, @@ -261,7 +262,7 @@ break; } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS case Generation::ParNew: case Generation::ASParNew: { @@ -282,7 +283,7 @@ break; } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS case Generation::MarkSweepCompact: { assert(major_mgr != NULL && minor_mgr == NULL, "Should have only one manager"); @@ -293,7 +294,7 @@ break; } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS case Generation::ConcurrentMarkSweep: case Generation::ASConcurrentMarkSweep: { @@ -306,7 +307,7 @@ true /* support_usage_threshold */); break; } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS default: assert(false, "should not reach here"); @@ -326,7 +327,7 @@ } -#ifndef SERIALGC +#if INCLUDE_ALL_GCS void MemoryService::add_psYoung_memory_pool(PSYoungGen* gen, MemoryManager* major_mgr, MemoryManager* minor_mgr) { assert(major_mgr != NULL && minor_mgr != NULL, "Should have two managers"); @@ -384,7 +385,7 @@ mgr->add_pool(old_gen); _pools_list->append(old_gen); } -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS void MemoryService::add_code_heap_memory_pool(CodeHeap* heap) { _code_heap_pool = new CodeHeapPool(heap, @@ -534,17 +535,17 @@ TraceMemoryManagerStats::TraceMemoryManagerStats(Generation::Name kind, GCCause::Cause cause) { switch (kind) { case Generation::DefNew: -#ifndef SERIALGC +#if INCLUDE_ALL_GCS case Generation::ParNew: case Generation::ASParNew: -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS _fullGC=false; break; case Generation::MarkSweepCompact: -#ifndef SERIALGC +#if INCLUDE_ALL_GCS case Generation::ConcurrentMarkSweep: case Generation::ASConcurrentMarkSweep: -#endif // SERIALGC +#endif // INCLUDE_ALL_GCS _fullGC=true; break; default: diff -r da53cb17186a -r 412d722168bc src/share/vm/services/psMemoryPool.hpp --- a/src/share/vm/services/psMemoryPool.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/services/psMemoryPool.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -25,7 +25,8 @@ #ifndef SHARE_VM_SERVICES_PSMEMORYPOOL_HPP #define SHARE_VM_SERVICES_PSMEMORYPOOL_HPP -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "gc_implementation/parallelScavenge/psOldGen.hpp" #include "gc_implementation/parallelScavenge/psYoungGen.hpp" #include "gc_implementation/shared/mutableSpace.hpp" @@ -34,7 +35,7 @@ #include "memory/space.hpp" #include "services/memoryPool.hpp" #include "services/memoryUsage.hpp" -#endif +#endif // INCLUDE_ALL_GCS class PSGenerationPool : public CollectedMemoryPool { private: diff -r da53cb17186a -r 412d722168bc src/share/vm/services/runtimeService.cpp --- a/src/share/vm/services/runtimeService.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/services/runtimeService.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -29,6 +29,7 @@ #include "services/runtimeService.hpp" #include "utilities/dtrace.hpp" #include "utilities/exceptions.hpp" +#include "utilities/macros.hpp" #ifndef USDT2 HS_DTRACE_PROBE_DECL(hs_private, safepoint__begin); diff -r da53cb17186a -r 412d722168bc src/share/vm/utilities/macros.hpp --- a/src/share/vm/utilities/macros.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/utilities/macros.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -130,23 +130,23 @@ #endif // INCLUDE_MANAGEMENT /* - * When INCLUDE_ALTERNATE_GCS is false the only garbage collectors + * When INCLUDE_ALL_GCS is false the only garbage collectors * included in the JVM are defaultNewGeneration and markCompact. * - * When INCLUDE_ALTERNATE_GCS is true all garbage collectors are + * When INCLUDE_ALL_GCS is true all garbage collectors are * included in the JVM. */ -#ifndef INCLUDE_ALTERNATE_GCS -#define INCLUDE_ALTERNATE_GCS 1 -#endif // INCLUDE_ALTERNATE_GCS +#ifndef INCLUDE_ALL_GCS +#define INCLUDE_ALL_GCS 1 +#endif // INCLUDE_ALL_GCS -#if INCLUDE_ALTERNATE_GCS -#define NOT_ALTERNATE_GCS_RETURN /* next token must be ; */ -#define NOT_ALTERNATE_GCS_RETURN_(code) /* next token must be ; */ +#if INCLUDE_ALL_GCS +#define NOT_ALL_GCS_RETURN /* next token must be ; */ +#define NOT_ALL_GCS_RETURN_(code) /* next token must be ; */ #else -#define NOT_ALTERNATE_GCS_RETURN {} -#define NOT_ALTERNATE_GCS_RETURN_(code) { return code; } -#endif // INCLUDE_ALTERNATE_GCS +#define NOT_ALL_GCS_RETURN {} +#define NOT_ALL_GCS_RETURN_(code) { return code; } +#endif // INCLUDE_ALL_GCS #ifndef INCLUDE_NMT #define INCLUDE_NMT 1 diff -r da53cb17186a -r 412d722168bc src/share/vm/utilities/top.hpp --- a/src/share/vm/utilities/top.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/utilities/top.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -33,9 +33,9 @@ #include "utilities/macros.hpp" #include "utilities/ostream.hpp" #include "utilities/sizes.hpp" -#ifndef SERIALGC +#if INCLUDE_ALL_GCS #include "gc_implementation/g1/g1_globals.hpp" -#endif +#endif // INCLUDE_ALL_GCS #ifdef COMPILER1 #include "c1/c1_globals.hpp" #endif diff -r da53cb17186a -r 412d722168bc src/share/vm/utilities/yieldingWorkgroup.cpp --- a/src/share/vm/utilities/yieldingWorkgroup.cpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/utilities/yieldingWorkgroup.cpp Fri Feb 08 08:07:06 2013 -0800 @@ -23,9 +23,10 @@ */ #include "precompiled.hpp" -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "utilities/yieldingWorkgroup.hpp" -#endif +#endif // INCLUDE_ALL_GCS // Forward declaration of classes declared here. diff -r da53cb17186a -r 412d722168bc src/share/vm/utilities/yieldingWorkgroup.hpp --- a/src/share/vm/utilities/yieldingWorkgroup.hpp Thu Feb 07 12:32:50 2013 -0800 +++ b/src/share/vm/utilities/yieldingWorkgroup.hpp Fri Feb 08 08:07:06 2013 -0800 @@ -25,9 +25,10 @@ #ifndef SHARE_VM_UTILITIES_YIELDINGWORKGROUP_HPP #define SHARE_VM_UTILITIES_YIELDINGWORKGROUP_HPP -#ifndef SERIALGC +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS #include "utilities/workgroup.hpp" -#endif +#endif // INCLUDE_ALL_GCS // Forward declarations diff -r da53cb17186a -r 412d722168bc test/TEST.ROOT --- a/test/TEST.ROOT Thu Feb 07 12:32:50 2013 -0800 +++ b/test/TEST.ROOT Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc test/compiler/8004741/Test8004741.java --- a/test/compiler/8004741/Test8004741.java Thu Feb 07 12:32:50 2013 -0800 +++ b/test/compiler/8004741/Test8004741.java Fri Feb 08 08:07:06 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); + } }; diff -r da53cb17186a -r 412d722168bc test/runtime/7158988/FieldMonitor.java --- a/test/runtime/7158988/FieldMonitor.java Thu Feb 07 12:32:50 2013 -0800 +++ b/test/runtime/7158988/FieldMonitor.java Fri Feb 08 08:07:06 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; diff -r da53cb17186a -r 412d722168bc test/runtime/7158988/TestFieldMonitor.sh --- a/test/runtime/7158988/TestFieldMonitor.sh Thu Feb 07 12:32:50 2013 -0800 +++ /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 diff -r da53cb17186a -r 412d722168bc test/runtime/8000968/Test8000968.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/8000968/Test8000968.sh Fri Feb 08 08:07:06 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 diff -r da53cb17186a -r 412d722168bc test/runtime/8007475/StackMapFrameTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/8007475/StackMapFrameTest.java Fri Feb 08 08:07:06 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(); + } + } +} diff -r da53cb17186a -r 412d722168bc test/runtime/NMT/AllocTestType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/NMT/AllocTestType.java Fri Feb 08 08:07:06 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 VM.native_memory summary' + pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary"}); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("Test (reserved=512KB, committed=512KB)"); + + // Free the memory allocated by NMTAllocTest + if (!WhiteBox.getWhiteBox().NMTFreeTestMemory()) { + throw new Exception("Call to WB API NMTFreeTestMemory() failed"); + } + + // Use WB API to ensure that all data has been merged before we continue + if (!WhiteBox.getWhiteBox().NMTWaitForDataMerge()) { + throw new Exception("Call to WB API NMTWaitForDataMerge() failed"); + } + output = new OutputAnalyzer(pb.start()); + output.shouldNotContain("Test (reserved="); + } +} diff -r da53cb17186a -r 412d722168bc test/runtime/NMT/BaselineWithParameter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/NMT/BaselineWithParameter.java Fri Feb 08 08:07:06 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 VM.native_memory baseline=false' + pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "baseline=false"}); + pb.start(); + + // Run 'jcmd VM.native_memory summary=false' + pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary=false"}); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("No command to execute"); + + } +} diff -r da53cb17186a -r 412d722168bc test/runtime/NMT/CommandLineDetail.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/NMT/CommandLineDetail.java Fri Feb 08 08:07:06 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); + } +} diff -r da53cb17186a -r 412d722168bc test/runtime/NMT/CommandLineEmptyArgument.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/NMT/CommandLineEmptyArgument.java Fri Feb 08 08:07:06 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); + } +} diff -r da53cb17186a -r 412d722168bc test/runtime/NMT/CommandLineInvalidArgument.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/NMT/CommandLineInvalidArgument.java Fri Feb 08 08:07:06 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); + } +} diff -r da53cb17186a -r 412d722168bc test/runtime/NMT/CommandLineSummary.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/NMT/CommandLineSummary.java Fri Feb 08 08:07:06 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); + } +} diff -r da53cb17186a -r 412d722168bc test/runtime/NMT/CommandLineTurnOffNMT.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/NMT/CommandLineTurnOffNMT.java Fri Feb 08 08:07:06 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); + } +} diff -r da53cb17186a -r 412d722168bc test/runtime/NMT/JcmdScale.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/NMT/JcmdScale.java Fri Feb 08 08:07:06 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"); + + } +} diff -r da53cb17186a -r 412d722168bc test/runtime/NMT/JcmdWithNMTDisabled.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/NMT/JcmdWithNMTDisabled.java Fri Feb 08 08:07:06 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"); + } +} diff -r da53cb17186a -r 412d722168bc test/runtime/NMT/PrintNMTStatistics.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/NMT/PrintNMTStatistics.java Fri Feb 08 08:07:06 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); + } +} diff -r da53cb17186a -r 412d722168bc test/runtime/NMT/PrintNMTStatisticsWithNMTDisabled.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/NMT/PrintNMTStatisticsWithNMTDisabled.java Fri Feb 08 08:07:06 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); + } +} diff -r da53cb17186a -r 412d722168bc test/runtime/NMT/ShutdownTwice.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/NMT/ShutdownTwice.java Fri Feb 08 08:07:06 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 VM.native_memory shutdown' + pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "shutdown"}); + output = new OutputAnalyzer(pb.start()); + + // Verify that jcmd reports that NMT is shutting down + output.shouldContain("Shutdown is in progress, it will take a few moments to completely shutdown"); + + // Run shutdown again + output = new OutputAnalyzer(pb.start()); + + // Verify that jcmd reports that NMT has been shutdown already + output.shouldContain("Native memory tracking has been shutdown by user"); + } +} diff -r da53cb17186a -r 412d722168bc test/runtime/NMT/SummaryAfterShutdown.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/NMT/SummaryAfterShutdown.java Fri Feb 08 08:07:06 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 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 VM.native_memory summary' + pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary"}); + output = new OutputAnalyzer(pb.start()); + + // Verify that jcmd reports that NMT has been shutdown + output.shouldContain("Native memory tracking has been shutdown by user"); + } +} diff -r da53cb17186a -r 412d722168bc test/runtime/NMT/SummarySanityCheck.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/NMT/SummarySanityCheck.java Fri Feb 08 08:07:06 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 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 '- (reserved=KB, committed=KB) + Pattern mtTypePattern = Pattern.compile("-\\s+(?[\\w\\s]+)\\(reserved=(?\\d+)KB,\\scommitted=(?\\d+)KB\\)"); + // Match 'Total: reserved=KB, committed=KB' + Pattern totalMemoryPattern = Pattern.compile("Total\\:\\s\\sreserved=(?\\d+)KB,\\s\\scommitted=(?\\d+)KB"); + + for (int i = 0; i < lines.length; i++) { + if (lines[i].startsWith("Total")) { + Matcher totalMemoryMatcher = totalMemoryPattern.matcher(lines[i]); + + if (totalMemoryMatcher.matches() && totalMemoryMatcher.groupCount() == 2) { + totalCommitted = Integer.parseInt(totalMemoryMatcher.group("committed")); + totalReserved = Integer.parseInt(totalMemoryMatcher.group("reserved")); + } else { + throwTestException("Failed to match the expected groups in 'Total' memory part"); + } + } else if (lines[i].startsWith("-")) { + Matcher typeMatcher = mtTypePattern.matcher(lines[i]); + if (typeMatcher.matches()) { + int typeCommitted = Integer.parseInt(typeMatcher.group("committed")); + int typeReserved = Integer.parseInt(typeMatcher.group("reserved")); + + // Make sure reserved is always less or equals + if (typeCommitted > typeReserved) { + throwTestException("Committed (" + typeCommitted + ") was more than Reserved (" + + typeReserved + ") for mtType: " + typeMatcher.group("typename")); + } + + // Add to total and compare them in the end + totalCommittedSum += typeCommitted; + totalReservedSum += typeReserved; + } else { + throwTestException("Failed to match the group on line " + i); + } + } + } + + // See if they add up correctly, rounding is a problem so make sure we're within +/- 8KB + int committedDiff = totalCommitted - totalCommittedSum; + if (committedDiff > 8 || committedDiff < -8) { + throwTestException("Total committed (" + totalCommitted + ") did not match the summarized committed (" + totalCommittedSum + ")" ); + } + + int reservedDiff = totalReserved - totalReservedSum; + if (reservedDiff > 8 || reservedDiff < -8) { + throwTestException("Total reserved (" + totalReserved + ") did not match the summarized reserved (" + totalReservedSum + ")" ); + } + } + + private static void throwTestException(String reason) throws Exception { + throw new Exception(reason + " . Stdout is :\n" + jcmdout); + } +} diff -r da53cb17186a -r 412d722168bc test/testlibrary/OutputAnalyzerTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/testlibrary/OutputAnalyzerTest.java Fri Feb 08 08:07:06 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 + } + } +} diff -r da53cb17186a -r 412d722168bc test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java Fri Feb 08 08:07:06 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; + } +} diff -r da53cb17186a -r 412d722168bc test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java Fri Feb 08 08:07:06 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; + } +} diff -r da53cb17186a -r 412d722168bc test/testlibrary/com/oracle/java/testlibrary/OutputBuffer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/testlibrary/com/oracle/java/testlibrary/OutputBuffer.java Fri Feb 08 08:07:06 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; + } +} diff -r da53cb17186a -r 412d722168bc test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java Fri Feb 08 08:07:06 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 args = new ArrayList<>(); + args.add(javapath); + Collections.addAll(args, getPlatformSpecificVMArgs()); + Collections.addAll(args, command); + + return new ProcessBuilder(args.toArray(new String[args.size()])); + + } + +} diff -r da53cb17186a -r 412d722168bc test/testlibrary/com/oracle/java/testlibrary/StreamPumper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/testlibrary/com/oracle/java/testlibrary/StreamPumper.java Fri Feb 08 08:07:06 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 in and write + * to out until in 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(); + } + } + } +}