Merge
This commit is contained in:
commit
8d3083be98
@ -162,3 +162,4 @@ b2972095a4b1e2a97409b7c3df61f3b263a5ce14 jdk8-b37
|
||||
d939bd0ab13c16647ffa38cc4b64fb31b7d44e10 jdk8-b38
|
||||
8927dd68aee3fa54a1a698e2980e1b2f6c7c12c1 jdk8-b39
|
||||
a2b2d435f1d275fa8010774c653197c64e326d3a jdk8-b40
|
||||
1a8c7c530f8a9b7f5bdb9b0693b2f5435ca5205e jdk8-b41
|
||||
|
@ -250,3 +250,5 @@ bfcf92bfefb82da00f7fdbf0d9273feaa0a9456d jdk8-b37
|
||||
14b0e07ab9a6fa1662414496b7e07ac8450cf517 hs24-b11
|
||||
ff9decc8235d5af80ea45fda4ecbe643ea252564 jdk8-b40
|
||||
785573170238f0eae6dc8e22ecf1050fbc9ea055 hs24-b12
|
||||
37add4fa0296705f67481e1fd50e2900cd25e39b jdk8-b41
|
||||
bd568544be7fcd12a9327e6c448592198d57b043 hs24-b13
|
||||
|
@ -81,6 +81,7 @@ public class AccessFlags implements /* imports */ ClassConstants {
|
||||
// field flags
|
||||
public boolean fieldAccessWatched () { return (flags & JVM_ACC_FIELD_ACCESS_WATCHED) != 0; }
|
||||
public boolean fieldModificationWatched() { return (flags & JVM_ACC_FIELD_MODIFICATION_WATCHED) != 0; }
|
||||
public boolean fieldHasGenericSignature() { return (flags & JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE)!= 0; }
|
||||
|
||||
public void printOn(PrintStream tty) {
|
||||
// prints only .class flags and not the hotspot internal flags
|
||||
|
@ -50,7 +50,6 @@ public class InstanceKlass extends Klass {
|
||||
private static int INITVAL_INDEX_OFFSET;
|
||||
private static int LOW_OFFSET;
|
||||
private static int HIGH_OFFSET;
|
||||
private static int GENERIC_SIGNATURE_INDEX_OFFSET;
|
||||
private static int FIELD_SLOTS;
|
||||
|
||||
// ClassState constants
|
||||
@ -99,7 +98,6 @@ public class InstanceKlass extends Klass {
|
||||
INITVAL_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::initval_index_offset").intValue();
|
||||
LOW_OFFSET = db.lookupIntConstant("FieldInfo::low_offset").intValue();
|
||||
HIGH_OFFSET = db.lookupIntConstant("FieldInfo::high_offset").intValue();
|
||||
GENERIC_SIGNATURE_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::generic_signature_offset").intValue();
|
||||
FIELD_SLOTS = db.lookupIntConstant("FieldInfo::field_slots").intValue();
|
||||
// read ClassState constants
|
||||
CLASS_STATE_UNPARSABLE_BY_GC = db.lookupIntConstant("instanceKlass::unparsable_by_gc").intValue();
|
||||
@ -279,7 +277,25 @@ public class InstanceKlass extends Klass {
|
||||
}
|
||||
|
||||
public short getFieldGenericSignatureIndex(int index) {
|
||||
return getFields().getShortAt(index * FIELD_SLOTS + GENERIC_SIGNATURE_INDEX_OFFSET);
|
||||
int len = (int)getFields().getLength();
|
||||
int allFieldsCount = getAllFieldsCount();
|
||||
int generic_signature_slot = allFieldsCount * FIELD_SLOTS;
|
||||
for (int i = 0; i < allFieldsCount; i++) {
|
||||
short flags = getFieldAccessFlags(i);
|
||||
AccessFlags access = new AccessFlags(flags);
|
||||
if (i == index) {
|
||||
if (access.fieldHasGenericSignature()) {
|
||||
return getFields().getShortAt(generic_signature_slot);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (access.fieldHasGenericSignature()) {
|
||||
generic_signature_slot ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Symbol getFieldGenericSignature(int index) {
|
||||
@ -309,7 +325,18 @@ public class InstanceKlass extends Klass {
|
||||
public ObjArray getTransitiveInterfaces() { return (ObjArray) transitiveInterfaces.getValue(this); }
|
||||
public TypeArray getFields() { return (TypeArray) fields.getValue(this); }
|
||||
public int getJavaFieldsCount() { return (int) javaFieldsCount.getValue(this); }
|
||||
public int getAllFieldsCount() { return (int)getFields().getLength() / FIELD_SLOTS; }
|
||||
public int getAllFieldsCount() {
|
||||
int len = (int)getFields().getLength();
|
||||
int allFieldsCount = 0;
|
||||
for (; allFieldsCount*FIELD_SLOTS < len; allFieldsCount++) {
|
||||
short flags = getFieldAccessFlags(allFieldsCount);
|
||||
AccessFlags access = new AccessFlags(flags);
|
||||
if (access.fieldHasGenericSignature()) {
|
||||
len --;
|
||||
}
|
||||
}
|
||||
return allFieldsCount;
|
||||
}
|
||||
public ConstantPool getConstants() { return (ConstantPool) constants.getValue(this); }
|
||||
public Oop getClassLoader() { return classLoader.getValue(this); }
|
||||
public Oop getProtectionDomain() { return protectionDomain.getValue(this); }
|
||||
|
@ -153,6 +153,8 @@ public interface ClassConstants
|
||||
public static final long JVM_ACC_FIELD_ACCESS_WATCHED = 0x00002000;
|
||||
// field modification is watched by JVMTI
|
||||
public static final long JVM_ACC_FIELD_MODIFICATION_WATCHED = 0x00008000;
|
||||
// field has generic signature
|
||||
public static final long JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE = 0x00000800;
|
||||
|
||||
// flags accepted by set_field_flags
|
||||
public static final long JVM_ACC_FIELD_FLAGS = 0x00008000 | JVM_ACC_WRITTEN_FLAGS;
|
||||
|
@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2012
|
||||
|
||||
HS_MAJOR_VER=24
|
||||
HS_MINOR_VER=0
|
||||
HS_BUILD_NUMBER=12
|
||||
HS_BUILD_NUMBER=13
|
||||
|
||||
JDK_MAJOR_VER=1
|
||||
JDK_MINOR_VER=8
|
||||
|
@ -133,7 +133,8 @@ jprt.build.targets.standard= \
|
||||
${jprt.my.linux.x64}-{product|fastdebug}, \
|
||||
${jprt.my.macosx.x64}-{product|fastdebug|debug}, \
|
||||
${jprt.my.windows.i586}-{product|fastdebug|debug}, \
|
||||
${jprt.my.windows.x64}-{product|fastdebug|debug}
|
||||
${jprt.my.windows.x64}-{product|fastdebug|debug}, \
|
||||
${jprt.my.linux.armvfp}-{product|fastdebug}
|
||||
|
||||
jprt.build.targets.open= \
|
||||
${jprt.my.solaris.i586}-{productOpen}, \
|
||||
|
@ -123,25 +123,10 @@ ifeq ($(JDK6_OR_EARLIER),0)
|
||||
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
|
||||
# Default OBJCOPY comes from the SUNWbinutils package:
|
||||
DEF_OBJCOPY=/usr/sfw/bin/gobjcopy
|
||||
ifeq ($(VM_PLATFORM),solaris_amd64)
|
||||
# On Solaris AMD64/X64, gobjcopy is not happy and fails:
|
||||
#
|
||||
# usr/sfw/bin/gobjcopy --add-gnu-debuglink=<lib>.debuginfo <lib>.so
|
||||
# BFD: stKPaiop: Not enough room for program headers, try linking with -N
|
||||
# /usr/sfw/bin/gobjcopy: stKPaiop: Bad value
|
||||
# BFD: stKPaiop: Not enough room for program headers, try linking with -N
|
||||
# /usr/sfw/bin/gobjcopy: libsaproc.debuginfo: Bad value
|
||||
# BFD: stKPaiop: Not enough room for program headers, try linking with -N
|
||||
# /usr/sfw/bin/gobjcopy: stKPaiop: Bad value
|
||||
_JUNK_ := $(shell \
|
||||
echo >&2 "INFO: $(DEF_OBJCOPY) is not working on Solaris AMD64/X64")
|
||||
OBJCOPY=
|
||||
else
|
||||
OBJCOPY=$(shell test -x $(DEF_OBJCOPY) && echo $(DEF_OBJCOPY))
|
||||
ifneq ($(ALT_OBJCOPY),)
|
||||
_JUNK_ := $(shell echo >&2 "INFO: ALT_OBJCOPY=$(ALT_OBJCOPY)")
|
||||
OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY))
|
||||
endif
|
||||
OBJCOPY=$(shell test -x $(DEF_OBJCOPY) && echo $(DEF_OBJCOPY))
|
||||
ifneq ($(ALT_OBJCOPY),)
|
||||
_JUNK_ := $(shell echo >&2 "INFO: ALT_OBJCOPY=$(ALT_OBJCOPY)")
|
||||
OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY))
|
||||
endif
|
||||
else
|
||||
OBJCOPY=
|
||||
|
@ -108,15 +108,24 @@ XLIBJVM_DTRACE_DIZ = 64/$(LIBJVM_DTRACE_DIZ)
|
||||
XLIBJVM_DTRACE_G_DEBUGINFO = 64/$(LIBJVM_DTRACE_G_DEBUGINFO)
|
||||
XLIBJVM_DTRACE_G_DIZ = 64/$(LIBJVM_DTRACE_G_DIZ)
|
||||
|
||||
$(XLIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE)
|
||||
$(XLIBJVM_DB): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE)
|
||||
@echo Making $@
|
||||
$(QUIETLY) mkdir -p 64/ ; \
|
||||
$(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. -I$(GENERATED) \
|
||||
$(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc
|
||||
[ -f $(XLIBJVM_DB_G) ] || { ln -s $(LIBJVM_DB) $(XLIBJVM_DB_G); }
|
||||
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
|
||||
# gobjcopy crashes on "empty" section headers with the SHF_ALLOC flag set.
|
||||
# Clear the SHF_ALLOC flag (if set) from empty section headers.
|
||||
# An empty section header has sh_addr == 0 and sh_size == 0.
|
||||
# This problem has only been seen on Solaris X64, but we call this tool
|
||||
# on all Solaris builds just in case.
|
||||
$(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@
|
||||
$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(XLIBJVM_DB_DEBUGINFO)
|
||||
$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(XLIBJVM_DB_DEBUGINFO) $@
|
||||
# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
|
||||
# Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available.
|
||||
# $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(XLIBJVM_DB_DEBUGINFO) $@
|
||||
$(QUIETLY) $(ADD_GNU_DEBUGLINK) $(XLIBJVM_DB_DEBUGINFO) $@
|
||||
ifeq ($(STRIP_POLICY),all_strip)
|
||||
$(QUIETLY) $(STRIP) $@
|
||||
else
|
||||
@ -133,15 +142,19 @@ ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
|
||||
endif
|
||||
endif
|
||||
|
||||
$(XLIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
|
||||
$(XLIBJVM_DTRACE): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
|
||||
@echo Making $@
|
||||
$(QUIETLY) mkdir -p 64/ ; \
|
||||
$(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. \
|
||||
$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
|
||||
[ -f $(XLIBJVM_DTRACE_G) ] || { ln -s $(LIBJVM_DTRACE) $(XLIBJVM_DTRACE_G); }
|
||||
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
|
||||
# Clear the SHF_ALLOC flag (if set) from empty section headers.
|
||||
$(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@
|
||||
$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(XLIBJVM_DTRACE_DEBUGINFO)
|
||||
$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(XLIBJVM_DTRACE_DEBUGINFO) $@
|
||||
# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
|
||||
# $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(XLIBJVM_DTRACE_DEBUGINFO) $@
|
||||
$(QUIETLY) $(ADD_GNU_DEBUGLINK) $(XLIBJVM_DTRACE_DEBUGINFO) $@
|
||||
ifeq ($(STRIP_POLICY),all_strip)
|
||||
$(QUIETLY) $(STRIP) $@
|
||||
else
|
||||
@ -198,14 +211,18 @@ $(JVMOFFS).cpp: $(GENOFFS) $(JVMOFFS).h $(JVMOFFS)Index.h
|
||||
$(JVMOFFS.o): $(JVMOFFS).h $(JVMOFFS).cpp
|
||||
$(QUIETLY) $(CXX) -c -I. -o $@ $(ARCHFLAG) -D$(TYPE) $(JVMOFFS).cpp
|
||||
|
||||
$(LIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS.o) $(XLIBJVM_DB) $(LIBJVM_DB_MAPFILE)
|
||||
$(LIBJVM_DB): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS.o) $(XLIBJVM_DB) $(LIBJVM_DB_MAPFILE)
|
||||
@echo Making $@
|
||||
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. -I$(GENERATED) \
|
||||
$(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc
|
||||
[ -f $(LIBJVM_DB_G) ] || { ln -s $@ $(LIBJVM_DB_G); }
|
||||
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
|
||||
# Clear the SHF_ALLOC flag (if set) from empty section headers.
|
||||
$(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@
|
||||
$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DB_DEBUGINFO)
|
||||
$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DB_DEBUGINFO) $@
|
||||
# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
|
||||
# $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DB_DEBUGINFO) $@
|
||||
$(QUIETLY) $(ADD_GNU_DEBUGLINK) $(LIBJVM_DB_DEBUGINFO) $@
|
||||
ifeq ($(STRIP_POLICY),all_strip)
|
||||
$(QUIETLY) $(STRIP) $@
|
||||
else
|
||||
@ -222,14 +239,18 @@ ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
|
||||
endif
|
||||
endif
|
||||
|
||||
$(LIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(XLIBJVM_DTRACE) $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
|
||||
$(LIBJVM_DTRACE): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(XLIBJVM_DTRACE) $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
|
||||
@echo Making $@
|
||||
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. \
|
||||
$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
|
||||
[ -f $(LIBJVM_DTRACE_G) ] || { ln -s $@ $(LIBJVM_DTRACE_G); }
|
||||
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
|
||||
# Clear the SHF_ALLOC flag (if set) from empty section headers.
|
||||
$(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@
|
||||
$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DTRACE_DEBUGINFO)
|
||||
$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DTRACE_DEBUGINFO) $@
|
||||
# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
|
||||
# $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DTRACE_DEBUGINFO) $@
|
||||
$(QUIETLY) $(ADD_GNU_DEBUGLINK) $(LIBJVM_DTRACE_DEBUGINFO) $@
|
||||
ifeq ($(STRIP_POLICY),all_strip)
|
||||
$(QUIETLY) $(STRIP) $@
|
||||
else
|
||||
|
51
hotspot/make/solaris/makefiles/fix_empty_sec_hdr_flags.make
Normal file
51
hotspot/make/solaris/makefiles/fix_empty_sec_hdr_flags.make
Normal file
@ -0,0 +1,51 @@
|
||||
#
|
||||
# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
|
||||
# Rules to build fix_empty_sec_hdr_flags, used by vm.make on Solaris
|
||||
|
||||
GENERATED = ../generated
|
||||
FIX_EMPTY_SEC_HDR_FLAGS = $(GENERATED)/fix_empty_sec_hdr_flags
|
||||
|
||||
FIX_EMPTY_SEC_HDR_FLAGS_DIR = $(GAMMADIR)/src/os/solaris/fix_empty_sec_hdr_flags
|
||||
FIX_EMPTY_SEC_HDR_FLAGS_SRC = $(FIX_EMPTY_SEC_HDR_FLAGS_DIR)/fix_empty_sec_hdr_flags.c
|
||||
FIX_EMPTY_SEC_HDR_FLAGS_FLAGS =
|
||||
LIBS_FIX_EMPTY_SEC_HDR_FLAGS += -lelf
|
||||
|
||||
ifeq ("${Platform_compiler}", "sparcWorks")
|
||||
# Enable the following FIX_EMPTY_SEC_HDR_FLAGS_FLAGS addition if you need to
|
||||
# compare the built ELF objects.
|
||||
#
|
||||
# The -g option makes static data global and the "-W0,-noglobal"
|
||||
# option tells the compiler to not globalize static data using a unique
|
||||
# globalization prefix. Instead force the use of a static globalization
|
||||
# prefix based on the source filepath so the objects from two identical
|
||||
# compilations are the same.
|
||||
#
|
||||
# Note: The blog says to use "-W0,-xglobalstatic", but that doesn't
|
||||
# seem to work. I got "-W0,-noglobal" from Kelly and that works.
|
||||
#FIX_EMPTY_SEC_HDR_FLAGS_FLAGS += -W0,-noglobal
|
||||
endif # Platform_compiler == sparcWorks
|
||||
|
||||
$(FIX_EMPTY_SEC_HDR_FLAGS): $(FIX_EMPTY_SEC_HDR_FLAGS_SRC)
|
||||
$(CC) -g -o $@ $< $(FIX_EMPTY_SEC_HDR_FLAGS_FLAGS) $(LIBS_FIX_EMPTY_SEC_HDR_FLAGS)
|
@ -52,14 +52,23 @@ else
|
||||
LFLAGS_JSIG += -mt -xnolib
|
||||
endif
|
||||
|
||||
$(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE)
|
||||
$(LIBJSIG): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE)
|
||||
@echo Making signal interposition lib...
|
||||
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \
|
||||
$(LFLAGS_JSIG) -o $@ $< -ldl
|
||||
$(LFLAGS_JSIG) -o $@ $(JSIGSRCDIR)/jsig.c -ldl
|
||||
[ -f $(LIBJSIG_G) ] || { ln -s $@ $(LIBJSIG_G); }
|
||||
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
|
||||
# gobjcopy crashes on "empty" section headers with the SHF_ALLOC flag set.
|
||||
# Clear the SHF_ALLOC flag (if set) from empty section headers.
|
||||
# An empty section header has sh_addr == 0 and sh_size == 0.
|
||||
# This problem has only been seen on Solaris X64, but we call this tool
|
||||
# on all Solaris builds just in case.
|
||||
$(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@
|
||||
$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJSIG_DEBUGINFO)
|
||||
$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJSIG_DEBUGINFO) $@
|
||||
# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
|
||||
# Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available.
|
||||
# $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJSIG_DEBUGINFO) $@
|
||||
$(QUIETLY) $(ADD_GNU_DEBUGLINK) $(LIBJSIG_DEBUGINFO) $@
|
||||
ifeq ($(STRIP_POLICY),all_strip)
|
||||
$(QUIETLY) $(STRIP) $@
|
||||
else
|
||||
|
@ -90,7 +90,7 @@ $(shell uname -r -v \
|
||||
# when actually building on Nevada-B158 or earlier:
|
||||
#SOLARIS_11_B159_OR_LATER=-DSOLARIS_11_B159_OR_LATER
|
||||
|
||||
$(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE)
|
||||
$(LIBSAPROC): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(SASRCFILES) $(SAMAPFILE)
|
||||
$(QUIETLY) if [ "$(BOOT_JAVA_HOME)" = "" ]; then \
|
||||
echo "ALT_BOOTDIR, BOOTDIR or JAVA_HOME needs to be defined to build SA"; \
|
||||
exit 1; \
|
||||
@ -109,8 +109,17 @@ $(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE)
|
||||
-ldl -ldemangle -lthread -lc
|
||||
[ -f $(LIBSAPROC_G) ] || { ln -s $@ $(LIBSAPROC_G); }
|
||||
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
|
||||
# gobjcopy crashes on "empty" section headers with the SHF_ALLOC flag set.
|
||||
# Clear the SHF_ALLOC flag (if set) from empty section headers.
|
||||
# An empty section header has sh_addr == 0 and sh_size == 0.
|
||||
# This problem has only been seen on Solaris X64, but we call this tool
|
||||
# on all Solaris builds just in case.
|
||||
$(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@
|
||||
$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBSAPROC_DEBUGINFO)
|
||||
$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBSAPROC_DEBUGINFO) $@
|
||||
# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
|
||||
# Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available.
|
||||
# $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBSAPROC_DEBUGINFO) $@
|
||||
$(QUIETLY) $(ADD_GNU_DEBUGLINK) $(LIBSAPROC_DEBUGINFO) $@
|
||||
ifeq ($(STRIP_POLICY),all_strip)
|
||||
$(QUIETLY) $(STRIP) $@
|
||||
else
|
||||
|
@ -148,6 +148,10 @@ include $(MAKEFILES_DIR)/dtrace.make
|
||||
# add_gnu_debuglink tool
|
||||
include $(MAKEFILES_DIR)/add_gnu_debuglink.make
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# fix_empty_sec_hdr_flags tool
|
||||
include $(MAKEFILES_DIR)/fix_empty_sec_hdr_flags.make
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# JVM
|
||||
|
||||
@ -280,7 +284,7 @@ else
|
||||
LINK_VM = $(LINK_LIB.CXX)
|
||||
endif
|
||||
# making the library:
|
||||
$(LIBJVM): $(ADD_GNU_DEBUGLINK) $(LIBJVM.o) $(LIBJVM_MAPFILE)
|
||||
$(LIBJVM): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(LIBJVM.o) $(LIBJVM_MAPFILE)
|
||||
ifeq ($(filter -sbfast -xsbfast, $(CFLAGS_BROWSE)),)
|
||||
@echo Linking vm...
|
||||
$(QUIETLY) $(LINK_LIB.CXX/PRE_HOOK)
|
||||
@ -290,10 +294,15 @@ ifeq ($(filter -sbfast -xsbfast, $(CFLAGS_BROWSE)),)
|
||||
$(QUIETLY) [ -f $(LIBJVM_G) ] || ln -s $@ $(LIBJVM_G)
|
||||
$(QUIETLY) [ -f $(LIBJVM_G).1 ] || ln -s $@.1 $(LIBJVM_G).1
|
||||
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
|
||||
# gobjcopy crashes on "empty" section headers with the SHF_ALLOC flag set.
|
||||
# Clear the SHF_ALLOC flag (if set) from empty section headers.
|
||||
# An empty section header has sh_addr == 0 and sh_size == 0.
|
||||
# This problem has only been seen on Solaris X64, but we call this tool
|
||||
# on all Solaris builds just in case.
|
||||
$(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@
|
||||
$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DEBUGINFO)
|
||||
# $(OBJCOPY) --add-gnu-debuglink=... corrupts the SUNW_dof section
|
||||
# in libjvm.so. Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY)
|
||||
# is available.
|
||||
# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
|
||||
# Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available.
|
||||
# $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DEBUGINFO) $@
|
||||
$(QUIETLY) $(ADD_GNU_DEBUGLINK) $(LIBJVM_DEBUGINFO) $@
|
||||
ifeq ($(STRIP_POLICY),all_strip)
|
||||
|
@ -143,14 +143,7 @@ _JUNK_ := $(shell \
|
||||
MAKE_ARGS += ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)
|
||||
|
||||
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
|
||||
# Disable ZIP_DEBUGINFO_FILES by default because various tests are
|
||||
# failing in nightly when the debug info files are ZIP'ed.
|
||||
#ZIP_DEBUGINFO_FILES ?= 0
|
||||
# The above conditional setting logic is unreliable on Windows for
|
||||
# unknown reasons. We force ZIP_DEBUGINFO_FILES to be disabled on
|
||||
# Windows until we figure out why the various tests are failing
|
||||
# AND why the conditional setting logic is unreliable.
|
||||
ZIP_DEBUGINFO_FILES=0
|
||||
ZIP_DEBUGINFO_FILES ?= 1
|
||||
else
|
||||
ZIP_DEBUGINFO_FILES=0
|
||||
endif
|
||||
|
@ -42,26 +42,19 @@
|
||||
#ifdef _ALLBSD_SOURCE
|
||||
|
||||
#ifdef __APPLE__
|
||||
thread_t _thread_id;
|
||||
typedef thread_t thread_id_t;
|
||||
#else
|
||||
pthread_t _thread_id;
|
||||
typedef pthread_t thread_id_t;
|
||||
#endif
|
||||
|
||||
#else
|
||||
typedef pid_t thread_id_t;
|
||||
#endif
|
||||
|
||||
// _pthread_id is the pthread id, which is used by library calls
|
||||
// (e.g. pthread_kill).
|
||||
pthread_t _pthread_id;
|
||||
|
||||
#else
|
||||
// _thread_id is kernel thread id (similar to LWP id on Solaris). Each
|
||||
// thread has a unique thread_id (BsdThreads or NPTL). It can be used
|
||||
// to access /proc.
|
||||
pid_t _thread_id;
|
||||
|
||||
// _pthread_id is the pthread id, which is used by library calls
|
||||
// (e.g. pthread_kill).
|
||||
pthread_t _pthread_id;
|
||||
#endif
|
||||
|
||||
sigset_t _caller_sigmask; // Caller's signal mask
|
||||
|
||||
public:
|
||||
@ -70,28 +63,11 @@
|
||||
sigset_t caller_sigmask() const { return _caller_sigmask; }
|
||||
void set_caller_sigmask(sigset_t sigmask) { _caller_sigmask = sigmask; }
|
||||
|
||||
#ifdef _ALLBSD_SOURCE
|
||||
#ifdef __APPLE__
|
||||
static size_t thread_id_size() { return sizeof(thread_t); }
|
||||
thread_t thread_id() const {
|
||||
return _thread_id;
|
||||
}
|
||||
#else
|
||||
static size_t thread_id_size() { return sizeof(pthread_t); }
|
||||
pthread_t thread_id() const {
|
||||
return _thread_id;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
static size_t thread_id_size() { return sizeof(pid_t); }
|
||||
pid_t thread_id() const {
|
||||
return _thread_id;
|
||||
}
|
||||
#endif
|
||||
#ifndef PRODUCT
|
||||
// Used for debugging, return a unique integer for each thread.
|
||||
intptr_t thread_identifier() const { return (intptr_t)_pthread_id; }
|
||||
#endif
|
||||
|
||||
#ifdef ASSERT
|
||||
// We expect no reposition failures so kill vm if we get one.
|
||||
//
|
||||
@ -99,21 +75,7 @@
|
||||
return false;
|
||||
}
|
||||
#endif // ASSERT
|
||||
#ifdef _ALLBSD_SOURCE
|
||||
#ifdef __APPLE__
|
||||
void set_thread_id(thread_t id) {
|
||||
_thread_id = id;
|
||||
}
|
||||
#else
|
||||
void set_thread_id(pthread_t id) {
|
||||
_thread_id = id;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
void set_thread_id(pid_t id) {
|
||||
_thread_id = id;
|
||||
}
|
||||
#endif
|
||||
|
||||
pthread_t pthread_id() const {
|
||||
return _pthread_id;
|
||||
}
|
||||
|
@ -24,6 +24,8 @@
|
||||
|
||||
#ifndef OS_LINUX_VM_OSTHREAD_LINUX_HPP
|
||||
#define OS_LINUX_VM_OSTHREAD_LINUX_HPP
|
||||
public:
|
||||
typedef pid_t thread_id_t;
|
||||
|
||||
private:
|
||||
int _thread_type;
|
||||
@ -37,13 +39,6 @@
|
||||
_thread_type = type;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// _thread_id is kernel thread id (similar to LWP id on Solaris). Each
|
||||
// thread has a unique thread_id (LinuxThreads or NPTL). It can be used
|
||||
// to access /proc.
|
||||
pid_t _thread_id;
|
||||
|
||||
// _pthread_id is the pthread id, which is used by library calls
|
||||
// (e.g. pthread_kill).
|
||||
pthread_t _pthread_id;
|
||||
@ -56,11 +51,6 @@
|
||||
sigset_t caller_sigmask() const { return _caller_sigmask; }
|
||||
void set_caller_sigmask(sigset_t sigmask) { _caller_sigmask = sigmask; }
|
||||
|
||||
static size_t thread_id_size() { return sizeof(pid_t); }
|
||||
|
||||
pid_t thread_id() const {
|
||||
return _thread_id;
|
||||
}
|
||||
#ifndef PRODUCT
|
||||
// Used for debugging, return a unique integer for each thread.
|
||||
int thread_identifier() const { return _thread_id; }
|
||||
@ -72,9 +62,6 @@
|
||||
return false;
|
||||
}
|
||||
#endif // ASSERT
|
||||
void set_thread_id(pid_t id) {
|
||||
_thread_id = id;
|
||||
}
|
||||
pthread_t pthread_id() const {
|
||||
return _pthread_id;
|
||||
}
|
||||
|
@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Name: fix_empty_sec_hdr_flags.c
|
||||
*
|
||||
* Description: Remove the SHF_ALLOC flag from "empty" section headers.
|
||||
* An "empty" section header has sh_addr == 0 and sh_size == 0.
|
||||
*
|
||||
* This program is adapted from the example program shown on the
|
||||
* elf(3elf) man page and from code from the Solaris compiler
|
||||
* driver.
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <libelf.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static void failure(void);
|
||||
|
||||
void
|
||||
main(int argc, char ** argv) {
|
||||
void * ehdr; /* ELF header */
|
||||
unsigned int i; /* section counter */
|
||||
int fd; /* descriptor for file */
|
||||
Elf * elf; /* ELF descriptor */
|
||||
char * elf_ident; /* ELF identity string */
|
||||
char * elf_obj; /* elf_obj file */
|
||||
int fix_count; /* number of flags fixed */
|
||||
int is_elfclass64; /* is an ELFCLASS64 file? */
|
||||
Elf_Scn * scn; /* ELF section descriptor */
|
||||
void * shdr; /* ELF section header */
|
||||
Elf_Data * shstrtab; /* ELF section header string table */
|
||||
|
||||
if (argc != 2) {
|
||||
(void) fprintf(stderr, "Usage: %s elf_obj\n", argv[0]);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
/* open the elf_obj */
|
||||
elf_obj = argv[1];
|
||||
if ((fd = open(elf_obj, O_RDWR)) == -1) {
|
||||
(void) fprintf(stderr, "%s: cannot open file.\n", elf_obj);
|
||||
exit(3);
|
||||
}
|
||||
|
||||
(void) printf("Opening '%s' for update\n", elf_obj);
|
||||
(void) fflush(stdout);
|
||||
(void) elf_version(EV_CURRENT); /* coordinate ELF versions */
|
||||
|
||||
/* obtain the ELF descriptors from the input file */
|
||||
if ((elf = elf_begin(fd, ELF_C_RDWR, NULL)) == NULL) {
|
||||
failure();
|
||||
}
|
||||
|
||||
/* determine if ELFCLASS64 or not? */
|
||||
elf_ident = elf_getident(elf, NULL);
|
||||
is_elfclass64 = (elf_ident[EI_CLASS] == ELFCLASS64);
|
||||
|
||||
/* get the ELF header */
|
||||
if (is_elfclass64) {
|
||||
ehdr = elf64_getehdr(elf);
|
||||
} else {
|
||||
ehdr = elf32_getehdr(elf);
|
||||
}
|
||||
if (ehdr == NULL) {
|
||||
failure();
|
||||
}
|
||||
|
||||
/* get the ELF section descriptor */
|
||||
if (is_elfclass64) {
|
||||
scn = elf_getscn(elf, ((Elf64_Ehdr *) ehdr)->e_shstrndx);
|
||||
} else {
|
||||
scn = elf_getscn(elf, ((Elf32_Ehdr *) ehdr)->e_shstrndx);
|
||||
}
|
||||
if (scn == NULL) {
|
||||
failure();
|
||||
}
|
||||
|
||||
/* get the section header string table */
|
||||
shstrtab = elf_getdata(scn, NULL);
|
||||
if (shstrtab == NULL) {
|
||||
failure();
|
||||
}
|
||||
|
||||
fix_count = 0;
|
||||
|
||||
/* traverse the sections of the input file */
|
||||
for (i = 1, scn = NULL; scn = elf_nextscn(elf, scn); i++) {
|
||||
int has_flag_set; /* is SHF_ALLOC flag set? */
|
||||
int is_empty; /* is section empty? */
|
||||
char * name; /* short hand pointer */
|
||||
|
||||
/* get the section header */
|
||||
if (is_elfclass64) {
|
||||
shdr = elf64_getshdr(scn);
|
||||
} else {
|
||||
shdr = elf32_getshdr(scn);
|
||||
}
|
||||
if (shdr == NULL) {
|
||||
failure();
|
||||
}
|
||||
|
||||
if (is_elfclass64) {
|
||||
name = (char *)shstrtab->d_buf + ((Elf64_Shdr *) shdr)->sh_name;
|
||||
} else {
|
||||
name = (char *)shstrtab->d_buf + ((Elf32_Shdr *) shdr)->sh_name;
|
||||
}
|
||||
|
||||
if (is_elfclass64) {
|
||||
has_flag_set = ((Elf64_Shdr *) shdr)->sh_flags & SHF_ALLOC;
|
||||
is_empty = ((Elf64_Shdr *) shdr)->sh_addr == 0 &&
|
||||
((Elf64_Shdr *) shdr)->sh_size == 0;
|
||||
} else {
|
||||
has_flag_set = ((Elf32_Shdr *) shdr)->sh_flags & SHF_ALLOC;
|
||||
is_empty = ((Elf32_Shdr *) shdr)->sh_addr == 0 &&
|
||||
((Elf32_Shdr *) shdr)->sh_size == 0;
|
||||
}
|
||||
|
||||
if (is_empty && has_flag_set) {
|
||||
(void) printf("section[%u] '%s' is empty, "
|
||||
"but SHF_ALLOC flag is set.\n", i, name);
|
||||
(void) printf("Clearing the SHF_ALLOC flag.\n");
|
||||
|
||||
if (is_elfclass64) {
|
||||
((Elf64_Shdr *) shdr)->sh_flags &= ~SHF_ALLOC;
|
||||
} else {
|
||||
((Elf32_Shdr *) shdr)->sh_flags &= ~SHF_ALLOC;
|
||||
}
|
||||
fix_count++;
|
||||
}
|
||||
} /* end for each ELF section */
|
||||
|
||||
if (fix_count > 0) {
|
||||
(void) printf("Saving %d updates to '%s'\n", fix_count, elf_obj);
|
||||
(void) fflush(stdout);
|
||||
(void) elf_update(elf, ELF_C_NULL); /* recalc ELF memory structures */
|
||||
(void) elf_update(elf, ELF_C_WRITE); /* write out changes to ELF obj */
|
||||
} else {
|
||||
(void) printf("No SHF_ALLOC flags needed to be cleared.\n");
|
||||
}
|
||||
|
||||
(void) elf_end(elf); /* done with ELF obj */
|
||||
(void) close(fd);
|
||||
|
||||
(void) printf("Done %s '%s'\n",
|
||||
(fix_count > 0) ? "updating" : "with", elf_obj);
|
||||
(void) fflush(stdout);
|
||||
exit(0);
|
||||
} /* end main */
|
||||
|
||||
|
||||
static void
|
||||
failure() {
|
||||
(void) fprintf(stderr, "%s\n", elf_errmsg(elf_errno()));
|
||||
exit(6);
|
||||
}
|
@ -26,9 +26,10 @@
|
||||
#define OS_SOLARIS_VM_OSTHREAD_SOLARIS_HPP
|
||||
|
||||
// This is embedded via include into the class OSThread
|
||||
public:
|
||||
typedef thread_t thread_id_t;
|
||||
|
||||
private:
|
||||
thread_t _thread_id; // Solaris thread id
|
||||
uint _lwp_id; // lwp ID, only used with bound threads
|
||||
int _native_priority; // Saved native priority when starting
|
||||
// a bound thread
|
||||
@ -36,8 +37,6 @@
|
||||
bool _vm_created_thread; // true if the VM created this thread,
|
||||
// false if primary thread or attached thread
|
||||
public:
|
||||
static size_t thread_id_size() { return sizeof(thread_t); }
|
||||
thread_t thread_id() const { return _thread_id; }
|
||||
uint lwp_id() const { return _lwp_id; }
|
||||
int native_priority() const { return _native_priority; }
|
||||
|
||||
@ -63,7 +62,6 @@
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
void set_thread_id(thread_t id) { _thread_id = id; }
|
||||
void set_lwp_id(uint id) { _lwp_id = id; }
|
||||
void set_native_priority(int prio) { _native_priority = prio; }
|
||||
|
||||
|
@ -25,12 +25,13 @@
|
||||
#ifndef OS_WINDOWS_VM_OSTHREAD_WINDOWS_HPP
|
||||
#define OS_WINDOWS_VM_OSTHREAD_WINDOWS_HPP
|
||||
|
||||
typedef void* HANDLE;
|
||||
typedef void* HANDLE;
|
||||
public:
|
||||
typedef unsigned long thread_id_t;
|
||||
|
||||
private:
|
||||
// Win32-specific thread information
|
||||
HANDLE _thread_handle; // Win32 thread handle
|
||||
unsigned long _thread_id; // Win32 thread id
|
||||
HANDLE _interrupt_event; // Event signalled on thread interrupt
|
||||
ThreadState _last_state;
|
||||
|
||||
@ -42,9 +43,6 @@ typedef void* HANDLE;
|
||||
HANDLE interrupt_event() const { return _interrupt_event; }
|
||||
void set_interrupt_event(HANDLE interrupt_event) { _interrupt_event = interrupt_event; }
|
||||
|
||||
|
||||
static size_t thread_id_size() { return sizeof(unsigned long); }
|
||||
unsigned long thread_id() const { return _thread_id; }
|
||||
#ifndef PRODUCT
|
||||
// Used for debugging, return a unique integer for each thread.
|
||||
int thread_identifier() const { return _thread_id; }
|
||||
@ -56,8 +54,6 @@ typedef void* HANDLE;
|
||||
return false;
|
||||
}
|
||||
#endif // ASSERT
|
||||
void set_thread_id(unsigned long thread_id) { _thread_id = thread_id; }
|
||||
|
||||
bool is_try_mutex_enter() { return false; }
|
||||
|
||||
// This is a temporary fix for the thread states during
|
||||
|
@ -29,18 +29,12 @@
|
||||
// constants required by the Serviceability Agent. This file is
|
||||
// referenced by vmStructs.cpp.
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define OS_THREAD_ID_TYPE thread_t
|
||||
#else
|
||||
#define OS_THREAD_ID_TYPE pthread_t
|
||||
#endif
|
||||
|
||||
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
|
||||
\
|
||||
/******************************/ \
|
||||
/* Threads (NOTE: incomplete) */ \
|
||||
/******************************/ \
|
||||
nonstatic_field(OSThread, _thread_id, OS_THREAD_ID_TYPE) \
|
||||
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
|
||||
nonstatic_field(OSThread, _pthread_id, pthread_t) \
|
||||
/* This must be the last entry, and must be present */ \
|
||||
last_entry()
|
||||
@ -52,7 +46,7 @@
|
||||
/* Posix Thread IDs */ \
|
||||
/**********************/ \
|
||||
\
|
||||
declare_unsigned_integer_type(thread_t) \
|
||||
declare_unsigned_integer_type(OSThread::thread_id_t) \
|
||||
declare_unsigned_integer_type(pthread_t) \
|
||||
\
|
||||
/* This must be the last entry, and must be present */ \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -36,7 +36,7 @@
|
||||
/******************************/ \
|
||||
\
|
||||
nonstatic_field(JavaThread, _base_of_stack_pointer, intptr_t*) \
|
||||
nonstatic_field(OSThread, _thread_id, pid_t) \
|
||||
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
|
||||
nonstatic_field(OSThread, _pthread_id, pthread_t) \
|
||||
/* This must be the last entry, and must be present */ \
|
||||
last_entry()
|
||||
@ -48,7 +48,7 @@
|
||||
/* POSIX Thread IDs */ \
|
||||
/**********************/ \
|
||||
\
|
||||
declare_integer_type(pid_t) \
|
||||
declare_integer_type(OSThread::thread_id_t) \
|
||||
declare_unsigned_integer_type(pthread_t) \
|
||||
\
|
||||
/* This must be the last entry, and must be present */ \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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,7 +34,7 @@
|
||||
/******************************/ \
|
||||
/* Threads (NOTE: incomplete) */ \
|
||||
/******************************/ \
|
||||
nonstatic_field(OSThread, _thread_id, pid_t) \
|
||||
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
|
||||
nonstatic_field(OSThread, _pthread_id, pthread_t) \
|
||||
/* This must be the last entry, and must be present */ \
|
||||
last_entry()
|
||||
@ -46,7 +46,7 @@
|
||||
/* Posix Thread IDs */ \
|
||||
/**********************/ \
|
||||
\
|
||||
declare_integer_type(pid_t) \
|
||||
declare_integer_type(OSThread::thread_id_t) \
|
||||
declare_unsigned_integer_type(pthread_t) \
|
||||
\
|
||||
/* This must be the last entry, and must be present */ \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -36,7 +36,7 @@
|
||||
/******************************/ \
|
||||
\
|
||||
nonstatic_field(JavaThread, _base_of_stack_pointer, intptr_t*) \
|
||||
nonstatic_field(OSThread, _thread_id, thread_t) \
|
||||
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
|
||||
/* This must be the last entry, and must be present */ \
|
||||
last_entry()
|
||||
|
||||
@ -47,7 +47,7 @@
|
||||
/* Solaris Thread IDs */ \
|
||||
/**********************/ \
|
||||
\
|
||||
declare_unsigned_integer_type(thread_t) \
|
||||
declare_unsigned_integer_type(OSThread::thread_id_t) \
|
||||
\
|
||||
/* This must be the last entry, and must be present */ \
|
||||
last_entry()
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -35,7 +35,7 @@
|
||||
/* Threads (NOTE: incomplete) */ \
|
||||
/******************************/ \
|
||||
\
|
||||
nonstatic_field(OSThread, _thread_id, thread_t) \
|
||||
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
|
||||
\
|
||||
/* This must be the last entry, and must be present */ \
|
||||
last_entry()
|
||||
@ -46,7 +46,7 @@
|
||||
/* Solaris Thread IDs */ \
|
||||
/**********************/ \
|
||||
\
|
||||
declare_unsigned_integer_type(thread_t) \
|
||||
declare_unsigned_integer_type(OSThread::thread_id_t) \
|
||||
\
|
||||
/* This must be the last entry, and must be present */ \
|
||||
last_entry()
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -35,7 +35,7 @@
|
||||
/* Threads (NOTE: incomplete) */ \
|
||||
/******************************/ \
|
||||
\
|
||||
nonstatic_field(OSThread, _thread_id, unsigned long) \
|
||||
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
|
||||
unchecked_nonstatic_field(OSThread, _thread_handle, sizeof(HANDLE)) /* NOTE: no type */ \
|
||||
\
|
||||
/* This must be the last entry, and must be present */ \
|
||||
@ -43,6 +43,7 @@
|
||||
|
||||
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
|
||||
\
|
||||
declare_unsigned_integer_type(OSThread::thread_id_t) \
|
||||
/* This must be the last entry, and must be present */ \
|
||||
last_entry()
|
||||
|
||||
|
@ -1082,12 +1082,36 @@ typeArrayHandle ClassFileParser::parse_fields(Symbol* class_name,
|
||||
|
||||
int num_injected = 0;
|
||||
InjectedField* injected = JavaClasses::get_injected(class_name, &num_injected);
|
||||
int total_fields = length + num_injected;
|
||||
|
||||
// Tuples of shorts [access, name index, sig index, initial value index, byte offset, generic signature index]
|
||||
typeArrayOop new_fields = oopFactory::new_permanent_shortArray((length + num_injected) * FieldInfo::field_slots, CHECK_(nullHandle));
|
||||
typeArrayHandle fields(THREAD, new_fields);
|
||||
// The field array starts with tuples of shorts
|
||||
// [access, name index, sig index, initial value index, byte offset].
|
||||
// A generic signature slot only exists for field with generic
|
||||
// signature attribute. And the access flag is set with
|
||||
// JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE for that field. The generic
|
||||
// signature slots are at the end of the field array and after all
|
||||
// other fields data.
|
||||
//
|
||||
// f1: [access, name index, sig index, initial value index, low_offset, high_offset]
|
||||
// f2: [access, name index, sig index, initial value index, low_offset, high_offset]
|
||||
// ...
|
||||
// fn: [access, name index, sig index, initial value index, low_offset, high_offset]
|
||||
// [generic signature index]
|
||||
// [generic signature index]
|
||||
// ...
|
||||
//
|
||||
// Allocate a temporary resource array for field data. For each field,
|
||||
// a slot is reserved in the temporary array for the generic signature
|
||||
// index. After parsing all fields, the data are copied to a permanent
|
||||
// array and any unused slots will be discarded.
|
||||
ResourceMark rm(THREAD);
|
||||
u2* fa = NEW_RESOURCE_ARRAY_IN_THREAD(
|
||||
THREAD, u2, total_fields * (FieldInfo::field_slots + 1));
|
||||
|
||||
typeArrayHandle field_annotations;
|
||||
// The generic signature slots start after all other fields' data.
|
||||
int generic_signature_slot = total_fields * FieldInfo::field_slots;
|
||||
int num_generic_signature = 0;
|
||||
for (int n = 0; n < length; n++) {
|
||||
cfs->guarantee_more(8, CHECK_(nullHandle)); // access_flags, name_index, descriptor_index, attributes_count
|
||||
|
||||
@ -1135,14 +1159,19 @@ typeArrayHandle ClassFileParser::parse_fields(Symbol* class_name,
|
||||
if (is_synthetic) {
|
||||
access_flags.set_is_synthetic();
|
||||
}
|
||||
if (generic_signature_index != 0) {
|
||||
access_flags.set_field_has_generic_signature();
|
||||
fa[generic_signature_slot] = generic_signature_index;
|
||||
generic_signature_slot ++;
|
||||
num_generic_signature ++;
|
||||
}
|
||||
}
|
||||
|
||||
FieldInfo* field = FieldInfo::from_field_array(fields(), n);
|
||||
FieldInfo* field = FieldInfo::from_field_array(fa, n);
|
||||
field->initialize(access_flags.as_short(),
|
||||
name_index,
|
||||
signature_index,
|
||||
constantvalue_index,
|
||||
generic_signature_index,
|
||||
0);
|
||||
|
||||
BasicType type = cp->basic_type_for_signature_at(signature_index);
|
||||
@ -1155,8 +1184,8 @@ typeArrayHandle ClassFileParser::parse_fields(Symbol* class_name,
|
||||
field->set_offset(atype);
|
||||
}
|
||||
|
||||
int index = length;
|
||||
if (num_injected != 0) {
|
||||
int index = length;
|
||||
for (int n = 0; n < num_injected; n++) {
|
||||
// Check for duplicates
|
||||
if (injected[n].may_be_java) {
|
||||
@ -1164,7 +1193,7 @@ typeArrayHandle ClassFileParser::parse_fields(Symbol* class_name,
|
||||
Symbol* signature = injected[n].signature();
|
||||
bool duplicate = false;
|
||||
for (int i = 0; i < length; i++) {
|
||||
FieldInfo* f = FieldInfo::from_field_array(fields(), i);
|
||||
FieldInfo* f = FieldInfo::from_field_array(fa, i);
|
||||
if (name == cp->symbol_at(f->name_index()) &&
|
||||
signature == cp->symbol_at(f->signature_index())) {
|
||||
// Symbol is desclared in Java so skip this one
|
||||
@ -1179,12 +1208,11 @@ typeArrayHandle ClassFileParser::parse_fields(Symbol* class_name,
|
||||
}
|
||||
|
||||
// Injected field
|
||||
FieldInfo* field = FieldInfo::from_field_array(fields(), index);
|
||||
FieldInfo* field = FieldInfo::from_field_array(fa, index);
|
||||
field->initialize(JVM_ACC_FIELD_INTERNAL,
|
||||
injected[n].name_index,
|
||||
injected[n].signature_index,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
|
||||
BasicType type = FieldType::basic_type(injected[n].signature());
|
||||
@ -1197,17 +1225,27 @@ typeArrayHandle ClassFileParser::parse_fields(Symbol* class_name,
|
||||
field->set_offset(atype);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
if (index < length + num_injected) {
|
||||
// sometimes injected fields already exist in the Java source so
|
||||
// the fields array could be too long. In that case trim the
|
||||
// fields array.
|
||||
new_fields = oopFactory::new_permanent_shortArray(index * FieldInfo::field_slots, CHECK_(nullHandle));
|
||||
for (int i = 0; i < index * FieldInfo::field_slots; i++) {
|
||||
new_fields->short_at_put(i, fields->short_at(i));
|
||||
}
|
||||
fields = new_fields;
|
||||
// Now copy the fields' data from the temporary resource array.
|
||||
// Sometimes injected fields already exist in the Java source so
|
||||
// the fields array could be too long. In that case the
|
||||
// fields array is trimed. Also unused slots that were reserved
|
||||
// for generic signature indexes are discarded.
|
||||
typeArrayOop new_fields = oopFactory::new_permanent_shortArray(
|
||||
index * FieldInfo::field_slots + num_generic_signature,
|
||||
CHECK_(nullHandle));
|
||||
typeArrayHandle fields(THREAD, new_fields);
|
||||
{
|
||||
int i = 0;
|
||||
for (; i < index * FieldInfo::field_slots; i++) {
|
||||
new_fields->short_at_put(i, fa[i]);
|
||||
}
|
||||
for (int j = total_fields * FieldInfo::field_slots;
|
||||
j < generic_signature_slot; j++) {
|
||||
new_fields->short_at_put(i++, fa[j]);
|
||||
}
|
||||
assert(i == new_fields->length(), "");
|
||||
}
|
||||
|
||||
if (_need_verify && length > 1) {
|
||||
|
@ -2763,7 +2763,7 @@ class ClassStatistics: AllStatic {
|
||||
class_size += ik->local_interfaces()->size();
|
||||
class_size += ik->transitive_interfaces()->size();
|
||||
// We do not have to count implementors, since we only store one!
|
||||
class_size += ik->all_fields_count() * FieldInfo::field_slots;
|
||||
class_size += ik->fields()->length();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,8 +58,11 @@ size_t MinChunkSize = 0;
|
||||
void CompactibleFreeListSpace::set_cms_values() {
|
||||
// Set CMS global values
|
||||
assert(MinChunkSize == 0, "already set");
|
||||
#define numQuanta(x,y) ((x+y-1)/y)
|
||||
MinChunkSize = numQuanta(sizeof(FreeChunk), MinObjAlignmentInBytes) * MinObjAlignment;
|
||||
|
||||
// MinChunkSize should be a multiple of MinObjAlignment and be large enough
|
||||
// for chunks to contain a FreeChunk.
|
||||
size_t min_chunk_size_in_bytes = align_size_up(sizeof(FreeChunk), MinObjAlignmentInBytes);
|
||||
MinChunkSize = min_chunk_size_in_bytes / BytesPerWord;
|
||||
|
||||
assert(IndexSetStart == 0 && IndexSetStride == 0, "already set");
|
||||
IndexSetStart = MinChunkSize;
|
||||
@ -2534,12 +2537,8 @@ void CompactibleFreeListSpace::check_free_list_consistency() const {
|
||||
" linear allocation buffers");
|
||||
assert(BinaryTreeDictionary<FreeChunk>::min_tree_chunk_size*HeapWordSize == sizeof(TreeChunk<FreeChunk>),
|
||||
"else MIN_TREE_CHUNK_SIZE is wrong");
|
||||
assert((IndexSetStride == 2 && IndexSetStart == 4) || // 32-bit
|
||||
(IndexSetStride == 1 && IndexSetStart == 3), "just checking"); // 64-bit
|
||||
assert((IndexSetStride != 2) || (IndexSetStart % 2 == 0),
|
||||
"Some for-loops may be incorrectly initialized");
|
||||
assert((IndexSetStride != 2) || (IndexSetSize % 2 == 1),
|
||||
"For-loops that iterate over IndexSet with stride 2 may be wrong");
|
||||
assert(IndexSetStart != 0, "IndexSetStart not initialized");
|
||||
assert(IndexSetStride != 0, "IndexSetStride not initialized");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -952,9 +952,18 @@ HeapWord* G1CollectedHeap::attempt_allocation_slow(size_t word_size,
|
||||
}
|
||||
should_try_gc = false;
|
||||
} else {
|
||||
// Read the GC count while still holding the Heap_lock.
|
||||
gc_count_before = total_collections();
|
||||
should_try_gc = true;
|
||||
// The GCLocker may not be active but the GCLocker initiated
|
||||
// GC may not yet have been performed (GCLocker::needs_gc()
|
||||
// returns true). In this case we do not try this GC and
|
||||
// wait until the GCLocker initiated GC is performed, and
|
||||
// then retry the allocation.
|
||||
if (GC_locker::needs_gc()) {
|
||||
should_try_gc = false;
|
||||
} else {
|
||||
// Read the GC count while still holding the Heap_lock.
|
||||
gc_count_before = total_collections();
|
||||
should_try_gc = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -975,6 +984,9 @@ HeapWord* G1CollectedHeap::attempt_allocation_slow(size_t word_size,
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
// The GCLocker is either active or the GCLocker initiated
|
||||
// GC has not yet been performed. Stall until it is and
|
||||
// then retry the allocation.
|
||||
GC_locker::stall_until_clear();
|
||||
}
|
||||
|
||||
@ -1054,9 +1066,18 @@ HeapWord* G1CollectedHeap::attempt_allocation_humongous(size_t word_size,
|
||||
if (GC_locker::is_active_and_needs_gc()) {
|
||||
should_try_gc = false;
|
||||
} else {
|
||||
// Read the GC count while still holding the Heap_lock.
|
||||
gc_count_before = total_collections();
|
||||
should_try_gc = true;
|
||||
// The GCLocker may not be active but the GCLocker initiated
|
||||
// GC may not yet have been performed (GCLocker::needs_gc()
|
||||
// returns true). In this case we do not try this GC and
|
||||
// wait until the GCLocker initiated GC is performed, and
|
||||
// then retry the allocation.
|
||||
if (GC_locker::needs_gc()) {
|
||||
should_try_gc = false;
|
||||
} else {
|
||||
// Read the GC count while still holding the Heap_lock.
|
||||
gc_count_before = total_collections();
|
||||
should_try_gc = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1081,6 +1102,9 @@ HeapWord* G1CollectedHeap::attempt_allocation_humongous(size_t word_size,
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
// The GCLocker is either active or the GCLocker initiated
|
||||
// GC has not yet been performed. Stall until it is and
|
||||
// then retry the allocation.
|
||||
GC_locker::stall_until_clear();
|
||||
}
|
||||
|
||||
@ -3906,12 +3930,6 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
|
||||
|
||||
gc_epilogue(false);
|
||||
}
|
||||
|
||||
if (ExitAfterGCNum > 0 && total_collections() == ExitAfterGCNum) {
|
||||
gclog_or_tty->print_cr("Stopping after GC #%d", ExitAfterGCNum);
|
||||
print_tracing_info();
|
||||
vm_exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
// The closing of the inner scope, immediately above, will complete
|
||||
|
@ -133,12 +133,7 @@ G1CollectorPolicy::G1CollectorPolicy() :
|
||||
? ParallelGCThreads : 1),
|
||||
|
||||
_recent_gc_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
|
||||
_all_pause_times_ms(new NumberSeq()),
|
||||
_stop_world_start(0.0),
|
||||
_all_stop_world_times_ms(new NumberSeq()),
|
||||
_all_yield_times_ms(new NumberSeq()),
|
||||
|
||||
_summary(new Summary()),
|
||||
|
||||
_cur_clear_ct_time_ms(0.0),
|
||||
_root_region_scan_wait_time_ms(0.0),
|
||||
@ -154,12 +149,6 @@ G1CollectorPolicy::G1CollectorPolicy() :
|
||||
_num_cc_clears(0L),
|
||||
#endif
|
||||
|
||||
_aux_num(10),
|
||||
_all_aux_times_ms(new NumberSeq[_aux_num]),
|
||||
_cur_aux_start_times_ms(new double[_aux_num]),
|
||||
_cur_aux_times_ms(new double[_aux_num]),
|
||||
_cur_aux_times_set(new bool[_aux_num]),
|
||||
|
||||
_concurrent_mark_remark_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
|
||||
_concurrent_mark_cleanup_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
|
||||
|
||||
@ -185,8 +174,6 @@ G1CollectorPolicy::G1CollectorPolicy() :
|
||||
_pause_time_target_ms((double) MaxGCPauseMillis),
|
||||
|
||||
_gcs_are_young(true),
|
||||
_young_pause_num(0),
|
||||
_mixed_pause_num(0),
|
||||
|
||||
_during_marking(false),
|
||||
_in_marking_window(false),
|
||||
@ -197,8 +184,6 @@ G1CollectorPolicy::G1CollectorPolicy() :
|
||||
|
||||
_recent_avg_pause_time_ratio(0.0),
|
||||
|
||||
_all_full_gc_times_ms(new NumberSeq()),
|
||||
|
||||
_initiate_conc_mark_if_possible(false),
|
||||
_during_initial_mark_pause(false),
|
||||
_last_young_gc(false),
|
||||
@ -851,7 +836,7 @@ void G1CollectorPolicy::record_full_collection_end() {
|
||||
double full_gc_time_sec = end_sec - _cur_collection_start_sec;
|
||||
double full_gc_time_ms = full_gc_time_sec * 1000.0;
|
||||
|
||||
_all_full_gc_times_ms->add(full_gc_time_ms);
|
||||
_trace_gen1_time_data.record_full_collection(full_gc_time_ms);
|
||||
|
||||
update_recent_gc_times(end_sec, full_gc_time_ms);
|
||||
|
||||
@ -900,7 +885,7 @@ void G1CollectorPolicy::record_collection_pause_start(double start_time_sec,
|
||||
_g1->used(), _g1->recalculate_used()));
|
||||
|
||||
double s_w_t_ms = (start_time_sec - _stop_world_start) * 1000.0;
|
||||
_all_stop_world_times_ms->add(s_w_t_ms);
|
||||
_trace_gen0_time_data.record_start_collection(s_w_t_ms);
|
||||
_stop_world_start = 0.0;
|
||||
|
||||
_cur_collection_start_sec = start_time_sec;
|
||||
@ -937,11 +922,6 @@ void G1CollectorPolicy::record_collection_pause_start(double start_time_sec,
|
||||
}
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < _aux_num; ++i) {
|
||||
_cur_aux_times_ms[i] = 0.0;
|
||||
_cur_aux_times_set[i] = false;
|
||||
}
|
||||
|
||||
// This is initialized to zero here and is set during the evacuation
|
||||
// pause if we actually waited for the root region scanning to finish.
|
||||
_root_region_scan_wait_time_ms = 0.0;
|
||||
@ -990,7 +970,7 @@ void G1CollectorPolicy::record_concurrent_mark_cleanup_completed() {
|
||||
void G1CollectorPolicy::record_concurrent_pause() {
|
||||
if (_stop_world_start > 0.0) {
|
||||
double yield_ms = (os::elapsedTime() - _stop_world_start) * 1000.0;
|
||||
_all_yield_times_ms->add(yield_ms);
|
||||
_trace_gen0_time_data.record_yield_time(yield_ms);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1197,21 +1177,6 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
|
||||
_mmu_tracker->add_pause(end_time_sec - elapsed_ms/1000.0,
|
||||
end_time_sec, false);
|
||||
|
||||
// This assert is exempted when we're doing parallel collection pauses,
|
||||
// because the fragmentation caused by the parallel GC allocation buffers
|
||||
// can lead to more memory being used during collection than was used
|
||||
// before. Best leave this out until the fragmentation problem is fixed.
|
||||
// Pauses in which evacuation failed can also lead to negative
|
||||
// collections, since no space is reclaimed from a region containing an
|
||||
// object whose evacuation failed.
|
||||
// Further, we're now always doing parallel collection. But I'm still
|
||||
// leaving this here as a placeholder for a more precise assertion later.
|
||||
// (DLD, 10/05.)
|
||||
assert((true || parallel) // Always using GC LABs now.
|
||||
|| _g1->evacuation_failed()
|
||||
|| _cur_collection_pause_used_at_start_bytes >= cur_used_bytes,
|
||||
"Negative collection");
|
||||
|
||||
size_t freed_bytes =
|
||||
_cur_collection_pause_used_at_start_bytes - cur_used_bytes;
|
||||
size_t surviving_bytes = _collection_set_bytes_used_before - freed_bytes;
|
||||
@ -1259,44 +1224,15 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
|
||||
other_time_ms -= _cur_clear_ct_time_ms;
|
||||
|
||||
// TraceGen0Time and TraceGen1Time summary info updating.
|
||||
_all_pause_times_ms->add(elapsed_ms);
|
||||
|
||||
if (update_stats) {
|
||||
_summary->record_total_time_ms(elapsed_ms);
|
||||
_summary->record_other_time_ms(other_time_ms);
|
||||
double parallel_known_time = known_time + termination_time;
|
||||
double parallel_other_time = _cur_collection_par_time_ms - parallel_known_time;
|
||||
|
||||
MainBodySummary* body_summary = _summary->main_body_summary();
|
||||
assert(body_summary != NULL, "should not be null!");
|
||||
|
||||
body_summary->record_root_region_scan_wait_time_ms(
|
||||
_root_region_scan_wait_time_ms);
|
||||
body_summary->record_ext_root_scan_time_ms(ext_root_scan_time);
|
||||
body_summary->record_satb_filtering_time_ms(satb_filtering_time);
|
||||
body_summary->record_update_rs_time_ms(update_rs_time);
|
||||
body_summary->record_scan_rs_time_ms(scan_rs_time);
|
||||
body_summary->record_obj_copy_time_ms(obj_copy_time);
|
||||
|
||||
if (parallel) {
|
||||
body_summary->record_parallel_time_ms(_cur_collection_par_time_ms);
|
||||
body_summary->record_termination_time_ms(termination_time);
|
||||
|
||||
double parallel_known_time = known_time + termination_time;
|
||||
double parallel_other_time = _cur_collection_par_time_ms - parallel_known_time;
|
||||
body_summary->record_parallel_other_time_ms(parallel_other_time);
|
||||
}
|
||||
|
||||
body_summary->record_clear_ct_time_ms(_cur_clear_ct_time_ms);
|
||||
|
||||
// We exempt parallel collection from this check because Alloc Buffer
|
||||
// fragmentation can produce negative collections. Same with evac
|
||||
// failure.
|
||||
// Further, we're now always doing parallel collection. But I'm still
|
||||
// leaving this here as a placeholder for a more precise assertion later.
|
||||
// (DLD, 10/05.
|
||||
assert((true || parallel)
|
||||
|| _g1->evacuation_failed()
|
||||
|| surviving_bytes <= _collection_set_bytes_used_before,
|
||||
"Or else negative collection!");
|
||||
_trace_gen0_time_data.record_end_collection(
|
||||
elapsed_ms, other_time_ms, _root_region_scan_wait_time_ms, _cur_collection_par_time_ms,
|
||||
ext_root_scan_time, satb_filtering_time, update_rs_time, scan_rs_time, obj_copy_time,
|
||||
termination_time, parallel_other_time, _cur_clear_ct_time_ms);
|
||||
|
||||
// this is where we update the allocation rate of the application
|
||||
double app_time_ms =
|
||||
@ -1349,12 +1285,6 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < _aux_num; ++i) {
|
||||
if (_cur_aux_times_set[i]) {
|
||||
_all_aux_times_ms[i].add(_cur_aux_times_ms[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (G1Log::finer()) {
|
||||
bool print_marking_info =
|
||||
_g1->mark_in_progress() && !last_pause_included_initial_mark;
|
||||
@ -1436,14 +1366,6 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
|
||||
print_stats(2, "Free CSet",
|
||||
(_recorded_young_free_cset_time_ms +
|
||||
_recorded_non_young_free_cset_time_ms));
|
||||
|
||||
for (int i = 0; i < _aux_num; ++i) {
|
||||
if (_cur_aux_times_set[i]) {
|
||||
char buffer[96];
|
||||
sprintf(buffer, "Aux%d", i);
|
||||
print_stats(1, buffer, _cur_aux_times_ms[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool new_in_marking_window = _in_marking_window;
|
||||
@ -1808,179 +1730,9 @@ void G1CollectorPolicy::count_CS_bytes_used() {
|
||||
_g1->collection_set_iterate(&cs_closure);
|
||||
}
|
||||
|
||||
void G1CollectorPolicy::print_summary(int level,
|
||||
const char* str,
|
||||
NumberSeq* seq) const {
|
||||
double sum = seq->sum();
|
||||
LineBuffer(level + 1).append_and_print_cr("%-24s = %8.2lf s (avg = %8.2lf ms)",
|
||||
str, sum / 1000.0, seq->avg());
|
||||
}
|
||||
|
||||
void G1CollectorPolicy::print_summary_sd(int level,
|
||||
const char* str,
|
||||
NumberSeq* seq) const {
|
||||
print_summary(level, str, seq);
|
||||
LineBuffer(level + 6).append_and_print_cr("(num = %5d, std dev = %8.2lf ms, max = %8.2lf ms)",
|
||||
seq->num(), seq->sd(), seq->maximum());
|
||||
}
|
||||
|
||||
void G1CollectorPolicy::check_other_times(int level,
|
||||
NumberSeq* other_times_ms,
|
||||
NumberSeq* calc_other_times_ms) const {
|
||||
bool should_print = false;
|
||||
LineBuffer buf(level + 2);
|
||||
|
||||
double max_sum = MAX2(fabs(other_times_ms->sum()),
|
||||
fabs(calc_other_times_ms->sum()));
|
||||
double min_sum = MIN2(fabs(other_times_ms->sum()),
|
||||
fabs(calc_other_times_ms->sum()));
|
||||
double sum_ratio = max_sum / min_sum;
|
||||
if (sum_ratio > 1.1) {
|
||||
should_print = true;
|
||||
buf.append_and_print_cr("## CALCULATED OTHER SUM DOESN'T MATCH RECORDED ###");
|
||||
}
|
||||
|
||||
double max_avg = MAX2(fabs(other_times_ms->avg()),
|
||||
fabs(calc_other_times_ms->avg()));
|
||||
double min_avg = MIN2(fabs(other_times_ms->avg()),
|
||||
fabs(calc_other_times_ms->avg()));
|
||||
double avg_ratio = max_avg / min_avg;
|
||||
if (avg_ratio > 1.1) {
|
||||
should_print = true;
|
||||
buf.append_and_print_cr("## CALCULATED OTHER AVG DOESN'T MATCH RECORDED ###");
|
||||
}
|
||||
|
||||
if (other_times_ms->sum() < -0.01) {
|
||||
buf.append_and_print_cr("## RECORDED OTHER SUM IS NEGATIVE ###");
|
||||
}
|
||||
|
||||
if (other_times_ms->avg() < -0.01) {
|
||||
buf.append_and_print_cr("## RECORDED OTHER AVG IS NEGATIVE ###");
|
||||
}
|
||||
|
||||
if (calc_other_times_ms->sum() < -0.01) {
|
||||
should_print = true;
|
||||
buf.append_and_print_cr("## CALCULATED OTHER SUM IS NEGATIVE ###");
|
||||
}
|
||||
|
||||
if (calc_other_times_ms->avg() < -0.01) {
|
||||
should_print = true;
|
||||
buf.append_and_print_cr("## CALCULATED OTHER AVG IS NEGATIVE ###");
|
||||
}
|
||||
|
||||
if (should_print)
|
||||
print_summary(level, "Other(Calc)", calc_other_times_ms);
|
||||
}
|
||||
|
||||
void G1CollectorPolicy::print_summary(PauseSummary* summary) const {
|
||||
bool parallel = G1CollectedHeap::use_parallel_gc_threads();
|
||||
MainBodySummary* body_summary = summary->main_body_summary();
|
||||
if (summary->get_total_seq()->num() > 0) {
|
||||
print_summary_sd(0, "Evacuation Pauses", summary->get_total_seq());
|
||||
if (body_summary != NULL) {
|
||||
print_summary(1, "Root Region Scan Wait", body_summary->get_root_region_scan_wait_seq());
|
||||
if (parallel) {
|
||||
print_summary(1, "Parallel Time", body_summary->get_parallel_seq());
|
||||
print_summary(2, "Ext Root Scanning", body_summary->get_ext_root_scan_seq());
|
||||
print_summary(2, "SATB Filtering", body_summary->get_satb_filtering_seq());
|
||||
print_summary(2, "Update RS", body_summary->get_update_rs_seq());
|
||||
print_summary(2, "Scan RS", body_summary->get_scan_rs_seq());
|
||||
print_summary(2, "Object Copy", body_summary->get_obj_copy_seq());
|
||||
print_summary(2, "Termination", body_summary->get_termination_seq());
|
||||
print_summary(2, "Parallel Other", body_summary->get_parallel_other_seq());
|
||||
{
|
||||
NumberSeq* other_parts[] = {
|
||||
body_summary->get_ext_root_scan_seq(),
|
||||
body_summary->get_satb_filtering_seq(),
|
||||
body_summary->get_update_rs_seq(),
|
||||
body_summary->get_scan_rs_seq(),
|
||||
body_summary->get_obj_copy_seq(),
|
||||
body_summary->get_termination_seq()
|
||||
};
|
||||
NumberSeq calc_other_times_ms(body_summary->get_parallel_seq(),
|
||||
6, other_parts);
|
||||
check_other_times(2, body_summary->get_parallel_other_seq(),
|
||||
&calc_other_times_ms);
|
||||
}
|
||||
} else {
|
||||
print_summary(1, "Ext Root Scanning", body_summary->get_ext_root_scan_seq());
|
||||
print_summary(1, "SATB Filtering", body_summary->get_satb_filtering_seq());
|
||||
print_summary(1, "Update RS", body_summary->get_update_rs_seq());
|
||||
print_summary(1, "Scan RS", body_summary->get_scan_rs_seq());
|
||||
print_summary(1, "Object Copy", body_summary->get_obj_copy_seq());
|
||||
}
|
||||
}
|
||||
print_summary(1, "Clear CT", body_summary->get_clear_ct_seq());
|
||||
print_summary(1, "Other", summary->get_other_seq());
|
||||
{
|
||||
if (body_summary != NULL) {
|
||||
NumberSeq calc_other_times_ms;
|
||||
if (parallel) {
|
||||
// parallel
|
||||
NumberSeq* other_parts[] = {
|
||||
body_summary->get_root_region_scan_wait_seq(),
|
||||
body_summary->get_parallel_seq(),
|
||||
body_summary->get_clear_ct_seq()
|
||||
};
|
||||
calc_other_times_ms = NumberSeq(summary->get_total_seq(),
|
||||
3, other_parts);
|
||||
} else {
|
||||
// serial
|
||||
NumberSeq* other_parts[] = {
|
||||
body_summary->get_root_region_scan_wait_seq(),
|
||||
body_summary->get_update_rs_seq(),
|
||||
body_summary->get_ext_root_scan_seq(),
|
||||
body_summary->get_satb_filtering_seq(),
|
||||
body_summary->get_scan_rs_seq(),
|
||||
body_summary->get_obj_copy_seq()
|
||||
};
|
||||
calc_other_times_ms = NumberSeq(summary->get_total_seq(),
|
||||
6, other_parts);
|
||||
}
|
||||
check_other_times(1, summary->get_other_seq(), &calc_other_times_ms);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LineBuffer(1).append_and_print_cr("none");
|
||||
}
|
||||
LineBuffer(0).append_and_print_cr("");
|
||||
}
|
||||
|
||||
void G1CollectorPolicy::print_tracing_info() const {
|
||||
if (TraceGen0Time) {
|
||||
gclog_or_tty->print_cr("ALL PAUSES");
|
||||
print_summary_sd(0, "Total", _all_pause_times_ms);
|
||||
gclog_or_tty->print_cr("");
|
||||
gclog_or_tty->print_cr("");
|
||||
gclog_or_tty->print_cr(" Young GC Pauses: %8d", _young_pause_num);
|
||||
gclog_or_tty->print_cr(" Mixed GC Pauses: %8d", _mixed_pause_num);
|
||||
gclog_or_tty->print_cr("");
|
||||
|
||||
gclog_or_tty->print_cr("EVACUATION PAUSES");
|
||||
print_summary(_summary);
|
||||
|
||||
gclog_or_tty->print_cr("MISC");
|
||||
print_summary_sd(0, "Stop World", _all_stop_world_times_ms);
|
||||
print_summary_sd(0, "Yields", _all_yield_times_ms);
|
||||
for (int i = 0; i < _aux_num; ++i) {
|
||||
if (_all_aux_times_ms[i].num() > 0) {
|
||||
char buffer[96];
|
||||
sprintf(buffer, "Aux%d", i);
|
||||
print_summary_sd(0, buffer, &_all_aux_times_ms[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (TraceGen1Time) {
|
||||
if (_all_full_gc_times_ms->num() > 0) {
|
||||
gclog_or_tty->print("\n%4d full_gcs: total time = %8.2f s",
|
||||
_all_full_gc_times_ms->num(),
|
||||
_all_full_gc_times_ms->sum() / 1000.0);
|
||||
gclog_or_tty->print_cr(" (avg = %8.2fms).", _all_full_gc_times_ms->avg());
|
||||
gclog_or_tty->print_cr(" [std. dev = %8.2f ms, max = %8.2f ms]",
|
||||
_all_full_gc_times_ms->sd(),
|
||||
_all_full_gc_times_ms->maximum());
|
||||
}
|
||||
}
|
||||
_trace_gen0_time_data.print();
|
||||
_trace_gen1_time_data.print();
|
||||
}
|
||||
|
||||
void G1CollectorPolicy::print_yg_surv_rate_info() const {
|
||||
@ -2531,9 +2283,9 @@ void G1CollectorPolicy::finalize_cset(double target_pause_time_ms) {
|
||||
_last_gc_was_young = gcs_are_young() ? true : false;
|
||||
|
||||
if (_last_gc_was_young) {
|
||||
++_young_pause_num;
|
||||
_trace_gen0_time_data.increment_young_collection_count();
|
||||
} else {
|
||||
++_mixed_pause_num;
|
||||
_trace_gen0_time_data.increment_mixed_collection_count();
|
||||
}
|
||||
|
||||
// The young list is laid with the survivor regions from the previous
|
||||
@ -2690,3 +2442,133 @@ void G1CollectorPolicy::finalize_cset(double target_pause_time_ms) {
|
||||
_recorded_non_young_cset_choice_time_ms =
|
||||
(non_young_end_time_sec - non_young_start_time_sec) * 1000.0;
|
||||
}
|
||||
|
||||
void TraceGen0TimeData::record_start_collection(double time_to_stop_the_world_ms) {
|
||||
if(TraceGen0Time) {
|
||||
_all_stop_world_times_ms.add(time_to_stop_the_world_ms);
|
||||
}
|
||||
}
|
||||
|
||||
void TraceGen0TimeData::record_yield_time(double yield_time_ms) {
|
||||
if(TraceGen0Time) {
|
||||
_all_yield_times_ms.add(yield_time_ms);
|
||||
}
|
||||
}
|
||||
|
||||
void TraceGen0TimeData::record_end_collection(
|
||||
double total_ms,
|
||||
double other_ms,
|
||||
double root_region_scan_wait_ms,
|
||||
double parallel_ms,
|
||||
double ext_root_scan_ms,
|
||||
double satb_filtering_ms,
|
||||
double update_rs_ms,
|
||||
double scan_rs_ms,
|
||||
double obj_copy_ms,
|
||||
double termination_ms,
|
||||
double parallel_other_ms,
|
||||
double clear_ct_ms)
|
||||
{
|
||||
if(TraceGen0Time) {
|
||||
_total.add(total_ms);
|
||||
_other.add(other_ms);
|
||||
_root_region_scan_wait.add(root_region_scan_wait_ms);
|
||||
_parallel.add(parallel_ms);
|
||||
_ext_root_scan.add(ext_root_scan_ms);
|
||||
_satb_filtering.add(satb_filtering_ms);
|
||||
_update_rs.add(update_rs_ms);
|
||||
_scan_rs.add(scan_rs_ms);
|
||||
_obj_copy.add(obj_copy_ms);
|
||||
_termination.add(termination_ms);
|
||||
_parallel_other.add(parallel_other_ms);
|
||||
_clear_ct.add(clear_ct_ms);
|
||||
}
|
||||
}
|
||||
|
||||
void TraceGen0TimeData::increment_young_collection_count() {
|
||||
if(TraceGen0Time) {
|
||||
++_young_pause_num;
|
||||
}
|
||||
}
|
||||
|
||||
void TraceGen0TimeData::increment_mixed_collection_count() {
|
||||
if(TraceGen0Time) {
|
||||
++_mixed_pause_num;
|
||||
}
|
||||
}
|
||||
|
||||
void TraceGen0TimeData::print_summary(int level,
|
||||
const char* str,
|
||||
const NumberSeq* seq) const {
|
||||
double sum = seq->sum();
|
||||
LineBuffer(level + 1).append_and_print_cr("%-24s = %8.2lf s (avg = %8.2lf ms)",
|
||||
str, sum / 1000.0, seq->avg());
|
||||
}
|
||||
|
||||
void TraceGen0TimeData::print_summary_sd(int level,
|
||||
const char* str,
|
||||
const NumberSeq* seq) const {
|
||||
print_summary(level, str, seq);
|
||||
LineBuffer(level + 6).append_and_print_cr("(num = %5d, std dev = %8.2lf ms, max = %8.2lf ms)",
|
||||
seq->num(), seq->sd(), seq->maximum());
|
||||
}
|
||||
|
||||
void TraceGen0TimeData::print() const {
|
||||
if (!TraceGen0Time) {
|
||||
return;
|
||||
}
|
||||
|
||||
gclog_or_tty->print_cr("ALL PAUSES");
|
||||
print_summary_sd(0, "Total", &_total);
|
||||
gclog_or_tty->print_cr("");
|
||||
gclog_or_tty->print_cr("");
|
||||
gclog_or_tty->print_cr(" Young GC Pauses: %8d", _young_pause_num);
|
||||
gclog_or_tty->print_cr(" Mixed GC Pauses: %8d", _mixed_pause_num);
|
||||
gclog_or_tty->print_cr("");
|
||||
|
||||
gclog_or_tty->print_cr("EVACUATION PAUSES");
|
||||
|
||||
if (_young_pause_num == 0 && _mixed_pause_num == 0) {
|
||||
gclog_or_tty->print_cr("none");
|
||||
} else {
|
||||
print_summary_sd(0, "Evacuation Pauses", &_total);
|
||||
print_summary(1, "Root Region Scan Wait", &_root_region_scan_wait);
|
||||
print_summary(1, "Parallel Time", &_parallel);
|
||||
print_summary(2, "Ext Root Scanning", &_ext_root_scan);
|
||||
print_summary(2, "SATB Filtering", &_satb_filtering);
|
||||
print_summary(2, "Update RS", &_update_rs);
|
||||
print_summary(2, "Scan RS", &_scan_rs);
|
||||
print_summary(2, "Object Copy", &_obj_copy);
|
||||
print_summary(2, "Termination", &_termination);
|
||||
print_summary(2, "Parallel Other", &_parallel_other);
|
||||
print_summary(1, "Clear CT", &_clear_ct);
|
||||
print_summary(1, "Other", &_other);
|
||||
}
|
||||
gclog_or_tty->print_cr("");
|
||||
|
||||
gclog_or_tty->print_cr("MISC");
|
||||
print_summary_sd(0, "Stop World", &_all_stop_world_times_ms);
|
||||
print_summary_sd(0, "Yields", &_all_yield_times_ms);
|
||||
}
|
||||
|
||||
void TraceGen1TimeData::record_full_collection(double full_gc_time_ms) {
|
||||
if (TraceGen1Time) {
|
||||
_all_full_gc_times.add(full_gc_time_ms);
|
||||
}
|
||||
}
|
||||
|
||||
void TraceGen1TimeData::print() const {
|
||||
if (!TraceGen1Time) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_all_full_gc_times.num() > 0) {
|
||||
gclog_or_tty->print("\n%4d full_gcs: total time = %8.2f s",
|
||||
_all_full_gc_times.num(),
|
||||
_all_full_gc_times.sum() / 1000.0);
|
||||
gclog_or_tty->print_cr(" (avg = %8.2fms).", _all_full_gc_times.avg());
|
||||
gclog_or_tty->print_cr(" [std. dev = %8.2f ms, max = %8.2f ms]",
|
||||
_all_full_gc_times.sd(),
|
||||
_all_full_gc_times.maximum());
|
||||
}
|
||||
}
|
||||
|
@ -37,49 +37,62 @@
|
||||
class HeapRegion;
|
||||
class CollectionSetChooser;
|
||||
|
||||
// Yes, this is a bit unpleasant... but it saves replicating the same thing
|
||||
// over and over again and introducing subtle problems through small typos and
|
||||
// cutting and pasting mistakes. The macros below introduces a number
|
||||
// sequnce into the following two classes and the methods that access it.
|
||||
// TraceGen0Time collects data on _both_ young and mixed evacuation pauses
|
||||
// (the latter may contain non-young regions - i.e. regions that are
|
||||
// technically in Gen1) while TraceGen1Time collects data about full GCs.
|
||||
class TraceGen0TimeData : public CHeapObj {
|
||||
private:
|
||||
unsigned _young_pause_num;
|
||||
unsigned _mixed_pause_num;
|
||||
|
||||
#define define_num_seq(name) \
|
||||
private: \
|
||||
NumberSeq _all_##name##_times_ms; \
|
||||
public: \
|
||||
void record_##name##_time_ms(double ms) { \
|
||||
_all_##name##_times_ms.add(ms); \
|
||||
} \
|
||||
NumberSeq* get_##name##_seq() { \
|
||||
return &_all_##name##_times_ms; \
|
||||
}
|
||||
NumberSeq _all_stop_world_times_ms;
|
||||
NumberSeq _all_yield_times_ms;
|
||||
|
||||
class MainBodySummary;
|
||||
NumberSeq _total;
|
||||
NumberSeq _other;
|
||||
NumberSeq _root_region_scan_wait;
|
||||
NumberSeq _parallel;
|
||||
NumberSeq _ext_root_scan;
|
||||
NumberSeq _satb_filtering;
|
||||
NumberSeq _update_rs;
|
||||
NumberSeq _scan_rs;
|
||||
NumberSeq _obj_copy;
|
||||
NumberSeq _termination;
|
||||
NumberSeq _parallel_other;
|
||||
NumberSeq _clear_ct;
|
||||
|
||||
class PauseSummary: public CHeapObj {
|
||||
define_num_seq(total)
|
||||
define_num_seq(other)
|
||||
void print_summary (int level, const char* str, const NumberSeq* seq) const;
|
||||
void print_summary_sd (int level, const char* str, const NumberSeq* seq) const;
|
||||
|
||||
public:
|
||||
virtual MainBodySummary* main_body_summary() { return NULL; }
|
||||
TraceGen0TimeData() : _young_pause_num(0), _mixed_pause_num(0) {};
|
||||
void record_start_collection(double time_to_stop_the_world_ms);
|
||||
void record_yield_time(double yield_time_ms);
|
||||
void record_end_collection(
|
||||
double total_ms,
|
||||
double other_ms,
|
||||
double root_region_scan_wait_ms,
|
||||
double parallel_ms,
|
||||
double ext_root_scan_ms,
|
||||
double satb_filtering_ms,
|
||||
double update_rs_ms,
|
||||
double scan_rs_ms,
|
||||
double obj_copy_ms,
|
||||
double termination_ms,
|
||||
double parallel_other_ms,
|
||||
double clear_ct_ms);
|
||||
void increment_young_collection_count();
|
||||
void increment_mixed_collection_count();
|
||||
void print() const;
|
||||
};
|
||||
|
||||
class MainBodySummary: public CHeapObj {
|
||||
define_num_seq(root_region_scan_wait)
|
||||
define_num_seq(parallel) // parallel only
|
||||
define_num_seq(ext_root_scan)
|
||||
define_num_seq(satb_filtering)
|
||||
define_num_seq(update_rs)
|
||||
define_num_seq(scan_rs)
|
||||
define_num_seq(obj_copy)
|
||||
define_num_seq(termination) // parallel only
|
||||
define_num_seq(parallel_other) // parallel only
|
||||
define_num_seq(clear_ct)
|
||||
};
|
||||
class TraceGen1TimeData : public CHeapObj {
|
||||
private:
|
||||
NumberSeq _all_full_gc_times;
|
||||
|
||||
class Summary: public PauseSummary,
|
||||
public MainBodySummary {
|
||||
public:
|
||||
virtual MainBodySummary* main_body_summary() { return this; }
|
||||
public:
|
||||
void record_full_collection(double full_gc_time_ms);
|
||||
void print() const;
|
||||
};
|
||||
|
||||
// There are three command line options related to the young gen size:
|
||||
@ -199,19 +212,10 @@ private:
|
||||
TruncatedSeq* _concurrent_mark_remark_times_ms;
|
||||
TruncatedSeq* _concurrent_mark_cleanup_times_ms;
|
||||
|
||||
Summary* _summary;
|
||||
TraceGen0TimeData _trace_gen0_time_data;
|
||||
TraceGen1TimeData _trace_gen1_time_data;
|
||||
|
||||
NumberSeq* _all_pause_times_ms;
|
||||
NumberSeq* _all_full_gc_times_ms;
|
||||
double _stop_world_start;
|
||||
NumberSeq* _all_stop_world_times_ms;
|
||||
NumberSeq* _all_yield_times_ms;
|
||||
|
||||
int _aux_num;
|
||||
NumberSeq* _all_aux_times_ms;
|
||||
double* _cur_aux_start_times_ms;
|
||||
double* _cur_aux_times_ms;
|
||||
bool* _cur_aux_times_set;
|
||||
|
||||
double* _par_last_gc_worker_start_times_ms;
|
||||
double* _par_last_ext_root_scan_times_ms;
|
||||
@ -243,9 +247,6 @@ private:
|
||||
|
||||
bool _last_gc_was_young;
|
||||
|
||||
unsigned _young_pause_num;
|
||||
unsigned _mixed_pause_num;
|
||||
|
||||
bool _during_marking;
|
||||
bool _in_marking_window;
|
||||
bool _in_marking_window_im;
|
||||
@ -557,15 +558,6 @@ private:
|
||||
|
||||
void print_par_stats(int level, const char* str, double* data, bool showDecimals = true);
|
||||
|
||||
void check_other_times(int level,
|
||||
NumberSeq* other_times_ms,
|
||||
NumberSeq* calc_other_times_ms) const;
|
||||
|
||||
void print_summary (PauseSummary* stats) const;
|
||||
|
||||
void print_summary (int level, const char* str, NumberSeq* seq) const;
|
||||
void print_summary_sd (int level, const char* str, NumberSeq* seq) const;
|
||||
|
||||
double avg_value (double* data);
|
||||
double max_value (double* data);
|
||||
double sum_of_values (double* data);
|
||||
@ -745,10 +737,6 @@ public:
|
||||
return _bytes_in_collection_set_before_gc;
|
||||
}
|
||||
|
||||
unsigned calc_gc_alloc_time_stamp() {
|
||||
return _all_pause_times_ms->num() + 1;
|
||||
}
|
||||
|
||||
// This should be called after the heap is resized.
|
||||
void record_new_heap_size(uint new_number_of_regions);
|
||||
|
||||
@ -867,18 +855,6 @@ public:
|
||||
_cur_collection_code_root_fixup_time_ms = ms;
|
||||
}
|
||||
|
||||
void record_aux_start_time(int i) {
|
||||
guarantee(i < _aux_num, "should be within range");
|
||||
_cur_aux_start_times_ms[i] = os::elapsedTime() * 1000.0;
|
||||
}
|
||||
|
||||
void record_aux_end_time(int i) {
|
||||
guarantee(i < _aux_num, "should be within range");
|
||||
double ms = os::elapsedTime() * 1000.0 - _cur_aux_start_times_ms[i];
|
||||
_cur_aux_times_set[i] = true;
|
||||
_cur_aux_times_ms[i] += ms;
|
||||
}
|
||||
|
||||
void record_ref_proc_time(double ms) {
|
||||
_cur_ref_proc_time_ms = ms;
|
||||
}
|
||||
|
@ -1106,7 +1106,8 @@ HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetSharedArray* bosa,
|
||||
void HeapRegionRemSet::setup_remset_size() {
|
||||
// Setup sparse and fine-grain tables sizes.
|
||||
// table_size = base * (log(region_size / 1M) + 1)
|
||||
int region_size_log_mb = MAX2((int)HeapRegion::LogOfHRGrainBytes - (int)LOG_M, 0);
|
||||
const int LOG_M = 20;
|
||||
int region_size_log_mb = MAX2(HeapRegion::LogOfHRGrainBytes - LOG_M, 0);
|
||||
if (FLAG_IS_DEFAULT(G1RSetSparseRegionEntries)) {
|
||||
G1RSetSparseRegionEntries = G1RSetSparseRegionEntriesBase * (region_size_log_mb + 1);
|
||||
}
|
||||
|
@ -677,11 +677,6 @@ void GenCollectedHeap::do_collection(bool full,
|
||||
#ifdef TRACESPINNING
|
||||
ParallelTaskTerminator::print_termination_counts();
|
||||
#endif
|
||||
|
||||
if (ExitAfterGCNum > 0 && total_collections() == ExitAfterGCNum) {
|
||||
tty->print_cr("Stopping after GC #%d", ExitAfterGCNum);
|
||||
vm_exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
HeapWord* GenCollectedHeap::satisfy_failed_allocation(size_t size, bool is_tlab) {
|
||||
|
@ -50,8 +50,7 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC {
|
||||
initval_index_offset = 3,
|
||||
low_offset = 4,
|
||||
high_offset = 5,
|
||||
generic_signature_offset = 6,
|
||||
field_slots = 7
|
||||
field_slots = 6
|
||||
};
|
||||
|
||||
private:
|
||||
@ -60,29 +59,28 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC {
|
||||
void set_name_index(u2 val) { _shorts[name_index_offset] = val; }
|
||||
void set_signature_index(u2 val) { _shorts[signature_index_offset] = val; }
|
||||
void set_initval_index(u2 val) { _shorts[initval_index_offset] = val; }
|
||||
void set_generic_signature_index(u2 val) { _shorts[generic_signature_offset] = val; }
|
||||
|
||||
u2 name_index() const { return _shorts[name_index_offset]; }
|
||||
u2 signature_index() const { return _shorts[signature_index_offset]; }
|
||||
u2 initval_index() const { return _shorts[initval_index_offset]; }
|
||||
u2 generic_signature_index() const { return _shorts[generic_signature_offset]; }
|
||||
|
||||
public:
|
||||
static FieldInfo* from_field_array(typeArrayOop fields, int index) {
|
||||
return ((FieldInfo*)fields->short_at_addr(index * field_slots));
|
||||
}
|
||||
static FieldInfo* from_field_array(u2* fields, int index) {
|
||||
return ((FieldInfo*)(fields + index * field_slots));
|
||||
}
|
||||
|
||||
void initialize(u2 access_flags,
|
||||
u2 name_index,
|
||||
u2 signature_index,
|
||||
u2 initval_index,
|
||||
u2 generic_signature_index,
|
||||
u4 offset) {
|
||||
_shorts[access_flags_offset] = access_flags;
|
||||
_shorts[name_index_offset] = name_index;
|
||||
_shorts[signature_index_offset] = signature_index;
|
||||
_shorts[initval_index_offset] = initval_index;
|
||||
_shorts[generic_signature_offset] = generic_signature_index;
|
||||
set_offset(offset);
|
||||
}
|
||||
|
||||
@ -105,14 +103,6 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC {
|
||||
return cp->symbol_at(index);
|
||||
}
|
||||
|
||||
Symbol* generic_signature(constantPoolHandle cp) const {
|
||||
int index = generic_signature_index();
|
||||
if (index == 0) {
|
||||
return NULL;
|
||||
}
|
||||
return cp->symbol_at(index);
|
||||
}
|
||||
|
||||
void set_access_flags(u2 val) { _shorts[access_flags_offset] = val; }
|
||||
void set_offset(u4 val) {
|
||||
_shorts[low_offset] = extract_low_short_from_int(val);
|
||||
|
@ -42,21 +42,57 @@ class FieldStreamBase : public StackObj {
|
||||
constantPoolHandle _constants;
|
||||
int _index;
|
||||
int _limit;
|
||||
int _generic_signature_slot;
|
||||
|
||||
FieldInfo* field() const { return FieldInfo::from_field_array(_fields(), _index); }
|
||||
|
||||
int init_generic_signature_start_slot() {
|
||||
int length = _fields->length();
|
||||
int num_fields = 0;
|
||||
int skipped_generic_signature_slots = 0;
|
||||
FieldInfo* fi;
|
||||
AccessFlags flags;
|
||||
/* Scan from 0 to the current _index. Count the number of generic
|
||||
signature slots for field[0] to field[_index - 1]. */
|
||||
for (int i = 0; i < _index; i++) {
|
||||
fi = FieldInfo::from_field_array(_fields(), i);
|
||||
flags.set_flags(fi->access_flags());
|
||||
if (flags.field_has_generic_signature()) {
|
||||
length --;
|
||||
skipped_generic_signature_slots ++;
|
||||
}
|
||||
}
|
||||
/* Scan from the current _index. */
|
||||
for (int i = _index; i*FieldInfo::field_slots < length; i++) {
|
||||
fi = FieldInfo::from_field_array(_fields(), i);
|
||||
flags.set_flags(fi->access_flags());
|
||||
if (flags.field_has_generic_signature()) {
|
||||
length --;
|
||||
}
|
||||
num_fields ++;
|
||||
}
|
||||
_generic_signature_slot = length + skipped_generic_signature_slots;
|
||||
assert(_generic_signature_slot <= _fields->length(), "");
|
||||
return num_fields;
|
||||
}
|
||||
|
||||
FieldStreamBase(typeArrayHandle fields, constantPoolHandle constants, int start, int limit) {
|
||||
_fields = fields;
|
||||
_constants = constants;
|
||||
_index = start;
|
||||
_limit = limit;
|
||||
int num_fields = init_generic_signature_start_slot();
|
||||
if (limit < start) {
|
||||
_limit = num_fields;
|
||||
} else {
|
||||
_limit = limit;
|
||||
}
|
||||
}
|
||||
|
||||
FieldStreamBase(typeArrayHandle fields, constantPoolHandle constants) {
|
||||
_fields = fields;
|
||||
_constants = constants;
|
||||
_index = 0;
|
||||
_limit = fields->length() / FieldInfo::field_slots;
|
||||
_limit = init_generic_signature_start_slot();
|
||||
}
|
||||
|
||||
public:
|
||||
@ -65,18 +101,26 @@ class FieldStreamBase : public StackObj {
|
||||
_constants = klass->constants();
|
||||
_index = 0;
|
||||
_limit = klass->java_fields_count();
|
||||
init_generic_signature_start_slot();
|
||||
}
|
||||
FieldStreamBase(instanceKlassHandle klass) {
|
||||
_fields = klass->fields();
|
||||
_constants = klass->constants();
|
||||
_index = 0;
|
||||
_limit = klass->java_fields_count();
|
||||
init_generic_signature_start_slot();
|
||||
}
|
||||
|
||||
// accessors
|
||||
int index() const { return _index; }
|
||||
|
||||
void next() { _index += 1; }
|
||||
void next() {
|
||||
if (access_flags().field_has_generic_signature()) {
|
||||
_generic_signature_slot ++;
|
||||
assert(_generic_signature_slot <= _fields->length(), "");
|
||||
}
|
||||
_index += 1;
|
||||
}
|
||||
bool done() const { return _index >= _limit; }
|
||||
|
||||
// Accessors for current field
|
||||
@ -103,7 +147,13 @@ class FieldStreamBase : public StackObj {
|
||||
}
|
||||
|
||||
Symbol* generic_signature() const {
|
||||
return field()->generic_signature(_constants);
|
||||
if (access_flags().field_has_generic_signature()) {
|
||||
assert(_generic_signature_slot < _fields->length(), "out of bounds");
|
||||
int index = _fields->short_at(_generic_signature_slot);
|
||||
return _constants->symbol_at(index);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int offset() const {
|
||||
@ -139,11 +189,19 @@ class JavaFieldStream : public FieldStreamBase {
|
||||
}
|
||||
int generic_signature_index() const {
|
||||
assert(!field()->is_internal(), "regular only");
|
||||
return field()->generic_signature_index();
|
||||
if (access_flags().field_has_generic_signature()) {
|
||||
assert(_generic_signature_slot < _fields->length(), "out of bounds");
|
||||
return _fields->short_at(_generic_signature_slot);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
void set_generic_signature_index(int index) {
|
||||
assert(!field()->is_internal(), "regular only");
|
||||
field()->set_generic_signature_index(index);
|
||||
if (access_flags().field_has_generic_signature()) {
|
||||
assert(_generic_signature_slot < _fields->length(), "out of bounds");
|
||||
_fields->short_at_put(_generic_signature_slot, index);
|
||||
}
|
||||
}
|
||||
int initval_index() const {
|
||||
assert(!field()->is_internal(), "regular only");
|
||||
@ -159,8 +217,8 @@ class JavaFieldStream : public FieldStreamBase {
|
||||
// Iterate over only the internal fields
|
||||
class InternalFieldStream : public FieldStreamBase {
|
||||
public:
|
||||
InternalFieldStream(instanceKlass* k): FieldStreamBase(k->fields(), k->constants(), k->java_fields_count(), k->all_fields_count()) {}
|
||||
InternalFieldStream(instanceKlassHandle k): FieldStreamBase(k->fields(), k->constants(), k->java_fields_count(), k->all_fields_count()) {}
|
||||
InternalFieldStream(instanceKlass* k): FieldStreamBase(k->fields(), k->constants(), k->java_fields_count(), 0) {}
|
||||
InternalFieldStream(instanceKlassHandle k): FieldStreamBase(k->fields(), k->constants(), k->java_fields_count(), 0) {}
|
||||
};
|
||||
|
||||
|
||||
|
@ -168,8 +168,19 @@ class instanceKlass: public Klass {
|
||||
objArrayOop _local_interfaces;
|
||||
// Interface (klassOops) this class implements transitively.
|
||||
objArrayOop _transitive_interfaces;
|
||||
// Instance and static variable information, 5-tuples of shorts [access, name
|
||||
// index, sig index, initval index, offset].
|
||||
// Instance and static variable information, starts with 6-tuples of shorts
|
||||
// [access, name index, sig index, initval index, low_offset, high_offset]
|
||||
// for all fields, followed by the generic signature data at the end of
|
||||
// the array. Only fields with generic signature attributes have the generic
|
||||
// signature data set in the array. The fields array looks like following:
|
||||
//
|
||||
// f1: [access, name index, sig index, initial value index, low_offset, high_offset]
|
||||
// f2: [access, name index, sig index, initial value index, low_offset, high_offset]
|
||||
// ...
|
||||
// fn: [access, name index, sig index, initial value index, low_offset, high_offset]
|
||||
// [generic signature index]
|
||||
// [generic signature index]
|
||||
// ...
|
||||
typeArrayOop _fields;
|
||||
// Constant pool for this class.
|
||||
constantPoolOop _constants;
|
||||
@ -351,9 +362,6 @@ class instanceKlass: public Klass {
|
||||
// Number of Java declared fields
|
||||
int java_fields_count() const { return (int)_java_fields_count; }
|
||||
|
||||
// Number of fields including any injected fields
|
||||
int all_fields_count() const { return _fields->length() / FieldInfo::field_slots; }
|
||||
|
||||
typeArrayOop fields() const { return _fields; }
|
||||
|
||||
void set_fields(typeArrayOop f, u2 java_fields_count) {
|
||||
|
@ -515,6 +515,12 @@ bool instanceRefKlass::owns_pending_list_lock(JavaThread* thread) {
|
||||
void instanceRefKlass::acquire_pending_list_lock(BasicLock *pending_list_basic_lock) {
|
||||
// we may enter this with pending exception set
|
||||
PRESERVE_EXCEPTION_MARK; // exceptions are never thrown, needed for TRAPS argument
|
||||
|
||||
// Create a HandleMark in case we retry a GC multiple times.
|
||||
// Each time we attempt the GC, we allocate the handle below
|
||||
// to hold the pending list lock. We want to free this handle.
|
||||
HandleMark hm;
|
||||
|
||||
Handle h_lock(THREAD, java_lang_ref_Reference::pending_list_lock());
|
||||
ObjectSynchronizer::fast_enter(h_lock, pending_list_basic_lock, false, THREAD);
|
||||
assert(ObjectSynchronizer::current_thread_holds_lock(
|
||||
@ -527,7 +533,12 @@ void instanceRefKlass::release_and_notify_pending_list_lock(
|
||||
BasicLock *pending_list_basic_lock) {
|
||||
// we may enter this with pending exception set
|
||||
PRESERVE_EXCEPTION_MARK; // exceptions are never thrown, needed for TRAPS argument
|
||||
//
|
||||
|
||||
// Create a HandleMark in case we retry a GC multiple times.
|
||||
// Each time we attempt the GC, we allocate the handle below
|
||||
// to hold the pending list lock. We want to free this handle.
|
||||
HandleMark hm;
|
||||
|
||||
Handle h_lock(THREAD, java_lang_ref_Reference::pending_list_lock());
|
||||
assert(ObjectSynchronizer::current_thread_holds_lock(
|
||||
JavaThread::current(), h_lock),
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "memory/universe.inline.hpp"
|
||||
#include "oops/instanceKlass.hpp"
|
||||
#include "oops/fieldStreams.hpp"
|
||||
#include "runtime/fieldDescriptor.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
#include "runtime/signature.hpp"
|
||||
@ -37,6 +38,20 @@ oop fieldDescriptor::loader() const {
|
||||
return instanceKlass::cast(_cp->pool_holder())->class_loader();
|
||||
}
|
||||
|
||||
Symbol* fieldDescriptor::generic_signature() const {
|
||||
int idx = 0;
|
||||
instanceKlass* ik = instanceKlass::cast(field_holder());
|
||||
for (AllFieldStream fs(ik); !fs.done(); fs.next()) {
|
||||
if (idx == _index) {
|
||||
return fs.generic_signature();
|
||||
} else {
|
||||
idx ++;
|
||||
}
|
||||
}
|
||||
assert(false, "should never happen");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
typeArrayOop fieldDescriptor::annotations() const {
|
||||
instanceKlass* ik = instanceKlass::cast(field_holder());
|
||||
objArrayOop md = ik->fields_annotations();
|
||||
|
@ -67,7 +67,7 @@ class fieldDescriptor VALUE_OBJ_CLASS_SPEC {
|
||||
oop loader() const;
|
||||
// Offset (in words) of field from start of instanceOop / klassOop
|
||||
int offset() const { return field()->offset(); }
|
||||
Symbol* generic_signature() const { return field()->generic_signature(_cp); }
|
||||
Symbol* generic_signature() const;
|
||||
int index() const { return _index; }
|
||||
typeArrayOop annotations() const;
|
||||
|
||||
|
@ -3285,9 +3285,6 @@ class CommandLineFlags {
|
||||
diagnostic(intx, VerifyGCLevel, 0, \
|
||||
"Generation level at which to start +VerifyBefore/AfterGC") \
|
||||
\
|
||||
develop(uintx, ExitAfterGCNum, 0, \
|
||||
"If non-zero, exit after this GC.") \
|
||||
\
|
||||
product(intx, MaxTenuringThreshold, 15, \
|
||||
"Maximum value for tenuring threshold") \
|
||||
\
|
||||
|
@ -61,7 +61,6 @@ enum ThreadState {
|
||||
class OSThread: public CHeapObj {
|
||||
friend class VMStructs;
|
||||
private:
|
||||
//void* _start_proc; // Thread start routine
|
||||
OSThreadStartFunc _start_proc; // Thread start routine
|
||||
void* _start_parm; // Thread start routine parameter
|
||||
volatile ThreadState _state; // Thread state *hint*
|
||||
@ -77,10 +76,7 @@ class OSThread: public CHeapObj {
|
||||
void set_state(ThreadState state) { _state = state; }
|
||||
ThreadState get_state() { return _state; }
|
||||
|
||||
// Constructor
|
||||
OSThread(OSThreadStartFunc start_proc, void* start_parm);
|
||||
|
||||
// Destructor
|
||||
~OSThread();
|
||||
|
||||
// Accessors
|
||||
@ -98,7 +94,6 @@ class OSThread: public CHeapObj {
|
||||
|
||||
// For java intrinsics:
|
||||
static ByteSize interrupted_offset() { return byte_offset_of(OSThread, _interrupted); }
|
||||
static ByteSize thread_id_offset() { return byte_offset_of(OSThread, _thread_id); }
|
||||
|
||||
// Platform dependent stuff
|
||||
#ifdef TARGET_OS_FAMILY_linux
|
||||
@ -114,6 +109,19 @@ class OSThread: public CHeapObj {
|
||||
# include "osThread_bsd.hpp"
|
||||
#endif
|
||||
|
||||
public:
|
||||
static ByteSize thread_id_offset() { return byte_offset_of(OSThread, _thread_id); }
|
||||
static size_t thread_id_size() { return sizeof(thread_id_t); }
|
||||
|
||||
thread_id_t thread_id() const { return _thread_id; }
|
||||
|
||||
void set_thread_id(thread_id_t id) { _thread_id = id; }
|
||||
|
||||
private:
|
||||
// _thread_id is kernel thread id (similar to LWP id on Solaris). Each
|
||||
// thread has a unique thread_id (BsdThreads or NPTL). It can be used
|
||||
// to access /proc.
|
||||
thread_id_t _thread_id;
|
||||
};
|
||||
|
||||
|
||||
|
@ -2352,7 +2352,6 @@ static inline uint64_t cast_uint64_t(size_t x)
|
||||
declare_constant(FieldInfo::initval_index_offset) \
|
||||
declare_constant(FieldInfo::low_offset) \
|
||||
declare_constant(FieldInfo::high_offset) \
|
||||
declare_constant(FieldInfo::generic_signature_offset) \
|
||||
declare_constant(FieldInfo::field_slots) \
|
||||
\
|
||||
/************************************************/ \
|
||||
|
@ -80,10 +80,12 @@ enum {
|
||||
JVM_ACC_FIELD_ACCESS_WATCHED = 0x00002000, // field access is watched by JVMTI
|
||||
JVM_ACC_FIELD_MODIFICATION_WATCHED = 0x00008000, // field modification is watched by JVMTI
|
||||
JVM_ACC_FIELD_INTERNAL = 0x00000400, // internal field, same as JVM_ACC_ABSTRACT
|
||||
JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE = 0x00000800, // field has generic signature
|
||||
|
||||
JVM_ACC_FIELD_INTERNAL_FLAGS = JVM_ACC_FIELD_ACCESS_WATCHED |
|
||||
JVM_ACC_FIELD_MODIFICATION_WATCHED |
|
||||
JVM_ACC_FIELD_INTERNAL,
|
||||
JVM_ACC_FIELD_INTERNAL |
|
||||
JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE,
|
||||
|
||||
// flags accepted by set_field_flags()
|
||||
JVM_ACC_FIELD_FLAGS = JVM_RECOGNIZED_FIELD_MODIFIERS | JVM_ACC_FIELD_INTERNAL_FLAGS
|
||||
@ -156,6 +158,8 @@ class AccessFlags VALUE_OBJ_CLASS_SPEC {
|
||||
bool is_field_modification_watched() const
|
||||
{ return (_flags & JVM_ACC_FIELD_MODIFICATION_WATCHED) != 0; }
|
||||
bool is_internal() const { return (_flags & JVM_ACC_FIELD_INTERNAL) != 0; }
|
||||
bool field_has_generic_signature() const
|
||||
{ return (_flags & JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE) != 0; }
|
||||
|
||||
// get .class file flags
|
||||
jint get_flags () const { return (_flags & JVM_ACC_WRITTEN_FLAGS); }
|
||||
@ -225,6 +229,10 @@ class AccessFlags VALUE_OBJ_CLASS_SPEC {
|
||||
atomic_clear_bits(JVM_ACC_FIELD_MODIFICATION_WATCHED);
|
||||
}
|
||||
}
|
||||
void set_field_has_generic_signature()
|
||||
{
|
||||
atomic_set_bits(JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE);
|
||||
}
|
||||
|
||||
// Conversion
|
||||
jshort as_short() const { return (jshort)_flags; }
|
||||
|
@ -161,10 +161,6 @@ const size_t M = K*K;
|
||||
const size_t G = M*K;
|
||||
const size_t HWperKB = K / sizeof(HeapWord);
|
||||
|
||||
const size_t LOG_K = 10;
|
||||
const size_t LOG_M = 2 * LOG_K;
|
||||
const size_t LOG_G = 2 * LOG_M;
|
||||
|
||||
const jint min_jint = (jint)1 << (sizeof(jint)*BitsPerByte-1); // 0x80000000 == smallest jint
|
||||
const jint max_jint = (juint)min_jint - 1; // 0x7FFFFFFF == largest jint
|
||||
|
||||
|
@ -115,24 +115,6 @@ bool NumberSeq::check_nums(NumberSeq *total, int n, NumberSeq **parts) {
|
||||
return true;
|
||||
}
|
||||
|
||||
NumberSeq::NumberSeq(NumberSeq *total, int n, NumberSeq **parts) {
|
||||
guarantee(check_nums(total, n, parts), "all seq lengths should match");
|
||||
double sum = total->sum();
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (parts[i] != NULL)
|
||||
sum -= parts[i]->sum();
|
||||
}
|
||||
|
||||
_num = total->num();
|
||||
_sum = sum;
|
||||
|
||||
// we do not calculate these...
|
||||
_sum_of_squares = -1.0;
|
||||
_maximum = -1.0;
|
||||
_davg = -1.0;
|
||||
_dvariance = -1.0;
|
||||
}
|
||||
|
||||
void NumberSeq::add(double val) {
|
||||
AbsSeq::add(val);
|
||||
|
||||
|
@ -93,7 +93,6 @@ protected:
|
||||
|
||||
public:
|
||||
NumberSeq(double alpha = DEFAULT_ALPHA_VALUE);
|
||||
NumberSeq(NumberSeq* total, int n_parts, NumberSeq** parts);
|
||||
|
||||
virtual void add(double val);
|
||||
virtual double maximum() const { return _maximum; }
|
||||
|
74
hotspot/test/gc/7168848/HumongousAlloc.java
Normal file
74
hotspot/test/gc/7168848/HumongousAlloc.java
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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 Humongous.java
|
||||
* @bug 7168848
|
||||
* @summary G1: humongous object allocations should initiate marking cycles when necessary
|
||||
* @run main/othervm -Xms100m -Xmx100m -XX:+PrintGC -XX:G1HeapRegionSize=1m -XX:+UseG1GC HumongousAlloc
|
||||
*
|
||||
*/
|
||||
import java.lang.management.GarbageCollectorMXBean;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.util.List;
|
||||
|
||||
public class HumongousAlloc {
|
||||
|
||||
public static byte[] dummy;
|
||||
private static int sleepFreq = 40;
|
||||
private static int sleepTime = 1000;
|
||||
private static double size = 0.75;
|
||||
private static int iterations = 50;
|
||||
private static int MB = 1024 * 1024;
|
||||
|
||||
public static void allocate(int size, int sleepTime, int sleepFreq) throws InterruptedException {
|
||||
System.out.println("Will allocate objects of size: " + size
|
||||
+ " bytes and sleep for " + sleepTime
|
||||
+ " ms after every " + sleepFreq + "th allocation.");
|
||||
int count = 0;
|
||||
while (count < iterations) {
|
||||
for (int i = 0; i < sleepFreq; i++) {
|
||||
dummy = new byte[size - 16];
|
||||
}
|
||||
Thread.sleep(sleepTime);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
allocate((int) (size * MB), sleepTime, sleepFreq);
|
||||
List<GarbageCollectorMXBean> collectors = ManagementFactory.getGarbageCollectorMXBeans();
|
||||
for (GarbageCollectorMXBean collector : collectors) {
|
||||
if (collector.getName().contains("G1 Old")) {
|
||||
long count = collector.getCollectionCount();
|
||||
if (count > 0) {
|
||||
throw new RuntimeException("Failed: FullGCs should not have happened. The number of FullGC run is " + count);
|
||||
}
|
||||
else {
|
||||
System.out.println("Passed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user