--- a/.hgtags Thu Mar 01 01:30:10 2018 +0100
+++ b/.hgtags Thu Mar 01 01:35:46 2018 +0100
@@ -471,3 +471,5 @@
107413b070b92c88bde6230ceb4a19b579781068 jdk-10+43
dfa46cfe56346884a61efdc30dc50f7505d66761 jdk-11+1
03ae177c26b016353e5ea1cab6ffd051dfa086ca jdk-11+2
+663f20fc51091bd7f95d18448850ba091207b7bd jdk-10+44
+4f96cf952e71cb8a127334494faf28880c26181b jdk-10+45
--- a/make/Docs.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/Docs.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -61,7 +61,7 @@
$(SUPPORT_OUTPUTDIR)/rmic/* $(TOPDIR)/src/*/share/doc/stub)
# URLs
-JAVADOC_BASE_URL := http://www.oracle.com/pls/topic/lookup?ctx=javase9&id=homepage
+JAVADOC_BASE_URL := http://www.oracle.com/pls/topic/lookup?ctx=javase10&id=homepage
BUG_SUBMIT_URL := http://bugreport.java.com/bugreport/
COPYRIGHT_URL := {@docroot}/../legal/copyright.html
LICENSE_URL := http://www.oracle.com/technetwork/java/javase/terms/license/java10speclicense.html
--- a/make/common/MakeBase.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/common/MakeBase.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -423,7 +423,7 @@
################################################################################
-MAX_PARAMS := 35
+MAX_PARAMS := 36
PARAM_SEQUENCE := $(call sequence, 2, $(MAX_PARAMS))
# Template for creating a macro taking named parameters. To use it, assign the
--- a/make/common/NativeCompilation.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/common/NativeCompilation.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -30,7 +30,7 @@
ifndef _NATIVE_COMPILATION_GMK
_NATIVE_COMPILATION_GMK := 1
-ifeq (,$(_MAKEBASE_GMK))
+ifeq ($(_MAKEBASE_GMK), )
$(error You must include MakeBase.gmk prior to including NativeCompilation.gmk)
endif
@@ -231,32 +231,32 @@
endif
endif
- ifneq (,$$(filter %.c,$2))
+ ifneq ($$(filter %.c, $2), )
# Compile as a C file
- $1_$2_FLAGS=$(CFLAGS_CCACHE) $$($1_$2_USE_PCH_FLAGS) $4 \
+ $1_$2_FLAGS := $(CFLAGS_CCACHE) $$($1_$2_USE_PCH_FLAGS) $4 \
$$($1_$(notdir $2)_OPT_CFLAGS) \
$$($1_$(notdir $2)_CFLAGS) $$($1_$2_THIS_FILE) -c
- $1_$2_COMP=$5
- $1_$2_DEP_FLAG:=$(C_FLAG_DEPS)
- else ifneq (,$$(filter %.m,$2))
+ $1_$2_COMP := $5
+ $1_$2_DEP_FLAG := $(C_FLAG_DEPS)
+ else ifneq ($$(filter %.m, $2), )
# Compile as an Objective-C file
- $1_$2_FLAGS=-x objective-c $(CFLAGS_CCACHE) $$($1_$2_USE_PCH_FLAGS) $4 \
+ $1_$2_FLAGS := -x objective-c $(CFLAGS_CCACHE) $$($1_$2_USE_PCH_FLAGS) $4 \
$$($1_$(notdir $2)_OPT_CFLAGS) \
$$($1_$(notdir $2)_CFLAGS) $$($1_$2_THIS_FILE) -c
- $1_$2_COMP=$5
- $1_$2_DEP_FLAG:=$(C_FLAG_DEPS)
- else ifneq (,$$(filter %.s %.S,$2))
+ $1_$2_COMP := $5
+ $1_$2_DEP_FLAG := $(C_FLAG_DEPS)
+ else ifneq ($$(filter %.s %.S, $2), )
# Compile as assembler file
- $1_$2_FLAGS=$8
- $1_$2_COMP=$(AS)
- $1_$2_DEP_FLAG:=
- else ifneq (,$$(filter %.cpp,$2)$$(filter %.cc,$2)$$(filter %.mm,$2))
+ $1_$2_FLAGS := $8
+ $1_$2_COMP := $(AS)
+ $1_$2_DEP_FLAG :=
+ else ifneq ($$(filter %.cpp, $2)$$(filter %.cc, $2)$$(filter %.mm, $2), )
# Compile as a C++ or Objective-C++ file
- $1_$2_FLAGS=$(CFLAGS_CCACHE) $$($1_$2_USE_PCH_FLAGS) $6 \
+ $1_$2_FLAGS := $(CFLAGS_CCACHE) $$($1_$2_USE_PCH_FLAGS) $6 \
$$($1_$(notdir $2)_OPT_CXXFLAGS) \
$$($1_$(notdir $2)_CXXFLAGS) $$($1_$2_THIS_FILE) -c
- $1_$2_COMP=$7
- $1_$2_DEP_FLAG:=$(CXX_FLAG_DEPS)
+ $1_$2_COMP := $7
+ $1_$2_DEP_FLAG := $(CXX_FLAG_DEPS)
else
$$(error Internal error in NativeCompilation.gmk: no compiler for file $2)
endif
@@ -264,14 +264,14 @@
$1_$2_OBJ := $3/$$(call replace_with_obj_extension, $$(notdir $2))
# Only continue if this object file hasn't been processed already. This lets the first found
# source file override any other with the same name.
- ifeq (,$$(findstring $$($1_$2_OBJ),$$($1_OBJS_SO_FAR)))
- $1_OBJS_SO_FAR+=$$($1_$2_OBJ)
- ifeq (,$$(filter %.s %.S,$2))
+ ifeq ($$(findstring $$($1_$2_OBJ), $$($1_OBJS_SO_FAR)), )
+ $1_OBJS_SO_FAR += $$($1_$2_OBJ)
+ ifeq ($$(filter %.s %.S, $2), )
# And this is the dependency file for this obj file.
- $1_$2_DEP:=$$(patsubst %$(OBJ_SUFFIX),%.d,$$($1_$2_OBJ))
+ $1_$2_DEP := $$(patsubst %$(OBJ_SUFFIX),%.d,$$($1_$2_OBJ))
# The dependency target file lists all dependencies as empty targets
# to avoid make error "No rule to make target" for removed files
- $1_$2_DEP_TARGETS:=$$(patsubst %$(OBJ_SUFFIX),%.d.targets,$$($1_$2_OBJ))
+ $1_$2_DEP_TARGETS := $$(patsubst %$(OBJ_SUFFIX),%.d.targets,$$($1_$2_OBJ))
# Include previously generated dependency information. (if it exists)
-include $$($1_$2_DEP)
@@ -280,7 +280,7 @@
ifeq ($(TOOLCHAIN_TYPE), microsoft)
# To avoid name clashes between pdbs for objects and libs/execs, put
# object pdbs in a separate subdir.
- $1_$2_DEBUG_OUT_FLAGS:=-Fd$$(strip $$(patsubst $$($1_OBJECT_DIR)/%, \
+ $1_$2_DEBUG_OUT_FLAGS := -Fd$$(strip $$(patsubst $$($1_OBJECT_DIR)/%, \
$$($1_OBJECT_DIR)/pdb/%, $$(patsubst %$(OBJ_SUFFIX),%.pdb,$$($1_$2_OBJ))))
endif
endif
@@ -293,10 +293,10 @@
endif
$$($1_$2_OBJ) : $2 $$($1_COMPILE_VARDEPS_FILE) $$($1_$2_VARDEPS_FILE) | $$($1_BUILD_INFO)
- $$(call LogInfo, Compiling $$(notdir $2) (for $$(notdir $$($1_TARGET))))
+ $$(call LogInfo, Compiling $$(notdir $2) (for $$($1_BASENAME)))
$$(call MakeDir, $$(@D) $$(@D)/pdb)
ifneq ($(TOOLCHAIN_TYPE), microsoft)
- ifeq ($(TOOLCHAIN_TYPE)$$(filter %.s,$2), solstudio)
+ ifeq ($(TOOLCHAIN_TYPE)$$(filter %.s, $2), solstudio)
# The Solaris studio compiler doesn't output the full path to the object file in the
# generated deps files. Fixing it with sed. If compiling assembly, don't try this.
$$(call ExecuteWithLog, $$@, \
@@ -308,7 +308,7 @@
endif
# Create a dependency target file from the dependency file.
# Solution suggested by http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/
- ifneq ($$($1_$2_DEP),)
+ ifneq ($$($1_$2_DEP), )
$(SED) $(DEPENDENCY_TARGET_SED_PATTERN) $$($1_$2_DEP) > $$($1_$2_DEP_TARGETS)
endif
else
@@ -338,6 +338,9 @@
# and the targets generated are listed in a variable by that name.
#
# Remaining parameters are named arguments. These include:
+# NAME The base name for the resulting binary, excluding decorations (like *.exe)
+# TYPE Type of binary (EXECUTABLE, LIBRARY or STATIC_LIBRARY). Default is LIBRARY.
+# SUFFIX Override the default suffix for the output file
# TOOLCHAIN Name of toolchain setup to use. Defaults to TOOLCHAIN_DEFAULT.
# SRC one or more directory roots to scan for C/C++ files.
# CFLAGS the compiler flags to be used, used both for C and C++.
@@ -347,8 +350,6 @@
# ARFLAGS the archiver flags to be used
# OBJECT_DIR the directory where we store the object files
# OUTPUT_DIR the directory where the resulting binary is put
-# LIBRARY the resulting library file
-# PROGRAM the resulting exec file
# INCLUDES only pick source from these directories
# EXCLUDES do not pick source from these directories
# INCLUDE_FILES only compile exactly these files!
@@ -385,105 +386,59 @@
SetupNativeCompilation = $(NamedParamsMacroTemplate)
define SetupNativeCompilationBody
+ # If type is unspecified, default to LIBRARY
+ ifeq ($$($1_TYPE), )
+ $1_TYPE := LIBRARY
+ endif
+
# If we're doing a static build and producing a library
# force it to be a static library and remove the -l libraries
ifeq ($(STATIC_BUILD), true)
- ifneq ($$($1_LIBRARY),)
- $1_STATIC_LIBRARY := $$($1_LIBRARY)
- $1_LIBRARY :=
+ ifeq ($$($1_TYPE), LIBRARY)
+ $1_TYPE := STATIC_LIBRARY
endif
endif
- ifneq (,$$($1_BIN))
- $$(error BIN has been replaced with OBJECT_DIR)
- endif
-
- ifneq (,$$($1_LIB))
- $$(error LIB has been replaced with LIBRARY)
- endif
-
- ifneq (,$$($1_EXE))
- $$(error EXE has been replaced with PROGRAM)
- endif
-
- ifneq (,$$($1_LIBRARY))
- ifeq (,$$($1_OUTPUT_DIR))
- $$(error LIBRARY requires OUTPUT_DIR)
- endif
-
- ifneq ($$($1_LIBRARY),$(basename $$($1_LIBRARY)))
- $$(error directory of LIBRARY should be specified using OUTPUT_DIR)
- endif
-
- ifneq (,$(findstring $(SHARED_LIBRARY_SUFFIX),$$($1_LIBRARY)))
- $$(error LIBRARY should be specified without SHARED_LIBRARY_SUFFIX: $(SHARED_LIBRARY_SUFFIX))
- endif
-
- ifneq (,$(findstring $(LIBRARY_PREFIX),$$($1_LIBRARY)))
- $$(error LIBRARY should be specified without LIBRARY_PREFIX: $(LIBRARY_PREFIX))
- endif
-
- ifeq ($$($1_SUFFIX), )
- $1_SUFFIX := $(SHARED_LIBRARY_SUFFIX)
- endif
-
- $1_BASENAME:=$(LIBRARY_PREFIX)$$($1_LIBRARY)$$($1_SUFFIX)
- $1_TARGET:=$$($1_OUTPUT_DIR)/$$($1_BASENAME)
- $1_NOSUFFIX:=$(LIBRARY_PREFIX)$$($1_LIBRARY)
- endif
-
- ifneq (,$$($1_STATIC_LIBRARY))
- ifeq (,$$($1_OUTPUT_DIR))
- $$(error STATIC_LIBRARY requires OUTPUT_DIR)
- endif
-
- ifneq ($$($1_STATIC_LIBRARY),$(basename $$($1_STATIC_LIBRARY)))
- $$(error directory of STATIC_LIBRARY should be specified using OUTPUT_DIR)
- endif
-
- ifneq (,$(findstring $(STATIC_LIBRARY_SUFFIX),$$($1_STATIC_LIBRARY)))
- $$(error STATIC_LIBRARY should be specified without STATIC_LIBRARY_SUFFIX: $(STATIC_LIBRARY_SUFFIX))
- endif
-
- ifneq (,$(findstring $(LIBRARY_PREFIX),$$($1_STATIC_LIBRARY)))
- $$(error STATIC_LIBRARY should be specified without LIBRARY_PREFIX: $(LIBRARY_PREFIX))
- endif
-
- ifeq ($$($1_SUFFIX), )
- $1_SUFFIX := $(STATIC_LIBRARY_SUFFIX)
- endif
-
- $1_BASENAME:=$(LIBRARY_PREFIX)$$($1_STATIC_LIBRARY)$$($1_SUFFIX)
- $1_TARGET:=$$($1_OUTPUT_DIR)/$$($1_BASENAME)
- $1_NOSUFFIX:=$(LIBRARY_PREFIX)$$($1_STATIC_LIBRARY)
- endif
-
- ifneq (,$$($1_PROGRAM))
- ifeq (,$$($1_OUTPUT_DIR))
- $$(error PROGRAM requires OUTPUT_DIR)
- endif
-
- ifneq ($$($1_PROGRAM),$(basename $$($1_PROGRAM)))
- $$(error directory of PROGRAM should be specified using OUTPUT_DIR)
- endif
-
- ifneq (,$(findstring $(EXE_SUFFIX),$$($1_PROGRAM)))
- $$(error PROGRAM should be specified without EXE_SUFFIX: $(EXE_SUFFIX))
- endif
-
+ ifeq ($$($1_TYPE), EXECUTABLE)
+ $1_PREFIX :=
ifeq ($$($1_SUFFIX), )
$1_SUFFIX := $(EXE_SUFFIX)
endif
+ else
+ $1_PREFIX := $(LIBRARY_PREFIX)
+ ifeq ($$($1_TYPE), LIBRARY)
+ ifeq ($$($1_SUFFIX), )
+ $1_SUFFIX := $(SHARED_LIBRARY_SUFFIX)
+ endif
+ else ifeq ($$($1_TYPE), STATIC_LIBRARY)
+ ifeq ($$($1_SUFFIX), )
+ $1_SUFFIX := $(STATIC_LIBRARY_SUFFIX)
+ endif
+ endif
+ endif
- $1_BASENAME:=$$($1_PROGRAM)$$($1_SUFFIX)
- $1_TARGET:=$$($1_OUTPUT_DIR)/$$($1_BASENAME)
- $1_NOSUFFIX:=$$($1_PROGRAM)
+ ifneq ($$($1_NAME), $(basename $$($1_NAME)))
+ $$(error NAME must not contain any directory path in $1)
endif
- $1_SAFE_NAME := $$(strip $$(subst /,_, $1))
+ ifneq ($(findstring $$($1_SUFFIX), $$($1_NAME)), )
+ $$(error NAME should be specified without suffix: $$($1_SUFFIX) in $1)
+ endif
+ ifneq ($(findstring $$($1_PREFIX), $$($1_NAME)), )
+ $$(error NAME should be specified without prefix: $$($1_PREFIX) in $1)
+ endif
+ ifeq ($$($1_OUTPUT_DIR), )
+ $$(error OUTPUT_DIR is missing in $1)
+ endif
+ ifneq ($$($1_MANIFEST), )
+ ifeq ($$($1_MANIFEST_VERSION), )
+ $$(error If MANIFEST is provided, then MANIFEST_VERSION is required in $1)
+ endif
+ endif
- ifeq (,$$($1_TARGET))
- $$(error Neither PROGRAM, LIBRARY nor STATIC_LIBRARY has been specified for SetupNativeCompilation)
- endif
+ $1_BASENAME := $$($1_PREFIX)$$($1_NAME)$$($1_SUFFIX)
+ $1_TARGET := $$($1_OUTPUT_DIR)/$$($1_BASENAME)
+ $1_NOSUFFIX := $$($1_PREFIX)$$($1_NAME)
+ $1_SAFE_NAME := $$(strip $$(subst /,_, $1))
# Setup the toolchain to be used
$$(call SetIfEmpty, $1_TOOLCHAIN, TOOLCHAIN_DEFAULT)
@@ -499,41 +454,35 @@
$$(call SetIfEmpty, $1_SYSROOT_CFLAGS, $$($$($1_TOOLCHAIN)_SYSROOT_CFLAGS))
$$(call SetIfEmpty, $1_SYSROOT_LDFLAGS, $$($$($1_TOOLCHAIN)_SYSROOT_LDFLAGS))
- ifneq ($$($1_MANIFEST), )
- ifeq ($$($1_MANIFEST_VERSION), )
- $$(error If MANIFEST is provided, then MANIFEST_VERSION is required in $1)
- endif
- endif
-
# Make sure the dirs exist.
- $$(call MakeDir,$$($1_OBJECT_DIR) $$($1_OUTPUT_DIR))
- $$(foreach d,$$($1_SRC), $$(if $$(wildcard $$d),, \
+ $$(call MakeDir, $$($1_OBJECT_DIR) $$($1_OUTPUT_DIR))
+ $$(foreach d, $$($1_SRC), $$(if $$(wildcard $$d), , \
$$(error SRC specified to SetupNativeCompilation $1 contains missing directory $$d)))
# Find all files in the source trees. Preserve order.
- $1_SRCS := $$(foreach s, $$($1_SRC), $$(call CacheFind,$$(s)))
+ $1_SRCS := $$(foreach s, $$($1_SRC), $$(call CacheFind, $$(s)))
$1_SRCS := $$(filter $$(NATIVE_SOURCE_EXTENSIONS), $$($1_SRCS))
# Extract the C/C++ files.
ifneq ($$($1_EXCLUDE_PATTERNS), )
# We must not match the exclude pattern against the src root(s).
$1_SRCS_WITHOUT_ROOTS := $$($1_SRCS)
- $$(foreach i,$$($1_SRC),$$(eval $1_SRCS_WITHOUT_ROOTS := $$(patsubst \
+ $$(foreach i, $$($1_SRC), $$(eval $1_SRCS_WITHOUT_ROOTS := $$(patsubst \
$$i/%,%, $$($1_SRCS_WITHOUT_ROOTS))))
$1_ALL_EXCLUDE_FILES := $$(call containing, $$($1_EXCLUDE_PATTERNS), \
$$($1_SRCS_WITHOUT_ROOTS))
endif
- ifneq ($$($1_EXCLUDE_FILES),)
+ ifneq ($$($1_EXCLUDE_FILES), )
$1_ALL_EXCLUDE_FILES += $$($1_EXCLUDE_FILES)
endif
- ifneq ($$($1_ALL_EXCLUDE_FILES),)
+ ifneq ($$($1_ALL_EXCLUDE_FILES), )
$1_EXCLUDE_FILES_PAT := $$($1_ALL_EXCLUDE_FILES) \
- $$(foreach i,$$($1_SRC),$$(addprefix $$i/,$$($1_ALL_EXCLUDE_FILES)))
- $1_EXCLUDE_FILES_PAT := $$(addprefix %,$$($1_EXCLUDE_FILES_PAT))
- $1_SRCS := $$(filter-out $$($1_EXCLUDE_FILES_PAT),$$($1_SRCS))
+ $$(foreach i, $$($1_SRC), $$(addprefix $$i/, $$($1_ALL_EXCLUDE_FILES)))
+ $1_EXCLUDE_FILES_PAT := $$(addprefix %, $$($1_EXCLUDE_FILES_PAT))
+ $1_SRCS := $$(filter-out $$($1_EXCLUDE_FILES_PAT), $$($1_SRCS))
endif
ifneq ($$($1_INCLUDE_FILES), )
- $1_INCLUDE_FILES_PAT := $$(foreach i,$$($1_SRC),$$(addprefix $$i/,$$($1_INCLUDE_FILES)))
- $1_SRCS := $$(filter $$($1_INCLUDE_FILES_PAT),$$($1_SRCS))
+ $1_INCLUDE_FILES_PAT := $$(foreach i, $$($1_SRC), $$(addprefix $$i/, $$($1_INCLUDE_FILES)))
+ $1_SRCS := $$(filter $$($1_INCLUDE_FILES_PAT), $$($1_SRCS))
endif
# There can be only a single bin dir root, no need to foreach over the roots.
$1_BINS := $$(wildcard $$($1_OBJECT_DIR)/*$(OBJ_SUFFIX))
@@ -541,29 +490,29 @@
# and we have a list of all existing object files: $$($1_BINS)
# Prepend the source/bin path to the filter expressions. Then do the filtering.
- ifneq ($$($1_INCLUDES),)
- $1_SRC_INCLUDES := $$(foreach i,$$($1_SRC),$$(addprefix $$i/,$$(addsuffix /%,$$($1_INCLUDES))))
- $1_SRCS := $$(filter $$($1_SRC_INCLUDES),$$($1_SRCS))
+ ifneq ($$($1_INCLUDES), )
+ $1_SRC_INCLUDES := $$(foreach i, $$($1_SRC), $$(addprefix $$i/, $$(addsuffix /%, $$($1_INCLUDES))))
+ $1_SRCS := $$(filter $$($1_SRC_INCLUDES), $$($1_SRCS))
endif
- ifneq ($$($1_EXCLUDES),)
- $1_SRC_EXCLUDES := $$(addsuffix /%,$$($1_EXCLUDES))
- $1_SRC_EXCLUDES += $$(foreach i,$$($1_SRC),$$(addprefix $$i/,$$(addsuffix /%,$$($1_EXCLUDES))))
- $1_SRCS := $$(filter-out $$($1_SRC_EXCLUDES),$$($1_SRCS))
+ ifneq ($$($1_EXCLUDES), )
+ $1_SRC_EXCLUDES := $$(addsuffix /%, $$($1_EXCLUDES))
+ $1_SRC_EXCLUDES += $$(foreach i, $$($1_SRC), $$(addprefix $$i/, $$(addsuffix /%, $$($1_EXCLUDES))))
+ $1_SRCS := $$(filter-out $$($1_SRC_EXCLUDES), $$($1_SRCS))
endif
$1_SRCS += $$($1_EXTRA_FILES)
- ifeq (,$$($1_SRCS))
+ ifeq ($$($1_SRCS), )
$$(error No sources found for $1 when looking inside the dirs $$($1_SRC))
endif
# Calculate the expected output from compiling the sources
$1_EXPECTED_OBJS_FILENAMES := $$(call replace_with_obj_extension, $$(notdir $$($1_SRCS)))
- $1_EXPECTED_OBJS := $$(addprefix $$($1_OBJECT_DIR)/,$$($1_EXPECTED_OBJS_FILENAMES))
+ $1_EXPECTED_OBJS := $$(addprefix $$($1_OBJECT_DIR)/, $$($1_EXPECTED_OBJS_FILENAMES))
# Are there too many object files on disk? Perhaps because some source file was removed?
- $1_SUPERFLOUS_OBJS:=$$(sort $$(filter-out $$($1_EXPECTED_OBJS),$$($1_BINS)))
+ $1_SUPERFLOUS_OBJS := $$(sort $$(filter-out $$($1_EXPECTED_OBJS), $$($1_BINS)))
# Clean out the superfluous object files.
- ifneq ($$($1_SUPERFLUOUS_OBJS),)
+ ifneq ($$($1_SUPERFLUOUS_OBJS), )
$$(shell $(RM) -f $$($1_SUPERFLUOUS_OBJS))
endif
# Sort to remove dupliates and provide a reproducable order on the input files to the linker.
@@ -571,42 +520,42 @@
# Pickup extra OPENJDK_TARGET_OS_TYPE, OPENJDK_TARGET_OS, and/or OPENJDK_TARGET_OS plus
# OPENJDK_TARGET_CPU pair dependent variables for CFLAGS.
- $1_EXTRA_CFLAGS:=$$($1_CFLAGS_$(OPENJDK_TARGET_OS_TYPE)) $$($1_CFLAGS_$(OPENJDK_TARGET_OS)) \
+ $1_EXTRA_CFLAGS := $$($1_CFLAGS_$(OPENJDK_TARGET_OS_TYPE)) $$($1_CFLAGS_$(OPENJDK_TARGET_OS)) \
$$($1_CFLAGS_$(OPENJDK_TARGET_OS)_$(OPENJDK_TARGET_CPU))
- ifneq ($(DEBUG_LEVEL),release)
+ ifneq ($(DEBUG_LEVEL), release)
# Pickup extra debug dependent variables for CFLAGS
- $1_EXTRA_CFLAGS+=$$($1_CFLAGS_debug)
- $1_EXTRA_CFLAGS+=$$($1_CFLAGS_$(OPENJDK_TARGET_OS_TYPE)_debug)
- $1_EXTRA_CFLAGS+=$$($1_CFLAGS_$(OPENJDK_TARGET_OS)_debug)
- $1_EXTRA_CFLAGS+=$$($1_CFLAGS_$(OPENJDK_TARGET_OS)_$(OPENJDK_TARGET_CPU)_debug)
+ $1_EXTRA_CFLAGS += $$($1_CFLAGS_debug)
+ $1_EXTRA_CFLAGS += $$($1_CFLAGS_$(OPENJDK_TARGET_OS_TYPE)_debug)
+ $1_EXTRA_CFLAGS += $$($1_CFLAGS_$(OPENJDK_TARGET_OS)_debug)
+ $1_EXTRA_CFLAGS += $$($1_CFLAGS_$(OPENJDK_TARGET_OS)_$(OPENJDK_TARGET_CPU)_debug)
else
- $1_EXTRA_CFLAGS+=$$($1_CFLAGS_release)
- $1_EXTRA_CFLAGS+=$$($1_CFLAGS_$(OPENJDK_TARGET_OS_TYPE)_release)
- $1_EXTRA_CFLAGS+=$$($1_CFLAGS_$(OPENJDK_TARGET_OS)_release)
- $1_EXTRA_CFLAGS+=$$($1_CFLAGS_$(OPENJDK_TARGET_OS)_$(OPENJDK_TARGET_CPU)_release)
+ $1_EXTRA_CFLAGS += $$($1_CFLAGS_release)
+ $1_EXTRA_CFLAGS += $$($1_CFLAGS_$(OPENJDK_TARGET_OS_TYPE)_release)
+ $1_EXTRA_CFLAGS += $$($1_CFLAGS_$(OPENJDK_TARGET_OS)_release)
+ $1_EXTRA_CFLAGS += $$($1_CFLAGS_$(OPENJDK_TARGET_OS)_$(OPENJDK_TARGET_CPU)_release)
endif
# Pickup extra OPENJDK_TARGET_OS_TYPE and/or OPENJDK_TARGET_OS dependent variables for CXXFLAGS.
- $1_EXTRA_CXXFLAGS:=$$($1_CXXFLAGS_$(OPENJDK_TARGET_OS_TYPE)) $$($1_CXXFLAGS_$(OPENJDK_TARGET_OS))
- ifneq ($(DEBUG_LEVEL),release)
+ $1_EXTRA_CXXFLAGS := $$($1_CXXFLAGS_$(OPENJDK_TARGET_OS_TYPE)) $$($1_CXXFLAGS_$(OPENJDK_TARGET_OS))
+ ifneq ($(DEBUG_LEVEL), release)
# Pickup extra debug dependent variables for CXXFLAGS
- $1_EXTRA_CXXFLAGS+=$$($1_CXXFLAGS_debug)
- $1_EXTRA_CXXFLAGS+=$$($1_CXXFLAGS_$(OPENJDK_TARGET_OS_TYPE)_debug)
- $1_EXTRA_CXXFLAGS+=$$($1_CXXFLAGS_$(OPENJDK_TARGET_OS)_debug)
+ $1_EXTRA_CXXFLAGS += $$($1_CXXFLAGS_debug)
+ $1_EXTRA_CXXFLAGS += $$($1_CXXFLAGS_$(OPENJDK_TARGET_OS_TYPE)_debug)
+ $1_EXTRA_CXXFLAGS += $$($1_CXXFLAGS_$(OPENJDK_TARGET_OS)_debug)
else
- $1_EXTRA_CXXFLAGS+=$$($1_CXXFLAGS_release)
- $1_EXTRA_CXXFLAGS+=$$($1_CXXFLAGS_$(OPENJDK_TARGET_OS_TYPE)_release)
- $1_EXTRA_CXXFLAGS+=$$($1_CXXFLAGS_$(OPENJDK_TARGET_OS)_release)
+ $1_EXTRA_CXXFLAGS += $$($1_CXXFLAGS_release)
+ $1_EXTRA_CXXFLAGS += $$($1_CXXFLAGS_$(OPENJDK_TARGET_OS_TYPE)_release)
+ $1_EXTRA_CXXFLAGS += $$($1_CXXFLAGS_$(OPENJDK_TARGET_OS)_release)
endif
# If no C++ flags are explicitly set, default to using the C flags.
# After that, we can set additional C++ flags that should not interfere
# with the mechanism for copying the C flags by default.
- ifeq ($$($1_CXXFLAGS),)
- $1_CXXFLAGS:=$$($1_CFLAGS)
+ ifeq ($$($1_CXXFLAGS), )
+ $1_CXXFLAGS := $$($1_CFLAGS)
endif
- ifeq ($$(strip $$($1_EXTRA_CXXFLAGS)),)
- $1_EXTRA_CXXFLAGS:=$$($1_EXTRA_CFLAGS)
+ ifeq ($$(strip $$($1_EXTRA_CXXFLAGS)), )
+ $1_EXTRA_CXXFLAGS := $$($1_EXTRA_CFLAGS)
endif
ifeq ($(COMPILE_WITH_DEBUG_SYMBOLS), true)
@@ -616,19 +565,19 @@
$1_EXTRA_CXXFLAGS += $$($1_CXXFLAGS_DEBUG_SYMBOLS)
endif
- ifneq (,$$($1_REORDER))
+ ifneq ($$($1_REORDER), )
$1_EXTRA_CFLAGS += $$(C_FLAG_REORDER)
$1_EXTRA_CXXFLAGS += $$(C_FLAG_REORDER)
endif
# Pass the library name for static JNI library naming
- ifneq ($$($1_STATIC_LIBRARY),)
- $1_EXTRA_CFLAGS += -DLIBRARY_NAME=$$($1_STATIC_LIBRARY)
- $1_EXTRA_CXXFLAGS += -DLIBRARY_NAME=$$($1_STATIC_LIBRARY)
+ ifeq ($$($1_TYPE), STATIC_LIBRARY)
+ $1_EXTRA_CFLAGS += -DLIBRARY_NAME=$$($1_NAME)
+ $1_EXTRA_CXXFLAGS += -DLIBRARY_NAME=$$($1_NAME)
endif
# Pick up disabled warnings, if possible on this platform.
- ifneq ($(DISABLE_WARNING_PREFIX),)
+ ifneq ($(DISABLE_WARNING_PREFIX), )
$1_EXTRA_CFLAGS += $$(addprefix $(DISABLE_WARNING_PREFIX), \
$$($1_DISABLED_WARNINGS_$(TOOLCHAIN_TYPE)) \
$$($1_DISABLED_WARNINGS_C_$(TOOLCHAIN_TYPE)))
@@ -639,8 +588,8 @@
# Check if warnings should be considered errors.
# Pick first binary and toolchain specific, then binary specific, then general setting.
- ifeq ($$($1_WARNINGS_AS_ERRORS_$(TOOLCHAIN_TYPE)),)
- ifeq ($$($1_WARNINGS_AS_ERRORS),)
+ ifeq ($$($1_WARNINGS_AS_ERRORS_$(TOOLCHAIN_TYPE)), )
+ ifeq ($$($1_WARNINGS_AS_ERRORS), )
$1_WARNINGS_AS_ERRORS_$(TOOLCHAIN_TYPE) := $$(WARNINGS_AS_ERRORS)
else
$1_WARNINGS_AS_ERRORS_$(TOOLCHAIN_TYPE) := $$($1_WARNINGS_AS_ERRORS)
@@ -740,7 +689,7 @@
endif
# Now call add_native_source for each source file we are going to compile.
- $$(foreach p,$$($1_SRCS), \
+ $$(foreach p, $$($1_SRCS), \
$$(eval $$(call add_native_source,$1,$$p,$$($1_OBJECT_DIR), \
$$($1_CFLAGS) $$($1_EXTRA_CFLAGS) $$($1_SYSROOT_CFLAGS), \
$$($1_CC), \
@@ -750,7 +699,7 @@
# Setup rule for printing progress info when compiling source files.
# This is a rough heuristic and may not always print accurate information.
$$($1_BUILD_INFO): $$($1_SRCS) $$($1_COMPILE_VARDEPS_FILE)
- ifeq ($$(wildcard $$($1_TARGET)),)
+ ifeq ($$(wildcard $$($1_TARGET)), )
$(ECHO) 'Creating $$(subst $$(OUTPUTDIR)/,,$$($1_TARGET)) from $$(words \
$$(filter-out %.vardeps, $$?)) file(s)'
else
@@ -763,10 +712,10 @@
# On windows we need to create a resource file
ifeq ($(OPENJDK_TARGET_OS), windows)
- ifneq (,$$($1_VERSIONINFO_RESOURCE))
- $1_RES:=$$($1_OBJECT_DIR)/$$($1_BASENAME).res
- $1_RES_DEP:=$$($1_RES).d
- $1_RES_DEP_TARGETS:=$$($1_RES).d.targets
+ ifneq ($$($1_VERSIONINFO_RESOURCE), )
+ $1_RES := $$($1_OBJECT_DIR)/$$($1_BASENAME).res
+ $1_RES_DEP := $$($1_RES).d
+ $1_RES_DEP_TARGETS := $$($1_RES).d.targets
-include $$($1_RES_DEP)
-include $$($1_RES_DEP_TARGETS)
@@ -775,7 +724,7 @@
$$($1_RES).vardeps)
$$($1_RES): $$($1_VERSIONINFO_RESOURCE) $$($1_RES_VARDEPS_FILE)
- $$(call LogInfo, Compiling resource $$(notdir $$($1_VERSIONINFO_RESOURCE)) (for $$(notdir $$($1_TARGET))))
+ $$(call LogInfo, Compiling resource $$(notdir $$($1_VERSIONINFO_RESOURCE)) (for $$($1_BASENAME)))
$$(call MakeDir, $$(@D) $$($1_OBJECT_DIR))
$$(call ExecuteWithLog, $$@, \
$$($1_RC) $$($1_RC_FLAGS) $$($1_SYSROOT_CFLAGS) $(CC_OUT_OPTION)$$@ \
@@ -798,10 +747,10 @@
endif
endif
- ifneq ($(DISABLE_MAPFILES),true)
+ ifneq ($(DISABLE_MAPFILES), true)
$1_REAL_MAPFILE := $$($1_MAPFILE)
- ifneq ($(OPENJDK_TARGET_OS),windows)
- ifneq (,$$($1_REORDER))
+ ifneq ($(OPENJDK_TARGET_OS), windows)
+ ifneq ($$($1_REORDER), )
$1_REAL_MAPFILE := $$($1_OBJECT_DIR)/mapfile
$$($1_REAL_MAPFILE) : $$($1_MAPFILE) $$($1_REORDER)
@@ -815,9 +764,9 @@
# Pickup extra OPENJDK_TARGET_OS_TYPE and/or OPENJDK_TARGET_OS dependent variables
# for LDFLAGS and LIBS
- $1_EXTRA_LDFLAGS:=$$($1_LDFLAGS_$(OPENJDK_TARGET_OS_TYPE)) $$($1_LDFLAGS_$(OPENJDK_TARGET_OS))
- $1_EXTRA_LIBS:=$$($1_LIBS_$(OPENJDK_TARGET_OS_TYPE)) $$($1_LIBS_$(OPENJDK_TARGET_OS))
- ifneq (,$$($1_REAL_MAPFILE))
+ $1_EXTRA_LDFLAGS := $$($1_LDFLAGS_$(OPENJDK_TARGET_OS_TYPE)) $$($1_LDFLAGS_$(OPENJDK_TARGET_OS))
+ $1_EXTRA_LIBS := $$($1_LIBS_$(OPENJDK_TARGET_OS_TYPE)) $$($1_LIBS_$(OPENJDK_TARGET_OS))
+ ifneq ($$($1_REAL_MAPFILE), )
$1_EXTRA_LDFLAGS += $(call SET_SHARED_LIBRARY_MAPFILE,$$($1_REAL_MAPFILE))
endif
@@ -835,7 +784,7 @@
ifeq ($$($1_COPY_DEBUG_SYMBOLS), true)
ifneq ($$($1_DEBUG_SYMBOLS), false)
# Only copy debug symbols for dynamic libraries and programs.
- ifeq ($$($1_STATIC_LIBRARY), )
+ ifneq ($$($1_TYPE), STATIC_LIBRARY)
# Generate debuginfo files.
ifeq ($(OPENJDK_TARGET_OS), windows)
$1_EXTRA_LDFLAGS += -debug "-pdb:$$($1_OUTPUT_DIR)/$$($1_NOSUFFIX).pdb" \
@@ -899,17 +848,17 @@
endif
endif
- ifneq (,$$($1_LIBRARY))
+ ifeq ($$($1_TYPE), LIBRARY)
# Generating a dynamic library.
$1_EXTRA_LDFLAGS += $$(call SET_SHARED_LIBRARY_NAME,$$($1_BASENAME))
ifeq ($(OPENJDK_TARGET_OS), windows)
- $1_EXTRA_LDFLAGS += "-implib:$$($1_OBJECT_DIR)/$$($1_LIBRARY).lib"
+ $1_EXTRA_LDFLAGS += "-implib:$$($1_OBJECT_DIR)/$$($1_NAME).lib"
# Create a rule for the import lib so that other rules may depend on it
- $$($1_OBJECT_DIR)/$$($1_LIBRARY).lib: $$($1_TARGET)
+ $$($1_OBJECT_DIR)/$$($1_NAME).lib: $$($1_TARGET)
endif
# Create loadmap on AIX. Helps in diagnosing some problems.
- ifneq ($(COMPILER_BINDCMD_FILE_FLAG),)
+ ifneq ($(COMPILER_BINDCMD_FILE_FLAG), )
$1_EXTRA_LDFLAGS += $(COMPILER_BINDCMD_FILE_FLAG)$$($1_OBJECT_DIR)/$$($1_NOSUFFIX).loadmap
endif
@@ -924,7 +873,7 @@
# If there are many object files, use an @-file...
ifneq ($$(word 17, $$($1_ALL_OBJS)), )
$1_OBJ_FILE_LIST := $$($1_OBJECT_DIR)/_$1_objectfilenames.txt
- ifneq ($(COMPILER_COMMAND_FILE_FLAG),)
+ ifneq ($(COMPILER_COMMAND_FILE_FLAG), )
$1_LD_OBJ_ARG := $(COMPILER_COMMAND_FILE_FLAG)$$($1_OBJ_FILE_LIST)
else
# ...except for toolchains which don't support them.
@@ -986,7 +935,7 @@
endif
- ifneq (,$$($1_STATIC_LIBRARY))
+ ifeq ($$($1_TYPE), STATIC_LIBRARY)
$1_VARDEPS := $$($1_AR) $$($1_ARFLAGS) $$($1_LIBS) \
$$($1_EXTRA_LIBS)
$1_VARDEPS_FILE := $$(call DependOnVariable, $1_VARDEPS, \
@@ -1000,7 +949,7 @@
endif
$$($1_TARGET): $$($1_ALL_OBJS) $$($1_RES) $$($1_VARDEPS_FILE) $$(STATIC_MAPFILE_DEP)
- $$(call LogInfo, Archiving $$($1_STATIC_LIBRARY))
+ $$(call LogInfo, Building static library $$($1_BASENAME))
$$(call ExecuteWithLog, $$($1_OBJECT_DIR)/$$($1_SAFE_NAME)_link, \
$$($1_AR) $$($1_ARFLAGS) $(AR_OUT_OPTION)$$($1_TARGET) $$($1_ALL_OBJS) \
$$($1_RES))
@@ -1013,7 +962,7 @@
endif
endif
- ifneq (,$$($1_PROGRAM))
+ ifeq ($$($1_TYPE), EXECUTABLE)
# A executable binary has been specified, setup the target for it.
$1_VARDEPS := $$($1_LD) $$($1_SYSROOT_LDFLAGS) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) \
$$($1_LIBS) $$($1_EXTRA_LIBS) $$($1_MT) \
@@ -1038,13 +987,13 @@
$$($1_LIBS) $$($1_EXTRA_LIBS))
ifeq ($(OPENJDK_TARGET_OS), windows)
ifneq ($$($1_MANIFEST), )
- $$($1_MT) -nologo -manifest $$($1_MANIFEST) -identity:"$$($1_PROGRAM).exe, version=$$($1_MANIFEST_VERSION)" -outputresource:$$@;#1
+ $$($1_MT) -nologo -manifest $$($1_MANIFEST) -identity:"$$($1_NAME).exe, version=$$($1_MANIFEST_VERSION)" -outputresource:$$@;#1
endif
endif
# This only works if the openjdk_codesign identity is present on the system. Let
# silently fail otherwise.
- ifneq (,$(CODESIGN))
- ifneq (,$$($1_CODESIGN))
+ ifneq ($(CODESIGN), )
+ ifneq ($$($1_CODESIGN), )
$(CODESIGN) -s openjdk_codesign $$@
endif
endif
--- a/make/common/TestFilesCompilation.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/common/TestFilesCompilation.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2018, 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
@@ -61,11 +61,13 @@
$1_OUTPUT_SUBDIR := lib
$1_CFLAGS := $(CFLAGS_TESTLIB) $(CFLAGS_WARNINGS_ARE_ERRORS)
$1_LDFLAGS := $(LDFLAGS_TESTLIB) $(call SET_SHARED_LIBRARY_ORIGIN)
+ $1_COMPILATION_TYPE := LIBRARY
else ifeq ($$($1_TYPE), PROGRAM)
$1_PREFIX = exe
$1_OUTPUT_SUBDIR := bin
$1_CFLAGS := $(CFLAGS_TESTEXE) $(CFLAGS_WARNINGS_ARE_ERRORS)
$1_LDFLAGS := $(LDFLAGS_TESTEXE)
+ $1_COMPILATION_TYPE := EXECUTABLE
else
$$(error Unknown type: $$($1_TYPE))
endif
@@ -78,7 +80,8 @@
$$(foreach file, $$($1_FILE_LIST),\
$$(eval name := $$(strip $$(patsubst $$($1_PREFIX)%, %, $$(basename $$(notdir $$(file)))))) \
$$(eval $$(call SetupNativeCompilation, BUILD_TEST_$$(name), \
- $$($1_TYPE) := $$(name), \
+ NAME := $$(name), \
+ TYPE := $$($1_COMPILATION_TYPE), \
SRC := $$(patsubst %/,%,$$(dir $$(file))), \
INCLUDE_FILES := $$(notdir $$(file)), \
OBJECT_DIR := $$($1_OUTPUT_DIR)/support/$$($1_PREFIX)$$(name), \
--- a/make/hotspot/gensrc/GensrcAdlc.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/hotspot/gensrc/GensrcAdlc.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2018, 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
@@ -63,6 +63,8 @@
ADLC_CFLAGS += -I$(TOPDIR)/src/hotspot/share
$(eval $(call SetupNativeCompilation, BUILD_ADLC, \
+ NAME := adlc, \
+ TYPE := EXECUTABLE, \
TOOLCHAIN := TOOLCHAIN_BUILD_LINK_CXX, \
SRC := $(TOPDIR)/src/hotspot/share/adlc, \
EXTRA_FILES := $(TOPDIR)/src/hotspot/share/opto/opcodes.cpp, \
@@ -71,7 +73,6 @@
LIBS := $(ADLC_LIBS), \
OBJECT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/adlc/objs, \
OUTPUT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/adlc, \
- PROGRAM := adlc, \
DEBUG_SYMBOLS := false, \
DISABLED_WARNINGS_clang := tautological-compare, \
DISABLED_WARNINGS_solstudio := notemsource, \
--- a/make/hotspot/lib/CompileDtracePostJvm.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/hotspot/lib/CompileDtracePostJvm.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -46,13 +46,14 @@
# in the libjvm.so, using JVM_CFLAGS as setup in CompileJvm.gmk. Otherwise
# this would preferrably have been done as a part of GensrcDtrace.gmk.
$(eval $(call SetupNativeCompilation, BUILD_DTRACE_GEN_OFFSETS, \
+ NAME := dtraceGenOffsets, \
+ TYPE := EXECUTABLE, \
SRC := $(TOPDIR)/make/hotspot/src/native/dtrace, \
TOOLCHAIN := $(TOOLCHAIN_BUILD), \
LDFLAGS := -m64, \
CFLAGS := -m64 $(JVM_CFLAGS), \
OBJECT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/dtrace-gen-offsets/objs, \
OUTPUT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/dtrace-gen-offsets, \
- PROGRAM := dtraceGenOffsets, \
))
DTRACE_GEN_OFFSETS_TOOL := $(BUILD_DTRACE_GEN_OFFSETS_TARGET)
@@ -159,7 +160,7 @@
LIBJVM_DTRACE_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/libjvm_dtrace
$(eval $(call SetupNativeCompilation, BUILD_LIBJVM_DTRACE, \
- LIBRARY := jvm_dtrace, \
+ NAME := jvm_dtrace, \
OUTPUT_DIR := $(JVM_LIB_OUTPUTDIR), \
SRC := $(TOPDIR)/src/java.base/solaris/native/libjvm_dtrace, \
CFLAGS := -m64 -G -mt -KPIC, \
@@ -174,7 +175,7 @@
# Note that libjvm_db.c has tests for COMPILER2, but this was never set by
# the old build.
$(eval $(call SetupNativeCompilation, BUILD_LIBJVM_DB, \
- LIBRARY := jvm_db, \
+ NAME := jvm_db, \
OUTPUT_DIR := $(JVM_LIB_OUTPUTDIR), \
SRC := $(TOPDIR)/src/java.base/solaris/native/libjvm_db, \
CFLAGS := -I$(JVM_VARIANT_OUTPUTDIR)/gensrc -I$(DTRACE_SUPPORT_DIR) \
--- a/make/hotspot/lib/CompileGtest.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/hotspot/lib/CompileGtest.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2016, 2018, 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
@@ -63,8 +63,8 @@
# exclusive to the gtest libjvm.so.
$(eval $(call SetupNativeCompilation, BUILD_GTEST_LIBJVM, \
+ NAME := jvm, \
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
- LIBRARY := jvm, \
OUTPUT_DIR := $(JVM_OUTPUTDIR)/gtest, \
OBJECT_DIR := $(JVM_OUTPUTDIR)/gtest/objs, \
SRC := $(GTEST_TEST_SRC), \
@@ -87,6 +87,7 @@
DISABLED_WARNINGS_clang := undef switch format-nonliteral \
tautological-undefined-compare $(BUILD_LIBJVM_DISABLED_WARNINGS_clang), \
DISABLED_WARNINGS_solstudio := identexpected, \
+ DISABLED_WARNINGS_CXX_microsoft := 4996, \
LDFLAGS := $(JVM_LDFLAGS), \
LDFLAGS_solaris := -library=stlport4 $(call SET_SHARED_LIBRARY_ORIGIN), \
LDFLAGS_aix := -bbigtoc, \
@@ -107,7 +108,8 @@
$(eval $(call SetupNativeCompilation, BUILD_GTEST_LAUNCHER, \
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
- PROGRAM := gtestLauncher, \
+ NAME := gtestLauncher, \
+ TYPE := EXECUTABLE, \
OUTPUT_DIR := $(JVM_OUTPUTDIR)/gtest, \
EXTRA_FILES := $(GTEST_LAUNCHER_SRC), \
OBJECT_DIR := $(JVM_OUTPUTDIR)/gtest/launcher-objs, \
--- a/make/hotspot/lib/CompileJvm.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/hotspot/lib/CompileJvm.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -210,8 +210,8 @@
# Now set up the actual compilation of the main hotspot native library
$(eval $(call SetupNativeCompilation, BUILD_LIBJVM, \
+ NAME := jvm, \
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
- LIBRARY := jvm, \
OUTPUT_DIR := $(JVM_LIB_OUTPUTDIR), \
SRC := $(JVM_SRC_DIRS), \
EXTRA_FILES := $(DTRACE_EXTRA_SOURCE_FILES), \
--- a/make/hotspot/lib/CompileLibjsig.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/hotspot/lib/CompileLibjsig.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2018, 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
@@ -90,7 +90,7 @@
LIB_OUTPUTDIR := $(call FindLibDirForModule, java.base)
$(eval $(call SetupNativeCompilation, BUILD_LIBJSIG, \
- LIBRARY := jsig, \
+ NAME := jsig, \
SRC := $(LIBJSIG_SRC_DIR), \
OUTPUT_DIR := $(LIB_OUTPUTDIR), \
LANG := C, \
--- a/make/jdk/src/classes/build/tools/taglet/ExtLink.java Thu Mar 01 01:30:10 2018 +0100
+++ b/make/jdk/src/classes/build/tools/taglet/ExtLink.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -49,14 +49,14 @@
* will produce the following html
* <p>
* {@code
- * Please see <a href="https://www.oracle.com/pls/topic/lookup?ctx=javase9&id=Borealis">a spectacular</a> sight.
+ * Please see <a href="https://www.oracle.com/pls/topic/lookup?ctx=javase10&id=Borealis">a spectacular</a> sight.
* }
*/
public class ExtLink implements Taglet {
static final String TAG_NAME = "extLink";
- static final String URL = "https://www.oracle.com/pls/topic/lookup?ctx=javase9&id=";
+ static final String URL = "https://www.oracle.com/pls/topic/lookup?ctx=javase10&id=";
static final Pattern TAG_PATTERN = Pattern.compile("(?s)(\\s*)(?<name>\\w+)(\\s+)(?<desc>.*)$");
--- a/make/launcher/Launcher-java.base.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/launcher/Launcher-java.base.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, 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
@@ -73,6 +73,8 @@
ifeq ($(OPENJDK_TARGET_OS), linux)
$(eval $(call SetupNativeCompilation, BUILD_JEXEC, \
+ NAME := jexec, \
+ TYPE := EXECUTABLE, \
SRC := $(TOPDIR)/src/$(MODULE)/unix/native/launcher, \
INCLUDE_FILES := jexec.c, \
OPTIMIZATION := LOW, \
@@ -83,7 +85,6 @@
LDFLAGS := $(LDFLAGS_JDKEXE), \
OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/jexec_obj, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_libs/$(MODULE), \
- PROGRAM := jexec, \
))
TARGETS += $(BUILD_JEXEC)
@@ -93,6 +94,8 @@
ifneq ($(findstring $(OPENJDK_TARGET_OS), macosx solaris aix), )
$(eval $(call SetupNativeCompilation, BUILD_JSPAWNHELPER, \
+ NAME := jspawnhelper, \
+ TYPE := EXECUTABLE, \
SRC := $(TOPDIR)/src/$(MODULE)/unix/native/jspawnhelper, \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKEXE) -I$(TOPDIR)/src/$(MODULE)/unix/native/libjava, \
@@ -100,7 +103,6 @@
LDFLAGS := $(LDFLAGS_JDKEXE), \
OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/jspawnhelper, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_libs/$(MODULE), \
- PROGRAM := jspawnhelper, \
))
TARGETS += $(BUILD_JSPAWNHELPER)
--- a/make/launcher/Launcher-jdk.accessibility.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/launcher/Launcher-jdk.accessibility.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2018, 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
@@ -33,7 +33,9 @@
JABSWITCH_SRC := $(TOPDIR)/src/jdk.accessibility/windows/native/jabswitch
ACCESSBRIDGE_SRC := $(TOPDIR)/src/jdk.accessibility/windows/native/common
- $(eval $(call SetupNativeCompilation,BUILD_JABSWITCH, \
+ $(eval $(call SetupNativeCompilation, BUILD_JABSWITCH, \
+ NAME := jabswitch, \
+ TYPE := EXECUTABLE, \
SRC := $(JABSWITCH_SRC), \
INCLUDE_FILES := jabswitch.cpp, \
CFLAGS := $(filter-out -Zc:wchar_t-, $(CFLAGS_JDKEXE)) -Zc:wchar_t \
@@ -44,7 +46,6 @@
LIBS := advapi32.lib version.lib user32.lib, \
OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/jdk.accessibility/jabswitch, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_cmds/jdk.accessibility, \
- PROGRAM := jabswitch, \
VERSIONINFO_RESOURCE := $(ACCESSBRIDGE_SRC)/AccessBridgeStatusWindow.RC, \
RC_FLAGS := $(RC_FLAGS) \
-D "JDK_FNAME=jabswitch.exe" \
@@ -70,6 +71,8 @@
# Parameter 2 ACCESSBRIDGE_ARCH_ -D suffix
$$(eval $$(call SetupNativeCompilation, BUILD_JACCESSINSPECTOR$1, \
+ NAME := jaccessinspector$1, \
+ TYPE := EXECUTABLE, \
SRC := $(TOPDIR)/jaccessinspector $(TOPDIR)/common \
$(TOPDIR)/toolscommon $(TOPDIR)/bridge, \
CFLAGS := $$(CFLAGS_JDKEXE) $(TOOLS_CFLAGS) -DACCESSBRIDGE_ARCH_$2 -EHsc, \
@@ -77,7 +80,6 @@
LIBS := advapi32.lib user32.lib, \
OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/jdk.accessibility/jaccessinspector$1, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_cmds/jdk.accessibility, \
- PROGRAM := jaccessinspector$1, \
VERSIONINFO_RESOURCE := $(TOPDIR)/jaccessinspector/jaccessinspectorWindow.rc, \
RC_FLAGS := $$(RC_FLAGS) \
-D "JDK_FNAME=jaccessinspector$1.exe" \
@@ -96,7 +98,9 @@
# Parameter 1 File name suffix
# Parameter 2 ACCESSBRIDGE_ARCH_ -D suffix
- $$(eval $$(call SetupNativeCompilation,BUILD_JACCESSWALKER$1, \
+ $$(eval $$(call SetupNativeCompilation, BUILD_JACCESSWALKER$1, \
+ NAME := jaccesswalker$1, \
+ TYPE := EXECUTABLE, \
SRC := $(TOPDIR)/jaccesswalker $(TOPDIR)/common \
$(TOPDIR)/toolscommon $(TOPDIR)/bridge, \
CFLAGS := $$(CFLAGS_JDKEXE) $(TOOLS_CFLAGS) -DACCESSBRIDGE_ARCH_$2 -EHsc, \
@@ -104,7 +108,6 @@
LIBS := advapi32.lib comctl32.lib gdi32.lib user32.lib, \
OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/jdk.accessibility/jaccesswalker$1, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_cmds/jdk.accessibility, \
- PROGRAM := jaccesswalker$1, \
VERSIONINFO_RESOURCE := $(TOPDIR)/jaccesswalker/jaccesswalkerWindow.rc, \
RC_FLAGS := $$(RC_FLAGS) \
-D "JDK_FNAME=jaccesswalker$1.exe" \
--- a/make/launcher/Launcher-jdk.pack.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/launcher/Launcher-jdk.pack.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, 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
@@ -73,7 +73,9 @@
UNPACK_MAPFILE := $(UNPACK_MAPFILE_DIR)/mapfile-vers-unpack200
endif
-$(eval $(call SetupNativeCompilation,BUILD_UNPACKEXE, \
+$(eval $(call SetupNativeCompilation, BUILD_UNPACKEXE, \
+ NAME := unpack200, \
+ TYPE := EXECUTABLE, \
SRC := $(UNPACKEXE_SRC), \
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
OPTIMIZATION := LOW, \
@@ -91,7 +93,6 @@
LIBS_solaris := -lc, \
OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/unpackexe, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_cmds/$(MODULE), \
- PROGRAM := unpack200, \
VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
RC_FLAGS := $(RC_FLAGS) \
-D "JDK_FNAME=unpack200.exe" \
--- a/make/launcher/LauncherCommon.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/launcher/LauncherCommon.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, 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
@@ -183,6 +183,8 @@
endif
$$(eval $$(call SetupNativeCompilation, BUILD_LAUNCHER_$1, \
+ NAME := $1, \
+ TYPE := EXECUTABLE, \
EXTRA_FILES := $(LAUNCHER_SRC)/main.c, \
OPTIMIZATION := $$($1_OPTIMIZATION), \
CFLAGS := $$($1_CFLAGS) \
@@ -211,7 +213,6 @@
$$($1_LIBS_windows), \
OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/$1_objs, \
OUTPUT_DIR := $$($1_OUTPUT_DIR), \
- PROGRAM := $1, \
VERSIONINFO_RESOURCE := $$($1_VERSION_INFO_RESOURCE), \
RC_FLAGS := $$(RC_FLAGS) \
-D "JDK_FNAME=$1$(EXE_SUFFIX)" \
--- a/make/lib/Awt2dLibraries.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/Awt2dLibraries.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, 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
@@ -48,8 +48,8 @@
BUILD_LIBMLIB_LDLIBS += $(LIBM) $(LIBDL)
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBMLIB_IMAGE, \
- LIBRARY := mlib_image, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBMLIB_IMAGE, \
+ NAME := mlib_image, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(BUILD_LIBMLIB_SRC), \
EXCLUDE_FILES := mlib_c_ImageBlendTable.c, \
@@ -107,8 +107,8 @@
LIBMLIB_IMAGE_V_CFLAGS += $(filter-out -DMLIB_NO_LIBSUNMATH, $(BUILD_LIBMLIB_CFLAGS))
- $(eval $(call SetupNativeCompilation,BUILD_LIBMLIB_IMAGE_V, \
- LIBRARY := mlib_image_v, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBMLIB_IMAGE_V, \
+ NAME := mlib_image_v, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBMLIB_IMAGE_V_SRC), \
EXCLUDE_FILES := $(BUILD_LIBMLIB_IMAGE_V_EXFILES), \
@@ -226,8 +226,8 @@
LIBAWT_CFLAGS += -fgcse-after-reload
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBAWT, \
- LIBRARY := awt, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBAWT, \
+ NAME := awt, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBAWT_DIRS), \
EXCLUDES := $(LIBAWT_EXCLUDES), \
@@ -347,8 +347,8 @@
BUILD_LIBAWT_XAWT_debug_mem.c_CFLAGS := -w
endif
- $(eval $(call SetupNativeCompilation,BUILD_LIBAWT_XAWT, \
- LIBRARY := awt_xawt, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBAWT_XAWT, \
+ NAME := awt_xawt, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBAWT_XAWT_DIRS), \
EXCLUDES := $(LIBAWT_XAWT_EXCLUDES), \
@@ -406,8 +406,8 @@
LIBLCMS_CPPFLAGS += $(addprefix -I, $(LIBLCMS_SRC))
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBLCMS, \
- LIBRARY := lcms, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBLCMS, \
+ NAME := lcms, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBLCMS_SRC), \
INCLUDE_FILES := $(BUILD_LIBLCMS_INCLUDE_FILES), \
@@ -483,8 +483,8 @@
BUILD_LIBJAVAJPEG_HEADERS := $(addprefix -I, $(LIBJAVAJPEG_SRC))
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBJAVAJPEG, \
- LIBRARY := javajpeg, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBJAVAJPEG, \
+ NAME := javajpeg, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBJAVAJPEG_SRC), \
INCLUDE_FILES := $(BUILD_LIBJAVAJPEG_INCLUDE_FILES), \
@@ -547,8 +547,8 @@
endif
endif
- $(eval $(call SetupNativeCompilation,BUILD_LIBAWT_HEADLESS, \
- LIBRARY := awt_headless, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBAWT_HEADLESS, \
+ NAME := awt_headless, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBAWT_HEADLESS_DIRS), \
EXCLUDES := $(LIBAWT_HEADLESS_EXCLUDES), \
@@ -657,8 +657,8 @@
BUILD_LIBFONTMANAGER_ExtensionSubtables.cpp_CXXFLAGS := -fno-strict-aliasing
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBFONTMANAGER, \
- LIBRARY := fontmanager, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBFONTMANAGER, \
+ NAME := fontmanager, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libfontmanager, \
SRC := $(LIBFONTMANAGER_SRC), \
EXCLUDE_FILES := $(LIBFONTMANAGER_EXCLUDE_FILES) \
@@ -744,8 +744,8 @@
ifeq ($(OPENJDK_TARGET_CPU), x86)
KERNEL32_LIB := kernel32.lib
endif
- $(eval $(call SetupNativeCompilation,BUILD_LIBJAWT, \
- LIBRARY := jawt, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBJAWT, \
+ NAME := jawt, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBJAWT_SRC), \
INCLUDE_FILES := $(LIBJAWT_INCLUDE_FILES), \
@@ -804,8 +804,8 @@
endif
endif
- $(eval $(call SetupNativeCompilation,BUILD_LIBJAWT, \
- LIBRARY := jawt, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBJAWT, \
+ NAME := jawt, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBJAWT_SRC), \
INCLUDE_FILES := $(JAWT_FILES), \
@@ -935,8 +935,8 @@
LIBSPLASHSCREEN_LIBS += $(X_LIBS) -lX11 -lXext $(LIBM) -lpthread -ldl
endif
- $(eval $(call SetupNativeCompilation,BUILD_LIBSPLASHSCREEN, \
- LIBRARY := splashscreen, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBSPLASHSCREEN, \
+ NAME := splashscreen, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBSPLASHSCREEN_DIRS), \
EXCLUDE_FILES := imageioJPEG.c jpegdecoder.c pngtest.c, \
@@ -1008,8 +1008,8 @@
LIBAWT_LWAWT_EXFILES := fontpath.c awt_Font.c X11Color.c
LIBAWT_LWAWT_EXCLUDES := $(TOPDIR)/src/java.desktop/unix/native/common/awt/medialib
- $(eval $(call SetupNativeCompilation,BUILD_LIBAWT_LWAWT, \
- LIBRARY := awt_lwawt, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBAWT_LWAWT, \
+ NAME := awt_lwawt, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBAWT_LWAWT_DIRS), \
INCLUDE_FILES := $(LIBAWT_LWAWT_FILES), \
@@ -1057,8 +1057,8 @@
ifeq ($(OPENJDK_TARGET_OS), macosx)
- $(eval $(call SetupNativeCompilation,BUILD_LIBOSXUI, \
- LIBRARY := osxui, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBOSXUI, \
+ NAME := osxui, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(TOPDIR)/src/java.desktop/macosx/native/libosxui, \
OPTIMIZATION := LOW, \
--- a/make/lib/CoreLibraries.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/CoreLibraries.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, 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
@@ -55,8 +55,9 @@
LIBFDLIBM_CFLAGS := -I$(LIBFDLIBM_SRC)
ifneq ($(OPENJDK_TARGET_OS), macosx)
- $(eval $(call SetupNativeCompilation,BUILD_LIBFDLIBM, \
- STATIC_LIBRARY := fdlibm, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBFDLIBM, \
+ NAME := fdlibm, \
+ TYPE := STATIC_LIBRARY, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE), \
SRC := $(LIBFDLIBM_SRC), \
OPTIMIZATION := $(BUILD_LIBFDLIBM_OPTIMIZATION), \
@@ -77,8 +78,8 @@
# On macosx the old build does partial (incremental) linking of fdlibm instead of
# a plain static library.
- $(eval $(call SetupNativeCompilation,BUILD_LIBFDLIBM_MAC, \
- LIBRARY := fdlibm, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBFDLIBM_MAC, \
+ NAME := fdlibm, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libfdlibm, \
SRC := $(LIBFDLIBM_SRC), \
CFLAGS := $(CFLAGS_JDKLIB) $(LIBFDLIBM_CFLAGS), \
@@ -107,8 +108,8 @@
endif
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBVERIFY, \
- LIBRARY := verify, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBVERIFY, \
+ NAME := verify, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(TOPDIR)/src/java.base/share/native/libverify, \
OPTIMIZATION := $(LIBVERIFY_OPTIMIZATION), \
@@ -155,8 +156,8 @@
endif
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBJAVA, \
- LIBRARY := java, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBJAVA, \
+ NAME := java, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBJAVA_SRC_DIRS), \
OPTIMIZATION := HIGH, \
@@ -218,8 +219,8 @@
BUILD_LIBZIP_MMAP := -DUSE_MMAP
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBZIP, \
- LIBRARY := zip, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBZIP, \
+ NAME := zip, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
OPTIMIZATION := LOW, \
SRC := $(TOPDIR)/src/java.base/share/native/libzip, \
@@ -262,8 +263,8 @@
-I$(SUPPORT_OUTPUTDIR)/headers/java.base \
#
-$(eval $(call SetupNativeCompilation,BUILD_LIBJIMAGE, \
- LIBRARY := jimage, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBJIMAGE, \
+ NAME := jimage, \
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
OPTIMIZATION := LOW, \
@@ -358,8 +359,8 @@
)
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBJLI, \
- LIBRARY := jli, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBJLI, \
+ NAME := jli, \
OUTPUT_DIR := $(LIBJLI_OUTPUT_DIR), \
SRC := $(LIBJLI_SRC_DIRS), \
EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
@@ -415,8 +416,9 @@
# with the shared library, so the static library is given a different name. No harm
# in doing it for all platform to reduce complexity.
ifeq ($(OPENJDK_TARGET_OS), windows)
- $(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC, \
- STATIC_LIBRARY := jli_static, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBJLI_STATIC, \
+ NAME := jli_static, \
+ TYPE := STATIC_LIBRARY, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE), \
SRC := $(LIBJLI_SRC_DIRS), \
EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
@@ -434,8 +436,8 @@
# On macosx they do partial (incremental) linking of libjli_static.a
# code it here...rather than add support to NativeCompilation
# as this is first time I see it
- $(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC, \
- LIBRARY := jli_static, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBJLI_STATIC, \
+ NAME := jli_static, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE), \
SRC := $(LIBJLI_SRC_DIRS), \
EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
@@ -457,8 +459,9 @@
else ifeq ($(OPENJDK_TARGET_OS), aix)
# AIX also requires a static libjli because the compiler doesn't support '-rpath'
- $(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC, \
- STATIC_LIBRARY := jli_static, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBJLI_STATIC, \
+ NAME := jli_static, \
+ TYPE := STATIC_LIBRARY, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE), \
SRC := $(LIBJLI_SRC_DIRS), \
EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
--- a/make/lib/Lib-java.instrument.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/Lib-java.instrument.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, 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
@@ -49,8 +49,8 @@
LIBINSTRUMENT_CFLAGS += -Dstrcasecmp=stricmp
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBINSTRUMENT, \
- LIBRARY := instrument, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBINSTRUMENT, \
+ NAME := instrument, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBINSTRUMENT_SRC), \
OPTIMIZATION := LOW, \
--- a/make/lib/Lib-java.management.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/Lib-java.management.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -44,8 +44,8 @@
endif
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBMANAGEMENT, \
- LIBRARY := management, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBMANAGEMENT, \
+ NAME := management, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBMANAGEMENT_SRC), \
OPTIMIZATION := $(LIBMANAGEMENT_OPTIMIZATION), \
--- a/make/lib/Lib-java.prefs.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/Lib-java.prefs.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, 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
@@ -33,8 +33,8 @@
LIBPREF_SRC_DIRS := $(TOPDIR)/src/java.prefs/$(OPENJDK_TARGET_OS_TYPE)/native/libprefs
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBPREFS, \
- LIBRARY := prefs, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBPREFS, \
+ NAME := prefs, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBPREF_SRC_DIRS), \
OPTIMIZATION := HIGH, \
--- a/make/lib/Lib-java.rmi.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/Lib-java.rmi.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -27,8 +27,8 @@
################################################################################
-$(eval $(call SetupNativeCompilation,BUILD_LIBRMI, \
- LIBRARY := rmi, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBRMI, \
+ NAME := rmi, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(TOPDIR)/src/java.rmi/share/native/librmi, \
OPTIMIZATION := LOW, \
--- a/make/lib/Lib-java.security.jgss.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/Lib-java.security.jgss.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -32,8 +32,8 @@
$(TOPDIR)/src/java.security.jgss/$(OPENJDK_TARGET_OS_TYPE)/native/libj2gss \
#
- $(eval $(call SetupNativeCompilation,BUILD_LIBJ2GSS, \
- LIBRARY := j2gss, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBJ2GSS, \
+ NAME := j2gss, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBJ2GSS_SRC), \
OPTIMIZATION := LOW, \
@@ -74,8 +74,8 @@
ifneq ($(BUILD_LIBKRB5_NAME), )
# libosxkrb5 needs to call deprecated krb5 APIs so that java
# can use the native credentials cache.
- $(eval $(call SetupNativeCompilation,BUILD_LIBKRB5, \
- LIBRARY := $(BUILD_LIBKRB5_NAME), \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBKRB5, \
+ NAME := $(BUILD_LIBKRB5_NAME), \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(BUILD_LIBKRB5_SRC), \
OPTIMIZATION := LOW, \
--- a/make/lib/Lib-java.smartcardio.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/Lib-java.smartcardio.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, 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
@@ -33,8 +33,8 @@
-I$(TOPDIR)/src/java.smartcardio/$(OPENJDK_TARGET_OS_TYPE)/native/libj2pcsc/MUSCLE \
-I$(SUPPORT_OUTPUTDIR)/headers/java.smartcardio
-$(eval $(call SetupNativeCompilation,BUILD_LIBJ2PCSC, \
- LIBRARY := j2pcsc, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBJ2PCSC, \
+ NAME := j2pcsc, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBJ2PCSC_SRC), \
CFLAGS_unix := -D__sun_jdk, \
--- a/make/lib/Lib-jdk.accessibility.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/Lib-jdk.accessibility.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -41,8 +41,8 @@
# Parameter 1 Suffix
# Parameter 2 ACCESSBRIDGE_ARCH_ suffix
- $(call SetupNativeCompilation,BUILD_JAVAACCESSBRIDGE$1, \
- LIBRARY = javaaccessbridge$1, \
+ $(call SetupNativeCompilation, BUILD_JAVAACCESSBRIDGE$1, \
+ NAME := javaaccessbridge$1, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(JAVA_AB_SRCDIR), \
OPTIMIZATION := LOW, \
@@ -71,8 +71,8 @@
define SetupWinDLL
# Parameter 1 Suffix
# Parameter 2 ACCESSBRIDGE_ARCH_ suffix
- $(call SetupNativeCompilation,BUILD_WINDOWSACCESSBRIDGE$1, \
- LIBRARY = windowsaccessbridge$1, \
+ $(call SetupNativeCompilation, BUILD_WINDOWSACCESSBRIDGE$1, \
+ NAME := windowsaccessbridge$1, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(WIN_AB_SRCDIR), \
OPTIMIZATION := LOW, \
@@ -99,8 +99,8 @@
define SetupAccessBridgeSysInfo
- $(call SetupNativeCompilation,BUILD_ACCESSBRIDGESYSINFO, \
- LIBRARY = jabsysinfo, \
+ $(call SetupNativeCompilation, BUILD_ACCESSBRIDGESYSINFO, \
+ NAME := jabsysinfo, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(SYSINFO_SRCDIR), \
OPTIMIZATION := LOW, \
--- a/make/lib/Lib-jdk.attach.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/Lib-jdk.attach.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -34,8 +34,8 @@
LIBATTACH_CFLAGS := -DPSAPI_VERSION=1
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBATTACH, \
- LIBRARY := attach, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBATTACH, \
+ NAME := attach, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(call FindSrcDirsForLib, jdk.attach, attach), \
OPTIMIZATION := LOW, \
--- a/make/lib/Lib-jdk.crypto.cryptoki.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/Lib-jdk.crypto.cryptoki.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -30,8 +30,8 @@
LIBJ2PKCS11_SRC := $(TOPDIR)/src/jdk.crypto.cryptoki/share/native/libj2pkcs11 \
$(TOPDIR)/src/jdk.crypto.cryptoki/$(OPENJDK_TARGET_OS_TYPE)/native/libj2pkcs11
-$(eval $(call SetupNativeCompilation,BUILD_LIBJ2PKCS11, \
- LIBRARY := j2pkcs11, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBJ2PKCS11, \
+ NAME := j2pkcs11, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBJ2PKCS11_SRC), \
OPTIMIZATION := LOW, \
--- a/make/lib/Lib-jdk.crypto.ec.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/Lib-jdk.crypto.ec.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -43,8 +43,8 @@
ECC_JNI_SOLSPARC_FILTER := -xregs=no%appl
endif
- $(eval $(call SetupNativeCompilation,BUILD_LIBSUNEC, \
- LIBRARY := sunec, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBSUNEC, \
+ NAME := sunec, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBSUNEC_SRC), \
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
--- a/make/lib/Lib-jdk.crypto.mscapi.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/Lib-jdk.crypto.mscapi.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, 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
@@ -31,8 +31,8 @@
LIBSUNMSCAPI_SRC := $(TOPDIR)/src/jdk.crypto.mscapi/$(OPENJDK_TARGET_OS_TYPE)/native/libsunmscapi
- $(eval $(call SetupNativeCompilation,BUILD_LIBSUNMSCAPI, \
- LIBRARY := sunmscapi, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBSUNMSCAPI, \
+ NAME := sunmscapi, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBSUNMSCAPI_SRC), \
OPTIMIZATION := LOW, \
--- a/make/lib/Lib-jdk.crypto.ucrypto.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/Lib-jdk.crypto.ucrypto.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2018, 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
@@ -31,8 +31,8 @@
LIBJ2UCRYPTO_SRC := $(TOPDIR)/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto
- $(eval $(call SetupNativeCompilation,BUILD_LIBJ2UCRYPTO, \
- LIBRARY := j2ucrypto, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBJ2UCRYPTO, \
+ NAME := j2ucrypto, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBJ2UCRYPTO_SRC), \
OPTIMIZATION := LOW, \
--- a/make/lib/Lib-jdk.hotspot.agent.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/Lib-jdk.hotspot.agent.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2018, 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
@@ -98,12 +98,12 @@
################################################################################
$(eval $(call SetupNativeCompilation, BUILD_LIBSA, \
+ NAME := $(SA_NAME), \
TOOLCHAIN := $(SA_TOOLCHAIN), \
OPTIMIZATION := NONE, \
DISABLED_WARNINGS_microsoft := 4267, \
DISABLED_WARNINGS_gcc := sign-compare, \
DISABLED_WARNINGS_CXX_solstudio := truncwarn unknownpragma, \
- LIBRARY := $(SA_NAME), \
OUTPUT_DIR := $(call FindLibDirForModule, $(MODULE)), \
SRC := $(SA_SRC), \
EXCLUDE_FILES := test.c saproc_audit.cpp $(SA_EXCLUDE_FILES), \
--- a/make/lib/Lib-jdk.internal.le.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/Lib-jdk.internal.le.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -36,8 +36,8 @@
-I$(SUPPORT_OUTPUTDIR)/headers/jdk.internal.le \
#
- $(eval $(call SetupNativeCompilation,BUILD_LIBLE, \
- LIBRARY := le, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBLE, \
+ NAME := le, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBLE_SRC), \
OPTIMIZATION := LOW, \
--- a/make/lib/Lib-jdk.jdi.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/Lib-jdk.jdi.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -39,8 +39,8 @@
-I$(SUPPORT_OUTPUTDIR)/headers/jdk.jdi \
#
- $(eval $(call SetupNativeCompilation,BUILD_LIBDT_SHMEM, \
- LIBRARY := dt_shmem, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBDT_SHMEM, \
+ NAME := dt_shmem, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBDT_SHMEM_SRC), \
OPTIMIZATION := LOW, \
--- a/make/lib/Lib-jdk.jdwp.agent.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/Lib-jdk.jdwp.agent.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -36,14 +36,13 @@
-I$(TOPDIR)/src/jdk.jdwp.agent/share/native/include \
#
-$(eval $(call SetupNativeCompilation,BUILD_LIBDT_SOCKET, \
- LIBRARY := dt_socket, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBDT_SOCKET, \
+ NAME := dt_socket, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBDT_SOCKET_SRC), \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) -DUSE_MMAP \
$(LIBDT_SOCKET_CPPFLAGS), \
- DISABLED_WARNINGS_gcc := shift-negative-value, \
MAPFILE := $(TOPDIR)/make/mapfiles/libdt_socket/mapfile-vers, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
@@ -74,8 +73,8 @@
$(addprefix -I, $(LIBJDWP_SRC))
# JDWP_LOGGING causes log messages to be compiled into the library.
-$(eval $(call SetupNativeCompilation,BUILD_LIBJDWP, \
- LIBRARY := jdwp, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBJDWP, \
+ NAME := jdwp, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBJDWP_SRC), \
OPTIMIZATION := LOW, \
--- a/make/lib/Lib-jdk.management.agent.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/Lib-jdk.management.agent.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2017, 2018, 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
@@ -33,8 +33,8 @@
$(LIBJAVA_HEADER_FLAGS) \
#
-$(eval $(call SetupNativeCompilation,BUILD_LIBMANAGEMENT_AGENT, \
- LIBRARY := management_agent, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBMANAGEMENT_AGENT, \
+ NAME := management_agent, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBMANAGEMENT_AGENT_SRC), \
OPTIMIZATION := LOW, \
--- a/make/lib/Lib-jdk.management.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/Lib-jdk.management.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2018, 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
@@ -53,8 +53,8 @@
endif
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBMANAGEMENT_EXT, \
- LIBRARY := management_ext, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBMANAGEMENT_EXT, \
+ NAME := management_ext, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBMANAGEMENT_EXT_SRC), \
LANG := C, \
--- a/make/lib/Lib-jdk.net.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/Lib-jdk.net.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@
ifeq ($(OPENJDK_TARGET_OS), solaris)
$(eval $(call SetupNativeCompilation, BUILD_LIBEXTNET, \
- LIBRARY := extnet, \
+ NAME := extnet, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(TOPDIR)/src/jdk.net/solaris/native/libextnet, \
OPTIMIZATION := LOW, \
@@ -51,7 +51,7 @@
ifeq ($(OPENJDK_TARGET_OS), linux)
$(eval $(call SetupNativeCompilation, BUILD_LIBEXTNET, \
- LIBRARY := extnet, \
+ NAME := extnet, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(TOPDIR)/src/jdk.net/linux/native/libextnet, \
OPTIMIZATION := LOW, \
--- a/make/lib/Lib-jdk.pack.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/Lib-jdk.pack.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -27,8 +27,8 @@
################################################################################
-$(eval $(call SetupNativeCompilation,BUILD_LIBUNPACK, \
- LIBRARY := unpack, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBUNPACK, \
+ NAME := unpack, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(TOPDIR)/src/jdk.pack/share/native/libunpack \
$(TOPDIR)/src/jdk.pack/share/native/common-unpack, \
--- a/make/lib/Lib-jdk.sctp.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/Lib-jdk.sctp.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -30,8 +30,8 @@
ifeq ($(OPENJDK_TARGET_OS_TYPE), unix)
ifeq (, $(filter $(OPENJDK_TARGET_OS), macosx aix))
- $(eval $(call SetupNativeCompilation,BUILD_LIBSCTP, \
- LIBRARY := sctp, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBSCTP, \
+ NAME := sctp, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(TOPDIR)/src/jdk.sctp/$(OPENJDK_TARGET_OS_TYPE)/native/libsctp, \
OPTIMIZATION := LOW, \
--- a/make/lib/Lib-jdk.security.auth.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/Lib-jdk.security.auth.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -38,8 +38,8 @@
LIBJAAS_NAME := jaas_nt
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBJAAS, \
- LIBRARY := $(LIBJAAS_NAME), \
+$(eval $(call SetupNativeCompilation, BUILD_LIBJAAS, \
+ NAME := $(LIBJAAS_NAME), \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(call FindSrcDirsForLib, jdk.security.auth, jaas), \
OPTIMIZATION := LOW, \
--- a/make/lib/LibosxLibraries.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/LibosxLibraries.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -34,8 +34,8 @@
-I$(SUPPORT_OUTPUTDIR)/headers/java.desktop \
#
- $(eval $(call SetupNativeCompilation,BUILD_LIBOSX, \
- LIBRARY := osx, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBOSX, \
+ NAME := osx, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBOSX_DIRS), \
OPTIMIZATION := LOW, \
--- a/make/lib/NetworkingLibraries.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/NetworkingLibraries.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,8 @@
LIBNET_SRC_DIRS := $(call FindSrcDirsForLib, java.base, net)
-$(eval $(call SetupNativeCompilation,BUILD_LIBNET, \
- LIBRARY := net, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBNET, \
+ NAME := net, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBNET_SRC_DIRS), \
OPTIMIZATION := LOW, \
--- a/make/lib/NioLibraries.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/NioLibraries.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, 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
@@ -56,8 +56,8 @@
BUILD_LIBNIO_MAPFILE := $(TOPDIR)/make/mapfiles/libnio/mapfile-$(OPENJDK_TARGET_OS)
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBNIO, \
- LIBRARY := nio, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBNIO, \
+ NAME := nio, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(BUILD_LIBNIO_SRC), \
EXCLUDE_FILES := $(BUILD_LIBNIO_EXFILES), \
--- a/make/lib/PlatformLibraries.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/PlatformLibraries.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -29,8 +29,8 @@
LIBOSXAPP_SRC := $(TOPDIR)/src/java.desktop/macosx/native/libosxapp
- $(eval $(call SetupNativeCompilation,BUILD_LIBOSXAPP, \
- LIBRARY := osxapp, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBOSXAPP, \
+ NAME := osxapp, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBOSXAPP_SRC), \
OPTIMIZATION := LOW, \
--- a/make/lib/SecurityLibraries.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/SecurityLibraries.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2018, 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
@@ -26,7 +26,7 @@
include LibCommon.gmk
ifeq ($(OPENJDK_TARGET_OS), macosx)
- # JavaNativeFoundation framework not supported in static builds
+ # JavaNativeFoundation framework not supported in static builds
ifneq ($(STATIC_BUILD), true)
################################################################################
@@ -36,8 +36,8 @@
$(LIBJAVA_HEADER_FLAGS) \
-I$(SUPPORT_OUTPUTDIR)/headers/java.base \
- $(eval $(call SetupNativeCompilation,BUILD_LIBOSXSECURITY, \
- LIBRARY := osxsecurity, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBOSXSECURITY, \
+ NAME := osxsecurity, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBOSXSECURITY_DIRS), \
OPTIMIZATION := LOW, \
--- a/make/lib/SoundLibraries.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/lib/SoundLibraries.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, 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
@@ -114,8 +114,8 @@
LIBJSOUND_CFLAGS += -DEXTRA_SOUND_JNI_LIBS='"$(EXTRA_SOUND_JNI_LIBS)"'
-$(eval $(call SetupNativeCompilation,BUILD_LIBJSOUND, \
- LIBRARY := jsound, \
+$(eval $(call SetupNativeCompilation, BUILD_LIBJSOUND, \
+ NAME := jsound, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBJSOUND_SRC_DIRS), \
INCLUDE_FILES := $(LIBJSOUND_SRC_FILES), \
@@ -149,8 +149,8 @@
ifneq ($(filter jsoundalsa, $(EXTRA_SOUND_JNI_LIBS)), )
- $(eval $(call SetupNativeCompilation,BUILD_LIBJSOUNDALSA, \
- LIBRARY := jsoundalsa, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBJSOUNDALSA, \
+ NAME := jsoundalsa, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBJSOUND_SRC_DIRS), \
INCLUDE_FILES := Utilities.c $(LIBJSOUND_MIDIFILES) $(LIBJSOUND_PORTFILES) \
@@ -186,8 +186,8 @@
ifneq ($(filter jsoundds, $(EXTRA_SOUND_JNI_LIBS)), )
- $(eval $(call SetupNativeCompilation,BUILD_LIBJSOUNDDS, \
- LIBRARY := jsoundds, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBJSOUNDDS, \
+ NAME := jsoundds, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBJSOUND_SRC_DIRS), \
INCLUDE_FILES := Utilities.c $(LIBJSOUND_DAUDIOFILES) \
--- a/make/nashorn/package-list Thu Mar 01 01:30:10 2018 +0100
+++ b/make/nashorn/package-list Thu Mar 01 01:35:46 2018 +0100
@@ -261,7 +261,6 @@
jdk.jshell.execution
jdk.jshell.spi
jdk.jshell.tool
-jdk.management.cmm
jdk.management.jfr
jdk.management.resource
jdk.nashorn.api.scripting
--- a/make/test/BuildFailureHandler.gmk Thu Mar 01 01:30:10 2018 +0100
+++ b/make/test/BuildFailureHandler.gmk Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2016, 2018, 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
@@ -64,7 +64,7 @@
ifeq ($(OPENJDK_TARGET_OS), windows)
$(eval $(call SetupNativeCompilation, BUILD_LIBTIMEOUT_HANDLER, \
- LIBRARY := timeoutHandler, \
+ NAME := timeoutHandler, \
SRC := $(FH_BASEDIR)/src/windows/native/libtimeoutHandler, \
OBJECT_DIR := $(FH_SUPPORT)/libtimeoutHandler, \
OUTPUT_DIR := $(FH_SUPPORT), \
--- a/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -684,14 +684,14 @@
}
if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) &&
- UseTLAB && FastTLABRefill) {
+ UseTLAB && Universe::heap()->supports_inline_contig_alloc()) {
Label slow_path;
Register obj_size = r2;
Register t1 = r19;
Register t2 = r4;
assert_different_registers(klass, obj, obj_size, t1, t2);
- __ stp(r5, r19, Address(__ pre(sp, -2 * wordSize)));
+ __ stp(r19, zr, Address(__ pre(sp, -2 * wordSize)));
if (id == fast_new_instance_init_check_id) {
// make sure the klass is initialized
@@ -716,24 +716,6 @@
}
#endif // ASSERT
- // if we got here then the TLAB allocation failed, so try
- // refilling the TLAB or allocating directly from eden.
- Label retry_tlab, try_eden;
- __ tlab_refill(retry_tlab, try_eden, slow_path); // does not destroy r3 (klass), returns r5
-
- __ bind(retry_tlab);
-
- // get the instance size (size is postive so movl is fine for 64bit)
- __ ldrw(obj_size, Address(klass, Klass::layout_helper_offset()));
-
- __ tlab_allocate(obj, obj_size, 0, t1, t2, slow_path);
-
- __ initialize_object(obj, klass, obj_size, 0, t1, t2, /* is_tlab_allocated */ true);
- __ verify_oop(obj);
- __ ldp(r5, r19, Address(__ post(sp, 2 * wordSize)));
- __ ret(lr);
-
- __ bind(try_eden);
// get the instance size (size is postive so movl is fine for 64bit)
__ ldrw(obj_size, Address(klass, Klass::layout_helper_offset()));
@@ -742,11 +724,11 @@
__ initialize_object(obj, klass, obj_size, 0, t1, t2, /* is_tlab_allocated */ false);
__ verify_oop(obj);
- __ ldp(r5, r19, Address(__ post(sp, 2 * wordSize)));
+ __ ldp(r19, zr, Address(__ post(sp, 2 * wordSize)));
__ ret(lr);
__ bind(slow_path);
- __ ldp(r5, r19, Address(__ post(sp, 2 * wordSize)));
+ __ ldp(r19, zr, Address(__ post(sp, 2 * wordSize)));
}
__ enter();
@@ -814,7 +796,7 @@
}
#endif // ASSERT
- if (UseTLAB && FastTLABRefill) {
+ if (UseTLAB && Universe::heap()->supports_inline_contig_alloc()) {
Register arr_size = r4;
Register t1 = r2;
Register t2 = r5;
@@ -826,45 +808,10 @@
__ cmpw(length, rscratch1);
__ br(Assembler::HI, slow_path);
- // if we got here then the TLAB allocation failed, so try
- // refilling the TLAB or allocating directly from eden.
- Label retry_tlab, try_eden;
- const Register thread =
- __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves r19 & r3, returns rthread
-
- __ bind(retry_tlab);
-
// get the allocation size: round_up(hdr + length << (layout_helper & 0x1F))
// since size is positive ldrw does right thing on 64bit
__ ldrw(t1, Address(klass, Klass::layout_helper_offset()));
- __ lslvw(arr_size, length, t1);
- __ ubfx(t1, t1, Klass::_lh_header_size_shift,
- exact_log2(Klass::_lh_header_size_mask + 1));
- __ add(arr_size, arr_size, t1);
- __ add(arr_size, arr_size, MinObjAlignmentInBytesMask); // align up
- __ andr(arr_size, arr_size, ~MinObjAlignmentInBytesMask);
-
- __ tlab_allocate(obj, arr_size, 0, t1, t2, slow_path); // preserves arr_size
-
- __ initialize_header(obj, klass, length, t1, t2);
- __ ldrb(t1, Address(klass, in_bytes(Klass::layout_helper_offset()) + (Klass::_lh_header_size_shift / BitsPerByte)));
- assert(Klass::_lh_header_size_shift % BitsPerByte == 0, "bytewise");
- assert(Klass::_lh_header_size_mask <= 0xFF, "bytewise");
- __ andr(t1, t1, Klass::_lh_header_size_mask);
- __ sub(arr_size, arr_size, t1); // body length
- __ add(t1, t1, obj); // body start
- if (!ZeroTLAB) {
- __ initialize_body(t1, arr_size, 0, t2);
- }
- __ verify_oop(obj);
-
- __ ret(lr);
-
- __ bind(try_eden);
- // get the allocation size: round_up(hdr + length << (layout_helper & 0x1F))
- // since size is positive ldrw does right thing on 64bit
- __ ldrw(t1, Address(klass, Klass::layout_helper_offset()));
- // since size is postive movw does right thing on 64bit
+ // since size is positive movw does right thing on 64bit
__ movw(arr_size, length);
__ lslvw(arr_size, length, t1);
__ ubfx(t1, t1, Klass::_lh_header_size_shift,
@@ -874,7 +821,7 @@
__ andr(arr_size, arr_size, ~MinObjAlignmentInBytesMask);
__ eden_allocate(obj, arr_size, 0, t1, slow_path); // preserves arr_size
- __ incr_allocated_bytes(thread, arr_size, 0, rscratch1);
+ __ incr_allocated_bytes(rthread, arr_size, 0, rscratch1);
__ initialize_header(obj, klass, length, t1, t2);
__ ldrb(t1, Address(klass, in_bytes(Klass::layout_helper_offset()) + (Klass::_lh_header_size_shift / BitsPerByte)));
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -4096,131 +4096,6 @@
// verify_tlab();
}
-// Preserves r19, and r3.
-Register MacroAssembler::tlab_refill(Label& retry,
- Label& try_eden,
- Label& slow_case) {
- Register top = r0;
- Register t1 = r2;
- Register t2 = r4;
- assert_different_registers(top, rthread, t1, t2, /* preserve: */ r19, r3);
- Label do_refill, discard_tlab;
-
- if (!Universe::heap()->supports_inline_contig_alloc()) {
- // No allocation in the shared eden.
- b(slow_case);
- }
-
- ldr(top, Address(rthread, in_bytes(JavaThread::tlab_top_offset())));
- ldr(t1, Address(rthread, in_bytes(JavaThread::tlab_end_offset())));
-
- // calculate amount of free space
- sub(t1, t1, top);
- lsr(t1, t1, LogHeapWordSize);
-
- // Retain tlab and allocate object in shared space if
- // the amount free in the tlab is too large to discard.
-
- ldr(rscratch1, Address(rthread, in_bytes(JavaThread::tlab_refill_waste_limit_offset())));
- cmp(t1, rscratch1);
- br(Assembler::LE, discard_tlab);
-
- // Retain
- // ldr(rscratch1, Address(rthread, in_bytes(JavaThread::tlab_refill_waste_limit_offset())));
- mov(t2, (int32_t) ThreadLocalAllocBuffer::refill_waste_limit_increment());
- add(rscratch1, rscratch1, t2);
- str(rscratch1, Address(rthread, in_bytes(JavaThread::tlab_refill_waste_limit_offset())));
-
- if (TLABStats) {
- // increment number of slow_allocations
- addmw(Address(rthread, in_bytes(JavaThread::tlab_slow_allocations_offset())),
- 1, rscratch1);
- }
- b(try_eden);
-
- bind(discard_tlab);
- if (TLABStats) {
- // increment number of refills
- addmw(Address(rthread, in_bytes(JavaThread::tlab_number_of_refills_offset())), 1,
- rscratch1);
- // accumulate wastage -- t1 is amount free in tlab
- addmw(Address(rthread, in_bytes(JavaThread::tlab_fast_refill_waste_offset())), t1,
- rscratch1);
- }
-
- // if tlab is currently allocated (top or end != null) then
- // fill [top, end + alignment_reserve) with array object
- cbz(top, do_refill);
-
- // set up the mark word
- mov(rscratch1, (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2));
- str(rscratch1, Address(top, oopDesc::mark_offset_in_bytes()));
- // set the length to the remaining space
- sub(t1, t1, typeArrayOopDesc::header_size(T_INT));
- add(t1, t1, (int32_t)ThreadLocalAllocBuffer::alignment_reserve());
- lsl(t1, t1, log2_intptr(HeapWordSize/sizeof(jint)));
- strw(t1, Address(top, arrayOopDesc::length_offset_in_bytes()));
- // set klass to intArrayKlass
- {
- unsigned long offset;
- // dubious reloc why not an oop reloc?
- adrp(rscratch1, ExternalAddress((address)Universe::intArrayKlassObj_addr()),
- offset);
- ldr(t1, Address(rscratch1, offset));
- }
- // store klass last. concurrent gcs assumes klass length is valid if
- // klass field is not null.
- store_klass(top, t1);
-
- mov(t1, top);
- ldr(rscratch1, Address(rthread, in_bytes(JavaThread::tlab_start_offset())));
- sub(t1, t1, rscratch1);
- incr_allocated_bytes(rthread, t1, 0, rscratch1);
-
- // refill the tlab with an eden allocation
- bind(do_refill);
- ldr(t1, Address(rthread, in_bytes(JavaThread::tlab_size_offset())));
- lsl(t1, t1, LogHeapWordSize);
- // allocate new tlab, address returned in top
- eden_allocate(top, t1, 0, t2, slow_case);
-
- // Check that t1 was preserved in eden_allocate.
-#ifdef ASSERT
- if (UseTLAB) {
- Label ok;
- Register tsize = r4;
- assert_different_registers(tsize, rthread, t1);
- str(tsize, Address(pre(sp, -16)));
- ldr(tsize, Address(rthread, in_bytes(JavaThread::tlab_size_offset())));
- lsl(tsize, tsize, LogHeapWordSize);
- cmp(t1, tsize);
- br(Assembler::EQ, ok);
- STOP("assert(t1 != tlab size)");
- should_not_reach_here();
-
- bind(ok);
- ldr(tsize, Address(post(sp, 16)));
- }
-#endif
- str(top, Address(rthread, in_bytes(JavaThread::tlab_start_offset())));
- str(top, Address(rthread, in_bytes(JavaThread::tlab_top_offset())));
- add(top, top, t1);
- sub(top, top, (int32_t)ThreadLocalAllocBuffer::alignment_reserve_in_bytes());
- str(top, Address(rthread, in_bytes(JavaThread::tlab_end_offset())));
-
- if (ZeroTLAB) {
- // This is a fast TLAB refill, therefore the GC is not notified of it.
- // So compiled code must fill the new TLAB with zeroes.
- ldr(top, Address(rthread, in_bytes(JavaThread::tlab_start_offset())));
- zero_memory(top,t1,t2);
- }
-
- verify_tlab();
- b(retry);
-
- return rthread; // for use by caller
-}
-
// Zero words; len is in bytes
// Destroys all registers except addr
// len must be a nonzero multiple of wordSize
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -861,7 +861,6 @@
Register t2, // temp register
Label& slow_case // continuation point if fast allocation fails
);
- Register tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case); // returns TLS address
void zero_memory(Register addr, Register len, Register t1);
void verify_tlab();
--- a/src/hotspot/cpu/arm/c1_Runtime1_arm.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/arm/c1_Runtime1_arm.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -722,10 +722,10 @@
const Register result = R0;
const Register klass = R1;
- if (UseTLAB && FastTLABRefill && id != new_instance_id) {
+ if (UseTLAB && Universe::heap()->supports_inline_contig_alloc() && id != new_instance_id) {
// We come here when TLAB allocation failed.
- // In this case we either refill TLAB or allocate directly from eden.
- Label retry_tlab, try_eden, slow_case, slow_case_no_pop;
+ // In this case we try to allocate directly from eden.
+ Label slow_case, slow_case_no_pop;
// Make sure the class is fully initialized
if (id == fast_new_instance_init_check_id) {
@@ -742,17 +742,6 @@
__ raw_push(R4, R5, LR);
- __ tlab_refill(result, obj_size, tmp1, tmp2, obj_end, try_eden, slow_case);
-
- __ bind(retry_tlab);
- __ ldr_u32(obj_size, Address(klass, Klass::layout_helper_offset()));
- __ tlab_allocate(result, obj_end, tmp1, obj_size, slow_case); // initializes result and obj_end
- __ initialize_object(result, obj_end, klass, noreg /* len */, tmp1, tmp2,
- instanceOopDesc::header_size() * HeapWordSize, -1,
- /* is_tlab_allocated */ true);
- __ raw_pop_and_ret(R4, R5);
-
- __ bind(try_eden);
__ ldr_u32(obj_size, Address(klass, Klass::layout_helper_offset()));
__ eden_allocate(result, obj_end, tmp1, tmp2, obj_size, slow_case); // initializes result and obj_end
__ incr_allocated_bytes(obj_size, tmp2);
@@ -803,10 +792,10 @@
const Register klass = R1;
const Register length = R2;
- if (UseTLAB && FastTLABRefill) {
+ if (UseTLAB && Universe::heap()->supports_inline_contig_alloc()) {
// We come here when TLAB allocation failed.
- // In this case we either refill TLAB or allocate directly from eden.
- Label retry_tlab, try_eden, slow_case, slow_case_no_pop;
+ // In this case we try to allocate directly from eden.
+ Label slow_case, slow_case_no_pop;
#ifdef AARCH64
__ mov_slow(Rtemp, C1_MacroAssembler::max_array_allocation_length);
@@ -825,40 +814,6 @@
__ raw_push(R4, R5, LR);
- __ tlab_refill(result, arr_size, tmp1, tmp2, tmp3, try_eden, slow_case);
-
- __ bind(retry_tlab);
- // Get the allocation size: round_up((length << (layout_helper & 0xff)) + header_size)
- __ ldr_u32(tmp1, Address(klass, Klass::layout_helper_offset()));
- __ mov(arr_size, MinObjAlignmentInBytesMask);
- __ and_32(tmp2, tmp1, (unsigned int)(Klass::_lh_header_size_mask << Klass::_lh_header_size_shift));
-
-#ifdef AARCH64
- __ lslv_w(tmp3, length, tmp1);
- __ add(arr_size, arr_size, tmp3);
-#else
- __ add(arr_size, arr_size, AsmOperand(length, lsl, tmp1));
-#endif // AARCH64
-
- __ add(arr_size, arr_size, AsmOperand(tmp2, lsr, Klass::_lh_header_size_shift));
- __ align_reg(arr_size, arr_size, MinObjAlignmentInBytes);
-
- // tlab_allocate initializes result and obj_end, and preserves tmp2 which contains header_size
- __ tlab_allocate(result, obj_end, tmp1, arr_size, slow_case);
-
- assert_different_registers(result, obj_end, klass, length, tmp1, tmp2);
- __ initialize_header(result, klass, length, tmp1);
-
- __ add(tmp2, result, AsmOperand(tmp2, lsr, Klass::_lh_header_size_shift));
- if (!ZeroTLAB) {
- __ initialize_body(tmp2, obj_end, tmp1);
- }
-
- __ membar(MacroAssembler::StoreStore, tmp1);
-
- __ raw_pop_and_ret(R4, R5);
-
- __ bind(try_eden);
// Get the allocation size: round_up((length << (layout_helper & 0xff)) + header_size)
__ ldr_u32(tmp1, Address(klass, Klass::layout_helper_offset()));
__ mov(arr_size, MinObjAlignmentInBytesMask);
--- a/src/hotspot/cpu/arm/macroAssembler_arm.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/arm/macroAssembler_arm.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1316,98 +1316,6 @@
str(obj_end, Address(Rthread, JavaThread::tlab_top_offset()));
}
-void MacroAssembler::tlab_refill(Register top, Register tmp1, Register tmp2,
- Register tmp3, Register tmp4,
- Label& try_eden, Label& slow_case) {
- if (!Universe::heap()->supports_inline_contig_alloc()) {
- b(slow_case);
- return;
- }
-
- InlinedAddress intArrayKlass_addr((address)Universe::intArrayKlassObj_addr());
- Label discard_tlab, do_refill;
- ldr(top, Address(Rthread, JavaThread::tlab_top_offset()));
- ldr(tmp1, Address(Rthread, JavaThread::tlab_end_offset()));
- ldr(tmp2, Address(Rthread, JavaThread::tlab_refill_waste_limit_offset()));
-
- // Calculate amount of free space
- sub(tmp1, tmp1, top);
- // Retain tlab and allocate in shared space
- // if the amount of free space in tlab is too large to discard
- cmp(tmp2, AsmOperand(tmp1, lsr, LogHeapWordSize));
- b(discard_tlab, ge);
-
- // Increment waste limit to prevent getting stuck on this slow path
- mov_slow(tmp3, ThreadLocalAllocBuffer::refill_waste_limit_increment());
- add(tmp2, tmp2, tmp3);
- str(tmp2, Address(Rthread, JavaThread::tlab_refill_waste_limit_offset()));
- if (TLABStats) {
- ldr_u32(tmp2, Address(Rthread, JavaThread::tlab_slow_allocations_offset()));
- add_32(tmp2, tmp2, 1);
- str_32(tmp2, Address(Rthread, JavaThread::tlab_slow_allocations_offset()));
- }
- b(try_eden);
- bind_literal(intArrayKlass_addr);
-
- bind(discard_tlab);
- if (TLABStats) {
- ldr_u32(tmp2, Address(Rthread, JavaThread::tlab_number_of_refills_offset()));
- ldr_u32(tmp3, Address(Rthread, JavaThread::tlab_fast_refill_waste_offset()));
- add_32(tmp2, tmp2, 1);
- add_32(tmp3, tmp3, AsmOperand(tmp1, lsr, LogHeapWordSize));
- str_32(tmp2, Address(Rthread, JavaThread::tlab_number_of_refills_offset()));
- str_32(tmp3, Address(Rthread, JavaThread::tlab_fast_refill_waste_offset()));
- }
- // If tlab is currently allocated (top or end != null)
- // then fill [top, end + alignment_reserve) with array object
- cbz(top, do_refill);
-
- // Set up the mark word
- mov_slow(tmp2, (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2));
- str(tmp2, Address(top, oopDesc::mark_offset_in_bytes()));
- // Set klass to intArrayKlass and the length to the remaining space
- ldr_literal(tmp2, intArrayKlass_addr);
- add(tmp1, tmp1, ThreadLocalAllocBuffer::alignment_reserve_in_bytes() -
- typeArrayOopDesc::header_size(T_INT) * HeapWordSize);
- Register klass = tmp2;
- ldr(klass, Address(tmp2));
- logical_shift_right(tmp1, tmp1, LogBytesPerInt); // divide by sizeof(jint)
- str_32(tmp1, Address(top, arrayOopDesc::length_offset_in_bytes()));
- store_klass(klass, top); // blows klass:
- klass = noreg;
-
- ldr(tmp1, Address(Rthread, JavaThread::tlab_start_offset()));
- sub(tmp1, top, tmp1); // size of tlab's allocated portion
- incr_allocated_bytes(tmp1, tmp2);
-
- bind(do_refill);
- // Refill the tlab with an eden allocation
- ldr(tmp1, Address(Rthread, JavaThread::tlab_size_offset()));
- logical_shift_left(tmp4, tmp1, LogHeapWordSize);
- eden_allocate(top, tmp1, tmp2, tmp3, tmp4, slow_case);
- str(top, Address(Rthread, JavaThread::tlab_start_offset()));
- str(top, Address(Rthread, JavaThread::tlab_top_offset()));
-
-#ifdef ASSERT
- // Verify that tmp1 contains tlab_end
- ldr(tmp2, Address(Rthread, JavaThread::tlab_size_offset()));
- add(tmp2, top, AsmOperand(tmp2, lsl, LogHeapWordSize));
- cmp(tmp1, tmp2);
- breakpoint(ne);
-#endif
-
- sub(tmp1, tmp1, ThreadLocalAllocBuffer::alignment_reserve_in_bytes());
- str(tmp1, Address(Rthread, JavaThread::tlab_end_offset()));
-
- if (ZeroTLAB) {
- // clobbers start and tmp
- // top must be preserved!
- add(tmp1, tmp1, ThreadLocalAllocBuffer::alignment_reserve_in_bytes());
- ldr(tmp2, Address(Rthread, JavaThread::tlab_start_offset()));
- zero_memory(tmp2, tmp1, tmp3);
- }
-}
-
// Fills memory regions [start..end] with zeroes. Clobbers `start` and `tmp` registers.
void MacroAssembler::zero_memory(Register start, Register end, Register tmp) {
Label loop;
--- a/src/hotspot/cpu/arm/macroAssembler_arm.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/arm/macroAssembler_arm.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -359,8 +359,6 @@
void tlab_allocate(Register obj, Register obj_end, Register tmp1,
RegisterOrConstant size_expression, Label& slow_case);
- void tlab_refill(Register top, Register tmp1, Register tmp2, Register tmp3, Register tmp4,
- Label& try_eden, Label& slow_case);
void zero_memory(Register start, Register end, Register tmp);
void incr_allocated_bytes(RegisterOrConstant size_in_bytes, Register tmp);
--- a/src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -413,34 +413,9 @@
assert(id == fast_new_instance_init_check_id, "bad StubID");
__ set_info("fast new_instance init check", dont_gc_arguments);
}
+
// We don't support eden allocation.
-// if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) &&
-// UseTLAB && FastTLABRefill) {
-// if (id == fast_new_instance_init_check_id) {
-// // make sure the klass is initialized
-// __ lbz(R0, in_bytes(InstanceKlass::init_state_offset()), R3_ARG1);
-// __ cmpwi(CCR0, R0, InstanceKlass::fully_initialized);
-// __ bne(CCR0, slow_path);
-// }
-//#ifdef ASSERT
-// // assert object can be fast path allocated
-// {
-// Label ok, not_ok;
-// __ lwz(R0, in_bytes(Klass::layout_helper_offset()), R3_ARG1);
-// // make sure it's an instance (LH > 0)
-// __ cmpwi(CCR0, R0, 0);
-// __ ble(CCR0, not_ok);
-// __ testbitdi(CCR0, R0, R0, Klass::_lh_instance_slow_path_bit);
-// __ beq(CCR0, ok);
-//
-// __ bind(not_ok);
-// __ stop("assert(can be fast path allocated)");
-// __ bind(ok);
-// }
-//#endif // ASSERT
-// // We don't support eden allocation.
-// __ bind(slow_path);
-// }
+
oop_maps = generate_stub_call(sasm, R3_RET, CAST_FROM_FN_PTR(address, new_instance), R4_ARG2);
}
break;
--- a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -2336,9 +2336,6 @@
std(new_top, in_bytes(JavaThread::tlab_top_offset()), R16_thread);
//verify_tlab(); not implemented
}
-void MacroAssembler::tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case) {
- unimplemented("tlab_refill");
-}
void MacroAssembler::incr_allocated_bytes(RegisterOrConstant size_in_bytes, Register t1, Register t2) {
unimplemented("incr_allocated_bytes");
}
--- a/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -602,7 +602,6 @@
Register t1, // temp register
Label& slow_case // continuation point if fast allocation fails
);
- void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case);
void incr_allocated_bytes(RegisterOrConstant size_in_bytes, Register t1, Register t2);
enum { trampoline_stub_size = 6 * 4 };
--- a/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -346,11 +346,6 @@
__ set_info("fast new_instance init check", dont_gc_arguments);
}
- if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) &&
- UseTLAB && FastTLABRefill) {
- // Sapjvm: must call RT to generate allocation events.
- }
-
OopMap* map = save_live_registers_except_r2(sasm);
int call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_instance), klass);
oop_maps = new OopMapSet();
@@ -411,10 +406,6 @@
}
#endif // ASSERT
- if (UseTLAB && FastTLABRefill) {
- // sapjvm: must call RT to generate allocation events.
- }
-
OopMap* map = save_live_registers_except_r2(sasm);
int call_offset;
if (id == new_type_array_id) {
--- a/src/hotspot/cpu/sparc/c1_Runtime1_sparc.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/sparc/c1_Runtime1_sparc.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -389,7 +389,7 @@
}
if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) &&
- UseTLAB && FastTLABRefill) {
+ UseTLAB && Universe::heap()->supports_inline_contig_alloc()) {
Label slow_path;
Register G1_obj_size = G1;
Register G3_t1 = G3;
@@ -424,25 +424,8 @@
__ bind(ok);
}
#endif // ASSERT
- // if we got here then the TLAB allocation failed, so try
- // refilling the TLAB or allocating directly from eden.
- Label retry_tlab, try_eden;
- __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves G5_klass
- __ bind(retry_tlab);
-
- // get the instance size
- __ ld(G5_klass, in_bytes(Klass::layout_helper_offset()), G1_obj_size);
-
- __ tlab_allocate(O0_obj, G1_obj_size, 0, G3_t1, slow_path);
-
- __ initialize_object(O0_obj, G5_klass, G1_obj_size, 0, G3_t1, G4_t2, /* is_tlab_allocated */ true);
- __ verify_oop(O0_obj);
- __ mov(O0, I0);
- __ ret();
- __ delayed()->restore();
-
- __ bind(try_eden);
+ // If we got here then the TLAB allocation failed, so try allocating directly from eden.
// get the instance size
__ ld(G5_klass, in_bytes(Klass::layout_helper_offset()), G1_obj_size);
__ eden_allocate(O0_obj, G1_obj_size, 0, G3_t1, G4_t2, slow_path);
@@ -508,73 +491,6 @@
}
#endif // ASSERT
- if (UseTLAB && FastTLABRefill) {
- Label slow_path;
- Register G1_arr_size = G1;
- Register G3_t1 = G3;
- Register O1_t2 = O1;
- assert_different_registers(G5_klass, G4_length, G1_arr_size, G3_t1, O1_t2);
-
- // check that array length is small enough for fast path
- __ set(C1_MacroAssembler::max_array_allocation_length, G3_t1);
- __ cmp(G4_length, G3_t1);
- __ br(Assembler::greaterUnsigned, false, Assembler::pn, slow_path);
- __ delayed()->nop();
-
- // if we got here then the TLAB allocation failed, so try
- // refilling the TLAB or allocating directly from eden.
- Label retry_tlab, try_eden;
- __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves G4_length and G5_klass
-
- __ bind(retry_tlab);
-
- // get the allocation size: (length << (layout_helper & 0x1F)) + header_size
- __ ld(klass_lh, G3_t1);
- __ sll(G4_length, G3_t1, G1_arr_size);
- __ srl(G3_t1, Klass::_lh_header_size_shift, G3_t1);
- __ and3(G3_t1, Klass::_lh_header_size_mask, G3_t1);
- __ add(G1_arr_size, G3_t1, G1_arr_size);
- __ add(G1_arr_size, MinObjAlignmentInBytesMask, G1_arr_size); // align up
- __ and3(G1_arr_size, ~MinObjAlignmentInBytesMask, G1_arr_size);
-
- __ tlab_allocate(O0_obj, G1_arr_size, 0, G3_t1, slow_path); // preserves G1_arr_size
-
- __ initialize_header(O0_obj, G5_klass, G4_length, G3_t1, O1_t2);
- __ ldub(klass_lh, G3_t1, klass_lh_header_size_offset);
- __ sub(G1_arr_size, G3_t1, O1_t2); // body length
- __ add(O0_obj, G3_t1, G3_t1); // body start
- if (!ZeroTLAB) {
- __ initialize_body(G3_t1, O1_t2);
- }
- __ verify_oop(O0_obj);
- __ retl();
- __ delayed()->nop();
-
- __ bind(try_eden);
- // get the allocation size: (length << (layout_helper & 0x1F)) + header_size
- __ ld(klass_lh, G3_t1);
- __ sll(G4_length, G3_t1, G1_arr_size);
- __ srl(G3_t1, Klass::_lh_header_size_shift, G3_t1);
- __ and3(G3_t1, Klass::_lh_header_size_mask, G3_t1);
- __ add(G1_arr_size, G3_t1, G1_arr_size);
- __ add(G1_arr_size, MinObjAlignmentInBytesMask, G1_arr_size);
- __ and3(G1_arr_size, ~MinObjAlignmentInBytesMask, G1_arr_size);
-
- __ eden_allocate(O0_obj, G1_arr_size, 0, G3_t1, O1_t2, slow_path); // preserves G1_arr_size
- __ incr_allocated_bytes(G1_arr_size, G3_t1, O1_t2);
-
- __ initialize_header(O0_obj, G5_klass, G4_length, G3_t1, O1_t2);
- __ ldub(klass_lh, G3_t1, klass_lh_header_size_offset);
- __ sub(G1_arr_size, G3_t1, O1_t2); // body length
- __ add(O0_obj, G3_t1, G3_t1); // body start
- __ initialize_body(G3_t1, O1_t2);
- __ verify_oop(O0_obj);
- __ retl();
- __ delayed()->nop();
-
- __ bind(slow_path);
- }
-
if (id == new_type_array_id) {
oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_type_array), G5_klass, G4_length);
} else {
--- a/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -3242,127 +3242,6 @@
verify_tlab();
}
-
-void MacroAssembler::tlab_refill(Label& retry, Label& try_eden, Label& slow_case) {
- Register top = O0;
- Register t1 = G1;
- Register t2 = G3;
- Register t3 = O1;
- assert_different_registers(top, t1, t2, t3, G4, G5 /* preserve G4 and G5 */);
- Label do_refill, discard_tlab;
-
- if (!Universe::heap()->supports_inline_contig_alloc()) {
- // No allocation in the shared eden.
- ba(slow_case);
- delayed()->nop();
- }
-
- ld_ptr(G2_thread, in_bytes(JavaThread::tlab_top_offset()), top);
- ld_ptr(G2_thread, in_bytes(JavaThread::tlab_end_offset()), t1);
- ld_ptr(G2_thread, in_bytes(JavaThread::tlab_refill_waste_limit_offset()), t2);
-
- // calculate amount of free space
- sub(t1, top, t1);
- srl_ptr(t1, LogHeapWordSize, t1);
-
- // Retain tlab and allocate object in shared space if
- // the amount free in the tlab is too large to discard.
- cmp(t1, t2);
-
- brx(Assembler::lessEqual, false, Assembler::pt, discard_tlab);
- // increment waste limit to prevent getting stuck on this slow path
- if (Assembler::is_simm13(ThreadLocalAllocBuffer::refill_waste_limit_increment())) {
- delayed()->add(t2, ThreadLocalAllocBuffer::refill_waste_limit_increment(), t2);
- } else {
- delayed()->nop();
- // set64 does not use the temp register if the given constant is 32 bit. So
- // we can just use any register; using G0 results in ignoring of the upper 32 bit
- // of that value.
- set64(ThreadLocalAllocBuffer::refill_waste_limit_increment(), t3, G0);
- add(t2, t3, t2);
- }
-
- st_ptr(t2, G2_thread, in_bytes(JavaThread::tlab_refill_waste_limit_offset()));
- if (TLABStats) {
- // increment number of slow_allocations
- ld(G2_thread, in_bytes(JavaThread::tlab_slow_allocations_offset()), t2);
- add(t2, 1, t2);
- stw(t2, G2_thread, in_bytes(JavaThread::tlab_slow_allocations_offset()));
- }
- ba(try_eden);
- delayed()->nop();
-
- bind(discard_tlab);
- if (TLABStats) {
- // increment number of refills
- ld(G2_thread, in_bytes(JavaThread::tlab_number_of_refills_offset()), t2);
- add(t2, 1, t2);
- stw(t2, G2_thread, in_bytes(JavaThread::tlab_number_of_refills_offset()));
- // accumulate wastage
- ld(G2_thread, in_bytes(JavaThread::tlab_fast_refill_waste_offset()), t2);
- add(t2, t1, t2);
- stw(t2, G2_thread, in_bytes(JavaThread::tlab_fast_refill_waste_offset()));
- }
-
- // if tlab is currently allocated (top or end != null) then
- // fill [top, end + alignment_reserve) with array object
- br_null_short(top, Assembler::pn, do_refill);
-
- set((intptr_t)markOopDesc::prototype()->copy_set_hash(0x2), t2);
- st_ptr(t2, top, oopDesc::mark_offset_in_bytes()); // set up the mark word
- // set klass to intArrayKlass
- sub(t1, typeArrayOopDesc::header_size(T_INT), t1);
- add(t1, ThreadLocalAllocBuffer::alignment_reserve(), t1);
- sll_ptr(t1, log2_intptr(HeapWordSize/sizeof(jint)), t1);
- st(t1, top, arrayOopDesc::length_offset_in_bytes());
- set((intptr_t)Universe::intArrayKlassObj_addr(), t2);
- ld_ptr(t2, 0, t2);
- // store klass last. concurrent gcs assumes klass length is valid if
- // klass field is not null.
- store_klass(t2, top);
- verify_oop(top);
-
- ld_ptr(G2_thread, in_bytes(JavaThread::tlab_start_offset()), t1);
- sub(top, t1, t1); // size of tlab's allocated portion
- incr_allocated_bytes(t1, t2, t3);
-
- // refill the tlab with an eden allocation
- bind(do_refill);
- ld_ptr(G2_thread, in_bytes(JavaThread::tlab_size_offset()), t1);
- sll_ptr(t1, LogHeapWordSize, t1);
- // allocate new tlab, address returned in top
- eden_allocate(top, t1, 0, t2, t3, slow_case);
-
- st_ptr(top, G2_thread, in_bytes(JavaThread::tlab_start_offset()));
- st_ptr(top, G2_thread, in_bytes(JavaThread::tlab_top_offset()));
-#ifdef ASSERT
- // check that tlab_size (t1) is still valid
- {
- Label ok;
- ld_ptr(G2_thread, in_bytes(JavaThread::tlab_size_offset()), t2);
- sll_ptr(t2, LogHeapWordSize, t2);
- cmp_and_br_short(t1, t2, Assembler::equal, Assembler::pt, ok);
- STOP("assert(t1 == tlab_size)");
- should_not_reach_here();
-
- bind(ok);
- }
-#endif // ASSERT
- add(top, t1, top); // t1 is tlab_size
- sub(top, ThreadLocalAllocBuffer::alignment_reserve_in_bytes(), top);
- st_ptr(top, G2_thread, in_bytes(JavaThread::tlab_end_offset()));
-
- if (ZeroTLAB) {
- // This is a fast TLAB refill, therefore the GC is not notified of it.
- // So compiled code must fill the new TLAB with zeroes.
- ld_ptr(G2_thread, in_bytes(JavaThread::tlab_start_offset()), t2);
- zero_memory(t2, t1);
- }
- verify_tlab();
- ba(retry);
- delayed()->nop();
-}
-
void MacroAssembler::zero_memory(Register base, Register index) {
assert_different_registers(base, index);
Label loop;
--- a/src/hotspot/cpu/sparc/macroAssembler_sparc.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/sparc/macroAssembler_sparc.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1266,7 +1266,6 @@
Register t1, // temp register
Label& slow_case // continuation point if fast allocation fails
);
- void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case);
void zero_memory(Register base, Register index);
void incr_allocated_bytes(RegisterOrConstant size_in_bytes,
Register t1, Register t2);
--- a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -529,12 +529,16 @@
if (SafepointMechanism::uses_thread_local_poll()) {
#ifdef _LP64
- __ movptr(rscratch1, Address(r15_thread, Thread::polling_page_offset()));
+ const Register poll_addr = rscratch1;
+ __ movptr(poll_addr, Address(r15_thread, Thread::polling_page_offset()));
+#else
+ const Register poll_addr = rbx;
+ assert(FrameMap::is_caller_save_register(poll_addr), "will overwrite");
+ __ get_thread(poll_addr);
+ __ movptr(poll_addr, Address(poll_addr, Thread::polling_page_offset()));
+#endif
__ relocate(relocInfo::poll_return_type);
- __ testl(rax, Address(rscratch1, 0));
-#else
- ShouldNotReachHere();
-#endif
+ __ testl(rax, Address(poll_addr, 0));
} else {
AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type);
@@ -555,16 +559,20 @@
int offset = __ offset();
if (SafepointMechanism::uses_thread_local_poll()) {
#ifdef _LP64
- __ movptr(rscratch1, Address(r15_thread, Thread::polling_page_offset()));
+ const Register poll_addr = rscratch1;
+ __ movptr(poll_addr, Address(r15_thread, Thread::polling_page_offset()));
+#else
+ assert(tmp->is_cpu_register(), "needed");
+ const Register poll_addr = tmp->as_register();
+ __ get_thread(poll_addr);
+ __ movptr(poll_addr, Address(poll_addr, in_bytes(Thread::polling_page_offset())));
+#endif
add_debug_info_for_branch(info);
__ relocate(relocInfo::poll_type);
address pre_pc = __ pc();
- __ testl(rax, Address(rscratch1, 0));
+ __ testl(rax, Address(poll_addr, 0));
address post_pc = __ pc();
- guarantee(pointer_delta(post_pc, pre_pc, 1) == 3, "must be exact length");
-#else
- ShouldNotReachHere();
-#endif
+ guarantee(pointer_delta(post_pc, pre_pc, 1) == 2 LP64_ONLY(+1), "must be exact length");
} else {
AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_type);
if (Assembler::is_polling_page_far()) {
--- a/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -143,6 +143,7 @@
LIR_Opr LIRGenerator::safepoint_poll_register() {
+ NOT_LP64( if (SafepointMechanism::uses_thread_local_poll()) { return new_register(T_ADDRESS); } )
return LIR_OprFact::illegalOpr;
}
@@ -1515,7 +1516,7 @@
if (x->is_safepoint()) {
// increment backedge counter if needed
increment_backedge_counter(state_for(x, x->state_before()), x->profiled_bci());
- __ safepoint(LIR_OprFact::illegalOpr, state_for(x, x->state_before()));
+ __ safepoint(safepoint_poll_register(), state_for(x, x->state_before()));
}
set_no_result(x);
--- a/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -994,8 +994,8 @@
__ set_info("fast new_instance init check", dont_gc_arguments);
}
- if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) &&
- UseTLAB && FastTLABRefill) {
+ if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) && UseTLAB
+ && Universe::heap()->supports_inline_contig_alloc()) {
Label slow_path;
Register obj_size = rcx;
Register t1 = rbx;
@@ -1030,21 +1030,8 @@
// if we got here then the TLAB allocation failed, so try
// refilling the TLAB or allocating directly from eden.
Label retry_tlab, try_eden;
- const Register thread =
- __ tlab_refill(retry_tlab, try_eden, slow_path); // does not destroy rdx (klass), returns rdi
-
- __ bind(retry_tlab);
-
- // get the instance size (size is postive so movl is fine for 64bit)
- __ movl(obj_size, Address(klass, Klass::layout_helper_offset()));
-
- __ tlab_allocate(obj, obj_size, 0, t1, t2, slow_path);
-
- __ initialize_object(obj, klass, obj_size, 0, t1, t2, /* is_tlab_allocated */ true);
- __ verify_oop(obj);
- __ pop(rbx);
- __ pop(rdi);
- __ ret(0);
+ const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread);
+ NOT_LP64(__ get_thread(thread));
__ bind(try_eden);
// get the instance size (size is postive so movl is fine for 64bit)
@@ -1128,24 +1115,13 @@
}
#endif // ASSERT
- if (UseTLAB && FastTLABRefill) {
+ // If we got here, the TLAB allocation failed, so try allocating from
+ // eden if inline contiguous allocations are supported.
+ if (UseTLAB && Universe::heap()->supports_inline_contig_alloc()) {
Register arr_size = rsi;
Register t1 = rcx; // must be rcx for use as shift count
Register t2 = rdi;
Label slow_path;
- assert_different_registers(length, klass, obj, arr_size, t1, t2);
-
- // check that array length is small enough for fast path.
- __ cmpl(length, C1_MacroAssembler::max_array_allocation_length);
- __ jcc(Assembler::above, slow_path);
-
- // if we got here then the TLAB allocation failed, so try
- // refilling the TLAB or allocating directly from eden.
- Label retry_tlab, try_eden;
- const Register thread =
- __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves rbx & rdx, returns rdi
-
- __ bind(retry_tlab);
// get the allocation size: round_up(hdr + length << (layout_helper & 0x1F))
// since size is positive movl does right thing on 64bit
@@ -1160,36 +1136,11 @@
__ addptr(arr_size, MinObjAlignmentInBytesMask); // align up
__ andptr(arr_size, ~MinObjAlignmentInBytesMask);
- __ tlab_allocate(obj, arr_size, 0, t1, t2, slow_path); // preserves arr_size
-
- __ initialize_header(obj, klass, length, t1, t2);
- __ movb(t1, Address(klass, in_bytes(Klass::layout_helper_offset()) + (Klass::_lh_header_size_shift / BitsPerByte)));
- assert(Klass::_lh_header_size_shift % BitsPerByte == 0, "bytewise");
- assert(Klass::_lh_header_size_mask <= 0xFF, "bytewise");
- __ andptr(t1, Klass::_lh_header_size_mask);
- __ subptr(arr_size, t1); // body length
- __ addptr(t1, obj); // body start
- if (!ZeroTLAB) {
- __ initialize_body(t1, arr_size, 0, t2);
- }
- __ verify_oop(obj);
- __ ret(0);
+ __ eden_allocate(obj, arr_size, 0, t1, slow_path); // preserves arr_size
- __ bind(try_eden);
- // get the allocation size: round_up(hdr + length << (layout_helper & 0x1F))
- // since size is positive movl does right thing on 64bit
- __ movl(t1, Address(klass, Klass::layout_helper_offset()));
- // since size is postive movl does right thing on 64bit
- __ movl(arr_size, length);
- assert(t1 == rcx, "fixed register usage");
- __ shlptr(arr_size /* by t1=rcx, mod 32 */);
- __ shrptr(t1, Klass::_lh_header_size_shift);
- __ andptr(t1, Klass::_lh_header_size_mask);
- __ addptr(arr_size, t1);
- __ addptr(arr_size, MinObjAlignmentInBytesMask); // align up
- __ andptr(arr_size, ~MinObjAlignmentInBytesMask);
-
- __ eden_allocate(obj, arr_size, 0, t1, slow_path); // preserves arr_size
+ // Using t2 for non 64-bit.
+ const Register thread = NOT_LP64(t2) LP64_ONLY(r15_thread);
+ NOT_LP64(__ get_thread(thread));
__ incr_allocated_bytes(thread, arr_size, 0);
__ initialize_header(obj, klass, length, t1, t2);
--- a/src/hotspot/cpu/x86/globalDefinitions_x86.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/x86/globalDefinitions_x86.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, 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
@@ -65,9 +65,6 @@
#define SUPPORT_RESERVED_STACK_AREA
#endif
-#ifdef _LP64
-// X64 have implemented the local polling
#define THREAD_LOCAL_POLL
-#endif
#endif // CPU_X86_VM_GLOBALDEFINITIONS_X86_HPP
--- a/src/hotspot/cpu/x86/globals_x86.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/x86/globals_x86.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, 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
@@ -97,9 +97,10 @@
define_pd_global(intx, InitArrayShortSize, 8*BytesPerLong);
-#ifdef _LP64
+#if defined(_LP64) || defined(_WINDOWS)
define_pd_global(bool, ThreadLocalHandshakes, true);
#else
+// get_thread() is slow on linux 32 bit, therefore off by default
define_pd_global(bool, ThreadLocalHandshakes, false);
#endif
--- a/src/hotspot/cpu/x86/interp_masm_x86.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/x86/interp_masm_x86.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -830,13 +830,12 @@
if (verifyoop) {
verify_oop(rax, state);
}
+
+ address* const safepoint_table = Interpreter::safept_table(state);
#ifdef _LP64
-
Label no_safepoint, dispatch;
- address* const safepoint_table = Interpreter::safept_table(state);
if (SafepointMechanism::uses_thread_local_poll() && table != safepoint_table && generate_poll) {
NOT_PRODUCT(block_comment("Thread-local Safepoint poll"));
-
testb(Address(r15_thread, Thread::polling_page_offset()), SafepointMechanism::poll_bit());
jccb(Assembler::zero, no_safepoint);
@@ -851,9 +850,23 @@
#else
Address index(noreg, rbx, Address::times_ptr);
- ExternalAddress tbl((address)table);
- ArrayAddress dispatch(tbl, index);
- jump(dispatch);
+ if (SafepointMechanism::uses_thread_local_poll() && table != safepoint_table && generate_poll) {
+ NOT_PRODUCT(block_comment("Thread-local Safepoint poll"));
+ Label no_safepoint;
+ const Register thread = rcx;
+ get_thread(thread);
+ testb(Address(thread, Thread::polling_page_offset()), SafepointMechanism::poll_bit());
+
+ jccb(Assembler::zero, no_safepoint);
+ ArrayAddress dispatch_addr(ExternalAddress((address)safepoint_table), index);
+ jump(dispatch_addr);
+ bind(no_safepoint);
+ }
+
+ {
+ ArrayAddress dispatch_addr(ExternalAddress((address)table), index);
+ jump(dispatch_addr);
+ }
#endif // _LP64
}
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -3767,10 +3767,17 @@
movl(as_Address(ArrayAddress(page, index)), tmp);
}
-#ifdef _LP64
void MacroAssembler::safepoint_poll(Label& slow_path, Register thread_reg, Register temp_reg) {
if (SafepointMechanism::uses_thread_local_poll()) {
- testb(Address(r15_thread, Thread::polling_page_offset()), SafepointMechanism::poll_bit());
+#ifdef _LP64
+ assert(thread_reg == r15_thread, "should be");
+#else
+ if (thread_reg == noreg) {
+ thread_reg = temp_reg;
+ get_thread(thread_reg);
+ }
+#endif
+ testb(Address(thread_reg, Thread::polling_page_offset()), SafepointMechanism::poll_bit());
jcc(Assembler::notZero, slow_path); // handshake bit set implies poll
} else {
cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
@@ -3778,13 +3785,6 @@
jcc(Assembler::notEqual, slow_path);
}
}
-#else
-void MacroAssembler::safepoint_poll(Label& slow_path) {
- cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
- SafepointSynchronize::_not_synchronized);
- jcc(Assembler::notEqual, slow_path);
-}
-#endif
// Calls to C land
//
@@ -5604,121 +5604,6 @@
verify_tlab();
}
-// Preserves rbx, and rdx.
-Register MacroAssembler::tlab_refill(Label& retry,
- Label& try_eden,
- Label& slow_case) {
- Register top = rax;
- Register t1 = rcx; // object size
- Register t2 = rsi;
- Register thread_reg = NOT_LP64(rdi) LP64_ONLY(r15_thread);
- assert_different_registers(top, thread_reg, t1, t2, /* preserve: */ rbx, rdx);
- Label do_refill, discard_tlab;
-
- if (!Universe::heap()->supports_inline_contig_alloc()) {
- // No allocation in the shared eden.
- jmp(slow_case);
- }
-
- NOT_LP64(get_thread(thread_reg));
-
- movptr(top, Address(thread_reg, in_bytes(JavaThread::tlab_top_offset())));
- movptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_end_offset())));
-
- // calculate amount of free space
- subptr(t1, top);
- shrptr(t1, LogHeapWordSize);
-
- // Retain tlab and allocate object in shared space if
- // the amount free in the tlab is too large to discard.
- cmpptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_refill_waste_limit_offset())));
- jcc(Assembler::lessEqual, discard_tlab);
-
- // Retain
- // %%% yuck as movptr...
- movptr(t2, (int32_t) ThreadLocalAllocBuffer::refill_waste_limit_increment());
- addptr(Address(thread_reg, in_bytes(JavaThread::tlab_refill_waste_limit_offset())), t2);
- if (TLABStats) {
- // increment number of slow_allocations
- addl(Address(thread_reg, in_bytes(JavaThread::tlab_slow_allocations_offset())), 1);
- }
- jmp(try_eden);
-
- bind(discard_tlab);
- if (TLABStats) {
- // increment number of refills
- addl(Address(thread_reg, in_bytes(JavaThread::tlab_number_of_refills_offset())), 1);
- // accumulate wastage -- t1 is amount free in tlab
- addl(Address(thread_reg, in_bytes(JavaThread::tlab_fast_refill_waste_offset())), t1);
- }
-
- // if tlab is currently allocated (top or end != null) then
- // fill [top, end + alignment_reserve) with array object
- testptr(top, top);
- jcc(Assembler::zero, do_refill);
-
- // set up the mark word
- movptr(Address(top, oopDesc::mark_offset_in_bytes()), (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2));
- // set the length to the remaining space
- subptr(t1, typeArrayOopDesc::header_size(T_INT));
- addptr(t1, (int32_t)ThreadLocalAllocBuffer::alignment_reserve());
- shlptr(t1, log2_intptr(HeapWordSize/sizeof(jint)));
- movl(Address(top, arrayOopDesc::length_offset_in_bytes()), t1);
- // set klass to intArrayKlass
- // dubious reloc why not an oop reloc?
- movptr(t1, ExternalAddress((address)Universe::intArrayKlassObj_addr()));
- // store klass last. concurrent gcs assumes klass length is valid if
- // klass field is not null.
- store_klass(top, t1);
-
- movptr(t1, top);
- subptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_start_offset())));
- incr_allocated_bytes(thread_reg, t1, 0);
-
- // refill the tlab with an eden allocation
- bind(do_refill);
- movptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset())));
- shlptr(t1, LogHeapWordSize);
- // allocate new tlab, address returned in top
- eden_allocate(top, t1, 0, t2, slow_case);
-
- // Check that t1 was preserved in eden_allocate.
-#ifdef ASSERT
- if (UseTLAB) {
- Label ok;
- Register tsize = rsi;
- assert_different_registers(tsize, thread_reg, t1);
- push(tsize);
- movptr(tsize, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset())));
- shlptr(tsize, LogHeapWordSize);
- cmpptr(t1, tsize);
- jcc(Assembler::equal, ok);
- STOP("assert(t1 != tlab size)");
- should_not_reach_here();
-
- bind(ok);
- pop(tsize);
- }
-#endif
- movptr(Address(thread_reg, in_bytes(JavaThread::tlab_start_offset())), top);
- movptr(Address(thread_reg, in_bytes(JavaThread::tlab_top_offset())), top);
- addptr(top, t1);
- subptr(top, (int32_t)ThreadLocalAllocBuffer::alignment_reserve_in_bytes());
- movptr(Address(thread_reg, in_bytes(JavaThread::tlab_end_offset())), top);
-
- if (ZeroTLAB) {
- // This is a fast TLAB refill, therefore the GC is not notified of it.
- // So compiled code must fill the new TLAB with zeroes.
- movptr(top, Address(thread_reg, in_bytes(JavaThread::tlab_start_offset())));
- zero_memory(top, t1, 0, t2);
- }
-
- verify_tlab();
- jmp(retry);
-
- return thread_reg; // for use by caller
-}
-
// Preserves the contents of address, destroys the contents length_in_bytes and temp.
void MacroAssembler::zero_memory(Register address, Register length_in_bytes, int offset_in_bytes, Register temp) {
assert(address != length_in_bytes && address != temp && temp != length_in_bytes, "registers must be different");
--- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -531,7 +531,6 @@
Register t2, // temp register
Label& slow_case // continuation point if fast allocation fails
);
- Register tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case); // returns TLS address
void zero_memory(Register address, Register length_in_bytes, int offset_in_bytes, Register temp);
void incr_allocated_bytes(Register thread,
@@ -657,11 +656,9 @@
// Support for serializing memory accesses between threads
void serialize_memory(Register thread, Register tmp);
-#ifdef _LP64
+ // If thread_reg is != noreg the code assumes the register passed contains
+ // the thread (required on 64 bit).
void safepoint_poll(Label& slow_path, Register thread_reg, Register temp_reg);
-#else
- void safepoint_poll(Label& slow_path);
-#endif
void verify_tlab();
--- a/src/hotspot/cpu/x86/nativeInst_x86.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/x86/nativeInst_x86.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -704,14 +704,18 @@
inline bool NativeInstruction::is_cond_jump() { return (int_at(0) & 0xF0FF) == 0x800F /* long jump */ ||
(ubyte_at(0) & 0xF0) == 0x70; /* short jump */ }
inline bool NativeInstruction::is_safepoint_poll() {
+ if (SafepointMechanism::uses_thread_local_poll()) {
#ifdef AMD64
- if (SafepointMechanism::uses_thread_local_poll()) {
const bool has_rex_prefix = ubyte_at(0) == NativeTstRegMem::instruction_rex_b_prefix;
const int test_offset = has_rex_prefix ? 1 : 0;
+#else
+ const int test_offset = 0;
+#endif
const bool is_test_opcode = ubyte_at(test_offset) == NativeTstRegMem::instruction_code_memXregl;
const bool is_rax_target = (ubyte_at(test_offset + 1) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg;
return is_test_opcode && is_rax_target;
}
+#ifdef AMD64
// Try decoding a near safepoint first:
if (ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
ubyte_at(1) == 0x05) { // 00 rax 101
--- a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -2111,16 +2111,13 @@
Label after_transition;
// check for safepoint operation in progress and/or pending suspend requests
- { Label Continue;
-
- __ cmp32(ExternalAddress((address)SafepointSynchronize::address_of_state()),
- SafepointSynchronize::_not_synchronized);
-
- Label L;
- __ jcc(Assembler::notEqual, L);
+ { Label Continue, slow_path;
+
+ __ safepoint_poll(slow_path, thread, noreg);
+
__ cmpl(Address(thread, JavaThread::suspend_flags_offset()), 0);
__ jcc(Assembler::equal, Continue);
- __ bind(L);
+ __ bind(slow_path);
// Don't use call_VM as it will see a possible pending exception and forward it
// and never return here preventing us from clearing _last_native_pc down below.
@@ -2996,8 +2993,11 @@
// if this was not a poll_return then we need to correct the return address now.
if (!cause_return) {
- __ movptr(rax, Address(java_thread, JavaThread::saved_exception_pc_offset()));
- __ movptr(Address(rbp, wordSize), rax);
+ // Get the return pc saved by the signal handler and stash it in its appropriate place on the stack.
+ // Additionally, rbx is a callee saved register and we can look at it later to determine
+ // if someone changed the return address for us!
+ __ movptr(rbx, Address(java_thread, JavaThread::saved_exception_pc_offset()));
+ __ movptr(Address(rbp, wordSize), rbx);
}
// do the call
@@ -3029,11 +3029,63 @@
__ bind(noException);
+ Label no_adjust, bail, not_special;
+ if (SafepointMechanism::uses_thread_local_poll() && !cause_return) {
+ // If our stashed return pc was modified by the runtime we avoid touching it
+ __ cmpptr(rbx, Address(rbp, wordSize));
+ __ jccb(Assembler::notEqual, no_adjust);
+
+ // Skip over the poll instruction.
+ // See NativeInstruction::is_safepoint_poll()
+ // Possible encodings:
+ // 85 00 test %eax,(%rax)
+ // 85 01 test %eax,(%rcx)
+ // 85 02 test %eax,(%rdx)
+ // 85 03 test %eax,(%rbx)
+ // 85 06 test %eax,(%rsi)
+ // 85 07 test %eax,(%rdi)
+ //
+ // 85 04 24 test %eax,(%rsp)
+ // 85 45 00 test %eax,0x0(%rbp)
+
+#ifdef ASSERT
+ __ movptr(rax, rbx); // remember where 0x85 should be, for verification below
+#endif
+ // rsp/rbp base encoding takes 3 bytes with the following register values:
+ // rsp 0x04
+ // rbp 0x05
+ __ movzbl(rcx, Address(rbx, 1));
+ __ andptr(rcx, 0x07); // looking for 0x04 .. 0x05
+ __ subptr(rcx, 4); // looking for 0x00 .. 0x01
+ __ cmpptr(rcx, 1);
+ __ jcc(Assembler::above, not_special);
+ __ addptr(rbx, 1);
+ __ bind(not_special);
+#ifdef ASSERT
+ // Verify the correct encoding of the poll we're about to skip.
+ __ cmpb(Address(rax, 0), NativeTstRegMem::instruction_code_memXregl);
+ __ jcc(Assembler::notEqual, bail);
+ // Mask out the modrm bits
+ __ testb(Address(rax, 1), NativeTstRegMem::modrm_mask);
+ // rax encodes to 0, so if the bits are nonzero it's incorrect
+ __ jcc(Assembler::notZero, bail);
+#endif
+ // Adjust return pc forward to step over the safepoint poll instruction
+ __ addptr(rbx, 2);
+ __ movptr(Address(rbp, wordSize), rbx);
+ }
+
+ __ bind(no_adjust);
// Normal exit, register restoring and exit
RegisterSaver::restore_live_registers(masm, save_vectors);
__ ret(0);
+#ifdef ASSERT
+ __ bind(bail);
+ __ stop("Attempting to adjust pc to skip safepoint poll but the return point is not what we expected");
+#endif
+
// make sure all code is generated
masm->flush();
--- a/src/hotspot/cpu/x86/stubRoutines_x86.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/x86/stubRoutines_x86.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, 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
@@ -303,45 +303,45 @@
// used in MacroAssembler::sha512_AVX2
ALIGNED_(64) julong StubRoutines::x86::_k512_W[] =
{
- 0x428a2f98d728ae22LL, 0x7137449123ef65cdLL,
- 0xb5c0fbcfec4d3b2fLL, 0xe9b5dba58189dbbcLL,
- 0x3956c25bf348b538LL, 0x59f111f1b605d019LL,
- 0x923f82a4af194f9bLL, 0xab1c5ed5da6d8118LL,
- 0xd807aa98a3030242LL, 0x12835b0145706fbeLL,
- 0x243185be4ee4b28cLL, 0x550c7dc3d5ffb4e2LL,
- 0x72be5d74f27b896fLL, 0x80deb1fe3b1696b1LL,
- 0x9bdc06a725c71235LL, 0xc19bf174cf692694LL,
- 0xe49b69c19ef14ad2LL, 0xefbe4786384f25e3LL,
- 0x0fc19dc68b8cd5b5LL, 0x240ca1cc77ac9c65LL,
- 0x2de92c6f592b0275LL, 0x4a7484aa6ea6e483LL,
- 0x5cb0a9dcbd41fbd4LL, 0x76f988da831153b5LL,
- 0x983e5152ee66dfabLL, 0xa831c66d2db43210LL,
- 0xb00327c898fb213fLL, 0xbf597fc7beef0ee4LL,
- 0xc6e00bf33da88fc2LL, 0xd5a79147930aa725LL,
- 0x06ca6351e003826fLL, 0x142929670a0e6e70LL,
- 0x27b70a8546d22ffcLL, 0x2e1b21385c26c926LL,
- 0x4d2c6dfc5ac42aedLL, 0x53380d139d95b3dfLL,
- 0x650a73548baf63deLL, 0x766a0abb3c77b2a8LL,
- 0x81c2c92e47edaee6LL, 0x92722c851482353bLL,
- 0xa2bfe8a14cf10364LL, 0xa81a664bbc423001LL,
- 0xc24b8b70d0f89791LL, 0xc76c51a30654be30LL,
- 0xd192e819d6ef5218LL, 0xd69906245565a910LL,
- 0xf40e35855771202aLL, 0x106aa07032bbd1b8LL,
- 0x19a4c116b8d2d0c8LL, 0x1e376c085141ab53LL,
- 0x2748774cdf8eeb99LL, 0x34b0bcb5e19b48a8LL,
- 0x391c0cb3c5c95a63LL, 0x4ed8aa4ae3418acbLL,
- 0x5b9cca4f7763e373LL, 0x682e6ff3d6b2b8a3LL,
- 0x748f82ee5defb2fcLL, 0x78a5636f43172f60LL,
- 0x84c87814a1f0ab72LL, 0x8cc702081a6439ecLL,
- 0x90befffa23631e28LL, 0xa4506cebde82bde9LL,
- 0xbef9a3f7b2c67915LL, 0xc67178f2e372532bLL,
- 0xca273eceea26619cLL, 0xd186b8c721c0c207LL,
- 0xeada7dd6cde0eb1eLL, 0xf57d4f7fee6ed178LL,
- 0x06f067aa72176fbaLL, 0x0a637dc5a2c898a6LL,
- 0x113f9804bef90daeLL, 0x1b710b35131c471bLL,
- 0x28db77f523047d84LL, 0x32caab7b40c72493LL,
- 0x3c9ebe0a15c9bebcLL, 0x431d67c49c100d4cLL,
- 0x4cc5d4becb3e42b6LL, 0x597f299cfc657e2aLL,
- 0x5fcb6fab3ad6faecLL, 0x6c44198c4a475817LL,
+ 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
+ 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
+ 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+ 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
+ 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
+ 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+ 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
+ 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
+ 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+ 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
+ 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
+ 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+ 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
+ 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
+ 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+ 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
+ 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
+ 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+ 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
+ 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
+ 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+ 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
+ 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
+ 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+ 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
+ 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
+ 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+ 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
+ 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
+ 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+ 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
+ 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
+ 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+ 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
+ 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
+ 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+ 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
+ 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
+ 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+ 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL,
};
#endif
--- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, 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
@@ -1148,7 +1148,7 @@
Label slow_path;
#ifndef _LP64
- __ safepoint_poll(slow_path);
+ __ safepoint_poll(slow_path, thread, noreg);
#else
__ safepoint_poll(slow_path, r15_thread, rscratch1);
#endif
--- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_32.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_32.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -61,10 +61,7 @@
Label slow_path;
// If we need a safepoint check, generate full interpreter entry.
- ExternalAddress state(SafepointSynchronize::address_of_state());
- __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
- SafepointSynchronize::_not_synchronized);
- __ jcc(Assembler::notEqual, slow_path);
+ __ safepoint_poll(slow_path, noreg, rdi);
// We don't generate local frame and don't align stack because
// we call stub code and there is no safepoint on this path.
@@ -113,10 +110,7 @@
Label slow_path;
// If we need a safepoint check, generate full interpreter entry.
- ExternalAddress state(SafepointSynchronize::address_of_state());
- __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
- SafepointSynchronize::_not_synchronized);
- __ jcc(Assembler::notEqual, slow_path);
+ __ safepoint_poll(slow_path, noreg, rdi);
// We don't generate local frame and don't align stack because
// we call stub code and there is no safepoint on this path.
--- a/src/hotspot/cpu/x86/templateTable_x86.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/x86/templateTable_x86.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -2692,11 +2692,16 @@
__ bind(skip_register_finalizer);
}
-#ifdef _LP64
if (SafepointMechanism::uses_thread_local_poll() && _desc->bytecode() != Bytecodes::_return_register_finalizer) {
Label no_safepoint;
NOT_PRODUCT(__ block_comment("Thread-local Safepoint poll"));
+#ifdef _LP64
__ testb(Address(r15_thread, Thread::polling_page_offset()), SafepointMechanism::poll_bit());
+#else
+ const Register thread = rdi;
+ __ get_thread(thread);
+ __ testb(Address(thread, Thread::polling_page_offset()), SafepointMechanism::poll_bit());
+#endif
__ jcc(Assembler::zero, no_safepoint);
__ push(state);
__ call_VM(noreg, CAST_FROM_FN_PTR(address,
@@ -2704,7 +2709,6 @@
__ pop(state);
__ bind(no_safepoint);
}
-#endif
// Narrow result if state is itos but result type is smaller.
// Need to narrow in the return bytecode rather than in generate_return_entry
--- a/src/hotspot/cpu/x86/x86_32.ad Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/cpu/x86/x86_32.ad Thu Mar 01 01:35:46 2018 +0100
@@ -317,7 +317,7 @@
// Indicate if the safepoint node needs the polling page as an input.
// Since x86 does have absolute addressing, it doesn't.
bool SafePointNode::needs_polling_address_input() {
- return false;
+ return SafepointMechanism::uses_thread_local_poll();
}
//
@@ -706,34 +706,25 @@
}
if (do_polling() && C->is_method_compilation()) {
- cbuf.relocate(cbuf.insts_end(), relocInfo::poll_return_type, 0);
- emit_opcode(cbuf,0x85);
- emit_rm(cbuf, 0x0, EAX_enc, 0x5); // EAX
- emit_d32(cbuf, (intptr_t)os::get_polling_page());
+ if (SafepointMechanism::uses_thread_local_poll()) {
+ Register pollReg = as_Register(EBX_enc);
+ MacroAssembler masm(&cbuf);
+ masm.get_thread(pollReg);
+ masm.movl(pollReg, Address(pollReg, in_bytes(Thread::polling_page_offset())));
+ masm.relocate(relocInfo::poll_return_type);
+ masm.testl(rax, Address(pollReg, 0));
+ } else {
+ cbuf.relocate(cbuf.insts_end(), relocInfo::poll_return_type, 0);
+ emit_opcode(cbuf,0x85);
+ emit_rm(cbuf, 0x0, EAX_enc, 0x5); // EAX
+ emit_d32(cbuf, (intptr_t)os::get_polling_page());
+ }
}
}
uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
- Compile *C = ra_->C;
- // If method set FPU control word, restore to standard control word
- int size = C->in_24_bit_fp_mode() ? 6 : 0;
- if (C->max_vector_size() > 16) size += 3; // vzeroupper
- if (do_polling() && C->is_method_compilation()) size += 6;
-
- int framesize = C->frame_size_in_bytes();
- assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
- // Remove two words for return addr and rbp,
- framesize -= 2*wordSize;
-
- size++; // popl rbp,
-
- if (framesize >= 128) {
- size += 6;
- } else {
- size += framesize ? 3 : 0;
- }
- size += 64; // added to support ReservedStackAccess
- return size;
+ return MachNode::size(ra_); // too many variables; just compute it
+ // the hard way
}
int MachEpilogNode::reloc() const {
@@ -13336,6 +13327,7 @@
// ============================================================================
// Safepoint Instruction
instruct safePoint_poll(eFlagsReg cr) %{
+ predicate(SafepointMechanism::uses_global_page_poll());
match(SafePoint);
effect(KILL cr);
@@ -13354,6 +13346,25 @@
ins_pipe( ialu_reg_mem );
%}
+instruct safePoint_poll_tls(eFlagsReg cr, eRegP_no_EBP poll) %{
+ predicate(SafepointMechanism::uses_thread_local_poll());
+ match(SafePoint poll);
+ effect(KILL cr, USE poll);
+
+ format %{ "TSTL #EAX,[$poll]\t! Safepoint: poll for GC" %}
+ ins_cost(125);
+ // EBP would need size(3)
+ size(2); /* setting an explicit size will cause debug builds to assert if size is incorrect */
+ ins_encode %{
+ __ relocate(relocInfo::poll_type);
+ address pre_pc = __ pc();
+ __ testl(rax, Address($poll$$Register, 0));
+ address post_pc = __ pc();
+ guarantee(pre_pc[0] == 0x85, "must emit test-ax [reg]");
+ %}
+ ins_pipe(ialu_reg_mem);
+%}
+
// ============================================================================
// This name is KNOWN by the ADLC and cannot be changed.
--- a/src/hotspot/os/bsd/decoder_machO.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/os/bsd/decoder_machO.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -27,6 +27,7 @@
#ifdef __APPLE__
#include "jvm.h"
#include "decoder_machO.hpp"
+#include "memory/allocation.inline.hpp"
#include <cxxabi.h>
#include <mach-o/loader.h>
--- a/src/hotspot/os/linux/globals_linux.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/os/linux/globals_linux.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, 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
@@ -62,6 +62,11 @@
product(bool, UseContainerSupport, true, \
"Enable detection and runtime container configuration support") \
\
+ product(bool, PreferContainerQuotaForCPUCount, true, \
+ "Calculate the container CPU availability based on the value" \
+ " of quotas (if set), when true. Otherwise, use the CPU" \
+ " shares value, provided it is less than quota.") \
+ \
diagnostic(bool, UseCpuAllocPath, false, \
"Use CPU_ALLOC code path in os::active_processor_count ")
--- a/src/hotspot/os/linux/osContainer_linux.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/os/linux/osContainer_linux.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -499,11 +499,11 @@
/* active_processor_count
*
* Calculate an appropriate number of active processors for the
- * VM to use based on these three cgroup options.
+ * VM to use based on these three inputs.
*
* cpu affinity
- * cpu quota & cpu period
- * cpu shares
+ * cgroup cpu quota & cpu period
+ * cgroup cpu shares
*
* Algorithm:
*
@@ -513,42 +513,61 @@
* required CPUs by dividing quota by period.
*
* If shares are in effect (shares != -1), calculate the number
- * of cpus required for the shares by dividing the share value
+ * of CPUs required for the shares by dividing the share value
* by PER_CPU_SHARES.
*
* All results of division are rounded up to the next whole number.
*
- * Return the smaller number from the three different settings.
+ * If neither shares or quotas have been specified, return the
+ * number of active processors in the system.
+ *
+ * If both shares and quotas have been specified, the results are
+ * based on the flag PreferContainerQuotaForCPUCount. If true,
+ * return the quota value. If false return the smallest value
+ * between shares or quotas.
+ *
+ * If shares and/or quotas have been specified, the resulting number
+ * returned will never exceed the number of active processors.
*
* return:
- * number of cpus
- * OSCONTAINER_ERROR if failure occured during extract of cpuset info
+ * number of CPUs
*/
int OSContainer::active_processor_count() {
- int cpu_count, share_count, quota_count;
- int share, quota, period;
+ int quota_count = 0, share_count = 0;
+ int cpu_count, limit_count;
int result;
- cpu_count = os::Linux::active_processor_count();
+ cpu_count = limit_count = os::Linux::active_processor_count();
+ int quota = cpu_quota();
+ int period = cpu_period();
+ int share = cpu_shares();
- share = cpu_shares();
+ if (quota > -1 && period > 0) {
+ quota_count = ceilf((float)quota / (float)period);
+ log_trace(os, container)("CPU Quota count based on quota/period: %d", quota_count);
+ }
if (share > -1) {
share_count = ceilf((float)share / (float)PER_CPU_SHARES);
- log_trace(os, container)("cpu_share count: %d", share_count);
- } else {
- share_count = cpu_count;
+ log_trace(os, container)("CPU Share count based on shares: %d", share_count);
}
- quota = cpu_quota();
- period = cpu_period();
- if (quota > -1 && period > 0) {
- quota_count = ceilf((float)quota / (float)period);
- log_trace(os, container)("quota_count: %d", quota_count);
- } else {
- quota_count = cpu_count;
+ // If both shares and quotas are setup results depend
+ // on flag PreferContainerQuotaForCPUCount.
+ // If true, limit CPU count to quota
+ // If false, use minimum of shares and quotas
+ if (quota_count !=0 && share_count != 0) {
+ if (PreferContainerQuotaForCPUCount) {
+ limit_count = quota_count;
+ } else {
+ limit_count = MIN2(quota_count, share_count);
+ }
+ } else if (quota_count != 0) {
+ limit_count = quota_count;
+ } else if (share_count != 0) {
+ limit_count = share_count;
}
- result = MIN2(cpu_count, MIN2(share_count, quota_count));
+ result = MIN2(cpu_count, limit_count);
log_trace(os, container)("OSContainer::active_processor_count: %d", result);
return result;
}
--- a/src/hotspot/os/windows/os_windows.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/os/windows/os_windows.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -979,11 +979,6 @@
}
-static BOOL (WINAPI *_MiniDumpWriteDump)(HANDLE, DWORD, HANDLE, MINIDUMP_TYPE,
- PMINIDUMP_EXCEPTION_INFORMATION,
- PMINIDUMP_USER_STREAM_INFORMATION,
- PMINIDUMP_CALLBACK_INFORMATION);
-
static HANDLE dumpFile = NULL;
// Check if dump file can be created.
--- a/src/hotspot/os/windows/semaphore_windows.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/os/windows/semaphore_windows.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
#include "memory/allocation.hpp"
-#include <windef.h>
+#include <windows.h>
class WindowsSemaphore : public CHeapObj<mtInternal> {
HANDLE _semaphore;
--- a/src/hotspot/os/windows/sharedRuntimeRem.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/os/windows/sharedRuntimeRem.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "runtime/sharedRuntime.hpp"
#ifdef _WIN64
// These are copied defines from fdlibm.h, this allows us to keep the code
--- a/src/hotspot/os/windows/symbolengine.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/os/windows/symbolengine.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -26,6 +26,7 @@
#include "utilities/globalDefinitions.hpp"
#include "symbolengine.hpp"
#include "utilities/debug.hpp"
+#include "utilities/ostream.hpp"
#include "windbghelp.hpp"
#include <windows.h>
--- a/src/hotspot/os/windows/windbghelp.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/os/windows/windbghelp.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -22,8 +22,8 @@
*
*/
-#ifndef OS_WINDOWS_VM_DBGHELPLOADER_HPP
-#define OS_WINDOWS_VM_DBGHELPLOADER_HPP
+#ifndef OS_WINDOWS_WINDBGHELP_HPP
+#define OS_WINDOWS_WINDBGHELP_HPP
#include <windows.h>
#include <imagehlp.h>
@@ -71,6 +71,5 @@
};
+#endif // OS_WINDOWS_WINDBGHELP_HPP
-#endif // OS_WINDOWS_VM_DBGHELPLOADER_HPP
-
--- a/src/hotspot/share/adlc/arena.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/adlc/arena.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, 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
@@ -69,6 +69,11 @@
//------------------------------Chunk------------------------------------------
// Linked list of raw memory chunks
class Chunk: public CHeapObj {
+ private:
+ // This ordinary operator delete is needed even though not used, so the
+ // below two-argument operator delete will be treated as a placement
+ // delete rather than an ordinary sized delete; see C++14 3.7.4.2/p2.
+ void operator delete(void* p);
public:
void* operator new(size_t size, size_t length) throw();
void operator delete(void* p, size_t length);
--- a/src/hotspot/share/aot/aotCodeHeap.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/aot/aotCodeHeap.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, 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
@@ -194,7 +194,7 @@
}
AOTLib::~AOTLib() {
- free((void*) _name);
+ os::free((void*) _name);
}
AOTCodeHeap::~AOTCodeHeap() {
@@ -207,7 +207,7 @@
}
AOTLib::AOTLib(void* handle, const char* name, int dso_id) : _valid(true), _dl_handle(handle), _dso_id(dso_id) {
- _name = (const char*) strdup(name);
+ _name = (const char*) os::strdup(name);
// Verify that VM runs with the same parameters as AOT tool.
_config = (AOTConfiguration*) load_symbol("A.config");
--- a/src/hotspot/share/c1/c1_Runtime1.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/c1/c1_Runtime1.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -47,6 +47,7 @@
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "oops/access.inline.hpp"
+#include "oops/objArrayOop.inline.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/atomic.hpp"
--- a/src/hotspot/share/ci/ciArray.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/ci/ciArray.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -30,7 +30,7 @@
#include "ci/ciUtilities.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
-#include "oops/typeArrayOop.hpp"
+#include "oops/typeArrayOop.inline.hpp"
// ciArray
//
--- a/src/hotspot/share/ci/ciTypeArray.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/ci/ciTypeArray.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "ci/ciTypeArray.hpp"
#include "ci/ciUtilities.hpp"
+#include "oops/typeArrayOop.inline.hpp"
// ciTypeArray
//
--- a/src/hotspot/share/classfile/classLoader.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/classfile/classLoader.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -137,7 +137,6 @@
PerfCounter* ClassLoader::_sync_JVMDefineClassLockFreeCounter = NULL;
PerfCounter* ClassLoader::_sync_JNIDefineClassLockFreeCounter = NULL;
PerfCounter* ClassLoader::_unsafe_defineClassCallCounter = NULL;
-PerfCounter* ClassLoader::_isUnsyncloadClass = NULL;
PerfCounter* ClassLoader::_load_instance_class_failCounter = NULL;
GrowableArray<ModuleClassPathList*>* ClassLoader::_patch_mod_entries = NULL;
@@ -1642,9 +1641,6 @@
// of the bug fix of 6365597. They are mainly focused on finding out
// the behavior of system & user-defined classloader lock, whether
// ClassLoader.loadClass/findClass is being called synchronized or not.
- // Also two additional counters are created to see whether 'UnsyncloadClass'
- // flag is being set or not and how many times load_instance_class call
- // fails with linkageError etc.
NEWPERFEVENTCOUNTER(_sync_systemLoaderLockContentionRate, SUN_CLS,
"systemLoaderLockContentionRate");
NEWPERFEVENTCOUNTER(_sync_nonSystemLoaderLockContentionRate, SUN_CLS,
@@ -1660,14 +1656,8 @@
NEWPERFEVENTCOUNTER(_unsafe_defineClassCallCounter, SUN_CLS,
"unsafeDefineClassCalls");
- NEWPERFEVENTCOUNTER(_isUnsyncloadClass, SUN_CLS, "isUnsyncloadClassSet");
NEWPERFEVENTCOUNTER(_load_instance_class_failCounter, SUN_CLS,
"loadInstanceClassFailRate");
-
- // increment the isUnsyncloadClass counter if UnsyncloadClass is set.
- if (UnsyncloadClass) {
- _isUnsyncloadClass->inc();
- }
}
// lookup zip library entry points
--- a/src/hotspot/share/classfile/classLoader.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/classfile/classLoader.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -207,7 +207,6 @@
static PerfCounter* _sync_JNIDefineClassLockFreeCounter;
static PerfCounter* _unsafe_defineClassCallCounter;
- static PerfCounter* _isUnsyncloadClass;
static PerfCounter* _load_instance_class_failCounter;
// The boot class path consists of 3 ordered pieces:
--- a/src/hotspot/share/classfile/classLoaderData.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/classfile/classLoaderData.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1001,9 +1001,8 @@
if (!is_anonymous) {
- ClassLoaderData** cld_addr = java_lang_ClassLoader::loader_data_addr(loader());
// First, Atomically set it
- ClassLoaderData* old = Atomic::cmpxchg(cld, cld_addr, (ClassLoaderData*)NULL);
+ ClassLoaderData* old = java_lang_ClassLoader::cmpxchg_loader_data(cld, loader(), NULL);
if (old != NULL) {
delete cld;
// Returns the data.
--- a/src/hotspot/share/classfile/javaAssertions.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/classfile/javaAssertions.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -31,6 +31,7 @@
#include "memory/oopFactory.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "runtime/handles.inline.hpp"
bool JavaAssertions::_userDefault = false;
--- a/src/hotspot/share/classfile/javaClasses.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/classfile/javaClasses.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -46,7 +46,7 @@
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
-#include "oops/typeArrayOop.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "prims/resolvedMethodTable.hpp"
#include "runtime/fieldDescriptor.hpp"
#include "runtime/handles.inline.hpp"
@@ -3403,7 +3403,7 @@
DependencyContext java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(oop call_site) {
assert(java_lang_invoke_MethodHandleNatives_CallSiteContext::is_instance(call_site), "");
- intptr_t* vmdeps_addr = (intptr_t*)call_site->address_field_addr(_vmdependencies_offset);
+ intptr_t* vmdeps_addr = (intptr_t*)call_site->field_addr(_vmdependencies_offset);
DependencyContext dep_ctx(vmdeps_addr);
return dep_ctx;
}
@@ -3458,13 +3458,14 @@
int java_lang_ClassLoader::name_offset = -1;
int java_lang_ClassLoader::unnamedModule_offset = -1;
-ClassLoaderData** java_lang_ClassLoader::loader_data_addr(oop loader) {
- assert(loader != NULL && oopDesc::is_oop(loader), "loader must be oop");
- return (ClassLoaderData**) loader->address_field_addr(_loader_data_offset);
-}
-
ClassLoaderData* java_lang_ClassLoader::loader_data(oop loader) {
- return *java_lang_ClassLoader::loader_data_addr(loader);
+ assert(loader != NULL && oopDesc::is_oop(loader), "loader must be oop");
+ return HeapAccess<>::load_at(loader, _loader_data_offset);
+}
+
+ClassLoaderData* java_lang_ClassLoader::cmpxchg_loader_data(ClassLoaderData* new_data, oop loader, ClassLoaderData* expected_data) {
+ assert(loader != NULL && oopDesc::is_oop(loader), "loader must be oop");
+ return HeapAccess<>::atomic_cmpxchg_at(new_data, loader, _loader_data_offset, expected_data);
}
void java_lang_ClassLoader::compute_offsets() {
--- a/src/hotspot/share/classfile/javaClasses.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/classfile/javaClasses.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -881,15 +881,15 @@
static inline oop referent(oop ref);
static inline void set_referent(oop ref, oop value);
static inline void set_referent_raw(oop ref, oop value);
- static inline HeapWord* referent_addr(oop ref);
+ static inline HeapWord* referent_addr_raw(oop ref);
static inline oop next(oop ref);
static inline void set_next(oop ref, oop value);
static inline void set_next_raw(oop ref, oop value);
- static inline HeapWord* next_addr(oop ref);
+ static inline HeapWord* next_addr_raw(oop ref);
static inline oop discovered(oop ref);
static inline void set_discovered(oop ref, oop value);
static inline void set_discovered_raw(oop ref, oop value);
- static inline HeapWord* discovered_addr(oop ref);
+ static inline HeapWord* discovered_addr_raw(oop ref);
static bool is_referent_field(oop obj, ptrdiff_t offset);
static inline bool is_phantom(oop ref);
};
@@ -1229,8 +1229,8 @@
public:
static void compute_offsets();
- static ClassLoaderData** loader_data_addr(oop loader);
static ClassLoaderData* loader_data(oop loader);
+ static ClassLoaderData* cmpxchg_loader_data(ClassLoaderData* new_data, oop loader, ClassLoaderData* expected_data);
static oop parent(oop loader);
static oop name(oop loader);
--- a/src/hotspot/share/classfile/javaClasses.inline.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/classfile/javaClasses.inline.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -100,8 +100,8 @@
void java_lang_ref_Reference::set_referent_raw(oop ref, oop value) {
ref->obj_field_put_raw(referent_offset, value);
}
-HeapWord* java_lang_ref_Reference::referent_addr(oop ref) {
- return ref->obj_field_addr<HeapWord>(referent_offset);
+HeapWord* java_lang_ref_Reference::referent_addr_raw(oop ref) {
+ return ref->obj_field_addr_raw<HeapWord>(referent_offset);
}
oop java_lang_ref_Reference::next(oop ref) {
return ref->obj_field(next_offset);
@@ -112,8 +112,8 @@
void java_lang_ref_Reference::set_next_raw(oop ref, oop value) {
ref->obj_field_put_raw(next_offset, value);
}
-HeapWord* java_lang_ref_Reference::next_addr(oop ref) {
- return ref->obj_field_addr<HeapWord>(next_offset);
+HeapWord* java_lang_ref_Reference::next_addr_raw(oop ref) {
+ return ref->obj_field_addr_raw<HeapWord>(next_offset);
}
oop java_lang_ref_Reference::discovered(oop ref) {
return ref->obj_field(discovered_offset);
@@ -124,8 +124,8 @@
void java_lang_ref_Reference::set_discovered_raw(oop ref, oop value) {
ref->obj_field_put_raw(discovered_offset, value);
}
-HeapWord* java_lang_ref_Reference::discovered_addr(oop ref) {
- return ref->obj_field_addr<HeapWord>(discovered_offset);
+HeapWord* java_lang_ref_Reference::discovered_addr_raw(oop ref) {
+ return ref->obj_field_addr_raw<HeapWord>(discovered_offset);
}
bool java_lang_ref_Reference::is_phantom(oop ref) {
return InstanceKlass::cast(ref->klass())->reference_type() == REF_PHANTOM;
--- a/src/hotspot/share/classfile/stringTable.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/classfile/stringTable.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -37,6 +37,7 @@
#include "memory/resourceArea.hpp"
#include "oops/access.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/mutexLocker.hpp"
#include "services/diagnosticCommand.hpp"
--- a/src/hotspot/share/classfile/systemDictionary.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/classfile/systemDictionary.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -106,7 +106,6 @@
oop SystemDictionary::_java_system_loader = NULL;
oop SystemDictionary::_java_platform_loader = NULL;
-bool SystemDictionary::_has_loadClassInternal = false;
bool SystemDictionary::_has_checkPackageAccess = false;
// lazily initialized klass variables
@@ -159,7 +158,7 @@
// Parallel class loading check
bool SystemDictionary::is_parallelCapable(Handle class_loader) {
- if (UnsyncloadClass || class_loader.is_null()) return true;
+ if (class_loader.is_null()) return true;
if (AlwaysLockClassLoader) return false;
return java_lang_ClassLoader::parallelCapable(class_loader());
}
@@ -503,8 +502,7 @@
//
// We only get here if
// 1) custom classLoader, i.e. not bootstrap classloader
-// 2) UnsyncloadClass not set
-// 3) custom classLoader has broken the class loader objectLock
+// 2) custom classLoader has broken the class loader objectLock
// so another thread got here in parallel
//
// lockObject must be held.
@@ -594,7 +592,6 @@
} else {
placeholder = placeholders()->get_entry(p_index, p_hash, name, loader_data);
if (placeholder && placeholder->super_load_in_progress() ){
- // Before UnsyncloadClass:
// We only get here if the application has released the
// classloader lock when another thread was in the middle of loading a
// superclass/superinterface for this class, and now
@@ -687,9 +684,9 @@
// defining the class in parallel by accident.
// This lock must be acquired here so the waiter will find
// any successful result in the SystemDictionary and not attempt
- // the define
- // ParallelCapable Classloaders and the bootstrap classloader,
- // or all classloaders with UnsyncloadClass do not acquire lock here
+ // the define.
+ // ParallelCapable Classloaders and the bootstrap classloader
+ // do not acquire lock here.
bool DoObjectLock = true;
if (is_parallelCapable(class_loader)) {
DoObjectLock = false;
@@ -765,14 +762,11 @@
// and that lock is still held when calling classloader's loadClass.
// For these classloaders, we ensure that the first requestor
// completes the load and other requestors wait for completion.
- // case 3. UnsyncloadClass - don't use objectLocker
- // With this flag, we allow parallel classloading of a
- // class/classloader pair
- // case4. Bootstrap classloader - don't own objectLocker
+ // case 3. Bootstrap classloader - don't own objectLocker
// This classloader supports parallelism at the classloader level,
// but only allows a single load of a class/classloader pair.
// No performance benefit and no deadlock issues.
- // case 5. parallelCapable user level classloaders - without objectLocker
+ // case 4. parallelCapable user level classloaders - without objectLocker
// Allow parallel classloading of a class/classloader pair
{
@@ -788,7 +782,7 @@
// case 1: traditional: should never see load_in_progress.
while (!class_has_been_loaded && oldprobe && oldprobe->instance_load_in_progress()) {
- // case 4: bootstrap classloader: prevent futile classloading,
+ // case 3: bootstrap classloader: prevent futile classloading,
// wait on first requestor
if (class_loader.is_null()) {
SystemDictionary_lock->wait();
@@ -811,7 +805,7 @@
}
}
// All cases: add LOAD_INSTANCE holding SystemDictionary_lock
- // case 3: UnsyncloadClass || case 5: parallelCapable: allow competing threads to try
+ // case 4: parallelCapable: allow competing threads to try
// LOAD_INSTANCE in parallel
if (!throw_circularity_error && !class_has_been_loaded) {
@@ -844,28 +838,6 @@
// Do actual loading
k = load_instance_class(name, class_loader, THREAD);
- // For UnsyncloadClass only
- // If they got a linkageError, check if a parallel class load succeeded.
- // If it did, then for bytecode resolution the specification requires
- // that we return the same result we did for the other thread, i.e. the
- // successfully loaded InstanceKlass
- // Should not get here for classloaders that support parallelism
- // with the new cleaner mechanism, even with AllowParallelDefineClass
- // Bootstrap goes through here to allow for an extra guarantee check
- if (UnsyncloadClass || (class_loader.is_null())) {
- if (k == NULL && HAS_PENDING_EXCEPTION
- && PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) {
- MutexLocker mu(SystemDictionary_lock, THREAD);
- InstanceKlass* check = find_class(d_hash, name, dictionary);
- if (check != NULL) {
- // Klass is already loaded, so just use it
- k = check;
- CLEAR_PENDING_EXCEPTION;
- guarantee((!class_loader.is_null()), "dup definition for bootstrap loader?");
- }
- }
- }
-
// If everything was OK (no exceptions, no null return value), and
// class_loader is NOT the defining loader, do a little more bookkeeping.
if (!HAS_PENDING_EXCEPTION && k != NULL &&
@@ -1097,7 +1069,7 @@
HandleMark hm(THREAD);
// Classloaders that support parallelism, e.g. bootstrap classloader,
- // or all classloaders with UnsyncloadClass do not acquire lock here
+ // do not acquire lock here
bool DoObjectLock = true;
if (is_parallelCapable(class_loader)) {
DoObjectLock = false;
@@ -1556,40 +1528,17 @@
InstanceKlass* spec_klass = SystemDictionary::ClassLoader_klass();
- // Call public unsynchronized loadClass(String) directly for all class loaders
- // for parallelCapable class loaders. JDK >=7, loadClass(String, boolean) will
+ // Call public unsynchronized loadClass(String) directly for all class loaders.
+ // For parallelCapable class loaders, JDK >=7, loadClass(String, boolean) will
// acquire a class-name based lock rather than the class loader object lock.
- // JDK < 7 already acquire the class loader lock in loadClass(String, boolean),
- // so the call to loadClassInternal() was not required.
- //
- // UnsyncloadClass flag means both call loadClass(String) and do
- // not acquire the class loader lock even for class loaders that are
- // not parallelCapable. This was a risky transitional
- // flag for diagnostic purposes only. It is risky to call
- // custom class loaders without synchronization.
- // WARNING If a custom class loader does NOT synchronizer findClass, or callers of
- // findClass, the UnsyncloadClass flag risks unexpected timing bugs in the field.
- // Do NOT assume this will be supported in future releases.
- //
- // Added MustCallLoadClassInternal in case we discover in the field
- // a customer that counts on this call
- if (MustCallLoadClassInternal && has_loadClassInternal()) {
- JavaCalls::call_special(&result,
- class_loader,
- spec_klass,
- vmSymbols::loadClassInternal_name(),
- vmSymbols::string_class_signature(),
- string,
- CHECK_NULL);
- } else {
- JavaCalls::call_virtual(&result,
- class_loader,
- spec_klass,
- vmSymbols::loadClass_name(),
- vmSymbols::string_class_signature(),
- string,
- CHECK_NULL);
- }
+ // JDK < 7 already acquire the class loader lock in loadClass(String, boolean).
+ JavaCalls::call_virtual(&result,
+ class_loader,
+ spec_klass,
+ vmSymbols::loadClass_name(),
+ vmSymbols::string_class_signature(),
+ string,
+ CHECK_NULL);
assert(result.get_type() == T_OBJECT, "just checking");
oop obj = (oop) result.get_jobject();
@@ -1718,7 +1667,7 @@
{
MutexLocker mu(SystemDictionary_lock, THREAD);
// First check if class already defined
- if (UnsyncloadClass || (is_parallelDefine(class_loader))) {
+ if (is_parallelDefine(class_loader)) {
InstanceKlass* check = find_class(d_hash, name_h, dictionary);
if (check != NULL) {
return check;
@@ -1737,7 +1686,7 @@
// Only special cases allow parallel defines and can use other thread's results
// Other cases fall through, and may run into duplicate defines
// caught by finding an entry in the SystemDictionary
- if ((UnsyncloadClass || is_parallelDefine(class_loader)) && (probe->instance_klass() != NULL)) {
+ if (is_parallelDefine(class_loader) && (probe->instance_klass() != NULL)) {
placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, THREAD);
SystemDictionary_lock->notify_all();
#ifdef ASSERT
@@ -2174,10 +2123,6 @@
//_box_klasses[T_OBJECT] = WK_KLASS(object_klass);
//_box_klasses[T_ARRAY] = WK_KLASS(object_klass);
- { // Compute whether we should use loadClass or loadClassInternal when loading classes.
- Method* method = InstanceKlass::cast(ClassLoader_klass())->find_method(vmSymbols::loadClassInternal_name(), vmSymbols::string_class_signature());
- _has_loadClassInternal = (method != NULL);
- }
{ // Compute whether we should use checkPackageAccess or NOT
Method* method = InstanceKlass::cast(ClassLoader_klass())->find_method(vmSymbols::checkPackageAccess_name(), vmSymbols::class_protectiondomain_signature());
_has_checkPackageAccess = (method != NULL);
--- a/src/hotspot/share/classfile/systemDictionary.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/classfile/systemDictionary.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -467,9 +467,6 @@
static void load_abstract_ownable_synchronizer_klass(TRAPS);
protected:
- // Tells whether ClassLoader.loadClassInternal is present
- static bool has_loadClassInternal() { return _has_loadClassInternal; }
-
// Returns the class loader data to be used when looking up/updating the
// system dictionary.
static ClassLoaderData *class_loader_data(Handle class_loader) {
@@ -746,7 +743,6 @@
static oop _java_system_loader;
static oop _java_platform_loader;
- static bool _has_loadClassInternal;
static bool _has_checkPackageAccess;
};
--- a/src/hotspot/share/classfile/systemDictionaryShared.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, 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
@@ -48,6 +48,7 @@
#include "oops/klass.inline.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
--- a/src/hotspot/share/classfile/vmSymbols.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/classfile/vmSymbols.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -360,7 +360,6 @@
template(run_finalization_name, "runFinalization") \
template(dispatchUncaughtException_name, "dispatchUncaughtException") \
template(loadClass_name, "loadClass") \
- template(loadClassInternal_name, "loadClassInternal") \
template(get_name, "get") \
template(put_name, "put") \
template(type_name, "type") \
--- a/src/hotspot/share/gc/cms/cmsCollectorPolicy.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/cms/cmsCollectorPolicy.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -51,26 +51,3 @@
_space_alignment = _gen_alignment = (uintx)Generation::GenGrain;
_heap_alignment = compute_heap_alignment();
}
-
-void ConcurrentMarkSweepPolicy::initialize_generations() {
- _young_gen_spec = new GenerationSpec(Generation::ParNew, _initial_young_size,
- _max_young_size, _gen_alignment);
- _old_gen_spec = new GenerationSpec(Generation::ConcurrentMarkSweep,
- _initial_old_size, _max_old_size, _gen_alignment);
-}
-
-void ConcurrentMarkSweepPolicy::initialize_size_policy(size_t init_eden_size,
- size_t init_promo_size,
- size_t init_survivor_size) {
- double max_gc_pause_sec = ((double) MaxGCPauseMillis)/1000.0;
- _size_policy = new AdaptiveSizePolicy(init_eden_size,
- init_promo_size,
- init_survivor_size,
- max_gc_pause_sec,
- GCTimeRatio);
-}
-
-void ConcurrentMarkSweepPolicy::initialize_gc_policy_counters() {
- // initialize the policy counters - 2 collectors, 2 generations
- _gc_policy_counters = new GCPolicyCounters("ParNew:CMS", 2, 2);
-}
--- a/src/hotspot/share/gc/cms/cmsCollectorPolicy.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/cms/cmsCollectorPolicy.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -30,18 +30,9 @@
class ConcurrentMarkSweepPolicy : public GenCollectorPolicy {
protected:
void initialize_alignments();
- void initialize_generations();
public:
ConcurrentMarkSweepPolicy() {}
-
- ConcurrentMarkSweepPolicy* as_concurrent_mark_sweep_policy() { return this; }
-
- void initialize_gc_policy_counters();
-
- virtual void initialize_size_policy(size_t init_eden_size,
- size_t init_promo_size,
- size_t init_survivor_size);
};
#endif // SHARE_VM_GC_CMS_CMSCOLLECTORPOLICY_HPP
--- a/src/hotspot/share/gc/cms/cmsHeap.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/cms/cmsHeap.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -64,7 +64,13 @@
};
CMSHeap::CMSHeap(GenCollectorPolicy *policy) :
- GenCollectedHeap(policy), _eden_pool(NULL), _survivor_pool(NULL), _old_pool(NULL) {
+ GenCollectedHeap(policy,
+ Generation::ParNew,
+ Generation::ConcurrentMarkSweep,
+ "ParNew::CMS"),
+ _eden_pool(NULL),
+ _survivor_pool(NULL),
+ _old_pool(NULL) {
_workers = new WorkGang("GC Thread", ParallelGCThreads,
/* are_GC_task_threads */true,
/* are_ConcurrentGC_threads */false);
@@ -77,7 +83,6 @@
// If we are running CMS, create the collector responsible
// for collecting the CMS generations.
- assert(collector_policy()->is_concurrent_mark_sweep_policy(), "must be CMS policy");
if (!create_cms_collector()) {
return JNI_ENOMEM;
}
@@ -152,11 +157,10 @@
bool CMSHeap::create_cms_collector() {
assert(old_gen()->kind() == Generation::ConcurrentMarkSweep,
"Unexpected generation kinds");
- assert(gen_policy()->is_concurrent_mark_sweep_policy(), "Unexpected policy type");
CMSCollector* collector =
new CMSCollector((ConcurrentMarkSweepGeneration*) old_gen(),
rem_set(),
- gen_policy()->as_concurrent_mark_sweep_policy());
+ (ConcurrentMarkSweepPolicy*) gen_policy());
if (collector == NULL || !collector->completed_initialization()) {
if (collector) {
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, 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
@@ -300,8 +300,7 @@
}
AdaptiveSizePolicy* CMSCollector::size_policy() {
- CMSHeap* heap = CMSHeap::heap();
- return heap->gen_policy()->size_policy();
+ return CMSHeap::heap()->size_policy();
}
void ConcurrentMarkSweepGeneration::initialize_performance_counters() {
@@ -1182,8 +1181,6 @@
// this is not likely to be productive in practice because it's probably too
// late anyway.
CMSHeap* heap = CMSHeap::heap();
- assert(heap->collector_policy()->is_generation_policy(),
- "You may want to check the correctness of the following");
if (heap->incremental_collection_will_fail(true /* consult_young */)) {
log.print("CMSCollector: collect because incremental collection will fail ");
return true;
@@ -1498,7 +1495,7 @@
max_eden_size,
full,
gc_cause,
- heap->collector_policy());
+ heap->soft_ref_policy());
// Reset the expansion cause, now that we just completed
// a collection cycle.
@@ -1890,7 +1887,7 @@
}
// Should this be in gc_epilogue?
- collector_policy()->counters()->update_counters();
+ heap->counters()->update_counters();
{
// Clear _foregroundGCShouldWait and, in the event that the
@@ -5551,7 +5548,7 @@
// already have the lock
assert(_collectorState == Resetting, "just checking");
assert_lock_strong(bitMapLock());
- GCIdMarkAndRestore gc_id_mark(_cmsThread->gc_id());
+ GCIdMark gc_id_mark(_cmsThread->gc_id());
_markBitMap.clear_all();
_collectorState = Idling;
register_gc_end();
--- a/src/hotspot/share/gc/cms/parNewGeneration.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/cms/parNewGeneration.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -889,7 +889,7 @@
_gc_timer->register_gc_start();
- AdaptiveSizePolicy* size_policy = gch->gen_policy()->size_policy();
+ AdaptiveSizePolicy* size_policy = gch->size_policy();
WorkGang* workers = gch->workers();
assert(workers != NULL, "Need workgang for parallel work");
uint active_workers =
@@ -1490,4 +1490,3 @@
SharedRestorePreservedMarksTaskExecutor task_executor(CMSHeap::heap()->workers());
_preserved_marks_set.restore(&task_executor);
}
-
--- a/src/hotspot/share/gc/g1/concurrentMarkThread.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/g1/concurrentMarkThread.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, 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
@@ -268,8 +268,6 @@
cm()->concurrent_cycle_start();
- assert(GCId::current() != GCId::undefined(), "GC id should have been set up by the initial mark GC.");
-
GCTraceConcTime(Info, gc) tt("Concurrent Cycle");
{
ResourceMark rm;
--- a/src/hotspot/share/gc/g1/g1AllocationContext.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1AllocationContext.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -41,12 +41,4 @@
}
};
-class AllocationContextStats: public StackObj {
-public:
- inline void clear() { }
- inline void update(bool full_gc) { }
- inline void update_after_mark() { }
- inline bool available() { return false; }
-};
-
#endif // SHARE_VM_GC_G1_G1ALLOCATIONCONTEXT_HPP
--- a/src/hotspot/share/gc/g1/g1Arguments.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1Arguments.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -40,9 +40,6 @@
void G1Arguments::initialize_flags() {
GCArguments::initialize_flags();
assert(UseG1GC, "Error");
-#if defined(COMPILER1) || INCLUDE_JVMCI
- FastTLABRefill = false;
-#endif
FLAG_SET_DEFAULT(ParallelGCThreads, Abstract_VM_Version::parallel_worker_threads());
if (ParallelGCThreads == 0) {
assert(!FLAG_IS_DEFAULT(ParallelGCThreads), "The default value for ParallelGCThreads should not be 0.");
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -59,6 +59,7 @@
#include "gc/g1/heapRegionRemSet.hpp"
#include "gc/g1/heapRegionSet.inline.hpp"
#include "gc/g1/vm_operations_g1.hpp"
+#include "gc/shared/adaptiveSizePolicy.hpp"
#include "gc/shared/gcHeapSummary.hpp"
#include "gc/shared/gcId.hpp"
#include "gc/shared/gcLocker.inline.hpp"
@@ -1168,7 +1169,7 @@
}
const bool do_clear_all_soft_refs = clear_all_soft_refs ||
- collector_policy()->should_clear_all_soft_refs();
+ soft_ref_policy()->should_clear_all_soft_refs();
G1FullCollector collector(this, &_full_gc_memory_manager, explicit_gc, do_clear_all_soft_refs);
GCTraceTime(Info, gc) tm("Pause Full", NULL, gc_cause(), true);
@@ -1343,7 +1344,7 @@
return result;
}
- assert(!collector_policy()->should_clear_all_soft_refs(),
+ assert(!soft_ref_policy()->should_clear_all_soft_refs(),
"Flag should have been handled and cleared prior to this point");
// What else? We might try synchronous finalization later. If the total
@@ -1463,6 +1464,7 @@
CollectedHeap(),
_young_gen_sampling_thread(NULL),
_collector_policy(collector_policy),
+ _soft_ref_policy(),
_memory_manager("G1 Young Generation", "end of minor GC"),
_full_gc_memory_manager("G1 Old Generation", "end of major GC"),
_eden_pool(NULL),
@@ -1893,6 +1895,10 @@
return _collector_policy;
}
+SoftRefPolicy* G1CollectedHeap::soft_ref_policy() {
+ return &_soft_ref_policy;
+}
+
size_t G1CollectedHeap::capacity() const {
return _hrm.length() * HeapRegion::GrainBytes;
}
@@ -1989,7 +1995,6 @@
switch (cause) {
case GCCause::_java_lang_system_gc: return ExplicitGCInvokesConcurrent;
case GCCause::_dcmd_gc_run: return ExplicitGCInvokesConcurrent;
- case GCCause::_update_allocation_context_stats_inc: return true;
case GCCause::_wb_conc_mark: return true;
default : return false;
}
@@ -2542,8 +2547,6 @@
resize_all_tlabs();
g1_policy()->phase_times()->record_resize_tlab_time_ms((os::elapsedTime() - start) * 1000.0);
- allocation_context_stats().update(full);
-
MemoryService::track_memory_usage();
// We have just completed a GC. Update the soft reference
// policy with the new heap occupancy
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -49,6 +49,7 @@
#include "gc/shared/gcHeapSummary.hpp"
#include "gc/shared/plab.hpp"
#include "gc/shared/preservedMarks.hpp"
+#include "gc/shared/softRefPolicy.hpp"
#include "memory/memRegion.hpp"
#include "services/memoryManager.hpp"
#include "utilities/stack.hpp"
@@ -150,6 +151,8 @@
WorkGang* _workers;
G1CollectorPolicy* _collector_policy;
+ SoftRefPolicy _soft_ref_policy;
+
GCMemoryManager _memory_manager;
GCMemoryManager _full_gc_memory_manager;
@@ -222,9 +225,6 @@
// Class that handles archive allocation ranges.
G1ArchiveAllocator* _archive_allocator;
- // Statistics for each allocation context
- AllocationContextStats _allocation_context_stats;
-
// GC allocation statistics policy for survivors.
G1EvacStats _survivor_evac_stats;
@@ -277,8 +277,7 @@
// (b) cause == _g1_humongous_allocation
// (c) cause == _java_lang_system_gc and +ExplicitGCInvokesConcurrent.
// (d) cause == _dcmd_gc_run and +ExplicitGCInvokesConcurrent.
- // (e) cause == _update_allocation_context_stats_inc
- // (f) cause == _wb_conc_mark
+ // (e) cause == _wb_conc_mark
bool should_do_concurrent_full_gc(GCCause::Cause cause);
// indicates whether we are in young or mixed GC mode
@@ -580,8 +579,6 @@
// Determines PLAB size for a given destination.
inline size_t desired_plab_sz(InCSetState dest);
- inline AllocationContextStats& allocation_context_stats();
-
// Do anything common to GC's.
void gc_prologue(bool full);
void gc_epilogue(bool full);
@@ -998,8 +995,7 @@
virtual CollectorPolicy* collector_policy() const;
- // Adaptive size policy. No such thing for g1.
- virtual AdaptiveSizePolicy* size_policy() { return NULL; }
+ virtual SoftRefPolicy* soft_ref_policy();
virtual GrowableArray<GCMemoryManager*> memory_managers();
virtual GrowableArray<MemoryPool*> memory_pools();
@@ -1130,11 +1126,6 @@
// "CollectedHeap" supports.
virtual void collect(GCCause::Cause cause);
- virtual bool copy_allocation_context_stats(const jint* contexts,
- jlong* totals,
- jbyte* accuracy,
- jint len);
-
// True iff an evacuation has failed in the most-recent collection.
bool evacuation_failed() { return _evacuation_failed; }
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -57,10 +57,6 @@
// Inline functions for G1CollectedHeap
-inline AllocationContextStats& G1CollectedHeap::allocation_context_stats() {
- return _allocation_context_stats;
-}
-
// Return the region with the given index. It assumes the index is valid.
inline HeapRegion* G1CollectedHeap::region_at(uint index) const { return _hrm.at(index); }
--- a/src/hotspot/share/gc/g1/g1CollectedHeap_ext.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap_ext.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -30,13 +30,6 @@
class STWGCTimer;
-bool G1CollectedHeap::copy_allocation_context_stats(const jint* contexts,
- jlong* totals,
- jbyte* accuracy,
- jint len) {
- return false;
-}
-
G1Policy* G1CollectedHeap::create_g1_policy(STWGCTimer* gc_timer) {
return new G1DefaultPolicy(gc_timer);
}
--- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -38,6 +38,7 @@
#include "gc/g1/heapRegion.inline.hpp"
#include "gc/g1/heapRegionRemSet.hpp"
#include "gc/g1/heapRegionSet.inline.hpp"
+#include "gc/shared/adaptiveSizePolicy.hpp"
#include "gc/shared/gcId.hpp"
#include "gc/shared/gcTimer.hpp"
#include "gc/shared/gcTrace.hpp"
@@ -1275,7 +1276,6 @@
// We reclaimed old regions so we should calculate the sizes to make
// sure we update the old gen/space data.
g1h->g1mm()->update_sizes();
- g1h->allocation_context_stats().update_after_mark();
}
void G1ConcurrentMark::complete_cleanup() {
--- a/src/hotspot/share/gc/g1/g1FullGCScope.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1FullGCScope.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -35,7 +35,7 @@
_tracer(),
_active(),
_cpu_time(),
- _soft_refs(clear_soft, _g1h->collector_policy()),
+ _soft_refs(clear_soft, _g1h->soft_ref_policy()),
_memory_stats(memory_manager, _g1h->gc_cause()),
_collector_stats(_g1h->g1mm()->full_collection_counters()),
_heap_transition(_g1h) {
--- a/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, 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
@@ -235,13 +235,7 @@
size_t const _page_size;
public:
G1PretouchTask(char* start_address, char* end_address, size_t page_size) :
- AbstractGangTask("G1 PreTouch",
- Universe::is_fully_initialized() &&
- Thread::current()->is_Named_thread() ? GCId::current_raw() :
- // During VM initialization there is
- // no GC cycle that this task can be
- // associated with.
- GCId::undefined()),
+ AbstractGangTask("G1 PreTouch"),
_cur_addr(start_address),
_start_addr(start_address),
_end_addr(end_address),
--- a/src/hotspot/share/gc/g1/g1RemSet.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1RemSet.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -586,6 +586,20 @@
return;
}
+ // While we are processing RSet buffers during the collection, we
+ // actually don't want to scan any cards on the collection set,
+ // since we don't want to update remembered sets with entries that
+ // point into the collection set, given that live objects from the
+ // collection set are about to move and such entries will be stale
+ // very soon. This change also deals with a reliability issue which
+ // involves scanning a card in the collection set and coming across
+ // an array that was being chunked and looking malformed. Note,
+ // however, that if evacuation fails, we have to scan any objects
+ // that were not moved and create any missing entries.
+ if (r->in_collection_set()) {
+ return;
+ }
+
// The result from the hot card cache insert call is either:
// * pointer to the current card
// (implying that the current card is not 'hot'),
@@ -610,7 +624,8 @@
// Check whether the region formerly in the cache should be
// ignored, as discussed earlier for the original card. The
- // region could have been freed while in the cache.
+ // region could have been freed while in the cache. The cset is
+ // not relevant here, since we're in concurrent phase.
if (!r->is_old_or_humongous()) {
return;
}
--- a/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -220,8 +220,39 @@
return *p == g1_young_card_val();
}
-void G1SATBCardTableLoggingModRefBS::flush_deferred_barriers(JavaThread* thread) {
- CardTableModRefBS::flush_deferred_barriers(thread);
+void G1SATBCardTableLoggingModRefBS::on_thread_attach(JavaThread* thread) {
+ // This method initializes the SATB and dirty card queues before a
+ // JavaThread is added to the Java thread list. Right now, we don't
+ // have to do anything to the dirty card queue (it should have been
+ // activated when the thread was created), but we have to activate
+ // the SATB queue if the thread is created while a marking cycle is
+ // in progress. The activation / de-activation of the SATB queues at
+ // the beginning / end of a marking cycle is done during safepoints
+ // so we have to make sure this method is called outside one to be
+ // able to safely read the active field of the SATB queue set. Right
+ // now, it is called just before the thread is added to the Java
+ // thread list in the Threads::add() method. That method is holding
+ // the Threads_lock which ensures we are outside a safepoint. We
+ // cannot do the obvious and set the active field of the SATB queue
+ // when the thread is created given that, in some cases, safepoints
+ // might happen between the JavaThread constructor being called and the
+ // thread being added to the Java thread list (an example of this is
+ // when the structure for the DestroyJavaVM thread is created).
+ assert(!SafepointSynchronize::is_at_safepoint(), "We should not be at a safepoint");
+ assert(!thread->satb_mark_queue().is_active(), "SATB queue should not be active");
+ assert(thread->satb_mark_queue().is_empty(), "SATB queue should be empty");
+ assert(thread->dirty_card_queue().is_active(), "Dirty card queue should be active");
+
+ // If we are creating the thread during a marking cycle, we should
+ // set the active field of the SATB queue to true.
+ if (thread->satb_mark_queue_set().is_active()) {
+ thread->satb_mark_queue().set_active(true);
+ }
+}
+
+void G1SATBCardTableLoggingModRefBS::on_thread_detach(JavaThread* thread) {
+ // Flush any deferred card marks, SATB buffers and dirty card queue buffers
+ CardTableModRefBS::on_thread_detach(thread);
thread->satb_mark_queue().flush();
thread->dirty_card_queue().flush();
}
--- a/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -154,7 +154,8 @@
void write_ref_field_post(T* field, oop new_val);
void write_ref_field_post_slow(volatile jbyte* byte);
- virtual void flush_deferred_barriers(JavaThread* thread);
+ virtual void on_thread_attach(JavaThread* thread);
+ virtual void on_thread_detach(JavaThread* thread);
virtual bool card_mark_must_follow_store() const {
return true;
--- a/src/hotspot/share/gc/g1/g1StringDedupTable.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1StringDedupTable.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,7 @@
#include "gc/shared/gcLocker.hpp"
#include "logging/log.hpp"
#include "memory/padded.inline.hpp"
+#include "oops/arrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/typeArrayOop.hpp"
#include "runtime/mutexLocker.hpp"
--- a/src/hotspot/share/gc/g1/satbMarkQueue.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/g1/satbMarkQueue.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -40,7 +40,8 @@
// them with their active field set to false. If a thread is
// created during a cycle and its SATB queue needs to be activated
// before the thread starts running, we'll need to set its active
- // field to true. This is done in JavaThread::initialize_queues().
+ // field to true. This is done in G1SATBCardTableLoggingModRefBS::
+ // on_thread_attach().
PtrQueue(qset, permanent, false /* active */)
{ }
--- a/src/hotspot/share/gc/parallel/generationSizer.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/parallel/generationSizer.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -41,11 +41,5 @@
void initialize_alignments();
void initialize_flags();
void initialize_size_info();
-
- public:
- // We don't have associated counters and complain if this is invoked.
- void initialize_gc_policy_counters() {
- ShouldNotReachHere();
- }
};
#endif // SHARE_VM_GC_PARALLEL_GENERATIONSIZER_HPP
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -331,7 +331,7 @@
// excesses). Fill op.result() with a filler object so that the
// heap remains parsable.
const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
- const bool softrefs_clear = collector_policy()->all_soft_refs_clear();
+ const bool softrefs_clear = soft_ref_policy()->all_soft_refs_clear();
if (limit_exceeded && softrefs_clear) {
*gc_overhead_limit_was_exceeded = true;
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -34,6 +34,7 @@
#include "gc/shared/collectorPolicy.hpp"
#include "gc/shared/gcPolicyCounters.hpp"
#include "gc/shared/gcWhen.hpp"
+#include "gc/shared/softRefPolicy.hpp"
#include "gc/shared/strongRootsScope.hpp"
#include "memory/metaspace.hpp"
#include "utilities/growableArray.hpp"
@@ -59,6 +60,8 @@
GenerationSizer* _collector_policy;
+ SoftRefPolicy _soft_ref_policy;
+
// Collection of generations that are adjacent in the
// space reserved for the heap.
AdjoiningGenerations* _gens;
@@ -106,6 +109,8 @@
virtual CollectorPolicy* collector_policy() const { return _collector_policy; }
+ virtual SoftRefPolicy* soft_ref_policy() { return &_soft_ref_policy; }
+
virtual GrowableArray<GCMemoryManager*> memory_managers();
virtual GrowableArray<MemoryPool*> memory_pools();
--- a/src/hotspot/share/gc/parallel/psCompactionManager.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/parallel/psCompactionManager.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, 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
@@ -181,7 +181,7 @@
template <class T>
static void oop_pc_follow_contents_specialized(InstanceRefKlass* klass, oop obj, ParCompactionManager* cm) {
- T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
+ T* referent_addr = (T*)java_lang_ref_Reference::referent_addr_raw(obj);
T heap_oop = oopDesc::load_heap_oop(referent_addr);
log_develop_trace(gc, ref)("InstanceRefKlass::oop_pc_follow_contents " PTR_FORMAT, p2i(obj));
if (!oopDesc::is_null(heap_oop)) {
@@ -198,12 +198,12 @@
cm->mark_and_push(referent_addr);
}
}
- T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
+ T* next_addr = (T*)java_lang_ref_Reference::next_addr_raw(obj);
// Treat discovered as normal oop, if ref is not "active",
// i.e. if next is non-NULL.
T next_oop = oopDesc::load_heap_oop(next_addr);
if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
- T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
+ T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr_raw(obj);
log_develop_trace(gc, ref)(" Process discovered as normal " PTR_FORMAT, p2i(discovered_addr));
cm->mark_and_push(discovered_addr);
}
--- a/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -29,7 +29,8 @@
#include "gc/parallel/psCompactionManager.hpp"
#include "gc/parallel/psParallelCompact.inline.hpp"
#include "gc/shared/taskqueue.inline.hpp"
-#include "oops/objArrayOop.hpp"
+#include "oops/arrayOop.inline.hpp"
+#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "utilities/debug.hpp"
#include "utilities/globalDefinitions.hpp"
@@ -117,7 +118,7 @@
const size_t stride = MIN2(len - beg_index, ObjArrayMarkingStride);
const size_t end_index = beg_index + stride;
- T* const base = (T*)obj->base();
+ T* const base = (T*)obj->base_raw();
T* const beg = base + beg_index;
T* const end = base + end_index;
--- a/src/hotspot/share/gc/parallel/psMarkSweep.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/parallel/psMarkSweep.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -98,7 +98,7 @@
}
const bool clear_all_soft_refs =
- heap->collector_policy()->should_clear_all_soft_refs();
+ heap->soft_ref_policy()->should_clear_all_soft_refs();
uint count = maximum_heap_compaction ? 1 : MarkSweepAlwaysCompactCount;
UIntFlagSetting flag_setting(MarkSweepAlwaysCompactCount, count);
@@ -126,7 +126,7 @@
// The scope of casr should end after code that can change
// CollectorPolicy::_should_clear_all_soft_refs.
- ClearedAllSoftRefs casr(clear_all_softrefs, heap->collector_policy());
+ ClearedAllSoftRefs casr(clear_all_softrefs, heap->soft_ref_policy());
PSYoungGen* young_gen = heap->young_gen();
PSOldGen* old_gen = heap->old_gen();
@@ -320,7 +320,7 @@
max_eden_size,
true /* full gc*/,
gc_cause,
- heap->collector_policy());
+ heap->soft_ref_policy());
size_policy->decay_supplemental_growth(true /* full gc*/);
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, 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
@@ -1707,7 +1707,7 @@
}
const bool clear_all_soft_refs =
- heap->collector_policy()->should_clear_all_soft_refs();
+ heap->soft_ref_policy()->should_clear_all_soft_refs();
PSParallelCompact::invoke_no_policy(clear_all_soft_refs ||
maximum_heap_compaction);
@@ -1741,7 +1741,7 @@
// The scope of casr should end after code that can change
// CollectorPolicy::_should_clear_all_soft_refs.
ClearedAllSoftRefs casr(maximum_heap_compaction,
- heap->collector_policy());
+ heap->soft_ref_policy());
if (ZapUnusedHeapArea) {
// Save information needed to minimize mangling
@@ -1869,7 +1869,7 @@
max_eden_size,
true /* full gc*/,
gc_cause,
- heap->collector_policy());
+ heap->soft_ref_policy());
size_policy->decay_supplemental_growth(true /* full gc*/);
@@ -3087,11 +3087,11 @@
template <class T>
static void oop_pc_update_pointers_specialized(oop obj, ParCompactionManager* cm) {
- T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
+ T* referent_addr = (T*)java_lang_ref_Reference::referent_addr_raw(obj);
PSParallelCompact::adjust_pointer(referent_addr, cm);
- T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
+ T* next_addr = (T*)java_lang_ref_Reference::next_addr_raw(obj);
PSParallelCompact::adjust_pointer(next_addr, cm);
- T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
+ T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr_raw(obj);
PSParallelCompact::adjust_pointer(discovered_addr, cm);
debug_only(trace_reference_gc("InstanceRefKlass::oop_update_ptrs", obj,
referent_addr, next_addr, discovered_addr);)
--- a/src/hotspot/share/gc/parallel/psPromotionManager.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/parallel/psPromotionManager.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -38,9 +38,11 @@
#include "memory/memRegion.hpp"
#include "memory/padded.inline.hpp"
#include "memory/resourceArea.hpp"
+#include "oops/arrayOop.inline.hpp"
#include "oops/instanceKlass.inline.hpp"
#include "oops/instanceMirrorKlass.inline.hpp"
#include "oops/objArrayKlass.inline.hpp"
+#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
PaddedEnd<PSPromotionManager>* PSPromotionManager::_manager_array = NULL;
@@ -434,7 +436,7 @@
template <class T>
static void oop_ps_push_contents_specialized(oop obj, InstanceRefKlass *klass, PSPromotionManager* pm) {
- T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
+ T* referent_addr = (T*)java_lang_ref_Reference::referent_addr_raw(obj);
if (PSScavenge::should_scavenge(referent_addr)) {
ReferenceProcessor* rp = PSScavenge::reference_processor();
if (rp->discover_reference(obj, klass->reference_type())) {
@@ -448,10 +450,10 @@
}
// Treat discovered as normal oop, if ref is not "active",
// i.e. if next is non-NULL.
- T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
+ T* next_addr = (T*)java_lang_ref_Reference::next_addr_raw(obj);
T next_oop = oopDesc::load_heap_oop(next_addr);
if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
- T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
+ T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr_raw(obj);
log_develop_trace(gc, ref)(" Process discovered as normal " PTR_FORMAT, p2i(discovered_addr));
if (PSScavenge::should_scavenge(discovered_addr)) {
pm->claim_or_forward_depth(discovered_addr);
--- a/src/hotspot/share/gc/parallel/psScavenge.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/parallel/psScavenge.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -228,8 +228,8 @@
if (need_full_gc) {
GCCauseSetter gccs(heap, GCCause::_adaptive_size_policy);
- CollectorPolicy* cp = heap->collector_policy();
- const bool clear_all_softrefs = cp->should_clear_all_soft_refs();
+ SoftRefPolicy* srp = heap->soft_ref_policy();
+ const bool clear_all_softrefs = srp->should_clear_all_soft_refs();
if (UseParallelOldGC) {
full_gc_done = PSParallelCompact::invoke_no_policy(clear_all_softrefs);
@@ -569,7 +569,7 @@
max_eden_size,
false /* not full gc*/,
gc_cause,
- heap->collector_policy());
+ heap->soft_ref_policy());
size_policy->decay_supplemental_growth(false /* not full gc*/);
}
--- a/src/hotspot/share/gc/serial/defNewGeneration.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/serial/defNewGeneration.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "gc/serial/defNewGeneration.inline.hpp"
+#include "gc/shared/adaptiveSizePolicy.hpp"
#include "gc/shared/ageTable.inline.hpp"
#include "gc/shared/cardTableRS.hpp"
#include "gc/shared/collectorCounters.hpp"
@@ -564,7 +565,7 @@
_tenuring_threshold = age_table()->compute_tenuring_threshold(desired_survivor_size);
if (UsePerfData) {
- GCPolicyCounters* gc_counters = GenCollectedHeap::heap()->gen_policy()->counters();
+ GCPolicyCounters* gc_counters = GenCollectedHeap::heap()->counters();
gc_counters->tenuring_threshold()->set_value(_tenuring_threshold);
gc_counters->desired_survivor_size()->set_value(desired_survivor_size * oopSize);
}
@@ -616,9 +617,6 @@
assert(gch->no_allocs_since_save_marks(),
"save marks have not been newly set.");
- // Not very pretty.
- CollectorPolicy* cp = gch->collector_policy();
-
FastScanClosure fsc_with_no_gc_barrier(this, false);
FastScanClosure fsc_with_gc_barrier(this, true);
@@ -688,7 +686,7 @@
// A successful scavenge should restart the GC time limit count which is
// for full GC's.
- AdaptiveSizePolicy* size_policy = gch->gen_policy()->size_policy();
+ AdaptiveSizePolicy* size_policy = gch->size_policy();
size_policy->reset_gc_overhead_limit_count();
assert(!gch->incremental_collection_failed(), "Should be clear");
} else {
@@ -953,7 +951,7 @@
// update the generation and space performance counters
update_counters();
- gch->gen_policy()->counters()->update_counters();
+ gch->counters()->update_counters();
}
void DefNewGeneration::record_spaces_top() {
--- a/src/hotspot/share/gc/serial/genMarkSweep.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/serial/genMarkSweep.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -60,7 +60,7 @@
GenCollectedHeap* gch = GenCollectedHeap::heap();
#ifdef ASSERT
- if (gch->collector_policy()->should_clear_all_soft_refs()) {
+ if (gch->soft_ref_policy()->should_clear_all_soft_refs()) {
assert(clear_all_softrefs, "Policy should have been checked earlier");
}
#endif
--- a/src/hotspot/share/gc/serial/serialHeap.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/serial/serialHeap.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -29,7 +29,13 @@
#include "services/memoryManager.hpp"
SerialHeap::SerialHeap(GenCollectorPolicy* policy) :
- GenCollectedHeap(policy), _eden_pool(NULL), _survivor_pool(NULL), _old_pool(NULL) {
+ GenCollectedHeap(policy,
+ Generation::DefNew,
+ Generation::MarkSweepCompact,
+ "Copy:MSC"),
+ _eden_pool(NULL),
+ _survivor_pool(NULL),
+ _old_pool(NULL) {
_young_manager = new GCMemoryManager("Copy", "end of minor GC");
_old_manager = new GCMemoryManager("MarkSweepCompact", "end of major GC");
}
--- a/src/hotspot/share/gc/shared/adaptiveSizePolicy.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/shared/adaptiveSizePolicy.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -27,10 +27,12 @@
#include "gc/shared/collectorPolicy.hpp"
#include "gc/shared/gcCause.hpp"
#include "gc/shared/gcUtil.inline.hpp"
+#include "gc/shared/softRefPolicy.hpp"
#include "gc/shared/workgroup.hpp"
#include "logging/log.hpp"
#include "runtime/timer.hpp"
#include "utilities/ostream.hpp"
+
elapsedTimer AdaptiveSizePolicy::_minor_timer;
elapsedTimer AdaptiveSizePolicy::_major_timer;
bool AdaptiveSizePolicy::_debug_perturbation = false;
@@ -409,7 +411,7 @@
size_t max_eden_size,
bool is_full_gc,
GCCause::Cause gc_cause,
- CollectorPolicy* collector_policy) {
+ SoftRefPolicy* soft_ref_policy) {
// Ignore explicit GC's. Exiting here does not set the flag and
// does not reset the count. Updating of the averages for system
@@ -506,7 +508,7 @@
// The clearing will be done on the next GC.
bool near_limit = gc_overhead_limit_near();
if (near_limit) {
- collector_policy->set_should_clear_all_soft_refs(true);
+ soft_ref_policy->set_should_clear_all_soft_refs(true);
log_trace(gc, ergo)("Nearing GC overhead limit, will be clearing all SoftReference");
}
}
--- a/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -37,7 +37,7 @@
// Forward decls
class elapsedTimer;
-class CollectorPolicy;
+class SoftRefPolicy;
class AdaptiveSizePolicy : public CHeapObj<mtGC> {
friend class GCAdaptivePolicyCounters;
@@ -486,7 +486,7 @@
size_t max_eden_size,
bool is_full_gc,
GCCause::Cause gc_cause,
- CollectorPolicy* collector_policy);
+ SoftRefPolicy* soft_ref_policy);
static bool should_update_promo_stats(GCCause::Cause cause) {
return ((GCCause::is_user_requested_gc(cause) &&
--- a/src/hotspot/share/gc/shared/barrierSet.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/shared/barrierSet.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -115,7 +115,8 @@
// is redone until it succeeds. This can e.g. prevent allocations from the slow path
// to be in old.
virtual void on_slowpath_allocation_exit(JavaThread* thread, oop new_obj) {}
- virtual void flush_deferred_barriers(JavaThread* thread) {}
+ virtual void on_thread_attach(JavaThread* thread) {}
+ virtual void on_thread_detach(JavaThread* thread) {}
virtual void make_parsable(JavaThread* thread) {}
protected:
@@ -272,6 +273,10 @@
static void clone_in_heap(oop src, oop dst, size_t size) {
Raw::clone(src, dst, size);
}
+
+ static oop resolve(oop obj) {
+ return Raw::resolve(obj);
+ }
};
};
--- a/src/hotspot/share/gc/shared/barrierSetConfig.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/shared/barrierSetConfig.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -52,9 +52,17 @@
// To enable runtime-resolution of GC barriers on primitives, please
// define SUPPORT_BARRIER_ON_PRIMITIVES.
#ifdef SUPPORT_BARRIER_ON_PRIMITIVES
-#define BT_BUILDTIME_DECORATORS INTERNAL_BT_BARRIER_ON_PRIMITIVES
+#define ACCESS_PRIMITIVE_SUPPORT INTERNAL_BT_BARRIER_ON_PRIMITIVES
#else
-#define BT_BUILDTIME_DECORATORS INTERNAL_EMPTY
+#define ACCESS_PRIMITIVE_SUPPORT INTERNAL_EMPTY
#endif
+#ifdef SUPPORT_NOT_TO_SPACE_INVARIANT
+#define ACCESS_TO_SPACE_INVARIANT_SUPPORT INTERNAL_EMPTY
+#else
+#define ACCESS_TO_SPACE_INVARIANT_SUPPORT INTERNAL_BT_TO_SPACE_INVARIANT
+#endif
+
+#define BT_BUILDTIME_DECORATORS (ACCESS_PRIMITIVE_SUPPORT | ACCESS_TO_SPACE_INVARIANT_SUPPORT)
+
#endif // SHARE_VM_GC_SHARED_BARRIERSETCONFIG_HPP
--- a/src/hotspot/share/gc/shared/cardTableModRefBS.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/shared/cardTableModRefBS.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -627,7 +627,7 @@
#endif
}
-void CardTableModRefBS::flush_deferred_barriers(JavaThread* thread) {
+void CardTableModRefBS::on_thread_detach(JavaThread* thread) {
// The deferred store barriers must all have been flushed to the
// card-table (or other remembered set structure) before GC starts
// processing the card-table (or other remembered set).
--- a/src/hotspot/share/gc/shared/cardTableModRefBS.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/shared/cardTableModRefBS.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -357,7 +357,7 @@
virtual bool is_in_young(oop obj) const = 0;
virtual void on_slowpath_allocation_exit(JavaThread* thread, oop new_obj);
- virtual void flush_deferred_barriers(JavaThread* thread);
+ virtual void on_thread_detach(JavaThread* thread);
virtual void make_parsable(JavaThread* thread) { flush_deferred_card_mark_barrier(thread); }
--- a/src/hotspot/share/gc/shared/collectedHeap.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/shared/collectedHeap.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -28,6 +28,7 @@
#include "gc/shared/barrierSet.inline.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
+#include "gc/shared/gcLocker.inline.hpp"
#include "gc/shared/gcHeapSummary.hpp"
#include "gc/shared/gcTrace.hpp"
#include "gc/shared/gcTraceTime.inline.hpp"
@@ -41,9 +42,11 @@
#include "runtime/init.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/threadSMR.hpp"
+#include "runtime/vmThread.hpp"
#include "services/heapDumper.hpp"
#include "utilities/align.hpp"
+class ClassLoaderData;
#ifdef ASSERT
int CollectedHeap::_fire_out_of_memory_count = 0;
@@ -233,6 +236,80 @@
}
}
+MetaWord* CollectedHeap::satisfy_failed_metadata_allocation(ClassLoaderData* loader_data,
+ size_t word_size,
+ Metaspace::MetadataType mdtype) {
+ uint loop_count = 0;
+ uint gc_count = 0;
+ uint full_gc_count = 0;
+
+ assert(!Heap_lock->owned_by_self(), "Should not be holding the Heap_lock");
+
+ do {
+ MetaWord* result = loader_data->metaspace_non_null()->allocate(word_size, mdtype);
+ if (result != NULL) {
+ return result;
+ }
+
+ if (GCLocker::is_active_and_needs_gc()) {
+ // If the GCLocker is active, just expand and allocate.
+ // If that does not succeed, wait if this thread is not
+ // in a critical section itself.
+ result = loader_data->metaspace_non_null()->expand_and_allocate(word_size, mdtype);
+ if (result != NULL) {
+ return result;
+ }
+ JavaThread* jthr = JavaThread::current();
+ if (!jthr->in_critical()) {
+ // Wait for JNI critical section to be exited
+ GCLocker::stall_until_clear();
+ // The GC invoked by the last thread leaving the critical
+ // section will be a young collection and a full collection
+ // is (currently) needed for unloading classes so continue
+ // to the next iteration to get a full GC.
+ continue;
+ } else {
+ if (CheckJNICalls) {
+ fatal("Possible deadlock due to allocating while"
+ " in jni critical section");
+ }
+ return NULL;
+ }
+ }
+
+ { // Need lock to get self consistent gc_count's
+ MutexLocker ml(Heap_lock);
+ gc_count = Universe::heap()->total_collections();
+ full_gc_count = Universe::heap()->total_full_collections();
+ }
+
+ // Generate a VM operation
+ VM_CollectForMetadataAllocation op(loader_data,
+ word_size,
+ mdtype,
+ gc_count,
+ full_gc_count,
+ GCCause::_metadata_GC_threshold);
+ VMThread::execute(&op);
+
+ // If GC was locked out, try again. Check before checking success because the
+ // prologue could have succeeded and the GC still have been locked out.
+ if (op.gc_locked()) {
+ continue;
+ }
+
+ if (op.prologue_succeeded()) {
+ return op.result();
+ }
+ loop_count++;
+ if ((QueuedAllocationWarningCount > 0) &&
+ (loop_count % QueuedAllocationWarningCount == 0)) {
+ log_warning(gc, ergo)("satisfy_failed_metadata_allocation() retries %d times,"
+ " size=" SIZE_FORMAT, loop_count, word_size);
+ }
+ } while (true); // Until a GC is done
+}
+
void CollectedHeap::set_barrier_set(BarrierSet* barrier_set) {
_barrier_set = barrier_set;
BarrierSet::set_bs(barrier_set);
--- a/src/hotspot/share/gc/shared/collectedHeap.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/shared/collectedHeap.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -50,6 +50,7 @@
class GCMemoryManager;
class MemoryPool;
class MetaspaceSummary;
+class SoftRefPolicy;
class Thread;
class ThreadClosure;
class VirtualSpaceSummary;
@@ -411,6 +412,10 @@
// the context of the vm thread.
virtual void collect_as_vm_thread(GCCause::Cause cause);
+ virtual MetaWord* satisfy_failed_metadata_allocation(ClassLoaderData* loader_data,
+ size_t size,
+ Metaspace::MetadataType mdtype);
+
// Returns the barrier set for this heap
BarrierSet* barrier_set() { return _barrier_set; }
void set_barrier_set(BarrierSet* barrier_set);
@@ -438,6 +443,9 @@
// Return the CollectorPolicy for the heap
virtual CollectorPolicy* collector_policy() const = 0;
+ // Return the SoftRefPolicy for the heap;
+ virtual SoftRefPolicy* soft_ref_policy() = 0;
+
virtual GrowableArray<GCMemoryManager*> memory_managers() = 0;
virtual GrowableArray<MemoryPool*> memory_pools() = 0;
@@ -492,7 +500,7 @@
void pre_full_gc_dump(GCTimer* timer);
void post_full_gc_dump(GCTimer* timer);
- VirtualSpaceSummary create_heap_space_summary();
+ virtual VirtualSpaceSummary create_heap_space_summary();
GCHeapSummary create_heap_summary();
MetaspaceSummary create_metaspace_summary();
@@ -599,20 +607,6 @@
return (CIFireOOMAt > 1 && _fire_out_of_memory_count >= CIFireOOMAt);
}
#endif
-
- public:
- // Copy the current allocation context statistics for the specified contexts.
- // For each context in contexts, set the corresponding entries in the totals
- // and accuracy arrays to the current values held by the statistics. Each
- // array should be of length len.
- // Returns true if there are more stats available.
- virtual bool copy_allocation_context_stats(const jint* contexts,
- jlong* totals,
- jbyte* accuracy,
- jint len) {
- return false;
- }
-
};
// Class to set and reset the GC cause for a CollectedHeap.
@@ -622,16 +616,12 @@
GCCause::Cause _previous_cause;
public:
GCCauseSetter(CollectedHeap* heap, GCCause::Cause cause) {
- assert(SafepointSynchronize::is_at_safepoint(),
- "This method manipulates heap state without locking");
_heap = heap;
_previous_cause = _heap->gc_cause();
_heap->set_gc_cause(cause);
}
~GCCauseSetter() {
- assert(SafepointSynchronize::is_at_safepoint(),
- "This method manipulates heap state without locking");
_heap->set_gc_cause(_previous_cause);
}
};
--- a/src/hotspot/share/gc/shared/collectorPolicy.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/shared/collectorPolicy.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -50,9 +50,7 @@
_heap_alignment(0),
_initial_heap_byte_size(InitialHeapSize),
_max_heap_byte_size(MaxHeapSize),
- _min_heap_byte_size(Arguments::min_heap_size()),
- _should_clear_all_soft_refs(false),
- _all_soft_refs_clear(false)
+ _min_heap_byte_size(Arguments::min_heap_size())
{}
#ifdef ASSERT
@@ -145,20 +143,6 @@
DEBUG_ONLY(CollectorPolicy::assert_size_info();)
}
-bool CollectorPolicy::use_should_clear_all_soft_refs(bool v) {
- bool result = _should_clear_all_soft_refs;
- set_should_clear_all_soft_refs(false);
- return result;
-}
-
-CardTableRS* CollectorPolicy::create_rem_set(MemRegion whole_heap) {
- return new CardTableRS(whole_heap);
-}
-
-void CollectorPolicy::cleared_all_soft_refs() {
- _all_soft_refs_clear = true;
-}
-
size_t CollectorPolicy::compute_heap_alignment() {
// The card marking array and the offset arrays for old generations are
// committed in os pages as well. Make sure they are entirely full (to
@@ -186,10 +170,7 @@
_min_old_size(0),
_initial_old_size(0),
_max_old_size(0),
- _gen_alignment(0),
- _young_gen_spec(NULL),
- _old_gen_spec(NULL),
- _size_policy(NULL)
+ _gen_alignment(0)
{}
size_t GenCollectorPolicy::scale_by_NewRatio_aligned(size_t base_size) {
@@ -202,29 +183,6 @@
return desired_size < max_minus ? desired_size : max_minus;
}
-
-void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size,
- size_t init_promo_size,
- size_t init_survivor_size) {
- const double max_gc_pause_sec = ((double) MaxGCPauseMillis) / 1000.0;
- _size_policy = new AdaptiveSizePolicy(init_eden_size,
- init_promo_size,
- init_survivor_size,
- max_gc_pause_sec,
- GCTimeRatio);
-}
-
-void GenCollectorPolicy::cleared_all_soft_refs() {
- // If near gc overhear limit, continue to clear SoftRefs. SoftRefs may
- // have been cleared in the last collection but if the gc overhear
- // limit continues to be near, SoftRefs should still be cleared.
- if (size_policy() != NULL) {
- _should_clear_all_soft_refs = size_policy()->gc_overhead_limit_near();
- }
-
- CollectorPolicy::cleared_all_soft_refs();
-}
-
size_t GenCollectorPolicy::young_gen_size_lower_bound() {
// The young generation must be aligned and have room for eden + two survivors
return align_up(3 * _space_alignment, _gen_alignment);
@@ -580,322 +538,6 @@
DEBUG_ONLY(GenCollectorPolicy::assert_size_info();)
}
-HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size,
- bool is_tlab,
- bool* gc_overhead_limit_was_exceeded) {
- GenCollectedHeap *gch = GenCollectedHeap::heap();
-
- debug_only(gch->check_for_valid_allocation_state());
- assert(gch->no_gc_in_progress(), "Allocation during gc not allowed");
-
- // In general gc_overhead_limit_was_exceeded should be false so
- // set it so here and reset it to true only if the gc time
- // limit is being exceeded as checked below.
- *gc_overhead_limit_was_exceeded = false;
-
- HeapWord* result = NULL;
-
- // Loop until the allocation is satisfied, or unsatisfied after GC.
- for (uint try_count = 1, gclocker_stalled_count = 0; /* return or throw */; try_count += 1) {
- HandleMark hm; // Discard any handles allocated in each iteration.
-
- // First allocation attempt is lock-free.
- Generation *young = gch->young_gen();
- assert(young->supports_inline_contig_alloc(),
- "Otherwise, must do alloc within heap lock");
- if (young->should_allocate(size, is_tlab)) {
- result = young->par_allocate(size, is_tlab);
- if (result != NULL) {
- assert(gch->is_in_reserved(result), "result not in heap");
- return result;
- }
- }
- uint gc_count_before; // Read inside the Heap_lock locked region.
- {
- MutexLocker ml(Heap_lock);
- log_trace(gc, alloc)("GenCollectorPolicy::mem_allocate_work: attempting locked slow path allocation");
- // Note that only large objects get a shot at being
- // allocated in later generations.
- bool first_only = ! should_try_older_generation_allocation(size);
-
- result = gch->attempt_allocation(size, is_tlab, first_only);
- if (result != NULL) {
- assert(gch->is_in_reserved(result), "result not in heap");
- return result;
- }
-
- if (GCLocker::is_active_and_needs_gc()) {
- if (is_tlab) {
- return NULL; // Caller will retry allocating individual object.
- }
- if (!gch->is_maximal_no_gc()) {
- // Try and expand heap to satisfy request.
- result = expand_heap_and_allocate(size, is_tlab);
- // Result could be null if we are out of space.
- if (result != NULL) {
- return result;
- }
- }
-
- if (gclocker_stalled_count > GCLockerRetryAllocationCount) {
- return NULL; // We didn't get to do a GC and we didn't get any memory.
- }
-
- // If this thread is not in a jni critical section, we stall
- // the requestor until the critical section has cleared and
- // GC allowed. When the critical section clears, a GC is
- // initiated by the last thread exiting the critical section; so
- // we retry the allocation sequence from the beginning of the loop,
- // rather than causing more, now probably unnecessary, GC attempts.
- JavaThread* jthr = JavaThread::current();
- if (!jthr->in_critical()) {
- MutexUnlocker mul(Heap_lock);
- // Wait for JNI critical section to be exited
- GCLocker::stall_until_clear();
- gclocker_stalled_count += 1;
- continue;
- } else {
- if (CheckJNICalls) {
- fatal("Possible deadlock due to allocating while"
- " in jni critical section");
- }
- return NULL;
- }
- }
-
- // Read the gc count while the heap lock is held.
- gc_count_before = gch->total_collections();
- }
-
- VM_GenCollectForAllocation op(size, is_tlab, gc_count_before);
- VMThread::execute(&op);
- if (op.prologue_succeeded()) {
- result = op.result();
- if (op.gc_locked()) {
- assert(result == NULL, "must be NULL if gc_locked() is true");
- continue; // Retry and/or stall as necessary.
- }
-
- // Allocation has failed and a collection
- // has been done. If the gc time limit was exceeded the
- // this time, return NULL so that an out-of-memory
- // will be thrown. Clear gc_overhead_limit_exceeded
- // so that the overhead exceeded does not persist.
-
- const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
- const bool softrefs_clear = all_soft_refs_clear();
-
- if (limit_exceeded && softrefs_clear) {
- *gc_overhead_limit_was_exceeded = true;
- size_policy()->set_gc_overhead_limit_exceeded(false);
- if (op.result() != NULL) {
- CollectedHeap::fill_with_object(op.result(), size);
- }
- return NULL;
- }
- assert(result == NULL || gch->is_in_reserved(result),
- "result not in heap");
- return result;
- }
-
- // Give a warning if we seem to be looping forever.
- if ((QueuedAllocationWarningCount > 0) &&
- (try_count % QueuedAllocationWarningCount == 0)) {
- log_warning(gc, ergo)("GenCollectorPolicy::mem_allocate_work retries %d times,"
- " size=" SIZE_FORMAT " %s", try_count, size, is_tlab ? "(TLAB)" : "");
- }
- }
-}
-
-HeapWord* GenCollectorPolicy::expand_heap_and_allocate(size_t size,
- bool is_tlab) {
- GenCollectedHeap *gch = GenCollectedHeap::heap();
- HeapWord* result = NULL;
- Generation *old = gch->old_gen();
- if (old->should_allocate(size, is_tlab)) {
- result = old->expand_and_allocate(size, is_tlab);
- }
- if (result == NULL) {
- Generation *young = gch->young_gen();
- if (young->should_allocate(size, is_tlab)) {
- result = young->expand_and_allocate(size, is_tlab);
- }
- }
- assert(result == NULL || gch->is_in_reserved(result), "result not in heap");
- return result;
-}
-
-HeapWord* GenCollectorPolicy::satisfy_failed_allocation(size_t size,
- bool is_tlab) {
- GenCollectedHeap *gch = GenCollectedHeap::heap();
- GCCauseSetter x(gch, GCCause::_allocation_failure);
- HeapWord* result = NULL;
-
- assert(size != 0, "Precondition violated");
- if (GCLocker::is_active_and_needs_gc()) {
- // GC locker is active; instead of a collection we will attempt
- // to expand the heap, if there's room for expansion.
- if (!gch->is_maximal_no_gc()) {
- result = expand_heap_and_allocate(size, is_tlab);
- }
- return result; // Could be null if we are out of space.
- } else if (!gch->incremental_collection_will_fail(false /* don't consult_young */)) {
- // Do an incremental collection.
- gch->do_collection(false, // full
- false, // clear_all_soft_refs
- size, // size
- is_tlab, // is_tlab
- GenCollectedHeap::OldGen); // max_generation
- } else {
- log_trace(gc)(" :: Trying full because partial may fail :: ");
- // Try a full collection; see delta for bug id 6266275
- // for the original code and why this has been simplified
- // with from-space allocation criteria modified and
- // such allocation moved out of the safepoint path.
- gch->do_collection(true, // full
- false, // clear_all_soft_refs
- size, // size
- is_tlab, // is_tlab
- GenCollectedHeap::OldGen); // max_generation
- }
-
- result = gch->attempt_allocation(size, is_tlab, false /*first_only*/);
-
- if (result != NULL) {
- assert(gch->is_in_reserved(result), "result not in heap");
- return result;
- }
-
- // OK, collection failed, try expansion.
- result = expand_heap_and_allocate(size, is_tlab);
- if (result != NULL) {
- return result;
- }
-
- // If we reach this point, we're really out of memory. Try every trick
- // we can to reclaim memory. Force collection of soft references. Force
- // a complete compaction of the heap. Any additional methods for finding
- // free memory should be here, especially if they are expensive. If this
- // attempt fails, an OOM exception will be thrown.
- {
- UIntFlagSetting flag_change(MarkSweepAlwaysCompactCount, 1); // Make sure the heap is fully compacted
-
- gch->do_collection(true, // full
- true, // clear_all_soft_refs
- size, // size
- is_tlab, // is_tlab
- GenCollectedHeap::OldGen); // max_generation
- }
-
- result = gch->attempt_allocation(size, is_tlab, false /* first_only */);
- if (result != NULL) {
- assert(gch->is_in_reserved(result), "result not in heap");
- return result;
- }
-
- assert(!should_clear_all_soft_refs(),
- "Flag should have been handled and cleared prior to this point");
-
- // What else? We might try synchronous finalization later. If the total
- // space available is large enough for the allocation, then a more
- // complete compaction phase than we've tried so far might be
- // appropriate.
- return NULL;
-}
-
-MetaWord* CollectorPolicy::satisfy_failed_metadata_allocation(
- ClassLoaderData* loader_data,
- size_t word_size,
- Metaspace::MetadataType mdtype) {
- uint loop_count = 0;
- uint gc_count = 0;
- uint full_gc_count = 0;
-
- assert(!Heap_lock->owned_by_self(), "Should not be holding the Heap_lock");
-
- do {
- MetaWord* result = loader_data->metaspace_non_null()->allocate(word_size, mdtype);
- if (result != NULL) {
- return result;
- }
-
- if (GCLocker::is_active_and_needs_gc()) {
- // If the GCLocker is active, just expand and allocate.
- // If that does not succeed, wait if this thread is not
- // in a critical section itself.
- result =
- loader_data->metaspace_non_null()->expand_and_allocate(word_size,
- mdtype);
- if (result != NULL) {
- return result;
- }
- JavaThread* jthr = JavaThread::current();
- if (!jthr->in_critical()) {
- // Wait for JNI critical section to be exited
- GCLocker::stall_until_clear();
- // The GC invoked by the last thread leaving the critical
- // section will be a young collection and a full collection
- // is (currently) needed for unloading classes so continue
- // to the next iteration to get a full GC.
- continue;
- } else {
- if (CheckJNICalls) {
- fatal("Possible deadlock due to allocating while"
- " in jni critical section");
- }
- return NULL;
- }
- }
-
- { // Need lock to get self consistent gc_count's
- MutexLocker ml(Heap_lock);
- gc_count = Universe::heap()->total_collections();
- full_gc_count = Universe::heap()->total_full_collections();
- }
-
- // Generate a VM operation
- VM_CollectForMetadataAllocation op(loader_data,
- word_size,
- mdtype,
- gc_count,
- full_gc_count,
- GCCause::_metadata_GC_threshold);
- VMThread::execute(&op);
-
- // If GC was locked out, try again. Check before checking success because the
- // prologue could have succeeded and the GC still have been locked out.
- if (op.gc_locked()) {
- continue;
- }
-
- if (op.prologue_succeeded()) {
- return op.result();
- }
- loop_count++;
- if ((QueuedAllocationWarningCount > 0) &&
- (loop_count % QueuedAllocationWarningCount == 0)) {
- log_warning(gc, ergo)("satisfy_failed_metadata_allocation() retries %d times,"
- " size=" SIZE_FORMAT, loop_count, word_size);
- }
- } while (true); // Until a GC is done
-}
-
-// Return true if any of the following is true:
-// . the allocation won't fit into the current young gen heap
-// . gc locker is occupied (jni critical section)
-// . heap memory is tight -- the most recent previous collection
-// was a full collection because a partial collection (would
-// have) failed and is likely to fail again
-bool GenCollectorPolicy::should_try_older_generation_allocation(
- size_t word_size) const {
- GenCollectedHeap* gch = GenCollectedHeap::heap();
- size_t young_capacity = gch->young_gen()->capacity_before_gc();
- return (word_size > heap_word_size(young_capacity))
- || GCLocker::is_active_and_needs_gc()
- || gch->incremental_collection_failed();
-}
-
-
//
// MarkSweepPolicy methods
//
@@ -904,14 +546,3 @@
_space_alignment = _gen_alignment = (size_t)Generation::GenGrain;
_heap_alignment = compute_heap_alignment();
}
-
-void MarkSweepPolicy::initialize_generations() {
- _young_gen_spec = new GenerationSpec(Generation::DefNew, _initial_young_size, _max_young_size, _gen_alignment);
- _old_gen_spec = new GenerationSpec(Generation::MarkSweepCompact, _initial_old_size, _max_old_size, _gen_alignment);
-}
-
-void MarkSweepPolicy::initialize_gc_policy_counters() {
- // Initialize the policy counters - 2 collectors, 2 generations.
- _gc_policy_counters = new GCPolicyCounters("Copy:MSC", 2, 2);
-}
-
--- a/src/hotspot/share/gc/shared/collectorPolicy.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/shared/collectorPolicy.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, 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
@@ -53,7 +53,6 @@
class G1CollectorPolicy;
#endif // INCLUDE_ALL_GCS
-class GCPolicyCounters;
class MarkSweepPolicy;
class CollectorPolicy : public CHeapObj<mtGC> {
@@ -72,21 +71,10 @@
size_t _space_alignment;
size_t _heap_alignment;
- // Set to true when policy wants soft refs cleared.
- // Reset to false by gc after it clears all soft refs.
- bool _should_clear_all_soft_refs;
-
- // Set to true by the GC if the just-completed gc cleared all
- // softrefs. This is set to true whenever a gc clears all softrefs, and
- // set to false each time gc returns to the mutator. For example, in the
- // ParallelScavengeHeap case the latter would be done toward the end of
- // mem_allocate() where it returns op.result()
- bool _all_soft_refs_clear;
-
CollectorPolicy();
public:
- virtual void initialize_all() {
+ void initialize_all() {
initialize_alignments();
initialize_flags();
initialize_size_info();
@@ -101,58 +89,6 @@
size_t initial_heap_byte_size() { return _initial_heap_byte_size; }
size_t max_heap_byte_size() { return _max_heap_byte_size; }
size_t min_heap_byte_size() { return _min_heap_byte_size; }
-
- bool should_clear_all_soft_refs() { return _should_clear_all_soft_refs; }
- void set_should_clear_all_soft_refs(bool v) { _should_clear_all_soft_refs = v; }
- // Returns the current value of _should_clear_all_soft_refs.
- // _should_clear_all_soft_refs is set to false as a side effect.
- bool use_should_clear_all_soft_refs(bool v);
- bool all_soft_refs_clear() { return _all_soft_refs_clear; }
- void set_all_soft_refs_clear(bool v) { _all_soft_refs_clear = v; }
-
- // Called by the GC after Soft Refs have been cleared to indicate
- // that the request in _should_clear_all_soft_refs has been fulfilled.
- virtual void cleared_all_soft_refs();
-
- // Identification methods.
- virtual GenCollectorPolicy* as_generation_policy() { return NULL; }
- virtual MarkSweepPolicy* as_mark_sweep_policy() { return NULL; }
-#if INCLUDE_ALL_GCS
- virtual ConcurrentMarkSweepPolicy* as_concurrent_mark_sweep_policy() { return NULL; }
-#endif // INCLUDE_ALL_GCS
- // Note that these are not virtual.
- bool is_generation_policy() { return as_generation_policy() != NULL; }
- bool is_mark_sweep_policy() { return as_mark_sweep_policy() != NULL; }
-#if INCLUDE_ALL_GCS
- bool is_concurrent_mark_sweep_policy() { return as_concurrent_mark_sweep_policy() != NULL; }
-#else // INCLUDE_ALL_GCS
- bool is_concurrent_mark_sweep_policy() { return false; }
-#endif // INCLUDE_ALL_GCS
-
-
- virtual CardTableRS* create_rem_set(MemRegion reserved);
-
- MetaWord* satisfy_failed_metadata_allocation(ClassLoaderData* loader_data,
- size_t size,
- Metaspace::MetadataType mdtype);
-};
-
-class ClearedAllSoftRefs : public StackObj {
- bool _clear_all_soft_refs;
- CollectorPolicy* _collector_policy;
- public:
- ClearedAllSoftRefs(bool clear_all_soft_refs,
- CollectorPolicy* collector_policy) :
- _clear_all_soft_refs(clear_all_soft_refs),
- _collector_policy(collector_policy) {}
-
- ~ClearedAllSoftRefs() {
- if (_clear_all_soft_refs) {
- _collector_policy->cleared_all_soft_refs();
- }
- }
-
- bool should_clear() { return _clear_all_soft_refs; }
};
class GenCollectorPolicy : public CollectorPolicy {
@@ -171,27 +107,12 @@
// time. When using large pages they can differ.
size_t _gen_alignment;
- GenerationSpec* _young_gen_spec;
- GenerationSpec* _old_gen_spec;
-
- GCPolicyCounters* _gc_policy_counters;
-
- // The sizing of the heap is controlled by a sizing policy.
- AdaptiveSizePolicy* _size_policy;
-
- // Return true if an allocation should be attempted in the older generation
- // if it fails in the younger generation. Return false, otherwise.
- virtual bool should_try_older_generation_allocation(size_t word_size) const;
-
void initialize_flags();
void initialize_size_info();
DEBUG_ONLY(void assert_flags();)
DEBUG_ONLY(void assert_size_info();)
- // Try to allocate space by expanding the heap.
- virtual HeapWord* expand_heap_and_allocate(size_t size, bool is_tlab);
-
// Compute max heap alignment.
size_t compute_max_alignment();
@@ -215,63 +136,17 @@
size_t initial_old_size() { return _initial_old_size; }
size_t max_old_size() { return _max_old_size; }
- GenerationSpec* young_gen_spec() const {
- assert(_young_gen_spec != NULL, "_young_gen_spec should have been initialized");
- return _young_gen_spec;
- }
-
- GenerationSpec* old_gen_spec() const {
- assert(_old_gen_spec != NULL, "_old_gen_spec should have been initialized");
- return _old_gen_spec;
- }
-
- // Performance Counter support
- GCPolicyCounters* counters() { return _gc_policy_counters; }
-
- // Create the jstat counters for the GC policy.
- virtual void initialize_gc_policy_counters() = 0;
-
- virtual GenCollectorPolicy* as_generation_policy() { return this; }
-
- virtual void initialize_generations() { };
-
- virtual void initialize_all() {
- CollectorPolicy::initialize_all();
- initialize_generations();
- }
-
size_t young_gen_size_lower_bound();
size_t old_gen_size_lower_bound();
-
- HeapWord* mem_allocate_work(size_t size,
- bool is_tlab,
- bool* gc_overhead_limit_was_exceeded);
-
- HeapWord *satisfy_failed_allocation(size_t size, bool is_tlab);
-
- // Adaptive size policy
- AdaptiveSizePolicy* size_policy() { return _size_policy; }
-
- virtual void initialize_size_policy(size_t init_eden_size,
- size_t init_promo_size,
- size_t init_survivor_size);
-
- virtual void cleared_all_soft_refs();
-
};
class MarkSweepPolicy : public GenCollectorPolicy {
protected:
void initialize_alignments();
- void initialize_generations();
public:
MarkSweepPolicy() {}
-
- MarkSweepPolicy* as_mark_sweep_policy() { return this; }
-
- void initialize_gc_policy_counters();
};
#endif // SHARE_VM_GC_SHARED_COLLECTORPOLICY_HPP
--- a/src/hotspot/share/gc/shared/gcCause.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/shared/gcCause.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -60,10 +60,6 @@
case _wb_full_gc:
return "WhiteBox Initiated Full GC";
- case _update_allocation_context_stats_inc:
- case _update_allocation_context_stats_full:
- return "Update Allocation Context Stats";
-
case _no_gc:
return "No GC";
--- a/src/hotspot/share/gc/shared/gcCause.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/shared/gcCause.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -52,8 +52,6 @@
_wb_young_gc,
_wb_conc_mark,
_wb_full_gc,
- _update_allocation_context_stats_inc,
- _update_allocation_context_stats_full,
/* implementation independent, but reserved for GC use */
_no_gc,
--- a/src/hotspot/share/gc/shared/gcId.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/shared/gcId.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,27 +35,28 @@
return (NamedThread*)Thread::current();
}
-const uint GCId::create() {
+uint GCId::create() {
return _next_id++;
}
-const uint GCId::peek() {
+uint GCId::peek() {
return _next_id;
}
-const uint GCId::current() {
- assert(currentNamedthread()->gc_id() != undefined(), "Using undefined GC id.");
- return current_raw();
+uint GCId::current() {
+ const uint gc_id = currentNamedthread()->gc_id();
+ assert(gc_id != undefined(), "Using undefined GC id.");
+ return gc_id;
}
-const uint GCId::current_raw() {
- return currentNamedthread()->gc_id();
+uint GCId::current_or_undefined() {
+ return Thread::current()->is_Named_thread() ? currentNamedthread()->gc_id() : undefined();
}
size_t GCId::print_prefix(char* buf, size_t len) {
Thread* thread = Thread::current_or_null();
- if (thread != NULL && thread->is_Named_thread()) {
- uint gc_id = current_raw();
+ if (thread != NULL) {
+ uint gc_id = current_or_undefined();
if (gc_id != undefined()) {
int ret = jio_snprintf(buf, len, "GC(%u) ", gc_id);
assert(ret > 0, "Failed to print prefix. Log buffer too small?");
@@ -65,28 +66,14 @@
return 0;
}
-GCIdMark::GCIdMark() : _gc_id(GCId::create()) {
- currentNamedthread()->set_gc_id(_gc_id);
+GCIdMark::GCIdMark() : _previous_gc_id(currentNamedthread()->gc_id()) {
+ currentNamedthread()->set_gc_id(GCId::create());
}
-GCIdMark::GCIdMark(uint gc_id) : _gc_id(gc_id) {
- currentNamedthread()->set_gc_id(_gc_id);
+GCIdMark::GCIdMark(uint gc_id) : _previous_gc_id(currentNamedthread()->gc_id()) {
+ currentNamedthread()->set_gc_id(gc_id);
}
GCIdMark::~GCIdMark() {
- currentNamedthread()->set_gc_id(GCId::undefined());
-}
-
-GCIdMarkAndRestore::GCIdMarkAndRestore() : _gc_id(GCId::create()) {
- _previous_gc_id = GCId::current_raw();
- currentNamedthread()->set_gc_id(_gc_id);
-}
-
-GCIdMarkAndRestore::GCIdMarkAndRestore(uint gc_id) : _gc_id(gc_id) {
- _previous_gc_id = GCId::current_raw();
- currentNamedthread()->set_gc_id(_gc_id);
-}
-
-GCIdMarkAndRestore::~GCIdMarkAndRestore() {
currentNamedthread()->set_gc_id(_previous_gc_id);
}
--- a/src/hotspot/share/gc/shared/gcId.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/shared/gcId.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,38 +28,32 @@
#include "memory/allocation.hpp"
class GCId : public AllStatic {
+private:
friend class GCIdMark;
- friend class GCIdMarkAndRestore;
+
static uint _next_id;
static const uint UNDEFINED = (uint)-1;
- static const uint create();
+ static uint create();
- public:
+public:
// Returns the currently active GC id. Asserts that there is an active GC id.
- static const uint current();
+ static uint current();
// Same as current() but can return undefined() if no GC id is currently active
- static const uint current_raw();
+ static uint current_or_undefined();
// Returns the next expected GCId.
- static const uint peek();
- static const uint undefined() { return UNDEFINED; }
+ static uint peek();
+ static uint undefined() { return UNDEFINED; }
static size_t print_prefix(char* buf, size_t len);
};
class GCIdMark : public StackObj {
- uint _gc_id;
- public:
+private:
+ const uint _previous_gc_id;
+
+public:
GCIdMark();
GCIdMark(uint gc_id);
~GCIdMark();
};
-class GCIdMarkAndRestore : public StackObj {
- uint _gc_id;
- uint _previous_gc_id;
- public:
- GCIdMarkAndRestore();
- GCIdMarkAndRestore(uint gc_id);
- ~GCIdMarkAndRestore();
-};
-
#endif // SHARE_VM_GC_SHARED_GCID_HPP
--- a/src/hotspot/share/gc/shared/gcTimer.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/shared/gcTimer.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, 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
@@ -68,14 +68,14 @@
GCTimer::register_gc_end(time);
}
-void ConcurrentGCTimer::register_gc_pause_start(const char* name) {
+void ConcurrentGCTimer::register_gc_pause_start(const char* name, const Ticks& time) {
assert(!_is_concurrent_phase_active, "A pause phase can't be started while a concurrent phase is active.");
- GCTimer::register_gc_pause_start(name);
+ GCTimer::register_gc_pause_start(name, time);
}
-void ConcurrentGCTimer::register_gc_pause_end() {
+void ConcurrentGCTimer::register_gc_pause_end(const Ticks& time) {
assert(!_is_concurrent_phase_active, "A pause phase can't be ended while a concurrent phase is active.");
- GCTimer::register_gc_pause_end();
+ GCTimer::register_gc_pause_end(time);
}
void ConcurrentGCTimer::register_gc_concurrent_start(const char* name, const Ticks& time) {
--- a/src/hotspot/share/gc/shared/gcTimer.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/shared/gcTimer.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -166,8 +166,8 @@
public:
ConcurrentGCTimer(): GCTimer(), _is_concurrent_phase_active(false) {};
- void register_gc_pause_start(const char* name);
- void register_gc_pause_end();
+ void register_gc_pause_start(const char* name, const Ticks& time = Ticks::now());
+ void register_gc_pause_end(const Ticks& time = Ticks::now());
void register_gc_concurrent_start(const char* name, const Ticks& time = Ticks::now());
void register_gc_concurrent_end(const Ticks& time = Ticks::now());
--- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -30,10 +30,13 @@
#include "classfile/vmSymbols.hpp"
#include "code/codeCache.hpp"
#include "code/icBuffer.hpp"
+#include "gc/shared/adaptiveSizePolicy.hpp"
+#include "gc/shared/cardTableRS.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "gc/shared/collectorCounters.hpp"
#include "gc/shared/gcId.hpp"
#include "gc/shared/gcLocker.inline.hpp"
+#include "gc/shared/gcPolicyCounters.hpp"
#include "gc/shared/gcTrace.hpp"
#include "gc/shared/gcTraceTime.inline.hpp"
#include "gc/shared/genCollectedHeap.hpp"
@@ -60,14 +63,25 @@
#include "utilities/stack.inline.hpp"
#include "utilities/vmError.hpp"
-GenCollectedHeap::GenCollectedHeap(GenCollectorPolicy *policy) :
+GenCollectedHeap::GenCollectedHeap(GenCollectorPolicy *policy,
+ Generation::Name young,
+ Generation::Name old,
+ const char* policy_counters_name) :
CollectedHeap(),
_rem_set(NULL),
+ _young_gen_spec(new GenerationSpec(young,
+ policy->initial_young_size(),
+ policy->max_young_size(),
+ policy->gen_alignment())),
+ _old_gen_spec(new GenerationSpec(old,
+ policy->initial_old_size(),
+ policy->max_old_size(),
+ policy->gen_alignment())),
_gen_policy(policy),
+ _soft_ref_gen_policy(),
+ _gc_policy_counters(new GCPolicyCounters(policy_counters_name, 2, 2)),
_process_strong_tasks(new SubTasksDone(GCH_PS_NumElements)),
- _full_collections_completed(0)
-{
- assert(policy != NULL, "Sanity check");
+ _full_collections_completed(0) {
}
jint GenCollectedHeap::initialize() {
@@ -95,32 +109,40 @@
initialize_reserved_region((HeapWord*)heap_rs.base(), (HeapWord*)(heap_rs.base() + heap_rs.size()));
- _rem_set = collector_policy()->create_rem_set(reserved_region());
+ _rem_set = new CardTableRS(reserved_region());
set_barrier_set(rem_set()->bs());
- ReservedSpace young_rs = heap_rs.first_part(gen_policy()->young_gen_spec()->max_size(), false, false);
- _young_gen = gen_policy()->young_gen_spec()->init(young_rs, rem_set());
- heap_rs = heap_rs.last_part(gen_policy()->young_gen_spec()->max_size());
+ ReservedSpace young_rs = heap_rs.first_part(_young_gen_spec->max_size(), false, false);
+ _young_gen = _young_gen_spec->init(young_rs, rem_set());
+ heap_rs = heap_rs.last_part(_young_gen_spec->max_size());
- ReservedSpace old_rs = heap_rs.first_part(gen_policy()->old_gen_spec()->max_size(), false, false);
- _old_gen = gen_policy()->old_gen_spec()->init(old_rs, rem_set());
+ ReservedSpace old_rs = heap_rs.first_part(_old_gen_spec->max_size(), false, false);
+ _old_gen = _old_gen_spec->init(old_rs, rem_set());
clear_incremental_collection_failed();
return JNI_OK;
}
+void GenCollectedHeap::initialize_size_policy(size_t init_eden_size,
+ size_t init_promo_size,
+ size_t init_survivor_size) {
+ const double max_gc_pause_sec = ((double) MaxGCPauseMillis) / 1000.0;
+ _size_policy = new AdaptiveSizePolicy(init_eden_size,
+ init_promo_size,
+ init_survivor_size,
+ max_gc_pause_sec,
+ GCTimeRatio);
+}
+
char* GenCollectedHeap::allocate(size_t alignment,
ReservedSpace* heap_rs){
// Now figure out the total size.
const size_t pageSize = UseLargePages ? os::large_page_size() : os::vm_page_size();
assert(alignment % pageSize == 0, "Must be");
- GenerationSpec* young_spec = gen_policy()->young_gen_spec();
- GenerationSpec* old_spec = gen_policy()->old_gen_spec();
-
// Check for overflow.
- size_t total_reserved = young_spec->max_size() + old_spec->max_size();
- if (total_reserved < young_spec->max_size()) {
+ size_t total_reserved = _young_gen_spec->max_size() + _old_gen_spec->max_size();
+ if (total_reserved < _young_gen_spec->max_size()) {
vm_exit_during_initialization("The size of the object heap + VM data exceeds "
"the maximum representable size");
}
@@ -146,10 +168,9 @@
check_gen_kinds();
DefNewGeneration* def_new_gen = (DefNewGeneration*)_young_gen;
- _gen_policy->initialize_size_policy(def_new_gen->eden()->capacity(),
- _old_gen->capacity(),
- def_new_gen->from()->capacity());
- _gen_policy->initialize_gc_policy_counters();
+ initialize_size_policy(def_new_gen->eden()->capacity(),
+ _old_gen->capacity(),
+ def_new_gen->from()->capacity());
}
void GenCollectedHeap::ref_processing_init() {
@@ -157,6 +178,14 @@
_old_gen->ref_processor_init();
}
+GenerationSpec* GenCollectedHeap::young_gen_spec() const {
+ return _young_gen_spec;
+}
+
+GenerationSpec* GenCollectedHeap::old_gen_spec() const {
+ return _old_gen_spec;
+}
+
size_t GenCollectedHeap::capacity() const {
return _young_gen->capacity() + _old_gen->capacity();
}
@@ -202,6 +231,157 @@
return _full_collections_completed;
}
+// Return true if any of the following is true:
+// . the allocation won't fit into the current young gen heap
+// . gc locker is occupied (jni critical section)
+// . heap memory is tight -- the most recent previous collection
+// was a full collection because a partial collection (would
+// have) failed and is likely to fail again
+bool GenCollectedHeap::should_try_older_generation_allocation(size_t word_size) const {
+ size_t young_capacity = young_gen()->capacity_before_gc();
+ return (word_size > heap_word_size(young_capacity))
+ || GCLocker::is_active_and_needs_gc()
+ || incremental_collection_failed();
+}
+
+HeapWord* GenCollectedHeap::expand_heap_and_allocate(size_t size, bool is_tlab) {
+ HeapWord* result = NULL;
+ if (old_gen()->should_allocate(size, is_tlab)) {
+ result = old_gen()->expand_and_allocate(size, is_tlab);
+ }
+ if (result == NULL) {
+ if (young_gen()->should_allocate(size, is_tlab)) {
+ result = young_gen()->expand_and_allocate(size, is_tlab);
+ }
+ }
+ assert(result == NULL || is_in_reserved(result), "result not in heap");
+ return result;
+}
+
+HeapWord* GenCollectedHeap::mem_allocate_work(size_t size,
+ bool is_tlab,
+ bool* gc_overhead_limit_was_exceeded) {
+ debug_only(check_for_valid_allocation_state());
+ assert(no_gc_in_progress(), "Allocation during gc not allowed");
+
+ // In general gc_overhead_limit_was_exceeded should be false so
+ // set it so here and reset it to true only if the gc time
+ // limit is being exceeded as checked below.
+ *gc_overhead_limit_was_exceeded = false;
+
+ HeapWord* result = NULL;
+
+ // Loop until the allocation is satisfied, or unsatisfied after GC.
+ for (uint try_count = 1, gclocker_stalled_count = 0; /* return or throw */; try_count += 1) {
+ HandleMark hm; // Discard any handles allocated in each iteration.
+
+ // First allocation attempt is lock-free.
+ Generation *young = young_gen();
+ assert(young->supports_inline_contig_alloc(),
+ "Otherwise, must do alloc within heap lock");
+ if (young->should_allocate(size, is_tlab)) {
+ result = young->par_allocate(size, is_tlab);
+ if (result != NULL) {
+ assert(is_in_reserved(result), "result not in heap");
+ return result;
+ }
+ }
+ uint gc_count_before; // Read inside the Heap_lock locked region.
+ {
+ MutexLocker ml(Heap_lock);
+ log_trace(gc, alloc)("GenCollectedHeap::mem_allocate_work: attempting locked slow path allocation");
+ // Note that only large objects get a shot at being
+ // allocated in later generations.
+ bool first_only = !should_try_older_generation_allocation(size);
+
+ result = attempt_allocation(size, is_tlab, first_only);
+ if (result != NULL) {
+ assert(is_in_reserved(result), "result not in heap");
+ return result;
+ }
+
+ if (GCLocker::is_active_and_needs_gc()) {
+ if (is_tlab) {
+ return NULL; // Caller will retry allocating individual object.
+ }
+ if (!is_maximal_no_gc()) {
+ // Try and expand heap to satisfy request.
+ result = expand_heap_and_allocate(size, is_tlab);
+ // Result could be null if we are out of space.
+ if (result != NULL) {
+ return result;
+ }
+ }
+
+ if (gclocker_stalled_count > GCLockerRetryAllocationCount) {
+ return NULL; // We didn't get to do a GC and we didn't get any memory.
+ }
+
+ // If this thread is not in a jni critical section, we stall
+ // the requestor until the critical section has cleared and
+ // GC allowed. When the critical section clears, a GC is
+ // initiated by the last thread exiting the critical section; so
+ // we retry the allocation sequence from the beginning of the loop,
+ // rather than causing more, now probably unnecessary, GC attempts.
+ JavaThread* jthr = JavaThread::current();
+ if (!jthr->in_critical()) {
+ MutexUnlocker mul(Heap_lock);
+ // Wait for JNI critical section to be exited
+ GCLocker::stall_until_clear();
+ gclocker_stalled_count += 1;
+ continue;
+ } else {
+ if (CheckJNICalls) {
+ fatal("Possible deadlock due to allocating while"
+ " in jni critical section");
+ }
+ return NULL;
+ }
+ }
+
+ // Read the gc count while the heap lock is held.
+ gc_count_before = total_collections();
+ }
+
+ VM_GenCollectForAllocation op(size, is_tlab, gc_count_before);
+ VMThread::execute(&op);
+ if (op.prologue_succeeded()) {
+ result = op.result();
+ if (op.gc_locked()) {
+ assert(result == NULL, "must be NULL if gc_locked() is true");
+ continue; // Retry and/or stall as necessary.
+ }
+
+ // Allocation has failed and a collection
+ // has been done. If the gc time limit was exceeded the
+ // this time, return NULL so that an out-of-memory
+ // will be thrown. Clear gc_overhead_limit_exceeded
+ // so that the overhead exceeded does not persist.
+
+ const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
+ const bool softrefs_clear = soft_ref_policy()->all_soft_refs_clear();
+
+ if (limit_exceeded && softrefs_clear) {
+ *gc_overhead_limit_was_exceeded = true;
+ size_policy()->set_gc_overhead_limit_exceeded(false);
+ if (op.result() != NULL) {
+ CollectedHeap::fill_with_object(op.result(), size);
+ }
+ return NULL;
+ }
+ assert(result == NULL || is_in_reserved(result),
+ "result not in heap");
+ return result;
+ }
+
+ // Give a warning if we seem to be looping forever.
+ if ((QueuedAllocationWarningCount > 0) &&
+ (try_count % QueuedAllocationWarningCount == 0)) {
+ log_warning(gc, ergo)("GenCollectedHeap::mem_allocate_work retries %d times,"
+ " size=" SIZE_FORMAT " %s", try_count, size, is_tlab ? "(TLAB)" : "");
+ }
+ }
+}
#ifndef PRODUCT
// Override of memory state checking method in CollectedHeap:
@@ -253,9 +433,9 @@
HeapWord* GenCollectedHeap::mem_allocate(size_t size,
bool* gc_overhead_limit_was_exceeded) {
- return gen_policy()->mem_allocate_work(size,
- false /* is_tlab */,
- gc_overhead_limit_was_exceeded);
+ return mem_allocate_work(size,
+ false /* is_tlab */,
+ gc_overhead_limit_was_exceeded);
}
bool GenCollectedHeap::must_clear_all_soft_refs() {
@@ -367,12 +547,12 @@
return; // GC is disabled (e.g. JNI GetXXXCritical operation)
}
- GCIdMarkAndRestore gc_id_mark;
+ GCIdMark gc_id_mark;
const bool do_clear_all_soft_refs = clear_all_soft_refs ||
- collector_policy()->should_clear_all_soft_refs();
+ soft_ref_policy()->should_clear_all_soft_refs();
- ClearedAllSoftRefs casr(do_clear_all_soft_refs, collector_policy());
+ ClearedAllSoftRefs casr(do_clear_all_soft_refs, soft_ref_policy());
const size_t metadata_prev_used = MetaspaceAux::used_bytes();
@@ -442,7 +622,7 @@
if (do_young_collection) {
// We did a young GC. Need a new GC id for the old GC.
- GCIdMarkAndRestore gc_id_mark;
+ GCIdMark gc_id_mark;
GCTraceTime(Info, gc) t("Pause Full", NULL, gc_cause(), true);
collect_generation(_old_gen, full, size, is_tlab, run_verification && VerifyGCLevel <= 1, do_clear_all_soft_refs, true);
} else {
@@ -503,7 +683,79 @@
}
HeapWord* GenCollectedHeap::satisfy_failed_allocation(size_t size, bool is_tlab) {
- return gen_policy()->satisfy_failed_allocation(size, is_tlab);
+ GCCauseSetter x(this, GCCause::_allocation_failure);
+ HeapWord* result = NULL;
+
+ assert(size != 0, "Precondition violated");
+ if (GCLocker::is_active_and_needs_gc()) {
+ // GC locker is active; instead of a collection we will attempt
+ // to expand the heap, if there's room for expansion.
+ if (!is_maximal_no_gc()) {
+ result = expand_heap_and_allocate(size, is_tlab);
+ }
+ return result; // Could be null if we are out of space.
+ } else if (!incremental_collection_will_fail(false /* don't consult_young */)) {
+ // Do an incremental collection.
+ do_collection(false, // full
+ false, // clear_all_soft_refs
+ size, // size
+ is_tlab, // is_tlab
+ GenCollectedHeap::OldGen); // max_generation
+ } else {
+ log_trace(gc)(" :: Trying full because partial may fail :: ");
+ // Try a full collection; see delta for bug id 6266275
+ // for the original code and why this has been simplified
+ // with from-space allocation criteria modified and
+ // such allocation moved out of the safepoint path.
+ do_collection(true, // full
+ false, // clear_all_soft_refs
+ size, // size
+ is_tlab, // is_tlab
+ GenCollectedHeap::OldGen); // max_generation
+ }
+
+ result = attempt_allocation(size, is_tlab, false /*first_only*/);
+
+ if (result != NULL) {
+ assert(is_in_reserved(result), "result not in heap");
+ return result;
+ }
+
+ // OK, collection failed, try expansion.
+ result = expand_heap_and_allocate(size, is_tlab);
+ if (result != NULL) {
+ return result;
+ }
+
+ // If we reach this point, we're really out of memory. Try every trick
+ // we can to reclaim memory. Force collection of soft references. Force
+ // a complete compaction of the heap. Any additional methods for finding
+ // free memory should be here, especially if they are expensive. If this
+ // attempt fails, an OOM exception will be thrown.
+ {
+ UIntFlagSetting flag_change(MarkSweepAlwaysCompactCount, 1); // Make sure the heap is fully compacted
+
+ do_collection(true, // full
+ true, // clear_all_soft_refs
+ size, // size
+ is_tlab, // is_tlab
+ GenCollectedHeap::OldGen); // max_generation
+ }
+
+ result = attempt_allocation(size, is_tlab, false /* first_only */);
+ if (result != NULL) {
+ assert(is_in_reserved(result), "result not in heap");
+ return result;
+ }
+
+ assert(!soft_ref_policy()->should_clear_all_soft_refs(),
+ "Flag should have been handled and cleared prior to this point");
+
+ // What else? We might try synchronous finalization later. If the total
+ // space available is large enough for the allocation, then a more
+ // complete compaction phase than we've tried so far might be
+ // appropriate.
+ return NULL;
}
#ifdef ASSERT
@@ -886,9 +1138,9 @@
HeapWord* GenCollectedHeap::allocate_new_tlab(size_t size) {
bool gc_overhead_limit_was_exceeded;
- return gen_policy()->mem_allocate_work(size /* size */,
- true /* is_tlab */,
- &gc_overhead_limit_was_exceeded);
+ return mem_allocate_work(size /* size */,
+ true /* is_tlab */,
+ &gc_overhead_limit_was_exceeded);
}
// Requires "*prev_ptr" to be non-NULL. Deletes and a block of minimal size
--- a/src/hotspot/share/gc/shared/genCollectedHeap.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -25,11 +25,14 @@
#ifndef SHARE_VM_GC_SHARED_GENCOLLECTEDHEAP_HPP
#define SHARE_VM_GC_SHARED_GENCOLLECTEDHEAP_HPP
-#include "gc/shared/adaptiveSizePolicy.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "gc/shared/collectorPolicy.hpp"
#include "gc/shared/generation.hpp"
+#include "gc/shared/softRefGenPolicy.hpp"
+class AdaptiveSizePolicy;
+class GCPolicyCounters;
+class GenerationSpec;
class StrongRootsScope;
class SubTasksDone;
class WorkGang;
@@ -64,12 +67,22 @@
Generation* _young_gen;
Generation* _old_gen;
+ GenerationSpec* _young_gen_spec;
+ GenerationSpec* _old_gen_spec;
+
// The singleton CardTable Remembered Set.
CardTableRS* _rem_set;
// The generational collector policy.
GenCollectorPolicy* _gen_policy;
+ SoftRefGenPolicy _soft_ref_gen_policy;
+
+ // The sizing of the heap is controlled by a sizing policy.
+ AdaptiveSizePolicy* _size_policy;
+
+ GCPolicyCounters* _gc_policy_counters;
+
// Indicates that the most recent previous incremental collection failed.
// The flag is cleared when an action is taken that might clear the
// condition that caused that incremental collection to fail.
@@ -143,7 +156,10 @@
// we absolutely __must__ clear soft refs?
bool must_clear_all_soft_refs();
- GenCollectedHeap(GenCollectorPolicy *policy);
+ GenCollectedHeap(GenCollectorPolicy *policy,
+ Generation::Name young,
+ Generation::Name old,
+ const char* policy_counters_name);
virtual void check_gen_kinds() = 0;
@@ -152,6 +168,10 @@
// Returns JNI_OK on success
virtual jint initialize();
+ void initialize_size_policy(size_t init_eden_size,
+ size_t init_promo_size,
+ size_t init_survivor_size);
+
// Does operations required after initialization has been done.
void post_initialize();
@@ -161,16 +181,24 @@
bool is_young_gen(const Generation* gen) const { return gen == _young_gen; }
bool is_old_gen(const Generation* gen) const { return gen == _old_gen; }
+ GenerationSpec* young_gen_spec() const;
+ GenerationSpec* old_gen_spec() const;
+
// The generational collector policy.
GenCollectorPolicy* gen_policy() const { return _gen_policy; }
virtual CollectorPolicy* collector_policy() const { return gen_policy(); }
+ virtual SoftRefPolicy* soft_ref_policy() { return &_soft_ref_gen_policy; }
+
// Adaptive size policy
virtual AdaptiveSizePolicy* size_policy() {
- return gen_policy()->size_policy();
+ return _size_policy;
}
+ // Performance Counter support
+ GCPolicyCounters* counters() { return _gc_policy_counters; }
+
// Return the (conservative) maximum heap alignment
static size_t conservative_max_heap_alignment() {
return Generation::GenGrain;
@@ -456,6 +484,17 @@
private:
+ // Return true if an allocation should be attempted in the older generation
+ // if it fails in the younger generation. Return false, otherwise.
+ bool should_try_older_generation_allocation(size_t word_size) const;
+
+ // Try to allocate space by expanding the heap.
+ HeapWord* expand_heap_and_allocate(size_t size, bool is_tlab);
+
+ HeapWord* mem_allocate_work(size_t size,
+ bool is_tlab,
+ bool* gc_overhead_limit_was_exceeded);
+
// Override
void check_for_non_bad_heap_word_value(HeapWord* addr,
size_t size) PRODUCT_RETURN;
--- a/src/hotspot/share/gc/shared/generation.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/shared/generation.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -63,9 +63,9 @@
size_t Generation::initial_size() {
GenCollectedHeap* gch = GenCollectedHeap::heap();
if (gch->is_young_gen(this)) {
- return gch->gen_policy()->young_gen_spec()->init_size();
+ return gch->young_gen_spec()->init_size();
}
- return gch->gen_policy()->old_gen_spec()->init_size();
+ return gch->old_gen_spec()->init_size();
}
size_t Generation::max_capacity() const {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/oopStorageParState.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_SHARED_OOPSTORAGEPARSTATE_HPP
+#define SHARE_GC_SHARED_OOPSTORAGEPARSTATE_HPP
+
+#include "gc/shared/oopStorage.hpp"
+#include "memory/allocation.hpp"
+#include "utilities/macros.hpp"
+
+#if INCLUDE_ALL_GCS
+
+//////////////////////////////////////////////////////////////////////////////
+// Support for parallel and optionally concurrent state iteration.
+//
+// Parallel iteration is for the exclusive use of the GC. Other iteration
+// clients must use serial iteration.
+//
+// Concurrent Iteration
+//
+// Iteration involves the _active_list, which contains all of the blocks owned
+// by a storage object. This is a doubly-linked list, linked through
+// dedicated fields in the blocks.
+//
+// At most one concurrent ParState can exist at a time for a given storage
+// object.
+//
+// A concurrent ParState sets the associated storage's
+// _concurrent_iteration_active flag true when the state is constructed, and
+// sets it false when the state is destroyed. These assignments are made with
+// _active_mutex locked. Meanwhile, empty block deletion is not done while
+// _concurrent_iteration_active is true. The flag check and the dependent
+// removal of a block from the _active_list is performed with _active_mutex
+// locked. This prevents concurrent iteration and empty block deletion from
+// interfering with with each other.
+//
+// Both allocate() and delete_empty_blocks_concurrent() lock the
+// _allocate_mutex while performing their respective list manipulations,
+// preventing them from interfering with each other.
+//
+// When allocate() creates a new block, it is added to the front of the
+// _active_list. Then _active_head is set to the new block. When concurrent
+// iteration is started (by a parallel worker thread calling the state's
+// iterate() function), the current _active_head is used as the initial block
+// for the iteration, with iteration proceeding down the list headed by that
+// block.
+//
+// As a result, the list over which concurrent iteration operates is stable.
+// However, once the iteration is started, later allocations may add blocks to
+// the front of the list that won't be examined by the iteration. And while
+// the list is stable, concurrent allocate() and release() operations may
+// change the set of allocated entries in a block at any time during the
+// iteration.
+//
+// As a result, a concurrent iteration handler must accept that some
+// allocations and releases that occur after the iteration started will not be
+// seen by the iteration. Further, some may overlap examination by the
+// iteration. To help with this, allocate() and release() have an invariant
+// that an entry's value must be NULL when it is not in use.
+//
+// An in-progress delete_empty_blocks_concurrent() operation can contend with
+// the start of a concurrent iteration over the _active_mutex. Since both are
+// under GC control, that potential contention can be eliminated by never
+// scheduling both operations to run at the same time.
+//
+// ParState<concurrent, is_const>
+// concurrent must be true if iteration is concurrent with the
+// mutator, false if iteration is at a safepoint.
+//
+// is_const must be true if the iteration is over a constant storage
+// object, false if the iteration may modify the storage object.
+//
+// ParState([const] OopStorage* storage)
+// Construct an object for managing an iteration over storage. For a
+// concurrent ParState, empty block deletion for the associated storage
+// is inhibited for the life of the ParState. There can be no more
+// than one live concurrent ParState at a time for a given storage object.
+//
+// template<typename F> void iterate(F f)
+// Repeatedly claims a block from the associated storage that has
+// not been processed by this iteration (possibly by other threads),
+// and applies f to each entry in the claimed block. Assume p is of
+// type const oop* or oop*, according to is_const. Then f(p) must be
+// a valid expression whose value is ignored. Concurrent uses must
+// be prepared for an entry's value to change at any time, due to
+// mutator activity.
+//
+// template<typename Closure> void oops_do(Closure* cl)
+// Wrapper around iterate, providing an adaptation layer allowing
+// the use of OopClosures and similar objects for iteration. Assume
+// p is of type const oop* or oop*, according to is_const. Then
+// cl->do_oop(p) must be a valid expression whose value is ignored.
+// Concurrent uses must be prepared for the entry's value to change
+// at any time, due to mutator activity.
+//
+// Optional operations, provided only if !concurrent && !is_const.
+// These are not provided when is_const, because the storage object
+// may be modified by the iteration infrastructure, even if the
+// provided closure doesn't modify the storage object. These are not
+// provided when concurrent because any pre-filtering behavior by the
+// iteration infrastructure is inappropriate for concurrent iteration;
+// modifications of the storage by the mutator could result in the
+// pre-filtering being applied (successfully or not) to objects that
+// are unrelated to what the closure finds in the entry.
+//
+// template<typename Closure> void weak_oops_do(Closure* cl)
+// template<typename IsAliveClosure, typename Closure>
+// void weak_oops_do(IsAliveClosure* is_alive, Closure* cl)
+// Wrappers around iterate, providing an adaptation layer allowing
+// the use of is-alive closures and OopClosures for iteration.
+// Assume p is of type oop*. Then
+//
+// - cl->do_oop(p) must be a valid expression whose value is ignored.
+//
+// - is_alive->do_object_b(*p) must be a valid expression whose value
+// is convertible to bool.
+//
+// If *p == NULL then neither is_alive nor cl will be invoked for p.
+// If is_alive->do_object_b(*p) is false, then cl will not be
+// invoked on p.
+
+class OopStorage::BasicParState VALUE_OBJ_CLASS_SPEC {
+ OopStorage* _storage;
+ void* volatile _next_block;
+ bool _concurrent;
+
+ // Noncopyable.
+ BasicParState(const BasicParState&);
+ BasicParState& operator=(const BasicParState&);
+
+ void update_iteration_state(bool value);
+ void ensure_iteration_started();
+ Block* claim_next_block();
+
+ // Wrapper for iteration handler; ignore handler result and return true.
+ template<typename F> class AlwaysTrueFn;
+
+public:
+ BasicParState(OopStorage* storage, bool concurrent);
+ ~BasicParState();
+
+ template<bool is_const, typename F> void iterate(F f);
+};
+
+template<bool concurrent, bool is_const>
+class OopStorage::ParState VALUE_OBJ_CLASS_SPEC {
+ BasicParState _basic_state;
+
+public:
+ ParState(const OopStorage* storage) :
+ // For simplicity, always recorded as non-const.
+ _basic_state(const_cast<OopStorage*>(storage), concurrent)
+ {}
+
+ template<typename F> void iterate(F f);
+ template<typename Closure> void oops_do(Closure* cl);
+};
+
+template<>
+class OopStorage::ParState<false, false> VALUE_OBJ_CLASS_SPEC {
+ BasicParState _basic_state;
+
+public:
+ ParState(OopStorage* storage) :
+ _basic_state(storage, false)
+ {}
+
+ template<typename F> void iterate(F f);
+ template<typename Closure> void oops_do(Closure* cl);
+ template<typename Closure> void weak_oops_do(Closure* cl);
+ template<typename IsAliveClosure, typename Closure>
+ void weak_oops_do(IsAliveClosure* is_alive, Closure* cl);
+};
+
+#endif // INCLUDE_ALL_GCS
+
+#endif // SHARE_GC_SHARED_OOPSTORAGEPARSTATE_HPP
--- a/src/hotspot/share/gc/shared/oopStorageParState.inline.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/shared/oopStorageParState.inline.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -26,152 +26,13 @@
#define SHARE_GC_SHARED_OOPSTORAGEPARSTATE_INLINE_HPP
#include "gc/shared/oopStorage.inline.hpp"
+#include "gc/shared/oopStorageParState.hpp"
#include "memory/allocation.hpp"
#include "metaprogramming/conditional.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
-//////////////////////////////////////////////////////////////////////////////
-// Support for parallel and optionally concurrent state iteration.
-//
-// Parallel iteration is for the exclusive use of the GC. Other iteration
-// clients must use serial iteration.
-//
-// Concurrent Iteration
-//
-// Iteration involves the _active_list, which contains all of the blocks owned
-// by a storage object. This is a doubly-linked list, linked through
-// dedicated fields in the blocks.
-//
-// At most one concurrent ParState can exist at a time for a given storage
-// object.
-//
-// A concurrent ParState sets the associated storage's
-// _concurrent_iteration_active flag true when the state is constructed, and
-// sets it false when the state is destroyed. These assignments are made with
-// _active_mutex locked. Meanwhile, empty block deletion is not done while
-// _concurrent_iteration_active is true. The flag check and the dependent
-// removal of a block from the _active_list is performed with _active_mutex
-// locked. This prevents concurrent iteration and empty block deletion from
-// interfering with with each other.
-//
-// Both allocate() and delete_empty_blocks_concurrent() lock the
-// _allocate_mutex while performing their respective list manipulations,
-// preventing them from interfering with each other.
-//
-// When allocate() creates a new block, it is added to the front of the
-// _active_list. Then _active_head is set to the new block. When concurrent
-// iteration is started (by a parallel worker thread calling the state's
-// iterate() function), the current _active_head is used as the initial block
-// for the iteration, with iteration proceeding down the list headed by that
-// block.
-//
-// As a result, the list over which concurrent iteration operates is stable.
-// However, once the iteration is started, later allocations may add blocks to
-// the front of the list that won't be examined by the iteration. And while
-// the list is stable, concurrent allocate() and release() operations may
-// change the set of allocated entries in a block at any time during the
-// iteration.
-//
-// As a result, a concurrent iteration handler must accept that some
-// allocations and releases that occur after the iteration started will not be
-// seen by the iteration. Further, some may overlap examination by the
-// iteration. To help with this, allocate() and release() have an invariant
-// that an entry's value must be NULL when it is not in use.
-//
-// An in-progress delete_empty_blocks_concurrent() operation can contend with
-// the start of a concurrent iteration over the _active_mutex. Since both are
-// under GC control, that potential contention can be eliminated by never
-// scheduling both operations to run at the same time.
-//
-// ParState<concurrent, is_const>
-// concurrent must be true if iteration is concurrent with the
-// mutator, false if iteration is at a safepoint.
-//
-// is_const must be true if the iteration is over a constant storage
-// object, false if the iteration may modify the storage object.
-//
-// ParState([const] OopStorage* storage)
-// Construct an object for managing an iteration over storage. For a
-// concurrent ParState, empty block deletion for the associated storage
-// is inhibited for the life of the ParState. There can be no more
-// than one live concurrent ParState at a time for a given storage object.
-//
-// template<typename F> void iterate(F f)
-// Repeatedly claims a block from the associated storage that has
-// not been processed by this iteration (possibly by other threads),
-// and applies f to each entry in the claimed block. Assume p is of
-// type const oop* or oop*, according to is_const. Then f(p) must be
-// a valid expression whose value is ignored. Concurrent uses must
-// be prepared for an entry's value to change at any time, due to
-// mutator activity.
-//
-// template<typename Closure> void oops_do(Closure* cl)
-// Wrapper around iterate, providing an adaptation layer allowing
-// the use of OopClosures and similar objects for iteration. Assume
-// p is of type const oop* or oop*, according to is_const. Then
-// cl->do_oop(p) must be a valid expression whose value is ignored.
-// Concurrent uses must be prepared for the entry's value to change
-// at any time, due to mutator activity.
-//
-// Optional operations, provided only if !concurrent && !is_const.
-// These are not provided when is_const, because the storage object
-// may be modified by the iteration infrastructure, even if the
-// provided closure doesn't modify the storage object. These are not
-// provided when concurrent because any pre-filtering behavior by the
-// iteration infrastructure is inappropriate for concurrent iteration;
-// modifications of the storage by the mutator could result in the
-// pre-filtering being applied (successfully or not) to objects that
-// are unrelated to what the closure finds in the entry.
-//
-// template<typename Closure> void weak_oops_do(Closure* cl)
-// template<typename IsAliveClosure, typename Closure>
-// void weak_oops_do(IsAliveClosure* is_alive, Closure* cl)
-// Wrappers around iterate, providing an adaptation layer allowing
-// the use of is-alive closures and OopClosures for iteration.
-// Assume p is of type oop*. Then
-//
-// - cl->do_oop(p) must be a valid expression whose value is ignored.
-//
-// - is_alive->do_object_b(*p) must be a valid expression whose value
-// is convertible to bool.
-//
-// If *p == NULL then neither is_alive nor cl will be invoked for p.
-// If is_alive->do_object_b(*p) is false, then cl will not be
-// invoked on p.
-
-class OopStorage::BasicParState VALUE_OBJ_CLASS_SPEC {
- OopStorage* _storage;
- void* volatile _next_block;
- bool _concurrent;
-
- // Noncopyable.
- BasicParState(const BasicParState&);
- BasicParState& operator=(const BasicParState&);
-
- void update_iteration_state(bool value);
- void ensure_iteration_started();
- Block* claim_next_block();
-
- // Wrapper for iteration handler; ignore handler result and return true.
- template<typename F> class AlwaysTrueFn;
-
-public:
- BasicParState(OopStorage* storage, bool concurrent);
- ~BasicParState();
-
- template<bool is_const, typename F> void iterate(F f) {
- // Wrap f in ATF so we can use Block::iterate.
- AlwaysTrueFn<F> atf_f(f);
- ensure_iteration_started();
- typename Conditional<is_const, const Block*, Block*>::type block;
- while ((block = claim_next_block()) != NULL) {
- block->iterate(atf_f);
- }
- }
-};
-
template<typename F>
class OopStorage::BasicParState::AlwaysTrueFn VALUE_OBJ_CLASS_SPEC {
F _f;
@@ -183,57 +44,49 @@
bool operator()(OopPtr ptr) const { _f(ptr); return true; }
};
-template<bool concurrent, bool is_const>
-class OopStorage::ParState VALUE_OBJ_CLASS_SPEC {
- BasicParState _basic_state;
-
-public:
- ParState(const OopStorage* storage) :
- // For simplicity, always recorded as non-const.
- _basic_state(const_cast<OopStorage*>(storage), concurrent)
- {}
+template<bool is_const, typename F>
+inline void OopStorage::BasicParState::iterate(F f) {
+ // Wrap f in ATF so we can use Block::iterate.
+ AlwaysTrueFn<F> atf_f(f);
+ ensure_iteration_started();
+ typename Conditional<is_const, const Block*, Block*>::type block;
+ while ((block = claim_next_block()) != NULL) {
+ block->iterate(atf_f);
+ }
+}
- template<typename F>
- void iterate(F f) {
- _basic_state.template iterate<is_const>(f);
- }
-
- template<typename Closure>
- void oops_do(Closure* cl) {
- this->iterate(oop_fn(cl));
- }
-};
-
-template<>
-class OopStorage::ParState<false, false> VALUE_OBJ_CLASS_SPEC {
- BasicParState _basic_state;
+template<bool concurrent, bool is_const>
+template<typename F>
+inline void OopStorage::ParState<concurrent, is_const>::iterate(F f) {
+ _basic_state.template iterate<is_const>(f);
+}
-public:
- ParState(OopStorage* storage) :
- _basic_state(storage, false)
- {}
+template<bool concurrent, bool is_const>
+template<typename Closure>
+inline void OopStorage::ParState<concurrent, is_const>::oops_do(Closure* cl) {
+ this->iterate(oop_fn(cl));
+}
- template<typename F>
- void iterate(F f) {
- _basic_state.template iterate<false>(f);
- }
+template<typename F>
+inline void OopStorage::ParState<false, false>::iterate(F f) {
+ _basic_state.template iterate<false>(f);
+}
- template<typename Closure>
- void oops_do(Closure* cl) {
- this->iterate(oop_fn(cl));
- }
+template<typename Closure>
+inline void OopStorage::ParState<false, false>::oops_do(Closure* cl) {
+ this->iterate(oop_fn(cl));
+}
- template<typename Closure>
- void weak_oops_do(Closure* cl) {
- this->iterate(skip_null_fn(oop_fn(cl)));
- }
+template<typename Closure>
+inline void OopStorage::ParState<false, false>::weak_oops_do(Closure* cl) {
+ this->iterate(skip_null_fn(oop_fn(cl)));
+}
- template<typename IsAliveClosure, typename Closure>
- void weak_oops_do(IsAliveClosure* is_alive, Closure* cl) {
- this->iterate(if_alive_fn(is_alive, oop_fn(cl)));
- }
-};
+template<typename IsAliveClosure, typename Closure>
+inline void OopStorage::ParState<false, false>::weak_oops_do(IsAliveClosure* is_alive, Closure* cl) {
+ this->iterate(if_alive_fn(is_alive, oop_fn(cl)));
+}
#endif // INCLUDE_ALL_GCS
-#endif // include guard
+#endif // SHARE_GC_SHARED_OOPSTORAGEPARSTATE_INLINE_HPP
--- a/src/hotspot/share/gc/shared/referenceProcessor.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/shared/referenceProcessor.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, 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
@@ -363,12 +363,12 @@
}
void DiscoveredListIterator::load_ptrs(DEBUG_ONLY(bool allow_null_referent)) {
- _discovered_addr = java_lang_ref_Reference::discovered_addr(_ref);
+ _discovered_addr = java_lang_ref_Reference::discovered_addr_raw(_ref);
oop discovered = java_lang_ref_Reference::discovered(_ref);
assert(_discovered_addr && oopDesc::is_oop_or_null(discovered),
"Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered));
_next = discovered;
- _referent_addr = java_lang_ref_Reference::referent_addr(_ref);
+ _referent_addr = java_lang_ref_Reference::referent_addr_raw(_ref);
_referent = java_lang_ref_Reference::referent(_ref);
assert(Universe::heap()->is_in_reserved_or_null(_referent),
"Wrong oop found in java.lang.Reference object");
@@ -494,7 +494,7 @@
DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
while (iter.has_next()) {
iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
- HeapWord* next_addr = java_lang_ref_Reference::next_addr(iter.obj());
+ HeapWord* next_addr = java_lang_ref_Reference::next_addr_raw(iter.obj());
oop next = java_lang_ref_Reference::next(iter.obj());
if ((iter.referent() == NULL || iter.is_referent_alive() ||
next != NULL)) {
@@ -1019,7 +1019,7 @@
ResourceMark rm; // Needed for tracing.
- HeapWord* const discovered_addr = java_lang_ref_Reference::discovered_addr(obj);
+ HeapWord* const discovered_addr = java_lang_ref_Reference::discovered_addr_raw(obj);
const oop discovered = java_lang_ref_Reference::discovered(obj);
assert(oopDesc::is_oop_or_null(discovered), "Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered));
if (discovered != NULL) {
@@ -1186,10 +1186,10 @@
// Keep alive its cohort.
iter.make_referent_alive();
if (UseCompressedOops) {
- narrowOop* next_addr = (narrowOop*)java_lang_ref_Reference::next_addr(obj);
+ narrowOop* next_addr = (narrowOop*)java_lang_ref_Reference::next_addr_raw(obj);
keep_alive->do_oop(next_addr);
} else {
- oop* next_addr = (oop*)java_lang_ref_Reference::next_addr(obj);
+ oop* next_addr = (oop*)java_lang_ref_Reference::next_addr_raw(obj);
keep_alive->do_oop(next_addr);
}
iter.move_to_next();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/softRefGenPolicy.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/shared/adaptiveSizePolicy.hpp"
+#include "gc/shared/genCollectedHeap.hpp"
+#include "gc/shared/softRefGenPolicy.hpp"
+
+void SoftRefGenPolicy::cleared_all_soft_refs() {
+ // If near gc overhear limit, continue to clear SoftRefs. SoftRefs may
+ // have been cleared in the last collection but if the gc overhear
+ // limit continues to be near, SoftRefs should still be cleared.
+ AdaptiveSizePolicy* size_policy = GenCollectedHeap::heap()->size_policy();
+ if (size_policy != NULL) {
+ set_should_clear_all_soft_refs(size_policy->gc_overhead_limit_near());
+ }
+
+ SoftRefPolicy::cleared_all_soft_refs();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/softRefGenPolicy.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_SHARED_SOFTREFGENPOLICY_HPP
+#define SHARE_VM_GC_SHARED_SOFTREFGENPOLICY_HPP
+
+#include "gc/shared/softRefPolicy.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class AdaptiveSizePolicy;
+
+class SoftRefGenPolicy : public SoftRefPolicy {
+public:
+ virtual void cleared_all_soft_refs();
+};
+
+#endif // SHARE_VM_GC_SHARED_SOFTREFGENPOLICY_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/softRefPolicy.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/shared/softRefPolicy.hpp"
+
+SoftRefPolicy::SoftRefPolicy() :
+ _should_clear_all_soft_refs(false),
+ _all_soft_refs_clear(false) {
+}
+
+bool SoftRefPolicy::use_should_clear_all_soft_refs(bool v) {
+ bool result = _should_clear_all_soft_refs;
+ set_should_clear_all_soft_refs(false);
+ return result;
+}
+
+void SoftRefPolicy::cleared_all_soft_refs() {
+ _all_soft_refs_clear = true;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/softRefPolicy.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_SHARED_SOFTREFPOLICY_HPP
+#define SHARE_VM_GC_SHARED_SOFTREFPOLICY_HPP
+
+#include "memory/allocation.hpp"
+
+class SoftRefPolicy {
+ private:
+ // Set to true when policy wants soft refs cleared.
+ // Reset to false by gc after it clears all soft refs.
+ bool _should_clear_all_soft_refs;
+
+ // Set to true by the GC if the just-completed gc cleared all
+ // softrefs. This is set to true whenever a gc clears all softrefs, and
+ // set to false each time gc returns to the mutator. For example, in the
+ // ParallelScavengeHeap case the latter would be done toward the end of
+ // mem_allocate() where it returns op.result()
+ bool _all_soft_refs_clear;
+
+ public:
+ SoftRefPolicy();
+
+ bool should_clear_all_soft_refs() { return _should_clear_all_soft_refs; }
+ void set_should_clear_all_soft_refs(bool v) { _should_clear_all_soft_refs = v; }
+ // Returns the current value of _should_clear_all_soft_refs.
+ // _should_clear_all_soft_refs is set to false as a side effect.
+ bool use_should_clear_all_soft_refs(bool v);
+ bool all_soft_refs_clear() { return _all_soft_refs_clear; }
+ void set_all_soft_refs_clear(bool v) { _all_soft_refs_clear = v; }
+
+ // Called by the GC after Soft Refs have been cleared to indicate
+ // that the request in _should_clear_all_soft_refs has been fulfilled.
+ virtual void cleared_all_soft_refs();
+};
+
+class ClearedAllSoftRefs : public StackObj {
+ bool _clear_all_soft_refs;
+ SoftRefPolicy* _soft_ref_policy;
+ public:
+ ClearedAllSoftRefs(bool clear_all_soft_refs, SoftRefPolicy* soft_ref_policy) :
+ _clear_all_soft_refs(clear_all_soft_refs),
+ _soft_ref_policy(soft_ref_policy) {}
+
+ ~ClearedAllSoftRefs() {
+ if (_clear_all_soft_refs) {
+ _soft_ref_policy->cleared_all_soft_refs();
+ }
+ }
+
+ bool should_clear() { return _clear_all_soft_refs; }
+};
+
+#endif // SHARE_VM_GC_SHARED_SOFTREFPOLICY_HPP
--- a/src/hotspot/share/gc/shared/vmGCOperations.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/shared/vmGCOperations.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -46,7 +46,7 @@
VM_GC_Operation::~VM_GC_Operation() {
CollectedHeap* ch = Universe::heap();
- ch->collector_policy()->set_all_soft_refs_clear(false);
+ ch->soft_ref_policy()->set_all_soft_refs_clear(false);
}
// The same dtrace probe can't be inserted in two different files, so we
--- a/src/hotspot/share/gc/shared/workgroup.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/gc/shared/workgroup.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, 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
@@ -59,14 +59,9 @@
const uint _gc_id;
public:
- AbstractGangTask(const char* name) :
+ explicit AbstractGangTask(const char* name) :
_name(name),
- _gc_id(GCId::current_raw())
- {}
-
- AbstractGangTask(const char* name, const uint gc_id) :
- _name(name),
- _gc_id(gc_id)
+ _gc_id(GCId::current_or_undefined())
{}
// The abstract work method.
--- a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,8 +34,10 @@
#include "jvmci/jvmciJavaClasses.hpp"
#include "jvmci/jvmciCompilerToVM.hpp"
#include "jvmci/jvmciRuntime.hpp"
+#include "oops/arrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/objArrayOop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/safepointMechanism.inline.hpp"
#include "utilities/align.hpp"
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -32,6 +32,7 @@
#include "oops/fieldStreams.hpp"
#include "oops/oop.inline.hpp"
#include "oops/objArrayOop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "runtime/fieldDescriptor.hpp"
#include "runtime/javaCalls.hpp"
#include "jvmci/jvmciRuntime.hpp"
--- a/src/hotspot/share/logging/logConfiguration.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/logging/logConfiguration.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,8 +30,8 @@
#include "logging/logDiagnosticCommand.hpp"
#include "logging/logFileOutput.hpp"
#include "logging/logOutput.hpp"
+#include "logging/logSelectionList.hpp"
#include "logging/logStream.hpp"
-#include "logging/logTagLevelExpression.hpp"
#include "logging/logTagSet.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
@@ -207,7 +207,7 @@
delete output;
}
-void LogConfiguration::configure_output(size_t idx, const LogTagLevelExpression& tag_level_expression, const LogDecorators& decorators) {
+void LogConfiguration::configure_output(size_t idx, const LogSelectionList& selections, const LogDecorators& decorators) {
assert(ConfigurationLock::current_thread_has_lock(), "Must hold configuration lock to call this function.");
assert(idx < _n_outputs, "Invalid index, idx = " SIZE_FORMAT " and _n_outputs = " SIZE_FORMAT, idx, _n_outputs);
LogOutput* output = _outputs[idx];
@@ -217,7 +217,7 @@
bool enabled = false;
for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
- LogLevelType level = tag_level_expression.level_for(*ts);
+ LogLevelType level = selections.level_for(*ts);
// Ignore tagsets that do not, and will not log on the output
if (!ts->has_output(output) && (level == LogLevel::NotMentioned || level == LogLevel::Off)) {
@@ -299,11 +299,11 @@
void LogConfiguration::configure_stdout(LogLevelType level, int exact_match, ...) {
size_t i;
va_list ap;
- LogTagLevelExpression expr;
+ LogTagType tags[LogTag::MaxTags];
va_start(ap, exact_match);
for (i = 0; i < LogTag::MaxTags; i++) {
LogTagType tag = static_cast<LogTagType>(va_arg(ap, int));
- expr.add_tag(tag);
+ tags[i] = tag;
if (tag == LogTag::__NO_TAG) {
assert(i > 0, "Must specify at least one tag!");
break;
@@ -313,17 +313,14 @@
"Too many tags specified! Can only have up to " SIZE_FORMAT " tags in a tag set.", LogTag::MaxTags);
va_end(ap);
- if (!exact_match) {
- expr.set_allow_other_tags();
- }
- expr.set_level(level);
- expr.new_combination();
- assert(expr.verify_tagsets(),
- "configure_stdout() called with invalid/non-existing tag set");
+ LogSelection selection(tags, !exact_match, level);
+ assert(selection.tag_sets_selected() > 0,
+ "configure_stdout() called with invalid/non-existing log selection");
+ LogSelectionList list(selection);
// Apply configuration to stdout (output #0), with the same decorators as before.
ConfigurationLock cl;
- configure_output(0, expr, _outputs[0]->decorators());
+ configure_output(0, list, _outputs[0]->decorators());
notify_update_listeners();
}
@@ -382,7 +379,7 @@
}
bool LogConfiguration::parse_log_arguments(const char* outputstr,
- const char* what,
+ const char* selectionstr,
const char* decoratorstr,
const char* output_options,
outputStream* errstream) {
@@ -391,8 +388,8 @@
outputstr = "stdout";
}
- LogTagLevelExpression expr;
- if (!expr.parse(what, errstream)) {
+ LogSelectionList selections;
+ if (!selections.parse(selectionstr, errstream)) {
return false;
}
@@ -433,9 +430,9 @@
return false;
}
}
- configure_output(idx, expr, decorators);
+ configure_output(idx, selections, decorators);
notify_update_listeners();
- expr.verify_tagsets(errstream);
+ selections.verify_selections(errstream);
return true;
}
@@ -454,10 +451,7 @@
out->cr();
out->print("Available log tags:");
- for (size_t i = 1; i < LogTag::Count; i++) {
- out->print("%s %s", (i == 1 ? "" : ","), LogTag::name(static_cast<LogTagType>(i)));
- }
- out->cr();
+ LogTag::list_tags(out);
LogTagSet::describe_tagsets(out);
}
@@ -494,13 +488,12 @@
}
jio_fprintf(out, "\n Decorators can also be specified as 'none' for no decoration.\n\n");
- jio_fprintf(out, "Available log tags:\n");
- for (size_t i = 1; i < LogTag::Count; i++) {
- jio_fprintf(out, "%s %s", (i == 1 ? "" : ","), LogTag::name(static_cast<LogTagType>(i)));
- }
- jio_fprintf(out, "\n Specifying 'all' instead of a tag combination matches all tag combinations.\n\n");
+ fileStream stream(out, false);
+ stream.print_cr("Available log tags:");
+ LogTag::list_tags(&stream);
+ stream.print_cr(" Specifying 'all' instead of a tag combination matches all tag combinations.");
+ stream.cr();
- fileStream stream(out, false);
LogTagSet::describe_tagsets(&stream);
jio_fprintf(out, "\nAvailable log outputs:\n"
--- a/src/hotspot/share/logging/logConfiguration.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/logging/logConfiguration.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@
class LogOutput;
class LogDecorators;
-class LogTagLevelExpression;
+class LogSelectionList;
// Global configuration of logging. Handles parsing and configuration of the logging framework,
// and manages the list of configured log outputs. The actual tag and level configuration is
@@ -75,7 +75,7 @@
static size_t find_output(const char* name);
// Configure output (add or update existing configuration) to log on tag-level combination using specified decorators.
- static void configure_output(size_t idx, const LogTagLevelExpression& tag_level_expression, const LogDecorators& decorators);
+ static void configure_output(size_t idx, const LogSelectionList& tag_level_expression, const LogDecorators& decorators);
// This should be called after any configuration change while still holding ConfigurationLock
static void notify_update_listeners();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/logging/logSelection.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#include "precompiled.hpp"
+#include "utilities/ostream.hpp"
+#include "logging/logSelection.hpp"
+#include "logging/logTagSet.hpp"
+#include "runtime/os.inline.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/ostream.hpp"
+
+const LogSelection LogSelection::Invalid;
+
+LogSelection::LogSelection() : _ntags(0), _wildcard(false), _level(LogLevel::Invalid), _tag_sets_selected(0) {
+}
+
+LogSelection::LogSelection(const LogTagType tags[LogTag::MaxTags], bool wildcard, LogLevelType level)
+ : _ntags(0), _wildcard(wildcard), _level(level), _tag_sets_selected(0) {
+ while (_ntags < LogTag::MaxTags && tags[_ntags] != LogTag::__NO_TAG) {
+ _tags[_ntags] = tags[_ntags];
+ _ntags++;
+ }
+
+ for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
+ if (selects(*ts)) {
+ _tag_sets_selected++;
+ }
+ }
+}
+
+bool LogSelection::operator==(const LogSelection& ref) const {
+ if (_ntags != ref._ntags ||
+ _wildcard != ref._wildcard ||
+ _level != ref._level ||
+ _tag_sets_selected != ref._tag_sets_selected) {
+ return false;
+ }
+ for (size_t i = 0; i < _ntags; i++) {
+ if (_tags[i] != ref._tags[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool LogSelection::operator!=(const LogSelection& ref) const {
+ return !operator==(ref);
+}
+
+static LogSelection parse_internal(char *str, outputStream* errstream) {
+ // Parse the level, if specified
+ LogLevelType level = LogLevel::Unspecified;
+ char* equals = strchr(str, '=');
+ if (equals != NULL) {
+ level = LogLevel::from_string(equals + 1);
+ if (level == LogLevel::Invalid) {
+ if (errstream != NULL) {
+ errstream->print_cr("Invalid level '%s' in log selection.", equals + 1);
+ }
+ return LogSelection::Invalid;
+ }
+ *equals = '\0';
+ }
+
+ size_t ntags = 0;
+ LogTagType tags[LogTag::MaxTags] = { LogTag::__NO_TAG };
+
+ // Parse special tags such as 'all'
+ if (strcmp(str, "all") == 0) {
+ return LogSelection(tags, true, level);
+ }
+
+ // Check for '*' suffix
+ bool wildcard = false;
+ char* asterisk_pos = strchr(str, '*');
+ if (asterisk_pos != NULL && asterisk_pos[1] == '\0') {
+ wildcard = true;
+ *asterisk_pos = '\0';
+ }
+
+ // Parse the tag expression (t1+t2+...+tn)
+ char* plus_pos;
+ char* cur_tag = str;
+ do {
+ plus_pos = strchr(cur_tag, '+');
+ if (plus_pos != NULL) {
+ *plus_pos = '\0';
+ }
+ LogTagType tag = LogTag::from_string(cur_tag);
+ if (tag == LogTag::__NO_TAG) {
+ if (errstream != NULL) {
+ errstream->print_cr("Invalid tag '%s' in log selection.", cur_tag);
+ }
+ return LogSelection::Invalid;
+ }
+ if (ntags == LogTag::MaxTags) {
+ if (errstream != NULL) {
+ errstream->print_cr("Too many tags in log selection '%s' (can only have up to " SIZE_FORMAT " tags).",
+ str, LogTag::MaxTags);
+ }
+ return LogSelection::Invalid;
+ }
+ tags[ntags++] = tag;
+ cur_tag = plus_pos + 1;
+ } while (plus_pos != NULL);
+
+ for (size_t i = 0; i < ntags; i++) {
+ for (size_t j = 0; j < ntags; j++) {
+ if (i != j && tags[i] == tags[j]) {
+ if (errstream != NULL) {
+ errstream->print_cr("Log selection contains duplicates of tag %s.", LogTag::name(tags[i]));
+ }
+ return LogSelection::Invalid;
+ }
+ }
+ }
+
+ return LogSelection(tags, wildcard, level);
+}
+
+LogSelection LogSelection::parse(const char* str, outputStream* error_stream) {
+ char* copy = os::strdup_check_oom(str, mtLogging);
+ LogSelection s = parse_internal(copy, error_stream);
+ os::free(copy);
+ return s;
+}
+
+bool LogSelection::selects(const LogTagSet& ts) const {
+ if (!_wildcard && _ntags != ts.ntags()) {
+ return false;
+ }
+ for (size_t i = 0; i < _ntags; i++) {
+ if (!ts.contains(_tags[i])) {
+ return false;
+ }
+ }
+ return true;
+}
+
+size_t LogSelection::ntags() const {
+ return _ntags;
+}
+
+LogLevelType LogSelection::level() const {
+ return _level;
+}
+
+size_t LogSelection::tag_sets_selected() const {
+ return _tag_sets_selected;
+}
+
+int LogSelection::describe_tags(char* buf, size_t bufsize) const {
+ int tot_written = 0;
+ for (size_t i = 0; i < _ntags; i++) {
+ int written = jio_snprintf(buf + tot_written, bufsize - tot_written,
+ "%s%s", (i == 0 ? "" : "+"), LogTag::name(_tags[i]));
+ if (written == -1) {
+ return written;
+ }
+ tot_written += written;
+ }
+
+ if (_wildcard) {
+ int written = jio_snprintf(buf + tot_written, bufsize - tot_written, "*");
+ if (written == -1) {
+ return written;
+ }
+ tot_written += written;
+ }
+ return tot_written;
+}
+
+int LogSelection::describe(char* buf, size_t bufsize) const {
+ int tot_written = describe_tags(buf, bufsize);
+
+ int written = jio_snprintf(buf + tot_written, bufsize - tot_written, "=%s", LogLevel::name(_level));
+ if (written == -1) {
+ return -1;
+ }
+ tot_written += written;
+ return tot_written;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/logging/logSelection.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef SHARE_VM_LOGGING_LOGSELECTION_HPP
+#define SHARE_VM_LOGGING_LOGSELECTION_HPP
+
+#include "logging/logLevel.hpp"
+#include "logging/logTag.hpp"
+#include "memory/allocation.hpp"
+
+class LogTagSet;
+
+// Class representing a selection of tags with for a given level.
+// Consists of a set of tags, an optional wildcard flag, and a level, e.g. "tag1+tag2*=level".
+class LogSelection : public StackObj {
+ friend class LogSelectionList;
+
+ private:
+ size_t _ntags;
+ LogTagType _tags[LogTag::MaxTags];
+ bool _wildcard;
+ LogLevelType _level;
+ size_t _tag_sets_selected;
+
+ LogSelection();
+
+ public:
+ static const LogSelection Invalid;
+
+ static LogSelection parse(const char* str, outputStream* error_stream = NULL);
+
+ LogSelection(const LogTagType tags[LogTag::MaxTags], bool wildcard, LogLevelType level);
+
+ bool operator==(const LogSelection& ref) const;
+ bool operator!=(const LogSelection& ref) const;
+
+ size_t ntags() const;
+ LogLevelType level() const;
+ size_t tag_sets_selected() const;
+
+ bool selects(const LogTagSet& ts) const;
+
+ int describe_tags(char* buf, size_t bufsize) const;
+ int describe(char* buf, size_t bufsize) const;
+};
+
+#endif // SHARE_VM_LOGGING_LOGSELECTION_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/logging/logSelectionList.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "logging/logSelectionList.hpp"
+#include "logging/logTagSet.hpp"
+#include "runtime/arguments.hpp"
+#include "runtime/os.inline.hpp"
+
+static const char* DefaultExpressionString = "all";
+
+bool LogSelectionList::verify_selections(outputStream* out) const {
+ bool valid = true;
+
+ for (size_t i = 0; i < _nselections; i++) {
+ if (_selections[i].tag_sets_selected() == 0) {
+ // Return immediately unless all invalid selections should be listed
+ if (out == NULL) {
+ return false;
+ }
+
+ if (valid) {
+ out->print("No tag set matches selection(s):");
+ }
+ valid = false;
+
+ char buf[256];
+ _selections[i].describe_tags(buf, sizeof(buf));
+ out->print(" %s", buf);
+ }
+ }
+ if (!valid && out != NULL) {
+ out->cr();
+ }
+ return valid;
+}
+
+
+bool LogSelectionList::parse(const char* str, outputStream* errstream) {
+ bool success = true;
+ if (str == NULL || strcmp(str, "") == 0) {
+ str = DefaultExpressionString;
+ }
+ char* copy = os::strdup_check_oom(str, mtLogging);
+ // Split string on commas
+ for (char *comma_pos = copy, *cur = copy; success && comma_pos != NULL; cur = comma_pos + 1) {
+ if (_nselections == MaxSelections) {
+ if (errstream != NULL) {
+ errstream->print_cr("Can not have more than " SIZE_FORMAT " log selections in a single configuration.",
+ MaxSelections);
+ }
+ success = false;
+ break;
+ }
+
+ comma_pos = strchr(cur, ',');
+ if (comma_pos != NULL) {
+ *comma_pos = '\0';
+ }
+
+ LogSelection selection = LogSelection::parse(cur, errstream);
+ if (selection == LogSelection::Invalid) {
+ success = false;
+ break;
+ }
+ _selections[_nselections++] = selection;
+ }
+
+ os::free(copy);
+ return success;
+}
+
+LogLevelType LogSelectionList::level_for(const LogTagSet& ts) const {
+ // Return NotMentioned if the given tagset isn't covered by this expression.
+ LogLevelType level = LogLevel::NotMentioned;
+ for (size_t i= 0; i < _nselections; i++) {
+ if (_selections[i].selects(ts)) {
+ level = _selections[i].level();
+ }
+ }
+ return level;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/logging/logSelectionList.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015, 2018 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef SHARE_VM_LOGGING_LOGSELECTIONLIST_HPP
+#define SHARE_VM_LOGGING_LOGSELECTIONLIST_HPP
+
+#include "logging/logConfiguration.hpp"
+#include "logging/logSelection.hpp"
+#include "logging/logTag.hpp"
+#include "memory/allocation.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class LogTagSet;
+
+// Class used to temporary encode a series of log selections during log configuration.
+// Consists of ordered LogSelections, i.e. "tag1+tag2=level1,tag3*=level2".
+class LogSelectionList : public StackObj {
+ public:
+ static const size_t MaxSelections = 256;
+
+ private:
+ friend void LogConfiguration::configure_stdout(LogLevelType, int, ...);
+
+ size_t _nselections;
+ LogSelection _selections[MaxSelections];
+
+ public:
+ LogSelectionList() : _nselections(0) {
+ }
+
+ LogSelectionList(const LogSelection& selection) : _nselections(1) {
+ _selections[0] = selection;
+ }
+
+ bool parse(const char* str, outputStream* errstream = NULL);
+ LogLevelType level_for(const LogTagSet& ts) const;
+
+ // Verify that each selection actually selects something.
+ // Returns false if some invalid selection was found. If given an outputstream,
+ // this function will list all the invalid selections on the stream.
+ bool verify_selections(outputStream* out = NULL) const;
+};
+
+#endif // SHARE_VM_LOGGING_LOGSELECTIONLIST_HPP
--- a/src/hotspot/share/logging/logTag.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/logging/logTag.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,8 @@
#include "precompiled.hpp"
#include "logging/logTag.hpp"
#include "utilities/globalDefinitions.hpp"
+#include "utilities/ostream.hpp"
+#include "utilities/quickSort.hpp"
const char* LogTag::_name[] = {
"", // __NO_TAG
@@ -40,3 +42,29 @@
}
return __NO_TAG;
}
+
+static int cmp_logtag(LogTagType a, LogTagType b) {
+ return strcmp(LogTag::name(a), LogTag::name(b));
+}
+
+static const size_t sorted_tagcount = LogTag::Count - 1; // Not counting _NO_TAG
+static LogTagType sorted_tags[sorted_tagcount];
+
+class TagSorter {
+ public:
+ TagSorter() {
+ for (size_t i = 1; i < LogTag::Count; i++) {
+ sorted_tags[i - 1] = static_cast<LogTagType>(i);
+ }
+ QuickSort::sort(sorted_tags, sorted_tagcount, cmp_logtag, true);
+ }
+};
+
+static TagSorter tagsorter; // Sorts tags during static initialization
+
+void LogTag::list_tags(outputStream* out) {
+ for (size_t i = 0; i < sorted_tagcount; i++) {
+ out->print("%s %s", (i == 0 ? "" : ","), _name[sorted_tags[i]]);
+ }
+ out->cr();
+}
--- a/src/hotspot/share/logging/logTag.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/logging/logTag.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -192,6 +192,7 @@
}
static LogTag::type from_string(const char *str);
+ static void list_tags(outputStream* out);
private:
static const char* _name[];
--- a/src/hotspot/share/logging/logTagLevelExpression.cpp Thu Mar 01 01:30:10 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-#include "precompiled.hpp"
-#include "logging/logTagLevelExpression.hpp"
-#include "logging/logTagSet.hpp"
-#include "runtime/arguments.hpp"
-#include "runtime/os.inline.hpp"
-
-const char* LogTagLevelExpression::DefaultExpressionString = "all";
-
-static bool matches_tagset(const LogTagType tags[],
- bool allow_other_tags,
- const LogTagSet& ts) {
- bool contains_all = true;
- size_t tag_idx;
- for (tag_idx = 0; tag_idx < LogTag::MaxTags && tags[tag_idx] != LogTag::__NO_TAG; tag_idx++) {
- if (!ts.contains(tags[tag_idx])) {
- contains_all = false;
- break;
- }
- }
- // All tags in the expression must be part of the tagset,
- // and either the expression allows other tags (has a wildcard),
- // or the number of tags in the expression and tagset must match.
- return contains_all && (allow_other_tags || tag_idx == ts.ntags());
-}
-
-bool LogTagLevelExpression::verify_tagsets(outputStream* out) const {
- bool valid = true;
-
- for (size_t i = 0; i < _ncombinations; i++) {
- bool matched = false;
- for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
- if (matches_tagset(_tags[i], _allow_other_tags[i], *ts)) {
- matched = true;
- break;
- }
- }
-
- if (!matched) {
- // If this was the first invalid combination, write the message header
- if (valid && out != NULL) {
- out->print("No tag set matches selection(s): ");
- }
- valid = false;
-
- // Break as soon as possible unless listing all invalid combinations
- if (out == NULL) {
- break;
- }
-
- // List the combination on the outputStream
- for (size_t t = 0; t < LogTag::MaxTags && _tags[i][t] != LogTag::__NO_TAG; t++) {
- out->print("%s%s", (t == 0 ? "" : "+"), LogTag::name(_tags[i][t]));
- }
- if (_allow_other_tags[i]) {
- out->print("*");
- }
- out->print(" ");
- }
- }
-
- if (!valid && out != NULL) {
- out->cr();
- }
-
- return valid;
-}
-
-bool LogTagLevelExpression::parse(const char* str, outputStream* errstream) {
- bool success = true;
- if (str == NULL || strcmp(str, "") == 0) {
- str = DefaultExpressionString;
- }
- char* copy = os::strdup_check_oom(str, mtLogging);
- // Split string on commas
- for (char *comma_pos = copy, *cur = copy; success && comma_pos != NULL; cur = comma_pos + 1) {
- if (_ncombinations == MaxCombinations) {
- if (errstream != NULL) {
- errstream->print_cr("Can not have more than " SIZE_FORMAT " tag combinations in a what-expression.",
- MaxCombinations);
- }
- success = false;
- break;
- }
-
- comma_pos = strchr(cur, ',');
- if (comma_pos != NULL) {
- *comma_pos = '\0';
- }
-
- // Parse the level, if specified
- LogLevelType level = LogLevel::Unspecified;
- char* equals = strchr(cur, '=');
- if (equals != NULL) {
- level = LogLevel::from_string(equals + 1);
- if (level == LogLevel::Invalid) {
- if (errstream != NULL) {
- errstream->print_cr("Invalid level '%s' in what-expression.", equals + 1);
- }
- success = false;
- break;
- }
- *equals = '\0'; // now ignore "=level" part of substr
- }
- set_level(level);
-
- // Parse special tags such as 'all'
- if (strcmp(cur, "all") == 0) {
- set_allow_other_tags();
- new_combination();
- continue;
- }
-
- // Check for '*' suffix
- char* asterisk_pos = strchr(cur, '*');
- if (asterisk_pos != NULL && asterisk_pos[1] == '\0') {
- set_allow_other_tags();
- *asterisk_pos = '\0';
- }
-
- // Parse the tag expression (t1+t2+...+tn)
- char* plus_pos;
- char* cur_tag = cur;
- do {
- plus_pos = strchr(cur_tag, '+');
- if (plus_pos != NULL) {
- *plus_pos = '\0';
- }
- LogTagType tag = LogTag::from_string(cur_tag);
- if (tag == LogTag::__NO_TAG) {
- if (errstream != NULL) {
- errstream->print_cr("Invalid tag '%s' in what-expression.", cur_tag);
- }
- success = false;
- break;
- }
- if (_ntags == LogTag::MaxTags) {
- if (errstream != NULL) {
- errstream->print_cr("Tag combination exceeds the maximum of " SIZE_FORMAT " tags.",
- LogTag::MaxTags);
- }
- success = false;
- break;
- }
- if (!add_tag(tag)) {
- if (errstream != NULL) {
- errstream->print_cr("Tag combination have duplicate tag '%s' in what-expression.",
- cur_tag);
- }
- success = false;
- break;
- }
- cur_tag = plus_pos + 1;
- } while (plus_pos != NULL);
-
- new_combination();
- }
-
- os::free(copy);
- return success;
-}
-
-LogLevelType LogTagLevelExpression::level_for(const LogTagSet& ts) const {
- // Return NotMentioned if the given tagset isn't covered by this expression.
- LogLevelType level = LogLevel::NotMentioned;
- for (size_t combination = 0; combination < _ncombinations; combination++) {
- if (matches_tagset(_tags[combination], _allow_other_tags[combination], ts)) {
- level = _level[combination];
- }
- }
- return level;
-}
-
--- a/src/hotspot/share/logging/logTagLevelExpression.hpp Thu Mar 01 01:30:10 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-#ifndef SHARE_VM_LOGGING_LOGTAGLEVELEXPRESSION_HPP
-#define SHARE_VM_LOGGING_LOGTAGLEVELEXPRESSION_HPP
-
-#include "logging/logConfiguration.hpp"
-#include "logging/logLevel.hpp"
-#include "logging/logTag.hpp"
-#include "memory/allocation.hpp"
-#include "utilities/debug.hpp"
-#include "utilities/globalDefinitions.hpp"
-
-class LogTagSet;
-
-// Class used to temporary encode a 'what'-expression during log configuration.
-// Consists of a combination of tags and levels, e.g. "tag1+tag2=level1,tag3*=level2".
-class LogTagLevelExpression : public StackObj {
- public:
- static const size_t MaxCombinations = 256;
-
- private:
- friend void LogConfiguration::configure_stdout(LogLevelType, int, ...);
-
- static const char* DefaultExpressionString;
-
- size_t _ntags, _ncombinations;
- LogTagType _tags[MaxCombinations][LogTag::MaxTags];
- LogLevelType _level[MaxCombinations];
- bool _allow_other_tags[MaxCombinations];
-
- void new_combination() {
- // Make sure either all tags are set or the last tag is __NO_TAG
- if (_ntags < LogTag::MaxTags) {
- _tags[_ncombinations][_ntags] = LogTag::__NO_TAG;
- }
-
- _ncombinations++;
- _ntags = 0;
- }
-
- bool add_tag(LogTagType tag) {
- assert(_ntags < LogTag::MaxTags, "Can't have more tags than MaxTags!");
- for (size_t i = 0; i < _ntags; i++) {
- if (_tags[_ncombinations][i] == tag) {
- return false;
- }
- }
- _tags[_ncombinations][_ntags++] = tag;
- return true;
- }
-
- void set_level(LogLevelType level) {
- _level[_ncombinations] = level;
- }
-
- void set_allow_other_tags() {
- _allow_other_tags[_ncombinations] = true;
- }
-
- public:
- LogTagLevelExpression() : _ntags(0), _ncombinations(0) {
- for (size_t combination = 0; combination < MaxCombinations; combination++) {
- _level[combination] = LogLevel::Invalid;
- _allow_other_tags[combination] = false;
- _tags[combination][0] = LogTag::__NO_TAG;
- }
- }
-
- bool parse(const char* str, outputStream* errstream = NULL);
- LogLevelType level_for(const LogTagSet& ts) const;
-
- // Verify the tagsets/selections mentioned in this expression.
- // Returns false if some invalid tagset was found. If given an outputstream,
- // this function will list all the invalid selections on the stream.
- bool verify_tagsets(outputStream* out = NULL) const;
-};
-
-#endif // SHARE_VM_LOGGING_LOGTAGLEVELEXPRESSION_HPP
--- a/src/hotspot/share/memory/metaspace.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/memory/metaspace.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -3952,8 +3952,7 @@
// Only start a GC if the bootstrapping has completed.
// Try to clean out some memory and retry.
- result = Universe::heap()->collector_policy()->satisfy_failed_metadata_allocation(
- loader_data, word_size, mdtype);
+ result = Universe::heap()->satisfy_failed_metadata_allocation(loader_data, word_size, mdtype);
}
}
--- a/src/hotspot/share/memory/metaspace.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/memory/metaspace.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -87,7 +87,7 @@
friend class MetaspaceGC;
friend class MetaspaceAux;
friend class MetaspaceShared;
- friend class CollectorPolicy;
+ friend class CollectedHeap;
friend class PrintCLDMetaspaceInfoClosure;
public:
--- a/src/hotspot/share/memory/oopFactory.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/memory/oopFactory.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,7 @@
#include "oops/instanceOop.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
typeArrayOop oopFactory::new_charArray(const char* utf8_str, TRAPS) {
--- a/src/hotspot/share/memory/universe.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/memory/universe.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -134,7 +134,6 @@
oop Universe::_arithmetic_exception_instance = NULL;
oop Universe::_virtual_machine_error_instance = NULL;
oop Universe::_vm_exception = NULL;
-oop Universe::_allocation_context_notification_obj = NULL;
oop Universe::_reference_pending_list = NULL;
Array<int>* Universe::_the_empty_int_array = NULL;
@@ -213,7 +212,6 @@
f->do_oop((oop*)&_main_thread_group);
f->do_oop((oop*)&_system_thread_group);
f->do_oop((oop*)&_vm_exception);
- f->do_oop((oop*)&_allocation_context_notification_obj);
f->do_oop((oop*)&_reference_pending_list);
debug_only(f->do_oop((oop*)&_fullgc_alot_dummy_array);)
}
--- a/src/hotspot/share/memory/universe.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/memory/universe.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -181,8 +181,6 @@
// the vm thread.
static oop _vm_exception;
- static oop _allocation_context_notification_obj;
-
// References waiting to be transferred to the ReferenceHandler
static oop _reference_pending_list;
@@ -334,9 +332,6 @@
static oop virtual_machine_error_instance() { return _virtual_machine_error_instance; }
static oop vm_exception() { return _vm_exception; }
- static inline oop allocation_context_notification_obj();
- static inline void set_allocation_context_notification_obj(oop obj);
-
// Reference pending list manipulation. Access is protected by
// Heap_lock. The getter, setter and predicate require the caller
// owns the lock. Swap is used by parallel non-concurrent reference
--- a/src/hotspot/share/memory/universe.inline.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/memory/universe.inline.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -41,12 +41,4 @@
return type == T_DOUBLE || type == T_LONG;
}
-inline oop Universe::allocation_context_notification_obj() {
- return _allocation_context_notification_obj;
-}
-
-inline void Universe::set_allocation_context_notification_obj(oop obj) {
- _allocation_context_notification_obj = obj;
-}
-
#endif // SHARE_VM_MEMORY_UNIVERSE_INLINE_HPP
--- a/src/hotspot/share/oops/access.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/oops/access.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -55,6 +55,7 @@
// * atomic_xchg_at: Atomically swap a new value at an internal pointer address if previous value matched the compared value.
// * arraycopy: Copy data from one heap array to another heap array.
// * clone: Clone the contents of an object to a newly allocated object.
+// * resolve: Resolve a stable to-space invariant oop that is guaranteed not to relocate its payload until a subsequent thread transition.
typedef uint64_t DecoratorSet;
@@ -69,12 +70,15 @@
// == Internal build-time Decorators ==
// * INTERNAL_BT_BARRIER_ON_PRIMITIVES: This is set in the barrierSetConfig.hpp file.
+// * INTERNAL_BT_TO_SPACE_INVARIANT: This is set in the barrierSetConfig.hpp file iff
+// no GC is bundled in the build that is to-space invariant.
const DecoratorSet INTERNAL_BT_BARRIER_ON_PRIMITIVES = UCONST64(1) << 3;
+const DecoratorSet INTERNAL_BT_TO_SPACE_INVARIANT = UCONST64(1) << 4;
// == Internal run-time Decorators ==
// * INTERNAL_RT_USE_COMPRESSED_OOPS: This decorator will be set in runtime resolved
// access backends iff UseCompressedOops is true.
-const DecoratorSet INTERNAL_RT_USE_COMPRESSED_OOPS = UCONST64(1) << 4;
+const DecoratorSet INTERNAL_RT_USE_COMPRESSED_OOPS = UCONST64(1) << 5;
const DecoratorSet INTERNAL_DECORATOR_MASK = INTERNAL_CONVERT_COMPRESSED_OOP | INTERNAL_VALUE_IS_OOP |
INTERNAL_BT_BARRIER_ON_PRIMITIVES | INTERNAL_RT_USE_COMPRESSED_OOPS;
@@ -138,12 +142,12 @@
// - Guarantees from MO_RELAXED loads and MO_RELAXED stores hold.
// * MO_SEQ_CST: Sequentially consistent xchg.
// - Guarantees from MO_SEQ_CST loads and MO_SEQ_CST stores hold.
-const DecoratorSet MO_UNORDERED = UCONST64(1) << 5;
-const DecoratorSet MO_VOLATILE = UCONST64(1) << 6;
-const DecoratorSet MO_RELAXED = UCONST64(1) << 7;
-const DecoratorSet MO_ACQUIRE = UCONST64(1) << 8;
-const DecoratorSet MO_RELEASE = UCONST64(1) << 9;
-const DecoratorSet MO_SEQ_CST = UCONST64(1) << 10;
+const DecoratorSet MO_UNORDERED = UCONST64(1) << 6;
+const DecoratorSet MO_VOLATILE = UCONST64(1) << 7;
+const DecoratorSet MO_RELAXED = UCONST64(1) << 8;
+const DecoratorSet MO_ACQUIRE = UCONST64(1) << 9;
+const DecoratorSet MO_RELEASE = UCONST64(1) << 10;
+const DecoratorSet MO_SEQ_CST = UCONST64(1) << 11;
const DecoratorSet MO_DECORATOR_MASK = MO_UNORDERED | MO_VOLATILE | MO_RELAXED |
MO_ACQUIRE | MO_RELEASE | MO_SEQ_CST;
@@ -166,10 +170,10 @@
// responsibility of performing the access and what barriers to be performed to the GC. This is the default.
// Note that primitive accesses will only be resolved on the barrier set if the appropriate build-time
// decorator for enabling primitive barriers is enabled for the build.
-const DecoratorSet AS_RAW = UCONST64(1) << 11;
-const DecoratorSet AS_DEST_NOT_INITIALIZED = UCONST64(1) << 12;
-const DecoratorSet AS_NO_KEEPALIVE = UCONST64(1) << 13;
-const DecoratorSet AS_NORMAL = UCONST64(1) << 14;
+const DecoratorSet AS_RAW = UCONST64(1) << 12;
+const DecoratorSet AS_DEST_NOT_INITIALIZED = UCONST64(1) << 13;
+const DecoratorSet AS_NO_KEEPALIVE = UCONST64(1) << 14;
+const DecoratorSet AS_NORMAL = UCONST64(1) << 15;
const DecoratorSet AS_DECORATOR_MASK = AS_RAW | AS_DEST_NOT_INITIALIZED |
AS_NO_KEEPALIVE | AS_NORMAL;
@@ -182,10 +186,10 @@
// * ON_UNKNOWN_OOP_REF: The memory access is performed on a reference of unknown strength.
// This could for example come from the unsafe API.
// * Default (no explicit reference strength specified): ON_STRONG_OOP_REF
-const DecoratorSet ON_STRONG_OOP_REF = UCONST64(1) << 15;
-const DecoratorSet ON_WEAK_OOP_REF = UCONST64(1) << 16;
-const DecoratorSet ON_PHANTOM_OOP_REF = UCONST64(1) << 17;
-const DecoratorSet ON_UNKNOWN_OOP_REF = UCONST64(1) << 18;
+const DecoratorSet ON_STRONG_OOP_REF = UCONST64(1) << 16;
+const DecoratorSet ON_WEAK_OOP_REF = UCONST64(1) << 17;
+const DecoratorSet ON_PHANTOM_OOP_REF = UCONST64(1) << 18;
+const DecoratorSet ON_UNKNOWN_OOP_REF = UCONST64(1) << 19;
const DecoratorSet ON_DECORATOR_MASK = ON_STRONG_OOP_REF | ON_WEAK_OOP_REF |
ON_PHANTOM_OOP_REF | ON_UNKNOWN_OOP_REF;
@@ -200,18 +204,18 @@
// * IN_CONCURRENT_ROOT: The access is performed in an off-heap data structure pointing into the Java heap,
// but is notably not scanned during safepoints. This is sometimes a special case for some GCs and
// implies that it is also an IN_ROOT.
-const DecoratorSet IN_HEAP = UCONST64(1) << 19;
-const DecoratorSet IN_HEAP_ARRAY = UCONST64(1) << 20;
-const DecoratorSet IN_ROOT = UCONST64(1) << 21;
-const DecoratorSet IN_CONCURRENT_ROOT = UCONST64(1) << 22;
-const DecoratorSet IN_ARCHIVE_ROOT = UCONST64(1) << 23;
+const DecoratorSet IN_HEAP = UCONST64(1) << 20;
+const DecoratorSet IN_HEAP_ARRAY = UCONST64(1) << 21;
+const DecoratorSet IN_ROOT = UCONST64(1) << 22;
+const DecoratorSet IN_CONCURRENT_ROOT = UCONST64(1) << 23;
+const DecoratorSet IN_ARCHIVE_ROOT = UCONST64(1) << 24;
const DecoratorSet IN_DECORATOR_MASK = IN_HEAP | IN_HEAP_ARRAY |
IN_ROOT | IN_CONCURRENT_ROOT |
IN_ARCHIVE_ROOT;
// == Value Decorators ==
// * OOP_NOT_NULL: This property can make certain barriers faster such as compressing oops.
-const DecoratorSet OOP_NOT_NULL = UCONST64(1) << 24;
+const DecoratorSet OOP_NOT_NULL = UCONST64(1) << 25;
const DecoratorSet OOP_DECORATOR_MASK = OOP_NOT_NULL;
// == Arraycopy Decorators ==
@@ -224,11 +228,11 @@
// * ARRAYCOPY_ARRAYOF: The copy is in the arrayof form.
// * ARRAYCOPY_ATOMIC: The accesses have to be atomic over the size of its elements.
// * ARRAYCOPY_ALIGNED: The accesses have to be aligned on a HeapWord.
-const DecoratorSet ARRAYCOPY_CHECKCAST = UCONST64(1) << 25;
-const DecoratorSet ARRAYCOPY_DISJOINT = UCONST64(1) << 26;
-const DecoratorSet ARRAYCOPY_ARRAYOF = UCONST64(1) << 27;
-const DecoratorSet ARRAYCOPY_ATOMIC = UCONST64(1) << 28;
-const DecoratorSet ARRAYCOPY_ALIGNED = UCONST64(1) << 29;
+const DecoratorSet ARRAYCOPY_CHECKCAST = UCONST64(1) << 26;
+const DecoratorSet ARRAYCOPY_DISJOINT = UCONST64(1) << 27;
+const DecoratorSet ARRAYCOPY_ARRAYOF = UCONST64(1) << 28;
+const DecoratorSet ARRAYCOPY_ATOMIC = UCONST64(1) << 29;
+const DecoratorSet ARRAYCOPY_ALIGNED = UCONST64(1) << 30;
const DecoratorSet ARRAYCOPY_DECORATOR_MASK = ARRAYCOPY_CHECKCAST | ARRAYCOPY_DISJOINT |
ARRAYCOPY_DISJOINT | ARRAYCOPY_ARRAYOF |
ARRAYCOPY_ATOMIC | ARRAYCOPY_ALIGNED;
@@ -297,6 +301,9 @@
template <DecoratorSet decorators>
void clone(oop src, oop dst, size_t size);
+ template <DecoratorSet decorators>
+ oop resolve(oop src);
+
// Infer the type that should be returned from a load.
template <typename P, DecoratorSet decorators>
class LoadProxy: public StackObj {
@@ -500,6 +507,11 @@
OopType new_oop_value = new_value;
return AccessInternal::atomic_xchg<decorators | INTERNAL_VALUE_IS_OOP>(new_oop_value, addr);
}
+
+ static oop resolve(oop obj) {
+ verify_decorators<INTERNAL_EMPTY>();
+ return AccessInternal::resolve<decorators>(obj);
+ }
};
// Helper for performing raw accesses (knows only of memory ordering
--- a/src/hotspot/share/oops/access.inline.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/oops/access.inline.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -206,6 +206,13 @@
}
};
+ template <class GCBarrierType, DecoratorSet decorators>
+ struct PostRuntimeDispatch<GCBarrierType, BARRIER_RESOLVE, decorators>: public AllStatic {
+ static oop access_barrier(oop obj) {
+ return GCBarrierType::resolve(obj);
+ }
+ };
+
// Resolving accessors with barriers from the barrier set happens in two steps.
// 1. Expand paths with runtime-decorators, e.g. is UseCompressedOops on or off.
// 2. Expand paths for each BarrierSet available in the system.
@@ -443,6 +450,22 @@
}
};
+ template <DecoratorSet decorators, typename T>
+ struct RuntimeDispatch<decorators, T, BARRIER_RESOLVE>: AllStatic {
+ typedef typename AccessFunction<decorators, T, BARRIER_RESOLVE>::type func_t;
+ static func_t _resolve_func;
+
+ static oop resolve_init(oop obj) {
+ func_t function = BarrierResolver<decorators, func_t, BARRIER_RESOLVE>::resolve_barrier();
+ _resolve_func = function;
+ return function(obj);
+ }
+
+ static inline oop resolve(oop obj) {
+ return _resolve_func(obj);
+ }
+ };
+
// Initialize the function pointers to point to the resolving function.
template <DecoratorSet decorators, typename T>
typename AccessFunction<decorators, T, BARRIER_STORE>::type
@@ -484,6 +507,10 @@
typename AccessFunction<decorators, T, BARRIER_CLONE>::type
RuntimeDispatch<decorators, T, BARRIER_CLONE>::_clone_func = &clone_init;
+ template <DecoratorSet decorators, typename T>
+ typename AccessFunction<decorators, T, BARRIER_RESOLVE>::type
+ RuntimeDispatch<decorators, T, BARRIER_RESOLVE>::_resolve_func = &resolve_init;
+
// Step 3: Pre-runtime dispatching.
// The PreRuntimeDispatch class is responsible for filtering the barrier strength
// decorators. That is, for AS_RAW, it hardwires the accesses without a runtime
@@ -766,6 +793,21 @@
clone(oop src, oop dst, size_t size) {
RuntimeDispatch<decorators, oop, BARRIER_CLONE>::clone(src, dst, size);
}
+
+ template <DecoratorSet decorators>
+ inline static typename EnableIf<
+ HasDecorator<decorators, INTERNAL_BT_TO_SPACE_INVARIANT>::value, oop>::type
+ resolve(oop obj) {
+ typedef RawAccessBarrier<decorators & RAW_DECORATOR_MASK> Raw;
+ return Raw::resolve(obj);
+ }
+
+ template <DecoratorSet decorators>
+ inline static typename EnableIf<
+ !HasDecorator<decorators, INTERNAL_BT_TO_SPACE_INVARIANT>::value, oop>::type
+ resolve(oop obj) {
+ return RuntimeDispatch<decorators, oop, BARRIER_RESOLVE>::resolve(obj);
+ }
};
// This class adds implied decorators that follow according to decorator rules.
@@ -1051,6 +1093,12 @@
const DecoratorSet expanded_decorators = DecoratorFixup<decorators>::value;
PreRuntimeDispatch::clone<expanded_decorators>(src, dst, size);
}
+
+ template <DecoratorSet decorators>
+ inline oop resolve(oop obj) {
+ const DecoratorSet expanded_decorators = DecoratorFixup<decorators>::value;
+ return PreRuntimeDispatch::resolve<expanded_decorators>(obj);
+ }
}
template <DecoratorSet decorators>
--- a/src/hotspot/share/oops/accessBackend.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/oops/accessBackend.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -52,7 +52,8 @@
BARRIER_ATOMIC_XCHG,
BARRIER_ATOMIC_XCHG_AT,
BARRIER_ARRAYCOPY,
- BARRIER_CLONE
+ BARRIER_CLONE,
+ BARRIER_RESOLVE
};
template <DecoratorSet decorators, typename T>
@@ -100,6 +101,7 @@
typedef bool (*arraycopy_func_t)(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length);
typedef void (*clone_func_t)(oop src, oop dst, size_t size);
+ typedef oop (*resolve_func_t)(oop obj);
};
template <DecoratorSet decorators, typename T, BarrierType barrier> struct AccessFunction {};
@@ -119,6 +121,7 @@
ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_ATOMIC_XCHG_AT, atomic_xchg_at_func_t);
ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_ARRAYCOPY, arraycopy_func_t);
ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_CLONE, clone_func_t);
+ ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_RESOLVE, resolve_func_t);
#undef ACCESS_GENERATE_ACCESS_FUNCTION
template <DecoratorSet decorators, typename T, BarrierType barrier_type>
@@ -379,6 +382,8 @@
static bool oop_arraycopy(arrayOop src_obj, arrayOop dst_obj, HeapWord* src, HeapWord* dst, size_t length);
static void clone(oop src, oop dst, size_t size);
+
+ static oop resolve(oop obj) { return obj; }
};
#endif // SHARE_VM_RUNTIME_ACCESSBACKEND_HPP
--- a/src/hotspot/share/oops/annotations.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/oops/annotations.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -31,6 +31,7 @@
#include "memory/oopFactory.hpp"
#include "oops/annotations.hpp"
#include "oops/instanceKlass.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "utilities/ostream.hpp"
// Allocate annotations in metadata area
--- a/src/hotspot/share/oops/arrayOop.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/oops/arrayOop.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -76,10 +76,10 @@
return header_size(type) * HeapWordSize;
}
- // Returns the address of the first element.
- void* base(BasicType type) const {
- return (void*) (((intptr_t) this) + base_offset_in_bytes(type));
- }
+ // Returns the address of the first element. The elements in the array will not
+ // relocate from this address until a subsequent thread transition.
+ inline void* base(BasicType type) const;
+ inline void* base_raw(BasicType type) const; // GC barrier invariant
// Tells whether index is within bounds.
bool is_within_bounds(int index) const { return 0 <= index && index < length(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/oops/arrayOop.inline.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_OOPS_ARRAYOOP_INLINE_HPP
+#define SHARE_OOPS_ARRAYOOP_INLINE_HPP
+
+#include "oops/access.inline.hpp"
+#include "oops/arrayOop.hpp"
+
+void* arrayOopDesc::base(BasicType type) const {
+ oop resolved_obj = Access<>::resolve(as_oop());
+ return arrayOop(resolved_obj)->base_raw(type);
+}
+
+void* arrayOopDesc::base_raw(BasicType type) const {
+ return reinterpret_cast<void*>(cast_from_oop<intptr_t>(as_oop()) + base_offset_in_bytes(type));
+}
+
+#endif // SHARE_OOPS_ARRAYOOP_INLINE_HPP
--- a/src/hotspot/share/oops/constantPool.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/oops/constantPool.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -43,6 +43,7 @@
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "runtime/fieldType.hpp"
#include "runtime/init.hpp"
#include "runtime/javaCalls.hpp"
@@ -546,12 +547,6 @@
}
}
-
-Klass* ConstantPool::klass_ref_at_if_loaded(const constantPoolHandle& this_cp, int which) {
- return klass_at_if_loaded(this_cp, this_cp->klass_ref_index_at(which));
-}
-
-
Method* ConstantPool::method_at_if_loaded(const constantPoolHandle& cpool,
int which) {
if (cpool->cache() == NULL) return NULL; // nothing to load yet
--- a/src/hotspot/share/oops/constantPool.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/oops/constantPool.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -147,7 +147,7 @@
assert(is_within_bounds(which), "index out of bounds");
assert(!tag_at(which).is_unresolved_klass() && !tag_at(which).is_unresolved_klass_in_error(), "Corrupted constant pool");
// Uses volatile because the klass slot changes without a lock.
- intptr_t adr = OrderAccess::load_acquire(obj_at_addr_raw(which));
+ intptr_t adr = OrderAccess::load_acquire(obj_at_addr(which));
assert(adr != 0 || which == 0, "cp entry for klass should not be zero");
return CPSlot(adr);
}
@@ -157,7 +157,7 @@
assert(s.value() != 0, "Caught something");
*(intptr_t*)&base()[which] = s.value();
}
- intptr_t* obj_at_addr_raw(int which) const {
+ intptr_t* obj_at_addr(int which) const {
assert(is_within_bounds(which), "index out of bounds");
return (intptr_t*) &base()[which];
}
@@ -824,7 +824,6 @@
static bool has_method_type_at_if_loaded (const constantPoolHandle& this_cp, int which);
static oop method_type_at_if_loaded (const constantPoolHandle& this_cp, int which);
static Klass* klass_at_if_loaded (const constantPoolHandle& this_cp, int which);
- static Klass* klass_ref_at_if_loaded (const constantPoolHandle& this_cp, int which);
// Routines currently used for annotations (only called by jvm.cpp) but which might be used in the
// future by other Java code. These take constant pool indices rather than
--- a/src/hotspot/share/oops/instanceKlass.inline.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/oops/instanceKlass.inline.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -56,7 +56,7 @@
template <bool nv, typename T, class OopClosureType>
ALWAYSINLINE void InstanceKlass::oop_oop_iterate_oop_map(OopMapBlock* map, oop obj, OopClosureType* closure) {
- T* p = (T*)obj->obj_field_addr<T>(map->offset());
+ T* p = (T*)obj->obj_field_addr_raw<T>(map->offset());
T* const end = p + map->count();
for (; p < end; ++p) {
@@ -67,7 +67,7 @@
#if INCLUDE_ALL_GCS
template <bool nv, typename T, class OopClosureType>
ALWAYSINLINE void InstanceKlass::oop_oop_iterate_oop_map_reverse(OopMapBlock* map, oop obj, OopClosureType* closure) {
- T* const start = (T*)obj->obj_field_addr<T>(map->offset());
+ T* const start = (T*)obj->obj_field_addr_raw<T>(map->offset());
T* p = start + map->count();
while (start < p) {
@@ -79,7 +79,7 @@
template <bool nv, typename T, class OopClosureType>
ALWAYSINLINE void InstanceKlass::oop_oop_iterate_oop_map_bounded(OopMapBlock* map, oop obj, OopClosureType* closure, MemRegion mr) {
- T* p = (T*)obj->obj_field_addr<T>(map->offset());
+ T* p = (T*)obj->obj_field_addr_raw<T>(map->offset());
T* end = p + map->count();
T* const l = (T*)mr.start();
--- a/src/hotspot/share/oops/instanceRefKlass.inline.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/oops/instanceRefKlass.inline.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, 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
@@ -37,7 +37,7 @@
template <bool nv, typename T, class OopClosureType, class Contains>
void InstanceRefKlass::do_referent(oop obj, OopClosureType* closure, Contains& contains) {
- T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
+ T* referent_addr = (T*)java_lang_ref_Reference::referent_addr_raw(obj);
if (contains(referent_addr)) {
Devirtualizer<nv>::do_oop(closure, referent_addr);
}
@@ -45,7 +45,7 @@
template <bool nv, typename T, class OopClosureType, class Contains>
void InstanceRefKlass::do_next(oop obj, OopClosureType* closure, Contains& contains) {
- T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
+ T* next_addr = (T*)java_lang_ref_Reference::next_addr_raw(obj);
if (contains(next_addr)) {
Devirtualizer<nv>::do_oop(closure, next_addr);
}
@@ -53,7 +53,7 @@
template <bool nv, typename T, class OopClosureType, class Contains>
void InstanceRefKlass::do_discovered(oop obj, OopClosureType* closure, Contains& contains) {
- T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
+ T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr_raw(obj);
if (contains(discovered_addr)) {
Devirtualizer<nv>::do_oop(closure, discovered_addr);
}
@@ -63,7 +63,7 @@
bool InstanceRefKlass::try_discover(oop obj, ReferenceType type, OopClosureType* closure) {
ReferenceProcessor* rp = closure->ref_processor();
if (rp != NULL) {
- T referent_oop = oopDesc::load_heap_oop((T*)java_lang_ref_Reference::referent_addr(obj));
+ T referent_oop = oopDesc::load_heap_oop((T*)java_lang_ref_Reference::referent_addr_raw(obj));
if (!oopDesc::is_null(referent_oop)) {
oop referent = oopDesc::decode_heap_oop_not_null(referent_oop);
if (!referent->is_gc_marked()) {
@@ -86,7 +86,7 @@
do_referent<nv, T>(obj, closure, contains);
// Treat discovered as normal oop, if ref is not "active" (next non-NULL).
- T next_oop = oopDesc::load_heap_oop((T*)java_lang_ref_Reference::next_addr(obj));
+ T next_oop = oopDesc::load_heap_oop((T*)java_lang_ref_Reference::next_addr_raw(obj));
if (!oopDesc::is_null(next_oop)) {
do_discovered<nv, T>(obj, closure, contains);
}
@@ -189,9 +189,9 @@
#ifdef ASSERT
template <typename T>
void InstanceRefKlass::trace_reference_gc(const char *s, oop obj) {
- T* referent_addr = (T*) java_lang_ref_Reference::referent_addr(obj);
- T* next_addr = (T*) java_lang_ref_Reference::next_addr(obj);
- T* discovered_addr = (T*) java_lang_ref_Reference::discovered_addr(obj);
+ T* referent_addr = (T*) java_lang_ref_Reference::referent_addr_raw(obj);
+ T* next_addr = (T*) java_lang_ref_Reference::next_addr_raw(obj);
+ T* discovered_addr = (T*) java_lang_ref_Reference::discovered_addr_raw(obj);
log_develop_trace(gc, ref)("InstanceRefKlass %s for obj " PTR_FORMAT, s, p2i(obj));
log_develop_trace(gc, ref)(" referent_addr/* " PTR_FORMAT " / " PTR_FORMAT,
--- a/src/hotspot/share/oops/klass.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/oops/klass.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -577,21 +577,15 @@
if (is_instance_klass()) {
const InstanceKlass* ik = static_cast<const InstanceKlass*>(this);
if (ik->is_anonymous()) {
- intptr_t hash = 0;
- if (ik->java_mirror() != NULL) {
- // java_mirror might not be created yet, return 0 as hash.
- hash = ik->java_mirror()->identity_hash();
- }
- char hash_buf[40];
- sprintf(hash_buf, "/" UINTX_FORMAT, (uintx)hash);
- size_t hash_len = strlen(hash_buf);
-
- size_t result_len = name()->utf8_length();
- char* result = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1);
- name()->as_klass_external_name(result, (int) result_len + 1);
- assert(strlen(result) == result_len, "");
- strcpy(result + result_len, hash_buf);
- assert(strlen(result) == result_len + hash_len, "");
+ char addr_buf[20];
+ jio_snprintf(addr_buf, 20, "/" INTPTR_FORMAT, p2i(ik));
+ size_t addr_len = strlen(addr_buf);
+ size_t name_len = name()->utf8_length();
+ char* result = NEW_RESOURCE_ARRAY(char, name_len + addr_len + 1);
+ name()->as_klass_external_name(result, (int) name_len + 1);
+ assert(strlen(result) == name_len, "");
+ strcpy(result + name_len, addr_buf);
+ assert(strlen(result) == name_len + addr_len, "");
return result;
}
}
@@ -737,4 +731,82 @@
return true;
}
-#endif
+#endif // PRODUCT
+
+// The caller of class_loader_and_module_name() (or one of its callers)
+// must use a ResourceMark in order to correctly free the result.
+const char* Klass::class_loader_and_module_name() const {
+ const char* delim = "/";
+ size_t delim_len = strlen(delim);
+
+ const char* fqn = external_name();
+ // Length of message to return; always include FQN
+ size_t msglen = strlen(fqn) + 1;
+
+ bool has_cl_name = false;
+ bool has_mod_name = false;
+ bool has_version = false;
+
+ // Use class loader name, if exists and not builtin
+ const char* class_loader_name = "";
+ ClassLoaderData* cld = class_loader_data();
+ assert(cld != NULL, "class_loader_data should not be NULL");
+ if (!cld->is_builtin_class_loader_data()) {
+ // If not builtin, look for name
+ oop loader = class_loader();
+ if (loader != NULL) {
+ oop class_loader_name_oop = java_lang_ClassLoader::name(loader);
+ if (class_loader_name_oop != NULL) {
+ class_loader_name = java_lang_String::as_utf8_string(class_loader_name_oop);
+ if (class_loader_name != NULL && class_loader_name[0] != '\0') {
+ has_cl_name = true;
+ msglen += strlen(class_loader_name) + delim_len;
+ }
+ }
+ }
+ }
+
+ const char* module_name = "";
+ const char* version = "";
+ const Klass* bottom_klass = is_objArray_klass() ?
+ ObjArrayKlass::cast(this)->bottom_klass() : this;
+ if (bottom_klass->is_instance_klass()) {
+ ModuleEntry* module = InstanceKlass::cast(bottom_klass)->module();
+ // Use module name, if exists
+ if (module->is_named()) {
+ has_mod_name = true;
+ module_name = module->name()->as_C_string();
+ msglen += strlen(module_name);
+ // Use version if exists and is not a jdk module
+ if (module->is_non_jdk_module() && module->version() != NULL) {
+ has_version = true;
+ version = module->version()->as_C_string();
+ msglen += strlen("@") + strlen(version);
+ }
+ }
+ } else {
+ // klass is an array of primitives, so its module is java.base
+ module_name = JAVA_BASE_NAME;
+ }
+
+ if (has_cl_name || has_mod_name) {
+ msglen += delim_len;
+ }
+
+ char* message = NEW_RESOURCE_ARRAY_RETURN_NULL(char, msglen);
+
+ // Just return the FQN if error in allocating string
+ if (message == NULL) {
+ return fqn;
+ }
+
+ jio_snprintf(message, msglen, "%s%s%s%s%s%s%s",
+ class_loader_name,
+ (has_cl_name) ? delim : "",
+ (has_mod_name) ? module_name : "",
+ (has_version) ? "@" : "",
+ (has_version) ? version : "",
+ (has_cl_name || has_mod_name) ? delim : "",
+ fqn);
+ return message;
+}
--- a/src/hotspot/share/oops/klass.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/oops/klass.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -506,6 +506,8 @@
// and the package separators as '/'.
virtual const char* signature_name() const;
+ const char* class_loader_and_module_name() const;
+
// type testing operations
#ifdef ASSERT
protected:
--- a/src/hotspot/share/oops/objArrayKlass.inline.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/oops/objArrayKlass.inline.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
#include "memory/memRegion.hpp"
#include "memory/iterator.inline.hpp"
+#include "oops/arrayOop.inline.hpp"
#include "oops/arrayKlass.hpp"
#include "oops/klass.hpp"
#include "oops/objArrayKlass.hpp"
@@ -110,7 +111,7 @@
template <bool nv, typename T, class OopClosureType>
void ObjArrayKlass::oop_oop_iterate_range_specialized(objArrayOop a, OopClosureType* closure, int start, int end) {
- T* low = start == 0 ? cast_from_oop<T*>(a) : a->obj_at_addr<T>(start);
+ T* low = start == 0 ? cast_from_oop<T*>(a) : a->obj_at_addr_raw<T>(start);
T* high = (T*)a->base() + end;
oop_oop_iterate_elements_specialized_bounded<nv, T>(a, closure, low, high);
--- a/src/hotspot/share/oops/objArrayOop.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/oops/objArrayOop.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -26,7 +26,7 @@
#include "gc/shared/specialized_oop_closures.hpp"
#include "oops/access.inline.hpp"
#include "oops/objArrayKlass.hpp"
-#include "oops/objArrayOop.hpp"
+#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
oop objArrayOopDesc::atomic_compare_exchange_oop(int index, oop exchange_value,
--- a/src/hotspot/share/oops/objArrayOop.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/oops/objArrayOop.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,10 +41,8 @@
friend class CSetMarkOopClosure;
friend class G1ParScanPartialArrayClosure;
- template <class T> T* obj_at_addr(int index) const {
- assert(is_within_bounds(index), "index out of bounds");
- return &((T*)base())[index];
- }
+ template <class T> T* obj_at_addr(int index) const;
+ template <class T> T* obj_at_addr_raw(int index) const;
template <class T>
static ptrdiff_t obj_at_offset(int index) {
@@ -84,7 +82,8 @@
}
// base is the address following the header.
- HeapWord* base() const { return (HeapWord*) arrayOopDesc::base(T_OBJECT); }
+ HeapWord* base() const;
+ HeapWord* base_raw() const;
// Accessing
oop obj_at(int index) const;
--- a/src/hotspot/share/oops/objArrayOop.inline.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/oops/objArrayOop.inline.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -26,10 +26,24 @@
#define SHARE_VM_OOPS_OBJARRAYOOP_INLINE_HPP
#include "oops/access.inline.hpp"
+#include "oops/arrayOop.inline.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/globals.hpp"
+inline HeapWord* objArrayOopDesc::base() const { return (HeapWord*) arrayOopDesc::base(T_OBJECT); }
+inline HeapWord* objArrayOopDesc::base_raw() const { return (HeapWord*) arrayOopDesc::base_raw(T_OBJECT); }
+
+template <class T> T* objArrayOopDesc::obj_at_addr(int index) const {
+ assert(is_within_bounds(index), "index out of bounds");
+ return &((T*)base())[index];
+}
+
+template <class T> T* objArrayOopDesc::obj_at_addr_raw(int index) const {
+ assert(is_within_bounds(index), "index out of bounds");
+ return &((T*)base_raw())[index];
+}
+
inline oop objArrayOopDesc::obj_at(int index) const {
ptrdiff_t offset = UseCompressedOops ? obj_at_offset<narrowOop>(index) : obj_at_offset<oop>(index);
return HeapAccess<IN_HEAP_ARRAY>::oop_load_at(as_oop(), offset);
--- a/src/hotspot/share/oops/oop.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/oops/oop.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -119,26 +119,13 @@
protected:
inline oop as_oop() const { return const_cast<oopDesc*>(this); }
- private:
+ public:
// field addresses in oop
- inline void* field_base(int offset) const;
+ inline void* field_addr(int offset) const;
+ inline void* field_addr_raw(int offset) const;
- inline jbyte* byte_field_addr(int offset) const;
- inline jchar* char_field_addr(int offset) const;
- inline jboolean* bool_field_addr(int offset) const;
- inline jint* int_field_addr(int offset) const;
- inline jshort* short_field_addr(int offset) const;
- inline jlong* long_field_addr(int offset) const;
- inline jfloat* float_field_addr(int offset) const;
- inline jdouble* double_field_addr(int offset) const;
- inline Metadata** metadata_field_addr(int offset) const;
-
- public:
// Need this as public for garbage collection.
- template <class T> inline T* obj_field_addr(int offset) const;
-
- // Needed for javaClasses
- inline address* address_field_addr(int offset) const;
+ template <class T> inline T* obj_field_addr_raw(int offset) const;
inline static bool is_null(oop obj) { return obj == NULL; }
inline static bool is_null(narrowOop obj) { return obj == 0; }
--- a/src/hotspot/share/oops/oop.inline.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/oops/oop.inline.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -233,21 +233,11 @@
bool oopDesc::is_objArray() const { return klass()->is_objArray_klass(); }
bool oopDesc::is_typeArray() const { return klass()->is_typeArray_klass(); }
-void* oopDesc::field_base(int offset) const { return (void*)&((char*)this)[offset]; }
+void* oopDesc::field_addr_raw(int offset) const { return reinterpret_cast<void*>(cast_from_oop<intptr_t>(as_oop()) + offset); }
+void* oopDesc::field_addr(int offset) const { return Access<>::resolve(as_oop())->field_addr_raw(offset); }
-jbyte* oopDesc::byte_field_addr(int offset) const { return (jbyte*) field_base(offset); }
-jchar* oopDesc::char_field_addr(int offset) const { return (jchar*) field_base(offset); }
-jboolean* oopDesc::bool_field_addr(int offset) const { return (jboolean*) field_base(offset); }
-jint* oopDesc::int_field_addr(int offset) const { return (jint*) field_base(offset); }
-jshort* oopDesc::short_field_addr(int offset) const { return (jshort*) field_base(offset); }
-jlong* oopDesc::long_field_addr(int offset) const { return (jlong*) field_base(offset); }
-jfloat* oopDesc::float_field_addr(int offset) const { return (jfloat*) field_base(offset); }
-jdouble* oopDesc::double_field_addr(int offset) const { return (jdouble*) field_base(offset); }
-Metadata** oopDesc::metadata_field_addr(int offset) const { return (Metadata**)field_base(offset); }
-
-template <class T> T* oopDesc::obj_field_addr(int offset) const { return (T*) field_base(offset); }
-address* oopDesc::address_field_addr(int offset) const { return (address*) field_base(offset); }
-
+template <class T>
+T* oopDesc::obj_field_addr_raw(int offset) const { return (T*) field_addr_raw(offset); }
// Functions for getting and setting oops within instance objects.
// If the oops are compressed, the type passed to these overloaded functions
--- a/src/hotspot/share/oops/oopsHierarchy.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/oops/oopsHierarchy.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -125,13 +125,6 @@
// from javaCalls.cpp
operator jobject () const { return (jobject)obj(); }
- // from javaClasses.cpp
- operator JavaThread* () const { return (JavaThread*)obj(); }
-
-#ifndef _LP64
- // from jvm.cpp
- operator jlong* () const { return (jlong*)obj(); }
-#endif
// from parNewGeneration and other things that want to get to the end of
// an oop for stuff (like ObjArrayKlass.cpp)
--- a/src/hotspot/share/oops/typeArrayOop.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/oops/typeArrayOop.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,110 +34,67 @@
#include <limits.h>
class typeArrayOopDesc : public arrayOopDesc {
+private:
+ template <class T>
+ static ptrdiff_t element_offset(BasicType bt, int index) {
+ return arrayOopDesc::base_offset_in_bytes(bt) + sizeof(T) * index;
+ }
+
protected:
- jchar* char_base() const { return (jchar*) base(T_CHAR); }
- jboolean* bool_base() const { return (jboolean*)base(T_BOOLEAN); }
- jbyte* byte_base() const { return (jbyte*) base(T_BYTE); }
- jint* int_base() const { return (jint*) base(T_INT); }
- jlong* long_base() const { return (jlong*) base(T_LONG); }
- jshort* short_base() const { return (jshort*) base(T_SHORT); }
- jfloat* float_base() const { return (jfloat*) base(T_FLOAT); }
- jdouble* double_base() const { return (jdouble*) base(T_DOUBLE); }
+ jchar* char_base() const;
+ jboolean* bool_base() const;
+ jbyte* byte_base() const;
+ jint* int_base() const;
+ jlong* long_base() const;
+ jshort* short_base() const;
+ jfloat* float_base() const;
+ jdouble* double_base() const;
friend class TypeArrayKlass;
public:
- jbyte* byte_at_addr(int which) const {
- assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
- return &byte_base()[which];
- }
-
- jboolean* bool_at_addr(int which) const {
- assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
- return &bool_base()[which];
- }
-
- jchar* char_at_addr(int which) const {
- assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
- return &char_base()[which];
- }
-
- jint* int_at_addr(int which) const {
- assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
- return &int_base()[which];
- }
+ jbyte* byte_at_addr(int which) const;
+ jboolean* bool_at_addr(int which) const;
+ jchar* char_at_addr(int which) const;
+ jint* int_at_addr(int which) const;
+ jshort* short_at_addr(int which) const;
+ jushort* ushort_at_addr(int which) const;
+ jlong* long_at_addr(int which) const;
+ jfloat* float_at_addr(int which) const;
+ jdouble* double_at_addr(int which) const;
- jshort* short_at_addr(int which) const {
- assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
- return &short_base()[which];
- }
-
- jushort* ushort_at_addr(int which) const { // for field descriptor arrays
- assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
- return (jushort*) &short_base()[which];
- }
+ jbyte byte_at(int which) const;
+ void byte_at_put(int which, jbyte contents);
- jlong* long_at_addr(int which) const {
- assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
- return &long_base()[which];
- }
+ jboolean bool_at(int which) const;
+ void bool_at_put(int which, jboolean contents);
- jfloat* float_at_addr(int which) const {
- assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
- return &float_base()[which];
- }
-
- jdouble* double_at_addr(int which) const {
- assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
- return &double_base()[which];
- }
+ jchar char_at(int which) const;
+ void char_at_put(int which, jchar contents);
- jbyte byte_at(int which) const { return *byte_at_addr(which); }
- void byte_at_put(int which, jbyte contents) { *byte_at_addr(which) = contents; }
+ jint int_at(int which) const;
+ void int_at_put(int which, jint contents);
- jboolean bool_at(int which) const { return *bool_at_addr(which); }
- void bool_at_put(int which, jboolean contents) { *bool_at_addr(which) = (((jint)contents) & 1); }
-
- jchar char_at(int which) const { return *char_at_addr(which); }
- void char_at_put(int which, jchar contents) { *char_at_addr(which) = contents; }
+ jshort short_at(int which) const;
+ void short_at_put(int which, jshort contents);
- jint int_at(int which) const { return *int_at_addr(which); }
- void int_at_put(int which, jint contents) { *int_at_addr(which) = contents; }
-
- jshort short_at(int which) const { return *short_at_addr(which); }
- void short_at_put(int which, jshort contents) { *short_at_addr(which) = contents; }
+ jushort ushort_at(int which) const;
+ void ushort_at_put(int which, jushort contents);
- jushort ushort_at(int which) const { return *ushort_at_addr(which); }
- void ushort_at_put(int which, jushort contents) { *ushort_at_addr(which) = contents; }
-
- jlong long_at(int which) const { return *long_at_addr(which); }
- void long_at_put(int which, jlong contents) { *long_at_addr(which) = contents; }
+ jlong long_at(int which) const;
+ void long_at_put(int which, jlong contents);
- jfloat float_at(int which) const { return *float_at_addr(which); }
- void float_at_put(int which, jfloat contents) { *float_at_addr(which) = contents; }
+ jfloat float_at(int which) const;
+ void float_at_put(int which, jfloat contents);
- jdouble double_at(int which) const { return *double_at_addr(which); }
- void double_at_put(int which, jdouble contents) { *double_at_addr(which) = contents; }
-
- jbyte byte_at_acquire(int which) const { return OrderAccess::load_acquire(byte_at_addr(which)); }
- void release_byte_at_put(int which, jbyte contents) { OrderAccess::release_store(byte_at_addr(which), contents); }
+ jdouble double_at(int which) const;
+ void double_at_put(int which, jdouble contents);
- // Java thinks Symbol arrays are just arrays of either long or int, since
- // there doesn't seem to be T_ADDRESS, so this is a bit of unfortunate
- // casting
-#ifdef _LP64
- Symbol* symbol_at(int which) const {
- return (Symbol*)*long_at_addr(which); }
- void symbol_at_put(int which, Symbol* contents) {
- *long_at_addr(which) = (jlong)contents;
- }
-#else
- Symbol* symbol_at(int which) const {
- return (Symbol*)*int_at_addr(which); }
- void symbol_at_put(int which, Symbol* contents) {
- *int_at_addr(which) = (int)contents;
- }
-#endif // _LP64
+ jbyte byte_at_acquire(int which) const;
+ void release_byte_at_put(int which, jbyte contents);
+
+ Symbol* symbol_at(int which) const;
+ void symbol_at_put(int which, Symbol* contents);
// Sizing
--- a/src/hotspot/share/oops/typeArrayOop.inline.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/oops/typeArrayOop.inline.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,9 @@
#ifndef SHARE_VM_OOPS_TYPEARRAYOOP_INLINE_HPP
#define SHARE_VM_OOPS_TYPEARRAYOOP_INLINE_HPP
+#include "oops/access.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/arrayOop.inline.hpp"
#include "oops/typeArrayOop.hpp"
int typeArrayOopDesc::object_size() {
@@ -33,4 +35,172 @@
return object_size(tk->layout_helper(), length());
}
+inline jchar* typeArrayOopDesc::char_base() const { return (jchar*) base(T_CHAR); }
+inline jboolean* typeArrayOopDesc::bool_base() const { return (jboolean*)base(T_BOOLEAN); }
+inline jbyte* typeArrayOopDesc::byte_base() const { return (jbyte*) base(T_BYTE); }
+inline jint* typeArrayOopDesc::int_base() const { return (jint*) base(T_INT); }
+inline jlong* typeArrayOopDesc::long_base() const { return (jlong*) base(T_LONG); }
+inline jshort* typeArrayOopDesc::short_base() const { return (jshort*) base(T_SHORT); }
+inline jfloat* typeArrayOopDesc::float_base() const { return (jfloat*) base(T_FLOAT); }
+inline jdouble* typeArrayOopDesc::double_base() const { return (jdouble*) base(T_DOUBLE); }
+
+inline jbyte* typeArrayOopDesc::byte_at_addr(int which) const {
+ assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+ return &byte_base()[which];
+}
+
+inline jboolean* typeArrayOopDesc::bool_at_addr(int which) const {
+ assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+ return &bool_base()[which];
+}
+
+inline jchar* typeArrayOopDesc::char_at_addr(int which) const {
+ assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+ return &char_base()[which];
+}
+
+inline jint* typeArrayOopDesc::int_at_addr(int which) const {
+ assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+ return &int_base()[which];
+}
+
+inline jshort* typeArrayOopDesc::short_at_addr(int which) const {
+ assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+ return &short_base()[which];
+}
+
+inline jushort* typeArrayOopDesc::ushort_at_addr(int which) const { // for field descriptor arrays
+ assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+ return (jushort*) &short_base()[which];
+}
+
+inline jlong* typeArrayOopDesc::long_at_addr(int which) const {
+ assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+ return &long_base()[which];
+}
+
+inline jfloat* typeArrayOopDesc::float_at_addr(int which) const {
+ assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+ return &float_base()[which];
+}
+
+inline jdouble* typeArrayOopDesc::double_at_addr(int which) const {
+ assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+ return &double_base()[which];
+}
+
+inline jbyte typeArrayOopDesc::byte_at(int which) const {
+ ptrdiff_t offset = element_offset<jbyte>(T_BYTE, which);
+ return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
+}
+inline void typeArrayOopDesc::byte_at_put(int which, jbyte contents) {
+ ptrdiff_t offset = element_offset<jbyte>(T_BYTE, which);
+ HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
+}
+
+inline jboolean typeArrayOopDesc::bool_at(int which) const {
+ ptrdiff_t offset = element_offset<jboolean>(T_BOOLEAN, which);
+ return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
+}
+inline void typeArrayOopDesc::bool_at_put(int which, jboolean contents) {
+ ptrdiff_t offset = element_offset<jboolean>(T_BOOLEAN, which);
+ HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, jboolean(contents & 1));
+}
+
+inline jchar typeArrayOopDesc::char_at(int which) const {
+ ptrdiff_t offset = element_offset<jchar>(T_CHAR, which);
+ return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
+}
+inline void typeArrayOopDesc::char_at_put(int which, jchar contents) {
+ ptrdiff_t offset = element_offset<jchar>(T_CHAR, which);
+ HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
+}
+
+inline jint typeArrayOopDesc::int_at(int which) const {
+ ptrdiff_t offset = element_offset<jint>(T_INT, which);
+ return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
+}
+inline void typeArrayOopDesc::int_at_put(int which, jint contents) {
+ ptrdiff_t offset = element_offset<jint>(T_INT, which);
+ HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
+}
+
+inline jshort typeArrayOopDesc::short_at(int which) const {
+ ptrdiff_t offset = element_offset<jshort>(T_SHORT, which);
+ return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
+}
+inline void typeArrayOopDesc::short_at_put(int which, jshort contents) {
+ ptrdiff_t offset = element_offset<jshort>(T_SHORT, which);
+ HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
+}
+
+inline jushort typeArrayOopDesc::ushort_at(int which) const {
+ ptrdiff_t offset = element_offset<jushort>(T_SHORT, which);
+ return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
+}
+inline void typeArrayOopDesc::ushort_at_put(int which, jushort contents) {
+ ptrdiff_t offset = element_offset<jushort>(T_SHORT, which);
+ HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
+}
+
+inline jlong typeArrayOopDesc::long_at(int which) const {
+ ptrdiff_t offset = element_offset<jlong>(T_LONG, which);
+ return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
+}
+inline void typeArrayOopDesc::long_at_put(int which, jlong contents) {
+ ptrdiff_t offset = element_offset<jlong>(T_LONG, which);
+ HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
+}
+
+inline jfloat typeArrayOopDesc::float_at(int which) const {
+ ptrdiff_t offset = element_offset<jfloat>(T_FLOAT, which);
+ return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
+}
+inline void typeArrayOopDesc::float_at_put(int which, jfloat contents) {
+ ptrdiff_t offset = element_offset<jfloat>(T_FLOAT, which);
+ HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
+}
+
+inline jdouble typeArrayOopDesc::double_at(int which) const {
+ ptrdiff_t offset = element_offset<jdouble>(T_DOUBLE, which);
+ return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
+}
+inline void typeArrayOopDesc::double_at_put(int which, jdouble contents) {
+ ptrdiff_t offset = element_offset<jdouble>(T_DOUBLE, which);
+ HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
+}
+
+inline jbyte typeArrayOopDesc::byte_at_acquire(int which) const {
+ ptrdiff_t offset = element_offset<jbyte>(T_BYTE, which);
+ return HeapAccess<MO_ACQUIRE | IN_HEAP_ARRAY>::load_at(as_oop(), offset);
+}
+inline void typeArrayOopDesc::release_byte_at_put(int which, jbyte contents) {
+ ptrdiff_t offset = element_offset<jbyte>(T_BYTE, which);
+ HeapAccess<MO_RELEASE | IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
+}
+
+// Java thinks Symbol arrays are just arrays of either long or int, since
+// there doesn't seem to be T_ADDRESS, so this is a bit of unfortunate
+// casting
+#ifdef _LP64
+inline Symbol* typeArrayOopDesc::symbol_at(int which) const {
+ ptrdiff_t offset = element_offset<jlong>(T_LONG, which);
+ return (Symbol*)(jlong) HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
+}
+inline void typeArrayOopDesc::symbol_at_put(int which, Symbol* contents) {
+ ptrdiff_t offset = element_offset<jlong>(T_LONG, which);
+ HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, (jlong)contents);
+}
+#else
+inline Symbol* typeArrayOopDesc::symbol_at(int which) const {
+ ptrdiff_t offset = element_offset<jint>(T_INT, which);
+ return (Symbol*)(jint) HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
+}
+inline void typeArrayOopDesc::symbol_at_put(int which, Symbol* contents) {
+ ptrdiff_t offset = element_offset<jint>(T_INT, which);
+ HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, (jint)contents);
+}
+#endif // _LP64
+
+
#endif // SHARE_VM_OOPS_TYPEARRAYOOP_INLINE_HPP
--- a/src/hotspot/share/opto/buildOopMap.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/opto/buildOopMap.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, 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
@@ -618,7 +618,7 @@
// last block as his only undone child, we can move the OopFlow from the
// pred to this block. Otherwise we have to grab a new OopFlow.
OopFlow *flow = NULL; // Flag for finding optimized flow
- Block *pred = (Block*)0xdeadbeef;
+ Block *pred = (Block*)((intptr_t)0xdeadbeef);
// Scan this block's preds to find a done predecessor
for (uint j = 1; j < b->num_preds(); j++) {
Block* p = _cfg->get_block_for_node(b->pred(j));
--- a/src/hotspot/share/opto/compile.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/opto/compile.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -2449,8 +2449,8 @@
print_method(PHASE_FINAL_CODE);
// He's dead, Jim.
- _cfg = (PhaseCFG*)0xdeadbeef;
- _regalloc = (PhaseChaitin*)0xdeadbeef;
+ _cfg = (PhaseCFG*)((intptr_t)0xdeadbeef);
+ _regalloc = (PhaseChaitin*)((intptr_t)0xdeadbeef);
}
--- a/src/hotspot/share/opto/gcm.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/opto/gcm.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -1486,7 +1486,7 @@
}
#endif
// Dead.
- _node_latency = (GrowableArray<uint> *)0xdeadbeef;
+ _node_latency = (GrowableArray<uint> *)((intptr_t)0xdeadbeef);
}
bool PhaseCFG::do_global_code_motion() {
--- a/src/hotspot/share/opto/idealGraphPrinter.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/opto/idealGraphPrinter.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2018, 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
@@ -602,7 +602,7 @@
}
#endif
- if (_chaitin && _chaitin != (PhaseChaitin *)0xdeadbeef) {
+ if (_chaitin && _chaitin != (PhaseChaitin *)((intptr_t)0xdeadbeef)) {
buffer[0] = 0;
_chaitin->dump_register(node, buffer);
print_prop("reg", buffer);
--- a/src/hotspot/share/opto/library_call.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/opto/library_call.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -2408,7 +2408,7 @@
offset = argument(2); // type: long
// We currently rely on the cookies produced by Unsafe.xxxFieldOffset
// to be plain byte offsets, which are also the same as those accepted
- // by oopDesc::field_base.
+ // by oopDesc::field_addr.
assert(Unsafe_field_offset_to_byte_offset(11) == 11,
"fieldOffset must be byte-scaled");
// 32-bit machines ignore the high half!
@@ -2838,7 +2838,7 @@
// Build field offset expression.
// We currently rely on the cookies produced by Unsafe.xxxFieldOffset
// to be plain byte offsets, which are also the same as those accepted
- // by oopDesc::field_base.
+ // by oopDesc::field_addr.
assert(Unsafe_field_offset_to_byte_offset(11) == 11, "fieldOffset must be byte-scaled");
// 32-bit machines ignore the high half of long offsets
offset = ConvL2X(offset);
--- a/src/hotspot/share/opto/output.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/opto/output.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, 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
@@ -2575,7 +2575,7 @@
}
Node *kill = def; // Rename 'def' to more descriptive 'kill'
- debug_only( def = (Node*)0xdeadbeef; )
+ debug_only( def = (Node*)((intptr_t)0xdeadbeef); )
// After some number of kills there _may_ be a later def
Node *later_def = NULL;
--- a/src/hotspot/share/opto/split_if.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/opto/split_if.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, 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
@@ -292,7 +292,7 @@
Node *PhaseIdealLoop::spinup( Node *iff_dom, Node *new_false, Node *new_true, Node *use_blk, Node *def, small_cache *cache ) {
if (use_blk->is_top()) // Handle dead uses
return use_blk;
- Node *prior_n = (Node*)0xdeadbeef;
+ Node *prior_n = (Node*)((intptr_t)0xdeadbeef);
Node *n = use_blk; // Get path input
assert( use_blk != iff_dom, "" );
// Here's the "spinup" the dominator tree loop. Do a cache-check
@@ -339,7 +339,7 @@
}
// Update cache everywhere
- prior_n = (Node*)0xdeadbeef; // Reset IDOM walk
+ prior_n = (Node*)((intptr_t)0xdeadbeef); // Reset IDOM walk
n = use_blk; // Get path input
// Spin-up the idom tree again, basically doing path-compression.
// Insert cache entries along the way, so that if we ever hit this
--- a/src/hotspot/share/prims/jni.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/prims/jni.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -44,6 +44,7 @@
#include "memory/resourceArea.hpp"
#include "memory/universe.inline.hpp"
#include "oops/access.inline.hpp"
+#include "oops/arrayOop.inline.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/instanceOop.hpp"
#include "oops/markOop.hpp"
@@ -53,7 +54,7 @@
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
#include "oops/typeArrayKlass.hpp"
-#include "oops/typeArrayOop.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "prims/jniCheck.hpp"
#include "prims/jniExport.hpp"
#include "prims/jniFastGetField.hpp"
--- a/src/hotspot/share/prims/jvm.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/prims/jvm.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -166,9 +166,8 @@
}
} else if (last_caller != NULL &&
last_caller->method_holder()->name() ==
- vmSymbols::java_lang_ClassLoader() &&
- (last_caller->name() == vmSymbols::loadClassInternal_name() ||
- last_caller->name() == vmSymbols::loadClass_name())) {
+ vmSymbols::java_lang_ClassLoader() &&
+ last_caller->name() == vmSymbols::loadClass_name()) {
found_it = true;
} else if (!vfst.at_end()) {
if (vfst.method()->is_native()) {
--- a/src/hotspot/share/prims/jvmtiTagMap.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/prims/jvmtiTagMap.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -31,10 +31,12 @@
#include "jvmtifiles/jvmtiEnv.hpp"
#include "memory/resourceArea.hpp"
#include "oops/access.inline.hpp"
+#include "oops/arrayOop.inline.hpp"
#include "oops/instanceMirrorKlass.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "prims/jvmtiEventController.hpp"
#include "prims/jvmtiEventController.inline.hpp"
#include "prims/jvmtiExport.hpp"
--- a/src/hotspot/share/prims/methodHandles.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/prims/methodHandles.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -36,6 +36,7 @@
#include "memory/resourceArea.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/compilationPolicy.hpp"
#include "runtime/javaCalls.hpp"
--- a/src/hotspot/share/prims/unsafe.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/prims/unsafe.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, 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
@@ -33,6 +33,7 @@
#include "oops/fieldStreams.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "prims/unsafe.hpp"
#include "runtime/atomic.hpp"
#include "runtime/globals.hpp"
@@ -108,8 +109,8 @@
assert(byte_offset >= 0 && byte_offset <= (jlong)MAX_OBJECT_SIZE, "sane offset");
if (byte_offset == (jint)byte_offset) {
void* ptr_plus_disp = (address)p + byte_offset;
- assert((void*)p->obj_field_addr<oop>((jint)byte_offset) == ptr_plus_disp,
- "raw [ptr+disp] must be consistent with oop::field_base");
+ assert(p->field_addr_raw((jint)byte_offset) == ptr_plus_disp,
+ "raw [ptr+disp] must be consistent with oop::field_addr_raw");
}
jlong p_size = HeapWordSize * (jlong)(p->size());
assert(byte_offset < p_size, "Unsafe access: offset " INT64_FORMAT " > object's size " INT64_FORMAT, (int64_t)byte_offset, (int64_t)p_size);
--- a/src/hotspot/share/prims/whitebox.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/prims/whitebox.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -44,6 +44,7 @@
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "prims/wbtestmethods/parserTests.hpp"
#include "prims/whitebox.hpp"
#include "runtime/arguments.hpp"
@@ -59,8 +60,8 @@
#include "runtime/vm_version.hpp"
#include "utilities/align.hpp"
#include "utilities/debug.hpp"
+#include "utilities/elfFile.hpp"
#include "utilities/exceptions.hpp"
-#include "utilities/elfFile.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_CDS
#include "prims/cdsoffsets.hpp"
@@ -80,7 +81,6 @@
#endif // INCLUDE_NMT
#ifdef LINUX
-#include "utilities/elfFile.hpp"
#include "osContainer_linux.hpp"
#endif
@@ -602,6 +602,13 @@
return addr;
WB_END
+WB_ENTRY(jlong, WB_NMTAttemptReserveMemoryAt(JNIEnv* env, jobject o, jlong addr, jlong size))
+ addr = (jlong)(uintptr_t)os::attempt_reserve_memory_at((size_t)size, (char*)(uintptr_t)addr);
+ MemTracker::record_virtual_memory_type((address)addr, mtTest);
+
+ return addr;
+WB_END
+
WB_ENTRY(void, WB_NMTCommitMemory(JNIEnv* env, jobject o, jlong addr, jlong size))
os::commit_memory((char *)(uintptr_t)addr, size, !ExecMem);
MemTracker::record_virtual_memory_type((address)(uintptr_t)addr, mtTest);
@@ -1212,12 +1219,12 @@
WB_END
WB_ENTRY(void, WB_FullGC(JNIEnv* env, jobject o))
- Universe::heap()->collector_policy()->set_should_clear_all_soft_refs(true);
+ Universe::heap()->soft_ref_policy()->set_should_clear_all_soft_refs(true);
Universe::heap()->collect(GCCause::_wb_full_gc);
#if INCLUDE_ALL_GCS
if (UseG1GC) {
// Needs to be cleared explicitly for G1
- Universe::heap()->collector_policy()->set_should_clear_all_soft_refs(false);
+ Universe::heap()->soft_ref_policy()->set_should_clear_all_soft_refs(false);
}
#endif // INCLUDE_ALL_GCS
WB_END
@@ -1740,6 +1747,10 @@
#endif // INCLUDE_CDS
WB_END
+WB_ENTRY(jboolean, WB_IsJavaHeapArchiveSupported(JNIEnv* env))
+ return MetaspaceShared::is_heap_object_archiving_allowed();
+WB_END
+
#if INCLUDE_CDS
@@ -1970,6 +1981,7 @@
{CC"NMTMallocWithPseudoStack", CC"(JI)J", (void*)&WB_NMTMallocWithPseudoStack},
{CC"NMTFree", CC"(J)V", (void*)&WB_NMTFree },
{CC"NMTReserveMemory", CC"(J)J", (void*)&WB_NMTReserveMemory },
+ {CC"NMTAttemptReserveMemoryAt", CC"(JJ)J", (void*)&WB_NMTAttemptReserveMemoryAt },
{CC"NMTCommitMemory", CC"(JJ)V", (void*)&WB_NMTCommitMemory },
{CC"NMTUncommitMemory", CC"(JJ)V", (void*)&WB_NMTUncommitMemory },
{CC"NMTReleaseMemory", CC"(JJ)V", (void*)&WB_NMTReleaseMemory },
@@ -2116,6 +2128,8 @@
{CC"getResolvedReferences", CC"(Ljava/lang/Class;)Ljava/lang/Object;", (void*)&WB_GetResolvedReferences},
{CC"areOpenArchiveHeapObjectsMapped", CC"()Z", (void*)&WB_AreOpenArchiveHeapObjectsMapped},
{CC"isCDSIncludedInVmBuild", CC"()Z", (void*)&WB_IsCDSIncludedInVmBuild },
+ {CC"isJavaHeapArchiveSupported", CC"()Z", (void*)&WB_IsJavaHeapArchiveSupported },
+
{CC"clearInlineCaches0", CC"(Z)V", (void*)&WB_ClearInlineCaches },
{CC"handshakeWalkStack", CC"(Ljava/lang/Thread;Z)I", (void*)&WB_HandshakeWalkStack },
{CC"addCompilerDirective", CC"(Ljava/lang/String;)I",
--- a/src/hotspot/share/runtime/arguments.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/runtime/arguments.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -509,7 +509,6 @@
{ "MinRAMFraction", JDK_Version::jdk(10), JDK_Version::undefined(), JDK_Version::undefined() },
{ "InitialRAMFraction", JDK_Version::jdk(10), JDK_Version::undefined(), JDK_Version::undefined() },
{ "UseMembar", JDK_Version::jdk(10), JDK_Version::undefined(), JDK_Version::undefined() },
- { "FastTLABRefill", JDK_Version::jdk(10), JDK_Version::jdk(11), JDK_Version::jdk(12) },
{ "SafepointSpinBeforeYield", JDK_Version::jdk(10), JDK_Version::jdk(11), JDK_Version::jdk(12) },
{ "DeferThrSuspendLoopCount", JDK_Version::jdk(10), JDK_Version::jdk(11), JDK_Version::jdk(12) },
{ "DeferPollingPageLoopCount", JDK_Version::jdk(10), JDK_Version::jdk(11), JDK_Version::jdk(12) },
@@ -521,8 +520,8 @@
// --- Deprecated alias flags (see also aliased_jvm_flags) - sorted by obsolete_in then expired_in:
{ "DefaultMaxRAMFraction", JDK_Version::jdk(8), JDK_Version::undefined(), JDK_Version::undefined() },
{ "CreateMinidumpOnCrash", JDK_Version::jdk(9), JDK_Version::undefined(), JDK_Version::undefined() },
- { "MustCallLoadClassInternal", JDK_Version::jdk(10), JDK_Version::undefined(), JDK_Version::undefined() },
- { "UnsyncloadClass", JDK_Version::jdk(10), JDK_Version::undefined(), JDK_Version::undefined() },
+ { "MustCallLoadClassInternal", JDK_Version::jdk(10), JDK_Version::jdk(11), JDK_Version::jdk(12) },
+ { "UnsyncloadClass", JDK_Version::jdk(10), JDK_Version::jdk(11), JDK_Version::jdk(12) },
// -------------- Obsolete Flags - sorted by expired_in --------------
{ "ConvertSleepToYield", JDK_Version::jdk(9), JDK_Version::jdk(10), JDK_Version::jdk(11) },
@@ -531,6 +530,8 @@
{ "CheckAssertionStatusDirectives",JDK_Version::undefined(), JDK_Version::jdk(11), JDK_Version::jdk(12) },
{ "PrintMallocFree", JDK_Version::undefined(), JDK_Version::jdk(11), JDK_Version::jdk(12) },
{ "PrintMalloc", JDK_Version::undefined(), JDK_Version::jdk(11), JDK_Version::jdk(12) },
+ { "ShowSafepointMsgs", JDK_Version::undefined(), JDK_Version::jdk(11), JDK_Version::jdk(12) },
+ { "FastTLABRefill", JDK_Version::jdk(10), JDK_Version::jdk(11), JDK_Version::jdk(12) },
{ "PermSize", JDK_Version::undefined(), JDK_Version::jdk(8), JDK_Version::undefined() },
{ "MaxPermSize", JDK_Version::undefined(), JDK_Version::jdk(8), JDK_Version::undefined() },
{ "SharedReadWriteSize", JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() },
@@ -1826,6 +1827,13 @@
}
#endif
+#if defined(IA32)
+ // Only server compiler can optimize safepoints well enough.
+ if (!is_server_compilation_mode_vm()) {
+ FLAG_SET_ERGO_IF_DEFAULT(bool, ThreadLocalHandshakes, false);
+ }
+#endif
+
set_conservative_max_heap_alignment();
#ifndef ZERO
--- a/src/hotspot/share/runtime/atomic.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/runtime/atomic.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, 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
@@ -131,6 +131,7 @@
cmpxchg_memory_order order = memory_order_conservative);
private:
+WINDOWS_ONLY(public:) // VS2017 warns (C2027) use of undefined type if IsPointerConvertible is declared private
// Test whether From is implicitly convertible to To.
// From and To must be pointer types.
// Note: Provides the limited subset of C++11 std::is_convertible
--- a/src/hotspot/share/runtime/deoptimization.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/runtime/deoptimization.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -40,6 +40,7 @@
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/fieldStreams.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "oops/verifyOopClosure.hpp"
#include "prims/jvmtiThreadState.hpp"
#include "runtime/biasedLocking.hpp"
--- a/src/hotspot/share/runtime/globals.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/runtime/globals.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -842,9 +842,6 @@
product(bool, FailOverToOldVerifier, true, \
"Fail over to old verifier when split verifier fails") \
\
- develop(bool, ShowSafepointMsgs, false, \
- "Show message about safepoint synchronization") \
- \
product(bool, SafepointTimeout, false, \
"Time out and warn or fail after SafepointTimeoutDelay " \
"milliseconds if failed to reach safepoint") \
@@ -1142,11 +1139,6 @@
diagnostic(bool, DynamicallyResizeSystemDictionaries, true, \
"Dynamically resize system dictionaries as needed") \
\
- diagnostic(bool, UnsyncloadClass, false, \
- "Unstable: VM calls loadClass unsynchronized. Custom " \
- "class loader must call VM synchronized for findClass " \
- "and defineClass.") \
- \
product(bool, AlwaysLockClassLoader, false, \
"Require the VM to acquire the class loader lock before calling " \
"loadClass() even for class loaders registering " \
@@ -1156,9 +1148,6 @@
"Allow parallel defineClass requests for class loaders " \
"registering as parallel capable") \
\
- product(bool, MustCallLoadClassInternal, false, \
- "Call loadClassInternal() rather than loadClass()") \
- \
product_pd(bool, DontYieldALot, \
"Throw away obvious excess yield calls") \
\
@@ -2012,9 +2001,6 @@
product(bool, ZeroTLAB, false, \
"Zero out the newly created TLAB") \
\
- product(bool, FastTLABRefill, false, \
- "(Deprecated) Use fast TLAB refill code") \
- \
product(bool, TLABStats, true, \
"Provide more detailed and expensive TLAB statistics.") \
\
--- a/src/hotspot/share/runtime/handles.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/runtime/handles.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -97,10 +97,6 @@
// during GC phase 3, a handle may be a forward pointer that
// is not yet valid, so loosen the assertion
while (bottom < top) {
- // This test can be moved up but for now check every oop.
-
- assert(oopDesc::is_oop(*bottom, true), "handle should point to oop");
-
f->do_oop(bottom++);
}
return handles_visited;
--- a/src/hotspot/share/runtime/objectMonitor.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/runtime/objectMonitor.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, 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
@@ -102,8 +102,6 @@
int ObjectMonitor::Knob_VerifyInUse = 0;
int ObjectMonitor::Knob_VerifyMatch = 0;
int ObjectMonitor::Knob_SpinLimit = 5000; // derived by an external tool -
-static int Knob_LogSpins = 0; // enable jvmstat tally for spins
-static int Knob_HandOff = 0;
static int Knob_ReportSettings = 0;
static int Knob_SpinBase = 0; // Floor AKA SpinMin
@@ -2229,18 +2227,7 @@
PerfCounter * ObjectMonitor::_sync_ContendedLockAttempts = NULL;
PerfCounter * ObjectMonitor::_sync_FutileWakeups = NULL;
PerfCounter * ObjectMonitor::_sync_Parks = NULL;
-PerfCounter * ObjectMonitor::_sync_EmptyNotifications = NULL;
PerfCounter * ObjectMonitor::_sync_Notifications = NULL;
-PerfCounter * ObjectMonitor::_sync_PrivateA = NULL;
-PerfCounter * ObjectMonitor::_sync_PrivateB = NULL;
-PerfCounter * ObjectMonitor::_sync_SlowExit = NULL;
-PerfCounter * ObjectMonitor::_sync_SlowEnter = NULL;
-PerfCounter * ObjectMonitor::_sync_SlowNotify = NULL;
-PerfCounter * ObjectMonitor::_sync_SlowNotifyAll = NULL;
-PerfCounter * ObjectMonitor::_sync_FailedSpins = NULL;
-PerfCounter * ObjectMonitor::_sync_SuccessfulSpins = NULL;
-PerfCounter * ObjectMonitor::_sync_MonInCirculation = NULL;
-PerfCounter * ObjectMonitor::_sync_MonScavenged = NULL;
PerfCounter * ObjectMonitor::_sync_Inflations = NULL;
PerfCounter * ObjectMonitor::_sync_Deflations = NULL;
PerfLongVariable * ObjectMonitor::_sync_MonExtant = NULL;
@@ -2271,18 +2258,7 @@
NEWPERFCOUNTER(_sync_ContendedLockAttempts);
NEWPERFCOUNTER(_sync_FutileWakeups);
NEWPERFCOUNTER(_sync_Parks);
- NEWPERFCOUNTER(_sync_EmptyNotifications);
NEWPERFCOUNTER(_sync_Notifications);
- NEWPERFCOUNTER(_sync_SlowEnter);
- NEWPERFCOUNTER(_sync_SlowExit);
- NEWPERFCOUNTER(_sync_SlowNotify);
- NEWPERFCOUNTER(_sync_SlowNotifyAll);
- NEWPERFCOUNTER(_sync_FailedSpins);
- NEWPERFCOUNTER(_sync_SuccessfulSpins);
- NEWPERFCOUNTER(_sync_PrivateA);
- NEWPERFCOUNTER(_sync_PrivateB);
- NEWPERFCOUNTER(_sync_MonInCirculation);
- NEWPERFCOUNTER(_sync_MonScavenged);
NEWPERFVARIABLE(_sync_MonExtant);
#undef NEWPERFCOUNTER
#undef NEWPERFVARIABLE
@@ -2328,7 +2304,7 @@
if (SyncKnobs == NULL) SyncKnobs = "";
size_t sz = strlen(SyncKnobs);
- char * knobs = (char *) malloc(sz + 2);
+ char * knobs = (char *) os::malloc(sz + 2, mtInternal);
if (knobs == NULL) {
vm_exit_out_of_memory(sz + 2, OOM_MALLOC_ERROR, "Parse SyncKnobs");
guarantee(0, "invariant");
@@ -2351,7 +2327,6 @@
SETKNOB(SpinBackOff);
SETKNOB(CASPenalty);
SETKNOB(OXPenalty);
- SETKNOB(LogSpins);
SETKNOB(SpinSetSucc);
SETKNOB(SuccEnabled);
SETKNOB(SuccRestrict);
@@ -2389,11 +2364,7 @@
Knob_FixedSpin = -1;
}
- if (Knob_LogSpins == 0) {
- ObjectMonitor::_sync_FailedSpins = NULL;
- }
-
- free(knobs);
+ os::free(knobs);
OrderAccess::fence();
InitDone = 1;
}
--- a/src/hotspot/share/runtime/objectMonitor.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/runtime/objectMonitor.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, 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
@@ -191,18 +191,7 @@
static PerfCounter * _sync_ContendedLockAttempts;
static PerfCounter * _sync_FutileWakeups;
static PerfCounter * _sync_Parks;
- static PerfCounter * _sync_EmptyNotifications;
static PerfCounter * _sync_Notifications;
- static PerfCounter * _sync_SlowEnter;
- static PerfCounter * _sync_SlowExit;
- static PerfCounter * _sync_SlowNotify;
- static PerfCounter * _sync_SlowNotifyAll;
- static PerfCounter * _sync_FailedSpins;
- static PerfCounter * _sync_SuccessfulSpins;
- static PerfCounter * _sync_PrivateA;
- static PerfCounter * _sync_PrivateB;
- static PerfCounter * _sync_MonInCirculation;
- static PerfCounter * _sync_MonScavenged;
static PerfCounter * _sync_Inflations;
static PerfCounter * _sync_Deflations;
static PerfLongVariable * _sync_MonExtant;
--- a/src/hotspot/share/runtime/os.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/runtime/os.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -93,6 +93,18 @@
os::init_globals();
}
+static time_t get_timezone(const struct tm* time_struct) {
+#if defined(_ALLBSD_SOURCE)
+ return time_struct->tm_gmtoff;
+#elif defined(_WINDOWS)
+ long zone;
+ _get_timezone(&zone);
+ return static_cast<time_t>(zone);
+#else
+ return timezone;
+#endif
+}
+
// Fill in buffer with current local time as an ISO-8601 string.
// E.g., yyyy-mm-ddThh:mm:ss-zzzz.
// Returns buffer, or NULL if it failed.
@@ -137,11 +149,7 @@
return NULL;
}
}
-#if defined(_ALLBSD_SOURCE)
- const time_t zone = (time_t) time_struct.tm_gmtoff;
-#else
- const time_t zone = timezone;
-#endif
+ const time_t zone = get_timezone(&time_struct);
// If daylight savings time is in effect,
// we are 1 hour East of our time zone
@@ -1706,7 +1714,7 @@
} else {
result = pd_attempt_reserve_memory_at(bytes, addr);
if (result != NULL) {
- MemTracker::record_virtual_memory_reserve_and_commit((address)result, bytes, CALLER_PC);
+ MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC);
}
}
return result;
--- a/src/hotspot/share/runtime/reflection.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/runtime/reflection.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -39,6 +39,7 @@
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "prims/jvmtiExport.hpp"
#include "runtime/arguments.hpp"
#include "runtime/handles.inline.hpp"
--- a/src/hotspot/share/runtime/safepoint.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/runtime/safepoint.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -893,10 +893,6 @@
assert(SafepointSynchronize::is_synchronizing(), "polling encountered outside safepoint synchronization");
}
- if (ShowSafepointMsgs) {
- tty->print("handle_polling_page_exception: ");
- }
-
if (PrintSafepointStatistics) {
inc_page_trap_count();
}
@@ -1098,9 +1094,6 @@
"polling page exception on thread not running state: %u", uint(t));
// Step 1: Find the nmethod from the return address
- if (ShowSafepointMsgs && Verbose) {
- tty->print_cr("Polling page exception at " INTPTR_FORMAT, p2i(thread()->saved_exception_pc()));
- }
address real_return_addr = thread()->saved_exception_pc();
CodeBlob *cb = CodeCache::find_blob(real_return_addr);
@@ -1421,32 +1414,3 @@
INT64_FORMAT_W(5) " ms",
(int64_t)(_max_vmop_time / MICROUNITS));
}
-
-// ------------------------------------------------------------------------------------------------
-// Non-product code
-
-#ifndef PRODUCT
-
-void SafepointSynchronize::print_state() {
- if (_state == _not_synchronized) {
- tty->print_cr("not synchronized");
- } else if (_state == _synchronizing || _state == _synchronized) {
- tty->print_cr("State: %s", (_state == _synchronizing) ? "synchronizing" :
- "synchronized");
-
- for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur = jtiwh.next(); ) {
- cur->safepoint_state()->print();
- }
- }
-}
-
-void SafepointSynchronize::safepoint_msg(const char* format, ...) {
- if (ShowSafepointMsgs) {
- va_list ap;
- va_start(ap, format);
- tty->vprint_cr(format, ap);
- va_end(ap);
- }
-}
-
-#endif // !PRODUCT
--- a/src/hotspot/share/runtime/safepoint.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/runtime/safepoint.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -191,10 +191,6 @@
static bool is_cleanup_needed();
static void do_cleanup_tasks();
- // Debugging
- static void print_state() PRODUCT_RETURN;
- static void safepoint_msg(const char* format, ...) ATTRIBUTE_PRINTF(1, 2) PRODUCT_RETURN;
-
static void deferred_initialize_stat();
static void print_stat_on_exit();
inline static void inc_vmop_coalesced_count() { _coalesced_vmop_count++; }
@@ -258,15 +254,6 @@
// Initialize
static void create(JavaThread *thread);
static void destroy(JavaThread *thread);
-
- void safepoint_msg(const char* format, ...) ATTRIBUTE_PRINTF(2, 3) {
- if (ShowSafepointMsgs) {
- va_list ap;
- va_start(ap, format);
- tty->vprint_cr(format, ap);
- va_end(ap);
- }
- }
};
--- a/src/hotspot/share/runtime/serviceThread.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/runtime/serviceThread.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -29,7 +29,6 @@
#include "runtime/mutexLocker.hpp"
#include "runtime/os.hpp"
#include "prims/jvmtiImpl.hpp"
-#include "services/allocationContextService.hpp"
#include "services/diagnosticArgument.hpp"
#include "services/diagnosticFramework.hpp"
#include "services/gcNotifier.hpp"
@@ -105,8 +104,7 @@
while (!(sensors_changed = LowMemoryDetector::has_pending_requests()) &&
!(has_jvmti_events = JvmtiDeferredEventQueue::has_events()) &&
!(has_gc_notification_event = GCNotifier::has_event()) &&
- !(has_dcmd_notification_event = DCmdFactory::has_pending_jmx_notification()) &&
- !(acs_notify = AllocationContextService::should_notify())) {
+ !(has_dcmd_notification_event = DCmdFactory::has_pending_jmx_notification())) {
// wait until one of the sensors has pending requests, or there is a
// pending JVMTI event or JMX GC notification to post
Service_lock->wait(Mutex::_no_safepoint_check_flag);
@@ -132,10 +130,6 @@
if(has_dcmd_notification_event) {
DCmdFactory::send_notification(CHECK);
}
-
- if (acs_notify) {
- AllocationContextService::notify(CHECK);
- }
}
}
--- a/src/hotspot/share/runtime/sharedRuntime.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/runtime/sharedRuntime.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1922,95 +1922,27 @@
vframeStream vfst(thread, true);
assert(!vfst.at_end(), "Java frame must exist");
Bytecode_checkcast cc(vfst.method(), vfst.method()->bcp_from(vfst.bci()));
- Klass* target_klass = vfst.method()->constants()->klass_at(
- cc.index(), thread);
- return generate_class_cast_message(caster_klass, target_klass);
-}
-
-// The caller of class_loader_and_module_name() (or one of its callers)
-// must use a ResourceMark in order to correctly free the result.
-const char* class_loader_and_module_name(Klass* klass) {
- const char* delim = "/";
- size_t delim_len = strlen(delim);
-
- const char* fqn = klass->external_name();
- // Length of message to return; always include FQN
- size_t msglen = strlen(fqn) + 1;
-
- bool has_cl_name = false;
- bool has_mod_name = false;
- bool has_version = false;
-
- // Use class loader name, if exists and not builtin
- const char* class_loader_name = "";
- ClassLoaderData* cld = klass->class_loader_data();
- assert(cld != NULL, "class_loader_data should not be NULL");
- if (!cld->is_builtin_class_loader_data()) {
- // If not builtin, look for name
- oop loader = klass->class_loader();
- if (loader != NULL) {
- oop class_loader_name_oop = java_lang_ClassLoader::name(loader);
- if (class_loader_name_oop != NULL) {
- class_loader_name = java_lang_String::as_utf8_string(class_loader_name_oop);
- if (class_loader_name != NULL && class_loader_name[0] != '\0') {
- has_cl_name = true;
- msglen += strlen(class_loader_name) + delim_len;
- }
- }
- }
+ constantPoolHandle cpool(thread, vfst.method()->constants());
+ Klass* target_klass = ConstantPool::klass_at_if_loaded(cpool, cc.index());
+ Symbol* target_klass_name = NULL;
+ if (target_klass == NULL) {
+ // This klass should be resolved, but just in case, get the name in the klass slot.
+ target_klass_name = cpool->klass_name_at(cc.index());
}
-
- const char* module_name = "";
- const char* version = "";
- Klass* bottom_klass = klass->is_objArray_klass() ?
- ObjArrayKlass::cast(klass)->bottom_klass() : klass;
- if (bottom_klass->is_instance_klass()) {
- ModuleEntry* module = InstanceKlass::cast(bottom_klass)->module();
- // Use module name, if exists
- if (module->is_named()) {
- has_mod_name = true;
- module_name = module->name()->as_C_string();
- msglen += strlen(module_name);
- // Use version if exists and is not a jdk module
- if (module->is_non_jdk_module() && module->version() != NULL) {
- has_version = true;
- version = module->version()->as_C_string();
- msglen += strlen("@") + strlen(version);
- }
- }
- } else {
- // klass is an array of primitives, so its module is java.base
- module_name = JAVA_BASE_NAME;
- }
-
- if (has_cl_name || has_mod_name) {
- msglen += delim_len;
- }
-
- char* message = NEW_RESOURCE_ARRAY_RETURN_NULL(char, msglen);
-
- // Just return the FQN if error in allocating string
- if (message == NULL) {
- return fqn;
- }
-
- jio_snprintf(message, msglen, "%s%s%s%s%s%s%s",
- class_loader_name,
- (has_cl_name) ? delim : "",
- (has_mod_name) ? module_name : "",
- (has_version) ? "@" : "",
- (has_version) ? version : "",
- (has_cl_name || has_mod_name) ? delim : "",
- fqn);
- return message;
+ return generate_class_cast_message(caster_klass, target_klass, target_klass_name);
}
+
+// The caller of generate_class_cast_message() (or one of its callers)
+// must use a ResourceMark in order to correctly free the result.
char* SharedRuntime::generate_class_cast_message(
- Klass* caster_klass, Klass* target_klass) {
-
- const char* caster_name = class_loader_and_module_name(caster_klass);
-
- const char* target_name = class_loader_and_module_name(target_klass);
+ Klass* caster_klass, Klass* target_klass, Symbol* target_klass_name) {
+
+ const char* caster_name = caster_klass->class_loader_and_module_name();
+
+ assert(target_klass != NULL || target_klass_name != NULL, "one must be provided");
+ const char* target_name = target_klass == NULL ? target_klass_name->as_C_string() :
+ target_klass->class_loader_and_module_name();
size_t msglen = strlen(caster_name) + strlen(" cannot be cast to ") + strlen(target_name) + 1;
--- a/src/hotspot/share/runtime/sharedRuntime.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/runtime/sharedRuntime.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -318,7 +318,7 @@
// The caller (or one of it's callers) must use a ResourceMark
// in order to correctly free the result.
//
- static char* generate_class_cast_message(Klass* caster_klass, Klass* target_klass);
+ static char* generate_class_cast_message(Klass* caster_klass, Klass* target_klass, Symbol* target_klass_name = NULL);
// Resolves a call site- may patch in the destination of the call into the
// compiled code.
--- a/src/hotspot/share/runtime/synchronizer.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/runtime/synchronizer.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, 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
@@ -184,8 +184,6 @@
// have to pass through, and we must also be able to deal with
// asynchronous exceptions. The caller is responsible for checking
// the threads pending exception if needed.
-// doLock was added to support classloading with UnsyncloadClass which
-// requires flag based choice of locking the classloader lock.
class ObjectLocker : public StackObj {
private:
Thread* _thread;
--- a/src/hotspot/share/runtime/thread.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/runtime/thread.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -51,6 +51,7 @@
#include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "oops/verifyOopClosure.hpp"
#include "prims/jvm_misc.hpp"
#include "prims/jvmtiExport.hpp"
@@ -1997,7 +1998,7 @@
// We must flush any deferred card marks and other various GC barrier
// related buffers (e.g. G1 SATB buffer and G1 dirty card queue buffer)
// before removing a thread from the list of active threads.
- BarrierSet::barrier_set()->flush_deferred_barriers(this);
+ BarrierSet::barrier_set()->on_thread_detach(this);
log_info(os, thread)("JavaThread %s (tid: " UINTX_FORMAT ").",
exit_type == JavaThread::normal_exit ? "exiting" : "detaching",
@@ -2026,36 +2027,6 @@
}
}
-#if INCLUDE_ALL_GCS
-// Flush G1-related queues.
-void JavaThread::flush_barrier_queues() {
- satb_mark_queue().flush();
- dirty_card_queue().flush();
-}
-
-void JavaThread::initialize_queues() {
- assert(!SafepointSynchronize::is_at_safepoint(),
- "we should not be at a safepoint");
-
- SATBMarkQueue& satb_queue = satb_mark_queue();
- SATBMarkQueueSet& satb_queue_set = satb_mark_queue_set();
- // The SATB queue should have been constructed with its active
- // field set to false.
- assert(!satb_queue.is_active(), "SATB queue should not be active");
- assert(satb_queue.is_empty(), "SATB queue should be empty");
- // If we are creating the thread during a marking cycle, we should
- // set the active field of the SATB queue to true.
- if (satb_queue_set.is_active()) {
- satb_queue.set_active(true);
- }
-
- DirtyCardQueue& dirty_queue = dirty_card_queue();
- // The dirty card queue should have been constructed with its
- // active field set to true.
- assert(dirty_queue.is_active(), "dirty card queue should be active");
-}
-#endif // INCLUDE_ALL_GCS
-
void JavaThread::cleanup_failed_attach_current_thread() {
if (active_handles() != NULL) {
JNIHandleBlock* block = active_handles();
@@ -2076,19 +2047,12 @@
tlab().make_parsable(true); // retire TLAB, if any
}
-#if INCLUDE_ALL_GCS
- if (UseG1GC) {
- flush_barrier_queues();
- }
-#endif // INCLUDE_ALL_GCS
+ BarrierSet::barrier_set()->on_thread_detach(this);
Threads::remove(this);
this->smr_delete();
}
-
-
-
JavaThread* JavaThread::active() {
Thread* thread = Thread::current();
if (thread->is_Java_thread()) {
@@ -4341,9 +4305,8 @@
// The threads lock must be owned at this point
assert_locked_or_safepoint(Threads_lock);
- // See the comment for this method in thread.hpp for its purpose and
- // why it is called here.
- p->initialize_queues();
+ BarrierSet::barrier_set()->on_thread_attach(p);
+
p->set_next(_thread_list);
_thread_list = p;
--- a/src/hotspot/share/runtime/thread.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/runtime/thread.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -1075,8 +1075,6 @@
DirtyCardQueue _dirty_card_queue; // Thread-local log for dirty cards.
// Set of all such queues.
static DirtyCardQueueSet _dirty_card_queue_set;
-
- void flush_barrier_queues();
#endif // INCLUDE_ALL_GCS
friend class VMThread;
@@ -1968,29 +1966,6 @@
}
#endif // INCLUDE_ALL_GCS
- // This method initializes the SATB and dirty card queues before a
- // JavaThread is added to the Java thread list. Right now, we don't
- // have to do anything to the dirty card queue (it should have been
- // activated when the thread was created), but we have to activate
- // the SATB queue if the thread is created while a marking cycle is
- // in progress. The activation / de-activation of the SATB queues at
- // the beginning / end of a marking cycle is done during safepoints
- // so we have to make sure this method is called outside one to be
- // able to safely read the active field of the SATB queue set. Right
- // now, it is called just before the thread is added to the Java
- // thread list in the Threads::add() method. That method is holding
- // the Threads_lock which ensures we are outside a safepoint. We
- // cannot do the obvious and set the active field of the SATB queue
- // when the thread is created given that, in some cases, safepoints
- // might happen between the JavaThread constructor being called and the
- // thread being added to the Java thread list (an example of this is
- // when the structure for the DestroyJavaVM thread is created).
-#if INCLUDE_ALL_GCS
- void initialize_queues();
-#else // INCLUDE_ALL_GCS
- void initialize_queues() { }
-#endif // INCLUDE_ALL_GCS
-
// Machine dependent stuff
#include OS_CPU_HEADER(thread)
--- a/src/hotspot/share/runtime/vmStructs.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/runtime/vmStructs.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -514,9 +514,8 @@
\
nonstatic_field(GenCollectedHeap, _young_gen, Generation*) \
nonstatic_field(GenCollectedHeap, _old_gen, Generation*) \
- \
- nonstatic_field(GenCollectorPolicy, _young_gen_spec, GenerationSpec*) \
- nonstatic_field(GenCollectorPolicy, _old_gen_spec, GenerationSpec*) \
+ nonstatic_field(GenCollectedHeap, _young_gen_spec, GenerationSpec*) \
+ nonstatic_field(GenCollectedHeap, _old_gen_spec, GenerationSpec*) \
\
nonstatic_field(HeapWord, i, char*) \
\
@@ -1470,7 +1469,6 @@
declare_type(DefNewGeneration, Generation) \
declare_type(CardGeneration, Generation) \
declare_type(TenuredGeneration, CardGeneration) \
- declare_toplevel_type(GenCollectorPolicy) \
declare_toplevel_type(Space) \
declare_type(CompactibleSpace, Space) \
declare_type(ContiguousSpace, CompactibleSpace) \
--- a/src/hotspot/share/services/allocationContextService.hpp Thu Mar 01 01:30:10 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SERVICES_ALLOCATION_CONTEXT_SERVICE_HPP
-#define SHARE_VM_SERVICES_ALLOCATION_CONTEXT_SERVICE_HPP
-
-#include "utilities/exceptions.hpp"
-
-class AllocationContextService: public AllStatic {
-public:
- static inline bool should_notify();
- static inline void notify(TRAPS);
-};
-
-bool AllocationContextService::should_notify() { return false; }
-void AllocationContextService::notify(TRAPS) { }
-
-#endif // SHARE_VM_SERVICES_ALLOCATION_CONTEXT_SERVICE_HPP
--- a/src/hotspot/share/services/attachListener.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/services/attachListener.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
#include "gc/shared/vmGCOperations.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "prims/jvmtiExport.hpp"
#include "runtime/arguments.hpp"
#include "runtime/globals.hpp"
--- a/src/hotspot/share/services/diagnosticCommand.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/services/diagnosticCommand.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2018, 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
@@ -31,6 +31,7 @@
#include "gc/shared/vmGCOperations.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "runtime/globals.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/os.hpp"
@@ -88,6 +89,7 @@
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHierarchyDCmd>(full_export, true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SymboltableDCmd>(full_export, true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<StringtableDCmd>(full_export, true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<MetaspaceDCmd>(full_export, true, false));
#if INCLUDE_JVMTI // Both JVMTI and SERVICES have to be enabled to have this dcmd
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JVMTIAgentLoadDCmd>(full_export, true, false));
#endif // INCLUDE_JVMTI
--- a/src/hotspot/share/services/diagnosticCommand.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/services/diagnosticCommand.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2018, 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
@@ -839,4 +839,25 @@
virtual void execute(DCmdSource source, TRAPS);
};
+class MetaspaceDCmd : public DCmd {
+public:
+ MetaspaceDCmd(outputStream* output, bool heap);
+ static const char* name() {
+ return "VM.metaspace";
+ }
+ static const char* description() {
+ return "Prints the statistics for the metaspace";
+ }
+ static const char* impact() {
+ return "Medium: Depends on number of classes loaded.";
+ }
+ static const JavaPermission permission() {
+ JavaPermission p = {"java.lang.management.ManagementPermission",
+ "monitor", NULL};
+ return p;
+ }
+ static int num_arguments() { return 0; }
+ virtual void execute(DCmdSource source, TRAPS);
+};
+
#endif // SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP
--- a/src/hotspot/share/services/heapDumper.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/services/heapDumper.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -35,6 +35,7 @@
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jniHandles.hpp"
#include "runtime/os.hpp"
--- a/src/hotspot/share/services/management.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/services/management.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -33,6 +33,7 @@
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "runtime/arguments.hpp"
#include "runtime/globals.hpp"
#include "runtime/handles.inline.hpp"
--- a/src/hotspot/share/services/memReporter.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/services/memReporter.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -291,7 +291,7 @@
outputStream* out = output();
const char* scale = current_scale();
const NativeCallStack* stack = reserved_rgn->call_stack();
- bool all_committed = reserved_rgn->all_committed();
+ bool all_committed = reserved_rgn->size() == reserved_rgn->committed_size();
const char* region_type = (all_committed ? "reserved and committed" : "reserved");
out->print_cr(" ");
print_virtual_memory_region(region_type, reserved_rgn->base(), reserved_rgn->size());
@@ -303,7 +303,17 @@
stack->print_on(out, 4);
}
- if (all_committed) return;
+ if (all_committed) {
+ CommittedRegionIterator itr = reserved_rgn->iterate_committed_regions();
+ const CommittedMemoryRegion* committed_rgn = itr.next();
+ if (committed_rgn->size() == reserved_rgn->size() && committed_rgn->call_stack()->equals(*stack)) {
+ // One region spanning the entire reserved region, with the same stack trace.
+ // Don't print this regions because the "reserved and committed" line above
+ // already indicates that the region is comitted.
+ assert(itr.next() == NULL, "Unexpectedly more than one regions");
+ return;
+ }
+ }
CommittedRegionIterator itr = reserved_rgn->iterate_committed_regions();
const CommittedMemoryRegion* committed_rgn;
@@ -745,4 +755,3 @@
out->print_cr(")\n");
}
-
--- a/src/hotspot/share/services/memTracker.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/services/memTracker.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -113,6 +113,8 @@
};
class MemTracker : AllStatic {
+ friend class VirtualMemoryTrackerTest;
+
public:
static inline NMT_TrackingLevel tracking_level() {
if (_tracking_level == NMT_unknown) {
@@ -215,8 +217,7 @@
if (addr != NULL) {
ThreadCritical tc;
if (tracking_level() < NMT_summary) return;
- VirtualMemoryTracker::add_reserved_region((address)addr, size,
- stack, flag, true);
+ VirtualMemoryTracker::add_reserved_region((address)addr, size, stack, flag);
VirtualMemoryTracker::add_committed_region((address)addr, size, stack);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/services/metaspaceDCmd.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#include "precompiled.hpp"
+#include "memory/metaspace.hpp"
+#include "services/diagnosticCommand.hpp"
+
+MetaspaceDCmd::MetaspaceDCmd(outputStream* output, bool heap): DCmd(output, heap) {
+}
+
+void MetaspaceDCmd::execute(DCmdSource source, TRAPS) {
+ const size_t scale = 1 * K;
+ VM_PrintMetadata op(output(), scale);
+ VMThread::execute(&op);
+}
+
--- a/src/hotspot/share/services/nmtDCmd.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/services/nmtDCmd.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -40,8 +40,6 @@
_detail("detail", "request runtime to report memory allocation >= "
"1K by each callsite.",
"BOOLEAN", false, "false"),
- _metadata("metadata", "request runtime to report metadata information",
- "BOOLEAN", false, "false"),
_baseline("baseline", "request runtime to baseline current memory usage, " \
"so it can be compared against in later time.",
"BOOLEAN", false, "false"),
@@ -61,7 +59,6 @@
"STRING", false, "KB") {
_dcmdparser.add_dcmd_option(&_summary);
_dcmdparser.add_dcmd_option(&_detail);
- _dcmdparser.add_dcmd_option(&_metadata);
_dcmdparser.add_dcmd_option(&_baseline);
_dcmdparser.add_dcmd_option(&_summary_diff);
_dcmdparser.add_dcmd_option(&_detail_diff);
@@ -97,7 +94,6 @@
int nopt = 0;
if (_summary.is_set() && _summary.value()) { ++nopt; }
if (_detail.is_set() && _detail.value()) { ++nopt; }
- if (_metadata.is_set() && _metadata.value()) { ++nopt; }
if (_baseline.is_set() && _baseline.value()) { ++nopt; }
if (_summary_diff.is_set() && _summary_diff.value()) { ++nopt; }
if (_detail_diff.is_set() && _detail_diff.value()) { ++nopt; }
@@ -127,10 +123,6 @@
return;
}
report(false, scale_unit);
- } else if (_metadata.value()) {
- size_t scale = get_scale(_scale.value());
- VM_PrintMetadata op(output(), scale);
- VMThread::execute(&op);
} else if (_baseline.value()) {
MemBaseline& baseline = MemTracker::get_baseline();
if (!baseline.baseline(MemTracker::tracking_level() != NMT_detail)) {
--- a/src/hotspot/share/services/nmtDCmd.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/services/nmtDCmd.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -39,7 +39,6 @@
protected:
DCmdArgument<bool> _summary;
DCmdArgument<bool> _detail;
- DCmdArgument<bool> _metadata;
DCmdArgument<bool> _baseline;
DCmdArgument<bool> _summary_diff;
DCmdArgument<bool> _detail_diff;
--- a/src/hotspot/share/services/serviceUtil.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/services/serviceUtil.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -63,6 +63,7 @@
return true;
}
}
+ fatal("visible_oop: should never reach here #1");
return false;
}
// object arrays are visible if they aren't system object arrays
@@ -74,6 +75,7 @@
return true;
}
// everything else (Method*s, ...) aren't visible
+ fatal("visible_oop: should never reach here #2");
return false;
}; // end of visible_oop()
--- a/src/hotspot/share/services/virtualMemoryTracker.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/services/virtualMemoryTracker.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, 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
@@ -48,57 +48,105 @@
return r1.compare(r2);
}
+static bool is_mergeable_with(CommittedMemoryRegion* rgn, address addr, size_t size, const NativeCallStack& stack) {
+ return rgn->adjacent_to(addr, size) && rgn->call_stack()->equals(stack);
+}
+
+static bool is_same_as(CommittedMemoryRegion* rgn, address addr, size_t size, const NativeCallStack& stack) {
+ // It would have made sense to use rgn->equals(...), but equals returns true for overlapping regions.
+ return rgn->same_region(addr, size) && rgn->call_stack()->equals(stack);
+}
+
+static LinkedListNode<CommittedMemoryRegion>* find_preceding_node_from(LinkedListNode<CommittedMemoryRegion>* from, address addr) {
+ LinkedListNode<CommittedMemoryRegion>* preceding = NULL;
+
+ for (LinkedListNode<CommittedMemoryRegion>* node = from; node != NULL; node = node->next()) {
+ CommittedMemoryRegion* rgn = node->data();
+
+ // We searched past the region start.
+ if (rgn->end() > addr) {
+ break;
+ }
+
+ preceding = node;
+ }
+
+ return preceding;
+}
+
+static bool try_merge_with(LinkedListNode<CommittedMemoryRegion>* node, address addr, size_t size, const NativeCallStack& stack) {
+ if (node != NULL) {
+ CommittedMemoryRegion* rgn = node->data();
+
+ if (is_mergeable_with(rgn, addr, size, stack)) {
+ rgn->expand_region(addr, size);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static bool try_merge_with(LinkedListNode<CommittedMemoryRegion>* node, LinkedListNode<CommittedMemoryRegion>* other) {
+ if (other == NULL) {
+ return false;
+ }
+
+ CommittedMemoryRegion* rgn = other->data();
+ return try_merge_with(node, rgn->base(), rgn->size(), *rgn->call_stack());
+}
+
bool ReservedMemoryRegion::add_committed_region(address addr, size_t size, const NativeCallStack& stack) {
assert(addr != NULL, "Invalid address");
assert(size > 0, "Invalid size");
assert(contain_region(addr, size), "Not contain this region");
- if (all_committed()) return true;
+ // Find the region that fully precedes the [addr, addr + size) region.
+ LinkedListNode<CommittedMemoryRegion>* prev = find_preceding_node_from(_committed_regions.head(), addr);
+ LinkedListNode<CommittedMemoryRegion>* next = (prev != NULL ? prev->next() : _committed_regions.head());
- CommittedMemoryRegion committed_rgn(addr, size, stack);
- LinkedListNode<CommittedMemoryRegion>* node = _committed_regions.head();
-
- while (node != NULL) {
- CommittedMemoryRegion* rgn = node->data();
- if (rgn->same_region(addr, size)) {
+ if (next != NULL) {
+ // Ignore request if region already exists.
+ if (is_same_as(next->data(), addr, size, stack)) {
return true;
}
- if (rgn->adjacent_to(addr, size)) {
- // special case to expand prior region if there is no next region
- LinkedListNode<CommittedMemoryRegion>* next = node->next();
- if (next == NULL && rgn->call_stack()->equals(stack)) {
- VirtualMemorySummary::record_uncommitted_memory(rgn->size(), flag());
- // the two adjacent regions have the same call stack, merge them
- rgn->expand_region(addr, size);
- VirtualMemorySummary::record_committed_memory(rgn->size(), flag());
- return true;
- }
- }
+ // The new region is after prev, and either overlaps with the
+ // next region (and maybe more regions), or overlaps with no region.
+ if (next->data()->overlap_region(addr, size)) {
+ // Remove _all_ overlapping regions, and parts of regions,
+ // in preparation for the addition of this new region.
+ remove_uncommitted_region(addr, size);
- if (rgn->overlap_region(addr, size)) {
- // Clear a space for this region in the case it overlaps with any regions.
- remove_uncommitted_region(addr, size);
- break; // commit below
+ // The remove could have split a region into two and created a
+ // new prev region. Need to reset the prev and next pointers.
+ prev = find_preceding_node_from((prev != NULL ? prev : _committed_regions.head()), addr);
+ next = (prev != NULL ? prev->next() : _committed_regions.head());
}
- if (rgn->end() >= addr + size){
- break;
- }
- node = node->next();
}
- // New committed region
- VirtualMemorySummary::record_committed_memory(size, flag());
- return add_committed_region(committed_rgn);
+ // At this point the previous overlapping regions have been
+ // cleared, and the full region is guaranteed to be inserted.
+ VirtualMemorySummary::record_committed_memory(size, flag());
+
+ // Try to merge with prev and possibly next.
+ if (try_merge_with(prev, addr, size, stack)) {
+ if (try_merge_with(prev, next)) {
+ // prev was expanded to contain the new region
+ // and next, need to remove next from the list
+ _committed_regions.remove_after(prev);
+ }
+
+ return true;
}
-void ReservedMemoryRegion::set_all_committed(bool b) {
- if (all_committed() != b) {
- _all_committed = b;
- if (b) {
- VirtualMemorySummary::record_committed_memory(size(), flag());
- }
+ // Didn't merge with prev, try with next.
+ if (try_merge_with(next, addr, size, stack)) {
+ return true;
}
+
+ // Couldn't merge with any regions - create a new region.
+ return add_committed_region(CommittedMemoryRegion(addr, size, stack));
}
bool ReservedMemoryRegion::remove_uncommitted_region(LinkedListNode<CommittedMemoryRegion>* node,
@@ -135,94 +183,57 @@
}
bool ReservedMemoryRegion::remove_uncommitted_region(address addr, size_t sz) {
- // uncommit stack guard pages
- if (flag() == mtThreadStack && !same_region(addr, sz)) {
- return true;
- }
-
assert(addr != NULL, "Invalid address");
assert(sz > 0, "Invalid size");
- if (all_committed()) {
- assert(_committed_regions.is_empty(), "Sanity check");
- assert(contain_region(addr, sz), "Reserved region does not contain this region");
- set_all_committed(false);
- VirtualMemorySummary::record_uncommitted_memory(sz, flag());
- if (same_region(addr, sz)) {
+ CommittedMemoryRegion del_rgn(addr, sz, *call_stack());
+ address end = addr + sz;
+
+ LinkedListNode<CommittedMemoryRegion>* head = _committed_regions.head();
+ LinkedListNode<CommittedMemoryRegion>* prev = NULL;
+ CommittedMemoryRegion* crgn;
+
+ while (head != NULL) {
+ crgn = head->data();
+
+ if (crgn->same_region(addr, sz)) {
+ VirtualMemorySummary::record_uncommitted_memory(crgn->size(), flag());
+ _committed_regions.remove_after(prev);
return true;
- } else {
- CommittedMemoryRegion rgn(base(), size(), *call_stack());
- if (rgn.base() == addr || rgn.end() == (addr + sz)) {
- rgn.exclude_region(addr, sz);
- return add_committed_region(rgn);
+ }
+
+ // del_rgn contains crgn
+ if (del_rgn.contain_region(crgn->base(), crgn->size())) {
+ VirtualMemorySummary::record_uncommitted_memory(crgn->size(), flag());
+ head = head->next();
+ _committed_regions.remove_after(prev);
+ continue; // don't update head or prev
+ }
+
+ // Found addr in the current crgn. There are 2 subcases:
+ if (crgn->contain_address(addr)) {
+
+ // (1) Found addr+size in current crgn as well. (del_rgn is contained in crgn)
+ if (crgn->contain_address(end - 1)) {
+ VirtualMemorySummary::record_uncommitted_memory(sz, flag());
+ return remove_uncommitted_region(head, addr, sz); // done!
} else {
- // split this region
- // top of the whole region
- address top =rgn.end();
- // use this region for lower part
- size_t exclude_size = rgn.end() - addr;
- rgn.exclude_region(addr, exclude_size);
- if (add_committed_region(rgn)) {
- // higher part
- address high_base = addr + sz;
- size_t high_size = top - high_base;
- CommittedMemoryRegion high_rgn(high_base, high_size, NativeCallStack::EMPTY_STACK);
- return add_committed_region(high_rgn);
- } else {
- return false;
- }
- }
- }
- } else {
- CommittedMemoryRegion del_rgn(addr, sz, *call_stack());
- address end = addr + sz;
-
- LinkedListNode<CommittedMemoryRegion>* head = _committed_regions.head();
- LinkedListNode<CommittedMemoryRegion>* prev = NULL;
- CommittedMemoryRegion* crgn;
-
- while (head != NULL) {
- crgn = head->data();
-
- if (crgn->same_region(addr, sz)) {
- VirtualMemorySummary::record_uncommitted_memory(crgn->size(), flag());
- _committed_regions.remove_after(prev);
- return true;
+ // (2) Did not find del_rgn's end in crgn.
+ size_t size = crgn->end() - del_rgn.base();
+ crgn->exclude_region(addr, size);
+ VirtualMemorySummary::record_uncommitted_memory(size, flag());
}
- // del_rgn contains crgn
- if (del_rgn.contain_region(crgn->base(), crgn->size())) {
- VirtualMemorySummary::record_uncommitted_memory(crgn->size(), flag());
- head = head->next();
- _committed_regions.remove_after(prev);
- continue; // don't update head or prev
- }
-
- // Found addr in the current crgn. There are 2 subcases:
- if (crgn->contain_address(addr)) {
+ } else if (crgn->contain_address(end - 1)) {
+ // Found del_rgn's end, but not its base addr.
+ size_t size = del_rgn.end() - crgn->base();
+ crgn->exclude_region(crgn->base(), size);
+ VirtualMemorySummary::record_uncommitted_memory(size, flag());
+ return true; // should be done if the list is sorted properly!
+ }
- // (1) Found addr+size in current crgn as well. (del_rgn is contained in crgn)
- if (crgn->contain_address(end - 1)) {
- VirtualMemorySummary::record_uncommitted_memory(sz, flag());
- return remove_uncommitted_region(head, addr, sz); // done!
- } else {
- // (2) Did not find del_rgn's end in crgn.
- size_t size = crgn->end() - del_rgn.base();
- crgn->exclude_region(addr, size);
- VirtualMemorySummary::record_uncommitted_memory(size, flag());
- }
-
- } else if (crgn->contain_address(end - 1)) {
- // Found del_rgn's end, but not its base addr.
- size_t size = del_rgn.end() - crgn->base();
- crgn->exclude_region(crgn->base(), size);
- VirtualMemorySummary::record_uncommitted_memory(size, flag());
- return true; // should be done if the list is sorted properly!
- }
-
- prev = head;
- head = head->next();
- }
+ prev = head;
+ head = head->next();
}
return true;
@@ -256,18 +267,14 @@
}
size_t ReservedMemoryRegion::committed_size() const {
- if (all_committed()) {
- return size();
- } else {
- size_t committed = 0;
- LinkedListNode<CommittedMemoryRegion>* head =
- _committed_regions.head();
- while (head != NULL) {
- committed += head->data()->size();
- head = head->next();
- }
- return committed;
+ size_t committed = 0;
+ LinkedListNode<CommittedMemoryRegion>* head =
+ _committed_regions.head();
+ while (head != NULL) {
+ committed += head->data()->size();
+ head = head->next();
}
+ return committed;
}
void ReservedMemoryRegion::set_flag(MEMFLAGS f) {
@@ -296,22 +303,16 @@
}
bool VirtualMemoryTracker::add_reserved_region(address base_addr, size_t size,
- const NativeCallStack& stack, MEMFLAGS flag, bool all_committed) {
+ const NativeCallStack& stack, MEMFLAGS flag) {
assert(base_addr != NULL, "Invalid address");
assert(size > 0, "Invalid size");
assert(_reserved_regions != NULL, "Sanity check");
ReservedMemoryRegion rgn(base_addr, size, stack, flag);
ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn);
- LinkedListNode<ReservedMemoryRegion>* node;
+
if (reserved_rgn == NULL) {
VirtualMemorySummary::record_reserved_memory(size, flag);
- node = _reserved_regions->add(rgn);
- if (node != NULL) {
- node->data()->set_all_committed(all_committed);
- return true;
- } else {
- return false;
- }
+ return _reserved_regions->add(rgn) != NULL;
} else {
if (reserved_rgn->same_region(base_addr, size)) {
reserved_rgn->set_call_stack(stack);
--- a/src/hotspot/share/services/virtualMemoryTracker.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/services/virtualMemoryTracker.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -210,6 +210,8 @@
inline bool overlap_region(address addr, size_t sz) const {
+ assert(sz > 0, "Invalid size");
+ assert(size() > 0, "Invalid size");
VirtualMemoryRegion rgn(addr, sz);
return contain_address(addr) ||
contain_address(addr + sz - 1) ||
@@ -295,18 +297,14 @@
NativeCallStack _stack;
MEMFLAGS _flag;
- bool _all_committed;
-
public:
ReservedMemoryRegion(address base, size_t size, const NativeCallStack& stack,
MEMFLAGS flag = mtNone) :
- VirtualMemoryRegion(base, size), _stack(stack), _flag(flag),
- _all_committed(false) { }
+ VirtualMemoryRegion(base, size), _stack(stack), _flag(flag) { }
ReservedMemoryRegion(address base, size_t size) :
- VirtualMemoryRegion(base, size), _stack(NativeCallStack::EMPTY_STACK), _flag(mtNone),
- _all_committed(false) { }
+ VirtualMemoryRegion(base, size), _stack(NativeCallStack::EMPTY_STACK), _flag(mtNone) { }
// Copy constructor
ReservedMemoryRegion(const ReservedMemoryRegion& rr) :
@@ -347,9 +345,6 @@
// the new region
void move_committed_regions(address addr, ReservedMemoryRegion& rgn);
- inline bool all_committed() const { return _all_committed; }
- void set_all_committed(bool b);
-
CommittedRegionIterator iterate_committed_regions() const {
return CommittedRegionIterator(_committed_regions.head());
}
@@ -360,17 +355,14 @@
_stack = *other.call_stack();
_flag = other.flag();
- _all_committed = other.all_committed();
- if (other.all_committed()) {
- set_all_committed(true);
- } else {
- CommittedRegionIterator itr = other.iterate_committed_regions();
- const CommittedMemoryRegion* rgn = itr.next();
- while (rgn != NULL) {
- _committed_regions.add(*rgn);
- rgn = itr.next();
- }
+
+ CommittedRegionIterator itr = other.iterate_committed_regions();
+ const CommittedMemoryRegion* rgn = itr.next();
+ while (rgn != NULL) {
+ _committed_regions.add(*rgn);
+ rgn = itr.next();
}
+
return *this;
}
@@ -396,14 +388,15 @@
// Main class called from MemTracker to track virtual memory allocations, commits and releases.
class VirtualMemoryTracker : AllStatic {
+ friend class VirtualMemoryTrackerTest;
+
public:
static bool initialize(NMT_TrackingLevel level);
// Late phase initialization
static bool late_initialize(NMT_TrackingLevel level);
- static bool add_reserved_region (address base_addr, size_t size, const NativeCallStack& stack,
- MEMFLAGS flag = mtNone, bool all_committed = false);
+ static bool add_reserved_region (address base_addr, size_t size, const NativeCallStack& stack, MEMFLAGS flag = mtNone);
static bool add_committed_region (address base_addr, size_t size, const NativeCallStack& stack);
static bool remove_uncommitted_region (address base_addr, size_t size);
--- a/src/hotspot/share/utilities/copy.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/utilities/copy.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -27,6 +27,7 @@
#include "runtime/stubRoutines.hpp"
#include "utilities/align.hpp"
+#include "utilities/debug.hpp"
#include "utilities/macros.hpp"
// Assembly code for platforms that need it.
@@ -88,20 +89,20 @@
// Word-aligned words, conjoint, not atomic on each word
static void conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
- assert_params_ok(from, to, LogHeapWordSize);
+ assert_params_ok(from, to, HeapWordSize);
pd_conjoint_words(from, to, count);
}
// Word-aligned words, disjoint, not atomic on each word
static void disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
- assert_params_ok(from, to, LogHeapWordSize);
+ assert_params_ok(from, to, HeapWordSize);
assert_disjoint(from, to, count);
pd_disjoint_words(from, to, count);
}
// Word-aligned words, disjoint, atomic on each word
static void disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) {
- assert_params_ok(from, to, LogHeapWordSize);
+ assert_params_ok(from, to, HeapWordSize);
assert_disjoint(from, to, count);
pd_disjoint_words_atomic(from, to, count);
}
@@ -133,32 +134,32 @@
// jshorts, conjoint, atomic on each jshort
static void conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) {
- assert_params_ok(from, to, LogBytesPerShort);
+ assert_params_ok(from, to, BytesPerShort);
pd_conjoint_jshorts_atomic(from, to, count);
}
// jints, conjoint, atomic on each jint
static void conjoint_jints_atomic(const jint* from, jint* to, size_t count) {
- assert_params_ok(from, to, LogBytesPerInt);
+ assert_params_ok(from, to, BytesPerInt);
pd_conjoint_jints_atomic(from, to, count);
}
// jlongs, conjoint, atomic on each jlong
static void conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) {
- assert_params_ok(from, to, LogBytesPerLong);
+ assert_params_ok(from, to, BytesPerLong);
pd_conjoint_jlongs_atomic(from, to, count);
}
// oops, conjoint, atomic on each oop
static void conjoint_oops_atomic(const oop* from, oop* to, size_t count) {
- assert_params_ok(from, to, LogBytesPerHeapOop);
+ assert_params_ok(from, to, BytesPerHeapOop);
pd_conjoint_oops_atomic(from, to, count);
}
// overloaded for UseCompressedOops
static void conjoint_oops_atomic(const narrowOop* from, narrowOop* to, size_t count) {
assert(sizeof(narrowOop) == sizeof(jint), "this cast is wrong");
- assert_params_ok(from, to, LogBytesPerInt);
+ assert_params_ok(from, to, BytesPerInt);
pd_conjoint_jints_atomic((const jint*)from, (jint*)to, count);
}
@@ -175,25 +176,25 @@
// jshorts, conjoint array, atomic on each jshort
static void arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) {
- assert_params_ok(from, to, LogBytesPerShort);
+ assert_params_ok(from, to, BytesPerShort);
pd_arrayof_conjoint_jshorts(from, to, count);
}
// jints, conjoint array, atomic on each jint
static void arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) {
- assert_params_ok(from, to, LogBytesPerInt);
+ assert_params_ok(from, to, BytesPerInt);
pd_arrayof_conjoint_jints(from, to, count);
}
// jlongs, conjoint array, atomic on each jlong
static void arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) {
- assert_params_ok(from, to, LogBytesPerLong);
+ assert_params_ok(from, to, BytesPerLong);
pd_arrayof_conjoint_jlongs(from, to, count);
}
// oops, conjoint array, atomic on each oop
static void arrayof_conjoint_oops(const HeapWord* from, HeapWord* to, size_t count) {
- assert_params_ok(from, to, LogBytesPerHeapOop);
+ assert_params_ok(from, to, BytesPerHeapOop);
pd_arrayof_conjoint_oops(from, to, count);
}
@@ -202,7 +203,7 @@
// Copy word-aligned words from higher to lower addresses, not atomic on each word
inline static void conjoint_words_to_lower(const HeapWord* from, HeapWord* to, size_t byte_count) {
// byte_count is in bytes to check its alignment
- assert_params_ok(from, to, LogHeapWordSize);
+ assert_params_ok(from, to, HeapWordSize);
assert_byte_count_ok(byte_count, HeapWordSize);
size_t count = align_up(byte_count, HeapWordSize) >> LogHeapWordSize;
@@ -216,7 +217,7 @@
// Copy word-aligned words from lower to higher addresses, not atomic on each word
inline static void conjoint_words_to_higher(const HeapWord* from, HeapWord* to, size_t byte_count) {
// byte_count is in bytes to check its alignment
- assert_params_ok(from, to, LogHeapWordSize);
+ assert_params_ok(from, to, HeapWordSize);
assert_byte_count_ok(byte_count, HeapWordSize);
size_t count = align_up(byte_count, HeapWordSize) >> LogHeapWordSize;
@@ -271,7 +272,7 @@
// Fill word-aligned words, not atomic on each word
// set_words
static void fill_to_words(HeapWord* to, size_t count, juint value = 0) {
- assert_params_ok(to, LogHeapWordSize);
+ assert_params_ok(to, HeapWordSize);
pd_fill_to_words(to, count, value);
}
@@ -295,7 +296,7 @@
// Zero word-aligned words, not atomic on each word
static void zero_to_words(HeapWord* to, size_t count) {
- assert_params_ok(to, LogHeapWordSize);
+ assert_params_ok(to, HeapWordSize);
pd_zero_to_words(to, count);
}
@@ -315,49 +316,29 @@
// These methods raise a fatal if they detect a problem.
static void assert_disjoint(const HeapWord* from, HeapWord* to, size_t count) {
-#ifdef ASSERT
- if (!params_disjoint(from, to, count))
- basic_fatal("source and dest overlap");
-#endif
+ assert(params_disjoint(from, to, count), "source and dest overlap");
+ }
+
+ static void assert_params_ok(const void* from, void* to, intptr_t alignment) {
+ assert(is_aligned(from, alignment), "must be aligned: " INTPTR_FORMAT, p2i(from));
+ assert(is_aligned(to, alignment), "must be aligned: " INTPTR_FORMAT, p2i(to));
}
- static void assert_params_ok(const void* from, void* to, intptr_t log_align) {
-#ifdef ASSERT
- if (mask_bits((uintptr_t)from, right_n_bits(log_align)) != 0)
- basic_fatal("not aligned");
- if (mask_bits((uintptr_t)to, right_n_bits(log_align)) != 0)
- basic_fatal("not aligned");
-#endif
+ static void assert_params_ok(HeapWord* to, intptr_t alignment) {
+ assert(is_aligned(to, alignment), "must be aligned: " INTPTR_FORMAT, p2i(to));
}
- static void assert_params_ok(HeapWord* to, intptr_t log_align) {
-#ifdef ASSERT
- if (mask_bits((uintptr_t)to, right_n_bits(log_align)) != 0)
- basic_fatal("not word aligned");
-#endif
- }
static void assert_params_aligned(const HeapWord* from, HeapWord* to) {
-#ifdef ASSERT
- if (mask_bits((uintptr_t)from, BytesPerLong-1) != 0)
- basic_fatal("not long aligned");
- if (mask_bits((uintptr_t)to, BytesPerLong-1) != 0)
- basic_fatal("not long aligned");
-#endif
+ assert(is_aligned(from, BytesPerLong), "must be aligned: " INTPTR_FORMAT, p2i(from));
+ assert(is_aligned(to, BytesPerLong), "must be aligned: " INTPTR_FORMAT, p2i(to));
}
static void assert_params_aligned(HeapWord* to) {
-#ifdef ASSERT
- if (mask_bits((uintptr_t)to, BytesPerLong-1) != 0)
- basic_fatal("not long aligned");
-#endif
+ assert(is_aligned(to, BytesPerLong), "must be aligned: " INTPTR_FORMAT, p2i(to));
}
static void assert_byte_count_ok(size_t byte_count, size_t unit_size) {
-#ifdef ASSERT
- if (!is_aligned(byte_count, unit_size)) {
- basic_fatal("byte count must be aligned");
- }
-#endif
+ assert(is_aligned(byte_count, unit_size), "byte count must be aligned");
}
// Platform dependent implementations of the above methods.
--- a/src/hotspot/share/utilities/debug.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/utilities/debug.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -503,12 +503,6 @@
SystemDictionary::print();
}
-
-extern "C" void safepoints() {
- Command c("safepoints");
- SafepointSynchronize::print_state();
-}
-
#endif // !PRODUCT
extern "C" void pss() { // print all stacks
--- a/src/hotspot/share/utilities/globalDefinitions.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/utilities/globalDefinitions.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -48,10 +48,6 @@
// Oop encoding heap max
uint64_t OopEncodingHeapMax = 0;
-void basic_fatal(const char* msg) {
- fatal("%s", msg);
-}
-
// Something to help porters sleep at night
void basic_types_init() {
--- a/src/hotspot/share/utilities/globalDefinitions.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/utilities/globalDefinitions.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -939,15 +939,12 @@
class methodHandle;
class JavaCallArguments;
-// Basic support for errors.
-extern void basic_fatal(const char* msg);
-
//----------------------------------------------------------------------------------------------------
// Special constants for debugging
const jint badInt = -3; // generic "bad int" value
-const long badAddressVal = -2; // generic "bad address" value
-const long badOopVal = -1; // generic "bad oop" value
+const intptr_t badAddressVal = -2; // generic "bad address" value
+const intptr_t badOopVal = -1; // generic "bad oop" value
const intptr_t badHeapOopVal = (intptr_t) CONST64(0x2BAD4B0BBAADBABE); // value used to zap heap after GC
const int badStackSegVal = 0xCA; // value used to zap stack segments
const int badHandleValue = 0xBC; // value used to zap vm handle area
--- a/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,7 @@
# include <string.h>
# include <stdarg.h>
# include <stdlib.h>
+# include <stdint.h>
# include <stddef.h>// for offsetof
# include <io.h> // for stream.cpp
# include <float.h> // for _isnan
@@ -42,6 +43,7 @@
# include <time.h>
# include <fcntl.h>
# include <limits.h>
+# include <inttypes.h>
// Need this on windows to get the math constants (e.g., M_PI).
#define _USE_MATH_DEFINES
# include <math.h>
@@ -77,43 +79,18 @@
// pointer is stored as integer value.
#define NULL_WORD NULL
-// Compiler-specific primitive types
-typedef unsigned __int8 uint8_t;
-typedef unsigned __int16 uint16_t;
-typedef unsigned __int32 uint32_t;
-typedef unsigned __int64 uint64_t;
-
#ifdef _WIN64
-typedef unsigned __int64 uintptr_t;
+typedef int64_t ssize_t;
#else
-typedef unsigned int uintptr_t;
-#endif
-typedef signed __int8 int8_t;
-typedef signed __int16 int16_t;
-typedef signed __int32 int32_t;
-typedef signed __int64 int64_t;
-#ifdef _WIN64
-typedef signed __int64 intptr_t;
-typedef signed __int64 ssize_t;
-#else
-typedef signed int intptr_t;
-typedef signed int ssize_t;
-#endif
-
-#ifndef UINTPTR_MAX
-#ifdef _WIN64
-#define UINTPTR_MAX _UI64_MAX
-#else
-#define UINTPTR_MAX _UI32_MAX
-#endif
+typedef int32_t ssize_t;
#endif
// Additional Java basic types
-typedef unsigned char jubyte;
-typedef unsigned short jushort;
-typedef unsigned int juint;
-typedef unsigned __int64 julong;
+typedef uint8_t jubyte;
+typedef uint16_t jushort;
+typedef uint32_t juint;
+typedef uint64_t julong;
// Non-standard stdlib-like stuff:
inline int strcasecmp(const char *s1, const char *s2) { return _stricmp(s1,s2); }
@@ -187,26 +164,6 @@
// Formatting.
#define FORMAT64_MODIFIER "I64"
-// Visual Studio doesn't provide inttypes.h so provide appropriate definitions here.
-// The 32 bits ones might need I32 but seem to work ok without it.
-#define PRId32 "d"
-#define PRIu32 "u"
-#define PRIx32 "x"
-
-#define PRId64 "I64d"
-#define PRIu64 "I64u"
-#define PRIx64 "I64x"
-
-#ifdef _LP64
-#define PRIdPTR "I64d"
-#define PRIuPTR "I64u"
-#define PRIxPTR "I64x"
-#else
-#define PRIdPTR "d"
-#define PRIuPTR "u"
-#define PRIxPTR "x"
-#endif
-
#define offset_of(klass,field) offsetof(klass,field)
#ifndef USE_LIBRARY_BASED_TLS_ONLY
--- a/src/java.base/share/classes/java/lang/ClassLoader.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/share/classes/java/lang/ClassLoader.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, 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
@@ -650,21 +650,6 @@
return lock;
}
- // This method is invoked by the virtual machine to load a class.
- private Class<?> loadClassInternal(String name)
- throws ClassNotFoundException
- {
- // For backward compatibility, explicitly lock on 'this' when
- // the current class loader is not parallel capable.
- if (parallelLockMap == null) {
- synchronized (this) {
- return loadClass(name);
- }
- } else {
- return loadClass(name);
- }
- }
-
// Invoked by the VM after loading class with this loader.
private void checkPackageAccess(Class<?> cls, ProtectionDomain pd) {
final SecurityManager sm = System.getSecurityManager();
--- a/src/java.base/share/classes/java/lang/System.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/share/classes/java/lang/System.java Thu Mar 01 01:35:46 2018 +0100
@@ -2080,8 +2080,8 @@
E[] getEnumConstantsShared(Class<E> klass) {
return klass.getEnumConstantsShared();
}
- public void blockedOn(Thread t, Interruptible b) {
- t.blockedOn(b);
+ public void blockedOn(Interruptible b) {
+ Thread.blockedOn(b);
}
public void registerShutdownHook(int slot, boolean registerShutdownInProgress, Runnable hook) {
Shutdown.add(slot, registerShutdownInProgress, hook);
--- a/src/java.base/share/classes/java/lang/Thread.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/share/classes/java/lang/Thread.java Thu Mar 01 01:35:46 2018 +0100
@@ -231,9 +231,10 @@
/* Set the blocker field; invoked via jdk.internal.misc.SharedSecrets
* from java.nio code
*/
- void blockedOn(Interruptible b) {
- synchronized (blockerLock) {
- blocker = b;
+ static void blockedOn(Interruptible b) {
+ Thread me = Thread.currentThread();
+ synchronized (me.blockerLock) {
+ me.blocker = b;
}
}
@@ -1006,18 +1007,22 @@
* @spec JSR-51
*/
public void interrupt() {
- if (this != Thread.currentThread())
+ Thread me = Thread.currentThread();
+ if (this != me)
checkAccess();
- synchronized (blockerLock) {
- Interruptible b = blocker;
- if (b != null) {
- interrupt0(); // Just to set the interrupt flag
- b.interrupt(this);
- return;
+ // set interrupt status
+ interrupt0();
+
+ // thread may be blocked in an I/O operation
+ if (this != me && blocker != null) {
+ synchronized (blockerLock) {
+ Interruptible b = blocker;
+ if (b != null) {
+ b.interrupt(this);
+ }
}
}
- interrupt0();
}
/**
--- a/src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java Thu Mar 01 01:35:46 2018 +0100
@@ -209,8 +209,7 @@
* Returns the result of invoking a method handle with the provided
* arguments.
*
- * @param lookup the lookup context describing the class performing the
- * operation (normally stacked by the JVM)
+ * @param lookup unused
* @param name unused
* @param type the type of the value to be returned, which must be
* compatible with the return type of the method handle
--- a/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Thu Mar 01 01:35:46 2018 +0100
@@ -928,6 +928,12 @@
if (member == null) return false;
if (member.isConstructor()) return false;
Class<?> cls = member.getDeclaringClass();
+ // Fast-path non-private members declared by MethodHandles, which is a common
+ // case
+ if (MethodHandle.class.isAssignableFrom(cls) && !member.isPrivate()) {
+ assert(isStaticallyInvocableType(member.getMethodOrFieldType()));
+ return true;
+ }
if (cls.isArray() || cls.isPrimitive())
return false; // FIXME
if (cls.isAnonymousClass() || cls.isLocalClass())
@@ -936,12 +942,8 @@
return false; // not on BCP
if (ReflectUtil.isVMAnonymousClass(cls)) // FIXME: switch to supported API once it is added
return false;
- MethodType mtype = member.getMethodOrFieldType();
- if (!isStaticallyNameable(mtype.returnType()))
+ if (!isStaticallyInvocableType(member.getMethodOrFieldType()))
return false;
- for (Class<?> ptype : mtype.parameterArray())
- if (!isStaticallyNameable(ptype))
- return false;
if (!member.isPrivate() && VerifyAccess.isSamePackage(MethodHandle.class, cls))
return true; // in java.lang.invoke package
if (member.isPublic() && isStaticallyNameable(cls))
@@ -949,9 +951,22 @@
return false;
}
+ private static boolean isStaticallyInvocableType(MethodType mtype) {
+ if (!isStaticallyNameable(mtype.returnType()))
+ return false;
+ for (Class<?> ptype : mtype.parameterArray())
+ if (!isStaticallyNameable(ptype))
+ return false;
+ return true;
+ }
+
static boolean isStaticallyNameable(Class<?> cls) {
if (cls == Object.class)
return true;
+ if (MethodHandle.class.isAssignableFrom(cls)) {
+ assert(!ReflectUtil.isVMAnonymousClass(cls));
+ return true;
+ }
while (cls.isArray())
cls = cls.getComponentType();
if (cls.isPrimitive())
--- a/src/java.base/share/classes/java/nio/channels/spi/AbstractInterruptibleChannel.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/share/classes/java/nio/channels/spi/AbstractInterruptibleChannel.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, 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
@@ -205,6 +205,6 @@
// -- jdk.internal.misc.SharedSecrets --
static void blockedOn(Interruptible intr) { // package-private
- SharedSecrets.getJavaLangAccess().blockedOn(Thread.currentThread(), intr);
+ SharedSecrets.getJavaLangAccess().blockedOn(intr);
}
}
--- a/src/java.base/share/classes/jdk/internal/loader/BootLoader.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/share/classes/jdk/internal/loader/BootLoader.java Thu Mar 01 01:35:46 2018 +0100
@@ -67,7 +67,7 @@
// ServiceCatalog for the boot class loader
private static final ServicesCatalog SERVICES_CATALOG = ServicesCatalog.create();
- // ClassLoaderValue map for boot class loader
+ // ClassLoaderValue map for the boot class loader
private static final ConcurrentHashMap<?, ?> CLASS_LOADER_VALUE_MAP
= new ConcurrentHashMap<>();
--- a/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java Thu Mar 01 01:35:46 2018 +0100
@@ -103,7 +103,7 @@
// parent ClassLoader
private final BuiltinClassLoader parent;
- // the URL class path or null if there is no class path
+ // the URL class path, or null if there is no class path
private final URLClassPath ucp;
--- a/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java Thu Mar 01 01:35:46 2018 +0100
@@ -54,39 +54,27 @@
private static final PlatformClassLoader PLATFORM_LOADER;
private static final AppClassLoader APP_LOADER;
- /**
- * Creates the built-in class loaders
- */
+ // Creates the built-in class loaders.
static {
-
// -Xbootclasspath/a or -javaagent with Boot-Class-Path attribute
- URLClassPath bcp = null;
- String s = VM.getSavedProperty("jdk.boot.class.path.append");
- if (s != null && s.length() > 0)
- bcp = new URLClassPath(s, true);
+ String append = VM.getSavedProperty("jdk.boot.class.path.append");
+ BOOT_LOADER =
+ new BootClassLoader((append != null && append.length() > 0)
+ ? new URLClassPath(append, true)
+ : null);
+ PLATFORM_LOADER = new PlatformClassLoader(BOOT_LOADER);
- // we have a class path if -cp is specified or -m is not specified.
- // If neither is specified then default to -cp <working directory>
- // If -cp is not specified and -m is specified, the value of
- // java.class.path is an empty string, then no class path.
- String mainMid = System.getProperty("jdk.module.main");
+ // A class path is required when no initial module is specified.
+ // In this case the class path defaults to "", meaning the current
+ // working directory. When an initial module is specified, on the
+ // contrary, we drop this historic interpretation of the empty
+ // string and instead treat it as unspecified.
String cp = System.getProperty("java.class.path");
- if (mainMid == null) {
- // no main module specified so class path required
- if (cp == null) {
- cp = "";
- }
- } else {
- // main module specified, ignore empty class path
- if (cp != null && cp.length() == 0) {
- cp = null;
- }
+ if (cp == null || cp.length() == 0) {
+ String initialModuleName = System.getProperty("jdk.module.main");
+ cp = (initialModuleName == null) ? "" : null;
}
URLClassPath ucp = new URLClassPath(cp, false);
-
- // create the class loaders
- BOOT_LOADER = new BootClassLoader(bcp);
- PLATFORM_LOADER = new PlatformClassLoader(BOOT_LOADER);
APP_LOADER = new AppClassLoader(PLATFORM_LOADER, ucp);
}
--- a/src/java.base/share/classes/jdk/internal/loader/Loader.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/share/classes/jdk/internal/loader/Loader.java Thu Mar 01 01:35:46 2018 +0100
@@ -63,7 +63,6 @@
import jdk.internal.misc.SharedSecrets;
import jdk.internal.module.Resources;
-
/**
* A class loader that loads classes and resources from a collection of
* modules, or from a single module where the class loader is a member
@@ -111,7 +110,7 @@
private final Map<ModuleReference, ModuleReader> moduleToReader
= new ConcurrentHashMap<>();
- // ACC used when loading classes and resources */
+ // ACC used when loading classes and resources
private final AccessControlContext acc;
/**
--- a/src/java.base/share/classes/jdk/internal/loader/LoaderPool.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/share/classes/jdk/internal/loader/LoaderPool.java Thu Mar 01 01:35:46 2018 +0100
@@ -83,4 +83,3 @@
}
}
-
--- a/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java Thu Mar 01 01:35:46 2018 +0100
@@ -43,8 +43,10 @@
import java.security.AccessController;
import java.security.CodeSigner;
import java.security.Permission;
+import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.security.cert.Certificate;
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -56,7 +58,6 @@
import java.util.NoSuchElementException;
import java.util.Properties;
import java.util.Set;
-import java.util.Stack;
import java.util.StringTokenizer;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
@@ -100,10 +101,10 @@
}
/* The original search path of URLs. */
- private final List<URL> path;
+ private final ArrayList<URL> path;
- /* The stack of unopened URLs */
- private final Stack<URL> urls = new Stack<>();
+ /* The deque of unopened URLs */
+ private final ArrayDeque<URL> unopenedUrls;
/* The resulting search path of Loaders */
private final ArrayList<Loader> loaders = new ArrayList<>();
@@ -137,12 +138,15 @@
public URLClassPath(URL[] urls,
URLStreamHandlerFactory factory,
AccessControlContext acc) {
- List<URL> path = new ArrayList<>(urls.length);
+ ArrayList<URL> path = new ArrayList<>(urls.length);
+ ArrayDeque<URL> unopenedUrls = new ArrayDeque<>(urls.length);
for (URL url : urls) {
path.add(url);
+ unopenedUrls.add(url);
}
this.path = path;
- push(urls);
+ this.unopenedUrls = unopenedUrls;
+
if (factory != null) {
jarHandler = factory.createURLStreamHandler("jar");
} else {
@@ -168,33 +172,31 @@
* @apiNote Used to create the application class path.
*/
URLClassPath(String cp, boolean skipEmptyElements) {
- List<URL> path = new ArrayList<>();
+ ArrayList<URL> path = new ArrayList<>();
if (cp != null) {
// map each element of class path to a file URL
- int off = 0;
- int next;
- while ((next = cp.indexOf(File.pathSeparator, off)) != -1) {
- String element = cp.substring(off, next);
+ int off = 0, next;
+ do {
+ next = cp.indexOf(File.pathSeparator, off);
+ String element = (next == -1)
+ ? cp.substring(off)
+ : cp.substring(off, next);
if (element.length() > 0 || !skipEmptyElements) {
URL url = toFileURL(element);
if (url != null) path.add(url);
}
off = next + 1;
- }
-
- // remaining element
- String element = cp.substring(off);
- if (element.length() > 0 || !skipEmptyElements) {
- URL url = toFileURL(element);
- if (url != null) path.add(url);
- }
-
- // push the URLs
- for (int i = path.size() - 1; i >= 0; --i) {
- urls.push(path.get(i));
- }
+ } while (next != -1);
}
+ // can't use ArrayDeque#addAll or new ArrayDeque(Collection);
+ // it's too early in the bootstrap to trigger use of lambdas
+ int size = path.size();
+ ArrayDeque<URL> unopenedUrls = new ArrayDeque<>(size);
+ for (int i = 0; i < size; i++)
+ unopenedUrls.add(path.get(i));
+
+ this.unopenedUrls = unopenedUrls;
this.path = path;
this.jarHandler = null;
this.acc = null;
@@ -209,7 +211,7 @@
try {
loader.close();
} catch (IOException e) {
- result.add (e);
+ result.add(e);
}
}
closed = true;
@@ -224,14 +226,13 @@
* URLs, then invoking this method has no effect.
*/
public synchronized void addURL(URL url) {
- if (closed)
+ if (closed || url == null)
return;
- synchronized (urls) {
- if (url == null || path.contains(url))
- return;
-
- urls.add(0, url);
- path.add(url);
+ synchronized (unopenedUrls) {
+ if (! path.contains(url)) {
+ unopenedUrls.addLast(url);
+ path.add(url);
+ }
}
}
@@ -261,8 +262,8 @@
* Returns the original search path of URLs.
*/
public URL[] getURLs() {
- synchronized (urls) {
- return path.toArray(new URL[path.size()]);
+ synchronized (unopenedUrls) {
+ return path.toArray(new URL[0]);
}
}
@@ -272,7 +273,7 @@
*
* @param name the name of the resource
* @param check whether to perform a security check
- * @return a <code>URL</code> for the resource, or <code>null</code>
+ * @return a {@code URL} for the resource, or {@code null}
* if the resource could not be found.
*/
public URL findResource(String name, boolean check) {
@@ -412,17 +413,14 @@
if (closed) {
return null;
}
- // Expand URL search path until the request can be satisfied
- // or the URL stack is empty.
+ // Expand URL search path until the request can be satisfied
+ // or unopenedUrls is exhausted.
while (loaders.size() < index + 1) {
- // Pop the next URL from the URL stack
- URL url;
- synchronized (urls) {
- if (urls.empty()) {
+ final URL url;
+ synchronized (unopenedUrls) {
+ url = unopenedUrls.pollFirst();
+ if (url == null)
return null;
- } else {
- url = urls.pop();
- }
}
// Skip this URL if it already has a Loader. (Loader
// may be null in the case where URL has not been opened
@@ -436,7 +434,7 @@
try {
loader = getLoader(url);
// If the loader defines a local class path then add the
- // URLs to the list of URLs to be opened.
+ // URLs as the next URLs to be opened.
URL[] urls = loader.getClassPath();
if (urls != null) {
push(urls);
@@ -465,8 +463,8 @@
*/
private Loader getLoader(final URL url) throws IOException {
try {
- return java.security.AccessController.doPrivileged(
- new java.security.PrivilegedExceptionAction<>() {
+ return AccessController.doPrivileged(
+ new PrivilegedExceptionAction<>() {
public Loader run() throws IOException {
String protocol = url.getProtocol(); // lower cased in URL
String file = url.getFile();
@@ -487,7 +485,7 @@
}
}
}, acc);
- } catch (java.security.PrivilegedActionException pae) {
+ } catch (PrivilegedActionException pae) {
throw (IOException)pae.getException();
}
}
@@ -501,19 +499,19 @@
}
/*
- * Pushes the specified URLs onto the list of unopened URLs.
+ * Pushes the specified URLs onto the head of unopened URLs.
*/
- private void push(URL[] us) {
- synchronized (urls) {
- for (int i = us.length - 1; i >= 0; --i) {
- urls.push(us[i]);
+ private void push(URL[] urls) {
+ synchronized (unopenedUrls) {
+ for (int i = urls.length - 1; i >= 0; --i) {
+ unopenedUrls.addFirst(urls[i]);
}
}
}
/*
- * Check whether the resource URL should be returned.
- * Return null on security check failure.
+ * Checks whether the resource URL should be returned.
+ * Returns null on security check failure.
* Called by java.net.URLClassLoader.
*/
public static URL checkURL(URL url) {
@@ -528,8 +526,8 @@
}
/*
- * Check whether the resource URL should be returned.
- * Throw exception on failure.
+ * Checks whether the resource URL should be returned.
+ * Throws exception on failure.
* Called internally within this file.
*/
public static void check(URL url) throws IOException {
@@ -668,8 +666,8 @@
}
/*
- * close this loader and release all resources
- * method overridden in sub-classes
+ * Closes this loader and release all resources.
+ * Method overridden in sub-classes.
*/
@Override
public void close() throws IOException {
@@ -740,8 +738,8 @@
private void ensureOpen() throws IOException {
if (jar == null) {
try {
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedExceptionAction<>() {
+ AccessController.doPrivileged(
+ new PrivilegedExceptionAction<>() {
public Void run() throws IOException {
if (DEBUG) {
System.err.println("Opening " + csu);
@@ -757,7 +755,7 @@
// if the same URL occurs later on the main class path. We set
// Loader to null here to avoid creating a Loader for each
// URL until we actually need to try to load something from them.
- for(int i = 0; i < jarfiles.length; i++) {
+ for (int i = 0; i < jarfiles.length; i++) {
try {
URL jarURL = new URL(csu, jarfiles[i]);
// If a non-null loader already exists, leave it alone.
@@ -773,7 +771,7 @@
return null;
}
}, acc);
- } catch (java.security.PrivilegedActionException pae) {
+ } catch (PrivilegedActionException pae) {
throw (IOException)pae.getException();
}
}
@@ -876,7 +874,7 @@
boolean validIndex(final String name) {
String packageName = name;
int pos;
- if((pos = name.lastIndexOf('/')) != -1) {
+ if ((pos = name.lastIndexOf('/')) != -1) {
packageName = name.substring(0, pos);
}
@@ -886,7 +884,7 @@
while (enum_.hasMoreElements()) {
entry = enum_.nextElement();
entryName = entry.getName();
- if((pos = entryName.lastIndexOf('/')) != -1)
+ if ((pos = entryName.lastIndexOf('/')) != -1)
entryName = entryName.substring(0, pos);
if (entryName.equals(packageName)) {
return true;
@@ -933,7 +931,7 @@
* visited by linking through the index files. This helper method uses
* a HashSet to store the URLs of jar files that have been searched and
* uses it to avoid going into an infinite loop, looking for a
- * non-existent resource
+ * non-existent resource.
*/
Resource getResource(final String name, boolean check,
Set<String> visited) {
@@ -945,14 +943,14 @@
/* If there no jar files in the index that can potential contain
* this resource then return immediately.
*/
- if((jarFilesList = index.get(name)) == null)
+ if ((jarFilesList = index.get(name)) == null)
return null;
do {
int size = jarFilesList.size();
jarFiles = jarFilesList.toArray(new String[size]);
/* loop through the mapped jar file list */
- while(count < size) {
+ while (count < size) {
String jarName = jarFiles[count++];
JarLoader newLoader;
final URL url;
@@ -977,7 +975,7 @@
* account the relative path.
*/
JarIndex newIndex = newLoader.getIndex();
- if(newIndex != null) {
+ if (newIndex != null) {
int pos = jarName.lastIndexOf('/');
newIndex.merge(this.index, (pos == -1 ?
null : jarName.substring(0, pos + 1)));
@@ -986,7 +984,7 @@
/* put it in the global hashtable */
lmap.put(urlNoFragString, newLoader);
}
- } catch (java.security.PrivilegedActionException pae) {
+ } catch (PrivilegedActionException pae) {
continue;
} catch (MalformedURLException e) {
continue;
@@ -1029,7 +1027,7 @@
/* Process the index of the new loader
*/
- if((res = newLoader.getResource(name, check, visited))
+ if ((res = newLoader.getResource(name, check, visited))
!= null) {
return res;
}
@@ -1039,7 +1037,7 @@
jarFilesList = index.get(name);
// If the count is unchanged, we are done.
- } while(count < jarFilesList.size());
+ } while (count < jarFilesList.size());
return null;
}
--- a/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, 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
@@ -100,9 +100,9 @@
<E extends Enum<E>> E[] getEnumConstantsShared(Class<E> klass);
/**
- * Set thread's blocker field.
+ * Set current thread's blocker field.
*/
- void blockedOn(Thread t, Interruptible b);
+ void blockedOn(Interruptible b);
/**
* Registers a shutdown hook.
--- a/src/java.base/share/classes/sun/invoke/util/ValueConversions.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/share/classes/sun/invoke/util/ValueConversions.java Thu Mar 01 01:35:46 2018 +0100
@@ -377,7 +377,7 @@
MethodType type = MethodType.methodType(wrap.primitiveType());
switch (wrap) {
case VOID:
- mh = EMPTY;
+ mh = Handles.EMPTY;
break;
case OBJECT:
case INT: case LONG: case FLOAT: case DOUBLE:
@@ -400,26 +400,28 @@
throw new IllegalArgumentException("cannot find zero constant for " + wrap);
}
- private static final MethodHandle CAST_REFERENCE, IGNORE, EMPTY;
- static {
- try {
- MethodType idType = MethodType.genericMethodType(1);
- MethodType ignoreType = idType.changeReturnType(void.class);
- CAST_REFERENCE = IMPL_LOOKUP.findVirtual(Class.class, "cast", idType);
- IGNORE = IMPL_LOOKUP.findStatic(THIS_CLASS, "ignore", ignoreType);
- EMPTY = IMPL_LOOKUP.findStatic(THIS_CLASS, "empty", ignoreType.dropParameterTypes(0, 1));
- } catch (NoSuchMethodException | IllegalAccessException ex) {
- throw newInternalError("uncaught exception", ex);
+ private static class Handles {
+ static final MethodHandle CAST_REFERENCE, IGNORE, EMPTY;
+ static {
+ try {
+ MethodType idType = MethodType.genericMethodType(1);
+ MethodType ignoreType = idType.changeReturnType(void.class);
+ CAST_REFERENCE = IMPL_LOOKUP.findVirtual(Class.class, "cast", idType);
+ IGNORE = IMPL_LOOKUP.findStatic(THIS_CLASS, "ignore", ignoreType);
+ EMPTY = IMPL_LOOKUP.findStatic(THIS_CLASS, "empty", ignoreType.dropParameterTypes(0, 1));
+ } catch (NoSuchMethodException | IllegalAccessException ex) {
+ throw newInternalError("uncaught exception", ex);
+ }
}
}
public static MethodHandle ignore() {
- return IGNORE;
+ return Handles.IGNORE;
}
/** Return a method that casts its second argument (an Object) to the given type (a Class). */
public static MethodHandle cast() {
- return CAST_REFERENCE;
+ return Handles.CAST_REFERENCE;
}
/// Primitive conversions.
--- a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Thu Mar 01 01:35:46 2018 +0100
@@ -41,15 +41,17 @@
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.channels.AlreadyBoundException;
+import java.nio.channels.AlreadyConnectedException;
+import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.DatagramChannel;
import java.nio.channels.MembershipKey;
import java.nio.channels.NotYetConnectedException;
import java.nio.channels.SelectionKey;
-import java.nio.channels.UnsupportedAddressTypeException;
import java.nio.channels.spi.SelectorProvider;
import java.util.Collections;
import java.util.HashSet;
+import java.util.Objects;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
@@ -64,21 +66,16 @@
extends DatagramChannel
implements SelChImpl
{
-
// Used to make native read and write calls
private static NativeDispatcher nd = new DatagramDispatcher();
+ // The protocol family of the socket
+ private final ProtocolFamily family;
+
// Our file descriptor
private final FileDescriptor fd;
private final int fdVal;
- // The protocol family of the socket
- private final ProtocolFamily family;
-
- // IDs of native threads doing reads and writes, for signalling
- private volatile long readerThread;
- private volatile long writerThread;
-
// Cached InetAddress and port for unconnected DatagramChannels
// used by receive0
private InetAddress cachedSenderInetAddress;
@@ -97,13 +94,18 @@
// -- The following fields are protected by stateLock
// State (does not necessarily increase monotonically)
- private static final int ST_UNINITIALIZED = -1;
private static final int ST_UNCONNECTED = 0;
private static final int ST_CONNECTED = 1;
- private static final int ST_KILLED = 2;
- private int state = ST_UNINITIALIZED;
+ private static final int ST_CLOSING = 2;
+ private static final int ST_KILLPENDING = 3;
+ private static final int ST_KILLED = 4;
+ private int state;
- // Binding
+ // IDs of native threads doing reads and writes, for signalling
+ private long readerThread;
+ private long writerThread;
+
+ // Binding and remote address (when connected)
private InetSocketAddress localAddress;
private InetSocketAddress remoteAddress;
@@ -127,11 +129,11 @@
super(sp);
ResourceManager.beforeUdpCreate();
try {
- this.family = Net.isIPv6Available() ?
- StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
+ this.family = Net.isIPv6Available()
+ ? StandardProtocolFamily.INET6
+ : StandardProtocolFamily.INET;
this.fd = Net.socket(family, false);
this.fdVal = IOUtil.fdVal(fd);
- this.state = ST_UNCONNECTED;
} catch (IOException ioe) {
ResourceManager.afterUdpClose();
throw ioe;
@@ -142,13 +144,10 @@
throws IOException
{
super(sp);
+ Objects.requireNonNull(family, "'family' is null");
if ((family != StandardProtocolFamily.INET) &&
- (family != StandardProtocolFamily.INET6))
- {
- if (family == null)
- throw new NullPointerException("'family' is null");
- else
- throw new UnsupportedOperationException("Protocol family not supported");
+ (family != StandardProtocolFamily.INET6)) {
+ throw new UnsupportedOperationException("Protocol family not supported");
}
if (family == StandardProtocolFamily.INET6) {
if (!Net.isIPv6Available()) {
@@ -161,7 +160,6 @@
this.family = family;
this.fd = Net.socket(family, false);
this.fdVal = IOUtil.fdVal(fd);
- this.state = ST_UNCONNECTED;
} catch (IOException ioe) {
ResourceManager.afterUdpClose();
throw ioe;
@@ -176,14 +174,23 @@
// increment UDP count to match decrement when closing
ResourceManager.beforeUdpCreate();
- this.family = Net.isIPv6Available() ?
- StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
+ this.family = Net.isIPv6Available()
+ ? StandardProtocolFamily.INET6
+ : StandardProtocolFamily.INET;
this.fd = fd;
this.fdVal = IOUtil.fdVal(fd);
- this.state = ST_UNCONNECTED;
- this.localAddress = Net.localAddress(fd);
+ synchronized (stateLock) {
+ this.localAddress = Net.localAddress(fd);
+ }
}
+ // @throws ClosedChannelException if channel is closed
+ private void ensureOpen() throws ClosedChannelException {
+ if (!isOpen())
+ throw new ClosedChannelException();
+ }
+
+ @Override
public DatagramSocket socket() {
synchronized (stateLock) {
if (socket == null)
@@ -195,8 +202,7 @@
@Override
public SocketAddress getLocalAddress() throws IOException {
synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
+ ensureOpen();
// Perform security check before returning address
return Net.getRevealedLocalAddress(localAddress);
}
@@ -205,8 +211,7 @@
@Override
public SocketAddress getRemoteAddress() throws IOException {
synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
+ ensureOpen();
return remoteAddress;
}
}
@@ -215,8 +220,7 @@
public <T> DatagramChannel setOption(SocketOption<T> name, T value)
throws IOException
{
- if (name == null)
- throw new NullPointerException();
+ Objects.requireNonNull(name);
if (!supportedOptions().contains(name))
throw new UnsupportedOperationException("'" + name + "' not supported");
@@ -251,9 +255,8 @@
}
return this;
}
- if (name == StandardSocketOptions.SO_REUSEADDR &&
- Net.useExclusiveBind() && localAddress != null)
- {
+ if (name == StandardSocketOptions.SO_REUSEADDR
+ && Net.useExclusiveBind() && localAddress != null) {
reuseAddressEmulated = true;
this.isReuseAddress = (Boolean)value;
}
@@ -269,8 +272,7 @@
public <T> T getOption(SocketOption<T> name)
throws IOException
{
- if (name == null)
- throw new NullPointerException();
+ Objects.requireNonNull(name);
if (!supportedOptions().contains(name))
throw new UnsupportedOperationException("'" + name + "' not supported");
@@ -307,9 +309,7 @@
}
}
- if (name == StandardSocketOptions.SO_REUSEADDR &&
- reuseAddressEmulated)
- {
+ if (name == StandardSocketOptions.SO_REUSEADDR && reuseAddressEmulated) {
return (T)Boolean.valueOf(isReuseAddress);
}
@@ -322,7 +322,7 @@
static final Set<SocketOption<?>> defaultOptions = defaultOptions();
private static Set<SocketOption<?>> defaultOptions() {
- HashSet<SocketOption<?>> set = new HashSet<>(8);
+ HashSet<SocketOption<?>> set = new HashSet<>();
set.add(StandardSocketOptions.SO_SNDBUF);
set.add(StandardSocketOptions.SO_RCVBUF);
set.add(StandardSocketOptions.SO_REUSEADDR);
@@ -334,9 +334,7 @@
set.add(StandardSocketOptions.IP_MULTICAST_IF);
set.add(StandardSocketOptions.IP_MULTICAST_TTL);
set.add(StandardSocketOptions.IP_MULTICAST_LOOP);
- ExtendedSocketOptions extendedOptions =
- ExtendedSocketOptions.getInstance();
- set.addAll(extendedOptions.options());
+ set.addAll(ExtendedSocketOptions.getInstance().options());
return Collections.unmodifiableSet(set);
}
}
@@ -346,33 +344,78 @@
return DefaultOptionsHolder.defaultOptions;
}
- private void ensureOpen() throws ClosedChannelException {
- if (!isOpen())
- throw new ClosedChannelException();
+ /**
+ * Marks the beginning of a read operation that might block.
+ *
+ * @param blocking true if configured blocking
+ * @param mustBeConnected true if the socket must be connected
+ * @return remote address if connected
+ * @throws ClosedChannelException if the channel is closed
+ * @throws NotYetConnectedException if mustBeConnected and not connected
+ * @throws IOException if socket not bound and cannot be bound
+ */
+ private SocketAddress beginRead(boolean blocking, boolean mustBeConnected)
+ throws IOException
+ {
+ if (blocking) {
+ // set hook for Thread.interrupt
+ begin();
+ }
+ SocketAddress remote;
+ synchronized (stateLock) {
+ ensureOpen();
+ remote = remoteAddress;
+ if ((remote == null) && mustBeConnected)
+ throw new NotYetConnectedException();
+ if (localAddress == null)
+ bindInternal(null);
+ if (blocking)
+ readerThread = NativeThread.current();
+ }
+ return remote;
+ }
+
+ /**
+ * Marks the end of a read operation that may have blocked.
+ *
+ * @throws AsynchronousCloseException if the channel was closed asynchronously
+ */
+ private void endRead(boolean blocking, boolean completed)
+ throws AsynchronousCloseException
+ {
+ if (blocking) {
+ synchronized (stateLock) {
+ readerThread = 0;
+ // notify any thread waiting in implCloseSelectableChannel
+ if (state == ST_CLOSING) {
+ stateLock.notifyAll();
+ }
+ }
+ // remove hook for Thread.interrupt
+ end(completed);
+ }
}
private SocketAddress sender; // Set by receive0 (## ugh)
+ @Override
public SocketAddress receive(ByteBuffer dst) throws IOException {
if (dst.isReadOnly())
throw new IllegalArgumentException("Read-only buffer");
+
readLock.lock();
try {
- ensureOpen();
- // Socket was not bound before attempting receive
- if (localAddress() == null)
- bind(null);
+ boolean blocking = isBlocking();
int n = 0;
ByteBuffer bb = null;
try {
- begin();
- if (!isOpen())
- return null;
- SecurityManager security = System.getSecurityManager();
- readerThread = NativeThread.current();
- if (isConnected() || (security == null)) {
+ SocketAddress remote = beginRead(blocking, false);
+ boolean connected = (remote != null);
+ SecurityManager sm = System.getSecurityManager();
+ if (connected || (sm == null)) {
+ // connected or no security manager
do {
- n = receive(fd, dst);
+ n = receive(fd, dst, connected);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
if (n == IOStatus.UNAVAILABLE)
return null;
@@ -382,15 +425,14 @@
bb = Util.getTemporaryDirectBuffer(dst.remaining());
for (;;) {
do {
- n = receive(fd, bb);
+ n = receive(fd, bb, connected);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
if (n == IOStatus.UNAVAILABLE)
return null;
InetSocketAddress isa = (InetSocketAddress)sender;
try {
- security.checkAccept(
- isa.getAddress().getHostAddress(),
- isa.getPort());
+ sm.checkAccept(isa.getAddress().getHostAddress(),
+ isa.getPort());
} catch (SecurityException se) {
// Ignore packet
bb.clear();
@@ -402,12 +444,12 @@
break;
}
}
+ assert sender != null;
return sender;
} finally {
if (bb != null)
Util.releaseTemporaryDirectBuffer(bb);
- readerThread = 0;
- end((n > 0) || (n == IOStatus.UNAVAILABLE));
+ endRead(blocking, n > 0);
assert IOStatus.check(n);
}
} finally {
@@ -415,7 +457,7 @@
}
}
- private int receive(FileDescriptor fd, ByteBuffer dst)
+ private int receive(FileDescriptor fd, ByteBuffer dst, boolean connected)
throws IOException
{
int pos = dst.position();
@@ -423,7 +465,7 @@
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
if (dst instanceof DirectBuffer && rem > 0)
- return receiveIntoNativeBuffer(fd, dst, rem, pos);
+ return receiveIntoNativeBuffer(fd, dst, rem, pos, connected);
// Substitute a native buffer. If the supplied buffer is empty
// we must instead use a nonempty buffer, otherwise the call
@@ -431,7 +473,7 @@
int newSize = Math.max(rem, 1);
ByteBuffer bb = Util.getTemporaryDirectBuffer(newSize);
try {
- int n = receiveIntoNativeBuffer(fd, bb, newSize, 0);
+ int n = receiveIntoNativeBuffer(fd, bb, newSize, 0, connected);
bb.flip();
if (n > 0 && rem > 0)
dst.put(bb);
@@ -442,11 +484,10 @@
}
private int receiveIntoNativeBuffer(FileDescriptor fd, ByteBuffer bb,
- int rem, int pos)
+ int rem, int pos, boolean connected)
throws IOException
{
- int n = receive0(fd, ((DirectBuffer)bb).address() + pos, rem,
- isConnected());
+ int n = receive0(fd, ((DirectBuffer)bb).address() + pos, rem, connected);
if (n > 0)
bb.position(pos + n);
return n;
@@ -455,59 +496,44 @@
public int send(ByteBuffer src, SocketAddress target)
throws IOException
{
- if (src == null)
- throw new NullPointerException();
+ Objects.requireNonNull(src);
+ InetSocketAddress isa = Net.checkAddress(target, family);
writeLock.lock();
try {
- ensureOpen();
- InetSocketAddress isa = Net.checkAddress(target);
- InetAddress ia = isa.getAddress();
- if (ia == null)
- throw new IOException("Target address not resolved");
- synchronized (stateLock) {
- if (!isConnected()) {
- if (target == null)
- throw new NullPointerException();
+ boolean blocking = isBlocking();
+ int n = 0;
+ try {
+ SocketAddress remote = beginWrite(blocking, false);
+ if (remote != null) {
+ // connected
+ if (!target.equals(remote)) {
+ throw new IllegalArgumentException(
+ "Connected address not equal to target address");
+ }
+ do {
+ n = IOUtil.write(fd, src, -1, nd);
+ } while ((n == IOStatus.INTERRUPTED) && isOpen());
+ } else {
+ // not connected
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
+ InetAddress ia = isa.getAddress();
if (ia.isMulticastAddress()) {
sm.checkMulticast(ia);
} else {
- sm.checkConnect(ia.getHostAddress(),
- isa.getPort());
+ sm.checkConnect(ia.getHostAddress(), isa.getPort());
}
}
- } else { // Connected case; Check address then write
- if (!target.equals(remoteAddress)) {
- throw new IllegalArgumentException(
- "Connected address not equal to target address");
- }
- return write(src);
+ do {
+ n = send(fd, src, isa);
+ } while ((n == IOStatus.INTERRUPTED) && isOpen());
}
- }
-
- int n = 0;
- try {
- begin();
- if (!isOpen())
- return 0;
- writerThread = NativeThread.current();
- do {
- n = send(fd, src, isa);
- } while ((n == IOStatus.INTERRUPTED) && isOpen());
-
- synchronized (stateLock) {
- if (isOpen() && (localAddress == null)) {
- localAddress = Net.localAddress(fd);
- }
- }
- return IOStatus.normalize(n);
} finally {
- writerThread = 0;
- end((n > 0) || (n == IOStatus.UNAVAILABLE));
+ endWrite(blocking, n > 0);
assert IOStatus.check(n);
}
+ return IOStatus.normalize(n);
} finally {
writeLock.unlock();
}
@@ -567,141 +593,180 @@
return written;
}
+ @Override
public int read(ByteBuffer buf) throws IOException {
- if (buf == null)
- throw new NullPointerException();
+ Objects.requireNonNull(buf);
+
readLock.lock();
try {
- synchronized (stateLock) {
- ensureOpen();
- if (!isConnected())
- throw new NotYetConnectedException();
- }
+ boolean blocking = isBlocking();
int n = 0;
try {
- begin();
- if (!isOpen())
- return 0;
- readerThread = NativeThread.current();
+ beginRead(blocking, true);
do {
n = IOUtil.read(fd, buf, -1, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
- return IOStatus.normalize(n);
+
} finally {
- readerThread = 0;
- end((n > 0) || (n == IOStatus.UNAVAILABLE));
+ endRead(blocking, n > 0);
assert IOStatus.check(n);
}
+ return IOStatus.normalize(n);
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ @Override
+ public long read(ByteBuffer[] dsts, int offset, int length)
+ throws IOException
+ {
+ Objects.checkFromIndexSize(offset, length, dsts.length);
+
+ readLock.lock();
+ try {
+ boolean blocking = isBlocking();
+ long n = 0;
+ try {
+ beginRead(blocking, true);
+ do {
+ n = IOUtil.read(fd, dsts, offset, length, nd);
+ } while ((n == IOStatus.INTERRUPTED) && isOpen());
+
+ } finally {
+ endRead(blocking, n > 0);
+ assert IOStatus.check(n);
+ }
+ return IOStatus.normalize(n);
} finally {
readLock.unlock();
}
}
- public long read(ByteBuffer[] dsts, int offset, int length)
+ /**
+ * Marks the beginning of a write operation that might block.
+ * @param blocking true if configured blocking
+ * @param mustBeConnected true if the socket must be connected
+ * @return remote address if connected
+ * @throws ClosedChannelException if the channel is closed
+ * @throws NotYetConnectedException if mustBeConnected and not connected
+ * @throws IOException if socket not bound and cannot be bound
+ */
+ private SocketAddress beginWrite(boolean blocking, boolean mustBeConnected)
throws IOException
{
- if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
- throw new IndexOutOfBoundsException();
+ if (blocking) {
+ // set hook for Thread.interrupt
+ begin();
+ }
+ SocketAddress remote;
+ synchronized (stateLock) {
+ ensureOpen();
+ remote = remoteAddress;
+ if ((remote == null) && mustBeConnected)
+ throw new NotYetConnectedException();
+ if (localAddress == null)
+ bindInternal(null);
+ if (blocking)
+ writerThread = NativeThread.current();
+ }
+ return remote;
+ }
+
+ /**
+ * Marks the end of a write operation that may have blocked.
+ *
+ * @throws AsynchronousCloseException if the channel was closed asynchronously
+ */
+ private void endWrite(boolean blocking, boolean completed)
+ throws AsynchronousCloseException
+ {
+ if (blocking) {
+ synchronized (stateLock) {
+ writerThread = 0;
+ // notify any thread waiting in implCloseSelectableChannel
+ if (state == ST_CLOSING) {
+ stateLock.notifyAll();
+ }
+ }
+ // remove hook for Thread.interrupt
+ end(completed);
+ }
+ }
+
+ @Override
+ public int write(ByteBuffer buf) throws IOException {
+ Objects.requireNonNull(buf);
+
+ writeLock.lock();
+ try {
+ boolean blocking = isBlocking();
+ int n = 0;
+ try {
+ beginWrite(blocking, true);
+ do {
+ n = IOUtil.write(fd, buf, -1, nd);
+ } while ((n == IOStatus.INTERRUPTED) && isOpen());
+ } finally {
+ endWrite(blocking, n > 0);
+ assert IOStatus.check(n);
+ }
+ return IOStatus.normalize(n);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ @Override
+ public long write(ByteBuffer[] srcs, int offset, int length)
+ throws IOException
+ {
+ Objects.checkFromIndexSize(offset, length, srcs.length);
+
+ writeLock.lock();
+ try {
+ boolean blocking = isBlocking();
+ long n = 0;
+ try {
+ beginWrite(blocking, true);
+ do {
+ n = IOUtil.write(fd, srcs, offset, length, nd);
+ } while ((n == IOStatus.INTERRUPTED) && isOpen());
+ } finally {
+ endWrite(blocking, n > 0);
+ assert IOStatus.check(n);
+ }
+ return IOStatus.normalize(n);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ @Override
+ protected void implConfigureBlocking(boolean block) throws IOException {
readLock.lock();
try {
- synchronized (stateLock) {
- ensureOpen();
- if (!isConnected())
- throw new NotYetConnectedException();
- }
- long n = 0;
+ writeLock.lock();
try {
- begin();
- if (!isOpen())
- return 0;
- readerThread = NativeThread.current();
- do {
- n = IOUtil.read(fd, dsts, offset, length, nd);
- } while ((n == IOStatus.INTERRUPTED) && isOpen());
- return IOStatus.normalize(n);
+ synchronized (stateLock) {
+ ensureOpen();
+ IOUtil.configureBlocking(fd, block);
+ }
} finally {
- readerThread = 0;
- end((n > 0) || (n == IOStatus.UNAVAILABLE));
- assert IOStatus.check(n);
+ writeLock.unlock();
}
} finally {
readLock.unlock();
}
}
- public int write(ByteBuffer buf) throws IOException {
- if (buf == null)
- throw new NullPointerException();
- writeLock.lock();
- try {
- synchronized (stateLock) {
- ensureOpen();
- if (!isConnected())
- throw new NotYetConnectedException();
- }
- int n = 0;
- try {
- begin();
- if (!isOpen())
- return 0;
- writerThread = NativeThread.current();
- do {
- n = IOUtil.write(fd, buf, -1, nd);
- } while ((n == IOStatus.INTERRUPTED) && isOpen());
- return IOStatus.normalize(n);
- } finally {
- writerThread = 0;
- end((n > 0) || (n == IOStatus.UNAVAILABLE));
- assert IOStatus.check(n);
- }
- } finally {
- writeLock.unlock();
- }
- }
-
- public long write(ByteBuffer[] srcs, int offset, int length)
- throws IOException
- {
- if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
- throw new IndexOutOfBoundsException();
- writeLock.lock();
- try {
- synchronized (stateLock) {
- ensureOpen();
- if (!isConnected())
- throw new NotYetConnectedException();
- }
- long n = 0;
- try {
- begin();
- if (!isOpen())
- return 0;
- writerThread = NativeThread.current();
- do {
- n = IOUtil.write(fd, srcs, offset, length, nd);
- } while ((n == IOStatus.INTERRUPTED) && isOpen());
- return IOStatus.normalize(n);
- } finally {
- writerThread = 0;
- end((n > 0) || (n == IOStatus.UNAVAILABLE));
- assert IOStatus.check(n);
- }
- } finally {
- writeLock.unlock();
- }
- }
-
- protected void implConfigureBlocking(boolean block) throws IOException {
- IOUtil.configureBlocking(fd, block);
- }
-
- public SocketAddress localAddress() {
+ InetSocketAddress localAddress() {
synchronized (stateLock) {
return localAddress;
}
}
- public SocketAddress remoteAddress() {
+ InetSocketAddress remoteAddress() {
synchronized (stateLock) {
return remoteAddress;
}
@@ -717,30 +782,7 @@
ensureOpen();
if (localAddress != null)
throw new AlreadyBoundException();
- InetSocketAddress isa;
- if (local == null) {
- // only Inet4Address allowed with IPv4 socket
- if (family == StandardProtocolFamily.INET) {
- isa = new InetSocketAddress(InetAddress.getByName("0.0.0.0"), 0);
- } else {
- isa = new InetSocketAddress(0);
- }
- } else {
- isa = Net.checkAddress(local);
-
- // only Inet4Address allowed with IPv4 socket
- if (family == StandardProtocolFamily.INET) {
- InetAddress addr = isa.getAddress();
- if (!(addr instanceof Inet4Address))
- throw new UnsupportedAddressTypeException();
- }
- }
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkListen(isa.getPort());
- }
- Net.bind(family, fd, isa.getAddress(), isa.getPort());
- localAddress = Net.localAddress(fd);
+ bindInternal(local);
}
} finally {
writeLock.unlock();
@@ -751,34 +793,58 @@
return this;
}
+ private void bindInternal(SocketAddress local) throws IOException {
+ assert Thread.holdsLock(stateLock) && (localAddress == null);
+
+ InetSocketAddress isa;
+ if (local == null) {
+ // only Inet4Address allowed with IPv4 socket
+ if (family == StandardProtocolFamily.INET) {
+ isa = new InetSocketAddress(InetAddress.getByName("0.0.0.0"), 0);
+ } else {
+ isa = new InetSocketAddress(0);
+ }
+ } else {
+ isa = Net.checkAddress(local, family);
+ }
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkListen(isa.getPort());
+
+ Net.bind(family, fd, isa.getAddress(), isa.getPort());
+ localAddress = Net.localAddress(fd);
+ }
+
+ @Override
public boolean isConnected() {
synchronized (stateLock) {
return (state == ST_CONNECTED);
}
}
- void ensureOpenAndUnconnected() throws IOException { // package-private
- synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
- if (state != ST_UNCONNECTED)
- throw new IllegalStateException("Connect already invoked");
- }
- }
-
@Override
public DatagramChannel connect(SocketAddress sa) throws IOException {
+ InetSocketAddress isa = Net.checkAddress(sa, family);
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ InetAddress ia = isa.getAddress();
+ if (ia.isMulticastAddress()) {
+ sm.checkMulticast(ia);
+ } else {
+ sm.checkConnect(ia.getHostAddress(), isa.getPort());
+ sm.checkAccept(ia.getHostAddress(), isa.getPort());
+ }
+ }
+
readLock.lock();
try {
writeLock.lock();
try {
synchronized (stateLock) {
- ensureOpenAndUnconnected();
- InetSocketAddress isa = Net.checkAddress(sa);
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- sm.checkConnect(isa.getAddress().getHostAddress(),
- isa.getPort());
+ ensureOpen();
+ if (state == ST_CONNECTED)
+ throw new AlreadyConnectedException();
+
int n = Net.connect(family,
fd,
isa.getAddress(),
@@ -786,31 +852,26 @@
if (n <= 0)
throw new Error(); // Can't happen
- // Connection succeeded; disallow further invocation
- state = ST_CONNECTED;
+ // connected
remoteAddress = isa;
- sender = isa;
- cachedSenderInetAddress = isa.getAddress();
- cachedSenderPort = isa.getPort();
+ state = ST_CONNECTED;
- // set or refresh local address
+ // refresh local address
localAddress = Net.localAddress(fd);
// flush any packets already received.
- synchronized (blockingLock()) {
- boolean blocking = isBlocking();
- try {
- ByteBuffer tmpBuf = ByteBuffer.allocate(100);
- if (blocking) {
- configureBlocking(false);
- }
- do {
- tmpBuf.clear();
- } while (receive(tmpBuf) != null);
- } finally {
- if (blocking) {
- configureBlocking(true);
- }
+ boolean blocking = isBlocking();
+ if (blocking) {
+ IOUtil.configureBlocking(fd, false);
+ }
+ try {
+ ByteBuffer buf = ByteBuffer.allocate(100);
+ while (receive(buf) != null) {
+ buf.clear();
+ }
+ } finally {
+ if (blocking) {
+ IOUtil.configureBlocking(fd, true);
}
}
}
@@ -823,21 +884,21 @@
return this;
}
+ @Override
public DatagramChannel disconnect() throws IOException {
readLock.lock();
try {
writeLock.lock();
try {
synchronized (stateLock) {
- if (!isConnected() || !isOpen())
+ if (!isOpen() || (state != ST_CONNECTED))
return this;
- InetSocketAddress isa = remoteAddress;
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- sm.checkConnect(isa.getAddress().getHostAddress(),
- isa.getPort());
+
+ // disconnect socket
boolean isIPv6 = (family == StandardProtocolFamily.INET6);
disconnect0(fd, isIPv6);
+
+ // no longer connected
remoteAddress = null;
state = ST_UNCONNECTED;
@@ -891,8 +952,7 @@
sm.checkMulticast(group);
synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
+ ensureOpen();
// check the registry to see if we are already a member of the group
if (registry == null) {
@@ -963,8 +1023,7 @@
InetAddress source)
throws IOException
{
- if (source == null)
- throw new NullPointerException("source address is null");
+ Objects.requireNonNull(source);
return innerJoin(group, interf, source);
}
@@ -1065,37 +1124,99 @@
}
}
+ /**
+ * Invoked by implCloseChannel to close the channel.
+ *
+ * This method waits for outstanding I/O operations to complete. When in
+ * blocking mode, the socket is pre-closed and the threads in blocking I/O
+ * operations are signalled to ensure that the outstanding I/O operations
+ * complete quickly.
+ *
+ * The socket is closed by this method when it is not registered with a
+ * Selector. Note that a channel configured blocking may be registered with
+ * a Selector. This arises when a key is canceled and the channel configured
+ * to blocking mode before the key is flushed from the Selector.
+ */
+ @Override
protected void implCloseSelectableChannel() throws IOException {
+ assert !isOpen();
+
+ boolean blocking;
+ boolean interrupted = false;
+
+ // set state to ST_CLOSING and invalid membership keys
synchronized (stateLock) {
- if (state != ST_KILLED)
- nd.preClose(fd);
- ResourceManager.afterUdpClose();
+ assert state < ST_CLOSING;
+ blocking = isBlocking();
+ state = ST_CLOSING;
- // if member of mulitcast group then invalidate all keys
+ // if member of any multicast groups then invalidate the keys
if (registry != null)
registry.invalidateAll();
+ }
- long th;
- if ((th = readerThread) != 0)
- NativeThread.signal(th);
- if ((th = writerThread) != 0)
- NativeThread.signal(th);
- if (!isRegistered())
- kill();
+ // wait for any outstanding I/O operations to complete
+ if (blocking) {
+ synchronized (stateLock) {
+ assert state == ST_CLOSING;
+ long reader = readerThread;
+ long writer = writerThread;
+ if (reader != 0 || writer != 0) {
+ nd.preClose(fd);
+
+ if (reader != 0)
+ NativeThread.signal(reader);
+ if (writer != 0)
+ NativeThread.signal(writer);
+
+ // wait for blocking I/O operations to end
+ while (readerThread != 0 || writerThread != 0) {
+ try {
+ stateLock.wait();
+ } catch (InterruptedException e) {
+ interrupted = true;
+ }
+ }
+ }
+ }
+ } else {
+ // non-blocking mode: wait for read/write to complete
+ readLock.lock();
+ try {
+ writeLock.lock();
+ writeLock.unlock();
+ } finally {
+ readLock.unlock();
+ }
}
+
+ // set state to ST_KILLPENDING
+ synchronized (stateLock) {
+ assert state == ST_CLOSING;
+ state = ST_KILLPENDING;
+ }
+
+ // close socket if not registered with Selector
+ if (!isRegistered())
+ kill();
+
+ // restore interrupt status
+ if (interrupted)
+ Thread.currentThread().interrupt();
}
+ @Override
public void kill() throws IOException {
synchronized (stateLock) {
- if (state == ST_KILLED)
- return;
- if (state == ST_UNINITIALIZED) {
+ if (state == ST_KILLPENDING) {
state = ST_KILLED;
- return;
+ try {
+ nd.close(fd);
+ } finally {
+ // notify resource manager
+ ResourceManager.afterUdpClose();
+ }
}
- assert !isOpen() && !isRegistered();
- nd.close(fd);
- state = ST_KILLED;
}
}
@@ -1148,26 +1269,25 @@
return translateReadyOps(ops, 0, sk);
}
- // package-private
- int poll(int events, long timeout) throws IOException {
- assert Thread.holdsLock(blockingLock()) && !isBlocking();
+ /**
+ * Poll this channel's socket for reading up to the given timeout.
+ * @return {@code true} if the socket is polled
+ */
+ boolean pollRead(long timeout) throws IOException {
+ boolean blocking = isBlocking();
+ assert Thread.holdsLock(blockingLock()) && blocking;
readLock.lock();
try {
- int n = 0;
+ boolean polled = false;
try {
- begin();
- synchronized (stateLock) {
- if (!isOpen())
- return 0;
- readerThread = NativeThread.current();
- }
- n = Net.poll(fd, events, timeout);
+ beginRead(blocking, false);
+ int n = Net.poll(fd, Net.POLLIN, timeout);
+ polled = (n > 0);
} finally {
- readerThread = 0;
- end(n > 0);
+ endRead(blocking, polled);
}
- return n;
+ return polled;
} finally {
readLock.unlock();
}
@@ -1216,5 +1336,4 @@
IOUtil.load();
initIDs();
}
-
}
--- a/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java Thu Mar 01 01:35:46 2018 +0100
@@ -41,6 +41,7 @@
import java.nio.channels.ClosedChannelException;
import java.nio.channels.DatagramChannel;
import java.nio.channels.IllegalBlockingModeException;
+import java.util.Objects;
// Make a datagram-socket channel look like a datagram socket.
@@ -53,7 +54,6 @@
public class DatagramSocketAdaptor
extends DatagramSocket
{
-
// The channel being adapted
private final DatagramChannelImpl dc;
@@ -63,7 +63,7 @@
// ## super will create a useless impl
private DatagramSocketAdaptor(DatagramChannelImpl dc) throws IOException {
// Invoke the DatagramSocketAdaptor(SocketAddress) constructor,
- // passing a dummy DatagramSocketImpl object to aovid any native
+ // passing a dummy DatagramSocketImpl object to avoid any native
// resource allocation in super class and invoking our bind method
// before the dc field is initialized.
super(dummyDatagramSocket);
@@ -87,10 +87,10 @@
throw new IllegalArgumentException("connect: " + port);
if (remote == null)
throw new IllegalArgumentException("connect: null address");
- if (isClosed())
- return;
try {
dc.connect(remote);
+ } catch (ClosedChannelException e) {
+ // ignore
} catch (Exception x) {
Net.translateToSocketException(x);
}
@@ -115,8 +115,7 @@
}
public void connect(SocketAddress remote) throws SocketException {
- if (remote == null)
- throw new IllegalArgumentException("Address can't be null");
+ Objects.requireNonNull(remote, "Address can't be null");
connectInternal(remote);
}
@@ -137,15 +136,13 @@
}
public InetAddress getInetAddress() {
- return (isConnected()
- ? Net.asInetSocketAddress(dc.remoteAddress()).getAddress()
- : null);
+ InetSocketAddress remote = dc.remoteAddress();
+ return (remote != null) ? remote.getAddress() : null;
}
public int getPort() {
- return (isConnected()
- ? Net.asInetSocketAddress(dc.remoteAddress()).getPort()
- : -1);
+ InetSocketAddress remote = dc.remoteAddress();
+ return (remote != null) ? remote.getPort() : -1;
}
public void send(DatagramPacket p) throws IOException {
@@ -161,8 +158,7 @@
if (p.getAddress() == null) {
// Legacy DatagramSocket will send in this case
// and set address and port of the packet
- InetSocketAddress isa = (InetSocketAddress)
- dc.remoteAddress();
+ InetSocketAddress isa = dc.remoteAddress();
p.setPort(isa.getPort());
p.setAddress(isa.getAddress());
dc.write(bb);
@@ -181,36 +177,24 @@
}
}
- // Must hold dc.blockingLock()
- //
private SocketAddress receive(ByteBuffer bb) throws IOException {
- if (timeout == 0) {
- return dc.receive(bb);
- }
+ assert Thread.holdsLock(dc.blockingLock()) && dc.isBlocking();
- dc.configureBlocking(false);
- try {
- SocketAddress sender;
- if ((sender = dc.receive(bb)) != null)
- return sender;
- long to = timeout;
+ long to = this.timeout;
+ if (to == 0) {
+ return dc.receive(bb);
+ } else {
for (;;) {
if (!dc.isOpen())
- throw new ClosedChannelException();
+ throw new ClosedChannelException();
long st = System.currentTimeMillis();
- int result = dc.poll(Net.POLLIN, to);
- if (result > 0 && ((result & Net.POLLIN) != 0)) {
- if ((sender = dc.receive(bb)) != null)
- return sender;
+ if (dc.pollRead(to)) {
+ return dc.receive(bb);
}
to -= System.currentTimeMillis() - st;
if (to <= 0)
throw new SocketTimeoutException();
}
- } finally {
- try {
- dc.configureBlocking(true);
- } catch (ClosedChannelException e) { }
}
}
@@ -236,10 +220,10 @@
public InetAddress getLocalAddress() {
if (isClosed())
return null;
- SocketAddress local = dc.localAddress();
+ InetSocketAddress local = dc.localAddress();
if (local == null)
local = new InetSocketAddress(0);
- InetAddress result = ((InetSocketAddress)local).getAddress();
+ InetAddress result = local.getAddress();
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
try {
@@ -255,9 +239,9 @@
if (isClosed())
return -1;
try {
- SocketAddress local = dc.getLocalAddress();
+ InetSocketAddress local = dc.localAddress();
if (local != null) {
- return ((InetSocketAddress)local).getPort();
+ return local.getPort();
}
} catch (Exception x) {
}
--- a/src/java.base/share/classes/sun/nio/ch/IOUtil.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/share/classes/sun/nio/ch/IOUtil.java Thu Mar 01 01:35:46 2018 +0100
@@ -55,8 +55,7 @@
throws IOException
{
if (src instanceof DirectBuffer) {
- return writeFromNativeBuffer(fd, src, position,
- directIO, alignment, nd);
+ return writeFromNativeBuffer(fd, src, position, directIO, alignment, nd);
}
// Substitute a native buffer
@@ -77,8 +76,7 @@
// Do not update src until we see how many bytes were written
src.position(pos);
- int n = writeFromNativeBuffer(fd, bb, position,
- directIO, alignment, nd);
+ int n = writeFromNativeBuffer(fd, bb, position, directIO, alignment, nd);
if (n > 0) {
// now update src
src.position(pos + n);
@@ -232,8 +230,7 @@
if (dst.isReadOnly())
throw new IllegalArgumentException("Read-only buffer");
if (dst instanceof DirectBuffer)
- return readIntoNativeBuffer(fd, dst, position,
- directIO, alignment, nd);
+ return readIntoNativeBuffer(fd, dst, position, directIO, alignment, nd);
// Substitute a native buffer
ByteBuffer bb;
@@ -245,8 +242,7 @@
bb = Util.getTemporaryDirectBuffer(rem);
}
try {
- int n = readIntoNativeBuffer(fd, bb, position,
- directIO, alignment,nd);
+ int n = readIntoNativeBuffer(fd, bb, position, directIO, alignment,nd);
bb.flip();
if (n > 0)
dst.put(bb);
--- a/src/java.base/share/classes/sun/nio/ch/MembershipKeyImpl.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/share/classes/sun/nio/ch/MembershipKeyImpl.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,11 @@
package sun.nio.ch;
-import java.nio.channels.*;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.io.IOException;
+import java.nio.channels.MembershipKey;
+import java.nio.channels.MulticastChannel;
import java.util.HashSet;
/**
@@ -46,7 +47,7 @@
private volatile boolean invalid;
// lock used when creating or accessing blockedSet
- private Object stateLock = new Object();
+ private final Object stateLock = new Object();
// set of source addresses that are blocked
private HashSet<InetAddress> blockedSet;
--- a/src/java.base/share/classes/sun/nio/ch/Net.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/share/classes/sun/nio/ch/Net.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,12 +25,30 @@
package sun.nio.ch;
-import java.io.*;
-import java.net.*;
-import java.nio.channels.*;
-import java.util.*;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.NetworkInterface;
+import java.net.ProtocolFamily;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketOption;
+import java.net.StandardProtocolFamily;
+import java.net.StandardSocketOptions;
+import java.net.UnknownHostException;
+import java.nio.channels.AlreadyBoundException;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.NotYetBoundException;
+import java.nio.channels.NotYetConnectedException;
+import java.nio.channels.UnresolvedAddressException;
+import java.nio.channels.UnsupportedAddressTypeException;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.util.Enumeration;
+
import sun.net.ext.ExtendedSocketOptions;
import sun.security.action.GetPropertyAction;
@@ -116,6 +134,16 @@
return isa;
}
+ static InetSocketAddress checkAddress(SocketAddress sa, ProtocolFamily family) {
+ InetSocketAddress isa = checkAddress(sa);
+ if (family == StandardProtocolFamily.INET) {
+ InetAddress addr = isa.getAddress();
+ if (!(addr instanceof Inet4Address))
+ throw new UnsupportedAddressTypeException();
+ }
+ return isa;
+ }
+
static InetSocketAddress asInetSocketAddress(SocketAddress sa) {
if (!(sa instanceof InetSocketAddress))
throw new UnsupportedAddressTypeException();
--- a/src/java.base/share/classes/sun/nio/ch/SelChImpl.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/share/classes/sun/nio/ch/SelChImpl.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,6 @@
import java.io.FileDescriptor;
import java.io.IOException;
-
/**
* An interface that allows translation (and more!).
*
@@ -50,7 +49,7 @@
* contains at least one bit that the previous value did not
* contain
*/
- public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl sk);
+ boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl sk);
/**
* Sets the specified ops if present in interestOps. The specified
@@ -60,7 +59,7 @@
* contains at least one bit that the previous value did not
* contain
*/
- public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk);
+ boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk);
void translateAndSetInterestOps(int ops, SelectionKeyImpl sk);
--- a/src/java.base/share/classes/sun/nio/ch/ServerSocketAdaptor.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/share/classes/sun/nio/ch/ServerSocketAdaptor.java Thu Mar 01 01:35:46 2018 +0100
@@ -34,7 +34,6 @@
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.StandardSocketOptions;
-import java.nio.channels.ClosedChannelException;
import java.nio.channels.IllegalBlockingModeException;
import java.nio.channels.NotYetBoundException;
import java.nio.channels.ServerSocketChannel;
@@ -51,7 +50,6 @@
class ServerSocketAdaptor // package-private
extends ServerSocket
{
-
// The channel being adapted
private final ServerSocketChannelImpl ssc;
@@ -67,13 +65,10 @@
}
// ## super will create a useless impl
- private ServerSocketAdaptor(ServerSocketChannelImpl ssc)
- throws IOException
- {
+ private ServerSocketAdaptor(ServerSocketChannelImpl ssc) throws IOException {
this.ssc = ssc;
}
-
public void bind(SocketAddress local) throws IOException {
bind(local, 50);
}
@@ -89,26 +84,31 @@
}
public InetAddress getInetAddress() {
- if (!ssc.isBound())
+ InetSocketAddress local = ssc.localAddress();
+ if (local == null) {
return null;
- return Net.getRevealedLocalAddress(ssc.localAddress()).getAddress();
-
+ } else {
+ return Net.getRevealedLocalAddress(local).getAddress();
+ }
}
public int getLocalPort() {
- if (!ssc.isBound())
+ InetSocketAddress local = ssc.localAddress();
+ if (local == null) {
return -1;
- return Net.asInetSocketAddress(ssc.localAddress()).getPort();
+ } else {
+ return local.getPort();
+ }
}
-
public Socket accept() throws IOException {
synchronized (ssc.blockingLock()) {
try {
if (!ssc.isBound())
throw new NotYetBoundException();
- if (timeout == 0) {
+ long to = this.timeout;
+ if (to == 0) {
// for compatibility reasons: accept connection if available
// when configured non-blocking
SocketChannel sc = ssc.accept();
@@ -119,28 +119,15 @@
if (!ssc.isBlocking())
throw new IllegalBlockingModeException();
- ssc.configureBlocking(false);
- try {
- SocketChannel sc;
- if ((sc = ssc.accept()) != null)
- return sc.socket();
- long to = timeout;
- for (;;) {
- if (!ssc.isOpen())
- throw new ClosedChannelException();
- long st = System.currentTimeMillis();
- int result = ssc.poll(Net.POLLIN, to);
- if (result > 0 && ((sc = ssc.accept()) != null))
- return sc.socket();
- to -= System.currentTimeMillis() - st;
- if (to <= 0)
- throw new SocketTimeoutException();
- }
- } finally {
- try {
- ssc.configureBlocking(true);
- } catch (ClosedChannelException e) { }
+ for (;;) {
+ long st = System.currentTimeMillis();
+ if (ssc.pollAccept(to))
+ return ssc.accept().socket();
+ to -= System.currentTimeMillis() - st;
+ if (to <= 0)
+ throw new SocketTimeoutException();
}
+
} catch (Exception x) {
Net.translateException(x);
assert false;
@@ -216,5 +203,4 @@
return -1; // Never happens
}
}
-
}
--- a/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Thu Mar 01 01:35:46 2018 +0100
@@ -35,6 +35,7 @@
import java.net.StandardProtocolFamily;
import java.net.StandardSocketOptions;
import java.nio.channels.AlreadyBoundException;
+import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.NotYetBoundException;
import java.nio.channels.SelectionKey;
@@ -43,6 +44,7 @@
import java.nio.channels.spi.SelectorProvider;
import java.util.Collections;
import java.util.HashSet;
+import java.util.Objects;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
@@ -56,7 +58,6 @@
extends ServerSocketChannel
implements SelChImpl
{
-
// Used to make native close and configure calls
private static NativeDispatcher nd;
@@ -64,10 +65,7 @@
private final FileDescriptor fd;
private final int fdVal;
- // ID of native thread currently blocked in this channel, for signalling
- private volatile long thread;
-
- // Lock held by thread currently blocked in this channel
+ // Lock held by thread currently blocked on this channel
private final ReentrantLock acceptLock = new ReentrantLock();
// Lock held by any thread that modifies the state fields declared below
@@ -77,10 +75,14 @@
// -- The following fields are protected by stateLock
// Channel state, increases monotonically
- private static final int ST_UNINITIALIZED = -1;
private static final int ST_INUSE = 0;
- private static final int ST_KILLED = 1;
- private int state = ST_UNINITIALIZED;
+ private static final int ST_CLOSING = 1;
+ private static final int ST_KILLPENDING = 2;
+ private static final int ST_KILLED = 3;
+ private int state;
+
+ // ID of native thread currently blocked in this channel, for signalling
+ private long thread;
// Binding
private InetSocketAddress localAddress; // null => unbound
@@ -98,22 +100,28 @@
super(sp);
this.fd = Net.serverSocket(true);
this.fdVal = IOUtil.fdVal(fd);
- this.state = ST_INUSE;
}
- ServerSocketChannelImpl(SelectorProvider sp,
- FileDescriptor fd,
- boolean bound)
+ ServerSocketChannelImpl(SelectorProvider sp, FileDescriptor fd, boolean bound)
throws IOException
{
super(sp);
this.fd = fd;
this.fdVal = IOUtil.fdVal(fd);
- this.state = ST_INUSE;
- if (bound)
- localAddress = Net.localAddress(fd);
+ if (bound) {
+ synchronized (stateLock) {
+ localAddress = Net.localAddress(fd);
+ }
+ }
}
+ // @throws ClosedChannelException if channel is closed
+ private void ensureOpen() throws ClosedChannelException {
+ if (!isOpen())
+ throw new ClosedChannelException();
+ }
+
+ @Override
public ServerSocket socket() {
synchronized (stateLock) {
if (socket == null)
@@ -125,11 +133,10 @@
@Override
public SocketAddress getLocalAddress() throws IOException {
synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
- return localAddress == null ? localAddress
- : Net.getRevealedLocalAddress(
- Net.asInetSocketAddress(localAddress));
+ ensureOpen();
+ return (localAddress == null)
+ ? null
+ : Net.getRevealedLocalAddress(localAddress);
}
}
@@ -137,13 +144,11 @@
public <T> ServerSocketChannel setOption(SocketOption<T> name, T value)
throws IOException
{
- if (name == null)
- throw new NullPointerException();
+ Objects.requireNonNull(name);
if (!supportedOptions().contains(name))
throw new UnsupportedOperationException("'" + name + "' not supported");
synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
+ ensureOpen();
if (name == StandardSocketOptions.IP_TOS) {
ProtocolFamily family = Net.isIPv6Available() ?
@@ -152,9 +157,7 @@
return this;
}
- if (name == StandardSocketOptions.SO_REUSEADDR &&
- Net.useExclusiveBind())
- {
+ if (name == StandardSocketOptions.SO_REUSEADDR && Net.useExclusiveBind()) {
// SO_REUSEADDR emulated when using exclusive bind
isReuseAddress = (Boolean)value;
} else {
@@ -170,17 +173,13 @@
public <T> T getOption(SocketOption<T> name)
throws IOException
{
- if (name == null)
- throw new NullPointerException();
+ Objects.requireNonNull(name);
if (!supportedOptions().contains(name))
throw new UnsupportedOperationException("'" + name + "' not supported");
synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
- if (name == StandardSocketOptions.SO_REUSEADDR &&
- Net.useExclusiveBind())
- {
+ ensureOpen();
+ if (name == StandardSocketOptions.SO_REUSEADDR && Net.useExclusiveBind()) {
// SO_REUSEADDR emulated when using exclusive bind
return (T)Boolean.valueOf(isReuseAddress);
}
@@ -193,7 +192,7 @@
static final Set<SocketOption<?>> defaultOptions = defaultOptions();
private static Set<SocketOption<?>> defaultOptions() {
- HashSet<SocketOption<?>> set = new HashSet<>(2);
+ HashSet<SocketOption<?>> set = new HashSet<>();
set.add(StandardSocketOptions.SO_RCVBUF);
set.add(StandardSocketOptions.SO_REUSEADDR);
if (Net.isReusePortAvailable()) {
@@ -209,35 +208,23 @@
return DefaultOptionsHolder.defaultOptions;
}
- public boolean isBound() {
- synchronized (stateLock) {
- return localAddress != null;
- }
- }
-
- public InetSocketAddress localAddress() {
- synchronized (stateLock) {
- return localAddress;
- }
- }
-
@Override
public ServerSocketChannel bind(SocketAddress local, int backlog) throws IOException {
acceptLock.lock();
try {
- if (!isOpen())
- throw new ClosedChannelException();
- if (isBound())
- throw new AlreadyBoundException();
- InetSocketAddress isa = (local == null) ? new InetSocketAddress(0) :
- Net.checkAddress(local);
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- sm.checkListen(isa.getPort());
- NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
- Net.bind(fd, isa.getAddress(), isa.getPort());
- Net.listen(fd, backlog < 1 ? 50 : backlog);
synchronized (stateLock) {
+ ensureOpen();
+ if (localAddress != null)
+ throw new AlreadyBoundException();
+ InetSocketAddress isa = (local == null)
+ ? new InetSocketAddress(0)
+ : Net.checkAddress(local);
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkListen(isa.getPort());
+ NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
+ Net.bind(fd, isa.getAddress(), isa.getPort());
+ Net.listen(fd, backlog < 1 ? 50 : backlog);
localAddress = Net.localAddress(fd);
}
} finally {
@@ -246,47 +233,78 @@
return this;
}
+ /**
+ * Marks the beginning of an I/O operation that might block.
+ *
+ * @throws ClosedChannelException if the channel is closed
+ * @throws NotYetBoundException if the channel's socket has not been bound yet
+ */
+ private void begin(boolean blocking) throws ClosedChannelException {
+ if (blocking)
+ begin(); // set blocker to close channel if interrupted
+ synchronized (stateLock) {
+ ensureOpen();
+ if (localAddress == null)
+ throw new NotYetBoundException();
+ if (blocking)
+ thread = NativeThread.current();
+ }
+ }
+
+ /**
+ * Marks the end of an I/O operation that may have blocked.
+ *
+ * @throws AsynchronousCloseException if the channel was closed due to this
+ * thread being interrupted on a blocking I/O operation.
+ */
+ private void end(boolean blocking, boolean completed)
+ throws AsynchronousCloseException
+ {
+ if (blocking) {
+ synchronized (stateLock) {
+ thread = 0;
+ // notify any thread waiting in implCloseSelectableChannel
+ if (state == ST_CLOSING) {
+ stateLock.notifyAll();
+ }
+ }
+ end(completed);
+ }
+ }
+
+ @Override
public SocketChannel accept() throws IOException {
acceptLock.lock();
try {
- if (!isOpen())
- throw new ClosedChannelException();
- if (!isBound())
- throw new NotYetBoundException();
- SocketChannel sc = null;
-
int n = 0;
FileDescriptor newfd = new FileDescriptor();
InetSocketAddress[] isaa = new InetSocketAddress[1];
+ boolean blocking = isBlocking();
try {
- begin();
- if (!isOpen())
- return null;
- thread = NativeThread.current();
- for (;;) {
+ begin(blocking);
+ do {
n = accept(this.fd, newfd, isaa);
- if ((n == IOStatus.INTERRUPTED) && isOpen())
- continue;
- break;
- }
+ } while (n == IOStatus.INTERRUPTED && isOpen());
} finally {
- thread = 0;
- end(n > 0);
+ end(blocking, n > 0);
assert IOStatus.check(n);
}
if (n < 1)
return null;
+ // newly accepted socket is initially in blocking mode
IOUtil.configureBlocking(newfd, true);
+
InetSocketAddress isa = isaa[0];
- sc = new SocketChannelImpl(provider(), newfd, isa);
+ SocketChannel sc = new SocketChannelImpl(provider(), newfd, isa);
+
+ // check permitted to accept connections from the remote address
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
try {
- sm.checkAccept(isa.getAddress().getHostAddress(),
- isa.getPort());
+ sm.checkAccept(isa.getAddress().getHostAddress(), isa.getPort());
} catch (SecurityException x) {
sc.close();
throw x;
@@ -299,33 +317,133 @@
}
}
+ @Override
protected void implConfigureBlocking(boolean block) throws IOException {
- IOUtil.configureBlocking(fd, block);
- }
-
- protected void implCloseSelectableChannel() throws IOException {
- synchronized (stateLock) {
- if (state != ST_KILLED)
- nd.preClose(fd);
- long th = thread;
- if (th != 0)
- NativeThread.signal(th);
- if (!isRegistered())
- kill();
+ acceptLock.lock();
+ try {
+ synchronized (stateLock) {
+ ensureOpen();
+ IOUtil.configureBlocking(fd, block);
+ }
+ } finally {
+ acceptLock.unlock();
}
}
+ /**
+ * Invoked by implCloseChannel to close the channel.
+ *
+ * This method waits for outstanding I/O operations to complete. When in
+ * blocking mode, the socket is pre-closed and the threads in blocking I/O
+ * operations are signalled to ensure that the outstanding I/O operations
+ * complete quickly.
+ *
+ * The socket is closed by this method when it is not registered with a
+ * Selector. Note that a channel configured blocking may be registered with
+ * a Selector. This arises when a key is canceled and the channel configured
+ * to blocking mode before the key is flushed from the Selector.
+ */
+ @Override
+ protected void implCloseSelectableChannel() throws IOException {
+ assert !isOpen();
+
+ boolean interrupted = false;
+ boolean blocking;
+
+ // set state to ST_CLOSING
+ synchronized (stateLock) {
+ assert state < ST_CLOSING;
+ state = ST_CLOSING;
+ blocking = isBlocking();
+ }
+
+ // wait for any outstanding accept to complete
+ if (blocking) {
+ synchronized (stateLock) {
+ assert state == ST_CLOSING;
+ long th = thread;
+ if (th != 0) {
+ nd.preClose(fd);
+ NativeThread.signal(th);
+
+ // wait for accept operation to end
+ while (thread != 0) {
+ try {
+ stateLock.wait();
+ } catch (InterruptedException e) {
+ interrupted = true;
+ }
+ }
+ }
+ }
+ } else {
+ // non-blocking mode: wait for accept to complete
+ acceptLock.lock();
+ acceptLock.unlock();
+ }
+
+ // set state to ST_KILLPENDING
+ synchronized (stateLock) {
+ assert state == ST_CLOSING;
+ state = ST_KILLPENDING;
+ }
+
+ // close socket if not registered with Selector
+ if (!isRegistered())
+ kill();
+
+ // restore interrupt status
+ if (interrupted)
+ Thread.currentThread().interrupt();
+ }
+
+ @Override
public void kill() throws IOException {
synchronized (stateLock) {
- if (state == ST_KILLED)
- return;
- if (state == ST_UNINITIALIZED) {
+ if (state == ST_KILLPENDING) {
state = ST_KILLED;
- return;
+ nd.close(fd);
}
- assert !isOpen() && !isRegistered();
- nd.close(fd);
- state = ST_KILLED;
+ }
+ }
+
+ /**
+ * Returns true if channel's socket is bound
+ */
+ boolean isBound() {
+ synchronized (stateLock) {
+ return localAddress != null;
+ }
+ }
+
+ /**
+ * Returns the local address, or null if not bound
+ */
+ InetSocketAddress localAddress() {
+ synchronized (stateLock) {
+ return localAddress;
+ }
+ }
+
+ /**
+ * Poll this channel's socket for a new connection up to the given timeout.
+ * @return {@code true} if there is a connection to accept
+ */
+ boolean pollAccept(long timeout) throws IOException {
+ assert Thread.holdsLock(blockingLock()) && isBlocking();
+ acceptLock.lock();
+ try {
+ boolean polled = false;
+ try {
+ begin(true);
+ int n = Net.poll(fd, Net.POLLIN, timeout);
+ polled = (n > 0);
+ } finally {
+ end(true, polled);
+ }
+ return polled;
+ } finally {
+ acceptLock.unlock();
}
}
@@ -367,31 +485,6 @@
return translateReadyOps(ops, 0, sk);
}
- // package-private
- int poll(int events, long timeout) throws IOException {
- assert Thread.holdsLock(blockingLock()) && !isBlocking();
-
- acceptLock.lock();
- try {
- int n = 0;
- try {
- begin();
- synchronized (stateLock) {
- if (!isOpen())
- return 0;
- thread = NativeThread.current();
- }
- n = Net.poll(fd, events, timeout);
- } finally {
- thread = 0;
- end(n > 0);
- }
- return n;
- } finally {
- acceptLock.unlock();
- }
- }
-
/**
* Translates an interest operation set into a native poll event set
*/
@@ -421,7 +514,7 @@
sb.append("closed");
} else {
synchronized (stateLock) {
- InetSocketAddress addr = localAddress();
+ InetSocketAddress addr = localAddress;
if (addr == null) {
sb.append("unbound");
} else {
@@ -438,7 +531,8 @@
*
* @implNote Wrap native call to allow instrumentation.
*/
- private int accept(FileDescriptor ssfd, FileDescriptor newfd,
+ private int accept(FileDescriptor ssfd,
+ FileDescriptor newfd,
InetSocketAddress[] isaa)
throws IOException
{
@@ -452,7 +546,8 @@
// Returns 1 on success, or IOStatus.UNAVAILABLE (if non-blocking and no
// connections are pending) or IOStatus.INTERRUPTED.
//
- private native int accept0(FileDescriptor ssfd, FileDescriptor newfd,
+ private native int accept0(FileDescriptor ssfd,
+ FileDescriptor newfd,
InetSocketAddress[] isaa)
throws IOException;
--- a/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java Thu Mar 01 01:35:46 2018 +0100
@@ -44,16 +44,10 @@
import java.nio.channels.SocketChannel;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
-import java.util.concurrent.TimeUnit;
+import static java.util.concurrent.TimeUnit.*;
// Make a socket channel look like a socket.
//
-// The only aspects of java.net.Socket-hood that we don't attempt to emulate
-// here are the interrupted-I/O exceptions (which our Solaris implementations
-// attempt to support) and the sending of urgent data. Otherwise an adapted
-// socket should look enough like a real java.net.Socket to fool most of the
-// developers most of the time, right down to the exception message strings.
-//
// The methods in this class are defined in exactly the same order as in
// java.net.Socket so as to simplify tracking future changes to that class.
//
@@ -61,7 +55,6 @@
class SocketAdaptor
extends Socket
{
-
// The channel being adapted
private final SocketChannelImpl sc;
@@ -102,40 +95,42 @@
throw new IllegalBlockingModeException();
try {
+ // no timeout
if (timeout == 0) {
sc.connect(remote);
return;
}
+ // timed connect
sc.configureBlocking(false);
try {
if (sc.connect(remote))
return;
- long timeoutNanos =
- TimeUnit.NANOSECONDS.convert(timeout,
- TimeUnit.MILLISECONDS);
- for (;;) {
- if (!sc.isOpen())
- throw new ClosedChannelException();
- long startTime = System.nanoTime();
-
- int result = sc.poll(Net.POLLCONN, timeout);
- if (result > 0 && sc.finishConnect())
- break;
- timeoutNanos -= System.nanoTime() - startTime;
- if (timeoutNanos <= 0) {
- try {
- sc.close();
- } catch (IOException x) { }
- throw new SocketTimeoutException();
- }
- }
} finally {
try {
sc.configureBlocking(true);
} catch (ClosedChannelException e) { }
}
+ long timeoutNanos = NANOSECONDS.convert(timeout, MILLISECONDS);
+ long to = timeout;
+ for (;;) {
+ long startTime = System.nanoTime();
+ if (sc.pollConnected(to)) {
+ boolean connected = sc.finishConnect();
+ assert connected;
+ break;
+ }
+ timeoutNanos -= System.nanoTime() - startTime;
+ if (timeoutNanos <= 0) {
+ try {
+ sc.close();
+ } catch (IOException x) { }
+ throw new SocketTimeoutException();
+ }
+ to = MILLISECONDS.convert(timeoutNanos, NANOSECONDS);
+ }
+
} catch (Exception x) {
Net.translateException(x, true);
}
@@ -152,11 +147,11 @@
}
public InetAddress getInetAddress() {
- SocketAddress remote = sc.remoteAddress();
+ InetSocketAddress remote = sc.remoteAddress();
if (remote == null) {
return null;
} else {
- return ((InetSocketAddress)remote).getAddress();
+ return remote.getAddress();
}
}
@@ -171,20 +166,20 @@
}
public int getPort() {
- SocketAddress remote = sc.remoteAddress();
+ InetSocketAddress remote = sc.remoteAddress();
if (remote == null) {
return 0;
} else {
- return ((InetSocketAddress)remote).getPort();
+ return remote.getPort();
}
}
public int getLocalPort() {
- SocketAddress local = sc.localAddress();
+ InetSocketAddress local = sc.localAddress();
if (local == null) {
return -1;
} else {
- return ((InetSocketAddress)local).getPort();
+ return local.getPort();
}
}
@@ -202,34 +197,22 @@
if (!sc.isBlocking())
throw new IllegalBlockingModeException();
- if (timeout == 0)
+ // no timeout
+ long to = SocketAdaptor.this.timeout;
+ if (to == 0)
return sc.read(bb);
- sc.configureBlocking(false);
- try {
- int n;
- if ((n = sc.read(bb)) != 0)
- return n;
- long timeoutNanos =
- TimeUnit.NANOSECONDS.convert(timeout,
- TimeUnit.MILLISECONDS);
- for (;;) {
- if (!sc.isOpen())
- throw new ClosedChannelException();
- long startTime = System.nanoTime();
- int result = sc.poll(Net.POLLIN, timeout);
- if (result > 0) {
- if ((n = sc.read(bb)) != 0)
- return n;
- }
- timeoutNanos -= System.nanoTime() - startTime;
- if (timeoutNanos <= 0)
- throw new SocketTimeoutException();
+ // timed read
+ long timeoutNanos = NANOSECONDS.convert(to, MILLISECONDS);
+ for (;;) {
+ long startTime = System.nanoTime();
+ if (sc.pollRead(to)) {
+ return sc.read(bb);
}
- } finally {
- try {
- sc.configureBlocking(true);
- } catch (ClosedChannelException e) { }
+ timeoutNanos -= System.nanoTime() - startTime;
+ if (timeoutNanos <= 0)
+ throw new SocketTimeoutException();
+ to = MILLISECONDS.convert(timeoutNanos, NANOSECONDS);
}
}
}
@@ -453,5 +436,4 @@
public boolean isOutputShutdown() {
return !sc.isOutputOpen();
}
-
}
--- a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java Thu Mar 01 01:35:46 2018 +0100
@@ -48,6 +48,7 @@
import java.nio.channels.spi.SelectorProvider;
import java.util.Collections;
import java.util.HashSet;
+import java.util.Objects;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
@@ -62,7 +63,6 @@
extends SocketChannel
implements SelChImpl
{
-
// Used to make native read and write calls
private static NativeDispatcher nd;
@@ -70,10 +70,6 @@
private final FileDescriptor fd;
private final int fdVal;
- // IDs of native threads doing reads and writes, for signalling
- private volatile long readerThread;
- private volatile long writerThread;
-
// Lock held by current reading or connecting thread
private final ReentrantLock readLock = new ReentrantLock();
@@ -84,28 +80,32 @@
// DO NOT invoke a blocking I/O operation while holding this lock!
private final Object stateLock = new Object();
+ // Input/Output closed
+ private volatile boolean isInputClosed;
+ private volatile boolean isOutputClosed;
+
// -- The following fields are protected by stateLock
// set true when exclusive binding is on and SO_REUSEADDR is emulated
private boolean isReuseAddress;
// State, increases monotonically
- private static final int ST_UNINITIALIZED = -1;
private static final int ST_UNCONNECTED = 0;
- private static final int ST_PENDING = 1;
+ private static final int ST_CONNECTIONPENDING = 1;
private static final int ST_CONNECTED = 2;
- private static final int ST_KILLPENDING = 3;
- private static final int ST_KILLED = 4;
- private int state = ST_UNINITIALIZED;
+ private static final int ST_CLOSING = 3;
+ private static final int ST_KILLPENDING = 4;
+ private static final int ST_KILLED = 5;
+ private int state;
+
+ // IDs of native threads doing reads and writes, for signalling
+ private long readerThread;
+ private long writerThread;
// Binding
private InetSocketAddress localAddress;
private InetSocketAddress remoteAddress;
- // Input/Output open
- private boolean isInputOpen = true;
- private boolean isOutputOpen = true;
-
// Socket adaptor, created on demand
private Socket socket;
@@ -118,36 +118,43 @@
super(sp);
this.fd = Net.socket(true);
this.fdVal = IOUtil.fdVal(fd);
- this.state = ST_UNCONNECTED;
}
- SocketChannelImpl(SelectorProvider sp,
- FileDescriptor fd,
- boolean bound)
+ SocketChannelImpl(SelectorProvider sp, FileDescriptor fd, boolean bound)
throws IOException
{
super(sp);
this.fd = fd;
this.fdVal = IOUtil.fdVal(fd);
- this.state = ST_UNCONNECTED;
- if (bound)
- this.localAddress = Net.localAddress(fd);
+ if (bound) {
+ synchronized (stateLock) {
+ this.localAddress = Net.localAddress(fd);
+ }
+ }
}
// Constructor for sockets obtained from server sockets
//
- SocketChannelImpl(SelectorProvider sp,
- FileDescriptor fd, InetSocketAddress remote)
+ SocketChannelImpl(SelectorProvider sp, FileDescriptor fd, InetSocketAddress isa)
throws IOException
{
super(sp);
this.fd = fd;
this.fdVal = IOUtil.fdVal(fd);
- this.state = ST_CONNECTED;
- this.localAddress = Net.localAddress(fd);
- this.remoteAddress = remote;
+ synchronized (stateLock) {
+ this.localAddress = Net.localAddress(fd);
+ this.remoteAddress = isa;
+ this.state = ST_CONNECTED;
+ }
}
+ // @throws ClosedChannelException if channel is closed
+ private void ensureOpen() throws ClosedChannelException {
+ if (!isOpen())
+ throw new ClosedChannelException();
+ }
+
+ @Override
public Socket socket() {
synchronized (stateLock) {
if (socket == null)
@@ -159,17 +166,15 @@
@Override
public SocketAddress getLocalAddress() throws IOException {
synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
- return Net.getRevealedLocalAddress(localAddress);
+ ensureOpen();
+ return Net.getRevealedLocalAddress(localAddress);
}
}
@Override
public SocketAddress getRemoteAddress() throws IOException {
synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
+ ensureOpen();
return remoteAddress;
}
}
@@ -178,14 +183,12 @@
public <T> SocketChannel setOption(SocketOption<T> name, T value)
throws IOException
{
- if (name == null)
- throw new NullPointerException();
+ Objects.requireNonNull(name);
if (!supportedOptions().contains(name))
throw new UnsupportedOperationException("'" + name + "' not supported");
synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
+ ensureOpen();
if (name == StandardSocketOptions.IP_TOS) {
ProtocolFamily family = Net.isIPv6Available() ?
@@ -211,18 +214,14 @@
public <T> T getOption(SocketOption<T> name)
throws IOException
{
- if (name == null)
- throw new NullPointerException();
+ Objects.requireNonNull(name);
if (!supportedOptions().contains(name))
throw new UnsupportedOperationException("'" + name + "' not supported");
synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
+ ensureOpen();
- if (name == StandardSocketOptions.SO_REUSEADDR &&
- Net.useExclusiveBind())
- {
+ if (name == StandardSocketOptions.SO_REUSEADDR && Net.useExclusiveBind()) {
// SO_REUSEADDR emulated when using exclusive bind
return (T)Boolean.valueOf(isReuseAddress);
}
@@ -243,7 +242,7 @@
static final Set<SocketOption<?>> defaultOptions = defaultOptions();
private static Set<SocketOption<?>> defaultOptions() {
- HashSet<SocketOption<?>> set = new HashSet<>(8);
+ HashSet<SocketOption<?>> set = new HashSet<>();
set.add(StandardSocketOptions.SO_SNDBUF);
set.add(StandardSocketOptions.SO_RCVBUF);
set.add(StandardSocketOptions.SO_KEEPALIVE);
@@ -256,9 +255,7 @@
// additional options required by socket adaptor
set.add(StandardSocketOptions.IP_TOS);
set.add(ExtendedSocketOption.SO_OOBINLINE);
- ExtendedSocketOptions extendedOptions =
- ExtendedSocketOptions.getInstance();
- set.addAll(extendedOptions.options());
+ set.addAll(ExtendedSocketOptions.getInstance().options());
return Collections.unmodifiableSet(set);
}
}
@@ -268,329 +265,277 @@
return DefaultOptionsHolder.defaultOptions;
}
- private boolean ensureReadOpen() throws ClosedChannelException {
+ /**
+ * Marks the beginning of a read operation that might block.
+ *
+ * @throws ClosedChannelException if the channel is closed
+ * @throws NotYetConnectedException if the channel is not yet connected
+ */
+ private void beginRead(boolean blocking) throws ClosedChannelException {
+ if (blocking) {
+ // set hook for Thread.interrupt
+ begin();
+ }
synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
- if (!isConnected())
+ ensureOpen();
+ if (state != ST_CONNECTED)
throw new NotYetConnectedException();
- if (!isInputOpen)
- return false;
- else
- return true;
+ if (blocking)
+ readerThread = NativeThread.current();
}
}
- private void ensureWriteOpen() throws ClosedChannelException {
- synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
- if (!isOutputOpen)
- throw new ClosedChannelException();
- if (!isConnected())
- throw new NotYetConnectedException();
+ /**
+ * Marks the end of a read operation that may have blocked.
+ *
+ * @throws AsynchronousCloseException if the channel was closed due to this
+ * thread being interrupted on a blocking read operation.
+ */
+ private void endRead(boolean blocking, boolean completed)
+ throws AsynchronousCloseException
+ {
+ if (blocking) {
+ synchronized (stateLock) {
+ readerThread = 0;
+ // notify any thread waiting in implCloseSelectableChannel
+ if (state == ST_CLOSING) {
+ stateLock.notifyAll();
+ }
+ }
+ // remove hook for Thread.interrupt
+ end(completed);
}
}
- private void readerCleanup() throws IOException {
- synchronized (stateLock) {
- readerThread = 0;
- if (state == ST_KILLPENDING)
- kill();
+ @Override
+ public int read(ByteBuffer buf) throws IOException {
+ Objects.requireNonNull(buf);
+
+ readLock.lock();
+ try {
+ boolean blocking = isBlocking();
+ int n = 0;
+ try {
+ beginRead(blocking);
+
+ // check if input is shutdown
+ if (isInputClosed)
+ return IOStatus.EOF;
+
+ if (blocking) {
+ do {
+ n = IOUtil.read(fd, buf, -1, nd);
+ } while (n == IOStatus.INTERRUPTED && isOpen());
+ } else {
+ n = IOUtil.read(fd, buf, -1, nd);
+ }
+ } finally {
+ endRead(blocking, n > 0);
+ if (n <= 0 && isInputClosed)
+ return IOStatus.EOF;
+ }
+ return IOStatus.normalize(n);
+ } finally {
+ readLock.unlock();
}
}
- private void writerCleanup() throws IOException {
- synchronized (stateLock) {
- writerThread = 0;
- if (state == ST_KILLPENDING)
- kill();
- }
- }
-
- public int read(ByteBuffer buf) throws IOException {
-
- if (buf == null)
- throw new NullPointerException();
+ @Override
+ public long read(ByteBuffer[] dsts, int offset, int length)
+ throws IOException
+ {
+ Objects.checkFromIndexSize(offset, length, dsts.length);
readLock.lock();
try {
- if (!ensureReadOpen())
- return -1;
+ boolean blocking = isBlocking();
+ long n = 0;
+ try {
+ beginRead(blocking);
+
+ // check if input is shutdown
+ if (isInputClosed)
+ return IOStatus.EOF;
+
+ if (blocking) {
+ do {
+ n = IOUtil.read(fd, dsts, offset, length, nd);
+ } while (n == IOStatus.INTERRUPTED && isOpen());
+ } else {
+ n = IOUtil.read(fd, dsts, offset, length, nd);
+ }
+ } finally {
+ endRead(blocking, n > 0);
+ if (n <= 0 && isInputClosed)
+ return IOStatus.EOF;
+ }
+ return IOStatus.normalize(n);
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ /**
+ * Marks the beginning of a write operation that might block.
+ *
+ * @throws ClosedChannelException if the channel is closed or output shutdown
+ * @throws NotYetConnectedException if the channel is not yet connected
+ */
+ private void beginWrite(boolean blocking) throws ClosedChannelException {
+ if (blocking) {
+ // set hook for Thread.interrupt
+ begin();
+ }
+ synchronized (stateLock) {
+ ensureOpen();
+ if (isOutputClosed)
+ throw new ClosedChannelException();
+ if (state != ST_CONNECTED)
+ throw new NotYetConnectedException();
+ if (blocking)
+ writerThread = NativeThread.current();
+ }
+ }
+
+ /**
+ * Marks the end of a write operation that may have blocked.
+ *
+ * @throws AsynchronousCloseException if the channel was closed due to this
+ * thread being interrupted on a blocking write operation.
+ */
+ private void endWrite(boolean blocking, boolean completed)
+ throws AsynchronousCloseException
+ {
+ if (blocking) {
+ synchronized (stateLock) {
+ writerThread = 0;
+ // notify any thread waiting in implCloseSelectableChannel
+ if (state == ST_CLOSING) {
+ stateLock.notifyAll();
+ }
+ }
+ // remove hook for Thread.interrupt
+ end(completed);
+ }
+ }
+
+ @Override
+ public int write(ByteBuffer buf) throws IOException {
+ Objects.requireNonNull(buf);
+
+ writeLock.lock();
+ try {
+ boolean blocking = isBlocking();
int n = 0;
try {
-
- // Set up the interruption machinery; see
- // AbstractInterruptibleChannel for details
- //
- begin();
+ beginWrite(blocking);
+ if (blocking) {
+ do {
+ n = IOUtil.write(fd, buf, -1, nd);
+ } while (n == IOStatus.INTERRUPTED && isOpen());
+ } else {
+ n = IOUtil.write(fd, buf, -1, nd);
+ }
+ } finally {
+ endWrite(blocking, n > 0);
+ if (n <= 0 && isOutputClosed)
+ throw new AsynchronousCloseException();
+ }
+ return IOStatus.normalize(n);
+ } finally {
+ writeLock.unlock();
+ }
+ }
- synchronized (stateLock) {
- if (!isOpen()) {
- // Either the current thread is already interrupted, so
- // begin() closed the channel, or another thread closed the
- // channel since we checked it a few bytecodes ago. In
- // either case the value returned here is irrelevant since
- // the invocation of end() in the finally block will throw
- // an appropriate exception.
- //
- return 0;
-
- }
-
- // Save this thread so that it can be signalled on those
- // platforms that require it
- //
- readerThread = NativeThread.current();
- }
+ @Override
+ public long write(ByteBuffer[] srcs, int offset, int length)
+ throws IOException
+ {
+ Objects.checkFromIndexSize(offset, length, srcs.length);
- // Between the previous test of isOpen() and the return of the
- // IOUtil.read invocation below, this channel might be closed
- // or this thread might be interrupted. We rely upon the
- // implicit synchronization point in the kernel read() call to
- // make sure that the right thing happens. In either case the
- // implCloseSelectableChannel method is ultimately invoked in
- // some other thread, so there are three possibilities:
- //
- // - implCloseSelectableChannel() invokes nd.preClose()
- // before this thread invokes read(), in which case the
- // read returns immediately with either EOF or an error,
- // the latter of which will cause an IOException to be
- // thrown.
- //
- // - implCloseSelectableChannel() invokes nd.preClose() after
- // this thread is blocked in read(). On some operating
- // systems (e.g., Solaris and Windows) this causes the read
- // to return immediately with either EOF or an error
- // indication.
- //
- // - implCloseSelectableChannel() invokes nd.preClose() after
- // this thread is blocked in read() but the operating
- // system (e.g., Linux) doesn't support preemptive close,
- // so implCloseSelectableChannel() proceeds to signal this
- // thread, thereby causing the read to return immediately
- // with IOStatus.INTERRUPTED.
- //
- // In all three cases the invocation of end() in the finally
- // clause will notice that the channel has been closed and
- // throw an appropriate exception (AsynchronousCloseException
- // or ClosedByInterruptException) if necessary.
- //
- // *There is A fourth possibility. implCloseSelectableChannel()
- // invokes nd.preClose(), signals reader/writer thred and quickly
- // moves on to nd.close() in kill(), which does a real close.
- // Then a third thread accepts a new connection, opens file or
- // whatever that causes the released "fd" to be recycled. All
- // above happens just between our last isOpen() check and the
- // next kernel read reached, with the recycled "fd". The solution
- // is to postpone the real kill() if there is a reader or/and
- // writer thread(s) over there "waiting", leave the cleanup/kill
- // to the reader or writer thread. (the preClose() still happens
- // so the connection gets cut off as usual).
- //
- // For socket channels there is the additional wrinkle that
- // asynchronous shutdown works much like asynchronous close,
- // except that the channel is shutdown rather than completely
- // closed. This is analogous to the first two cases above,
- // except that the shutdown operation plays the role of
- // nd.preClose().
- for (;;) {
- n = IOUtil.read(fd, buf, -1, nd);
- if ((n == IOStatus.INTERRUPTED) && isOpen()) {
- // The system call was interrupted but the channel
- // is still open, so retry
- continue;
- }
- return IOStatus.normalize(n);
+ writeLock.lock();
+ try {
+ boolean blocking = isBlocking();
+ long n = 0;
+ try {
+ beginWrite(blocking);
+ if (blocking) {
+ do {
+ n = IOUtil.write(fd, srcs, offset, length, nd);
+ } while (n == IOStatus.INTERRUPTED && isOpen());
+ } else {
+ n = IOUtil.write(fd, srcs, offset, length, nd);
}
-
} finally {
- readerCleanup(); // Clear reader thread
- // The end method, which is defined in our superclass
- // AbstractInterruptibleChannel, resets the interruption
- // machinery. If its argument is true then it returns
- // normally; otherwise it checks the interrupt and open state
- // of this channel and throws an appropriate exception if
- // necessary.
- //
- // So, if we actually managed to do any I/O in the above try
- // block then we pass true to the end method. We also pass
- // true if the channel was in non-blocking mode when the I/O
- // operation was initiated but no data could be transferred;
- // this prevents spurious exceptions from being thrown in the
- // rare event that a channel is closed or a thread is
- // interrupted at the exact moment that a non-blocking I/O
- // request is made.
- //
- end(n > 0 || (n == IOStatus.UNAVAILABLE));
+ endWrite(blocking, n > 0);
+ if (n <= 0 && isOutputClosed)
+ throw new AsynchronousCloseException();
+ }
+ return IOStatus.normalize(n);
+ } finally {
+ writeLock.unlock();
+ }
+ }
- // Extra case for socket channels: Asynchronous shutdown
- //
+ /**
+ * Writes a byte of out of band data.
+ */
+ int sendOutOfBandData(byte b) throws IOException {
+ writeLock.lock();
+ try {
+ boolean blocking = isBlocking();
+ int n = 0;
+ try {
+ beginWrite(blocking);
+ if (blocking) {
+ do {
+ n = sendOutOfBandData(fd, b);
+ } while (n == IOStatus.INTERRUPTED && isOpen());
+ } else {
+ n = sendOutOfBandData(fd, b);
+ }
+ } finally {
+ endWrite(blocking, n > 0);
+ if (n <= 0 && isOutputClosed)
+ throw new AsynchronousCloseException();
+ }
+ return IOStatus.normalize(n);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ @Override
+ protected void implConfigureBlocking(boolean block) throws IOException {
+ readLock.lock();
+ try {
+ writeLock.lock();
+ try {
synchronized (stateLock) {
- if ((n <= 0) && (!isInputOpen))
- return IOStatus.EOF;
+ ensureOpen();
+ IOUtil.configureBlocking(fd, block);
}
-
- assert IOStatus.check(n);
-
+ } finally {
+ writeLock.unlock();
}
} finally {
readLock.unlock();
}
}
- public long read(ByteBuffer[] dsts, int offset, int length)
- throws IOException
- {
- if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
- throw new IndexOutOfBoundsException();
- readLock.lock();
- try {
- if (!ensureReadOpen())
- return -1;
- long n = 0;
- try {
- begin();
- synchronized (stateLock) {
- if (!isOpen())
- return 0;
- readerThread = NativeThread.current();
- }
-
- for (;;) {
- n = IOUtil.read(fd, dsts, offset, length, nd);
- if ((n == IOStatus.INTERRUPTED) && isOpen())
- continue;
- return IOStatus.normalize(n);
- }
- } finally {
- readerCleanup();
- end(n > 0 || (n == IOStatus.UNAVAILABLE));
- synchronized (stateLock) {
- if ((n <= 0) && (!isInputOpen))
- return IOStatus.EOF;
- }
- assert IOStatus.check(n);
- }
- } finally {
- readLock.unlock();
- }
- }
-
- public int write(ByteBuffer buf) throws IOException {
- if (buf == null)
- throw new NullPointerException();
- writeLock.lock();
- try {
- ensureWriteOpen();
- int n = 0;
- try {
- begin();
- synchronized (stateLock) {
- if (!isOpen())
- return 0;
- writerThread = NativeThread.current();
- }
- for (;;) {
- n = IOUtil.write(fd, buf, -1, nd);
- if ((n == IOStatus.INTERRUPTED) && isOpen())
- continue;
- return IOStatus.normalize(n);
- }
- } finally {
- writerCleanup();
- end(n > 0 || (n == IOStatus.UNAVAILABLE));
- synchronized (stateLock) {
- if ((n <= 0) && (!isOutputOpen))
- throw new AsynchronousCloseException();
- }
- assert IOStatus.check(n);
- }
- } finally {
- writeLock.unlock();
- }
- }
-
- public long write(ByteBuffer[] srcs, int offset, int length)
- throws IOException
- {
- if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
- throw new IndexOutOfBoundsException();
- writeLock.lock();
- try {
- ensureWriteOpen();
- long n = 0;
- try {
- begin();
- synchronized (stateLock) {
- if (!isOpen())
- return 0;
- writerThread = NativeThread.current();
- }
- for (;;) {
- n = IOUtil.write(fd, srcs, offset, length, nd);
- if ((n == IOStatus.INTERRUPTED) && isOpen())
- continue;
- return IOStatus.normalize(n);
- }
- } finally {
- writerCleanup();
- end((n > 0) || (n == IOStatus.UNAVAILABLE));
- synchronized (stateLock) {
- if ((n <= 0) && (!isOutputOpen))
- throw new AsynchronousCloseException();
- }
- assert IOStatus.check(n);
- }
- } finally {
- writeLock.unlock();
- }
- }
-
- // package-private
- int sendOutOfBandData(byte b) throws IOException {
- writeLock.lock();
- try {
- ensureWriteOpen();
- int n = 0;
- try {
- begin();
- synchronized (stateLock) {
- if (!isOpen())
- return 0;
- writerThread = NativeThread.current();
- }
- for (;;) {
- n = sendOutOfBandData(fd, b);
- if ((n == IOStatus.INTERRUPTED) && isOpen())
- continue;
- return IOStatus.normalize(n);
- }
- } finally {
- writerCleanup();
- end((n > 0) || (n == IOStatus.UNAVAILABLE));
- synchronized (stateLock) {
- if ((n <= 0) && (!isOutputOpen))
- throw new AsynchronousCloseException();
- }
- assert IOStatus.check(n);
- }
- } finally {
- writeLock.unlock();
- }
- }
-
- protected void implConfigureBlocking(boolean block) throws IOException {
- IOUtil.configureBlocking(fd, block);
- }
-
- public InetSocketAddress localAddress() {
+ /**
+ * Returns the local address, or null if not bound
+ */
+ InetSocketAddress localAddress() {
synchronized (stateLock) {
return localAddress;
}
}
- public SocketAddress remoteAddress() {
+ /**
+ * Returns the remote address, or null if not connected
+ */
+ InetSocketAddress remoteAddress() {
synchronized (stateLock) {
return remoteAddress;
}
@@ -603,9 +548,8 @@
writeLock.lock();
try {
synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
- if (state == ST_PENDING)
+ ensureOpen();
+ if (state == ST_CONNECTIONPENDING)
throw new ConnectionPendingException();
if (localAddress != null)
throw new AlreadyBoundException();
@@ -628,101 +572,115 @@
return this;
}
+ @Override
public boolean isConnected() {
synchronized (stateLock) {
return (state == ST_CONNECTED);
}
}
+ @Override
public boolean isConnectionPending() {
synchronized (stateLock) {
- return (state == ST_PENDING);
+ return (state == ST_CONNECTIONPENDING);
}
}
- void ensureOpenAndUnconnected() throws IOException { // package-private
+ /**
+ * Marks the beginning of a connect operation that might block.
+ *
+ * @throws ClosedChannelException if the channel is closed
+ * @throws AlreadyConnectedException if already connected
+ * @throws ConnectionPendingException is a connection is pending
+ */
+ private void beginConnect(boolean blocking) throws ClosedChannelException {
+ if (blocking) {
+ // set hook for Thread.interrupt
+ begin();
+ }
synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
+ ensureOpen();
if (state == ST_CONNECTED)
throw new AlreadyConnectedException();
- if (state == ST_PENDING)
+ if (state == ST_CONNECTIONPENDING)
throw new ConnectionPendingException();
+ if (blocking)
+ readerThread = NativeThread.current();
}
}
+ /**
+ * Marks the end of a connect operation that may have blocked.
+ *
+ * @throws AsynchronousCloseException if the channel was closed due to this
+ * thread being interrupted on a blocking connect operation.
+ */
+ private void endConnect(boolean blocking, boolean completed)
+ throws AsynchronousCloseException
+ {
+ endRead(blocking, completed);
+ }
+
+ @Override
public boolean connect(SocketAddress sa) throws IOException {
+ InetSocketAddress isa = Net.checkAddress(sa);
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkConnect(isa.getAddress().getHostAddress(), isa.getPort());
+
readLock.lock();
try {
writeLock.lock();
try {
- ensureOpenAndUnconnected();
- InetSocketAddress isa = Net.checkAddress(sa);
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- sm.checkConnect(isa.getAddress().getHostAddress(),
- isa.getPort());
- synchronized (blockingLock()) {
- int n = 0;
- try {
- try {
- begin();
- synchronized (stateLock) {
- if (!isOpen()) {
- return false;
- }
- // notify hook only if unbound
- if (localAddress == null) {
- NetHooks.beforeTcpConnect(fd,
- isa.getAddress(),
- isa.getPort());
- }
- readerThread = NativeThread.current();
- }
- for (;;) {
- InetAddress ia = isa.getAddress();
- if (ia.isAnyLocalAddress())
- ia = InetAddress.getLocalHost();
- n = Net.connect(fd,
- ia,
- isa.getPort());
- if ((n == IOStatus.INTERRUPTED) && isOpen())
- continue;
- break;
- }
-
- } finally {
- readerCleanup();
- end((n > 0) || (n == IOStatus.UNAVAILABLE));
- assert IOStatus.check(n);
- }
- } catch (IOException x) {
- // If an exception was thrown, close the channel after
- // invoking end() so as to avoid bogus
- // AsynchronousCloseExceptions
- close();
- throw x;
- }
- synchronized (stateLock) {
- remoteAddress = isa;
- if (n > 0) {
-
- // Connection succeeded; disallow further
- // invocation
- state = ST_CONNECTED;
- if (isOpen())
- localAddress = Net.localAddress(fd);
- return true;
- }
- // If nonblocking and no exception then connection
- // pending; disallow another invocation
- if (!isBlocking())
- state = ST_PENDING;
- else
- assert false;
+ // notify before-connect hook
+ synchronized (stateLock) {
+ if (state == ST_UNCONNECTED && localAddress == null) {
+ NetHooks.beforeTcpConnect(fd, isa.getAddress(), isa.getPort());
}
}
- return false;
+
+ InetAddress ia = isa.getAddress();
+ if (ia.isAnyLocalAddress())
+ ia = InetAddress.getLocalHost();
+
+ int n = 0;
+ boolean blocking = isBlocking();
+ try {
+ try {
+ beginConnect(blocking);
+ if (blocking) {
+ do {
+ n = Net.connect(fd, ia, isa.getPort());
+ } while (n == IOStatus.INTERRUPTED && isOpen());
+ } else {
+ n = Net.connect(fd, ia, isa.getPort());
+ }
+ } finally {
+ endConnect(blocking, n > 0);
+ }
+ } catch (IOException x) {
+ // connect failed, close socket
+ close();
+ throw x;
+ }
+
+ // connection may be established
+ synchronized (stateLock) {
+ if (!isOpen())
+ throw new AsynchronousCloseException();
+ remoteAddress = isa;
+ if (n > 0) {
+ // connected established
+ localAddress = Net.localAddress(fd);
+ state = ST_CONNECTED;
+ return true;
+ } else {
+ // connection pending
+ assert !blocking;
+ state = ST_CONNECTIONPENDING;
+ return false;
+ }
+ }
} finally {
writeLock.unlock();
}
@@ -731,83 +689,85 @@
}
}
+ /**
+ * Marks the beginning of a finishConnect operation that might block.
+ *
+ * @throws ClosedChannelException if the channel is closed
+ * @throws NoConnectionPendingException if no connection is pending
+ */
+ private void beginFinishConnect(boolean blocking) throws ClosedChannelException {
+ if (blocking) {
+ // set hook for Thread.interrupt
+ begin();
+ }
+ synchronized (stateLock) {
+ ensureOpen();
+ if (state != ST_CONNECTIONPENDING)
+ throw new NoConnectionPendingException();
+ if (blocking)
+ readerThread = NativeThread.current();
+ }
+ }
+
+ /**
+ * Marks the end of a finishConnect operation that may have blocked.
+ *
+ * @throws AsynchronousCloseException if the channel was closed due to this
+ * thread being interrupted on a blocking connect operation.
+ */
+ private void endFinishConnect(boolean blocking, boolean completed)
+ throws AsynchronousCloseException
+ {
+ endRead(blocking, completed);
+ }
+
+ @Override
public boolean finishConnect() throws IOException {
readLock.lock();
try {
writeLock.lock();
try {
+ // already connected?
synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
if (state == ST_CONNECTED)
return true;
- if (state != ST_PENDING)
- throw new NoConnectionPendingException();
}
+
int n = 0;
+ boolean blocking = isBlocking();
try {
try {
- begin();
- synchronized (blockingLock()) {
- synchronized (stateLock) {
- if (!isOpen()) {
- return false;
- }
- readerThread = NativeThread.current();
- }
- if (!isBlocking()) {
- for (;;) {
- n = checkConnect(fd, false);
- if ((n == IOStatus.INTERRUPTED) && isOpen())
- continue;
- break;
- }
- } else {
- for (;;) {
- n = checkConnect(fd, true);
- if (n == 0) {
- // Loop in case of
- // spurious notifications
- continue;
- }
- if ((n == IOStatus.INTERRUPTED) && isOpen())
- continue;
- break;
- }
- }
+ beginFinishConnect(blocking);
+ if (blocking) {
+ do {
+ n = checkConnect(fd, true);
+ } while (n == 0 || (n == IOStatus.INTERRUPTED) && isOpen());
+ } else {
+ n = checkConnect(fd, false);
}
} finally {
- synchronized (stateLock) {
- readerThread = 0;
- if (state == ST_KILLPENDING) {
- kill();
- // poll()/getsockopt() does not report
- // error (throws exception, with n = 0)
- // on Linux platform after dup2 and
- // signal-wakeup. Force n to 0 so the
- // end() can throw appropriate exception
- n = 0;
- }
- }
- end((n > 0) || (n == IOStatus.UNAVAILABLE));
- assert IOStatus.check(n);
+ endFinishConnect(blocking, n > 0);
}
} catch (IOException x) {
- // If an exception was thrown, close the channel after
- // invoking end() so as to avoid bogus
- // AsynchronousCloseExceptions
close();
throw x;
}
- if (n > 0) {
- synchronized (stateLock) {
+
+ // post finishConnect, connection may be established
+ synchronized (stateLock) {
+ if (!isOpen())
+ throw new AsynchronousCloseException();
+ if (n > 0) {
+ // connection established
+ localAddress = Net.localAddress(fd);
state = ST_CONNECTED;
- if (isOpen())
- localAddress = Net.localAddress(fd);
+ return true;
+ } else {
+ // connection still pending
+ assert !blocking;
+ return false;
}
- return true;
}
- return false;
} finally {
writeLock.unlock();
}
@@ -816,18 +776,119 @@
}
}
+ /**
+ * Invoked by implCloseChannel to close the channel.
+ *
+ * This method waits for outstanding I/O operations to complete. When in
+ * blocking mode, the socket is pre-closed and the threads in blocking I/O
+ * operations are signalled to ensure that the outstanding I/O operations
+ * complete quickly.
+ *
+ * If the socket is connected then it is shutdown by this method. The
+ * shutdown ensures that the peer reads EOF for the case that the socket is
+ * not pre-closed or closed by this method.
+ *
+ * The socket is closed by this method when it is not registered with a
+ * Selector. Note that a channel configured blocking may be registered with
+ * a Selector. This arises when a key is canceled and the channel configured
+ * to blocking mode before the key is flushed from the Selector.
+ */
+ @Override
+ protected void implCloseSelectableChannel() throws IOException {
+ assert !isOpen();
+
+ boolean blocking;
+ boolean connected;
+ boolean interrupted = false;
+
+ // set state to ST_CLOSING
+ synchronized (stateLock) {
+ assert state < ST_CLOSING;
+ blocking = isBlocking();
+ connected = (state == ST_CONNECTED);
+ state = ST_CLOSING;
+ }
+
+ // wait for any outstanding I/O operations to complete
+ if (blocking) {
+ synchronized (stateLock) {
+ assert state == ST_CLOSING;
+ long reader = readerThread;
+ long writer = writerThread;
+ if (reader != 0 || writer != 0) {
+ nd.preClose(fd);
+ connected = false; // fd is no longer connected socket
+
+ if (reader != 0)
+ NativeThread.signal(reader);
+ if (writer != 0)
+ NativeThread.signal(writer);
+
+ // wait for blocking I/O operations to end
+ while (readerThread != 0 || writerThread != 0) {
+ try {
+ stateLock.wait();
+ } catch (InterruptedException e) {
+ interrupted = true;
+ }
+ }
+ }
+ }
+ } else {
+ // non-blocking mode: wait for read/write to complete
+ readLock.lock();
+ try {
+ writeLock.lock();
+ writeLock.unlock();
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ // set state to ST_KILLPENDING
+ synchronized (stateLock) {
+ assert state == ST_CLOSING;
+ // if connected, and the channel is registered with a Selector, we
+ // shutdown the output so that the peer reads EOF
+ if (connected && isRegistered()) {
+ try {
+ Net.shutdown(fd, Net.SHUT_WR);
+ } catch (IOException ignore) { }
+ }
+ state = ST_KILLPENDING;
+ }
+
+ // close socket if not registered with Selector
+ if (!isRegistered())
+ kill();
+
+ // restore interrupt status
+ if (interrupted)
+ Thread.currentThread().interrupt();
+ }
+
+ @Override
+ public void kill() throws IOException {
+ synchronized (stateLock) {
+ if (state == ST_KILLPENDING) {
+ state = ST_KILLED;
+ nd.close(fd);
+ }
+ }
+ }
+
@Override
public SocketChannel shutdownInput() throws IOException {
synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
+ ensureOpen();
if (!isConnected())
throw new NotYetConnectedException();
- if (isInputOpen) {
+ if (!isInputClosed) {
Net.shutdown(fd, Net.SHUT_RD);
- if (readerThread != 0)
- NativeThread.signal(readerThread);
- isInputOpen = false;
+ long thread = readerThread;
+ if (thread != 0)
+ NativeThread.signal(thread);
+ isInputClosed = true;
}
return this;
}
@@ -836,94 +897,78 @@
@Override
public SocketChannel shutdownOutput() throws IOException {
synchronized (stateLock) {
- if (!isOpen())
- throw new ClosedChannelException();
+ ensureOpen();
if (!isConnected())
throw new NotYetConnectedException();
- if (isOutputOpen) {
+ if (!isOutputClosed) {
Net.shutdown(fd, Net.SHUT_WR);
- if (writerThread != 0)
- NativeThread.signal(writerThread);
- isOutputOpen = false;
+ long thread = writerThread;
+ if (thread != 0)
+ NativeThread.signal(thread);
+ isOutputClosed = true;
}
return this;
}
}
- public boolean isInputOpen() {
- synchronized (stateLock) {
- return isInputOpen;
- }
+ boolean isInputOpen() {
+ return !isInputClosed;
+ }
+
+ boolean isOutputOpen() {
+ return !isOutputClosed;
}
- public boolean isOutputOpen() {
- synchronized (stateLock) {
- return isOutputOpen;
+ /**
+ * Poll this channel's socket for reading up to the given timeout.
+ * @return {@code true} if the socket is polled
+ */
+ boolean pollRead(long timeout) throws IOException {
+ boolean blocking = isBlocking();
+ assert Thread.holdsLock(blockingLock()) && blocking;
+
+ readLock.lock();
+ try {
+ boolean polled = false;
+ try {
+ beginRead(blocking);
+ int n = Net.poll(fd, Net.POLLIN, timeout);
+ polled = (n > 0);
+ } finally {
+ endRead(blocking, polled);
+ }
+ return polled;
+ } finally {
+ readLock.unlock();
}
}
- // AbstractInterruptibleChannel synchronizes invocations of this method
- // using AbstractInterruptibleChannel.closeLock, and also ensures that this
- // method is only ever invoked once. Before we get to this method, isOpen
- // (which is volatile) will have been set to false.
- //
- protected void implCloseSelectableChannel() throws IOException {
- synchronized (stateLock) {
- isInputOpen = false;
- isOutputOpen = false;
-
- // Close the underlying file descriptor and dup it to a known fd
- // that's already closed. This prevents other operations on this
- // channel from using the old fd, which might be recycled in the
- // meantime and allocated to an entirely different channel.
- //
- if (state != ST_KILLED)
- nd.preClose(fd);
-
- // Signal native threads, if needed. If a target thread is not
- // currently blocked in an I/O operation then no harm is done since
- // the signal handler doesn't actually do anything.
- //
- if (readerThread != 0)
- NativeThread.signal(readerThread);
-
- if (writerThread != 0)
- NativeThread.signal(writerThread);
+ /**
+ * Poll this channel's socket for a connection, up to the given timeout.
+ * @return {@code true} if the socket is polled
+ */
+ boolean pollConnected(long timeout) throws IOException {
+ boolean blocking = isBlocking();
+ assert Thread.holdsLock(blockingLock()) && blocking;
- // If this channel is not registered then it's safe to close the fd
- // immediately since we know at this point that no thread is
- // blocked in an I/O operation upon the channel and, since the
- // channel is marked closed, no thread will start another such
- // operation. If this channel is registered then we don't close
- // the fd since it might be in use by a selector. In that case
- // closing this channel caused its keys to be cancelled, so the
- // last selector to deregister a key for this channel will invoke
- // kill() to close the fd.
- //
- if (!isRegistered())
- kill();
- }
- }
-
- public void kill() throws IOException {
- synchronized (stateLock) {
- if (state == ST_KILLED)
- return;
- if (state == ST_UNINITIALIZED) {
- state = ST_KILLED;
- return;
+ readLock.lock();
+ try {
+ writeLock.lock();
+ try {
+ boolean polled = false;
+ try {
+ beginFinishConnect(blocking);
+ int n = Net.poll(fd, Net.POLLCONN, timeout);
+ polled = (n > 0);
+ } finally {
+ endFinishConnect(blocking, polled);
+ }
+ return polled;
+ } finally {
+ writeLock.unlock();
}
- assert !isOpen() && !isRegistered();
-
- // Postpone the kill if there is a waiting reader
- // or writer thread. See the comments in read() for
- // more detailed explanation.
- if (readerThread == 0 && writerThread == 0) {
- nd.close(fd);
- state = ST_KILLED;
- } else {
- state = ST_KILLPENDING;
- }
+ } finally {
+ readLock.unlock();
}
}
@@ -956,7 +1001,7 @@
if (((ops & Net.POLLCONN) != 0) &&
((intOps & SelectionKey.OP_CONNECT) != 0) &&
- ((state == ST_UNCONNECTED) || (state == ST_PENDING))) {
+ ((state == ST_UNCONNECTED) || (state == ST_CONNECTIONPENDING))) {
newOps |= SelectionKey.OP_CONNECT;
}
@@ -977,31 +1022,6 @@
return translateReadyOps(ops, 0, sk);
}
- // package-private
- int poll(int events, long timeout) throws IOException {
- assert Thread.holdsLock(blockingLock()) && !isBlocking();
-
- readLock.lock();
- try {
- int n = 0;
- try {
- begin();
- synchronized (stateLock) {
- if (!isOpen())
- return 0;
- readerThread = NativeThread.current();
- }
- n = Net.poll(fd, events, timeout);
- } finally {
- readerCleanup();
- end(n > 0);
- }
- return n;
- } finally {
- readLock.unlock();
- }
- }
-
/**
* Translates an interest operation set into a native poll event set
*/
@@ -1037,14 +1057,14 @@
case ST_UNCONNECTED:
sb.append("unconnected");
break;
- case ST_PENDING:
+ case ST_CONNECTIONPENDING:
sb.append("connection-pending");
break;
case ST_CONNECTED:
sb.append("connected");
- if (!isInputOpen)
+ if (isInputClosed)
sb.append(" ishut");
- if (!isOutputOpen)
+ if (isOutputClosed)
sb.append(" oshut");
break;
}
--- a/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java Thu Mar 01 01:35:46 2018 +0100
@@ -28,31 +28,26 @@
import java.io.FileDescriptor;
import java.io.IOException;
import java.nio.ByteBuffer;
+import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.ClosedChannelException;
+import java.nio.channels.NotYetConnectedException;
import java.nio.channels.Pipe;
import java.nio.channels.SelectionKey;
import java.nio.channels.spi.SelectorProvider;
+import java.util.Objects;
import java.util.concurrent.locks.ReentrantLock;
-
class SinkChannelImpl
extends Pipe.SinkChannel
implements SelChImpl
{
-
// Used to make native read and write calls
private static final NativeDispatcher nd = new FileDispatcherImpl();
// The file descriptor associated with this channel
private final FileDescriptor fd;
-
- // fd value needed for dev/poll. This value will remain valid
- // even after the value in the file descriptor object has been set to -1
private final int fdVal;
- // ID of native thread doing write, for signalling
- private volatile long thread;
-
// Lock held by current writing thread
private final ReentrantLock writeLock = new ReentrantLock();
@@ -63,10 +58,14 @@
// -- The following fields are protected by stateLock
// Channel state
- private static final int ST_UNINITIALIZED = -1;
private static final int ST_INUSE = 0;
- private static final int ST_KILLED = 1;
- private volatile int state = ST_UNINITIALIZED;
+ private static final int ST_CLOSING = 1;
+ private static final int ST_KILLPENDING = 2;
+ private static final int ST_KILLED = 3;
+ private int state;
+
+ // ID of native thread doing write, for signalling
+ private long thread;
// -- End of fields protected by stateLock
@@ -83,39 +82,88 @@
super(sp);
this.fd = fd;
this.fdVal = IOUtil.fdVal(fd);
- this.state = ST_INUSE;
}
+ /**
+ * Invoked by implCloseChannel to close the channel.
+ */
+ @Override
protected void implCloseSelectableChannel() throws IOException {
+ assert !isOpen();
+
+ boolean interrupted = false;
+ boolean blocking;
+
+ // set state to ST_CLOSING
synchronized (stateLock) {
- if (state != ST_KILLED)
- nd.preClose(fd);
- long th = thread;
- if (th != 0)
- NativeThread.signal(th);
- if (!isRegistered())
- kill();
+ assert state < ST_CLOSING;
+ state = ST_CLOSING;
+ blocking = isBlocking();
+ }
+
+ // wait for any outstanding write to complete
+ if (blocking) {
+ synchronized (stateLock) {
+ assert state == ST_CLOSING;
+ long th = thread;
+ if (th != 0) {
+ nd.preClose(fd);
+ NativeThread.signal(th);
+
+ // wait for write operation to end
+ while (thread != 0) {
+ try {
+ stateLock.wait();
+ } catch (InterruptedException e) {
+ interrupted = true;
+ }
+ }
+ }
+ }
+ } else {
+ // non-blocking mode: wait for write to complete
+ writeLock.lock();
+ writeLock.unlock();
+ }
+
+ // set state to ST_KILLPENDING
+ synchronized (stateLock) {
+ assert state == ST_CLOSING;
+ state = ST_KILLPENDING;
+ }
+
+ // close socket if not registered with Selector
+ if (!isRegistered())
+ kill();
+
+ // restore interrupt status
+ if (interrupted)
+ Thread.currentThread().interrupt();
+ }
+
+ @Override
+ public void kill() throws IOException {
+ synchronized (stateLock) {
+ assert thread == 0;
+ if (state == ST_KILLPENDING) {
+ state = ST_KILLED;
+ nd.close(fd);
+ }
}
}
- public void kill() throws IOException {
- synchronized (stateLock) {
- if (state == ST_KILLED)
- return;
- if (state == ST_UNINITIALIZED) {
- state = ST_KILLED;
- return;
+ @Override
+ protected void implConfigureBlocking(boolean block) throws IOException {
+ writeLock.lock();
+ try {
+ synchronized (stateLock) {
+ IOUtil.configureBlocking(fd, block);
}
- assert !isOpen() && !isRegistered();
- nd.close(fd);
- state = ST_KILLED;
+ } finally {
+ writeLock.unlock();
}
}
- protected void implConfigureBlocking(boolean block) throws IOException {
- IOUtil.configureBlocking(fd, block);
- }
-
public boolean translateReadyOps(int ops, int initialOps,
SelectionKeyImpl sk) {
int intOps = sk.nioInterestOps();// Do this just once, it synchronizes
@@ -153,67 +201,95 @@
sk.selector.putEventOps(sk, ops);
}
- private void ensureOpen() throws IOException {
- if (!isOpen())
- throw new ClosedChannelException();
+ /**
+ * Marks the beginning of a write operation that might block.
+ *
+ * @throws ClosedChannelException if the channel is closed
+ * @throws NotYetConnectedException if the channel is not yet connected
+ */
+ private void beginWrite(boolean blocking) throws ClosedChannelException {
+ if (blocking) {
+ // set hook for Thread.interrupt
+ begin();
+ }
+ synchronized (stateLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+ if (blocking)
+ thread = NativeThread.current();
+ }
}
+ /**
+ * Marks the end of a write operation that may have blocked.
+ *
+ * @throws AsynchronousCloseException if the channel was closed due to this
+ * thread being interrupted on a blocking write operation.
+ */
+ private void endWrite(boolean blocking, boolean completed)
+ throws AsynchronousCloseException
+ {
+ if (blocking) {
+ synchronized (stateLock) {
+ thread = 0;
+ // notify any thread waiting in implCloseSelectableChannel
+ if (state == ST_CLOSING) {
+ stateLock.notifyAll();
+ }
+ }
+ // remove hook for Thread.interrupt
+ end(completed);
+ }
+ }
+
+ @Override
public int write(ByteBuffer src) throws IOException {
+ Objects.requireNonNull(src);
+
writeLock.lock();
try {
- ensureOpen();
+ boolean blocking = isBlocking();
int n = 0;
try {
- begin();
- if (!isOpen())
- return 0;
- thread = NativeThread.current();
+ beginWrite(blocking);
do {
n = IOUtil.write(fd, src, -1, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
- return IOStatus.normalize(n);
} finally {
- thread = 0;
- end((n > 0) || (n == IOStatus.UNAVAILABLE));
+ endWrite(blocking, n > 0);
assert IOStatus.check(n);
}
+ return IOStatus.normalize(n);
} finally {
writeLock.unlock();
}
}
- public long write(ByteBuffer[] srcs) throws IOException {
- if (srcs == null)
- throw new NullPointerException();
+ @Override
+ public long write(ByteBuffer[] srcs, int offset, int length) throws IOException {
+ Objects.checkFromIndexSize(offset, length, srcs.length);
writeLock.lock();
try {
- ensureOpen();
+ boolean blocking = isBlocking();
long n = 0;
try {
- begin();
- if (!isOpen())
- return 0;
- thread = NativeThread.current();
+ beginWrite(blocking);
do {
- n = IOUtil.write(fd, srcs, nd);
+ n = IOUtil.write(fd, srcs, offset, length, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
- return IOStatus.normalize(n);
} finally {
- thread = 0;
- end((n > 0) || (n == IOStatus.UNAVAILABLE));
+ endWrite(blocking, n > 0);
assert IOStatus.check(n);
}
+ return IOStatus.normalize(n);
} finally {
writeLock.unlock();
}
}
- public long write(ByteBuffer[] srcs, int offset, int length)
- throws IOException
- {
- if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
- throw new IndexOutOfBoundsException();
- return write(Util.subsequence(srcs, offset, length));
+ @Override
+ public long write(ByteBuffer[] srcs) throws IOException {
+ return write(srcs, 0, srcs.length);
}
}
--- a/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java Thu Mar 01 01:35:46 2018 +0100
@@ -28,31 +28,26 @@
import java.io.FileDescriptor;
import java.io.IOException;
import java.nio.ByteBuffer;
+import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.ClosedChannelException;
+import java.nio.channels.NotYetConnectedException;
import java.nio.channels.Pipe;
import java.nio.channels.SelectionKey;
import java.nio.channels.spi.SelectorProvider;
+import java.util.Objects;
import java.util.concurrent.locks.ReentrantLock;
-
class SourceChannelImpl
extends Pipe.SourceChannel
implements SelChImpl
{
-
// Used to make native read and write calls
private static final NativeDispatcher nd = new FileDispatcherImpl();
// The file descriptor associated with this channel
private final FileDescriptor fd;
-
- // fd value needed for dev/poll. This value will remain valid
- // even after the value in the file descriptor object has been set to -1
private final int fdVal;
- // ID of native thread doing read, for signalling
- private volatile long thread;
-
// Lock held by current reading thread
private final ReentrantLock readLock = new ReentrantLock();
@@ -63,10 +58,14 @@
// -- The following fields are protected by stateLock
// Channel state
- private static final int ST_UNINITIALIZED = -1;
private static final int ST_INUSE = 0;
- private static final int ST_KILLED = 1;
- private volatile int state = ST_UNINITIALIZED;
+ private static final int ST_CLOSING = 1;
+ private static final int ST_KILLPENDING = 2;
+ private static final int ST_KILLED = 3;
+ private int state;
+
+ // ID of native thread doing read, for signalling
+ private long thread;
// -- End of fields protected by stateLock
@@ -83,39 +82,88 @@
super(sp);
this.fd = fd;
this.fdVal = IOUtil.fdVal(fd);
- this.state = ST_INUSE;
}
+ /**
+ * Invoked by implCloseChannel to close the channel.
+ */
+ @Override
protected void implCloseSelectableChannel() throws IOException {
+ assert !isOpen();
+
+ boolean interrupted = false;
+ boolean blocking;
+
+ // set state to ST_CLOSING
synchronized (stateLock) {
- if (state != ST_KILLED)
- nd.preClose(fd);
- long th = thread;
- if (th != 0)
- NativeThread.signal(th);
- if (!isRegistered())
- kill();
+ assert state < ST_CLOSING;
+ state = ST_CLOSING;
+ blocking = isBlocking();
+ }
+
+ // wait for any outstanding read to complete
+ if (blocking) {
+ synchronized (stateLock) {
+ assert state == ST_CLOSING;
+ long th = thread;
+ if (th != 0) {
+ nd.preClose(fd);
+ NativeThread.signal(th);
+
+ // wait for read operation to end
+ while (thread != 0) {
+ try {
+ stateLock.wait();
+ } catch (InterruptedException e) {
+ interrupted = true;
+ }
+ }
+ }
+ }
+ } else {
+ // non-blocking mode: wait for read to complete
+ readLock.lock();
+ readLock.unlock();
+ }
+
+ // set state to ST_KILLPENDING
+ synchronized (stateLock) {
+ assert state == ST_CLOSING;
+ state = ST_KILLPENDING;
+ }
+
+ // close socket if not registered with Selector
+ if (!isRegistered())
+ kill();
+
+ // restore interrupt status
+ if (interrupted)
+ Thread.currentThread().interrupt();
+ }
+
+ @Override
+ public void kill() throws IOException {
+ synchronized (stateLock) {
+ assert thread == 0;
+ if (state == ST_KILLPENDING) {
+ state = ST_KILLED;
+ nd.close(fd);
+ }
}
}
- public void kill() throws IOException {
- synchronized (stateLock) {
- if (state == ST_KILLED)
- return;
- if (state == ST_UNINITIALIZED) {
- state = ST_KILLED;
- return;
+ @Override
+ protected void implConfigureBlocking(boolean block) throws IOException {
+ readLock.lock();
+ try {
+ synchronized (stateLock) {
+ IOUtil.configureBlocking(fd, block);
}
- assert !isOpen() && !isRegistered();
- nd.close(fd);
- state = ST_KILLED;
+ } finally {
+ readLock.unlock();
}
}
- protected void implConfigureBlocking(boolean block) throws IOException {
- IOUtil.configureBlocking(fd, block);
- }
-
public boolean translateReadyOps(int ops, int initialOps,
SelectionKeyImpl sk) {
int intOps = sk.nioInterestOps(); // Do this just once, it synchronizes
@@ -153,68 +201,95 @@
sk.selector.putEventOps(sk, ops);
}
- private void ensureOpen() throws IOException {
- if (!isOpen())
- throw new ClosedChannelException();
+ /**
+ * Marks the beginning of a read operation that might block.
+ *
+ * @throws ClosedChannelException if the channel is closed
+ * @throws NotYetConnectedException if the channel is not yet connected
+ */
+ private void beginRead(boolean blocking) throws ClosedChannelException {
+ if (blocking) {
+ // set hook for Thread.interrupt
+ begin();
+ }
+ synchronized (stateLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+ if (blocking)
+ thread = NativeThread.current();
+ }
}
+ /**
+ * Marks the end of a read operation that may have blocked.
+ *
+ * @throws AsynchronousCloseException if the channel was closed due to this
+ * thread being interrupted on a blocking read operation.
+ */
+ private void endRead(boolean blocking, boolean completed)
+ throws AsynchronousCloseException
+ {
+ if (blocking) {
+ synchronized (stateLock) {
+ thread = 0;
+ // notify any thread waiting in implCloseSelectableChannel
+ if (state == ST_CLOSING) {
+ stateLock.notifyAll();
+ }
+ }
+ // remove hook for Thread.interrupt
+ end(completed);
+ }
+ }
+
+ @Override
public int read(ByteBuffer dst) throws IOException {
+ Objects.requireNonNull(dst);
readLock.lock();
try {
- ensureOpen();
+ boolean blocking = isBlocking();
int n = 0;
try {
- begin();
- if (!isOpen())
- return 0;
- thread = NativeThread.current();
+ beginRead(blocking);
do {
n = IOUtil.read(fd, dst, -1, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
- return IOStatus.normalize(n);
} finally {
- thread = 0;
- end((n > 0) || (n == IOStatus.UNAVAILABLE));
+ endRead(blocking, n > 0);
assert IOStatus.check(n);
}
+ return IOStatus.normalize(n);
} finally {
readLock.unlock();
}
}
- public long read(ByteBuffer[] dsts, int offset, int length)
- throws IOException
- {
- if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
- throw new IndexOutOfBoundsException();
- return read(Util.subsequence(dsts, offset, length));
- }
-
- public long read(ByteBuffer[] dsts) throws IOException {
- if (dsts == null)
- throw new NullPointerException();
+ @Override
+ public long read(ByteBuffer[] dsts, int offset, int length) throws IOException {
+ Objects.checkFromIndexSize(offset, length, dsts.length);
readLock.lock();
try {
- ensureOpen();
+ boolean blocking = isBlocking();
long n = 0;
try {
- begin();
- if (!isOpen())
- return 0;
- thread = NativeThread.current();
+ beginRead(blocking);
do {
- n = IOUtil.read(fd, dsts, nd);
+ n = IOUtil.read(fd, dsts, offset, length, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
- return IOStatus.normalize(n);
} finally {
- thread = 0;
- end((n > 0) || (n == IOStatus.UNAVAILABLE));
+ endRead(blocking, n > 0);
assert IOStatus.check(n);
}
+ return IOStatus.normalize(n);
} finally {
readLock.unlock();
}
}
+
+ @Override
+ public long read(ByteBuffer[] dsts) throws IOException {
+ return read(dsts, 0, dsts.length);
+ }
}
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -21,6 +21,7 @@
package com.sun.org.apache.xerces.internal.impl;
+import com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException;
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
import com.sun.org.apache.xerces.internal.util.AugmentationsImpl;
import com.sun.org.apache.xerces.internal.util.XMLAttributesIteratorImpl;
@@ -45,6 +46,7 @@
import com.sun.xml.internal.stream.XMLBufferListener;
import com.sun.xml.internal.stream.XMLEntityStorage;
import com.sun.xml.internal.stream.dtd.DTDGrammarUtil;
+import java.io.CharConversionException;
import java.io.EOFException;
import java.io.IOException;
import javax.xml.XMLConstants;
@@ -3075,6 +3077,20 @@
}//switch
}
+ // encoding errors
+ catch (MalformedByteSequenceException e) {
+ fErrorReporter.reportError(e.getDomain(), e.getKey(),
+ e.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
+ return -1;
+ }
+ catch (CharConversionException e) {
+ fErrorReporter.reportError(
+ XMLMessageFormatter.XML_DOMAIN,
+ "CharConversionFailure",
+ null,
+ XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
+ return -1;
+ }
// premature end of file
catch (EOFException e) {
endOfFileHook(e);
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -22,6 +22,8 @@
package com.sun.org.apache.xerces.internal.impl;
import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDDescription;
+import com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException;
+import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
import com.sun.org.apache.xerces.internal.util.XMLChar;
@@ -38,6 +40,7 @@
import com.sun.xml.internal.stream.Entity;
import com.sun.xml.internal.stream.StaxXMLInputSource;
import com.sun.xml.internal.stream.dtd.DTDGrammarUtil;
+import java.io.CharConversionException;
import java.io.EOFException;
import java.io.IOException;
import javax.xml.stream.XMLInputFactory;
@@ -758,7 +761,19 @@
return XMLEvent.START_DOCUMENT;
}
-
+ // encoding errors
+ catch (MalformedByteSequenceException e) {
+ fErrorReporter.reportError(e.getDomain(), e.getKey(),
+ e.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
+ return -1;
+ } catch (CharConversionException e) {
+ fErrorReporter.reportError(
+ XMLMessageFormatter.XML_DOMAIN,
+ "CharConversionFailure",
+ null,
+ XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
+ return -1;
+ }
// premature end of file
catch (EOFException e) {
reportFatalError("PrematureEOF", null);
@@ -980,6 +995,19 @@
*/
}
}
+ // encoding errors
+ catch (MalformedByteSequenceException e) {
+ fErrorReporter.reportError(e.getDomain(), e.getKey(),
+ e.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
+ return -1;
+ } catch (CharConversionException e) {
+ fErrorReporter.reportError(
+ XMLMessageFormatter.XML_DOMAIN,
+ "CharConversionFailure",
+ null,
+ XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
+ return -1;
+ }
// premature end of file
catch (EOFException e) {
reportFatalError("PrematureEOF", null);
@@ -1152,7 +1180,19 @@
}
} while (complete || again);
}
-
+ // encoding errors
+ catch (MalformedByteSequenceException e) {
+ fErrorReporter.reportError(e.getDomain(), e.getKey(),
+ e.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
+ return false;
+ } catch (CharConversionException e) {
+ fErrorReporter.reportError(
+ XMLMessageFormatter.XML_DOMAIN,
+ "CharConversionFailure",
+ null,
+ XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
+ return false;
+ }
// premature end of file
catch (EOFException e) {
e.printStackTrace();
@@ -1416,7 +1456,18 @@
}
default: throw new XNIException("Scanner State " + fScannerState + " not Recognized ");
}//switch
-
+ // encoding errors
+ } catch (MalformedByteSequenceException e) {
+ fErrorReporter.reportError(e.getDomain(), e.getKey(),
+ e.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
+ return -1;
+ } catch (CharConversionException e) {
+ fErrorReporter.reportError(
+ XMLMessageFormatter.XML_DOMAIN,
+ "CharConversionFailure",
+ null,
+ XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
+ return -1;
} catch (EOFException e) {
// NOTE: This is the only place we're allowed to reach
// the real end of the document stream. Unless the
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLVersionDetector.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLVersionDetector.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -20,9 +20,11 @@
package com.sun.org.apache.xerces.internal.impl;
+import java.io.CharConversionException;
import java.io.EOFException;
import java.io.IOException;
+import com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException;
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
import com.sun.org.apache.xerces.internal.util.SymbolTable;
import com.sun.org.apache.xerces.internal.xni.XMLString;
@@ -196,7 +198,21 @@
return Constants.XML_VERSION_1_0;
// premature end of file
}
- catch (EOFException e) {
+ // encoding errors
+ catch (MalformedByteSequenceException e) {
+ fErrorReporter.reportError(e.getDomain(), e.getKey(),
+ e.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
+ scanner.detectingVersion = false;
+ return Constants.XML_VERSION_1_0;
+ } catch (CharConversionException e) {
+ fErrorReporter.reportError(
+ XMLMessageFormatter.XML_DOMAIN,
+ "CharConversionFailure",
+ null,
+ XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
+ scanner.detectingVersion = false;
+ return Constants.XML_VERSION_1_0;
+ } catch (EOFException e) {
fErrorReporter.reportError(
XMLMessageFormatter.XML_DOMAIN,
"PrematureEOF",
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/io/Latin1Reader.java Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,219 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sun.org.apache.xerces.internal.impl.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+/**
+ * <p>
+ * Reader for the ISO-8859-1 encoding.</p>
+ *
+ * @xerces.internal
+ *
+ * @author Michael Glavassevich, IBM
+ *
+ * @version $Id: Latin1Reader.java 718095 2008-11-16 20:00:14Z mrglavas $
+ */
+public final class Latin1Reader
+ extends Reader {
+
+ //
+ // Constants
+ //
+ /**
+ * Default byte buffer size (2048).
+ */
+ public static final int DEFAULT_BUFFER_SIZE = 2048;
+
+ //
+ // Data
+ //
+ /**
+ * Input stream.
+ */
+ protected final InputStream fInputStream;
+
+ /**
+ * Byte buffer.
+ */
+ protected final byte[] fBuffer;
+
+ //
+ // Constructors
+ //
+ /**
+ * Constructs an ISO-8859-1 reader from the specified input stream using the
+ * default buffer size.
+ *
+ * @param inputStream The input stream.
+ */
+ public Latin1Reader(InputStream inputStream) {
+ this(inputStream, DEFAULT_BUFFER_SIZE);
+ } // <init>(InputStream)
+
+ /**
+ * Constructs an ISO-8859-1 reader from the specified input stream and
+ * buffer size.
+ *
+ * @param inputStream The input stream.
+ * @param size The initial buffer size.
+ */
+ public Latin1Reader(InputStream inputStream, int size) {
+ this(inputStream, new byte[size]);
+ } // <init>(InputStream, int)
+
+ /**
+ * Constructs an ISO-8859-1 reader from the specified input stream and
+ * buffer.
+ *
+ * @param inputStream The input stream.
+ * @param buffer The byte buffer.
+ */
+ public Latin1Reader(InputStream inputStream, byte[] buffer) {
+ fInputStream = inputStream;
+ fBuffer = buffer;
+ } // <init>(InputStream, byte[])
+
+ //
+ // Reader methods
+ //
+ /**
+ * Read a single character. This method will block until a character is
+ * available, an I/O error occurs, or the end of the stream is reached.
+ *
+ * <p>
+ * Subclasses that intend to support efficient single-character input should
+ * override this method.
+ *
+ * @return The character read, as an integer in the range 0 to 255
+ * (<tt>0x00-0xff</tt>), or -1 if the end of the stream has been reached
+ *
+ * @exception IOException If an I/O error occurs
+ */
+ public int read() throws IOException {
+ return fInputStream.read();
+ } // read():int
+
+ /**
+ * Read characters into a portion of an array. This method will block until
+ * some input is available, an I/O error occurs, or the end of the stream is
+ * reached.
+ *
+ * @param ch Destination buffer
+ * @param offset Offset at which to start storing characters
+ * @param length Maximum number of characters to read
+ *
+ * @return The number of characters read, or -1 if the end of the stream has
+ * been reached
+ *
+ * @exception IOException If an I/O error occurs
+ */
+ public int read(char ch[], int offset, int length) throws IOException {
+ if (length > fBuffer.length) {
+ length = fBuffer.length;
+ }
+ int count = fInputStream.read(fBuffer, 0, length);
+ for (int i = 0; i < count; ++i) {
+ ch[offset + i] = (char) (fBuffer[i] & 0xff);
+ }
+ return count;
+ } // read(char[],int,int)
+
+ /**
+ * Skip characters. This method will block until some characters are
+ * available, an I/O error occurs, or the end of the stream is reached.
+ *
+ * @param n The number of characters to skip
+ *
+ * @return The number of characters actually skipped
+ *
+ * @exception IOException If an I/O error occurs
+ */
+ public long skip(long n) throws IOException {
+ return fInputStream.skip(n);
+ } // skip(long):long
+
+ /**
+ * Tell whether this stream is ready to be read.
+ *
+ * @return True if the next read() is guaranteed not to block for input,
+ * false otherwise. Note that returning false does not guarantee that the
+ * next read will block.
+ *
+ * @exception IOException If an I/O error occurs
+ */
+ public boolean ready() throws IOException {
+ return false;
+ } // ready()
+
+ /**
+ * Tell whether this stream supports the mark() operation.
+ */
+ public boolean markSupported() {
+ return fInputStream.markSupported();
+ } // markSupported()
+
+ /**
+ * Mark the present position in the stream. Subsequent calls to reset() will
+ * attempt to reposition the stream to this point. Not all character-input
+ * streams support the mark() operation.
+ *
+ * @param readAheadLimit Limit on the number of characters that may be read
+ * while still preserving the mark. After reading this many characters,
+ * attempting to reset the stream may fail.
+ *
+ * @exception IOException If the stream does not support mark(), or if some
+ * other I/O error occurs
+ */
+ public void mark(int readAheadLimit) throws IOException {
+ fInputStream.mark(readAheadLimit);
+ } // mark(int)
+
+ /**
+ * Reset the stream. If the stream has been marked, then attempt to
+ * reposition it at the mark. If the stream has not been marked, then
+ * attempt to reset it in some way appropriate to the particular stream, for
+ * example by repositioning it to its starting point. Not all
+ * character-input streams support the reset() operation, and some support
+ * reset() without supporting mark().
+ *
+ * @exception IOException If the stream has not been marked, or if the mark
+ * has been invalidated, or if the stream does not support reset(), or if
+ * some other I/O error occurs
+ */
+ public void reset() throws IOException {
+ fInputStream.reset();
+ } // reset()
+
+ /**
+ * Close the stream. Once a stream has been closed, further read(), ready(),
+ * mark(), or reset() invocations will throw an IOException. Closing a
+ * previously-closed stream, however, has no effect.
+ *
+ * @exception IOException If an I/O error occurs
+ */
+ public void close() throws IOException {
+ fInputStream.close();
+ } // close()
+
+} // class Latin1Reader
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/io/UTF16Reader.java Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,333 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sun.org.apache.xerces.internal.impl.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.Locale;
+
+import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
+import com.sun.org.apache.xerces.internal.util.MessageFormatter;
+
+/**
+ * <p>
+ * A UTF-16 reader. Can also be used for UCS-2 (i.e. ISO-10646-UCS-2).</p>
+ *
+ * @xerces.internal
+ *
+ * @author Michael Glavassevich, IBM
+ *
+ * @version $Id: UTF16Reader.java 718095 2008-11-16 20:00:14Z mrglavas $
+ */
+public final class UTF16Reader
+ extends Reader {
+
+ //
+ // Constants
+ //
+ /**
+ * Default byte buffer size (4096).
+ */
+ public static final int DEFAULT_BUFFER_SIZE = 4096;
+
+ //
+ // Data
+ //
+ /**
+ * Input stream.
+ */
+ protected final InputStream fInputStream;
+
+ /**
+ * Byte buffer.
+ */
+ protected final byte[] fBuffer;
+
+ /**
+ * Endianness.
+ */
+ protected final boolean fIsBigEndian;
+
+ // message formatter; used to produce localized exception messages
+ private final MessageFormatter fFormatter;
+
+ // Locale to use for messages
+ private final Locale fLocale;
+
+ //
+ // Constructors
+ //
+ /**
+ * Constructs a UTF-16 reader from the specified input stream using the
+ * default buffer size. Primarily for testing.
+ *
+ * @param inputStream The input stream.
+ * @param isBigEndian The byte order.
+ */
+ public UTF16Reader(InputStream inputStream, boolean isBigEndian) {
+ this(inputStream, DEFAULT_BUFFER_SIZE, isBigEndian,
+ new XMLMessageFormatter(), Locale.getDefault());
+ } // <init>(InputStream, boolean)
+
+ /**
+ * Constructs a UTF-16 reader from the specified input stream using the
+ * default buffer size and the given MessageFormatter.
+ *
+ * @param inputStream The input stream.
+ * @param isBigEndian The byte order.
+ */
+ public UTF16Reader(InputStream inputStream, boolean isBigEndian,
+ MessageFormatter messageFormatter, Locale locale) {
+ this(inputStream, DEFAULT_BUFFER_SIZE, isBigEndian, messageFormatter, locale);
+ } // <init>(InputStream, boolean, MessageFormatter, Locale)
+
+ /**
+ * Constructs a UTF-16 reader from the specified input stream and buffer
+ * size and given MessageFormatter.
+ *
+ * @param inputStream The input stream.
+ * @param size The initial buffer size.
+ * @param isBigEndian The byte order.
+ * @param messageFormatter Given MessageFormatter
+ * @param locale Locale to use for messages
+ */
+ public UTF16Reader(InputStream inputStream, int size, boolean isBigEndian,
+ MessageFormatter messageFormatter, Locale locale) {
+ this(inputStream, new byte[size], isBigEndian, messageFormatter, locale);
+ } // <init>(InputStream, int, boolean, MessageFormatter, Locale)
+
+ /**
+ * Constructs a UTF-16 reader from the specified input stream, buffer and
+ * MessageFormatter.
+ *
+ * @param inputStream The input stream.
+ * @param buffer The byte buffer.
+ * @param isBigEndian The byte order.
+ * @param messageFormatter Given MessageFormatter
+ * @param locale Locale to use for messages
+ */
+ public UTF16Reader(InputStream inputStream, byte[] buffer, boolean isBigEndian,
+ MessageFormatter messageFormatter, Locale locale) {
+ fInputStream = inputStream;
+ fBuffer = buffer;
+ fIsBigEndian = isBigEndian;
+ fFormatter = messageFormatter;
+ fLocale = locale;
+ } // <init>(InputStream, byte[], boolean, MessageFormatter, Locale)
+
+ //
+ // Reader methods
+ //
+ /**
+ * Read a single character. This method will block until a character is
+ * available, an I/O error occurs, or the end of the stream is reached.
+ *
+ * <p>
+ * Subclasses that intend to support efficient single-character input should
+ * override this method.
+ *
+ * @return The character read, as an integer in the range 0 to 65535
+ * (<tt>0x00-0xffff</tt>), or -1 if the end of the stream has been reached
+ *
+ * @exception IOException If an I/O error occurs
+ */
+ public int read() throws IOException {
+ final int b0 = fInputStream.read();
+ if (b0 == -1) {
+ return -1;
+ }
+ final int b1 = fInputStream.read();
+ if (b1 == -1) {
+ expectedTwoBytes();
+ }
+ // UTF-16BE
+ if (fIsBigEndian) {
+ return (b0 << 8) | b1;
+ }
+ // UTF-16LE
+ return (b1 << 8) | b0;
+ } // read():int
+
+ /**
+ * Read characters into a portion of an array. This method will block until
+ * some input is available, an I/O error occurs, or the end of the stream is
+ * reached.
+ *
+ * @param ch Destination buffer
+ * @param offset Offset at which to start storing characters
+ * @param length Maximum number of characters to read
+ *
+ * @return The number of characters read, or -1 if the end of the stream has
+ * been reached
+ *
+ * @exception IOException If an I/O error occurs
+ */
+ public int read(char ch[], int offset, int length) throws IOException {
+ int byteLength = length << 1;
+ if (byteLength > fBuffer.length) {
+ byteLength = fBuffer.length;
+ }
+ int byteCount = fInputStream.read(fBuffer, 0, byteLength);
+ if (byteCount == -1) {
+ return -1;
+ }
+ // If an odd number of bytes were read, we still need to read one more.
+ if ((byteCount & 1) != 0) {
+ int b = fInputStream.read();
+ if (b == -1) {
+ expectedTwoBytes();
+ }
+ fBuffer[byteCount++] = (byte) b;
+ }
+ final int charCount = byteCount >> 1;
+ if (fIsBigEndian) {
+ processBE(ch, offset, charCount);
+ } else {
+ processLE(ch, offset, charCount);
+ }
+ return charCount;
+ } // read(char[],int,int)
+
+ /**
+ * Skip characters. This method will block until some characters are
+ * available, an I/O error occurs, or the end of the stream is reached.
+ *
+ * @param n The number of characters to skip
+ *
+ * @return The number of characters actually skipped
+ *
+ * @exception IOException If an I/O error occurs
+ */
+ public long skip(long n) throws IOException {
+ long bytesSkipped = fInputStream.skip(n << 1);
+ if ((bytesSkipped & 1) != 0) {
+ int b = fInputStream.read();
+ if (b == -1) {
+ expectedTwoBytes();
+ }
+ ++bytesSkipped;
+ }
+ return bytesSkipped >> 1;
+ } // skip(long):long
+
+ /**
+ * Tell whether this stream is ready to be read.
+ *
+ * @return True if the next read() is guaranteed not to block for input,
+ * false otherwise. Note that returning false does not guarantee that the
+ * next read will block.
+ *
+ * @exception IOException If an I/O error occurs
+ */
+ public boolean ready() throws IOException {
+ return false;
+ } // ready()
+
+ /**
+ * Tell whether this stream supports the mark() operation.
+ */
+ public boolean markSupported() {
+ return false;
+ } // markSupported()
+
+ /**
+ * Mark the present position in the stream. Subsequent calls to reset() will
+ * attempt to reposition the stream to this point. Not all character-input
+ * streams support the mark() operation.
+ *
+ * @param readAheadLimit Limit on the number of characters that may be read
+ * while still preserving the mark. After reading this many characters,
+ * attempting to reset the stream may fail.
+ *
+ * @exception IOException If the stream does not support mark(), or if some
+ * other I/O error occurs
+ */
+ public void mark(int readAheadLimit) throws IOException {
+ throw new IOException(fFormatter.formatMessage(fLocale, "OperationNotSupported", new Object[]{"mark()", "UTF-16"}));
+ } // mark(int)
+
+ /**
+ * Reset the stream. If the stream has been marked, then attempt to
+ * reposition it at the mark. If the stream has not been marked, then
+ * attempt to reset it in some way appropriate to the particular stream, for
+ * example by repositioning it to its starting point. Not all
+ * character-input streams support the reset() operation, and some support
+ * reset() without supporting mark().
+ *
+ * @exception IOException If the stream has not been marked, or if the mark
+ * has been invalidated, or if the stream does not support reset(), or if
+ * some other I/O error occurs
+ */
+ public void reset() throws IOException {
+ } // reset()
+
+ /**
+ * Close the stream. Once a stream has been closed, further read(), ready(),
+ * mark(), or reset() invocations will throw an IOException. Closing a
+ * previously-closed stream, however, has no effect.
+ *
+ * @exception IOException If an I/O error occurs
+ */
+ public void close() throws IOException {
+ fInputStream.close();
+ } // close()
+
+ //
+ // Private methods
+ //
+ /**
+ * Decodes UTF-16BE *
+ */
+ private void processBE(final char ch[], int offset, final int count) {
+ int curPos = 0;
+ for (int i = 0; i < count; ++i) {
+ final int b0 = fBuffer[curPos++] & 0xff;
+ final int b1 = fBuffer[curPos++] & 0xff;
+ ch[offset++] = (char) ((b0 << 8) | b1);
+ }
+ } // processBE(char[],int,int)
+
+ /**
+ * Decodes UTF-16LE *
+ */
+ private void processLE(final char ch[], int offset, final int count) {
+ int curPos = 0;
+ for (int i = 0; i < count; ++i) {
+ final int b0 = fBuffer[curPos++] & 0xff;
+ final int b1 = fBuffer[curPos++] & 0xff;
+ ch[offset++] = (char) ((b1 << 8) | b0);
+ }
+ } // processLE(char[],int,int)
+
+ /**
+ * Throws an exception for expected byte.
+ */
+ private void expectedTwoBytes()
+ throws MalformedByteSequenceException {
+ throw new MalformedByteSequenceException(fFormatter,
+ fLocale,
+ XMLMessageFormatter.XML_DOMAIN,
+ "ExpectedByte",
+ new Object[]{"2", "2"});
+ } // expectedTwoBytes()
+
+} // class UTF16Reader
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/AbstractSAXParser.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -46,6 +46,7 @@
import com.sun.org.apache.xerces.internal.xs.AttributePSVI;
import com.sun.org.apache.xerces.internal.xs.ElementPSVI;
import com.sun.org.apache.xerces.internal.xs.PSVIProvider;
+import java.io.CharConversionException;
import java.io.IOException;
import java.util.Locale;
import javax.xml.XMLConstants;
@@ -1143,7 +1144,7 @@
// wrap XNI exceptions as SAX exceptions
catch (XMLParseException e) {
Exception ex = e.getException();
- if (ex == null) {
+ if (ex == null || ex instanceof CharConversionException) {
// must be a parser exception; mine it for locator info and throw
// a SAXParseException
LocatorImpl locatorImpl = new LocatorImpl(){
@@ -1163,7 +1164,9 @@
locatorImpl.setSystemId(e.getExpandedSystemId());
locatorImpl.setLineNumber(e.getLineNumber());
locatorImpl.setColumnNumber(e.getColumnNumber());
- throw new SAXParseException(e.getMessage(), locatorImpl);
+ throw (ex == null) ?
+ new SAXParseException(e.getMessage(), locatorImpl) :
+ new SAXParseException(e.getMessage(), locatorImpl, ex);
}
if (ex instanceof SAXException) {
// why did we create an XMLParseException?
@@ -1216,7 +1219,7 @@
// wrap XNI exceptions as SAX exceptions
catch (XMLParseException e) {
Exception ex = e.getException();
- if (ex == null) {
+ if (ex == null || ex instanceof CharConversionException) {
// must be a parser exception; mine it for locator info and throw
// a SAXParseException
LocatorImpl locatorImpl = new LocatorImpl() {
@@ -1236,7 +1239,9 @@
locatorImpl.setSystemId(e.getExpandedSystemId());
locatorImpl.setLineNumber(e.getLineNumber());
locatorImpl.setColumnNumber(e.getColumnNumber());
- throw new SAXParseException(e.getMessage(), locatorImpl);
+ throw (ex == null) ?
+ new SAXParseException(e.getMessage(), locatorImpl) :
+ new SAXParseException(e.getMessage(), locatorImpl, ex);
}
if (ex instanceof SAXException) {
// why did we create an XMLParseException?
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/DOMParser.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/parsers/DOMParser.java Thu Mar 01 01:35:46 2018 +0100
@@ -40,6 +40,7 @@
import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException;
import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
+import java.io.CharConversionException;
import org.w3c.dom.Node;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
@@ -184,7 +185,7 @@
// wrap XNI exceptions as SAX exceptions
catch (XMLParseException e) {
Exception ex = e.getException();
- if (ex == null) {
+ if (ex == null || ex instanceof CharConversionException) {
// must be a parser exception; mine it for locator info and throw
// a SAXParseException
LocatorImpl locatorImpl = new LocatorImpl();
@@ -192,7 +193,9 @@
locatorImpl.setSystemId(e.getExpandedSystemId());
locatorImpl.setLineNumber(e.getLineNumber());
locatorImpl.setColumnNumber(e.getColumnNumber());
- throw new SAXParseException(e.getMessage(), locatorImpl);
+ throw (ex == null) ?
+ new SAXParseException(e.getMessage(), locatorImpl) :
+ new SAXParseException(e.getMessage(), locatorImpl, ex);
}
if (ex instanceof SAXException) {
// why did we create an XMLParseException?
@@ -246,7 +249,7 @@
// wrap XNI exceptions as SAX exceptions
catch (XMLParseException e) {
Exception ex = e.getException();
- if (ex == null) {
+ if (ex == null || ex instanceof CharConversionException) {
// must be a parser exception; mine it for locator info and throw
// a SAXParseException
LocatorImpl locatorImpl = new LocatorImpl();
@@ -254,7 +257,9 @@
locatorImpl.setSystemId(e.getExpandedSystemId());
locatorImpl.setLineNumber(e.getLineNumber());
locatorImpl.setColumnNumber(e.getColumnNumber());
- throw new SAXParseException(e.getMessage(), locatorImpl);
+ throw (ex == null) ?
+ new SAXParseException(e.getMessage(), locatorImpl) :
+ new SAXParseException(e.getMessage(), locatorImpl, ex);
}
if (ex instanceof SAXException) {
// why did we create an XMLParseException?
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/XMLLocatorWrapper.java Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,113 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.sun.org.apache.xerces.internal.util;
+
+import com.sun.org.apache.xerces.internal.xni.XMLLocator;
+
+/**
+ * <p>A light wrapper around an <code>XMLLocator</code>.</p>
+ *
+ * @author Michael Glavassevich, IBM
+ *
+ * @version $Id: XMLLocatorWrapper.java 533423 2007-04-28 20:47:15Z mrglavas $
+ */
+public final class XMLLocatorWrapper implements XMLLocator {
+
+ private XMLLocator fLocator = null;
+
+ public XMLLocatorWrapper() {}
+
+ public void setLocator(XMLLocator locator) {
+ fLocator = locator;
+ }
+
+ public XMLLocator getLocator() {
+ return fLocator;
+ }
+
+ /*
+ * XMLLocator methods
+ */
+
+ public String getPublicId() {
+ if (fLocator != null) {
+ return fLocator.getPublicId();
+ }
+ return null;
+ }
+
+ public String getLiteralSystemId() {
+ if (fLocator != null) {
+ return fLocator.getLiteralSystemId();
+ }
+ return null;
+ }
+
+ public String getBaseSystemId() {
+ if (fLocator != null) {
+ return fLocator.getBaseSystemId();
+ }
+ return null;
+ }
+
+ public String getExpandedSystemId() {
+ if (fLocator != null) {
+ return fLocator.getExpandedSystemId();
+ }
+ return null;
+ }
+
+ public int getLineNumber() {
+ if (fLocator != null) {
+ return fLocator.getLineNumber();
+ }
+ return -1;
+ }
+
+ public int getColumnNumber() {
+ if (fLocator != null) {
+ return fLocator.getColumnNumber();
+ }
+ return -1;
+ }
+
+ public int getCharacterOffset() {
+ if (fLocator != null) {
+ return fLocator.getCharacterOffset();
+ }
+ return -1;
+ }
+
+ public String getEncoding() {
+ if (fLocator != null) {
+ return fLocator.getEncoding();
+ }
+ return null;
+ }
+
+ public String getXMLVersion() {
+ if (fLocator != null) {
+ return fLocator.getXMLVersion();
+ }
+ return null;
+ }
+}
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -36,9 +36,9 @@
import com.sun.org.apache.xerces.internal.util.URI;
import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl;
import com.sun.org.apache.xerces.internal.util.XMLChar;
+import com.sun.org.apache.xerces.internal.util.XMLLocatorWrapper;
import com.sun.org.apache.xerces.internal.util.XMLResourceIdentifierImpl;
import com.sun.org.apache.xerces.internal.util.XMLSymbols;
-import com.sun.org.apache.xerces.internal.utils.ObjectFactory;
import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
import com.sun.org.apache.xerces.internal.xni.Augmentations;
@@ -157,8 +157,8 @@
public final static String CURRENT_BASE_URI = "currentBaseURI";
// used for adding [base URI] attributes
- public final static String XINCLUDE_BASE = "base".intern();
- public final static QName XML_BASE_QNAME =
+ private final static String XINCLUDE_BASE = "base".intern();
+ private final static QName XML_BASE_QNAME =
new QName(
XMLSymbols.PREFIX_XML,
XINCLUDE_BASE,
@@ -166,15 +166,15 @@
NamespaceContext.XML_URI);
// used for adding [language] attributes
- public final static String XINCLUDE_LANG = "lang".intern();
- public final static QName XML_LANG_QNAME =
+ private final static String XINCLUDE_LANG = "lang".intern();
+ private final static QName XML_LANG_QNAME =
new QName(
XMLSymbols.PREFIX_XML,
XINCLUDE_LANG,
(XMLSymbols.PREFIX_XML + ":" + XINCLUDE_LANG).intern(),
NamespaceContext.XML_URI);
- public final static QName NEW_NS_ATTR_QNAME =
+ private final static QName NEW_NS_ATTR_QNAME =
new QName(
XMLSymbols.PREFIX_XMLNS,
"",
@@ -217,6 +217,10 @@
protected static final String XINCLUDE_FIXUP_LANGUAGE =
Constants.XERCES_FEATURE_PREFIX + Constants.XINCLUDE_FIXUP_LANGUAGE_FEATURE;
+ /** Property identifier: JAXP schema language. */
+ protected static final String JAXP_SCHEMA_LANGUAGE =
+ Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE;
+
/** Property identifier: symbol table. */
protected static final String SYMBOL_TABLE =
Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
@@ -234,7 +238,7 @@
Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
/** property identifier: buffer size. */
- public static final String BUFFER_SIZE =
+ protected static final String BUFFER_SIZE =
Constants.XERCES_PROPERTY_PREFIX + Constants.BUFFER_SIZE_PROPERTY;
protected static final String PARSER_SETTINGS =
@@ -292,6 +296,7 @@
protected XPointerProcessor fXPtrProcessor = null;
protected XMLLocator fDocLocation;
+ protected XMLLocatorWrapper fXIncludeLocator = new XMLLocatorWrapper();
protected XIncludeMessageFormatter fXIncludeMessageFormatter = new XIncludeMessageFormatter();
protected XIncludeNamespaceSupport fNamespaceContext;
protected SymbolTable fSymbolTable;
@@ -305,17 +310,19 @@
protected XIncludeTextReader fXInclude11TextReader;
// these are needed for XML Base processing
- protected XMLResourceIdentifier fCurrentBaseURI;
- protected IntStack fBaseURIScope;
- protected Stack<String> fBaseURI;
- protected Stack<String> fLiteralSystemID;
- protected Stack<String> fExpandedSystemID;
+ protected final XMLResourceIdentifier fCurrentBaseURI;
+ protected final IntStack fBaseURIScope;
+ protected final Stack<String> fBaseURI;
+ protected final Stack<String> fLiteralSystemID;
+ protected final Stack<String> fExpandedSystemID;
// these are needed for Language Fixup
- protected IntStack fLanguageScope;
- protected Stack<String> fLanguageStack;
+ protected final IntStack fLanguageScope;
+ protected final Stack<String> fLanguageStack;
protected String fCurrentLanguage;
+ protected String fHrefFromParent;
+
// used for passing features on to child XIncludeHandler objects
protected ParserConfigurationSettings fSettings;
@@ -361,6 +368,9 @@
// track whether a DTD is being parsed
private boolean fInDTD;
+ // tracks whether content has been reported on the child pipeline
+ boolean fHasIncludeReportedContent;
+
// track whether the root element of the result infoset has been processed
private boolean fSeenRootElement;
@@ -593,15 +603,21 @@
copyFeatures(componentManager, fSettings);
// We don't want a schema validator on the new pipeline,
- // so if it was enabled, we set the feature to false. If
- // the validation feature was also enabled we turn on
- // dynamic validation, so that DTD validation is performed
- // on the included documents only if they have a DOCTYPE.
- // This is consistent with the behaviour on the main pipeline.
+ // so if it was enabled, we set the feature to false.
try {
if (componentManager.getFeature(SCHEMA_VALIDATION)) {
fSettings.setFeature(SCHEMA_VALIDATION, false);
- if (componentManager.getFeature(VALIDATION)) {
+ // If the value of the JAXP 1.2 schema language property
+ // is http://www.w3.org/2001/XMLSchema we're only validating
+ // against XML schema so we disable validation on the new pipeline.
+ if (Constants.NS_XMLSCHEMA.equals(componentManager.getProperty(JAXP_SCHEMA_LANGUAGE))) {
+ fSettings.setFeature(VALIDATION, false);
+ }
+ // If the validation feature was also enabled we turn on
+ // dynamic validation, so that DTD validation is performed
+ // on the included documents only if they have a DOCTYPE.
+ // This is consistent with the behaviour on the main pipeline.
+ else if (componentManager.getFeature(VALIDATION)) {
fSettings.setFeature(DYNAMIC_VALIDATION, true);
}
}
@@ -776,7 +792,15 @@
@Override
public void setDocumentHandler(XMLDocumentHandler handler) {
- fDocumentHandler = handler;
+ if (fDocumentHandler != handler) {
+ fDocumentHandler = handler;
+ if (fXIncludeChildConfig != null) {
+ fXIncludeChildConfig.setDocumentHandler(handler);
+ }
+ if (fXPointerChildConfig != null) {
+ fXPointerChildConfig.setDocumentHandler(handler);
+ }
+ }
}
@Override
@@ -806,36 +830,39 @@
// otherwise, the locator from the root document would always be used
fErrorReporter.setDocumentLocator(locator);
- if (!isRootDocument()
- && fParentXIncludeHandler.searchForRecursiveIncludes(locator)) {
- reportFatalError(
- "RecursiveInclude",
- new Object[] { locator.getExpandedSystemId()});
- }
-
if (!(namespaceContext instanceof XIncludeNamespaceSupport)) {
reportFatalError("IncompatibleNamespaceContext");
}
fNamespaceContext = (XIncludeNamespaceSupport)namespaceContext;
fDocLocation = locator;
+ fXIncludeLocator.setLocator(fDocLocation);
// initialize the current base URI
- fCurrentBaseURI.setBaseSystemId(locator.getBaseSystemId());
- fCurrentBaseURI.setExpandedSystemId(locator.getExpandedSystemId());
- fCurrentBaseURI.setLiteralSystemId(locator.getLiteralSystemId());
+ setupCurrentBaseURI(locator);
saveBaseURI();
if (augs == null) {
augs = new AugmentationsImpl();
}
augs.putItem(CURRENT_BASE_URI, fCurrentBaseURI);
+ // abort here if we detect a recursive include
+ if (!isRootDocument()) {
+ fParentXIncludeHandler.fHasIncludeReportedContent = true;
+ if (fParentXIncludeHandler.searchForRecursiveIncludes(
+ fCurrentBaseURI.getExpandedSystemId())) {
+ reportFatalError(
+ "RecursiveInclude",
+ new Object[] { fCurrentBaseURI.getExpandedSystemId()});
+ }
+ }
+
// initialize the current language
fCurrentLanguage = XMLSymbols.EMPTY_STRING;
saveLanguage(fCurrentLanguage);
if (isRootDocument() && fDocumentHandler != null) {
fDocumentHandler.startDocument(
- locator,
+ fXIncludeLocator,
encoding,
namespaceContext,
augs);
@@ -1671,7 +1698,7 @@
catch (IOException | CatalogException e) {
reportResourceError(
"XMLResourceError",
- new Object[] { href, e.getMessage()});
+ new Object[] { href, e.getMessage()}, e);
return false;
}
}
@@ -1750,6 +1777,8 @@
// ???
newHandler.setParent(this);
+ newHandler.setHref(href);
+ newHandler.setXIncludeLocator(fXIncludeLocator);
newHandler.setDocumentHandler(this.getDocumentHandler());
fXPointerChildConfig = fChildConfig;
} else {
@@ -1758,7 +1787,8 @@
Constants.XERCES_PROPERTY_PREFIX
+ Constants.XINCLUDE_HANDLER_PROPERTY);
- newHandler.setParent(this);
+ newHandler.setParent(this);
+ newHandler.setHref(href);
newHandler.setDocumentHandler(this.getDocumentHandler());
fXIncludeChildConfig = fChildConfig;
}
@@ -1766,7 +1796,7 @@
// If an xpointer attribute is present
if (xpointer != null ) {
- fChildConfig = fXPointerChildConfig ;
+ fChildConfig = fXPointerChildConfig;
// Parse the XPointer expression
try {
@@ -1790,10 +1820,12 @@
fNeedCopyFeatures = false;
try {
+ fHasIncludeReportedContent = false;
fNamespaceContext.pushScope();
fChildConfig.parse(includedSource);
- // necessary to make sure proper location is reported in errors
+ // necessary to make sure proper location is reported to the application and in errors
+ fXIncludeLocator.setLocator(fDocLocation);
if (fErrorReporter != null) {
fErrorReporter.setDocumentLocator(fDocLocation);
}
@@ -1811,23 +1843,32 @@
}
}
catch (XNIException e) {
- // necessary to make sure proper location is reported in errors
+ // necessary to make sure proper location is reported to the application and in errors
+ fXIncludeLocator.setLocator(fDocLocation);
if (fErrorReporter != null) {
fErrorReporter.setDocumentLocator(fDocLocation);
}
reportFatalError("XMLParseError", new Object[] { href, e.getMessage() });
}
catch (IOException e) {
- // necessary to make sure proper location is reported in errors
+ // necessary to make sure proper location is reported to the application and in errors
+ fXIncludeLocator.setLocator(fDocLocation);
if (fErrorReporter != null) {
fErrorReporter.setDocumentLocator(fDocLocation);
}
- // An IOException indicates that we had trouble reading the file, not
- // that it was an invalid XML file. So we send a resource error, not a
- // fatal error.
+ // If the start document event has been seen on the child pipeline it
+ // means the resource was successfully opened and we started reporting
+ // document events. If an IOException is thrown after the start document
+ // event we had a failure midstream and cannot recover.
+ if (fHasIncludeReportedContent) {
+ throw new XNIException(e);
+ }
+ // In other circumstances an IOException indicates that we had trouble
+ // accessing or opening the file, not that it was an invalid XML file. So we
+ // send a resource error, not a fatal error.
reportResourceError(
"XMLResourceError",
- new Object[] { href, e.getMessage()});
+ new Object[] { href, e.getMessage()}, e);
return false;
}
finally {
@@ -1841,6 +1882,8 @@
XIncludeTextReader textReader = null;
try {
+ fHasIncludeReportedContent = false;
+
// Setup the appropriate text reader.
if (!fIsXML11) {
if (fXInclude10TextReader == null) {
@@ -1866,16 +1909,22 @@
// encoding errors
catch (MalformedByteSequenceException ex) {
fErrorReporter.reportError(ex.getDomain(), ex.getKey(),
- ex.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR);
+ ex.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR, ex);
}
catch (CharConversionException e) {
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
- "CharConversionFailure", null, XMLErrorReporter.SEVERITY_FATAL_ERROR);
+ "CharConversionFailure", null, XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
}
catch (IOException e) {
+ // If a characters event has already been sent down the pipeline it
+ // means the resource was successfully opened and that this IOException
+ // is from a failure midstream from which we cannot recover.
+ if (fHasIncludeReportedContent) {
+ throw new XNIException(e);
+ }
reportResourceError(
"TextResourceError",
- new Object[] { href, e.getMessage()});
+ new Object[] { href, e.getMessage()}, e);
return false;
}
finally {
@@ -1886,7 +1935,7 @@
catch (IOException e) {
reportResourceError(
"TextResourceError",
- new Object[] { href, e.getMessage()});
+ new Object[] { href, e.getMessage()}, e);
return false;
}
}
@@ -1977,37 +2026,51 @@
return parentLanguage != null && parentLanguage.equalsIgnoreCase(fCurrentLanguage);
}
- /**
- * Checks if the file indicated by the given XMLLocator has already been included
- * in the current stack.
- * @param includedSource the source to check for inclusion
- * @return true if the source has already been included
- */
- protected boolean searchForRecursiveIncludes(XMLLocator includedSource) {
- String includedSystemId = includedSource.getExpandedSystemId();
+ private void setupCurrentBaseURI(XMLLocator locator) {
+ fCurrentBaseURI.setBaseSystemId(locator.getBaseSystemId());
+ if (locator.getLiteralSystemId() != null) {
+ fCurrentBaseURI.setLiteralSystemId(locator.getLiteralSystemId());
+ }
+ else {
+ fCurrentBaseURI.setLiteralSystemId(fHrefFromParent);
+ }
- if (includedSystemId == null) {
+ String expandedSystemId = locator.getExpandedSystemId();
+ if (expandedSystemId == null) {
+ // attempt to expand it ourselves
try {
- includedSystemId =
+ expandedSystemId =
XMLEntityManager.expandSystemId(
- includedSource.getLiteralSystemId(),
- includedSource.getBaseSystemId(),
+ fCurrentBaseURI.getLiteralSystemId(),
+ fCurrentBaseURI.getBaseSystemId(),
false);
+ if (expandedSystemId == null) {
+ expandedSystemId = fCurrentBaseURI.getLiteralSystemId();
+ }
}
catch (MalformedURIException e) {
reportFatalError("ExpandedSystemId");
}
}
+ fCurrentBaseURI.setExpandedSystemId(expandedSystemId);
+ }
- if (includedSystemId.equals(fCurrentBaseURI.getExpandedSystemId())) {
+ /**
+ * Checks if the file indicated by the given system id has already been
+ * included in the current stack.
+ * @param includedSysId the system id to check for inclusion
+ * @return true if the source has already been included
+ */
+ protected boolean searchForRecursiveIncludes(String includedSysId) {
+ if (includedSysId.equals(fCurrentBaseURI.getExpandedSystemId())) {
return true;
}
-
- if (fParentXIncludeHandler == null) {
+ else if (fParentXIncludeHandler == null) {
return false;
}
- return fParentXIncludeHandler.searchForRecursiveIncludes(
- includedSource);
+ else {
+ return fParentXIncludeHandler.searchForRecursiveIncludes(includedSysId);
+ }
}
/**
@@ -2045,7 +2108,7 @@
* unparsed entities are processed as described in the spec, sections 4.5.1 and 4.5.2
* </ul>
* @param attributes
- * @return
+ * @return the processed XMLAttributes
*/
protected XMLAttributes processAttributes(XMLAttributes attributes) {
if (isTopLevelIncludedItem()) {
@@ -2198,7 +2261,7 @@
return relativeURI;
}
else {
- if (relativeURI.equals("")) {
+ if (relativeURI.length() == 0) {
relativeURI = fCurrentBaseURI.getLiteralSystemId();
}
@@ -2207,7 +2270,7 @@
fParentRelativeURI =
fParentXIncludeHandler.getRelativeBaseURI();
}
- if (fParentRelativeURI.equals("")) {
+ if (fParentRelativeURI.length() == 0) {
return relativeURI;
}
@@ -2420,7 +2483,7 @@
* as an ancestor of the current item.
*
* @param depth
- * @return
+ * @return true if an include was seen at the given depth, false otherwise
*/
protected boolean getSawInclude(int depth) {
if (depth >= fSawInclude.length) {
@@ -2430,11 +2493,15 @@
}
protected void reportResourceError(String key) {
- this.reportFatalError(key, null);
+ this.reportResourceError(key, null);
}
protected void reportResourceError(String key, Object[] args) {
- this.reportError(key, args, XMLErrorReporter.SEVERITY_WARNING);
+ this.reportResourceError(key, args, null);
+ }
+
+ protected void reportResourceError(String key, Object[] args, Exception exception) {
+ this.reportError(key, args, XMLErrorReporter.SEVERITY_WARNING, exception);
}
protected void reportFatalError(String key) {
@@ -2442,16 +2509,21 @@
}
protected void reportFatalError(String key, Object[] args) {
- this.reportError(key, args, XMLErrorReporter.SEVERITY_FATAL_ERROR);
+ this.reportFatalError(key, args, null);
}
- private void reportError(String key, Object[] args, short severity) {
+ protected void reportFatalError(String key, Object[] args, Exception exception) {
+ this.reportError(key, args, XMLErrorReporter.SEVERITY_FATAL_ERROR, exception);
+ }
+
+ private void reportError(String key, Object[] args, short severity, Exception exception) {
if (fErrorReporter != null) {
fErrorReporter.reportError(
XIncludeMessageFormatter.XINCLUDE_DOMAIN,
key,
args,
- severity);
+ severity,
+ exception);
}
// we won't worry about when error reporter is null, since there should always be
// at least the default error reporter
@@ -2465,6 +2537,14 @@
fParentXIncludeHandler = parent;
}
+ protected void setHref(String href) {
+ fHrefFromParent = href;
+ }
+
+ protected void setXIncludeLocator(XMLLocatorWrapper locator) {
+ fXIncludeLocator = locator;
+ }
+
// used to know whether to pass declarations to the document handler
protected boolean isRootDocument() {
return fParentXIncludeHandler == null;
@@ -2849,7 +2929,7 @@
/**
* Saves the given language on the top of the stack.
*
- * @param lanaguage the language to push onto the stack.
+ * @param language the language to push onto the stack.
*/
protected void saveLanguage(String language) {
fLanguageScope.push(fDepth);
@@ -3013,7 +3093,7 @@
// the second hex character if a character needs to be escaped
private static final char gAfterEscaping2[] = new char[128];
private static final char[] gHexChs = {'0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
// initialize the above 3 arrays
static {
char[] escChs = {' ', '<', '>', '"', '{', '}', '|', '\\', '^', '`'};
@@ -3104,7 +3184,7 @@
// for each byte
for (i = 0; i < len; i++) {
b = bytes[i];
- // for non-ascii character: make it positive, then escape
+ // for non-ASCII character: make it positive, then escape
if (b < 0) {
ch = b + 256;
buffer.append('%');
@@ -3123,7 +3203,7 @@
}
// If escaping happened, create a new string;
- // otherwise, return the orginal one.
+ // otherwise, return the original one.
if (buffer.length() != len) {
return buffer.toString();
}
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xinclude/XIncludeTextReader.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xinclude/XIncludeTextReader.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -23,6 +23,8 @@
import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader;
+import com.sun.org.apache.xerces.internal.impl.io.Latin1Reader;
+import com.sun.org.apache.xerces.internal.impl.io.UTF16Reader;
import com.sun.org.apache.xerces.internal.impl.io.UTF8Reader;
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
import com.sun.org.apache.xerces.internal.util.EncodingMap;
@@ -67,7 +69,7 @@
public class XIncludeTextReader {
private Reader fReader;
- private XIncludeHandler fHandler;
+ private final XIncludeHandler fHandler;
private XMLInputSource fSource;
private XMLErrorReporter fErrorReporter;
private XMLString fTempString = new XMLString();
@@ -149,12 +151,12 @@
stream = new BufferedInputStream(urlCon.getInputStream());
// content type will be string like "text/xml; charset=UTF-8" or "text/xml"
- String rawContentType = urlCon.getContentType();
+ final String rawContentType = urlCon.getContentType();
// text/xml and application/xml offer only one optional parameter
- int index = (rawContentType != null) ? rawContentType.indexOf(';') : -1;
+ final int index = (rawContentType != null) ? rawContentType.indexOf(';') : -1;
- String contentType = null;
+ final String contentType;
String charset = null;
if (index != -1) {
// this should be something like "text/xml"
@@ -181,14 +183,16 @@
}
}
else {
- contentType = rawContentType.trim();
+ contentType = (rawContentType != null) ? rawContentType.trim() : "";
}
String detectedEncoding = null;
/** The encoding of such a resource is determined by:
1 external encoding information, if available, otherwise
-- the most common type of external information is the "charset" parameter of a MIME package
- 2 if the media type of the resource is text/xml, application/xml, or matches the conventions text/*+xml or application/*+xml as described in XML Media Types [IETF RFC 3023], the encoding is recognized as specified in XML 1.0, otherwise
+ 2 if the media type of the resource is text/xml, application/xml, or matches the conventions
+ text/*+xml or application/*+xml as described in XML Media Types [IETF RFC 3023], the encoding
+ is recognized as specified in XML 1.0, otherwise
3 the value of the encoding attribute if one exists, otherwise
4 UTF-8.
**/
@@ -225,15 +229,17 @@
// eat the Byte Order Mark
encoding = consumeBOM(stream, encoding);
- // If the document is UTF-8 or US-ASCII use
- // the Xerces readers for these encodings. For
- // US-ASCII consult the encoding map since
- // this encoding has many aliases.
+ // If the document is UTF-8, UTF-16, US-ASCII or ISO-8859-1 use
+ // the Xerces readers for these encodings. For US-ASCII and ISO-8859-1
+ // consult the encoding map since these encodings have many aliases.
if (encoding.equals("UTF-8")) {
- return new UTF8Reader(stream,
- fTempString.ch.length,
- fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN),
- fErrorReporter.getLocale() );
+ return createUTF8Reader(stream);
+ }
+ else if (encoding.equals("UTF-16BE")) {
+ return createUTF16Reader(stream, true);
+ }
+ else if (encoding.equals("UTF-16LE")) {
+ return createUTF16Reader(stream, false);
}
// Try to use a Java reader.
@@ -251,16 +257,45 @@
new Object[] {encoding} ) );
}
else if (javaEncoding.equals("ASCII")) {
- return new ASCIIReader(stream,
- fTempString.ch.length,
- fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN),
- fErrorReporter.getLocale() );
+ return createASCIIReader(stream);
}
-
+ else if (javaEncoding.equals("ISO8859_1")) {
+ return createLatin1Reader(stream);
+ }
return new InputStreamReader(stream, javaEncoding);
}
}
+ /** Create a new UTF-8 reader from the InputStream. **/
+ private Reader createUTF8Reader(InputStream stream) {
+ return new UTF8Reader(stream,
+ fTempString.ch.length,
+ fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN),
+ fErrorReporter.getLocale());
+ }
+
+ /** Create a new UTF-16 reader from the InputStream. **/
+ private Reader createUTF16Reader(InputStream stream, boolean isBigEndian) {
+ return new UTF16Reader(stream,
+ (fTempString.ch.length << 1),
+ isBigEndian,
+ fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN),
+ fErrorReporter.getLocale());
+ }
+
+ /** Create a new ASCII reader from the InputStream. **/
+ private Reader createASCIIReader(InputStream stream) {
+ return new ASCIIReader(stream,
+ fTempString.ch.length,
+ fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN),
+ fErrorReporter.getLocale());
+ }
+
+ /** Create a new ISO-8859-1 reader from the InputStream. **/
+ private Reader createLatin1Reader(InputStream stream) {
+ return new Latin1Reader(stream, fTempString.ch.length);
+ }
+
/**
* XMLEntityManager cares about endian-ness, since it creates its own optimized
* readers. Since we're just using generic Java readers for now, we're not caring
@@ -416,6 +451,7 @@
fReader = getReader(fSource);
fSource = null;
int readSize = fReader.read(fTempString.ch, 0, fTempString.ch.length - 1);
+ fHandler.fHasIncludeReportedContent = true;
while (readSize != -1) {
for (int i = 0; i < readSize; ++i) {
char ch = fTempString.ch[i];
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Thu Mar 01 01:35:46 2018 +0100
@@ -35,7 +35,6 @@
import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.parser.Tokens.*;
import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
-import com.sun.tools.javac.resources.CompilerProperties;
import com.sun.tools.javac.resources.CompilerProperties.Errors;
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
import com.sun.tools.javac.resources.CompilerProperties.Warnings;
@@ -43,9 +42,7 @@
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
-import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.JCDiagnostic.Error;
-import com.sun.tools.javac.util.JCDiagnostic.Warning;
import com.sun.tools.javac.util.JCDiagnostic.Fragment;
import com.sun.tools.javac.util.List;
@@ -58,6 +55,9 @@
import static com.sun.tools.javac.parser.Tokens.TokenKind.IMPORT;
import static com.sun.tools.javac.parser.Tokens.TokenKind.LT;
import static com.sun.tools.javac.tree.JCTree.Tag.*;
+import static com.sun.tools.javac.resources.CompilerProperties.Fragments.ImplicitAndExplicitNotAllowed;
+import static com.sun.tools.javac.resources.CompilerProperties.Fragments.VarAndExplicitNotAllowed;
+import static com.sun.tools.javac.resources.CompilerProperties.Fragments.VarAndImplicitNotAllowed;
/** The parser maps a token sequence into an abstract syntax
* tree. It operates by recursive descent, with code derived
@@ -1673,8 +1673,6 @@
CAST,
EXPLICIT_LAMBDA,
IMPLICIT_LAMBDA,
- IMPLICIT_LAMBDA_ALL_VAR,
- BAD_LAMBDA,
PARENS
}
@@ -1682,89 +1680,77 @@
List<JCVariableDecl> params = explicitParams ?
formalParameters(true) :
implicitParameters(hasParens);
-
if (explicitParams) {
- LambdaClassfier lambdaClassfier = new LambdaClassfier();
+ LambdaClassifier lambdaClassifier = new LambdaClassifier();
for (JCVariableDecl param: params) {
if (param.vartype != null &&
isRestrictedLocalVarTypeName(param.vartype) &&
param.vartype.hasTag(TYPEARRAY)) {
log.error(DiagnosticFlag.SYNTAX, param.pos, Errors.VarNotAllowedArray);
}
- if (param.vartype != null && param.name != names.empty) {
- if (isRestrictedLocalVarTypeName(param.vartype)) {
- lambdaClassfier.addImplicitVarParameter();
- } else {
- lambdaClassfier.addExplicitParameter();
- }
- }
- if (param.vartype == null && param.name != names.empty ||
- param.vartype != null && param.name == names.empty) {
- lambdaClassfier.addImplicitParameter();
- }
- if (lambdaClassfier.result() == ParensResult.BAD_LAMBDA) {
+ lambdaClassifier.addParameter(param);
+ if (lambdaClassifier.result() == LambdaParameterKind.ERROR) {
break;
}
}
- if (lambdaClassfier.diagFragment != null) {
- log.error(DiagnosticFlag.SYNTAX, pos, Errors.InvalidLambdaParameterDeclaration(lambdaClassfier.diagFragment));
+ if (lambdaClassifier.diagFragment != null) {
+ log.error(DiagnosticFlag.SYNTAX, pos, Errors.InvalidLambdaParameterDeclaration(lambdaClassifier.diagFragment));
}
}
return lambdaExpressionOrStatementRest(params, pos);
}
- class LambdaClassfier {
- ParensResult kind; //ParensResult.EXPLICIT_LAMBDA;
+ enum LambdaParameterKind {
+ EXPLICIT(0),
+ IMPLICIT(1),
+ VAR(2),
+ ERROR(-1);
+
+ private final int index;
+
+ LambdaParameterKind(int index) {
+ this.index = index;
+ }
+ }
+
+ private final static Fragment[][] decisionTable = new Fragment[][]{
+ /* EXPLICIT IMPLICIT VAR */
+ /* EXPLICIT */ {null, ImplicitAndExplicitNotAllowed, VarAndExplicitNotAllowed},
+ /* IMPLICIT */ {ImplicitAndExplicitNotAllowed, null, VarAndImplicitNotAllowed},
+ /* VAR */ {VarAndExplicitNotAllowed, VarAndImplicitNotAllowed, null}
+ };
+
+ class LambdaClassifier {
+
+ LambdaParameterKind kind;
Fragment diagFragment;
List<JCVariableDecl> params;
- void addExplicitParameter() {
- reduce(ParensResult.EXPLICIT_LAMBDA);
- }
-
- void addImplicitVarParameter() {
- reduce(ParensResult.IMPLICIT_LAMBDA_ALL_VAR);
+ void addParameter(JCVariableDecl param) {
+ if (param.vartype != null && param.name != names.empty) {
+ if (isRestrictedLocalVarTypeName(param.vartype)) {
+ reduce(LambdaParameterKind.VAR);
+ } else {
+ reduce(LambdaParameterKind.EXPLICIT);
+ }
+ }
+ if (param.vartype == null && param.name != names.empty ||
+ param.vartype != null && param.name == names.empty) {
+ reduce(LambdaParameterKind.IMPLICIT);
+ }
}
- void addImplicitParameter() {
- reduce(ParensResult.IMPLICIT_LAMBDA);
- }
-
- private void reduce(ParensResult newKind) {
+ private void reduce(LambdaParameterKind newKind) {
if (kind == null) {
kind = newKind;
- } else if (kind != newKind && kind != ParensResult.BAD_LAMBDA) {
- ParensResult currentKind = kind;
- kind = ParensResult.BAD_LAMBDA;
- switch (currentKind) {
- case EXPLICIT_LAMBDA:
- if (newKind == ParensResult.IMPLICIT_LAMBDA) {
- diagFragment = Fragments.ImplicitAndExplicitNotAllowed;
- } else if (newKind == ParensResult.IMPLICIT_LAMBDA_ALL_VAR) {
- diagFragment = Fragments.VarAndExplicitNotAllowed;
- }
- break;
- case IMPLICIT_LAMBDA:
- if (newKind == ParensResult.EXPLICIT_LAMBDA) {
- diagFragment = Fragments.ImplicitAndExplicitNotAllowed;
- } else if (newKind == ParensResult.IMPLICIT_LAMBDA_ALL_VAR) {
- diagFragment = Fragments.VarAndImplicitNotAllowed;
- }
- break;
- case IMPLICIT_LAMBDA_ALL_VAR:
- if (newKind == ParensResult.EXPLICIT_LAMBDA) {
- diagFragment = Fragments.VarAndExplicitNotAllowed;
- } else if (newKind == ParensResult.IMPLICIT_LAMBDA) {
- diagFragment = Fragments.VarAndImplicitNotAllowed;
- }
- break;
- default:
- throw new AssertionError("unexpected option for field kind");
- }
+ } else if (kind != newKind && kind != LambdaParameterKind.ERROR) {
+ LambdaParameterKind currentKind = kind;
+ kind = LambdaParameterKind.ERROR;
+ diagFragment = decisionTable[currentKind.index][newKind.index];
}
}
- ParensResult result() {
+ LambdaParameterKind result() {
return kind;
}
}
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GCCause.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GCCause.java Thu Mar 01 01:35:46 2018 +0100
@@ -38,8 +38,6 @@
_wb_young_gc ("WhiteBox Initiated Young GC"),
_wb_conc_mark ("WhiteBox Initiated Concurrent Mark"),
_wb_full_gc ("WhiteBox Initiated Full GC"),
- _update_allocation_context_stats_inc ("Update Allocation Context Stats"),
- _update_allocation_context_stats_full ("Update Allocation Context Stats"),
_no_gc ("No GC"),
_no_cause_specified ("Unknown GCCause"),
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GenCollectedHeap.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GenCollectedHeap.java Thu Mar 01 01:35:46 2018 +0100
@@ -54,12 +54,10 @@
youngGenField = type.getAddressField("_young_gen");
oldGenField = type.getAddressField("_old_gen");
+ youngGenSpecField = type.getAddressField("_young_gen_spec");
+ oldGenSpecField = type.getAddressField("_old_gen_spec");
genFactory = new GenerationFactory();
-
- Type collectorPolicyType = db.lookupType("GenCollectorPolicy");
- youngGenSpecField = collectorPolicyType.getAddressField("_young_gen_spec");
- oldGenSpecField = collectorPolicyType.getAddressField("_old_gen_spec");
}
public GenCollectedHeap(Address addr) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, 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
@@ -553,7 +553,6 @@
classFileCounter++;
if (className.startsWith("jdk.management.") ||
- className.startsWith("jdk.internal.cmm.*") ||
// GR-5881: The class initializer for
// sun.tools.jconsole.OutputViewer
// spawns non-daemon threads for redirecting sysout and syserr.
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java Thu Mar 01 01:35:46 2018 +0100
@@ -426,6 +426,7 @@
.setCharset(configuration.charset)
.addKeywords(metakeywords)
.setStylesheets(configuration.getMainStylesheet(), configuration.getAdditionalStylesheets())
+ .setUseModuleDirectories(configuration.useModuleDirectories)
.setIndex(configuration.createindex, mainBodyScript);
Content htmlTree = HtmlTree.HTML(configuration.getLocale().getLanguage(), head.toContent(), body);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Head.java Thu Mar 01 01:30:10 2018 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Head.java Thu Mar 01 01:35:46 2018 +0100
@@ -60,6 +60,7 @@
private boolean showTimestamp;
private boolean showGeneratedBy; // temporary: for compatibility
private boolean showMetaCreated; // temporary: for compatibility
+ private boolean useModuleDirectories;
private DocFile mainStylesheetFile;
private List<DocFile> additionalStylesheetFiles = Collections.emptyList();
private boolean index;
@@ -175,6 +176,17 @@
}
/**
+ * Sets whether the module directories should be used. This is used to set the JavaScript variable.
+ *
+ * @param useModuleDirectories true if the module directories should be used
+ * @return this object
+ */
+ public Head setUseModuleDirectories(boolean useModuleDirectories) {
+ this.useModuleDirectories = useModuleDirectories;
+ return this;
+ }
+
+ /**
* Sets whether or not to include the supporting scripts and stylesheets for the
* "search" feature.
* If the feature is enabled, a {@code Script} must be provided into which some
@@ -305,7 +317,9 @@
String ptrPath = pathToRoot.isEmpty() ? "." : pathToRoot.getPath();
mainBodyScript.append("var pathtoroot = ")
.appendStringLiteral(ptrPath + "/")
- .append(";loadScripts(document, \'script\');");
+ .append(";\n")
+ .append("var useModuleDirectories = " + useModuleDirectories + ";\n")
+ .append("loadScripts(document, \'script\');");
}
addJQueryFile(tree, DocPaths.JSZIP_MIN);
addJQueryFile(tree, DocPaths.JSZIPUTILS_MIN);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js Thu Mar 01 01:30:10 2018 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js Thu Mar 01 01:35:46 2018 +0100
@@ -76,6 +76,25 @@
}
return label;
}
+function getURLPrefix(ui) {
+ var urlPrefix="";
+ if (useModuleDirectories) {
+ var slash = "/";
+ if (ui.item.category === catModules) {
+ return ui.item.l + slash;
+ } else if (ui.item.category === catPackages) {
+ return ui.item.m + slash;
+ } else if (ui.item.category === catTypes || ui.item.category === catMembers) {
+ $.each(packageSearchIndex, function(index, item) {
+ if (ui.item.p == item.l) {
+ urlPrefix = item.m + slash;
+ }
+ });
+ return urlPrefix;
+ }
+ }
+ return urlPrefix;
+}
var watermark = 'Search';
$(function() {
$("#search").val('');
@@ -314,22 +333,26 @@
},
select: function(event, ui) {
if (ui.item.l !== noResult.l) {
- var url = "";
+ var url = getURLPrefix(ui);
if (ui.item.category === catModules) {
- url = ui.item.l + "-summary.html";
+ if (useModuleDirectories) {
+ url += "module-summary.html";
+ } else {
+ url = ui.item.l + "-summary.html";
+ }
} else if (ui.item.category === catPackages) {
- url = ui.item.l.replace(/\./g, '/') + "/package-summary.html";
+ url += ui.item.l.replace(/\./g, '/') + "/package-summary.html";
} else if (ui.item.category === catTypes) {
if (ui.item.p === "<Unnamed>") {
- url = ui.item.l + ".html";
+ url += ui.item.l + ".html";
} else {
- url = ui.item.p.replace(/\./g, '/') + "/" + ui.item.l + ".html";
+ url += ui.item.p.replace(/\./g, '/') + "/" + ui.item.l + ".html";
}
} else if (ui.item.category === catMembers) {
if (ui.item.p === "<Unnamed>") {
- url = ui.item.c + ".html" + "#";
+ url += ui.item.c + ".html" + "#";
} else {
- url = ui.item.p.replace(/\./g, '/') + "/" + ui.item.c + ".html" + "#";
+ url += ui.item.p.replace(/\./g, '/') + "/" + ui.item.c + ".html" + "#";
}
if (ui.item.url) {
url += ui.item.url;
--- a/test/hotspot/gtest/gc/shared/test_oopStorage.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/gtest/gc/shared/test_oopStorage.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -896,7 +896,7 @@
public:
Task(const char* name, Storage* storage, VerifyState* vstate) :
- AbstractGangTask(name, GCId::undefined()),
+ AbstractGangTask(name),
_state(storage),
_vstate(vstate)
{}
@@ -915,7 +915,7 @@
class OopStorageTestParIteration::TaskUsingOopsDo : public AbstractGangTask {
public:
TaskUsingOopsDo(const char* name, OopStorage* storage, VerifyState* vstate) :
- AbstractGangTask(name, GCId::undefined()),
+ AbstractGangTask(name),
_state(storage),
_vstate(vstate)
{}
--- a/test/hotspot/gtest/logging/logTestUtils.inline.hpp Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/gtest/logging/logTestUtils.inline.hpp Thu Mar 01 01:35:46 2018 +0100
@@ -30,6 +30,12 @@
#define LOG_TEST_STRING_LITERAL "a (hopefully) unique log message for testing"
+static const char* invalid_selection_substr[] = {
+ "=", "+", " ", "+=", "+=*", "*+", " +", "**", "++", ".", ",", ",," ",+",
+ " *", "all+", "all*", "+all", "+all=Warning", "==Info", "=InfoWarning",
+ "BadTag+", "logging++", "logging*+", ",=", "gc+gc+"
+};
+
static inline bool string_contains_substring(const char* haystack, const char* needle) {
return strstr(haystack, needle) != NULL;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/logging/test_logSelection.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "jvm.h"
+#include "logging/logLevel.hpp"
+#include "logging/logSelection.hpp"
+#include "logging/logTagSet.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "logTestUtils.inline.hpp"
+#include "unittest.hpp"
+
+// These tests can only run in debug VMs because they rely on the (debug-only) LogTag::_test
+#ifdef ASSERT
+
+#define NON_EXISTING_TAG_SET "logging+test+start+exit+safepoint"
+
+// let google test know how to print LogSelection nicely for better error messages
+void PrintTo(const LogSelection& sel, ::std::ostream* os) {
+ if (sel == LogSelection::Invalid) {
+ *os << "LogSelection::Invalid";
+ return;
+ }
+ char buf[256];
+ sel.describe(buf, sizeof(buf));
+ *os << buf;
+}
+
+TEST(LogSelection, sanity) {
+ LogTagType tags[LogTag::MaxTags] = { PREFIX_LOG_TAG(logging), PREFIX_LOG_TAG(test), PREFIX_LOG_TAG(_NO_TAG) };
+ LogSelection selection(tags, false, LogLevel::Trace);
+
+ EXPECT_EQ(2u, selection.ntags());
+ EXPECT_EQ(LogLevel::Trace, selection.level());
+
+ // Verify that copying the selection also works as expected
+ LogSelection copy = selection;
+ EXPECT_EQ(2u, copy.ntags());
+ EXPECT_EQ(LogLevel::Trace, copy.level());
+
+ tags[0] = PREFIX_LOG_TAG(gc);
+ tags[1] = PREFIX_LOG_TAG(_NO_TAG);
+ LogSelection copy2(tags, true, LogLevel::Off); // start with a completely different selection
+ copy2 = selection; // and test copy assignment
+ EXPECT_EQ(2u, copy2.ntags());
+ EXPECT_EQ(LogLevel::Trace, copy2.level());
+}
+
+TEST(LogSelection, tag_sets_selected) {
+ LogTagType tags[LogTag::MaxTags] = { PREFIX_LOG_TAG(logging), PREFIX_LOG_TAG(test), PREFIX_LOG_TAG(_NO_TAG) };
+ LogSelection selection(tags, false, LogLevel::Trace);
+
+ EXPECT_EQ(1u, selection.tag_sets_selected()) << "there should be a single (it's not a wildcard selection) "
+ "tag set selected by this (in gtest libjvm)";
+
+ EXPECT_EQ(LogTagSet::ntagsets(), LogSelection::parse("all").tag_sets_selected()) << "all should select every tag set";
+ EXPECT_EQ(0u, LogSelection::parse(NON_EXISTING_TAG_SET).tag_sets_selected()) <<
+ "(assuming the tag set doesn't exist) the selection shouldn't select any tag sets";
+}
+
+static const char* valid_expression[] = {
+ "all", "gc", "gc+logging", "logging+gc", "logging+gc*", "gc=trace",
+ "logging+gc=trace", "logging*", "logging*=info", "gc+logging*=error"
+};
+
+TEST(LogSelection, parse) {
+ LogTagType tags[LogTag::MaxTags] = { PREFIX_LOG_TAG(logging), PREFIX_LOG_TAG(test), PREFIX_LOG_TAG(_NO_TAG) };
+ LogSelection selection(tags, true, LogLevel::Off);
+ LogSelection parsed = LogSelection::parse("logging+test*=off");
+ EXPECT_EQ(selection, parsed) << "parsed selection not equal to programmatically constructed";
+
+ // Verify valid expressions parse without problems
+ for (size_t i = 0; i < ARRAY_SIZE(valid_expression); i++) {
+ EXPECT_NE(LogSelection::Invalid, LogSelection::parse(valid_expression[i])) <<
+ "Valid expression '" << valid_expression[i] << "' did not parse";
+ }
+
+ // Test 'all' with each level
+ for (LogLevelType level = LogLevel::First; level <= LogLevel::Last; level = static_cast<LogLevelType>(level + 1)) {
+ char buf[64];
+ int ret = jio_snprintf(buf, sizeof(buf), "all=%s", LogLevel::name(level));
+ ASSERT_NE(-1, ret);
+
+ LogSelection sel = LogSelection::parse(buf);
+ EXPECT_EQ(LogTagSet::ntagsets(), sel.tag_sets_selected()) << "'all' should select all tag sets";
+ EXPECT_EQ(level, sel.level());
+ }
+
+ // Test with 5 tags
+ LogTagType expected_tags[] = { PREFIX_LOG_TAG(logging), PREFIX_LOG_TAG(test), PREFIX_LOG_TAG(start),
+ PREFIX_LOG_TAG(exit), PREFIX_LOG_TAG(safepoint) };
+ LogSelection expected(expected_tags, false, LogLevel::Debug);
+ LogSelection five_tag_selection = LogSelection::parse("logging+test+start+exit+safepoint=debug");
+ EXPECT_EQ(5u, five_tag_selection.ntags()) << "parsed wrong number of tags";
+ EXPECT_EQ(expected, five_tag_selection);
+ EXPECT_EQ(LogLevel::Debug, five_tag_selection.level());
+
+ // Test implicit level
+ selection = LogSelection::parse("logging");
+ EXPECT_EQ(LogLevel::Unspecified, selection.level()) << "parsed implicit level incorrectly";
+ EXPECT_EQ(1u, selection.ntags());
+}
+
+TEST(LogSelection, parse_invalid) {
+
+ // Attempt to parse an expression with too many tags
+ EXPECT_EQ(LogSelection::Invalid, LogSelection::parse(NON_EXISTING_TAG_SET "+gc"));
+
+ // Construct a bunch of invalid expressions and verify that they don't parse
+ for (size_t i = 0; i < ARRAY_SIZE(valid_expression); i++) {
+ char buf[256];
+ for (size_t j = 0; j < ARRAY_SIZE(invalid_selection_substr); j++) {
+ // Prefix with invalid substr
+ jio_snprintf(buf, sizeof(buf), "%s%s", invalid_selection_substr[j], valid_expression[i]);
+ EXPECT_EQ(LogSelection::Invalid, LogSelection::parse(buf)) << "'" << buf << "'" << " considered legal";
+
+ // Suffix with invalid substr
+ jio_snprintf(buf, sizeof(buf), "%s%s", valid_expression[i], invalid_selection_substr[j]);
+ EXPECT_EQ(LogSelection::Invalid, LogSelection::parse(buf)) << "'" << buf << "'" << " considered legal";
+
+ // Use only the invalid substr
+ EXPECT_EQ(LogSelection::Invalid, LogSelection::parse(invalid_selection_substr[j])) <<
+ "'" << invalid_selection_substr[j] << "'" << " considered legal";
+ }
+
+ // Suffix/prefix with some unique invalid prefixes/suffixes
+ jio_snprintf(buf, sizeof(buf), "*%s", valid_expression[i]);
+ EXPECT_EQ(LogSelection::Invalid, LogSelection::parse(buf)) << "'" << buf << "'" << " considered legal";
+
+ jio_snprintf(buf, sizeof(buf), "logging*%s", valid_expression[i]);
+ EXPECT_EQ(LogSelection::Invalid, LogSelection::parse(buf)) << "'" << buf << "'" << " considered legal";
+ }
+}
+
+TEST(LogSelection, equals) {
+ LogTagType tags[LogTag::MaxTags] = { PREFIX_LOG_TAG(logging), PREFIX_LOG_TAG(test), PREFIX_LOG_TAG(_NO_TAG) };
+ LogSelection selection(tags, true, LogLevel::Info);
+ LogSelection copy(tags, true, LogLevel::Info);
+ EXPECT_EQ(selection, selection);
+ EXPECT_EQ(selection, copy);
+
+ tags[0] = PREFIX_LOG_TAG(gc);
+ LogSelection other_tags(tags, true, LogLevel::Info);
+ EXPECT_NE(selection, other_tags);
+
+ tags[0] = PREFIX_LOG_TAG(test);
+ tags[1] = PREFIX_LOG_TAG(logging);
+ LogSelection reversed(tags, true, LogLevel::Info);
+ EXPECT_NE(selection, reversed);
+
+ LogSelection no_wildcard(tags, false, LogLevel::Info);
+ EXPECT_NE(selection, no_wildcard);
+
+ LogSelection different_level(tags, true, LogLevel::Warning);
+ EXPECT_NE(selection, different_level);
+
+ tags[2] = PREFIX_LOG_TAG(gc);
+ tags[3] = PREFIX_LOG_TAG(_NO_TAG);
+ LogSelection more_tags(tags, true, LogLevel::Info);
+ EXPECT_NE(selection, more_tags);
+
+ tags[1] = PREFIX_LOG_TAG(_NO_TAG);
+ LogSelection fewer_tags(tags, true, LogLevel::Info);
+ EXPECT_NE(selection, fewer_tags);
+}
+
+TEST(LogSelection, describe_tags) {
+ char buf[256];
+ LogTagType tags[LogTag::MaxTags] = { PREFIX_LOG_TAG(logging), PREFIX_LOG_TAG(test), PREFIX_LOG_TAG(_NO_TAG) };
+ LogSelection selection(tags, true, LogLevel::Off);
+ selection.describe_tags(buf, sizeof(buf));
+ EXPECT_STREQ("logging+test*", buf);
+}
+
+TEST(LogSelection, describe) {
+ char buf[256];
+ LogTagType tags[LogTag::MaxTags] = { PREFIX_LOG_TAG(logging), PREFIX_LOG_TAG(test), PREFIX_LOG_TAG(_NO_TAG) };
+ LogSelection selection(tags, true, LogLevel::Off);
+ selection.describe(buf, sizeof(buf));
+ EXPECT_STREQ("logging+test*=off", buf);
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/logging/test_logSelectionList.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "jvm.h"
+#include "logging/logLevel.hpp"
+#include "logging/logSelectionList.hpp"
+#include "logging/logTagSet.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "logTestUtils.inline.hpp"
+#include "unittest.hpp"
+
+TEST(LogSelectionList, combination_limit) {
+ size_t max_combinations = LogSelectionList::MaxSelections;
+ EXPECT_GT(max_combinations, LogTagSet::ntagsets())
+ << "Combination limit not sufficient for configuring all available tag sets";
+}
+
+TEST(LogSelectionList, parse) {
+ char buf[256];
+ const char* valid_expression[] = {
+ "logging=off,all", "gc,logging", "logging+gc", "logging+gc,gc", "gc=trace,logging=info",
+ "logging+gc=trace,gc+logging=warning,logging", "gc,all=info"
+ };
+
+ // Verify valid expressions parse without problems
+ for (size_t i = 0; i < ARRAY_SIZE(valid_expression); i++) {
+ LogSelectionList expr;
+ EXPECT_TRUE(expr.parse(valid_expression[i])) << "Valid expression '" << valid_expression[i] << "' did not parse";
+ }
+
+ // Verify invalid expressions do not parse
+ for (size_t i = 0; i < ARRAY_SIZE(valid_expression); i++) {
+ for (size_t j = 0; j < ARRAY_SIZE(invalid_selection_substr); j++) {
+ // Prefix with invalid substr
+ LogSelectionList expr;
+ jio_snprintf(buf, sizeof(buf), "%s%s", invalid_selection_substr[j], valid_expression[i]);
+ EXPECT_FALSE(expr.parse(buf)) << "'" << buf << "'" << " considered legal";
+
+ // Suffix with invalid substr
+ LogSelectionList expr1;
+ jio_snprintf(buf, sizeof(buf), "%s%s", valid_expression[i], invalid_selection_substr[j]);
+ EXPECT_FALSE(expr1.parse(buf)) << "'" << buf << "'" << " considered legal";
+
+ // Use only the invalid substr
+ LogSelectionList expr2;
+ EXPECT_FALSE(expr2.parse(invalid_selection_substr[j])) << "'" << invalid_selection_substr[j] << "'" << " considered legal";
+ }
+
+ // Suffix/prefix with some unique invalid prefixes/suffixes
+ LogSelectionList expr;
+ jio_snprintf(buf, sizeof(buf), "*%s", valid_expression[i]);
+ EXPECT_FALSE(expr.parse(buf)) << "'" << buf << "'" << " considered legal";
+
+ LogSelectionList expr1;
+ jio_snprintf(buf, sizeof(buf), "logging*%s", valid_expression[i]);
+ EXPECT_FALSE(expr1.parse(buf)) << "'" << buf << "'" << " considered legal";
+ }
+}
+
+// Test the level_for() function for an empty expression
+TEST(LogSelectionList, level_for_empty) {
+ LogSelectionList emptyexpr;
+ ASSERT_TRUE(emptyexpr.parse(""));
+ // All tagsets should be unspecified since the expression doesn't involve any tagset
+ for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
+ EXPECT_EQ(LogLevel::Unspecified, emptyexpr.level_for(*ts));
+ }
+}
+
+// Test level_for() with an expression that has overlap (last subexpression should be used)
+TEST(LogSelectionList, level_for_overlap) {
+ LogSelectionList overlapexpr;
+ // The all=warning will be overridden with gc=info and/or logging+safepoint*=trace
+ ASSERT_TRUE(overlapexpr.parse("all=warning,gc=info,logging+safepoint*=trace"));
+ for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
+ if (ts->contains(PREFIX_LOG_TAG(gc)) && ts->ntags() == 1) {
+ EXPECT_EQ(LogLevel::Info, overlapexpr.level_for(*ts));
+ } else if (ts->contains(PREFIX_LOG_TAG(logging)) && ts->contains(PREFIX_LOG_TAG(safepoint))) {
+ EXPECT_EQ(LogLevel::Trace, overlapexpr.level_for(*ts));
+ } else {
+ EXPECT_EQ(LogLevel::Warning, overlapexpr.level_for(*ts));
+ }
+ }
+ EXPECT_EQ(LogLevel::Warning, overlapexpr.level_for(LogTagSetMapping<LOG_TAGS(class)>::tagset()));
+ EXPECT_EQ(LogLevel::Info, overlapexpr.level_for(LogTagSetMapping<LOG_TAGS(gc)>::tagset()));
+ EXPECT_EQ(LogLevel::Trace, overlapexpr.level_for(LogTagSetMapping<LOG_TAGS(logging, safepoint)>::tagset()));
+ EXPECT_EQ(LogLevel::Trace,
+ overlapexpr.level_for(LogTagSetMapping<LOG_TAGS(logging, gc, class, safepoint, heap)>::tagset()));
+}
+
+// Test level_for() with an expression containing two independent subexpressions
+TEST(LogSelectionList, level_for_disjoint) {
+ LogSelectionList reducedexpr;
+ ASSERT_TRUE(reducedexpr.parse("gc+logging=trace,class*=error"));
+ EXPECT_EQ(LogLevel::Error, reducedexpr.level_for(LogTagSetMapping<LOG_TAGS(class)>::tagset()));
+ EXPECT_EQ(LogLevel::Error, reducedexpr.level_for(LogTagSetMapping<LOG_TAGS(safepoint, class)>::tagset()));
+ EXPECT_EQ(LogLevel::NotMentioned, reducedexpr.level_for(LogTagSetMapping<LOG_TAGS(safepoint)>::tagset()));
+ EXPECT_EQ(LogLevel::NotMentioned, reducedexpr.level_for(LogTagSetMapping<LOG_TAGS(logging)>::tagset()));
+ EXPECT_EQ(LogLevel::NotMentioned, reducedexpr.level_for(LogTagSetMapping<LOG_TAGS(gc)>::tagset()));
+ EXPECT_EQ(LogLevel::Trace, reducedexpr.level_for(LogTagSetMapping<LOG_TAGS(logging, gc)>::tagset()));
+}
+
+// Test level_for() with an expression that is completely overridden in the last part of the expression
+TEST(LogSelectionList, level_for_override) {
+ LogSelectionList overrideexpr;
+ // No matter what, everything should be set to error level because of the last part
+ ASSERT_TRUE(overrideexpr.parse("logging,gc*=trace,all=error"));
+ EXPECT_EQ(LogLevel::Error, overrideexpr.level_for(LogTagSetMapping<LOG_TAGS(class)>::tagset()));
+ EXPECT_EQ(LogLevel::Error, overrideexpr.level_for(LogTagSetMapping<LOG_TAGS(logging)>::tagset()));
+ EXPECT_EQ(LogLevel::Error, overrideexpr.level_for(LogTagSetMapping<LOG_TAGS(gc)>::tagset()));
+ EXPECT_EQ(LogLevel::Error, overrideexpr.level_for(LogTagSetMapping<LOG_TAGS(logging, gc)>::tagset()));
+}
+
+// Test level_for() with a mixed expression with a bit of everything
+TEST(LogSelectionList, level_for_mixed) {
+ LogSelectionList mixedexpr;
+ ASSERT_TRUE(mixedexpr.parse("all=warning,gc*=debug,gc=trace,safepoint*=off"));
+ EXPECT_EQ(LogLevel::Warning, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(logging)>::tagset()));
+ EXPECT_EQ(LogLevel::Warning, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(logging, class)>::tagset()));
+ EXPECT_EQ(LogLevel::Debug, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(gc, class)>::tagset()));
+ EXPECT_EQ(LogLevel::Off, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(gc, safepoint, logging)>::tagset()));
+ EXPECT_EQ(LogLevel::Off, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(safepoint)>::tagset()));
+ EXPECT_EQ(LogLevel::Debug, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(logging, gc)>::tagset()));
+ EXPECT_EQ(LogLevel::Trace, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(gc)>::tagset()));
+}
--- a/test/hotspot/gtest/logging/test_logTag.cpp Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/gtest/logging/test_logTag.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
#include "precompiled.hpp"
#include "logging/logTag.hpp"
+#include "utilities/ostream.hpp"
#include "unittest.hpp"
TEST(LogTag, from_string) {
@@ -51,3 +52,31 @@
LOG_TAG_LIST
#undef LOG_TAG
}
+
+TEST(LogTag, list_tags) {
+ char buf[LogTag::Count * 16] = {0};
+ stringStream ss(buf, sizeof(buf));
+ LogTag::list_tags(&ss);
+
+ bool listed_tags[LogTag::Count] = { false };
+
+ char* last_tag = NULL;
+ for (char* tag = buf; *tag != '\0';) {
+ char* end = strpbrk(tag, ",\n");
+ ASSERT_TRUE(end != NULL) << "line should end with newline";
+ *end = '\0';
+ if (*tag == ' ') {
+ tag++;
+ }
+
+ EXPECT_TRUE(last_tag == NULL || strcmp(last_tag, tag) < 0) << tag << " should be listed before " << last_tag;
+ listed_tags[LogTag::from_string(tag)] = true;
+
+ last_tag = tag;
+ tag = end + 1;
+ }
+
+ for (size_t i = 1; i < LogTag::Count; i++) {
+ EXPECT_TRUE(listed_tags[i]) << "tag '" << LogTag::name(static_cast<LogTagType>(i)) << "' not listed!";
+ }
+}
--- a/test/hotspot/gtest/logging/test_logTagLevelExpression.cpp Thu Mar 01 01:30:10 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,190 +0,0 @@
-/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include "precompiled.hpp"
-#include "jvm.h"
-#include "logging/logLevel.hpp"
-#include "logging/logTagLevelExpression.hpp"
-#include "logging/logTagSet.hpp"
-#include "unittest.hpp"
-#include "utilities/globalDefinitions.hpp"
-
-TEST(LogTagLevelExpression, combination_limit) {
- size_t max_combinations = LogTagLevelExpression::MaxCombinations;
- EXPECT_GT(max_combinations, LogTagSet::ntagsets())
- << "Combination limit not sufficient for configuring all available tag sets";
-}
-
-TEST(LogTagLevelExpression, parse) {
- char buf[256];
- const char* invalid_substr[] = {
- "=", "+", " ", "+=", "+=*", "*+", " +", "**", "++", ".", ",", ",," ",+",
- " *", "all+", "all*", "+all", "+all=Warning", "==Info", "=InfoWarning",
- "BadTag+", "logging++", "logging*+", ",=", "gc+gc+"
- };
- const char* valid_expression[] = {
- "all", "gc", "gc,logging", "gc+logging", "logging+gc", "logging+gc,gc", "logging+gc*", "gc=trace",
- "gc=trace,logging=info", "logging+gc=trace", "logging+gc=trace,gc+logging=warning,logging",
- "gc,all=info", "logging*", "logging*=info", "gc+logging*=error", "logging*,gc=info"
- };
-
- // Verify valid expressions parse without problems
- for (size_t i = 0; i < ARRAY_SIZE(valid_expression); i++) {
- LogTagLevelExpression expr;
- EXPECT_TRUE(expr.parse(valid_expression[i])) << "Valid expression '" << valid_expression[i] << "' did not parse";
- }
-
- // Verify we can use 'all' with each available level
- for (uint level = LogLevel::First; level <= LogLevel::Last; level++) {
- char buf[32];
- int ret = jio_snprintf(buf, sizeof(buf), "all=%s", LogLevel::name(static_cast<LogLevelType>(level)));
- ASSERT_NE(ret, -1);
-
- LogTagLevelExpression expr;
- EXPECT_TRUE(expr.parse(buf));
- }
-
- // Verify invalid expressions do not parse
- for (size_t i = 0; i < ARRAY_SIZE(valid_expression); i++) {
- for (size_t j = 0; j < ARRAY_SIZE(invalid_substr); j++) {
- // Prefix with invalid substr
- LogTagLevelExpression expr;
- jio_snprintf(buf, sizeof(buf), "%s%s", invalid_substr[j], valid_expression[i]);
- EXPECT_FALSE(expr.parse(buf)) << "'" << buf << "'" << " considered legal";
-
- // Suffix with invalid substr
- LogTagLevelExpression expr1;
- jio_snprintf(buf, sizeof(buf), "%s%s", valid_expression[i], invalid_substr[j]);
- EXPECT_FALSE(expr1.parse(buf)) << "'" << buf << "'" << " considered legal";
-
- // Use only the invalid substr
- LogTagLevelExpression expr2;
- EXPECT_FALSE(expr2.parse(invalid_substr[j])) << "'" << invalid_substr[j] << "'" << " considered legal";
- }
-
- // Suffix/prefix with some unique invalid prefixes/suffixes
- LogTagLevelExpression expr;
- jio_snprintf(buf, sizeof(buf), "*%s", valid_expression[i]);
- EXPECT_FALSE(expr.parse(buf)) << "'" << buf << "'" << " considered legal";
-
- LogTagLevelExpression expr1;
- jio_snprintf(buf, sizeof(buf), "logging*%s", valid_expression[i]);
- EXPECT_FALSE(expr1.parse(buf)) << "'" << buf << "'" << " considered legal";
- }
-}
-
-// Test the level_for() function for an empty expression
-TEST(LogTagLevelExpression, level_for_empty) {
- LogTagLevelExpression emptyexpr;
- ASSERT_TRUE(emptyexpr.parse(""));
- // All tagsets should be unspecified since the expression doesn't involve any tagset
- for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
- EXPECT_EQ(LogLevel::Unspecified, emptyexpr.level_for(*ts));
- }
-}
-
-// Test level_for() with "all" without any specified level
-TEST(LogTagLevelExpression, level_for_all) {
- LogTagLevelExpression allexpr;
- ASSERT_TRUE(allexpr.parse("all"));
- // Level will be unspecified since no level was given
- for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
- EXPECT_EQ(LogLevel::Unspecified, allexpr.level_for(*ts));
- }
-}
-
-// Test level_for() with "all=debug"
-TEST(LogTagLevelExpression, level_for_all_debug) {
- LogTagLevelExpression alldebugexpr;
- ASSERT_TRUE(alldebugexpr.parse("all=debug"));
- // All tagsets should report debug level
- for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
- EXPECT_EQ(LogLevel::Debug, alldebugexpr.level_for(*ts));
- }
-}
-
-// Test level_for() with "all=off"
-TEST(LogTagLevelExpression, level_for_all_off) {
- LogTagLevelExpression alloffexpr;
- ASSERT_TRUE(alloffexpr.parse("all=off"));
- for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
- EXPECT_EQ(LogLevel::Off, alloffexpr.level_for(*ts));
- }
-}
-
-// Test level_for() with an expression that has overlap (last subexpression should be used)
-TEST(LogTagLevelExpression, level_for_overlap) {
- LogTagLevelExpression overlapexpr;
- // The all=warning will be overridden with gc=info and/or logging+safepoint*=trace
- ASSERT_TRUE(overlapexpr.parse("all=warning,gc=info,logging+safepoint*=trace"));
- for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
- if (ts->contains(PREFIX_LOG_TAG(gc)) && ts->ntags() == 1) {
- EXPECT_EQ(LogLevel::Info, overlapexpr.level_for(*ts));
- } else if (ts->contains(PREFIX_LOG_TAG(logging)) && ts->contains(PREFIX_LOG_TAG(safepoint))) {
- EXPECT_EQ(LogLevel::Trace, overlapexpr.level_for(*ts));
- } else {
- EXPECT_EQ(LogLevel::Warning, overlapexpr.level_for(*ts));
- }
- }
- EXPECT_EQ(LogLevel::Warning, overlapexpr.level_for(LogTagSetMapping<LOG_TAGS(class)>::tagset()));
- EXPECT_EQ(LogLevel::Info, overlapexpr.level_for(LogTagSetMapping<LOG_TAGS(gc)>::tagset()));
- EXPECT_EQ(LogLevel::Trace, overlapexpr.level_for(LogTagSetMapping<LOG_TAGS(logging, safepoint)>::tagset()));
- EXPECT_EQ(LogLevel::Trace,
- overlapexpr.level_for(LogTagSetMapping<LOG_TAGS(logging, gc, class, safepoint, heap)>::tagset()));
-}
-
-// Test level_for() with an expression containing two independent subexpressions
-TEST(LogTagLevelExpression, level_for_disjoint) {
- LogTagLevelExpression reducedexpr;
- ASSERT_TRUE(reducedexpr.parse("gc+logging=trace,class*=error"));
- EXPECT_EQ(LogLevel::Error, reducedexpr.level_for(LogTagSetMapping<LOG_TAGS(class)>::tagset()));
- EXPECT_EQ(LogLevel::Error, reducedexpr.level_for(LogTagSetMapping<LOG_TAGS(safepoint, class)>::tagset()));
- EXPECT_EQ(LogLevel::NotMentioned, reducedexpr.level_for(LogTagSetMapping<LOG_TAGS(safepoint)>::tagset()));
- EXPECT_EQ(LogLevel::NotMentioned, reducedexpr.level_for(LogTagSetMapping<LOG_TAGS(logging)>::tagset()));
- EXPECT_EQ(LogLevel::NotMentioned, reducedexpr.level_for(LogTagSetMapping<LOG_TAGS(gc)>::tagset()));
- EXPECT_EQ(LogLevel::Trace, reducedexpr.level_for(LogTagSetMapping<LOG_TAGS(logging, gc)>::tagset()));
-}
-
-// Test level_for() with an expression that is completely overridden in the last part of the expression
-TEST(LogTagLevelExpression, level_for_override) {
- LogTagLevelExpression overrideexpr;
- // No matter what, everything should be set to error level because of the last part
- ASSERT_TRUE(overrideexpr.parse("logging,gc*=trace,all=error"));
- EXPECT_EQ(LogLevel::Error, overrideexpr.level_for(LogTagSetMapping<LOG_TAGS(class)>::tagset()));
- EXPECT_EQ(LogLevel::Error, overrideexpr.level_for(LogTagSetMapping<LOG_TAGS(logging)>::tagset()));
- EXPECT_EQ(LogLevel::Error, overrideexpr.level_for(LogTagSetMapping<LOG_TAGS(gc)>::tagset()));
- EXPECT_EQ(LogLevel::Error, overrideexpr.level_for(LogTagSetMapping<LOG_TAGS(logging, gc)>::tagset()));
-}
-
-// Test level_for() with a mixed expression with a bit of everything
-TEST(LogTagLevelExpression, level_for_mixed) {
- LogTagLevelExpression mixedexpr;
- ASSERT_TRUE(mixedexpr.parse("all=warning,gc*=debug,gc=trace,safepoint*=off"));
- EXPECT_EQ(LogLevel::Warning, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(logging)>::tagset()));
- EXPECT_EQ(LogLevel::Warning, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(logging, class)>::tagset()));
- EXPECT_EQ(LogLevel::Debug, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(gc, class)>::tagset()));
- EXPECT_EQ(LogLevel::Off, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(gc, safepoint, logging)>::tagset()));
- EXPECT_EQ(LogLevel::Off, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(safepoint)>::tagset()));
- EXPECT_EQ(LogLevel::Debug, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(logging, gc)>::tagset()));
- EXPECT_EQ(LogLevel::Trace, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(gc)>::tagset()));
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/oops/test_typeArrayOop.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2017, Red Hat, Inc. and/or its affiliates.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "memory/universe.hpp"
+#include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
+#include "unittest.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+TEST_VM(typeArrayOopDesc, bool_at_put) {
+ char mem[100];
+ memset(mem, 0, ARRAY_SIZE(mem));
+
+ char* addr = align_up(mem, 16);
+
+ typeArrayOop o = (typeArrayOop) addr;
+ o->set_klass(Universe::boolArrayKlassObj());
+ o->set_length(10);
+
+
+ ASSERT_EQ((jboolean)0, o->bool_at(0));
+ ASSERT_EQ((jboolean)0, o->bool_at(1));
+ ASSERT_EQ((jboolean)0, o->bool_at(2));
+ ASSERT_EQ((jboolean)0, o->bool_at(3));
+ ASSERT_EQ((jboolean)0, o->bool_at(4));
+ ASSERT_EQ((jboolean)0, o->bool_at(5));
+ ASSERT_EQ((jboolean)0, o->bool_at(6));
+ ASSERT_EQ((jboolean)0, o->bool_at(7));
+
+ o->bool_at_put(3, 255); // Check for masking store.
+ o->bool_at_put(2, 1);
+ o->bool_at_put(1, 1);
+ o->bool_at_put(0, 1);
+
+ ASSERT_EQ((jboolean)1, o->bool_at(0));
+ ASSERT_EQ((jboolean)1, o->bool_at(1));
+ ASSERT_EQ((jboolean)1, o->bool_at(2));
+ ASSERT_EQ((jboolean)1, o->bool_at(3));
+ ASSERT_EQ((jboolean)0, o->bool_at(4));
+ ASSERT_EQ((jboolean)0, o->bool_at(5));
+ ASSERT_EQ((jboolean)0, o->bool_at(6));
+ ASSERT_EQ((jboolean)0, o->bool_at(7));
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/runtime/test_virtualMemoryTracker.cpp Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,550 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+
+// Included early because the NMT flags don't include it.
+#include "utilities/macros.hpp"
+
+#if INCLUDE_NMT
+
+#include "services/memTracker.hpp"
+#include "services/virtualMemoryTracker.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "unittest.hpp"
+
+namespace {
+ struct R {
+ address _addr;
+ size_t _size;
+ };
+}
+
+#define check(rmr, regions) check_inner((rmr), (regions), ARRAY_SIZE(regions), __FILE__, __LINE__)
+
+#define check_empty(rmr) \
+ do { \
+ check_inner((rmr), NULL, 0, __FILE__, __LINE__); \
+ } while (false)
+
+static void check_inner(ReservedMemoryRegion* rmr, R* regions, size_t regions_size, const char* file, int line) {
+ CommittedRegionIterator iter = rmr->iterate_committed_regions();
+ size_t i = 0;
+ size_t size = 0;
+
+#define WHERE " from " << file << ":" << line
+
+ for (const CommittedMemoryRegion* region = iter.next(); region != NULL; region = iter.next()) {
+ EXPECT_LT(i, regions_size) << WHERE;
+ EXPECT_EQ(region->base(), regions[i]._addr) << WHERE;
+ EXPECT_EQ(region->size(), regions[i]._size) << WHERE;
+ size += region->size();
+ i++;
+ }
+
+ EXPECT_EQ(i, regions_size) << WHERE;
+ EXPECT_EQ(size, rmr->committed_size()) << WHERE;
+}
+
+class VirtualMemoryTrackerTest {
+public:
+ static void test_add_committed_region_adjacent() {
+ VirtualMemoryTracker::initialize(NMT_detail);
+ VirtualMemoryTracker::late_initialize(NMT_detail);
+
+ address addr = (address)0x10000000;
+ size_t size = 0x01000000;
+
+ address frame1 = (address)0x1234;
+ address frame2 = (address)0x1235;
+
+ NativeCallStack stack(&frame1, 1);
+ NativeCallStack stack2(&frame2, 1);
+
+ // Add the reserved memory
+ VirtualMemoryTracker::add_reserved_region(addr, size, stack, mtTest);
+
+ // Fetch the added RMR added above
+ ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));
+
+ ASSERT_EQ(rmr->size(), size);
+ ASSERT_EQ(rmr->base(), addr);
+
+ // Commit Size Granularity
+ const size_t cs = 0x1000;
+
+ // Commit adjacent regions with same stack
+
+ { // Commit one region
+ rmr->add_committed_region(addr + cs, cs, stack);
+ R r[] = { {addr + cs, cs} };
+ check(rmr, r);
+ }
+
+ { // Commit adjacent - lower address
+ rmr->add_committed_region(addr, cs, stack);
+ R r[] = { {addr, 2 * cs} };
+ check(rmr, r);
+ }
+
+ { // Commit adjacent - higher address
+ rmr->add_committed_region(addr + 2 * cs, cs, stack);
+ R r[] = { {addr, 3 * cs} };
+ check(rmr, r);
+ }
+
+ // Cleanup
+ rmr->remove_uncommitted_region(addr, 3 * cs);
+ ASSERT_EQ(rmr->committed_size(), 0u);
+
+
+ // Commit adjacent regions with different stacks
+
+ { // Commit one region
+ rmr->add_committed_region(addr + cs, cs, stack);
+ R r[] = { {addr + cs, cs} };
+ check(rmr, r);
+ }
+
+ { // Commit adjacent - lower address
+ rmr->add_committed_region(addr, cs, stack2);
+ R r[] = { {addr, cs},
+ {addr + cs, cs} };
+ check(rmr, r);
+ }
+
+ { // Commit adjacent - higher address
+ rmr->add_committed_region(addr + 2 * cs, cs, stack2);
+ R r[] = { {addr, cs},
+ {addr + cs, cs},
+ {addr + 2 * cs, cs} };
+ check(rmr, r);
+ }
+
+ // Cleanup
+ rmr->remove_uncommitted_region(addr, 3 * cs);
+ ASSERT_EQ(rmr->committed_size(), 0u);
+ }
+
+ static void test_add_committed_region_adjacent_overlapping() {
+ VirtualMemoryTracker::initialize(NMT_detail);
+ VirtualMemoryTracker::late_initialize(NMT_detail);
+
+ address addr = (address)0x10000000;
+ size_t size = 0x01000000;
+
+ address frame1 = (address)0x1234;
+ address frame2 = (address)0x1235;
+
+ NativeCallStack stack(&frame1, 1);
+ NativeCallStack stack2(&frame2, 1);
+
+ // Add the reserved memory
+ VirtualMemoryTracker::add_reserved_region(addr, size, stack, mtTest);
+
+ // Fetch the added RMR added above
+ ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));
+
+ ASSERT_EQ(rmr->size(), size);
+ ASSERT_EQ(rmr->base(), addr);
+
+ // Commit Size Granularity
+ const size_t cs = 0x1000;
+
+ // Commit adjacent and overlapping regions with same stack
+
+ { // Commit two non-adjacent regions
+ rmr->add_committed_region(addr, 2 * cs, stack);
+ rmr->add_committed_region(addr + 3 * cs, 2 * cs, stack);
+ R r[] = { {addr, 2 * cs},
+ {addr + 3 * cs, 2 * cs} };
+ check(rmr, r);
+ }
+
+ { // Commit adjacent and overlapping
+ rmr->add_committed_region(addr + 2 * cs, 2 * cs, stack);
+ R r[] = { {addr, 5 * cs} };
+ check(rmr, r);
+ }
+
+ // revert to two non-adjacent regions
+ rmr->remove_uncommitted_region(addr + 2 * cs, cs);
+ ASSERT_EQ(rmr->committed_size(), 4 * cs);
+
+ { // Commit overlapping and adjacent
+ rmr->add_committed_region(addr + cs, 2 * cs, stack);
+ R r[] = { {addr, 5 * cs} };
+ check(rmr, r);
+ }
+
+ // Cleanup
+ rmr->remove_uncommitted_region(addr, 5 * cs);
+ ASSERT_EQ(rmr->committed_size(), 0u);
+
+
+ // Commit adjacent and overlapping regions with different stacks
+
+ { // Commit two non-adjacent regions
+ rmr->add_committed_region(addr, 2 * cs, stack);
+ rmr->add_committed_region(addr + 3 * cs, 2 * cs, stack);
+ R r[] = { {addr, 2 * cs},
+ {addr + 3 * cs, 2 * cs} };
+ check(rmr, r);
+ }
+
+ { // Commit adjacent and overlapping
+ rmr->add_committed_region(addr + 2 * cs, 2 * cs, stack2);
+ R r[] = { {addr, 2 * cs},
+ {addr + 2 * cs, 2 * cs},
+ {addr + 4 * cs, cs} };
+ check(rmr, r);
+ }
+
+ // revert to two non-adjacent regions
+ rmr->add_committed_region(addr, 5 * cs, stack);
+ rmr->remove_uncommitted_region(addr + 2 * cs, cs);
+ ASSERT_EQ(rmr->committed_size(), 4 * cs);
+
+ { // Commit overlapping and adjacent
+ rmr->add_committed_region(addr + cs, 2 * cs, stack2);
+ R r[] = { {addr, cs},
+ {addr + cs, 2 * cs},
+ {addr + 3 * cs, 2 * cs} };
+ check(rmr, r);
+ }
+ }
+
+ static void test_add_committed_region_overlapping() {
+ VirtualMemoryTracker::initialize(NMT_detail);
+ VirtualMemoryTracker::late_initialize(NMT_detail);
+
+ address addr = (address)0x10000000;
+ size_t size = 0x01000000;
+
+ address frame1 = (address)0x1234;
+ address frame2 = (address)0x1235;
+
+ NativeCallStack stack(&frame1, 1);
+ NativeCallStack stack2(&frame2, 1);
+
+ // Add the reserved memory
+ VirtualMemoryTracker::add_reserved_region(addr, size, stack, mtTest);
+
+ // Fetch the added RMR added above
+ ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));
+
+ ASSERT_EQ(rmr->size(), size);
+ ASSERT_EQ(rmr->base(), addr);
+
+ // Commit Size Granularity
+ const size_t cs = 0x1000;
+
+ // With same stack
+
+ { // Commit one region
+ rmr->add_committed_region(addr, cs, stack);
+ R r[] = { {addr, cs} };
+ check(rmr, r);
+ }
+
+ { // Commit the same region
+ rmr->add_committed_region(addr, cs, stack);
+ R r[] = { {addr, cs} };
+ check(rmr, r);
+ }
+
+ { // Commit a succeeding region
+ rmr->add_committed_region(addr + cs, cs, stack);
+ R r[] = { {addr, 2 * cs} };
+ check(rmr, r);
+ }
+
+ { // Commit over two regions
+ rmr->add_committed_region(addr, 2 * cs, stack);
+ R r[] = { {addr, 2 * cs} };
+ check(rmr, r);
+ }
+
+ {// Commit first part of a region
+ rmr->add_committed_region(addr, cs, stack);
+ R r[] = { {addr, 2 * cs} };
+ check(rmr, r);
+ }
+
+ { // Commit second part of a region
+ rmr->add_committed_region(addr + cs, cs, stack);
+ R r[] = { {addr, 2 * cs} };
+ check(rmr, r);
+ }
+
+ { // Commit a third part
+ rmr->add_committed_region(addr + 2 * cs, cs, stack);
+ R r[] = { {addr, 3 * cs} };
+ check(rmr, r);
+ }
+
+ { // Commit in the middle of a region
+ rmr->add_committed_region(addr + 1 * cs, cs, stack);
+ R r[] = { {addr, 3 * cs} };
+ check(rmr, r);
+ }
+
+ // Cleanup
+ rmr->remove_uncommitted_region(addr, 3 * cs);
+ ASSERT_EQ(rmr->committed_size(), 0u);
+
+ // With preceding region
+
+ rmr->add_committed_region(addr, cs, stack);
+ rmr->add_committed_region(addr + 2 * cs, 3 * cs, stack);
+
+ rmr->add_committed_region(addr + 2 * cs, cs, stack);
+ {
+ R r[] = { {addr, cs},
+ {addr + 2 * cs, 3 * cs} };
+ check(rmr, r);
+ }
+
+ rmr->add_committed_region(addr + 3 * cs, cs, stack);
+ {
+ R r[] = { {addr, cs},
+ {addr + 2 * cs, 3 * cs} };
+ check(rmr, r);
+ }
+
+ rmr->add_committed_region(addr + 4 * cs, cs, stack);
+ {
+ R r[] = { {addr, cs},
+ {addr + 2 * cs, 3 * cs} };
+ check(rmr, r);
+ }
+
+ // Cleanup
+ rmr->remove_uncommitted_region(addr, 5 * cs);
+ ASSERT_EQ(rmr->committed_size(), 0u);
+
+ // With different stacks
+
+ { // Commit one region
+ rmr->add_committed_region(addr, cs, stack);
+ R r[] = { {addr, cs} };
+ check(rmr, r);
+ }
+
+ { // Commit the same region
+ rmr->add_committed_region(addr, cs, stack2);
+ R r[] = { {addr, cs} };
+ check(rmr, r);
+ }
+
+ { // Commit a succeeding region
+ rmr->add_committed_region(addr + cs, cs, stack);
+ R r[] = { {addr, cs},
+ {addr + cs, cs} };
+ check(rmr, r);
+ }
+
+ { // Commit over two regions
+ rmr->add_committed_region(addr, 2 * cs, stack);
+ R r[] = { {addr, 2 * cs} };
+ check(rmr, r);
+ }
+
+ {// Commit first part of a region
+ rmr->add_committed_region(addr, cs, stack2);
+ R r[] = { {addr, cs},
+ {addr + cs, cs} };
+ check(rmr, r);
+ }
+
+ { // Commit second part of a region
+ rmr->add_committed_region(addr + cs, cs, stack2);
+ R r[] = { {addr, 2 * cs} };
+ check(rmr, r);
+ }
+
+ { // Commit a third part
+ rmr->add_committed_region(addr + 2 * cs, cs, stack2);
+ R r[] = { {addr, 3 * cs} };
+ check(rmr, r);
+ }
+
+ { // Commit in the middle of a region
+ rmr->add_committed_region(addr + 1 * cs, cs, stack);
+ R r[] = { {addr, cs},
+ {addr + cs, cs},
+ {addr + 2 * cs, cs} };
+ check(rmr, r);
+ }
+ }
+
+ static void test_add_committed_region() {
+ test_add_committed_region_adjacent();
+ test_add_committed_region_adjacent_overlapping();
+ test_add_committed_region_overlapping();
+ }
+
+ template <size_t S>
+ static void fix(R r[S]) {
+
+ }
+
+ static void test_remove_uncommitted_region() {
+ VirtualMemoryTracker::initialize(NMT_detail);
+ VirtualMemoryTracker::late_initialize(NMT_detail);
+
+ address addr = (address)0x10000000;
+ size_t size = 0x01000000;
+
+ address frame1 = (address)0x1234;
+ address frame2 = (address)0x1235;
+
+ NativeCallStack stack(&frame1, 1);
+ NativeCallStack stack2(&frame2, 1);
+
+ // Add the reserved memory
+ VirtualMemoryTracker::add_reserved_region(addr, size, stack, mtTest);
+
+ // Fetch the added RMR added above
+ ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));
+
+ ASSERT_EQ(rmr->size(), size);
+ ASSERT_EQ(rmr->base(), addr);
+
+ // Commit Size Granularity
+ const size_t cs = 0x1000;
+
+ { // Commit regions
+ rmr->add_committed_region(addr, 3 * cs, stack);
+ R r[] = { {addr, 3 * cs} };
+ check(rmr, r);
+
+ // Remove only existing
+ rmr->remove_uncommitted_region(addr, 3 * cs);
+ check_empty(rmr);
+ }
+
+ {
+ rmr->add_committed_region(addr + 0 * cs, cs, stack);
+ rmr->add_committed_region(addr + 2 * cs, cs, stack);
+ rmr->add_committed_region(addr + 4 * cs, cs, stack);
+
+ { // Remove first
+ rmr->remove_uncommitted_region(addr, cs);
+ R r[] = { {addr + 2 * cs, cs},
+ {addr + 4 * cs, cs} };
+ check(rmr, r);
+ }
+
+ // add back
+ rmr->add_committed_region(addr, cs, stack);
+
+ { // Remove middle
+ rmr->remove_uncommitted_region(addr + 2 * cs, cs);
+ R r[] = { {addr + 0 * cs, cs},
+ {addr + 4 * cs, cs} };
+ check(rmr, r);
+ }
+
+ // add back
+ rmr->add_committed_region(addr + 2 * cs, cs, stack);
+
+ { // Remove end
+ rmr->remove_uncommitted_region(addr + 4 * cs, cs);
+ R r[] = { {addr + 0 * cs, cs},
+ {addr + 2 * cs, cs} };
+ check(rmr, r);
+ }
+
+ rmr->remove_uncommitted_region(addr, 5 * cs);
+ check_empty(rmr);
+ }
+
+ { // Remove larger region
+ rmr->add_committed_region(addr + 1 * cs, cs, stack);
+ rmr->remove_uncommitted_region(addr, 3 * cs);
+ check_empty(rmr);
+ }
+
+ { // Remove smaller region - in the middle
+ rmr->add_committed_region(addr, 3 * cs, stack);
+ rmr->remove_uncommitted_region(addr + 1 * cs, cs);
+ R r[] = { { addr + 0 * cs, cs},
+ { addr + 2 * cs, cs} };
+ check(rmr, r);
+
+ rmr->remove_uncommitted_region(addr, 3 * cs);
+ check_empty(rmr);
+ }
+
+ { // Remove smaller region - at the beginning
+ rmr->add_committed_region(addr, 3 * cs, stack);
+ rmr->remove_uncommitted_region(addr + 0 * cs, cs);
+ R r[] = { { addr + 1 * cs, 2 * cs} };
+ check(rmr, r);
+
+ rmr->remove_uncommitted_region(addr, 3 * cs);
+ check_empty(rmr);
+ }
+
+ { // Remove smaller region - at the end
+ rmr->add_committed_region(addr, 3 * cs, stack);
+ rmr->remove_uncommitted_region(addr + 2 * cs, cs);
+ R r[] = { { addr, 2 * cs} };
+ check(rmr, r);
+
+ rmr->remove_uncommitted_region(addr, 3 * cs);
+ check_empty(rmr);
+ }
+
+ { // Remove smaller, overlapping region - at the beginning
+ rmr->add_committed_region(addr + 1 * cs, 4 * cs, stack);
+ rmr->remove_uncommitted_region(addr, 2 * cs);
+ R r[] = { { addr + 2 * cs, 3 * cs} };
+ check(rmr, r);
+
+ rmr->remove_uncommitted_region(addr + 1 * cs, 4 * cs);
+ check_empty(rmr);
+ }
+
+ { // Remove smaller, overlapping region - at the end
+ rmr->add_committed_region(addr, 3 * cs, stack);
+ rmr->remove_uncommitted_region(addr + 2 * cs, 2 * cs);
+ R r[] = { { addr, 2 * cs} };
+ check(rmr, r);
+
+ rmr->remove_uncommitted_region(addr, 3 * cs);
+ check_empty(rmr);
+ }
+ }
+};
+
+TEST_VM(VirtualMemoryTracker, add_committed_region) {
+ VirtualMemoryTrackerTest::test_add_committed_region();
+}
+
+TEST_VM(VirtualMemoryTracker, remove_uncommitted_region) {
+ VirtualMemoryTrackerTest::test_remove_uncommitted_region();
+}
+
+#endif // INCLUDE_NMT
--- a/test/hotspot/jtreg/ProblemList.txt Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/ProblemList.txt Thu Mar 01 01:35:46 2018 +0100
@@ -46,16 +46,11 @@
compiler/compilercontrol/jcmd/ClearDirectivesFileStackTest.java 8140405 generic-all
compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java 8158860 generic-all
compiler/jvmci/compilerToVM/InvalidateInstalledCodeTest.java 8163894 generic-all
-compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java 8180324 generic-all
-compiler/startup/SmallCodeCacheStartup.java 8134286 generic-all
compiler/tiered/LevelTransitionTest.java 8067651 generic-all
compiler/types/correctness/CorrectnessTest.java 8066173 generic-all
compiler/types/correctness/OffTest.java 8066173 generic-all
compiler/c2/Test8007294.java 8192992 generic-all
-# aot test intermittently failing in jprt 8175791
-compiler/aot/DeoptimizationTest.java 8175791 windows-all
-
applications/ctw/modules/java_desktop.java 8189604 windows-all
applications/ctw/modules/jdk_jconsole.java 8189604 windows-all
@@ -69,7 +64,7 @@
gc/g1/humongousObjects/TestHeapCounters.java 8178918 generic-all
gc/g1/TestVerifyGCType.java 8193067 generic-all
gc/stress/gclocker/TestGCLockerWithParallel.java 8180622 generic-all
-gc/stress/gclocker/TestGCLockerWithG1.java 8179226 generic-all
+gc/stress/gclocker/TestGCLockerWithG1.java 8180622 generic-all
gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java 8177765 generic-all
gc/stress/TestJNIBlockFullGC/TestJNIBlockFullGC.java 8192647 generic-all
@@ -78,18 +73,16 @@
# :hotspot_runtime
runtime/CompressedOops/UseCompressedOops.java 8079353 generic-all
-# This test is disabled since it will stress NMT and timeout during normal testing
-runtime/NMT/MallocStressTest.java 8166548 generic-all
runtime/SharedArchiveFile/DefaultUseWithClient.java 8154204 generic-all
#############################################################################
# :hotspot_serviceability
-serviceability/jdwp/AllModulesCommandTest.java 8170541 generic-all
-serviceability/sa/sadebugd/SADebugDTest.java 8163805 generic-all
-serviceability/jvmti/ModuleAwareAgents/ClassFileLoadHook/MAAClassFileLoadHook.java 8173936 generic-all
-serviceability/sa/TestRevPtrsForInvokeDynamic.java 8191270 generic-all
+serviceability/jdwp/AllModulesCommandTest.java 8170541 generic-all
+serviceability/sa/TestRevPtrsForInvokeDynamic.java 8191270 generic-all
+serviceability/sa/sadebugd/SADebugDTest.java 8163805 generic-all
+
#############################################################################
# :hotspot_misc
--- a/test/hotspot/jtreg/TEST.ROOT Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/TEST.ROOT Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2018, 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
@@ -54,6 +54,7 @@
vm.aot \
vm.cds \
vm.cds.custom.loaders \
+ vm.cds.archived.java.heap \
vm.graal.enabled \
docker.support
--- a/test/hotspot/jtreg/TEST.groups Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/TEST.groups Thu Mar 01 01:35:46 2018 +0100
@@ -54,11 +54,16 @@
hotspot_native_sanity = \
native_sanity
-hotspot_tier1_common = \
+tier1_common = \
sanity/BasicVMTest.java \
gtest/GTestWrapper.java
-hotspot_tier1_compiler_1 = \
+tier1_compiler = \
+ :tier1_compiler_1 \
+ :tier1_compiler_2 \
+ :tier1_compiler_3
+
+tier1_compiler_1 = \
compiler/aot/ \
compiler/arraycopy/ \
compiler/c1/ \
@@ -74,7 +79,7 @@
-compiler/c2/Test6603011.java \
-compiler/c2/Test6912517.java \
-hotspot_tier1_compiler_2 = \
+tier1_compiler_2 = \
compiler/classUnloading/ \
compiler/codecache/ \
compiler/codegen/ \
@@ -93,7 +98,7 @@
-compiler/codecache/stress \
-compiler/gcbarriers/PreserveFPRegistersTest.java
-hotspot_tier1_compiler_3 = \
+tier1_compiler_3 = \
compiler/intrinsics/ \
compiler/jsr292/ \
compiler/loopopts/ \
@@ -116,14 +121,20 @@
hotspot_not_fast_compiler = \
:hotspot_compiler \
- -:hotspot_tier1_compiler_1 \
- -:hotspot_tier1_compiler_2 \
- -:hotspot_tier1_compiler_3 \
+ -:tier1_compiler_1 \
+ -:tier1_compiler_2 \
+ -:tier1_compiler_3 \
-hotspot_tier1_gc_1 = \
+tier1_gc = \
+ :tier1_gc_1 \
+ :tier1_gc_2 \
+ :tier1_gc_gcold \
+ :tier1_gc_gcbasher
+
+tier1_gc_1 = \
gc/g1/
-hotspot_tier1_gc_2 = \
+tier1_gc_2 = \
sanity/ExecuteInternalVMTests.java \
gc/ \
-gc/g1/ \
@@ -133,19 +144,19 @@
-gc/cms/TestMBeanCMS.java \
-gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java
-hotspot_tier1_gc_gcold = \
+tier1_gc_gcold = \
gc/stress/gcold/TestGCOldWithG1.java
gc/stress/gcold/TestGCOldWithCMS.java
gc/stress/gcold/TestGCOldWithSerial.java
gc/stress/gcold/TestGCOldWithParallel.java
-hotspot_tier1_gc_gcbasher = \
+tier1_gc_gcbasher = \
gc/stress/gcbasher/TestGCBasherWithG1.java \
gc/stress/gcbasher/TestGCBasherWithCMS.java \
gc/stress/gcbasher/TestGCBasherWithSerial.java \
gc/stress/gcbasher/TestGCBasherWithParallel.java
-hotspot_tier1_runtime = \
+tier1_runtime = \
runtime/ \
-runtime/6626217/Test6626217.sh \
-runtime/7100935 \
@@ -190,7 +201,7 @@
-runtime/containers/ \
sanity/ \
testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java \
- -:hotspot_tier1_runtime_appcds_exclude
+ -:tier1_runtime_appcds_exclude
hotspot_cds = \
runtime/SharedArchiveFile/ \
@@ -202,30 +213,26 @@
runtime/appcds/
# A subset of AppCDS tests to be run in JPRT push
-hotspot_tier1_runtime_appcds = \
+tier1_runtime_appcds = \
runtime/appcds/HelloTest.java \
runtime/appcds/sharedStrings/SharedStringsBasic.java \
runtime/appcds/ClassLoaderTest.java
-hotspot_tier1_runtime_appcds_exclude = \
+tier1_runtime_appcds_exclude = \
runtime/appcds/ \
- -:hotspot_tier1_runtime_appcds
+ -:tier1_runtime_appcds
-hotspot_tier1_serviceability = \
+tier1_serviceability = \
serviceability/dcmd/compiler \
serviceability/logging \
serviceability/sa
-hotspot_tier1 = \
- :hotspot_tier1_common \
- :hotspot_tier1_compiler_1 \
- :hotspot_tier1_compiler_2 \
- :hotspot_tier1_compiler_3 \
- :hotspot_tier1_gc_1 \
- :hotspot_tier1_gc_2 \
- :hotspot_tier1_gc_gcold \
- :hotspot_tier1_runtime \
- :hotspot_tier1_serviceability
+tier1 = \
+ :tier1_common \
+ :tier1_compiler \
+ :tier1_gc \
+ :tier1_runtime \
+ :tier1_serviceability
hotspot_tier2_runtime = \
runtime/ \
@@ -233,20 +240,20 @@
-runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java \
-runtime/Thread/TestThreadDumpMonitorContention.java \
-runtime/containers/ \
- -:hotspot_tier1_runtime \
- -:hotspot_tier1_serviceability \
+ -:tier1_runtime \
+ -:tier1_serviceability \
-:hotspot_tier2_runtime_platform_agnostic
hotspot_tier2_runtime_platform_agnostic = \
runtime/SelectionResolution \
- -:hotspot_tier1_runtime
+ -:tier1_runtime
hotspot_tier3_runtime = \
runtime/ \
serviceability/ \
-runtime/containers/ \
- -:hotspot_tier1_runtime \
- -:hotspot_tier1_serviceability \
+ -:tier1_runtime \
+ -:tier1_serviceability \
-:hotspot_tier2_runtime_platform_agnostic \
-:hotspot_tier2_runtime
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/AndnTestI.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/AndnTestI.java Thu Mar 01 01:35:46 2018 +0100
@@ -24,7 +24,7 @@
/*
* @test
* @bug 8031321
- * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/AndnTestL.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/AndnTestL.java Thu Mar 01 01:35:46 2018 +0100
@@ -24,7 +24,7 @@
/*
* @test
* @bug 8031321
- * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BlsiTestI.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BlsiTestI.java Thu Mar 01 01:35:46 2018 +0100
@@ -24,7 +24,7 @@
/*
* @test
* @bug 8031321
- * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BlsiTestL.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BlsiTestL.java Thu Mar 01 01:35:46 2018 +0100
@@ -24,7 +24,7 @@
/*
* @test
* @bug 8031321
- * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BlsmskTestI.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BlsmskTestI.java Thu Mar 01 01:35:46 2018 +0100
@@ -24,7 +24,7 @@
/*
* @test
* @bug 8031321
- * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BlsmskTestL.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BlsmskTestL.java Thu Mar 01 01:35:46 2018 +0100
@@ -24,7 +24,7 @@
/*
* @test
* @bug 8031321
- * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BlsrTestI.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BlsrTestI.java Thu Mar 01 01:35:46 2018 +0100
@@ -24,7 +24,7 @@
/*
* @test
* @bug 8031321
- * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BlsrTestL.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BlsrTestL.java Thu Mar 01 01:35:46 2018 +0100
@@ -24,7 +24,7 @@
/*
* @test
* @bug 8031321
- * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/LZcntTestI.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/LZcntTestI.java Thu Mar 01 01:35:46 2018 +0100
@@ -24,7 +24,7 @@
/*
* @test
* @bug 8031321
- * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/LZcntTestL.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/LZcntTestL.java Thu Mar 01 01:35:46 2018 +0100
@@ -24,7 +24,7 @@
/*
* @test
* @bug 8031321
- * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/TZcntTestI.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/TZcntTestI.java Thu Mar 01 01:35:46 2018 +0100
@@ -24,7 +24,7 @@
/*
* @test
* @bug 8031321
- * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/TZcntTestL.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/TZcntTestL.java Thu Mar 01 01:35:46 2018 +0100
@@ -24,7 +24,7 @@
/*
* @test
* @bug 8031321
- * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
* @library /test/lib /
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java Thu Mar 01 01:35:46 2018 +0100
@@ -41,7 +41,6 @@
public static final String[][] DEPRECATED_OPTIONS = {
// deprecated non-alias flags:
{"MaxGCMinorPauseMillis", "1032"},
- {"MustCallLoadClassInternal", "false"},
{"MaxRAMFraction", "8"},
{"MinRAMFraction", "2"},
{"InitialRAMFraction", "64"},
@@ -106,7 +105,6 @@
public static void main(String[] args) throws Throwable {
testDeprecated(DEPRECATED_OPTIONS); // Make sure that each deprecated option is mentioned in the output.
- testDeprecatedDiagnostic("UnsyncloadClass", "false");
testDeprecatedDiagnostic("IgnoreUnverifiableClassesDuringDump", "false");
}
}
--- a/test/hotspot/jtreg/runtime/Metaspace/DefineClass.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/Metaspace/DefineClass.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,4 +1,5 @@
/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -29,17 +30,9 @@
* @library /test/lib
* @run main/othervm test.DefineClass defineClass
* @run main/othervm test.DefineClass defineSystemClass
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions
- -XX:+UnsyncloadClass -XX:+AllowParallelDefineClass
- test.DefineClass defineClassParallel
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions
- -XX:+UnsyncloadClass -XX:-AllowParallelDefineClass
+ * @run main/othervm -XX:+AllowParallelDefineClass
test.DefineClass defineClassParallel
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions
- -XX:-UnsyncloadClass -XX:+AllowParallelDefineClass
- test.DefineClass defineClassParallel
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions
- -XX:-UnsyncloadClass -XX:-AllowParallelDefineClass
+ * @run main/othervm -XX:-AllowParallelDefineClass
test.DefineClass defineClassParallel
* @run main/othervm -Djdk.attach.allowAttachSelf test.DefineClass redefineClass
* @run main/othervm -Djdk.attach.allowAttachSelf test.DefineClass redefineClassWithError
@@ -126,7 +119,7 @@
}
catch (LinkageError jle) {
// Expected with a parallel capable class loader and
- // -XX:+UnsyncloadClass or -XX:+AllowParallelDefineClass
+ // -XX:+AllowParallelDefineClass
pcl.incrementLinkageErrors();
}
@@ -320,7 +313,7 @@
}
System.out.print("Counted " + pcl.getLinkageErrors() + " LinkageErrors ");
System.out.println(pcl.getLinkageErrors() == 0 ?
- "" : "(use -XX:+UnsyncloadClass and/or -XX:+AllowParallelDefineClass to avoid this)");
+ "" : "(use -XX:+AllowParallelDefineClass to avoid this)");
System.gc();
System.out.println("System.gc()");
// After System.gc() we expect to remain with two instances: one is the initial version which is
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/NMT/VirtualAllocAttemptReserveMemoryAt.java Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Test that os::attempt_reserve_memory_at doesn't register the memory as committed
+ * @key nmt jcmd
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * java.management
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail VirtualAllocAttemptReserveMemoryAt
+ *
+ */
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.JDKToolFinder;
+
+import sun.hotspot.WhiteBox;
+
+import static jdk.test.lib.Asserts.*;
+
+public class VirtualAllocAttemptReserveMemoryAt {
+
+ public static WhiteBox wb = WhiteBox.getWhiteBox();
+
+ public static void main(String args[]) throws Exception {
+ long reserveSize = 4 * 1024 * 1024; // 4096KB
+
+ String pid = Long.toString(ProcessTools.getProcessId());
+ ProcessBuilder pb = new ProcessBuilder();
+
+ // Find an address
+ long addr = wb.NMTReserveMemory(reserveSize);
+
+ // Release it
+ wb.NMTReleaseMemory(addr, reserveSize);
+
+ long attempt_addr = wb.NMTAttemptReserveMemoryAt(addr, reserveSize);
+
+ if (attempt_addr == 0) {
+ // We didn't manage ot get the requested memory address.
+ // It's not necessarily a bug, so giving up.
+ return;
+ }
+
+ assertEQ(addr, attempt_addr);
+
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid,
+ "VM.native_memory", "detail" });
+
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+ output.shouldContain("Test (reserved=4096KB, committed=0KB)");
+
+ wb.NMTReleaseMemory(addr, reserveSize);
+ output = new OutputAnalyzer(pb.start());
+ output.shouldNotContain("Test (reserved=");
+ output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
+ + Long.toHexString(addr + reserveSize) + "\\] reserved 4096KB for Test");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/NMT/VirtualAllocCommitMerge.java Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Test merging of committed virtual memory and that we track it correctly
+ * @key nmt jcmd
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * java.management
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail VirtualAllocCommitMerge
+ *
+ */
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.JDKToolFinder;
+
+import sun.hotspot.WhiteBox;
+
+public class VirtualAllocCommitMerge {
+
+ public static WhiteBox wb = WhiteBox.getWhiteBox();
+
+ public static void main(String args[]) throws Exception {
+ OutputAnalyzer output;
+ long commitSize = 128 * 1024; // 128KB
+ long reserveSize = 4 * 1024 * 1024; // 4096KB
+ long addr;
+
+ String pid = Long.toString(ProcessTools.getProcessId());
+ ProcessBuilder pb = new ProcessBuilder();
+
+ // reserve
+ addr = wb.NMTReserveMemory(reserveSize);
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid,
+ "VM.native_memory", "detail" });
+
+ output = new OutputAnalyzer(pb.start());
+ checkReservedCommittedSummary(output, "4096KB", "0KB");
+ checkReserved(output, addr, reserveSize, "4096KB");
+
+ long addrA = addr + (0 * commitSize);
+ long addrB = addr + (1 * commitSize);
+ long addrC = addr + (2 * commitSize);
+ long addrD = addr + (3 * commitSize);
+ long addrE = addr + (4 * commitSize);
+
+ {
+ // commit overlapping ABC, A, B, C
+ wb.NMTCommitMemory(addrA, 3 * commitSize);
+
+ output = new OutputAnalyzer(pb.start());
+ checkReservedCommittedSummary(output, "4096KB", "384KB");
+ checkReserved(output, addr, reserveSize, "4096KB");
+
+ checkCommitted(output, addrA, 3 * commitSize, "384KB");
+
+
+ wb.NMTCommitMemory(addrA, commitSize);
+
+ output = new OutputAnalyzer(pb.start());
+ checkReservedCommittedSummary(output, "4096KB", "384KB");
+ checkReserved(output, addr, reserveSize, "4096KB");
+
+ checkCommitted(output, addrA, 3 * commitSize, "384KB");
+
+
+ wb.NMTCommitMemory(addrB, commitSize);
+
+ output = new OutputAnalyzer(pb.start());
+ checkReservedCommittedSummary(output, "4096KB", "384KB");
+ checkReserved(output, addr, reserveSize, "4096KB");
+
+ checkCommitted(output, addrA, 3 * commitSize, "384KB");
+
+ wb.NMTCommitMemory(addrC, commitSize);
+
+ output = new OutputAnalyzer(pb.start());
+ checkReservedCommittedSummary(output, "4096KB", "384KB");
+ checkReserved(output, addr, reserveSize, "4096KB");
+
+ checkCommitted(output, addrA, 3 * commitSize, "384KB");
+
+ // uncommit
+ wb.NMTUncommitMemory(addrA, 3 * commitSize);
+
+ output = new OutputAnalyzer(pb.start());
+ checkReservedCommittedSummary(output, "4096KB", "0KB");
+ }
+
+ // Test discontigous areas
+ {
+ // commit ACE
+ wb.NMTCommitMemory(addrA, commitSize);
+ wb.NMTCommitMemory(addrC, commitSize);
+ wb.NMTCommitMemory(addrE, commitSize);
+
+ output = new OutputAnalyzer(pb.start());
+ checkReservedCommittedSummary(output, "4096KB", "384KB");
+ checkReserved(output, addr, reserveSize, "4096KB");
+
+ checkCommitted(output, addrA, commitSize, "128KB");
+ checkCommitted(output, addrC, commitSize, "128KB");
+ checkCommitted(output, addrE, commitSize, "128KB");
+
+ // uncommit ACE
+ wb.NMTUncommitMemory(addrA, commitSize);
+ wb.NMTUncommitMemory(addrC, commitSize);
+ wb.NMTUncommitMemory(addrE, commitSize);
+
+ output = new OutputAnalyzer(pb.start());
+ checkReservedCommittedSummary(output, "4096KB", "0KB");
+ }
+
+ // Test contiguous areas
+ {
+ // commit AB
+ wb.NMTCommitMemory(addrA, commitSize);
+ wb.NMTCommitMemory(addrB, commitSize);
+
+ output = new OutputAnalyzer(pb.start());
+ checkReservedCommittedSummary(output, "4096KB", "256KB");
+ checkReserved(output, addr, reserveSize, "4096KB");
+
+ checkCommitted(output, addrA, 2 * commitSize, "256KB");
+
+ // uncommit AB
+ wb.NMTUncommitMemory(addrA, commitSize);
+ wb.NMTUncommitMemory(addrB, commitSize);
+
+ output = new OutputAnalyzer(pb.start());
+ checkReservedCommittedSummary(output, "4096KB", "0KB");
+ }
+
+ {
+ // commit BA
+ wb.NMTCommitMemory(addrB, commitSize);
+ wb.NMTCommitMemory(addrA, commitSize);
+
+ output = new OutputAnalyzer(pb.start());
+ checkReservedCommittedSummary(output, "4096KB", "256KB");
+ checkReserved(output, addr, reserveSize, "4096KB");
+
+ checkCommitted(output, addrA, 2 * commitSize, "256KB");
+
+ // uncommit AB
+ wb.NMTUncommitMemory(addrB, commitSize);
+ wb.NMTUncommitMemory(addrA, commitSize);
+
+ output = new OutputAnalyzer(pb.start());
+ checkReservedCommittedSummary(output, "4096KB", "0KB");
+ }
+
+ {
+ // commit ABC
+ wb.NMTCommitMemory(addrA, commitSize);
+ wb.NMTCommitMemory(addrB, commitSize);
+ wb.NMTCommitMemory(addrC, commitSize);
+
+ output = new OutputAnalyzer(pb.start());
+ checkReservedCommittedSummary(output, "4096KB", "384KB");
+ checkReserved(output, addr, reserveSize, "4096KB");
+
+ checkCommitted(output, addrA, 3 * commitSize, "384KB");
+
+ // uncommit
+ wb.NMTUncommitMemory(addrA, commitSize);
+ wb.NMTUncommitMemory(addrB, commitSize);
+ wb.NMTUncommitMemory(addrC, commitSize);
+
+ output = new OutputAnalyzer(pb.start());
+ checkReservedCommittedSummary(output, "4096KB", "0KB");
+ }
+
+ {
+ // commit ACB
+ wb.NMTCommitMemory(addrA, commitSize);
+ wb.NMTCommitMemory(addrC, commitSize);
+ wb.NMTCommitMemory(addrB, commitSize);
+
+ output = new OutputAnalyzer(pb.start());
+ checkReservedCommittedSummary(output, "4096KB", "384KB");
+ checkReserved(output, addr, reserveSize, "4096KB");
+
+ checkCommitted(output, addrA, 3 * commitSize, "384KB");
+
+ // uncommit
+ wb.NMTUncommitMemory(addrA, commitSize);
+ wb.NMTUncommitMemory(addrC, commitSize);
+ wb.NMTUncommitMemory(addrB, commitSize);
+
+ output = new OutputAnalyzer(pb.start());
+ checkReservedCommittedSummary(output, "4096KB", "0KB");
+ }
+
+ {
+ // commit BAC
+ wb.NMTCommitMemory(addrB, commitSize);
+ wb.NMTCommitMemory(addrA, commitSize);
+ wb.NMTCommitMemory(addrC, commitSize);
+
+ output = new OutputAnalyzer(pb.start());
+ checkReservedCommittedSummary(output, "4096KB", "384KB");
+ checkReserved(output, addr, reserveSize, "4096KB");
+
+ checkCommitted(output, addrA, 3 * commitSize, "384KB");
+
+ // uncommit
+ wb.NMTUncommitMemory(addrB, commitSize);
+ wb.NMTUncommitMemory(addrA, commitSize);
+ wb.NMTUncommitMemory(addrC, commitSize);
+
+ output = new OutputAnalyzer(pb.start());
+ checkReservedCommittedSummary(output, "4096KB", "0KB");
+ }
+
+ {
+ // commit BCA
+ wb.NMTCommitMemory(addrB, commitSize);
+ wb.NMTCommitMemory(addrC, commitSize);
+ wb.NMTCommitMemory(addrA, commitSize);
+
+ output = new OutputAnalyzer(pb.start());
+ checkReservedCommittedSummary(output, "4096KB", "384KB");
+ checkReserved(output, addr, reserveSize, "4096KB");
+
+ checkCommitted(output, addrA, 3 * commitSize, "384KB");
+
+ // uncommit
+ wb.NMTUncommitMemory(addrB, commitSize);
+ wb.NMTUncommitMemory(addrC, commitSize);
+ wb.NMTUncommitMemory(addrA, commitSize);
+
+ output = new OutputAnalyzer(pb.start());
+ checkReservedCommittedSummary(output, "4096KB", "0KB");
+ }
+
+ {
+ // commit CAB
+ wb.NMTCommitMemory(addrC, commitSize);
+ wb.NMTCommitMemory(addrA, commitSize);
+ wb.NMTCommitMemory(addrB, commitSize);
+
+ output = new OutputAnalyzer(pb.start());
+ checkReservedCommittedSummary(output, "4096KB", "384KB");
+ checkReserved(output, addr, reserveSize, "4096KB");
+
+ checkCommitted(output, addrA, 3 * commitSize, "384KB");
+
+ // uncommit
+ wb.NMTUncommitMemory(addrC, commitSize);
+ wb.NMTUncommitMemory(addrA, commitSize);
+ wb.NMTUncommitMemory(addrB, commitSize);
+
+ output = new OutputAnalyzer(pb.start());
+ checkReservedCommittedSummary(output, "4096KB", "0KB");
+ }
+
+ {
+ // commit CBA
+ wb.NMTCommitMemory(addrC, commitSize);
+ wb.NMTCommitMemory(addrB, commitSize);
+ wb.NMTCommitMemory(addrA, commitSize);
+
+ output = new OutputAnalyzer(pb.start());
+ checkReservedCommittedSummary(output, "4096KB", "384KB");
+ checkReserved(output, addr, reserveSize, "4096KB");
+
+ checkCommitted(output, addrA, 3 * commitSize, "384KB");
+
+ // uncommit
+ wb.NMTUncommitMemory(addrC, commitSize);
+ wb.NMTUncommitMemory(addrB, commitSize);
+ wb.NMTUncommitMemory(addrA, commitSize);
+
+ output = new OutputAnalyzer(pb.start());
+ checkReservedCommittedSummary(output, "4096KB", "0KB");
+ }
+
+ // release
+ wb.NMTReleaseMemory(addr, reserveSize);
+ output = new OutputAnalyzer(pb.start());
+ output.shouldNotContain("Test (reserved=");
+ output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
+ + Long.toHexString(addr + reserveSize) + "\\] reserved 4096KB for Test");
+ }
+
+ public static void checkReservedCommittedSummary(OutputAnalyzer output, String reservedString, String committedString) {
+ output.shouldContain("Test (reserved=" + reservedString + ", committed=" + committedString + ")");
+ }
+
+ public static void checkReserved(OutputAnalyzer output, long addr, long size, String sizeString) {
+ output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
+ + Long.toHexString(addr + size)
+ + "\\] reserved 4096KB for Test");
+ }
+
+ public static void checkCommitted(OutputAnalyzer output, long addr, long size, String sizeString) {
+ output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
+ + Long.toHexString(addr + size)
+ + "\\] committed " + sizeString + " from.*");
+ }
+}
--- a/test/hotspot/jtreg/runtime/RedefineTests/RedefineRunningMethods.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/RedefineTests/RedefineRunningMethods.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8055008
+ * @bug 8055008 8197901
* @summary Redefine EMCP and non-EMCP methods that are running in an infinite loop
* @library /test/lib
* @modules java.base/jdk.internal.misc
@@ -31,8 +31,9 @@
* java.instrument
* jdk.jartool/sun.tools.jar
* @run main RedefineClassHelper
- * @run main/othervm -javaagent:redefineagent.jar -Xlog:redefine+class+iklass+add=trace,redefine+class+iklass+purge=trace RedefineRunningMethods
+ * @run main/othervm -javaagent:redefineagent.jar -Xlog:redefine+class+iklass+add=trace,redefine+class+iklass+purge=trace,all=trace:file=all.log RedefineRunningMethods
*/
+// Test is executed with full trace logging redirected to a file to ensure there is no crash during logging anonymous classes - see JDK-8197901
public class RedefineRunningMethods {
public static String newB =
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/ArchiveDoesNotExist.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/ArchiveDoesNotExist.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@
/**
* @test ArchiveDoesNotExist
- * @requires vm.cds
* @summary Test how VM handles "file does not exist" situation while
* attempting to use CDS archive. JVM should exit gracefully
* when sharing mode is ON, and continue w/o sharing if sharing
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/CdsDifferentCompactStrings.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/CdsDifferentCompactStrings.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@
/**
* @test CdsDifferentCompactStrings
- * @requires vm.cds
* @summary CDS (class data sharing) requires the same -XX:[+-]CompactStrings
* setting between archive creation time and load time.
* @requires vm.cds
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/CdsDifferentObjectAlignment.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/CdsDifferentObjectAlignment.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@
/**
* @test CdsDifferentObjectAlignment
- * @requires vm.cds
* @summary Testing CDS (class data sharing) using varying object alignment.
* Using different object alignment for each dump/load pair.
* This is a negative test; using object alignment for loading that
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/CdsSameObjectAlignment.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/CdsSameObjectAlignment.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@
/**
* @test CdsSameObjectAlignment
- * @requires vm.cds
* @summary Testing CDS (class data sharing) using varying object alignment.
* Using same object alignment for each dump/load pair
* @requires vm.cds
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/DumpSharedDictionary.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/DumpSharedDictionary.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,9 +25,6 @@
* @test
* @bug 8130072
* @summary Check that Shared Dictionary is printed out with jcmd
- * Feature support: compressed oops/kptrs, 64-bit os, not on windows
- * @requires vm.cds
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
* @requires vm.cds
* @library /test/lib
* @modules java.base/jdk.internal.misc
@@ -47,7 +44,6 @@
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-XX:+UnlockDiagnosticVMOptions",
"-XX:SharedArchiveFile=./DumpSharedDictionary.jsa",
- "-XX:+UseCompressedOops",
"-Xshare:dump");
OutputAnalyzer out = CDSTestUtils.executeAndLog(pb, "dump");
@@ -58,7 +54,6 @@
pb = ProcessTools.createJavaProcessBuilder(
"-XX:+UnlockDiagnosticVMOptions",
"-XX:SharedArchiveFile=./DumpSharedDictionary.jsa",
- "-XX:+UseCompressedOops",
"-Dtest.jdk=" + testjdkPath,
"-Xshare:on", "DumpSharedDictionary", "test");
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/PrintSharedArchiveAndExit.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/PrintSharedArchiveAndExit.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@
/**
* @test
- * @requires vm.cds
* @bug 8066670
* @summary Testing -XX:+PrintSharedArchiveAndExit option
* @requires vm.cds
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/SASymbolTableTest.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/SASymbolTableTest.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@
/**
* @test SASymbolTableTest
- * @requires vm.cds
* @summary Walk symbol table using SA, with and without CDS.
* @requires vm.cds
* @library /test/lib
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedArchiveFile.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedArchiveFile.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@
/**
* @test
- * @requires vm.cds
* @bug 8014138
* @summary Testing new -XX:SharedArchiveFile=<file-name> option
* @requires vm.cds
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedBaseAddress.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedBaseAddress.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@
/**
* @test SharedBaseAddress
- * @requires vm.cds
* @summary Test variety of values for SharedBaseAddress, making sure
* VM handles normal values as well as edge values w/o a crash.
* @requires vm.cds
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedStrings.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedStrings.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,13 +23,9 @@
/**
* @test
- * @requires vm.cds
* @summary Check to make sure that shared strings in the bootstrap CDS archive
* are actually shared
- * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
- * @requires vm.gc.G1
+ * @requires vm.cds.archived.java.heap
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
@@ -51,8 +47,6 @@
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-XX:+UnlockDiagnosticVMOptions",
"-XX:SharedArchiveFile=./SharedStrings.jsa",
- "-XX:+UseG1GC",
- "-XX:+UseCompressedOops",
"-Xlog:cds,cds+hashtables",
// Needed for bootclasspath match, for CDS to work with WhiteBox API
"-Xbootclasspath/a:" + ClassFileInstaller.getJarPath("whitebox.jar"),
@@ -65,8 +59,6 @@
pb = ProcessTools.createJavaProcessBuilder(
"-XX:+UnlockDiagnosticVMOptions",
"-XX:SharedArchiveFile=./SharedStrings.jsa",
- // these are required modes for shared strings
- "-XX:+UseCompressedOops", "-XX:+UseG1GC",
// needed for access to white box test API
"-Xbootclasspath/a:" + ClassFileInstaller.getJarPath("whitebox.jar"),
"-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedStringsDedup.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedStringsDedup.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,12 +23,8 @@
/**
* @test SharedStringsDedup
- * @requires vm.cds
* @summary Test -Xshare:auto with shared strings and -XX:+UseStringDeduplication
- * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
- * @requires vm.gc.G1
+ * @requires vm.cds.archived.java.heap
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
@@ -46,9 +42,8 @@
public class SharedStringsDedup {
public static void main(String[] args) throws Exception {
OutputAnalyzer out =
- CDSTestUtils.createArchive("-XX:+UseCompressedOops", "-XX:+UseG1GC");
+ CDSTestUtils.createArchive();
CDSTestUtils.checkDump(out, "Shared string table stats");
- CDSTestUtils.runWithArchiveAndCheck("-XX:+UseCompressedOops", "-XX:+UseG1GC",
- "-XX:+UseStringDeduplication");
+ CDSTestUtils.runWithArchiveAndCheck("-XX:+UseStringDeduplication");
}
}
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedStringsRunAuto.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedStringsRunAuto.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,12 +23,8 @@
/**
* @test SharedStringsAuto
- * @requires vm.cds
* @summary Test -Xshare:auto with shared strings.
- * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
- * @requires vm.gc.G1
+ * @requires vm.cds.archived.java.heap
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
@@ -42,8 +38,8 @@
public class SharedStringsRunAuto {
public static void main(String[] args) throws Exception {
OutputAnalyzer out =
- CDSTestUtils.createArchive("-XX:+UseCompressedOops", "-XX:+UseG1GC");
+ CDSTestUtils.createArchive();
CDSTestUtils.checkDump(out, "Shared string table stats");
- CDSTestUtils.runWithArchiveAndCheck("-XX:+UseCompressedOops", "-XX:+UseG1GC");
+ CDSTestUtils.runWithArchiveAndCheck();
}
}
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedSymbolTableBucketSize.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedSymbolTableBucketSize.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@
/**
* @test
- * @requires vm.cds
* @bug 8059510
* @summary Test SharedSymbolTableBucketSize option
* @requires vm.cds
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/SpaceUtilizationCheck.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/SpaceUtilizationCheck.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@
/**
* @test SpaceUtilizationCheck
- * @requires vm.cds
* @summary Check if the space utilization for shared spaces is adequate
* @requires vm.cds
* @library /test/lib
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/TestInterpreterMethodEntries.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/TestInterpreterMethodEntries.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@
/**
* @test InterpreterMethodEntries
- * @requires vm.cds
* @bug 8169711
* @summary Test interpreter method entries for intrinsics with CDS (class data sharing)
* and different settings of the intrinsic flag during dump/use of the archive.
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformInterfaceAndImplementor.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformInterfaceAndImplementor.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@
/**
* @test
- * @requires vm.cds
* @summary Exercise initial transformation (ClassFileLoadHook)
* with CDS with Interface/Implementor pair
* @library /test/lib /runtime/SharedArchiveFile /testlibrary/jvmti
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformSuperAndSubClasses.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformSuperAndSubClasses.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,6 @@
/**
* @test
- * @requires vm.cds
* @summary Exercise initial transformation (ClassFileLoadHook)
* with CDS with SubClass and SuperClass
* @library /test/lib /runtime/SharedArchiveFile /testlibrary/jvmti
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformSuperSubTwoPckgs.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformSuperSubTwoPckgs.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,6 @@
/**
* @test
- * @requires vm.cds
* @summary Exercise initial transformation (ClassFileLoadHook)
* with CDS with SubClass and SuperClass, each lives in own separate package
* @library /test/lib /runtime/SharedArchiveFile /testlibrary/jvmti
--- a/test/hotspot/jtreg/runtime/appcds/ProhibitedPackage.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/ProhibitedPackage.java Thu Mar 01 01:35:46 2018 +0100
@@ -26,7 +26,6 @@
* @test
* @summary AppCDS handling of prohibited package.
* @requires vm.cds
- * @requires vm.cds
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/runtime/appcds/cacheObject/CheckCachedResolvedReferences.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/CheckCachedResolvedReferences.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,6 @@
* @summary Test resolved_references
* @requires vm.cds
* @requires vm.cds.custom.loaders
- * @requires (vm.gc=="null")
* @library /test/lib /test/hotspot/jtreg/runtime/appcds
* @modules java.base/jdk.internal.misc
* @modules java.management
--- a/test/hotspot/jtreg/runtime/appcds/cacheObject/DumpTimeVerifyFailure.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/DumpTimeVerifyFailure.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -26,9 +26,7 @@
* @test
* @summary Dump time should not crash if any class with shared strings fails verification due to missing dependencies.
* @bug 8186789
- * @requires vm.cds
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires (vm.gc=="null")
+ * @requires vm.cds.archived.java.heap
* @library /test/lib /test/hotspot/jtreg/runtime/appcds
* @modules java.base/jdk.internal.misc
* @modules java.management
--- a/test/hotspot/jtreg/runtime/appcds/cacheObject/GCStressTest.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/GCStressTest.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,9 +25,7 @@
/*
* @test
* @summary
- * @requires vm.cds
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires (vm.gc=="null")
+ * @requires vm.cds.archived.java.heap
* @library /test/lib /test/hotspot/jtreg/runtime/appcds
* @modules java.base/jdk.internal.misc
* @modules java.management
--- a/test/hotspot/jtreg/runtime/appcds/cacheObject/OpenArchiveRegion.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/OpenArchiveRegion.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,7 @@
/*
* @test
* @summary Test open archive heap regions
- * @requires vm.cds
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
+ * @requires vm.cds.archived.java.heap
* @requires (vm.gc=="null")
* @library /test/lib /test/hotspot/jtreg/runtime/appcds
* @modules java.base/jdk.internal.misc
--- a/test/hotspot/jtreg/runtime/appcds/cacheObject/RangeNotWithinHeap.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/RangeNotWithinHeap.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,9 +28,8 @@
* mapped due to out of range, and -Xshare:on should not fail. Test on
* linux 64-bit only since the HeapBaseMinAddress value is platform specific.
* The value used in the test may cause different behavior on other platforms.
- * @requires vm.cds
- * @requires (os.family == "linux") & (os.arch == "amd64") & (sun.arch.data.model == "64")
- * @requires (vm.gc=="null")
+ * @requires vm.cds.archived.java.heap
+ * @requires os.family == "linux"
* @library /test/lib /test/hotspot/jtreg/runtime/appcds
* @modules java.base/jdk.internal.misc
* @modules java.management
--- a/test/hotspot/jtreg/runtime/appcds/cacheObject/RedefineClassTest.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/RedefineClassTest.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -26,10 +26,7 @@
* @test
* @summary Redefine shared class. GC should not cause crash with cached resolved_references.
* @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/test-classes /test/hotspot/jtreg/runtime/appcds/jvmti
- * @requires vm.cds
- * @requires vm.gc.G1
- * @requires vm.flavor != "minimal"
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
+ * @requires vm.cds.archived.java.heap
* @modules java.base/jdk.internal.misc
* jdk.jartool/sun.tools.jar
* java.management
--- a/test/hotspot/jtreg/runtime/appcds/javaldr/GCSharedStringsDuringDump.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/javaldr/GCSharedStringsDuringDump.java Thu Mar 01 01:35:46 2018 +0100
@@ -27,10 +27,7 @@
* @summary Similar to GCDuringDumping.java, this test adds the -XX:SharedArchiveConfigFile
* option for testing the interaction with GC and shared strings.
* @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/test-classes
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
- * @requires vm.flavor != "minimal"
- * @requires vm.gc.G1
+ * @requires vm.cds.archived.java.heap
* @modules java.base/jdk.internal.misc
* jdk.jartool/sun.tools.jar
* java.management
@@ -94,8 +91,6 @@
OutputAnalyzer output = TestCommon.dump(
appJar, TestCommon.list("GCSharedStringsDuringDumpWb"),
bootClassPath, extraArg, "-Xmx32m", gcLog,
- "-XX:+UseCompressedOops", "-XX:+UseG1GC",
- "-XX:SharedReadOnlySize=30m",
"-XX:SharedArchiveConfigFile=" + sharedArchiveCfgFile);
if (output.getStdout().contains("Too many string space regions") ||
@@ -108,8 +103,6 @@
TestCommon.testDump(
appJar, TestCommon.list("GCSharedStringsDuringDumpWb"),
bootClassPath, extraArg, "-Xmx8g", "-XX:NewSize=8m", gcLog,
- "-XX:+UseCompressedOops", "-XX:+UseG1GC",
- "-XX:SharedReadOnlySize=30m",
"-XX:SharedArchiveConfigFile=" + sharedArchiveCfgFile);
}
@@ -118,8 +111,6 @@
bootClassPath,
"-Xmx32m",
"-XX:+PrintSharedSpaces",
- "-XX:+UseCompressedOops",
- "-XX:+UseG1GC",
"-XX:+UnlockDiagnosticVMOptions",
"-XX:+WhiteBoxAPI",
"-XX:SharedReadOnlySize=30m",
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/ExerciseGC.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/ExerciseGC.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,9 +25,7 @@
/*
* @test
* @summary Exercise GC with shared strings
- * @requires vm.cds
- * @requires vm.gc.G1
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
+ * @requires vm.cds.archived.java.heap
* @library /test/hotspot/jtreg/runtime/appcds /test/lib
* @modules java.base/jdk.internal.misc
* @modules java.management
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/FlagCombo.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/FlagCombo.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,9 +25,7 @@
/*
* @test
* @summary Test relevant combinations of command line flags with shared strings
- * @requires vm.cds
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires (vm.gc=="null")
+ * @requires vm.cds.archived.java.heap
* @library /test/lib /test/hotspot/jtreg/runtime/appcds
* @modules java.base/jdk.internal.misc
* @modules java.management
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/IncompatibleOptions.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/IncompatibleOptions.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, 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
@@ -26,9 +26,7 @@
* @test
* @summary Test options that are incompatible with use of shared strings
* Also test mismatch in oops encoding between dump time and run time
- * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
+ * @requires vm.cds.archived.java.heap
* @requires (vm.gc=="null")
* @library /test/lib /test/hotspot/jtreg/runtime/appcds
* @modules java.base/jdk.internal.misc
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/InternSharedString.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/InternSharedString.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,7 @@
/*
* @test
* @summary Test shared strings together with string intern operation
- * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
- * @requires vm.gc.G1
+ * @requires vm.cds.archived.java.heap
* @library /test/hotspot/jtreg/runtime/appcds /test/lib
* @modules java.base/jdk.internal.misc
* @modules java.management
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/InvalidFileFormat.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/InvalidFileFormat.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,7 @@
/*
* @test
* @summary Check most common errors in file format
- * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
- * @requires vm.gc.G1
+ * @requires vm.cds.archived.java.heap
* @library /test/lib /test/hotspot/jtreg/runtime/appcds
* @modules java.base/jdk.internal.misc
* @modules java.management
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/LargePages.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/LargePages.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,7 @@
/*
* @test
* @summary Basic shared string test with large pages
- * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
- * @requires vm.gc.G1
+ * @requires vm.cds.archived.java.heap
* @library /test/lib /test/hotspot/jtreg/runtime/appcds
* @modules java.base/jdk.internal.misc
* @modules java.management
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/LockSharedStrings.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/LockSharedStrings.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,7 @@
/*
* @test
* @summary Test locking on shared strings
- * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
- * @requires vm.gc.G1
+ * @requires vm.cds.archived.java.heap
* @library /test/hotspot/jtreg/runtime/appcds /test/lib
* @modules java.base/jdk.internal.misc
* @modules java.management
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsBasic.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsBasic.java Thu Mar 01 01:35:46 2018 +0100
@@ -25,10 +25,7 @@
/*
* @test
* @summary Basic test for shared strings
- * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
- * @requires vm.gc.G1
+ * @requires vm.cds.archived.java.heap
* @library /test/hotspot/jtreg/runtime/appcds /test/lib
* @modules java.base/jdk.internal.misc
* @modules java.management
@@ -52,8 +49,6 @@
ProcessBuilder dumpPb = ProcessTools.createJavaProcessBuilder(true,
TestCommon.makeCommandLineForAppCDS(
"-XX:+UseAppCDS",
- "-XX:+UseCompressedOops",
- "-XX:+UseG1GC",
"-cp", appJar,
"-XX:SharedArchiveConfigFile=" + sharedArchiveConfigFile,
"-XX:SharedArchiveFile=./SharedStringsBasic.jsa",
@@ -67,8 +62,6 @@
ProcessBuilder runPb = ProcessTools.createJavaProcessBuilder(true,
TestCommon.makeCommandLineForAppCDS(
"-XX:+UseAppCDS",
- "-XX:+UseCompressedOops",
- "-XX:+UseG1GC",
"-cp", appJar,
"-XX:SharedArchiveFile=./SharedStringsBasic.jsa",
"-Xshare:auto",
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsBasicPlus.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsBasicPlus.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,7 @@
/*
* @test
* @summary Basic plus test for shared strings
- * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
- * @requires vm.gc.G1
+ * @requires vm.cds.archived.java.heap
* @library /test/hotspot/jtreg/runtime/appcds /test/lib
* @modules java.base/jdk.internal.misc
* @modules java.management
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsStress.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsStress.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,7 @@
/*
* @test
* @summary Write a lots of shared strings.
- * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
- * @requires vm.gc.G1
+ * @requires vm.cds.archived.java.heap
* @library /test/hotspot/jtreg/runtime/appcds /test/lib
* @modules jdk.jartool/sun.tools.jar
* @build HelloString
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsWbTest.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsWbTest.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,7 @@
/*
* @test
* @summary White box test for shared strings
- * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
- * @requires vm.gc.G1
+ * @requires vm.cds.archived.java.heap
* @library /test/lib /test/hotspot/jtreg/runtime/appcds
* @modules java.base/jdk.internal.misc
* @modules java.management
--- a/test/hotspot/jtreg/runtime/containers/docker/TestCPUAwareness.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/hotspot/jtreg/runtime/containers/docker/TestCPUAwareness.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -94,14 +94,23 @@
// Test subset of cpuset with one element
if (cpuSet.size() >= 1) {
String testCpuSet = CPUSetsReader.listToString(cpuSet, 1);
- testAPCCombo(testCpuSet, 200*1000, 100*1000, 4*1024, 1);
+ testAPCCombo(testCpuSet, 200*1000, 100*1000, 4*1024, true, 1);
}
// Test subset of cpuset with two elements
if (cpuSet.size() >= 2) {
String testCpuSet = CPUSetsReader.listToString(cpuSet, 2);
- testAPCCombo(testCpuSet, 200*1000, 100*1000, 4*1024, 2);
- testAPCCombo(testCpuSet, 200*1000, 100*1000, 1*1024, 2);
+ testAPCCombo(testCpuSet, 200*1000, 100*1000, 4*1024, true, 2);
+ testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023, true, 2);
+ testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023, false, 1);
+ }
+
+ // Test subset of cpuset with three elements
+ if (cpuSet.size() >= 3) {
+ String testCpuSet = CPUSetsReader.listToString(cpuSet, 3);
+ testAPCCombo(testCpuSet, 100*1000, 100*1000, 2*1024, true, 1);
+ testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023, true, 2);
+ testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023, false, 1);
}
}
}
@@ -159,12 +168,14 @@
// Test correctess of automatically selected active processor cound
private static void testAPCCombo(String cpuset, int quota, int period, int shares,
- int expectedAPC) throws Exception {
+ boolean usePreferContainerQuotaForCPUCount,
+ int expectedAPC) throws Exception {
Common.logNewTestCase("test APC Combo");
System.out.println("cpuset = " + cpuset);
System.out.println("quota = " + quota);
System.out.println("period = " + period);
System.out.println("shares = " + period);
+ System.out.println("usePreferContainerQuotaForCPUCount = " + usePreferContainerQuotaForCPUCount);
System.out.println("expectedAPC = " + expectedAPC);
expectedAPC = adjustExpectedAPCForAvailableCPUs(expectedAPC);
@@ -174,6 +185,9 @@
.addDockerOpts("--cpu-period=" + period)
.addDockerOpts("--cpu-quota=" + quota)
.addDockerOpts("--cpu-shares=" + shares);
+
+ if (!usePreferContainerQuotaForCPUCount) opts.addJavaOpts("-XX:-PreferContainerQuotaForCPUCount");
+
Common.run(opts)
.shouldMatch("active_processor_count.*" + expectedAPC);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jaxp/javax/xml/jaxp/unittest/common/EncodingErrorsReportingTest.java Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8038043
+ * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
+ * @run testng/othervm common.EncodingErrorsReportingTest
+ * @run testng/othervm -DrunSecMngr=true common.EncodingErrorsReportingTest
+ * @summary Verifies that parsers reports location of wrong UTF-8 symbols in
+ * XML files parsed and included via xi:include element
+ */
+package common;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.function.Function;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Listeners;
+import org.testng.annotations.Test;
+import org.testng.Assert;
+
+@Listeners({jaxp.library.BasePolicy.class})
+public class EncodingErrorsReportingTest implements EntityResolver {
+
+ /*
+ * Test reporting of wrong UTF8 byte sequence location by SAX and DOM parsers
+ */
+ @Test(dataProvider = "invalidUTF8BytesInXml")
+ public void testMalformedByteException(Function<byte[], Exception> parseF,
+ byte[] xmlData, int expLine, int expColumn) {
+ // Check if data was generated without errors
+ Assert.assertNotNull(xmlData, "Error in xml test data generation");
+
+ // Execute supplier to get parse exception
+ Exception caughtEx = parseF.apply(xmlData);
+
+ // Check if exception was thrown
+ Assert.assertNotNull(caughtEx, "No caught exception");
+ boolean isSPE = caughtEx instanceof SAXParseException;
+ Assert.assertTrue(isSPE, "Caught exception is not SAXParseException");
+ SAXParseException spe = (SAXParseException) caughtEx;
+
+ // Check if cause is properly set
+ Throwable cause = spe.getCause();
+ Assert.assertNotNull(cause, "Cause is null");
+ Assert.assertEquals("com.sun.org.apache.xerces.internal" +
+ ".impl.io.MalformedByteSequenceException",
+ cause.getClass().getName(),
+ "Cause is not MalformedByteSequenceException");
+
+ // Check error locator parameters
+ int column_number = spe.getColumnNumber();
+ int line_number = spe.getLineNumber();
+ Assert.assertEquals(line_number, expLine, "Wrong line number reported");
+ Assert.assertEquals(column_number, expColumn, "Wrong column number reported");
+ }
+
+ // Provider with supplier functions that process XML content with different parsers
+ @DataProvider(name = "invalidUTF8BytesInXml")
+ public Object[][] parsersResultsSupplier() {
+ return new Object[][]{
+ // Tests for invalid UTF-8 byte in xml element
+ {(Function<byte[], Exception>) this::parseWithSAX,
+ invalidByteInXmlElement(), 3, 15},
+ {(Function<byte[], Exception>) this::parseWithDOM,
+ invalidByteInXmlElement(), 3, 15},
+ // Tests for invalid UTF-8 byte in xml attribute
+ {(Function<byte[], Exception>) this::parseWithSAX,
+ invalidByteInXmlAttribute(), 4, 21},
+ {(Function<byte[], Exception>) this::parseWithDOM,
+ invalidByteInXmlAttribute(), 4, 21},
+ // Tests for invalid UTF-8 byte in xml version string
+ {(Function<byte[], Exception>) this::parseWithSAX,
+ invalidByteInXmlVersionDecl(), 1, 16},
+ {(Function<byte[], Exception>) this::parseWithDOM,
+ invalidByteInXmlVersionDecl(), 1, 16},
+ // Tests for invalid byte in XML file included
+ // into parsed XML file with xi:include element
+ {(Function<byte[], Exception>) this::parseSaxAndXinclude,
+ XINCLUDE_TEST_XML.getBytes(), 5, 53},
+ {(Function<byte[], Exception>) this::parseDomAndXinclude,
+ XINCLUDE_TEST_XML.getBytes(), 5, 53},
+ };
+ }
+
+ // Parse constructed XML with SAXParser and save the observed exception
+ private Exception parseWithSAX(byte[] data) {
+ Exception caughtEx = null;
+ try {
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ SAXParser saxParser = factory.newSAXParser();
+ InputStream inputStream = new ByteArrayInputStream(data);
+ saxParser.parse(inputStream, new DefaultHandler());
+ } catch (Exception e) {
+ caughtEx = e;
+ }
+ return caughtEx;
+ }
+
+ // Parse constructed XML with DOMParser and save the observed exception
+ private Exception parseWithDOM(byte[] data) {
+ Exception caughtEx = null;
+ try {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ InputStream inputStream = new ByteArrayInputStream(data);
+ db.parse(inputStream);
+ } catch (Exception e) {
+ caughtEx = e;
+ }
+ return caughtEx;
+ }
+
+ // Parse XML content that includes faulty XML content with xi:include element.
+ // XML data is parsed by SAX parser
+ private Exception parseSaxAndXinclude(byte[] data) {
+ Exception caughtEx = null;
+ try {
+ // Create SAX parser factory and make it xi:include aware
+ SAXParserFactory spf = SAXParserFactory.newDefaultInstance();
+ spf.setNamespaceAware(true);
+ spf.setXIncludeAware(true);
+ // Set this test class as entity resolver
+ XMLReader reader = spf.newSAXParser().getXMLReader();
+ reader.setEntityResolver(this);
+ // Parse XML
+ InputStream inputStream = new ByteArrayInputStream(data);
+ reader.parse(new InputSource(inputStream));
+ } catch (Exception e) {
+ caughtEx = e;
+ }
+ return caughtEx;
+ }
+
+ // Parse XML content that includes faulty XML content with xi:include element.
+ // XML data is parsed by DOM parser
+ private Exception parseDomAndXinclude(byte[] data) {
+ Exception caughtEx = null;
+ try {
+ // Create DOM builder factory and make it xi:include aware
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+ dbf.setXIncludeAware(true);
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ // Set this test class as entity resolver
+ db.setEntityResolver(this);
+ InputStream inputStream = new ByteArrayInputStream(data);
+ // Parse XML
+ db.parse(inputStream);
+ } catch (Exception e) {
+ caughtEx = e;
+ }
+ return caughtEx;
+ }
+
+ // EntityResolver method to intercept load of test XML file content and
+ // redirect it to ByteArrayInputStream
+ @Override
+ public InputSource resolveEntity(String publicId, String systemId) throws IOException, SAXException {
+ if (systemId != null && systemId.endsWith(XINCLUDE_TEST_FN)) {
+ return new InputSource(
+ new ByteArrayInputStream(
+ generateXmlBytes("Wrong byte is ", "here", 0xFE)
+ )
+ );
+ }
+ return null;
+ }
+
+ // Construct XML content with invalid byte in xml element
+ private static byte[] invalidByteInXmlElement() {
+ final String prefix = "<?xml version=\"1.0\"?>\n<test>\n<bad-encoding>";
+ final String postfix = "</bad-encoding></test>";
+ return generateXmlBytes(prefix, postfix, 0xFA);
+ }
+
+ // Construct XML content with invalid byte in xml version declaration
+ private static byte[] invalidByteInXmlVersionDecl() {
+ final String prefix = "<?xml version=\"";
+ final String postfix = "1.0\"?><test><bad-encoding></bad-encoding></test>";
+ return generateXmlBytes(prefix, postfix, 0xFB);
+ }
+
+ // Construct XML content with invalid byte in xml attribute
+ private static byte[] invalidByteInXmlAttribute() {
+ final String prefix = "<?xml version=\"1.0\"?>\n<test>\n\n<bad-att attribute=\"";
+ final String postfix = "\"></bad-att></test>";
+ return generateXmlBytes(prefix, postfix, 0xFC);
+ }
+
+ // Test helper function to generate XML text with invalid UTF-8 byte inside
+ private static byte[] generateXmlBytes(String prefix, String postfix, int b) {
+ try {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ baos.write(prefix.getBytes());
+ baos.write(b);
+ baos.write(postfix.getBytes());
+ return baos.toByteArray();
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ // XML file name to be included with xi:include directive
+ private final static String XINCLUDE_TEST_FN = "xincludeTestFile.xml";
+
+ // xi:include test XML file that includes xml content with invalid byte
+ private final static String XINCLUDE_TEST_XML =
+ "<?xml version=\"1.0\"?>\n" +
+ "<!DOCTYPE testXInclude [\n" +
+ "<!ENTITY xincludeTestFile \""+XINCLUDE_TEST_FN+"\">]>\n" +
+ "<testXInclude xmlns:xi=\"http://www.w3.org/2001/XInclude\">\n" +
+ "<xi:include href=\"&xincludeTestFile;\" parse=\"text\"/>\n" +
+ "</testXInclude>";
+}
--- a/test/jdk/ProblemList.txt Thu Mar 01 01:30:10 2018 +0100
+++ b/test/jdk/ProblemList.txt Thu Mar 01 01:35:46 2018 +0100
@@ -467,7 +467,7 @@
tools/launcher/FXLauncherTest.java 8068049 linux-all,macosx-all
-tools/jimage/JImageExtractTest.java 8198405 windows-all
+tools/jimage/JImageExtractTest.java 8198405,8198819 generic-all
tools/jimage/JImageListTest.java 8198405 windows-all
############################################################################
@@ -486,6 +486,10 @@
com/sun/jdi/NashornPopFrameTest.java 8187143 generic-all
+com/sun/jdi/EarlyReturnTest.java 8198803 generic-all
+com/sun/jdi/EarlyReturnNegativeTest.java 8198803 generic-all
+com/sun/jdi/MethodExitReturnValuesTest.java 8198803 generic-all
+
############################################################################
# jdk_time
--- a/test/jdk/TEST.groups Thu Mar 01 01:30:10 2018 +0100
+++ b/test/jdk/TEST.groups Thu Mar 01 01:35:46 2018 +0100
@@ -28,6 +28,7 @@
tier1 = \
:jdk_lang \
:jdk_util \
+ :jdk_svc_sanity \
sun/nio/cs/ISO8859x.java \
java/nio/Buffer \
com/sun/crypto/provider/Cipher \
--- a/test/jdk/com/sun/jdi/JDIScaffold.java Thu Mar 01 01:30:10 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,595 +0,0 @@
-/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * 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.
- */
-
-import com.sun.jdi.*;
-import com.sun.jdi.request.*;
-import com.sun.jdi.event.*;
-import java.util.*;
-import java.io.*;
-
-
-/**
- * Framework used by all JDI regression tests
- */
-abstract public class JDIScaffold {
- private boolean shouldTrace = false;
- private VMConnection connection;
- private VirtualMachine vm;
- private EventRequestManager requestManager;
- private List listeners = Collections.synchronizedList(new LinkedList());
- ThreadReference vmStartThread = null;
- boolean vmDied = false;
- boolean vmDisconnected = false;
-
- static private class ArgInfo {
- String targetVMArgs = "";
- String targetAppCommandLine = "";
- String connectorSpec = "com.sun.jdi.CommandLineLaunch:";
- int traceFlags = 0;
- }
-
- static public interface TargetListener {
- boolean eventSetReceived(EventSet set);
- boolean eventSetComplete(EventSet set);
- boolean eventReceived(Event event);
- boolean breakpointReached(BreakpointEvent event);
- boolean exceptionThrown(ExceptionEvent event);
- boolean stepCompleted(StepEvent event);
- boolean classPrepared(ClassPrepareEvent event);
- boolean classUnloaded(ClassUnloadEvent event);
- boolean methodEntered(MethodEntryEvent event);
- boolean methodExited(MethodExitEvent event);
- boolean fieldAccessed(AccessWatchpointEvent event);
- boolean fieldModified(ModificationWatchpointEvent event);
- boolean threadStarted(ThreadStartEvent event);
- boolean threadDied(ThreadDeathEvent event);
- boolean vmStarted(VMStartEvent event);
- boolean vmDied(VMDeathEvent event);
- boolean vmDisconnected(VMDisconnectEvent event);
- }
-
- static public class TargetAdapter implements TargetListener {
- public boolean eventSetReceived(EventSet set) {
- return false;
- }
- public boolean eventSetComplete(EventSet set) {
- return false;
- }
- public boolean eventReceived(Event event) {
- return false;
- }
- public boolean breakpointReached(BreakpointEvent event) {
- return false;
- }
- public boolean exceptionThrown(ExceptionEvent event) {
- return false;
- }
- public boolean stepCompleted(StepEvent event) {
- return false;
- }
- public boolean classPrepared(ClassPrepareEvent event) {
- return false;
- }
- public boolean classUnloaded(ClassUnloadEvent event) {
- return false;
- }
- public boolean methodEntered(MethodEntryEvent event) {
- return false;
- }
- public boolean methodExited(MethodExitEvent event) {
- return false;
- }
- public boolean fieldAccessed(AccessWatchpointEvent event) {
- return false;
- }
- public boolean fieldModified(ModificationWatchpointEvent event) {
- return false;
- }
- public boolean threadStarted(ThreadStartEvent event) {
- return false;
- }
- public boolean threadDied(ThreadDeathEvent event) {
- return false;
- }
- public boolean vmStarted(VMStartEvent event) {
- return false;
- }
- public boolean vmDied(VMDeathEvent event) {
- return false;
- }
- public boolean vmDisconnected(VMDisconnectEvent event) {
- return false;
- }
- }
-
- private class EventHandler implements Runnable {
- EventHandler() {
- Thread thread = new Thread(this);
- thread.setDaemon(true);
- thread.start();
- }
-
- private boolean notifyEvent(TargetListener listener, Event event) {
- if (listener.eventReceived(event) == true) {
- return true;
- } else if (event instanceof BreakpointEvent) {
- return listener.breakpointReached((BreakpointEvent)event);
- } else if (event instanceof ExceptionEvent) {
- return listener.exceptionThrown((ExceptionEvent)event);
- } else if (event instanceof StepEvent) {
- return listener.stepCompleted((StepEvent)event);
- } else if (event instanceof ClassPrepareEvent) {
- return listener.classPrepared((ClassPrepareEvent)event);
- } else if (event instanceof ClassUnloadEvent) {
- return listener.classUnloaded((ClassUnloadEvent)event);
- } else if (event instanceof MethodEntryEvent) {
- return listener.methodEntered((MethodEntryEvent)event);
- } else if (event instanceof MethodExitEvent) {
- return listener.methodExited((MethodExitEvent)event);
- } else if (event instanceof AccessWatchpointEvent) {
- return listener.fieldAccessed((AccessWatchpointEvent)event);
- } else if (event instanceof ModificationWatchpointEvent) {
- return listener.fieldModified((ModificationWatchpointEvent)event);
- } else if (event instanceof ThreadStartEvent) {
- return listener.threadStarted((ThreadStartEvent)event);
- } else if (event instanceof ThreadDeathEvent) {
- return listener.threadDied((ThreadDeathEvent)event);
- } else if (event instanceof VMStartEvent) {
- return listener.vmStarted((VMStartEvent)event);
- } else if (event instanceof VMDeathEvent) {
- return listener.vmDied((VMDeathEvent)event);
- } else if (event instanceof VMDisconnectEvent) {
- return listener.vmDisconnected((VMDisconnectEvent)event);
- } else {
- throw new InternalError("Unknown event type: " + event.getClass());
- }
- }
-
- private void traceSuspendPolicy(int policy) {
- if (shouldTrace) {
- switch (policy) {
- case EventRequest.SUSPEND_NONE:
- traceln("JDI: runloop: suspend = SUSPEND_NONE");
- break;
- case EventRequest.SUSPEND_ALL:
- traceln("JDI: runloop: suspend = SUSPEND_ALL");
- break;
- case EventRequest.SUSPEND_EVENT_THREAD:
- traceln("JDI: runloop: suspend = SUSPEND_EVENT_THREAD");
- break;
- }
- }
- }
-
- public void run() {
- boolean connected = true;
- do {
- try {
- EventSet set = vm.eventQueue().remove();
- traceSuspendPolicy(set.suspendPolicy());
- synchronized (listeners) {
- ListIterator iter = listeners.listIterator();
- while (iter.hasNext()) {
- TargetListener listener = (TargetListener)iter.next();
- traceln("JDI: runloop: listener = " + listener);
- if (listener.eventSetReceived(set) == true) {
- iter.remove();
- } else {
- Iterator jter = set.iterator();
- while (jter.hasNext()) {
- Event event = (Event)jter.next();
- traceln("JDI: runloop: event = " + event.getClass());
- if (event instanceof VMDisconnectEvent) {
- connected = false;
- }
- if (notifyEvent(listener, event) == true) {
- iter.remove();
- break;
- }
- }
- traceln("JDI: runloop: end of events loop");
- if (listener.eventSetComplete(set) == true) {
- iter.remove();
- }
- }
- traceln("JDI: runloop: end of listener");
- }
- }
- } catch (InterruptedException e) {
- }
- traceln("JDI: runloop: end of outer loop");
- } while (connected);
- }
- }
-
- /**
- * Constructor
- */
- public JDIScaffold() {
- }
-
- public void enableScaffoldTrace() {
- this.shouldTrace = true;
- }
-
- public void disableScaffoldTrace() {
- this.shouldTrace = false;
- }
-
-
- /*
- * Test cases should implement tests in runTests and should
- * initiate testing by calling run().
- */
- abstract protected void runTests() throws Exception;
-
- final public void startTests() throws Exception {
- try {
- runTests();
- } finally {
- shutdown();
- }
- }
-
- protected void println(String str) {
- System.err.println(str);
- }
-
- protected void traceln(String str) {
- if (shouldTrace) {
- println(str);
- }
- }
-
- private ArgInfo parseArgs(String args[]) {
- ArgInfo argInfo = new ArgInfo();
- for (int i = 0; i < args.length; i++) {
- if (args[i].equals("-connect")) {
- i++;
- argInfo.connectorSpec = args[i];
- } else if (args[i].equals("-trace")) {
- i++;
- argInfo.traceFlags = Integer.decode(args[i]).intValue();
- } else if (args[i].startsWith("-J")) {
- argInfo.targetVMArgs += (args[i].substring(2) + ' ');
-
- /*
- * classpath can span two arguments so we need to handle
- * it specially.
- */
- if (args[i].equals("-J-classpath")) {
- i++;
- argInfo.targetVMArgs += (args[i] + ' ');
- }
- } else {
- argInfo.targetAppCommandLine += (args[i] + ' ');
- }
- }
- return argInfo;
- }
-
- public void connect(String args[]) {
- ArgInfo argInfo = parseArgs(args);
-
- argInfo.targetVMArgs += VMConnection.getDebuggeeVMOptions();
- connection = new VMConnection(argInfo.connectorSpec,
- argInfo.traceFlags);
- if (!connection.isLaunch()) {
- throw new UnsupportedOperationException(
- "Listening and Attaching not yet supported");
- }
-
- /*
- * Add a listener to track VM start/death/disconnection and
- * to update status fields accordingly.
- */
- addListener(new TargetAdapter() {
- public boolean vmStarted(VMStartEvent event) {
- traceln("JDI: listener1: got VMStart");
- synchronized(JDIScaffold.this) {
- vmStartThread = event.thread();
- JDIScaffold.this.notifyAll();
- }
- return false;
- }
-
- public boolean vmDied(VMDeathEvent event) {
- traceln("JDI: listener1: got VMDeath");
- synchronized(JDIScaffold.this) {
- vmDied = true;
- JDIScaffold.this.notifyAll();
- }
- return false;
- }
-
- public boolean vmDisconnected(VMDisconnectEvent event) {
- traceln("JDI: listener1: got VMDisconnectedEvent");
- synchronized(JDIScaffold.this) {
- vmDisconnected = true;
- JDIScaffold.this.notifyAll();
- }
- return false;
- }
- });
-
- if (connection.connector().name().equals("com.sun.jdi.CommandLineLaunch")) {
- if (argInfo.targetVMArgs.length() > 0) {
- if (connection.connectorArg("options").length() > 0) {
- throw new IllegalArgumentException("VM options in two places");
- }
- connection.setConnectorArg("options", argInfo.targetVMArgs);
- }
- if (argInfo.targetAppCommandLine.length() > 0) {
- if (connection.connectorArg("main").length() > 0) {
- throw new IllegalArgumentException("Command line in two places");
- }
- connection.setConnectorArg("main", argInfo.targetAppCommandLine);
- }
- }
-
- vm = connection.open();
- requestManager = vm.eventRequestManager();
- new EventHandler();
- }
-
-
- public VirtualMachine vm() {
- return vm;
- }
-
- public EventRequestManager eventRequestManager() {
- return requestManager;
- }
-
- public void addListener(TargetListener listener) {
- listeners.add(listener);
- }
-
- public void removeListener(TargetListener listener) {
- listeners.remove(listener);
- }
-
- public synchronized ThreadReference waitForVMStart() {
- while ((vmStartThread == null) && !vmDisconnected) {
- try {
- wait();
- } catch (InterruptedException e) {
- }
- }
-
- if (vmStartThread == null) {
- throw new VMDisconnectedException();
- }
-
- return vmStartThread;
- }
-
- public synchronized void waitForVMDeath() {
- while (!vmDied && !vmDisconnected) {
- try {
- traceln("JDI: waitForVMDeath: waiting");
- wait();
- } catch (InterruptedException e) {
- }
- }
- traceln("JDI: waitForVMDeath: done waiting");
-
- if (!vmDied) {
- throw new VMDisconnectedException();
- }
- }
-
- public Event waitForRequestedEvent(final EventRequest request) {
- class EventNotification {
- Event event;
- boolean disconnected = false;
- }
- final EventNotification en = new EventNotification();
-
- TargetAdapter adapter = new TargetAdapter() {
- public boolean eventReceived(Event event) {
- if (request.equals(event.request())) {
- synchronized (en) {
- en.event = event;
- en.notifyAll();
- }
- return true;
- } else if (event instanceof VMDisconnectEvent) {
- synchronized (en) {
- en.disconnected = true;
- en.notifyAll();
- }
- return true;
- } else {
- return false;
- }
- }
- };
-
- addListener(adapter);
-
- try {
- synchronized (en) {
- vm.resume();
- while (!en.disconnected && (en.event == null)) {
- en.wait();
- }
- }
- } catch (InterruptedException e) {
- return null;
- }
-
- if (en.disconnected) {
- throw new RuntimeException("VM Disconnected before requested event occurred");
- }
- return en.event;
- }
-
- private StepEvent doStep(ThreadReference thread, int gran, int depth) {
- final StepRequest sr =
- requestManager.createStepRequest(thread, gran, depth);
-
- sr.addClassExclusionFilter("java.*");
- sr.addClassExclusionFilter("javax.*");
- sr.addClassExclusionFilter("sun.*");
- sr.addClassExclusionFilter("com.sun.*");
- sr.addClassExclusionFilter("com.oracle.*");
- sr.addClassExclusionFilter("oracle.*");
- sr.addClassExclusionFilter("jdk.internal.*");
- sr.addCountFilter(1);
- sr.enable();
- StepEvent retEvent = (StepEvent)waitForRequestedEvent(sr);
- requestManager.deleteEventRequest(sr);
- return retEvent;
- }
-
- public StepEvent stepIntoInstruction(ThreadReference thread) {
- return doStep(thread, StepRequest.STEP_MIN, StepRequest.STEP_INTO);
- }
-
- public StepEvent stepIntoLine(ThreadReference thread) {
- return doStep(thread, StepRequest.STEP_LINE, StepRequest.STEP_INTO);
- }
-
- public StepEvent stepOverInstruction(ThreadReference thread) {
- return doStep(thread, StepRequest.STEP_MIN, StepRequest.STEP_OVER);
- }
-
- public StepEvent stepOverLine(ThreadReference thread) {
- return doStep(thread, StepRequest.STEP_LINE, StepRequest.STEP_OVER);
- }
-
- public StepEvent stepOut(ThreadReference thread) {
- return doStep(thread, StepRequest.STEP_LINE, StepRequest.STEP_OUT);
- }
-
- public BreakpointEvent resumeTo(Location loc) {
- final BreakpointRequest request =
- requestManager.createBreakpointRequest(loc);
- request.addCountFilter(1);
- request.enable();
- return (BreakpointEvent)waitForRequestedEvent(request);
- }
-
- public ReferenceType findReferenceType(String name) {
- List rts = vm.classesByName(name);
- Iterator iter = rts.iterator();
- while (iter.hasNext()) {
- ReferenceType rt = (ReferenceType)iter.next();
- if (rt.name().equals(name)) {
- return rt;
- }
- }
- return null;
- }
-
- public Method findMethod(ReferenceType rt, String name, String signature) {
- List methods = rt.methods();
- Iterator iter = methods.iterator();
- while (iter.hasNext()) {
- Method method = (Method)iter.next();
- if (method.name().equals(name) &&
- method.signature().equals(signature)) {
- return method;
- }
- }
- return null;
- }
-
- public Location findLocation(ReferenceType rt, int lineNumber)
- throws AbsentInformationException {
- List locs = rt.locationsOfLine(lineNumber);
- if (locs.size() == 0) {
- throw new IllegalArgumentException("Bad line number");
- } else if (locs.size() > 1) {
- throw new IllegalArgumentException("Line number has multiple locations");
- }
-
- return (Location)locs.get(0);
- }
-
- public BreakpointEvent resumeTo(String clsName, String methodName,
- String methodSignature) {
- ReferenceType rt = findReferenceType(clsName);
- if (rt == null) {
- rt = resumeToPrepareOf(clsName).referenceType();
- }
-
- Method method = findMethod(rt, methodName, methodSignature);
- if (method == null) {
- throw new IllegalArgumentException("Bad method name/signature");
- }
-
- return resumeTo(method.location());
- }
-
- public BreakpointEvent resumeTo(String clsName, int lineNumber) throws AbsentInformationException {
- ReferenceType rt = findReferenceType(clsName);
- if (rt == null) {
- rt = resumeToPrepareOf(clsName).referenceType();
- }
-
- return resumeTo(findLocation(rt, lineNumber));
- }
-
- public ClassPrepareEvent resumeToPrepareOf(String className) {
- final ClassPrepareRequest request =
- requestManager.createClassPrepareRequest();
- request.addClassFilter(className);
- request.addCountFilter(1);
- request.enable();
- return (ClassPrepareEvent)waitForRequestedEvent(request);
- }
-
- public void resumeToVMDeath() {
- // If we are very close to VM death, we might get a VM disconnect
- // before resume is complete. In that case ignore any VMDisconnectException
- // and let the waitForVMDeath to clean up.
- try {
- traceln("JDI: resumeToVMDeath: resuming");
- vm.resume();
- traceln("JDI: resumeToVMDeath: resumed");
- } catch (VMDisconnectedException e) {
- // clean up below
- }
- waitForVMDeath();
- }
-
- public void shutdown() {
- shutdown(null);
- }
-
- public void shutdown(String message) {
- if ((connection != null) && !vmDied) {
- try {
- connection.disposeVM();
- } catch (VMDisconnectedException e) {
- // Shutting down after the VM has gone away. This is
- // not an error, and we just ignore it.
- }
- }
- if (message != null) {
- System.out.println(message);
- }
- }
-}
--- a/test/jdk/com/sun/jdi/LaunchCommandLine.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/jdk/com/sun/jdi/LaunchCommandLine.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
* @summary Test launcher command line construction
* @author Gordon Hirsch
*
- * @run build JDIScaffold VMConnection
+ * @run build TestScaffold VMConnection
* @run compile -g HelloWorld.java
* @run build LaunchCommandLine
*
@@ -39,14 +39,14 @@
import java.util.List;
-public class LaunchCommandLine extends JDIScaffold {
+public class LaunchCommandLine extends TestScaffold {
public static void main(String args[]) throws Exception {
new LaunchCommandLine(args).startTests();
}
LaunchCommandLine(String args[]) {
// args are set in code below
- super();
+ super(args);
}
protected void runTests() throws Exception {
@@ -96,7 +96,7 @@
}
// Allow application to complete
- resumeToVMDeath();
+ resumeToVMDisconnect();
}
}
--- a/test/jdk/com/sun/jdi/ModificationWatchpoints.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/jdk/com/sun/jdi/ModificationWatchpoints.java Thu Mar 01 01:35:46 2018 +0100
@@ -26,9 +26,9 @@
* @bug 4409582
* @summary Test all info returned by modification watchpoints
* @author Daniel Prusa (or someone in the FFJ group)
- * @author Robert Field (modified to JDIScaffold)
+ * @author Robert Field
*
- * @run build JDIScaffold VMConnection
+ * @run build TestScaffold VMConnection
* @run compile -g ModificationWatchpoints.java
* @run driver ModificationWatchpoints
*/
--- a/test/jdk/com/sun/jdi/NativeInstanceFilter.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/jdk/com/sun/jdi/NativeInstanceFilter.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
* @summary Instance filter doesn't filter event if it occurs in native method
* @author Keith McGuigan
*
- * @run build JDIScaffold VMConnection
+ * @run build TestScaffold VMConnection
* @compile -XDignore.symbol.file NativeInstanceFilterTarg.java
* @run driver NativeInstanceFilter
*/
@@ -41,56 +41,24 @@
import com.sun.jdi.event.*;
import com.sun.jdi.request.*;
-public class NativeInstanceFilter extends JDIScaffold {
+public class NativeInstanceFilter extends TestScaffold {
static int unfilteredEvents = 0;
+ EventSet eventSet = null;
+ ObjectReference instance = null;
public static void main(String args[]) throws Exception {
- new NativeInstanceFilter().startTests();
+ new NativeInstanceFilter(args).startTests();
}
- public NativeInstanceFilter() {
- super();
+ public NativeInstanceFilter(String args[]) {
+ super(args);
}
static EventRequestManager requestManager = null;
static MethodExitRequest request = null;
static ThreadReference mainThread = null;
- private void listen() {
- TargetAdapter adapter = new TargetAdapter() {
- EventSet set = null;
- ObjectReference instance = null;
-
- public boolean eventSetReceived(EventSet set) {
- this.set = set;
- return false;
- }
-
- public boolean methodExited(MethodExitEvent event) {
- String name = event.method().name();
- if (instance == null && name.equals("latch")) {
- // Grab the instance (return value) and set up as filter
- System.out.println("Setting up instance filter");
- instance = (ObjectReference)event.returnValue();
- requestManager.deleteEventRequest(request);
- request = requestManager.createMethodExitRequest();
- request.addInstanceFilter(instance);
- request.addThreadFilter(mainThread);
- request.enable();
- } else if (instance != null && name.equals("intern")) {
- // If not for the filter, this will be called twice
- System.out.println("method exit event (String.intern())");
- ++unfilteredEvents;
- }
- set.resume();
- return false;
- }
- };
- addListener(adapter);
- }
-
-
protected void runTests() throws Exception {
String[] args = new String[2];
args[0] = "-connect";
@@ -99,21 +67,25 @@
connect(args);
waitForVMStart();
- // VM has started, but hasn't started running the test program yet.
+ BreakpointEvent bpe = resumeTo("NativeInstanceFilterTarg", "main", "([Ljava/lang/String;)V");
+ mainThread = bpe.thread();
requestManager = vm().eventRequestManager();
- ClassPrepareEvent e = resumeToPrepareOf("NativeInstanceFilterTarg");
- ReferenceType referenceType = e.referenceType();
- mainThread = e.thread();
request = requestManager.createMethodExitRequest();
request.addThreadFilter(mainThread);
request.enable();
- listen();
+ try {
+ addListener(this);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ failure("failure: Could not add listener");
+ throw new Exception("NativeInstanceFilter: failed");
+ }
vm().resume();
- waitForVMDeath();
+ waitForVMDisconnect();
if (unfilteredEvents != 1) {
throw new Exception(
@@ -121,4 +93,27 @@
}
System.out.println("Passed: Event filtered out.");
}
+
+ public void eventSetReceived(EventSet set) {
+ this.eventSet = set;
+ }
+
+ public void methodExited(MethodExitEvent event) {
+ String name = event.method().name();
+ if (instance == null && name.equals("latch")) {
+ // Grab the instance (return value) and set up as filter
+ System.out.println("Setting up instance filter");
+ instance = (ObjectReference)event.returnValue();
+ requestManager.deleteEventRequest(request);
+ request = requestManager.createMethodExitRequest();
+ request.addInstanceFilter(instance);
+ request.addThreadFilter(mainThread);
+ request.enable();
+ } else if (instance != null && name.equals("intern")) {
+ // If not for the filter, this will be called twice
+ System.out.println("method exit event (String.intern())");
+ ++unfilteredEvents;
+ }
+ eventSet.resume();
+ }
}
--- a/test/jdk/com/sun/jdi/UnpreparedByName.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/jdk/com/sun/jdi/UnpreparedByName.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@
* won't be returned by classesByName.
* @author Robert Field
*
- * @run build JDIScaffold VMConnection
+ * @run build TestScaffold VMConnection
* @run compile -g InnerTarg.java
* @run build UnpreparedByName
*
@@ -41,22 +41,18 @@
import java.util.List;
import java.util.Iterator;
-public class UnpreparedByName extends JDIScaffold {
- final String[] args;
+public class UnpreparedByName extends TestScaffold {
public static void main(String args[]) throws Exception {
new UnpreparedByName(args).startTests();
}
UnpreparedByName(String args[]) throws Exception {
- super();
- this.args = args;
+ super(args);
}
protected void runTests() throws Exception {
- connect(args);
- waitForVMStart();
- resumeTo("InnerTarg", "go", "()V");
+ startTo("InnerTarg", "go", "()V");
List classes = vm().classesByName("InnerTarg$TheInner");
if (classes.size() == 0) {
@@ -75,6 +71,6 @@
}
// Allow application to complete
- resumeToVMDeath();
+ resumeToVMDisconnect();
}
}
--- a/test/jdk/com/sun/jdi/UnpreparedClasses.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/jdk/com/sun/jdi/UnpreparedClasses.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@
* loaded class list are prepared classes.
* @author Robert Field
*
- * @run build JDIScaffold VMConnection
+ * @run build TestScaffold VMConnection
* @run compile -g InnerTarg.java
* @run build UnpreparedClasses
*
@@ -41,22 +41,18 @@
import java.util.List;
import java.util.Iterator;
-public class UnpreparedClasses extends JDIScaffold {
- final String[] args;
+public class UnpreparedClasses extends TestScaffold {
public static void main(String args[]) throws Exception {
new UnpreparedClasses(args).startTests();
}
UnpreparedClasses(String args[]) throws Exception {
- super();
- this.args = args;
+ super(args);
}
protected void runTests() throws Exception {
- connect(args);
- waitForVMStart();
- resumeTo("InnerTarg", "go", "()V");
+ startTo("InnerTarg", "go", "()V");
List all = vm().allClasses();
for (Iterator it = all.iterator(); it.hasNext(); ) {
@@ -73,6 +69,6 @@
}
// Allow application to complete
- resumeToVMDeath();
+ resumeToVMDisconnect();
}
}
--- a/test/jdk/com/sun/jdi/Vars.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/jdk/com/sun/jdi/Vars.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, 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
@@ -26,7 +26,7 @@
* @summary Test Method.variables() and the like.
* @author Robert Field
*
- * @run build JDIScaffold VMConnection
+ * @run build TestScaffold VMConnection
* @run compile -g Vars.java
* @run driver Vars
*/
@@ -68,14 +68,12 @@
/*
* "Vars" test runs TestVars and makes LocalVariable queries
*/
-public class Vars extends JDIScaffold {
- final String[] args;
+public class Vars extends TestScaffold {
boolean failed = false;
Vars(String args[]) {
- super();
- this.args = args;
+ super(args);
}
public static void main(String[] args) throws Exception {
@@ -144,16 +142,10 @@
}
protected void runTests() throws Exception {
- List argList = new ArrayList(Arrays.asList(args));
- argList.add("TestVars");
- System.out.println("run args: " + argList);
- connect((String[])argList.toArray(args));
- waitForVMStart();
-
/*
* Get to a point where the classes are loaded.
*/
- BreakpointEvent bp = resumeTo("TestVars", "hi", "()V");
+ BreakpointEvent bp = startTo("TestVars", "hi", "()V");
/*
* These classes should have no line numbers, except for
@@ -196,7 +188,7 @@
test(method, ARGUMENTS, "normal/arguments", "sh,lo");
// Allow application to complete
- resumeToVMDeath();
+ resumeToVMDisconnect();
if (failed) {
throw new Exception("Vars: failed");
--- a/test/jdk/java/lang/StackWalker/VerifyStackTrace.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/jdk/java/lang/StackWalker/VerifyStackTrace.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,7 +36,7 @@
/**
* @test
- * @bug 8140450
+ * @bug 8140450 8197901
* @summary Verify stack trace information obtained with respect to StackWalker
* options, when the stack contains lambdas, method handle invoke
* virtual calls, and reflection.
@@ -131,10 +131,10 @@
// test output in here (don't forget the final \n):
private final String expected =
"1: VerifyStackTrace.lambda$test$1(VerifyStackTrace.java:213)\n" +
- "2: VerifyStackTrace$$Lambda$1/662441761.run(Unknown Source)\n" +
+ "2: VerifyStackTrace$$Lambda$1/0x00000007c0089430.run(Unknown Source)\n" +
"3: VerifyStackTrace$Handle.execute(VerifyStackTrace.java:149)\n" +
- "4: java.base/java.lang.invoke.LambdaForm$DMH/2008017533.invokeVirtual_LL_V(LambdaForm$DMH)\n" +
- "5: java.base/java.lang.invoke.LambdaForm$MH/1395089624.invoke_MT(LambdaForm$MH)\n" +
+ "4: java.base/java.lang.invoke.LambdaForm$DMH/0x00000007c008a830.invokeVirtual_LL_V(LambdaForm$DMH)\n" +
+ "5: java.base/java.lang.invoke.LambdaForm$MH/0x00000007c008a830.invoke_MT(LambdaForm$MH)\n" +
"6: VerifyStackTrace$Handle.run(VerifyStackTrace.java:162)\n" +
"7: VerifyStackTrace.invoke(VerifyStackTrace.java:192)\n" +
"8: java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n" +
@@ -201,8 +201,8 @@
// out before comparing. We also erase the hash-like names of
// synthetic frames introduced by lambdas & method handles
return produced.replaceAll(":[1-9][0-9]*\\)", ":00)")
- .replaceAll("/[0-9]+\\.run", "/xxxxxxxx.run")
- .replaceAll("/[0-9]+\\.invoke", "/xxxxxxxx.invoke")
+ .replaceAll("/0x[0-9a-f]+\\.run", "/xxxxxxxx.run")
+ .replaceAll("/0x[0-9a-f]+\\.invoke", "/xxxxxxxx.invoke")
// LFs may or may not be pre-generated, making frames differ
.replaceAll("DirectMethodHandle\\$Holder", "LambdaForm\\$DMH")
.replaceAll("Invokers\\$Holder", "LambdaForm\\$MH")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/text/Normalizer/NormalizerAPITest.java Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4221795
+ * @summary Confirm Normalizer's fundamental behavior
+ * @modules java.base/sun.text java.base/sun.text.normalizer
+ * @library /java/text/testlib
+ * @compile -XDignore.symbol.file NormalizerAPITest.java
+ * @run main/timeout=30 NormalizerAPITest
+ */
+
+import java.text.Normalizer;
+import java.nio.CharBuffer;
+
+
+/*
+ * Tests around null/"" arguments for public methods.
+ *
+ * You may think that so elaborate testing for such a part is not necessary.
+ * But I actually detected a bug by this program during my porting work.
+ */
+public class NormalizerAPITest extends IntlTest {
+
+ //
+ // Shortcuts
+ //
+
+ /*
+ * Normalization forms
+ */
+ static final Normalizer.Form NFC = Normalizer.Form.NFC;
+ static final Normalizer.Form NFD = Normalizer.Form.NFD;
+ static final Normalizer.Form NFKC = Normalizer.Form.NFKC;
+ static final Normalizer.Form NFKD = Normalizer.Form.NFKD;
+ static final Normalizer.Form[] forms = {NFC, NFD, NFKC, NFKD};
+
+ static final Normalizer.Form NULL = null;
+
+ /*
+ * Option
+ */
+ static final int[] options = {
+ 0x00,
+ sun.text.Normalizer.UNICODE_3_2,
+ sun.text.normalizer.NormalizerBase.UNICODE_3_2,
+ sun.text.normalizer.NormalizerBase.UNICODE_LATEST,
+ };
+
+ static final String nonNullStr = "testdata";
+
+
+ public static void main(String[] args) throws Exception {
+ new NormalizerAPITest().run(args);
+ }
+
+ /*
+ * Check if normalize(null) throws NullPointerException as expected.
+ */
+ void Test_NullPointerException_java_normalize() {
+ boolean error = false;
+
+ /* Check null as String to be normalized */
+ for (int i = 0; i < forms.length; i++) {
+ try {
+ String s = Normalizer.normalize(null, forms[i]);
+ error = true;
+ }
+ catch (NullPointerException e) {
+ }
+ }
+
+ /* Check null as a Normalization form */
+ try {
+ String s = Normalizer.normalize(nonNullStr, NULL);
+ error = true;
+ }
+ catch (NullPointerException e) {
+ }
+
+ if (error) {
+ errln("normalize(null) should throw NullPointerException.");
+ }
+ }
+
+ /*
+ * Check if normalize(null) throws NullPointerException as expected.
+ */
+ void Test_NullPointerException_sun_normalize() {
+ boolean error = false;
+
+ for (int j = 0; j < options.length; j++) {
+ for (int i = 0; i < forms.length; i++) {
+ /* Check null as a String to be normalized */
+ try {
+ String s = sun.text.Normalizer.normalize(null, forms[i], options[j]);
+ error = true;
+ }
+ catch (NullPointerException e) {
+ }
+ }
+
+ /* Check null as a Normalization form */
+ try {
+ String s = sun.text.Normalizer.normalize(nonNullStr, NULL, options[j]);
+ error = true;
+ }
+ catch (NullPointerException e) {
+ }
+ }
+
+ if (error) {
+ errln("normalize(null) should throw NullPointerException.");
+ }
+ }
+
+ /*
+ * Check if isNormalized(null) throws NullPointerException as expected.
+ */
+ void Test_NullPointerException_java_isNormalized() {
+ boolean error = false;
+
+ for (int i = 0; i < forms.length; i++) {
+ try {
+ /* Check null as a String to be scanned */
+ boolean b = Normalizer.isNormalized(null, forms[i]);
+ error = true;
+ }
+ catch (NullPointerException e) {
+ }
+ }
+
+ /* Check null as a String to be scanned */
+ try {
+ boolean b = Normalizer.isNormalized(nonNullStr, NULL);
+ error = true;
+ }
+
+ catch (NullPointerException e) {
+ }
+ if (error) {
+ errln("isNormalized(null) should throw NullPointerException.");
+ }
+ }
+
+ /*
+ * Check if isNormalized(null) throws NullPointerException as expected.
+ */
+ void Test_NullPointerException_sun_isNormalized() {
+ boolean error = false;
+
+ for (int j = 0; j < options.length; j++) {
+ for (int i = 0; i < forms.length; i++) {
+ try {
+ /* Check null as a String to be scanned */
+ boolean b = sun.text.Normalizer.isNormalized(null, forms[i], options[j]);
+ error = true;
+ }
+ catch (NullPointerException e) {
+ }
+ }
+
+ /* Check null as a String to be scanned */
+ try {
+ boolean b = sun.text.Normalizer.isNormalized(nonNullStr, NULL, options[j]);
+ error = true;
+ }
+ catch (NullPointerException e) {
+ }
+ }
+
+ if (error) {
+ errln("isNormalized(null) should throw NullPointerException.");
+ }
+ }
+
+ /*
+ * Check if isNormalized("") doesn't throw NullPointerException and returns
+ * "" as expected.
+ */
+ void Test_No_NullPointerException_java_normalize() {
+ boolean error = false;
+
+ for (int i = 0; i < forms.length; i++) {
+ try {
+ String s = Normalizer.normalize("", forms[i]);
+ if (!s.equals("")) {
+ error = true;
+ }
+ }
+ catch (NullPointerException e) {
+ error = true;
+ }
+ }
+
+ if (error) {
+ errln("normalize() for String(\"\") should return \"\".");
+ }
+ }
+
+ /*
+ * Check if isNormalized("") doesn't throw NullPointerException and returns
+ * "" as expected.
+ */
+ void Test_No_NullPointerException_sun_normalize() {
+ boolean error = false;
+
+ for (int j = 0; j < options.length; j++) {
+ for (int i = 0; i < forms.length; i++) {
+ try {
+ String s = sun.text.Normalizer.normalize("", forms[i], options[j]);
+ if (!s.equals("")) {
+ error = true;
+ }
+ }
+ catch (NullPointerException e) {
+ error = true;
+ }
+ }
+ }
+ if (error) {
+ errln("normalize() for String(\"\") should return \"\".");
+ }
+ }
+
+ /*
+ * Check if isNormalized("") doesn't throw NullPointerException and returns
+ * "" as expected.
+ */
+ void Test_No_NullPointerException_java_isNormalized() {
+ boolean error = false;
+
+ for (int i = 0; i < forms.length; i++) {
+ try {
+ boolean b = Normalizer.isNormalized("", forms[i]);
+ if (!b) {
+ error = true;
+ }
+ }
+ catch (NullPointerException e) {
+ error = true;
+ }
+ }
+ if (error) {
+ errln("isNormalized() for String(\"\") should not return true.");
+ }
+ }
+
+ /*
+ * Check if isNormalized("") doesn't throw NullPointerException and returns
+ * "" as expected.
+ */
+ void Test_No_NullPointerException_sun_isNormalized() {
+ boolean error = false;
+
+ for (int j = 0; j < options.length; j++) {
+ for (int i = 0; i < forms.length; i++) {
+ try {
+ boolean b = sun.text.Normalizer.isNormalized("", forms[i], options[j]);
+ if (!b) {
+ error = true;
+ }
+ }
+ catch (NullPointerException e) {
+ error = true;
+ }
+ }
+ }
+ if (error) {
+ errln("isNormalized() for String(\"\") should not return true.");
+ }
+ }
+
+ /*
+ * Check if normalize() and isNormalized() work as expected for every
+ * known class which implement CharSequence Interface.
+ */
+ void Test_CharSequence() {
+
+ check_CharSequence(String.valueOf(inputData),
+ String.valueOf(outputData));
+
+ check_CharSequence(new StringBuffer(original),
+ new StringBuffer(expected));
+
+ check_CharSequence(new StringBuilder(original),
+ new StringBuilder(expected));
+
+ check_CharSequence(CharBuffer.wrap(inputData),
+ CharBuffer.wrap(outputData));
+ }
+
+
+ void check_CharSequence(CharSequence in, CharSequence expected) {
+ String out = Normalizer.normalize(in, NFD);
+ if (!out.equals(expected.toString())) {
+ errln("java.text.Normalizer.normalize(" +
+ in.getClass().getSimpleName() + ") failed.");
+ }
+ out = sun.text.Normalizer.normalize(in, NFD,
+ sun.text.normalizer.NormalizerBase.UNICODE_LATEST);
+ if (!out.equals(expected.toString())) {
+ errln("sun.text.Normalizer.normalize(" +
+ in.getClass().getSimpleName() + ") failed.");
+ }
+
+ if (!Normalizer.isNormalized(expected, NFD)) {
+ errln("java.text.Normalizer.isNormalize(" +
+ in.getClass().getSimpleName() + ") failed.");
+ }
+ if (!sun.text.Normalizer.isNormalized(expected, NFD,
+ sun.text.normalizer.NormalizerBase.UNICODE_LATEST)) {
+ errln("sun.text.Normalizer.isNormalize(" +
+ in.getClass().getSimpleName() + ") failed.");
+ }
+ }
+
+ static final char[] inputData = {'T', 's', 'c', 'h', 'u', '\u1e9b'};
+ static final char[] outputData = {'T', 's', 'c', 'h', 'u', '\u017f', '\u0307'};
+ static final String original = String.valueOf(inputData);
+ static final String expected = String.valueOf(outputData);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/text/Normalizer/ThreadSafeTest.java Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4221795 8032446
+ * @summary Confirm that java.text.Normalizer and sun.text.Normalize are
+ * thread-safe.
+ * @modules java.base/sun.text java.base/sun.text.normalizer
+ * @compile -XDignore.symbol.file ThreadSafeTest.java
+ * @run main/othervm -esa ThreadSafeTest 5 10
+ */
+
+// Usage: java ThreadSafeTest [threadsFactor [duration]]
+public class ThreadSafeTest {
+
+ static volatile boolean runrun = true;
+ static volatile boolean error = false;
+
+ public static void main(String[] args) throws Exception {
+ int threadsFactor = 5;
+ if (args.length > 0) {
+ threadsFactor = Math.max(Integer.parseInt(args[0]), 5);
+ }
+ int duration = 180;
+ if (args.length > 1) {
+ duration = Math.max(5, Integer.parseInt(args[1]));
+ }
+ int nProcessors = Runtime.getRuntime().availableProcessors();
+ int nTasks = nProcessors * threadsFactor;
+ Thread[] tasks = new Thread[nTasks];
+
+ System.out.println("Testing with " + nTasks + " threads on " +
+ nProcessors + " processors for " + duration +
+ " seconds.");
+
+ for (int i = 0; i < nTasks; i++) {
+ tasks[i] = new Thread(new Worker());
+ }
+ for (int i = 0; i < nTasks; i++) {
+ tasks[i].start();
+ }
+
+ try {
+ for (int i = 0; runrun && i < duration; i++) {
+ Thread.sleep(1000); // 1 second
+ }
+ runrun = false;
+ for (int i = 0; i < nTasks; i++) {
+ tasks[i].join();
+ }
+ }
+ catch (InterruptedException e) {
+ }
+
+ if (error) {
+ throw new RuntimeException("Normalizer is not thread-safe.");
+ }
+ }
+
+ static void testJavaNormalize(int num, java.text.Normalizer.Form form) {
+ String got = java.text.Normalizer.normalize(data[num][0], form);
+ if (!got.equals(data[num][1])) {
+ System.err.println("java.text.Normalizer.normalize(" +
+ form.toString() + ") failed.");
+ error = true;
+ }
+ }
+
+ static void testSunNormalize(int num, java.text.Normalizer.Form form,
+ int option) {
+ String got = sun.text.Normalizer.normalize(data[num][0], form, option);
+ if (!got.equals(data[num][1])) {
+ System.err.println("sun.text.Normalizer.normalize(" +
+ form.toString() + ", " +
+ Integer.toHexString(option) + ") failed.");
+ error = true;
+ }
+ }
+
+ static void testIsNormalized(int num, java.text.Normalizer.Form form) {
+ boolean normalized = java.text.Normalizer.isNormalized(data[num][1], form);
+ if (!normalized) {
+ System.err.println("java.text.Normalizer.isNormalized(" +
+ form.toString() + ") failed.");
+ error = true;
+ }
+ }
+
+ static class Worker implements Runnable {
+ public void run() {
+ while (runrun) {
+ testJavaNormalize(0, java.text.Normalizer.Form.NFKC);
+ testSunNormalize(1, java.text.Normalizer.Form.NFC,
+ sun.text.Normalizer.UNICODE_3_2);
+ testJavaNormalize(2, java.text.Normalizer.Form.NFKD);
+ testSunNormalize(3, java.text.Normalizer.Form.NFC,
+ sun.text.normalizer.NormalizerBase.UNICODE_LATEST);
+ testJavaNormalize(4, java.text.Normalizer.Form.NFD);
+
+ testIsNormalized(0, java.text.Normalizer.Form.NFKC);
+ testIsNormalized(2, java.text.Normalizer.Form.NFKD);
+ testIsNormalized(4, java.text.Normalizer.Form.NFD);
+
+ if (error) {
+ runrun = false;
+ return;
+ }
+ }
+ }
+ }
+
+ static final String[][] data = {
+ /* From: To: */
+ {"A\u0300\u0316", "\u00C0\u0316"},
+ {"\u0071\u0307\u0323\u0072", "\u0071\u0323\u0307\u0072"},
+ {"\u0f77", "\u0fb2\u0f71\u0f80"},
+ {"D\u0307\u0328\u0323", "\u1e0c\u0328\u0307"},
+ {"\u0f71\u0f72\u0f73\u0f74\u0f75",
+ "\u0F71\u0F71\u0F71\u0F72\u0F72\u0F74\u0F74"},
+ };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/security/ssl/HandshakeHash/DigestBase.java Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2018, 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.
+ */
+
+import java.security.*;
+
+class DigestBase extends MessageDigestSpi {
+
+ private MessageDigest digest = null;
+
+ public DigestBase(String alg, String provider) throws Exception {
+ digest = MessageDigest.getInstance(alg, provider);
+ }
+
+ @Override
+ protected void engineUpdate(byte input) {
+ digest.update(input);
+ }
+
+ @Override
+ protected void engineUpdate(byte[] input, int offset, int len) {
+ digest.update(input, offset, len);
+ }
+
+ @Override
+ protected byte[] engineDigest() {
+ return digest.digest();
+ }
+
+ @Override
+ protected void engineReset() {
+ digest.reset();
+ }
+
+ public static final class MD5 extends DigestBase {
+ public MD5() throws Exception {
+ super("MD5", "SUN");
+ }
+ }
+
+ public static final class SHA extends DigestBase {
+ public SHA() throws Exception {
+ super("SHA", "SUN");
+ }
+ }
+
+ public static final class SHA256 extends DigestBase {
+ public SHA256() throws Exception {
+ super("SHA-256", "SUN");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/security/ssl/HandshakeHash/HandshakeHashCloneExhaustion.java Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2016, 2018, 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.
+ */
+
+//
+// Please run in othervm mode. SunJSSE does not support dynamic system
+// properties, no way to re-use system properties in samevm/agentvm mode.
+//
+
+/*
+ * @test
+ * @bug 8148421 8193683
+ * @summary Transport Layer Security (TLS) Session Hash and Extended
+ * Master Secret Extension
+ * @summary Increase the number of clones in the CloneableDigest
+ * @library /javax/net/ssl/templates
+ * @compile DigestBase.java
+ * @run main/othervm HandshakeHashCloneExhaustion
+ * TLSv1.2 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+ * @run main/othervm HandshakeHashCloneExhaustion
+ * TLSv1.1 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+ */
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.Security;
+import javax.net.ssl.SSLSocket;
+
+public class HandshakeHashCloneExhaustion extends SSLSocketTemplate {
+
+ private static String[] protocol;
+ private static String[] ciphersuite;
+
+ /*
+ * ==================
+ * Run the test case.
+ */
+ public static void main(String[] args) throws Exception {
+ // Add in a non-cloneable MD5/SHA1/SHA-256 implementation
+ Security.insertProviderAt(new MyProvider(), 1);
+
+ if (args.length != 2) {
+ throw new Exception(
+ "Usage: HandshakeHashCloneExhaustion protocol ciphersuite");
+ }
+
+ System.out.println("Testing: " + args[0] + " " + args[1]);
+ protocol = new String [] { args[0] };
+ ciphersuite = new String[] { args[1] };
+
+ (new HandshakeHashCloneExhaustion()).run();
+ }
+
+ @Override
+ protected void runServerApplication(SSLSocket socket) throws Exception {
+ socket.setNeedClientAuth(true);
+ socket.setEnabledProtocols(protocol);
+ socket.setEnabledCipherSuites(ciphersuite);
+
+ // here comes the test logic
+ InputStream sslIS = socket.getInputStream();
+ OutputStream sslOS = socket.getOutputStream();
+
+ sslIS.read();
+ sslOS.write(85);
+ sslOS.flush();
+ }
+
+ @Override
+ protected void runClientApplication(SSLSocket socket) throws Exception {
+ InputStream sslIS = socket.getInputStream();
+ OutputStream sslOS = socket.getOutputStream();
+
+ sslOS.write(280);
+ sslOS.flush();
+ sslIS.read();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/security/ssl/HandshakeHash/MyProvider.java Thu Mar 01 01:35:46 2018 +0100
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2018, 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.
+ */
+
+import java.security.*;
+
+public final class MyProvider extends Provider {
+
+ public MyProvider() {
+ super("MyProvider", "1.0",
+ "Test Provider: SHA1/MD5/SHA256 exhaustion testing");
+ put("MessageDigest.SHA", "DigestBase.SHADigest");
+ put("MessageDigest.MD5", "DigestBase.MD5Digest");
+ put("MessageDigest.SHA-256", "DigestBase.SHA256Digest");
+ }
+}
--- a/test/jtreg-ext/requires/VMProps.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/jtreg-ext/requires/VMProps.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,7 @@
// vm.cds is true if the VM is compiled with cds support.
map.put("vm.cds", vmCDS());
map.put("vm.cds.custom.loaders", vmCDSForCustomLoaders());
+ map.put("vm.cds.archived.java.heap", vmCDSForArchivedJavaHeap());
// vm.graal.enabled is true if Graal is used as JIT
map.put("vm.graal.enabled", isGraalEnabled());
map.put("docker.support", dockerSupport());
@@ -300,7 +301,7 @@
/**
* Check for CDS support for custom loaders.
*
- * @return true if CDS is supported for customer loader by the VM to be tested.
+ * @return true if CDS provides support for customer loader in the VM to be tested.
*/
protected String vmCDSForCustomLoaders() {
if (vmCDS().equals("true") && Platform.areCustomLoadersSupportedForCDS()) {
@@ -311,6 +312,19 @@
}
/**
+ * Check for CDS support for archived Java heap regions.
+ *
+ * @return true if CDS provides support for archive Java heap regions in the VM to be tested.
+ */
+ protected String vmCDSForArchivedJavaHeap() {
+ if (vmCDS().equals("true") && WB.isJavaHeapArchiveSupported()) {
+ return "true";
+ } else {
+ return "false";
+ }
+ }
+
+ /**
* Check if Graal is used as JIT compiler.
*
* @return true if Graal is used as JIT compiler.
--- a/test/langtools/jdk/javadoc/doclet/testModules/jdk/element-list Thu Mar 01 01:30:10 2018 +0100
+++ b/test/langtools/jdk/javadoc/doclet/testModules/jdk/element-list Thu Mar 01 01:35:46 2018 +0100
@@ -310,8 +310,6 @@
module:jdk.management
com.sun.management
module:jdk.management.agent
-module:jdk.management.cmm
-jdk.management.cmm
module:jdk.management.jfr
jdk.management.jfr
module:jdk.management.resource
--- a/test/langtools/jdk/javadoc/doclet/testSearch/TestSearch.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/langtools/jdk/javadoc/doclet/testSearch/TestSearch.java Thu Mar 01 01:35:46 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,7 @@
/*
* @test
* @bug 8141492 8071982 8141636 8147890 8166175 8168965 8176794 8175218 8147881
- * 8181622 8182263 8074407 8187521
+ * 8181622 8182263 8074407 8187521 8198522
* @summary Test the search feature of javadoc.
* @author bpatel
* @library ../lib
@@ -43,7 +43,7 @@
void test1() {
javadoc("-d", "out-1", "-sourcepath", "-use", testSrc("UnnamedPkgClass.java"));
checkExit(Exit.OK);
- checkSearchOutput("UnnamedPkgClass.html", true);
+ checkSearchOutput("UnnamedPkgClass.html", true, true);
checkJqueryAndImageFiles(true);
checkSearchJS();
checkFiles(false,
@@ -249,6 +249,16 @@
"type-search-index.js");
}
+ @Test
+ void testNoModuleDirectories() {
+ javadoc("-d", "out-noMdlDir", "--no-module-directories", "-Xdoclint:none",
+ "-sourcepath", testSrc,
+ "-use", "pkg", "pkg1", "pkg2", "pkg3");
+ checkExit(Exit.OK);
+ checkSearchOutput(true, false);
+ checkSearchJS();
+ }
+
void checkDocLintErrors() {
checkOutput(Output.OUT, true,
"A sample method. Testing search tag for {@index \"unclosed quote}.",
@@ -258,10 +268,14 @@
}
void checkSearchOutput(boolean expectedOutput) {
- checkSearchOutput("overview-summary.html", expectedOutput);
+ checkSearchOutput("overview-summary.html", expectedOutput, true);
}
- void checkSearchOutput(String fileName, boolean expectedOutput) {
+ void checkSearchOutput(boolean expectedOutput, boolean moduleDirectoriesVar) {
+ checkSearchOutput("overview-summary.html", expectedOutput, moduleDirectoriesVar);
+ }
+
+ void checkSearchOutput(String fileName, boolean expectedOutput, boolean moduleDirectoriesVar) {
// Test for search related markup
checkOutput(fileName, expectedOutput,
"<link rel=\"stylesheet\" type=\"text/css\" href=\"jquery/jquery-ui.css\" title=\"Style\">\n",
@@ -272,7 +286,9 @@
"<![endif]-->\n",
"<script type=\"text/javascript\" src=\"jquery/jquery-1.10.2.js\"></script>\n",
"<script type=\"text/javascript\" src=\"jquery/jquery-ui.js\"></script>",
- "var pathtoroot = \"./\";loadScripts(document, 'script');",
+ "var pathtoroot = \"./\";\n"
+ + "var useModuleDirectories = " + moduleDirectoriesVar + ";\n"
+ + "loadScripts(document, 'script');",
"<ul class=\"navListSearch\">\n",
"<li><label for=\"search\">SEARCH:</label>\n"
+ "<input type=\"text\" id=\"search\" value=\"search\" disabled=\"disabled\">\n"
@@ -503,7 +519,26 @@
+ " if ($(this).val() == watermark) {\n"
+ " $(this).val('').removeClass('watermark');\n"
+ " }\n"
- + " });");
+ + " });",
+ "function getURLPrefix(ui) {\n"
+ + " var urlPrefix=\"\";\n"
+ + " if (useModuleDirectories) {\n"
+ + " var slash = \"/\";\n"
+ + " if (ui.item.category === catModules) {\n"
+ + " return ui.item.l + slash;\n"
+ + " } else if (ui.item.category === catPackages) {\n"
+ + " return ui.item.m + slash;\n"
+ + " } else if (ui.item.category === catTypes || ui.item.category === catMembers) {\n"
+ + " $.each(packageSearchIndex, function(index, item) {\n"
+ + " if (ui.item.p == item.l) {\n"
+ + " urlPrefix = item.m + slash;\n"
+ + " }\n"
+ + " });\n"
+ + " return urlPrefix;\n"
+ + " }\n"
+ + " }\n"
+ + " return urlPrefix;\n"
+ + "}");
}
void checkSingleIndexSearchTagDuplication() {
--- a/test/lib/sun/hotspot/WhiteBox.java Thu Mar 01 01:30:10 2018 +0100
+++ b/test/lib/sun/hotspot/WhiteBox.java Thu Mar 01 01:35:46 2018 +0100
@@ -206,6 +206,7 @@
public native long NMTMalloc(long size);
public native void NMTFree(long mem);
public native long NMTReserveMemory(long size);
+ public native long NMTAttemptReserveMemoryAt(long addr, long size);
public native void NMTCommitMemory(long addr, long size);
public native void NMTUncommitMemory(long addr, long size);
public native void NMTReleaseMemory(long addr, long size);
@@ -524,6 +525,7 @@
public native boolean isSharedClass(Class<?> c);
public native boolean areSharedStringsIgnored();
public native boolean isCDSIncludedInVmBuild();
+ public native boolean isJavaHeapArchiveSupported();
public native Object getResolvedReferences(Class<?> c);
public native boolean areOpenArchiveHeapObjectsMapped();