Merge
This commit is contained in:
commit
d5cad58ba3
hotspot
agent/src/share/classes/sun/jvm/hotspot
debugger/windbg
memory
runtime
make
src
cpu/x86/vm
os_cpu
share
tools/whitebox/sun/hotspot
vm
classfile
classFileParser.cppclassLoaderData.cppclassLoaderData.hppmetadataOnStackMark.cppmetadataOnStackMark.hppstackMapFrame.hppsystemDictionary.cppsystemDictionary.hppvmSymbols.hpp
gc_implementation
interpreter
memory
oops
annotations.cppannotations.hpparrayKlass.hppconstMethod.cppconstMethod.hppconstantPool.cppconstantPool.hppinstanceKlass.cppinstanceKlass.hppklass.cppklass.hppmethod.cppmethod.hppmethodData.cppmethodData.hppoop.inline.hpp
prims
jniCheck.hppjvm.cppjvm.hjvmtiCodeBlobEvents.hppjvmtiEnv.cppjvmtiEnvBase.cppjvmtiExport.cppjvmtiExtensions.hppjvmtiImpl.cppjvmtiImpl.hppjvmtiRawMonitor.hppjvmtiRedefineClasses.cppjvmtiRedefineClasses.hppjvmtiTagMap.hppwhitebox.cpp
runtime
services
test
@ -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);
|
||||
}
|
||||
}
|
||||
|
14
hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_x86/Win32X86JavaThreadPDAccess.java
14
hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_x86/Win32X86JavaThreadPDAccess.java
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -42,7 +42,7 @@ public class Win32X86JavaThreadPDAccess implements JavaThreadPDAccess {
|
||||
private static AddressField osThreadField;
|
||||
|
||||
// Field from OSThread
|
||||
private static Field osThreadThreadHandleField;
|
||||
private static Field osThreadThreadIdField;
|
||||
|
||||
// This is currently unneeded but is being kept in case we change
|
||||
// the currentFrameGuess algorithm
|
||||
@ -63,7 +63,7 @@ public class Win32X86JavaThreadPDAccess implements JavaThreadPDAccess {
|
||||
osThreadField = type.getAddressField("_osthread");
|
||||
|
||||
type = db.lookupType("OSThread");
|
||||
osThreadThreadHandleField = type.getField("_thread_handle");
|
||||
osThreadThreadIdField = type.getField("_thread_id");
|
||||
}
|
||||
|
||||
public Address getLastJavaFP(Address addr) {
|
||||
@ -127,10 +127,10 @@ public class Win32X86JavaThreadPDAccess implements JavaThreadPDAccess {
|
||||
// Fetch the OSThread (for now and for simplicity, not making a
|
||||
// separate "OSThread" class in this package)
|
||||
Address osThreadAddr = osThreadField.getValue(addr);
|
||||
// Get the address of the HANDLE within the OSThread
|
||||
Address threadHandleAddr =
|
||||
osThreadAddr.addOffsetTo(osThreadThreadHandleField.getOffset());
|
||||
// Get the address of the thread_id within the OSThread
|
||||
Address threadIdAddr =
|
||||
osThreadAddr.addOffsetTo(osThreadThreadIdField.getOffset());
|
||||
JVMDebugger debugger = VM.getVM().getDebugger();
|
||||
return debugger.getThreadForIdentifierAddress(threadHandleAddr);
|
||||
return debugger.getThreadForIdentifierAddress(threadIdAddr);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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") \
|
||||
|
@ -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;}
|
||||
};
|
||||
|
||||
|
||||
|
@ -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"
|
||||
@ -1027,7 +1028,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 +1955,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 ); }
|
||||
|
@ -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; }
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -43,6 +43,10 @@
|
||||
#include "gc_implementation/g1/heapRegionRemSet.hpp"
|
||||
#endif // !SERIALGC
|
||||
|
||||
#ifdef INCLUDE_NMT
|
||||
#include "services/memTracker.hpp"
|
||||
#endif // INCLUDE_NMT
|
||||
|
||||
bool WhiteBox::_used = false;
|
||||
|
||||
WB_ENTRY(jlong, WB_GetObjectAddress(JNIEnv* env, jobject o, jobject obj))
|
||||
@ -110,6 +114,60 @@ WB_ENTRY(jint, WB_G1RegionSize(JNIEnv* env, jobject o))
|
||||
WB_END
|
||||
#endif // !SERIALGC
|
||||
|
||||
#ifdef INCLUDE_NMT
|
||||
// Keep track of the 3 allocations in NMTAllocTest so we can free them later
|
||||
// on and verify that they're not visible anymore
|
||||
static void* nmtMtTest1 = NULL, *nmtMtTest2 = NULL, *nmtMtTest3 = NULL;
|
||||
|
||||
// Alloc memory using the test memory type so that we can use that to see if
|
||||
// NMT picks it up correctly
|
||||
WB_ENTRY(jboolean, WB_NMTAllocTest(JNIEnv* env))
|
||||
void *mem;
|
||||
|
||||
if (!MemTracker::is_on() || MemTracker::shutdown_in_progress()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Allocate 2 * 128k + 256k + 1024k and free the 1024k one to make sure we track
|
||||
// everything correctly. Total should be 512k held alive.
|
||||
nmtMtTest1 = os::malloc(128 * 1024, mtTest);
|
||||
mem = os::malloc(1024 * 1024, mtTest);
|
||||
nmtMtTest2 = os::malloc(256 * 1024, mtTest);
|
||||
os::free(mem, mtTest);
|
||||
nmtMtTest3 = os::malloc(128 * 1024, mtTest);
|
||||
|
||||
return true;
|
||||
WB_END
|
||||
|
||||
// Free the memory allocated by NMTAllocTest
|
||||
WB_ENTRY(jboolean, WB_NMTFreeTestMemory(JNIEnv* env))
|
||||
|
||||
if (nmtMtTest1 == NULL || nmtMtTest2 == NULL || nmtMtTest3 == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
os::free(nmtMtTest1, mtTest);
|
||||
nmtMtTest1 = NULL;
|
||||
os::free(nmtMtTest2, mtTest);
|
||||
nmtMtTest2 = NULL;
|
||||
os::free(nmtMtTest3, mtTest);
|
||||
nmtMtTest3 = NULL;
|
||||
|
||||
return true;
|
||||
WB_END
|
||||
|
||||
// Block until the current generation of NMT data to be merged, used to reliably test the NMT feature
|
||||
WB_ENTRY(jboolean, WB_NMTWaitForDataMerge(JNIEnv* env))
|
||||
|
||||
if (!MemTracker::is_on() || MemTracker::shutdown_in_progress()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return MemTracker::wbtest_wait_for_data_merge();
|
||||
WB_END
|
||||
|
||||
#endif // INCLUDE_NMT
|
||||
|
||||
//Some convenience methods to deal with objects from java
|
||||
int WhiteBox::offset_for_field(const char* field_name, oop object,
|
||||
Symbol* signature_symbol) {
|
||||
@ -177,6 +235,11 @@ static JNINativeMethod methods[] = {
|
||||
{CC"g1NumFreeRegions", CC"()J", (void*)&WB_G1NumFreeRegions },
|
||||
{CC"g1RegionSize", CC"()I", (void*)&WB_G1RegionSize },
|
||||
#endif // !SERIALGC
|
||||
#ifdef INCLUDE_NMT
|
||||
{CC"NMTAllocTest", CC"()Z", (void*)&WB_NMTAllocTest },
|
||||
{CC"NMTFreeTestMemory", CC"()Z", (void*)&WB_NMTFreeTestMemory },
|
||||
{CC"NMTWaitForDataMerge",CC"()Z", (void*)&WB_NMTWaitForDataMerge},
|
||||
#endif // INCLUDE_NMT
|
||||
};
|
||||
|
||||
#undef CC
|
||||
|
@ -827,7 +827,8 @@ bool Arguments::process_argument(const char* arg,
|
||||
return true;
|
||||
}
|
||||
|
||||
const char * const argname = *arg == '+' || *arg == '-' ? arg + 1 : arg;
|
||||
bool has_plus_minus = (*arg == '+' || *arg == '-');
|
||||
const char* const argname = has_plus_minus ? arg + 1 : arg;
|
||||
if (is_newly_obsolete(arg, &since)) {
|
||||
char version[256];
|
||||
since.to_string(version, sizeof(version));
|
||||
@ -838,13 +839,29 @@ bool Arguments::process_argument(const char* arg,
|
||||
// For locked flags, report a custom error message if available.
|
||||
// Otherwise, report the standard unrecognized VM option.
|
||||
|
||||
Flag* locked_flag = Flag::find_flag((char*)argname, strlen(argname), true);
|
||||
if (locked_flag != NULL) {
|
||||
size_t arg_len;
|
||||
const char* equal_sign = strchr(argname, '=');
|
||||
if (equal_sign == NULL) {
|
||||
arg_len = strlen(argname);
|
||||
} else {
|
||||
arg_len = equal_sign - argname;
|
||||
}
|
||||
|
||||
Flag* found_flag = Flag::find_flag((char*)argname, arg_len, true);
|
||||
if (found_flag != NULL) {
|
||||
char locked_message_buf[BUFLEN];
|
||||
locked_flag->get_locked_message(locked_message_buf, BUFLEN);
|
||||
found_flag->get_locked_message(locked_message_buf, BUFLEN);
|
||||
if (strlen(locked_message_buf) == 0) {
|
||||
jio_fprintf(defaultStream::error_stream(),
|
||||
"Unrecognized VM option '%s'\n", argname);
|
||||
if (found_flag->is_bool() && !has_plus_minus) {
|
||||
jio_fprintf(defaultStream::error_stream(),
|
||||
"Missing +/- setting for VM option '%s'\n", argname);
|
||||
} else if (!found_flag->is_bool() && has_plus_minus) {
|
||||
jio_fprintf(defaultStream::error_stream(),
|
||||
"Unexpected +/- setting in VM option '%s'\n", argname);
|
||||
} else {
|
||||
jio_fprintf(defaultStream::error_stream(),
|
||||
"Improperly specified VM option '%s'\n", argname);
|
||||
}
|
||||
} else {
|
||||
jio_fprintf(defaultStream::error_stream(), "%s", locked_message_buf);
|
||||
}
|
||||
@ -1429,13 +1446,18 @@ void Arguments::set_ergonomics_flags() {
|
||||
}
|
||||
// Set the ClassMetaspaceSize to something that will not need to be
|
||||
// expanded, since it cannot be expanded.
|
||||
if (UseCompressedKlassPointers && FLAG_IS_DEFAULT(ClassMetaspaceSize)) {
|
||||
// 100,000 classes seems like a good size, so 100M assumes around 1K
|
||||
// per klass. The vtable and oopMap is embedded so we don't have a fixed
|
||||
// size per klass. Eventually, this will be parameterized because it
|
||||
// would also be useful to determine the optimal size of the
|
||||
// systemDictionary.
|
||||
FLAG_SET_ERGO(uintx, ClassMetaspaceSize, 100*M);
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (ClassMetaspaceSize > KlassEncodingMetaspaceMax) {
|
||||
warning("Class metaspace size is too large for UseCompressedKlassPointers");
|
||||
FLAG_SET_DEFAULT(UseCompressedKlassPointers, false);
|
||||
} else if (FLAG_IS_DEFAULT(ClassMetaspaceSize)) {
|
||||
// 100,000 classes seems like a good size, so 100M assumes around 1K
|
||||
// per klass. The vtable and oopMap is embedded so we don't have a fixed
|
||||
// size per klass. Eventually, this will be parameterized because it
|
||||
// would also be useful to determine the optimal size of the
|
||||
// systemDictionary.
|
||||
FLAG_SET_ERGO(uintx, ClassMetaspaceSize, 100*M);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Also checks that certain machines are slower with compressed oops
|
||||
@ -2472,10 +2494,7 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
|
||||
|
||||
// -Xshare:dump
|
||||
} else if (match_option(option, "-Xshare:dump", &tail)) {
|
||||
#if defined(KERNEL)
|
||||
vm_exit_during_initialization(
|
||||
"Dumping a shared archive is not supported on the Kernel JVM.", NULL);
|
||||
#elif !INCLUDE_CDS
|
||||
#if !INCLUDE_CDS
|
||||
vm_exit_during_initialization(
|
||||
"Dumping a shared archive is not supported in this VM.", NULL);
|
||||
#else
|
||||
@ -3463,36 +3482,6 @@ void Arguments::PropertyList_unique_add(SystemProperty** plist, const char* k, c
|
||||
PropertyList_add(plist, k, v);
|
||||
}
|
||||
|
||||
#ifdef KERNEL
|
||||
char *Arguments::get_kernel_properties() {
|
||||
// Find properties starting with kernel and append them to string
|
||||
// We need to find out how long they are first because the URL's that they
|
||||
// might point to could get long.
|
||||
int length = 0;
|
||||
SystemProperty* prop;
|
||||
for (prop = _system_properties; prop != NULL; prop = prop->next()) {
|
||||
if (strncmp(prop->key(), "kernel.", 7 ) == 0) {
|
||||
length += (strlen(prop->key()) + strlen(prop->value()) + 5); // "-D ="
|
||||
}
|
||||
}
|
||||
// Add one for null terminator.
|
||||
char *props = AllocateHeap(length + 1, mtInternal);
|
||||
if (length != 0) {
|
||||
int pos = 0;
|
||||
for (prop = _system_properties; prop != NULL; prop = prop->next()) {
|
||||
if (strncmp(prop->key(), "kernel.", 7 ) == 0) {
|
||||
jio_snprintf(&props[pos], length-pos,
|
||||
"-D%s=%s ", prop->key(), prop->value());
|
||||
pos = strlen(props);
|
||||
}
|
||||
}
|
||||
}
|
||||
// null terminate props in case of null
|
||||
props[length] = '\0';
|
||||
return props;
|
||||
}
|
||||
#endif // KERNEL
|
||||
|
||||
// Copies src into buf, replacing "%%" with "%" and "%p" with pid
|
||||
// Returns true if all of the source pointed by src has been copied over to
|
||||
// the destination buffer pointed by buf. Otherwise, returns false.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -540,11 +540,6 @@ class Arguments : AllStatic {
|
||||
|
||||
// Utility: copies src into buf, replacing "%%" with "%" and "%p" with pid.
|
||||
static bool copy_expand_pid(const char* src, size_t srclen, char* buf, size_t buflen);
|
||||
|
||||
#ifdef KERNEL
|
||||
// For java kernel vm, return property string for kernel properties.
|
||||
static char *get_kernel_properties();
|
||||
#endif // KERNEL
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_RUNTIME_ARGUMENTS_HPP
|
||||
|
@ -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
|
||||
@ -3739,28 +3739,6 @@ static OnLoadEntry_t lookup_on_load(AgentLibrary* agent, const char *on_load_sym
|
||||
name)) {
|
||||
library = os::dll_load(buffer, ebuf, sizeof ebuf);
|
||||
}
|
||||
#ifdef KERNEL
|
||||
// Download instrument dll
|
||||
if (library == NULL && strcmp(name, "instrument") == 0) {
|
||||
char *props = Arguments::get_kernel_properties();
|
||||
char *home = Arguments::get_java_home();
|
||||
const char *fmt = "%s/bin/java %s -Dkernel.background.download=false"
|
||||
" sun.jkernel.DownloadManager -download client_jvm";
|
||||
size_t length = strlen(props) + strlen(home) + strlen(fmt) + 1;
|
||||
char *cmd = NEW_C_HEAP_ARRAY(char, length, mtThread);
|
||||
jio_snprintf(cmd, length, fmt, home, props);
|
||||
int status = os::fork_and_exec(cmd);
|
||||
FreeHeap(props);
|
||||
if (status == -1) {
|
||||
warning(cmd);
|
||||
vm_exit_during_initialization("fork_and_exec failed: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
FREE_C_HEAP_ARRAY(char, cmd, mtThread);
|
||||
// when this comes back the instrument.dll should be where it belongs.
|
||||
library = os::dll_load(buffer, ebuf, sizeof ebuf);
|
||||
}
|
||||
#endif // KERNEL
|
||||
if (library == NULL) { // Try the local directory
|
||||
char ns[1] = {0};
|
||||
if (os::dll_build_name(buffer, sizeof(buffer), ns, name)) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,9 +25,7 @@
|
||||
#ifndef SHARE_VM_RUNTIME_VMSTRUCTS_HPP
|
||||
#define SHARE_VM_RUNTIME_VMSTRUCTS_HPP
|
||||
|
||||
#ifndef VM_STRUCTS_KERNEL
|
||||
#include "utilities/debug.hpp"
|
||||
#endif
|
||||
#ifdef COMPILER1
|
||||
#include "c1/c1_Runtime1.hpp"
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -111,9 +111,6 @@ void Abstract_VM_Version::initialize() {
|
||||
#endif
|
||||
|
||||
#ifndef VMTYPE
|
||||
#ifdef KERNEL
|
||||
#define VMTYPE "Kernel"
|
||||
#else // KERNEL
|
||||
#ifdef TIERED
|
||||
#define VMTYPE "Server"
|
||||
#else // TIERED
|
||||
@ -128,7 +125,6 @@ void Abstract_VM_Version::initialize() {
|
||||
COMPILER2_PRESENT("Server")
|
||||
#endif // ZERO
|
||||
#endif // TIERED
|
||||
#endif // KERNEL
|
||||
#endif
|
||||
|
||||
#ifndef HOTSPOT_VM_DISTRO
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -170,7 +170,6 @@ static jint jcmd(AttachOperation* op, outputStream* out) {
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
#ifndef SERVICES_KERNEL // Heap dumping not supported
|
||||
// Implementation of "dumpheap" command.
|
||||
// See also: HeapDumpDCmd class
|
||||
//
|
||||
@ -212,7 +211,6 @@ jint dump_heap(AttachOperation* op, outputStream* out) {
|
||||
}
|
||||
return JNI_OK;
|
||||
}
|
||||
#endif // SERVICES_KERNEL
|
||||
|
||||
// Implementation of "inspectheap" command
|
||||
// See also: ClassHistogramDCmd class
|
||||
@ -382,9 +380,7 @@ static jint print_flag(AttachOperation* op, outputStream* out) {
|
||||
static AttachOperationFunctionInfo funcs[] = {
|
||||
{ "agentProperties", get_agent_properties },
|
||||
{ "datadump", data_dump },
|
||||
#ifndef SERVICES_KERNEL
|
||||
{ "dumpheap", dump_heap },
|
||||
#endif // SERVICES_KERNEL
|
||||
{ "load", JvmtiExport::load_agent_library },
|
||||
{ "properties", get_system_properties },
|
||||
{ "threaddump", thread_dump },
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -38,8 +38,6 @@
|
||||
// complets the result value and any result data is returned to the client
|
||||
// tool.
|
||||
|
||||
#ifndef SERVICES_KERNEL
|
||||
|
||||
class AttachOperation;
|
||||
|
||||
typedef jint (*AttachOperationFunction)(AttachOperation* op, outputStream* out);
|
||||
@ -48,7 +46,6 @@ struct AttachOperationFunctionInfo {
|
||||
const char* name;
|
||||
AttachOperationFunction func;
|
||||
};
|
||||
#endif // SERVICES_KERNEL
|
||||
|
||||
class AttachListener: AllStatic {
|
||||
public:
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -43,12 +43,12 @@ void DCmdRegistrant::register_dcmds(){
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMUptimeDCmd>(true, false));
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SystemGCDCmd>(true, false));
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RunFinalizationDCmd>(true, false));
|
||||
#if INCLUDE_SERVICES // Heap dumping supported
|
||||
#if INCLUDE_SERVICES // Heap dumping/inspection supported
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapDumpDCmd>(true, false));
|
||||
#endif // INCLUDE_SERVICES
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHistogramDCmd>(true, false));
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassStatsDCmd>(true, false));
|
||||
#endif // INCLUDE_SERVICES
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(true, false));
|
||||
|
||||
//Enhanced JMX Agent Support
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStartRemoteDCmd>(true,false));
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStartLocalDCmd>(true,false));
|
||||
@ -252,7 +252,7 @@ void RunFinalizationDCmd::execute(TRAPS) {
|
||||
vmSymbols::void_method_signature(), CHECK);
|
||||
}
|
||||
|
||||
#if INCLUDE_SERVICES // Heap dumping supported
|
||||
#if INCLUDE_SERVICES // Heap dumping/inspection supported
|
||||
HeapDumpDCmd::HeapDumpDCmd(outputStream* output, bool heap) :
|
||||
DCmdWithParser(output, heap),
|
||||
_filename("filename","Name of the dump file", "STRING",true),
|
||||
@ -292,7 +292,6 @@ int HeapDumpDCmd::num_arguments() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif // INCLUDE_SERVICES
|
||||
|
||||
ClassHistogramDCmd::ClassHistogramDCmd(outputStream* output, bool heap) :
|
||||
DCmdWithParser(output, heap),
|
||||
@ -319,6 +318,65 @@ int ClassHistogramDCmd::num_arguments() {
|
||||
}
|
||||
}
|
||||
|
||||
#define DEFAULT_COLUMNS "InstBytes,KlassBytes,CpAll,annotations,MethodCount,Bytecodes,MethodAll,ROAll,RWAll,Total"
|
||||
ClassStatsDCmd::ClassStatsDCmd(outputStream* output, bool heap) :
|
||||
DCmdWithParser(output, heap),
|
||||
_csv("-csv", "Print in CSV (comma-separated values) format for spreadsheets",
|
||||
"BOOLEAN", false, "false"),
|
||||
_all("-all", "Show all columns",
|
||||
"BOOLEAN", false, "false"),
|
||||
_help("-help", "Show meaning of all the columns",
|
||||
"BOOLEAN", false, "false"),
|
||||
_columns("columns", "Comma-separated list of all the columns to show. "
|
||||
"If not specified, the following columns are shown: " DEFAULT_COLUMNS,
|
||||
"STRING", false) {
|
||||
_dcmdparser.add_dcmd_option(&_all);
|
||||
_dcmdparser.add_dcmd_option(&_csv);
|
||||
_dcmdparser.add_dcmd_option(&_help);
|
||||
_dcmdparser.add_dcmd_argument(&_columns);
|
||||
}
|
||||
|
||||
void ClassStatsDCmd::execute(TRAPS) {
|
||||
if (!UnlockDiagnosticVMOptions) {
|
||||
output()->print_cr("GC.class_stats command requires -XX:+UnlockDiagnosticVMOptions");
|
||||
return;
|
||||
}
|
||||
|
||||
VM_GC_HeapInspection heapop(output(),
|
||||
true, /* request_full_gc */
|
||||
true /* need_prologue */);
|
||||
heapop.set_csv_format(_csv.value());
|
||||
heapop.set_print_help(_help.value());
|
||||
heapop.set_print_class_stats(true);
|
||||
if (_all.value()) {
|
||||
if (_columns.has_value()) {
|
||||
output()->print_cr("Cannot specify -all and individual columns at the same time");
|
||||
return;
|
||||
} else {
|
||||
heapop.set_columns(NULL);
|
||||
}
|
||||
} else {
|
||||
if (_columns.has_value()) {
|
||||
heapop.set_columns(_columns.value());
|
||||
} else {
|
||||
heapop.set_columns(DEFAULT_COLUMNS);
|
||||
}
|
||||
}
|
||||
VMThread::execute(&heapop);
|
||||
}
|
||||
|
||||
int ClassStatsDCmd::num_arguments() {
|
||||
ResourceMark rm;
|
||||
ClassStatsDCmd* dcmd = new ClassStatsDCmd(NULL, false);
|
||||
if (dcmd != NULL) {
|
||||
DCmdMark mark(dcmd);
|
||||
return dcmd->_dcmdparser.num_arguments();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif // INCLUDE_SERVICES
|
||||
|
||||
ThreadDumpDCmd::ThreadDumpDCmd(outputStream* output, bool heap) :
|
||||
DCmdWithParser(output, heap),
|
||||
_locks("-l", "print java.util.concurrent locks", "BOOLEAN", false, "false") {
|
||||
@ -406,7 +464,32 @@ JMXStartRemoteDCmd::JMXStartRemoteDCmd(outputStream *output, bool heap_allocated
|
||||
|
||||
_jmxremote_ssl_config_file
|
||||
("jmxremote.ssl.config.file",
|
||||
"set com.sun.management.jmxremote.ssl_config_file", "STRING", false)
|
||||
"set com.sun.management.jmxremote.ssl_config_file", "STRING", false),
|
||||
|
||||
// JDP Protocol support
|
||||
_jmxremote_autodiscovery
|
||||
("jmxremote.autodiscovery",
|
||||
"set com.sun.management.jmxremote.autodiscovery", "STRING", false),
|
||||
|
||||
_jdp_port
|
||||
("jdp.port",
|
||||
"set com.sun.management.jdp.port", "INT", false),
|
||||
|
||||
_jdp_address
|
||||
("jdp.address",
|
||||
"set com.sun.management.jdp.address", "STRING", false),
|
||||
|
||||
_jdp_source_addr
|
||||
("jdp.source_addr",
|
||||
"set com.sun.management.jdp.source_addr", "STRING", false),
|
||||
|
||||
_jdp_ttl
|
||||
("jdp.ttl",
|
||||
"set com.sun.management.jdp.ttl", "INT", false),
|
||||
|
||||
_jdp_pause
|
||||
("jdp.pause",
|
||||
"set com.sun.management.jdp.pause", "INT", false)
|
||||
|
||||
{
|
||||
_dcmdparser.add_dcmd_option(&_config_file);
|
||||
@ -422,6 +505,12 @@ JMXStartRemoteDCmd::JMXStartRemoteDCmd(outputStream *output, bool heap_allocated
|
||||
_dcmdparser.add_dcmd_option(&_jmxremote_ssl_enabled_protocols);
|
||||
_dcmdparser.add_dcmd_option(&_jmxremote_ssl_need_client_auth);
|
||||
_dcmdparser.add_dcmd_option(&_jmxremote_ssl_config_file);
|
||||
_dcmdparser.add_dcmd_option(&_jmxremote_autodiscovery);
|
||||
_dcmdparser.add_dcmd_option(&_jdp_port);
|
||||
_dcmdparser.add_dcmd_option(&_jdp_address);
|
||||
_dcmdparser.add_dcmd_option(&_jdp_source_addr);
|
||||
_dcmdparser.add_dcmd_option(&_jdp_ttl);
|
||||
_dcmdparser.add_dcmd_option(&_jdp_pause);
|
||||
}
|
||||
|
||||
|
||||
@ -436,7 +525,6 @@ int JMXStartRemoteDCmd::num_arguments() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void JMXStartRemoteDCmd::execute(TRAPS) {
|
||||
ResourceMark rm(THREAD);
|
||||
HandleMark hm(THREAD);
|
||||
@ -466,7 +554,9 @@ void JMXStartRemoteDCmd::execute(TRAPS) {
|
||||
// file.
|
||||
#define PUT_OPTION(a) \
|
||||
if ( (a).is_set() ){ \
|
||||
options.print("%scom.sun.management.%s=%s", comma, (a).name(), (a).value()); \
|
||||
options.print(\
|
||||
( *((a).type()) == 'I' ) ? "%scom.sun.management.%s=%d" : "%scom.sun.management.%s=%s",\
|
||||
comma, (a).name(), (a).value()); \
|
||||
comma[0] = ','; \
|
||||
}
|
||||
|
||||
@ -483,6 +573,12 @@ void JMXStartRemoteDCmd::execute(TRAPS) {
|
||||
PUT_OPTION(_jmxremote_ssl_enabled_protocols);
|
||||
PUT_OPTION(_jmxremote_ssl_need_client_auth);
|
||||
PUT_OPTION(_jmxremote_ssl_config_file);
|
||||
PUT_OPTION(_jmxremote_autodiscovery);
|
||||
PUT_OPTION(_jdp_port);
|
||||
PUT_OPTION(_jdp_address);
|
||||
PUT_OPTION(_jdp_source_addr);
|
||||
PUT_OPTION(_jdp_ttl);
|
||||
PUT_OPTION(_jdp_pause);
|
||||
|
||||
#undef PUT_OPTION
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -178,7 +178,7 @@ public:
|
||||
};
|
||||
#endif // INCLUDE_SERVICES
|
||||
|
||||
// See also: inspeactheap in attachListener.cpp
|
||||
// See also: inspectheap in attachListener.cpp
|
||||
class ClassHistogramDCmd : public DCmdWithParser {
|
||||
protected:
|
||||
DCmdArgument<bool> _all;
|
||||
@ -197,6 +197,27 @@ public:
|
||||
virtual void execute(TRAPS);
|
||||
};
|
||||
|
||||
class ClassStatsDCmd : public DCmdWithParser {
|
||||
protected:
|
||||
DCmdArgument<bool> _all;
|
||||
DCmdArgument<bool> _csv;
|
||||
DCmdArgument<bool> _help;
|
||||
DCmdArgument<char*> _columns;
|
||||
public:
|
||||
ClassStatsDCmd(outputStream* output, bool heap);
|
||||
static const char* name() {
|
||||
return "GC.class_stats";
|
||||
}
|
||||
static const char* description() {
|
||||
return "Provide statistics about Java class meta data. Requires -XX:+UnlockDiagnosticVMOptions.";
|
||||
}
|
||||
static const char* impact() {
|
||||
return "High: Depends on Java heap size and content.";
|
||||
}
|
||||
static int num_arguments();
|
||||
virtual void execute(TRAPS);
|
||||
};
|
||||
|
||||
// See also: thread_dump in attachListener.cpp
|
||||
class ThreadDumpDCmd : public DCmdWithParser {
|
||||
protected:
|
||||
@ -236,6 +257,16 @@ class JMXStartRemoteDCmd : public DCmdWithParser {
|
||||
DCmdArgument<char *> _jmxremote_ssl_need_client_auth;
|
||||
DCmdArgument<char *> _jmxremote_ssl_config_file;
|
||||
|
||||
// JDP support
|
||||
// Keep autodiscovery char* not bool to pass true/false
|
||||
// as property value to java level.
|
||||
DCmdArgument<char *> _jmxremote_autodiscovery;
|
||||
DCmdArgument<jlong> _jdp_port;
|
||||
DCmdArgument<char *> _jdp_address;
|
||||
DCmdArgument<char *> _jdp_source_addr;
|
||||
DCmdArgument<jlong> _jdp_ttl;
|
||||
DCmdArgument<jlong> _jdp_pause;
|
||||
|
||||
public:
|
||||
JMXStartRemoteDCmd(outputStream *output, bool heap_allocated);
|
||||
|
||||
|
@ -40,6 +40,7 @@ MemType2Name MemBaseline::MemType2NameMap[NUMBER_OF_MEMORY_TYPE] = {
|
||||
{mtNMT, "Memory Tracking"},
|
||||
{mtChunk, "Pooled Free Chunks"},
|
||||
{mtClassShared,"Shared spaces for classes"},
|
||||
{mtTest, "Test"},
|
||||
{mtNone, "Unknown"} // It can happen when type tagging records are lagging
|
||||
// behind
|
||||
};
|
||||
|
@ -27,8 +27,8 @@
|
||||
#include "services/memTracker.hpp"
|
||||
|
||||
volatile jint SequenceGenerator::_seq_number = 1;
|
||||
volatile unsigned long SequenceGenerator::_generation = 1;
|
||||
NOT_PRODUCT(jint SequenceGenerator::_max_seq_number = 1;)
|
||||
DEBUG_ONLY(volatile unsigned long SequenceGenerator::_generation = 0;)
|
||||
|
||||
jint SequenceGenerator::next() {
|
||||
jint seq = Atomic::add(1, &_seq_number);
|
||||
|
@ -47,16 +47,16 @@ class SequenceGenerator : AllStatic {
|
||||
static void reset() {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "Safepoint required");
|
||||
_seq_number = 1;
|
||||
DEBUG_ONLY(_generation ++;)
|
||||
_generation ++;
|
||||
};
|
||||
|
||||
DEBUG_ONLY(static unsigned long current_generation() { return (unsigned long)_generation; })
|
||||
static unsigned long current_generation() { return _generation; }
|
||||
NOT_PRODUCT(static jint max_seq_num() { return _max_seq_number; })
|
||||
|
||||
private:
|
||||
static volatile jint _seq_number;
|
||||
NOT_PRODUCT(static jint _max_seq_number; )
|
||||
DEBUG_ONLY(static volatile unsigned long _generation; )
|
||||
static volatile jint _seq_number;
|
||||
static volatile unsigned long _generation;
|
||||
NOT_PRODUCT(static jint _max_seq_number; )
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -55,7 +55,7 @@ volatile jint MemRecorder::_instance_count = 0;
|
||||
MemRecorder::MemRecorder() {
|
||||
assert(MemTracker::is_on(), "Native memory tracking is off");
|
||||
Atomic::inc(&_instance_count);
|
||||
debug_only(set_generation();)
|
||||
set_generation();
|
||||
|
||||
if (MemTracker::track_callsite()) {
|
||||
_pointer_records = new (std::nothrow)FixedSizeMemPointerArray<SeqMemPointerRecordEx,
|
||||
@ -151,11 +151,12 @@ SequencedRecordIterator MemRecorder::pointer_itr() {
|
||||
}
|
||||
|
||||
|
||||
#ifdef ASSERT
|
||||
void MemRecorder::set_generation() {
|
||||
_generation = SequenceGenerator::current_generation();
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
|
||||
void MemRecorder::check_dup_seq(jint seq) const {
|
||||
MemPointerArrayIteratorImpl itr(_pointer_records);
|
||||
MemPointerRecord* rc = (MemPointerRecord*)itr.current();
|
||||
|
@ -213,7 +213,7 @@ class MemRecorder : public CHeapObj<mtNMT|otNMTRecorder> {
|
||||
// used for linked list
|
||||
MemRecorder* _next;
|
||||
// active recorder can only record a certain generation data
|
||||
debug_only(unsigned long _generation;)
|
||||
unsigned long _generation;
|
||||
|
||||
protected:
|
||||
_NOINLINE_ MemRecorder();
|
||||
@ -251,6 +251,8 @@ class MemRecorder : public CHeapObj<mtNMT|otNMTRecorder> {
|
||||
|
||||
SequencedRecordIterator pointer_itr();
|
||||
|
||||
// return the generation of this recorder which it belongs to
|
||||
unsigned long get_generation() const { return _generation; }
|
||||
protected:
|
||||
// number of MemRecorder instance
|
||||
static volatile jint _instance_count;
|
||||
@ -263,7 +265,7 @@ class MemRecorder : public CHeapObj<mtNMT|otNMTRecorder> {
|
||||
static int sort_record_fn(const void* e1, const void* e2);
|
||||
|
||||
debug_only(void check_dup_seq(jint seq) const;)
|
||||
debug_only(void set_generation();)
|
||||
void set_generation();
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_SERVICES_MEM_RECORDER_HPP
|
||||
|
@ -91,6 +91,8 @@ void MemTrackWorker::run() {
|
||||
MemSnapshot* snapshot = MemTracker::get_snapshot();
|
||||
assert(snapshot != NULL, "Worker should not be started");
|
||||
MemRecorder* rec;
|
||||
unsigned long processing_generation = 0;
|
||||
bool worker_idle = false;
|
||||
|
||||
while (!MemTracker::shutdown_in_progress()) {
|
||||
NOT_PRODUCT(_last_gen_in_use = generations_in_use();)
|
||||
@ -100,6 +102,12 @@ void MemTrackWorker::run() {
|
||||
rec = _gen[_head].next_recorder();
|
||||
}
|
||||
if (rec != NULL) {
|
||||
if (rec->get_generation() != processing_generation || worker_idle) {
|
||||
processing_generation = rec->get_generation();
|
||||
worker_idle = false;
|
||||
MemTracker::set_current_processing_generation(processing_generation);
|
||||
}
|
||||
|
||||
// merge the recorder into staging area
|
||||
if (!snapshot->merge(rec)) {
|
||||
MemTracker::shutdown(MemTracker::NMT_out_of_memory);
|
||||
@ -129,6 +137,9 @@ void MemTrackWorker::run() {
|
||||
MemTracker::shutdown(MemTracker::NMT_out_of_memory);
|
||||
}
|
||||
} else {
|
||||
// worker thread is idle
|
||||
worker_idle = true;
|
||||
MemTracker::report_worker_idle();
|
||||
snapshot->wait(1000);
|
||||
ThreadCritical tc;
|
||||
// check if more data arrived
|
||||
|
@ -107,6 +107,7 @@ class MemTrackWorker : public NamedThread {
|
||||
NOT_PRODUCT(int _merge_count;)
|
||||
NOT_PRODUCT(int _last_gen_in_use;)
|
||||
|
||||
// how many generations are queued
|
||||
inline int generations_in_use() const {
|
||||
return (_tail >= _head ? (_tail - _head + 1) : (MAX_GENERATIONS - (_head - _tail) + 1));
|
||||
}
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "runtime/safepoint.hpp"
|
||||
#include "runtime/threadCritical.hpp"
|
||||
#include "runtime/vm_operations.hpp"
|
||||
#include "services/memPtr.hpp"
|
||||
#include "services/memReporter.hpp"
|
||||
#include "services/memTracker.hpp"
|
||||
@ -65,6 +66,8 @@ volatile MemTracker::NMTStates MemTracker::_state = NMT_uninited;
|
||||
MemTracker::ShutdownReason MemTracker::_reason = NMT_shutdown_none;
|
||||
int MemTracker::_thread_count = 255;
|
||||
volatile jint MemTracker::_pooled_recorder_count = 0;
|
||||
volatile unsigned long MemTracker::_processing_generation = 0;
|
||||
volatile bool MemTracker::_worker_thread_idle = false;
|
||||
debug_only(intx MemTracker::_main_thread_tid = 0;)
|
||||
NOT_PRODUCT(volatile jint MemTracker::_pending_recorder_count = 0;)
|
||||
|
||||
@ -279,7 +282,7 @@ MemRecorder* MemTracker::get_new_or_pooled_instance() {
|
||||
}
|
||||
cur_head->set_next(NULL);
|
||||
Atomic::dec(&_pooled_recorder_count);
|
||||
debug_only(cur_head->set_generation();)
|
||||
cur_head->set_generation();
|
||||
return cur_head;
|
||||
}
|
||||
}
|
||||
@ -570,6 +573,51 @@ bool MemTracker::print_memory_usage(BaselineOutputer& out, size_t unit, bool sum
|
||||
return false;
|
||||
}
|
||||
|
||||
// Whitebox API for blocking until the current generation of NMT data has been merged
|
||||
bool MemTracker::wbtest_wait_for_data_merge() {
|
||||
// NMT can't be shutdown while we're holding _query_lock
|
||||
MutexLockerEx lock(_query_lock, true);
|
||||
assert(_worker_thread != NULL, "Invalid query");
|
||||
// the generation at query time, so NMT will spin till this generation is processed
|
||||
unsigned long generation_at_query_time = SequenceGenerator::current_generation();
|
||||
unsigned long current_processing_generation = _processing_generation;
|
||||
// if generation counter overflown
|
||||
bool generation_overflown = (generation_at_query_time < current_processing_generation);
|
||||
long generations_to_wrap = MAX_UNSIGNED_LONG - current_processing_generation;
|
||||
// spin
|
||||
while (!shutdown_in_progress()) {
|
||||
if (!generation_overflown) {
|
||||
if (current_processing_generation > generation_at_query_time) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
assert(generations_to_wrap >= 0, "Sanity check");
|
||||
long current_generations_to_wrap = MAX_UNSIGNED_LONG - current_processing_generation;
|
||||
assert(current_generations_to_wrap >= 0, "Sanity check");
|
||||
// to overflow an unsigned long should take long time, so to_wrap check should be sufficient
|
||||
if (current_generations_to_wrap > generations_to_wrap &&
|
||||
current_processing_generation > generation_at_query_time) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// if worker thread is idle, but generation is not advancing, that means
|
||||
// there is not safepoint to let NMT advance generation, force one.
|
||||
if (_worker_thread_idle) {
|
||||
VM_ForceSafepoint vfs;
|
||||
VMThread::execute(&vfs);
|
||||
}
|
||||
MemSnapshot* snapshot = get_snapshot();
|
||||
if (snapshot == NULL) {
|
||||
return false;
|
||||
}
|
||||
snapshot->wait(1000);
|
||||
current_processing_generation = _processing_generation;
|
||||
}
|
||||
// We end up here if NMT is shutting down before our data has been merged
|
||||
return false;
|
||||
}
|
||||
|
||||
// compare memory usage between current snapshot and baseline
|
||||
bool MemTracker::compare_memory_usage(BaselineOutputer& out, size_t unit, bool summary_only) {
|
||||
MutexLockerEx lock(_query_lock, true);
|
||||
|
@ -91,9 +91,10 @@ class MemTracker : AllStatic {
|
||||
static bool compare_memory_usage(BaselineOutputer& out, size_t unit,
|
||||
bool summary_only = true) { }
|
||||
|
||||
static bool wbtest_wait_for_data_merge() { }
|
||||
|
||||
static inline void sync() { }
|
||||
static inline void thread_exiting(JavaThread* thread) { }
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -111,6 +112,10 @@ class MemTracker : AllStatic {
|
||||
|
||||
extern bool NMT_track_callsite;
|
||||
|
||||
#ifndef MAX_UNSIGNED_LONG
|
||||
#define MAX_UNSIGNED_LONG (unsigned long)(-1)
|
||||
#endif
|
||||
|
||||
#ifdef ASSERT
|
||||
#define DEBUG_CALLER_PC (NMT_track_callsite ? os::get_caller_pc(2) : 0)
|
||||
#else
|
||||
@ -380,6 +385,11 @@ class MemTracker : AllStatic {
|
||||
static bool compare_memory_usage(BaselineOutputer& out, size_t unit,
|
||||
bool summary_only = true);
|
||||
|
||||
// the version for whitebox testing support, it ensures that all memory
|
||||
// activities before this method call, are reflected in the snapshot
|
||||
// database.
|
||||
static bool wbtest_wait_for_data_merge();
|
||||
|
||||
// sync is called within global safepoint to synchronize nmt data
|
||||
static void sync();
|
||||
|
||||
@ -432,6 +442,15 @@ class MemTracker : AllStatic {
|
||||
static void create_record_in_recorder(address addr, MEMFLAGS type,
|
||||
size_t size, address pc, JavaThread* thread);
|
||||
|
||||
static void set_current_processing_generation(unsigned long generation) {
|
||||
_worker_thread_idle = false;
|
||||
_processing_generation = generation;
|
||||
}
|
||||
|
||||
static void report_worker_idle() {
|
||||
_worker_thread_idle = true;
|
||||
}
|
||||
|
||||
private:
|
||||
// global memory snapshot
|
||||
static MemSnapshot* _snapshot;
|
||||
@ -483,6 +502,11 @@ class MemTracker : AllStatic {
|
||||
static volatile enum NMTStates _state;
|
||||
// the reason for shutting down nmt
|
||||
static enum ShutdownReason _reason;
|
||||
// the generation that NMT is processing
|
||||
static volatile unsigned long _processing_generation;
|
||||
// although NMT is still procesing current generation, but
|
||||
// there is not more recorder to process, set idle state
|
||||
static volatile bool _worker_thread_idle;
|
||||
};
|
||||
|
||||
#endif // !INCLUDE_NMT
|
||||
|
@ -28,4 +28,4 @@
|
||||
# DO NOT EDIT without first contacting hotspot-regtest@sun.com
|
||||
|
||||
# The list of keywords supported in this test suite
|
||||
keys=cte_test
|
||||
keys=cte_test jcmd nmt regression
|
||||
|
@ -24,8 +24,10 @@
|
||||
/*
|
||||
* @test FieldMonitor.java
|
||||
* @bug 7158988
|
||||
* @key regression
|
||||
* @summary verify jvm does not crash while debugging
|
||||
* @run shell TestFieldMonitor.sh
|
||||
* @run compile TestPostFieldModification.java
|
||||
* @run main/othervm FieldMonitor
|
||||
* @author axel.siebenborn@sap.com
|
||||
*/
|
||||
import java.io.BufferedReader;
|
||||
|
@ -1,75 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "${TESTSRC}" = "" ]
|
||||
then TESTSRC=.
|
||||
fi
|
||||
|
||||
if [ "${TESTJAVA}" = "" ]
|
||||
then
|
||||
PARENT=`dirname \`which java\``
|
||||
TESTJAVA=`dirname ${PARENT}`
|
||||
echo "TESTJAVA not set, selecting " ${TESTJAVA}
|
||||
echo "If this is incorrect, try setting the variable manually."
|
||||
fi
|
||||
|
||||
if [ "${TESTCLASSES}" = "" ]
|
||||
then
|
||||
echo "TESTCLASSES not set. Test cannot execute. Failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# set platform-dependent variables
|
||||
OS=`uname -s`
|
||||
case "$OS" in
|
||||
SunOS | Linux | Darwin)
|
||||
NULL=/dev/null
|
||||
PS=":"
|
||||
FS="/"
|
||||
;;
|
||||
Windows_95 | Windows_98 | Windows_ME )
|
||||
NULL=NUL
|
||||
PS=";"
|
||||
FS="\\"
|
||||
echo "Test skipped, only for WinNT"
|
||||
exit 0
|
||||
;;
|
||||
Windows_NT )
|
||||
NULL=NUL
|
||||
PS=";"
|
||||
FS="\\"
|
||||
;;
|
||||
CYGWIN_NT* )
|
||||
NULL=/dev/null
|
||||
PS=";"
|
||||
FS="/"
|
||||
;;
|
||||
CYGWIN_* )
|
||||
NULL=/dev/null
|
||||
PS=";"
|
||||
FS="/"
|
||||
echo "Test skipped, only for WinNT"
|
||||
exit 0
|
||||
;;
|
||||
* )
|
||||
echo "Unrecognized system!"
|
||||
exit 1;
|
||||
;;
|
||||
esac
|
||||
|
||||
#CLASSPATH=.${PS}${TESTCLASSES} ; export CLASSPATH
|
||||
|
||||
cp ${TESTSRC}${FS}*.java .
|
||||
|
||||
${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -fullversion
|
||||
|
||||
${TESTJAVA}${FS}bin${FS}javac -classpath .${PS}$TESTJAVA${FS}lib${FS}tools.jar *.java
|
||||
|
||||
${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -classpath .${PS}$TESTJAVA${FS}lib${FS}tools.jar FieldMonitor > test.out
|
||||
|
||||
grep "A fatal error has been detected" test.out > ${NULL}
|
||||
if [ $? = 0 ]; then
|
||||
cat test.out
|
||||
STATUS=1
|
||||
fi
|
||||
|
||||
exit $STATUS
|
99
hotspot/test/runtime/8000968/Test8000968.sh
Normal file
99
hotspot/test/runtime/8000968/Test8000968.sh
Normal file
@ -0,0 +1,99 @@
|
||||
#
|
||||
# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
|
||||
# @test Test8000968.sh
|
||||
# @bug 8000968
|
||||
# @summary NPG: UseCompressedKlassPointers asserts with ObjectAlignmentInBytes=32
|
||||
# @run shell Test8000968.sh
|
||||
#
|
||||
|
||||
if [ "${TESTJAVA}" = "" ]
|
||||
then
|
||||
PARENT=`dirname \`which java\``
|
||||
TESTJAVA=`dirname ${PARENT}`
|
||||
printf "TESTJAVA not set, selecting " ${TESTJAVA}
|
||||
printf " If this is incorrect, try setting the variable manually.\n"
|
||||
fi
|
||||
|
||||
|
||||
# set platform-dependent variables
|
||||
OS=`uname -s`
|
||||
case "$OS" in
|
||||
Windows_* )
|
||||
FS="\\"
|
||||
NULL=NUL
|
||||
;;
|
||||
* )
|
||||
FS="/"
|
||||
NULL=/dev/null
|
||||
;;
|
||||
esac
|
||||
|
||||
JAVA=${TESTJAVA}${FS}bin${FS}java
|
||||
|
||||
#
|
||||
# See if platform has 64 bit java.
|
||||
#
|
||||
${JAVA} ${TESTVMOPTS} -d64 -version 2>&1 | grep -i "does not support" > ${NULL}
|
||||
if [ "$?" != "1" ]
|
||||
then
|
||||
printf "Platform is 32 bit, does not support -XX:ObjectAlignmentInBytes= option.\n"
|
||||
printf "Passed.\n"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
#
|
||||
# Test -XX:ObjectAlignmentInBytes with -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops.
|
||||
#
|
||||
${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=16 -version 2>&1 > ${NULL}
|
||||
if [ "$?" != "0" ]
|
||||
then
|
||||
printf "FAILED: -XX:ObjectAlignmentInBytes=16 option did not work.\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=32 -version 2>&1 > ${NULL}
|
||||
if [ "$?" != "0" ]
|
||||
then
|
||||
printf "FAILED: -XX:ObjectAlignmentInBytes=32 option did not work.\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=64 -version 2>&1 > ${NULL}
|
||||
if [ "$?" != "0" ]
|
||||
then
|
||||
printf "FAILED: -XX:ObjectAlignmentInBytes=64 option did not work.\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=128 -version 2>&1 > ${NULL}
|
||||
if [ "$?" != "0" ]
|
||||
then
|
||||
printf "FAILED: -XX:ObjectAlignmentInBytes=128 option did not work.\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
printf "Passed.\n"
|
||||
exit 0
|
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