mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-05 07:58:40 +00:00
Merge
This commit is contained in:
commit
0ca96a4047
@ -442,3 +442,4 @@ af46576a8d7cb4003028b8ee8bf408cfe227315b jdk9-b32
|
||||
b1c2dd843f247a1db19e1e85eb62ca405f72dc26 jdk9-b37
|
||||
c363a8b87e477ee45d6d3cb2a36cb365141bc596 jdk9-b38
|
||||
9cb75e5e394827ccbaf2e15524108a412dc4ddc5 jdk9-b39
|
||||
6b09b3193d731e3288e2a240c504a20d0a06c766 jdk9-b40
|
||||
|
||||
@ -219,7 +219,7 @@ public class OopUtilities implements /* imports */ JVMTIThreadState {
|
||||
if (threadNameField == null) {
|
||||
SystemDictionary sysDict = VM.getVM().getSystemDictionary();
|
||||
InstanceKlass k = sysDict.getThreadKlass();
|
||||
threadNameField = (OopField) k.findField("name", "[C");
|
||||
threadNameField = (OopField) k.findField("name", "Ljava/lang/String;");
|
||||
threadGroupField = (OopField) k.findField("group", "Ljava/lang/ThreadGroup;");
|
||||
threadEETopField = (LongField) k.findField("eetop", "J");
|
||||
threadTIDField = (LongField) k.findField("tid", "J");
|
||||
@ -258,7 +258,7 @@ public class OopUtilities implements /* imports */ JVMTIThreadState {
|
||||
|
||||
public static String threadOopGetName(Oop threadOop) {
|
||||
initThreadFields();
|
||||
return charArrayToString((TypeArray) threadNameField.getValue(threadOop));
|
||||
return stringOopToString(threadNameField.getValue(threadOop));
|
||||
}
|
||||
|
||||
/** May return null if, e.g., thread was not started */
|
||||
|
||||
@ -40,6 +40,8 @@ AGENT_DIR = $(GAMMADIR)/agent
|
||||
|
||||
include $(GAMMADIR)/make/sa.files
|
||||
|
||||
-include $(HS_ALT_MAKE)/bsd/makefiles/sa.make
|
||||
|
||||
TOPDIR = $(shell echo `pwd`)
|
||||
GENERATED = $(TOPDIR)/../generated
|
||||
|
||||
|
||||
@ -214,7 +214,7 @@ ifeq ($(USE_CLANG), true)
|
||||
WARNINGS_ARE_ERRORS += -Wno-return-type -Wno-empty-body
|
||||
endif
|
||||
|
||||
WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef -Wunused-function -Wunused-value -Wformat=2
|
||||
WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef -Wunused-function -Wunused-value -Wformat=2 -Wreturn-type
|
||||
|
||||
ifeq ($(USE_CLANG),)
|
||||
# Since GCC 4.3, -Wconversion has changed its meanings to warn these implicit
|
||||
|
||||
@ -1,54 +0,0 @@
|
||||
#
|
||||
# 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 add_gnu_debuglink, used by vm.make on Solaris
|
||||
|
||||
# Allow $(ADD_GNU_DEBUGLINK) to be called from any directory.
|
||||
# We don't set or use the GENERATED macro to avoid affecting
|
||||
# other HotSpot Makefiles.
|
||||
TOPDIR = $(shell echo `pwd`)
|
||||
ADD_GNU_DEBUGLINK = $(TOPDIR)/../generated/add_gnu_debuglink
|
||||
|
||||
ADD_GNU_DEBUGLINK_DIR = $(GAMMADIR)/src/os/solaris/add_gnu_debuglink
|
||||
ADD_GNU_DEBUGLINK_SRC = $(ADD_GNU_DEBUGLINK_DIR)/add_gnu_debuglink.c
|
||||
ADD_GNU_DEBUGLINK_FLAGS =
|
||||
LIBS_ADD_GNU_DEBUGLINK += -lelf
|
||||
|
||||
ifeq ("${Platform_compiler}", "sparcWorks")
|
||||
# Enable the following ADD_GNU_DEBUGLINK_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.
|
||||
#ADD_GNU_DEBUGLINK_FLAGS += -W0,-noglobal
|
||||
endif # Platform_compiler == sparcWorks
|
||||
|
||||
$(ADD_GNU_DEBUGLINK): $(ADD_GNU_DEBUGLINK_SRC)
|
||||
$(CC) -g -o $@ $< $(ADD_GNU_DEBUGLINK_FLAGS) $(LIBS_ADD_GNU_DEBUGLINK)
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -138,6 +138,55 @@ ifeq ($(JDK6_OR_EARLIER),0)
|
||||
OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY))
|
||||
endif
|
||||
|
||||
ifneq ($(OBJCOPY),)
|
||||
# OBJCOPY version check:
|
||||
# - version number is last blank separate word on first line
|
||||
# - version number formats that have been seen:
|
||||
# - <major>.<minor>
|
||||
# - <major>.<minor>.<micro>
|
||||
#
|
||||
# Full Debug Symbols on Solaris needs version 2.21.1 or newer.
|
||||
#
|
||||
OBJCOPY_VERS_CHK := $(shell \
|
||||
$(OBJCOPY) --version \
|
||||
| sed -n \
|
||||
-e 's/.* //' \
|
||||
-e '/^[01]\./b bad' \
|
||||
-e '/^2\./{' \
|
||||
-e ' s/^2\.//' \
|
||||
-e ' /^[0-9]$$/b bad' \
|
||||
-e ' /^[0-9]\./b bad' \
|
||||
-e ' /^1[0-9]$$/b bad' \
|
||||
-e ' /^1[0-9]\./b bad' \
|
||||
-e ' /^20\./b bad' \
|
||||
-e ' /^21\.0$$/b bad' \
|
||||
-e ' /^21\.0\./b bad' \
|
||||
-e '}' \
|
||||
-e ':good' \
|
||||
-e 's/.*/VALID_VERSION/p' \
|
||||
-e 'q' \
|
||||
-e ':bad' \
|
||||
-e 's/.*/BAD_VERSION/p' \
|
||||
-e 'q' \
|
||||
)
|
||||
ifeq ($(OBJCOPY_VERS_CHK),BAD_VERSION)
|
||||
_JUNK_ := $(shell \
|
||||
echo >&2 "WARNING: $(OBJCOPY) --version info:"; \
|
||||
$(OBJCOPY) --version | sed -n -e 's/^/WARNING: /p' -e 'q' >&2; \
|
||||
echo >&2 "WARNING: an objcopy version of 2.21.1 or newer" \
|
||||
"is needed to create valid .debuginfo files."; \
|
||||
echo >&2 "WARNING: ignoring above objcopy command."; \
|
||||
echo >&2 "WARNING: patch 149063-01 or newer contains the" \
|
||||
"correct Solaris 10 SPARC version."; \
|
||||
echo >&2 "WARNING: patch 149064-01 or newer contains the" \
|
||||
"correct Solaris 10 X86 version."; \
|
||||
echo >&2 "WARNING: Solaris 11 Update 1 contains the" \
|
||||
"correct version."; \
|
||||
)
|
||||
OBJCOPY=
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(OBJCOPY),)
|
||||
$(eval $(call print_info, "no objcopy cmd found so cannot create .debuginfo files."))
|
||||
ENABLE_FULL_DEBUG_SYMBOLS=0
|
||||
|
||||
@ -101,25 +101,16 @@ XLIBJVM_DB_DIZ = $(XLIBJVM_DIR)/$(LIBJVM_DB_DIZ)
|
||||
XLIBJVM_DTRACE_DEBUGINFO = $(XLIBJVM_DIR)/$(LIBJVM_DTRACE_DEBUGINFO)
|
||||
XLIBJVM_DTRACE_DIZ = $(XLIBJVM_DIR)/$(LIBJVM_DTRACE_DIZ)
|
||||
|
||||
$(XLIBJVM_DB): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE)
|
||||
$(XLIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE)
|
||||
@echo $(LOG_INFO) Making $@
|
||||
$(QUIETLY) mkdir -p $(XLIBJVM_DIR) ; \
|
||||
$(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. -I$(GENERATED) \
|
||||
$(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc
|
||||
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)
|
||||
# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
|
||||
# Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available.
|
||||
# $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DB_DEBUGINFO) $(LIBJVM_DB) ;
|
||||
# Do this part in the $(XLIBJVM_DIR) subdir so $(XLIBJVM_DIR) is not
|
||||
# in the link name:
|
||||
( cd $(XLIBJVM_DIR) && $(ADD_GNU_DEBUGLINK) $(LIBJVM_DB_DEBUGINFO) $(LIBJVM_DB) )
|
||||
( cd $(XLIBJVM_DIR) && $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DB_DEBUGINFO) $(LIBJVM_DB) )
|
||||
ifeq ($(STRIP_POLICY),all_strip)
|
||||
$(QUIETLY) $(STRIP) $@
|
||||
else
|
||||
@ -136,20 +127,16 @@ ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
|
||||
endif
|
||||
endif
|
||||
|
||||
$(XLIBJVM_DTRACE): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
|
||||
$(XLIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
|
||||
@echo $(LOG_INFO) Making $@
|
||||
$(QUIETLY) mkdir -p $(XLIBJVM_DIR) ; \
|
||||
$(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. \
|
||||
$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
|
||||
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)
|
||||
# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
|
||||
# $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DTRACE_DEBUGINFO) $(LIBJVM_DTRACE) ;
|
||||
# Do this part in the $(XLIBJVM_DIR) subdir so $(XLIBJVM_DIR) is not
|
||||
# in the link name:
|
||||
( cd $(XLIBJVM_DIR) && $(ADD_GNU_DEBUGLINK) $(LIBJVM_DTRACE_DEBUGINFO) $(LIBJVM_DTRACE) )
|
||||
( cd $(XLIBJVM_DIR) && $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DTRACE_DEBUGINFO) $(LIBJVM_DTRACE) )
|
||||
ifeq ($(STRIP_POLICY),all_strip)
|
||||
$(QUIETLY) $(STRIP) $@
|
||||
else
|
||||
@ -206,17 +193,13 @@ $(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): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS.o) $(XLIBJVM_DB) $(LIBJVM_DB_MAPFILE)
|
||||
$(LIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS.o) $(XLIBJVM_DB) $(LIBJVM_DB_MAPFILE)
|
||||
@echo $(LOG_INFO) Making $@
|
||||
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. -I$(GENERATED) \
|
||||
$(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc
|
||||
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)
|
||||
# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
|
||||
# $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DB_DEBUGINFO) $@
|
||||
$(QUIETLY) $(ADD_GNU_DEBUGLINK) $(LIBJVM_DB_DEBUGINFO) $@
|
||||
$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DB_DEBUGINFO) $@
|
||||
ifeq ($(STRIP_POLICY),all_strip)
|
||||
$(QUIETLY) $(STRIP) $@
|
||||
else
|
||||
@ -231,17 +214,13 @@ ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
|
||||
endif
|
||||
endif
|
||||
|
||||
$(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)
|
||||
$(LIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(XLIBJVM_DTRACE) $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
|
||||
@echo $(LOG_INFO) Making $@
|
||||
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. \
|
||||
$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
|
||||
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)
|
||||
# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
|
||||
# $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DTRACE_DEBUGINFO) $@
|
||||
$(QUIETLY) $(ADD_GNU_DEBUGLINK) $(LIBJVM_DTRACE_DEBUGINFO) $@
|
||||
$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DTRACE_DEBUGINFO) $@
|
||||
ifeq ($(STRIP_POLICY),all_strip)
|
||||
$(QUIETLY) $(STRIP) $@
|
||||
else
|
||||
|
||||
@ -1,54 +0,0 @@
|
||||
#
|
||||
# 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
|
||||
|
||||
# Allow $(FIX_EMPTY_SEC_HDR_FLAGS) to be called from any directory.
|
||||
# We don't set or use the GENERATED macro to avoid affecting
|
||||
# other HotSpot Makefiles.
|
||||
TOPDIR = $(shell echo `pwd`)
|
||||
FIX_EMPTY_SEC_HDR_FLAGS = $(TOPDIR)/../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)
|
||||
@ -47,22 +47,13 @@ else
|
||||
LFLAGS_JSIG += -mt -xnolib
|
||||
endif
|
||||
|
||||
$(LIBJSIG): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE)
|
||||
$(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE)
|
||||
@echo $(LOG_INFO) Making signal interposition lib...
|
||||
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \
|
||||
$(LFLAGS_JSIG) -o $@ $(JSIGSRCDIR)/jsig.c -ldl
|
||||
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)
|
||||
# $(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) $@
|
||||
$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJSIG_DEBUGINFO) $@
|
||||
ifeq ($(STRIP_POLICY),all_strip)
|
||||
$(QUIETLY) $(STRIP) $@
|
||||
else
|
||||
|
||||
@ -90,7 +90,7 @@ $(shell uname -r -v \
|
||||
#SOLARIS_11_B159_OR_LATER=-DSOLARIS_11_B159_OR_LATER
|
||||
|
||||
|
||||
$(LIBSAPROC): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(SASRCFILES) $(SADISOBJ) $(SAMAPFILE)
|
||||
$(LIBSAPROC): $(SASRCFILES) $(SADISOBJ) $(SAMAPFILE)
|
||||
$(QUIETLY) if [ "$(BOOT_JAVA_HOME)" = "" ]; then \
|
||||
echo "ALT_BOOTDIR, BOOTDIR or JAVA_HOME needs to be defined to build SA"; \
|
||||
exit 1; \
|
||||
@ -121,17 +121,8 @@ $(SADISOBJ): $(SADISSRCFILES)
|
||||
-c -o $(SADISOBJ)
|
||||
|
||||
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)
|
||||
# $(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) $@
|
||||
$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBSAPROC_DEBUGINFO) $@
|
||||
ifeq ($(STRIP_POLICY),all_strip)
|
||||
$(QUIETLY) $(STRIP) $@
|
||||
else
|
||||
|
||||
@ -154,14 +154,6 @@ JDK_LIBDIR = $(JAVA_HOME)/jre/lib/$(LIBARCH)
|
||||
# jvm_db & dtrace
|
||||
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
|
||||
|
||||
@ -302,7 +294,7 @@ else
|
||||
LINK_VM = $(LINK_LIB.CXX)
|
||||
endif
|
||||
# making the library:
|
||||
$(LIBJVM): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(LIBJVM.o) $(LIBJVM_MAPFILE)
|
||||
$(LIBJVM): $(LIBJVM.o) $(LIBJVM_MAPFILE)
|
||||
ifeq ($(filter -sbfast -xsbfast, $(CFLAGS_BROWSE)),)
|
||||
@echo $(LOG_INFO) Linking vm...
|
||||
$(QUIETLY) $(LINK_LIB.CXX/PRE_HOOK)
|
||||
@ -310,17 +302,8 @@ ifeq ($(filter -sbfast -xsbfast, $(CFLAGS_BROWSE)),)
|
||||
$(QUIETLY) $(LINK_LIB.CXX/POST_HOOK)
|
||||
$(QUIETLY) rm -f $@.1 && ln -s $@ $@.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 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) $@
|
||||
$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DEBUGINFO) $@
|
||||
ifeq ($(STRIP_POLICY),all_strip)
|
||||
$(QUIETLY) $(STRIP) $@
|
||||
else
|
||||
|
||||
@ -89,19 +89,24 @@ AGCT_EXPORT=/export:AsyncGetCallTrace
|
||||
|
||||
# If you modify exports below please do the corresponding changes in
|
||||
# src/share/tools/ProjectCreator/WinGammaPlatformVC7.java
|
||||
LD_FLAGS=$(LD_FLAGS) $(STACK_SIZE) /subsystem:windows /dll /base:0x8000000 \
|
||||
/export:JNI_GetDefaultJavaVMInitArgs \
|
||||
/export:JNI_CreateJavaVM \
|
||||
/export:JVM_FindClassFromBootLoader \
|
||||
/export:JNI_GetCreatedJavaVMs \
|
||||
/export:jio_snprintf \
|
||||
/export:jio_printf \
|
||||
/export:jio_fprintf \
|
||||
/export:jio_vfprintf \
|
||||
/export:jio_vsnprintf \
|
||||
$(AGCT_EXPORT) \
|
||||
/export:JVM_GetVersionInfo \
|
||||
/export:JVM_InitAgentProperties
|
||||
!if "$(BUILDARCH)" == "amd64"
|
||||
EXPORT_LIST=
|
||||
!else
|
||||
EXPORT_LIST=/export:JNI_GetDefaultJavaVMInitArgs \
|
||||
/export:JNI_CreateJavaVM \
|
||||
/export:JVM_FindClassFromBootLoader \
|
||||
/export:JNI_GetCreatedJavaVMs \
|
||||
/export:jio_snprintf \
|
||||
/export:jio_printf \
|
||||
/export:jio_fprintf \
|
||||
/export:jio_vfprintf \
|
||||
/export:jio_vsnprintf \
|
||||
$(AGCT_EXPORT) \
|
||||
/export:JVM_GetVersionInfo \
|
||||
/export:JVM_InitAgentProperties
|
||||
!endif
|
||||
|
||||
LD_FLAGS=$(LD_FLAGS) $(STACK_SIZE) /subsystem:windows /dll /base:0x8000000 $(EXPORT_LIST)
|
||||
|
||||
CXX_INCLUDE_DIRS=/I "..\generated"
|
||||
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#define CPU_PPC_VM_MACROASSEMBLER_PPC_HPP
|
||||
|
||||
#include "asm/assembler.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
// MacroAssembler extends Assembler by a few frequently used macros.
|
||||
|
||||
|
||||
@ -4813,6 +4813,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
StubRoutines::_atomic_add_entry = generate_atomic_add();
|
||||
StubRoutines::_atomic_xchg_ptr_entry = StubRoutines::_atomic_xchg_entry;
|
||||
StubRoutines::_atomic_cmpxchg_ptr_entry = StubRoutines::_atomic_cmpxchg_entry;
|
||||
StubRoutines::_atomic_cmpxchg_byte_entry = ShouldNotCallThisStub();
|
||||
StubRoutines::_atomic_cmpxchg_long_entry = generate_atomic_cmpxchg_long();
|
||||
StubRoutines::_atomic_add_ptr_entry = StubRoutines::_atomic_add_entry;
|
||||
#endif // COMPILER2 !=> _LP64
|
||||
|
||||
@ -1297,6 +1297,17 @@ void Assembler::cmpxchgl(Register reg, Address adr) { // cmpxchg
|
||||
emit_operand(reg, adr);
|
||||
}
|
||||
|
||||
// The 8-bit cmpxchg compares the value at adr with the contents of rax,
|
||||
// and stores reg into adr if so; otherwise, the value at adr is loaded into rax,.
|
||||
// The ZF is set if the compared values were equal, and cleared otherwise.
|
||||
void Assembler::cmpxchgb(Register reg, Address adr) { // cmpxchg
|
||||
InstructionMark im(this);
|
||||
prefix(adr, reg, true);
|
||||
emit_int8(0x0F);
|
||||
emit_int8((unsigned char)0xB0);
|
||||
emit_operand(reg, adr);
|
||||
}
|
||||
|
||||
void Assembler::comisd(XMMRegister dst, Address src) {
|
||||
// NOTE: dbx seems to decode this as comiss even though the
|
||||
// 0x66 is there. Strangly ucomisd comes out correct
|
||||
|
||||
@ -1006,6 +1006,7 @@ private:
|
||||
|
||||
void cmpxchg8 (Address adr);
|
||||
|
||||
void cmpxchgb(Register reg, Address adr);
|
||||
void cmpxchgl(Register reg, Address adr);
|
||||
|
||||
void cmpxchgq(Register reg, Address adr);
|
||||
|
||||
@ -594,9 +594,35 @@ class StubGenerator: public StubCodeGenerator {
|
||||
return start;
|
||||
}
|
||||
|
||||
// Support for jint atomic::atomic_cmpxchg_long(jlong exchange_value,
|
||||
// volatile jlong* dest,
|
||||
// jlong compare_value)
|
||||
// Support for jbyte atomic::atomic_cmpxchg(jbyte exchange_value, volatile jbyte* dest,
|
||||
// jbyte compare_value)
|
||||
//
|
||||
// Arguments :
|
||||
// c_rarg0: exchange_value
|
||||
// c_rarg1: dest
|
||||
// c_rarg2: compare_value
|
||||
//
|
||||
// Result:
|
||||
// if ( compare_value == *dest ) {
|
||||
// *dest = exchange_value
|
||||
// return compare_value;
|
||||
// else
|
||||
// return *dest;
|
||||
address generate_atomic_cmpxchg_byte() {
|
||||
StubCodeMark mark(this, "StubRoutines", "atomic_cmpxchg_byte");
|
||||
address start = __ pc();
|
||||
|
||||
__ movsbq(rax, c_rarg2);
|
||||
if ( os::is_MP() ) __ lock();
|
||||
__ cmpxchgb(c_rarg0, Address(c_rarg1, 0));
|
||||
__ ret(0);
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
// Support for jlong atomic::atomic_cmpxchg(jlong exchange_value,
|
||||
// volatile jlong* dest,
|
||||
// jlong compare_value)
|
||||
// Arguments :
|
||||
// c_rarg0: exchange_value
|
||||
// c_rarg1: dest
|
||||
@ -3894,6 +3920,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
StubRoutines::_atomic_xchg_entry = generate_atomic_xchg();
|
||||
StubRoutines::_atomic_xchg_ptr_entry = generate_atomic_xchg_ptr();
|
||||
StubRoutines::_atomic_cmpxchg_entry = generate_atomic_cmpxchg();
|
||||
StubRoutines::_atomic_cmpxchg_byte_entry = generate_atomic_cmpxchg_byte();
|
||||
StubRoutines::_atomic_cmpxchg_long_entry = generate_atomic_cmpxchg_long();
|
||||
StubRoutines::_atomic_add_entry = generate_atomic_add();
|
||||
StubRoutines::_atomic_add_ptr_entry = generate_atomic_add_ptr();
|
||||
|
||||
@ -1210,6 +1210,7 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bo
|
||||
|
||||
|
||||
Unimplemented();
|
||||
return 0; // Mute compiler
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
@ -30,7 +30,9 @@
|
||||
|
||||
int ZeroStack::suggest_size(Thread *thread) const {
|
||||
assert(needs_setup(), "already set up");
|
||||
return align_size_down(abi_stack_available(thread) / 2, wordSize);
|
||||
int abi_available = abi_stack_available(thread);
|
||||
assert(abi_available >= 0, "available abi stack must be >= 0");
|
||||
return align_size_down(abi_available / 2, wordSize);
|
||||
}
|
||||
|
||||
void ZeroStack::handle_overflow(TRAPS) {
|
||||
|
||||
@ -48,9 +48,11 @@ inline void ZeroStack::overflow_check(int required_words, TRAPS) {
|
||||
// to use under normal circumstances. Note that the returned
|
||||
// value can be negative.
|
||||
inline int ZeroStack::abi_stack_available(Thread *thread) const {
|
||||
int stack_used = thread->stack_base() - (address) &stack_used;
|
||||
guarantee(Thread::current() == thread, "should run in the same thread");
|
||||
int stack_used = thread->stack_base() - (address) &stack_used
|
||||
+ (StackYellowPages+StackRedPages+StackShadowPages) * os::vm_page_size();
|
||||
int stack_free = thread->stack_size() - stack_used;
|
||||
return stack_free - shadow_pages_size();
|
||||
return stack_free;
|
||||
}
|
||||
|
||||
#endif // CPU_ZERO_VM_STACK_ZERO_INLINE_HPP
|
||||
|
||||
@ -207,6 +207,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
StubRoutines::_atomic_xchg_ptr_entry = ShouldNotCallThisStub();
|
||||
StubRoutines::_atomic_cmpxchg_entry = ShouldNotCallThisStub();
|
||||
StubRoutines::_atomic_cmpxchg_ptr_entry = ShouldNotCallThisStub();
|
||||
StubRoutines::_atomic_cmpxchg_byte_entry = ShouldNotCallThisStub();
|
||||
StubRoutines::_atomic_cmpxchg_long_entry = ShouldNotCallThisStub();
|
||||
StubRoutines::_atomic_add_entry = ShouldNotCallThisStub();
|
||||
StubRoutines::_atomic_add_ptr_entry = ShouldNotCallThisStub();
|
||||
|
||||
@ -107,6 +107,12 @@
|
||||
#include <sys/vminfo.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
// If RUSAGE_THREAD for getrusage() has not been defined, do it here. The code calling
|
||||
// getrusage() is prepared to handle the associated failure.
|
||||
#ifndef RUSAGE_THREAD
|
||||
#define RUSAGE_THREAD (1) /* only the calling thread */
|
||||
#endif
|
||||
|
||||
// Add missing declarations (should be in procinfo.h but isn't until AIX 6.1).
|
||||
#if !defined(_AIXVERSION_610)
|
||||
extern "C" {
|
||||
@ -1072,15 +1078,19 @@ jlong os::elapsed_frequency() {
|
||||
return (1000 * 1000);
|
||||
}
|
||||
|
||||
// For now, we say that linux does not support vtime. I have no idea
|
||||
// whether it can actually be made to (DLD, 9/13/05).
|
||||
|
||||
bool os::supports_vtime() { return false; }
|
||||
bool os::supports_vtime() { return true; }
|
||||
bool os::enable_vtime() { return false; }
|
||||
bool os::vtime_enabled() { return false; }
|
||||
|
||||
double os::elapsedVTime() {
|
||||
// better than nothing, but not much
|
||||
return elapsedTime();
|
||||
struct rusage usage;
|
||||
int retval = getrusage(RUSAGE_THREAD, &usage);
|
||||
if (retval == 0) {
|
||||
return usage.ru_utime.tv_sec + usage.ru_stime.tv_sec + (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec) / (1000.0 * 1000);
|
||||
} else {
|
||||
// better than nothing, but not much
|
||||
return elapsedTime();
|
||||
}
|
||||
}
|
||||
|
||||
jlong os::javaTimeMillis() {
|
||||
|
||||
@ -422,7 +422,7 @@ static char* get_user_name_slow(int vmid, TRAPS) {
|
||||
// return the name of the user that owns the JVM indicated by the given vmid.
|
||||
//
|
||||
static char* get_user_name(int vmid, TRAPS) {
|
||||
return get_user_name_slow(vmid, CHECK_NULL);
|
||||
return get_user_name_slow(vmid, THREAD);
|
||||
}
|
||||
|
||||
// return the file name of the backing store file for the named
|
||||
|
||||
@ -422,7 +422,7 @@ static char* get_user_name_slow(int vmid, TRAPS) {
|
||||
// return the name of the user that owns the JVM indicated by the given vmid.
|
||||
//
|
||||
static char* get_user_name(int vmid, TRAPS) {
|
||||
return get_user_name_slow(vmid, CHECK_NULL);
|
||||
return get_user_name_slow(vmid, THREAD);
|
||||
}
|
||||
|
||||
// return the file name of the backing store file for the named
|
||||
|
||||
@ -68,6 +68,7 @@
|
||||
#include "utilities/events.hpp"
|
||||
#include "utilities/elfFile.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include "utilities/vmError.hpp"
|
||||
|
||||
// put OS-includes here
|
||||
|
||||
@ -422,7 +422,7 @@ static char* get_user_name_slow(int vmid, TRAPS) {
|
||||
// return the name of the user that owns the JVM indicated by the given vmid.
|
||||
//
|
||||
static char* get_user_name(int vmid, TRAPS) {
|
||||
return get_user_name_slow(vmid, CHECK_NULL);
|
||||
return get_user_name_slow(vmid, THREAD);
|
||||
}
|
||||
|
||||
// return the file name of the backing store file for the named
|
||||
|
||||
@ -1,285 +0,0 @@
|
||||
/*
|
||||
* 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: add_gnu_debuglink.c
|
||||
*
|
||||
* Description: Add a ".gnu_debuglink" section that refers to the specified
|
||||
* debug_info_path to the specified ELF object.
|
||||
*
|
||||
* This program is adapted from the example program shown on the
|
||||
* elf(3elf) man page and from code from the Solaris compiler
|
||||
* driver.
|
||||
*/
|
||||
|
||||
/*
|
||||
* needed to define SHF_EXCLUDE
|
||||
*/
|
||||
#define ELF_TARGET_ALL
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <libelf.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static void failure(void);
|
||||
static unsigned int gnu_debuglink_crc32(unsigned int crc, unsigned char *buf,
|
||||
size_t len);
|
||||
|
||||
void
|
||||
main(int argc, char ** argv) {
|
||||
/* new ELF section name */
|
||||
static char SEC_NAME[] = ".gnu_debuglink";
|
||||
|
||||
unsigned char buffer[8 * 1024]; /* I/O buffer */
|
||||
int buffer_len; /* buffer length */
|
||||
char * debug_info_path; /* debug info path */
|
||||
void * ehdr; /* ELF header */
|
||||
Elf * elf; /* ELF descriptor */
|
||||
char * elf_ident; /* ELF identity string */
|
||||
char * elf_obj; /* elf_obj file */
|
||||
int fd; /* descriptor for files */
|
||||
unsigned int file_crc = 0; /* CRC for debug info file */
|
||||
int is_elfclass64; /* is an ELFCLASS64 file? */
|
||||
Elf_Data * link_dat; /* ELF data for new debug info link */
|
||||
Elf_Data * name_dat; /* ELF data for new section name */
|
||||
Elf_Scn * new_scn; /* new ELF section descriptor */
|
||||
void * new_shdr; /* new ELF section header */
|
||||
Elf_Scn * scn; /* ELF section descriptor */
|
||||
void * shdr; /* ELF section header */
|
||||
|
||||
if (argc != 3) {
|
||||
(void) fprintf(stderr, "Usage: %s debug_info_path elf_obj\n", argv[0]);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
debug_info_path = argv[1]; /* save for later */
|
||||
if ((fd = open(debug_info_path, O_RDONLY)) == -1) {
|
||||
(void) fprintf(stderr, "%s: cannot open file.\n", debug_info_path);
|
||||
exit(3);
|
||||
}
|
||||
|
||||
(void) printf("Computing CRC for '%s'\n", debug_info_path);
|
||||
(void) fflush(stdout);
|
||||
/* compute CRC for the debug info file */
|
||||
for (;;) {
|
||||
int len = read(fd, buffer, sizeof buffer);
|
||||
if (len <= 0) {
|
||||
break;
|
||||
}
|
||||
file_crc = gnu_debuglink_crc32(file_crc, buffer, len);
|
||||
}
|
||||
(void) close(fd);
|
||||
|
||||
/* open the elf_obj */
|
||||
elf_obj = argv[2];
|
||||
if ((fd = open(elf_obj, O_RDWR)) == -1) {
|
||||
(void) fprintf(stderr, "%s: cannot open file.\n", elf_obj);
|
||||
exit(4);
|
||||
}
|
||||
|
||||
(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 */
|
||||
if (is_elfclass64) {
|
||||
shdr = elf64_getshdr(scn);
|
||||
} else {
|
||||
shdr = elf32_getshdr(scn);
|
||||
}
|
||||
if (shdr == NULL) {
|
||||
failure();
|
||||
}
|
||||
|
||||
(void) printf("Adding ELF data for new section name\n");
|
||||
(void) fflush(stdout);
|
||||
name_dat = elf_newdata(scn);
|
||||
name_dat->d_buf = (void *) SEC_NAME;
|
||||
if (is_elfclass64) {
|
||||
name_dat->d_off = ((Elf64_Shdr *) shdr)->sh_size + 1;
|
||||
} else {
|
||||
name_dat->d_off = ((Elf32_Shdr *) shdr)->sh_size + 1;
|
||||
}
|
||||
name_dat->d_align = 1;
|
||||
name_dat->d_size = strlen(SEC_NAME) + 1;
|
||||
|
||||
new_scn = elf_newscn(elf);
|
||||
|
||||
if (is_elfclass64) {
|
||||
new_shdr = elf64_getshdr(new_scn);
|
||||
((Elf64_Shdr *) new_shdr)->sh_flags = SHF_EXCLUDE;
|
||||
((Elf64_Shdr *) new_shdr)->sh_type = SHT_PROGBITS;
|
||||
((Elf64_Shdr *) new_shdr)->sh_name = ((Elf64_Shdr *) shdr)->sh_size;
|
||||
((Elf64_Shdr *) new_shdr)->sh_addralign = 1;
|
||||
((Elf64_Shdr *) shdr)->sh_size += (strlen(SEC_NAME) + 1);
|
||||
} else {
|
||||
new_shdr = elf32_getshdr(new_scn);
|
||||
((Elf32_Shdr *) new_shdr)->sh_flags = SHF_EXCLUDE;
|
||||
((Elf32_Shdr *) new_shdr)->sh_type = SHT_PROGBITS;
|
||||
((Elf32_Shdr *) new_shdr)->sh_name = ((Elf32_Shdr *) shdr)->sh_size;
|
||||
((Elf32_Shdr *) new_shdr)->sh_addralign = 1;
|
||||
((Elf32_Shdr *) shdr)->sh_size += (strlen(SEC_NAME) + 1);
|
||||
}
|
||||
|
||||
(void) printf("Adding ELF data for debug_info_path value\n");
|
||||
(void) fflush(stdout);
|
||||
(void) memset(buffer, 0, sizeof buffer);
|
||||
buffer_len = strlen(debug_info_path) + 1; /* +1 for NUL */
|
||||
(void) strncpy((char *) buffer, debug_info_path, buffer_len);
|
||||
if (buffer_len % 4 != 0) {
|
||||
/* not on a 4 byte boundary so pad to the next one */
|
||||
buffer_len += (4 - buffer_len % 4);
|
||||
}
|
||||
/* save the CRC */
|
||||
(void) memcpy(&buffer[buffer_len], &file_crc, sizeof file_crc);
|
||||
buffer_len += sizeof file_crc;
|
||||
|
||||
link_dat = elf_newdata(new_scn);
|
||||
link_dat->d_type = ELF_T_BYTE;
|
||||
link_dat->d_size = buffer_len;
|
||||
link_dat->d_buf = buffer;
|
||||
link_dat->d_align = 1;
|
||||
|
||||
(void) printf("Saving updates to '%s'\n", 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 */
|
||||
(void) elf_end(elf); /* done with ELF obj */
|
||||
(void) close(fd);
|
||||
|
||||
(void) printf("Done updating '%s'\n", elf_obj);
|
||||
(void) fflush(stdout);
|
||||
exit(0);
|
||||
} /* end main */
|
||||
|
||||
|
||||
static void
|
||||
failure() {
|
||||
(void) fprintf(stderr, "%s\n", elf_errmsg(elf_errno()));
|
||||
exit(5);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The CRC used in gnu_debuglink, retrieved from
|
||||
* http://sourceware.org/gdb/current/onlinedocs/gdb/Separate-Debug-Files.html#Separate-Debug-Files.
|
||||
*/
|
||||
|
||||
static unsigned int
|
||||
gnu_debuglink_crc32(unsigned int crc, unsigned char *buf, size_t len) {
|
||||
static const unsigned int crc32_table[256] = {
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
|
||||
0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
|
||||
0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
|
||||
0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
|
||||
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
|
||||
0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
|
||||
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
|
||||
0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
|
||||
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
|
||||
0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
|
||||
0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
|
||||
0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
|
||||
0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
|
||||
0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
|
||||
0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
|
||||
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
|
||||
0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
||||
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
|
||||
0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
|
||||
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
|
||||
0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
|
||||
0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
|
||||
0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
|
||||
0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
|
||||
0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
|
||||
0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
|
||||
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
|
||||
0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
|
||||
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
|
||||
0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
|
||||
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
|
||||
0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
|
||||
0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
|
||||
0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
|
||||
0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
|
||||
0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
|
||||
0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
|
||||
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
|
||||
0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
||||
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
|
||||
0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
|
||||
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
|
||||
0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
|
||||
0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
|
||||
0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
|
||||
0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
|
||||
0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
|
||||
0x2d02ef8d
|
||||
};
|
||||
|
||||
unsigned char *end;
|
||||
|
||||
crc = ~crc & 0xffffffff;
|
||||
for (end = buf + len; buf < end; ++buf) {
|
||||
crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
|
||||
}
|
||||
return ~crc & 0xffffffff;
|
||||
}
|
||||
@ -1,181 +0,0 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
@ -461,7 +461,7 @@ static char* get_user_name(int vmid, TRAPS) {
|
||||
// since the structured procfs and old procfs interfaces can't be
|
||||
// mixed, we attempt to find the file through a directory search.
|
||||
|
||||
return get_user_name_slow(vmid, CHECK_NULL);
|
||||
return get_user_name_slow(vmid, THREAD);
|
||||
}
|
||||
|
||||
// return the file name of the backing store file for the named
|
||||
|
||||
@ -88,6 +88,15 @@ inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* des
|
||||
return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest);
|
||||
}
|
||||
|
||||
#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE
|
||||
inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) {
|
||||
int mp = os::is_MP();
|
||||
__asm__ volatile (LOCK_IF_MP(%4) "cmpxchgb %1,(%3)"
|
||||
: "=a" (exchange_value)
|
||||
: "q" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
|
||||
: "cc", "memory");
|
||||
return exchange_value;
|
||||
}
|
||||
|
||||
inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) {
|
||||
int mp = os::is_MP();
|
||||
|
||||
@ -88,6 +88,15 @@ inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* des
|
||||
return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest);
|
||||
}
|
||||
|
||||
#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE
|
||||
inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) {
|
||||
int mp = os::is_MP();
|
||||
__asm__ volatile (LOCK_IF_MP(%4) "cmpxchgb %1,(%3)"
|
||||
: "=a" (exchange_value)
|
||||
: "q" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
|
||||
: "cc", "memory");
|
||||
return exchange_value;
|
||||
}
|
||||
|
||||
inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) {
|
||||
int mp = os::is_MP();
|
||||
|
||||
@ -542,6 +542,7 @@ JVM_handle_linux_signal(int sig,
|
||||
err.report_and_die();
|
||||
|
||||
ShouldNotReachHere();
|
||||
return true; // Mute compiler
|
||||
}
|
||||
|
||||
void os::Linux::init_thread_fpu_state(void) {
|
||||
|
||||
@ -68,6 +68,8 @@ inline void Atomic::dec_ptr(volatile void* dest) { (void)add_ptr(-1, dest);
|
||||
extern "C" {
|
||||
jint _Atomic_add(jint add_value, volatile jint* dest IS_MP_DECL());
|
||||
jint _Atomic_xchg(jint exchange_value, volatile jint* dest);
|
||||
jbyte _Atomic_cmpxchg_byte(jbyte exchange_value, volatile jbyte* dest,
|
||||
jbyte compare_value IS_MP_DECL());
|
||||
jint _Atomic_cmpxchg(jint exchange_value, volatile jint* dest,
|
||||
jint compare_value IS_MP_DECL());
|
||||
jlong _Atomic_cmpxchg_long(jlong exchange_value, volatile jlong* dest,
|
||||
@ -82,6 +84,11 @@ inline jint Atomic::xchg (jint exchange_value, volatile jint*
|
||||
return _Atomic_xchg(exchange_value, dest);
|
||||
}
|
||||
|
||||
#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE
|
||||
inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) {
|
||||
return _Atomic_cmpxchg_byte(exchange_value, dest, compare_value IS_MP_ARG());
|
||||
}
|
||||
|
||||
inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) {
|
||||
return _Atomic_cmpxchg(exchange_value, dest, compare_value IS_MP_ARG());
|
||||
}
|
||||
@ -217,6 +224,15 @@ extern "C" {
|
||||
return exchange_value;
|
||||
}
|
||||
|
||||
|
||||
inline jbyte _Atomic_cmpxchg_byte(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, int mp) {
|
||||
__asm__ volatile (LOCK_IF_MP(%4) "cmpxchgb %1,(%3)"
|
||||
: "=a" (exchange_value)
|
||||
: "q" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
|
||||
: "cc", "memory");
|
||||
return exchange_value;
|
||||
}
|
||||
|
||||
// This is the interface to the atomic instruction in solaris_i486.s.
|
||||
jlong _Atomic_cmpxchg_long_gcc(jlong exchange_value, volatile jlong* dest, jlong compare_value, int mp);
|
||||
|
||||
|
||||
@ -76,6 +76,23 @@
|
||||
xchgl (%ecx), %eax
|
||||
.end
|
||||
|
||||
// Support for jbyte Atomic::cmpxchg(jbyte exchange_value,
|
||||
// volatile jbyte *dest,
|
||||
// jbyte compare_value)
|
||||
// An additional bool (os::is_MP()) is passed as the last argument.
|
||||
.inline _Atomic_cmpxchg_byte,4
|
||||
movb 8(%esp), %al // compare_value
|
||||
movb 0(%esp), %cl // exchange_value
|
||||
movl 4(%esp), %edx // dest
|
||||
cmp $0, 12(%esp) // MP test
|
||||
jne 1f
|
||||
cmpxchgb %cl, (%edx)
|
||||
jmp 2f
|
||||
1: lock
|
||||
cmpxchgb %cl, (%edx)
|
||||
2:
|
||||
.end
|
||||
|
||||
// Support for jint Atomic::cmpxchg(jint exchange_value,
|
||||
// volatile jint *dest,
|
||||
// jint compare_value)
|
||||
|
||||
@ -77,6 +77,15 @@
|
||||
movq %rdi, %rax
|
||||
.end
|
||||
|
||||
// Support for jbyte Atomic::cmpxchg(jbyte exchange_value,
|
||||
// volatile jbyte *dest,
|
||||
// jbyte compare_value)
|
||||
.inline _Atomic_cmpxchg_byte,3
|
||||
movb %dl, %al // compare_value
|
||||
lock
|
||||
cmpxchgb %dil, (%rsi)
|
||||
.end
|
||||
|
||||
// Support for jint Atomic::cmpxchg(jint exchange_value,
|
||||
// volatile jint *dest,
|
||||
// jint compare_value)
|
||||
|
||||
@ -123,6 +123,11 @@ inline jint Atomic::cmpxchg (jint exchange_value, volatile jint*
|
||||
return (*os::atomic_cmpxchg_func)(exchange_value, dest, compare_value);
|
||||
}
|
||||
|
||||
#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE
|
||||
inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) {
|
||||
return (*os::atomic_cmpxchg_byte_func)(exchange_value, dest, compare_value);
|
||||
}
|
||||
|
||||
inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value) {
|
||||
return (*os::atomic_cmpxchg_long_func)(exchange_value, dest, compare_value);
|
||||
}
|
||||
@ -212,6 +217,19 @@ inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* des
|
||||
return (void*)xchg((jint)exchange_value, (volatile jint*)dest);
|
||||
}
|
||||
|
||||
#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE
|
||||
inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) {
|
||||
// alternative for InterlockedCompareExchange
|
||||
int mp = os::is_MP();
|
||||
__asm {
|
||||
mov edx, dest
|
||||
mov cl, exchange_value
|
||||
mov al, compare_value
|
||||
LOCK_IF_MP(mp)
|
||||
cmpxchg byte ptr [edx], cl
|
||||
}
|
||||
}
|
||||
|
||||
inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) {
|
||||
// alternative for InterlockedCompareExchange
|
||||
int mp = os::is_MP();
|
||||
|
||||
@ -220,6 +220,7 @@ void os::initialize_thread(Thread* thr) {
|
||||
typedef jint xchg_func_t (jint, volatile jint*);
|
||||
typedef intptr_t xchg_ptr_func_t (intptr_t, volatile intptr_t*);
|
||||
typedef jint cmpxchg_func_t (jint, volatile jint*, jint);
|
||||
typedef jbyte cmpxchg_byte_func_t (jbyte, volatile jbyte*, jbyte);
|
||||
typedef jlong cmpxchg_long_func_t (jlong, volatile jlong*, jlong);
|
||||
typedef jint add_func_t (jint, volatile jint*);
|
||||
typedef intptr_t add_ptr_func_t (intptr_t, volatile intptr_t*);
|
||||
@ -272,6 +273,23 @@ jint os::atomic_cmpxchg_bootstrap(jint exchange_value, volatile jint* dest, jint
|
||||
*dest = exchange_value;
|
||||
return old_value;
|
||||
}
|
||||
|
||||
jbyte os::atomic_cmpxchg_byte_bootstrap(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) {
|
||||
// try to use the stub:
|
||||
cmpxchg_byte_func_t* func = CAST_TO_FN_PTR(cmpxchg_byte_func_t*, StubRoutines::atomic_cmpxchg_byte_entry());
|
||||
|
||||
if (func != NULL) {
|
||||
os::atomic_cmpxchg_byte_func = func;
|
||||
return (*func)(exchange_value, dest, compare_value);
|
||||
}
|
||||
assert(Threads::number_of_threads() == 0, "for bootstrap only");
|
||||
|
||||
jbyte old_value = *dest;
|
||||
if (old_value == compare_value)
|
||||
*dest = exchange_value;
|
||||
return old_value;
|
||||
}
|
||||
|
||||
#endif // AMD64
|
||||
|
||||
jlong os::atomic_cmpxchg_long_bootstrap(jlong exchange_value, volatile jlong* dest, jlong compare_value) {
|
||||
@ -321,6 +339,7 @@ intptr_t os::atomic_add_ptr_bootstrap(intptr_t add_value, volatile intptr_t* des
|
||||
xchg_func_t* os::atomic_xchg_func = os::atomic_xchg_bootstrap;
|
||||
xchg_ptr_func_t* os::atomic_xchg_ptr_func = os::atomic_xchg_ptr_bootstrap;
|
||||
cmpxchg_func_t* os::atomic_cmpxchg_func = os::atomic_cmpxchg_bootstrap;
|
||||
cmpxchg_byte_func_t* os::atomic_cmpxchg_byte_func = os::atomic_cmpxchg_byte_bootstrap;
|
||||
add_func_t* os::atomic_add_func = os::atomic_add_bootstrap;
|
||||
add_ptr_func_t* os::atomic_add_ptr_func = os::atomic_add_ptr_bootstrap;
|
||||
|
||||
@ -635,7 +654,11 @@ void os::setup_fpu() {
|
||||
#ifndef PRODUCT
|
||||
void os::verify_stack_alignment() {
|
||||
#ifdef AMD64
|
||||
assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment");
|
||||
// The current_stack_pointer() calls generated get_previous_sp stub routine.
|
||||
// Only enable the assert after the routine becomes available.
|
||||
if (StubRoutines::code1() != NULL) {
|
||||
assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -33,6 +33,7 @@
|
||||
static intptr_t (*atomic_xchg_ptr_func) (intptr_t, volatile intptr_t*);
|
||||
|
||||
static jint (*atomic_cmpxchg_func) (jint, volatile jint*, jint);
|
||||
static jbyte (*atomic_cmpxchg_byte_func) (jbyte, volatile jbyte*, jbyte);
|
||||
static jlong (*atomic_cmpxchg_long_func) (jlong, volatile jlong*, jlong);
|
||||
|
||||
static jint (*atomic_add_func) (jint, volatile jint*);
|
||||
@ -42,6 +43,7 @@
|
||||
static intptr_t atomic_xchg_ptr_bootstrap (intptr_t, volatile intptr_t*);
|
||||
|
||||
static jint atomic_cmpxchg_bootstrap (jint, volatile jint*, jint);
|
||||
static jbyte atomic_cmpxchg_byte_bootstrap(jbyte, volatile jbyte*, jbyte);
|
||||
#else
|
||||
|
||||
static jlong (*atomic_cmpxchg_long_func) (jlong, volatile jlong*, jlong);
|
||||
|
||||
@ -512,7 +512,9 @@ abstract class GenericDebugConfig extends BuildConfig {
|
||||
abstract class GenericDebugNonKernelConfig extends GenericDebugConfig {
|
||||
protected void init(Vector includes, Vector defines) {
|
||||
super.init(includes, defines);
|
||||
getCI().getAdditionalNonKernelLinkerFlags(getV("LinkerFlags"));
|
||||
if (get("PlatformName").equals("Win32")) {
|
||||
getCI().getAdditionalNonKernelLinkerFlags(getV("LinkerFlags"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -401,16 +401,18 @@ class CompilerInterfaceVC10 extends CompilerInterface {
|
||||
Vector getBaseLinkerFlags(String outDir, String outDll, String platformName) {
|
||||
Vector rv = new Vector();
|
||||
|
||||
addAttr(rv, "AdditionalOptions",
|
||||
"/export:JNI_GetDefaultJavaVMInitArgs " +
|
||||
"/export:JNI_CreateJavaVM " +
|
||||
"/export:JVM_FindClassFromBootLoader "+
|
||||
"/export:JNI_GetCreatedJavaVMs "+
|
||||
"/export:jio_snprintf /export:jio_printf "+
|
||||
"/export:jio_fprintf /export:jio_vfprintf "+
|
||||
"/export:jio_vsnprintf "+
|
||||
"/export:JVM_GetVersionInfo "+
|
||||
"/export:JVM_InitAgentProperties");
|
||||
if(platformName.equals("Win32")) {
|
||||
addAttr(rv, "AdditionalOptions",
|
||||
"/export:JNI_GetDefaultJavaVMInitArgs " +
|
||||
"/export:JNI_CreateJavaVM " +
|
||||
"/export:JVM_FindClassFromBootLoader "+
|
||||
"/export:JNI_GetCreatedJavaVMs "+
|
||||
"/export:jio_snprintf /export:jio_printf "+
|
||||
"/export:jio_fprintf /export:jio_vfprintf "+
|
||||
"/export:jio_vsnprintf "+
|
||||
"/export:JVM_GetVersionInfo "+
|
||||
"/export:JVM_InitAgentProperties");
|
||||
}
|
||||
addAttr(rv, "AdditionalDependencies", "kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;Wsock32.lib;winmm.lib;psapi.lib;version.lib");
|
||||
addAttr(rv, "OutputFile", outDll);
|
||||
addAttr(rv, "SuppressStartupBanner", "true");
|
||||
|
||||
@ -53,6 +53,7 @@
|
||||
#include "runtime/reflection.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/thread.inline.hpp"
|
||||
#include "trace/tracing.hpp"
|
||||
#include "utilities/dtrace.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#ifdef COMPILER1
|
||||
@ -1141,6 +1142,16 @@ void ciEnv::record_failure(const char* reason) {
|
||||
}
|
||||
}
|
||||
|
||||
void ciEnv::report_failure(const char* reason) {
|
||||
// Create and fire JFR event
|
||||
EventCompilerFailure event;
|
||||
if (event.should_commit()) {
|
||||
event.set_compileID(compile_id());
|
||||
event.set_failure(reason);
|
||||
event.commit();
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// ciEnv::record_method_not_compilable()
|
||||
void ciEnv::record_method_not_compilable(const char* reason, bool all_tiers) {
|
||||
|
||||
@ -450,7 +450,8 @@ public:
|
||||
// Check for changes to the system dictionary during compilation
|
||||
bool system_dictionary_modification_counter_changed();
|
||||
|
||||
void record_failure(const char* reason);
|
||||
void record_failure(const char* reason); // Record failure and report later
|
||||
void report_failure(const char* reason); // Report failure immediately
|
||||
void record_method_not_compilable(const char* reason, bool all_tiers = true);
|
||||
void record_out_of_memory_failure();
|
||||
|
||||
|
||||
@ -46,6 +46,7 @@
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "oops/oop.inline2.hpp"
|
||||
#include "runtime/fieldType.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#if INCLUDE_ALL_GCS
|
||||
# include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
|
||||
#endif
|
||||
|
||||
@ -332,7 +332,7 @@ class CompileReplay : public StackObj {
|
||||
// Lookup a klass
|
||||
Klass* resolve_klass(const char* klass, TRAPS) {
|
||||
Symbol* klass_name = SymbolTable::lookup(klass, (int)strlen(klass), CHECK_NULL);
|
||||
return SystemDictionary::resolve_or_fail(klass_name, _loader, _protection_domain, true, CHECK_NULL);
|
||||
return SystemDictionary::resolve_or_fail(klass_name, _loader, _protection_domain, true, THREAD);
|
||||
}
|
||||
|
||||
// Parse the standard tuple of <klass> <name> <signature>
|
||||
|
||||
@ -35,6 +35,8 @@
|
||||
#include "interpreter/bytecode.hpp"
|
||||
#include "interpreter/bytecodes.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "opto/compile.hpp"
|
||||
#include "opto/node.hpp"
|
||||
#include "runtime/deoptimization.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
|
||||
@ -2646,7 +2648,7 @@ void ciTypeFlow::df_flow_types(Block* start,
|
||||
assert (!blk->has_pre_order(), "");
|
||||
blk->set_next_pre_order();
|
||||
|
||||
if (_next_pre_order >= MaxNodeLimit / 2) {
|
||||
if (_next_pre_order >= (int)Compile::current()->max_node_limit() / 2) {
|
||||
// Too many basic blocks. Bail out.
|
||||
// This can happen when try/finally constructs are nested to depth N,
|
||||
// and there is O(2**N) cloning of jsr bodies. See bug 4697245!
|
||||
|
||||
@ -31,9 +31,6 @@
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#if INCLUDE_CDS
|
||||
#include "classfile/systemDictionaryShared.hpp"
|
||||
#endif
|
||||
#include "classfile/verificationType.hpp"
|
||||
#include "classfile/verifier.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
@ -63,7 +60,11 @@
|
||||
#include "services/threadService.hpp"
|
||||
#include "utilities/array.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
#if INCLUDE_CDS
|
||||
#include "classfile/systemDictionaryShared.hpp"
|
||||
#endif
|
||||
|
||||
// We generally try to create the oops directly when parsing, rather than
|
||||
// allocating temporary data structures and copying the bytes twice. A
|
||||
|
||||
@ -29,10 +29,6 @@
|
||||
#include "classfile/classLoaderExt.hpp"
|
||||
#include "classfile/classLoaderData.inline.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#if INCLUDE_CDS
|
||||
#include "classfile/sharedPathsMiscInfo.hpp"
|
||||
#include "classfile/sharedClassUtil.hpp"
|
||||
#endif
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "compiler/compileBroker.hpp"
|
||||
@ -64,8 +60,13 @@
|
||||
#include "services/management.hpp"
|
||||
#include "services/threadService.hpp"
|
||||
#include "utilities/events.hpp"
|
||||
#include "utilities/hashtable.hpp"
|
||||
#include "utilities/hashtable.inline.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#if INCLUDE_CDS
|
||||
#include "classfile/sharedPathsMiscInfo.hpp"
|
||||
#include "classfile/sharedClassUtil.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
// Entry points in zip.dll for loading zip/jar file entries
|
||||
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
|
||||
#include "classfile/classFileParser.hpp"
|
||||
#include "runtime/perfData.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
// The VM class loader.
|
||||
#include <sys/stat.h>
|
||||
|
||||
@ -65,9 +65,8 @@
|
||||
#include "utilities/growableArray.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
|
||||
#if INCLUDE_TRACE
|
||||
#include "trace/tracing.hpp"
|
||||
#include "trace/tracing.hpp"
|
||||
#endif
|
||||
|
||||
ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL;
|
||||
@ -472,7 +471,7 @@ void ClassLoaderData::free_deallocate_list() {
|
||||
// These anonymous class loaders are to contain classes used for JSR292
|
||||
ClassLoaderData* ClassLoaderData::anonymous_class_loader_data(oop loader, TRAPS) {
|
||||
// Add a new class loader data to the graph.
|
||||
return ClassLoaderDataGraph::add(loader, true, CHECK_NULL);
|
||||
return ClassLoaderDataGraph::add(loader, true, THREAD);
|
||||
}
|
||||
|
||||
const char* ClassLoaderData::loader_name() {
|
||||
@ -978,4 +977,4 @@ void ClassLoaderDataGraph::class_unload_event(Klass* const k) {
|
||||
event.commit();
|
||||
}
|
||||
|
||||
#endif /* INCLUDE_TRACE */
|
||||
#endif // INCLUDE_TRACE
|
||||
|
||||
@ -31,8 +31,9 @@
|
||||
#include "memory/metaspaceCounters.hpp"
|
||||
#include "runtime/mutex.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#if INCLUDE_TRACE
|
||||
# include "utilities/ticks.hpp"
|
||||
#include "utilities/ticks.hpp"
|
||||
#endif
|
||||
|
||||
//
|
||||
|
||||
@ -63,6 +63,9 @@ public:
|
||||
ClassPathEntry* new_entry) {
|
||||
ClassLoader::add_to_list(new_entry);
|
||||
}
|
||||
static void append_boot_classpath(ClassPathEntry* new_entry) {
|
||||
ClassLoader::add_to_list(new_entry);
|
||||
}
|
||||
static void setup_search_paths() {}
|
||||
};
|
||||
|
||||
|
||||
@ -493,7 +493,7 @@ class MethodFamily : public ResourceObj {
|
||||
};
|
||||
|
||||
Symbol* MethodFamily::generate_no_defaults_message(TRAPS) const {
|
||||
return SymbolTable::new_symbol("No qualifying defaults found", CHECK_NULL);
|
||||
return SymbolTable::new_symbol("No qualifying defaults found", THREAD);
|
||||
}
|
||||
|
||||
Symbol* MethodFamily::generate_method_message(Symbol *klass_name, Method* method, TRAPS) const {
|
||||
@ -506,7 +506,7 @@ Symbol* MethodFamily::generate_method_message(Symbol *klass_name, Method* method
|
||||
ss.write((const char*)name->bytes(), name->utf8_length());
|
||||
ss.write((const char*)signature->bytes(), signature->utf8_length());
|
||||
ss.print(" is abstract");
|
||||
return SymbolTable::new_symbol(ss.base(), (int)ss.size(), CHECK_NULL);
|
||||
return SymbolTable::new_symbol(ss.base(), (int)ss.size(), THREAD);
|
||||
}
|
||||
|
||||
Symbol* MethodFamily::generate_conflicts_message(GrowableArray<Method*>* methods, TRAPS) const {
|
||||
@ -521,7 +521,7 @@ Symbol* MethodFamily::generate_conflicts_message(GrowableArray<Method*>* methods
|
||||
ss.print(".");
|
||||
ss.write((const char*)name->bytes(), name->utf8_length());
|
||||
}
|
||||
return SymbolTable::new_symbol(ss.base(), (int)ss.size(), CHECK_NULL);
|
||||
return SymbolTable::new_symbol(ss.base(), (int)ss.size(), THREAD);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
#include "oops/method.hpp"
|
||||
#include "oops/symbol.hpp"
|
||||
#include "oops/typeArrayOop.hpp"
|
||||
#include "prims/jvmtiRedefineClassesTrace.hpp"
|
||||
#include "runtime/fieldDescriptor.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
#include "runtime/interfaceSupport.hpp"
|
||||
@ -944,7 +945,7 @@ void java_lang_Thread::compute_offsets() {
|
||||
assert(_group_offset == 0, "offsets should be initialized only once");
|
||||
|
||||
Klass* k = SystemDictionary::Thread_klass();
|
||||
compute_offset(_name_offset, k, vmSymbols::name_name(), vmSymbols::char_array_signature());
|
||||
compute_offset(_name_offset, k, vmSymbols::name_name(), vmSymbols::string_signature());
|
||||
compute_offset(_group_offset, k, vmSymbols::group_name(), vmSymbols::threadgroup_signature());
|
||||
compute_offset(_contextClassLoader_offset, k, vmSymbols::contextClassLoader_name(), vmSymbols::classloader_signature());
|
||||
compute_offset(_inheritedAccessControlContext_offset, k, vmSymbols::inheritedAccessControlContext_name(), vmSymbols::accesscontrolcontext_signature());
|
||||
@ -974,15 +975,12 @@ void java_lang_Thread::set_thread(oop java_thread, JavaThread* thread) {
|
||||
}
|
||||
|
||||
|
||||
typeArrayOop java_lang_Thread::name(oop java_thread) {
|
||||
oop name = java_thread->obj_field(_name_offset);
|
||||
assert(name == NULL || (name->is_typeArray() && TypeArrayKlass::cast(name->klass())->element_type() == T_CHAR), "just checking");
|
||||
return typeArrayOop(name);
|
||||
oop java_lang_Thread::name(oop java_thread) {
|
||||
return java_thread->obj_field(_name_offset);
|
||||
}
|
||||
|
||||
|
||||
void java_lang_Thread::set_name(oop java_thread, typeArrayOop name) {
|
||||
assert(java_thread->obj_field(_name_offset) == NULL, "name should be NULL");
|
||||
void java_lang_Thread::set_name(oop java_thread, oop name) {
|
||||
java_thread->obj_field_put(_name_offset, name);
|
||||
}
|
||||
|
||||
@ -1952,7 +1950,7 @@ Handle java_lang_reflect_Method::create(TRAPS) {
|
||||
// This class is eagerly initialized during VM initialization, since we keep a refence
|
||||
// to one of the methods
|
||||
assert(InstanceKlass::cast(klass)->is_initialized(), "must be initialized");
|
||||
return InstanceKlass::cast(klass)->allocate_instance_handle(CHECK_NH);
|
||||
return InstanceKlass::cast(klass)->allocate_instance_handle(THREAD);
|
||||
}
|
||||
|
||||
oop java_lang_reflect_Method::clazz(oop reflect) {
|
||||
@ -2130,7 +2128,7 @@ Handle java_lang_reflect_Constructor::create(TRAPS) {
|
||||
instanceKlassHandle klass (THREAD, k);
|
||||
// Ensure it is initialized
|
||||
klass->initialize(CHECK_NH);
|
||||
return klass->allocate_instance_handle(CHECK_NH);
|
||||
return klass->allocate_instance_handle(THREAD);
|
||||
}
|
||||
|
||||
oop java_lang_reflect_Constructor::clazz(oop reflect) {
|
||||
@ -2270,7 +2268,7 @@ Handle java_lang_reflect_Field::create(TRAPS) {
|
||||
instanceKlassHandle klass (THREAD, k);
|
||||
// Ensure it is initialized
|
||||
klass->initialize(CHECK_NH);
|
||||
return klass->allocate_instance_handle(CHECK_NH);
|
||||
return klass->allocate_instance_handle(THREAD);
|
||||
}
|
||||
|
||||
oop java_lang_reflect_Field::clazz(oop reflect) {
|
||||
@ -2397,7 +2395,7 @@ Handle java_lang_reflect_Parameter::create(TRAPS) {
|
||||
instanceKlassHandle klass (THREAD, k);
|
||||
// Ensure it is initialized
|
||||
klass->initialize(CHECK_NH);
|
||||
return klass->allocate_instance_handle(CHECK_NH);
|
||||
return klass->allocate_instance_handle(THREAD);
|
||||
}
|
||||
|
||||
oop java_lang_reflect_Parameter::name(oop param) {
|
||||
@ -2447,7 +2445,7 @@ Handle sun_reflect_ConstantPool::create(TRAPS) {
|
||||
instanceKlassHandle klass (THREAD, k);
|
||||
// Ensure it is initialized
|
||||
klass->initialize(CHECK_NH);
|
||||
return klass->allocate_instance_handle(CHECK_NH);
|
||||
return klass->allocate_instance_handle(THREAD);
|
||||
}
|
||||
|
||||
|
||||
@ -2797,12 +2795,35 @@ Metadata* java_lang_invoke_MemberName::vmtarget(oop mname) {
|
||||
return (Metadata*)mname->address_field(_vmtarget_offset);
|
||||
}
|
||||
|
||||
bool java_lang_invoke_MemberName::is_method(oop mname) {
|
||||
assert(is_instance(mname), "must be MemberName");
|
||||
return (flags(mname) & (MN_IS_METHOD | MN_IS_CONSTRUCTOR)) > 0;
|
||||
}
|
||||
|
||||
#if INCLUDE_JVMTI
|
||||
// Can be executed on VM thread only
|
||||
void java_lang_invoke_MemberName::adjust_vmtarget(oop mname, Metadata* ref) {
|
||||
assert((is_instance(mname) && (flags(mname) & (MN_IS_METHOD | MN_IS_CONSTRUCTOR)) > 0), "wrong type");
|
||||
void java_lang_invoke_MemberName::adjust_vmtarget(oop mname, Method* old_method,
|
||||
Method* new_method, bool* trace_name_printed) {
|
||||
assert(is_method(mname), "wrong type");
|
||||
assert(Thread::current()->is_VM_thread(), "not VM thread");
|
||||
mname->address_field_put(_vmtarget_offset, (address)ref);
|
||||
|
||||
Method* target = (Method*)mname->address_field(_vmtarget_offset);
|
||||
if (target == old_method) {
|
||||
mname->address_field_put(_vmtarget_offset, (address)new_method);
|
||||
|
||||
if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
|
||||
if (!(*trace_name_printed)) {
|
||||
// RC_TRACE_MESG macro has an embedded ResourceMark
|
||||
RC_TRACE_MESG(("adjust: name=%s",
|
||||
old_method->method_holder()->external_name()));
|
||||
*trace_name_printed = true;
|
||||
}
|
||||
// RC_TRACE macro has an embedded ResourceMark
|
||||
RC_TRACE(0x00400000, ("MemberName method update: %s(%s)",
|
||||
new_method->name()->as_C_string(),
|
||||
new_method->signature()->as_C_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // INCLUDE_JVMTI
|
||||
|
||||
|
||||
@ -345,8 +345,8 @@ class java_lang_Thread : AllStatic {
|
||||
// Set JavaThread for instance
|
||||
static void set_thread(oop java_thread, JavaThread* thread);
|
||||
// Name
|
||||
static typeArrayOop name(oop java_thread);
|
||||
static void set_name(oop java_thread, typeArrayOop name);
|
||||
static oop name(oop java_thread);
|
||||
static void set_name(oop java_thread, oop name);
|
||||
// Priority
|
||||
static ThreadPriority priority(oop java_thread);
|
||||
static void set_priority(oop java_thread, ThreadPriority priority);
|
||||
@ -1100,7 +1100,8 @@ class java_lang_invoke_MemberName: AllStatic {
|
||||
static Metadata* vmtarget(oop mname);
|
||||
static void set_vmtarget(oop mname, Metadata* target);
|
||||
#if INCLUDE_JVMTI
|
||||
static void adjust_vmtarget(oop mname, Metadata* target);
|
||||
static void adjust_vmtarget(oop mname, Method* old_method, Method* new_method,
|
||||
bool* trace_name_printed);
|
||||
#endif // INCLUDE_JVMTI
|
||||
|
||||
static intptr_t vmindex(oop mname);
|
||||
@ -1114,6 +1115,8 @@ class java_lang_invoke_MemberName: AllStatic {
|
||||
return obj != NULL && is_subclass(obj->klass());
|
||||
}
|
||||
|
||||
static bool is_method(oop obj);
|
||||
|
||||
// Relevant integer codes (keep these in synch. with MethodHandleNatives.Constants):
|
||||
enum {
|
||||
MN_IS_METHOD = 0x00010000, // method (not constructor)
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
#include "runtime/atomic.inline.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "utilities/hashtable.inline.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#if INCLUDE_ALL_GCS
|
||||
#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
|
||||
#include "gc_implementation/g1/g1StringDedup.hpp"
|
||||
|
||||
@ -235,7 +235,7 @@ Symbol* SymbolTable::lookup(const char* name, int len, TRAPS) {
|
||||
MutexLocker ml(SymbolTable_lock, THREAD);
|
||||
|
||||
// Otherwise, add to symbol to table
|
||||
return the_table()->basic_add(index, (u1*)name, len, hashValue, true, CHECK_NULL);
|
||||
return the_table()->basic_add(index, (u1*)name, len, hashValue, true, THREAD);
|
||||
}
|
||||
|
||||
Symbol* SymbolTable::lookup(const Symbol* sym, int begin, int end, TRAPS) {
|
||||
@ -274,7 +274,7 @@ Symbol* SymbolTable::lookup(const Symbol* sym, int begin, int end, TRAPS) {
|
||||
// Grab SymbolTable_lock first.
|
||||
MutexLocker ml(SymbolTable_lock, THREAD);
|
||||
|
||||
return the_table()->basic_add(index, (u1*)buffer, len, hashValue, true, CHECK_NULL);
|
||||
return the_table()->basic_add(index, (u1*)buffer, len, hashValue, true, THREAD);
|
||||
}
|
||||
|
||||
Symbol* SymbolTable::lookup_only(const char* name, int len,
|
||||
|
||||
@ -31,10 +31,6 @@
|
||||
#include "classfile/resolutionErrors.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#if INCLUDE_CDS
|
||||
#include "classfile/sharedClassUtil.hpp"
|
||||
#include "classfile/systemDictionaryShared.hpp"
|
||||
#endif
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "compiler/compileBroker.hpp"
|
||||
#include "interpreter/bytecodeStream.hpp"
|
||||
@ -65,9 +61,12 @@
|
||||
#include "services/threadService.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include "utilities/ticks.hpp"
|
||||
|
||||
#if INCLUDE_CDS
|
||||
#include "classfile/sharedClassUtil.hpp"
|
||||
#include "classfile/systemDictionaryShared.hpp"
|
||||
#endif
|
||||
#if INCLUDE_TRACE
|
||||
#include "trace/tracing.hpp"
|
||||
#include "trace/tracing.hpp"
|
||||
#endif
|
||||
|
||||
Dictionary* SystemDictionary::_dictionary = NULL;
|
||||
@ -123,7 +122,7 @@ void SystemDictionary::compute_java_system_loader(TRAPS) {
|
||||
|
||||
ClassLoaderData* SystemDictionary::register_loader(Handle class_loader, TRAPS) {
|
||||
if (class_loader() == NULL) return ClassLoaderData::the_null_class_loader_data();
|
||||
return ClassLoaderDataGraph::find_or_create(class_loader, CHECK_NULL);
|
||||
return ClassLoaderDataGraph::find_or_create(class_loader, THREAD);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -233,15 +232,15 @@ Klass* SystemDictionary::resolve_or_null(Symbol* class_name, Handle class_loader
|
||||
class_name->as_C_string(),
|
||||
class_loader.is_null() ? "null" : class_loader->klass()->name()->as_C_string()));
|
||||
if (FieldType::is_array(class_name)) {
|
||||
return resolve_array_class_or_null(class_name, class_loader, protection_domain, CHECK_NULL);
|
||||
return resolve_array_class_or_null(class_name, class_loader, protection_domain, THREAD);
|
||||
} else if (FieldType::is_obj(class_name)) {
|
||||
ResourceMark rm(THREAD);
|
||||
// Ignore wrapping L and ;.
|
||||
TempNewSymbol name = SymbolTable::new_symbol(class_name->as_C_string() + 1,
|
||||
class_name->utf8_length() - 2, CHECK_NULL);
|
||||
return resolve_instance_class_or_null(name, class_loader, protection_domain, CHECK_NULL);
|
||||
return resolve_instance_class_or_null(name, class_loader, protection_domain, THREAD);
|
||||
} else {
|
||||
return resolve_instance_class_or_null(class_name, class_loader, protection_domain, CHECK_NULL);
|
||||
return resolve_instance_class_or_null(class_name, class_loader, protection_domain, THREAD);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2660,7 +2659,7 @@ void SystemDictionary::post_class_load_event(const Ticks& start_time,
|
||||
class_loader->klass() : (Klass*)NULL);
|
||||
event.commit();
|
||||
}
|
||||
#endif /* INCLUDE_TRACE */
|
||||
#endif // INCLUDE_TRACE
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
@ -289,7 +289,7 @@ class VerificationType VALUE_OBJ_CLASS_SPEC {
|
||||
if (is_reference() && from.is_reference()) {
|
||||
return is_reference_assignable_from(from, context,
|
||||
from_field_is_protected,
|
||||
CHECK_false);
|
||||
THREAD);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1927,7 +1927,7 @@ Klass* ClassVerifier::load_class(Symbol* name, TRAPS) {
|
||||
|
||||
return SystemDictionary::resolve_or_fail(
|
||||
name, Handle(THREAD, loader), Handle(THREAD, protection_domain),
|
||||
true, CHECK_NULL);
|
||||
true, THREAD);
|
||||
}
|
||||
|
||||
bool ClassVerifier::is_protected_access(instanceKlassHandle this_class,
|
||||
|
||||
@ -1807,7 +1807,7 @@ void CompileBroker::init_compiler_thread_log() {
|
||||
os::file_separator(), thread_id, os::current_process_id());
|
||||
}
|
||||
|
||||
fp = fopen(file_name, "at");
|
||||
fp = fopen(file_name, "wt");
|
||||
if (fp != NULL) {
|
||||
if (LogCompilation && Verbose) {
|
||||
tty->print_cr("Opening compilation log %s", file_name);
|
||||
@ -1985,6 +1985,7 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
|
||||
|
||||
if (ci_env.failing()) {
|
||||
task->set_failure_reason(ci_env.failure_reason());
|
||||
ci_env.report_failure(ci_env.failure_reason());
|
||||
const char* retry_message = ci_env.retry_message();
|
||||
if (_compilation_log != NULL) {
|
||||
_compilation_log->log_failure(thread, task, ci_env.failure_reason(), retry_message);
|
||||
|
||||
@ -56,8 +56,10 @@ CompileLog::CompileLog(const char* file_name, FILE* fp, intx thread_id)
|
||||
}
|
||||
|
||||
CompileLog::~CompileLog() {
|
||||
delete _out;
|
||||
delete _out; // Close fd in fileStream::~fileStream()
|
||||
_out = NULL;
|
||||
// Remove partial file after merging in CompileLog::finish_log_on_error
|
||||
unlink(_file);
|
||||
FREE_C_HEAP_ARRAY(char, _identities, mtCompiler);
|
||||
FREE_C_HEAP_ARRAY(char, _file, mtCompiler);
|
||||
}
|
||||
@ -278,10 +280,9 @@ void CompileLog::finish_log_on_error(outputStream* file, char* buf, int buflen)
|
||||
}
|
||||
file->print_raw_cr("</compilation_log>");
|
||||
close(partial_fd);
|
||||
unlink(partial_file);
|
||||
}
|
||||
CompileLog* next_log = log->_next;
|
||||
delete log;
|
||||
delete log; // Removes partial file
|
||||
log = next_log;
|
||||
}
|
||||
_first = NULL;
|
||||
|
||||
@ -192,7 +192,6 @@ ConcurrentMarkSweepGeneration::ConcurrentMarkSweepGeneration(
|
||||
FreeBlockDictionary<FreeChunk>::DictionaryChoice dictionaryChoice) :
|
||||
CardGeneration(rs, initial_byte_size, level, ct),
|
||||
_dilatation_factor(((double)MinChunkSize)/((double)(CollectedHeap::min_fill_size()))),
|
||||
_debug_collection_type(Concurrent_collection_type),
|
||||
_did_compact(false)
|
||||
{
|
||||
HeapWord* bottom = (HeapWord*) _virtual_space.low();
|
||||
@ -612,8 +611,6 @@ CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen,
|
||||
// Clip CMSBootstrapOccupancy between 0 and 100.
|
||||
_bootstrap_occupancy = ((double)CMSBootstrapOccupancy)/(double)100;
|
||||
|
||||
_full_gcs_since_conc_gc = 0;
|
||||
|
||||
// Now tell CMS generations the identity of their collector
|
||||
ConcurrentMarkSweepGeneration::set_collector(this);
|
||||
|
||||
@ -1247,20 +1244,6 @@ bool CMSCollector::shouldConcurrentCollect() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// For debugging purposes, change the type of collection.
|
||||
// If the rotation is not on the concurrent collection
|
||||
// type, don't start a concurrent collection.
|
||||
NOT_PRODUCT(
|
||||
if (RotateCMSCollectionTypes &&
|
||||
(_cmsGen->debug_collection_type() !=
|
||||
ConcurrentMarkSweepGeneration::Concurrent_collection_type)) {
|
||||
assert(_cmsGen->debug_collection_type() !=
|
||||
ConcurrentMarkSweepGeneration::Unknown_collection_type,
|
||||
"Bad cms collection type");
|
||||
return false;
|
||||
}
|
||||
)
|
||||
|
||||
FreelistLocker x(this);
|
||||
// ------------------------------------------------------------------
|
||||
// Print out lots of information which affects the initiation of
|
||||
@ -1441,16 +1424,6 @@ void CMSCollector::collect(bool full,
|
||||
size_t size,
|
||||
bool tlab)
|
||||
{
|
||||
if (!UseCMSCollectionPassing && _collectorState > Idling) {
|
||||
// For debugging purposes skip the collection if the state
|
||||
// is not currently idle
|
||||
if (TraceCMSState) {
|
||||
gclog_or_tty->print_cr("Thread " INTPTR_FORMAT " skipped full:%d CMS state %d",
|
||||
Thread::current(), full, _collectorState);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// The following "if" branch is present for defensive reasons.
|
||||
// In the current uses of this interface, it can be replaced with:
|
||||
// assert(!GC_locker.is_active(), "Can't be called otherwise");
|
||||
@ -1466,7 +1439,6 @@ void CMSCollector::collect(bool full,
|
||||
return;
|
||||
}
|
||||
acquire_control_and_collect(full, clear_all_soft_refs);
|
||||
_full_gcs_since_conc_gc++;
|
||||
}
|
||||
|
||||
void CMSCollector::request_full_gc(unsigned int full_gc_count, GCCause::Cause cause) {
|
||||
@ -1636,66 +1608,52 @@ void CMSCollector::acquire_control_and_collect(bool full,
|
||||
gclog_or_tty->print_cr(" gets control with state %d", _collectorState);
|
||||
}
|
||||
|
||||
// Check if we need to do a compaction, or if not, whether
|
||||
// we need to start the mark-sweep from scratch.
|
||||
bool should_compact = false;
|
||||
bool should_start_over = false;
|
||||
decide_foreground_collection_type(clear_all_soft_refs,
|
||||
&should_compact, &should_start_over);
|
||||
|
||||
NOT_PRODUCT(
|
||||
if (RotateCMSCollectionTypes) {
|
||||
if (_cmsGen->debug_collection_type() ==
|
||||
ConcurrentMarkSweepGeneration::MSC_foreground_collection_type) {
|
||||
should_compact = true;
|
||||
} else if (_cmsGen->debug_collection_type() ==
|
||||
ConcurrentMarkSweepGeneration::MS_foreground_collection_type) {
|
||||
should_compact = false;
|
||||
}
|
||||
// Inform cms gen if this was due to partial collection failing.
|
||||
// The CMS gen may use this fact to determine its expansion policy.
|
||||
GenCollectedHeap* gch = GenCollectedHeap::heap();
|
||||
if (gch->incremental_collection_will_fail(false /* don't consult_young */)) {
|
||||
assert(!_cmsGen->incremental_collection_failed(),
|
||||
"Should have been noticed, reacted to and cleared");
|
||||
_cmsGen->set_incremental_collection_failed();
|
||||
}
|
||||
)
|
||||
|
||||
if (first_state > Idling) {
|
||||
report_concurrent_mode_interruption();
|
||||
}
|
||||
|
||||
set_did_compact(should_compact);
|
||||
if (should_compact) {
|
||||
// If the collection is being acquired from the background
|
||||
// collector, there may be references on the discovered
|
||||
// references lists that have NULL referents (being those
|
||||
// that were concurrently cleared by a mutator) or
|
||||
// that are no longer active (having been enqueued concurrently
|
||||
// by the mutator).
|
||||
// Scrub the list of those references because Mark-Sweep-Compact
|
||||
// code assumes referents are not NULL and that all discovered
|
||||
// Reference objects are active.
|
||||
ref_processor()->clean_up_discovered_references();
|
||||
set_did_compact(true);
|
||||
|
||||
if (first_state > Idling) {
|
||||
save_heap_summary();
|
||||
}
|
||||
// If the collection is being acquired from the background
|
||||
// collector, there may be references on the discovered
|
||||
// references lists that have NULL referents (being those
|
||||
// that were concurrently cleared by a mutator) or
|
||||
// that are no longer active (having been enqueued concurrently
|
||||
// by the mutator).
|
||||
// Scrub the list of those references because Mark-Sweep-Compact
|
||||
// code assumes referents are not NULL and that all discovered
|
||||
// Reference objects are active.
|
||||
ref_processor()->clean_up_discovered_references();
|
||||
|
||||
do_compaction_work(clear_all_soft_refs);
|
||||
|
||||
// Has the GC time limit been exceeded?
|
||||
DefNewGeneration* young_gen = _young_gen->as_DefNewGeneration();
|
||||
size_t max_eden_size = young_gen->max_capacity() -
|
||||
young_gen->to()->capacity() -
|
||||
young_gen->from()->capacity();
|
||||
GenCollectedHeap* gch = GenCollectedHeap::heap();
|
||||
GCCause::Cause gc_cause = gch->gc_cause();
|
||||
size_policy()->check_gc_overhead_limit(_young_gen->used(),
|
||||
young_gen->eden()->used(),
|
||||
_cmsGen->max_capacity(),
|
||||
max_eden_size,
|
||||
full,
|
||||
gc_cause,
|
||||
gch->collector_policy());
|
||||
} else {
|
||||
do_mark_sweep_work(clear_all_soft_refs, first_state,
|
||||
should_start_over);
|
||||
if (first_state > Idling) {
|
||||
save_heap_summary();
|
||||
}
|
||||
|
||||
do_compaction_work(clear_all_soft_refs);
|
||||
|
||||
// Has the GC time limit been exceeded?
|
||||
DefNewGeneration* young_gen = _young_gen->as_DefNewGeneration();
|
||||
size_t max_eden_size = young_gen->max_capacity() -
|
||||
young_gen->to()->capacity() -
|
||||
young_gen->from()->capacity();
|
||||
GCCause::Cause gc_cause = gch->gc_cause();
|
||||
size_policy()->check_gc_overhead_limit(_young_gen->used(),
|
||||
young_gen->eden()->used(),
|
||||
_cmsGen->max_capacity(),
|
||||
max_eden_size,
|
||||
full,
|
||||
gc_cause,
|
||||
gch->collector_policy());
|
||||
|
||||
// Reset the expansion cause, now that we just completed
|
||||
// a collection cycle.
|
||||
clear_expansion_cause();
|
||||
@ -1713,68 +1671,6 @@ void CMSCollector::compute_new_size() {
|
||||
_cmsGen->compute_new_size_free_list();
|
||||
}
|
||||
|
||||
// A work method used by foreground collection to determine
|
||||
// what type of collection (compacting or not, continuing or fresh)
|
||||
// it should do.
|
||||
// NOTE: the intent is to make UseCMSCompactAtFullCollection
|
||||
// and CMSCompactWhenClearAllSoftRefs the default in the future
|
||||
// and do away with the flags after a suitable period.
|
||||
void CMSCollector::decide_foreground_collection_type(
|
||||
bool clear_all_soft_refs, bool* should_compact,
|
||||
bool* should_start_over) {
|
||||
// Normally, we'll compact only if the UseCMSCompactAtFullCollection
|
||||
// flag is set, and we have either requested a System.gc() or
|
||||
// the number of full gc's since the last concurrent cycle
|
||||
// has exceeded the threshold set by CMSFullGCsBeforeCompaction,
|
||||
// or if an incremental collection has failed
|
||||
GenCollectedHeap* gch = GenCollectedHeap::heap();
|
||||
assert(gch->collector_policy()->is_generation_policy(),
|
||||
"You may want to check the correctness of the following");
|
||||
// Inform cms gen if this was due to partial collection failing.
|
||||
// The CMS gen may use this fact to determine its expansion policy.
|
||||
if (gch->incremental_collection_will_fail(false /* don't consult_young */)) {
|
||||
assert(!_cmsGen->incremental_collection_failed(),
|
||||
"Should have been noticed, reacted to and cleared");
|
||||
_cmsGen->set_incremental_collection_failed();
|
||||
}
|
||||
*should_compact =
|
||||
UseCMSCompactAtFullCollection &&
|
||||
((_full_gcs_since_conc_gc >= CMSFullGCsBeforeCompaction) ||
|
||||
GCCause::is_user_requested_gc(gch->gc_cause()) ||
|
||||
gch->incremental_collection_will_fail(true /* consult_young */));
|
||||
*should_start_over = false;
|
||||
if (clear_all_soft_refs && !*should_compact) {
|
||||
// We are about to do a last ditch collection attempt
|
||||
// so it would normally make sense to do a compaction
|
||||
// to reclaim as much space as possible.
|
||||
if (CMSCompactWhenClearAllSoftRefs) {
|
||||
// Default: The rationale is that in this case either
|
||||
// we are past the final marking phase, in which case
|
||||
// we'd have to start over, or so little has been done
|
||||
// that there's little point in saving that work. Compaction
|
||||
// appears to be the sensible choice in either case.
|
||||
*should_compact = true;
|
||||
} else {
|
||||
// We have been asked to clear all soft refs, but not to
|
||||
// compact. Make sure that we aren't past the final checkpoint
|
||||
// phase, for that is where we process soft refs. If we are already
|
||||
// past that phase, we'll need to redo the refs discovery phase and
|
||||
// if necessary clear soft refs that weren't previously
|
||||
// cleared. We do so by remembering the phase in which
|
||||
// we came in, and if we are past the refs processing
|
||||
// phase, we'll choose to just redo the mark-sweep
|
||||
// collection from scratch.
|
||||
if (_collectorState > FinalMarking) {
|
||||
// We are past the refs processing phase;
|
||||
// start over and do a fresh synchronous CMS cycle
|
||||
_collectorState = Resetting; // skip to reset to start new cycle
|
||||
reset(false /* == !asynch */);
|
||||
*should_start_over = true;
|
||||
} // else we can continue a possibly ongoing current cycle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A work method used by the foreground collector to do
|
||||
// a mark-sweep-compact.
|
||||
void CMSCollector::do_compaction_work(bool clear_all_soft_refs) {
|
||||
@ -1787,10 +1683,6 @@ void CMSCollector::do_compaction_work(bool clear_all_soft_refs) {
|
||||
gc_tracer->report_gc_start(gch->gc_cause(), gc_timer->gc_start());
|
||||
|
||||
GCTraceTime t("CMS:MSC ", PrintGCDetails && Verbose, true, NULL, gc_tracer->gc_id());
|
||||
if (PrintGC && Verbose && !(GCCause::is_user_requested_gc(gch->gc_cause()))) {
|
||||
gclog_or_tty->print_cr("Compact ConcurrentMarkSweepGeneration after %d "
|
||||
"collections passed to foreground collector", _full_gcs_since_conc_gc);
|
||||
}
|
||||
|
||||
// Temporarily widen the span of the weak reference processing to
|
||||
// the entire heap.
|
||||
@ -1852,7 +1744,7 @@ void CMSCollector::do_compaction_work(bool clear_all_soft_refs) {
|
||||
_collectorState = Resetting;
|
||||
assert(_restart_addr == NULL,
|
||||
"Should have been NULL'd before baton was passed");
|
||||
reset(false /* == !asynch */);
|
||||
reset(false /* == !concurrent */);
|
||||
_cmsGen->reset_after_compaction();
|
||||
_concurrent_cycles_since_last_unload = 0;
|
||||
|
||||
@ -1875,40 +1767,6 @@ void CMSCollector::do_compaction_work(bool clear_all_soft_refs) {
|
||||
// in the heap's do_collection() method.
|
||||
}
|
||||
|
||||
// A work method used by the foreground collector to do
|
||||
// a mark-sweep, after taking over from a possibly on-going
|
||||
// concurrent mark-sweep collection.
|
||||
void CMSCollector::do_mark_sweep_work(bool clear_all_soft_refs,
|
||||
CollectorState first_state, bool should_start_over) {
|
||||
if (PrintGC && Verbose) {
|
||||
gclog_or_tty->print_cr("Pass concurrent collection to foreground "
|
||||
"collector with count %d",
|
||||
_full_gcs_since_conc_gc);
|
||||
}
|
||||
switch (_collectorState) {
|
||||
case Idling:
|
||||
if (first_state == Idling || should_start_over) {
|
||||
// The background GC was not active, or should
|
||||
// restarted from scratch; start the cycle.
|
||||
_collectorState = InitialMarking;
|
||||
}
|
||||
// If first_state was not Idling, then a background GC
|
||||
// was in progress and has now finished. No need to do it
|
||||
// again. Leave the state as Idling.
|
||||
break;
|
||||
case Precleaning:
|
||||
// In the foreground case don't do the precleaning since
|
||||
// it is not done concurrently and there is extra work
|
||||
// required.
|
||||
_collectorState = FinalMarking;
|
||||
}
|
||||
collect_in_foreground(clear_all_soft_refs, GenCollectedHeap::heap()->gc_cause());
|
||||
|
||||
// For a mark-sweep, compute_new_size() will be called
|
||||
// in the heap's do_collection() method.
|
||||
}
|
||||
|
||||
|
||||
void CMSCollector::print_eden_and_survivor_chunk_arrays() {
|
||||
DefNewGeneration* dng = _young_gen->as_DefNewGeneration();
|
||||
ContiguousSpace* eden_space = dng->eden();
|
||||
@ -1989,13 +1847,7 @@ class ReleaseForegroundGC: public StackObj {
|
||||
}
|
||||
};
|
||||
|
||||
// There are separate collect_in_background and collect_in_foreground because of
|
||||
// the different locking requirements of the background collector and the
|
||||
// foreground collector. There was originally an attempt to share
|
||||
// one "collect" method between the background collector and the foreground
|
||||
// collector but the if-then-else required made it cleaner to have
|
||||
// separate methods.
|
||||
void CMSCollector::collect_in_background(bool clear_all_soft_refs, GCCause::Cause cause) {
|
||||
void CMSCollector::collect_in_background(GCCause::Cause cause) {
|
||||
assert(Thread::current()->is_ConcurrentGC_thread(),
|
||||
"A CMS asynchronous collection is only allowed on a CMS thread.");
|
||||
|
||||
@ -2036,7 +1888,7 @@ void CMSCollector::collect_in_background(bool clear_all_soft_refs, GCCause::Caus
|
||||
// Used for PrintGC
|
||||
size_t prev_used;
|
||||
if (PrintGC && Verbose) {
|
||||
prev_used = _cmsGen->used(); // XXXPERM
|
||||
prev_used = _cmsGen->used();
|
||||
}
|
||||
|
||||
// The change of the collection state is normally done at this level;
|
||||
@ -2116,7 +1968,7 @@ void CMSCollector::collect_in_background(bool clear_all_soft_refs, GCCause::Caus
|
||||
break;
|
||||
case Marking:
|
||||
// initial marking in checkpointRootsInitialWork has been completed
|
||||
if (markFromRoots(true)) { // we were successful
|
||||
if (markFromRoots()) { // we were successful
|
||||
assert(_collectorState == Precleaning, "Collector state should "
|
||||
"have changed");
|
||||
} else {
|
||||
@ -2146,10 +1998,9 @@ void CMSCollector::collect_in_background(bool clear_all_soft_refs, GCCause::Caus
|
||||
break;
|
||||
case Sweeping:
|
||||
// final marking in checkpointRootsFinal has been completed
|
||||
sweep(true);
|
||||
sweep();
|
||||
assert(_collectorState == Resizing, "Collector state change "
|
||||
"to Resizing must be done under the free_list_lock");
|
||||
_full_gcs_since_conc_gc = 0;
|
||||
|
||||
case Resizing: {
|
||||
// Sweeping has been completed...
|
||||
@ -2222,12 +2073,6 @@ void CMSCollector::collect_in_background(bool clear_all_soft_refs, GCCause::Caus
|
||||
}
|
||||
}
|
||||
|
||||
void CMSCollector::register_foreground_gc_start(GCCause::Cause cause) {
|
||||
if (!_cms_start_registered) {
|
||||
register_gc_start(cause);
|
||||
}
|
||||
}
|
||||
|
||||
void CMSCollector::register_gc_start(GCCause::Cause cause) {
|
||||
_cms_start_registered = true;
|
||||
_gc_timer_cm->register_gc_start();
|
||||
@ -2255,120 +2100,6 @@ void CMSCollector::report_heap_summary(GCWhen::Type when) {
|
||||
_gc_tracer_cm->report_metaspace_summary(when, _last_metaspace_summary);
|
||||
}
|
||||
|
||||
void CMSCollector::collect_in_foreground(bool clear_all_soft_refs, GCCause::Cause cause) {
|
||||
assert(_foregroundGCIsActive && !_foregroundGCShouldWait,
|
||||
"Foreground collector should be waiting, not executing");
|
||||
assert(Thread::current()->is_VM_thread(), "A foreground collection"
|
||||
"may only be done by the VM Thread with the world stopped");
|
||||
assert(ConcurrentMarkSweepThread::vm_thread_has_cms_token(),
|
||||
"VM thread should have CMS token");
|
||||
|
||||
// The gc id is created in register_foreground_gc_start if this collection is synchronous
|
||||
const GCId gc_id = _collectorState == InitialMarking ? GCId::peek() : _gc_tracer_cm->gc_id();
|
||||
NOT_PRODUCT(GCTraceTime t("CMS:MS (foreground) ", PrintGCDetails && Verbose,
|
||||
true, NULL, gc_id);)
|
||||
COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact);
|
||||
|
||||
HandleMark hm; // Discard invalid handles created during verification
|
||||
|
||||
if (VerifyBeforeGC &&
|
||||
GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
|
||||
Universe::verify();
|
||||
}
|
||||
|
||||
// Snapshot the soft reference policy to be used in this collection cycle.
|
||||
ref_processor()->setup_policy(clear_all_soft_refs);
|
||||
|
||||
// Decide if class unloading should be done
|
||||
update_should_unload_classes();
|
||||
|
||||
bool init_mark_was_synchronous = false; // until proven otherwise
|
||||
while (_collectorState != Idling) {
|
||||
if (TraceCMSState) {
|
||||
gclog_or_tty->print_cr("Thread " INTPTR_FORMAT " in CMS state %d",
|
||||
Thread::current(), _collectorState);
|
||||
}
|
||||
switch (_collectorState) {
|
||||
case InitialMarking:
|
||||
register_foreground_gc_start(cause);
|
||||
init_mark_was_synchronous = true; // fact to be exploited in re-mark
|
||||
checkpointRootsInitial(false);
|
||||
assert(_collectorState == Marking, "Collector state should have changed"
|
||||
" within checkpointRootsInitial()");
|
||||
break;
|
||||
case Marking:
|
||||
// initial marking in checkpointRootsInitialWork has been completed
|
||||
if (VerifyDuringGC &&
|
||||
GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
|
||||
Universe::verify("Verify before initial mark: ");
|
||||
}
|
||||
{
|
||||
bool res = markFromRoots(false);
|
||||
assert(res && _collectorState == FinalMarking, "Collector state should "
|
||||
"have changed");
|
||||
break;
|
||||
}
|
||||
case FinalMarking:
|
||||
if (VerifyDuringGC &&
|
||||
GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
|
||||
Universe::verify("Verify before re-mark: ");
|
||||
}
|
||||
checkpointRootsFinal(false, clear_all_soft_refs,
|
||||
init_mark_was_synchronous);
|
||||
assert(_collectorState == Sweeping, "Collector state should not "
|
||||
"have changed within checkpointRootsFinal()");
|
||||
break;
|
||||
case Sweeping:
|
||||
// final marking in checkpointRootsFinal has been completed
|
||||
if (VerifyDuringGC &&
|
||||
GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
|
||||
Universe::verify("Verify before sweep: ");
|
||||
}
|
||||
sweep(false);
|
||||
assert(_collectorState == Resizing, "Incorrect state");
|
||||
break;
|
||||
case Resizing: {
|
||||
// Sweeping has been completed; the actual resize in this case
|
||||
// is done separately; nothing to be done in this state.
|
||||
_collectorState = Resetting;
|
||||
break;
|
||||
}
|
||||
case Resetting:
|
||||
// The heap has been resized.
|
||||
if (VerifyDuringGC &&
|
||||
GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
|
||||
Universe::verify("Verify before reset: ");
|
||||
}
|
||||
save_heap_summary();
|
||||
reset(false);
|
||||
assert(_collectorState == Idling, "Collector state should "
|
||||
"have changed");
|
||||
break;
|
||||
case Precleaning:
|
||||
case AbortablePreclean:
|
||||
// Elide the preclean phase
|
||||
_collectorState = FinalMarking;
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
if (TraceCMSState) {
|
||||
gclog_or_tty->print_cr(" Thread " INTPTR_FORMAT " done - next CMS state %d",
|
||||
Thread::current(), _collectorState);
|
||||
}
|
||||
}
|
||||
|
||||
if (VerifyAfterGC &&
|
||||
GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
|
||||
Universe::verify();
|
||||
}
|
||||
if (TraceCMSState) {
|
||||
gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT
|
||||
" exiting collection CMS state %d",
|
||||
Thread::current(), _collectorState);
|
||||
}
|
||||
}
|
||||
|
||||
bool CMSCollector::waitForForegroundGC() {
|
||||
bool res = false;
|
||||
assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
|
||||
@ -3345,7 +3076,7 @@ class CMSParInitialMarkTask: public CMSParMarkTask {
|
||||
// Checkpoint the roots into this generation from outside
|
||||
// this generation. [Note this initial checkpoint need only
|
||||
// be approximate -- we'll do a catch up phase subsequently.]
|
||||
void CMSCollector::checkpointRootsInitial(bool asynch) {
|
||||
void CMSCollector::checkpointRootsInitial() {
|
||||
assert(_collectorState == InitialMarking, "Wrong collector state");
|
||||
check_correct_thread_executing();
|
||||
TraceCMSMemoryManagerStats tms(_collectorState,GenCollectedHeap::heap()->gc_cause());
|
||||
@ -3356,32 +3087,19 @@ void CMSCollector::checkpointRootsInitial(bool asynch) {
|
||||
ReferenceProcessor* rp = ref_processor();
|
||||
SpecializationStats::clear();
|
||||
assert(_restart_addr == NULL, "Control point invariant");
|
||||
if (asynch) {
|
||||
{
|
||||
// acquire locks for subsequent manipulations
|
||||
MutexLockerEx x(bitMapLock(),
|
||||
Mutex::_no_safepoint_check_flag);
|
||||
checkpointRootsInitialWork(asynch);
|
||||
checkpointRootsInitialWork();
|
||||
// enable ("weak") refs discovery
|
||||
rp->enable_discovery(true /*verify_disabled*/, true /*check_no_refs*/);
|
||||
_collectorState = Marking;
|
||||
} else {
|
||||
// (Weak) Refs discovery: this is controlled from genCollectedHeap::do_collection
|
||||
// which recognizes if we are a CMS generation, and doesn't try to turn on
|
||||
// discovery; verify that they aren't meddling.
|
||||
assert(!rp->discovery_is_atomic(),
|
||||
"incorrect setting of discovery predicate");
|
||||
assert(!rp->discovery_enabled(), "genCollectedHeap shouldn't control "
|
||||
"ref discovery for this generation kind");
|
||||
// already have locks
|
||||
checkpointRootsInitialWork(asynch);
|
||||
// now enable ("weak") refs discovery
|
||||
rp->enable_discovery(true /*verify_disabled*/, false /*verify_no_refs*/);
|
||||
_collectorState = Marking;
|
||||
}
|
||||
SpecializationStats::print();
|
||||
}
|
||||
|
||||
void CMSCollector::checkpointRootsInitialWork(bool asynch) {
|
||||
void CMSCollector::checkpointRootsInitialWork() {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "world should be stopped");
|
||||
assert(_collectorState == InitialMarking, "just checking");
|
||||
|
||||
@ -3483,9 +3201,9 @@ void CMSCollector::checkpointRootsInitialWork(bool asynch) {
|
||||
verify_overflow_empty();
|
||||
}
|
||||
|
||||
bool CMSCollector::markFromRoots(bool asynch) {
|
||||
bool CMSCollector::markFromRoots() {
|
||||
// we might be tempted to assert that:
|
||||
// assert(asynch == !SafepointSynchronize::is_at_safepoint(),
|
||||
// assert(!SafepointSynchronize::is_at_safepoint(),
|
||||
// "inconsistent argument?");
|
||||
// However that wouldn't be right, because it's possible that
|
||||
// a safepoint is indeed in progress as a younger generation
|
||||
@ -3494,37 +3212,28 @@ bool CMSCollector::markFromRoots(bool asynch) {
|
||||
check_correct_thread_executing();
|
||||
verify_overflow_empty();
|
||||
|
||||
bool res;
|
||||
if (asynch) {
|
||||
// Weak ref discovery note: We may be discovering weak
|
||||
// refs in this generation concurrent (but interleaved) with
|
||||
// weak ref discovery by a younger generation collector.
|
||||
// Weak ref discovery note: We may be discovering weak
|
||||
// refs in this generation concurrent (but interleaved) with
|
||||
// weak ref discovery by a younger generation collector.
|
||||
|
||||
CMSTokenSyncWithLocks ts(true, bitMapLock());
|
||||
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
|
||||
CMSPhaseAccounting pa(this, "mark", _gc_tracer_cm->gc_id(), !PrintGCDetails);
|
||||
res = markFromRootsWork(asynch);
|
||||
if (res) {
|
||||
_collectorState = Precleaning;
|
||||
} else { // We failed and a foreground collection wants to take over
|
||||
assert(_foregroundGCIsActive, "internal state inconsistency");
|
||||
assert(_restart_addr == NULL, "foreground will restart from scratch");
|
||||
if (PrintGCDetails) {
|
||||
gclog_or_tty->print_cr("bailing out to foreground collection");
|
||||
}
|
||||
CMSTokenSyncWithLocks ts(true, bitMapLock());
|
||||
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
|
||||
CMSPhaseAccounting pa(this, "mark", _gc_tracer_cm->gc_id(), !PrintGCDetails);
|
||||
bool res = markFromRootsWork();
|
||||
if (res) {
|
||||
_collectorState = Precleaning;
|
||||
} else { // We failed and a foreground collection wants to take over
|
||||
assert(_foregroundGCIsActive, "internal state inconsistency");
|
||||
assert(_restart_addr == NULL, "foreground will restart from scratch");
|
||||
if (PrintGCDetails) {
|
||||
gclog_or_tty->print_cr("bailing out to foreground collection");
|
||||
}
|
||||
} else {
|
||||
assert(SafepointSynchronize::is_at_safepoint(),
|
||||
"inconsistent with asynch == false");
|
||||
// already have locks
|
||||
res = markFromRootsWork(asynch);
|
||||
_collectorState = FinalMarking;
|
||||
}
|
||||
verify_overflow_empty();
|
||||
return res;
|
||||
}
|
||||
|
||||
bool CMSCollector::markFromRootsWork(bool asynch) {
|
||||
bool CMSCollector::markFromRootsWork() {
|
||||
// iterate over marked bits in bit map, doing a full scan and mark
|
||||
// from these roots using the following algorithm:
|
||||
// . if oop is to the right of the current scan pointer,
|
||||
@ -3549,9 +3258,9 @@ bool CMSCollector::markFromRootsWork(bool asynch) {
|
||||
verify_overflow_empty();
|
||||
bool result = false;
|
||||
if (CMSConcurrentMTEnabled && ConcGCThreads > 0) {
|
||||
result = do_marking_mt(asynch);
|
||||
result = do_marking_mt();
|
||||
} else {
|
||||
result = do_marking_st(asynch);
|
||||
result = do_marking_st();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -3591,7 +3300,6 @@ class CMSConcMarkingTerminatorTerminator: public TerminatorTerminator {
|
||||
class CMSConcMarkingTask: public YieldingFlexibleGangTask {
|
||||
CMSCollector* _collector;
|
||||
int _n_workers; // requested/desired # workers
|
||||
bool _asynch;
|
||||
bool _result;
|
||||
CompactibleFreeListSpace* _cms_space;
|
||||
char _pad_front[64]; // padding to ...
|
||||
@ -3612,13 +3320,12 @@ class CMSConcMarkingTask: public YieldingFlexibleGangTask {
|
||||
public:
|
||||
CMSConcMarkingTask(CMSCollector* collector,
|
||||
CompactibleFreeListSpace* cms_space,
|
||||
bool asynch,
|
||||
YieldingFlexibleWorkGang* workers,
|
||||
OopTaskQueueSet* task_queues):
|
||||
YieldingFlexibleGangTask("Concurrent marking done multi-threaded"),
|
||||
_collector(collector),
|
||||
_cms_space(cms_space),
|
||||
_asynch(asynch), _n_workers(0), _result(true),
|
||||
_n_workers(0), _result(true),
|
||||
_task_queues(task_queues),
|
||||
_term(_n_workers, task_queues, _collector),
|
||||
_bit_map_lock(collector->bitMapLock())
|
||||
@ -3645,8 +3352,7 @@ class CMSConcMarkingTask: public YieldingFlexibleGangTask {
|
||||
void work(uint worker_id);
|
||||
bool should_yield() {
|
||||
return ConcurrentMarkSweepThread::should_yield()
|
||||
&& !_collector->foregroundGCIsActive()
|
||||
&& _asynch;
|
||||
&& !_collector->foregroundGCIsActive();
|
||||
}
|
||||
|
||||
virtual void coordinator_yield(); // stuff done by coordinator
|
||||
@ -3878,8 +3584,7 @@ void CMSConcMarkingTask::do_scan_and_mark(int i, CompactibleFreeListSpace* sp) {
|
||||
Par_MarkFromRootsClosure cl(this, _collector, my_span,
|
||||
&_collector->_markBitMap,
|
||||
work_queue(i),
|
||||
&_collector->_markStack,
|
||||
_asynch);
|
||||
&_collector->_markStack);
|
||||
_collector->_markBitMap.iterate(&cl, my_span.start(), my_span.end());
|
||||
} // else nothing to do for this task
|
||||
} // else nothing to do for this task
|
||||
@ -4084,7 +3789,7 @@ void CMSConcMarkingTask::coordinator_yield() {
|
||||
_collector->startTimer();
|
||||
}
|
||||
|
||||
bool CMSCollector::do_marking_mt(bool asynch) {
|
||||
bool CMSCollector::do_marking_mt() {
|
||||
assert(ConcGCThreads > 0 && conc_workers() != NULL, "precondition");
|
||||
int num_workers = AdaptiveSizePolicy::calc_active_conc_workers(
|
||||
conc_workers()->total_workers(),
|
||||
@ -4096,7 +3801,6 @@ bool CMSCollector::do_marking_mt(bool asynch) {
|
||||
|
||||
CMSConcMarkingTask tsk(this,
|
||||
cms_space,
|
||||
asynch,
|
||||
conc_workers(),
|
||||
task_queues());
|
||||
|
||||
@ -4125,7 +3829,7 @@ bool CMSCollector::do_marking_mt(bool asynch) {
|
||||
// If _restart_addr is non-NULL, a marking stack overflow
|
||||
// occurred; we need to do a fresh marking iteration from the
|
||||
// indicated restart address.
|
||||
if (_foregroundGCIsActive && asynch) {
|
||||
if (_foregroundGCIsActive) {
|
||||
// We may be running into repeated stack overflows, having
|
||||
// reached the limit of the stack size, while making very
|
||||
// slow forward progress. It may be best to bail out and
|
||||
@ -4154,14 +3858,14 @@ bool CMSCollector::do_marking_mt(bool asynch) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMSCollector::do_marking_st(bool asynch) {
|
||||
bool CMSCollector::do_marking_st() {
|
||||
ResourceMark rm;
|
||||
HandleMark hm;
|
||||
|
||||
// Temporarily make refs discovery single threaded (non-MT)
|
||||
ReferenceProcessorMTDiscoveryMutator rp_mut_discovery(ref_processor(), false);
|
||||
MarkFromRootsClosure markFromRootsClosure(this, _span, &_markBitMap,
|
||||
&_markStack, CMSYield && asynch);
|
||||
&_markStack, CMSYield);
|
||||
// the last argument to iterate indicates whether the iteration
|
||||
// should be incremental with periodic yields.
|
||||
_markBitMap.iterate(&markFromRootsClosure);
|
||||
@ -4169,7 +3873,7 @@ bool CMSCollector::do_marking_st(bool asynch) {
|
||||
// occurred; we need to do a fresh iteration from the
|
||||
// indicated restart address.
|
||||
while (_restart_addr != NULL) {
|
||||
if (_foregroundGCIsActive && asynch) {
|
||||
if (_foregroundGCIsActive) {
|
||||
// We may be running into repeated stack overflows, having
|
||||
// reached the limit of the stack size, while making very
|
||||
// slow forward progress. It may be best to bail out and
|
||||
@ -4703,8 +4407,7 @@ void CMSCollector::preclean_klasses(MarkRefsIntoAndScanClosure* cl, Mutex* freel
|
||||
verify_overflow_empty();
|
||||
}
|
||||
|
||||
void CMSCollector::checkpointRootsFinal(bool asynch,
|
||||
bool clear_all_soft_refs, bool init_mark_was_synchronous) {
|
||||
void CMSCollector::checkpointRootsFinal() {
|
||||
assert(_collectorState == FinalMarking, "incorrect state transition?");
|
||||
check_correct_thread_executing();
|
||||
// world is stopped at this checkpoint
|
||||
@ -4721,7 +4424,7 @@ void CMSCollector::checkpointRootsFinal(bool asynch,
|
||||
_young_gen->used() / K,
|
||||
_young_gen->capacity() / K);
|
||||
}
|
||||
if (asynch) {
|
||||
{
|
||||
if (CMSScavengeBeforeRemark) {
|
||||
GenCollectedHeap* gch = GenCollectedHeap::heap();
|
||||
// Temporarily set flag to false, GCH->do_collection will
|
||||
@ -4742,21 +4445,14 @@ void CMSCollector::checkpointRootsFinal(bool asynch,
|
||||
FreelistLocker x(this);
|
||||
MutexLockerEx y(bitMapLock(),
|
||||
Mutex::_no_safepoint_check_flag);
|
||||
assert(!init_mark_was_synchronous, "but that's impossible!");
|
||||
checkpointRootsFinalWork(asynch, clear_all_soft_refs, false);
|
||||
} else {
|
||||
// already have all the locks
|
||||
checkpointRootsFinalWork(asynch, clear_all_soft_refs,
|
||||
init_mark_was_synchronous);
|
||||
checkpointRootsFinalWork();
|
||||
}
|
||||
verify_work_stacks_empty();
|
||||
verify_overflow_empty();
|
||||
SpecializationStats::print();
|
||||
}
|
||||
|
||||
void CMSCollector::checkpointRootsFinalWork(bool asynch,
|
||||
bool clear_all_soft_refs, bool init_mark_was_synchronous) {
|
||||
|
||||
void CMSCollector::checkpointRootsFinalWork() {
|
||||
NOT_PRODUCT(GCTraceTime tr("checkpointRootsFinalWork", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());)
|
||||
|
||||
assert(haveFreelistLocks(), "must have free list locks");
|
||||
@ -4773,60 +4469,54 @@ void CMSCollector::checkpointRootsFinalWork(bool asynch,
|
||||
assert(haveFreelistLocks(), "must have free list locks");
|
||||
assert_lock_strong(bitMapLock());
|
||||
|
||||
if (!init_mark_was_synchronous) {
|
||||
// We might assume that we need not fill TLAB's when
|
||||
// CMSScavengeBeforeRemark is set, because we may have just done
|
||||
// a scavenge which would have filled all TLAB's -- and besides
|
||||
// Eden would be empty. This however may not always be the case --
|
||||
// for instance although we asked for a scavenge, it may not have
|
||||
// happened because of a JNI critical section. We probably need
|
||||
// a policy for deciding whether we can in that case wait until
|
||||
// the critical section releases and then do the remark following
|
||||
// the scavenge, and skip it here. In the absence of that policy,
|
||||
// or of an indication of whether the scavenge did indeed occur,
|
||||
// we cannot rely on TLAB's having been filled and must do
|
||||
// so here just in case a scavenge did not happen.
|
||||
gch->ensure_parsability(false); // fill TLAB's, but no need to retire them
|
||||
// Update the saved marks which may affect the root scans.
|
||||
gch->save_marks();
|
||||
// We might assume that we need not fill TLAB's when
|
||||
// CMSScavengeBeforeRemark is set, because we may have just done
|
||||
// a scavenge which would have filled all TLAB's -- and besides
|
||||
// Eden would be empty. This however may not always be the case --
|
||||
// for instance although we asked for a scavenge, it may not have
|
||||
// happened because of a JNI critical section. We probably need
|
||||
// a policy for deciding whether we can in that case wait until
|
||||
// the critical section releases and then do the remark following
|
||||
// the scavenge, and skip it here. In the absence of that policy,
|
||||
// or of an indication of whether the scavenge did indeed occur,
|
||||
// we cannot rely on TLAB's having been filled and must do
|
||||
// so here just in case a scavenge did not happen.
|
||||
gch->ensure_parsability(false); // fill TLAB's, but no need to retire them
|
||||
// Update the saved marks which may affect the root scans.
|
||||
gch->save_marks();
|
||||
|
||||
if (CMSPrintEdenSurvivorChunks) {
|
||||
print_eden_and_survivor_chunk_arrays();
|
||||
if (CMSPrintEdenSurvivorChunks) {
|
||||
print_eden_and_survivor_chunk_arrays();
|
||||
}
|
||||
|
||||
{
|
||||
COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
|
||||
|
||||
// Note on the role of the mod union table:
|
||||
// Since the marker in "markFromRoots" marks concurrently with
|
||||
// mutators, it is possible for some reachable objects not to have been
|
||||
// scanned. For instance, an only reference to an object A was
|
||||
// placed in object B after the marker scanned B. Unless B is rescanned,
|
||||
// A would be collected. Such updates to references in marked objects
|
||||
// are detected via the mod union table which is the set of all cards
|
||||
// dirtied since the first checkpoint in this GC cycle and prior to
|
||||
// the most recent young generation GC, minus those cleaned up by the
|
||||
// concurrent precleaning.
|
||||
if (CMSParallelRemarkEnabled && CollectedHeap::use_parallel_gc_threads()) {
|
||||
GCTraceTime t("Rescan (parallel) ", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());
|
||||
do_remark_parallel();
|
||||
} else {
|
||||
GCTraceTime t("Rescan (non-parallel) ", PrintGCDetails, false,
|
||||
_gc_timer_cm, _gc_tracer_cm->gc_id());
|
||||
do_remark_non_parallel();
|
||||
}
|
||||
|
||||
{
|
||||
COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
|
||||
|
||||
// Note on the role of the mod union table:
|
||||
// Since the marker in "markFromRoots" marks concurrently with
|
||||
// mutators, it is possible for some reachable objects not to have been
|
||||
// scanned. For instance, an only reference to an object A was
|
||||
// placed in object B after the marker scanned B. Unless B is rescanned,
|
||||
// A would be collected. Such updates to references in marked objects
|
||||
// are detected via the mod union table which is the set of all cards
|
||||
// dirtied since the first checkpoint in this GC cycle and prior to
|
||||
// the most recent young generation GC, minus those cleaned up by the
|
||||
// concurrent precleaning.
|
||||
if (CMSParallelRemarkEnabled && CollectedHeap::use_parallel_gc_threads()) {
|
||||
GCTraceTime t("Rescan (parallel) ", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());
|
||||
do_remark_parallel();
|
||||
} else {
|
||||
GCTraceTime t("Rescan (non-parallel) ", PrintGCDetails, false,
|
||||
_gc_timer_cm, _gc_tracer_cm->gc_id());
|
||||
do_remark_non_parallel();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
assert(!asynch, "Can't have init_mark_was_synchronous in asynch mode");
|
||||
// The initial mark was stop-world, so there's no rescanning to
|
||||
// do; go straight on to the next step below.
|
||||
}
|
||||
verify_work_stacks_empty();
|
||||
verify_overflow_empty();
|
||||
|
||||
{
|
||||
NOT_PRODUCT(GCTraceTime ts("refProcessingWork", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());)
|
||||
refProcessingWork(asynch, clear_all_soft_refs);
|
||||
refProcessingWork();
|
||||
}
|
||||
verify_work_stacks_empty();
|
||||
verify_overflow_empty();
|
||||
@ -5872,8 +5562,7 @@ void CMSRefProcTaskExecutor::execute(EnqueueTask& task)
|
||||
workers->run_task(&enq_task);
|
||||
}
|
||||
|
||||
void CMSCollector::refProcessingWork(bool asynch, bool clear_all_soft_refs) {
|
||||
|
||||
void CMSCollector::refProcessingWork() {
|
||||
ResourceMark rm;
|
||||
HandleMark hm;
|
||||
|
||||
@ -5881,7 +5570,7 @@ void CMSCollector::refProcessingWork(bool asynch, bool clear_all_soft_refs) {
|
||||
assert(rp->span().equals(_span), "Spans should be equal");
|
||||
assert(!rp->enqueuing_is_done(), "Enqueuing should not be complete");
|
||||
// Process weak references.
|
||||
rp->setup_policy(clear_all_soft_refs);
|
||||
rp->setup_policy(false);
|
||||
verify_work_stacks_empty();
|
||||
|
||||
CMSKeepAliveClosure cmsKeepAliveClosure(this, _span, &_markBitMap,
|
||||
@ -6005,7 +5694,7 @@ void CMSCollector::check_correct_thread_executing() {
|
||||
}
|
||||
#endif
|
||||
|
||||
void CMSCollector::sweep(bool asynch) {
|
||||
void CMSCollector::sweep() {
|
||||
assert(_collectorState == Sweeping, "just checking");
|
||||
check_correct_thread_executing();
|
||||
verify_work_stacks_empty();
|
||||
@ -6019,14 +5708,14 @@ void CMSCollector::sweep(bool asynch) {
|
||||
assert(!_intra_sweep_timer.is_active(), "Should not be active");
|
||||
_intra_sweep_timer.reset();
|
||||
_intra_sweep_timer.start();
|
||||
if (asynch) {
|
||||
{
|
||||
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
|
||||
CMSPhaseAccounting pa(this, "sweep", _gc_tracer_cm->gc_id(), !PrintGCDetails);
|
||||
// First sweep the old gen
|
||||
{
|
||||
CMSTokenSyncWithLocks ts(true, _cmsGen->freelistLock(),
|
||||
bitMapLock());
|
||||
sweepWork(_cmsGen, asynch);
|
||||
sweepWork(_cmsGen);
|
||||
}
|
||||
|
||||
// Update Universe::_heap_*_at_gc figures.
|
||||
@ -6040,13 +5729,6 @@ void CMSCollector::sweep(bool asynch) {
|
||||
Universe::update_heap_info_at_gc();
|
||||
_collectorState = Resizing;
|
||||
}
|
||||
} else {
|
||||
// already have needed locks
|
||||
sweepWork(_cmsGen, asynch);
|
||||
// Update heap occupancy information which is used as
|
||||
// input to soft ref clearing policy at the next gc.
|
||||
Universe::update_heap_info_at_gc();
|
||||
_collectorState = Resizing;
|
||||
}
|
||||
verify_work_stacks_empty();
|
||||
verify_overflow_empty();
|
||||
@ -6139,20 +5821,7 @@ void ConcurrentMarkSweepGeneration::update_gc_stats(int current_level,
|
||||
}
|
||||
}
|
||||
|
||||
void ConcurrentMarkSweepGeneration::rotate_debug_collection_type() {
|
||||
if (PrintGCDetails && Verbose) {
|
||||
gclog_or_tty->print("Rotate from %d ", _debug_collection_type);
|
||||
}
|
||||
_debug_collection_type = (CollectionTypes) (_debug_collection_type + 1);
|
||||
_debug_collection_type =
|
||||
(CollectionTypes) (_debug_collection_type % Unknown_collection_type);
|
||||
if (PrintGCDetails && Verbose) {
|
||||
gclog_or_tty->print_cr("to %d ", _debug_collection_type);
|
||||
}
|
||||
}
|
||||
|
||||
void CMSCollector::sweepWork(ConcurrentMarkSweepGeneration* gen,
|
||||
bool asynch) {
|
||||
void CMSCollector::sweepWork(ConcurrentMarkSweepGeneration* gen) {
|
||||
// We iterate over the space(s) underlying this generation,
|
||||
// checking the mark bit map to see if the bits corresponding
|
||||
// to specific blocks are marked or not. Blocks that are
|
||||
@ -6180,9 +5849,7 @@ void CMSCollector::sweepWork(ConcurrentMarkSweepGeneration* gen,
|
||||
|
||||
// check that we hold the requisite locks
|
||||
assert(have_cms_token(), "Should hold cms token");
|
||||
assert( (asynch && ConcurrentMarkSweepThread::cms_thread_has_cms_token())
|
||||
|| (!asynch && ConcurrentMarkSweepThread::vm_thread_has_cms_token()),
|
||||
"Should possess CMS token to sweep");
|
||||
assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(), "Should possess CMS token to sweep");
|
||||
assert_lock_strong(gen->freelistLock());
|
||||
assert_lock_strong(bitMapLock());
|
||||
|
||||
@ -6194,8 +5861,7 @@ void CMSCollector::sweepWork(ConcurrentMarkSweepGeneration* gen,
|
||||
gen->setNearLargestChunk();
|
||||
|
||||
{
|
||||
SweepClosure sweepClosure(this, gen, &_markBitMap,
|
||||
CMSYield && asynch);
|
||||
SweepClosure sweepClosure(this, gen, &_markBitMap, CMSYield);
|
||||
gen->cmsSpace()->blk_iterate_careful(&sweepClosure);
|
||||
// We need to free-up/coalesce garbage/blocks from a
|
||||
// co-terminal free run. This is done in the SweepClosure
|
||||
@ -6213,8 +5879,8 @@ void CMSCollector::sweepWork(ConcurrentMarkSweepGeneration* gen,
|
||||
|
||||
// Reset CMS data structures (for now just the marking bit map)
|
||||
// preparatory for the next cycle.
|
||||
void CMSCollector::reset(bool asynch) {
|
||||
if (asynch) {
|
||||
void CMSCollector::reset(bool concurrent) {
|
||||
if (concurrent) {
|
||||
CMSTokenSyncWithLocks ts(true, bitMapLock());
|
||||
|
||||
// If the state is not "Resetting", the foreground thread
|
||||
@ -6275,12 +5941,6 @@ void CMSCollector::reset(bool asynch) {
|
||||
_collectorState = Idling;
|
||||
}
|
||||
|
||||
NOT_PRODUCT(
|
||||
if (RotateCMSCollectionTypes) {
|
||||
_cmsGen->rotate_debug_collection_type();
|
||||
}
|
||||
)
|
||||
|
||||
register_gc_end();
|
||||
}
|
||||
|
||||
@ -6293,7 +5953,7 @@ void CMSCollector::do_CMS_operation(CMS_op_type op, GCCause::Cause gc_cause) {
|
||||
switch (op) {
|
||||
case CMS_op_checkpointRootsInitial: {
|
||||
SvcGCMarker sgcm(SvcGCMarker::OTHER);
|
||||
checkpointRootsInitial(true); // asynch
|
||||
checkpointRootsInitial();
|
||||
if (PrintGC) {
|
||||
_cmsGen->printOccupancy("initial-mark");
|
||||
}
|
||||
@ -6301,9 +5961,7 @@ void CMSCollector::do_CMS_operation(CMS_op_type op, GCCause::Cause gc_cause) {
|
||||
}
|
||||
case CMS_op_checkpointRootsFinal: {
|
||||
SvcGCMarker sgcm(SvcGCMarker::OTHER);
|
||||
checkpointRootsFinal(true, // asynch
|
||||
false, // !clear_all_soft_refs
|
||||
false); // !init_mark_was_synchronous
|
||||
checkpointRootsFinal();
|
||||
if (PrintGC) {
|
||||
_cmsGen->printOccupancy("remark");
|
||||
}
|
||||
@ -7193,8 +6851,7 @@ Par_MarkFromRootsClosure::Par_MarkFromRootsClosure(CMSConcMarkingTask* task,
|
||||
CMSCollector* collector, MemRegion span,
|
||||
CMSBitMap* bit_map,
|
||||
OopTaskQueue* work_queue,
|
||||
CMSMarkStack* overflow_stack,
|
||||
bool should_yield):
|
||||
CMSMarkStack* overflow_stack):
|
||||
_collector(collector),
|
||||
_whole_span(collector->_span),
|
||||
_span(span),
|
||||
@ -7202,7 +6859,6 @@ Par_MarkFromRootsClosure::Par_MarkFromRootsClosure(CMSConcMarkingTask* task,
|
||||
_mut(&collector->_modUnionTable),
|
||||
_work_queue(work_queue),
|
||||
_overflow_stack(overflow_stack),
|
||||
_yield(should_yield),
|
||||
_skip_bits(0),
|
||||
_task(task)
|
||||
{
|
||||
|
||||
@ -608,7 +608,6 @@ class CMSCollector: public CHeapObj<mtGC> {
|
||||
GCHeapSummary _last_heap_summary;
|
||||
MetaspaceSummary _last_metaspace_summary;
|
||||
|
||||
void register_foreground_gc_start(GCCause::Cause cause);
|
||||
void register_gc_start(GCCause::Cause cause);
|
||||
void register_gc_end();
|
||||
void save_heap_summary();
|
||||
@ -695,8 +694,6 @@ class CMSCollector: public CHeapObj<mtGC> {
|
||||
int _numYields;
|
||||
size_t _numDirtyCards;
|
||||
size_t _sweep_count;
|
||||
// Number of full gc's since the last concurrent gc.
|
||||
uint _full_gcs_since_conc_gc;
|
||||
|
||||
// Occupancy used for bootstrapping stats
|
||||
double _bootstrap_occupancy;
|
||||
@ -760,14 +757,14 @@ class CMSCollector: public CHeapObj<mtGC> {
|
||||
NOT_PRODUCT(bool par_simulate_overflow();) // MT version
|
||||
|
||||
// CMS work methods
|
||||
void checkpointRootsInitialWork(bool asynch); // Initial checkpoint work
|
||||
void checkpointRootsInitialWork(); // Initial checkpoint work
|
||||
|
||||
// A return value of false indicates failure due to stack overflow
|
||||
bool markFromRootsWork(bool asynch); // Concurrent marking work
|
||||
bool markFromRootsWork(); // Concurrent marking work
|
||||
|
||||
public: // FIX ME!!! only for testing
|
||||
bool do_marking_st(bool asynch); // Single-threaded marking
|
||||
bool do_marking_mt(bool asynch); // Multi-threaded marking
|
||||
bool do_marking_st(); // Single-threaded marking
|
||||
bool do_marking_mt(); // Multi-threaded marking
|
||||
|
||||
private:
|
||||
|
||||
@ -788,20 +785,19 @@ class CMSCollector: public CHeapObj<mtGC> {
|
||||
void reset_survivor_plab_arrays();
|
||||
|
||||
// Final (second) checkpoint work
|
||||
void checkpointRootsFinalWork(bool asynch, bool clear_all_soft_refs,
|
||||
bool init_mark_was_synchronous);
|
||||
void checkpointRootsFinalWork();
|
||||
// Work routine for parallel version of remark
|
||||
void do_remark_parallel();
|
||||
// Work routine for non-parallel version of remark
|
||||
void do_remark_non_parallel();
|
||||
// Reference processing work routine (during second checkpoint)
|
||||
void refProcessingWork(bool asynch, bool clear_all_soft_refs);
|
||||
void refProcessingWork();
|
||||
|
||||
// Concurrent sweeping work
|
||||
void sweepWork(ConcurrentMarkSweepGeneration* gen, bool asynch);
|
||||
void sweepWork(ConcurrentMarkSweepGeneration* gen);
|
||||
|
||||
// (Concurrent) resetting of support data structures
|
||||
void reset(bool asynch);
|
||||
void reset(bool concurrent);
|
||||
|
||||
// Clear _expansion_cause fields of constituent generations
|
||||
void clear_expansion_cause();
|
||||
@ -810,22 +806,10 @@ class CMSCollector: public CHeapObj<mtGC> {
|
||||
// used regions of each generation to limit the extent of sweep
|
||||
void save_sweep_limits();
|
||||
|
||||
// A work method used by foreground collection to determine
|
||||
// what type of collection (compacting or not, continuing or fresh)
|
||||
// it should do.
|
||||
void decide_foreground_collection_type(bool clear_all_soft_refs,
|
||||
bool* should_compact, bool* should_start_over);
|
||||
|
||||
// A work method used by the foreground collector to do
|
||||
// a mark-sweep-compact.
|
||||
void do_compaction_work(bool clear_all_soft_refs);
|
||||
|
||||
// A work method used by the foreground collector to do
|
||||
// a mark-sweep, after taking over from a possibly on-going
|
||||
// concurrent mark-sweep collection.
|
||||
void do_mark_sweep_work(bool clear_all_soft_refs,
|
||||
CollectorState first_state, bool should_start_over);
|
||||
|
||||
// Work methods for reporting concurrent mode interruption or failure
|
||||
bool is_external_interruption();
|
||||
void report_concurrent_mode_interruption();
|
||||
@ -868,15 +852,13 @@ class CMSCollector: public CHeapObj<mtGC> {
|
||||
// Locking checks
|
||||
NOT_PRODUCT(static bool have_cms_token();)
|
||||
|
||||
// XXXPERM bool should_collect(bool full, size_t size, bool tlab);
|
||||
bool shouldConcurrentCollect();
|
||||
|
||||
void collect(bool full,
|
||||
bool clear_all_soft_refs,
|
||||
size_t size,
|
||||
bool tlab);
|
||||
void collect_in_background(bool clear_all_soft_refs, GCCause::Cause cause);
|
||||
void collect_in_foreground(bool clear_all_soft_refs, GCCause::Cause cause);
|
||||
void collect_in_background(GCCause::Cause cause);
|
||||
|
||||
// In support of ExplicitGCInvokesConcurrent
|
||||
static void request_full_gc(unsigned int full_gc_count, GCCause::Cause cause);
|
||||
@ -928,18 +910,16 @@ class CMSCollector: public CHeapObj<mtGC> {
|
||||
void directAllocated(HeapWord* start, size_t size);
|
||||
|
||||
// Main CMS steps and related support
|
||||
void checkpointRootsInitial(bool asynch);
|
||||
bool markFromRoots(bool asynch); // a return value of false indicates failure
|
||||
// due to stack overflow
|
||||
void checkpointRootsInitial();
|
||||
bool markFromRoots(); // a return value of false indicates failure
|
||||
// due to stack overflow
|
||||
void preclean();
|
||||
void checkpointRootsFinal(bool asynch, bool clear_all_soft_refs,
|
||||
bool init_mark_was_synchronous);
|
||||
void sweep(bool asynch);
|
||||
void checkpointRootsFinal();
|
||||
void sweep();
|
||||
|
||||
// Check that the currently executing thread is the expected
|
||||
// one (foreground collector or background collector).
|
||||
static void check_correct_thread_executing() PRODUCT_RETURN;
|
||||
// XXXPERM void print_statistics() PRODUCT_RETURN;
|
||||
|
||||
bool is_cms_reachable(HeapWord* addr);
|
||||
|
||||
@ -1060,15 +1040,6 @@ class ConcurrentMarkSweepGeneration: public CardGeneration {
|
||||
// In support of MinChunkSize being larger than min object size
|
||||
const double _dilatation_factor;
|
||||
|
||||
enum CollectionTypes {
|
||||
Concurrent_collection_type = 0,
|
||||
MS_foreground_collection_type = 1,
|
||||
MSC_foreground_collection_type = 2,
|
||||
Unknown_collection_type = 3
|
||||
};
|
||||
|
||||
CollectionTypes _debug_collection_type;
|
||||
|
||||
// True if a compacting collection was done.
|
||||
bool _did_compact;
|
||||
bool did_compact() { return _did_compact; }
|
||||
@ -1152,7 +1123,7 @@ class ConcurrentMarkSweepGeneration: public CardGeneration {
|
||||
// hack to allow the collection of the younger gen first if the flag is
|
||||
// set.
|
||||
virtual bool full_collects_younger_generations() const {
|
||||
return UseCMSCompactAtFullCollection && !ScavengeBeforeFullGC;
|
||||
return !ScavengeBeforeFullGC;
|
||||
}
|
||||
|
||||
void space_iterate(SpaceClosure* blk, bool usedOnly = false);
|
||||
@ -1295,9 +1266,6 @@ class ConcurrentMarkSweepGeneration: public CardGeneration {
|
||||
// Resize the generation after a non-compacting
|
||||
// collection.
|
||||
void compute_new_size_free_list();
|
||||
|
||||
CollectionTypes debug_collection_type() { return _debug_collection_type; }
|
||||
void rotate_debug_collection_type();
|
||||
};
|
||||
|
||||
//
|
||||
@ -1344,7 +1312,6 @@ class Par_MarkFromRootsClosure: public BitMapClosure {
|
||||
CMSBitMap* _mut;
|
||||
OopTaskQueue* _work_queue;
|
||||
CMSMarkStack* _overflow_stack;
|
||||
bool _yield;
|
||||
int _skip_bits;
|
||||
HeapWord* _finger;
|
||||
HeapWord* _threshold;
|
||||
@ -1354,8 +1321,7 @@ class Par_MarkFromRootsClosure: public BitMapClosure {
|
||||
MemRegion span,
|
||||
CMSBitMap* bit_map,
|
||||
OopTaskQueue* work_queue,
|
||||
CMSMarkStack* overflow_stack,
|
||||
bool should_yield);
|
||||
CMSMarkStack* overflow_stack);
|
||||
bool do_bit(size_t offset);
|
||||
inline void do_yield_check();
|
||||
|
||||
|
||||
@ -398,8 +398,7 @@ inline void MarkFromRootsClosure::do_yield_check() {
|
||||
|
||||
inline void Par_MarkFromRootsClosure::do_yield_check() {
|
||||
if (ConcurrentMarkSweepThread::should_yield() &&
|
||||
!_collector->foregroundGCIsActive() &&
|
||||
_yield) {
|
||||
!_collector->foregroundGCIsActive()) {
|
||||
do_yield_work();
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,7 +134,7 @@ void ConcurrentMarkSweepThread::run() {
|
||||
if (_should_terminate) break;
|
||||
GCCause::Cause cause = _collector->_full_gc_requested ?
|
||||
_collector->_full_gc_cause : GCCause::_cms_concurrent_mark;
|
||||
_collector->collect_in_background(false, cause);
|
||||
_collector->collect_in_background(cause);
|
||||
}
|
||||
assert(_should_terminate, "just checking");
|
||||
// Check that the state of any protocol for synchronization
|
||||
|
||||
@ -42,8 +42,12 @@ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
|
||||
void VM_CMS_Operation::acquire_pending_list_lock() {
|
||||
// The caller may block while communicating
|
||||
// with the SLT thread in order to acquire/release the PLL.
|
||||
ConcurrentMarkSweepThread::slt()->
|
||||
manipulatePLL(SurrogateLockerThread::acquirePLL);
|
||||
SurrogateLockerThread* slt = ConcurrentMarkSweepThread::slt();
|
||||
if (slt != NULL) {
|
||||
slt->manipulatePLL(SurrogateLockerThread::acquirePLL);
|
||||
} else {
|
||||
SurrogateLockerThread::report_missing_slt();
|
||||
}
|
||||
}
|
||||
|
||||
void VM_CMS_Operation::release_and_notify_pending_list_lock() {
|
||||
|
||||
@ -1888,7 +1888,7 @@ jint G1CollectedHeap::initialize() {
|
||||
initialize_reserved_region((HeapWord*)heap_rs.base(), (HeapWord*)(heap_rs.base() + heap_rs.size()));
|
||||
|
||||
// Create the gen rem set (and barrier set) for the entire reserved region.
|
||||
_rem_set = collector_policy()->create_rem_set(reserved_region(), 2);
|
||||
_rem_set = collector_policy()->create_rem_set(reserved_region());
|
||||
set_barrier_set(rem_set()->bs());
|
||||
if (!barrier_set()->is_a(BarrierSet::G1SATBCTLogging)) {
|
||||
vm_exit_during_initialization("G1 requires a G1SATBLoggingCardTableModRefBS");
|
||||
@ -4270,10 +4270,11 @@ void G1ParCopyClosure<barrier, do_mark_object>::do_oop_work(T* p) {
|
||||
|
||||
if (state == G1CollectedHeap::InCSet) {
|
||||
oop forwardee;
|
||||
if (obj->is_forwarded()) {
|
||||
forwardee = obj->forwardee();
|
||||
markOop m = obj->mark();
|
||||
if (m->is_marked()) {
|
||||
forwardee = (oop) m->decode_pointer();
|
||||
} else {
|
||||
forwardee = _par_scan_state->copy_to_survivor_space(obj);
|
||||
forwardee = _par_scan_state->copy_to_survivor_space(obj, m);
|
||||
}
|
||||
assert(forwardee != NULL, "forwardee should not be NULL");
|
||||
oopDesc::encode_store_heap_oop(p, forwardee);
|
||||
|
||||
@ -150,7 +150,8 @@ void G1ParScanThreadState::trim_queue() {
|
||||
} while (!_refs->is_empty());
|
||||
}
|
||||
|
||||
oop G1ParScanThreadState::copy_to_survivor_space(oop const old) {
|
||||
oop G1ParScanThreadState::copy_to_survivor_space(oop const old,
|
||||
markOop const old_mark) {
|
||||
size_t word_sz = old->size();
|
||||
HeapRegion* from_region = _g1h->heap_region_containing_raw(old);
|
||||
// +1 to make the -1 indexes valid...
|
||||
@ -158,9 +159,8 @@ oop G1ParScanThreadState::copy_to_survivor_space(oop const old) {
|
||||
assert( (from_region->is_young() && young_index > 0) ||
|
||||
(!from_region->is_young() && young_index == 0), "invariant" );
|
||||
G1CollectorPolicy* g1p = _g1h->g1_policy();
|
||||
markOop m = old->mark();
|
||||
int age = m->has_displaced_mark_helper() ? m->displaced_mark_helper()->age()
|
||||
: m->age();
|
||||
uint age = old_mark->has_displaced_mark_helper() ? old_mark->displaced_mark_helper()->age()
|
||||
: old_mark->age();
|
||||
GCAllocPurpose alloc_purpose = g1p->evacuation_destination(from_region, age,
|
||||
word_sz);
|
||||
AllocationContext_t context = from_region->allocation_context();
|
||||
@ -196,30 +196,22 @@ oop G1ParScanThreadState::copy_to_survivor_space(oop const old) {
|
||||
alloc_purpose = to_region->is_young() ? GCAllocForSurvived : GCAllocForTenured;
|
||||
|
||||
if (g1p->track_object_age(alloc_purpose)) {
|
||||
// We could simply do obj->incr_age(). However, this causes a
|
||||
// performance issue. obj->incr_age() will first check whether
|
||||
// the object has a displaced mark by checking its mark word;
|
||||
// getting the mark word from the new location of the object
|
||||
// stalls. So, given that we already have the mark word and we
|
||||
// are about to install it anyway, it's better to increase the
|
||||
// age on the mark word, when the object does not have a
|
||||
// displaced mark word. We're not expecting many objects to have
|
||||
// a displaced marked word, so that case is not optimized
|
||||
// further (it could be...) and we simply call obj->incr_age().
|
||||
|
||||
if (m->has_displaced_mark_helper()) {
|
||||
// in this case, we have to install the mark word first,
|
||||
if (age < markOopDesc::max_age) {
|
||||
age++;
|
||||
}
|
||||
if (old_mark->has_displaced_mark_helper()) {
|
||||
// In this case, we have to install the mark word first,
|
||||
// otherwise obj looks to be forwarded (the old mark word,
|
||||
// which contains the forward pointer, was copied)
|
||||
obj->set_mark(m);
|
||||
obj->incr_age();
|
||||
obj->set_mark(old_mark);
|
||||
markOop new_mark = old_mark->displaced_mark_helper()->set_age(age);
|
||||
old_mark->set_displaced_mark_helper(new_mark);
|
||||
} else {
|
||||
m = m->incr_age();
|
||||
obj->set_mark(m);
|
||||
obj->set_mark(old_mark->set_age(age));
|
||||
}
|
||||
age_table()->add(obj, word_sz);
|
||||
age_table()->add(age, word_sz);
|
||||
} else {
|
||||
obj->set_mark(m);
|
||||
obj->set_mark(old_mark);
|
||||
}
|
||||
|
||||
if (G1StringDedup::is_enabled()) {
|
||||
|
||||
@ -195,7 +195,7 @@ class G1ParScanThreadState : public StackObj {
|
||||
inline void dispatch_reference(StarTask ref);
|
||||
public:
|
||||
|
||||
oop copy_to_survivor_space(oop const obj);
|
||||
oop copy_to_survivor_space(oop const obj, markOop const old_mark);
|
||||
|
||||
void trim_queue();
|
||||
|
||||
|
||||
@ -41,10 +41,11 @@ template <class T> void G1ParScanThreadState::do_oop_evac(T* p, HeapRegion* from
|
||||
G1CollectedHeap::in_cset_state_t in_cset_state = _g1h->in_cset_state(obj);
|
||||
if (in_cset_state == G1CollectedHeap::InCSet) {
|
||||
oop forwardee;
|
||||
if (obj->is_forwarded()) {
|
||||
forwardee = obj->forwardee();
|
||||
markOop m = obj->mark();
|
||||
if (m->is_marked()) {
|
||||
forwardee = (oop) m->decode_pointer();
|
||||
} else {
|
||||
forwardee = copy_to_survivor_space(obj);
|
||||
forwardee = copy_to_survivor_space(obj, m);
|
||||
}
|
||||
oopDesc::encode_store_heap_oop(p, forwardee);
|
||||
} else if (in_cset_state == G1CollectedHeap::IsHumongous) {
|
||||
|
||||
@ -32,9 +32,8 @@
|
||||
#include "runtime/orderAccess.inline.hpp"
|
||||
#include "runtime/thread.inline.hpp"
|
||||
|
||||
G1SATBCardTableModRefBS::G1SATBCardTableModRefBS(MemRegion whole_heap,
|
||||
int max_covered_regions) :
|
||||
CardTableModRefBSForCTRS(whole_heap, max_covered_regions)
|
||||
G1SATBCardTableModRefBS::G1SATBCardTableModRefBS(MemRegion whole_heap) :
|
||||
CardTableModRefBSForCTRS(whole_heap)
|
||||
{
|
||||
_kind = G1SATBCT;
|
||||
}
|
||||
@ -132,9 +131,8 @@ void G1SATBCardTableLoggingModRefBSChangedListener::on_commit(uint start_idx, si
|
||||
}
|
||||
|
||||
G1SATBCardTableLoggingModRefBS::
|
||||
G1SATBCardTableLoggingModRefBS(MemRegion whole_heap,
|
||||
int max_covered_regions) :
|
||||
G1SATBCardTableModRefBS(whole_heap, max_covered_regions),
|
||||
G1SATBCardTableLoggingModRefBS(MemRegion whole_heap) :
|
||||
G1SATBCardTableModRefBS(whole_heap),
|
||||
_dcqs(JavaThread::dirty_card_queue_set()),
|
||||
_listener()
|
||||
{
|
||||
|
||||
@ -50,8 +50,7 @@ public:
|
||||
// pre-marking object graph.
|
||||
static void enqueue(oop pre_val);
|
||||
|
||||
G1SATBCardTableModRefBS(MemRegion whole_heap,
|
||||
int max_covered_regions);
|
||||
G1SATBCardTableModRefBS(MemRegion whole_heap);
|
||||
|
||||
bool is_a(BarrierSet::Name bsn) {
|
||||
return bsn == BarrierSet::G1SATBCT || CardTableModRefBS::is_a(bsn);
|
||||
@ -152,8 +151,7 @@ class G1SATBCardTableLoggingModRefBS: public G1SATBCardTableModRefBS {
|
||||
return ReservedSpace::allocation_align_size_up(number_of_slots);
|
||||
}
|
||||
|
||||
G1SATBCardTableLoggingModRefBS(MemRegion whole_heap,
|
||||
int max_covered_regions);
|
||||
G1SATBCardTableLoggingModRefBS(MemRegion whole_heap);
|
||||
|
||||
virtual void initialize() { }
|
||||
virtual void initialize(G1RegionToSpaceMapper* mapper);
|
||||
|
||||
@ -1004,10 +1004,13 @@ HeapWord* G1OffsetTableContigSpace::cross_threshold(HeapWord* start,
|
||||
HeapWord* G1OffsetTableContigSpace::saved_mark_word() const {
|
||||
G1CollectedHeap* g1h = G1CollectedHeap::heap();
|
||||
assert( _gc_time_stamp <= g1h->get_gc_time_stamp(), "invariant" );
|
||||
if (_gc_time_stamp < g1h->get_gc_time_stamp())
|
||||
return top();
|
||||
else
|
||||
HeapWord* local_top = top();
|
||||
OrderAccess::loadload();
|
||||
if (_gc_time_stamp < g1h->get_gc_time_stamp()) {
|
||||
return local_top;
|
||||
} else {
|
||||
return Space::saved_mark_word();
|
||||
}
|
||||
}
|
||||
|
||||
void G1OffsetTableContigSpace::record_top_and_timestamp() {
|
||||
|
||||
@ -213,8 +213,12 @@ void VM_CGC_Operation::acquire_pending_list_lock() {
|
||||
assert(_needs_pll, "don't call this otherwise");
|
||||
// The caller may block while communicating
|
||||
// with the SLT thread in order to acquire/release the PLL.
|
||||
ConcurrentMarkThread::slt()->
|
||||
manipulatePLL(SurrogateLockerThread::acquirePLL);
|
||||
SurrogateLockerThread* slt = ConcurrentMarkThread::slt();
|
||||
if (slt != NULL) {
|
||||
slt->manipulatePLL(SurrogateLockerThread::acquirePLL);
|
||||
} else {
|
||||
SurrogateLockerThread::report_missing_slt();
|
||||
}
|
||||
}
|
||||
|
||||
void VM_CGC_Operation::release_and_notify_pending_list_lock() {
|
||||
|
||||
@ -53,8 +53,8 @@ class CardTableExtension : public CardTableModRefBS {
|
||||
verify_card = CardTableModRefBS::CT_MR_BS_last_reserved + 5
|
||||
};
|
||||
|
||||
CardTableExtension(MemRegion whole_heap, int max_covered_regions) :
|
||||
CardTableModRefBS(whole_heap, max_covered_regions) { }
|
||||
CardTableExtension(MemRegion whole_heap) :
|
||||
CardTableModRefBS(whole_heap) { }
|
||||
|
||||
// Too risky for the 4/10/02 putback
|
||||
// BarrierSet::Name kind() { return BarrierSet::CardTableExtension; }
|
||||
|
||||
@ -76,7 +76,7 @@ jint ParallelScavengeHeap::initialize() {
|
||||
|
||||
initialize_reserved_region((HeapWord*)heap_rs.base(), (HeapWord*)(heap_rs.base() + heap_rs.size()));
|
||||
|
||||
CardTableExtension* const barrier_set = new CardTableExtension(reserved_region(), 3);
|
||||
CardTableExtension* const barrier_set = new CardTableExtension(reserved_region());
|
||||
barrier_set->initialize();
|
||||
_barrier_set = barrier_set;
|
||||
oopDesc::set_bs(_barrier_set);
|
||||
|
||||
@ -55,7 +55,10 @@ class ageTable VALUE_OBJ_CLASS_SPEC {
|
||||
|
||||
// add entry
|
||||
void add(oop p, size_t oop_size) {
|
||||
uint age = p->age();
|
||||
add(p->age(), oop_size);
|
||||
}
|
||||
|
||||
void add(uint age, size_t oop_size) {
|
||||
assert(age > 0 && age < table_size, "invalid age of object");
|
||||
sizes[age] += oop_size;
|
||||
}
|
||||
|
||||
@ -138,6 +138,13 @@ SurrogateLockerThread* SurrogateLockerThread::make(TRAPS) {
|
||||
return res;
|
||||
}
|
||||
|
||||
void SurrogateLockerThread::report_missing_slt() {
|
||||
vm_exit_during_initialization(
|
||||
"GC before GC support fully initialized: "
|
||||
"SLT is needed but has not yet been created.");
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
void SurrogateLockerThread::manipulatePLL(SLT_msg_type msg) {
|
||||
MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
|
||||
assert(_buffer == empty, "Should be empty");
|
||||
|
||||
@ -93,6 +93,9 @@ class SurrogateLockerThread: public JavaThread {
|
||||
public:
|
||||
static SurrogateLockerThread* make(TRAPS);
|
||||
|
||||
// Terminate VM with error message that SLT needed but not yet created.
|
||||
static void report_missing_slt();
|
||||
|
||||
SurrogateLockerThread();
|
||||
|
||||
bool is_hidden_from_external_view() const { return true; }
|
||||
|
||||
@ -33,8 +33,8 @@
|
||||
#include "memory/referenceProcessorStats.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include "utilities/ticks.inline.hpp"
|
||||
|
||||
#if INCLUDE_ALL_GCS
|
||||
#include "gc_implementation/g1/evacuationInfo.hpp"
|
||||
#endif
|
||||
|
||||
@ -33,12 +33,11 @@
|
||||
#include "memory/allocation.hpp"
|
||||
#include "memory/metaspace.hpp"
|
||||
#include "memory/referenceType.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include "utilities/ticks.hpp"
|
||||
#if INCLUDE_ALL_GCS
|
||||
#include "gc_implementation/g1/g1YCTypes.hpp"
|
||||
#endif
|
||||
#include "utilities/macros.hpp"
|
||||
#include "utilities/ticks.hpp"
|
||||
|
||||
|
||||
class EvacuationInfo;
|
||||
class GCHeapSummary;
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
#include "runtime/os.hpp"
|
||||
#include "trace/tracing.hpp"
|
||||
#include "trace/traceBackend.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#if INCLUDE_ALL_GCS
|
||||
#include "gc_implementation/g1/evacuationInfo.hpp"
|
||||
#include "gc_implementation/g1/g1YCTypes.hpp"
|
||||
|
||||
@ -29,8 +29,8 @@
|
||||
#include "memory/heapInspection.hpp"
|
||||
#include "trace/tracing.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include "utilities/ticks.hpp"
|
||||
|
||||
#if INCLUDE_SERVICES
|
||||
|
||||
void ObjectCountEventSender::send(const KlassInfoEntry* entry, GCId gc_id, const Ticks& timestamp) {
|
||||
|
||||
@ -50,8 +50,7 @@ void* MetaspaceObj::operator new(size_t size, ClassLoaderData* loader_data,
|
||||
size_t word_size, bool read_only,
|
||||
MetaspaceObj::Type type, TRAPS) throw() {
|
||||
// Klass has it's own operator new
|
||||
return Metaspace::allocate(loader_data, word_size, read_only,
|
||||
type, CHECK_NULL);
|
||||
return Metaspace::allocate(loader_data, word_size, read_only, type, THREAD);
|
||||
}
|
||||
|
||||
bool MetaspaceObj::is_shared() const {
|
||||
|
||||
@ -49,7 +49,12 @@ public:
|
||||
TargetUninitialized = 1
|
||||
};
|
||||
protected:
|
||||
int _max_covered_regions;
|
||||
// Some barrier sets create tables whose elements correspond to parts of
|
||||
// the heap; the CardTableModRefBS is an example. Such barrier sets will
|
||||
// normally reserve space for such tables, and commit parts of the table
|
||||
// "covering" parts of the heap that are committed. At most one covered
|
||||
// region per generation is needed.
|
||||
static const int _max_covered_regions = 2;
|
||||
Name _kind;
|
||||
|
||||
public:
|
||||
@ -159,18 +164,6 @@ public:
|
||||
protected:
|
||||
virtual void write_region_work(MemRegion mr) = 0;
|
||||
public:
|
||||
|
||||
// Some barrier sets create tables whose elements correspond to parts of
|
||||
// the heap; the CardTableModRefBS is an example. Such barrier sets will
|
||||
// normally reserve space for such tables, and commit parts of the table
|
||||
// "covering" parts of the heap that are committed. The constructor is
|
||||
// passed the maximum number of independently committable subregions to
|
||||
// be covered, and the "resize_covered_region" function allows the
|
||||
// sub-parts of the heap to inform the barrier set of changes of their
|
||||
// sizes.
|
||||
BarrierSet(int max_covered_regions) :
|
||||
_max_covered_regions(max_covered_regions) {}
|
||||
|
||||
// Inform the BarrierSet that the the covered heap region that starts
|
||||
// with "base" has been changed to have the given size (possibly from 0,
|
||||
// for initialization.)
|
||||
|
||||
@ -23,8 +23,8 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include "gc_implementation/shared/allocationStats.hpp"
|
||||
#include "gc_implementation/shared/spaceDecorator.hpp"
|
||||
#include "memory/binaryTreeDictionary.hpp"
|
||||
#include "memory/freeList.hpp"
|
||||
#include "memory/freeBlockDictionary.hpp"
|
||||
@ -32,7 +32,6 @@
|
||||
#include "runtime/globals.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include "gc_implementation/shared/spaceDecorator.hpp"
|
||||
#if INCLUDE_ALL_GCS
|
||||
#include "gc_implementation/concurrentMarkSweep/adaptiveFreeList.hpp"
|
||||
#include "gc_implementation/concurrentMarkSweep/freeChunk.hpp"
|
||||
|
||||
@ -53,9 +53,8 @@ size_t CardTableModRefBS::compute_byte_map_size()
|
||||
return align_size_up(_guard_index + 1, MAX2(_page_size, granularity));
|
||||
}
|
||||
|
||||
CardTableModRefBS::CardTableModRefBS(MemRegion whole_heap,
|
||||
int max_covered_regions):
|
||||
ModRefBarrierSet(max_covered_regions),
|
||||
CardTableModRefBS::CardTableModRefBS(MemRegion whole_heap) :
|
||||
ModRefBarrierSet(),
|
||||
_whole_heap(whole_heap),
|
||||
_guard_index(0),
|
||||
_guard_region(),
|
||||
|
||||
@ -284,7 +284,7 @@ public:
|
||||
return bsn == BarrierSet::CardTableModRef || ModRefBarrierSet::is_a(bsn);
|
||||
}
|
||||
|
||||
CardTableModRefBS(MemRegion whole_heap, int max_covered_regions);
|
||||
CardTableModRefBS(MemRegion whole_heap);
|
||||
~CardTableModRefBS();
|
||||
|
||||
virtual void initialize();
|
||||
@ -482,9 +482,8 @@ protected:
|
||||
bool card_will_be_scanned(jbyte cv);
|
||||
bool card_may_have_been_dirty(jbyte cv);
|
||||
public:
|
||||
CardTableModRefBSForCTRS(MemRegion whole_heap,
|
||||
int max_covered_regions) :
|
||||
CardTableModRefBS(whole_heap, max_covered_regions) {}
|
||||
CardTableModRefBSForCTRS(MemRegion whole_heap) :
|
||||
CardTableModRefBS(whole_heap) {}
|
||||
|
||||
void set_CTRS(CardTableRS* rs) { _rs = rs; }
|
||||
};
|
||||
|
||||
@ -38,21 +38,18 @@
|
||||
#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
|
||||
#endif // INCLUDE_ALL_GCS
|
||||
|
||||
CardTableRS::CardTableRS(MemRegion whole_heap,
|
||||
int max_covered_regions) :
|
||||
CardTableRS::CardTableRS(MemRegion whole_heap) :
|
||||
GenRemSet(),
|
||||
_cur_youngergen_card_val(youngergenP1_card),
|
||||
_regions_to_iterate(max_covered_regions - 1)
|
||||
_cur_youngergen_card_val(youngergenP1_card)
|
||||
{
|
||||
#if INCLUDE_ALL_GCS
|
||||
if (UseG1GC) {
|
||||
_ct_bs = new G1SATBCardTableLoggingModRefBS(whole_heap,
|
||||
max_covered_regions);
|
||||
_ct_bs = new G1SATBCardTableLoggingModRefBS(whole_heap);
|
||||
} else {
|
||||
_ct_bs = new CardTableModRefBSForCTRS(whole_heap, max_covered_regions);
|
||||
_ct_bs = new CardTableModRefBSForCTRS(whole_heap);
|
||||
}
|
||||
#else
|
||||
_ct_bs = new CardTableModRefBSForCTRS(whole_heap, max_covered_regions);
|
||||
_ct_bs = new CardTableModRefBSForCTRS(whole_heap);
|
||||
#endif
|
||||
_ct_bs->initialize();
|
||||
set_bs(_ct_bs);
|
||||
|
||||
@ -83,7 +83,8 @@ class CardTableRS: public GenRemSet {
|
||||
|
||||
jbyte _cur_youngergen_card_val;
|
||||
|
||||
int _regions_to_iterate;
|
||||
// Number of generations, plus one for lingering PermGen issues in CardTableRS.
|
||||
static const int _regions_to_iterate = 3;
|
||||
|
||||
jbyte cur_youngergen_card_val() {
|
||||
return _cur_youngergen_card_val;
|
||||
@ -101,7 +102,7 @@ class CardTableRS: public GenRemSet {
|
||||
jbyte find_unused_youngergenP_card_value();
|
||||
|
||||
public:
|
||||
CardTableRS(MemRegion whole_heap, int max_covered_regions);
|
||||
CardTableRS(MemRegion whole_heap);
|
||||
~CardTableRS();
|
||||
|
||||
// *** GenRemSet functions.
|
||||
|
||||
@ -152,9 +152,8 @@ bool CollectorPolicy::use_should_clear_all_soft_refs(bool v) {
|
||||
return result;
|
||||
}
|
||||
|
||||
GenRemSet* CollectorPolicy::create_rem_set(MemRegion whole_heap,
|
||||
int max_covered_regions) {
|
||||
return new CardTableRS(whole_heap, max_covered_regions);
|
||||
GenRemSet* CollectorPolicy::create_rem_set(MemRegion whole_heap) {
|
||||
return new CardTableRS(whole_heap);
|
||||
}
|
||||
|
||||
void CollectorPolicy::cleared_all_soft_refs() {
|
||||
|
||||
@ -152,10 +152,7 @@ class CollectorPolicy : public CHeapObj<mtGC> {
|
||||
|
||||
virtual BarrierSet::Name barrier_set_name() = 0;
|
||||
|
||||
// Create the remembered set (to cover the given reserved region,
|
||||
// allowing breaking up into at most "max_covered_regions").
|
||||
virtual GenRemSet* create_rem_set(MemRegion reserved,
|
||||
int max_covered_regions);
|
||||
virtual GenRemSet* create_rem_set(MemRegion reserved);
|
||||
|
||||
// This method controls how a collector satisfies a request
|
||||
// for a block of memory. "gc_time_limit_was_exceeded" will
|
||||
|
||||
@ -23,14 +23,13 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#if INCLUDE_ALL_GCS
|
||||
#include "gc_implementation/concurrentMarkSweep/freeChunk.hpp"
|
||||
#endif // INCLUDE_ALL_GCS
|
||||
#include "memory/freeBlockDictionary.hpp"
|
||||
#include "memory/metachunk.hpp"
|
||||
#include "runtime/thread.inline.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#if INCLUDE_ALL_GCS
|
||||
#include "gc_implementation/concurrentMarkSweep/freeChunk.hpp"
|
||||
#endif // INCLUDE_ALL_GCS
|
||||
|
||||
#ifndef PRODUCT
|
||||
template <class Chunk> Mutex* FreeBlockDictionary<Chunk>::par_lock() const {
|
||||
|
||||
@ -31,7 +31,6 @@
|
||||
#include "runtime/mutex.hpp"
|
||||
#include "runtime/vmThread.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
#if INCLUDE_ALL_GCS
|
||||
#include "gc_implementation/concurrentMarkSweep/freeChunk.hpp"
|
||||
#endif // INCLUDE_ALL_GCS
|
||||
|
||||
@ -109,13 +109,11 @@ jint GenCollectedHeap::initialize() {
|
||||
|
||||
char* heap_address;
|
||||
size_t total_reserved = 0;
|
||||
int n_covered_regions = 0;
|
||||
ReservedSpace heap_rs;
|
||||
|
||||
size_t heap_alignment = collector_policy()->heap_alignment();
|
||||
|
||||
heap_address = allocate(heap_alignment, &total_reserved,
|
||||
&n_covered_regions, &heap_rs);
|
||||
heap_address = allocate(heap_alignment, &total_reserved, &heap_rs);
|
||||
|
||||
if (!heap_rs.is_reserved()) {
|
||||
vm_shutdown_during_initialization(
|
||||
@ -125,7 +123,7 @@ jint GenCollectedHeap::initialize() {
|
||||
|
||||
initialize_reserved_region((HeapWord*)heap_rs.base(), (HeapWord*)(heap_rs.base() + heap_rs.size()));
|
||||
|
||||
_rem_set = collector_policy()->create_rem_set(reserved_region(), n_covered_regions);
|
||||
_rem_set = collector_policy()->create_rem_set(reserved_region());
|
||||
set_barrier_set(rem_set()->bs());
|
||||
|
||||
_gch = this;
|
||||
@ -152,14 +150,12 @@ jint GenCollectedHeap::initialize() {
|
||||
|
||||
char* GenCollectedHeap::allocate(size_t alignment,
|
||||
size_t* _total_reserved,
|
||||
int* _n_covered_regions,
|
||||
ReservedSpace* heap_rs){
|
||||
const char overflow_msg[] = "The size of the object heap + VM data exceeds "
|
||||
"the maximum representable size";
|
||||
|
||||
// Now figure out the total size.
|
||||
size_t total_reserved = 0;
|
||||
int n_covered_regions = 0;
|
||||
const size_t pageSize = UseLargePages ?
|
||||
os::large_page_size() : os::vm_page_size();
|
||||
|
||||
@ -170,18 +166,12 @@ char* GenCollectedHeap::allocate(size_t alignment,
|
||||
if (total_reserved < _gen_specs[i]->max_size()) {
|
||||
vm_exit_during_initialization(overflow_msg);
|
||||
}
|
||||
n_covered_regions += _gen_specs[i]->n_covered_regions();
|
||||
}
|
||||
assert(total_reserved % alignment == 0,
|
||||
err_msg("Gen size; total_reserved=" SIZE_FORMAT ", alignment="
|
||||
SIZE_FORMAT, total_reserved, alignment));
|
||||
|
||||
// Needed until the cardtable is fixed to have the right number
|
||||
// of covered regions.
|
||||
n_covered_regions += 2;
|
||||
|
||||
*_total_reserved = total_reserved;
|
||||
*_n_covered_regions = n_covered_regions;
|
||||
|
||||
*heap_rs = Universe::reserve_heap(total_reserved, alignment);
|
||||
return heap_rs->base();
|
||||
|
||||
@ -121,9 +121,7 @@ public:
|
||||
|
||||
// Returns JNI_OK on success
|
||||
virtual jint initialize();
|
||||
char* allocate(size_t alignment,
|
||||
size_t* _total_reserved, int* _n_covered_regions,
|
||||
ReservedSpace* heap_rs);
|
||||
char* allocate(size_t alignment, size_t* _total_reserved, ReservedSpace* heap_rs);
|
||||
|
||||
// Does operations required after initialization has been done.
|
||||
void post_initialize();
|
||||
|
||||
@ -59,10 +59,6 @@ public:
|
||||
set_init_size(align_size_up(init_size(), alignment));
|
||||
set_max_size(align_size_up(max_size(), alignment));
|
||||
}
|
||||
|
||||
// Return the number of regions contained in the generation which
|
||||
// might need to be independently covered by a remembered set.
|
||||
virtual int n_covered_regions() const { return 1; }
|
||||
};
|
||||
|
||||
typedef GenerationSpec* GenerationSpecPtr;
|
||||
|
||||
@ -367,7 +367,7 @@ class HeapInspection : public StackObj {
|
||||
_csv_format(csv_format), _print_help(print_help),
|
||||
_print_class_stats(print_class_stats), _columns(columns) {}
|
||||
void heap_inspection(outputStream* st) NOT_SERVICES_RETURN;
|
||||
size_t populate_table(KlassInfoTable* cit, BoolObjectClosure* filter = NULL) NOT_SERVICES_RETURN;
|
||||
size_t populate_table(KlassInfoTable* cit, BoolObjectClosure* filter = NULL) NOT_SERVICES_RETURN_(0);
|
||||
static void find_instances_at_safepoint(Klass* k, GrowableArray<oop>* result) NOT_SERVICES_RETURN;
|
||||
private:
|
||||
void iterate_over_heap(KlassInfoTable* cit, BoolObjectClosure* filter = NULL);
|
||||
|
||||
@ -47,6 +47,7 @@
|
||||
#include "services/memoryService.hpp"
|
||||
#include "utilities/copy.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
|
||||
|
||||
@ -1411,7 +1412,7 @@ size_t MetaspaceGC::delta_capacity_until_GC(size_t bytes) {
|
||||
|
||||
size_t MetaspaceGC::capacity_until_GC() {
|
||||
size_t value = (size_t)OrderAccess::load_ptr_acquire(&_capacity_until_GC);
|
||||
assert(value >= MetaspaceSize, "Not initialied properly?");
|
||||
assert(value >= MetaspaceSize, "Not initialized properly?");
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@ -92,7 +92,7 @@ class MetaspaceShared : AllStatic {
|
||||
static void preload_and_dump(TRAPS) NOT_CDS_RETURN;
|
||||
static int preload_and_dump(const char * class_list_path,
|
||||
GrowableArray<Klass*>* class_promote_order,
|
||||
TRAPS) NOT_CDS_RETURN;
|
||||
TRAPS) NOT_CDS_RETURN_(0);
|
||||
|
||||
static ReservedSpace* shared_rs() {
|
||||
CDS_ONLY(return _shared_rs);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user