Merge
This commit is contained in:
commit
ff7575383f
@ -280,7 +280,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLo
|
||||
return (err == PS_OK)? array : 0;
|
||||
}
|
||||
|
||||
#if defined(i386) || defined(ia64) || defined(amd64) || defined(sparc) || defined(sparcv9)
|
||||
#if defined(i386) || defined(amd64) || defined(sparc) || defined(sparcv9)
|
||||
JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getThreadIntegerRegisterSet0
|
||||
(JNIEnv *env, jobject this_obj, jint lwp_id) {
|
||||
|
||||
@ -299,9 +299,6 @@ JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLo
|
||||
#ifdef i386
|
||||
#define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG
|
||||
#endif
|
||||
#ifdef ia64
|
||||
#define NPRGREG IA64_REG_COUNT
|
||||
#endif
|
||||
#ifdef amd64
|
||||
#define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG
|
||||
#endif
|
||||
@ -336,13 +333,6 @@ JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLo
|
||||
|
||||
#endif /* i386 */
|
||||
|
||||
#if ia64
|
||||
regs = (*env)->GetLongArrayElements(env, array, &isCopy);
|
||||
for (i = 0; i < NPRGREG; i++ ) {
|
||||
regs[i] = 0xDEADDEAD;
|
||||
}
|
||||
#endif /* ia64 */
|
||||
|
||||
#ifdef amd64
|
||||
#define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg
|
||||
|
||||
|
@ -79,14 +79,6 @@ combination of ptrace and /proc calls.
|
||||
|
||||
*************************************************************************************/
|
||||
|
||||
#ifdef ia64
|
||||
struct user_regs_struct {
|
||||
/* copied from user.h which doesn't define this in a struct */
|
||||
|
||||
#define IA64_REG_COUNT (EF_SIZE/8+32) /* integer and fp regs */
|
||||
unsigned long regs[IA64_REG_COUNT]; /* integer and fp regs */
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(sparc) || defined(sparcv9)
|
||||
#define user_regs_struct pt_regs
|
||||
|
@ -27,10 +27,7 @@
|
||||
|
||||
#include "sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal.h"
|
||||
|
||||
#ifdef _M_IA64
|
||||
#include "sun_jvm_hotspot_debugger_ia64_IA64ThreadContext.h"
|
||||
#define NPRGREG sun_jvm_hotspot_debugger_ia64_IA64ThreadContext_NPRGREG
|
||||
#elif _M_IX86
|
||||
#ifdef _M_IX86
|
||||
#include "sun_jvm_hotspot_debugger_x86_X86ThreadContext.h"
|
||||
#define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG
|
||||
#elif _M_AMD64
|
||||
@ -491,92 +488,7 @@ static bool addThreads(JNIEnv* env, jobject obj) {
|
||||
memset(&context, 0, sizeof(CONTEXT));
|
||||
|
||||
#undef REG_INDEX
|
||||
#ifdef _M_IA64
|
||||
#define REG_INDEX(x) sun_jvm_hotspot_debugger_ia64_IA64ThreadContext_##x
|
||||
|
||||
context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG;
|
||||
ptrIDebugAdvanced->GetThreadContext(&context, sizeof(CONTEXT));
|
||||
|
||||
ptrRegs[REG_INDEX(GR0)] = 0; // always 0
|
||||
ptrRegs[REG_INDEX(GR1)] = context.IntGp; // r1
|
||||
ptrRegs[REG_INDEX(GR2)] = context.IntT0; // r2-r3
|
||||
ptrRegs[REG_INDEX(GR3)] = context.IntT1;
|
||||
ptrRegs[REG_INDEX(GR4)] = context.IntS0; // r4-r7
|
||||
ptrRegs[REG_INDEX(GR5)] = context.IntS1;
|
||||
ptrRegs[REG_INDEX(GR6)] = context.IntS2;
|
||||
ptrRegs[REG_INDEX(GR7)] = context.IntS3;
|
||||
ptrRegs[REG_INDEX(GR8)] = context.IntV0; // r8
|
||||
ptrRegs[REG_INDEX(GR9)] = context.IntT2; // r9-r11
|
||||
ptrRegs[REG_INDEX(GR10)] = context.IntT3;
|
||||
ptrRegs[REG_INDEX(GR11)] = context.IntT4;
|
||||
ptrRegs[REG_INDEX(GR12)] = context.IntSp; // r12 stack pointer
|
||||
ptrRegs[REG_INDEX(GR13)] = context.IntTeb; // r13 teb
|
||||
ptrRegs[REG_INDEX(GR14)] = context.IntT5; // r14-r31
|
||||
ptrRegs[REG_INDEX(GR15)] = context.IntT6;
|
||||
ptrRegs[REG_INDEX(GR16)] = context.IntT7;
|
||||
ptrRegs[REG_INDEX(GR17)] = context.IntT8;
|
||||
ptrRegs[REG_INDEX(GR18)] = context.IntT9;
|
||||
ptrRegs[REG_INDEX(GR19)] = context.IntT10;
|
||||
ptrRegs[REG_INDEX(GR20)] = context.IntT11;
|
||||
ptrRegs[REG_INDEX(GR21)] = context.IntT12;
|
||||
ptrRegs[REG_INDEX(GR22)] = context.IntT13;
|
||||
ptrRegs[REG_INDEX(GR23)] = context.IntT14;
|
||||
ptrRegs[REG_INDEX(GR24)] = context.IntT15;
|
||||
ptrRegs[REG_INDEX(GR25)] = context.IntT16;
|
||||
ptrRegs[REG_INDEX(GR26)] = context.IntT17;
|
||||
ptrRegs[REG_INDEX(GR27)] = context.IntT18;
|
||||
ptrRegs[REG_INDEX(GR28)] = context.IntT19;
|
||||
ptrRegs[REG_INDEX(GR29)] = context.IntT20;
|
||||
ptrRegs[REG_INDEX(GR30)] = context.IntT21;
|
||||
ptrRegs[REG_INDEX(GR31)] = context.IntT22;
|
||||
|
||||
ptrRegs[REG_INDEX(INT_NATS)] = context.IntNats;
|
||||
ptrRegs[REG_INDEX(PREDS)] = context.Preds;
|
||||
|
||||
ptrRegs[REG_INDEX(BR_RP)] = context.BrRp;
|
||||
ptrRegs[REG_INDEX(BR1)] = context.BrS0; // b1-b5
|
||||
ptrRegs[REG_INDEX(BR2)] = context.BrS1;
|
||||
ptrRegs[REG_INDEX(BR3)] = context.BrS2;
|
||||
ptrRegs[REG_INDEX(BR4)] = context.BrS3;
|
||||
ptrRegs[REG_INDEX(BR5)] = context.BrS4;
|
||||
ptrRegs[REG_INDEX(BR6)] = context.BrT0; // b6-b7
|
||||
ptrRegs[REG_INDEX(BR7)] = context.BrT1;
|
||||
|
||||
ptrRegs[REG_INDEX(AP_UNAT)] = context.ApUNAT;
|
||||
ptrRegs[REG_INDEX(AP_LC)] = context.ApLC;
|
||||
ptrRegs[REG_INDEX(AP_EC)] = context.ApEC;
|
||||
ptrRegs[REG_INDEX(AP_CCV)] = context.ApCCV;
|
||||
ptrRegs[REG_INDEX(AP_DCR)] = context.ApDCR;
|
||||
|
||||
ptrRegs[REG_INDEX(RS_PFS)] = context.RsPFS;
|
||||
ptrRegs[REG_INDEX(RS_BSP)] = context.RsBSP;
|
||||
ptrRegs[REG_INDEX(RS_BSPSTORE)] = context.RsBSPSTORE;
|
||||
ptrRegs[REG_INDEX(RS_RSC)] = context.RsRSC;
|
||||
ptrRegs[REG_INDEX(RS_RNAT)] = context.RsRNAT;
|
||||
|
||||
ptrRegs[REG_INDEX(ST_IPSR)] = context.StIPSR;
|
||||
ptrRegs[REG_INDEX(ST_IIP)] = context.StIIP;
|
||||
ptrRegs[REG_INDEX(ST_IFS)] = context.StIFS;
|
||||
|
||||
ptrRegs[REG_INDEX(DB_I0)] = context.DbI0;
|
||||
ptrRegs[REG_INDEX(DB_I1)] = context.DbI1;
|
||||
ptrRegs[REG_INDEX(DB_I2)] = context.DbI2;
|
||||
ptrRegs[REG_INDEX(DB_I3)] = context.DbI3;
|
||||
ptrRegs[REG_INDEX(DB_I4)] = context.DbI4;
|
||||
ptrRegs[REG_INDEX(DB_I5)] = context.DbI5;
|
||||
ptrRegs[REG_INDEX(DB_I6)] = context.DbI6;
|
||||
ptrRegs[REG_INDEX(DB_I7)] = context.DbI7;
|
||||
|
||||
ptrRegs[REG_INDEX(DB_D0)] = context.DbD0;
|
||||
ptrRegs[REG_INDEX(DB_D1)] = context.DbD1;
|
||||
ptrRegs[REG_INDEX(DB_D2)] = context.DbD2;
|
||||
ptrRegs[REG_INDEX(DB_D3)] = context.DbD3;
|
||||
ptrRegs[REG_INDEX(DB_D4)] = context.DbD4;
|
||||
ptrRegs[REG_INDEX(DB_D5)] = context.DbD5;
|
||||
ptrRegs[REG_INDEX(DB_D6)] = context.DbD6;
|
||||
ptrRegs[REG_INDEX(DB_D7)] = context.DbD7;
|
||||
|
||||
#elif _M_IX86
|
||||
#ifdef _M_IX86
|
||||
#define REG_INDEX(x) sun_jvm_hotspot_debugger_x86_X86ThreadContext_##x
|
||||
|
||||
context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -34,21 +34,11 @@ class WindbgAMD64Thread implements ThreadProxy {
|
||||
private boolean gotID;
|
||||
private long id;
|
||||
|
||||
/** The address argument must be the address of the HANDLE of the
|
||||
desired thread in the target process. */
|
||||
// The address argument must be the address of the OSThread::_thread_id
|
||||
WindbgAMD64Thread(WindbgDebugger debugger, Address addr) {
|
||||
this.debugger = debugger;
|
||||
// FIXME: size of data fetched here should be configurable.
|
||||
// However, making it so would produce a dependency on the "types"
|
||||
// package from the debugger package, which is not desired.
|
||||
|
||||
// another hack here is that we use sys thread id instead of handle.
|
||||
// windbg can't get details based on handles it seems.
|
||||
// I assume that osThread_win32 thread struct has _thread_id (which
|
||||
// sys thread id) just after handle field.
|
||||
|
||||
this.sysId = (int) addr.addOffsetTo(debugger.getAddressSize()).getCIntegerAt(0, 4, true);
|
||||
gotID = false;
|
||||
this.sysId = (long)addr.getCIntegerAt(0, 4, true);
|
||||
gotID = false;
|
||||
}
|
||||
|
||||
WindbgAMD64Thread(WindbgDebugger debugger, long sysId) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -34,21 +34,11 @@ class WindbgX86Thread implements ThreadProxy {
|
||||
private boolean gotID;
|
||||
private long id;
|
||||
|
||||
/** The address argument must be the address of the HANDLE of the
|
||||
desired thread in the target process. */
|
||||
// The address argument must be the address of OSThread::_thread_id
|
||||
WindbgX86Thread(WindbgDebugger debugger, Address addr) {
|
||||
this.debugger = debugger;
|
||||
// FIXME: size of data fetched here should be configurable.
|
||||
// However, making it so would produce a dependency on the "types"
|
||||
// package from the debugger package, which is not desired.
|
||||
|
||||
// another hack here is that we use sys thread id instead of handle.
|
||||
// windbg can't get details based on handles it seems.
|
||||
// I assume that osThread_win32 thread struct has _thread_id (which
|
||||
// sys thread id) just after handle field.
|
||||
|
||||
this.sysId = (int) addr.addOffsetTo(debugger.getAddressSize()).getCIntegerAt(0, 4, true);
|
||||
gotID = false;
|
||||
this.sysId = (long)addr.getCIntegerAt(0, 4, true);
|
||||
gotID = false;
|
||||
}
|
||||
|
||||
WindbgX86Thread(WindbgDebugger debugger, long sysId) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* @(#)BinaryTreeDictionary.java
|
||||
* Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -30,7 +30,7 @@ import sun.jvm.hotspot.debugger.*;
|
||||
import sun.jvm.hotspot.types.*;
|
||||
import sun.jvm.hotspot.runtime.*;
|
||||
|
||||
public class BinaryTreeDictionary extends VMObject {
|
||||
public class AFLBinaryTreeDictionary extends VMObject {
|
||||
static {
|
||||
VM.registerVMInitializedObserver(new Observer() {
|
||||
public void update(Observable o, Object data) {
|
||||
@ -40,8 +40,8 @@ public class BinaryTreeDictionary extends VMObject {
|
||||
}
|
||||
|
||||
private static synchronized void initialize(TypeDataBase db) {
|
||||
Type type = db.lookupType("BinaryTreeDictionary");
|
||||
totalSizeField = type.getCIntegerField("_totalSize");
|
||||
Type type = db.lookupType("AFLBinaryTreeDictionary");
|
||||
totalSizeField = type.getCIntegerField("_total_size");
|
||||
}
|
||||
|
||||
// Fields
|
||||
@ -53,7 +53,7 @@ public class BinaryTreeDictionary extends VMObject {
|
||||
}
|
||||
|
||||
// Constructor
|
||||
public BinaryTreeDictionary(Address addr) {
|
||||
public AFLBinaryTreeDictionary(Address addr) {
|
||||
super(addr);
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -117,9 +117,9 @@ public class CompactibleFreeListSpace extends CompactibleSpace {
|
||||
}
|
||||
|
||||
// large block
|
||||
BinaryTreeDictionary bfbd = (BinaryTreeDictionary) VMObjectFactory.newObject(BinaryTreeDictionary.class,
|
||||
AFLBinaryTreeDictionary aflbd = (AFLBinaryTreeDictionary) VMObjectFactory.newObject(AFLBinaryTreeDictionary.class,
|
||||
dictionaryField.getValue(addr));
|
||||
size += bfbd.size();
|
||||
size += aflbd.size();
|
||||
|
||||
|
||||
// linear block in TLAB
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* @(#)FreeList.java
|
||||
*
|
||||
* Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -41,7 +41,7 @@ public class FreeList extends VMObject {
|
||||
}
|
||||
|
||||
private static synchronized void initialize(TypeDataBase db) {
|
||||
Type type = db.lookupType("FreeList");
|
||||
Type type = db.lookupType("FreeList<FreeChunk>");
|
||||
sizeField = type.getCIntegerField("_size");
|
||||
countField = type.getCIntegerField("_count");
|
||||
headerSize = type.getSize();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -32,6 +32,7 @@ import sun.jvm.hotspot.types.*;
|
||||
// to the sys_thread_t structure of the classic JVM implementation.
|
||||
public class OSThread extends VMObject {
|
||||
private static JIntField interruptedField;
|
||||
private static JIntField threadIdField;
|
||||
static {
|
||||
VM.registerVMInitializedObserver(new Observer() {
|
||||
public void update(Observable o, Object data) {
|
||||
@ -43,6 +44,7 @@ public class OSThread extends VMObject {
|
||||
private static synchronized void initialize(TypeDataBase db) {
|
||||
Type type = db.lookupType("OSThread");
|
||||
interruptedField = type.getJIntField("_interrupted");
|
||||
threadIdField = type.getJIntField("_thread_id");
|
||||
}
|
||||
|
||||
public OSThread(Address addr) {
|
||||
@ -52,4 +54,9 @@ public class OSThread extends VMObject {
|
||||
public boolean interrupted() {
|
||||
return ((int)interruptedField.getValue(addr)) != 0;
|
||||
}
|
||||
|
||||
public int threadId() {
|
||||
return (int)threadIdField.getValue(addr);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -43,7 +43,7 @@ public class Win32AMD64JavaThreadPDAccess implements JavaThreadPDAccess {
|
||||
private static AddressField osThreadField;
|
||||
|
||||
// Field from OSThread
|
||||
private static Field osThreadThreadHandleField;
|
||||
private static Field osThreadThreadIdField;
|
||||
|
||||
// This is currently unneeded but is being kept in case we change
|
||||
// the currentFrameGuess algorithm
|
||||
@ -64,7 +64,7 @@ public class Win32AMD64JavaThreadPDAccess implements JavaThreadPDAccess {
|
||||
osThreadField = type.getAddressField("_osthread");
|
||||
|
||||
type = db.lookupType("OSThread");
|
||||
osThreadThreadHandleField = type.getField("_thread_handle");
|
||||
osThreadThreadIdField = type.getField("_thread_id");
|
||||
}
|
||||
|
||||
public Address getLastJavaFP(Address addr) {
|
||||
@ -128,10 +128,10 @@ public class Win32AMD64JavaThreadPDAccess implements JavaThreadPDAccess {
|
||||
// Fetch the OSThread (for now and for simplicity, not making a
|
||||
// separate "OSThread" class in this package)
|
||||
Address osThreadAddr = osThreadField.getValue(addr);
|
||||
// Get the address of the HANDLE within the OSThread
|
||||
Address threadHandleAddr =
|
||||
osThreadAddr.addOffsetTo(osThreadThreadHandleField.getOffset());
|
||||
// Get the address of the thread_id within the OSThread
|
||||
Address threadIdAddr =
|
||||
osThreadAddr.addOffsetTo(osThreadThreadIdField.getOffset());
|
||||
JVMDebugger debugger = VM.getVM().getDebugger();
|
||||
return debugger.getThreadForIdentifierAddress(threadHandleAddr);
|
||||
return debugger.getThreadForIdentifierAddress(threadIdAddr);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -42,7 +42,7 @@ public class Win32X86JavaThreadPDAccess implements JavaThreadPDAccess {
|
||||
private static AddressField osThreadField;
|
||||
|
||||
// Field from OSThread
|
||||
private static Field osThreadThreadHandleField;
|
||||
private static Field osThreadThreadIdField;
|
||||
|
||||
// This is currently unneeded but is being kept in case we change
|
||||
// the currentFrameGuess algorithm
|
||||
@ -63,7 +63,7 @@ public class Win32X86JavaThreadPDAccess implements JavaThreadPDAccess {
|
||||
osThreadField = type.getAddressField("_osthread");
|
||||
|
||||
type = db.lookupType("OSThread");
|
||||
osThreadThreadHandleField = type.getField("_thread_handle");
|
||||
osThreadThreadIdField = type.getField("_thread_id");
|
||||
}
|
||||
|
||||
public Address getLastJavaFP(Address addr) {
|
||||
@ -127,10 +127,10 @@ public class Win32X86JavaThreadPDAccess implements JavaThreadPDAccess {
|
||||
// Fetch the OSThread (for now and for simplicity, not making a
|
||||
// separate "OSThread" class in this package)
|
||||
Address osThreadAddr = osThreadField.getValue(addr);
|
||||
// Get the address of the HANDLE within the OSThread
|
||||
Address threadHandleAddr =
|
||||
osThreadAddr.addOffsetTo(osThreadThreadHandleField.getOffset());
|
||||
// Get the address of the thread_id within the OSThread
|
||||
Address threadIdAddr =
|
||||
osThreadAddr.addOffsetTo(osThreadThreadIdField.getOffset());
|
||||
JVMDebugger debugger = VM.getVM().getDebugger();
|
||||
return debugger.getThreadForIdentifierAddress(threadHandleAddr);
|
||||
return debugger.getThreadForIdentifierAddress(threadIdAddr);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -87,7 +87,6 @@ endif
|
||||
# Typical C1/C2 targets made available with this Makefile
|
||||
C1_VM_TARGETS=product1 fastdebug1 optimized1 jvmg1
|
||||
C2_VM_TARGETS=product fastdebug optimized jvmg
|
||||
KERNEL_VM_TARGETS=productkernel fastdebugkernel optimizedkernel jvmgkernel
|
||||
ZERO_VM_TARGETS=productzero fastdebugzero optimizedzero jvmgzero
|
||||
SHARK_VM_TARGETS=productshark fastdebugshark optimizedshark jvmgshark
|
||||
MINIMAL1_VM_TARGETS=productminimal1 fastdebugminimal1 jvmgminimal1
|
||||
@ -161,11 +160,6 @@ $(C2_VM_TARGETS):
|
||||
$(CD) $(GAMMADIR)/make; \
|
||||
$(MAKE) BUILD_FLAVOR=$@ VM_TARGET=$@ generic_build2 $(ALT_OUT)
|
||||
|
||||
$(KERNEL_VM_TARGETS):
|
||||
$(CD) $(GAMMADIR)/make; \
|
||||
$(MAKE) BUILD_FLAVOR=$(@:%kernel=%) VM_TARGET=$@ \
|
||||
generic_buildkernel $(ALT_OUT)
|
||||
|
||||
$(ZERO_VM_TARGETS):
|
||||
$(CD) $(GAMMADIR)/make; \
|
||||
$(MAKE) BUILD_FLAVOR=$(@:%zero=%) VM_TARGET=$@ \
|
||||
@ -223,24 +217,6 @@ else
|
||||
$(MAKE_ARGS) $(VM_TARGET)
|
||||
endif
|
||||
|
||||
generic_buildkernel:
|
||||
$(MKDIR) -p $(OUTPUTDIR)
|
||||
ifeq ($(OSNAME),windows)
|
||||
ifeq ($(ARCH_DATA_MODEL), 32)
|
||||
$(CD) $(OUTPUTDIR); \
|
||||
$(NMAKE) -f $(ABS_OS_MAKEFILE) \
|
||||
Variant=kernel \
|
||||
WorkSpace=$(ABS_GAMMADIR) \
|
||||
BootStrapDir=$(ABS_BOOTDIR) \
|
||||
BuildUser=$(USERNAME) \
|
||||
$(MAKE_ARGS) $(VM_TARGET:%kernel=%)
|
||||
else
|
||||
@$(ECHO) "No kernel ($(VM_TARGET)) for ARCH_DATA_MODEL=$(ARCH_DATA_MODEL)"
|
||||
endif
|
||||
else
|
||||
@$(ECHO) "No kernel ($(VM_TARGET)) for OS_NAME=$(OSNAME)"
|
||||
endif
|
||||
|
||||
generic_buildzero:
|
||||
$(MKDIR) -p $(OUTPUTDIR)
|
||||
$(CD) $(OUTPUTDIR); \
|
||||
@ -314,12 +290,10 @@ XUSAGE=$(HS_SRC_DIR)/share/vm/Xusage.txt
|
||||
DOCS_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_docs
|
||||
C1_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_compiler1
|
||||
C2_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_compiler2
|
||||
KERNEL_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_kernel
|
||||
ZERO_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_zero
|
||||
SHARK_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_shark
|
||||
C1_DIR=$(C1_BASE_DIR)/$(VM_SUBDIR)
|
||||
C2_DIR=$(C2_BASE_DIR)/$(VM_SUBDIR)
|
||||
KERNEL_DIR=$(KERNEL_BASE_DIR)/$(VM_SUBDIR)
|
||||
ZERO_DIR=$(ZERO_BASE_DIR)/$(VM_SUBDIR)
|
||||
SHARK_DIR=$(SHARK_BASE_DIR)/$(VM_SUBDIR)
|
||||
MINIMAL1_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_minimal1
|
||||
@ -333,10 +307,6 @@ ifeq ($(JVM_VARIANT_CLIENT), true)
|
||||
MISC_DIR=$(C1_DIR)
|
||||
GEN_DIR=$(C1_BASE_DIR)/generated
|
||||
endif
|
||||
ifeq ($(JVM_VARIANT_KERNEL), true)
|
||||
MISC_DIR=$(C2_DIR)
|
||||
GEN_DIR=$(C2_BASE_DIR)/generated
|
||||
endif
|
||||
ifeq ($(JVM_VARIANT_ZEROSHARK), true)
|
||||
MISC_DIR=$(SHARK_DIR)
|
||||
GEN_DIR=$(SHARK_BASE_DIR)/generated
|
||||
@ -386,16 +356,6 @@ $(EXPORT_SERVER_DIR)/%.pdb: $(C2_DIR)/%.pdb
|
||||
$(install-file)
|
||||
$(EXPORT_SERVER_DIR)/%.map: $(C2_DIR)/%.map
|
||||
$(install-file)
|
||||
|
||||
# Kernel files always come from kernel area
|
||||
$(EXPORT_KERNEL_DIR)/%.diz: $(KERNEL_DIR)/%.diz
|
||||
$(install-file)
|
||||
$(EXPORT_KERNEL_DIR)/%.dll: $(KERNEL_DIR)/%.dll
|
||||
$(install-file)
|
||||
$(EXPORT_KERNEL_DIR)/%.pdb: $(KERNEL_DIR)/%.pdb
|
||||
$(install-file)
|
||||
$(EXPORT_KERNEL_DIR)/%.map: $(KERNEL_DIR)/%.map
|
||||
$(install-file)
|
||||
endif
|
||||
|
||||
# Minimal JVM files always come from minimal area
|
||||
@ -538,7 +498,7 @@ $(EXPORT_DOCS_DIR)/platform/jvmti/%: $(DOCS_DIR)/%
|
||||
$(install-file)
|
||||
|
||||
# Xusage file
|
||||
$(EXPORT_SERVER_DIR)/Xusage.txt $(EXPORT_CLIENT_DIR)/Xusage.txt $(EXPORT_KERNEL_DIR)/Xusage.txt $(EXPORT_MINIMAL_DIR)/Xusage.txt: $(XUSAGE)
|
||||
$(EXPORT_SERVER_DIR)/Xusage.txt $(EXPORT_CLIENT_DIR)/Xusage.txt $(EXPORT_MINIMAL_DIR)/Xusage.txt: $(XUSAGE)
|
||||
$(prep-target)
|
||||
$(RM) $@.temp
|
||||
$(SED) 's/\(separated by \)[;:]/\1$(PATH_SEP)/g' $< > $@.temp
|
||||
@ -551,7 +511,6 @@ clobber clean: clean_build clean_export clean_jdk
|
||||
clean_build:
|
||||
$(RM) -r $(C1_DIR)
|
||||
$(RM) -r $(C2_DIR)
|
||||
$(RM) -r $(KERNEL_DIR)
|
||||
$(RM) -r $(ZERO_DIR)
|
||||
$(RM) -r $(SHARK_DIR)
|
||||
$(RM) -r $(MINIMAL1_DIR)
|
||||
@ -586,10 +545,6 @@ test_jdk:
|
||||
$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -server -Xinternalversion
|
||||
$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -server -version
|
||||
endif
|
||||
ifeq ($(JVM_VARIANT_KERNEL), true)
|
||||
$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -kernel -Xinternalversion
|
||||
$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -kernel -version
|
||||
endif
|
||||
|
||||
copy_product_jdk::
|
||||
$(RM) -r $(JDK_IMAGE_DIR)
|
||||
@ -665,7 +620,6 @@ target_help:
|
||||
@$(ECHO) "Other targets are:"
|
||||
@$(ECHO) " $(C1_VM_TARGETS)"
|
||||
@$(ECHO) " $(C2_VM_TARGETS)"
|
||||
@$(ECHO) " $(KERNEL_VM_TARGETS)"
|
||||
@$(ECHO) " $(MINIMAL1_VM_TARGETS)"
|
||||
|
||||
# Variable help (only common ones used by this workspace)
|
||||
@ -761,8 +715,8 @@ endif
|
||||
include $(GAMMADIR)/make/jprt.gmk
|
||||
|
||||
.PHONY: all world clobber clean help $(C1_VM_TARGETS) $(C2_VM_TARGETS) \
|
||||
$(KERNEL_VM_TARGETS) $(MINIMAL1_VM_TARGETS) \
|
||||
generic_build1 generic_build2 generic_buildkernel generic_buildminimal1 generic_export \
|
||||
$(MINIMAL1_VM_TARGETS) \
|
||||
generic_build1 generic_build2 generic_buildminimal1 generic_export \
|
||||
export_product export_fastdebug export_debug export_optimized \
|
||||
export_jdk_product export_jdk_fastdebug export_jdk_debug \
|
||||
create_jdk copy_jdk update_jdk test_jdk \
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,10 +25,9 @@
|
||||
# Rules to build jvm_db/dtrace, used by vm.make
|
||||
|
||||
# We build libjvm_dtrace/libjvm_db/dtrace for COMPILER1 and COMPILER2
|
||||
# but not for CORE or KERNEL configurations.
|
||||
# but not for CORE configuration.
|
||||
|
||||
ifneq ("${TYPE}", "CORE")
|
||||
ifneq ("${TYPE}", "KERNEL")
|
||||
|
||||
ifeq ($(OS_VENDOR), Darwin)
|
||||
# we build dtrace for macosx using USDT2 probes
|
||||
@ -280,13 +279,6 @@ endif # ifneq ("${dtraceFound}", "")
|
||||
endif # ifeq ($(OS_VENDOR), Darwin)
|
||||
|
||||
|
||||
else # KERNEL build
|
||||
|
||||
dtraceCheck:
|
||||
$(QUIETLY) echo "**NOTICE** Dtrace support disabled for KERNEL builds"
|
||||
|
||||
endif # ifneq ("${TYPE}", "KERNEL")
|
||||
|
||||
else # CORE build
|
||||
|
||||
dtraceCheck:
|
||||
|
@ -188,6 +188,7 @@ SUNWprivate_1.1 {
|
||||
JVM_IsSilentCompiler;
|
||||
JVM_IsSupportedJNIVersion;
|
||||
JVM_IsThreadAlive;
|
||||
JVM_IsVMGeneratedMethodIx;
|
||||
JVM_LatestUserDefinedLoader;
|
||||
JVM_Listen;
|
||||
JVM_LoadClass0;
|
||||
|
@ -188,6 +188,7 @@ SUNWprivate_1.1 {
|
||||
JVM_IsSilentCompiler;
|
||||
JVM_IsSupportedJNIVersion;
|
||||
JVM_IsThreadAlive;
|
||||
JVM_IsVMGeneratedMethodIx;
|
||||
JVM_LatestUserDefinedLoader;
|
||||
JVM_Listen;
|
||||
JVM_LoadClass0;
|
||||
|
@ -184,6 +184,7 @@ SUNWprivate_1.1 {
|
||||
JVM_IsSilentCompiler;
|
||||
JVM_IsSupportedJNIVersion;
|
||||
JVM_IsThreadAlive;
|
||||
JVM_IsVMGeneratedMethodIx;
|
||||
JVM_LatestUserDefinedLoader;
|
||||
JVM_Listen;
|
||||
JVM_LoadClass0;
|
||||
|
@ -184,6 +184,7 @@ SUNWprivate_1.1 {
|
||||
JVM_IsSilentCompiler;
|
||||
JVM_IsSupportedJNIVersion;
|
||||
JVM_IsThreadAlive;
|
||||
JVM_IsVMGeneratedMethodIx;
|
||||
JVM_LatestUserDefinedLoader;
|
||||
JVM_Listen;
|
||||
JVM_LoadClass0;
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -157,13 +157,11 @@ SUBDIRS_C1 = $(addprefix $(OSNAME)_$(BUILDARCH)_compiler1/,$(TARGETS))
|
||||
SUBDIRS_C2 = $(addprefix $(OSNAME)_$(BUILDARCH)_compiler2/,$(TARGETS))
|
||||
SUBDIRS_TIERED = $(addprefix $(OSNAME)_$(BUILDARCH)_tiered/,$(TARGETS))
|
||||
SUBDIRS_CORE = $(addprefix $(OSNAME)_$(BUILDARCH)_core/,$(TARGETS))
|
||||
SUBDIRS_KERNEL = $(addprefix $(OSNAME)_$(BUILDARCH)_kernel/,$(TARGETS))
|
||||
|
||||
TARGETS_C2 = $(TARGETS)
|
||||
TARGETS_C1 = $(addsuffix 1,$(TARGETS))
|
||||
TARGETS_TIERED = $(addsuffix tiered,$(TARGETS))
|
||||
TARGETS_CORE = $(addsuffix core,$(TARGETS))
|
||||
TARGETS_KERNEL = $(addsuffix kernel,$(TARGETS))
|
||||
|
||||
BUILDTREE_MAKE = $(GAMMADIR)/make/$(OSNAME)/makefiles/buildtree.make
|
||||
BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OSNAME) ARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH)
|
||||
@ -229,10 +227,6 @@ $(SUBDIRS_CORE): $(BUILDTREE_MAKE)
|
||||
$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
|
||||
$(BUILDTREE) VARIANT=core
|
||||
|
||||
$(SUBDIRS_KERNEL): $(BUILDTREE_MAKE)
|
||||
$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
|
||||
$(BUILDTREE) VARIANT=kernel
|
||||
|
||||
# Define INSTALL=y at command line to automatically copy JVM into JAVA_HOME
|
||||
|
||||
$(TARGETS_C2): $(SUBDIRS_C2)
|
||||
@ -271,20 +265,10 @@ ifdef INSTALL
|
||||
cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && $(MAKE) $(MFLAGS) install
|
||||
endif
|
||||
|
||||
$(TARGETS_KERNEL): $(SUBDIRS_KERNEL)
|
||||
cd $(OSNAME)_$(BUILDARCH)_kernel/$(patsubst %kernel,%,$@) && $(MAKE) $(MFLAGS)
|
||||
ifeq ($(TEST_IN_BUILD),true)
|
||||
cd $(OSNAME)_$(BUILDARCH)_kernel/$(patsubst %kernel,%,$@) && ./test_gamma
|
||||
endif
|
||||
ifdef INSTALL
|
||||
cd $(OSNAME)_$(BUILDARCH)_kernel/$(patsubst %kernel,%,$@) && $(MAKE) $(MFLAGS) install
|
||||
endif
|
||||
|
||||
# Just build the tree, and nothing else:
|
||||
tree: $(SUBDIRS_C2)
|
||||
tree1: $(SUBDIRS_C1)
|
||||
treecore: $(SUBDIRS_CORE)
|
||||
treekernel: $(SUBDIRS_KERNEL)
|
||||
|
||||
# Doc target. This is the same for all build options.
|
||||
# Hence create a docs directory beside ...$(ARCH)_[...]
|
||||
@ -304,10 +288,10 @@ core: jvmgcore productcore
|
||||
clean_docs:
|
||||
rm -rf $(SUBDIR_DOCS)
|
||||
|
||||
clean_compiler1 clean_compiler2 clean_core clean_kernel:
|
||||
clean_compiler1 clean_compiler2 clean_core:
|
||||
rm -rf $(OSNAME)_$(BUILDARCH)_$(subst clean_,,$@)
|
||||
|
||||
clean: clean_compiler2 clean_compiler1 clean_core clean_docs clean_kernel
|
||||
clean: clean_compiler2 clean_compiler1 clean_core clean_docs
|
||||
|
||||
include $(GAMMADIR)/make/cscope.make
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,10 +25,9 @@
|
||||
# Rules to build jvm_db/dtrace, used by vm.make
|
||||
|
||||
# We build libjvm_dtrace/libjvm_db/dtrace for COMPILER1 and COMPILER2
|
||||
# but not for CORE or KERNEL configurations.
|
||||
# but not for CORE configuration.
|
||||
|
||||
ifneq ("${TYPE}", "CORE")
|
||||
ifneq ("${TYPE}", "KERNEL")
|
||||
|
||||
ifdef USE_GCC
|
||||
|
||||
@ -362,13 +361,6 @@ endif # ifneq ("${dtraceFound}", "")
|
||||
|
||||
endif # ifdef USE_GCC
|
||||
|
||||
else # KERNEL build
|
||||
|
||||
dtraceCheck:
|
||||
$(QUIETLY) echo "**NOTICE** Dtrace support disabled for KERNEL builds"
|
||||
|
||||
endif # ifneq ("${TYPE}", "KERNEL")
|
||||
|
||||
else # CORE build
|
||||
|
||||
dtraceCheck:
|
||||
|
@ -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
|
@ -184,6 +184,7 @@ SUNWprivate_1.1 {
|
||||
JVM_IsSilentCompiler;
|
||||
JVM_IsSupportedJNIVersion;
|
||||
JVM_IsThreadAlive;
|
||||
JVM_IsVMGeneratedMethodIx;
|
||||
JVM_LatestUserDefinedLoader;
|
||||
JVM_Listen;
|
||||
JVM_LoadClass0;
|
||||
|
@ -1,6 +1,6 @@
|
||||
@echo off
|
||||
REM
|
||||
REM Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
REM Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
REM
|
||||
REM This code is free software; you can redistribute it and/or modify it
|
||||
@ -67,7 +67,6 @@ goto usage
|
||||
|
||||
:test1
|
||||
if "%2" == "core" goto test2
|
||||
if "%2" == "kernel" goto test2
|
||||
if "%2" == "compiler1" goto test2
|
||||
if "%2" == "compiler2" goto test2
|
||||
if "%2" == "tiered" goto test2
|
||||
@ -109,7 +108,7 @@ echo Usage: build flavor version workspace bootstrap_dir [build_id] [windbg_home
|
||||
echo.
|
||||
echo where:
|
||||
echo flavor is "product", "debug" or "fastdebug",
|
||||
echo version is "core", "kernel", "compiler1", "compiler2", or "tiered",
|
||||
echo version is "core", "compiler1", "compiler2", or "tiered",
|
||||
echo workspace is source directory without trailing slash,
|
||||
echo bootstrap_dir is a full path to a JDK in which bin/java
|
||||
echo and bin/javac are present and working, and build_id is an
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -107,7 +107,6 @@ COMPILER2_PATHS="${COMPILER2_PATHS} ${GENERATED}/adfiles"
|
||||
# Include dirs per type.
|
||||
case "${TYPE}" in
|
||||
"core") Src_Dirs="${CORE_PATHS}" ;;
|
||||
"kernel") Src_Dirs="${BASE_PATHS} ${COMPILER1_PATHS}" ;;
|
||||
"compiler1") Src_Dirs="${CORE_PATHS} ${COMPILER1_PATHS}" ;;
|
||||
"compiler2") Src_Dirs="${CORE_PATHS} ${COMPILER2_PATHS}" ;;
|
||||
"tiered") Src_Dirs="${CORE_PATHS} ${COMPILER1_PATHS} ${COMPILER2_PATHS}" ;;
|
||||
@ -120,16 +119,12 @@ COMPILER1_SPECIFIC_FILES="c1_*"
|
||||
SHARK_SPECIFIC_FILES="shark"
|
||||
ZERO_SPECIFIC_FILES="zero"
|
||||
|
||||
# These files need to be excluded when building the kernel target.
|
||||
KERNEL_EXCLUDED_FILES="attachListener.cpp attachListener_windows.cpp metaspaceShared_${Platform_arch_model}.cpp forte.cpp fprofiler.cpp heapDumper.cpp heapInspection.cpp jniCheck.cpp jvmtiCodeBlobEvents.cpp jvmtiExtensions.cpp jvmtiImpl.cpp jvmtiRawMonitor.cpp jvmtiTagMap.cpp jvmtiTrace.cpp vmStructs.cpp g1MemoryPool.cpp psMemoryPool.cpp gcAdaptivePolicyCounters.cpp concurrentGCThread.cpp metaspaceShared.cpp mutableNUMASpace.cpp allocationStats.cpp gSpaceCounters.cpp immutableSpace.cpp mutableSpace.cpp spaceCounters.cpp yieldingWorkgroup.cpp"
|
||||
|
||||
# Always exclude these.
|
||||
Src_Files_EXCLUDE="jsig.c jvmtiEnvRecommended.cpp jvmtiEnvStub.cpp"
|
||||
|
||||
# Exclude per type.
|
||||
case "${TYPE}" in
|
||||
"core") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER1_SPECIFIC_FILES} ${COMPILER2_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES} ciTypeFlow.cpp" ;;
|
||||
"kernel") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER2_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES} ${KERNEL_EXCLUDED_FILES} ciTypeFlow.cpp" ;;
|
||||
"compiler1") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER2_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES} ciTypeFlow.cpp" ;;
|
||||
"compiler2") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER1_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES}" ;;
|
||||
"tiered") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES}" ;;
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -157,7 +157,7 @@ endif
|
||||
MAKE_ARGS += RM="$(RM)"
|
||||
MAKE_ARGS += ZIPEXE=$(ZIPEXE)
|
||||
|
||||
# On 32 bit windows we build server, client and kernel, on 64 bit just server.
|
||||
# On 32 bit windows we build server and client, on 64 bit just server.
|
||||
ifeq ($(JVM_VARIANTS),)
|
||||
ifeq ($(ARCH_DATA_MODEL), 32)
|
||||
JVM_VARIANTS:=client,server
|
||||
@ -250,7 +250,6 @@ endif
|
||||
|
||||
EXPORT_SERVER_DIR = $(EXPORT_JRE_BIN_DIR)/server
|
||||
EXPORT_CLIENT_DIR = $(EXPORT_JRE_BIN_DIR)/client
|
||||
EXPORT_KERNEL_DIR = $(EXPORT_JRE_BIN_DIR)/kernel
|
||||
|
||||
ifeq ($(JVM_VARIANT_SERVER),true)
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
|
||||
@ -277,18 +276,6 @@ ifeq ($(JVM_VARIANT_CLIENT),true)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(JVM_VARIANT_KERNEL),true)
|
||||
EXPORT_LIST += $(EXPORT_KERNEL_DIR)/Xusage.txt
|
||||
EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.$(LIBRARY_SUFFIX)
|
||||
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
|
||||
ifeq ($(ZIP_DEBUGINFO_FILES),1)
|
||||
EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.diz
|
||||
else
|
||||
EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.pdb
|
||||
EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.map
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/wb.jar
|
||||
|
||||
|
@ -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
|
||||
@ -166,63 +166,6 @@ ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \
|
||||
$(ProjectCreatorIDEOptionsIgnoreCompiler1:TARGET=core) \
|
||||
$(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=core)
|
||||
|
||||
##################################################
|
||||
# JKERNEL specific options
|
||||
##################################################
|
||||
ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \
|
||||
-define_kernel KERNEL \
|
||||
$(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=kernel) \
|
||||
-ignorePath_kernel src/share/vm/gc_implementation/parallelScavenge \
|
||||
-ignorePath_kernel src/share/vm/gc_implementation/parNew \
|
||||
-ignorePath_kernel src/share/vm/gc_implementation/concurrentMarkSweep \
|
||||
-ignorePath_kernel src/share/vm/gc_implementation/g1 \
|
||||
-ignoreFile_kernel attachListener.cpp \
|
||||
-ignoreFile_kernel attachListener_windows.cpp \
|
||||
-ignoreFile_kernel dump.cpp \
|
||||
-ignoreFile_kernel dump_$(Platform_arch_model).cpp \
|
||||
-ignoreFile_kernel forte.cpp \
|
||||
-ignoreFile_kernel fprofiler.cpp \
|
||||
-ignoreFile_kernel heapDumper.cpp \
|
||||
-ignoreFile_kernel heapInspection.cpp \
|
||||
-ignoreFile_kernel jniCheck.cpp \
|
||||
-ignoreFile_kernel jvmtiCodeBlobEvents.cpp \
|
||||
-ignoreFile_kernel jvmtiExtensions.cpp \
|
||||
-ignoreFile_kernel jvmtiImpl.cpp \
|
||||
-ignoreFile_kernel jvmtiRawMonitor.cpp \
|
||||
-ignoreFile_kernel jvmtiTagMap.cpp \
|
||||
-ignoreFile_kernel jvmtiTrace.cpp \
|
||||
-ignoreFile_kernel jvmtiTrace.hpp \
|
||||
-ignoreFile_kernel restore.cpp \
|
||||
-ignoreFile_kernel serialize.cpp \
|
||||
-ignoreFile_kernel vmStructs.cpp \
|
||||
-ignoreFile_kernel g1MemoryPool.cpp \
|
||||
-ignoreFile_kernel g1MemoryPool.hpp \
|
||||
-ignoreFile_kernel psMemoryPool.cpp \
|
||||
-ignoreFile_kernel psMemoryPool.hpp \
|
||||
-ignoreFile_kernel gcAdaptivePolicyCounters.cpp \
|
||||
-ignoreFile_kernel concurrentGCThread.cpp \
|
||||
-ignoreFile_kernel mutableNUMASpace.cpp \
|
||||
-ignoreFile_kernel ciTypeFlow.cpp \
|
||||
-ignoreFile_kernel ciTypeFlow.hpp \
|
||||
-ignoreFile_kernel oop.pcgc.inline.hpp \
|
||||
-ignoreFile_kernel oop.psgc.inline.hpp \
|
||||
-ignoreFile_kernel allocationStats.cpp \
|
||||
-ignoreFile_kernel allocationStats.hpp \
|
||||
-ignoreFile_kernel concurrentGCThread.hpp \
|
||||
-ignoreFile_kernel gSpaceCounters.cpp \
|
||||
-ignoreFile_kernel gSpaceCounters.hpp \
|
||||
-ignoreFile_kernel gcAdaptivePolicyCounters.hpp \
|
||||
-ignoreFile_kernel immutableSpace.cpp \
|
||||
-ignoreFile_kernel mutableNUMASpace.hpp \
|
||||
-ignoreFile_kernel mutableSpace.cpp \
|
||||
-ignoreFile_kernel spaceCounters.cpp \
|
||||
-ignoreFile_kernel spaceCounters.hpp \
|
||||
-ignoreFile_kernel yieldingWorkgroup.cpp \
|
||||
-ignoreFile_kernel yieldingWorkgroup.hpp \
|
||||
-ignorePath_kernel vmStructs_ \
|
||||
-ignoreFile_kernel $(Platform_arch_model).ad \
|
||||
-additionalFile_kernel gcTaskManager.hpp
|
||||
|
||||
##################################################
|
||||
# Client(C1) compiler specific options
|
||||
##################################################
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -44,10 +44,6 @@ CXX_FLAGS=$(CXX_FLAGS) /D "ASSERT"
|
||||
# No need to define anything, CORE is defined as !COMPILER1 && !COMPILER2
|
||||
!endif
|
||||
|
||||
!if "$(Variant)" == "kernel"
|
||||
CXX_FLAGS=$(CXX_FLAGS) /D "KERNEL"
|
||||
!endif
|
||||
|
||||
!if "$(Variant)" == "compiler1"
|
||||
CXX_FLAGS=$(CXX_FLAGS) /D "COMPILER1"
|
||||
!endif
|
||||
|
@ -42,7 +42,7 @@ define_pd_global(bool, ProfileInterpreter, false);
|
||||
#else
|
||||
define_pd_global(bool, ProfileInterpreter, true);
|
||||
#endif // CC_INTERP
|
||||
define_pd_global(bool, TieredCompilation, trueInTiered);
|
||||
define_pd_global(bool, TieredCompilation, false);
|
||||
define_pd_global(intx, CompileThreshold, 10000);
|
||||
define_pd_global(intx, BackEdgeThreshold, 140000);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -543,7 +543,7 @@ class Assembler : public AbstractAssembler {
|
||||
// of instructions are freely declared without the need for wrapping them an ifdef.
|
||||
// (Some dangerous instructions are ifdef's out of inappropriate jvm's.)
|
||||
// In the .cpp file the implementations are wrapped so that they are dropped out
|
||||
// of the resulting jvm. This is done mostly to keep the footprint of KERNEL
|
||||
// of the resulting jvm. This is done mostly to keep the footprint of MINIMAL
|
||||
// to the size it was prior to merging up the 32bit and 64bit assemblers.
|
||||
//
|
||||
// This does mean you'll get a linker/runtime error if you use a 64bit only instruction
|
||||
|
@ -44,7 +44,7 @@ define_pd_global(bool, ProfileInterpreter, false);
|
||||
#else
|
||||
define_pd_global(bool, ProfileInterpreter, true);
|
||||
#endif // CC_INTERP
|
||||
define_pd_global(bool, TieredCompilation, trueInTiered);
|
||||
define_pd_global(bool, TieredCompilation, false);
|
||||
define_pd_global(intx, CompileThreshold, 10000);
|
||||
define_pd_global(intx, BackEdgeThreshold, 100000);
|
||||
|
||||
|
@ -1155,13 +1155,9 @@ void os::Linux::capture_initial_stack(size_t max_size) {
|
||||
// for initial thread if its stack size exceeds 6M. Cap it at 2M,
|
||||
// in case other parts in glibc still assumes 2M max stack size.
|
||||
// FIXME: alt signal stack is gone, maybe we can relax this constraint?
|
||||
#ifndef IA64
|
||||
if (stack_size > 2 * K * K) stack_size = 2 * K * K;
|
||||
#else
|
||||
// Problem still exists RH7.2 (IA64 anyway) but 2MB is a little small
|
||||
if (stack_size > 4 * K * K) stack_size = 4 * K * K;
|
||||
#endif
|
||||
|
||||
if (stack_size > 2 * K * K IA64_ONLY(*2))
|
||||
stack_size = 2 * K * K IA64_ONLY(*2);
|
||||
// Try to figure out where the stack base (top) is. This is harder.
|
||||
//
|
||||
// When an application is started, glibc saves the initial stack pointer in
|
||||
@ -4367,16 +4363,12 @@ int os::Linux::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mute
|
||||
if (is_NPTL()) {
|
||||
return pthread_cond_timedwait(_cond, _mutex, _abstime);
|
||||
} else {
|
||||
#ifndef IA64
|
||||
// 6292965: LinuxThreads pthread_cond_timedwait() resets FPU control
|
||||
// word back to default 64bit precision if condvar is signaled. Java
|
||||
// wants 53bit precision. Save and restore current value.
|
||||
int fpu = get_fpu_control_word();
|
||||
#endif // IA64
|
||||
int status = pthread_cond_timedwait(_cond, _mutex, _abstime);
|
||||
#ifndef IA64
|
||||
set_fpu_control_word(fpu);
|
||||
#endif // IA64
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
@ -349,6 +349,33 @@ address os::current_stack_base() {
|
||||
|
||||
#ifdef _M_IA64
|
||||
// IA64 has memory and register stacks
|
||||
//
|
||||
// This is the stack layout you get on NT/IA64 if you specify 1MB stack limit
|
||||
// at thread creation (1MB backing store growing upwards, 1MB memory stack
|
||||
// growing downwards, 2MB summed up)
|
||||
//
|
||||
// ...
|
||||
// ------- top of stack (high address) -----
|
||||
// |
|
||||
// | 1MB
|
||||
// | Backing Store (Register Stack)
|
||||
// |
|
||||
// | / \
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// ------------------------ stack base -----
|
||||
// | 1MB
|
||||
// | Memory Stack
|
||||
// |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// | \ /
|
||||
// |
|
||||
// ----- bottom of stack (low address) -----
|
||||
// ...
|
||||
|
||||
stack_size = stack_size / 2;
|
||||
#endif
|
||||
return stack_bottom + stack_size;
|
||||
@ -2005,17 +2032,34 @@ LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo, address handler
|
||||
JavaThread* thread = JavaThread::current();
|
||||
// Save pc in thread
|
||||
#ifdef _M_IA64
|
||||
thread->set_saved_exception_pc((address)exceptionInfo->ContextRecord->StIIP);
|
||||
// Do not blow up if no thread info available.
|
||||
if (thread) {
|
||||
// Saving PRECISE pc (with slot information) in thread.
|
||||
uint64_t precise_pc = (uint64_t) exceptionInfo->ExceptionRecord->ExceptionAddress;
|
||||
// Convert precise PC into "Unix" format
|
||||
precise_pc = (precise_pc & 0xFFFFFFFFFFFFFFF0) | ((precise_pc & 0xF) >> 2);
|
||||
thread->set_saved_exception_pc((address)precise_pc);
|
||||
}
|
||||
// Set pc to handler
|
||||
exceptionInfo->ContextRecord->StIIP = (DWORD64)handler;
|
||||
// Clear out psr.ri (= Restart Instruction) in order to continue
|
||||
// at the beginning of the target bundle.
|
||||
exceptionInfo->ContextRecord->StIPSR &= 0xFFFFF9FFFFFFFFFF;
|
||||
assert(((DWORD64)handler & 0xF) == 0, "Target address must point to the beginning of a bundle!");
|
||||
#elif _M_AMD64
|
||||
thread->set_saved_exception_pc((address)exceptionInfo->ContextRecord->Rip);
|
||||
// Do not blow up if no thread info available.
|
||||
if (thread) {
|
||||
thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip);
|
||||
}
|
||||
// Set pc to handler
|
||||
exceptionInfo->ContextRecord->Rip = (DWORD64)handler;
|
||||
#else
|
||||
thread->set_saved_exception_pc((address)exceptionInfo->ContextRecord->Eip);
|
||||
// Do not blow up if no thread info available.
|
||||
if (thread) {
|
||||
thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Eip);
|
||||
}
|
||||
// Set pc to handler
|
||||
exceptionInfo->ContextRecord->Eip = (LONG)handler;
|
||||
exceptionInfo->ContextRecord->Eip = (DWORD)(DWORD_PTR)handler;
|
||||
#endif
|
||||
|
||||
// Continue the execution
|
||||
@ -2040,6 +2084,14 @@ extern "C" void events();
|
||||
// included or copied here.
|
||||
#define EXCEPTION_INFO_EXEC_VIOLATION 0x08
|
||||
|
||||
// Handle NAT Bit consumption on IA64.
|
||||
#ifdef _M_IA64
|
||||
#define EXCEPTION_REG_NAT_CONSUMPTION STATUS_REG_NAT_CONSUMPTION
|
||||
#endif
|
||||
|
||||
// Windows Vista/2008 heap corruption check
|
||||
#define EXCEPTION_HEAP_CORRUPTION 0xC0000374
|
||||
|
||||
#define def_excpt(val) #val, val
|
||||
|
||||
struct siglabel {
|
||||
@ -2082,6 +2134,10 @@ struct siglabel exceptlabels[] = {
|
||||
def_excpt(EXCEPTION_GUARD_PAGE),
|
||||
def_excpt(EXCEPTION_INVALID_HANDLE),
|
||||
def_excpt(EXCEPTION_UNCAUGHT_CXX_EXCEPTION),
|
||||
def_excpt(EXCEPTION_HEAP_CORRUPTION),
|
||||
#ifdef _M_IA64
|
||||
def_excpt(EXCEPTION_REG_NAT_CONSUMPTION),
|
||||
#endif
|
||||
NULL, 0
|
||||
};
|
||||
|
||||
@ -2206,7 +2262,14 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
|
||||
if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH;
|
||||
DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
|
||||
#ifdef _M_IA64
|
||||
address pc = (address) exceptionInfo->ContextRecord->StIIP;
|
||||
// On Itanium, we need the "precise pc", which has the slot number coded
|
||||
// into the least 4 bits: 0000=slot0, 0100=slot1, 1000=slot2 (Windows format).
|
||||
address pc = (address) exceptionInfo->ExceptionRecord->ExceptionAddress;
|
||||
// Convert the pc to "Unix format", which has the slot number coded
|
||||
// into the least 2 bits: 0000=slot0, 0001=slot1, 0010=slot2
|
||||
// This is needed for IA64 because "relocation" / "implicit null check" / "poll instruction"
|
||||
// information is saved in the Unix format.
|
||||
address pc_unix_format = (address) ((((uint64_t)pc) & 0xFFFFFFFFFFFFFFF0) | ((((uint64_t)pc) & 0xF) >> 2));
|
||||
#elif _M_AMD64
|
||||
address pc = (address) exceptionInfo->ContextRecord->Rip;
|
||||
#else
|
||||
@ -2321,29 +2384,40 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
|
||||
if (exception_code == EXCEPTION_STACK_OVERFLOW) {
|
||||
if (os::uses_stack_guard_pages()) {
|
||||
#ifdef _M_IA64
|
||||
//
|
||||
// If it's a legal stack address continue, Windows will map it in.
|
||||
//
|
||||
// Use guard page for register stack.
|
||||
PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
|
||||
address addr = (address) exceptionRecord->ExceptionInformation[1];
|
||||
if (addr > thread->stack_yellow_zone_base() && addr < thread->stack_base() )
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
// Check for a register stack overflow on Itanium
|
||||
if (thread->addr_inside_register_stack_red_zone(addr)) {
|
||||
// Fatal red zone violation happens if the Java program
|
||||
// catches a StackOverflow error and does so much processing
|
||||
// that it runs beyond the unprotected yellow guard zone. As
|
||||
// a result, we are out of here.
|
||||
fatal("ERROR: Unrecoverable stack overflow happened. JVM will exit.");
|
||||
} else if(thread->addr_inside_register_stack(addr)) {
|
||||
// Disable the yellow zone which sets the state that
|
||||
// we've got a stack overflow problem.
|
||||
if (thread->stack_yellow_zone_enabled()) {
|
||||
thread->disable_stack_yellow_zone();
|
||||
}
|
||||
// Give us some room to process the exception.
|
||||
thread->disable_register_stack_guard();
|
||||
// Tracing with +Verbose.
|
||||
if (Verbose) {
|
||||
tty->print_cr("SOF Compiled Register Stack overflow at " INTPTR_FORMAT " (SIGSEGV)", pc);
|
||||
tty->print_cr("Register Stack access at " INTPTR_FORMAT, addr);
|
||||
tty->print_cr("Register Stack base " INTPTR_FORMAT, thread->register_stack_base());
|
||||
tty->print_cr("Register Stack [" INTPTR_FORMAT "," INTPTR_FORMAT "]",
|
||||
thread->register_stack_base(),
|
||||
thread->register_stack_base() + thread->stack_size());
|
||||
}
|
||||
|
||||
// The register save area is the same size as the memory stack
|
||||
// and starts at the page just above the start of the memory stack.
|
||||
// If we get a fault in this area, we've run out of register
|
||||
// stack. If we are in java, try throwing a stack overflow exception.
|
||||
if (addr > thread->stack_base() &&
|
||||
addr <= (thread->stack_base()+thread->stack_size()) ) {
|
||||
char buf[256];
|
||||
jio_snprintf(buf, sizeof(buf),
|
||||
"Register stack overflow, addr:%p, stack_base:%p\n",
|
||||
addr, thread->stack_base() );
|
||||
tty->print_raw_cr(buf);
|
||||
// If not in java code, return and hope for the best.
|
||||
return in_java ? Handle_Exception(exceptionInfo,
|
||||
SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW))
|
||||
: EXCEPTION_CONTINUE_EXECUTION;
|
||||
// Reguard the permanent register stack red zone just to be sure.
|
||||
// We saw Windows silently disabling this without telling us.
|
||||
thread->enable_register_stack_red_zone();
|
||||
|
||||
return Handle_Exception(exceptionInfo,
|
||||
SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW));
|
||||
}
|
||||
#endif
|
||||
if (thread->stack_yellow_zone_enabled()) {
|
||||
@ -2418,50 +2492,33 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
|
||||
{
|
||||
// Null pointer exception.
|
||||
#ifdef _M_IA64
|
||||
// We catch register stack overflows in compiled code by doing
|
||||
// an explicit compare and executing a st8(G0, G0) if the
|
||||
// BSP enters into our guard area. We test for the overflow
|
||||
// condition and fall into the normal null pointer exception
|
||||
// code if BSP hasn't overflowed.
|
||||
if ( in_java ) {
|
||||
if(thread->register_stack_overflow()) {
|
||||
assert((address)exceptionInfo->ContextRecord->IntS3 ==
|
||||
thread->register_stack_limit(),
|
||||
"GR7 doesn't contain register_stack_limit");
|
||||
// Disable the yellow zone which sets the state that
|
||||
// we've got a stack overflow problem.
|
||||
if (thread->stack_yellow_zone_enabled()) {
|
||||
thread->disable_stack_yellow_zone();
|
||||
// Process implicit null checks in compiled code. Note: Implicit null checks
|
||||
// can happen even if "ImplicitNullChecks" is disabled, e.g. in vtable stubs.
|
||||
if (CodeCache::contains((void*) pc_unix_format) && !MacroAssembler::needs_explicit_null_check((intptr_t) addr)) {
|
||||
CodeBlob *cb = CodeCache::find_blob_unsafe(pc_unix_format);
|
||||
// Handle implicit null check in UEP method entry
|
||||
if (cb && (cb->is_frame_complete_at(pc) ||
|
||||
(cb->is_nmethod() && ((nmethod *)cb)->inlinecache_check_contains(pc)))) {
|
||||
if (Verbose) {
|
||||
intptr_t *bundle_start = (intptr_t*) ((intptr_t) pc_unix_format & 0xFFFFFFFFFFFFFFF0);
|
||||
tty->print_cr("trap: null_check at " INTPTR_FORMAT " (SIGSEGV)", pc_unix_format);
|
||||
tty->print_cr(" to addr " INTPTR_FORMAT, addr);
|
||||
tty->print_cr(" bundle is " INTPTR_FORMAT " (high), " INTPTR_FORMAT " (low)",
|
||||
*(bundle_start + 1), *bundle_start);
|
||||
}
|
||||
// Give us some room to process the exception
|
||||
thread->disable_register_stack_guard();
|
||||
// Update GR7 with the new limit so we can continue running
|
||||
// compiled code.
|
||||
exceptionInfo->ContextRecord->IntS3 =
|
||||
(ULONGLONG)thread->register_stack_limit();
|
||||
return Handle_Exception(exceptionInfo,
|
||||
SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW));
|
||||
} else {
|
||||
//
|
||||
// Check for implicit null
|
||||
// We only expect null pointers in the stubs (vtable)
|
||||
// the rest are checked explicitly now.
|
||||
//
|
||||
if (((uintptr_t)addr) < os::vm_page_size() ) {
|
||||
// an access to the first page of VM--assume it is a null pointer
|
||||
address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
|
||||
if (stub != NULL) return Handle_Exception(exceptionInfo, stub);
|
||||
}
|
||||
SharedRuntime::continuation_for_implicit_exception(thread, pc_unix_format, SharedRuntime::IMPLICIT_NULL));
|
||||
}
|
||||
} // in_java
|
||||
}
|
||||
|
||||
// IA64 doesn't use implicit null checking yet. So we shouldn't
|
||||
// get here.
|
||||
tty->print_raw_cr("Access violation, possible null pointer exception");
|
||||
// Implicit null checks were processed above. Hence, we should not reach
|
||||
// here in the usual case => die!
|
||||
if (Verbose) tty->print_raw_cr("Access violation, possible null pointer exception");
|
||||
report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
|
||||
exceptionInfo->ContextRecord);
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
#else /* !IA64 */
|
||||
|
||||
#else // !IA64
|
||||
|
||||
// Windows 98 reports faulting addresses incorrectly
|
||||
if (!MacroAssembler::needs_explicit_null_check((intptr_t)addr) ||
|
||||
@ -2493,7 +2550,24 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
|
||||
report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
|
||||
exceptionInfo->ContextRecord);
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
} // /EXCEPTION_ACCESS_VIOLATION
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
#if defined _M_IA64
|
||||
else if ((exception_code == EXCEPTION_ILLEGAL_INSTRUCTION ||
|
||||
exception_code == EXCEPTION_ILLEGAL_INSTRUCTION_2)) {
|
||||
M37 handle_wrong_method_break(0, NativeJump::HANDLE_WRONG_METHOD, PR0);
|
||||
|
||||
// Compiled method patched to be non entrant? Following conditions must apply:
|
||||
// 1. must be first instruction in bundle
|
||||
// 2. must be a break instruction with appropriate code
|
||||
if((((uint64_t) pc & 0x0F) == 0) &&
|
||||
(((IPF_Bundle*) pc)->get_slot0() == handle_wrong_method_break.bits())) {
|
||||
return Handle_Exception(exceptionInfo,
|
||||
(address)SharedRuntime::get_handle_wrong_method_stub());
|
||||
}
|
||||
} // /EXCEPTION_ILLEGAL_INSTRUCTION
|
||||
#endif
|
||||
|
||||
|
||||
if (in_java) {
|
||||
switch (exception_code) {
|
||||
|
@ -372,7 +372,7 @@ frame os::current_frame() {
|
||||
CAST_FROM_FN_PTR(address, os::current_frame));
|
||||
if (os::is_first_C_frame(&myframe)) {
|
||||
// stack is not walkable
|
||||
return frame(NULL, NULL, NULL);
|
||||
return frame();
|
||||
} else {
|
||||
return os::get_sender_for_C_frame(&myframe);
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ frame os::current_frame() {
|
||||
CAST_FROM_FN_PTR(address, os::current_frame));
|
||||
if (os::is_first_C_frame(&myframe)) {
|
||||
// stack is not walkable
|
||||
return frame(NULL, NULL, NULL);
|
||||
return frame();
|
||||
} else {
|
||||
return os::get_sender_for_C_frame(&myframe);
|
||||
}
|
||||
|
@ -399,7 +399,7 @@ frame os::current_frame() {
|
||||
typedef intptr_t* get_fp_func ();
|
||||
get_fp_func* func = CAST_TO_FN_PTR(get_fp_func*,
|
||||
StubRoutines::x86::get_previous_fp_entry());
|
||||
if (func == NULL) return frame(NULL, NULL, NULL);
|
||||
if (func == NULL) return frame();
|
||||
intptr_t* fp = (*func)();
|
||||
#else
|
||||
intptr_t* fp = _get_previous_fp();
|
||||
@ -410,7 +410,7 @@ frame os::current_frame() {
|
||||
CAST_FROM_FN_PTR(address, os::current_frame));
|
||||
if (os::is_first_C_frame(&myframe)) {
|
||||
// stack is not walkable
|
||||
return frame(NULL, NULL, NULL);
|
||||
return frame();
|
||||
} else {
|
||||
return os::get_sender_for_C_frame(&myframe);
|
||||
}
|
||||
|
@ -76,4 +76,9 @@ public class WhiteBox {
|
||||
public native long g1NumFreeRegions();
|
||||
public native int g1RegionSize();
|
||||
public native Object[] parseCommandLine(String commandline, DiagnosticCommand[] args);
|
||||
|
||||
// NMT
|
||||
public native boolean NMTAllocTest();
|
||||
public native boolean NMTFreeTestMemory();
|
||||
public native boolean NMTWaitForDataMerge();
|
||||
}
|
||||
|
@ -168,7 +168,7 @@ void ADLParser::instr_parse(void) {
|
||||
// Check for block delimiter
|
||||
if ( (_curchar != '%')
|
||||
|| ( next_char(), (_curchar != '{')) ) {
|
||||
parse_err(SYNERR, "missing '%{' in instruction definition\n");
|
||||
parse_err(SYNERR, "missing '%%{' in instruction definition\n");
|
||||
return;
|
||||
}
|
||||
next_char(); // Maintain the invariant
|
||||
@ -253,7 +253,7 @@ void ADLParser::instr_parse(void) {
|
||||
} while(_curchar != '%');
|
||||
next_char();
|
||||
if (_curchar != '}') {
|
||||
parse_err(SYNERR, "missing '%}' in instruction definition\n");
|
||||
parse_err(SYNERR, "missing '%%}' in instruction definition\n");
|
||||
return;
|
||||
}
|
||||
// Check for "Set" form of chain rule
|
||||
@ -423,7 +423,7 @@ void ADLParser::oper_parse(void) {
|
||||
skipws();
|
||||
// Check for block delimiter
|
||||
if ((_curchar != '%') || (*(_ptr+1) != '{')) { // If not open block
|
||||
parse_err(SYNERR, "missing '%c{' in operand definition\n","%");
|
||||
parse_err(SYNERR, "missing '%%{' in operand definition\n");
|
||||
return;
|
||||
}
|
||||
next_char(); next_char(); // Skip over "%{" symbol
|
||||
@ -483,7 +483,7 @@ void ADLParser::oper_parse(void) {
|
||||
} while(_curchar != '%');
|
||||
next_char();
|
||||
if (_curchar != '}') {
|
||||
parse_err(SYNERR, "missing '%}' in operand definition\n");
|
||||
parse_err(SYNERR, "missing '%%}' in operand definition\n");
|
||||
return;
|
||||
}
|
||||
// Add operand to tail of operand list
|
||||
@ -1324,7 +1324,7 @@ void ADLParser::pipe_parse(void) {
|
||||
// Check for block delimiter
|
||||
if ( (_curchar != '%')
|
||||
|| ( next_char(), (_curchar != '{')) ) {
|
||||
parse_err(SYNERR, "missing '%{' in pipeline definition\n");
|
||||
parse_err(SYNERR, "missing '%%{' in pipeline definition\n");
|
||||
return;
|
||||
}
|
||||
next_char(); // Maintain the invariant
|
||||
@ -1341,7 +1341,7 @@ void ADLParser::pipe_parse(void) {
|
||||
skipws();
|
||||
if ( (_curchar != '%')
|
||||
|| ( next_char(), (_curchar != '{')) ) {
|
||||
parse_err(SYNERR, "expected '%{'\n");
|
||||
parse_err(SYNERR, "expected '%%{'\n");
|
||||
return;
|
||||
}
|
||||
next_char(); skipws();
|
||||
@ -1397,7 +1397,7 @@ void ADLParser::pipe_parse(void) {
|
||||
skipws();
|
||||
if ( (_curchar != '%')
|
||||
|| ( next_char(), (_curchar != '{')) ) {
|
||||
parse_err(SYNERR, "expected '%{'\n");
|
||||
parse_err(SYNERR, "expected '%%{'\n");
|
||||
return;
|
||||
}
|
||||
next_char(); skipws();
|
||||
@ -1586,7 +1586,7 @@ void ADLParser::pipe_parse(void) {
|
||||
|
||||
if ( (_curchar != '%')
|
||||
|| ( next_char(), (_curchar != '}')) ) {
|
||||
parse_err(SYNERR, "expected '%}', found \"%c\"\n", _curchar);
|
||||
parse_err(SYNERR, "expected '%%}', found \"%c\"\n", _curchar);
|
||||
}
|
||||
next_char(); skipws();
|
||||
|
||||
@ -1612,7 +1612,7 @@ void ADLParser::pipe_parse(void) {
|
||||
|
||||
next_char();
|
||||
if (_curchar != '}') {
|
||||
parse_err(SYNERR, "missing \"%}\" in pipeline definition\n");
|
||||
parse_err(SYNERR, "missing \"%%}\" in pipeline definition\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1775,7 +1775,7 @@ void ADLParser::pipe_class_parse(PipelineForm &pipeline) {
|
||||
// Check for block delimiter
|
||||
if ( (_curchar != '%')
|
||||
|| ( next_char(), (_curchar != '{')) ) {
|
||||
parse_err(SYNERR, "missing \"%{\" in pipe_class definition\n");
|
||||
parse_err(SYNERR, "missing \"%%{\" in pipe_class definition\n");
|
||||
return;
|
||||
}
|
||||
next_char();
|
||||
@ -2062,7 +2062,7 @@ void ADLParser::pipe_class_parse(PipelineForm &pipeline) {
|
||||
|
||||
next_char();
|
||||
if (_curchar != '}') {
|
||||
parse_err(SYNERR, "missing \"%}\" in pipe_class definition\n");
|
||||
parse_err(SYNERR, "missing \"%%}\" in pipe_class definition\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3341,12 +3341,12 @@ Interface *ADLParser::mem_interface_parse(void) {
|
||||
char *disp = NULL;
|
||||
|
||||
if (_curchar != '%') {
|
||||
parse_err(SYNERR, "Missing '%{' for 'interface' block.\n");
|
||||
parse_err(SYNERR, "Missing '%%{' for 'interface' block.\n");
|
||||
return NULL;
|
||||
}
|
||||
next_char(); // Skip '%'
|
||||
if (_curchar != '{') {
|
||||
parse_err(SYNERR, "Missing '%{' for 'interface' block.\n");
|
||||
parse_err(SYNERR, "Missing '%%{' for 'interface' block.\n");
|
||||
return NULL;
|
||||
}
|
||||
next_char(); // Skip '{'
|
||||
@ -3354,7 +3354,7 @@ Interface *ADLParser::mem_interface_parse(void) {
|
||||
do {
|
||||
char *field = get_ident();
|
||||
if (field == NULL) {
|
||||
parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n");
|
||||
parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%%}' ending interface.\n");
|
||||
return NULL;
|
||||
}
|
||||
if ( strcmp(field,"base") == 0 ) {
|
||||
@ -3370,13 +3370,13 @@ Interface *ADLParser::mem_interface_parse(void) {
|
||||
disp = interface_field_parse();
|
||||
}
|
||||
else {
|
||||
parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n");
|
||||
parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%%}' ending interface.\n");
|
||||
return NULL;
|
||||
}
|
||||
} while( _curchar != '%' );
|
||||
next_char(); // Skip '%'
|
||||
if ( _curchar != '}' ) {
|
||||
parse_err(SYNERR, "Missing '%}' for 'interface' block.\n");
|
||||
parse_err(SYNERR, "Missing '%%}' for 'interface' block.\n");
|
||||
return NULL;
|
||||
}
|
||||
next_char(); // Skip '}'
|
||||
@ -3403,12 +3403,12 @@ Interface *ADLParser::cond_interface_parse(void) {
|
||||
const char *greater_format = "gt";
|
||||
|
||||
if (_curchar != '%') {
|
||||
parse_err(SYNERR, "Missing '%{' for 'cond_interface' block.\n");
|
||||
parse_err(SYNERR, "Missing '%%{' for 'cond_interface' block.\n");
|
||||
return NULL;
|
||||
}
|
||||
next_char(); // Skip '%'
|
||||
if (_curchar != '{') {
|
||||
parse_err(SYNERR, "Missing '%{' for 'cond_interface' block.\n");
|
||||
parse_err(SYNERR, "Missing '%%{' for 'cond_interface' block.\n");
|
||||
return NULL;
|
||||
}
|
||||
next_char(); // Skip '{'
|
||||
@ -3416,7 +3416,7 @@ Interface *ADLParser::cond_interface_parse(void) {
|
||||
do {
|
||||
char *field = get_ident();
|
||||
if (field == NULL) {
|
||||
parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n");
|
||||
parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%%}' ending interface.\n");
|
||||
return NULL;
|
||||
}
|
||||
if ( strcmp(field,"equal") == 0 ) {
|
||||
@ -3438,13 +3438,13 @@ Interface *ADLParser::cond_interface_parse(void) {
|
||||
greater = interface_field_parse(&greater_format);
|
||||
}
|
||||
else {
|
||||
parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n");
|
||||
parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%%}' ending interface.\n");
|
||||
return NULL;
|
||||
}
|
||||
} while( _curchar != '%' );
|
||||
next_char(); // Skip '%'
|
||||
if ( _curchar != '}' ) {
|
||||
parse_err(SYNERR, "Missing '%}' for 'interface' block.\n");
|
||||
parse_err(SYNERR, "Missing '%%}' for 'interface' block.\n");
|
||||
return NULL;
|
||||
}
|
||||
next_char(); // Skip '}'
|
||||
@ -3543,7 +3543,7 @@ MatchRule *ADLParser::match_parse(FormDict &operands) {
|
||||
}
|
||||
else if ((cnstr = find_cpp_block("match constructor")) == NULL ) {
|
||||
parse_err(SYNERR, "invalid construction of match rule\n"
|
||||
"Missing ';' or invalid '%{' and '%}' constructor\n");
|
||||
"Missing ';' or invalid '%%{' and '%%}' constructor\n");
|
||||
return NULL; // No MatchRule to return
|
||||
}
|
||||
if (_AD._adl_debug > 1)
|
||||
@ -3646,7 +3646,7 @@ FormatRule* ADLParser::format_parse(void) {
|
||||
// Check for closing '"' and '%}' in format description
|
||||
skipws(); // Move to closing '%}'
|
||||
if ( _curchar != '%' ) {
|
||||
parse_err(SYNERR, "non-blank characters between closing '\"' and '%' in format");
|
||||
parse_err(SYNERR, "non-blank characters between closing '\"' and '%%' in format");
|
||||
return NULL;
|
||||
}
|
||||
} // Done with format description inside
|
||||
@ -3654,7 +3654,7 @@ FormatRule* ADLParser::format_parse(void) {
|
||||
skipws();
|
||||
// Past format description, at '%'
|
||||
if ( _curchar != '%' || *(_ptr+1) != '}' ) {
|
||||
parse_err(SYNERR, "missing '%}' at end of format block");
|
||||
parse_err(SYNERR, "missing '%%}' at end of format block");
|
||||
return NULL;
|
||||
}
|
||||
next_char(); // Move past the '%'
|
||||
@ -3785,7 +3785,7 @@ FormatRule* ADLParser::template_parse(void) {
|
||||
skipws();
|
||||
// Past format description, at '%'
|
||||
if ( _curchar != '%' || *(_ptr+1) != '}' ) {
|
||||
parse_err(SYNERR, "missing '%}' at end of format block");
|
||||
parse_err(SYNERR, "missing '%%}' at end of format block");
|
||||
return NULL;
|
||||
}
|
||||
next_char(); // Move past the '%'
|
||||
@ -3834,7 +3834,7 @@ ExpandRule* ADLParser::expand_parse(InstructForm *instr) {
|
||||
skipws(); // Skip leading whitespace
|
||||
if ((_curchar != '%')
|
||||
|| (next_char(), (_curchar != '{')) ) { // If not open block
|
||||
parse_err(SYNERR, "missing '%{' in expand definition\n");
|
||||
parse_err(SYNERR, "missing '%%{' in expand definition\n");
|
||||
return(NULL);
|
||||
}
|
||||
next_char(); // Maintain the invariant
|
||||
@ -3933,7 +3933,7 @@ ExpandRule* ADLParser::expand_parse(InstructForm *instr) {
|
||||
} while(_curchar != '%');
|
||||
next_char();
|
||||
if (_curchar != '}') {
|
||||
parse_err(SYNERR, "missing '%}' in expand rule definition\n");
|
||||
parse_err(SYNERR, "missing '%%}' in expand rule definition\n");
|
||||
return(NULL);
|
||||
}
|
||||
next_char();
|
||||
|
@ -3667,11 +3667,12 @@ bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, Bytecode
|
||||
}
|
||||
|
||||
// now perform tests that are based on flag settings
|
||||
if (callee->force_inline() || callee->should_inline()) {
|
||||
// ignore heuristic controls on inlining
|
||||
if (callee->force_inline())
|
||||
print_inlining(callee, "force inline by annotation");
|
||||
if (callee->force_inline()) {
|
||||
print_inlining(callee, "force inline by annotation");
|
||||
} else if (callee->should_inline()) {
|
||||
print_inlining(callee, "force inline by CompileOracle");
|
||||
} else {
|
||||
// use heuristic controls on inlining
|
||||
if (inline_level() > MaxInlineLevel ) INLINE_BAILOUT("inlining too deep");
|
||||
if (recursive_inline_level(callee) > MaxRecursiveInlineLevel) INLINE_BAILOUT("recursive inlining too deep");
|
||||
if (callee->code_size_for_inlining() > max_inline_size() ) INLINE_BAILOUT("callee is too large");
|
||||
|
@ -188,7 +188,7 @@ ciType* LoadIndexed::exact_type() const {
|
||||
|
||||
ciType* LoadIndexed::declared_type() const {
|
||||
ciType* array_type = array()->declared_type();
|
||||
if (array_type == NULL) {
|
||||
if (array_type == NULL || !array_type->is_loaded()) {
|
||||
return NULL;
|
||||
}
|
||||
assert(array_type->is_array_klass(), "what else?");
|
||||
|
@ -1168,7 +1168,7 @@ void ciEnv::dump_replay_data() {
|
||||
|
||||
void ciEnv::dump_replay_data(outputStream* out) {
|
||||
ASSERT_IN_VM;
|
||||
|
||||
ResourceMark rm;
|
||||
#if INCLUDE_JVMTI
|
||||
out->print_cr("JvmtiExport can_access_local_variables %d", _jvmti_can_access_local_variables);
|
||||
out->print_cr("JvmtiExport can_hotswap_or_post_breakpoint %d", _jvmti_can_hotswap_or_post_breakpoint);
|
||||
|
@ -580,6 +580,7 @@ class StaticFinalFieldPrinter : public FieldClosure {
|
||||
}
|
||||
void do_field(fieldDescriptor* fd) {
|
||||
if (fd->is_final() && !fd->has_initial_value()) {
|
||||
ResourceMark rm;
|
||||
oop mirror = fd->field_holder()->java_mirror();
|
||||
_out->print("staticfield %s %s %s ", _holder, fd->name()->as_quoted_ascii(), fd->signature()->as_quoted_ascii());
|
||||
switch (fd->field_type()) {
|
||||
@ -643,6 +644,8 @@ class StaticFinalFieldPrinter : public FieldClosure {
|
||||
|
||||
void ciInstanceKlass::dump_replay_data(outputStream* out) {
|
||||
ASSERT_IN_VM;
|
||||
ResourceMark rm;
|
||||
|
||||
InstanceKlass* ik = get_instanceKlass();
|
||||
ConstantPool* cp = ik->constants();
|
||||
|
||||
|
@ -977,7 +977,7 @@ bool ciMethod::can_be_compiled() {
|
||||
// ciMethod::set_not_compilable
|
||||
//
|
||||
// Tell the VM that this method cannot be compiled at all.
|
||||
void ciMethod::set_not_compilable() {
|
||||
void ciMethod::set_not_compilable(const char* reason) {
|
||||
check_is_loaded();
|
||||
VM_ENTRY_MARK;
|
||||
ciEnv* env = CURRENT_ENV;
|
||||
@ -986,7 +986,7 @@ void ciMethod::set_not_compilable() {
|
||||
} else {
|
||||
_is_c2_compilable = false;
|
||||
}
|
||||
get_Method()->set_not_compilable(env->comp_level());
|
||||
get_Method()->set_not_compilable(env->comp_level(), true, reason);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
@ -1178,6 +1178,7 @@ ciMethodBlocks *ciMethod::get_method_blocks() {
|
||||
|
||||
void ciMethod::dump_replay_data(outputStream* st) {
|
||||
ASSERT_IN_VM;
|
||||
ResourceMark rm;
|
||||
Method* method = get_Method();
|
||||
Klass* holder = method->method_holder();
|
||||
st->print_cr("ciMethod %s %s %s %d %d %d %d %d",
|
||||
|
@ -252,7 +252,7 @@ class ciMethod : public ciMetadata {
|
||||
bool has_option(const char *option);
|
||||
bool can_be_compiled();
|
||||
bool can_be_osr_compiled(int entry_bci);
|
||||
void set_not_compilable();
|
||||
void set_not_compilable(const char* reason = NULL);
|
||||
bool has_compiled_code();
|
||||
void log_nmethod_identity(xmlStream* log);
|
||||
bool is_not_reached(int bci);
|
||||
|
@ -374,6 +374,7 @@ void ciMethodData::print_impl(outputStream* st) {
|
||||
|
||||
void ciMethodData::dump_replay_data(outputStream* out) {
|
||||
ASSERT_IN_VM;
|
||||
ResourceMark rm;
|
||||
MethodData* mdo = get_MethodData();
|
||||
Method* method = mdo->method();
|
||||
Klass* holder = method->method_holder();
|
||||
|
@ -1947,6 +1947,8 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
|
||||
u2** localvariable_type_table_start;
|
||||
u2 method_parameters_length = 0;
|
||||
u1* method_parameters_data = NULL;
|
||||
bool method_parameters_seen = false;
|
||||
bool method_parameters_four_byte_flags;
|
||||
bool parsed_code_attribute = false;
|
||||
bool parsed_checked_exceptions_attribute = false;
|
||||
bool parsed_stackmap_attribute = false;
|
||||
@ -2157,22 +2159,32 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
|
||||
method_attribute_length,
|
||||
cp, CHECK_(nullHandle));
|
||||
} else if (method_attribute_name == vmSymbols::tag_method_parameters()) {
|
||||
// reject multiple method parameters
|
||||
if (method_parameters_seen) {
|
||||
classfile_parse_error("Multiple MethodParameters attributes in class file %s", CHECK_(nullHandle));
|
||||
}
|
||||
method_parameters_seen = true;
|
||||
method_parameters_length = cfs->get_u1_fast();
|
||||
// Track the actual size (note: this is written for clarity; a
|
||||
// decent compiler will CSE and constant-fold this into a single
|
||||
// expression)
|
||||
u2 actual_size = 1;
|
||||
method_parameters_data = cfs->get_u1_buffer();
|
||||
actual_size += 2 * method_parameters_length;
|
||||
cfs->skip_u2_fast(method_parameters_length);
|
||||
actual_size += 4 * method_parameters_length;
|
||||
cfs->skip_u4_fast(method_parameters_length);
|
||||
// Enforce attribute length
|
||||
if (method_attribute_length != actual_size) {
|
||||
// Use the attribute length to figure out the size of flags
|
||||
if (method_attribute_length == (method_parameters_length * 6u) + 1u) {
|
||||
method_parameters_four_byte_flags = true;
|
||||
} else if (method_attribute_length == (method_parameters_length * 4u) + 1u) {
|
||||
method_parameters_four_byte_flags = false;
|
||||
} else {
|
||||
classfile_parse_error(
|
||||
"Invalid MethodParameters method attribute length %u in class file %s",
|
||||
"Invalid MethodParameters method attribute length %u in class file",
|
||||
method_attribute_length, CHECK_(nullHandle));
|
||||
}
|
||||
method_parameters_data = cfs->get_u1_buffer();
|
||||
cfs->skip_u2_fast(method_parameters_length);
|
||||
if (method_parameters_four_byte_flags) {
|
||||
cfs->skip_u4_fast(method_parameters_length);
|
||||
} else {
|
||||
cfs->skip_u2_fast(method_parameters_length);
|
||||
}
|
||||
// ignore this attribute if it cannot be reflected
|
||||
if (!SystemDictionary::Parameter_klass_loaded())
|
||||
method_parameters_length = 0;
|
||||
@ -2316,15 +2328,16 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
|
||||
// Copy method parameters
|
||||
if (method_parameters_length > 0) {
|
||||
MethodParametersElement* elem = m->constMethod()->method_parameters_start();
|
||||
for(int i = 0; i < method_parameters_length; i++) {
|
||||
elem[i].name_cp_index =
|
||||
Bytes::get_Java_u2(method_parameters_data);
|
||||
for (int i = 0; i < method_parameters_length; i++) {
|
||||
elem[i].name_cp_index = Bytes::get_Java_u2(method_parameters_data);
|
||||
method_parameters_data += 2;
|
||||
u4 flags = Bytes::get_Java_u4(method_parameters_data);
|
||||
// This caused an alignment fault on Sparc, if flags was a u4
|
||||
elem[i].flags_lo = extract_low_short_from_int(flags);
|
||||
elem[i].flags_hi = extract_high_short_from_int(flags);
|
||||
method_parameters_data += 4;
|
||||
if (method_parameters_four_byte_flags) {
|
||||
elem[i].flags = Bytes::get_Java_u4(method_parameters_data);
|
||||
method_parameters_data += 4;
|
||||
} else {
|
||||
elem[i].flags = Bytes::get_Java_u2(method_parameters_data);
|
||||
method_parameters_data += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -50,11 +50,12 @@
|
||||
#include "classfile/classLoaderData.hpp"
|
||||
#include "classfile/classLoaderData.inline.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "classfile/metadataOnStackMark.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "memory/metadataFactory.hpp"
|
||||
#include "memory/metaspaceShared.hpp"
|
||||
#include "prims/jvmtiRedefineClasses.hpp"
|
||||
#include "memory/oopFactory.hpp"
|
||||
#include "runtime/jniHandles.hpp"
|
||||
#include "runtime/mutex.hpp"
|
||||
#include "runtime/safepoint.hpp"
|
||||
@ -723,13 +724,13 @@ void ClassLoaderDataGraph::dump_on(outputStream * const out) {
|
||||
}
|
||||
MetaspaceAux::dump(out);
|
||||
}
|
||||
#endif // PRODUCT
|
||||
|
||||
void ClassLoaderData::print_value_on(outputStream* out) const {
|
||||
if (class_loader() == NULL) {
|
||||
out->print_cr("NULL class_loader");
|
||||
out->print("NULL class_loader");
|
||||
} else {
|
||||
out->print("class loader "PTR_FORMAT, this);
|
||||
class_loader()->print_value_on(out);
|
||||
}
|
||||
}
|
||||
#endif // PRODUCT
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -220,7 +220,7 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
||||
void set_jmethod_ids(JNIMethodBlock* new_block) { _jmethod_ids = new_block; }
|
||||
|
||||
void print_value() { print_value_on(tty); }
|
||||
void print_value_on(outputStream* out) const PRODUCT_RETURN;
|
||||
void print_value_on(outputStream* out) const;
|
||||
void dump(outputStream * const out) PRODUCT_RETURN;
|
||||
void verify();
|
||||
const char* loader_name();
|
||||
|
69
hotspot/src/share/vm/classfile/metadataOnStackMark.cpp
Normal file
69
hotspot/src/share/vm/classfile/metadataOnStackMark.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/metadataOnStackMark.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "compiler/compileBroker.hpp"
|
||||
#include "oops/metadata.hpp"
|
||||
#include "runtime/synchronizer.hpp"
|
||||
#include "runtime/thread.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
|
||||
|
||||
// Keep track of marked on-stack metadata so it can be cleared.
|
||||
GrowableArray<Metadata*>* _marked_objects = NULL;
|
||||
NOT_PRODUCT(bool MetadataOnStackMark::_is_active = false;)
|
||||
|
||||
// Walk metadata on the stack and mark it so that redefinition doesn't delete
|
||||
// it. Class unloading also walks the previous versions and might try to
|
||||
// delete it, so this class is used by class unloading also.
|
||||
MetadataOnStackMark::MetadataOnStackMark() {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
|
||||
NOT_PRODUCT(_is_active = true;)
|
||||
if (_marked_objects == NULL) {
|
||||
_marked_objects = new (ResourceObj::C_HEAP, mtClass) GrowableArray<Metadata*>(1000, true);
|
||||
}
|
||||
Threads::metadata_do(Metadata::mark_on_stack);
|
||||
CodeCache::alive_nmethods_do(nmethod::mark_on_stack);
|
||||
CompileBroker::mark_on_stack();
|
||||
}
|
||||
|
||||
MetadataOnStackMark::~MetadataOnStackMark() {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
|
||||
// Unmark everything that was marked. Can't do the same walk because
|
||||
// redefine classes messes up the code cache so the set of methods
|
||||
// might not be the same.
|
||||
for (int i = 0; i< _marked_objects->length(); i++) {
|
||||
_marked_objects->at(i)->set_on_stack(false);
|
||||
}
|
||||
_marked_objects->clear(); // reuse growable array for next time.
|
||||
NOT_PRODUCT(_is_active = false;)
|
||||
}
|
||||
|
||||
// Record which objects are marked so we can unmark the same objects.
|
||||
void MetadataOnStackMark::record(Metadata* m) {
|
||||
assert(_is_active, "metadata on stack marking is active");
|
||||
_marked_objects->push(m);
|
||||
}
|
45
hotspot/src/share/vm/classfile/metadataOnStackMark.hpp
Normal file
45
hotspot/src/share/vm/classfile/metadataOnStackMark.hpp
Normal file
@ -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
|
@ -178,7 +178,7 @@ class StackMapFrame : public ResourceObj {
|
||||
#ifdef DEBUG
|
||||
// Put bogus type to indicate it's no longer valid.
|
||||
if (_stack_mark != -1) {
|
||||
for (int i = _stack_mark; i >= _stack_size; --i) {
|
||||
for (int i = _stack_mark - 1; i >= _stack_size; --i) {
|
||||
_stack[i] = VerificationType::bogus_type();
|
||||
}
|
||||
}
|
||||
|
@ -1199,66 +1199,6 @@ instanceKlassHandle SystemDictionary::load_shared_class(
|
||||
return ik;
|
||||
}
|
||||
|
||||
#ifdef KERNEL
|
||||
// Some classes on the bootstrap class path haven't been installed on the
|
||||
// system yet. Call the DownloadManager method to make them appear in the
|
||||
// bootstrap class path and try again to load the named class.
|
||||
// Note that with delegation class loaders all classes in another loader will
|
||||
// first try to call this so it'd better be fast!!
|
||||
static instanceKlassHandle download_and_retry_class_load(
|
||||
Symbol* class_name,
|
||||
TRAPS) {
|
||||
|
||||
Klass* dlm = SystemDictionary::DownloadManager_klass();
|
||||
instanceKlassHandle nk;
|
||||
|
||||
// If download manager class isn't loaded just return.
|
||||
if (dlm == NULL) return nk;
|
||||
|
||||
{ HandleMark hm(THREAD);
|
||||
ResourceMark rm(THREAD);
|
||||
Handle s = java_lang_String::create_from_symbol(class_name, CHECK_(nk));
|
||||
Handle class_string = java_lang_String::externalize_classname(s, CHECK_(nk));
|
||||
|
||||
// return value
|
||||
JavaValue result(T_OBJECT);
|
||||
|
||||
// Call the DownloadManager. We assume that it has a lock because
|
||||
// multiple classes could be not found and downloaded at the same time.
|
||||
// class sun.misc.DownloadManager;
|
||||
// public static String getBootClassPathEntryForClass(String className);
|
||||
JavaCalls::call_static(&result,
|
||||
KlassHandle(THREAD, dlm),
|
||||
vmSymbols::getBootClassPathEntryForClass_name(),
|
||||
vmSymbols::string_string_signature(),
|
||||
class_string,
|
||||
CHECK_(nk));
|
||||
|
||||
// Get result.string and add to bootclasspath
|
||||
assert(result.get_type() == T_OBJECT, "just checking");
|
||||
oop obj = (oop) result.get_jobject();
|
||||
if (obj == NULL) { return nk; }
|
||||
|
||||
Handle h_obj(THREAD, obj);
|
||||
char* new_class_name = java_lang_String::as_platform_dependent_str(h_obj,
|
||||
CHECK_(nk));
|
||||
|
||||
// lock the loader
|
||||
// we use this lock because JVMTI does.
|
||||
Handle loader_lock(THREAD, SystemDictionary::system_loader_lock());
|
||||
|
||||
ObjectLocker ol(loader_lock, THREAD);
|
||||
// add the file to the bootclasspath
|
||||
ClassLoader::update_class_path_entry_list(new_class_name, true);
|
||||
} // end HandleMark
|
||||
|
||||
if (TraceClassLoading) {
|
||||
ClassLoader::print_bootclasspath();
|
||||
}
|
||||
return ClassLoader::load_classfile(class_name, CHECK_(nk));
|
||||
}
|
||||
#endif // KERNEL
|
||||
|
||||
|
||||
instanceKlassHandle SystemDictionary::load_instance_class(Symbol* class_name, Handle class_loader, TRAPS) {
|
||||
instanceKlassHandle nh = instanceKlassHandle(); // null Handle
|
||||
@ -1278,15 +1218,6 @@ instanceKlassHandle SystemDictionary::load_instance_class(Symbol* class_name, Ha
|
||||
k = ClassLoader::load_classfile(class_name, CHECK_(nh));
|
||||
}
|
||||
|
||||
#ifdef KERNEL
|
||||
// If the VM class loader has failed to load the class, call the
|
||||
// DownloadManager class to make it magically appear on the classpath
|
||||
// and try again. This is only configured with the Kernel VM.
|
||||
if (k.is_null()) {
|
||||
k = download_and_retry_class_load(class_name, CHECK_(nh));
|
||||
}
|
||||
#endif // KERNEL
|
||||
|
||||
// find_or_define_instance_class may return a different InstanceKlass
|
||||
if (!k.is_null()) {
|
||||
k = find_or_define_instance_class(class_name, class_loader, k, CHECK_(nh));
|
||||
@ -1822,13 +1753,7 @@ bool SystemDictionary::initialize_wk_klass(WKID id, int init_opt, TRAPS) {
|
||||
Symbol* symbol = vmSymbols::symbol_at((vmSymbols::SID)sid);
|
||||
Klass** klassp = &_well_known_klasses[id];
|
||||
bool must_load = (init_opt < SystemDictionary::Opt);
|
||||
bool try_load = true;
|
||||
if (init_opt == SystemDictionary::Opt_Kernel) {
|
||||
#ifndef KERNEL
|
||||
try_load = false;
|
||||
#endif //KERNEL
|
||||
}
|
||||
if ((*klassp) == NULL && try_load) {
|
||||
if ((*klassp) == NULL) {
|
||||
if (must_load) {
|
||||
(*klassp) = resolve_or_fail(symbol, true, CHECK_0); // load required class
|
||||
} else {
|
||||
@ -1918,12 +1843,6 @@ void SystemDictionary::initialize_preloaded_classes(TRAPS) {
|
||||
//_box_klasses[T_OBJECT] = WK_KLASS(object_klass);
|
||||
//_box_klasses[T_ARRAY] = WK_KLASS(object_klass);
|
||||
|
||||
#ifdef KERNEL
|
||||
if (DownloadManager_klass() == NULL) {
|
||||
warning("Cannot find sun/jkernel/DownloadManager");
|
||||
}
|
||||
#endif // KERNEL
|
||||
|
||||
{ // Compute whether we should use loadClass or loadClassInternal when loading classes.
|
||||
Method* method = InstanceKlass::cast(ClassLoader_klass())->find_method(vmSymbols::loadClassInternal_name(), vmSymbols::string_class_signature());
|
||||
_has_loadClassInternal = (method != NULL);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -168,8 +168,6 @@ class SymbolPropertyTable;
|
||||
/* It's okay if this turns out to be NULL in non-1.4 JDKs. */ \
|
||||
do_klass(nio_Buffer_klass, java_nio_Buffer, Opt ) \
|
||||
\
|
||||
do_klass(DownloadManager_klass, sun_jkernel_DownloadManager, Opt_Kernel ) \
|
||||
\
|
||||
do_klass(PostVMInitHook_klass, sun_misc_PostVMInitHook, Opt ) \
|
||||
\
|
||||
/* Preload boxing klasses */ \
|
||||
@ -211,7 +209,6 @@ class SystemDictionary : AllStatic {
|
||||
Opt, // preload tried; NULL if not present
|
||||
Opt_Only_JDK14NewRef, // preload tried; use only with NewReflection
|
||||
Opt_Only_JDK15, // preload tried; use only with JDK1.5+
|
||||
Opt_Kernel, // preload tried only #ifdef KERNEL
|
||||
OPTION_LIMIT,
|
||||
CEIL_LG_OPTION_LIMIT = 4 // OPTION_LIMIT <= (1<<CEIL_LG_OPTION_LIMIT)
|
||||
};
|
||||
@ -394,7 +391,6 @@ public:
|
||||
static Klass* check_klass_Pre( Klass* k) { return check_klass(k); }
|
||||
static Klass* check_klass_Pre_JSR292(Klass* k) { return EnableInvokeDynamic ? check_klass(k) : k; }
|
||||
static Klass* check_klass_Opt( Klass* k) { return k; }
|
||||
static Klass* check_klass_Opt_Kernel(Klass* k) { return k; } //== Opt
|
||||
static Klass* check_klass_Opt_Only_JDK15(Klass* k) {
|
||||
assert(JDK_Version::is_gte_jdk15x_version(), "JDK 1.5 only");
|
||||
return k;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -108,7 +108,6 @@
|
||||
template(java_lang_Compiler, "java/lang/Compiler") \
|
||||
template(sun_misc_Signal, "sun/misc/Signal") \
|
||||
template(java_lang_AssertionStatusDirectives, "java/lang/AssertionStatusDirectives") \
|
||||
template(sun_jkernel_DownloadManager, "sun/jkernel/DownloadManager") \
|
||||
template(getBootClassPathEntryForClass_name, "getBootClassPathEntryForClass") \
|
||||
template(sun_misc_PostVMInitHook, "sun/misc/PostVMInitHook") \
|
||||
template(sun_misc_Launcher_ExtClassLoader, "sun/misc/Launcher$ExtClassLoader") \
|
||||
|
@ -1398,7 +1398,7 @@ bool CompileBroker::compilation_is_prohibited(methodHandle method, int osr_bci,
|
||||
method->print_short_name(tty);
|
||||
tty->cr();
|
||||
}
|
||||
method->set_not_compilable_quietly();
|
||||
method->set_not_compilable(CompLevel_all, !quietly, "excluded by CompilerOracle");
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -32,9 +32,9 @@
|
||||
nonstatic_field(CompactibleFreeListSpace, _bt, BlockOffsetArrayNonContigSpace) \
|
||||
\
|
||||
nonstatic_field(CMSBitMap, _bmWordSize, size_t) \
|
||||
nonstatic_field(CMSBitMap, _shifter, const int) \
|
||||
nonstatic_field(CMSBitMap, _bm, BitMap) \
|
||||
nonstatic_field(CMSBitMap, _virtual_space, VirtualSpace) \
|
||||
nonstatic_field(CMSBitMap, _shifter, const int) \
|
||||
nonstatic_field(CMSBitMap, _bm, BitMap) \
|
||||
nonstatic_field(CMSBitMap, _virtual_space, VirtualSpace) \
|
||||
nonstatic_field(CMSCollector, _markBitMap, CMSBitMap) \
|
||||
nonstatic_field(ConcurrentMarkSweepGeneration, _cmsSpace, CompactibleFreeListSpace*) \
|
||||
static_field(ConcurrentMarkSweepThread, _collector, CMSCollector*) \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -167,7 +167,9 @@ void VM_GC_HeapInspection::doit() {
|
||||
ch->collect_as_vm_thread(GCCause::_heap_inspection);
|
||||
}
|
||||
}
|
||||
HeapInspection::heap_inspection(_out, _need_prologue /* need_prologue */);
|
||||
HeapInspection inspect(_csv_format, _print_help, _print_class_stats,
|
||||
_columns);
|
||||
inspect.heap_inspection(_out, _need_prologue /* need_prologue */);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -130,6 +130,10 @@ class VM_GC_HeapInspection: public VM_GC_Operation {
|
||||
outputStream* _out;
|
||||
bool _full_gc;
|
||||
bool _need_prologue;
|
||||
bool _csv_format; // "comma separated values" format for spreadsheet.
|
||||
bool _print_help;
|
||||
bool _print_class_stats;
|
||||
const char* _columns;
|
||||
public:
|
||||
VM_GC_HeapInspection(outputStream* out, bool request_full_gc,
|
||||
bool need_prologue) :
|
||||
@ -140,6 +144,10 @@ class VM_GC_HeapInspection: public VM_GC_Operation {
|
||||
_out = out;
|
||||
_full_gc = request_full_gc;
|
||||
_need_prologue = need_prologue;
|
||||
_csv_format = false;
|
||||
_print_help = false;
|
||||
_print_class_stats = false;
|
||||
_columns = NULL;
|
||||
}
|
||||
|
||||
~VM_GC_HeapInspection() {}
|
||||
@ -147,6 +155,10 @@ class VM_GC_HeapInspection: public VM_GC_Operation {
|
||||
virtual bool skip_operation() const;
|
||||
virtual bool doit_prologue();
|
||||
virtual void doit();
|
||||
void set_csv_format(bool value) {_csv_format = value;}
|
||||
void set_print_help(bool value) {_print_help = value;}
|
||||
void set_print_class_stats(bool value) {_print_class_stats = value;}
|
||||
void set_columns(const char* value) {_columns = value;}
|
||||
};
|
||||
|
||||
|
||||
|
@ -3099,9 +3099,9 @@ BytecodeInterpreter::print() {
|
||||
tty->print_cr("&native_fresult: " INTPTR_FORMAT, (uintptr_t) &this->_native_fresult);
|
||||
tty->print_cr("native_lresult: " INTPTR_FORMAT, (uintptr_t) this->_native_lresult);
|
||||
#endif
|
||||
#if defined(IA64) && !defined(ZERO)
|
||||
#if !defined(ZERO)
|
||||
tty->print_cr("last_Java_fp: " INTPTR_FORMAT, (uintptr_t) this->_last_Java_fp);
|
||||
#endif // IA64 && !ZERO
|
||||
#endif // !ZERO
|
||||
tty->print_cr("self_link: " INTPTR_FORMAT, (uintptr_t) this->_self_link);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -1241,7 +1241,7 @@ void LinkResolver::resolve_handle_call(CallInfo& result, KlassHandle resolved_kl
|
||||
|
||||
void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
|
||||
assert(EnableInvokeDynamic, "");
|
||||
pool->set_invokedynamic(); // mark header to flag active call sites
|
||||
pool->set_has_invokedynamic(); // mark header to flag active call sites
|
||||
|
||||
//resolve_pool(<resolved_klass>, method_name, method_signature, current_klass, pool, index, CHECK);
|
||||
Symbol* method_name = pool->name_ref_at(index);
|
||||
|
@ -145,9 +145,10 @@ enum MemoryType {
|
||||
mtChunk = 0x0B00, // chunk that holds content of arenas
|
||||
mtJavaHeap = 0x0C00, // Java heap
|
||||
mtClassShared = 0x0D00, // class data sharing
|
||||
mt_number_of_types = 0x000D, // number of memory types (mtDontTrack
|
||||
mtTest = 0x0E00, // Test type for verifying NMT
|
||||
mt_number_of_types = 0x000E, // number of memory types (mtDontTrack
|
||||
// is not included as validate type)
|
||||
mtDontTrack = 0x0E00, // memory we do not or cannot track
|
||||
mtDontTrack = 0x0F00, // memory we do not or cannot track
|
||||
mt_masks = 0x7F00,
|
||||
|
||||
// object type mask
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -210,13 +210,14 @@ void FileMapInfo::open_for_write() {
|
||||
tty->print_cr(" %s", _full_path);
|
||||
}
|
||||
|
||||
// Remove the existing file in case another process has it open.
|
||||
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);
|
||||
#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);
|
||||
int fd = open(_full_path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0444);
|
||||
if (fd < 0) {
|
||||
fail_stop("Unable to create shared archive file %s.", _full_path);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/classLoaderData.hpp"
|
||||
#include "gc_interface/collectedHeap.hpp"
|
||||
#include "memory/genCollectedHeap.hpp"
|
||||
#include "memory/heapInspection.hpp"
|
||||
@ -41,12 +42,24 @@ int KlassInfoEntry::compare(KlassInfoEntry* e1, KlassInfoEntry* e2) {
|
||||
} else if(e1->_instance_words < e2->_instance_words) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
// Sort alphabetically, note 'Z' < '[' < 'a', but it's better to group
|
||||
// the array classes before all the instance classes.
|
||||
ResourceMark rm;
|
||||
const char* name1 = e1->klass()->external_name();
|
||||
const char* name2 = e2->klass()->external_name();
|
||||
bool d1 = (name1[0] == '[');
|
||||
bool d2 = (name2[0] == '[');
|
||||
if (d1 && !d2) {
|
||||
return -1;
|
||||
} else if (d2 && !d1) {
|
||||
return 1;
|
||||
} else {
|
||||
return strcmp(name1, name2);
|
||||
}
|
||||
}
|
||||
|
||||
void KlassInfoEntry::print_on(outputStream* st) const {
|
||||
ResourceMark rm;
|
||||
const char* name;;
|
||||
const char* KlassInfoEntry::name() const {
|
||||
const char* name;
|
||||
if (_klass->name() != NULL) {
|
||||
name = _klass->external_name();
|
||||
} else {
|
||||
@ -60,11 +73,17 @@ void KlassInfoEntry::print_on(outputStream* st) const {
|
||||
if (_klass == Universe::longArrayKlassObj()) name = "<longArrayKlass>"; else
|
||||
name = "<no name>";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
void KlassInfoEntry::print_on(outputStream* st) const {
|
||||
ResourceMark rm;
|
||||
|
||||
// simplify the formatting (ILP32 vs LP64) - always cast the numbers to 64-bit
|
||||
st->print_cr(INT64_FORMAT_W(13) " " UINT64_FORMAT_W(13) " %s",
|
||||
(jlong) _instance_count,
|
||||
(julong) _instance_words * HeapWordSize,
|
||||
name);
|
||||
name());
|
||||
}
|
||||
|
||||
KlassInfoEntry* KlassInfoBucket::lookup(Klass* const k) {
|
||||
@ -101,7 +120,14 @@ void KlassInfoBucket::empty() {
|
||||
}
|
||||
}
|
||||
|
||||
KlassInfoTable::KlassInfoTable(int size, HeapWord* ref) {
|
||||
void KlassInfoTable::AllClassesFinder::do_klass(Klass* k) {
|
||||
// This has the SIDE EFFECT of creating a KlassInfoEntry
|
||||
// for <k>, if one doesn't exist yet.
|
||||
_table->lookup(k);
|
||||
}
|
||||
|
||||
KlassInfoTable::KlassInfoTable(int size, HeapWord* ref,
|
||||
bool need_class_stats) {
|
||||
_size = 0;
|
||||
_ref = ref;
|
||||
_buckets = NEW_C_HEAP_ARRAY(KlassInfoBucket, size, mtInternal);
|
||||
@ -110,6 +136,10 @@ KlassInfoTable::KlassInfoTable(int size, HeapWord* ref) {
|
||||
for (int index = 0; index < _size; index++) {
|
||||
_buckets[index].initialize();
|
||||
}
|
||||
if (need_class_stats) {
|
||||
AllClassesFinder finder(this);
|
||||
ClassLoaderDataGraph::classes_do(&finder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,7 +195,8 @@ int KlassInfoHisto::sort_helper(KlassInfoEntry** e1, KlassInfoEntry** e2) {
|
||||
return (*e1)->compare(*e1,*e2);
|
||||
}
|
||||
|
||||
KlassInfoHisto::KlassInfoHisto(const char* title, int estimatedCount) :
|
||||
KlassInfoHisto::KlassInfoHisto(KlassInfoTable* cit, const char* title, int estimatedCount) :
|
||||
_cit(cit),
|
||||
_title(title) {
|
||||
_elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<KlassInfoEntry*>(estimatedCount,true);
|
||||
}
|
||||
@ -196,9 +227,205 @@ void KlassInfoHisto::print_elements(outputStream* st) const {
|
||||
total, totalw * HeapWordSize);
|
||||
}
|
||||
|
||||
void KlassInfoHisto::print_on(outputStream* st) const {
|
||||
st->print_cr("%s",title());
|
||||
print_elements(st);
|
||||
#define MAKE_COL_NAME(field, name, help) #name,
|
||||
#define MAKE_COL_HELP(field, name, help) help,
|
||||
|
||||
static const char *name_table[] = {
|
||||
HEAP_INSPECTION_COLUMNS_DO(MAKE_COL_NAME)
|
||||
};
|
||||
|
||||
static const char *help_table[] = {
|
||||
HEAP_INSPECTION_COLUMNS_DO(MAKE_COL_HELP)
|
||||
};
|
||||
|
||||
bool KlassInfoHisto::is_selected(const char *col_name) {
|
||||
if (_selected_columns == NULL) {
|
||||
return true;
|
||||
}
|
||||
if (strcmp(_selected_columns, col_name) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *start = strstr(_selected_columns, col_name);
|
||||
if (start == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The following must be true, because _selected_columns != col_name
|
||||
if (start > _selected_columns && start[-1] != ',') {
|
||||
return false;
|
||||
}
|
||||
char x = start[strlen(col_name)];
|
||||
if (x != ',' && x != '\0') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void KlassInfoHisto::print_title(outputStream* st, bool csv_format,
|
||||
bool selected[], int width_table[],
|
||||
const char *name_table[]) {
|
||||
if (csv_format) {
|
||||
st->print("Index,Super");
|
||||
for (int c=0; c<KlassSizeStats::_num_columns; c++) {
|
||||
if (selected[c]) {st->print(",%s", name_table[c]);}
|
||||
}
|
||||
st->print(",ClassName");
|
||||
} else {
|
||||
st->print("Index Super");
|
||||
for (int c=0; c<KlassSizeStats::_num_columns; c++) {
|
||||
if (selected[c]) {st->print(str_fmt(width_table[c]), name_table[c]);}
|
||||
}
|
||||
st->print(" ClassName");
|
||||
}
|
||||
|
||||
if (is_selected("ClassLoader")) {
|
||||
st->print(",ClassLoader");
|
||||
}
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void KlassInfoHisto::print_class_stats(outputStream* st,
|
||||
bool csv_format, const char *columns) {
|
||||
ResourceMark rm;
|
||||
KlassSizeStats sz, sz_sum;
|
||||
int i;
|
||||
julong *col_table = (julong*)(&sz);
|
||||
julong *colsum_table = (julong*)(&sz_sum);
|
||||
int width_table[KlassSizeStats::_num_columns];
|
||||
bool selected[KlassSizeStats::_num_columns];
|
||||
|
||||
_selected_columns = columns;
|
||||
|
||||
memset(&sz_sum, 0, sizeof(sz_sum));
|
||||
for (int c=0; c<KlassSizeStats::_num_columns; c++) {
|
||||
selected[c] = is_selected(name_table[c]);
|
||||
}
|
||||
|
||||
for(i=0; i < elements()->length(); i++) {
|
||||
elements()->at(i)->set_index(i+1);
|
||||
}
|
||||
|
||||
for (int pass=1; pass<=2; pass++) {
|
||||
if (pass == 2) {
|
||||
print_title(st, csv_format, selected, width_table, name_table);
|
||||
}
|
||||
for(i=0; i < elements()->length(); i++) {
|
||||
KlassInfoEntry* e = (KlassInfoEntry*)elements()->at(i);
|
||||
const Klass* k = e->klass();
|
||||
|
||||
memset(&sz, 0, sizeof(sz));
|
||||
sz._inst_count = e->count();
|
||||
sz._inst_bytes = HeapWordSize * e->words();
|
||||
k->collect_statistics(&sz);
|
||||
sz._total_bytes = sz._ro_bytes + sz._rw_bytes;
|
||||
|
||||
if (pass == 1) {
|
||||
for (int c=0; c<KlassSizeStats::_num_columns; c++) {
|
||||
colsum_table[c] += col_table[c];
|
||||
}
|
||||
} else {
|
||||
int super_index = -1;
|
||||
if (k->oop_is_instance()) {
|
||||
Klass* super = ((InstanceKlass*)k)->java_super();
|
||||
if (super) {
|
||||
KlassInfoEntry* super_e = _cit->lookup(super);
|
||||
if (super_e) {
|
||||
super_index = super_e->index();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (csv_format) {
|
||||
st->print("%d,%d", e->index(), super_index);
|
||||
for (int c=0; c<KlassSizeStats::_num_columns; c++) {
|
||||
if (selected[c]) {st->print("," JULONG_FORMAT, col_table[c]);}
|
||||
}
|
||||
st->print(",%s",e->name());
|
||||
} else {
|
||||
st->print("%5d %5d", e->index(), super_index);
|
||||
for (int c=0; c<KlassSizeStats::_num_columns; c++) {
|
||||
if (selected[c]) {print_julong(st, width_table[c], col_table[c]);}
|
||||
}
|
||||
st->print(" %s", e->name());
|
||||
}
|
||||
if (is_selected("ClassLoader")) {
|
||||
ClassLoaderData* loader_data = k->class_loader_data();
|
||||
st->print(",");
|
||||
loader_data->print_value_on(st);
|
||||
}
|
||||
st->cr();
|
||||
}
|
||||
}
|
||||
|
||||
if (pass == 1) {
|
||||
for (int c=0; c<KlassSizeStats::_num_columns; c++) {
|
||||
width_table[c] = col_width(colsum_table[c], name_table[c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sz_sum._inst_size = 0;
|
||||
|
||||
if (csv_format) {
|
||||
st->print(",");
|
||||
for (int c=0; c<KlassSizeStats::_num_columns; c++) {
|
||||
if (selected[c]) {st->print("," JULONG_FORMAT, colsum_table[c]);}
|
||||
}
|
||||
} else {
|
||||
st->print(" ");
|
||||
for (int c=0; c<KlassSizeStats::_num_columns; c++) {
|
||||
if (selected[c]) {print_julong(st, width_table[c], colsum_table[c]);}
|
||||
}
|
||||
st->print(" Total");
|
||||
if (sz_sum._total_bytes > 0) {
|
||||
st->cr();
|
||||
st->print(" ");
|
||||
for (int c=0; c<KlassSizeStats::_num_columns; c++) {
|
||||
if (selected[c]) {
|
||||
switch (c) {
|
||||
case KlassSizeStats::_index_inst_size:
|
||||
case KlassSizeStats::_index_inst_count:
|
||||
case KlassSizeStats::_index_method_count:
|
||||
st->print(str_fmt(width_table[c]), "-");
|
||||
break;
|
||||
default:
|
||||
{
|
||||
double perc = (double)(100) * (double)(colsum_table[c]) / (double)sz_sum._total_bytes;
|
||||
st->print(perc_fmt(width_table[c]), perc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
st->cr();
|
||||
|
||||
if (!csv_format) {
|
||||
print_title(st, csv_format, selected, width_table, name_table);
|
||||
}
|
||||
}
|
||||
|
||||
julong KlassInfoHisto::annotations_bytes(Array<AnnotationArray*>* p) const {
|
||||
julong bytes = 0;
|
||||
if (p != NULL) {
|
||||
for (int i = 0; i < p->length(); i++) {
|
||||
bytes += count_bytes_array(p->at(i));
|
||||
}
|
||||
bytes += count_bytes_array(p);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void KlassInfoHisto::print_histo_on(outputStream* st, bool print_stats,
|
||||
bool csv_format, const char *columns) {
|
||||
if (print_stats) {
|
||||
print_class_stats(st, csv_format, columns);
|
||||
} else {
|
||||
st->print_cr("%s",title());
|
||||
print_elements(st);
|
||||
}
|
||||
}
|
||||
|
||||
class HistoClosure : public KlassInfoClosure {
|
||||
@ -236,8 +463,26 @@ void HeapInspection::heap_inspection(outputStream* st, bool need_prologue) {
|
||||
CollectedHeap* heap = Universe::heap();
|
||||
bool is_shared_heap = false;
|
||||
|
||||
if (_print_help) {
|
||||
for (int c=0; c<KlassSizeStats::_num_columns; c++) {
|
||||
st->print("%s:\n\t", name_table[c]);
|
||||
const int max_col = 60;
|
||||
int col = 0;
|
||||
for (const char *p = help_table[c]; *p; p++,col++) {
|
||||
if (col >= max_col && *p == ' ') {
|
||||
st->print("\n\t");
|
||||
col = 0;
|
||||
} else {
|
||||
st->print("%c", *p);
|
||||
}
|
||||
}
|
||||
st->print_cr(".\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Collect klass instance info
|
||||
KlassInfoTable cit(KlassInfoTable::cit_size, ref);
|
||||
KlassInfoTable cit(KlassInfoTable::cit_size, ref, _print_class_stats);
|
||||
if (!cit.allocation_failed()) {
|
||||
// Iterate over objects in the heap
|
||||
RecordInstanceClosure ric(&cit);
|
||||
@ -252,14 +497,14 @@ void HeapInspection::heap_inspection(outputStream* st, bool need_prologue) {
|
||||
missed_count);
|
||||
}
|
||||
// Sort and print klass instance info
|
||||
KlassInfoHisto histo("\n"
|
||||
" num #instances #bytes class name\n"
|
||||
"----------------------------------------------",
|
||||
KlassInfoHisto::histo_initial_size);
|
||||
const char *title = "\n"
|
||||
" num #instances #bytes class name\n"
|
||||
"----------------------------------------------";
|
||||
KlassInfoHisto histo(&cit, title, KlassInfoHisto::histo_initial_size);
|
||||
HistoClosure hc(&histo);
|
||||
cit.iterate(&hc);
|
||||
histo.sort();
|
||||
histo.print_on(st);
|
||||
histo.print_histo_on(st, _print_class_stats, _csv_format, _columns);
|
||||
} else {
|
||||
st->print_cr("WARNING: Ran out of C-heap; histogram not generated");
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,6 +27,7 @@
|
||||
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "oops/annotations.hpp"
|
||||
|
||||
#if INCLUDE_SERVICES
|
||||
|
||||
@ -44,16 +45,144 @@
|
||||
// to KlassInfoEntry's and is used to sort
|
||||
// the entries.
|
||||
|
||||
#define HEAP_INSPECTION_COLUMNS_DO(f) \
|
||||
f(inst_size, InstSize, \
|
||||
"Size of each object instance of the Java class") \
|
||||
f(inst_count, InstCount, \
|
||||
"Number of object instances of the Java class") \
|
||||
f(inst_bytes, InstBytes, \
|
||||
"This is usually (InstSize * InstNum). The only exception is " \
|
||||
"java.lang.Class, whose InstBytes also includes the slots " \
|
||||
"used to store static fields. InstBytes is not counted in " \
|
||||
"ROAll, RWAll or Total") \
|
||||
f(mirror_bytes, Mirror, \
|
||||
"Size of the Klass::java_mirror() object") \
|
||||
f(klass_bytes, KlassBytes, \
|
||||
"Size of the InstanceKlass or ArrayKlass for this class. " \
|
||||
"Note that this includes VTab, ITab, OopMap") \
|
||||
f(secondary_supers_bytes, K_secondary_supers, \
|
||||
"Number of bytes used by the Klass::secondary_supers() array") \
|
||||
f(vtab_bytes, VTab, \
|
||||
"Size of the embedded vtable in InstanceKlass") \
|
||||
f(itab_bytes, ITab, \
|
||||
"Size of the embedded itable in InstanceKlass") \
|
||||
f(nonstatic_oopmap_bytes, OopMap, \
|
||||
"Size of the embedded nonstatic_oop_map in InstanceKlass") \
|
||||
f(methods_array_bytes, IK_methods, \
|
||||
"Number of bytes used by the InstanceKlass::methods() array") \
|
||||
f(method_ordering_bytes, IK_method_ordering, \
|
||||
"Number of bytes used by the InstanceKlass::method_ordering() array") \
|
||||
f(local_interfaces_bytes, IK_local_interfaces, \
|
||||
"Number of bytes used by the InstanceKlass::local_interfaces() array") \
|
||||
f(transitive_interfaces_bytes, IK_transitive_interfaces, \
|
||||
"Number of bytes used by the InstanceKlass::transitive_interfaces() array") \
|
||||
f(fields_bytes, IK_fields, \
|
||||
"Number of bytes used by the InstanceKlass::fields() array") \
|
||||
f(inner_classes_bytes, IK_inner_classes, \
|
||||
"Number of bytes used by the InstanceKlass::inner_classes() array") \
|
||||
f(signers_bytes, IK_signers, \
|
||||
"Number of bytes used by the InstanceKlass::singers() array") \
|
||||
f(class_annotations_bytes, class_annotations, \
|
||||
"Size of class annotations") \
|
||||
f(fields_annotations_bytes, fields_annotations, \
|
||||
"Size of field annotations") \
|
||||
f(methods_annotations_bytes, methods_annotations, \
|
||||
"Size of method annotations") \
|
||||
f(methods_parameter_annotations_bytes, methods_parameter_annotations, \
|
||||
"Size of method parameter annotations") \
|
||||
f(methods_default_annotations_bytes, methods_default_annotations, \
|
||||
"Size of methods default annotations") \
|
||||
f(type_annotations_bytes, type_annotations, \
|
||||
"Size of type annotations") \
|
||||
f(annotations_bytes, annotations, \
|
||||
"Size of all annotations") \
|
||||
f(cp_bytes, Cp, \
|
||||
"Size of InstanceKlass::constants()") \
|
||||
f(cp_tags_bytes, CpTags, \
|
||||
"Size of InstanceKlass::constants()->tags()") \
|
||||
f(cp_cache_bytes, CpCache, \
|
||||
"Size of InstanceKlass::constants()->cache()") \
|
||||
f(cp_operands_bytes, CpOperands, \
|
||||
"Size of InstanceKlass::constants()->operands()") \
|
||||
f(cp_refmap_bytes, CpRefMap, \
|
||||
"Size of InstanceKlass::constants()->reference_map()") \
|
||||
f(cp_all_bytes, CpAll, \
|
||||
"Sum of Cp + CpTags + CpCache + CpOperands + CpRefMap") \
|
||||
f(method_count, MethodCount, \
|
||||
"Number of methods in this class") \
|
||||
f(method_bytes, MethodBytes, \
|
||||
"Size of the Method object") \
|
||||
f(const_method_bytes, ConstMethod, \
|
||||
"Size of the ConstMethod object") \
|
||||
f(method_data_bytes, MethodData, \
|
||||
"Size of the MethodData object") \
|
||||
f(stackmap_bytes, StackMap, \
|
||||
"Size of the stackmap_data") \
|
||||
f(bytecode_bytes, Bytecodes, \
|
||||
"Of the MethodBytes column, how much are the space taken up by bytecodes") \
|
||||
f(method_all_bytes, MethodAll, \
|
||||
"Sum of MethodBytes + Constmethod + Stackmap + Methoddata") \
|
||||
f(ro_bytes, ROAll, \
|
||||
"Size of all class meta data that could (potentially) be placed " \
|
||||
"in read-only memory. (This could change with CDS design)") \
|
||||
f(rw_bytes, RWAll, \
|
||||
"Size of all class meta data that must be placed in read/write " \
|
||||
"memory. (This could change with CDS design) ") \
|
||||
f(total_bytes, Total, \
|
||||
"ROAll + RWAll. Note that this does NOT include InstBytes.")
|
||||
|
||||
// Size statistics for a Klass - filled in by Klass::collect_statistics()
|
||||
class KlassSizeStats {
|
||||
public:
|
||||
#define COUNT_KLASS_SIZE_STATS_FIELD(field, name, help) _index_ ## field,
|
||||
#define DECLARE_KLASS_SIZE_STATS_FIELD(field, name, help) julong _ ## field;
|
||||
|
||||
enum {
|
||||
HEAP_INSPECTION_COLUMNS_DO(COUNT_KLASS_SIZE_STATS_FIELD)
|
||||
_num_columns
|
||||
};
|
||||
|
||||
HEAP_INSPECTION_COLUMNS_DO(DECLARE_KLASS_SIZE_STATS_FIELD)
|
||||
|
||||
static int count(oop x) {
|
||||
return (HeapWordSize * ((x) ? (x)->size() : 0));
|
||||
}
|
||||
|
||||
static int count_array(objArrayOop x) {
|
||||
return (HeapWordSize * ((x) ? (x)->size() : 0));
|
||||
}
|
||||
|
||||
template <class T> static int count(T* x) {
|
||||
return (HeapWordSize * ((x) ? (x)->size() : 0));
|
||||
}
|
||||
|
||||
template <class T> static int count_array(T* x) {
|
||||
if (x == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if (x->length() == 0) {
|
||||
// This is a shared array, e.g., Universe::the_empty_int_array(). Don't
|
||||
// count it to avoid double-counting.
|
||||
return 0;
|
||||
}
|
||||
return HeapWordSize * x->size();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class KlassInfoEntry: public CHeapObj<mtInternal> {
|
||||
private:
|
||||
KlassInfoEntry* _next;
|
||||
Klass* _klass;
|
||||
long _instance_count;
|
||||
size_t _instance_words;
|
||||
long _index;
|
||||
|
||||
public:
|
||||
KlassInfoEntry(Klass* k, KlassInfoEntry* next) :
|
||||
_klass(k), _instance_count(0), _instance_words(0), _next(next)
|
||||
_klass(k), _instance_count(0), _instance_words(0), _next(next), _index(-1)
|
||||
{}
|
||||
KlassInfoEntry* next() { return _next; }
|
||||
bool is_equal(Klass* k) { return k == _klass; }
|
||||
@ -62,8 +191,11 @@ class KlassInfoEntry: public CHeapObj<mtInternal> {
|
||||
void set_count(long ct) { _instance_count = ct; }
|
||||
size_t words() { return _instance_words; }
|
||||
void set_words(size_t wds) { _instance_words = wds; }
|
||||
void set_index(long index) { _index = index; }
|
||||
long index() { return _index; }
|
||||
int compare(KlassInfoEntry* e1, KlassInfoEntry* e2);
|
||||
void print_on(outputStream* st) const;
|
||||
const char* name() const;
|
||||
};
|
||||
|
||||
class KlassInfoClosure: public StackObj {
|
||||
@ -95,45 +227,132 @@ class KlassInfoTable: public StackObj {
|
||||
|
||||
KlassInfoBucket* _buckets;
|
||||
uint hash(Klass* p);
|
||||
KlassInfoEntry* lookup(Klass* const k);
|
||||
KlassInfoEntry* lookup(Klass* const k); // allocates if not found!
|
||||
|
||||
class AllClassesFinder : public KlassClosure {
|
||||
KlassInfoTable *_table;
|
||||
public:
|
||||
AllClassesFinder(KlassInfoTable* table) : _table(table) {}
|
||||
virtual void do_klass(Klass* k);
|
||||
};
|
||||
|
||||
public:
|
||||
// Table size
|
||||
enum {
|
||||
cit_size = 20011
|
||||
};
|
||||
KlassInfoTable(int size, HeapWord* ref);
|
||||
KlassInfoTable(int size, HeapWord* ref, bool need_class_stats);
|
||||
~KlassInfoTable();
|
||||
bool record_instance(const oop obj);
|
||||
void iterate(KlassInfoClosure* cic);
|
||||
bool allocation_failed() { return _buckets == NULL; }
|
||||
|
||||
friend class KlassInfoHisto;
|
||||
};
|
||||
|
||||
class KlassInfoHisto : public StackObj {
|
||||
private:
|
||||
KlassInfoTable *_cit;
|
||||
GrowableArray<KlassInfoEntry*>* _elements;
|
||||
GrowableArray<KlassInfoEntry*>* elements() const { return _elements; }
|
||||
const char* _title;
|
||||
const char* title() const { return _title; }
|
||||
static int sort_helper(KlassInfoEntry** e1, KlassInfoEntry** e2);
|
||||
void print_elements(outputStream* st) const;
|
||||
void print_class_stats(outputStream* st, bool csv_format, const char *columns);
|
||||
julong annotations_bytes(Array<AnnotationArray*>* p) const;
|
||||
const char *_selected_columns;
|
||||
bool is_selected(const char *col_name);
|
||||
void print_title(outputStream* st, bool csv_format,
|
||||
bool selected_columns_table[], int width_table[],
|
||||
const char *name_table[]);
|
||||
|
||||
template <class T> static int count_bytes(T* x) {
|
||||
return (HeapWordSize * ((x) ? (x)->size() : 0));
|
||||
}
|
||||
|
||||
template <class T> static int count_bytes_array(T* x) {
|
||||
if (x == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if (x->length() == 0) {
|
||||
// This is a shared array, e.g., Universe::the_empty_int_array(). Don't
|
||||
// count it to avoid double-counting.
|
||||
return 0;
|
||||
}
|
||||
return HeapWordSize * x->size();
|
||||
}
|
||||
|
||||
// returns a format string to print a julong with the given width. E.g,
|
||||
// printf(num_fmt(6), julong(10)) would print out the number 10 with 4
|
||||
// leading spaces.
|
||||
static void print_julong(outputStream* st, int width, julong n) {
|
||||
int num_spaces = width - julong_width(n);
|
||||
if (num_spaces > 0) {
|
||||
st->print(str_fmt(num_spaces), "");
|
||||
}
|
||||
st->print(JULONG_FORMAT, n);
|
||||
}
|
||||
|
||||
static char* perc_fmt(int width) {
|
||||
static char buf[32];
|
||||
jio_snprintf(buf, sizeof(buf), "%%%d.1f%%%%", width-1);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static char* str_fmt(int width) {
|
||||
static char buf[32];
|
||||
jio_snprintf(buf, sizeof(buf), "%%%ds", width);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static int julong_width(julong n) {
|
||||
if (n == 0) {
|
||||
return 1;
|
||||
}
|
||||
int w = 0;
|
||||
while (n > 0) {
|
||||
n /= 10;
|
||||
w += 1;
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
static int col_width(julong n, const char *name) {
|
||||
int w = julong_width(n);
|
||||
int min = (int)(strlen(name));
|
||||
if (w < min) {
|
||||
w = min;
|
||||
}
|
||||
// add a leading space for separation.
|
||||
return w + 1;
|
||||
}
|
||||
|
||||
public:
|
||||
enum {
|
||||
histo_initial_size = 1000
|
||||
};
|
||||
KlassInfoHisto(const char* title,
|
||||
KlassInfoHisto(KlassInfoTable* cit, const char* title,
|
||||
int estimatedCount);
|
||||
~KlassInfoHisto();
|
||||
void add(KlassInfoEntry* cie);
|
||||
void print_on(outputStream* st) const;
|
||||
void print_histo_on(outputStream* st, bool print_class_stats, bool csv_format, const char *columns);
|
||||
void sort();
|
||||
};
|
||||
|
||||
#endif // INCLUDE_SERVICES
|
||||
|
||||
class HeapInspection : public AllStatic {
|
||||
class HeapInspection : public StackObj {
|
||||
bool _csv_format; // "comma separated values" format for spreadsheet.
|
||||
bool _print_help;
|
||||
bool _print_class_stats;
|
||||
const char* _columns;
|
||||
public:
|
||||
static void heap_inspection(outputStream* st, bool need_prologue) NOT_SERVICES_RETURN;
|
||||
HeapInspection(bool csv_format, bool print_help,
|
||||
bool print_class_stats, const char *columns) :
|
||||
_csv_format(csv_format), _print_help(print_help),
|
||||
_print_class_stats(print_class_stats), _columns(columns) {}
|
||||
void heap_inspection(outputStream* st, bool need_prologue) NOT_SERVICES_RETURN;
|
||||
static void find_instances_at_safepoint(Klass* k, GrowableArray<oop>* result) NOT_SERVICES_RETURN;
|
||||
};
|
||||
|
||||
|
@ -144,6 +144,7 @@ NarrowPtrStruct Universe::_narrow_oop = { NULL, 0, true };
|
||||
NarrowPtrStruct Universe::_narrow_klass = { NULL, 0, true };
|
||||
address Universe::_narrow_ptrs_base;
|
||||
|
||||
size_t Universe::_class_metaspace_size;
|
||||
|
||||
void Universe::basic_type_classes_do(void f(Klass*)) {
|
||||
f(boolArrayKlassObj());
|
||||
@ -689,8 +690,15 @@ char* Universe::preferred_heap_base(size_t heap_size, NARROW_OOP_MODE mode) {
|
||||
// Return specified base for the first request.
|
||||
if (!FLAG_IS_DEFAULT(HeapBaseMinAddress) && (mode == UnscaledNarrowOop)) {
|
||||
base = HeapBaseMinAddress;
|
||||
} else if (total_size <= OopEncodingHeapMax && (mode != HeapBasedNarrowOop)) {
|
||||
if (total_size <= NarrowOopHeapMax && (mode == UnscaledNarrowOop) &&
|
||||
|
||||
// If the total size and the metaspace size are small enough to allow
|
||||
// UnscaledNarrowOop then just use UnscaledNarrowOop.
|
||||
} else if ((total_size <= OopEncodingHeapMax) && (mode != HeapBasedNarrowOop) &&
|
||||
(!UseCompressedKlassPointers ||
|
||||
(((OopEncodingHeapMax - heap_size) + Universe::class_metaspace_size()) <= KlassEncodingMetaspaceMax))) {
|
||||
// We don't need to check the metaspace size here because it is always smaller
|
||||
// than total_size.
|
||||
if ((total_size <= NarrowOopHeapMax) && (mode == UnscaledNarrowOop) &&
|
||||
(Universe::narrow_oop_shift() == 0)) {
|
||||
// Use 32-bits oops without encoding and
|
||||
// place heap's top on the 4Gb boundary
|
||||
@ -706,14 +714,24 @@ char* Universe::preferred_heap_base(size_t heap_size, NARROW_OOP_MODE mode) {
|
||||
base = (OopEncodingHeapMax - heap_size);
|
||||
}
|
||||
}
|
||||
|
||||
// See if ZeroBaseNarrowOop encoding will work for a heap based at
|
||||
// (KlassEncodingMetaspaceMax - class_metaspace_size()).
|
||||
} else if (UseCompressedKlassPointers && (mode != HeapBasedNarrowOop) &&
|
||||
(Universe::class_metaspace_size() + HeapBaseMinAddress <= KlassEncodingMetaspaceMax) &&
|
||||
(KlassEncodingMetaspaceMax + heap_size - Universe::class_metaspace_size() <= OopEncodingHeapMax)) {
|
||||
base = (KlassEncodingMetaspaceMax - Universe::class_metaspace_size());
|
||||
} else {
|
||||
// Can't reserve below 32Gb.
|
||||
// UnscaledNarrowOop encoding didn't work, and no base was found for ZeroBasedOops or
|
||||
// HeapBasedNarrowOop encoding was requested. So, can't reserve below 32Gb.
|
||||
Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
|
||||
}
|
||||
|
||||
// Set narrow_oop_base and narrow_oop_use_implicit_null_checks
|
||||
// used in ReservedHeapSpace() constructors.
|
||||
// The final values will be set in initialize_heap() below.
|
||||
if (base != 0 && (base + heap_size) <= OopEncodingHeapMax) {
|
||||
if ((base != 0) && ((base + heap_size) <= OopEncodingHeapMax) &&
|
||||
(!UseCompressedKlassPointers || (base + Universe::class_metaspace_size()) <= KlassEncodingMetaspaceMax)) {
|
||||
// Use zero based compressed oops
|
||||
Universe::set_narrow_oop_base(NULL);
|
||||
// Don't need guard page for implicit checks in indexed
|
||||
@ -796,7 +814,9 @@ jint Universe::initialize_heap() {
|
||||
tty->print("heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB",
|
||||
Universe::heap()->base(), Universe::heap()->reserved_region().byte_size()/M);
|
||||
}
|
||||
if ((uint64_t)Universe::heap()->reserved_region().end() > OopEncodingHeapMax) {
|
||||
if (((uint64_t)Universe::heap()->reserved_region().end() > OopEncodingHeapMax) ||
|
||||
(UseCompressedKlassPointers &&
|
||||
((uint64_t)Universe::heap()->base() + Universe::class_metaspace_size() > KlassEncodingMetaspaceMax))) {
|
||||
// Can't reserve heap below 32Gb.
|
||||
// keep the Universe::narrow_oop_base() set in Universe::reserve_heap()
|
||||
Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
|
||||
@ -862,8 +882,8 @@ ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) {
|
||||
// be compressed the same as instances.
|
||||
// Need to round class space size up because it's below the heap and
|
||||
// the actual alignment depends on its size.
|
||||
size_t metaspace_size = align_size_up(ClassMetaspaceSize, alignment);
|
||||
size_t total_reserved = align_size_up(heap_size + metaspace_size, alignment);
|
||||
Universe::set_class_metaspace_size(align_size_up(ClassMetaspaceSize, alignment));
|
||||
size_t total_reserved = align_size_up(heap_size + Universe::class_metaspace_size(), alignment);
|
||||
char* addr = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop);
|
||||
|
||||
ReservedHeapSpace total_rs(total_reserved, alignment, UseLargePages, addr);
|
||||
@ -904,8 +924,8 @@ ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) {
|
||||
// compressed oops is greater than the one used for compressed klass
|
||||
// ptrs, a metadata space on top of the heap could become
|
||||
// unreachable.
|
||||
ReservedSpace class_rs = total_rs.first_part(metaspace_size);
|
||||
ReservedSpace heap_rs = total_rs.last_part(metaspace_size, alignment);
|
||||
ReservedSpace class_rs = total_rs.first_part(Universe::class_metaspace_size());
|
||||
ReservedSpace heap_rs = total_rs.last_part(Universe::class_metaspace_size(), alignment);
|
||||
Metaspace::initialize_class_space(class_rs);
|
||||
|
||||
if (UseCompressedOops) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -211,6 +211,9 @@ class Universe: AllStatic {
|
||||
static struct NarrowPtrStruct _narrow_klass;
|
||||
static address _narrow_ptrs_base;
|
||||
|
||||
// Aligned size of the metaspace.
|
||||
static size_t _class_metaspace_size;
|
||||
|
||||
// array of dummy objects used with +FullGCAlot
|
||||
debug_only(static objArrayOop _fullgc_alot_dummy_array;)
|
||||
// index of next entry to clear
|
||||
@ -278,6 +281,13 @@ class Universe: AllStatic {
|
||||
static bool reserve_metaspace_helper(bool with_base = false);
|
||||
static ReservedHeapSpace reserve_heap_metaspace(size_t heap_size, size_t alignment, bool& contiguous);
|
||||
|
||||
static size_t class_metaspace_size() {
|
||||
return _class_metaspace_size;
|
||||
}
|
||||
static void set_class_metaspace_size(size_t metaspace_size) {
|
||||
_class_metaspace_size = metaspace_size;
|
||||
}
|
||||
|
||||
// Debugging
|
||||
static int _verify_count; // number of verifies done
|
||||
// True during call to verify(). Should only be set/cleared in verify().
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,6 +24,7 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/classLoaderData.hpp"
|
||||
#include "memory/heapInspection.hpp"
|
||||
#include "memory/metadataFactory.hpp"
|
||||
#include "memory/oopFactory.hpp"
|
||||
#include "oops/annotations.hpp"
|
||||
@ -114,6 +115,50 @@ void Annotations::print_value_on(outputStream* st) const {
|
||||
st->print("Anotations(" INTPTR_FORMAT ")", this);
|
||||
}
|
||||
|
||||
#if INCLUDE_SERVICES
|
||||
// Size Statistics
|
||||
|
||||
julong Annotations::count_bytes(Array<AnnotationArray*>* p) {
|
||||
julong bytes = 0;
|
||||
if (p != NULL) {
|
||||
for (int i = 0; i < p->length(); i++) {
|
||||
bytes += KlassSizeStats::count_array(p->at(i));
|
||||
}
|
||||
bytes += KlassSizeStats::count_array(p);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void Annotations::collect_statistics(KlassSizeStats *sz) const {
|
||||
sz->_annotations_bytes = sz->count(this);
|
||||
sz->_class_annotations_bytes = sz->count(class_annotations());
|
||||
sz->_fields_annotations_bytes = count_bytes(fields_annotations());
|
||||
sz->_methods_annotations_bytes = count_bytes(methods_annotations());
|
||||
sz->_methods_parameter_annotations_bytes =
|
||||
count_bytes(methods_parameter_annotations());
|
||||
sz->_methods_default_annotations_bytes =
|
||||
count_bytes(methods_default_annotations());
|
||||
|
||||
const Annotations* type_anno = type_annotations();
|
||||
if (type_anno != NULL) {
|
||||
sz->_type_annotations_bytes = sz->count(type_anno);
|
||||
sz->_type_annotations_bytes += sz->count(type_anno->class_annotations());
|
||||
sz->_type_annotations_bytes += count_bytes(type_anno->fields_annotations());
|
||||
sz->_type_annotations_bytes += count_bytes(type_anno->methods_annotations());
|
||||
}
|
||||
|
||||
sz->_annotations_bytes +=
|
||||
sz->_class_annotations_bytes +
|
||||
sz->_fields_annotations_bytes +
|
||||
sz->_methods_annotations_bytes +
|
||||
sz->_methods_parameter_annotations_bytes +
|
||||
sz->_methods_default_annotations_bytes +
|
||||
sz->_type_annotations_bytes;
|
||||
|
||||
sz->_ro_bytes += sz->_annotations_bytes;
|
||||
}
|
||||
#endif // INCLUDE_SERVICES
|
||||
|
||||
#define BULLET " - "
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -34,6 +34,7 @@
|
||||
|
||||
class ClassLoaderData;
|
||||
class outputStream;
|
||||
class KlassSizeStats;
|
||||
|
||||
typedef Array<u1> AnnotationArray;
|
||||
|
||||
@ -82,7 +83,12 @@ class Annotations: public MetaspaceObj {
|
||||
Array<AnnotationArray*>* mda, TRAPS);
|
||||
void deallocate_contents(ClassLoaderData* loader_data);
|
||||
DEBUG_ONLY(bool on_stack() { return false; }) // for template
|
||||
|
||||
// Sizing (in words)
|
||||
static int size() { return sizeof(Annotations) / wordSize; }
|
||||
#if INCLUDE_SERVICES
|
||||
void collect_statistics(KlassSizeStats *sz) const;
|
||||
#endif
|
||||
|
||||
// Constructor to initialize to null
|
||||
Annotations() : _class_annotations(NULL),
|
||||
@ -142,7 +148,7 @@ class Annotations: public MetaspaceObj {
|
||||
void set_methods_annotations_of(instanceKlassHandle ik,
|
||||
int idnum, AnnotationArray* anno,
|
||||
Array<AnnotationArray*>** md_p, TRAPS);
|
||||
|
||||
static julong count_bytes(Array<AnnotationArray*>* p);
|
||||
public:
|
||||
const char* internal_name() const { return "{constant pool}"; }
|
||||
#ifndef PRODUCT
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -106,6 +106,14 @@ class ArrayKlass: public Klass {
|
||||
static int header_size() { return sizeof(ArrayKlass)/HeapWordSize; }
|
||||
static int static_size(int header_size);
|
||||
|
||||
#if INCLUDE_SERVICES
|
||||
virtual void collect_statistics(KlassSizeStats *sz) const {
|
||||
Klass::collect_statistics(sz);
|
||||
// Do nothing for now, but remember to modify if you add new
|
||||
// stuff to ArrayKlass.
|
||||
}
|
||||
#endif
|
||||
|
||||
// Java vtable
|
||||
klassVtable* vtable() const; // return new klassVtable
|
||||
int vtable_length() const { return _vtable_len; }
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,6 +25,7 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "memory/gcLocker.hpp"
|
||||
#include "memory/heapInspection.hpp"
|
||||
#include "memory/metadataFactory.hpp"
|
||||
#include "oops/constMethod.hpp"
|
||||
#include "oops/method.hpp"
|
||||
@ -330,6 +331,18 @@ void ConstMethod::print_value_on(outputStream* st) const {
|
||||
method()->print_value_on(st);
|
||||
}
|
||||
|
||||
#if INCLUDE_SERVICES
|
||||
// Size Statistics
|
||||
void ConstMethod::collect_statistics(KlassSizeStats *sz) const {
|
||||
int n1, n2, n3;
|
||||
sz->_const_method_bytes += (n1 = sz->count(this));
|
||||
sz->_bytecode_bytes += (n2 = code_size());
|
||||
sz->_stackmap_bytes += (n3 = sz->count_array(stackmap_data()));
|
||||
|
||||
sz->_method_all_bytes += n1 + n3; // note: n2 is part of n3
|
||||
sz->_ro_bytes += n1 + n3;
|
||||
}
|
||||
#endif // INCLUDE_SERVICES
|
||||
|
||||
// Verification
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -122,14 +122,10 @@ class ExceptionTableElement VALUE_OBJ_CLASS_SPEC {
|
||||
class MethodParametersElement VALUE_OBJ_CLASS_SPEC {
|
||||
public:
|
||||
u2 name_cp_index;
|
||||
// This has to happen, otherwise it will cause SIGBUS from a
|
||||
// misaligned u4 on some architectures (ie SPARC)
|
||||
// because MethodParametersElements are only aligned mod 2
|
||||
// within the ConstMethod container u2 flags_hi;
|
||||
u2 flags_hi;
|
||||
u2 flags_lo;
|
||||
u2 flags;
|
||||
};
|
||||
|
||||
class KlassSizeStats;
|
||||
|
||||
class ConstMethod : public MetaspaceObj {
|
||||
friend class VMStructs;
|
||||
@ -320,6 +316,9 @@ public:
|
||||
|
||||
int size() const { return _constMethod_size;}
|
||||
void set_constMethod_size(int size) { _constMethod_size = size; }
|
||||
#if INCLUDE_SERVICES
|
||||
void collect_statistics(KlassSizeStats *sz) const;
|
||||
#endif
|
||||
|
||||
// code size
|
||||
int code_size() const { return _code_size; }
|
||||
|
@ -25,16 +25,17 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/classLoaderData.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "classfile/metadataOnStackMark.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "interpreter/linkResolver.hpp"
|
||||
#include "memory/heapInspection.hpp"
|
||||
#include "memory/metadataFactory.hpp"
|
||||
#include "memory/oopFactory.hpp"
|
||||
#include "oops/constantPool.hpp"
|
||||
#include "oops/instanceKlass.hpp"
|
||||
#include "oops/objArrayKlass.hpp"
|
||||
#include "prims/jvmtiRedefineClasses.hpp"
|
||||
#include "runtime/fieldType.hpp"
|
||||
#include "runtime/init.hpp"
|
||||
#include "runtime/javaCalls.hpp"
|
||||
@ -65,11 +66,10 @@ ConstantPool::ConstantPool(Array<u1>* tags) {
|
||||
set_operands(NULL);
|
||||
set_pool_holder(NULL);
|
||||
set_flags(0);
|
||||
|
||||
// only set to non-zero if constant pool is merged by RedefineClasses
|
||||
set_version(0);
|
||||
set_lock(new Monitor(Monitor::nonleaf + 2, "A constant pool lock"));
|
||||
// all fields are initialized; needed for GC
|
||||
set_on_stack(false);
|
||||
|
||||
// initialize tag array
|
||||
int length = tags->length();
|
||||
@ -100,18 +100,6 @@ void ConstantPool::release_C_heap_structures() {
|
||||
set_lock(NULL);
|
||||
}
|
||||
|
||||
void ConstantPool::set_flag_at(FlagBit fb) {
|
||||
const int MAX_STATE_CHANGES = 2;
|
||||
for (int i = MAX_STATE_CHANGES + 10; i > 0; i--) {
|
||||
int oflags = _flags;
|
||||
int nflags = oflags | (1 << (int)fb);
|
||||
if (Atomic::cmpxchg(nflags, &_flags, oflags) == oflags)
|
||||
return;
|
||||
}
|
||||
assert(false, "failed to cmpxchg flags");
|
||||
_flags |= (1 << (int)fb); // better than nothing
|
||||
}
|
||||
|
||||
objArrayOop ConstantPool::resolved_references() const {
|
||||
return (objArrayOop)JNIHandles::resolve(_resolved_references);
|
||||
}
|
||||
@ -1111,32 +1099,9 @@ bool ConstantPool::compare_entry_to(int index1, constantPoolHandle cp2,
|
||||
} // end compare_entry_to()
|
||||
|
||||
|
||||
// Copy this constant pool's entries at start_i to end_i (inclusive)
|
||||
// to the constant pool to_cp's entries starting at to_i. A total of
|
||||
// (end_i - start_i) + 1 entries are copied.
|
||||
void ConstantPool::copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int end_i,
|
||||
constantPoolHandle to_cp, int to_i, TRAPS) {
|
||||
|
||||
int dest_i = to_i; // leave original alone for debug purposes
|
||||
|
||||
for (int src_i = start_i; src_i <= end_i; /* see loop bottom */ ) {
|
||||
copy_entry_to(from_cp, src_i, to_cp, dest_i, CHECK);
|
||||
|
||||
switch (from_cp->tag_at(src_i).value()) {
|
||||
case JVM_CONSTANT_Double:
|
||||
case JVM_CONSTANT_Long:
|
||||
// double and long take two constant pool entries
|
||||
src_i += 2;
|
||||
dest_i += 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
// all others take one constant pool entry
|
||||
src_i++;
|
||||
dest_i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
void ConstantPool::copy_operands(constantPoolHandle from_cp,
|
||||
constantPoolHandle to_cp,
|
||||
TRAPS) {
|
||||
|
||||
int from_oplen = operand_array_length(from_cp->operands());
|
||||
int old_oplen = operand_array_length(to_cp->operands());
|
||||
@ -1164,7 +1129,7 @@ void ConstantPool::copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int
|
||||
(len = old_off) * sizeof(u2));
|
||||
fillp += len;
|
||||
// first part of src
|
||||
Copy::conjoint_memory_atomic(to_cp->operands()->adr_at(0),
|
||||
Copy::conjoint_memory_atomic(from_cp->operands()->adr_at(0),
|
||||
new_operands->adr_at(fillp),
|
||||
(len = from_off) * sizeof(u2));
|
||||
fillp += len;
|
||||
@ -1174,7 +1139,7 @@ void ConstantPool::copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int
|
||||
(len = old_len - old_off) * sizeof(u2));
|
||||
fillp += len;
|
||||
// second part of src
|
||||
Copy::conjoint_memory_atomic(to_cp->operands()->adr_at(from_off),
|
||||
Copy::conjoint_memory_atomic(from_cp->operands()->adr_at(from_off),
|
||||
new_operands->adr_at(fillp),
|
||||
(len = from_len - from_off) * sizeof(u2));
|
||||
fillp += len;
|
||||
@ -1192,8 +1157,39 @@ void ConstantPool::copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int
|
||||
to_cp->set_operands(new_operands);
|
||||
}
|
||||
}
|
||||
} // end copy_operands()
|
||||
|
||||
} // end copy_cp_to()
|
||||
|
||||
// Copy this constant pool's entries at start_i to end_i (inclusive)
|
||||
// to the constant pool to_cp's entries starting at to_i. A total of
|
||||
// (end_i - start_i) + 1 entries are copied.
|
||||
void ConstantPool::copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int end_i,
|
||||
constantPoolHandle to_cp, int to_i, TRAPS) {
|
||||
|
||||
|
||||
int dest_i = to_i; // leave original alone for debug purposes
|
||||
|
||||
for (int src_i = start_i; src_i <= end_i; /* see loop bottom */ ) {
|
||||
copy_entry_to(from_cp, src_i, to_cp, dest_i, CHECK);
|
||||
|
||||
switch (from_cp->tag_at(src_i).value()) {
|
||||
case JVM_CONSTANT_Double:
|
||||
case JVM_CONSTANT_Long:
|
||||
// double and long take two constant pool entries
|
||||
src_i += 2;
|
||||
dest_i += 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
// all others take one constant pool entry
|
||||
src_i++;
|
||||
dest_i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
copy_operands(from_cp, to_cp, CHECK);
|
||||
|
||||
} // end copy_cp_to_impl()
|
||||
|
||||
|
||||
// Copy this constant pool's entry at from_i to the constant pool
|
||||
@ -1755,7 +1751,11 @@ int ConstantPool::copy_cpool_bytes(int cpool_size,
|
||||
|
||||
|
||||
void ConstantPool::set_on_stack(const bool value) {
|
||||
_on_stack = value;
|
||||
if (value) {
|
||||
_flags |= _on_stack;
|
||||
} else {
|
||||
_flags &= ~_on_stack;
|
||||
}
|
||||
if (value) MetadataOnStackMark::record(this);
|
||||
}
|
||||
|
||||
@ -1827,6 +1827,7 @@ void ConstantPool::print_on(outputStream* st) const {
|
||||
if (has_pseudo_string()) st->print(" has_pseudo_string");
|
||||
if (has_invokedynamic()) st->print(" has_invokedynamic");
|
||||
if (has_preresolution()) st->print(" has_preresolution");
|
||||
if (on_stack()) st->print(" on_stack");
|
||||
st->cr();
|
||||
}
|
||||
if (pool_holder() != NULL) {
|
||||
@ -1954,6 +1955,20 @@ void ConstantPool::print_value_on(outputStream* st) const {
|
||||
}
|
||||
}
|
||||
|
||||
#if INCLUDE_SERVICES
|
||||
// Size Statistics
|
||||
void ConstantPool::collect_statistics(KlassSizeStats *sz) const {
|
||||
sz->_cp_all_bytes += (sz->_cp_bytes = sz->count(this));
|
||||
sz->_cp_all_bytes += (sz->_cp_tags_bytes = sz->count_array(tags()));
|
||||
sz->_cp_all_bytes += (sz->_cp_cache_bytes = sz->count(cache()));
|
||||
sz->_cp_all_bytes += (sz->_cp_operands_bytes = sz->count_array(operands()));
|
||||
sz->_cp_all_bytes += (sz->_cp_refmap_bytes = sz->count_array(reference_map()));
|
||||
|
||||
sz->_ro_bytes += sz->_cp_operands_bytes + sz->_cp_tags_bytes +
|
||||
sz->_cp_refmap_bytes;
|
||||
sz->_rw_bytes += sz->_cp_bytes + sz->_cp_cache_bytes;
|
||||
}
|
||||
#endif // INCLUDE_SERVICES
|
||||
|
||||
// Verification
|
||||
|
||||
|
@ -80,6 +80,7 @@ class CPSlot VALUE_OBJ_CLASS_SPEC {
|
||||
}
|
||||
};
|
||||
|
||||
class KlassSizeStats;
|
||||
class ConstantPool : public Metadata {
|
||||
friend class VMStructs;
|
||||
friend class BytecodeInterpreter; // Directly extracts an oop in the pool for fast instanceof/checkcast
|
||||
@ -95,10 +96,15 @@ class ConstantPool : public Metadata {
|
||||
jobject _resolved_references;
|
||||
Array<u2>* _reference_map;
|
||||
|
||||
int _flags; // a few header bits to describe contents for GC
|
||||
int _length; // number of elements in the array
|
||||
enum {
|
||||
_has_invokedynamic = 1, // Flags
|
||||
_has_pseudo_string = 2,
|
||||
_has_preresolution = 4,
|
||||
_on_stack = 8
|
||||
};
|
||||
|
||||
bool _on_stack; // Redefined method still executing refers to this constant pool.
|
||||
int _flags; // old fashioned bit twiddling
|
||||
int _length; // number of elements in the array
|
||||
|
||||
union {
|
||||
// set for CDS to restore resolved references
|
||||
@ -115,17 +121,8 @@ class ConstantPool : public Metadata {
|
||||
|
||||
void set_operands(Array<u2>* operands) { _operands = operands; }
|
||||
|
||||
enum FlagBit {
|
||||
FB_has_invokedynamic = 1,
|
||||
FB_has_pseudo_string = 2,
|
||||
FB_has_preresolution = 3
|
||||
};
|
||||
|
||||
int flags() const { return _flags; }
|
||||
void set_flags(int f) { _flags = f; }
|
||||
bool flag_at(FlagBit fb) const { return (_flags & (1 << (int)fb)) != 0; }
|
||||
void set_flag_at(FlagBit fb);
|
||||
// no clear_flag_at function; they only increase
|
||||
int flags() const { return _flags; }
|
||||
void set_flags(int f) { _flags = f; }
|
||||
|
||||
private:
|
||||
intptr_t* base() const { return (intptr_t*) (((char*) this) + sizeof(ConstantPool)); }
|
||||
@ -178,18 +175,20 @@ class ConstantPool : public Metadata {
|
||||
Array<u1>* tags() const { return _tags; }
|
||||
Array<u2>* operands() const { return _operands; }
|
||||
|
||||
bool has_pseudo_string() const { return flag_at(FB_has_pseudo_string); }
|
||||
bool has_invokedynamic() const { return flag_at(FB_has_invokedynamic); }
|
||||
bool has_preresolution() const { return flag_at(FB_has_preresolution); }
|
||||
void set_pseudo_string() { set_flag_at(FB_has_pseudo_string); }
|
||||
void set_invokedynamic() { set_flag_at(FB_has_invokedynamic); }
|
||||
void set_preresolution() { set_flag_at(FB_has_preresolution); }
|
||||
bool has_invokedynamic() const { return (_flags & _has_invokedynamic) != 0; }
|
||||
void set_has_invokedynamic() { _flags |= _has_invokedynamic; }
|
||||
|
||||
bool has_pseudo_string() const { return (_flags & _has_pseudo_string) != 0; }
|
||||
void set_has_pseudo_string() { _flags |= _has_pseudo_string; }
|
||||
|
||||
bool has_preresolution() const { return (_flags & _has_preresolution) != 0; }
|
||||
void set_has_preresolution() { _flags |= _has_preresolution; }
|
||||
|
||||
// Redefine classes support. If a method refering to this constant pool
|
||||
// is on the executing stack, or as a handle in vm code, this constant pool
|
||||
// can't be removed from the set of previous versions saved in the instance
|
||||
// class.
|
||||
bool on_stack() const { return _on_stack; }
|
||||
bool on_stack() const { return (_flags &_on_stack) != 0; }
|
||||
void set_on_stack(const bool value);
|
||||
|
||||
// Klass holding pool
|
||||
@ -457,7 +456,7 @@ class ConstantPool : public Metadata {
|
||||
|
||||
void pseudo_string_at_put(int which, int obj_index, oop x) {
|
||||
assert(EnableInvokeDynamic, "");
|
||||
set_pseudo_string(); // mark header
|
||||
set_has_pseudo_string(); // mark header
|
||||
assert(tag_at(which).is_string(), "Corrupted constant pool");
|
||||
string_at_put(which, obj_index, x); // this works just fine
|
||||
}
|
||||
@ -686,9 +685,13 @@ class ConstantPool : public Metadata {
|
||||
return 0 <= index && index < length();
|
||||
}
|
||||
|
||||
// Sizing (in words)
|
||||
static int header_size() { return sizeof(ConstantPool)/HeapWordSize; }
|
||||
static int size(int length) { return align_object_size(header_size() + length); }
|
||||
int size() const { return size(length()); }
|
||||
#if INCLUDE_SERVICES
|
||||
void collect_statistics(KlassSizeStats *sz) const;
|
||||
#endif
|
||||
|
||||
friend class ClassFileParser;
|
||||
friend class SystemDictionary;
|
||||
@ -783,6 +786,7 @@ class ConstantPool : public Metadata {
|
||||
}
|
||||
static void copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int end_i, constantPoolHandle to_cp, int to_i, TRAPS);
|
||||
static void copy_entry_to(constantPoolHandle from_cp, int from_i, constantPoolHandle to_cp, int to_i, TRAPS);
|
||||
static void copy_operands(constantPoolHandle from_cp, constantPoolHandle to_cp, TRAPS);
|
||||
int find_matching_entry(int pattern_i, constantPoolHandle search_cp, TRAPS);
|
||||
int version() const { return _saved._version; }
|
||||
void set_version(int version) { _saved._version = version; }
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -34,6 +34,7 @@
|
||||
#include "interpreter/rewriter.hpp"
|
||||
#include "jvmtifiles/jvmti.h"
|
||||
#include "memory/genOopClosures.inline.hpp"
|
||||
#include "memory/heapInspection.hpp"
|
||||
#include "memory/metadataFactory.hpp"
|
||||
#include "memory/oopFactory.hpp"
|
||||
#include "oops/fieldStreams.hpp"
|
||||
@ -2960,6 +2961,52 @@ const char* InstanceKlass::internal_name() const {
|
||||
return external_name();
|
||||
}
|
||||
|
||||
#if INCLUDE_SERVICES
|
||||
// Size Statistics
|
||||
void InstanceKlass::collect_statistics(KlassSizeStats *sz) const {
|
||||
Klass::collect_statistics(sz);
|
||||
|
||||
sz->_inst_size = HeapWordSize * size_helper();
|
||||
sz->_vtab_bytes = HeapWordSize * align_object_offset(vtable_length());
|
||||
sz->_itab_bytes = HeapWordSize * align_object_offset(itable_length());
|
||||
sz->_nonstatic_oopmap_bytes = HeapWordSize *
|
||||
((is_interface() || is_anonymous()) ?
|
||||
align_object_offset(nonstatic_oop_map_size()) :
|
||||
nonstatic_oop_map_size());
|
||||
|
||||
int n = 0;
|
||||
n += (sz->_methods_array_bytes = sz->count_array(methods()));
|
||||
n += (sz->_method_ordering_bytes = sz->count_array(method_ordering()));
|
||||
n += (sz->_local_interfaces_bytes = sz->count_array(local_interfaces()));
|
||||
n += (sz->_transitive_interfaces_bytes = sz->count_array(transitive_interfaces()));
|
||||
n += (sz->_signers_bytes = sz->count_array(signers()));
|
||||
n += (sz->_fields_bytes = sz->count_array(fields()));
|
||||
n += (sz->_inner_classes_bytes = sz->count_array(inner_classes()));
|
||||
sz->_ro_bytes += n;
|
||||
|
||||
const ConstantPool* cp = constants();
|
||||
if (cp) {
|
||||
cp->collect_statistics(sz);
|
||||
}
|
||||
|
||||
const Annotations* anno = annotations();
|
||||
if (anno) {
|
||||
anno->collect_statistics(sz);
|
||||
}
|
||||
|
||||
const Array<Method*>* methods_array = methods();
|
||||
if (methods()) {
|
||||
for (int i = 0; i < methods_array->length(); i++) {
|
||||
Method* method = methods_array->at(i);
|
||||
if (method) {
|
||||
sz->_method_count ++;
|
||||
method->collect_statistics(sz);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // INCLUDE_SERVICES
|
||||
|
||||
// Verification
|
||||
|
||||
class VerifyFieldClosure: public OopClosure {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -256,6 +256,16 @@ class InstanceKlass: public Klass {
|
||||
// JVMTI fields can be moved to their own structure - see 6315920
|
||||
unsigned char * _cached_class_file_bytes; // JVMTI: cached class file, before retransformable agent modified it in CFLH
|
||||
jint _cached_class_file_len; // JVMTI: length of above
|
||||
|
||||
volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change
|
||||
|
||||
// Class states are defined as ClassState (see above).
|
||||
// Place the _init_state here to utilize the unused 2-byte after
|
||||
// _idnum_allocated_count.
|
||||
u1 _init_state; // state of class
|
||||
u1 _reference_type; // reference type
|
||||
|
||||
|
||||
JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map; // JVMTI: used during heap iteration
|
||||
|
||||
// Method array.
|
||||
@ -281,15 +291,6 @@ class InstanceKlass: public Klass {
|
||||
// ...
|
||||
Array<u2>* _fields;
|
||||
|
||||
volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change
|
||||
|
||||
// Class states are defined as ClassState (see above).
|
||||
// Place the _init_state here to utilize the unused 2-byte after
|
||||
// _idnum_allocated_count.
|
||||
u1 _init_state; // state of class
|
||||
|
||||
u1 _reference_type; // reference type
|
||||
|
||||
// embedded Java vtable follows here
|
||||
// embedded Java itables follows here
|
||||
// embedded static fields follows here
|
||||
@ -826,6 +827,9 @@ class InstanceKlass: public Klass {
|
||||
is_interface(),
|
||||
is_anonymous());
|
||||
}
|
||||
#if INCLUDE_SERVICES
|
||||
virtual void collect_statistics(KlassSizeStats *sz) const;
|
||||
#endif
|
||||
|
||||
static int vtable_start_offset() { return header_size(); }
|
||||
static int vtable_length_offset() { return offset_of(InstanceKlass, _vtable_len) / HeapWordSize; }
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -29,6 +29,7 @@
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "gc_implementation/shared/markSweep.inline.hpp"
|
||||
#include "gc_interface/collectedHeap.inline.hpp"
|
||||
#include "memory/heapInspection.hpp"
|
||||
#include "memory/metadataFactory.hpp"
|
||||
#include "memory/oopFactory.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
@ -624,6 +625,17 @@ void Klass::oop_print_value_on(oop obj, outputStream* st) {
|
||||
obj->print_address_on(st);
|
||||
}
|
||||
|
||||
#if INCLUDE_SERVICES
|
||||
// Size Statistics
|
||||
void Klass::collect_statistics(KlassSizeStats *sz) const {
|
||||
sz->_klass_bytes = sz->count(this);
|
||||
sz->_mirror_bytes = sz->count(java_mirror());
|
||||
sz->_secondary_supers_bytes = sz->count_array(secondary_supers());
|
||||
|
||||
sz->_ro_bytes += sz->_secondary_supers_bytes;
|
||||
sz->_rw_bytes += sz->_klass_bytes + sz->_mirror_bytes;
|
||||
}
|
||||
#endif // INCLUDE_SERVICES
|
||||
|
||||
// Verification
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -75,11 +75,11 @@
|
||||
// [class_loader_data]
|
||||
// [modifier_flags]
|
||||
// [access_flags ]
|
||||
// [verify_count ] - not in product
|
||||
// [alloc_count ]
|
||||
// [last_biased_lock_bulk_revocation_time] (64 bits)
|
||||
// [prototype_header]
|
||||
// [biased_lock_revocation_count]
|
||||
// [verify_count ] - not in product
|
||||
// [alloc_count ]
|
||||
// [_modified_oops]
|
||||
// [_accumulated_modified_oops]
|
||||
// [trace_id]
|
||||
@ -91,6 +91,7 @@ template <class T> class GrowableArray;
|
||||
class ClassLoaderData;
|
||||
class klassVtable;
|
||||
class ParCompactionManager;
|
||||
class KlassSizeStats;
|
||||
|
||||
class Klass : public Metadata {
|
||||
friend class VMStructs;
|
||||
@ -164,18 +165,18 @@ class Klass : public Metadata {
|
||||
jint _modifier_flags; // Processed access flags, for use by Class.getModifiers.
|
||||
AccessFlags _access_flags; // Access flags. The class/interface distinction is stored here.
|
||||
|
||||
#ifndef PRODUCT
|
||||
int _verify_count; // to avoid redundant verifies
|
||||
#endif
|
||||
|
||||
juint _alloc_count; // allocation profiling support
|
||||
|
||||
// Biased locking implementation and statistics
|
||||
// (the 64-bit chunk goes first, to avoid some fragmentation)
|
||||
jlong _last_biased_lock_bulk_revocation_time;
|
||||
markOop _prototype_header; // Used when biased locking is both enabled and disabled for this type
|
||||
jint _biased_lock_revocation_count;
|
||||
|
||||
#ifndef PRODUCT
|
||||
int _verify_count; // to avoid redundant verifies
|
||||
#endif
|
||||
|
||||
juint _alloc_count; // allocation profiling support
|
||||
|
||||
TRACE_DEFINE_KLASS_TRACE_ID;
|
||||
|
||||
// Remembered sets support for the oops in the klasses.
|
||||
@ -477,6 +478,9 @@ class Klass : public Metadata {
|
||||
|
||||
// Size of klass in word size.
|
||||
virtual int size() const = 0;
|
||||
#if INCLUDE_SERVICES
|
||||
virtual void collect_statistics(KlassSizeStats *sz) const;
|
||||
#endif
|
||||
|
||||
// Returns the Java name for a class (Resource allocated)
|
||||
// For arrays, this returns the name of the element with a leading '['.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/metadataOnStackMark.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "code/debugInfoRec.hpp"
|
||||
#include "gc_interface/collectedHeap.inline.hpp"
|
||||
@ -33,6 +34,7 @@
|
||||
#include "interpreter/oopMapCache.hpp"
|
||||
#include "memory/gcLocker.hpp"
|
||||
#include "memory/generation.hpp"
|
||||
#include "memory/heapInspection.hpp"
|
||||
#include "memory/metadataFactory.hpp"
|
||||
#include "memory/oopFactory.hpp"
|
||||
#include "oops/constMethod.hpp"
|
||||
@ -41,7 +43,6 @@
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "oops/symbol.hpp"
|
||||
#include "prims/jvmtiExport.hpp"
|
||||
#include "prims/jvmtiRedefineClasses.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
#include "prims/nativeLookup.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
@ -699,7 +700,7 @@ void Method::set_signature_handler(address handler) {
|
||||
}
|
||||
|
||||
|
||||
void Method::print_made_not_compilable(int comp_level, bool is_osr, bool report) {
|
||||
void Method::print_made_not_compilable(int comp_level, bool is_osr, bool report, const char* reason) {
|
||||
if (PrintCompilation && report) {
|
||||
ttyLocker ttyl;
|
||||
tty->print("made not %scompilable on ", is_osr ? "OSR " : "");
|
||||
@ -713,14 +714,21 @@ void Method::print_made_not_compilable(int comp_level, bool is_osr, bool report)
|
||||
}
|
||||
this->print_short_name(tty);
|
||||
int size = this->code_size();
|
||||
if (size > 0)
|
||||
if (size > 0) {
|
||||
tty->print(" (%d bytes)", size);
|
||||
}
|
||||
if (reason != NULL) {
|
||||
tty->print(" %s", reason);
|
||||
}
|
||||
tty->cr();
|
||||
}
|
||||
if ((TraceDeoptimization || LogCompilation) && (xtty != NULL)) {
|
||||
ttyLocker ttyl;
|
||||
xtty->begin_elem("make_not_%scompilable thread='" UINTX_FORMAT "'",
|
||||
is_osr ? "osr_" : "", os::current_thread_id());
|
||||
if (reason != NULL) {
|
||||
xtty->print(" reason=\'%s\'", reason);
|
||||
}
|
||||
xtty->method(this);
|
||||
xtty->stamp();
|
||||
xtty->end_elem();
|
||||
@ -742,8 +750,8 @@ bool Method::is_not_compilable(int comp_level) const {
|
||||
}
|
||||
|
||||
// call this when compiler finds that this method is not compilable
|
||||
void Method::set_not_compilable(int comp_level, bool report) {
|
||||
print_made_not_compilable(comp_level, /*is_osr*/ false, report);
|
||||
void Method::set_not_compilable(int comp_level, bool report, const char* reason) {
|
||||
print_made_not_compilable(comp_level, /*is_osr*/ false, report, reason);
|
||||
if (comp_level == CompLevel_all) {
|
||||
set_not_c1_compilable();
|
||||
set_not_c2_compilable();
|
||||
@ -768,8 +776,8 @@ bool Method::is_not_osr_compilable(int comp_level) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Method::set_not_osr_compilable(int comp_level, bool report) {
|
||||
print_made_not_compilable(comp_level, /*is_osr*/ true, report);
|
||||
void Method::set_not_osr_compilable(int comp_level, bool report, const char* reason) {
|
||||
print_made_not_compilable(comp_level, /*is_osr*/ true, report, reason);
|
||||
if (comp_level == CompLevel_all) {
|
||||
set_not_c1_osr_compilable();
|
||||
set_not_c2_osr_compilable();
|
||||
@ -1027,7 +1035,7 @@ methodHandle Method::make_method_handle_intrinsic(vmIntrinsics::ID iid,
|
||||
cp->set_pool_holder(InstanceKlass::cast(holder()));
|
||||
cp->symbol_at_put(_imcp_invoke_name, name);
|
||||
cp->symbol_at_put(_imcp_invoke_signature, signature);
|
||||
cp->set_preresolution();
|
||||
cp->set_has_preresolution();
|
||||
|
||||
// decide on access bits: public or not?
|
||||
int flags_bits = (JVM_ACC_NATIVE | JVM_ACC_SYNTHETIC | JVM_ACC_FINAL);
|
||||
@ -1954,6 +1962,22 @@ void Method::print_value_on(outputStream* st) const {
|
||||
if (WizardMode && code() != NULL) st->print(" ((nmethod*)%p)", code());
|
||||
}
|
||||
|
||||
#if INCLUDE_SERVICES
|
||||
// Size Statistics
|
||||
void Method::collect_statistics(KlassSizeStats *sz) const {
|
||||
int mysize = sz->count(this);
|
||||
sz->_method_bytes += mysize;
|
||||
sz->_method_all_bytes += mysize;
|
||||
sz->_rw_bytes += mysize;
|
||||
|
||||
if (constMethod()) {
|
||||
constMethod()->collect_statistics(sz);
|
||||
}
|
||||
if (method_data()) {
|
||||
method_data()->collect_statistics(sz);
|
||||
}
|
||||
}
|
||||
#endif // INCLUDE_SERVICES
|
||||
|
||||
// Verification
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -101,6 +101,7 @@ class LocalVariableTableElement;
|
||||
class AdapterHandlerEntry;
|
||||
class MethodData;
|
||||
class ConstMethod;
|
||||
class KlassSizeStats;
|
||||
|
||||
class Method : public Metadata {
|
||||
friend class VMStructs;
|
||||
@ -127,8 +128,8 @@ class Method : public Metadata {
|
||||
InvocationCounter _backedge_counter; // Incremented before each backedge taken - used to trigger frequencey-based optimizations
|
||||
|
||||
#ifdef TIERED
|
||||
jlong _prev_time; // Previous time the rate was acquired
|
||||
float _rate; // Events (invocation and backedge counter increments) per millisecond
|
||||
jlong _prev_time; // Previous time the rate was acquired
|
||||
#endif
|
||||
|
||||
#ifndef PRODUCT
|
||||
@ -593,6 +594,9 @@ class Method : public Metadata {
|
||||
static int header_size() { return sizeof(Method)/HeapWordSize; }
|
||||
static int size(bool is_native);
|
||||
int size() const { return method_size(); }
|
||||
#if INCLUDE_SERVICES
|
||||
void collect_statistics(KlassSizeStats *sz) const;
|
||||
#endif
|
||||
|
||||
// interpreter support
|
||||
static ByteSize const_offset() { return byte_offset_of(Method, _constMethod ); }
|
||||
@ -760,18 +764,18 @@ class Method : public Metadata {
|
||||
// whether it is not compilable for another reason like having a
|
||||
// breakpoint set in it.
|
||||
bool is_not_compilable(int comp_level = CompLevel_any) const;
|
||||
void set_not_compilable(int comp_level = CompLevel_all, bool report = true);
|
||||
void set_not_compilable(int comp_level = CompLevel_all, bool report = true, const char* reason = NULL);
|
||||
void set_not_compilable_quietly(int comp_level = CompLevel_all) {
|
||||
set_not_compilable(comp_level, false);
|
||||
}
|
||||
bool is_not_osr_compilable(int comp_level = CompLevel_any) const;
|
||||
void set_not_osr_compilable(int comp_level = CompLevel_all, bool report = true);
|
||||
void set_not_osr_compilable(int comp_level = CompLevel_all, bool report = true, const char* reason = NULL);
|
||||
void set_not_osr_compilable_quietly(int comp_level = CompLevel_all) {
|
||||
set_not_osr_compilable(comp_level, false);
|
||||
}
|
||||
|
||||
private:
|
||||
void print_made_not_compilable(int comp_level, bool is_osr, bool report);
|
||||
void print_made_not_compilable(int comp_level, bool is_osr, bool report, const char* reason);
|
||||
|
||||
public:
|
||||
bool is_not_c1_compilable() const { return access_flags().is_not_c1_compilable(); }
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,6 +27,7 @@
|
||||
#include "interpreter/bytecode.hpp"
|
||||
#include "interpreter/bytecodeStream.hpp"
|
||||
#include "interpreter/linkResolver.hpp"
|
||||
#include "memory/heapInspection.hpp"
|
||||
#include "oops/methodData.hpp"
|
||||
#include "prims/jvmtiRedefineClasses.hpp"
|
||||
#include "runtime/compilationPolicy.hpp"
|
||||
@ -859,6 +860,15 @@ void MethodData::print_data_on(outputStream* st) const {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if INCLUDE_SERVICES
|
||||
// Size Statistics
|
||||
void MethodData::collect_statistics(KlassSizeStats *sz) const {
|
||||
int n = sz->count(this);
|
||||
sz->_method_data_bytes += n;
|
||||
sz->_method_all_bytes += n;
|
||||
sz->_rw_bytes += n;
|
||||
}
|
||||
#endif // INCLUDE_SERVICES
|
||||
|
||||
// Verification
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -32,6 +32,7 @@
|
||||
#include "runtime/orderAccess.hpp"
|
||||
|
||||
class BytecodeStream;
|
||||
class KlassSizeStats;
|
||||
|
||||
// The MethodData object collects counts and other profile information
|
||||
// during zeroth-tier (interpretive) and first-tier execution.
|
||||
@ -1289,6 +1290,9 @@ public:
|
||||
// My size
|
||||
int size_in_bytes() const { return _size; }
|
||||
int size() const { return align_object_size(align_size_up(_size, BytesPerWord)/BytesPerWord); }
|
||||
#if INCLUDE_SERVICES
|
||||
void collect_statistics(KlassSizeStats *sz) const;
|
||||
#endif
|
||||
|
||||
int creation_mileage() const { return _creation_mileage; }
|
||||
void set_creation_mileage(int x) { _creation_mileage = x; }
|
||||
@ -1465,7 +1469,7 @@ public:
|
||||
void inc_decompile_count() {
|
||||
_nof_decompiles += 1;
|
||||
if (decompile_count() > (uint)PerMethodRecompilationCutoff) {
|
||||
method()->set_not_compilable(CompLevel_full_optimization);
|
||||
method()->set_not_compilable(CompLevel_full_optimization, true, "decompile_count > PerMethodRecompilationCutoff");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -227,12 +227,12 @@ inline oop oopDesc::decode_heap_oop(oop v) { return v; }
|
||||
// might not be the same as oop.
|
||||
|
||||
inline narrowOop oopDesc::encode_klass_not_null(Klass* v) {
|
||||
assert(!is_null(v), "oop value can never be zero");
|
||||
assert(!is_null(v), "klass value can never be zero");
|
||||
assert(check_klass_alignment(v), "Address not aligned");
|
||||
address base = Universe::narrow_klass_base();
|
||||
int shift = Universe::narrow_klass_shift();
|
||||
uint64_t pd = (uint64_t)(pointer_delta((void*)v, (void*)base, 1));
|
||||
assert(OopEncodingHeapMax > pd, "change encoding max if new encoding");
|
||||
assert(KlassEncodingMetaspaceMax > pd, "change encoding max if new encoding");
|
||||
uint64_t result = pd >> shift;
|
||||
assert((result & CONST64(0xffffffff00000000)) == 0, "narrow klass pointer overflow");
|
||||
assert(decode_klass(result) == v, "reversibility");
|
||||
|
@ -152,6 +152,7 @@ char* Symbol::as_C_string_flexible_buffer(Thread* t,
|
||||
}
|
||||
|
||||
void Symbol::print_symbol_on(outputStream* st) const {
|
||||
ResourceMark rm;
|
||||
st = st ? st : tty;
|
||||
st->print("%s", as_quoted_ascii());
|
||||
}
|
||||
|
@ -420,14 +420,24 @@ const char* InlineTree::check_can_parse(ciMethod* callee) {
|
||||
}
|
||||
|
||||
//------------------------------print_inlining---------------------------------
|
||||
// Really, the failure_msg can be a success message also.
|
||||
void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci, const char* failure_msg) const {
|
||||
C->print_inlining(callee_method, inline_level(), caller_bci, failure_msg ? failure_msg : "inline");
|
||||
if (callee_method == NULL) tty->print(" callee not monotonic or profiled");
|
||||
if (Verbose && callee_method) {
|
||||
const InlineTree *top = this;
|
||||
while( top->caller_tree() != NULL ) { top = top->caller_tree(); }
|
||||
//tty->print(" bcs: %d+%d invoked: %d", top->count_inline_bcs(), callee_method->code_size(), callee_method->interpreter_invocation_count());
|
||||
void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci,
|
||||
const char* msg, bool success) const {
|
||||
assert(msg != NULL, "just checking");
|
||||
if (C->log() != NULL) {
|
||||
if (success) {
|
||||
C->log()->inline_success(msg);
|
||||
} else {
|
||||
C->log()->inline_fail(msg);
|
||||
}
|
||||
}
|
||||
if (PrintInlining) {
|
||||
C->print_inlining(callee_method, inline_level(), caller_bci, msg);
|
||||
if (callee_method == NULL) tty->print(" callee not monotonic or profiled");
|
||||
if (Verbose && callee_method) {
|
||||
const InlineTree *top = this;
|
||||
while( top->caller_tree() != NULL ) { top = top->caller_tree(); }
|
||||
//tty->print(" bcs: %d+%d invoked: %d", top->count_inline_bcs(), callee_method->code_size(), callee_method->interpreter_invocation_count());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -451,23 +461,23 @@ WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms,
|
||||
|
||||
// Do some initial checks.
|
||||
if (!pass_initial_checks(caller_method, caller_bci, callee_method)) {
|
||||
if (PrintInlining) print_inlining(callee_method, caller_bci, "failed initial checks");
|
||||
print_inlining(callee_method, caller_bci, "failed initial checks",
|
||||
false /* !success */);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Do some parse checks.
|
||||
failure_msg = check_can_parse(callee_method);
|
||||
if (failure_msg != NULL) {
|
||||
if (PrintInlining) print_inlining(callee_method, caller_bci, failure_msg);
|
||||
print_inlining(callee_method, caller_bci, failure_msg,
|
||||
false /* !success */);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Check if inlining policy says no.
|
||||
WarmCallInfo wci = *(initial_wci);
|
||||
failure_msg = try_to_inline(callee_method, caller_method, caller_bci, profile, &wci, should_delay);
|
||||
if (failure_msg != NULL && C->log() != NULL) {
|
||||
C->log()->inline_fail(failure_msg);
|
||||
}
|
||||
failure_msg = try_to_inline(callee_method, caller_method, caller_bci, profile,
|
||||
&wci, should_delay);
|
||||
|
||||
#ifndef PRODUCT
|
||||
if (UseOldInlining && InlineWarmCalls
|
||||
@ -487,7 +497,7 @@ WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms,
|
||||
wci = *(WarmCallInfo::always_hot());
|
||||
else
|
||||
wci = *(WarmCallInfo::always_cold());
|
||||
}
|
||||
}
|
||||
if (!InlineWarmCalls) {
|
||||
if (!wci.is_cold() && !wci.is_hot()) {
|
||||
// Do not inline the warm calls.
|
||||
@ -496,11 +506,10 @@ WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms,
|
||||
}
|
||||
|
||||
if (!wci.is_cold()) {
|
||||
// In -UseOldInlining, the failure_msg may also be a success message.
|
||||
if (failure_msg == NULL) failure_msg = "inline (hot)";
|
||||
|
||||
// Inline!
|
||||
if (PrintInlining) print_inlining(callee_method, caller_bci, failure_msg);
|
||||
print_inlining(callee_method, caller_bci,
|
||||
failure_msg ? failure_msg : "inline (hot)",
|
||||
true /* success */);
|
||||
if (UseOldInlining)
|
||||
build_inline_tree_for_callee(callee_method, jvms, caller_bci);
|
||||
if (InlineWarmCalls && !wci.is_hot())
|
||||
@ -509,8 +518,9 @@ WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms,
|
||||
}
|
||||
|
||||
// Do not inline
|
||||
if (failure_msg == NULL) failure_msg = "too cold to inline";
|
||||
if (PrintInlining) print_inlining(callee_method, caller_bci, failure_msg);
|
||||
print_inlining(callee_method, caller_bci,
|
||||
failure_msg ? failure_msg : "too cold to inline",
|
||||
false /* !success */ );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -305,11 +305,13 @@ class LateInlineCallGenerator : public DirectCallGenerator {
|
||||
void LateInlineCallGenerator::do_late_inline() {
|
||||
// Can't inline it
|
||||
if (call_node() == NULL || call_node()->outcnt() == 0 ||
|
||||
call_node()->in(0) == NULL || call_node()->in(0)->is_top())
|
||||
call_node()->in(0) == NULL || call_node()->in(0)->is_top()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const TypeTuple *r = call_node()->tf()->domain();
|
||||
for (int i1 = 0; i1 < method()->arg_size(); i1++) {
|
||||
if (call_node()->in(TypeFunc::Parms + i1)->is_top()) {
|
||||
if (call_node()->in(TypeFunc::Parms + i1)->is_top() && r->field_at(TypeFunc::Parms + i1) != Type::HALF) {
|
||||
assert(Compile::current()->inlining_incrementally(), "shouldn't happen during parsing");
|
||||
return;
|
||||
}
|
||||
|
@ -88,12 +88,12 @@ void GraphKit::gen_stub(address C_function,
|
||||
thread,
|
||||
in_bytes(JavaThread::frame_anchor_offset()) +
|
||||
in_bytes(JavaFrameAnchor::last_Java_pc_offset()));
|
||||
#if defined(SPARC) || defined(IA64)
|
||||
#if defined(SPARC)
|
||||
Node* adr_flags = basic_plus_adr(top(),
|
||||
thread,
|
||||
in_bytes(JavaThread::frame_anchor_offset()) +
|
||||
in_bytes(JavaFrameAnchor::flags_offset()));
|
||||
#endif /* defined(SPARC) || defined(IA64) */
|
||||
#endif /* defined(SPARC) */
|
||||
|
||||
|
||||
// Drop in the last_Java_sp. last_Java_fp is not touched.
|
||||
@ -102,10 +102,8 @@ void GraphKit::gen_stub(address C_function,
|
||||
// users will look at the other fields.
|
||||
//
|
||||
Node *adr_sp = basic_plus_adr(top(), thread, in_bytes(JavaThread::last_Java_sp_offset()));
|
||||
#ifndef IA64
|
||||
Node *last_sp = basic_plus_adr(top(), frameptr(), (intptr_t) STACK_BIAS);
|
||||
store_to_memory(NULL, adr_sp, last_sp, T_ADDRESS, NoAlias);
|
||||
#endif
|
||||
|
||||
// Set _thread_in_native
|
||||
// The order of stores into TLS is critical! Setting _thread_in_native MUST
|
||||
@ -210,19 +208,12 @@ void GraphKit::gen_stub(address C_function,
|
||||
//-----------------------------
|
||||
|
||||
// Clear last_Java_sp
|
||||
#ifdef IA64
|
||||
if( os::is_MP() ) insert_mem_bar(Op_MemBarRelease);
|
||||
#endif
|
||||
|
||||
store_to_memory(NULL, adr_sp, null(), T_ADDRESS, NoAlias);
|
||||
#ifdef IA64
|
||||
if (os::is_MP() && UseMembar) insert_mem_bar(new MemBarVolatileNode());
|
||||
#endif // def IA64
|
||||
// Clear last_Java_pc and (optionally)_flags
|
||||
store_to_memory(NULL, adr_last_Java_pc, null(), T_ADDRESS, NoAlias);
|
||||
#if defined(SPARC) || defined(IA64)
|
||||
#if defined(SPARC)
|
||||
store_to_memory(NULL, adr_flags, intcon(0), T_INT, NoAlias);
|
||||
#endif /* defined(SPARC) || defined(IA64) */
|
||||
#endif /* defined(SPARC) */
|
||||
#ifdef IA64
|
||||
Node* adr_last_Java_fp = basic_plus_adr(top(), thread, in_bytes(JavaThread::last_Java_fp_offset()));
|
||||
if( os::is_MP() ) insert_mem_bar(Op_MemBarRelease);
|
||||
|
@ -73,7 +73,8 @@ protected:
|
||||
const char* try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result, bool& should_delay);
|
||||
const char* should_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const;
|
||||
const char* should_not_inline(ciMethod* callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const;
|
||||
void print_inlining(ciMethod *callee_method, int caller_bci, const char *failure_msg) const;
|
||||
void print_inlining(ciMethod* callee_method, int caller_bci,
|
||||
const char* msg, bool success) const;
|
||||
|
||||
InlineTree *caller_tree() const { return _caller_tree; }
|
||||
InlineTree* callee_at(int bci, ciMethod* m) const;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -487,7 +487,8 @@ void Parse::do_multianewarray() {
|
||||
fun, NULL, TypeRawPtr::BOTTOM,
|
||||
makecon(TypeKlassPtr::make(array_klass)),
|
||||
length[0], length[1], length[2],
|
||||
length[3], length[4]);
|
||||
(ndimensions > 2) ? length[3] : NULL,
|
||||
(ndimensions > 3) ? length[4] : NULL);
|
||||
} else {
|
||||
// Create a java array for dimension sizes
|
||||
Node* dims = NULL;
|
||||
|
@ -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.
|
||||
|
@ -1620,7 +1620,7 @@ JVM_ENTRY(jobjectArray, JVM_GetMethodParameters(JNIEnv *env, jobject method))
|
||||
// For a 0 index, give a NULL symbol
|
||||
Symbol* const sym = 0 != params[i].name_cp_index ?
|
||||
mh->constants()->symbol_at(params[i].name_cp_index) : NULL;
|
||||
int flags = build_int_from_shorts(params[i].flags_lo, params[i].flags_hi);
|
||||
int flags = params[i].flags;
|
||||
oop param = Reflection::new_parameter(reflected_method, i, sym,
|
||||
flags, CHECK_NULL);
|
||||
result->obj_at_put(i, param);
|
||||
@ -2302,6 +2302,15 @@ JVM_QUICK_ENTRY(jboolean, JVM_IsConstructorIx(JNIEnv *env, jclass cls, int metho
|
||||
JVM_END
|
||||
|
||||
|
||||
JVM_QUICK_ENTRY(jboolean, JVM_IsVMGeneratedMethodIx(JNIEnv *env, jclass cls, int method_index))
|
||||
JVMWrapper("JVM_IsVMGeneratedMethodIx");
|
||||
ResourceMark rm(THREAD);
|
||||
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
|
||||
k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);
|
||||
Method* method = InstanceKlass::cast(k)->methods()->at(method_index);
|
||||
return method->is_overpass();
|
||||
JVM_END
|
||||
|
||||
JVM_ENTRY(const char*, JVM_GetMethodIxNameUTF(JNIEnv *env, jclass cls, jint method_index))
|
||||
JVMWrapper("JVM_GetMethodIxIxUTF");
|
||||
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
|
||||
@ -4519,10 +4528,6 @@ JVM_ENTRY(void, JVM_GetVersionInfo(JNIEnv* env, jvm_version_info* info, size_t i
|
||||
// consider to expose this new capability in the sun.rt.jvmCapabilities jvmstat
|
||||
// counter defined in runtimeService.cpp.
|
||||
info->is_attachable = AttachListener::is_attach_supported();
|
||||
#ifdef KERNEL
|
||||
info->is_kernel_jvm = 1; // true;
|
||||
#else // KERNEL
|
||||
info->is_kernel_jvm = 0; // false;
|
||||
#endif // KERNEL
|
||||
}
|
||||
JVM_END
|
||||
|
@ -859,6 +859,13 @@ JVM_GetMethodIxMaxStack(JNIEnv *env, jclass cb, int index);
|
||||
JNIEXPORT jboolean JNICALL
|
||||
JVM_IsConstructorIx(JNIEnv *env, jclass cb, int index);
|
||||
|
||||
/*
|
||||
* Is the given method generated by the VM.
|
||||
* The method is identified by method_index.
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL
|
||||
JVM_IsVMGeneratedMethodIx(JNIEnv *env, jclass cb, int index);
|
||||
|
||||
/*
|
||||
* Returns the name of a given method in UTF format.
|
||||
* The result remains valid until JVM_ReleaseUTF is called.
|
||||
|
@ -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;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -647,8 +647,6 @@ JvmtiEnv::GetJLocationFormat(jvmtiJlocationFormat* format_ptr) {
|
||||
return JVMTI_ERROR_NONE;
|
||||
} /* end GetJLocationFormat */
|
||||
|
||||
#ifndef JVMTI_KERNEL
|
||||
|
||||
//
|
||||
// Thread functions
|
||||
//
|
||||
@ -3436,5 +3434,3 @@ JvmtiEnv::SetSystemProperty(const char* property, const char* value_ptr) {
|
||||
}
|
||||
return err;
|
||||
} /* end SetSystemProperty */
|
||||
|
||||
#endif // !JVMTI_KERNEL
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -74,10 +74,8 @@ JvmtiEnvBase::globally_initialize() {
|
||||
|
||||
JvmtiManageCapabilities::initialize();
|
||||
|
||||
#ifndef JVMTI_KERNEL
|
||||
// register extension functions and events
|
||||
JvmtiExtensions::register_extensions();
|
||||
#endif // !JVMTI_KERNEL
|
||||
|
||||
#ifdef JVMTI_TRACE
|
||||
JvmtiTrace::initialize();
|
||||
@ -236,14 +234,12 @@ JvmtiEnvBase::env_dispose() {
|
||||
// Same situation as with events (see above)
|
||||
set_native_method_prefixes(0, NULL);
|
||||
|
||||
#ifndef JVMTI_KERNEL
|
||||
JvmtiTagMap* tag_map_to_deallocate = _tag_map;
|
||||
set_tag_map(NULL);
|
||||
// A tag map can be big, deallocate it now
|
||||
if (tag_map_to_deallocate != NULL) {
|
||||
delete tag_map_to_deallocate;
|
||||
}
|
||||
#endif // !JVMTI_KERNEL
|
||||
|
||||
_needs_clean_up = true;
|
||||
}
|
||||
@ -255,14 +251,12 @@ JvmtiEnvBase::~JvmtiEnvBase() {
|
||||
// There is a small window of time during which the tag map of a
|
||||
// disposed environment could have been reallocated.
|
||||
// Make sure it is gone.
|
||||
#ifndef JVMTI_KERNEL
|
||||
JvmtiTagMap* tag_map_to_deallocate = _tag_map;
|
||||
set_tag_map(NULL);
|
||||
// A tag map can be big, deallocate it now
|
||||
if (tag_map_to_deallocate != NULL) {
|
||||
delete tag_map_to_deallocate;
|
||||
}
|
||||
#endif // !JVMTI_KERNEL
|
||||
|
||||
_magic = BAD_MAGIC;
|
||||
}
|
||||
@ -593,8 +587,6 @@ JvmtiEnvBase::get_jni_class_non_null(Klass* k) {
|
||||
return (jclass)jni_reference(k->java_mirror());
|
||||
}
|
||||
|
||||
#ifndef JVMTI_KERNEL
|
||||
|
||||
//
|
||||
// Field Information
|
||||
//
|
||||
@ -1482,5 +1474,3 @@ JvmtiMonitorClosure::do_monitor(ObjectMonitor* mon) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !JVMTI_KERNEL
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -677,7 +677,6 @@ void JvmtiExport::report_unsupported(bool on) {
|
||||
}
|
||||
|
||||
|
||||
#ifndef JVMTI_KERNEL
|
||||
static inline Klass* oop_to_klass(oop obj) {
|
||||
Klass* k = obj->klass();
|
||||
|
||||
@ -2178,7 +2177,6 @@ extern "C" {
|
||||
typedef jint (JNICALL *OnAttachEntry_t)(JavaVM*, char *, void *);
|
||||
}
|
||||
|
||||
#ifndef SERVICES_KERNEL
|
||||
jint JvmtiExport::load_agent_library(AttachOperation* op, outputStream* st) {
|
||||
char ebuf[1024];
|
||||
char buffer[JVM_MAXPATHLEN];
|
||||
@ -2259,7 +2257,6 @@ jint JvmtiExport::load_agent_library(AttachOperation* op, outputStream* st) {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif // SERVICES_KERNEL
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -2457,4 +2454,3 @@ JvmtiGCMarker::~JvmtiGCMarker() {
|
||||
JvmtiExport::post_garbage_collection_finish();
|
||||
}
|
||||
}
|
||||
#endif // JVMTI_KERNEL
|
||||
|
@ -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
|
||||
//
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -905,8 +905,6 @@ void JvmtiSuspendControl::print() {
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef KERNEL
|
||||
|
||||
JvmtiDeferredEvent JvmtiDeferredEvent::compiled_method_load_event(
|
||||
nmethod* nm) {
|
||||
JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_LOAD);
|
||||
@ -1098,5 +1096,3 @@ void JvmtiDeferredEventQueue::process_pending_events() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // ndef KERNEL
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,8 +25,6 @@
|
||||
#ifndef SHARE_VM_PRIMS_JVMTIIMPL_HPP
|
||||
#define SHARE_VM_PRIMS_JVMTIIMPL_HPP
|
||||
|
||||
#ifndef JVMTI_KERNEL
|
||||
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "jvmtifiles/jvmti.h"
|
||||
#include "oops/objArrayOop.hpp"
|
||||
@ -435,7 +433,6 @@ public:
|
||||
static void print();
|
||||
};
|
||||
|
||||
#endif // !JVMTI_KERNEL
|
||||
|
||||
/**
|
||||
* When a thread (such as the compiler thread or VM thread) cannot post a
|
||||
|
@ -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
|
||||
|
@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/metadataOnStackMark.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "classfile/verifier.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
@ -115,43 +116,6 @@ bool VM_RedefineClasses::doit_prologue() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Keep track of marked on-stack metadata so it can be cleared.
|
||||
GrowableArray<Metadata*>* _marked_objects = NULL;
|
||||
NOT_PRODUCT(bool MetadataOnStackMark::_is_active = false;)
|
||||
|
||||
// Walk metadata on the stack and mark it so that redefinition doesn't delete
|
||||
// it. Class unloading also walks the previous versions and might try to
|
||||
// delete it, so this class is used by class unloading also.
|
||||
MetadataOnStackMark::MetadataOnStackMark() {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
|
||||
NOT_PRODUCT(_is_active = true;)
|
||||
if (_marked_objects == NULL) {
|
||||
_marked_objects = new (ResourceObj::C_HEAP, mtClass) GrowableArray<Metadata*>(1000, true);
|
||||
}
|
||||
Threads::metadata_do(Metadata::mark_on_stack);
|
||||
CodeCache::alive_nmethods_do(nmethod::mark_on_stack);
|
||||
CompileBroker::mark_on_stack();
|
||||
}
|
||||
|
||||
MetadataOnStackMark::~MetadataOnStackMark() {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
|
||||
// Unmark everything that was marked. Can't do the same walk because
|
||||
// redefine classes messes up the code cache so the set of methods
|
||||
// might not be the same.
|
||||
for (int i = 0; i< _marked_objects->length(); i++) {
|
||||
_marked_objects->at(i)->set_on_stack(false);
|
||||
}
|
||||
_marked_objects->clear(); // reuse growable array for next time.
|
||||
NOT_PRODUCT(_is_active = false;)
|
||||
}
|
||||
|
||||
// Record which objects are marked so we can unmark the same objects.
|
||||
void MetadataOnStackMark::record(Metadata* m) {
|
||||
assert(_is_active, "metadata on stack marking is active");
|
||||
_marked_objects->push(m);
|
||||
}
|
||||
|
||||
|
||||
void VM_RedefineClasses::doit() {
|
||||
Thread *thread = Thread::current();
|
||||
|
||||
@ -314,76 +278,23 @@ void VM_RedefineClasses::append_entry(constantPoolHandle scratch_cp,
|
||||
case JVM_CONSTANT_NameAndType:
|
||||
{
|
||||
int name_ref_i = scratch_cp->name_ref_index_at(scratch_i);
|
||||
int new_name_ref_i = 0;
|
||||
bool match = (name_ref_i < *merge_cp_length_p) &&
|
||||
scratch_cp->compare_entry_to(name_ref_i, *merge_cp_p, name_ref_i,
|
||||
THREAD);
|
||||
if (!match) {
|
||||
// forward reference in *merge_cp_p or not a direct match
|
||||
|
||||
int found_i = scratch_cp->find_matching_entry(name_ref_i, *merge_cp_p,
|
||||
THREAD);
|
||||
if (found_i != 0) {
|
||||
guarantee(found_i != name_ref_i,
|
||||
"compare_entry_to() and find_matching_entry() do not agree");
|
||||
|
||||
// Found a matching entry somewhere else in *merge_cp_p so
|
||||
// just need a mapping entry.
|
||||
new_name_ref_i = found_i;
|
||||
map_index(scratch_cp, name_ref_i, found_i);
|
||||
} else {
|
||||
// no match found so we have to append this entry to *merge_cp_p
|
||||
append_entry(scratch_cp, name_ref_i, merge_cp_p, merge_cp_length_p,
|
||||
THREAD);
|
||||
// The above call to append_entry() can only append one entry
|
||||
// so the post call query of *merge_cp_length_p is only for
|
||||
// the sake of consistency.
|
||||
new_name_ref_i = *merge_cp_length_p - 1;
|
||||
}
|
||||
}
|
||||
int new_name_ref_i = find_or_append_indirect_entry(scratch_cp, name_ref_i, merge_cp_p,
|
||||
merge_cp_length_p, THREAD);
|
||||
|
||||
int signature_ref_i = scratch_cp->signature_ref_index_at(scratch_i);
|
||||
int new_signature_ref_i = 0;
|
||||
match = (signature_ref_i < *merge_cp_length_p) &&
|
||||
scratch_cp->compare_entry_to(signature_ref_i, *merge_cp_p,
|
||||
signature_ref_i, THREAD);
|
||||
if (!match) {
|
||||
// forward reference in *merge_cp_p or not a direct match
|
||||
|
||||
int found_i = scratch_cp->find_matching_entry(signature_ref_i,
|
||||
*merge_cp_p, THREAD);
|
||||
if (found_i != 0) {
|
||||
guarantee(found_i != signature_ref_i,
|
||||
"compare_entry_to() and find_matching_entry() do not agree");
|
||||
|
||||
// Found a matching entry somewhere else in *merge_cp_p so
|
||||
// just need a mapping entry.
|
||||
new_signature_ref_i = found_i;
|
||||
map_index(scratch_cp, signature_ref_i, found_i);
|
||||
} else {
|
||||
// no match found so we have to append this entry to *merge_cp_p
|
||||
append_entry(scratch_cp, signature_ref_i, merge_cp_p,
|
||||
merge_cp_length_p, THREAD);
|
||||
// The above call to append_entry() can only append one entry
|
||||
// so the post call query of *merge_cp_length_p is only for
|
||||
// the sake of consistency.
|
||||
new_signature_ref_i = *merge_cp_length_p - 1;
|
||||
}
|
||||
}
|
||||
int new_signature_ref_i = find_or_append_indirect_entry(scratch_cp, signature_ref_i,
|
||||
merge_cp_p, merge_cp_length_p,
|
||||
THREAD);
|
||||
|
||||
// If the referenced entries already exist in *merge_cp_p, then
|
||||
// both new_name_ref_i and new_signature_ref_i will both be 0.
|
||||
// In that case, all we are appending is the current entry.
|
||||
if (new_name_ref_i == 0) {
|
||||
new_name_ref_i = name_ref_i;
|
||||
} else {
|
||||
if (new_name_ref_i != name_ref_i) {
|
||||
RC_TRACE(0x00080000,
|
||||
("NameAndType entry@%d name_ref_index change: %d to %d",
|
||||
*merge_cp_length_p, name_ref_i, new_name_ref_i));
|
||||
}
|
||||
if (new_signature_ref_i == 0) {
|
||||
new_signature_ref_i = signature_ref_i;
|
||||
} else {
|
||||
if (new_signature_ref_i != signature_ref_i) {
|
||||
RC_TRACE(0x00080000,
|
||||
("NameAndType entry@%d signature_ref_index change: %d to %d",
|
||||
*merge_cp_length_p, signature_ref_i, new_signature_ref_i));
|
||||
@ -405,76 +316,12 @@ void VM_RedefineClasses::append_entry(constantPoolHandle scratch_cp,
|
||||
case JVM_CONSTANT_Methodref:
|
||||
{
|
||||
int klass_ref_i = scratch_cp->uncached_klass_ref_index_at(scratch_i);
|
||||
int new_klass_ref_i = 0;
|
||||
bool match = (klass_ref_i < *merge_cp_length_p) &&
|
||||
scratch_cp->compare_entry_to(klass_ref_i, *merge_cp_p, klass_ref_i,
|
||||
THREAD);
|
||||
if (!match) {
|
||||
// forward reference in *merge_cp_p or not a direct match
|
||||
int new_klass_ref_i = find_or_append_indirect_entry(scratch_cp, klass_ref_i,
|
||||
merge_cp_p, merge_cp_length_p, THREAD);
|
||||
|
||||
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 name_and_type_ref_i = scratch_cp->uncached_name_and_type_ref_index_at(scratch_i);
|
||||
int new_name_and_type_ref_i = find_or_append_indirect_entry(scratch_cp, name_and_type_ref_i,
|
||||
merge_cp_p, merge_cp_length_p, THREAD);
|
||||
|
||||
const char *entry_name;
|
||||
switch (scratch_cp->tag_at(scratch_i).value()) {
|
||||
@ -517,6 +364,72 @@ void VM_RedefineClasses::append_entry(constantPoolHandle scratch_cp,
|
||||
(*merge_cp_length_p)++;
|
||||
} break;
|
||||
|
||||
// this is an indirect CP entry so it needs special handling
|
||||
case JVM_CONSTANT_MethodType:
|
||||
{
|
||||
int ref_i = scratch_cp->method_type_index_at(scratch_i);
|
||||
int new_ref_i = find_or_append_indirect_entry(scratch_cp, ref_i, merge_cp_p,
|
||||
merge_cp_length_p, THREAD);
|
||||
if (new_ref_i != ref_i) {
|
||||
RC_TRACE(0x00080000,
|
||||
("MethodType entry@%d ref_index change: %d to %d",
|
||||
*merge_cp_length_p, ref_i, new_ref_i));
|
||||
}
|
||||
(*merge_cp_p)->method_type_index_at_put(*merge_cp_length_p, new_ref_i);
|
||||
if (scratch_i != *merge_cp_length_p) {
|
||||
// The new entry in *merge_cp_p is at a different index than
|
||||
// the new entry in scratch_cp so we need to map the index values.
|
||||
map_index(scratch_cp, scratch_i, *merge_cp_length_p);
|
||||
}
|
||||
(*merge_cp_length_p)++;
|
||||
} break;
|
||||
|
||||
// this is an indirect CP entry so it needs special handling
|
||||
case JVM_CONSTANT_MethodHandle:
|
||||
{
|
||||
int ref_kind = scratch_cp->method_handle_ref_kind_at(scratch_i);
|
||||
int ref_i = scratch_cp->method_handle_index_at(scratch_i);
|
||||
int new_ref_i = find_or_append_indirect_entry(scratch_cp, ref_i, merge_cp_p,
|
||||
merge_cp_length_p, THREAD);
|
||||
if (new_ref_i != ref_i) {
|
||||
RC_TRACE(0x00080000,
|
||||
("MethodHandle entry@%d ref_index change: %d to %d",
|
||||
*merge_cp_length_p, ref_i, new_ref_i));
|
||||
}
|
||||
(*merge_cp_p)->method_handle_index_at_put(*merge_cp_length_p, ref_kind, new_ref_i);
|
||||
if (scratch_i != *merge_cp_length_p) {
|
||||
// The new entry in *merge_cp_p is at a different index than
|
||||
// the new entry in scratch_cp so we need to map the index values.
|
||||
map_index(scratch_cp, scratch_i, *merge_cp_length_p);
|
||||
}
|
||||
(*merge_cp_length_p)++;
|
||||
} break;
|
||||
|
||||
// this is an indirect CP entry so it needs special handling
|
||||
case JVM_CONSTANT_InvokeDynamic:
|
||||
{
|
||||
// TBD: cross-checks and possible extra appends into CP and bsm operands
|
||||
// are needed as well. This issue is tracked by a separate bug 8007037.
|
||||
int bss_idx = scratch_cp->invoke_dynamic_bootstrap_specifier_index(scratch_i);
|
||||
|
||||
int ref_i = scratch_cp->invoke_dynamic_name_and_type_ref_index_at(scratch_i);
|
||||
int new_ref_i = find_or_append_indirect_entry(scratch_cp, ref_i, merge_cp_p,
|
||||
merge_cp_length_p, THREAD);
|
||||
if (new_ref_i != ref_i) {
|
||||
RC_TRACE(0x00080000,
|
||||
("InvokeDynamic entry@%d name_and_type ref_index change: %d to %d",
|
||||
*merge_cp_length_p, ref_i, new_ref_i));
|
||||
}
|
||||
|
||||
(*merge_cp_p)->invoke_dynamic_at_put(*merge_cp_length_p, bss_idx, new_ref_i);
|
||||
if (scratch_i != *merge_cp_length_p) {
|
||||
// The new entry in *merge_cp_p is at a different index than
|
||||
// the new entry in scratch_cp so we need to map the index values.
|
||||
map_index(scratch_cp, scratch_i, *merge_cp_length_p);
|
||||
}
|
||||
(*merge_cp_length_p)++;
|
||||
} break;
|
||||
|
||||
// At this stage, Class or UnresolvedClass could be here, but not
|
||||
// ClassIndex
|
||||
case JVM_CONSTANT_ClassIndex: // fall through
|
||||
@ -543,6 +456,35 @@ void VM_RedefineClasses::append_entry(constantPoolHandle scratch_cp,
|
||||
} // end append_entry()
|
||||
|
||||
|
||||
int VM_RedefineClasses::find_or_append_indirect_entry(constantPoolHandle scratch_cp,
|
||||
int ref_i, constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS) {
|
||||
|
||||
int new_ref_i = ref_i;
|
||||
bool match = (ref_i < *merge_cp_length_p) &&
|
||||
scratch_cp->compare_entry_to(ref_i, *merge_cp_p, ref_i, THREAD);
|
||||
|
||||
if (!match) {
|
||||
// forward reference in *merge_cp_p or not a direct match
|
||||
int found_i = scratch_cp->find_matching_entry(ref_i, *merge_cp_p, THREAD);
|
||||
if (found_i != 0) {
|
||||
guarantee(found_i != ref_i, "compare_entry_to() and find_matching_entry() do not agree");
|
||||
// Found a matching entry somewhere else in *merge_cp_p so just need a mapping entry.
|
||||
new_ref_i = found_i;
|
||||
map_index(scratch_cp, ref_i, found_i);
|
||||
} else {
|
||||
// no match found so we have to append this entry to *merge_cp_p
|
||||
append_entry(scratch_cp, ref_i, merge_cp_p, merge_cp_length_p, THREAD);
|
||||
// The above call to append_entry() can only append one entry
|
||||
// so the post call query of *merge_cp_length_p is only for
|
||||
// the sake of consistency.
|
||||
new_ref_i = *merge_cp_length_p - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return new_ref_i;
|
||||
} // end find_or_append_indirect_entry()
|
||||
|
||||
|
||||
void VM_RedefineClasses::swap_all_method_annotations(int i, int j, instanceKlassHandle scratch_class, TRAPS) {
|
||||
AnnotationArray* save;
|
||||
|
||||
@ -1158,6 +1100,8 @@ bool VM_RedefineClasses::merge_constant_pools(constantPoolHandle old_cp,
|
||||
}
|
||||
} // end for each old_cp entry
|
||||
|
||||
ConstantPool::copy_operands(old_cp, *merge_cp_p, CHECK_0);
|
||||
|
||||
// We don't need to sanity check that *merge_cp_length_p is within
|
||||
// *merge_cp_p bounds since we have the minimum on-entry check above.
|
||||
(*merge_cp_length_p) = old_i;
|
||||
@ -1341,8 +1285,12 @@ jvmtiError VM_RedefineClasses::merge_cp_and_rewrite(
|
||||
_index_map_count = 0;
|
||||
_index_map_p = new intArray(scratch_cp->length(), -1);
|
||||
|
||||
// reference to the cp holder is needed for copy_operands()
|
||||
merge_cp->set_pool_holder(scratch_class());
|
||||
bool result = merge_constant_pools(old_cp, scratch_cp, &merge_cp,
|
||||
&merge_cp_length, THREAD);
|
||||
merge_cp->set_pool_holder(NULL);
|
||||
|
||||
if (!result) {
|
||||
// The merge can fail due to memory allocation failure or due
|
||||
// to robustness checks.
|
||||
@ -1594,6 +1542,7 @@ void VM_RedefineClasses::rewrite_cp_refs_in_method(methodHandle method,
|
||||
case Bytecodes::_getfield : // fall through
|
||||
case Bytecodes::_getstatic : // fall through
|
||||
case Bytecodes::_instanceof : // fall through
|
||||
case Bytecodes::_invokedynamic : // fall through
|
||||
case Bytecodes::_invokeinterface: // fall through
|
||||
case Bytecodes::_invokespecial : // fall through
|
||||
case Bytecodes::_invokestatic : // fall through
|
||||
@ -2416,13 +2365,14 @@ void VM_RedefineClasses::set_new_constant_pool(
|
||||
assert(version != 0, "sanity check");
|
||||
smaller_cp->set_version(version);
|
||||
|
||||
// attach klass to new constant pool
|
||||
// reference to the cp holder is needed for copy_operands()
|
||||
smaller_cp->set_pool_holder(scratch_class());
|
||||
|
||||
scratch_cp->copy_cp_to(1, scratch_cp_length - 1, smaller_cp, 1, THREAD);
|
||||
scratch_cp = smaller_cp;
|
||||
|
||||
// attach new constant pool to klass
|
||||
scratch_cp->set_pool_holder(scratch_class());
|
||||
|
||||
// attach klass to new constant pool
|
||||
scratch_class->set_constants(scratch_cp());
|
||||
|
||||
int i; // for portability
|
||||
@ -3140,11 +3090,9 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass,
|
||||
Klass* the_class_oop = java_lang_Class::as_Klass(the_class_mirror);
|
||||
instanceKlassHandle the_class = instanceKlassHandle(THREAD, the_class_oop);
|
||||
|
||||
#ifndef JVMTI_KERNEL
|
||||
// Remove all breakpoints in methods of this class
|
||||
JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints();
|
||||
jvmti_breakpoints.clearall_in_class_at_safepoint(the_class_oop);
|
||||
#endif // !JVMTI_KERNEL
|
||||
|
||||
if (the_class_oop == Universe::reflect_invoke_cache()->klass()) {
|
||||
// We are redefining java.lang.reflect.Method. Method.invoke() is
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -421,10 +421,11 @@ class VM_RedefineClasses: public VM_Operation {
|
||||
// and in all direct and indirect subclasses.
|
||||
void increment_class_counter(InstanceKlass *ik, TRAPS);
|
||||
|
||||
// Support for constant pool merging (these routines are in alpha
|
||||
// order):
|
||||
// Support for constant pool merging (these routines are in alpha order):
|
||||
void append_entry(constantPoolHandle scratch_cp, int scratch_i,
|
||||
constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS);
|
||||
int find_or_append_indirect_entry(constantPoolHandle scratch_cp, int scratch_i,
|
||||
constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS);
|
||||
int find_new_index(int old_index);
|
||||
bool is_unresolved_class_mismatch(constantPoolHandle cp1, int index1,
|
||||
constantPoolHandle cp2, int index2);
|
||||
@ -487,17 +488,4 @@ class VM_RedefineClasses: public VM_Operation {
|
||||
// and redefine implementation
|
||||
static bool is_modifiable_class(oop klass_mirror);
|
||||
};
|
||||
|
||||
|
||||
// Helper class to mark and unmark metadata used on the stack as either handles
|
||||
// or executing methods, so that it can't be deleted during class redefinition
|
||||
// and class unloading.
|
||||
class MetadataOnStackMark : public StackObj {
|
||||
NOT_PRODUCT(static bool _is_active;)
|
||||
public:
|
||||
MetadataOnStackMark() NOT_JVMTI_RETURN;
|
||||
~MetadataOnStackMark() NOT_JVMTI_RETURN;
|
||||
static void record(Metadata* m) NOT_JVMTI_RETURN;
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_PRIMS_JVMTIREDEFINECLASSES_HPP
|
||||
|
@ -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;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user