--- a/doc/building.html Wed Jun 13 09:57:59 2018 -0700
+++ b/doc/building.html Wed Jun 13 11:01:25 2018 -0700
@@ -505,7 +505,7 @@
<ul>
<li><code>hotspot</code> - Build all of hotspot (but only hotspot)</li>
<li><code>hotspot-<variant></code> - Build just the specified jvm variant</li>
-<li><code>images</code> or <code>product-images</code> - Build the JRE and JDK images</li>
+<li><code>images</code> or <code>product-images</code> - Build the JDK image</li>
<li><code>docs</code> or <code>docs-image</code> - Build the documentation image</li>
<li><code>test-image</code> - Build the test image</li>
<li><code>all</code> or <code>all-images</code> - Build all images (product, docs and test)</li>
@@ -639,7 +639,7 @@
<p>OpenJDK contains two different ports for the aarch64 platform, one is the original aarch64 port from the <a href="http://openjdk.java.net/projects/aarch64-port">AArch64 Port Project</a> and one is a 64-bit version of the Oracle contributed ARM port. When targeting aarch64, by the default the original aarch64 port is used. To select the Oracle ARM 64 port, use <code>--with-cpu-port=arm64</code>. Also set the corresponding value (<code>aarch64</code> or <code>arm64</code>) to --with-abi-profile, to ensure a consistent build.</p>
<h3 id="verifying-the-build">Verifying the Build</h3>
<p>The build will end up in a directory named like <code>build/linux-arm-normal-server-release</code>.</p>
-<p>Inside this build output directory, the <code>images/jdk</code> and <code>images/jre</code> will contain the newly built JDK and JRE, respectively, for your <em>target</em> system.</p>
+<p>Inside this build output directory, the <code>images/jdk</code> will contain the newly built JDK, for your <em>target</em> system.</p>
<p>Copy these folders to your <em>target</em> system. Then you can run e.g. <code>images/jdk/bin/java -version</code>.</p>
<h2 id="build-performance">Build Performance</h2>
<p>Building OpenJDK requires a lot of horsepower. Some of the build tools can be adjusted to utilize more or less of resources such as parallel threads and memory. The <code>configure</code> script analyzes your system and selects reasonable values for such options based on your hardware. If you encounter resource problems, such as out of memory conditions, you can modify the detected values with:</p>
--- a/doc/building.md Wed Jun 13 09:57:59 2018 -0700
+++ b/doc/building.md Wed Jun 13 11:01:25 2018 -0700
@@ -747,7 +747,7 @@
* `hotspot` - Build all of hotspot (but only hotspot)
* `hotspot-<variant>` - Build just the specified jvm variant
- * `images` or `product-images` - Build the JRE and JDK images
+ * `images` or `product-images` - Build the JDK image
* `docs` or `docs-image` - Build the documentation image
* `test-image` - Build the test image
* `all` or `all-images` - Build all images (product, docs and test)
@@ -1039,8 +1039,8 @@
The build will end up in a directory named like
`build/linux-arm-normal-server-release`.
-Inside this build output directory, the `images/jdk` and `images/jre` will
-contain the newly built JDK and JRE, respectively, for your *target* system.
+Inside this build output directory, the `images/jdk` will contain the newly
+built JDK, for your *target* system.
Copy these folders to your *target* system. Then you can run e.g.
`images/jdk/bin/java -version`.
--- a/make/Bundles.gmk Wed Jun 13 09:57:59 2018 -0700
+++ b/make/Bundles.gmk Wed Jun 13 11:01:25 2018 -0700
@@ -146,19 +146,13 @@
# correct base directories.
ifeq ($(OPENJDK_TARGET_OS)-$(DEBUG_LEVEL), macosx-release)
JDK_IMAGE_DIR := $(JDK_MACOSX_BUNDLE_DIR)
- JRE_IMAGE_DIR := $(JRE_MACOSX_BUNDLE_DIR)
JDK_IMAGE_HOMEDIR := $(JDK_MACOSX_CONTENTS_DIR)/Home
- JRE_IMAGE_HOMEDIR := $(JRE_MACOSX_CONTENTS_DIR)/Home
JDK_BUNDLE_SUBDIR :=
- JRE_BUNDLE_SUBDIR :=
else
JDK_IMAGE_HOMEDIR := $(JDK_IMAGE_DIR)
- JRE_IMAGE_HOMEDIR := $(JRE_IMAGE_DIR)
JDK_BUNDLE_SUBDIR := jdk-$(VERSION_NUMBER)
- JRE_BUNDLE_SUBDIR := jre-$(VERSION_NUMBER)
ifneq ($(DEBUG_LEVEL), release)
JDK_BUNDLE_SUBDIR := $(JDK_BUNDLE_SUBDIR)/$(DEBUG_LEVEL)
- JRE_BUNDLE_SUBDIR := $(JRE_BUNDLE_SUBDIR)/$(DEBUG_LEVEL)
endif
endif
@@ -204,26 +198,6 @@
TEST_DEMOS_BUNDLE_FILES := $(filter $(JDK_IMAGE_HOMEDIR)/demo/%, $(ALL_JDK_FILES))
- ALL_JRE_FILES := $(call CacheFind, $(JRE_IMAGE_DIR))
-
- # Create special filter rules when dealing with unzipped .dSYM directories on
- # macosx
- ifeq ($(OPENJDK_TARGET_OS), macosx)
- ifeq ($(ZIP_EXTERNAL_DEBUG_SYMBOLS), false)
- JRE_SYMBOLS_EXCLUDE_PATTERN := $(addprefix %, \
- $(call containing, .dSYM/, $(patsubst $(JRE_IMAGE_DIR)/%, %, $(ALL_JRE_FILES))))
- endif
- endif
-
- JRE_BUNDLE_FILES := $(filter-out \
- $(JRE_SYMBOLS_EXCLUDE_PATTERN) \
- $(SYMBOLS_EXCLUDE_PATTERN), \
- $(ALL_JRE_FILES))
- JRE_SYMBOLS_BUNDLE_FILES := $(filter \
- $(JRE_SYMBOLS_EXCLUDE_PATTERN) \
- $(SYMBOLS_EXCLUDE_PATTERN), \
- $(ALL_JRE_FILES))
-
$(eval $(call SetupBundleFile, BUILD_JDK_BUNDLE, \
BUNDLE_NAME := $(JDK_BUNDLE_NAME), \
FILES := $(JDK_BUNDLE_FILES), \
@@ -234,15 +208,6 @@
PRODUCT_TARGETS += $(BUILD_JDK_BUNDLE)
- $(eval $(call SetupBundleFile, BUILD_JRE_BUNDLE, \
- BUNDLE_NAME := $(JRE_BUNDLE_NAME), \
- FILES := $(JRE_BUNDLE_FILES), \
- BASE_DIRS := $(JRE_IMAGE_DIR), \
- SUBDIR := $(JRE_BUNDLE_SUBDIR), \
- ))
-
- PRODUCT_TARGETS += $(BUILD_JRE_BUNDLE)
-
$(eval $(call SetupBundleFile, BUILD_JDK_SYMBOLS_BUNDLE, \
BUNDLE_NAME := $(JDK_SYMBOLS_BUNDLE_NAME), \
FILES := $(JDK_SYMBOLS_BUNDLE_FILES), \
@@ -253,16 +218,6 @@
PRODUCT_TARGETS += $(BUILD_JDK_SYMBOLS_BUNDLE)
- $(eval $(call SetupBundleFile, BUILD_JRE_SYMBOLS_BUNDLE, \
- BUNDLE_NAME := $(JRE_SYMBOLS_BUNDLE_NAME), \
- FILES := $(JRE_SYMBOLS_BUNDLE_FILES), \
- BASE_DIRS := $(JRE_IMAGE_DIR), \
- SUBDIR := $(JRE_BUNDLE_SUBDIR), \
- UNZIP_DEBUGINFO := true, \
- ))
-
- PRODUCT_TARGETS += $(BUILD_JRE_SYMBOLS_BUNDLE)
-
# The demo bundle is only created to support client tests. Ideally it should
# be built with the main test bundle, but since the prerequisites match
# better with the product build, it makes more sense to keep it there for now.
--- a/make/Help.gmk Wed Jun 13 09:57:59 2018 -0700
+++ b/make/Help.gmk Wed Jun 13 11:01:25 2018 -0700
@@ -40,10 +40,10 @@
$(info $(_) # image (alias for jdk or exploded-image))
$(info $(_) make all # Create all images: product, test, docs)
$(info $(_) # (alias for all-images))
- $(info $(_) make images # Create complete jdk and jre images)
+ $(info $(_) make images # Create a complete jdk image)
$(info $(_) # (alias for product-images))
$(info $(_) make <name>-image # Build just the image for any of: )
- $(info $(_) # jdk, jre, test, docs, symbols)
+ $(info $(_) # jdk, test, docs, symbols, legacy-jre)
$(info $(_) make <phase> # Build the specified phase and everything it depends on)
$(info $(_) # (gensrc, java, copy, libs, launchers, gendata, rmic))
$(info $(_) make *-only # Applies to most targets and disables building the)
--- a/make/Images.gmk Wed Jun 13 09:57:59 2018 -0700
+++ b/make/Images.gmk Wed Jun 13 11:01:25 2018 -0700
@@ -90,7 +90,7 @@
$(JDK_IMAGE_DIR)/$(JIMAGE_TARGET_FILE): $(JMODS) \
$(call DependOnVariable, JDK_MODULES_LIST) $(BASE_RELEASE_FILE)
- $(ECHO) Creating jdk jimage
+ $(ECHO) Creating jdk image
$(RM) -r $(JDK_IMAGE_DIR)
$(call ExecuteWithLog, $(SUPPORT_OUTPUTDIR)/images/jdk, \
$(JLINK_TOOL) --add-modules $(JDK_MODULES_LIST) \
@@ -101,7 +101,7 @@
$(JRE_IMAGE_DIR)/$(JIMAGE_TARGET_FILE): $(JMODS) \
$(call DependOnVariable, JRE_MODULES_LIST) $(BASE_RELEASE_FILE)
- $(ECHO) Creating jre jimage
+ $(ECHO) Creating legacy jre image
$(RM) -r $(JRE_IMAGE_DIR)
$(call ExecuteWithLog, $(SUPPORT_OUTPUTDIR)/images/jre, \
$(JLINK_TOOL) --add-modules $(JRE_MODULES_LIST) \
--- a/make/InitSupport.gmk Wed Jun 13 09:57:59 2018 -0700
+++ b/make/InitSupport.gmk Wed Jun 13 11:01:25 2018 -0700
@@ -34,6 +34,9 @@
ifeq ($(HAS_SPEC),)
+ # COMMA is defined in spec.gmk, but that is not included yet
+ COMMA := ,
+
# Include the corresponding closed file, if present.
ifneq ($(CUSTOM_MAKE_DIR), )
-include $(CUSTOM_MAKE_DIR)/InitSupport.gmk
@@ -531,8 +534,6 @@
define ParseLogOption
ifneq ($$(findstring $1, $$(LOG)),)
override $2 := true
- # COMMA is defined in spec.gmk, but that is not included yet
- COMMA := ,
# First try to remove ",<option>" if it exists, otherwise just remove "<option>"
LOG_STRIPPED := $$(subst $1,, $$(subst $$(COMMA)$$(strip $1),, $$(LOG)))
# We might have ended up with a leading comma. Remove it. Need override
@@ -550,8 +551,6 @@
# Make words of out comma-separated list and find the one with opt=val
value := $$(strip $$(subst $$(strip $1)=,, $$(filter $$(strip $1)=%, $$(subst $$(COMMA), , $$(LOG)))))
override $2 := $$(value)
- # COMMA is defined in spec.gmk, but that is not included yet
- COMMA := ,
# First try to remove ",<option>" if it exists, otherwise just remove "<option>"
LOG_STRIPPED := $$(subst $$(strip $1)=$$(value),, \
$$(subst $$(COMMA)$$(strip $1)=$$(value),, $$(LOG)))
--- a/make/Main.gmk Wed Jun 13 09:57:59 2018 -0700
+++ b/make/Main.gmk Wed Jun 13 11:01:25 2018 -0700
@@ -328,14 +328,17 @@
jdk-image:
+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Images.gmk jdk)
-jre-image:
+legacy-jre-image:
+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Images.gmk jre)
symbols-image:
+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Images.gmk symbols)
-mac-bundles-jdk:
- +($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f MacBundles.gmk)
+mac-jdk-bundle:
+ +($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f MacBundles.gmk jdk-bundle)
+
+mac-legacy-jre-bundle:
+ +($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f MacBundles.gmk jre-bundle)
release-file:
+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f ReleaseFile.gmk)
@@ -344,8 +347,8 @@
+($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f ExplodedImageOptimize.gmk)
ALL_TARGETS += store-source-revision create-source-revision-tracker bootcycle-images zip-security \
- zip-source jrtfs-jar jdk-image jre-image \
- symbols-image mac-bundles-jdk \
+ zip-source jrtfs-jar jdk-image legacy-jre-image \
+ symbols-image mac-jdk-bundle mac-legacy-jre-bundle \
release-file exploded-image-optimize
################################################################################
@@ -776,16 +779,17 @@
generate-link-opt-data: buildtools-jdk
# The generated classlist needs to go into java.base-jmod.
- java.base-jmod jdk.jlink-jmod jdk-image jre-image: generate-link-opt-data
+ java.base-jmod jdk.jlink-jmod jdk-image legacy-jre-image: generate-link-opt-data
endif
release-file: create-source-revision-tracker
jdk-image: jmods zip-source demos release-file
- jre-image: jmods release-file
+ legacy-jre-image: jmods release-file
symbols-image: $(LIBS_TARGETS) $(LAUNCHER_TARGETS)
- mac-bundles-jdk: jdk-image jre-image
+ mac-jdk-bundle: jdk-image
+ mac-legacy-jre-bundle: legacy-jre-image
# The optimize target can run as soon as the modules dir has been completely
# populated (java, copy and gendata targets) and the basic libs and launchers
@@ -956,14 +960,14 @@
# alias for backwards compatibility
docs-javadoc: docs-jdk-api
-mac-bundles: mac-bundles-jdk
+mac-bundles: mac-jdk-bundle
# The $(OUTPUTDIR)/images directory contain the resulting deliverables,
# and in line with this, our targets for creating these are named *-image[s].
-# This target builds the product images, e.g. the JRE and JDK image
+# This target builds the product images, e.g. the JDK image
# (and possibly other, more specific versions)
-product-images: jdk-image jre-image symbols-image exploded-image
+product-images: jdk-image symbols-image exploded-image
# zip-security is actually a bundle, but for now it needs to be considered
# an image until this can be cleaned up properly.
@@ -980,7 +984,7 @@
endif
ifeq ($(OPENJDK_TARGET_OS), macosx)
- product-images: mac-bundles
+ product-images: mac-jdk-bundle
endif
# This target builds the documentation image
--- a/make/autoconf/hotspot.m4 Wed Jun 13 09:57:59 2018 -0700
+++ b/make/autoconf/hotspot.m4 Wed Jun 13 11:01:25 2018 -0700
@@ -25,7 +25,7 @@
# All valid JVM features, regardless of platform
VALID_JVM_FEATURES="compiler1 compiler2 zero minimal dtrace jvmti jvmci \
- graal vm-structs jni-check services management cmsgc g1gc parallelgc serialgc nmt cds \
+ graal vm-structs jni-check services management cmsgc epsilongc g1gc parallelgc serialgc zgc nmt cds \
static-build link-time-opt aot jfr"
# Deprecated JVM features (these are ignored, but with a warning)
@@ -328,6 +328,19 @@
fi
fi
+ # Only enable ZGC on Linux x86_64
+ AC_MSG_CHECKING([if zgc should be built])
+ if HOTSPOT_CHECK_JVM_FEATURE(zgc); then
+ if test "x$OPENJDK_TARGET_OS" = "xlinux" && test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then
+ AC_MSG_RESULT([yes])
+ else
+ DISABLED_JVM_FEATURES="$DISABLED_JVM_FEATURES zgc"
+ AC_MSG_RESULT([no, platform not supported])
+ fi
+ else
+ AC_MSG_RESULT([no])
+ fi
+
# Turn on additional features based on other parts of configure
if test "x$INCLUDE_DTRACE" = "xtrue"; then
JVM_FEATURES="$JVM_FEATURES dtrace"
@@ -410,7 +423,7 @@
fi
# All variants but minimal (and custom) get these features
- NON_MINIMAL_FEATURES="$NON_MINIMAL_FEATURES cmsgc g1gc parallelgc serialgc jni-check jvmti management nmt services vm-structs"
+ NON_MINIMAL_FEATURES="$NON_MINIMAL_FEATURES cmsgc g1gc parallelgc serialgc epsilongc jni-check jvmti management nmt services vm-structs"
if test "x$ENABLE_CDS" = "xtrue"; then
NON_MINIMAL_FEATURES="$NON_MINIMAL_FEATURES cds"
fi
--- a/make/autoconf/spec.gmk.in Wed Jun 13 09:57:59 2018 -0700
+++ b/make/autoconf/spec.gmk.in Wed Jun 13 11:01:25 2018 -0700
@@ -858,18 +858,19 @@
else ifneq ($(DEBUG_LEVEL), release)
DEBUG_PART := -$(DEBUG_LEVEL)
endif
-JDK_BUNDLE_NAME := jdk-$(BASE_NAME)_bin$(DEBUG_PART).tar.gz
-JRE_BUNDLE_NAME := jre-$(BASE_NAME)_bin$(DEBUG_PART).tar.gz
+ifeq ($(OPENJDK_TARGET_OS), windows)
+ JDK_BUNDLE_EXTENSION := zip
+else
+ JDK_BUNDLE_EXTENSION := tar.gz
+endif
+JDK_BUNDLE_NAME := jdk-$(BASE_NAME)_bin$(DEBUG_PART).$(JDK_BUNDLE_EXTENSION)
JDK_SYMBOLS_BUNDLE_NAME := jdk-$(BASE_NAME)_bin$(DEBUG_PART)-symbols.tar.gz
-JRE_SYMBOLS_BUNDLE_NAME := jre-$(BASE_NAME)_bin$(DEBUG_PART)-symbols.tar.gz
TEST_DEMOS_BUNDLE_NAME := jdk-$(BASE_NAME)_bin-tests-demos$(DEBUG_PART).tar.gz
TEST_BUNDLE_NAME := jdk-$(BASE_NAME)_bin-tests$(DEBUG_PART).tar.gz
DOCS_BUNDLE_NAME := jdk-$(BASE_NAME)_doc-api-spec$(DEBUG_PART).tar.gz
JDK_BUNDLE := $(BUNDLES_OUTPUTDIR)/$(JDK_BUNDLE_NAME)
-JRE_BUNDLE := $(BUNDLES_OUTPUTDIR)/$(JRE_BUNDLE_NAME)
JDK_SYMBOLS_BUNDLE := $(BUNDLES_OUTPUTDIR)/$(JDK_SYMBOLS_BUNDLE_NAME)
-JRE_SYMBOLS_BUNDLE := $(BUNDLES_OUTPUTDIR)/$(JRE_SYMBOLS_BUNDLE_NAME)
TEST_DEMOS_BUNDLE := $(BUNDLES_OUTPUTDIR)/$(TEST_DEMOS_BUNDLE_NAME)
TEST_BUNDLE := $(BUNDLES_OUTPUTDIR)/$(TEST_BUNDLE_NAME)
DOCS_BUNDLE := $(BUNDLES_OUTPUTDIR)/$(DOCS_BUNDLE_NAME)
--- a/make/conf/jib-profiles.js Wed Jun 13 09:57:59 2018 -0700
+++ b/make/conf/jib-profiles.js Wed Jun 13 11:01:25 2018 -0700
@@ -272,28 +272,19 @@
*/
common.main_profile_artifacts = function (o) {
var jdk_subdir = (o.jdk_subdir != null ? o.jdk_subdir : "jdk-" + data.version);
- var jre_subdir = (o.jre_subdir != null ? o.jre_subdir : "jre-" + data.version);
+ var jdk_suffix = (o.jdk_suffix != null ? o.jdk_suffix : "tar.gz");
var pf = o.platform
return {
artifacts: {
jdk: {
- local: "bundles/\\(jdk.*bin.tar.gz\\)",
+ local: "bundles/\\(jdk.*bin." + jdk_suffix + "\\)",
remote: [
- "bundles/" + pf + "/jdk-" + data.version + "_" + pf + "_bin.tar.gz",
+ "bundles/" + pf + "/jdk-" + data.version + "_" + pf + "_bin." + jdk_suffix,
"bundles/" + pf + "/\\1"
],
subdir: jdk_subdir,
exploded: "images/jdk"
},
- jre: {
- local: "bundles/\\(jre.*bin.tar.gz\\)",
- remote: [
- "bundles/" + pf + "/jre-" + data.version + "_" + pf + "_bin.tar.gz",
- "bundles/" + pf + "/\\1"
- ],
- subdir: jre_subdir,
- exploded: "images/jre"
- },
test: {
local: "bundles/\\(jdk.*bin-tests.tar.gz\\)",
remote: [
@@ -319,15 +310,6 @@
subdir: jdk_subdir,
exploded: "images/jdk"
},
- jre_symbols: {
- local: "bundles/\\(jre.*bin-symbols.tar.gz\\)",
- remote: [
- "bundles/" + pf + "/jre-" + data.version + "_" + pf + "_bin-symbols.tar.gz",
- "bundles/" + pf + "/\\1"
- ],
- subdir: jre_subdir,
- exploded: "images/jre"
- }
}
};
};
@@ -339,28 +321,19 @@
*/
common.debug_profile_artifacts = function (o) {
var jdk_subdir = "jdk-" + data.version + "/fastdebug";
- var jre_subdir = "jre-" + data.version + "/fastdebug";
+ var jdk_suffix = (o.jdk_suffix != null ? o.jdk_suffix : "tar.gz");
var pf = o.platform
return {
artifacts: {
jdk: {
- local: "bundles/\\(jdk.*bin-debug.tar.gz\\)",
+ local: "bundles/\\(jdk.*bin-debug." + jdk_suffix + "\\)",
remote: [
- "bundles/" + pf + "/jdk-" + data.version + "_" + pf + "_bin-debug.tar.gz",
+ "bundles/" + pf + "/jdk-" + data.version + "_" + pf + "_bin-debug." + jdk_suffix,
"bundles/" + pf + "/\\1"
],
subdir: jdk_subdir,
exploded: "images/jdk"
},
- jre: {
- local: "bundles/\\(jre.*bin-debug.tar.gz\\)",
- remote: [
- "bundles/" + pf + "/jre-" + data.version + "_" + pf + "_bin-debug.tar.gz",
- "bundles/" + pf + "/\\1"
- ],
- subdir: jre_subdir,
- exploded: "images/jre"
- },
test: {
local: "bundles/\\(jdk.*bin-tests-debug.tar.gz\\)",
remote: [
@@ -378,15 +351,6 @@
subdir: jdk_subdir,
exploded: "images/jdk"
},
- jre_symbols: {
- local: "bundles/\\(jre.*bin-debug-symbols.tar.gz\\)",
- remote: [
- "bundles/" + pf + "/jre-" + data.version + "_" + pf + "_bin-debug-symbols.tar.gz",
- "bundles/" + pf + "/\\1"
- ],
- subdir: jre_subdir,
- exploded: "images/jre"
- }
}
};
};
@@ -619,7 +583,6 @@
"macosx-x64": {
platform: "osx-x64",
jdk_subdir: "jdk-" + data.version + ".jdk/Contents/Home",
- jre_subdir: "jre-" + data.version + ".jre/Contents/Home"
},
"solaris-x64": {
platform: "solaris-x64",
@@ -629,9 +592,11 @@
},
"windows-x64": {
platform: "windows-x64",
+ jdk_suffix: "zip",
},
"windows-x86": {
platform: "windows-x86",
+ jdk_suffix: "zip",
},
"linux-aarch64": {
platform: "linux-aarch64",
@@ -729,6 +694,14 @@
profiles[openName].artifacts["jdk"].remote));
});
+ // Enable ZGC in linux-x64-open builds
+ [ "linux-x64-open" ].forEach(function (name) {
+ var configureArgs = { configure_args: [ "--with-jvm-features=zgc" ] };
+ var debugName = name + common.debug_suffix;
+ profiles[name] = concatObjects(profiles[name], configureArgs);
+ profiles[debugName] = concatObjects(profiles[debugName], configureArgs);
+ });
+
// Profiles used to run tests. Used in JPRT and Mach 5.
var testOnlyProfiles = {
"run-test-jprt": {
--- a/make/data/jdwp/jdwp.spec Wed Jun 13 09:57:59 2018 -0700
+++ b/make/data/jdwp/jdwp.spec Wed Jun 13 11:01:25 2018 -0700
@@ -1997,8 +1997,7 @@
)
)
(Command Stop=10
- "Stops the thread with an asynchronous exception, as if done by "
- "java.lang.Thread.stop "
+ "Stops the thread with an asynchronous exception. "
(Out
(threadObject thread "The thread object ID. ")
(object throwable "Asynchronous exception. This object must "
--- a/make/gensrc/Gensrc-java.desktop.gmk Wed Jun 13 09:57:59 2018 -0700
+++ b/make/gensrc/Gensrc-java.desktop.gmk Wed Jun 13 11:01:25 2018 -0700
@@ -78,13 +78,6 @@
GENSRC_JAVA_DESKTOP += $(COMPILE_PROPERTIES)
-# Some resources bundles are already present as java files but still need to be
-# copied to zh_HK locale.
-$(eval $(call SetupCopy-zh_HK,COPY_ZH_HK, \
- $(TOPDIR)/src/java.desktop/share/classes/sun/applet/resources/MsgAppletViewer_zh_TW.java))
-
-GENSRC_JAVA_DESKTOP += $(COPY_ZH_HK)
-
################################################################################
java.desktop: $(GENSRC_JAVA_DESKTOP)
--- a/make/hotspot/lib/JvmFeatures.gmk Wed Jun 13 09:57:59 2018 -0700
+++ b/make/hotspot/lib/JvmFeatures.gmk Wed Jun 13 11:01:25 2018 -0700
@@ -155,6 +155,16 @@
JVM_EXCLUDE_FILES += psMarkSweep.cpp psMarkSweepDecorator.cpp
endif
+ifneq ($(call check-jvm-feature, epsilongc), true)
+ JVM_CFLAGS_FEATURES += -DINCLUDE_EPSILONGC=0
+ JVM_EXCLUDE_PATTERNS += gc/epsilon
+endif
+
+ifneq ($(call check-jvm-feature, zgc), true)
+ JVM_CFLAGS_FEATURES += -DINCLUDE_ZGC=0
+ JVM_EXCLUDE_PATTERNS += gc/z
+endif
+
ifneq ($(call check-jvm-feature, jfr), true)
JVM_CFLAGS_FEATURES += -DINCLUDE_JFR=0
JVM_EXCLUDE_PATTERNS += jfr
--- a/make/lib/Awt2dLibraries.gmk Wed Jun 13 09:57:59 2018 -0700
+++ b/make/lib/Awt2dLibraries.gmk Wed Jun 13 11:01:25 2018 -0700
@@ -228,7 +228,7 @@
format-nonliteral parentheses, \
DISABLED_WARNINGS_clang := logical-op-parentheses extern-initializer, \
DISABLED_WARNINGS_solstudio := E_DECLARATION_IN_CODE, \
- DISABLED_WARNINGS_microsoft := 4297 4244 4267 4996, \
+ DISABLED_WARNINGS_microsoft := 4244 4267 4996, \
ASFLAGS := $(LIBAWT_ASFLAGS), \
LDFLAGS := $(LDFLAGS_JDKLIB) $(call SET_SHARED_LIBRARY_ORIGIN), \
LDFLAGS_macosx := -L$(INSTALL_LIBRARIES_HERE), \
@@ -517,6 +517,7 @@
E_STATEMENT_NOT_REACHED \
E_END_OF_LOOP_CODE_NOT_REACHED, \
DISABLED_WARNINGS_microsoft := 4267 4244 4312, \
+ DISABLED_WARNINGS_gcc := implicit-fallthrough, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
))
--- a/make/lib/CoreLibraries.gmk Wed Jun 13 09:57:59 2018 -0700
+++ b/make/lib/CoreLibraries.gmk Wed Jun 13 11:01:25 2018 -0700
@@ -347,7 +347,8 @@
EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
EXTRA_FILES := $(LIBJLI_EXTRA_FILES), \
OPTIMIZATION := HIGH, \
- CFLAGS := $(STATIC_LIBRARY_FLAGS) $(LIBJLI_CFLAGS_JDKLIB) $(LIBJLI_CFLAGS), \
+ CFLAGS := $(STATIC_LIBRARY_FLAGS) $(LIBJLI_CFLAGS_JDKLIB) $(LIBJLI_CFLAGS) \
+ $(addprefix -I, $(LIBJLI_SRC_DIRS)), \
ARFLAGS := $(ARFLAGS), \
OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjli_static))
--- a/make/scripts/compare.sh Wed Jun 13 09:57:59 2018 -0700
+++ b/make/scripts/compare.sh Wed Jun 13 11:01:25 2018 -0700
@@ -1300,35 +1300,10 @@
THIS_JDK="$THIS/install/jdk"
OTHER_JDK="$OTHER/install/jdk"
echo "Selecting install images for JDK compare"
- if [ -d "$THIS/install/jre" ] && [ -d "$OTHER/install/jre" ]; then
- THIS_JRE="$THIS/install/jre"
- OTHER_JRE="$OTHER/install/jre"
- echo "Also selecting install images for JRE compare"
- else
- echo "No install JRE image found"
- fi
- elif [ -d "$THIS/images/jdk" ] && [ -d "$OTHER/deploy/images/jdk" ]; then
- THIS_JDK="$THIS/images/jdk"
- OTHER_JDK="$OTHER/deploy/images/jdk"
- echo "Selecting deploy images for JDK compare"
- if [ -d "$THIS/images/jre" ] && [ -d "$OTHER/deploy/images/jre" ]; then
- THIS_JRE="$THIS/images/jre"
- OTHER_JRE="$OTHER/deploy/images/jre"
- echo "Selecting deploy images for JRE compare"
- else
- echo "No deploy JRE image found"
- fi
elif [ -d "$THIS/images/jdk" ] && [ -d "$OTHER/images/jdk" ]; then
THIS_JDK="$THIS/images/jdk"
OTHER_JDK="$OTHER/images/jdk"
echo "Selecting normal images for JDK compare"
- if [ -d "$THIS/images/jre" ] && [ -d "$OTHER/images/jre" ]; then
- THIS_JRE="$THIS/images/jre"
- OTHER_JRE="$OTHER/images/jre"
- echo "Selecting normal images for JRE compare"
- else
- echo "No normal JRE image found"
- fi
elif [ -d "$(ls -d $THIS/licensee-src/build/*/images/jdk 2> /dev/null)" ] \
&& [ -d "$(ls -d $OTHER/licensee-src/build/*/images/jdk 2> /dev/null)" ]
then
@@ -1341,9 +1316,7 @@
THIS="$(ls -d $THIS/licensee-src/build/*)"
OTHER="$(ls -d $OTHER/licensee-src/build/*)"
THIS_JDK="$THIS/images/jdk"
- THIS_JRE="$THIS/images/jre"
OTHER_JDK="$OTHER/images/jdk"
- OTHER_JRE="$OTHER/images/jre"
# Rewrite the path to tools that are used from the build
JIMAGE="$(echo "$JIMAGE" | $SED "s|$OLD_THIS|$THIS|g")"
JAVAP="$(echo "$JAVAP" | $SED "s|$OLD_THIS|$THIS|g")"
@@ -1358,17 +1331,13 @@
&& [ -d "$OTHER/images/jdk-bundle" -o -d "$OTHER/deploy/images/jdk-bundle" ]; then
if [ -d "$THIS/deploy/images/jdk-bundle" ]; then
THIS_JDK_BUNDLE="$THIS/deploy/images/jdk-bundle"
- THIS_JRE_BUNDLE="$THIS/deploy/images/jre-bundle"
else
THIS_JDK_BUNDLE="$THIS/images/jdk-bundle"
- THIS_JRE_BUNDLE="$THIS/images/jre-bundle"
fi
if [ -d "$OTHER/deploy/images/jdk-bundle" ]; then
OTHER_JDK_BUNDLE="$OTHER/deploy/images/jdk-bundle"
- OTHER_JRE_BUNDLE="$OTHER/deploy/images/jre-bundle"
else
OTHER_JDK_BUNDLE="$OTHER/images/jdk-bundle"
- OTHER_JRE_BUNDLE="$OTHER/images/jre-bundle"
fi
echo "Also comparing jdk macosx bundles"
echo " $THIS_JDK_BUNDLE"
@@ -1457,22 +1426,12 @@
echo -n "JDK "
compare_files $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
fi
- if [ -n "$THIS_JRE" ] && [ -n "$OTHER_JRE" ]; then
- echo -n "JRE "
- compare_dirs $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre
- echo -n "JRE "
- compare_files $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre
- fi
if [ -n "$THIS_JDK_BUNDLE" ] && [ -n "$OTHER_JDK_BUNDLE" ]; then
echo -n "JDK Bundle "
compare_dirs $THIS_JDK_BUNDLE $OTHER_JDK_BUNDLE $COMPARE_ROOT/jdk-bundle
- echo -n "JRE Bundle "
- compare_dirs $THIS_JRE_BUNDLE $OTHER_JRE_BUNDLE $COMPARE_ROOT/jre-bundle
echo -n "JDK Bundle "
compare_files $THIS_JDK_BUNDLE $OTHER_JDK_BUNDLE $COMPARE_ROOT/jdk-bundle
- echo -n "JRE Bundle "
- compare_files $THIS_JRE_BUNDLE $OTHER_JRE_BUNDLE $COMPARE_ROOT/jre-bundle
fi
if [ -n "$THIS_DOCS" ] && [ -n "$OTHER_DOCS" ]; then
echo -n "Docs "
@@ -1538,15 +1497,9 @@
echo -n "JDK "
compare_general_files $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
fi
- if [ -n "$THIS_JRE" ] && [ -n "$OTHER_JRE" ]; then
- echo -n "JRE "
- compare_general_files $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre
- fi
if [ -n "$THIS_JDK_BUNDLE" ] && [ -n "$OTHER_JDK_BUNDLE" ]; then
echo -n "JDK Bundle "
compare_general_files $THIS_JDK_BUNDLE $OTHER_JDK_BUNDLE $COMPARE_ROOT/jdk-bundle
- echo -n "JRE Bundle "
- compare_general_files $THIS_JRE_BUNDLE $OTHER_JRE_BUNDLE $COMPARE_ROOT/jre-bundle
fi
if [ -n "$THIS_DOCS" ] && [ -n "$OTHER_DOCS" ]; then
echo -n "Docs "
@@ -1615,10 +1568,6 @@
echo -n "JDK "
compare_permissions $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
fi
- if [ -n "$THIS_JRE" ] && [ -n "$OTHER_JRE" ]; then
- echo -n "JRE "
- compare_permissions $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre
- fi
if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then
compare_permissions $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir
fi
@@ -1637,15 +1586,9 @@
echo -n "JDK "
compare_file_types $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
fi
- if [ -n "$THIS_JRE" ] && [ -n "$OTHER_JRE" ]; then
- echo -n "JRE "
- compare_file_types $THIS_JRE $OTHER_JRE $COMPARE_ROOT/jre
- fi
if [ -n "$THIS_JDK_BUNDLE" ] && [ -n "$OTHER_JDK_BUNDLE" ]; then
echo -n "JDK Bundle "
compare_file_types $THIS_JDK_BUNDLE $OTHER_JDK_BUNDLE $COMPARE_ROOT/jdk-bundle
- echo -n "JRE Bundle "
- compare_file_types $THIS_JRE_BUNDLE $OTHER_JRE_BUNDLE $COMPARE_ROOT/jre-bundle
fi
if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then
compare_file_types $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir
--- a/src/hotspot/cpu/aarch64/c1_CodeStubs_aarch64.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/aarch64/c1_CodeStubs_aarch64.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -73,19 +73,20 @@
}
if (_index->is_cpu_register()) {
- __ mov(r22, _index->as_register());
+ __ mov(rscratch1, _index->as_register());
} else {
- __ mov(r22, _index->as_jint());
+ __ mov(rscratch1, _index->as_jint());
}
Runtime1::StubID stub_id;
if (_throw_index_out_of_bounds_exception) {
stub_id = Runtime1::throw_index_exception_id;
} else {
assert(_array != NULL, "sanity");
- __ mov(r23, _array->as_pointer_register());
+ __ mov(rscratch2, _array->as_pointer_register());
stub_id = Runtime1::throw_range_check_failed_id;
}
- __ far_call(RuntimeAddress(Runtime1::entry_for(stub_id)), NULL, rscratch2);
+ __ lea(lr, RuntimeAddress(Runtime1::entry_for(stub_id)));
+ __ blr(lr);
ce->add_call_info_here(_info);
ce->verify_oop_map(_info);
debug_only(__ should_not_reach_here());
--- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -1880,7 +1880,7 @@
// cpu register - cpu register
Register reg2 = opr2->as_register();
if (opr1->type() == T_OBJECT || opr1->type() == T_ARRAY) {
- __ cmp(reg1, reg2);
+ __ cmpoop(reg1, reg2);
} else {
assert(opr2->type() != T_OBJECT && opr2->type() != T_ARRAY, "cmp int, oop?");
__ cmpw(reg1, reg2);
@@ -1911,8 +1911,9 @@
break;
case T_OBJECT:
case T_ARRAY:
- imm = jlong(opr2->as_constant_ptr()->as_jobject());
- break;
+ jobject2reg(opr2->as_constant_ptr()->as_jobject(), rscratch1);
+ __ cmpoop(reg1, rscratch1);
+ return;
default:
ShouldNotReachHere();
imm = 0; // unreachable
--- a/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -323,7 +323,7 @@
// target: the entry point of the method that creates and posts the exception oop
-// has_argument: true if the exception needs arguments (passed in r22 and r23)
+// has_argument: true if the exception needs arguments (passed in rscratch1 and rscratch2)
OopMapSet* Runtime1::generate_exception_throw(StubAssembler* sasm, address target, bool has_argument) {
// make a frame and preserve the caller's caller-save registers
@@ -332,7 +332,9 @@
if (!has_argument) {
call_offset = __ call_RT(noreg, noreg, target);
} else {
- call_offset = __ call_RT(noreg, noreg, target, r22, r23);
+ __ mov(c_rarg1, rscratch1);
+ __ mov(c_rarg2, rscratch2);
+ call_offset = __ call_RT(noreg, noreg, target);
}
OopMapSet* oop_maps = new OopMapSet();
oop_maps->add_gc_map(call_offset, oop_map);
--- a/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -56,6 +56,15 @@
}
break;
}
+ case T_BOOLEAN: __ load_unsigned_byte (dst, src); break;
+ case T_BYTE: __ load_signed_byte (dst, src); break;
+ case T_CHAR: __ load_unsigned_short(dst, src); break;
+ case T_SHORT: __ load_signed_short (dst, src); break;
+ case T_INT: __ ldrw (dst, src); break;
+ case T_LONG: __ ldr (dst, src); break;
+ case T_ADDRESS: __ ldr (dst, src); break;
+ case T_FLOAT: __ ldrs (v0, src); break;
+ case T_DOUBLE: __ ldrd (v0, src); break;
default: Unimplemented();
}
}
@@ -84,10 +93,27 @@
}
break;
}
+ case T_BOOLEAN:
+ __ andw(val, val, 0x1); // boolean is true if LSB is 1
+ __ strb(val, dst);
+ break;
+ case T_BYTE: __ strb(val, dst); break;
+ case T_CHAR: __ strh(val, dst); break;
+ case T_SHORT: __ strh(val, dst); break;
+ case T_INT: __ strw(val, dst); break;
+ case T_LONG: __ str (val, dst); break;
+ case T_ADDRESS: __ str (val, dst); break;
+ case T_FLOAT: __ strs(v0, dst); break;
+ case T_DOUBLE: __ strd(v0, dst); break;
default: Unimplemented();
}
}
+void BarrierSetAssembler::obj_equals(MacroAssembler* masm,
+ Register obj1, Register obj2) {
+ __ cmp(obj1, obj2);
+}
+
void BarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
Register obj, Register tmp, Label& slowpath) {
// If mask changes we need to ensure that the inverse is still encodable as an immediate
--- a/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -40,6 +40,9 @@
virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
Address dst, Register val, Register tmp1, Register tmp2);
+ virtual void obj_equals(MacroAssembler* masm,
+ Register obj1, Register obj2);
+
virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
Register obj, Register tmp, Label& slowpath);
--- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -268,9 +268,6 @@
void InterpreterMacroAssembler::load_resolved_reference_at_index(
Register result, Register index, Register tmp) {
assert_different_registers(result, index);
- // convert from field index to resolved_references() index and from
- // word index to byte offset. Since this is a java object, it can be compressed
- lslw(index, index, LogBytesPerHeapOop);
get_constant_pool(result);
// load pointer for resolved_references[] objArray
@@ -278,8 +275,8 @@
ldr(result, Address(result, ConstantPoolCache::resolved_references_offset_in_bytes()));
resolve_oop_handle(result, tmp);
// Add in the index
- add(result, result, index);
- load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
+ add(index, index, arrayOopDesc::base_offset_in_bytes(T_OBJECT) >> LogBytesPerHeapOop);
+ load_heap_oop(result, Address(result, index, Address::uxtw(LogBytesPerHeapOop)));
}
void InterpreterMacroAssembler::load_resolved_klass_at_offset(
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -2113,7 +2113,6 @@
#endif
void MacroAssembler::resolve_jobject(Register value, Register thread, Register tmp) {
- BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
Label done, not_weak;
cbz(value, done); // Use NULL as-is.
@@ -2121,15 +2120,15 @@
tbz(r0, 0, not_weak); // Test for jweak tag.
// Resolve jweak.
- bs->load_at(this, IN_ROOT | ON_PHANTOM_OOP_REF, T_OBJECT,
- value, Address(value, -JNIHandles::weak_tag_value), tmp, thread);
+ access_load_at(T_OBJECT, IN_ROOT | ON_PHANTOM_OOP_REF, value,
+ Address(value, -JNIHandles::weak_tag_value), tmp, thread);
verify_oop(value);
b(done);
bind(not_weak);
// Resolve (untagged) jobject.
- bs->load_at(this, IN_CONCURRENT_ROOT, T_OBJECT,
- value, Address(value, 0), tmp, thread);
+ access_load_at(T_OBJECT, IN_CONCURRENT_ROOT, value, Address(value, 0), tmp,
+ thread);
verify_oop(value);
bind(done);
}
@@ -3652,6 +3651,11 @@
cmp(src1, rscratch1);
}
+void MacroAssembler::cmpoop(Register obj1, Register obj2) {
+ BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
+ bs->obj_equals(this, obj1, obj2);
+}
+
void MacroAssembler::load_klass(Register dst, Register src) {
if (UseCompressedClassPointers) {
ldrw(dst, Address(src, oopDesc::klass_offset_in_bytes()));
@@ -3664,9 +3668,8 @@
// ((OopHandle)result).resolve();
void MacroAssembler::resolve_oop_handle(Register result, Register tmp) {
// OopHandle::resolve is an indirection.
- BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
- bs->load_at(this, IN_CONCURRENT_ROOT, T_OBJECT,
- result, Address(result, 0), tmp, rthread);
+ access_load_at(T_OBJECT, IN_CONCURRENT_ROOT,
+ result, Address(result, 0), tmp, noreg);
}
void MacroAssembler::load_mirror(Register dst, Register method, Register tmp) {
@@ -5050,6 +5053,8 @@
// a1 & a2 == 0 means (some-pointer is null) or
// (very-rare-or-even-probably-impossible-pointer-values)
// so, we can save one branch in most cases
+ cmpoop(a1, a2);
+ br(EQ, SAME);
eor(rscratch1, a1, a2);
tst(a1, a2);
mov(result, false);
@@ -5133,7 +5138,7 @@
// faster to perform another branch before comparing a1 and a2
cmp(cnt1, elem_per_word);
br(LE, SHORT); // short or same
- cmp(a1, a2);
+ cmpoop(a1, a2);
br(EQ, SAME);
ldr(tmp3, Address(pre(a1, base_offset)));
cmp(cnt1, stubBytesThreshold);
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -979,6 +979,8 @@
void addptr(const Address &dst, int32_t src);
void cmpptr(Register src1, Address src2);
+ void cmpoop(Register obj1, Register obj2);
+
// Various forms of CAS
void cmpxchg_obj_header(Register oldv, Register newv, Register obj, Register tmp,
--- a/src/hotspot/cpu/aarch64/methodHandles_aarch64.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/aarch64/methodHandles_aarch64.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -141,7 +141,7 @@
__ verify_oop(method_temp);
__ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes())), temp2);
__ verify_oop(method_temp);
- __ ldr(method_temp, Address(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes())));
+ __ access_load_at(T_ADDRESS, IN_HEAP, method_temp, Address(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes())), noreg, noreg);
if (VerifyMethodHandles && !for_compiler_entry) {
// make sure recv is already on stack
@@ -152,7 +152,7 @@
// assert(sizeof(u2) == sizeof(Method::_size_of_parameters), "");
Label L;
__ ldr(rscratch1, __ argument_address(temp2, -1));
- __ cmp(recv, rscratch1);
+ __ cmpoop(recv, rscratch1);
__ br(Assembler::EQ, L);
__ ldr(r0, __ argument_address(temp2, -1));
__ hlt(0);
@@ -340,7 +340,7 @@
verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3);
}
__ load_heap_oop(rmethod, member_vmtarget);
- __ ldr(rmethod, vmtarget_method);
+ __ access_load_at(T_ADDRESS, IN_HEAP, rmethod, vmtarget_method, noreg, noreg);
break;
case vmIntrinsics::_linkToStatic:
@@ -348,7 +348,7 @@
verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3);
}
__ load_heap_oop(rmethod, member_vmtarget);
- __ ldr(rmethod, vmtarget_method);
+ __ access_load_at(T_ADDRESS, IN_HEAP, rmethod, vmtarget_method, noreg, noreg);
break;
case vmIntrinsics::_linkToVirtual:
@@ -362,7 +362,7 @@
// pick out the vtable index from the MemberName, and then we can discard it:
Register temp2_index = temp2;
- __ ldr(temp2_index, member_vmindex);
+ __ access_load_at(T_ADDRESS, IN_HEAP, temp2_index, member_vmindex, noreg, noreg);
if (VerifyMethodHandles) {
Label L_index_ok;
@@ -394,7 +394,7 @@
__ verify_klass_ptr(temp3_intf);
Register rindex = rmethod;
- __ ldr(rindex, member_vmindex);
+ __ access_load_at(T_ADDRESS, IN_HEAP, rindex, member_vmindex, noreg, noreg);
if (VerifyMethodHandles) {
Label L;
__ cmpw(rindex, 0U);
--- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -760,8 +760,8 @@
// r0: array
// r1: index
index_check(r0, r1); // leaves index in r1, kills rscratch1
- __ lea(r1, Address(r0, r1, Address::uxtw(2)));
- __ ldrw(r0, Address(r1, arrayOopDesc::base_offset_in_bytes(T_INT)));
+ __ add(r1, r1, arrayOopDesc::base_offset_in_bytes(T_INT) >> 2);
+ __ access_load_at(T_INT, IN_HEAP | IN_HEAP_ARRAY, r0, Address(r0, r1, Address::uxtw(2)), noreg, noreg);
}
void TemplateTable::laload()
@@ -772,8 +772,8 @@
// r0: array
// r1: index
index_check(r0, r1); // leaves index in r1, kills rscratch1
- __ lea(r1, Address(r0, r1, Address::uxtw(3)));
- __ ldr(r0, Address(r1, arrayOopDesc::base_offset_in_bytes(T_LONG)));
+ __ add(r1, r1, arrayOopDesc::base_offset_in_bytes(T_LONG) >> 3);
+ __ access_load_at(T_LONG, IN_HEAP | IN_HEAP_ARRAY, r0, Address(r0, r1, Address::uxtw(3)), noreg, noreg);
}
void TemplateTable::faload()
@@ -784,8 +784,8 @@
// r0: array
// r1: index
index_check(r0, r1); // leaves index in r1, kills rscratch1
- __ lea(r1, Address(r0, r1, Address::uxtw(2)));
- __ ldrs(v0, Address(r1, arrayOopDesc::base_offset_in_bytes(T_FLOAT)));
+ __ add(r1, r1, arrayOopDesc::base_offset_in_bytes(T_FLOAT) >> 2);
+ __ access_load_at(T_FLOAT, IN_HEAP | IN_HEAP_ARRAY, r0, Address(r0, r1, Address::uxtw(2)), noreg, noreg);
}
void TemplateTable::daload()
@@ -796,8 +796,8 @@
// r0: array
// r1: index
index_check(r0, r1); // leaves index in r1, kills rscratch1
- __ lea(r1, Address(r0, r1, Address::uxtw(3)));
- __ ldrd(v0, Address(r1, arrayOopDesc::base_offset_in_bytes(T_DOUBLE)));
+ __ add(r1, r1, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) >> 3);
+ __ access_load_at(T_DOUBLE, IN_HEAP | IN_HEAP_ARRAY, r0, Address(r0, r1, Address::uxtw(3)), noreg, noreg);
}
void TemplateTable::aaload()
@@ -808,10 +808,9 @@
// r0: array
// r1: index
index_check(r0, r1); // leaves index in r1, kills rscratch1
- int s = (UseCompressedOops ? 2 : 3);
- __ lea(r1, Address(r0, r1, Address::uxtw(s)));
+ __ add(r1, r1, arrayOopDesc::base_offset_in_bytes(T_OBJECT) >> LogBytesPerHeapOop);
do_oop_load(_masm,
- Address(r1, arrayOopDesc::base_offset_in_bytes(T_OBJECT)),
+ Address(r0, r1, Address::uxtw(LogBytesPerHeapOop)),
r0,
IN_HEAP_ARRAY);
}
@@ -824,8 +823,8 @@
// r0: array
// r1: index
index_check(r0, r1); // leaves index in r1, kills rscratch1
- __ lea(r1, Address(r0, r1, Address::uxtw(0)));
- __ load_signed_byte(r0, Address(r1, arrayOopDesc::base_offset_in_bytes(T_BYTE)));
+ __ add(r1, r1, arrayOopDesc::base_offset_in_bytes(T_BYTE) >> 0);
+ __ access_load_at(T_BYTE, IN_HEAP | IN_HEAP_ARRAY, r0, Address(r0, r1, Address::uxtw(0)), noreg, noreg);
}
void TemplateTable::caload()
@@ -836,8 +835,8 @@
// r0: array
// r1: index
index_check(r0, r1); // leaves index in r1, kills rscratch1
- __ lea(r1, Address(r0, r1, Address::uxtw(1)));
- __ load_unsigned_short(r0, Address(r1, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
+ __ add(r1, r1, arrayOopDesc::base_offset_in_bytes(T_CHAR) >> 1);
+ __ access_load_at(T_CHAR, IN_HEAP | IN_HEAP_ARRAY, r0, Address(r0, r1, Address::uxtw(1)), noreg, noreg);
}
// iload followed by caload frequent pair
@@ -853,8 +852,8 @@
// r0: array
// r1: index
index_check(r0, r1); // leaves index in r1, kills rscratch1
- __ lea(r1, Address(r0, r1, Address::uxtw(1)));
- __ load_unsigned_short(r0, Address(r1, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
+ __ add(r1, r1, arrayOopDesc::base_offset_in_bytes(T_CHAR) >> 1);
+ __ access_load_at(T_CHAR, IN_HEAP | IN_HEAP_ARRAY, r0, Address(r0, r1, Address::uxtw(1)), noreg, noreg);
}
void TemplateTable::saload()
@@ -865,8 +864,8 @@
// r0: array
// r1: index
index_check(r0, r1); // leaves index in r1, kills rscratch1
- __ lea(r1, Address(r0, r1, Address::uxtw(1)));
- __ load_signed_short(r0, Address(r1, arrayOopDesc::base_offset_in_bytes(T_SHORT)));
+ __ add(r1, r1, arrayOopDesc::base_offset_in_bytes(T_SHORT) >> 1);
+ __ access_load_at(T_SHORT, IN_HEAP | IN_HEAP_ARRAY, r0, Address(r0, r1, Address::uxtw(1)), noreg, noreg);
}
void TemplateTable::iload(int n)
@@ -1059,9 +1058,8 @@
// r1: index
// r3: array
index_check(r3, r1); // prefer index in r1
- __ lea(rscratch1, Address(r3, r1, Address::uxtw(2)));
- __ strw(r0, Address(rscratch1,
- arrayOopDesc::base_offset_in_bytes(T_INT)));
+ __ add(r1, r1, arrayOopDesc::base_offset_in_bytes(T_INT) >> 2);
+ __ access_store_at(T_INT, IN_HEAP | IN_HEAP_ARRAY, Address(r3, r1, Address::uxtw(2)), r0, noreg, noreg);
}
void TemplateTable::lastore() {
@@ -1072,9 +1070,8 @@
// r1: index
// r3: array
index_check(r3, r1); // prefer index in r1
- __ lea(rscratch1, Address(r3, r1, Address::uxtw(3)));
- __ str(r0, Address(rscratch1,
- arrayOopDesc::base_offset_in_bytes(T_LONG)));
+ __ add(r1, r1, arrayOopDesc::base_offset_in_bytes(T_LONG) >> 3);
+ __ access_store_at(T_LONG, IN_HEAP | IN_HEAP_ARRAY, Address(r3, r1, Address::uxtw(3)), r0, noreg, noreg);
}
void TemplateTable::fastore() {
@@ -1085,9 +1082,8 @@
// r1: index
// r3: array
index_check(r3, r1); // prefer index in r1
- __ lea(rscratch1, Address(r3, r1, Address::uxtw(2)));
- __ strs(v0, Address(rscratch1,
- arrayOopDesc::base_offset_in_bytes(T_FLOAT)));
+ __ add(r1, r1, arrayOopDesc::base_offset_in_bytes(T_FLOAT) >> 2);
+ __ access_store_at(T_FLOAT, IN_HEAP | IN_HEAP_ARRAY, Address(r3, r1, Address::uxtw(2)), noreg /* ftos */, noreg, noreg);
}
void TemplateTable::dastore() {
@@ -1098,9 +1094,8 @@
// r1: index
// r3: array
index_check(r3, r1); // prefer index in r1
- __ lea(rscratch1, Address(r3, r1, Address::uxtw(3)));
- __ strd(v0, Address(rscratch1,
- arrayOopDesc::base_offset_in_bytes(T_DOUBLE)));
+ __ add(r1, r1, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) >> 3);
+ __ access_store_at(T_DOUBLE, IN_HEAP | IN_HEAP_ARRAY, Address(r3, r1, Address::uxtw(3)), noreg /* dtos */, noreg, noreg);
}
void TemplateTable::aastore() {
@@ -1111,10 +1106,10 @@
__ ldr(r2, at_tos_p1()); // index
__ ldr(r3, at_tos_p2()); // array
- Address element_address(r4, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
+ Address element_address(r3, r4, Address::uxtw(LogBytesPerHeapOop));
index_check(r3, r2); // kills r1
- __ lea(r4, Address(r3, r2, Address::uxtw(UseCompressedOops? 2 : 3)));
+ __ add(r4, r2, arrayOopDesc::base_offset_in_bytes(T_OBJECT) >> LogBytesPerHeapOop);
// do array store check - check for NULL value first
__ cbz(r0, is_null);
@@ -1176,9 +1171,8 @@
__ andw(r0, r0, 1); // if it is a T_BOOLEAN array, mask the stored value to 0/1
__ bind(L_skip);
- __ lea(rscratch1, Address(r3, r1, Address::uxtw(0)));
- __ strb(r0, Address(rscratch1,
- arrayOopDesc::base_offset_in_bytes(T_BYTE)));
+ __ add(r1, r1, arrayOopDesc::base_offset_in_bytes(T_BYTE) >> 0);
+ __ access_store_at(T_BYTE, IN_HEAP | IN_HEAP_ARRAY, Address(r3, r1, Address::uxtw(0)), r0, noreg, noreg);
}
void TemplateTable::castore()
@@ -1190,9 +1184,8 @@
// r1: index
// r3: array
index_check(r3, r1); // prefer index in r1
- __ lea(rscratch1, Address(r3, r1, Address::uxtw(1)));
- __ strh(r0, Address(rscratch1,
- arrayOopDesc::base_offset_in_bytes(T_CHAR)));
+ __ add(r1, r1, arrayOopDesc::base_offset_in_bytes(T_CHAR) >> 1);
+ __ access_store_at(T_CHAR, IN_HEAP | IN_HEAP_ARRAY, Address(r3, r1, Address::uxtw(1)), r0, noreg, noreg);
}
void TemplateTable::sastore()
@@ -2034,7 +2027,7 @@
// assume branch is more often taken than not (loops use backward branches)
Label not_taken;
__ pop_ptr(r1);
- __ cmp(r1, r0);
+ __ cmpoop(r1, r0);
__ br(j_not(cc), not_taken);
branch(false, false);
__ bind(not_taken);
@@ -2513,7 +2506,7 @@
if (is_static) rc = may_not_rewrite;
// btos
- __ load_signed_byte(r0, field);
+ __ access_load_at(T_BYTE, IN_HEAP, r0, field, noreg, noreg);
__ push(btos);
// Rewrite bytecode to be faster
if (rc == may_rewrite) {
@@ -2526,7 +2519,7 @@
__ br(Assembler::NE, notBool);
// ztos (same code as btos)
- __ ldrsb(r0, field);
+ __ access_load_at(T_BOOLEAN, IN_HEAP, r0, field, noreg, noreg);
__ push(ztos);
// Rewrite bytecode to be faster
if (rc == may_rewrite) {
@@ -2550,7 +2543,7 @@
__ cmp(flags, itos);
__ br(Assembler::NE, notInt);
// itos
- __ ldrw(r0, field);
+ __ access_load_at(T_INT, IN_HEAP, r0, field, noreg, noreg);
__ push(itos);
// Rewrite bytecode to be faster
if (rc == may_rewrite) {
@@ -2562,7 +2555,7 @@
__ cmp(flags, ctos);
__ br(Assembler::NE, notChar);
// ctos
- __ load_unsigned_short(r0, field);
+ __ access_load_at(T_CHAR, IN_HEAP, r0, field, noreg, noreg);
__ push(ctos);
// Rewrite bytecode to be faster
if (rc == may_rewrite) {
@@ -2574,7 +2567,7 @@
__ cmp(flags, stos);
__ br(Assembler::NE, notShort);
// stos
- __ load_signed_short(r0, field);
+ __ access_load_at(T_SHORT, IN_HEAP, r0, field, noreg, noreg);
__ push(stos);
// Rewrite bytecode to be faster
if (rc == may_rewrite) {
@@ -2586,7 +2579,7 @@
__ cmp(flags, ltos);
__ br(Assembler::NE, notLong);
// ltos
- __ ldr(r0, field);
+ __ access_load_at(T_LONG, IN_HEAP, r0, field, noreg, noreg);
__ push(ltos);
// Rewrite bytecode to be faster
if (rc == may_rewrite) {
@@ -2598,7 +2591,7 @@
__ cmp(flags, ftos);
__ br(Assembler::NE, notFloat);
// ftos
- __ ldrs(v0, field);
+ __ access_load_at(T_FLOAT, IN_HEAP, noreg /* ftos */, field, noreg, noreg);
__ push(ftos);
// Rewrite bytecode to be faster
if (rc == may_rewrite) {
@@ -2612,7 +2605,7 @@
__ br(Assembler::NE, notDouble);
#endif
// dtos
- __ ldrd(v0, field);
+ __ access_load_at(T_DOUBLE, IN_HEAP, noreg /* ftos */, field, noreg, noreg);
__ push(dtos);
// Rewrite bytecode to be faster
if (rc == may_rewrite) {
@@ -2750,7 +2743,7 @@
{
__ pop(btos);
if (!is_static) pop_and_check_object(obj);
- __ strb(r0, field);
+ __ access_store_at(T_BYTE, IN_HEAP, field, r0, noreg, noreg);
if (rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_bputfield, bc, r1, true, byte_no);
}
@@ -2765,8 +2758,7 @@
{
__ pop(ztos);
if (!is_static) pop_and_check_object(obj);
- __ andw(r0, r0, 0x1);
- __ strb(r0, field);
+ __ access_store_at(T_BOOLEAN, IN_HEAP, field, r0, noreg, noreg);
if (rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_zputfield, bc, r1, true, byte_no);
}
@@ -2797,7 +2789,7 @@
{
__ pop(itos);
if (!is_static) pop_and_check_object(obj);
- __ strw(r0, field);
+ __ access_store_at(T_INT, IN_HEAP, field, r0, noreg, noreg);
if (rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_iputfield, bc, r1, true, byte_no);
}
@@ -2812,7 +2804,7 @@
{
__ pop(ctos);
if (!is_static) pop_and_check_object(obj);
- __ strh(r0, field);
+ __ access_store_at(T_CHAR, IN_HEAP, field, r0, noreg, noreg);
if (rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_cputfield, bc, r1, true, byte_no);
}
@@ -2827,7 +2819,7 @@
{
__ pop(stos);
if (!is_static) pop_and_check_object(obj);
- __ strh(r0, field);
+ __ access_store_at(T_SHORT, IN_HEAP, field, r0, noreg, noreg);
if (rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_sputfield, bc, r1, true, byte_no);
}
@@ -2842,7 +2834,7 @@
{
__ pop(ltos);
if (!is_static) pop_and_check_object(obj);
- __ str(r0, field);
+ __ access_store_at(T_LONG, IN_HEAP, field, r0, noreg, noreg);
if (rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_lputfield, bc, r1, true, byte_no);
}
@@ -2857,7 +2849,7 @@
{
__ pop(ftos);
if (!is_static) pop_and_check_object(obj);
- __ strs(v0, field);
+ __ access_store_at(T_FLOAT, IN_HEAP, field, noreg /* ftos */, noreg, noreg);
if (rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_fputfield, bc, r1, true, byte_no);
}
@@ -2874,7 +2866,7 @@
{
__ pop(dtos);
if (!is_static) pop_and_check_object(obj);
- __ strd(v0, field);
+ __ access_store_at(T_DOUBLE, IN_HEAP, field, noreg /* dtos */, noreg, noreg);
if (rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_dputfield, bc, r1, true, byte_no);
}
@@ -3005,27 +2997,28 @@
do_oop_store(_masm, field, r0, IN_HEAP);
break;
case Bytecodes::_fast_lputfield:
- __ str(r0, field);
+ __ access_store_at(T_LONG, IN_HEAP, field, r0, noreg, noreg);
break;
case Bytecodes::_fast_iputfield:
- __ strw(r0, field);
+ __ access_store_at(T_INT, IN_HEAP, field, r0, noreg, noreg);
break;
case Bytecodes::_fast_zputfield:
- __ andw(r0, r0, 0x1); // boolean is true if LSB is 1
- // fall through to bputfield
+ __ access_store_at(T_BOOLEAN, IN_HEAP, field, r0, noreg, noreg);
+ break;
case Bytecodes::_fast_bputfield:
- __ strb(r0, field);
+ __ access_store_at(T_BYTE, IN_HEAP, field, r0, noreg, noreg);
break;
case Bytecodes::_fast_sputfield:
- // fall through
+ __ access_store_at(T_SHORT, IN_HEAP, field, r0, noreg, noreg);
+ break;
case Bytecodes::_fast_cputfield:
- __ strh(r0, field);
+ __ access_store_at(T_CHAR, IN_HEAP, field, r0, noreg, noreg);
break;
case Bytecodes::_fast_fputfield:
- __ strs(v0, field);
+ __ access_store_at(T_FLOAT, IN_HEAP, field, noreg /* ftos */, noreg, noreg);
break;
case Bytecodes::_fast_dputfield:
- __ strd(v0, field);
+ __ access_store_at(T_DOUBLE, IN_HEAP, field, noreg /* dtos */, noreg, noreg);
break;
default:
ShouldNotReachHere();
@@ -3098,25 +3091,25 @@
__ verify_oop(r0);
break;
case Bytecodes::_fast_lgetfield:
- __ ldr(r0, field);
+ __ access_load_at(T_LONG, IN_HEAP, r0, field, noreg, noreg);
break;
case Bytecodes::_fast_igetfield:
- __ ldrw(r0, field);
+ __ access_load_at(T_INT, IN_HEAP, r0, field, noreg, noreg);
break;
case Bytecodes::_fast_bgetfield:
- __ load_signed_byte(r0, field);
+ __ access_load_at(T_BYTE, IN_HEAP, r0, field, noreg, noreg);
break;
case Bytecodes::_fast_sgetfield:
- __ load_signed_short(r0, field);
+ __ access_load_at(T_SHORT, IN_HEAP, r0, field, noreg, noreg);
break;
case Bytecodes::_fast_cgetfield:
- __ load_unsigned_short(r0, field);
+ __ access_load_at(T_CHAR, IN_HEAP, r0, field, noreg, noreg);
break;
case Bytecodes::_fast_fgetfield:
- __ ldrs(v0, field);
+ __ access_load_at(T_FLOAT, IN_HEAP, noreg /* ftos */, field, noreg, noreg);
break;
case Bytecodes::_fast_dgetfield:
- __ ldrd(v0, field);
+ __ access_load_at(T_DOUBLE, IN_HEAP, noreg /* dtos */, field, noreg, noreg);
break;
default:
ShouldNotReachHere();
@@ -3161,14 +3154,14 @@
__ null_check(r0);
switch (state) {
case itos:
- __ ldrw(r0, Address(r0, r1, Address::lsl(0)));
+ __ access_load_at(T_INT, IN_HEAP, r0, Address(r0, r1, Address::lsl(0)), noreg, noreg);
break;
case atos:
do_oop_load(_masm, Address(r0, r1, Address::lsl(0)), r0, IN_HEAP);
__ verify_oop(r0);
break;
case ftos:
- __ ldrs(v0, Address(r0, r1, Address::lsl(0)));
+ __ access_load_at(T_FLOAT, IN_HEAP, noreg /* ftos */, Address(r0, r1, Address::lsl(0)), noreg, noreg);
break;
default:
ShouldNotReachHere();
--- a/src/hotspot/cpu/arm/macroAssembler_arm.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/arm/macroAssembler_arm.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -1367,9 +1367,12 @@
// Bump total bytes allocated by this thread
Label done;
- ldr(tmp, Address(Rthread, in_bytes(JavaThread::allocated_bytes_offset())));
+ // Borrow the Rthread for alloc counter
+ Register Ralloc = Rthread;
+ add(Ralloc, Ralloc, in_bytes(JavaThread::allocated_bytes_offset()));
+ ldr(tmp, Address(Ralloc));
adds(tmp, tmp, size_in_bytes);
- str(tmp, Address(Rthread, in_bytes(JavaThread::allocated_bytes_offset())), cc);
+ str(tmp, Address(Ralloc), cc);
b(done, cc);
// Increment the high word and store single-copy atomically (that is an unlikely scenario on typical embedded systems as it means >4GB has been allocated)
@@ -1387,14 +1390,17 @@
}
push(RegisterSet(low, high));
- ldrd(low, Address(Rthread, in_bytes(JavaThread::allocated_bytes_offset())));
+ ldrd(low, Address(Ralloc));
adds(low, low, size_in_bytes);
adc(high, high, 0);
- strd(low, Address(Rthread, in_bytes(JavaThread::allocated_bytes_offset())));
+ strd(low, Address(Ralloc));
pop(RegisterSet(low, high));
bind(done);
+
+ // Unborrow the Rthread
+ sub(Rthread, Ralloc, in_bytes(JavaThread::allocated_bytes_offset()));
#endif // AARCH64
}
--- a/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -3202,23 +3202,38 @@
const Register dest_reg = dest->as_pointer_register();
const Register base_reg = addr->base()->as_pointer_register();
- if (Assembler::is_simm13(addr->disp())) {
- if (addr->index()->is_valid()) {
- const Register index_reg = addr->index()->as_pointer_register();
- assert(index_reg != G3_scratch, "invariant");
- __ add(base_reg, addr->disp(), G3_scratch);
- __ add(index_reg, G3_scratch, dest_reg);
- } else {
- __ add(base_reg, addr->disp(), dest_reg);
- }
- } else {
- __ set(addr->disp(), G3_scratch);
+ if (patch_code != lir_patch_none) {
+ PatchingStub* patch = new PatchingStub(_masm, PatchingStub::access_field_id);
+ assert(addr->disp() != 0, "must have");
+ assert(base_reg != G3_scratch, "invariant");
+ __ patchable_set(0, G3_scratch);
+ patching_epilog(patch, patch_code, base_reg, info);
+ assert(dest_reg != G3_scratch, "invariant");
if (addr->index()->is_valid()) {
const Register index_reg = addr->index()->as_pointer_register();
assert(index_reg != G3_scratch, "invariant");
__ add(index_reg, G3_scratch, G3_scratch);
}
__ add(base_reg, G3_scratch, dest_reg);
+ } else {
+ if (Assembler::is_simm13(addr->disp())) {
+ if (addr->index()->is_valid()) {
+ const Register index_reg = addr->index()->as_pointer_register();
+ assert(index_reg != G3_scratch, "invariant");
+ __ add(base_reg, addr->disp(), G3_scratch);
+ __ add(index_reg, G3_scratch, dest_reg);
+ } else {
+ __ add(base_reg, addr->disp(), dest_reg);
+ }
+ } else {
+ __ set(addr->disp(), G3_scratch);
+ if (addr->index()->is_valid()) {
+ const Register index_reg = addr->index()->as_pointer_register();
+ assert(index_reg != G3_scratch, "invariant");
+ __ add(index_reg, G3_scratch, G3_scratch);
+ }
+ __ add(base_reg, G3_scratch, dest_reg);
+ }
}
}
--- a/src/hotspot/cpu/sparc/vm_version_ext_sparc.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/sparc/vm_version_ext_sparc.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -31,10 +31,13 @@
int VM_Version_Ext::_no_of_threads = 0;
int VM_Version_Ext::_no_of_cores = 0;
int VM_Version_Ext::_no_of_sockets = 0;
+#if defined(SOLARIS)
kid_t VM_Version_Ext::_kcid = -1;
+#endif
char VM_Version_Ext::_cpu_name[CPU_TYPE_DESC_BUF_SIZE] = {0};
char VM_Version_Ext::_cpu_desc[CPU_DETAILED_DESC_BUF_SIZE] = {0};
+#if defined(SOLARIS)
// get cpu information. It takes into account if the kstat chain id
// has been changed and update the info if necessary.
bool VM_Version_Ext::initialize_cpu_information(void) {
@@ -144,6 +147,13 @@
kstat_close(kc);
return true;
}
+#elif defined(LINUX)
+// get cpu information.
+bool VM_Version_Ext::initialize_cpu_information(void) {
+ // Not yet implemented.
+ return false;
+}
+#endif
int VM_Version_Ext::number_of_threads(void) {
initialize_cpu_information();
--- a/src/hotspot/cpu/sparc/vm_version_ext_sparc.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/sparc/vm_version_ext_sparc.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -27,8 +27,11 @@
#include "utilities/macros.hpp"
#include "vm_version_sparc.hpp"
+
+#if defined(SOLARIS)
#include <kstat.h>
#include <sys/processor.h>
+#endif
#define CPU_INFO "cpu_info"
#define CPU_TYPE "fpu_type"
@@ -45,7 +48,9 @@
static int _no_of_threads;
static int _no_of_cores;
static int _no_of_sockets;
+#if defined(SOLARIS)
static kid_t _kcid;
+#endif
static char _cpu_name[CPU_TYPE_DESC_BUF_SIZE];
static char _cpu_desc[CPU_DETAILED_DESC_BUF_SIZE];
--- a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -1346,7 +1346,11 @@
__ decode_heap_oop(dest->as_register());
}
#endif
- __ verify_oop(dest->as_register());
+
+ // Load barrier has not yet been applied, so ZGC can't verify the oop here
+ if (!UseZGC) {
+ __ verify_oop(dest->as_register());
+ }
} else if (type == T_ADDRESS && addr->disp() == oopDesc::klass_offset_in_bytes()) {
#ifdef _LP64
if (UseCompressedClassPointers) {
--- a/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -187,6 +187,27 @@
}
}
+#ifndef _LP64
+void BarrierSetAssembler::obj_equals(MacroAssembler* masm,
+ Address obj1, jobject obj2) {
+ __ cmpoop_raw(obj1, obj2);
+}
+
+void BarrierSetAssembler::obj_equals(MacroAssembler* masm,
+ Register obj1, jobject obj2) {
+ __ cmpoop_raw(obj1, obj2);
+}
+#endif
+void BarrierSetAssembler::obj_equals(MacroAssembler* masm,
+ Register obj1, Address obj2) {
+ __ cmpptr(obj1, obj2);
+}
+
+void BarrierSetAssembler::obj_equals(MacroAssembler* masm,
+ Register obj1, Register obj2) {
+ __ cmpptr(obj1, obj2);
+}
+
void BarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
Register obj, Register tmp, Label& slowpath) {
__ clear_jweak_tag(obj);
--- a/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -44,6 +44,18 @@
virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
Address dst, Register val, Register tmp1, Register tmp2);
+#ifndef _LP64
+ virtual void obj_equals(MacroAssembler* masm,
+ Address obj1, jobject obj2);
+ virtual void obj_equals(MacroAssembler* masm,
+ Register obj1, jobject obj2);
+#endif
+
+ virtual void obj_equals(MacroAssembler* masm,
+ Register obj1, Register obj2);
+ virtual void obj_equals(MacroAssembler* masm,
+ Register obj1, Address obj2);
+
// Support for jniFastGetField to try resolving a jobject/jweak in native
virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
Register obj, Register tmp, Label& slowpath);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,458 @@
+/*
+ * 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 "asm/macroAssembler.inline.hpp"
+#include "gc/z/zBarrier.inline.hpp"
+#include "gc/z/zBarrierSet.hpp"
+#include "gc/z/zBarrierSetAssembler.hpp"
+#include "gc/z/zBarrierSetRuntime.hpp"
+#include "runtime/stubCodeGenerator.hpp"
+#include "utilities/macros.hpp"
+#ifdef COMPILER1
+#include "c1/c1_LIRAssembler.hpp"
+#include "c1/c1_MacroAssembler.hpp"
+#include "gc/z/c1/zBarrierSetC1.hpp"
+#endif // COMPILER1
+
+#undef __
+#define __ masm->
+
+#ifdef PRODUCT
+#define BLOCK_COMMENT(str) /* nothing */
+#else
+#define BLOCK_COMMENT(str) __ block_comment(str)
+#endif
+
+static void call_vm(MacroAssembler* masm,
+ address entry_point,
+ Register arg0,
+ Register arg1) {
+ // Setup arguments
+ if (arg1 == c_rarg0) {
+ if (arg0 == c_rarg1) {
+ __ xchgptr(c_rarg1, c_rarg0);
+ } else {
+ __ movptr(c_rarg1, arg1);
+ __ movptr(c_rarg0, arg0);
+ }
+ } else {
+ if (arg0 != c_rarg0) {
+ __ movptr(c_rarg0, arg0);
+ }
+ if (arg1 != c_rarg1) {
+ __ movptr(c_rarg1, arg1);
+ }
+ }
+
+ // Call VM
+ __ MacroAssembler::call_VM_leaf_base(entry_point, 2);
+}
+
+void ZBarrierSetAssembler::load_at(MacroAssembler* masm,
+ DecoratorSet decorators,
+ BasicType type,
+ Register dst,
+ Address src,
+ Register tmp1,
+ Register tmp_thread) {
+ if (!ZBarrierSet::barrier_needed(decorators, type)) {
+ // Barrier not needed
+ BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
+ return;
+ }
+
+ BLOCK_COMMENT("ZBarrierSetAssembler::load_at {");
+
+ // Allocate scratch register
+ Register scratch = tmp1;
+ if (tmp1 == noreg) {
+ scratch = r12;
+ __ push(scratch);
+ }
+
+ assert_different_registers(dst, scratch);
+
+ Label done;
+
+ //
+ // Fast Path
+ //
+
+ // Load address
+ __ lea(scratch, src);
+
+ // Load oop at address
+ __ movptr(dst, Address(scratch, 0));
+
+ // Test address bad mask
+ __ testptr(dst, address_bad_mask_from_thread(r15_thread));
+ __ jcc(Assembler::zero, done);
+
+ //
+ // Slow path
+ //
+
+ // Save registers
+ __ push(rax);
+ __ push(rcx);
+ __ push(rdx);
+ __ push(rdi);
+ __ push(rsi);
+ __ push(r8);
+ __ push(r9);
+ __ push(r10);
+ __ push(r11);
+
+ // We may end up here from generate_native_wrapper, then the method may have
+ // floats as arguments, and we must spill them before calling the VM runtime
+ // leaf. From the interpreter all floats are passed on the stack.
+ assert(Argument::n_float_register_parameters_j == 8, "Assumption");
+ const int xmm_size = wordSize * 2;
+ const int xmm_spill_size = xmm_size * Argument::n_float_register_parameters_j;
+ __ subptr(rsp, xmm_spill_size);
+ __ movdqu(Address(rsp, xmm_size * 7), xmm7);
+ __ movdqu(Address(rsp, xmm_size * 6), xmm6);
+ __ movdqu(Address(rsp, xmm_size * 5), xmm5);
+ __ movdqu(Address(rsp, xmm_size * 4), xmm4);
+ __ movdqu(Address(rsp, xmm_size * 3), xmm3);
+ __ movdqu(Address(rsp, xmm_size * 2), xmm2);
+ __ movdqu(Address(rsp, xmm_size * 1), xmm1);
+ __ movdqu(Address(rsp, xmm_size * 0), xmm0);
+
+ // Call VM
+ call_vm(masm, ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(decorators), dst, scratch);
+
+ // Restore registers
+ __ movdqu(xmm0, Address(rsp, xmm_size * 0));
+ __ movdqu(xmm1, Address(rsp, xmm_size * 1));
+ __ movdqu(xmm2, Address(rsp, xmm_size * 2));
+ __ movdqu(xmm3, Address(rsp, xmm_size * 3));
+ __ movdqu(xmm4, Address(rsp, xmm_size * 4));
+ __ movdqu(xmm5, Address(rsp, xmm_size * 5));
+ __ movdqu(xmm6, Address(rsp, xmm_size * 6));
+ __ movdqu(xmm7, Address(rsp, xmm_size * 7));
+ __ addptr(rsp, xmm_spill_size);
+
+ __ pop(r11);
+ __ pop(r10);
+ __ pop(r9);
+ __ pop(r8);
+ __ pop(rsi);
+ __ pop(rdi);
+ __ pop(rdx);
+ __ pop(rcx);
+
+ if (dst == rax) {
+ __ addptr(rsp, wordSize);
+ } else {
+ __ movptr(dst, rax);
+ __ pop(rax);
+ }
+
+ __ bind(done);
+
+ // Restore scratch register
+ if (tmp1 == noreg) {
+ __ pop(scratch);
+ }
+
+ BLOCK_COMMENT("} ZBarrierSetAssembler::load_at");
+}
+
+#ifdef ASSERT
+
+void ZBarrierSetAssembler::store_at(MacroAssembler* masm,
+ DecoratorSet decorators,
+ BasicType type,
+ Address dst,
+ Register src,
+ Register tmp1,
+ Register tmp2) {
+ BLOCK_COMMENT("ZBarrierSetAssembler::store_at {");
+
+ // Verify oop store
+ if (type == T_OBJECT || type == T_ARRAY) {
+ // Note that src could be noreg, which means we
+ // are storing null and can skip verification.
+ if (src != noreg) {
+ Label done;
+ __ testptr(src, address_bad_mask_from_thread(r15_thread));
+ __ jcc(Assembler::zero, done);
+ __ stop("Verify oop store failed");
+ __ should_not_reach_here();
+ __ bind(done);
+ }
+ }
+
+ // Store value
+ BarrierSetAssembler::store_at(masm, decorators, type, dst, src, tmp1, tmp2);
+
+ BLOCK_COMMENT("} ZBarrierSetAssembler::store_at");
+}
+
+#endif // ASSERT
+
+void ZBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm,
+ DecoratorSet decorators,
+ BasicType type,
+ Register src,
+ Register dst,
+ Register count) {
+ if (!ZBarrierSet::barrier_needed(decorators, type)) {
+ // Barrier not needed
+ return;
+ }
+
+ BLOCK_COMMENT("ZBarrierSetAssembler::arraycopy_prologue {");
+
+ // Save registers
+ __ pusha();
+
+ // Call VM
+ call_vm(masm, ZBarrierSetRuntime::load_barrier_on_oop_array_addr(), src, count);
+
+ // Restore registers
+ __ popa();
+
+ BLOCK_COMMENT("} ZBarrierSetAssembler::arraycopy_prologue");
+}
+
+void ZBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm,
+ Register jni_env,
+ Register obj,
+ Register tmp,
+ Label& slowpath) {
+ BLOCK_COMMENT("ZBarrierSetAssembler::try_resolve_jobject_in_native {");
+
+ // Resolve jobject
+ BarrierSetAssembler::try_resolve_jobject_in_native(masm, jni_env, obj, tmp, slowpath);
+
+ // Test address bad mask
+ __ testptr(obj, address_bad_mask_from_jni_env(jni_env));
+ __ jcc(Assembler::notZero, slowpath);
+
+ BLOCK_COMMENT("} ZBarrierSetAssembler::try_resolve_jobject_in_native");
+}
+
+#ifdef COMPILER1
+
+#undef __
+#define __ ce->masm()->
+
+void ZBarrierSetAssembler::generate_c1_load_barrier_test(LIR_Assembler* ce,
+ LIR_Opr ref) const {
+ __ testptr(ref->as_register(), address_bad_mask_from_thread(r15_thread));
+}
+
+void ZBarrierSetAssembler::generate_c1_load_barrier_stub(LIR_Assembler* ce,
+ ZLoadBarrierStubC1* stub) const {
+ // Stub entry
+ __ bind(*stub->entry());
+
+ Register ref = stub->ref()->as_register();
+ Register ref_addr = noreg;
+
+ if (stub->ref_addr()->is_register()) {
+ // Address already in register
+ ref_addr = stub->ref_addr()->as_pointer_register();
+ } else {
+ // Load address into tmp register
+ ce->leal(stub->ref_addr(), stub->tmp(), stub->patch_code(), stub->patch_info());
+ ref_addr = stub->tmp()->as_pointer_register();
+ }
+
+ assert_different_registers(ref, ref_addr, noreg);
+
+ // Save rax unless it is the result register
+ if (ref != rax) {
+ __ push(rax);
+ }
+
+ // Setup arguments and call runtime stub
+ __ subptr(rsp, 2 * BytesPerWord);
+ ce->store_parameter(ref_addr, 1);
+ ce->store_parameter(ref, 0);
+ __ call(RuntimeAddress(stub->runtime_stub()));
+ __ addptr(rsp, 2 * BytesPerWord);
+
+ // Verify result
+ __ verify_oop(rax, "Bad oop");
+
+ // Restore rax unless it is the result register
+ if (ref != rax) {
+ __ movptr(ref, rax);
+ __ pop(rax);
+ }
+
+ // Stub exit
+ __ jmp(*stub->continuation());
+}
+
+#undef __
+#define __ sasm->
+
+void ZBarrierSetAssembler::generate_c1_load_barrier_runtime_stub(StubAssembler* sasm,
+ DecoratorSet decorators) const {
+ // Enter and save registers
+ __ enter();
+ __ save_live_registers_no_oop_map(true /* save_fpu_registers */);
+
+ // Setup arguments
+ __ load_parameter(1, c_rarg1);
+ __ load_parameter(0, c_rarg0);
+
+ // Call VM
+ __ call_VM_leaf(ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(decorators), c_rarg0, c_rarg1);
+
+ // Restore registers and return
+ __ restore_live_registers_except_rax(true /* restore_fpu_registers */);
+ __ leave();
+ __ ret(0);
+}
+
+#endif // COMPILER1
+
+#undef __
+#define __ cgen->assembler()->
+
+// Generates a register specific stub for calling
+// ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded() or
+// ZBarrierSetRuntime::load_barrier_on_weak_oop_field_preloaded().
+//
+// The raddr register serves as both input and output for this stub. When the stub is
+// called the raddr register contains the object field address (oop*) where the bad oop
+// was loaded from, which caused the slow path to be taken. On return from the stub the
+// raddr register contains the good/healed oop returned from
+// ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded() or
+// ZBarrierSetRuntime::load_barrier_on_weak_oop_field_preloaded().
+static address generate_load_barrier_stub(StubCodeGenerator* cgen, Register raddr, DecoratorSet decorators) {
+ // Don't generate stub for invalid registers
+ if (raddr == rsp || raddr == r12 || raddr == r15) {
+ return NULL;
+ }
+
+ // Create stub name
+ char name[64];
+ const bool weak = (decorators & ON_WEAK_OOP_REF) != 0;
+ os::snprintf(name, sizeof(name), "load_barrier%s_stub_%s", weak ? "_weak" : "", raddr->name());
+
+ __ align(CodeEntryAlignment);
+ StubCodeMark mark(cgen, "StubRoutines", os::strdup(name, mtCode));
+ address start = __ pc();
+
+ // Save live registers
+ if (raddr != rax) {
+ __ push(rax);
+ }
+ if (raddr != rcx) {
+ __ push(rcx);
+ }
+ if (raddr != rdx) {
+ __ push(rdx);
+ }
+ if (raddr != rsi) {
+ __ push(rsi);
+ }
+ if (raddr != rdi) {
+ __ push(rdi);
+ }
+ if (raddr != r8) {
+ __ push(r8);
+ }
+ if (raddr != r9) {
+ __ push(r9);
+ }
+ if (raddr != r10) {
+ __ push(r10);
+ }
+ if (raddr != r11) {
+ __ push(r11);
+ }
+
+ // Setup arguments
+ if (c_rarg1 != raddr) {
+ __ movq(c_rarg1, raddr);
+ }
+ __ movq(c_rarg0, Address(raddr, 0));
+
+ // Call barrier function
+ __ call_VM_leaf(ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(decorators), c_rarg0, c_rarg1);
+
+ // Move result returned in rax to raddr, if needed
+ if (raddr != rax) {
+ __ movq(raddr, rax);
+ }
+
+ // Restore saved registers
+ if (raddr != r11) {
+ __ pop(r11);
+ }
+ if (raddr != r10) {
+ __ pop(r10);
+ }
+ if (raddr != r9) {
+ __ pop(r9);
+ }
+ if (raddr != r8) {
+ __ pop(r8);
+ }
+ if (raddr != rdi) {
+ __ pop(rdi);
+ }
+ if (raddr != rsi) {
+ __ pop(rsi);
+ }
+ if (raddr != rdx) {
+ __ pop(rdx);
+ }
+ if (raddr != rcx) {
+ __ pop(rcx);
+ }
+ if (raddr != rax) {
+ __ pop(rax);
+ }
+
+ __ ret(0);
+
+ return start;
+}
+
+#undef __
+
+void ZBarrierSetAssembler::barrier_stubs_init() {
+ // Load barrier stubs
+ int stub_code_size = 256 * 16; // Rough estimate of code size
+
+ ResourceMark rm;
+ BufferBlob* bb = BufferBlob::create("zgc_load_barrier_stubs", stub_code_size);
+ CodeBuffer buf(bb);
+ StubCodeGenerator cgen(&buf);
+
+ Register rr = as_Register(0);
+ for (int i = 0; i < RegisterImpl::number_of_registers; i++) {
+ _load_barrier_slow_stub[i] = generate_load_barrier_stub(&cgen, rr, ON_STRONG_OOP_REF);
+ _load_barrier_weak_slow_stub[i] = generate_load_barrier_stub(&cgen, rr, ON_WEAK_OOP_REF);
+ rr = rr->successor();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,92 @@
+/*
+ * 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 CPU_X86_GC_Z_ZBARRIERSETASSEMBLER_X86_HPP
+#define CPU_X86_GC_Z_ZBARRIERSETASSEMBLER_X86_HPP
+
+#ifdef COMPILER1
+class LIR_Assembler;
+class LIR_OprDesc;
+typedef LIR_OprDesc* LIR_Opr;
+class StubAssembler;
+class ZLoadBarrierStubC1;
+#endif // COMPILER1
+
+class ZBarrierSetAssembler : public ZBarrierSetAssemblerBase {
+ address _load_barrier_slow_stub[RegisterImpl::number_of_registers];
+ address _load_barrier_weak_slow_stub[RegisterImpl::number_of_registers];
+
+public:
+ ZBarrierSetAssembler() :
+ _load_barrier_slow_stub(),
+ _load_barrier_weak_slow_stub() {}
+
+ address load_barrier_slow_stub(Register reg) { return _load_barrier_slow_stub[reg->encoding()]; }
+ address load_barrier_weak_slow_stub(Register reg) { return _load_barrier_weak_slow_stub[reg->encoding()]; }
+
+ virtual void load_at(MacroAssembler* masm,
+ DecoratorSet decorators,
+ BasicType type,
+ Register dst,
+ Address src,
+ Register tmp1,
+ Register tmp_thread);
+
+#ifdef ASSERT
+ virtual void store_at(MacroAssembler* masm,
+ DecoratorSet decorators,
+ BasicType type,
+ Address dst,
+ Register src,
+ Register tmp1,
+ Register tmp2);
+#endif // ASSERT
+
+ virtual void arraycopy_prologue(MacroAssembler* masm,
+ DecoratorSet decorators,
+ BasicType type,
+ Register src,
+ Register dst,
+ Register count);
+
+ virtual void try_resolve_jobject_in_native(MacroAssembler* masm,
+ Register jni_env,
+ Register obj,
+ Register tmp,
+ Label& slowpath);
+
+#ifdef COMPILER1
+ void generate_c1_load_barrier_test(LIR_Assembler* ce,
+ LIR_Opr ref) const;
+
+ void generate_c1_load_barrier_stub(LIR_Assembler* ce,
+ ZLoadBarrierStubC1* stub) const;
+
+ void generate_c1_load_barrier_runtime_stub(StubAssembler* sasm,
+ DecoratorSet decorators) const;
+#endif // COMPILER1
+
+ virtual void barrier_stubs_init();
+};
+
+#endif // CPU_X86_GC_Z_ZBARRIERSETASSEMBLER_X86_HPP
--- a/src/hotspot/cpu/x86/globals_x86.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/x86/globals_x86.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -150,6 +150,9 @@
product(bool, UseUnalignedLoadStores, false, \
"Use SSE2 MOVDQU instruction for Arraycopy") \
\
+ product(bool, UseXMMForObjInit, false, \
+ "Use XMM/YMM MOVDQU instruction for Object Initialization") \
+ \
product(bool, UseFastStosb, false, \
"Use fast-string operation for zeroing: rep stosb") \
\
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -118,12 +118,22 @@
cmp_literal32(src1, (int32_t)obj, metadata_Relocation::spec_for_immediate());
}
+void MacroAssembler::cmpoop_raw(Address src1, jobject obj) {
+ cmp_literal32(src1, (int32_t)obj, oop_Relocation::spec_for_immediate());
+}
+
+void MacroAssembler::cmpoop_raw(Register src1, jobject obj) {
+ cmp_literal32(src1, (int32_t)obj, oop_Relocation::spec_for_immediate());
+}
+
void MacroAssembler::cmpoop(Address src1, jobject obj) {
- cmp_literal32(src1, (int32_t)obj, oop_Relocation::spec_for_immediate());
+ BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
+ bs->obj_equals(this, src1, obj);
}
void MacroAssembler::cmpoop(Register src1, jobject obj) {
- cmp_literal32(src1, (int32_t)obj, oop_Relocation::spec_for_immediate());
+ BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
+ bs->obj_equals(this, src1, obj);
}
void MacroAssembler::extend_sign(Register hi, Register lo) {
@@ -2785,17 +2795,20 @@
}
void MacroAssembler::cmpoop(Register src1, Register src2) {
- cmpptr(src1, src2);
+ BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
+ bs->obj_equals(this, src1, src2);
}
void MacroAssembler::cmpoop(Register src1, Address src2) {
- cmpptr(src1, src2);
+ BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
+ bs->obj_equals(this, src1, src2);
}
#ifdef _LP64
void MacroAssembler::cmpoop(Register src1, jobject src2) {
movoop(rscratch1, src2);
- cmpptr(src1, rscratch1);
+ BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
+ bs->obj_equals(this, src1, rscratch1);
}
#endif
@@ -6777,7 +6790,59 @@
}
-void MacroAssembler::clear_mem(Register base, Register cnt, Register tmp, bool is_large) {
+// clear memory of size 'cnt' qwords, starting at 'base' using XMM/YMM registers
+void MacroAssembler::xmm_clear_mem(Register base, Register cnt, XMMRegister xtmp) {
+ // cnt - number of qwords (8-byte words).
+ // base - start address, qword aligned.
+ Label L_zero_64_bytes, L_loop, L_sloop, L_tail, L_end;
+ if (UseAVX >= 2) {
+ vpxor(xtmp, xtmp, xtmp, AVX_256bit);
+ } else {
+ pxor(xtmp, xtmp);
+ }
+ jmp(L_zero_64_bytes);
+
+ BIND(L_loop);
+ if (UseAVX >= 2) {
+ vmovdqu(Address(base, 0), xtmp);
+ vmovdqu(Address(base, 32), xtmp);
+ } else {
+ movdqu(Address(base, 0), xtmp);
+ movdqu(Address(base, 16), xtmp);
+ movdqu(Address(base, 32), xtmp);
+ movdqu(Address(base, 48), xtmp);
+ }
+ addptr(base, 64);
+
+ BIND(L_zero_64_bytes);
+ subptr(cnt, 8);
+ jccb(Assembler::greaterEqual, L_loop);
+ addptr(cnt, 4);
+ jccb(Assembler::less, L_tail);
+ // Copy trailing 32 bytes
+ if (UseAVX >= 2) {
+ vmovdqu(Address(base, 0), xtmp);
+ } else {
+ movdqu(Address(base, 0), xtmp);
+ movdqu(Address(base, 16), xtmp);
+ }
+ addptr(base, 32);
+ subptr(cnt, 4);
+
+ BIND(L_tail);
+ addptr(cnt, 4);
+ jccb(Assembler::lessEqual, L_end);
+ decrement(cnt);
+
+ BIND(L_sloop);
+ movq(Address(base, 0), xtmp);
+ addptr(base, 8);
+ decrement(cnt);
+ jccb(Assembler::greaterEqual, L_sloop);
+ BIND(L_end);
+}
+
+void MacroAssembler::clear_mem(Register base, Register cnt, Register tmp, XMMRegister xtmp, bool is_large) {
// cnt - number of qwords (8-byte words).
// base - start address, qword aligned.
// is_large - if optimizers know cnt is larger than InitArrayShortSize
@@ -6789,7 +6854,9 @@
Label DONE;
- xorptr(tmp, tmp);
+ if (!is_large || !UseXMMForObjInit) {
+ xorptr(tmp, tmp);
+ }
if (!is_large) {
Label LOOP, LONG;
@@ -6815,6 +6882,9 @@
if (UseFastStosb) {
shlptr(cnt, 3); // convert to number of bytes
rep_stosb();
+ } else if (UseXMMForObjInit) {
+ movptr(tmp, base);
+ xmm_clear_mem(tmp, cnt, xtmp);
} else {
NOT_LP64(shlptr(cnt, 1);) // convert to number of 32-bit words for 32-bit VM
rep_stos();
--- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -741,11 +741,13 @@
void cmpklass(Address dst, Metadata* obj);
void cmpklass(Register dst, Metadata* obj);
void cmpoop(Address dst, jobject obj);
+ void cmpoop_raw(Address dst, jobject obj);
#endif // _LP64
void cmpoop(Register src1, Register src2);
void cmpoop(Register src1, Address src2);
void cmpoop(Register dst, jobject obj);
+ void cmpoop_raw(Register dst, jobject obj);
// NOTE src2 must be the lval. This is NOT an mem-mem compare
void cmpptr(Address src1, AddressLiteral src2);
@@ -1578,7 +1580,10 @@
// clear memory of size 'cnt' qwords, starting at 'base';
// if 'is_large' is set, do not try to produce short loop
- void clear_mem(Register base, Register cnt, Register rtmp, bool is_large);
+ void clear_mem(Register base, Register cnt, Register rtmp, XMMRegister xtmp, bool is_large);
+
+ // clear memory of size 'cnt' qwords, starting at 'base' using XMM/YMM registers
+ void xmm_clear_mem(Register base, Register cnt, XMMRegister xtmp);
#ifdef COMPILER2
void string_indexof_char(Register str1, Register cnt1, Register ch, Register result,
--- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -44,6 +44,9 @@
#ifdef COMPILER2
#include "opto/runtime.hpp"
#endif
+#if INCLUDE_ZGC
+#include "gc/z/zThreadLocalData.hpp"
+#endif
// Declaration and definition of StubGenerator (no .hpp file).
// For a more detailed description of the stub routine structure
@@ -1026,6 +1029,15 @@
// make sure object is 'reasonable'
__ testptr(rax, rax);
__ jcc(Assembler::zero, exit); // if obj is NULL it is OK
+
+#if INCLUDE_ZGC
+ if (UseZGC) {
+ // Check if metadata bits indicate a bad oop
+ __ testptr(rax, Address(r15_thread, ZThreadLocalData::address_bad_mask_offset()));
+ __ jcc(Assembler::notZero, error);
+ }
+#endif
+
// Check if the oop is in the right area of memory
__ movptr(c_rarg2, rax);
__ movptr(c_rarg3, (intptr_t) Universe::verify_oop_mask());
--- a/src/hotspot/cpu/x86/vm_version_x86.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/x86/vm_version_x86.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -1396,6 +1396,16 @@
FLAG_SET_DEFAULT(UseFastStosb, false);
}
+ // Use XMM/YMM MOVDQU instruction for Object Initialization
+ if (!UseFastStosb && UseSSE >= 2 && UseUnalignedLoadStores) {
+ if (FLAG_IS_DEFAULT(UseXMMForObjInit)) {
+ UseXMMForObjInit = true;
+ }
+ } else if (UseXMMForObjInit) {
+ warning("UseXMMForObjInit requires SSE2 and unaligned load/stores. Feature is switched off.");
+ FLAG_SET_DEFAULT(UseXMMForObjInit, false);
+ }
+
#ifdef COMPILER2
if (FLAG_IS_DEFAULT(AlignVector)) {
// Modern processors allow misaligned memory operations for vectors.
--- a/src/hotspot/cpu/x86/x86.ad Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/x86/x86.ad Wed Jun 13 11:01:25 2018 -0700
@@ -1067,6 +1067,138 @@
#endif
);
+reg_class xmm0_reg(XMM0, XMM0b, XMM0c, XMM0d);
+reg_class ymm0_reg(XMM0, XMM0b, XMM0c, XMM0d, XMM0e, XMM0f, XMM0g, XMM0h);
+reg_class zmm0_reg(XMM0, XMM0b, XMM0c, XMM0d, XMM0e, XMM0f, XMM0g, XMM0h, XMM0i, XMM0j, XMM0k, XMM0l, XMM0m, XMM0n, XMM0o, XMM0p);
+
+reg_class xmm1_reg(XMM1, XMM1b, XMM1c, XMM1d);
+reg_class ymm1_reg(XMM1, XMM1b, XMM1c, XMM1d, XMM1e, XMM1f, XMM1g, XMM1h);
+reg_class zmm1_reg(XMM1, XMM1b, XMM1c, XMM1d, XMM1e, XMM1f, XMM1g, XMM1h, XMM1i, XMM1j, XMM1k, XMM1l, XMM1m, XMM1n, XMM1o, XMM1p);
+
+reg_class xmm2_reg(XMM2, XMM2b, XMM2c, XMM2d);
+reg_class ymm2_reg(XMM2, XMM2b, XMM2c, XMM2d, XMM2e, XMM2f, XMM2g, XMM2h);
+reg_class zmm2_reg(XMM2, XMM2b, XMM2c, XMM2d, XMM2e, XMM2f, XMM2g, XMM2h, XMM2i, XMM2j, XMM2k, XMM2l, XMM2m, XMM2n, XMM2o, XMM2p);
+
+reg_class xmm3_reg(XMM3, XMM3b, XMM3c, XMM3d);
+reg_class ymm3_reg(XMM3, XMM3b, XMM3c, XMM3d, XMM3e, XMM3f, XMM3g, XMM3h);
+reg_class zmm3_reg(XMM3, XMM3b, XMM3c, XMM3d, XMM3e, XMM3f, XMM3g, XMM3h, XMM3i, XMM3j, XMM3k, XMM3l, XMM3m, XMM3n, XMM3o, XMM3p);
+
+reg_class xmm4_reg(XMM4, XMM4b, XMM4c, XMM4d);
+reg_class ymm4_reg(XMM4, XMM4b, XMM4c, XMM4d, XMM4e, XMM4f, XMM4g, XMM4h);
+reg_class zmm4_reg(XMM4, XMM4b, XMM4c, XMM4d, XMM4e, XMM4f, XMM4g, XMM4h, XMM4i, XMM4j, XMM4k, XMM4l, XMM4m, XMM4n, XMM4o, XMM4p);
+
+reg_class xmm5_reg(XMM5, XMM5b, XMM5c, XMM5d);
+reg_class ymm5_reg(XMM5, XMM5b, XMM5c, XMM5d, XMM5e, XMM5f, XMM5g, XMM5h);
+reg_class zmm5_reg(XMM5, XMM5b, XMM5c, XMM5d, XMM5e, XMM5f, XMM5g, XMM5h, XMM5i, XMM5j, XMM5k, XMM5l, XMM5m, XMM5n, XMM5o, XMM5p);
+
+reg_class xmm6_reg(XMM6, XMM6b, XMM6c, XMM6d);
+reg_class ymm6_reg(XMM6, XMM6b, XMM6c, XMM6d, XMM6e, XMM6f, XMM6g, XMM6h);
+reg_class zmm6_reg(XMM6, XMM6b, XMM6c, XMM6d, XMM6e, XMM6f, XMM6g, XMM6h, XMM6i, XMM6j, XMM6k, XMM6l, XMM6m, XMM6n, XMM6o, XMM6p);
+
+reg_class xmm7_reg(XMM7, XMM7b, XMM7c, XMM7d);
+reg_class ymm7_reg(XMM7, XMM7b, XMM7c, XMM7d, XMM7e, XMM7f, XMM7g, XMM7h);
+reg_class zmm7_reg(XMM7, XMM7b, XMM7c, XMM7d, XMM7e, XMM7f, XMM7g, XMM7h, XMM7i, XMM7j, XMM7k, XMM7l, XMM7m, XMM7n, XMM7o, XMM7p);
+
+#ifdef _LP64
+
+reg_class xmm8_reg(XMM8, XMM8b, XMM8c, XMM8d);
+reg_class ymm8_reg(XMM8, XMM8b, XMM8c, XMM8d, XMM8e, XMM8f, XMM8g, XMM8h);
+reg_class zmm8_reg(XMM8, XMM8b, XMM8c, XMM8d, XMM8e, XMM8f, XMM8g, XMM8h, XMM8i, XMM8j, XMM8k, XMM8l, XMM8m, XMM8n, XMM8o, XMM8p);
+
+reg_class xmm9_reg(XMM9, XMM9b, XMM9c, XMM9d);
+reg_class ymm9_reg(XMM9, XMM9b, XMM9c, XMM9d, XMM9e, XMM9f, XMM9g, XMM9h);
+reg_class zmm9_reg(XMM9, XMM9b, XMM9c, XMM9d, XMM9e, XMM9f, XMM9g, XMM9h, XMM9i, XMM9j, XMM9k, XMM9l, XMM9m, XMM9n, XMM9o, XMM9p);
+
+reg_class xmm10_reg(XMM10, XMM10b, XMM10c, XMM10d);
+reg_class ymm10_reg(XMM10, XMM10b, XMM10c, XMM10d, XMM10e, XMM10f, XMM10g, XMM10h);
+reg_class zmm10_reg(XMM10, XMM10b, XMM10c, XMM10d, XMM10e, XMM10f, XMM10g, XMM10h, XMM10i, XMM10j, XMM10k, XMM10l, XMM10m, XMM10n, XMM10o, XMM10p);
+
+reg_class xmm11_reg(XMM11, XMM11b, XMM11c, XMM11d);
+reg_class ymm11_reg(XMM11, XMM11b, XMM11c, XMM11d, XMM11e, XMM11f, XMM11g, XMM11h);
+reg_class zmm11_reg(XMM11, XMM11b, XMM11c, XMM11d, XMM11e, XMM11f, XMM11g, XMM11h, XMM11i, XMM11j, XMM11k, XMM11l, XMM11m, XMM11n, XMM11o, XMM11p);
+
+reg_class xmm12_reg(XMM12, XMM12b, XMM12c, XMM12d);
+reg_class ymm12_reg(XMM12, XMM12b, XMM12c, XMM12d, XMM12e, XMM12f, XMM12g, XMM12h);
+reg_class zmm12_reg(XMM12, XMM12b, XMM12c, XMM12d, XMM12e, XMM12f, XMM12g, XMM12h, XMM12i, XMM12j, XMM12k, XMM12l, XMM12m, XMM12n, XMM12o, XMM12p);
+
+reg_class xmm13_reg(XMM13, XMM13b, XMM13c, XMM13d);
+reg_class ymm13_reg(XMM13, XMM13b, XMM13c, XMM13d, XMM13e, XMM13f, XMM13g, XMM13h);
+reg_class zmm13_reg(XMM13, XMM13b, XMM13c, XMM13d, XMM13e, XMM13f, XMM13g, XMM13h, XMM13i, XMM13j, XMM13k, XMM13l, XMM13m, XMM13n, XMM13o, XMM13p);
+
+reg_class xmm14_reg(XMM14, XMM14b, XMM14c, XMM14d);
+reg_class ymm14_reg(XMM14, XMM14b, XMM14c, XMM14d, XMM14e, XMM14f, XMM14g, XMM14h);
+reg_class zmm14_reg(XMM14, XMM14b, XMM14c, XMM14d, XMM14e, XMM14f, XMM14g, XMM14h, XMM14i, XMM14j, XMM14k, XMM14l, XMM14m, XMM14n, XMM14o, XMM14p);
+
+reg_class xmm15_reg(XMM15, XMM15b, XMM15c, XMM15d);
+reg_class ymm15_reg(XMM15, XMM15b, XMM15c, XMM15d, XMM15e, XMM15f, XMM15g, XMM15h);
+reg_class zmm15_reg(XMM15, XMM15b, XMM15c, XMM15d, XMM15e, XMM15f, XMM15g, XMM15h, XMM15i, XMM15j, XMM15k, XMM15l, XMM15m, XMM15n, XMM15o, XMM15p);
+
+reg_class xmm16_reg(XMM16, XMM16b, XMM16c, XMM16d);
+reg_class ymm16_reg(XMM16, XMM16b, XMM16c, XMM16d, XMM16e, XMM16f, XMM16g, XMM16h);
+reg_class zmm16_reg(XMM16, XMM16b, XMM16c, XMM16d, XMM16e, XMM16f, XMM16g, XMM16h, XMM16i, XMM16j, XMM16k, XMM16l, XMM16m, XMM16n, XMM16o, XMM16p);
+
+reg_class xmm17_reg(XMM17, XMM17b, XMM17c, XMM17d);
+reg_class ymm17_reg(XMM17, XMM17b, XMM17c, XMM17d, XMM17e, XMM17f, XMM17g, XMM17h);
+reg_class zmm17_reg(XMM17, XMM17b, XMM17c, XMM17d, XMM17e, XMM17f, XMM17g, XMM17h, XMM17i, XMM17j, XMM17k, XMM17l, XMM17m, XMM17n, XMM17o, XMM17p);
+
+reg_class xmm18_reg(XMM18, XMM18b, XMM18c, XMM18d);
+reg_class ymm18_reg(XMM18, XMM18b, XMM18c, XMM18d, XMM18e, XMM18f, XMM18g, XMM18h);
+reg_class zmm18_reg(XMM18, XMM18b, XMM18c, XMM18d, XMM18e, XMM18f, XMM18g, XMM18h, XMM18i, XMM18j, XMM18k, XMM18l, XMM18m, XMM18n, XMM18o, XMM18p);
+
+reg_class xmm19_reg(XMM19, XMM19b, XMM19c, XMM19d);
+reg_class ymm19_reg(XMM19, XMM19b, XMM19c, XMM19d, XMM19e, XMM19f, XMM19g, XMM19h);
+reg_class zmm19_reg(XMM19, XMM19b, XMM19c, XMM19d, XMM19e, XMM19f, XMM19g, XMM19h, XMM19i, XMM19j, XMM19k, XMM19l, XMM19m, XMM19n, XMM19o, XMM19p);
+
+reg_class xmm20_reg(XMM20, XMM20b, XMM20c, XMM20d);
+reg_class ymm20_reg(XMM20, XMM20b, XMM20c, XMM20d, XMM20e, XMM20f, XMM20g, XMM20h);
+reg_class zmm20_reg(XMM20, XMM20b, XMM20c, XMM20d, XMM20e, XMM20f, XMM20g, XMM20h, XMM20i, XMM20j, XMM20k, XMM20l, XMM20m, XMM20n, XMM20o, XMM20p);
+
+reg_class xmm21_reg(XMM21, XMM21b, XMM21c, XMM21d);
+reg_class ymm21_reg(XMM21, XMM21b, XMM21c, XMM21d, XMM21e, XMM21f, XMM21g, XMM21h);
+reg_class zmm21_reg(XMM21, XMM21b, XMM21c, XMM21d, XMM21e, XMM21f, XMM21g, XMM21h, XMM21i, XMM21j, XMM21k, XMM21l, XMM21m, XMM21n, XMM21o, XMM21p);
+
+reg_class xmm22_reg(XMM22, XMM22b, XMM22c, XMM22d);
+reg_class ymm22_reg(XMM22, XMM22b, XMM22c, XMM22d, XMM22e, XMM22f, XMM22g, XMM22h);
+reg_class zmm22_reg(XMM22, XMM22b, XMM22c, XMM22d, XMM22e, XMM22f, XMM22g, XMM22h, XMM22i, XMM22j, XMM22k, XMM22l, XMM22m, XMM22n, XMM22o, XMM22p);
+
+reg_class xmm23_reg(XMM23, XMM23b, XMM23c, XMM23d);
+reg_class ymm23_reg(XMM23, XMM23b, XMM23c, XMM23d, XMM23e, XMM23f, XMM23g, XMM23h);
+reg_class zmm23_reg(XMM23, XMM23b, XMM23c, XMM23d, XMM23e, XMM23f, XMM23g, XMM23h, XMM23i, XMM23j, XMM23k, XMM23l, XMM23m, XMM23n, XMM23o, XMM23p);
+
+reg_class xmm24_reg(XMM24, XMM24b, XMM24c, XMM24d);
+reg_class ymm24_reg(XMM24, XMM24b, XMM24c, XMM24d, XMM24e, XMM24f, XMM24g, XMM24h);
+reg_class zmm24_reg(XMM24, XMM24b, XMM24c, XMM24d, XMM24e, XMM24f, XMM24g, XMM24h, XMM24i, XMM24j, XMM24k, XMM24l, XMM24m, XMM24n, XMM24o, XMM24p);
+
+reg_class xmm25_reg(XMM25, XMM25b, XMM25c, XMM25d);
+reg_class ymm25_reg(XMM25, XMM25b, XMM25c, XMM25d, XMM25e, XMM25f, XMM25g, XMM25h);
+reg_class zmm25_reg(XMM25, XMM25b, XMM25c, XMM25d, XMM25e, XMM25f, XMM25g, XMM25h, XMM25i, XMM25j, XMM25k, XMM25l, XMM25m, XMM25n, XMM25o, XMM25p);
+
+reg_class xmm26_reg(XMM26, XMM26b, XMM26c, XMM26d);
+reg_class ymm26_reg(XMM26, XMM26b, XMM26c, XMM26d, XMM26e, XMM26f, XMM26g, XMM26h);
+reg_class zmm26_reg(XMM26, XMM26b, XMM26c, XMM26d, XMM26e, XMM26f, XMM26g, XMM26h, XMM26i, XMM26j, XMM26k, XMM26l, XMM26m, XMM26n, XMM26o, XMM26p);
+
+reg_class xmm27_reg(XMM27, XMM27b, XMM27c, XMM27d);
+reg_class ymm27_reg(XMM27, XMM27b, XMM27c, XMM27d, XMM27e, XMM27f, XMM27g, XMM27h);
+reg_class zmm27_reg(XMM27, XMM27b, XMM27c, XMM27d, XMM27e, XMM27f, XMM27g, XMM27h, XMM27i, XMM27j, XMM27k, XMM27l, XMM27m, XMM27n, XMM27o, XMM27p);
+
+reg_class xmm28_reg(XMM28, XMM28b, XMM28c, XMM28d);
+reg_class ymm28_reg(XMM28, XMM28b, XMM28c, XMM28d, XMM28e, XMM28f, XMM28g, XMM28h);
+reg_class zmm28_reg(XMM28, XMM28b, XMM28c, XMM28d, XMM28e, XMM28f, XMM28g, XMM28h, XMM28i, XMM28j, XMM28k, XMM28l, XMM28m, XMM28n, XMM28o, XMM28p);
+
+reg_class xmm29_reg(XMM29, XMM29b, XMM29c, XMM29d);
+reg_class ymm29_reg(XMM29, XMM29b, XMM29c, XMM29d, XMM29e, XMM29f, XMM29g, XMM29h);
+reg_class zmm29_reg(XMM29, XMM29b, XMM29c, XMM29d, XMM29e, XMM29f, XMM29g, XMM29h, XMM29i, XMM29j, XMM29k, XMM29l, XMM29m, XMM29n, XMM29o, XMM29p);
+
+reg_class xmm30_reg(XMM30, XMM30b, XMM30c, XMM30d);
+reg_class ymm30_reg(XMM30, XMM30b, XMM30c, XMM30d, XMM30e, XMM30f, XMM30g, XMM30h);
+reg_class zmm30_reg(XMM30, XMM30b, XMM30c, XMM30d, XMM30e, XMM30f, XMM30g, XMM30h, XMM30i, XMM30j, XMM30k, XMM30l, XMM30m, XMM30n, XMM30o, XMM30p);
+
+reg_class xmm31_reg(XMM31, XMM31b, XMM31c, XMM31d);
+reg_class ymm31_reg(XMM31, XMM31b, XMM31c, XMM31d, XMM31e, XMM31f, XMM31g, XMM31h);
+reg_class zmm31_reg(XMM31, XMM31b, XMM31c, XMM31d, XMM31e, XMM31f, XMM31g, XMM31h, XMM31i, XMM31j, XMM31k, XMM31l, XMM31m, XMM31n, XMM31o, XMM31p);
+
+#endif
+
%}
--- a/src/hotspot/cpu/x86/x86_32.ad Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/x86/x86_32.ad Wed Jun 13 11:01:25 2018 -0700
@@ -11482,10 +11482,10 @@
// =======================================================================
// fast clearing of an array
-instruct rep_stos(eCXRegI cnt, eDIRegP base, eAXRegI zero, Universe dummy, eFlagsReg cr) %{
+instruct rep_stos(eCXRegI cnt, eDIRegP base, regD tmp, eAXRegI zero, Universe dummy, eFlagsReg cr) %{
predicate(!((ClearArrayNode*)n)->is_large());
match(Set dummy (ClearArray cnt base));
- effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
+ effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr);
format %{ $$template
$$emit$$"XOR EAX,EAX\t# ClearArray:\n\t"
@@ -11502,6 +11502,32 @@
if (UseFastStosb) {
$$emit$$"SHL ECX,3\t# Convert doublewords to bytes\n\t"
$$emit$$"REP STOSB\t# store EAX into [EDI++] while ECX--\n\t"
+ } else if (UseXMMForObjInit) {
+ $$emit$$"MOV RDI,RAX\n\t"
+ $$emit$$"VPXOR YMM0,YMM0,YMM0\n\t"
+ $$emit$$"JMPQ L_zero_64_bytes\n\t"
+ $$emit$$"# L_loop:\t# 64-byte LOOP\n\t"
+ $$emit$$"VMOVDQU YMM0,(RAX)\n\t"
+ $$emit$$"VMOVDQU YMM0,0x20(RAX)\n\t"
+ $$emit$$"ADD 0x40,RAX\n\t"
+ $$emit$$"# L_zero_64_bytes:\n\t"
+ $$emit$$"SUB 0x8,RCX\n\t"
+ $$emit$$"JGE L_loop\n\t"
+ $$emit$$"ADD 0x4,RCX\n\t"
+ $$emit$$"JL L_tail\n\t"
+ $$emit$$"VMOVDQU YMM0,(RAX)\n\t"
+ $$emit$$"ADD 0x20,RAX\n\t"
+ $$emit$$"SUB 0x4,RCX\n\t"
+ $$emit$$"# L_tail:\t# Clearing tail bytes\n\t"
+ $$emit$$"ADD 0x4,RCX\n\t"
+ $$emit$$"JLE L_end\n\t"
+ $$emit$$"DEC RCX\n\t"
+ $$emit$$"# L_sloop:\t# 8-byte short loop\n\t"
+ $$emit$$"VMOVQ XMM0,(RAX)\n\t"
+ $$emit$$"ADD 0x8,RAX\n\t"
+ $$emit$$"DEC RCX\n\t"
+ $$emit$$"JGE L_sloop\n\t"
+ $$emit$$"# L_end:\n\t"
} else {
$$emit$$"SHL ECX,1\t# Convert doublewords to words\n\t"
$$emit$$"REP STOS\t# store EAX into [EDI++] while ECX--\n\t"
@@ -11509,28 +11535,57 @@
$$emit$$"# DONE"
%}
ins_encode %{
- __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, false);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct rep_stos_large(eCXRegI cnt, eDIRegP base, eAXRegI zero, Universe dummy, eFlagsReg cr) %{
+ __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register,
+ $tmp$$XMMRegister, false);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct rep_stos_large(eCXRegI cnt, eDIRegP base, regD tmp, eAXRegI zero, Universe dummy, eFlagsReg cr) %{
predicate(((ClearArrayNode*)n)->is_large());
match(Set dummy (ClearArray cnt base));
- effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
+ effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr);
format %{ $$template
- $$emit$$"XOR EAX,EAX\t# ClearArray:\n\t"
if (UseFastStosb) {
+ $$emit$$"XOR EAX,EAX\t# ClearArray:\n\t"
$$emit$$"SHL ECX,3\t# Convert doublewords to bytes\n\t"
$$emit$$"REP STOSB\t# store EAX into [EDI++] while ECX--\n\t"
+ } else if (UseXMMForObjInit) {
+ $$emit$$"MOV RDI,RAX\t# ClearArray:\n\t"
+ $$emit$$"VPXOR YMM0,YMM0,YMM0\n\t"
+ $$emit$$"JMPQ L_zero_64_bytes\n\t"
+ $$emit$$"# L_loop:\t# 64-byte LOOP\n\t"
+ $$emit$$"VMOVDQU YMM0,(RAX)\n\t"
+ $$emit$$"VMOVDQU YMM0,0x20(RAX)\n\t"
+ $$emit$$"ADD 0x40,RAX\n\t"
+ $$emit$$"# L_zero_64_bytes:\n\t"
+ $$emit$$"SUB 0x8,RCX\n\t"
+ $$emit$$"JGE L_loop\n\t"
+ $$emit$$"ADD 0x4,RCX\n\t"
+ $$emit$$"JL L_tail\n\t"
+ $$emit$$"VMOVDQU YMM0,(RAX)\n\t"
+ $$emit$$"ADD 0x20,RAX\n\t"
+ $$emit$$"SUB 0x4,RCX\n\t"
+ $$emit$$"# L_tail:\t# Clearing tail bytes\n\t"
+ $$emit$$"ADD 0x4,RCX\n\t"
+ $$emit$$"JLE L_end\n\t"
+ $$emit$$"DEC RCX\n\t"
+ $$emit$$"# L_sloop:\t# 8-byte short loop\n\t"
+ $$emit$$"VMOVQ XMM0,(RAX)\n\t"
+ $$emit$$"ADD 0x8,RAX\n\t"
+ $$emit$$"DEC RCX\n\t"
+ $$emit$$"JGE L_sloop\n\t"
+ $$emit$$"# L_end:\n\t"
} else {
+ $$emit$$"XOR EAX,EAX\t# ClearArray:\n\t"
$$emit$$"SHL ECX,1\t# Convert doublewords to words\n\t"
$$emit$$"REP STOS\t# store EAX into [EDI++] while ECX--\n\t"
}
$$emit$$"# DONE"
%}
ins_encode %{
- __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, true);
+ __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register,
+ $tmp$$XMMRegister, true);
%}
ins_pipe( pipe_slow );
%}
--- a/src/hotspot/cpu/x86/x86_64.ad Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/cpu/x86/x86_64.ad Wed Jun 13 11:01:25 2018 -0700
@@ -538,6 +538,12 @@
%}
+source_hpp %{
+#if INCLUDE_ZGC
+#include "gc/z/zBarrierSetAssembler.hpp"
+#endif
+%}
+
//----------SOURCE BLOCK-------------------------------------------------------
// This is a block of C++ code which provides values, functions, and
// definitions necessary in the rest of the architecture description
@@ -4221,6 +4227,135 @@
%}
%}
+// Operands for bound floating pointer register arguments
+operand rxmm0() %{
+ constraint(ALLOC_IN_RC(xmm0_reg)); match(VecX);
+ predicate((UseSSE > 0) && (UseAVX<= 2)); format%{%} interface(REG_INTER);
+%}
+operand rxmm1() %{
+ constraint(ALLOC_IN_RC(xmm1_reg)); match(VecX);
+ predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER);
+%}
+operand rxmm2() %{
+ constraint(ALLOC_IN_RC(xmm2_reg)); match(VecX);
+ predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER);
+%}
+operand rxmm3() %{
+ constraint(ALLOC_IN_RC(xmm3_reg)); match(VecX);
+ predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER);
+%}
+operand rxmm4() %{
+ constraint(ALLOC_IN_RC(xmm4_reg)); match(VecX);
+ predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER);
+%}
+operand rxmm5() %{
+ constraint(ALLOC_IN_RC(xmm5_reg)); match(VecX);
+ predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER);
+%}
+operand rxmm6() %{
+ constraint(ALLOC_IN_RC(xmm6_reg)); match(VecX);
+ predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER);
+%}
+operand rxmm7() %{
+ constraint(ALLOC_IN_RC(xmm7_reg)); match(VecX);
+ predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER);
+%}
+operand rxmm8() %{
+ constraint(ALLOC_IN_RC(xmm8_reg)); match(VecX);
+ predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER);
+%}
+operand rxmm9() %{
+ constraint(ALLOC_IN_RC(xmm9_reg)); match(VecX);
+ predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER);
+%}
+operand rxmm10() %{
+ constraint(ALLOC_IN_RC(xmm10_reg)); match(VecX);
+ predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER);
+%}
+operand rxmm11() %{
+ constraint(ALLOC_IN_RC(xmm11_reg)); match(VecX);
+ predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER);
+%}
+operand rxmm12() %{
+ constraint(ALLOC_IN_RC(xmm12_reg)); match(VecX);
+ predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER);
+%}
+operand rxmm13() %{
+ constraint(ALLOC_IN_RC(xmm13_reg)); match(VecX);
+ predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER);
+%}
+operand rxmm14() %{
+ constraint(ALLOC_IN_RC(xmm14_reg)); match(VecX);
+ predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER);
+%}
+operand rxmm15() %{
+ constraint(ALLOC_IN_RC(xmm15_reg)); match(VecX);
+ predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER);
+%}
+operand rxmm16() %{
+ constraint(ALLOC_IN_RC(xmm16_reg)); match(VecX);
+ predicate(UseAVX == 3); format%{%} interface(REG_INTER);
+%}
+operand rxmm17() %{
+ constraint(ALLOC_IN_RC(xmm17_reg)); match(VecX);
+ predicate(UseAVX == 3); format%{%} interface(REG_INTER);
+%}
+operand rxmm18() %{
+ constraint(ALLOC_IN_RC(xmm18_reg)); match(VecX);
+ predicate(UseAVX == 3); format%{%} interface(REG_INTER);
+%}
+operand rxmm19() %{
+ constraint(ALLOC_IN_RC(xmm19_reg)); match(VecX);
+ predicate(UseAVX == 3); format%{%} interface(REG_INTER);
+%}
+operand rxmm20() %{
+ constraint(ALLOC_IN_RC(xmm20_reg)); match(VecX);
+ predicate(UseAVX == 3); format%{%} interface(REG_INTER);
+%}
+operand rxmm21() %{
+ constraint(ALLOC_IN_RC(xmm21_reg)); match(VecX);
+ predicate(UseAVX == 3); format%{%} interface(REG_INTER);
+%}
+operand rxmm22() %{
+ constraint(ALLOC_IN_RC(xmm22_reg)); match(VecX);
+ predicate(UseAVX == 3); format%{%} interface(REG_INTER);
+%}
+operand rxmm23() %{
+ constraint(ALLOC_IN_RC(xmm23_reg)); match(VecX);
+ predicate(UseAVX == 3); format%{%} interface(REG_INTER);
+%}
+operand rxmm24() %{
+ constraint(ALLOC_IN_RC(xmm24_reg)); match(VecX);
+ predicate(UseAVX == 3); format%{%} interface(REG_INTER);
+%}
+operand rxmm25() %{
+ constraint(ALLOC_IN_RC(xmm25_reg)); match(VecX);
+ predicate(UseAVX == 3); format%{%} interface(REG_INTER);
+%}
+operand rxmm26() %{
+ constraint(ALLOC_IN_RC(xmm26_reg)); match(VecX);
+ predicate(UseAVX == 3); format%{%} interface(REG_INTER);
+%}
+operand rxmm27() %{
+ constraint(ALLOC_IN_RC(xmm27_reg)); match(VecX);
+ predicate(UseAVX == 3); format%{%} interface(REG_INTER);
+%}
+operand rxmm28() %{
+ constraint(ALLOC_IN_RC(xmm28_reg)); match(VecX);
+ predicate(UseAVX == 3); format%{%} interface(REG_INTER);
+%}
+operand rxmm29() %{
+ constraint(ALLOC_IN_RC(xmm29_reg)); match(VecX);
+ predicate(UseAVX == 3); format%{%} interface(REG_INTER);
+%}
+operand rxmm30() %{
+ constraint(ALLOC_IN_RC(xmm30_reg)); match(VecX);
+ predicate(UseAVX == 3); format%{%} interface(REG_INTER);
+%}
+operand rxmm31() %{
+ constraint(ALLOC_IN_RC(xmm31_reg)); match(VecX);
+ predicate(UseAVX == 3); format%{%} interface(REG_INTER);
+%}
//----------OPERAND CLASSES----------------------------------------------------
// Operand Classes are groups of operands that are used as to simplify
@@ -10635,12 +10770,12 @@
// =======================================================================
// fast clearing of an array
-instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy,
- rFlagsReg cr)
+instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero,
+ Universe dummy, rFlagsReg cr)
%{
predicate(!((ClearArrayNode*)n)->is_large());
match(Set dummy (ClearArray cnt base));
- effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
+ effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr);
format %{ $$template
$$emit$$"xorq rax, rax\t# ClearArray:\n\t"
@@ -10656,35 +10791,90 @@
if (UseFastStosb) {
$$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t"
$$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t"
+ } else if (UseXMMForObjInit) {
+ $$emit$$"mov rdi,rax\n\t"
+ $$emit$$"vpxor ymm0,ymm0,ymm0\n\t"
+ $$emit$$"jmpq L_zero_64_bytes\n\t"
+ $$emit$$"# L_loop:\t# 64-byte LOOP\n\t"
+ $$emit$$"vmovdqu ymm0,(rax)\n\t"
+ $$emit$$"vmovdqu ymm0,0x20(rax)\n\t"
+ $$emit$$"add 0x40,rax\n\t"
+ $$emit$$"# L_zero_64_bytes:\n\t"
+ $$emit$$"sub 0x8,rcx\n\t"
+ $$emit$$"jge L_loop\n\t"
+ $$emit$$"add 0x4,rcx\n\t"
+ $$emit$$"jl L_tail\n\t"
+ $$emit$$"vmovdqu ymm0,(rax)\n\t"
+ $$emit$$"add 0x20,rax\n\t"
+ $$emit$$"sub 0x4,rcx\n\t"
+ $$emit$$"# L_tail:\t# Clearing tail bytes\n\t"
+ $$emit$$"add 0x4,rcx\n\t"
+ $$emit$$"jle L_end\n\t"
+ $$emit$$"dec rcx\n\t"
+ $$emit$$"# L_sloop:\t# 8-byte short loop\n\t"
+ $$emit$$"vmovq xmm0,(rax)\n\t"
+ $$emit$$"add 0x8,rax\n\t"
+ $$emit$$"dec rcx\n\t"
+ $$emit$$"jge L_sloop\n\t"
+ $$emit$$"# L_end:\n\t"
} else {
$$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t"
}
$$emit$$"# DONE"
%}
ins_encode %{
- __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, false);
+ __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register,
+ $tmp$$XMMRegister, false);
%}
ins_pipe(pipe_slow);
%}
-instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy,
- rFlagsReg cr)
+instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero,
+ Universe dummy, rFlagsReg cr)
%{
predicate(((ClearArrayNode*)n)->is_large());
match(Set dummy (ClearArray cnt base));
- effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
+ effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr);
format %{ $$template
- $$emit$$"xorq rax, rax\t# ClearArray:\n\t"
if (UseFastStosb) {
+ $$emit$$"xorq rax, rax\t# ClearArray:\n\t"
$$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t"
$$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--"
+ } else if (UseXMMForObjInit) {
+ $$emit$$"mov rdi,rax\t# ClearArray:\n\t"
+ $$emit$$"vpxor ymm0,ymm0,ymm0\n\t"
+ $$emit$$"jmpq L_zero_64_bytes\n\t"
+ $$emit$$"# L_loop:\t# 64-byte LOOP\n\t"
+ $$emit$$"vmovdqu ymm0,(rax)\n\t"
+ $$emit$$"vmovdqu ymm0,0x20(rax)\n\t"
+ $$emit$$"add 0x40,rax\n\t"
+ $$emit$$"# L_zero_64_bytes:\n\t"
+ $$emit$$"sub 0x8,rcx\n\t"
+ $$emit$$"jge L_loop\n\t"
+ $$emit$$"add 0x4,rcx\n\t"
+ $$emit$$"jl L_tail\n\t"
+ $$emit$$"vmovdqu ymm0,(rax)\n\t"
+ $$emit$$"add 0x20,rax\n\t"
+ $$emit$$"sub 0x4,rcx\n\t"
+ $$emit$$"# L_tail:\t# Clearing tail bytes\n\t"
+ $$emit$$"add 0x4,rcx\n\t"
+ $$emit$$"jle L_end\n\t"
+ $$emit$$"dec rcx\n\t"
+ $$emit$$"# L_sloop:\t# 8-byte short loop\n\t"
+ $$emit$$"vmovq xmm0,(rax)\n\t"
+ $$emit$$"add 0x8,rax\n\t"
+ $$emit$$"dec rcx\n\t"
+ $$emit$$"jge L_sloop\n\t"
+ $$emit$$"# L_end:\n\t"
} else {
+ $$emit$$"xorq rax, rax\t# ClearArray:\n\t"
$$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--"
}
%}
ins_encode %{
- __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, true);
+ __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register,
+ $tmp$$XMMRegister, true);
%}
ins_pipe(pipe_slow);
%}
@@ -11547,6 +11737,16 @@
ins_pipe(ialu_cr_reg_mem);
%}
+instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero)
+%{
+ match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero));
+
+ format %{ "testq $src, $mem" %}
+ opcode(0x85);
+ ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
+ ins_pipe(ialu_cr_reg_mem);
+%}
+
// Manifest a CmpL result in an integer register. Very painful.
// This is the test to avoid.
instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags)
@@ -12320,6 +12520,223 @@
ins_pipe(pipe_jmp);
%}
+//
+// Execute ZGC load barrier (strong) slow path
+//
+
+// When running without XMM regs
+instruct loadBarrierSlowRegNoVec(rRegP dst, memory mem, rFlagsReg cr) %{
+
+ match(Set dst (LoadBarrierSlowReg mem));
+ predicate(MaxVectorSize < 16);
+
+ effect(DEF dst, KILL cr);
+
+ format %{"LoadBarrierSlowRegNoVec $dst, $mem" %}
+ ins_encode %{
+#if INCLUDE_ZGC
+ Register d = $dst$$Register;
+ ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
+
+ assert(d != r12, "Can't be R12!");
+ assert(d != r15, "Can't be R15!");
+ assert(d != rsp, "Can't be RSP!");
+
+ __ lea(d, $mem$$Address);
+ __ call(RuntimeAddress(bs->load_barrier_slow_stub(d)));
+#else
+ ShouldNotReachHere();
+#endif
+ %}
+ ins_pipe(pipe_slow);
+%}
+
+// For XMM and YMM enabled processors
+instruct loadBarrierSlowRegXmmAndYmm(rRegP dst, memory mem, rFlagsReg cr,
+ rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3,
+ rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7,
+ rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11,
+ rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{
+
+ match(Set dst (LoadBarrierSlowReg mem));
+ predicate((UseSSE > 0) && (UseAVX <= 2) && (MaxVectorSize >= 16));
+
+ effect(DEF dst, KILL cr,
+ KILL x0, KILL x1, KILL x2, KILL x3,
+ KILL x4, KILL x5, KILL x6, KILL x7,
+ KILL x8, KILL x9, KILL x10, KILL x11,
+ KILL x12, KILL x13, KILL x14, KILL x15);
+
+ format %{"LoadBarrierSlowRegXmm $dst, $mem" %}
+ ins_encode %{
+#if INCLUDE_ZGC
+ Register d = $dst$$Register;
+ ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
+
+ assert(d != r12, "Can't be R12!");
+ assert(d != r15, "Can't be R15!");
+ assert(d != rsp, "Can't be RSP!");
+
+ __ lea(d, $mem$$Address);
+ __ call(RuntimeAddress(bs->load_barrier_slow_stub(d)));
+#else
+ ShouldNotReachHere();
+#endif
+ %}
+ ins_pipe(pipe_slow);
+%}
+
+// For ZMM enabled processors
+instruct loadBarrierSlowRegZmm(rRegP dst, memory mem, rFlagsReg cr,
+ rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3,
+ rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7,
+ rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11,
+ rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15,
+ rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19,
+ rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23,
+ rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27,
+ rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{
+
+ match(Set dst (LoadBarrierSlowReg mem));
+ predicate((UseAVX == 3) && (MaxVectorSize >= 16));
+
+ effect(DEF dst, KILL cr,
+ KILL x0, KILL x1, KILL x2, KILL x3,
+ KILL x4, KILL x5, KILL x6, KILL x7,
+ KILL x8, KILL x9, KILL x10, KILL x11,
+ KILL x12, KILL x13, KILL x14, KILL x15,
+ KILL x16, KILL x17, KILL x18, KILL x19,
+ KILL x20, KILL x21, KILL x22, KILL x23,
+ KILL x24, KILL x25, KILL x26, KILL x27,
+ KILL x28, KILL x29, KILL x30, KILL x31);
+
+ format %{"LoadBarrierSlowRegZmm $dst, $mem" %}
+ ins_encode %{
+#if INCLUDE_ZGC
+ Register d = $dst$$Register;
+ ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
+
+ assert(d != r12, "Can't be R12!");
+ assert(d != r15, "Can't be R15!");
+ assert(d != rsp, "Can't be RSP!");
+
+ __ lea(d, $mem$$Address);
+ __ call(RuntimeAddress(bs->load_barrier_slow_stub(d)));
+#else
+ ShouldNotReachHere();
+#endif
+ %}
+ ins_pipe(pipe_slow);
+%}
+
+//
+// Execute ZGC load barrier (weak) slow path
+//
+
+// When running without XMM regs
+instruct loadBarrierWeakSlowRegNoVec(rRegP dst, memory mem, rFlagsReg cr) %{
+
+ match(Set dst (LoadBarrierSlowReg mem));
+ predicate(MaxVectorSize < 16);
+
+ effect(DEF dst, KILL cr);
+
+ format %{"LoadBarrierSlowRegNoVec $dst, $mem" %}
+ ins_encode %{
+#if INCLUDE_ZGC
+ Register d = $dst$$Register;
+ ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
+
+ assert(d != r12, "Can't be R12!");
+ assert(d != r15, "Can't be R15!");
+ assert(d != rsp, "Can't be RSP!");
+
+ __ lea(d, $mem$$Address);
+ __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d)));
+#else
+ ShouldNotReachHere();
+#endif
+ %}
+ ins_pipe(pipe_slow);
+%}
+
+// For XMM and YMM enabled processors
+instruct loadBarrierWeakSlowRegXmmAndYmm(rRegP dst, memory mem, rFlagsReg cr,
+ rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3,
+ rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7,
+ rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11,
+ rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{
+
+ match(Set dst (LoadBarrierWeakSlowReg mem));
+ predicate((UseSSE > 0) && (UseAVX <= 2) && (MaxVectorSize >= 16));
+
+ effect(DEF dst, KILL cr,
+ KILL x0, KILL x1, KILL x2, KILL x3,
+ KILL x4, KILL x5, KILL x6, KILL x7,
+ KILL x8, KILL x9, KILL x10, KILL x11,
+ KILL x12, KILL x13, KILL x14, KILL x15);
+
+ format %{"LoadBarrierWeakSlowRegXmm $dst, $mem" %}
+ ins_encode %{
+#if INCLUDE_ZGC
+ Register d = $dst$$Register;
+ ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
+
+ assert(d != r12, "Can't be R12!");
+ assert(d != r15, "Can't be R15!");
+ assert(d != rsp, "Can't be RSP!");
+
+ __ lea(d,$mem$$Address);
+ __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d)));
+#else
+ ShouldNotReachHere();
+#endif
+ %}
+ ins_pipe(pipe_slow);
+%}
+
+// For ZMM enabled processors
+instruct loadBarrierWeakSlowRegZmm(rRegP dst, memory mem, rFlagsReg cr,
+ rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3,
+ rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7,
+ rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11,
+ rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15,
+ rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19,
+ rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23,
+ rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27,
+ rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{
+
+ match(Set dst (LoadBarrierWeakSlowReg mem));
+ predicate((UseAVX == 3) && (MaxVectorSize >= 16));
+
+ effect(DEF dst, KILL cr,
+ KILL x0, KILL x1, KILL x2, KILL x3,
+ KILL x4, KILL x5, KILL x6, KILL x7,
+ KILL x8, KILL x9, KILL x10, KILL x11,
+ KILL x12, KILL x13, KILL x14, KILL x15,
+ KILL x16, KILL x17, KILL x18, KILL x19,
+ KILL x20, KILL x21, KILL x22, KILL x23,
+ KILL x24, KILL x25, KILL x26, KILL x27,
+ KILL x28, KILL x29, KILL x30, KILL x31);
+
+ format %{"LoadBarrierWeakSlowRegZmm $dst, $mem" %}
+ ins_encode %{
+#if INCLUDE_ZGC
+ Register d = $dst$$Register;
+ ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
+
+ assert(d != r12, "Can't be R12!");
+ assert(d != r15, "Can't be R15!");
+ assert(d != rsp, "Can't be RSP!");
+
+ __ lea(d,$mem$$Address);
+ __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d)));
+#else
+ ShouldNotReachHere();
+#endif
+ %}
+ ins_pipe(pipe_slow);
+%}
// ============================================================================
// This name is KNOWN by the ADLC and cannot be changed.
--- a/src/hotspot/os/aix/os_aix.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/os/aix/os_aix.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -899,8 +899,12 @@
// guard pages might not fit on the tiny stack created.
int ret = pthread_attr_setstacksize(&attr, stack_size);
if (ret != 0) {
- log_warning(os, thread)("The thread stack size specified is invalid: " SIZE_FORMAT "k",
+ log_warning(os, thread)("The %sthread stack size specified is invalid: " SIZE_FORMAT "k",
+ (thr_type == compiler_thread) ? "compiler " : ((thr_type == java_thread) ? "" : "VM "),
stack_size / K);
+ thread->set_osthread(NULL);
+ delete osthread;
+ return false;
}
// Save some cycles and a page by disabling OS guard pages where we have our own
--- a/src/hotspot/os/linux/os_linux.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/os/linux/os_linux.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -1988,6 +1988,8 @@
os::Linux::print_full_memory_info(st);
+ os::Linux::print_proc_sys_info(st);
+
os::Linux::print_container_info(st);
}
@@ -2120,6 +2122,24 @@
st->cr();
}
+void os::Linux::print_proc_sys_info(outputStream* st) {
+ st->cr();
+ st->print_cr("/proc/sys/kernel/threads-max (system-wide limit on the number of threads):");
+ _print_ascii_file("/proc/sys/kernel/threads-max", st);
+ st->cr();
+ st->cr();
+
+ st->print_cr("/proc/sys/vm/max_map_count (maximum number of memory map areas a process may have):");
+ _print_ascii_file("/proc/sys/vm/max_map_count", st);
+ st->cr();
+ st->cr();
+
+ st->print_cr("/proc/sys/kernel/pid_max (system-wide limit on number of process identifiers):");
+ _print_ascii_file("/proc/sys/kernel/pid_max", st);
+ st->cr();
+ st->cr();
+}
+
void os::Linux::print_full_memory_info(outputStream* st) {
st->print("\n/proc/meminfo:\n");
_print_ascii_file("/proc/meminfo", st);
@@ -3106,7 +3126,10 @@
bool os::committed_in_range(address start, size_t size, address& committed_start, size_t& committed_size) {
int mincore_return_value;
const size_t stripe = 1024; // query this many pages each time
- unsigned char vec[stripe];
+ unsigned char vec[stripe + 1];
+ // set a guard
+ vec[stripe] = 'X';
+
const size_t page_sz = os::vm_page_size();
size_t pages = size / page_sz;
@@ -3118,7 +3141,9 @@
int loops = (pages + stripe - 1) / stripe;
int committed_pages = 0;
address loop_base = start;
- for (int index = 0; index < loops; index ++) {
+ bool found_range = false;
+
+ for (int index = 0; index < loops && !found_range; index ++) {
assert(pages > 0, "Nothing to do");
int pages_to_query = (pages >= stripe) ? stripe : pages;
pages -= pages_to_query;
@@ -3133,12 +3158,14 @@
return false;
}
+ assert(vec[stripe] == 'X', "overflow guard");
assert(mincore_return_value == 0, "Range must be valid");
// Process this stripe
for (int vecIdx = 0; vecIdx < pages_to_query; vecIdx ++) {
if ((vec[vecIdx] & 0x01) == 0) { // not committed
// End of current contiguous region
if (committed_start != NULL) {
+ found_range = true;
break;
}
} else { // committed
--- a/src/hotspot/os/linux/os_linux.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/os/linux/os_linux.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -113,6 +113,7 @@
static void print_container_info(outputStream* st);
static void print_distro_info(outputStream* st);
static void print_libversion_info(outputStream* st);
+ static void print_proc_sys_info(outputStream* st);
public:
static bool _stack_is_executable;
--- a/src/hotspot/os_cpu/linux_sparc/thread_linux_sparc.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/os_cpu/linux_sparc/thread_linux_sparc.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -35,6 +35,13 @@
return frame(last_Java_sp(), frame::unpatchable, _anchor.last_Java_pc());
}
+bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) {
+ ucontext_t* uc = (ucontext_t*) ucontext;
+ *fr_addr = frame((intptr_t*)uc->uc_mcontext.mc_i7, frame::unpatchable,
+ (address)uc->uc_mcontext.mc_gregs[MC_PC]);
+ return true;
+}
+
// For Forte Analyzer AsyncGetCallTrace profiling support - thread is
// currently interrupted by SIGPROF
bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
--- a/src/hotspot/os_cpu/linux_sparc/thread_linux_sparc.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/os_cpu/linux_sparc/thread_linux_sparc.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -85,8 +85,9 @@
_base_of_stack_pointer = sp;
}
- bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext,
- bool isInJava);
+ bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext, bool isInJava);
+
+ bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava);
// These routines are only used on cpu architectures that
// have separate register stacks (Itanium).
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os_cpu/linux_x86/gc/z/zAddress_linux_x86.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 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 OS_CPU_LINUX_X86_ZADDRESS_LINUX_X86_INLINE_HPP
+#define OS_CPU_LINUX_X86_ZADDRESS_LINUX_X86_INLINE_HPP
+
+inline uintptr_t ZAddress::address(uintptr_t value) {
+ return value;
+}
+
+#endif // OS_CPU_LINUX_X86_ZADDRESS_LINUX_X86_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os_cpu/linux_x86/gc/z/zBackingFile_linux_x86.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,360 @@
+/*
+ * 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 "gc/z/zArray.inline.hpp"
+#include "gc/z/zBackingFile_linux_x86.hpp"
+#include "gc/z/zBackingPath_linux_x86.hpp"
+#include "gc/z/zErrno.hpp"
+#include "gc/z/zLargePages.inline.hpp"
+#include "logging/log.hpp"
+#include "runtime/init.hpp"
+#include "runtime/os.hpp"
+#include "utilities/align.hpp"
+#include "utilities/debug.hpp"
+
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+// Filesystem names
+#define ZFILESYSTEM_TMPFS "tmpfs"
+#define ZFILESYSTEM_HUGETLBFS "hugetlbfs"
+
+// Sysfs file for transparent huge page on tmpfs
+#define ZFILENAME_SHMEM_ENABLED "/sys/kernel/mm/transparent_hugepage/shmem_enabled"
+
+// Default mount points
+#define ZMOUNTPOINT_TMPFS "/dev/shm"
+#define ZMOUNTPOINT_HUGETLBFS "/hugepages"
+
+// Java heap filename
+#define ZFILENAME_HEAP "java_heap"
+
+// Support for building on older Linux systems
+#ifndef __NR_memfd_create
+#define __NR_memfd_create 319
+#endif
+#ifndef MFD_CLOEXEC
+#define MFD_CLOEXEC 0x0001U
+#endif
+#ifndef MFD_HUGETLB
+#define MFD_HUGETLB 0x0004U
+#endif
+#ifndef O_CLOEXEC
+#define O_CLOEXEC 02000000
+#endif
+#ifndef O_TMPFILE
+#define O_TMPFILE (020000000 | O_DIRECTORY)
+#endif
+
+// Filesystem types, see statfs(2)
+#ifndef TMPFS_MAGIC
+#define TMPFS_MAGIC 0x01021994
+#endif
+#ifndef HUGETLBFS_MAGIC
+#define HUGETLBFS_MAGIC 0x958458f6
+#endif
+
+static int z_memfd_create(const char *name, unsigned int flags) {
+ return syscall(__NR_memfd_create, name, flags);
+}
+
+ZBackingFile::ZBackingFile() :
+ _fd(-1),
+ _filesystem(0),
+ _initialized(false) {
+
+ // Create backing file
+ _fd = create_fd(ZFILENAME_HEAP);
+ if (_fd == -1) {
+ return;
+ }
+
+ // Get filesystem type
+ struct statfs statfs_buf;
+ if (fstatfs(_fd, &statfs_buf) == -1) {
+ ZErrno err;
+ log_error(gc, init)("Failed to determine filesystem type for backing file (%s)", err.to_string());
+ return;
+ }
+ _filesystem = statfs_buf.f_type;
+
+ // Make sure we're on a supported filesystem
+ if (!is_tmpfs() && !is_hugetlbfs()) {
+ log_error(gc, init)("Backing file must be located on a %s or a %s filesystem", ZFILESYSTEM_TMPFS, ZFILESYSTEM_HUGETLBFS);
+ return;
+ }
+
+ // Make sure the filesystem type matches requested large page type
+ if (ZLargePages::is_transparent() && !is_tmpfs()) {
+ log_error(gc, init)("-XX:+UseTransparentHugePages can only be enable when using a %s filesystem", ZFILESYSTEM_TMPFS);
+ return;
+ }
+
+ if (ZLargePages::is_transparent() && !tmpfs_supports_transparent_huge_pages()) {
+ log_error(gc, init)("-XX:+UseTransparentHugePages on a %s filesystem not supported by kernel", ZFILESYSTEM_TMPFS);
+ return;
+ }
+
+ if (ZLargePages::is_explicit() && !is_hugetlbfs()) {
+ log_error(gc, init)("-XX:+UseLargePages (without -XX:+UseTransparentHugePages) can only be enabled when using a %s filesystem", ZFILESYSTEM_HUGETLBFS);
+ return;
+ }
+
+ if (!ZLargePages::is_explicit() && is_hugetlbfs()) {
+ log_error(gc, init)("-XX:+UseLargePages must be enabled when using a %s filesystem", ZFILESYSTEM_HUGETLBFS);
+ return;
+ }
+
+ // Successfully initialized
+ _initialized = true;
+}
+
+int ZBackingFile::create_mem_fd(const char* name) const {
+ // Create file name
+ char filename[PATH_MAX];
+ snprintf(filename, sizeof(filename), "%s%s", name, ZLargePages::is_explicit() ? ".hugetlb" : "");
+
+ // Create file
+ const int extra_flags = ZLargePages::is_explicit() ? MFD_HUGETLB : 0;
+ const int fd = z_memfd_create(filename, MFD_CLOEXEC | extra_flags);
+ if (fd == -1) {
+ ZErrno err;
+ log_debug(gc, init)("Failed to create memfd file (%s)",
+ ((UseLargePages && err == EINVAL) ? "Hugepages not supported" : err.to_string()));
+ return -1;
+ }
+
+ log_debug(gc, init)("Heap backed by file /memfd:%s", filename);
+
+ return fd;
+}
+
+int ZBackingFile::create_file_fd(const char* name) const {
+ const char* const filesystem = ZLargePages::is_explicit() ? ZFILESYSTEM_HUGETLBFS : ZFILESYSTEM_TMPFS;
+ const char* const mountpoint = ZLargePages::is_explicit() ? ZMOUNTPOINT_HUGETLBFS : ZMOUNTPOINT_TMPFS;
+
+ // Find mountpoint
+ ZBackingPath path(filesystem, mountpoint);
+ if (path.get() == NULL) {
+ log_error(gc, init)("Use -XX:ZPath to specify the path to a %s filesystem", filesystem);
+ return -1;
+ }
+
+ // Try to create an anonymous file using the O_TMPFILE flag. Note that this
+ // flag requires kernel >= 3.11. If this fails we fall back to open/unlink.
+ const int fd_anon = open(path.get(), O_TMPFILE|O_EXCL|O_RDWR|O_CLOEXEC, S_IRUSR|S_IWUSR);
+ if (fd_anon == -1) {
+ ZErrno err;
+ log_debug(gc, init)("Failed to create anonymouns file in %s (%s)", path.get(),
+ (err == EINVAL ? "Not supported" : err.to_string()));
+ } else {
+ // Get inode number for anonymous file
+ struct stat stat_buf;
+ if (fstat(fd_anon, &stat_buf) == -1) {
+ ZErrno err;
+ log_error(gc, init)("Failed to determine inode number for anonymous file (%s)", err.to_string());
+ return -1;
+ }
+
+ log_debug(gc, init)("Heap backed by file %s/#" UINT64_FORMAT, path.get(), (uint64_t)stat_buf.st_ino);
+
+ return fd_anon;
+ }
+
+ log_debug(gc, init)("Falling back to open/unlink");
+
+ // Create file name
+ char filename[PATH_MAX];
+ snprintf(filename, sizeof(filename), "%s/%s.%d", path.get(), name, os::current_process_id());
+
+ // Create file
+ const int fd = open(filename, O_CREAT|O_EXCL|O_RDWR|O_CLOEXEC, S_IRUSR|S_IWUSR);
+ if (fd == -1) {
+ ZErrno err;
+ log_error(gc, init)("Failed to create file %s (%s)", filename, err.to_string());
+ return -1;
+ }
+
+ // Unlink file
+ if (unlink(filename) == -1) {
+ ZErrno err;
+ log_error(gc, init)("Failed to unlink file %s (%s)", filename, err.to_string());
+ return -1;
+ }
+
+ log_debug(gc, init)("Heap backed by file %s", filename);
+
+ return fd;
+}
+
+int ZBackingFile::create_fd(const char* name) const {
+ if (ZPath == NULL) {
+ // If the path is not explicitly specified, then we first try to create a memfd file
+ // instead of looking for a tmpfd/hugetlbfs mount point. Note that memfd_create() might
+ // not be supported at all (requires kernel >= 3.17), or it might not support large
+ // pages (requires kernel >= 4.14). If memfd_create() fails, then we try to create a
+ // file on an accessible tmpfs or hugetlbfs mount point.
+ const int fd = create_mem_fd(name);
+ if (fd != -1) {
+ return fd;
+ }
+
+ log_debug(gc, init)("Falling back to searching for an accessible moint point");
+ }
+
+ return create_file_fd(name);
+}
+
+bool ZBackingFile::is_initialized() const {
+ return _initialized;
+}
+
+int ZBackingFile::fd() const {
+ return _fd;
+}
+
+bool ZBackingFile::is_tmpfs() const {
+ return _filesystem == TMPFS_MAGIC;
+}
+
+bool ZBackingFile::is_hugetlbfs() const {
+ return _filesystem == HUGETLBFS_MAGIC;
+}
+
+bool ZBackingFile::tmpfs_supports_transparent_huge_pages() const {
+ // If the shmem_enabled file exists and is readable then we
+ // know the kernel supports transparent huge pages for tmpfs.
+ return access(ZFILENAME_SHMEM_ENABLED, R_OK) == 0;
+}
+
+bool ZBackingFile::try_split_and_expand_tmpfs(size_t offset, size_t length, size_t alignment) const {
+ // Try first smaller part.
+ const size_t offset0 = offset;
+ const size_t length0 = align_up(length / 2, alignment);
+ if (!try_expand_tmpfs(offset0, length0, alignment)) {
+ return false;
+ }
+
+ // Try second smaller part.
+ const size_t offset1 = offset0 + length0;
+ const size_t length1 = length - length0;
+ if (!try_expand_tmpfs(offset1, length1, alignment)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool ZBackingFile::try_expand_tmpfs(size_t offset, size_t length, size_t alignment) const {
+ assert(length > 0, "Invalid length");
+ assert(is_aligned(length, alignment), "Invalid length");
+
+ ZErrno err = posix_fallocate(_fd, offset, length);
+
+ if (err == EINTR && length > alignment) {
+ // Calling posix_fallocate() with a large length can take a long
+ // time to complete. When running profilers, such as VTune, this
+ // syscall will be constantly interrupted by signals. Expanding
+ // the file in smaller steps avoids this problem.
+ return try_split_and_expand_tmpfs(offset, length, alignment);
+ }
+
+ if (err) {
+ log_error(gc)("Failed to allocate backing file (%s)", err.to_string());
+ return false;
+ }
+
+ return true;
+}
+
+bool ZBackingFile::expand_tmpfs(size_t offset, size_t length) const {
+ assert(is_tmpfs(), "Wrong filesystem");
+ return try_expand_tmpfs(offset, length, os::vm_page_size());
+}
+
+bool ZBackingFile::expand_hugetlbfs(size_t offset, size_t length) const {
+ assert(is_hugetlbfs(), "Wrong filesystem");
+
+ // Prior to kernel 4.3, hugetlbfs did not support posix_fallocate().
+ // Instead of posix_fallocate() we can use a well-known workaround,
+ // which involves truncating the file to requested size and then try
+ // to map it to verify that there are enough huge pages available to
+ // back it.
+ while (ftruncate(_fd, offset + length) == -1) {
+ ZErrno err;
+ if (err != EINTR) {
+ log_error(gc)("Failed to truncate backing file (%s)", err.to_string());
+ return false;
+ }
+ }
+
+ // If we fail mapping during initialization, i.e. when we are pre-mapping
+ // the heap, then we wait and retry a few times before giving up. Otherwise
+ // there is a risk that running JVMs back-to-back will fail, since there
+ // is a delay between process termination and the huge pages owned by that
+ // process being returned to the huge page pool and made available for new
+ // allocations.
+ void* addr = MAP_FAILED;
+ const int max_attempts = 3;
+ for (int attempt = 1; attempt <= max_attempts; attempt++) {
+ addr = mmap(0, length, PROT_READ|PROT_WRITE, MAP_SHARED, _fd, offset);
+ if (addr != MAP_FAILED || is_init_completed()) {
+ // Mapping was successful or initialization phase has completed
+ break;
+ }
+
+ ZErrno err;
+ log_debug(gc)("Failed to map backing file (%s), attempt %d of %d",
+ err.to_string(), attempt, max_attempts);
+
+ // Wait and retry in one second, in the hope that
+ // huge pages will be available by then.
+ sleep(1);
+ }
+
+ if (addr == MAP_FAILED) {
+ // Not enough huge pages left
+ ZErrno err;
+ log_error(gc)("Failed to map backing file (%s)", err.to_string());
+ return false;
+ }
+
+ // Successful mapping, unmap again. From now on the pages we mapped
+ // will be reserved for this file.
+ if (munmap(addr, length) == -1) {
+ ZErrno err;
+ log_error(gc)("Failed to unmap backing file (%s)", err.to_string());
+ return false;
+ }
+
+ return true;
+}
+
+bool ZBackingFile::expand(size_t offset, size_t length) const {
+ return is_hugetlbfs() ? expand_hugetlbfs(offset, length) : expand_tmpfs(offset, length);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os_cpu/linux_x86/gc/z/zBackingFile_linux_x86.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef OS_CPU_LINUX_X86_ZBACKINGFILE_LINUX_X86_HPP
+#define OS_CPU_LINUX_X86_ZBACKINGFILE_LINUX_X86_HPP
+
+#include "memory/allocation.hpp"
+
+class ZBackingFile {
+private:
+ int _fd;
+ uint64_t _filesystem;
+ bool _initialized;
+
+ int create_mem_fd(const char* name) const;
+ int create_file_fd(const char* name) const;
+ int create_fd(const char* name) const;
+
+ bool is_tmpfs() const;
+ bool is_hugetlbfs() const;
+ bool tmpfs_supports_transparent_huge_pages() const;
+
+ bool try_split_and_expand_tmpfs(size_t offset, size_t length, size_t alignment) const;
+ bool try_expand_tmpfs(size_t offset, size_t length, size_t alignment) const;
+ bool expand_tmpfs(size_t offset, size_t length) const;
+
+ bool expand_hugetlbfs(size_t offset, size_t length) const;
+
+public:
+ ZBackingFile();
+
+ bool is_initialized() const;
+
+ int fd() const;
+ bool expand(size_t offset, size_t length) const;
+};
+
+#endif // OS_CPU_LINUX_X86_ZBACKINGFILE_LINUX_X86_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os_cpu/linux_x86/gc/z/zBackingPath_linux_x86.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,141 @@
+/*
+ * 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 "gc/z/zArray.inline.hpp"
+#include "gc/z/zBackingPath_linux_x86.hpp"
+#include "gc/z/zErrno.hpp"
+#include "logging/log.hpp"
+
+#include <stdio.h>
+#include <unistd.h>
+
+// Mount information, see proc(5) for more details.
+#define PROC_SELF_MOUNTINFO "/proc/self/mountinfo"
+
+ZBackingPath::ZBackingPath(const char* filesystem, const char* preferred_path) {
+ if (ZPath != NULL) {
+ // Use specified path
+ _path = strdup(ZPath);
+ } else {
+ // Find suitable path
+ _path = find_mountpoint(filesystem, preferred_path);
+ }
+}
+
+ZBackingPath::~ZBackingPath() {
+ free(_path);
+ _path = NULL;
+}
+
+char* ZBackingPath::get_mountpoint(const char* line, const char* filesystem) const {
+ char* line_mountpoint = NULL;
+ char* line_filesystem = NULL;
+
+ // Parse line and return a newly allocated string containing the mountpoint if
+ // the line contains a matching filesystem and the mountpoint is accessible by
+ // the current user.
+ if (sscanf(line, "%*u %*u %*u:%*u %*s %ms %*[^-]- %ms", &line_mountpoint, &line_filesystem) != 2 ||
+ strcmp(line_filesystem, filesystem) != 0 ||
+ access(line_mountpoint, R_OK|W_OK|X_OK) != 0) {
+ // Not a matching or accessible filesystem
+ free(line_mountpoint);
+ line_mountpoint = NULL;
+ }
+
+ free(line_filesystem);
+
+ return line_mountpoint;
+}
+
+void ZBackingPath::get_mountpoints(ZArray<char*>* mountpoints, const char* filesystem) const {
+ FILE* fd = fopen(PROC_SELF_MOUNTINFO, "r");
+ if (fd == NULL) {
+ ZErrno err;
+ log_error(gc, init)("Failed to open %s: %s", PROC_SELF_MOUNTINFO, err.to_string());
+ return;
+ }
+
+ char* line = NULL;
+ size_t length = 0;
+
+ while (getline(&line, &length, fd) != -1) {
+ char* const mountpoint = get_mountpoint(line, filesystem);
+ if (mountpoint != NULL) {
+ mountpoints->add(mountpoint);
+ }
+ }
+
+ free(line);
+ fclose(fd);
+}
+
+void ZBackingPath::free_mountpoints(ZArray<char*>* mountpoints) const {
+ ZArrayIterator<char*> iter(mountpoints);
+ for (char* mountpoint; iter.next(&mountpoint);) {
+ free(mountpoint);
+ }
+ mountpoints->clear();
+}
+
+char* ZBackingPath::find_mountpoint(const char* filesystem, const char* preferred_mountpoint) const {
+ char* path = NULL;
+ ZArray<char*> mountpoints;
+
+ get_mountpoints(&mountpoints, filesystem);
+
+ if (mountpoints.size() == 0) {
+ // No filesystem found
+ log_error(gc, init)("Failed to find an accessible %s filesystem", filesystem);
+ } else if (mountpoints.size() == 1) {
+ // One filesystem found
+ path = strdup(mountpoints.at(0));
+ } else if (mountpoints.size() > 1) {
+ // More than one filesystem found
+ ZArrayIterator<char*> iter(&mountpoints);
+ for (char* mountpoint; iter.next(&mountpoint);) {
+ if (!strcmp(mountpoint, preferred_mountpoint)) {
+ // Preferred mount point found
+ path = strdup(mountpoint);
+ break;
+ }
+ }
+
+ if (path == NULL) {
+ // Preferred mount point not found
+ log_error(gc, init)("More than one %s filesystem found:", filesystem);
+ ZArrayIterator<char*> iter2(&mountpoints);
+ for (char* mountpoint; iter2.next(&mountpoint);) {
+ log_error(gc, init)(" %s", mountpoint);
+ }
+ }
+ }
+
+ free_mountpoints(&mountpoints);
+
+ return path;
+}
+
+const char* ZBackingPath::get() const {
+ return _path;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os_cpu/linux_x86/gc/z/zBackingPath_linux_x86.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#ifndef OS_CPU_LINUX_X86_ZBACKINGPATH_LINUX_X86_HPP
+#define OS_CPU_LINUX_X86_ZBACKINGPATH_LINUX_X86_HPP
+
+#include "gc/z/zArray.hpp"
+#include "memory/allocation.hpp"
+
+class ZBackingPath : public StackObj {
+private:
+ char* _path;
+
+ char* get_mountpoint(const char* line, const char* filesystem) const;
+ void get_mountpoints(ZArray<char*>* mountpoints, const char* filesystem) const;
+ void free_mountpoints(ZArray<char*>* mountpoints) const;
+ char* find_mountpoint(const char* filesystem, const char* preferred_mountpoint) const;
+
+public:
+ ZBackingPath(const char* filesystem, const char* preferred_path);
+ ~ZBackingPath();
+
+ const char* get() const;
+};
+
+#endif // OS_CPU_LINUX_X86_ZBACKINGPATH_LINUX_X86_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os_cpu/linux_x86/gc/z/zGlobals_linux_x86.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 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 "gc/z/zGlobals.hpp"
+
+uintptr_t ZAddressReservedStart() {
+ return ZAddressMetadataMarked0;
+}
+
+uintptr_t ZAddressReservedEnd() {
+ return ZAddressMetadataRemapped + ZAddressOffsetMax;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os_cpu/linux_x86/gc/z/zGlobals_linux_x86.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,88 @@
+/*
+ * 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 OS_CPU_LINUX_X86_ZGLOBALS_LINUX_X86_HPP
+#define OS_CPU_LINUX_X86_ZGLOBALS_LINUX_X86_HPP
+
+//
+// Page Allocation Tiers
+// ---------------------
+//
+// Page Type Page Size Object Size Limit Object Alignment
+// ------------------------------------------------------------------
+// Small 2M <= 265K <MinObjAlignmentInBytes>
+// Medium 32M <= 4M 4K
+// Large X*M > 4M 2M
+// ------------------------------------------------------------------
+//
+//
+// Address Space & Pointer Layout
+// ------------------------------
+//
+// +--------------------------------+ 0x00007FFFFFFFFFFF (127TB)
+// . .
+// . .
+// . .
+// +--------------------------------+ 0x0000140000000000 (20TB)
+// | Remapped View |
+// +--------------------------------+ 0x0000100000000000 (16TB)
+// | (Reserved, but unused) |
+// +--------------------------------+ 0x00000c0000000000 (12TB)
+// | Marked1 View |
+// +--------------------------------+ 0x0000080000000000 (8TB)
+// | Marked0 View |
+// +--------------------------------+ 0x0000040000000000 (4TB)
+// . .
+// +--------------------------------+ 0x0000000000000000
+//
+//
+// 6 4 4 4 4 4 0
+// 3 7 6 5 2 1 0
+// +-------------------+-+----+-----------------------------------------------+
+// |00000000 00000000 0|0|1111|11 11111111 11111111 11111111 11111111 11111111|
+// +-------------------+-+----+-----------------------------------------------+
+// | | | |
+// | | | * 41-0 Object Offset (42-bits, 4TB address space)
+// | | |
+// | | * 45-42 Metadata Bits (4-bits) 0001 = Marked0 (Address view 4-8TB)
+// | | 0010 = Marked1 (Address view 8-12TB)
+// | | 0100 = Remapped (Address view 16-20TB)
+// | | 1000 = Finalizable (Address view N/A)
+// | |
+// | * 46-46 Unused (1-bit, always zero)
+// |
+// * 63-47 Fixed (17-bits, always zero)
+//
+
+const size_t ZPlatformPageSizeSmallShift = 21; // 2M
+
+const size_t ZPlatformAddressOffsetBits = 42; // 4TB
+
+const uintptr_t ZPlatformAddressMetadataShift = ZPlatformAddressOffsetBits;
+
+const uintptr_t ZPlatformAddressSpaceStart = (uintptr_t)1 << ZPlatformAddressOffsetBits;
+const uintptr_t ZPlatformAddressSpaceSize = ((uintptr_t)1 << ZPlatformAddressOffsetBits) * 4;
+
+const size_t ZPlatformCacheLineSize = 64;
+
+#endif // OS_CPU_LINUX_X86_ZGLOBALS_LINUX_X86_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os_cpu/linux_x86/gc/z/zLargePages_linux_x86.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 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 "gc/z/zLargePages.hpp"
+#include "runtime/globals.hpp"
+
+void ZLargePages::initialize_platform() {
+ if (UseLargePages) {
+ if (UseTransparentHugePages) {
+ _state = Transparent;
+ } else {
+ _state = Explicit;
+ }
+ } else {
+ _state = Disabled;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os_cpu/linux_x86/gc/z/zNUMA_linux_x86.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,83 @@
+/*
+ * 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 "gc/z/zErrno.hpp"
+#include "gc/z/zCPU.hpp"
+#include "gc/z/zNUMA.hpp"
+#include "runtime/os.hpp"
+#include "utilities/debug.hpp"
+
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#ifndef MPOL_F_NODE
+#define MPOL_F_NODE (1<<0) /* return next IL mode instead of node mask */
+#endif
+
+#ifndef MPOL_F_ADDR
+#define MPOL_F_ADDR (1<<1) /* look up vma using address */
+#endif
+
+static int z_get_mempolicy(uint32_t* mode, const unsigned long *nmask, unsigned long maxnode, uintptr_t addr, int flags) {
+ return syscall(__NR_get_mempolicy, mode, nmask, maxnode, addr, flags);
+}
+
+void ZNUMA::initialize_platform() {
+ _enabled = UseNUMA;
+}
+
+uint32_t ZNUMA::count() {
+ if (!_enabled) {
+ // NUMA support not enabled
+ return 1;
+ }
+
+ return os::Linux::numa_max_node() + 1;
+}
+
+uint32_t ZNUMA::id() {
+ if (!_enabled) {
+ // NUMA support not enabled
+ return 0;
+ }
+
+ return os::Linux::get_node_by_cpu(ZCPU::id());
+}
+
+uint32_t ZNUMA::memory_id(uintptr_t addr) {
+ if (!_enabled) {
+ // NUMA support not enabled, assume everything belongs to node zero
+ return 0;
+ }
+
+ uint32_t id = (uint32_t)-1;
+
+ if (z_get_mempolicy(&id, NULL, 0, addr, MPOL_F_NODE | MPOL_F_ADDR) == -1) {
+ ZErrno err;
+ fatal("Failed to get NUMA id for memory at " PTR_FORMAT " (%s)", addr, err.to_string());
+ }
+
+ assert(id < count(), "Invalid NUMA id");
+
+ return id;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os_cpu/linux_x86/gc/z/zPhysicalMemoryBacking_linux_x86.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,237 @@
+/*
+ * 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 "gc/z/zAddress.inline.hpp"
+#include "gc/z/zBackingFile_linux_x86.hpp"
+#include "gc/z/zErrno.hpp"
+#include "gc/z/zLargePages.inline.hpp"
+#include "gc/z/zMemory.hpp"
+#include "gc/z/zNUMA.hpp"
+#include "gc/z/zPhysicalMemory.inline.hpp"
+#include "gc/z/zPhysicalMemoryBacking_linux_x86.hpp"
+#include "logging/log.hpp"
+#include "runtime/os.hpp"
+#include "utilities/align.hpp"
+#include "utilities/debug.hpp"
+
+#include <stdio.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+
+// Support for building on older Linux systems
+#ifndef MADV_HUGEPAGE
+#define MADV_HUGEPAGE 14
+#endif
+
+// Proc file entry for max map mount
+#define ZFILENAME_PROC_MAX_MAP_COUNT "/proc/sys/vm/max_map_count"
+
+ZPhysicalMemoryBacking::ZPhysicalMemoryBacking(size_t max_capacity, size_t granule_size) :
+ _manager(),
+ _file(),
+ _granule_size(granule_size) {
+
+ // Check and warn if max map count seems too low
+ check_max_map_count(max_capacity, granule_size);
+}
+
+void ZPhysicalMemoryBacking::check_max_map_count(size_t max_capacity, size_t granule_size) const {
+ const char* const filename = ZFILENAME_PROC_MAX_MAP_COUNT;
+ FILE* const file = fopen(filename, "r");
+ if (file == NULL) {
+ // Failed to open file, skip check
+ log_debug(gc)("Failed to open %s", filename);
+ return;
+ }
+
+ size_t actual_max_map_count = 0;
+ const int result = fscanf(file, SIZE_FORMAT, &actual_max_map_count);
+ fclose(file);
+ if (result != 1) {
+ // Failed to read file, skip check
+ log_debug(gc)("Failed to read %s", filename);
+ return;
+ }
+
+ // The required max map count is impossible to calculate exactly since subsystems
+ // other than ZGC are also creating memory mappings, and we have no control over that.
+ // However, ZGC tends to create the most mappings and dominate the total count.
+ // In the worst cases, ZGC will map each granule three times, i.e. once per heap view.
+ // We speculate that we need another 20% to allow for non-ZGC subsystems to map memory.
+ const size_t required_max_map_count = (max_capacity / granule_size) * 3 * 1.2;
+ if (actual_max_map_count < required_max_map_count) {
+ log_warning(gc)("The system limit on number of memory mappings "
+ "per process might be too low for the given");
+ log_warning(gc)("Java heap size (" SIZE_FORMAT "M). Please "
+ "adjust %s to allow for at least", max_capacity / M, filename);
+ log_warning(gc)(SIZE_FORMAT " mappings (current limit is " SIZE_FORMAT "). "
+ "Continuing execution with the current limit could",
+ required_max_map_count, actual_max_map_count);
+ log_warning(gc)("lead to a fatal error down the line, due to failed "
+ "attempts to map memory.");
+ }
+}
+
+bool ZPhysicalMemoryBacking::is_initialized() const {
+ return _file.is_initialized();
+}
+
+bool ZPhysicalMemoryBacking::expand(size_t from, size_t to) {
+ const size_t size = to - from;
+
+ // Expand
+ if (!_file.expand(from, size)) {
+ return false;
+ }
+
+ // Add expanded space to free list
+ _manager.free(from, size);
+
+ return true;
+}
+
+ZPhysicalMemory ZPhysicalMemoryBacking::alloc(size_t size) {
+ assert(is_aligned(size, _granule_size), "Invalid size");
+
+ ZPhysicalMemory pmem;
+
+ // Allocate segments
+ for (size_t allocated = 0; allocated < size; allocated += _granule_size) {
+ const uintptr_t start = _manager.alloc_from_front(_granule_size);
+ assert(start != UINTPTR_MAX, "Allocation should never fail");
+ pmem.add_segment(ZPhysicalMemorySegment(start, _granule_size));
+ }
+
+ return pmem;
+}
+
+void ZPhysicalMemoryBacking::free(ZPhysicalMemory pmem) {
+ const size_t nsegments = pmem.nsegments();
+
+ // Free segments
+ for (size_t i = 0; i < nsegments; i++) {
+ const ZPhysicalMemorySegment segment = pmem.segment(i);
+ _manager.free(segment.start(), segment.size());
+ }
+}
+
+void ZPhysicalMemoryBacking::map_failed(ZErrno err) const {
+ if (err == ENOMEM) {
+ fatal("Failed to map memory. Please check the system limit on number of "
+ "memory mappings allowed per process (see %s)", ZFILENAME_PROC_MAX_MAP_COUNT);
+ } else {
+ fatal("Failed to map memory (%s)", err.to_string());
+ }
+}
+
+void ZPhysicalMemoryBacking::advise_view(uintptr_t addr, size_t size) const {
+ if (madvise((void*)addr, size, MADV_HUGEPAGE) == -1) {
+ ZErrno err;
+ log_error(gc)("Failed to advise use of transparent huge pages (%s)", err.to_string());
+ }
+}
+
+void ZPhysicalMemoryBacking::pretouch_view(uintptr_t addr, size_t size) const {
+ const size_t page_size = ZLargePages::is_explicit() ? os::large_page_size() : os::vm_page_size();
+ os::pretouch_memory((void*)addr, (void*)(addr + size), page_size);
+}
+
+void ZPhysicalMemoryBacking::map_view(ZPhysicalMemory pmem, uintptr_t addr, bool pretouch) const {
+ const size_t nsegments = pmem.nsegments();
+
+ // Map segments
+ for (size_t i = 0; i < nsegments; i++) {
+ const ZPhysicalMemorySegment segment = pmem.segment(i);
+ const size_t size = segment.size();
+ const void* const res = mmap((void*)addr, size, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_SHARED, _file.fd(), segment.start());
+ if (res == MAP_FAILED) {
+ ZErrno err;
+ map_failed(err);
+ }
+
+ // Advise on use of transparent huge pages before touching it
+ if (ZLargePages::is_transparent()) {
+ advise_view(addr, size);
+ }
+
+ // NUMA interleave memory before touching it
+ ZNUMA::memory_interleave(addr, size);
+
+ if (pretouch) {
+ pretouch_view(addr, size);
+ }
+
+ addr += size;
+ }
+}
+
+void ZPhysicalMemoryBacking::unmap_view(ZPhysicalMemory pmem, uintptr_t addr) const {
+ // Note that we must keep the address space reservation intact and just detach
+ // the backing memory. For this reason we map a new anonymous, non-accessible
+ // and non-reserved page over the mapping instead of actually unmapping.
+ const size_t size = pmem.size();
+ const void* const res = mmap((void*)addr, size, PROT_NONE, MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0);
+ if (res == MAP_FAILED) {
+ ZErrno err;
+ map_failed(err);
+ }
+}
+
+uintptr_t ZPhysicalMemoryBacking::nmt_address(uintptr_t offset) const {
+ // From an NMT point of view we treat the first heap mapping (marked0) as committed
+ return ZAddress::marked0(offset);
+}
+
+void ZPhysicalMemoryBacking::map(ZPhysicalMemory pmem, uintptr_t offset) const {
+ if (ZUnmapBadViews) {
+ // Only map the good view, for debugging only
+ map_view(pmem, ZAddress::good(offset), AlwaysPreTouch);
+ } else {
+ // Map all views
+ map_view(pmem, ZAddress::marked0(offset), AlwaysPreTouch);
+ map_view(pmem, ZAddress::marked1(offset), AlwaysPreTouch);
+ map_view(pmem, ZAddress::remapped(offset), AlwaysPreTouch);
+ }
+}
+
+void ZPhysicalMemoryBacking::unmap(ZPhysicalMemory pmem, uintptr_t offset) const {
+ if (ZUnmapBadViews) {
+ // Only map the good view, for debugging only
+ unmap_view(pmem, ZAddress::good(offset));
+ } else {
+ // Unmap all views
+ unmap_view(pmem, ZAddress::marked0(offset));
+ unmap_view(pmem, ZAddress::marked1(offset));
+ unmap_view(pmem, ZAddress::remapped(offset));
+ }
+}
+
+void ZPhysicalMemoryBacking::flip(ZPhysicalMemory pmem, uintptr_t offset) const {
+ assert(ZUnmapBadViews, "Should be enabled");
+ const uintptr_t addr_good = ZAddress::good(offset);
+ const uintptr_t addr_bad = ZAddress::is_marked(ZAddressGoodMask) ? ZAddress::remapped(offset) : ZAddress::marked(offset);
+ // Map/Unmap views
+ map_view(pmem, addr_good, false /* pretouch */);
+ unmap_view(pmem, addr_bad);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os_cpu/linux_x86/gc/z/zPhysicalMemoryBacking_linux_x86.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef OS_CPU_LINUX_X86_ZPHYSICALMEMORYBACKING_LINUX_X86_HPP
+#define OS_CPU_LINUX_X86_ZPHYSICALMEMORYBACKING_LINUX_X86_HPP
+
+#include "gc/z/zBackingFile_linux_x86.hpp"
+#include "gc/z/zMemory.hpp"
+
+class ZErrno;
+class ZPhysicalMemory;
+
+class ZPhysicalMemoryBacking {
+private:
+ ZMemoryManager _manager;
+ ZBackingFile _file;
+ const size_t _granule_size;
+
+ void check_max_map_count(size_t max_capacity, size_t granule_size) const;
+ void map_failed(ZErrno err) const;
+
+ void advise_view(uintptr_t addr, size_t size) const;
+ void pretouch_view(uintptr_t addr, size_t size) const;
+ void map_view(ZPhysicalMemory pmem, uintptr_t addr, bool pretouch) const;
+ void unmap_view(ZPhysicalMemory pmem, uintptr_t addr) const;
+
+public:
+ ZPhysicalMemoryBacking(size_t max_capacity, size_t granule_size);
+
+ bool is_initialized() const;
+
+ bool expand(size_t from, size_t to);
+ ZPhysicalMemory alloc(size_t size);
+ void free(ZPhysicalMemory pmem);
+
+ uintptr_t nmt_address(uintptr_t offset) const;
+
+ void map(ZPhysicalMemory pmem, uintptr_t offset) const;
+ void unmap(ZPhysicalMemory pmem, uintptr_t offset) const;
+ void flip(ZPhysicalMemory pmem, uintptr_t offset) const;
+};
+
+#endif // OS_CPU_LINUX_X86_ZPHYSICALMEMORYBACKING_LINUX_X86_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os_cpu/linux_x86/gc/z/zVirtualMemory_linux_x86.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015, 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 "gc/z/zVirtualMemory.hpp"
+#include "logging/log.hpp"
+
+#include <sys/mman.h>
+#include <sys/types.h>
+
+bool ZVirtualMemoryManager::reserve(uintptr_t start, size_t size) {
+ // Reserve address space
+ const uintptr_t actual_start = (uintptr_t)mmap((void*)start, size, PROT_NONE,
+ MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0);
+ if (actual_start != start) {
+ log_error(gc)("Failed to reserve address space for Java heap");
+ return false;
+ }
+
+ return true;
+}
--- a/src/hotspot/share/adlc/formssel.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/adlc/formssel.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -2282,6 +2282,9 @@
if (strcmp(name, "RegD") == 0) size = 2;
if (strcmp(name, "RegL") == 0) size = 2;
if (strcmp(name, "RegN") == 0) size = 1;
+ if (strcmp(name, "VecX") == 0) size = 4;
+ if (strcmp(name, "VecY") == 0) size = 8;
+ if (strcmp(name, "VecZ") == 0) size = 16;
if (strcmp(name, "RegP") == 0) size = globalAD->get_preproc_def("_LP64") ? 2 : 1;
if (size == 0) {
return false;
@@ -3509,6 +3512,7 @@
"ClearArray",
"GetAndSetB", "GetAndSetS", "GetAndAddI", "GetAndSetI", "GetAndSetP",
"GetAndAddB", "GetAndAddS", "GetAndAddL", "GetAndSetL", "GetAndSetN",
+ "LoadBarrierSlowReg", "LoadBarrierWeakSlowReg"
};
int cnt = sizeof(needs_ideal_memory_list)/sizeof(char*);
if( strcmp(_opType,"PrefetchAllocation")==0 )
--- a/src/hotspot/share/asm/codeBuffer.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/asm/codeBuffer.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -337,6 +337,7 @@
class CodeBuffer: public StackObj {
friend class CodeSection;
+ friend class StubCodeGenerator;
private:
// CodeBuffers must be allocated on the stack except for a single
--- a/src/hotspot/share/classfile/javaClasses.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/classfile/javaClasses.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -63,7 +63,6 @@
#include "runtime/vframe.inline.hpp"
#include "utilities/align.hpp"
#include "utilities/preserveException.hpp"
-
#if INCLUDE_JVMCI
#include "jvmci/jvmciJavaClasses.hpp"
#endif
@@ -798,7 +797,7 @@
// During bootstrap, java.lang.Class wasn't loaded so static field
// offsets were computed without the size added it. Go back and
// update all the static field offsets to included the size.
- for (JavaFieldStream fs(InstanceKlass::cast(k)); !fs.done(); fs.next()) {
+ for (JavaFieldStream fs(InstanceKlass::cast(k)); !fs.done(); fs.next()) {
if (fs.access_flags().is_static()) {
int real_offset = fs.offset() + InstanceMirrorKlass::offset_of_static_fields();
fs.set_offset(real_offset);
@@ -809,12 +808,8 @@
if (k->is_shared() && k->has_raw_archived_mirror()) {
if (MetaspaceShared::open_archive_heap_region_mapped()) {
- oop m = k->archived_java_mirror();
- assert(m != NULL, "archived mirror is NULL");
- assert(MetaspaceShared::is_archive_object(m), "must be archived mirror object");
- Handle m_h(THREAD, m);
- // restore_archived_mirror() clears the klass' _has_raw_archived_mirror flag
- restore_archived_mirror(k, m_h, Handle(), Handle(), Handle(), CHECK);
+ bool present = restore_archived_mirror(k, Handle(), Handle(), Handle(), CHECK);
+ assert(present, "Missing archived mirror for %s", k->external_name());
return;
} else {
k->set_java_mirror_handle(NULL);
@@ -1207,11 +1202,23 @@
return archived_mirror;
}
-// After the archived mirror object is restored, the shared klass'
-// _has_raw_archived_mirror flag is cleared
-void java_lang_Class::restore_archived_mirror(Klass *k, Handle mirror,
+// Returns true if the mirror is updated, false if no archived mirror
+// data is present. After the archived mirror object is restored, the
+// shared klass' _has_raw_archived_mirror flag is cleared.
+bool java_lang_Class::restore_archived_mirror(Klass *k,
Handle class_loader, Handle module,
Handle protection_domain, TRAPS) {
+ oop m = MetaspaceShared::materialize_archived_object(k->archived_java_mirror_raw());
+
+ if (m == NULL) {
+ return false;
+ }
+
+ log_debug(cds, mirror)("Archived mirror is: " PTR_FORMAT, p2i(m));
+
+ // mirror is archived, restore
+ assert(MetaspaceShared::is_archive_object(m), "must be archived mirror object");
+ Handle mirror(THREAD, m);
// The java.lang.Class field offsets were archived and reloaded from archive.
// No need to put classes on the fixup_mirror_list before java.lang.Class
@@ -1221,7 +1228,7 @@
// - local static final fields with initial values were initialized at dump time
// create the init_lock
- typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK);
+ typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK_(false));
set_init_lock(mirror(), r);
if (protection_domain.not_null()) {
@@ -1241,6 +1248,8 @@
ResourceMark rm;
log_trace(cds, mirror)("Restored %s archived mirror " PTR_FORMAT, k->external_name(), p2i(mirror()));
+
+ return true;
}
#endif // INCLUDE_CDS_JAVA_HEAP
--- a/src/hotspot/share/classfile/javaClasses.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/classfile/javaClasses.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -229,8 +229,9 @@
static oop archive_mirror(Klass* k, TRAPS) NOT_CDS_JAVA_HEAP_RETURN_(NULL);
static oop process_archived_mirror(Klass* k, oop mirror, oop archived_mirror, Thread *THREAD)
NOT_CDS_JAVA_HEAP_RETURN_(NULL);
- static void restore_archived_mirror(Klass *k, Handle mirror, Handle class_loader, Handle module,
- Handle protection_domain, TRAPS) NOT_CDS_JAVA_HEAP_RETURN;
+ static bool restore_archived_mirror(Klass *k, Handle class_loader, Handle module,
+ Handle protection_domain,
+ TRAPS) NOT_CDS_JAVA_HEAP_RETURN_(false);
static void fixup_module_field(Klass* k, Handle module);
--- a/src/hotspot/share/classfile/vmSymbols.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/classfile/vmSymbols.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -756,6 +756,9 @@
#endif // COMPILER1
#ifdef COMPILER2
case vmIntrinsics::_clone:
+#if INCLUDE_ZGC
+ if (UseZGC) return true;
+#endif
case vmIntrinsics::_copyOf:
case vmIntrinsics::_copyOfRange:
// These intrinsics use both the objectcopy and the arraycopy
--- a/src/hotspot/share/code/codeCache.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/code/codeCache.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -1609,6 +1609,7 @@
}
void CodeCache::print_summary(outputStream* st, bool detailed) {
+ int full_count = 0;
FOR_ALL_HEAPS(heap_iterator) {
CodeHeap* heap = (*heap_iterator);
size_t total = (heap->high_boundary() - heap->low_boundary());
@@ -1627,6 +1628,8 @@
p2i(heap->low_boundary()),
p2i(heap->high()),
p2i(heap->high_boundary()));
+
+ full_count += get_codemem_full_count(heap->code_blob_type());
}
}
@@ -1638,6 +1641,10 @@
"enabled" : Arguments::mode() == Arguments::_int ?
"disabled (interpreter mode)" :
"disabled (not enough contiguous free space left)");
+ st->print_cr(" stopped_count=%d, restarted_count=%d",
+ CompileBroker::get_total_compiler_stopped_count(),
+ CompileBroker::get_total_compiler_restarted_count());
+ st->print_cr(" full_count=%d", full_count);
}
}
--- a/src/hotspot/share/compiler/compileBroker.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/compiler/compileBroker.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -170,21 +170,23 @@
elapsedTimer CompileBroker::_t_invalidated_compilation;
elapsedTimer CompileBroker::_t_bailedout_compilation;
-int CompileBroker::_total_bailout_count = 0;
-int CompileBroker::_total_invalidated_count = 0;
-int CompileBroker::_total_compile_count = 0;
-int CompileBroker::_total_osr_compile_count = 0;
-int CompileBroker::_total_standard_compile_count = 0;
+int CompileBroker::_total_bailout_count = 0;
+int CompileBroker::_total_invalidated_count = 0;
+int CompileBroker::_total_compile_count = 0;
+int CompileBroker::_total_osr_compile_count = 0;
+int CompileBroker::_total_standard_compile_count = 0;
+int CompileBroker::_total_compiler_stopped_count = 0;
+int CompileBroker::_total_compiler_restarted_count = 0;
-int CompileBroker::_sum_osr_bytes_compiled = 0;
-int CompileBroker::_sum_standard_bytes_compiled = 0;
-int CompileBroker::_sum_nmethod_size = 0;
-int CompileBroker::_sum_nmethod_code_size = 0;
+int CompileBroker::_sum_osr_bytes_compiled = 0;
+int CompileBroker::_sum_standard_bytes_compiled = 0;
+int CompileBroker::_sum_nmethod_size = 0;
+int CompileBroker::_sum_nmethod_code_size = 0;
-long CompileBroker::_peak_compilation_time = 0;
+long CompileBroker::_peak_compilation_time = 0;
-CompileQueue* CompileBroker::_c2_compile_queue = NULL;
-CompileQueue* CompileBroker::_c1_compile_queue = NULL;
+CompileQueue* CompileBroker::_c2_compile_queue = NULL;
+CompileQueue* CompileBroker::_c1_compile_queue = NULL;
--- a/src/hotspot/share/compiler/compileBroker.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/compiler/compileBroker.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -219,6 +219,8 @@
static int _total_native_compile_count;
static int _total_osr_compile_count;
static int _total_standard_compile_count;
+ static int _total_compiler_stopped_count;
+ static int _total_compiler_restarted_count;
static int _sum_osr_bytes_compiled;
static int _sum_standard_bytes_compiled;
static int _sum_nmethod_size;
@@ -338,7 +340,15 @@
static bool set_should_compile_new_jobs(jint new_state) {
// Return success if the current caller set it
jint old = Atomic::cmpxchg(new_state, &_should_compile_new_jobs, 1-new_state);
- return (old == (1-new_state));
+ bool success = (old == (1-new_state));
+ if (success) {
+ if (new_state == run_compilation) {
+ _total_compiler_restarted_count++;
+ } else {
+ _total_compiler_stopped_count++;
+ }
+ }
+ return success;
}
static void disable_compilation_forever() {
@@ -393,18 +403,20 @@
static CompileLog* get_log(CompilerThread* ct);
- static int get_total_compile_count() { return _total_compile_count; }
- static int get_total_bailout_count() { return _total_bailout_count; }
- static int get_total_invalidated_count() { return _total_invalidated_count; }
- static int get_total_native_compile_count() { return _total_native_compile_count; }
- static int get_total_osr_compile_count() { return _total_osr_compile_count; }
- static int get_total_standard_compile_count() { return _total_standard_compile_count; }
- static int get_sum_osr_bytes_compiled() { return _sum_osr_bytes_compiled; }
- static int get_sum_standard_bytes_compiled() { return _sum_standard_bytes_compiled; }
- static int get_sum_nmethod_size() { return _sum_nmethod_size;}
- static int get_sum_nmethod_code_size() { return _sum_nmethod_code_size; }
- static long get_peak_compilation_time() { return _peak_compilation_time; }
- static long get_total_compilation_time() { return _t_total_compilation.milliseconds(); }
+ static int get_total_compile_count() { return _total_compile_count; }
+ static int get_total_bailout_count() { return _total_bailout_count; }
+ static int get_total_invalidated_count() { return _total_invalidated_count; }
+ static int get_total_native_compile_count() { return _total_native_compile_count; }
+ static int get_total_osr_compile_count() { return _total_osr_compile_count; }
+ static int get_total_standard_compile_count() { return _total_standard_compile_count; }
+ static int get_total_compiler_stopped_count() { return _total_compiler_stopped_count; }
+ static int get_total_compiler_restarted_count() { return _total_compiler_restarted_count; }
+ static int get_sum_osr_bytes_compiled() { return _sum_osr_bytes_compiled; }
+ static int get_sum_standard_bytes_compiled() { return _sum_standard_bytes_compiled; }
+ static int get_sum_nmethod_size() { return _sum_nmethod_size;}
+ static int get_sum_nmethod_code_size() { return _sum_nmethod_code_size; }
+ static long get_peak_compilation_time() { return _peak_compilation_time; }
+ static long get_total_compilation_time() { return _t_total_compilation.milliseconds(); }
// Log that compilation profiling is skipped because metaspace is full.
static void log_metaspace_failure();
--- a/src/hotspot/share/compiler/compilerDirectives.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/compiler/compilerDirectives.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -66,7 +66,8 @@
cflags(VectorizeDebug, uintx, 0, VectorizeDebug) \
cflags(CloneMapDebug, bool, false, CloneMapDebug) \
cflags(IGVPrintLevel, intx, PrintIdealGraphLevel, IGVPrintLevel) \
- cflags(MaxNodeLimit, intx, MaxNodeLimit, MaxNodeLimit)
+ cflags(MaxNodeLimit, intx, MaxNodeLimit, MaxNodeLimit) \
+ZGC_ONLY(cflags(ZOptimizeLoadBarriers, bool, ZOptimizeLoadBarriers, ZOptimizeLoadBarriers))
#else
#define compilerdirectives_c2_flags(cflags)
#endif
--- a/src/hotspot/share/compiler/disassembler.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/compiler/disassembler.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -155,6 +155,7 @@
CodeStrings _strings;
outputStream* _output;
address _start, _end;
+ ptrdiff_t _offset;
char _option_buf[512];
char _print_raw;
@@ -191,7 +192,8 @@
void print_address(address value);
public:
- decode_env(CodeBlob* code, outputStream* output, CodeStrings c = CodeStrings());
+ decode_env(CodeBlob* code, outputStream* output,
+ CodeStrings c = CodeStrings(), ptrdiff_t offset = 0);
address decode_instructions(address start, address end);
@@ -221,13 +223,15 @@
const char* options() { return _option_buf; }
};
-decode_env::decode_env(CodeBlob* code, outputStream* output, CodeStrings c) {
+decode_env::decode_env(CodeBlob* code, outputStream* output, CodeStrings c,
+ ptrdiff_t offset) {
memset(this, 0, sizeof(*this)); // Beware, this zeroes bits of fields.
_output = output ? output : tty;
_code = code;
if (code != NULL && code->is_nmethod())
_nm = (nmethod*) code;
_strings.copy(c);
+ _offset = offset;
// by default, output pc but not bytes:
_print_pc = true;
@@ -354,7 +358,7 @@
if (cb != NULL) {
cb->print_block_comment(st, p);
}
- _strings.print_block_comment(st, (intptr_t)(p - _start));
+ _strings.print_block_comment(st, (intptr_t)(p - _start + _offset));
if (_print_pc) {
st->print(" " PTR_FORMAT ": ", p2i(p));
}
@@ -507,10 +511,11 @@
env.decode_instructions(cb->code_begin(), cb->code_end());
}
-void Disassembler::decode(address start, address end, outputStream* st, CodeStrings c) {
+void Disassembler::decode(address start, address end, outputStream* st, CodeStrings c,
+ ptrdiff_t offset) {
ttyLocker ttyl;
if (!load_library()) return;
- decode_env env(CodeCache::find_blob_unsafe(start), st, c);
+ decode_env env(CodeCache::find_blob_unsafe(start), st, c, offset);
env.decode_instructions(start, end);
}
--- a/src/hotspot/share/compiler/disassembler.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/compiler/disassembler.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2016, 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
@@ -75,7 +75,8 @@
}
static void decode(CodeBlob *cb, outputStream* st = NULL);
static void decode(nmethod* nm, outputStream* st = NULL);
- static void decode(address begin, address end, outputStream* st = NULL, CodeStrings c = CodeStrings());
+ static void decode(address begin, address end, outputStream* st = NULL,
+ CodeStrings c = CodeStrings(), ptrdiff_t offset = 0);
};
#endif // SHARE_VM_COMPILER_DISASSEMBLER_HPP
--- a/src/hotspot/share/compiler/oopMap.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/compiler/oopMap.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -380,8 +380,12 @@
continue;
}
#ifdef ASSERT
- if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
- !Universe::heap()->is_in_or_null(*loc)) {
+ // We can not verify the oop here if we are using ZGC, the oop
+ // will be bad in case we had a safepoint between a load and a
+ // load barrier.
+ if (!UseZGC &&
+ ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
+ !Universe::heap()->is_in_or_null(*loc))) {
tty->print_cr("# Found non oop pointer. Dumping state at failure");
// try to dump out some helpful debugging information
trace_codeblob_maps(fr, reg_map);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilonArguments.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ * 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/epsilon/epsilonArguments.hpp"
+#include "gc/epsilon/epsilonHeap.hpp"
+#include "gc/epsilon/epsilonCollectorPolicy.hpp"
+#include "gc/shared/gcArguments.inline.hpp"
+#include "runtime/globals.hpp"
+#include "runtime/globals_extension.hpp"
+#include "runtime/vm_version.hpp"
+#include "utilities/macros.hpp"
+
+size_t EpsilonArguments::conservative_max_heap_alignment() {
+ return UseLargePages ? os::large_page_size() : os::vm_page_size();
+}
+
+void EpsilonArguments::initialize() {
+ GCArguments::initialize();
+
+ assert(UseEpsilonGC, "Sanity");
+
+ // Forcefully exit when OOME is detected. Nothing we can do at that point.
+ if (FLAG_IS_DEFAULT(ExitOnOutOfMemoryError)) {
+ FLAG_SET_DEFAULT(ExitOnOutOfMemoryError, true);
+ }
+
+ if (EpsilonMaxTLABSize < MinTLABSize) {
+ warning("EpsilonMaxTLABSize < MinTLABSize, adjusting it to " SIZE_FORMAT, MinTLABSize);
+ EpsilonMaxTLABSize = MinTLABSize;
+ }
+
+ if (!EpsilonElasticTLAB && EpsilonElasticTLABDecay) {
+ warning("Disabling EpsilonElasticTLABDecay because EpsilonElasticTLAB is disabled");
+ FLAG_SET_DEFAULT(EpsilonElasticTLABDecay, false);
+ }
+
+#ifdef COMPILER2
+ // Enable loop strip mining: there are still non-GC safepoints, no need to make it worse
+ if (FLAG_IS_DEFAULT(UseCountedLoopSafepoints)) {
+ FLAG_SET_DEFAULT(UseCountedLoopSafepoints, true);
+ if (FLAG_IS_DEFAULT(LoopStripMiningIter)) {
+ FLAG_SET_DEFAULT(LoopStripMiningIter, 1000);
+ }
+ }
+#endif
+}
+
+CollectedHeap* EpsilonArguments::create_heap() {
+ return create_heap_with_policy<EpsilonHeap, EpsilonCollectorPolicy>();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilonArguments.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ * 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_EPSILON_EPSILONARGUMENTS_HPP
+#define SHARE_GC_EPSILON_EPSILONARGUMENTS_HPP
+
+#include "gc/shared/gcArguments.hpp"
+
+class CollectedHeap;
+
+class EpsilonArguments : public GCArguments {
+public:
+ virtual void initialize();
+ virtual size_t conservative_max_heap_alignment();
+ virtual CollectedHeap* create_heap();
+};
+
+#endif // SHARE_GC_EPSILON_EPSILONARGUMENTS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilonBarrierSet.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ *
+ * 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 "runtime/thread.hpp"
+#include "gc/epsilon/epsilonBarrierSet.hpp"
+#include "gc/epsilon/epsilonThreadLocalData.hpp"
+#include "gc/shared/collectorPolicy.hpp"
+#include "gc/shared/barrierSet.hpp"
+#include "gc/shared/barrierSetAssembler.hpp"
+#include "utilities/macros.hpp"
+#ifdef COMPILER1
+#include "gc/shared/c1/barrierSetC1.hpp"
+#endif
+#ifdef COMPILER2
+#include "gc/shared/c2/barrierSetC2.hpp"
+#endif
+
+EpsilonBarrierSet::EpsilonBarrierSet() : BarrierSet(
+ make_barrier_set_assembler<BarrierSetAssembler>(),
+ make_barrier_set_c1<BarrierSetC1>(),
+ make_barrier_set_c2<BarrierSetC2>(),
+ BarrierSet::FakeRtti(BarrierSet::EpsilonBarrierSet)) {};
+
+void EpsilonBarrierSet::on_thread_create(Thread *thread) {
+ EpsilonThreadLocalData::create(thread);
+}
+
+void EpsilonBarrierSet::on_thread_destroy(Thread *thread) {
+ EpsilonThreadLocalData::destroy(thread);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilonBarrierSet.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ *
+ * 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_EPSILON_BARRIERSET_HPP
+#define SHARE_VM_GC_EPSILON_BARRIERSET_HPP
+
+#include "gc/shared/barrierSetAssembler.hpp"
+#include "gc/shared/barrierSet.hpp"
+
+// No interaction with application is required for Epsilon, and therefore
+// the barrier set is empty.
+class EpsilonBarrierSet: public BarrierSet {
+ friend class VMStructs;
+
+public:
+ EpsilonBarrierSet();
+
+ virtual void print_on(outputStream *st) const {}
+
+ virtual void on_thread_create(Thread* thread);
+ virtual void on_thread_destroy(Thread* thread);
+
+ template <DecoratorSet decorators, typename BarrierSetT = EpsilonBarrierSet>
+ class AccessBarrier: public BarrierSet::AccessBarrier<decorators, BarrierSetT> {};
+};
+
+template<>
+struct BarrierSet::GetName<EpsilonBarrierSet> {
+ static const BarrierSet::Name value = BarrierSet::EpsilonBarrierSet;
+};
+
+template<>
+struct BarrierSet::GetType<BarrierSet::EpsilonBarrierSet> {
+ typedef ::EpsilonBarrierSet type;
+};
+
+#endif // SHARE_VM_GC_EPSILON_BARRIERSET_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilonCollectorPolicy.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ *
+ * 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_EPSILON_COLLECTORPOLICY_HPP
+#define SHARE_VM_GC_EPSILON_COLLECTORPOLICY_HPP
+
+#include "gc/shared/collectorPolicy.hpp"
+
+class EpsilonCollectorPolicy: public CollectorPolicy {
+protected:
+ virtual void initialize_alignments() {
+ size_t page_size = UseLargePages ? os::large_page_size() : os::vm_page_size();
+ size_t align = MAX2((size_t)os::vm_allocation_granularity(), page_size);
+ _space_alignment = align;
+ _heap_alignment = align;
+ }
+
+public:
+ EpsilonCollectorPolicy() : CollectorPolicy() {};
+};
+
+#endif // SHARE_VM_GC_EPSILON_COLLECTORPOLICY_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilonHeap.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ *
+ * 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/epsilon/epsilonHeap.hpp"
+#include "gc/epsilon/epsilonMemoryPool.hpp"
+#include "gc/epsilon/epsilonThreadLocalData.hpp"
+#include "memory/allocation.hpp"
+#include "memory/allocation.inline.hpp"
+#include "memory/resourceArea.hpp"
+
+jint EpsilonHeap::initialize() {
+ size_t align = _policy->heap_alignment();
+ size_t init_byte_size = align_up(_policy->initial_heap_byte_size(), align);
+ size_t max_byte_size = align_up(_policy->max_heap_byte_size(), align);
+
+ // Initialize backing storage
+ ReservedSpace heap_rs = Universe::reserve_heap(max_byte_size, align);
+ _virtual_space.initialize(heap_rs, init_byte_size);
+
+ MemRegion committed_region((HeapWord*)_virtual_space.low(), (HeapWord*)_virtual_space.high());
+ MemRegion reserved_region((HeapWord*)_virtual_space.low_boundary(), (HeapWord*)_virtual_space.high_boundary());
+
+ initialize_reserved_region(reserved_region.start(), reserved_region.end());
+
+ _space = new ContiguousSpace();
+ _space->initialize(committed_region, /* clear_space = */ true, /* mangle_space = */ true);
+
+ // Precompute hot fields
+ _max_tlab_size = MIN2(CollectedHeap::max_tlab_size(), EpsilonMaxTLABSize / HeapWordSize);
+ _step_counter_update = MIN2<size_t>(max_byte_size / 16, EpsilonUpdateCountersStep);
+ _step_heap_print = (EpsilonPrintHeapSteps == 0) ? SIZE_MAX : (max_byte_size / EpsilonPrintHeapSteps);
+ _decay_time_ns = (int64_t) EpsilonTLABDecayTime * NANOSECS_PER_MILLISEC;
+
+ // Enable monitoring
+ _monitoring_support = new EpsilonMonitoringSupport(this);
+ _last_counter_update = 0;
+ _last_heap_print = 0;
+
+ // Install barrier set
+ BarrierSet::set_barrier_set(new EpsilonBarrierSet());
+
+ // All done, print out the configuration
+ if (init_byte_size != max_byte_size) {
+ log_info(gc)("Resizeable heap; starting at " SIZE_FORMAT "M, max: " SIZE_FORMAT "M, step: " SIZE_FORMAT "M",
+ init_byte_size / M, max_byte_size / M, EpsilonMinHeapExpand / M);
+ } else {
+ log_info(gc)("Non-resizeable heap; start/max: " SIZE_FORMAT "M", init_byte_size / M);
+ }
+
+ if (UseTLAB) {
+ log_info(gc)("Using TLAB allocation; max: " SIZE_FORMAT "K", _max_tlab_size * HeapWordSize / K);
+ if (EpsilonElasticTLAB) {
+ log_info(gc)("Elastic TLABs enabled; elasticity: %.2fx", EpsilonTLABElasticity);
+ }
+ if (EpsilonElasticTLABDecay) {
+ log_info(gc)("Elastic TLABs decay enabled; decay time: " SIZE_FORMAT "ms", EpsilonTLABDecayTime);
+ }
+ } else {
+ log_info(gc)("Not using TLAB allocation");
+ }
+
+ return JNI_OK;
+}
+
+void EpsilonHeap::post_initialize() {
+ CollectedHeap::post_initialize();
+}
+
+void EpsilonHeap::initialize_serviceability() {
+ _pool = new EpsilonMemoryPool(this);
+ _memory_manager.add_pool(_pool);
+}
+
+GrowableArray<GCMemoryManager*> EpsilonHeap::memory_managers() {
+ GrowableArray<GCMemoryManager*> memory_managers(1);
+ memory_managers.append(&_memory_manager);
+ return memory_managers;
+}
+
+GrowableArray<MemoryPool*> EpsilonHeap::memory_pools() {
+ GrowableArray<MemoryPool*> memory_pools(1);
+ memory_pools.append(_pool);
+ return memory_pools;
+}
+
+size_t EpsilonHeap::unsafe_max_tlab_alloc(Thread* thr) const {
+ // Return max allocatable TLAB size, and let allocation path figure out
+ // the actual TLAB allocation size.
+ return _max_tlab_size;
+}
+
+EpsilonHeap* EpsilonHeap::heap() {
+ CollectedHeap* heap = Universe::heap();
+ assert(heap != NULL, "Uninitialized access to EpsilonHeap::heap()");
+ assert(heap->kind() == CollectedHeap::Epsilon, "Not an Epsilon heap");
+ return (EpsilonHeap*)heap;
+}
+
+HeapWord* EpsilonHeap::allocate_work(size_t size) {
+ HeapWord* res = _space->par_allocate(size);
+
+ while (res == NULL) {
+ // Allocation failed, attempt expansion, and retry:
+ MutexLockerEx ml(Heap_lock);
+
+ size_t space_left = max_capacity() - capacity();
+ size_t want_space = MAX2(size, EpsilonMinHeapExpand);
+
+ if (want_space < space_left) {
+ // Enough space to expand in bulk:
+ bool expand = _virtual_space.expand_by(want_space);
+ assert(expand, "Should be able to expand");
+ } else if (size < space_left) {
+ // No space to expand in bulk, and this allocation is still possible,
+ // take all the remaining space:
+ bool expand = _virtual_space.expand_by(space_left);
+ assert(expand, "Should be able to expand");
+ } else {
+ // No space left:
+ return NULL;
+ }
+
+ _space->set_end((HeapWord *) _virtual_space.high());
+ res = _space->par_allocate(size);
+ }
+
+ size_t used = _space->used();
+
+ // Allocation successful, update counters
+ {
+ size_t last = _last_counter_update;
+ if ((used - last >= _step_counter_update) && Atomic::cmpxchg(used, &_last_counter_update, last) == last) {
+ _monitoring_support->update_counters();
+ }
+ }
+
+ // ...and print the occupancy line, if needed
+ {
+ size_t last = _last_heap_print;
+ if ((used - last >= _step_heap_print) && Atomic::cmpxchg(used, &_last_heap_print, last) == last) {
+ log_info(gc)("Heap: " SIZE_FORMAT "M reserved, " SIZE_FORMAT "M (%.2f%%) committed, " SIZE_FORMAT "M (%.2f%%) used",
+ max_capacity() / M,
+ capacity() / M,
+ capacity() * 100.0 / max_capacity(),
+ used / M,
+ used * 100.0 / max_capacity());
+ }
+ }
+
+ return res;
+}
+
+HeapWord* EpsilonHeap::allocate_new_tlab(size_t min_size,
+ size_t requested_size,
+ size_t* actual_size) {
+ Thread* thread = Thread::current();
+
+ // Defaults in case elastic paths are not taken
+ bool fits = true;
+ size_t size = requested_size;
+ size_t ergo_tlab = requested_size;
+ int64_t time = 0;
+
+ if (EpsilonElasticTLAB) {
+ ergo_tlab = EpsilonThreadLocalData::ergo_tlab_size(thread);
+
+ if (EpsilonElasticTLABDecay) {
+ int64_t last_time = EpsilonThreadLocalData::last_tlab_time(thread);
+ time = (int64_t) os::javaTimeNanos();
+
+ assert(last_time <= time, "time should be monotonic");
+
+ // If the thread had not allocated recently, retract the ergonomic size.
+ // This conserves memory when the thread had initial burst of allocations,
+ // and then started allocating only sporadically.
+ if (last_time != 0 && (time - last_time > _decay_time_ns)) {
+ ergo_tlab = 0;
+ EpsilonThreadLocalData::set_ergo_tlab_size(thread, 0);
+ }
+ }
+
+ // If we can fit the allocation under current TLAB size, do so.
+ // Otherwise, we want to elastically increase the TLAB size.
+ fits = (requested_size <= ergo_tlab);
+ if (!fits) {
+ size = (size_t) (ergo_tlab * EpsilonTLABElasticity);
+ }
+ }
+
+ // Always honor boundaries
+ size = MAX2(min_size, MIN2(_max_tlab_size, size));
+
+ if (log_is_enabled(Trace, gc)) {
+ ResourceMark rm;
+ log_trace(gc)("TLAB size for \"%s\" (Requested: " SIZE_FORMAT "K, Min: " SIZE_FORMAT
+ "K, Max: " SIZE_FORMAT "K, Ergo: " SIZE_FORMAT "K) -> " SIZE_FORMAT "K",
+ thread->name(),
+ requested_size * HeapWordSize / K,
+ min_size * HeapWordSize / K,
+ _max_tlab_size * HeapWordSize / K,
+ ergo_tlab * HeapWordSize / K,
+ size * HeapWordSize / K);
+ }
+
+ // All prepared, let's do it!
+ HeapWord* res = allocate_work(size);
+
+ if (res != NULL) {
+ // Allocation successful
+ *actual_size = size;
+ if (EpsilonElasticTLABDecay) {
+ EpsilonThreadLocalData::set_last_tlab_time(thread, time);
+ }
+ if (EpsilonElasticTLAB && !fits) {
+ // If we requested expansion, this is our new ergonomic TLAB size
+ EpsilonThreadLocalData::set_ergo_tlab_size(thread, size);
+ }
+ } else {
+ // Allocation failed, reset ergonomics to try and fit smaller TLABs
+ if (EpsilonElasticTLAB) {
+ EpsilonThreadLocalData::set_ergo_tlab_size(thread, 0);
+ }
+ }
+
+ return res;
+}
+
+HeapWord* EpsilonHeap::mem_allocate(size_t size, bool *gc_overhead_limit_was_exceeded) {
+ *gc_overhead_limit_was_exceeded = false;
+ return allocate_work(size);
+}
+
+void EpsilonHeap::collect(GCCause::Cause cause) {
+ log_info(gc)("GC request for \"%s\" is ignored", GCCause::to_string(cause));
+ _monitoring_support->update_counters();
+}
+
+void EpsilonHeap::do_full_collection(bool clear_all_soft_refs) {
+ log_info(gc)("Full GC request for \"%s\" is ignored", GCCause::to_string(gc_cause()));
+ _monitoring_support->update_counters();
+}
+
+void EpsilonHeap::safe_object_iterate(ObjectClosure *cl) {
+ _space->safe_object_iterate(cl);
+}
+
+void EpsilonHeap::print_on(outputStream *st) const {
+ st->print_cr("Epsilon Heap");
+
+ // Cast away constness:
+ ((VirtualSpace)_virtual_space).print_on(st);
+
+ st->print_cr("Allocation space:");
+ _space->print_on(st);
+}
+
+void EpsilonHeap::print_tracing_info() const {
+ Log(gc) log;
+ size_t allocated_kb = used() / K;
+ log.info("Total allocated: " SIZE_FORMAT " KB",
+ allocated_kb);
+ log.info("Average allocation rate: " SIZE_FORMAT " KB/sec",
+ (size_t)(allocated_kb * NANOSECS_PER_SEC / os::elapsed_counter()));
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilonHeap.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ *
+ * 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_EPSILON_COLLECTEDHEAP_HPP
+#define SHARE_VM_GC_EPSILON_COLLECTEDHEAP_HPP
+
+#include "gc/shared/collectedHeap.hpp"
+#include "gc/shared/softRefPolicy.hpp"
+#include "gc/shared/space.hpp"
+#include "services/memoryManager.hpp"
+#include "gc/epsilon/epsilonCollectorPolicy.hpp"
+#include "gc/epsilon/epsilonMonitoringSupport.hpp"
+#include "gc/epsilon/epsilonBarrierSet.hpp"
+#include "gc/epsilon/epsilon_globals.hpp"
+
+class EpsilonHeap : public CollectedHeap {
+ friend class VMStructs;
+private:
+ EpsilonCollectorPolicy* _policy;
+ SoftRefPolicy _soft_ref_policy;
+ EpsilonMonitoringSupport* _monitoring_support;
+ MemoryPool* _pool;
+ GCMemoryManager _memory_manager;
+ ContiguousSpace* _space;
+ VirtualSpace _virtual_space;
+ size_t _max_tlab_size;
+ size_t _step_counter_update;
+ size_t _step_heap_print;
+ int64_t _decay_time_ns;
+ volatile size_t _last_counter_update;
+ volatile size_t _last_heap_print;
+
+public:
+ static EpsilonHeap* heap();
+
+ EpsilonHeap(EpsilonCollectorPolicy* p) :
+ _policy(p),
+ _memory_manager("Epsilon Heap", "") {};
+
+ virtual Name kind() const {
+ return CollectedHeap::Epsilon;
+ }
+
+ virtual const char* name() const {
+ return "Epsilon";
+ }
+
+ virtual CollectorPolicy* collector_policy() const {
+ return _policy;
+ }
+
+ virtual SoftRefPolicy* soft_ref_policy() {
+ return &_soft_ref_policy;
+ }
+
+ virtual jint initialize();
+ virtual void post_initialize();
+ virtual void initialize_serviceability();
+
+ virtual GrowableArray<GCMemoryManager*> memory_managers();
+ virtual GrowableArray<MemoryPool*> memory_pools();
+
+ virtual size_t max_capacity() const { return _virtual_space.reserved_size(); }
+ virtual size_t capacity() const { return _virtual_space.committed_size(); }
+ virtual size_t used() const { return _space->used(); }
+
+ virtual bool is_in(const void* p) const {
+ return _space->is_in(p);
+ }
+
+ virtual bool is_scavengable(oop obj) {
+ // No GC is going to happen, therefore no objects ever move.
+ return false;
+ }
+
+ virtual bool is_maximal_no_gc() const {
+ // No GC is going to happen. Return "we are at max", when we are about to fail.
+ return used() == capacity();
+ }
+
+ // Allocation
+ HeapWord* allocate_work(size_t size);
+ virtual HeapWord* mem_allocate(size_t size, bool* gc_overhead_limit_was_exceeded);
+ virtual HeapWord* allocate_new_tlab(size_t min_size,
+ size_t requested_size,
+ size_t* actual_size);
+
+ // TLAB allocation
+ virtual bool supports_tlab_allocation() const { return true; }
+ virtual size_t tlab_capacity(Thread* thr) const { return capacity(); }
+ virtual size_t tlab_used(Thread* thr) const { return used(); }
+ virtual size_t max_tlab_size() const { return _max_tlab_size; }
+ virtual size_t unsafe_max_tlab_alloc(Thread* thr) const;
+
+ virtual void collect(GCCause::Cause cause);
+ virtual void do_full_collection(bool clear_all_soft_refs);
+
+ // Heap walking support
+ virtual void safe_object_iterate(ObjectClosure* cl);
+ virtual void object_iterate(ObjectClosure* cl) {
+ safe_object_iterate(cl);
+ }
+
+ // No support for block parsing.
+ virtual HeapWord* block_start(const void* addr) const { return NULL; }
+ virtual size_t block_size(const HeapWord* addr) const { return 0; }
+ virtual bool block_is_obj(const HeapWord* addr) const { return false; }
+
+ // No GC threads
+ virtual void print_gc_threads_on(outputStream* st) const {}
+ virtual void gc_threads_do(ThreadClosure* tc) const {}
+
+ // No heap verification
+ virtual void prepare_for_verify() {}
+ virtual void verify(VerifyOption option) {}
+
+ virtual jlong millis_since_last_gc() {
+ // Report time since the VM start
+ return os::elapsed_counter() / NANOSECS_PER_MILLISEC;
+ }
+
+ virtual void print_on(outputStream* st) const;
+ virtual void print_tracing_info() const;
+
+};
+
+#endif // SHARE_VM_GC_EPSILON_COLLECTEDHEAP_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilonMemoryPool.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ * 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/epsilon/epsilonHeap.hpp"
+#include "gc/epsilon/epsilonMemoryPool.hpp"
+
+EpsilonMemoryPool::EpsilonMemoryPool(EpsilonHeap* heap) :
+ _heap(heap),
+ CollectedMemoryPool("Epsilon Heap",
+ heap->capacity(),
+ heap->max_capacity(),
+ false) {
+ assert(UseEpsilonGC, "sanity");
+}
+
+MemoryUsage EpsilonMemoryPool::get_memory_usage() {
+ size_t initial_sz = initial_size();
+ size_t max_sz = max_size();
+ size_t used = used_in_bytes();
+ size_t committed = committed_in_bytes();
+
+ return MemoryUsage(initial_sz, used, committed, max_sz);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilonMemoryPool.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ *
+ * 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_EPSILON_EPSILONMEMORYPOOL_HPP
+#define SHARE_VM_GC_EPSILON_EPSILONMEMORYPOOL_HPP
+
+#include "gc/epsilon/epsilonHeap.hpp"
+#include "services/memoryPool.hpp"
+#include "services/memoryUsage.hpp"
+#include "utilities/macros.hpp"
+
+class EpsilonMemoryPool : public CollectedMemoryPool {
+private:
+ EpsilonHeap* _heap;
+
+public:
+ EpsilonMemoryPool(EpsilonHeap* heap);
+ size_t committed_in_bytes() { return _heap->capacity(); }
+ size_t used_in_bytes() { return _heap->used(); }
+ size_t max_size() const { return _heap->max_capacity(); }
+ MemoryUsage get_memory_usage();
+};
+
+#endif // SHARE_VM_GC_EPSILON_EPSILONMEMORYPOOL_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ *
+ * 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/epsilon/epsilonMonitoringSupport.hpp"
+#include "gc/epsilon/epsilonHeap.hpp"
+#include "gc/shared/generationCounters.hpp"
+#include "memory/allocation.hpp"
+#include "memory/allocation.inline.hpp"
+#include "memory/metaspaceCounters.hpp"
+#include "memory/resourceArea.hpp"
+#include "services/memoryService.hpp"
+
+class EpsilonSpaceCounters: public CHeapObj<mtGC> {
+ friend class VMStructs;
+
+private:
+ PerfVariable* _capacity;
+ PerfVariable* _used;
+ char* _name_space;
+
+public:
+ EpsilonSpaceCounters(const char* name,
+ int ordinal,
+ size_t max_size,
+ size_t initial_capacity,
+ GenerationCounters* gc) {
+ if (UsePerfData) {
+ EXCEPTION_MARK;
+ ResourceMark rm;
+
+ const char* cns = PerfDataManager::name_space(gc->name_space(), "space", ordinal);
+
+ _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1, mtGC);
+ strcpy(_name_space, cns);
+
+ const char* cname = PerfDataManager::counter_name(_name_space, "name");
+ PerfDataManager::create_string_constant(SUN_GC, cname, name, CHECK);
+
+ cname = PerfDataManager::counter_name(_name_space, "maxCapacity");
+ PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes, (jlong)max_size, CHECK);
+
+ cname = PerfDataManager::counter_name(_name_space, "capacity");
+ _capacity = PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_Bytes, initial_capacity, CHECK);
+
+ cname = PerfDataManager::counter_name(_name_space, "used");
+ _used = PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_Bytes, (jlong) 0, CHECK);
+
+ cname = PerfDataManager::counter_name(_name_space, "initCapacity");
+ PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes, initial_capacity, CHECK);
+ }
+ }
+
+ ~EpsilonSpaceCounters() {
+ if (_name_space != NULL) {
+ FREE_C_HEAP_ARRAY(char, _name_space);
+ }
+ }
+
+ inline void update_all(size_t capacity, size_t used) {
+ _capacity->set_value(capacity);
+ _used->set_value(used);
+ }
+};
+
+class EpsilonGenerationCounters : public GenerationCounters {
+private:
+ EpsilonHeap* _heap;
+public:
+ EpsilonGenerationCounters(EpsilonHeap* heap) :
+ GenerationCounters("Heap", 1, 1, 0, heap->max_capacity(), heap->capacity()),
+ _heap(heap)
+ {};
+
+ virtual void update_all() {
+ _current_size->set_value(_heap->capacity());
+ }
+};
+
+EpsilonMonitoringSupport::EpsilonMonitoringSupport(EpsilonHeap* heap) {
+ _heap_counters = new EpsilonGenerationCounters(heap);
+ _space_counters = new EpsilonSpaceCounters("Heap", 0, heap->max_capacity(), 0, _heap_counters);
+}
+
+void EpsilonMonitoringSupport::update_counters() {
+ MemoryService::track_memory_usage();
+
+ if (UsePerfData) {
+ EpsilonHeap* heap = EpsilonHeap::heap();
+ size_t used = heap->used();
+ size_t capacity = heap->capacity();
+ _heap_counters->update_all();
+ _space_counters->update_all(capacity, used);
+ MetaspaceCounters::update_performance_counters();
+ CompressedClassSpaceCounters::update_performance_counters();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ *
+ * 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_EPSILON_EPSILONMONITORINGSUPPORT_HPP
+#define SHARE_VM_GC_EPSILON_EPSILONMONITORINGSUPPORT_HPP
+
+#include "memory/allocation.hpp"
+
+class GenerationCounters;
+class EpsilonSpaceCounters;
+class EpsilonHeap;
+
+class EpsilonMonitoringSupport : public CHeapObj<mtGC> {
+private:
+ GenerationCounters* _heap_counters;
+ EpsilonSpaceCounters* _space_counters;
+
+public:
+ EpsilonMonitoringSupport(EpsilonHeap* heap);
+ void update_counters();
+};
+
+#endif // SHARE_VM_GC_EPSILON_EPSILONMONITORINGSUPPORT_HPP
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilonThreadLocalData.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2018, Red Hat, Inc. All rights reserved.
+ *
+ * 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_EPSILON_EPSILONTHREADLOCALDATA_HPP
+#define SHARE_VM_GC_EPSILON_EPSILONTHREADLOCALDATA_HPP
+
+#include "runtime/thread.hpp"
+#include "utilities/debug.hpp"
+
+class EpsilonThreadLocalData {
+private:
+ size_t _ergo_tlab_size;
+ int64_t _last_tlab_time;
+
+ EpsilonThreadLocalData() :
+ _ergo_tlab_size(0),
+ _last_tlab_time(0) {}
+
+ static EpsilonThreadLocalData* data(Thread* thread) {
+ assert(UseEpsilonGC, "Sanity");
+ return thread->gc_data<EpsilonThreadLocalData>();
+ }
+
+public:
+ static void create(Thread* thread) {
+ new (data(thread)) EpsilonThreadLocalData();
+ }
+
+ static void destroy(Thread* thread) {
+ data(thread)->~EpsilonThreadLocalData();
+ }
+
+ static size_t ergo_tlab_size(Thread *thread) {
+ return data(thread)->_ergo_tlab_size;
+ }
+
+ static int64_t last_tlab_time(Thread *thread) {
+ return data(thread)->_last_tlab_time;
+ }
+
+ static void set_ergo_tlab_size(Thread *thread, size_t val) {
+ data(thread)->_ergo_tlab_size = val;
+ }
+
+ static void set_last_tlab_time(Thread *thread, int64_t time) {
+ data(thread)->_last_tlab_time = time;
+ }
+};
+
+#endif // SHARE_VM_GC_EPSILON_EPSILONTHREADLOCALDATA_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilon_globals.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ * 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_EPSILON_GLOBALS_HPP
+#define SHARE_VM_GC_EPSILON_GLOBALS_HPP
+
+#include "runtime/globals.hpp"
+//
+// Defines all globals flags used by the Epsilon GC.
+//
+
+#define GC_EPSILON_FLAGS(develop, \
+ develop_pd, \
+ product, \
+ product_pd, \
+ diagnostic, \
+ diagnostic_pd, \
+ experimental, \
+ notproduct, \
+ manageable, \
+ product_rw, \
+ lp64_product, \
+ range, \
+ constraint, \
+ writeable) \
+ \
+ experimental(size_t, EpsilonPrintHeapSteps, 20, \
+ "Print heap occupancy stats with this number of steps. " \
+ "0 turns the printing off.") \
+ range(0, max_intx) \
+ \
+ experimental(size_t, EpsilonUpdateCountersStep, 1 * M, \
+ "Update heap occupancy counters after allocating this much " \
+ "memory. Higher values would make allocations faster at " \
+ "the expense of lower resolution in heap counters.") \
+ range(1, max_intx) \
+ \
+ experimental(size_t, EpsilonMaxTLABSize, 4 * M, \
+ "Max TLAB size to use with Epsilon GC. Larger value improves " \
+ "performance at the expense of per-thread memory waste. This " \
+ "asks TLAB machinery to cap TLAB sizes at this value.") \
+ range(1, max_intx) \
+ \
+ experimental(bool, EpsilonElasticTLAB, true, \
+ "Use elastic policy to manage TLAB sizes. This conserves memory " \
+ "for non-actively allocating threads, even when they request " \
+ "large TLABs for themselves. Active threads would experience " \
+ "smaller TLABs until policy catches up.") \
+ \
+ experimental(bool, EpsilonElasticTLABDecay, true, \
+ "Use timed decays to shrik TLAB sizes. This conserves memory " \
+ "for the threads that allocate in bursts of different sizes, " \
+ "for example the small/rare allocations coming after the initial "\
+ "large burst.") \
+ \
+ experimental(double, EpsilonTLABElasticity, 1.1, \
+ "Multiplier to use when deciding on next TLAB size. Larger value "\
+ "improves performance at the expense of per-thread memory waste. "\
+ "Lower value improves memory footprint, but penalizes actively " \
+ "allocating threads.") \
+ range(1, max_intx) \
+ \
+ experimental(size_t, EpsilonTLABDecayTime, 1000, \
+ "TLAB sizing policy decays to initial size after thread had not " \
+ "allocated for this long. Time is in milliseconds. Lower value " \
+ "improves memory footprint, but penalizes actively allocating " \
+ "threads.") \
+ range(1, max_intx) \
+ \
+ experimental(size_t, EpsilonMinHeapExpand, 128 * M, \
+ "Min expansion step for heap. Larger value improves performance " \
+ "at the potential expense of memory waste.") \
+ range(1, max_intx)
+
+#endif // SHARE_VM_GC_EPSILON_GLOBALS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/vmStructs_epsilon.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2018, Red Hat Inc. All rights reserved.
+ * 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_EPSILON_VMSTRUCTS_HPP
+#define SHARE_GC_EPSILON_VMSTRUCTS_HPP
+
+#include "gc/epsilon/epsilonHeap.hpp"
+#include "gc/shared/space.hpp"
+#include "memory/virtualspace.hpp"
+
+#define VM_STRUCTS_EPSILONGC(nonstatic_field, \
+ volatile_nonstatic_field, \
+ static_field) \
+ nonstatic_field(EpsilonHeap, _virtual_space, VirtualSpace) \
+ nonstatic_field(EpsilonHeap, _space, ContiguousSpace*)
+
+#define VM_TYPES_EPSILONGC(declare_type, \
+ declare_toplevel_type, \
+ declare_integer_type) \
+ declare_type(EpsilonHeap, CollectedHeap)
+
+#define VM_INT_CONSTANTS_EPSILONGC(declare_constant, \
+ declare_constant_with_value)
+
+#endif // SHARE_GC_EPSILON_VMSTRUCTS_HPP
--- a/src/hotspot/share/gc/g1/g1BarrierSet.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1BarrierSet.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -50,7 +50,7 @@
// pre-marking object graph.
static void enqueue(oop pre_val);
- static void enqueue_if_weak_or_archive(DecoratorSet decorators, oop value);
+ static void enqueue_if_weak(DecoratorSet decorators, oop value);
template <class T> void write_ref_array_pre_work(T* dst, size_t count);
virtual void write_ref_array_pre(oop* dst, size_t count, bool dest_uninitialized);
--- a/src/hotspot/share/gc/g1/g1BarrierSet.inline.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1BarrierSet.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -54,15 +54,14 @@
}
}
-inline void G1BarrierSet::enqueue_if_weak_or_archive(DecoratorSet decorators, oop value) {
+inline void G1BarrierSet::enqueue_if_weak(DecoratorSet decorators, oop value) {
assert((decorators & ON_UNKNOWN_OOP_REF) == 0, "Reference strength must be known");
- // Archive roots need to be enqueued since they add subgraphs to the
- // Java heap that were not there at the snapshot when marking started.
- // Weak and phantom references also need enqueueing for similar reasons.
- const bool in_archive_root = (decorators & IN_ARCHIVE_ROOT) != 0;
+ // Loading from a weak or phantom reference needs enqueueing, as
+ // the object may not have been reachable (part of the snapshot)
+ // when marking started.
const bool on_strong_oop_ref = (decorators & ON_STRONG_OOP_REF) != 0;
const bool peek = (decorators & AS_NO_KEEPALIVE) != 0;
- const bool needs_enqueue = in_archive_root || (!peek && !on_strong_oop_ref);
+ const bool needs_enqueue = (!peek && !on_strong_oop_ref);
if (needs_enqueue && value != NULL) {
enqueue(value);
@@ -74,7 +73,7 @@
inline oop G1BarrierSet::AccessBarrier<decorators, BarrierSetT>::
oop_load_not_in_heap(T* addr) {
oop value = ModRef::oop_load_not_in_heap(addr);
- enqueue_if_weak_or_archive(decorators, value);
+ enqueue_if_weak(decorators, value);
return value;
}
@@ -83,7 +82,7 @@
inline oop G1BarrierSet::AccessBarrier<decorators, BarrierSetT>::
oop_load_in_heap(T* addr) {
oop value = ModRef::oop_load_in_heap(addr);
- enqueue_if_weak_or_archive(decorators, value);
+ enqueue_if_weak(decorators, value);
return value;
}
@@ -91,7 +90,7 @@
inline oop G1BarrierSet::AccessBarrier<decorators, BarrierSetT>::
oop_load_in_heap_at(oop base, ptrdiff_t offset) {
oop value = ModRef::oop_load_in_heap_at(base, offset);
- enqueue_if_weak_or_archive(AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength<decorators>(base, offset), value);
+ enqueue_if_weak(AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength<decorators>(base, offset), value);
return value;
}
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -78,6 +78,7 @@
#include "logging/log.hpp"
#include "memory/allocation.hpp"
#include "memory/iterator.hpp"
+#include "memory/metaspaceShared.hpp"
#include "memory/resourceArea.hpp"
#include "oops/access.inline.hpp"
#include "oops/compressedOops.inline.hpp"
@@ -823,6 +824,18 @@
decrease_used(size_used);
}
+oop G1CollectedHeap::materialize_archived_object(oop obj) {
+ assert(obj != NULL, "archived obj is NULL");
+ assert(MetaspaceShared::is_archive_object(obj), "must be archived object");
+
+ // Loading an archived object makes it strongly reachable. If it is
+ // loaded during concurrent marking, it must be enqueued to the SATB
+ // queue, shading the previously white object gray.
+ G1BarrierSet::enqueue(obj);
+
+ return obj;
+}
+
HeapWord* G1CollectedHeap::attempt_allocation_humongous(size_t word_size) {
ResourceMark rm; // For retrieving the thread names in log messages.
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -699,6 +699,8 @@
// mapping failed, with the same non-overlapping and sorted MemRegion array.
void dealloc_archive_regions(MemRegion* range, size_t count);
+ oop materialize_archived_object(oop obj);
+
private:
// Shrink the garbage-first heap by at most the given size (in bytes!).
--- a/src/hotspot/share/gc/parallel/pcTasks.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/parallel/pcTasks.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -149,19 +149,16 @@
void RefProcTaskExecutor::execute(ProcessTask& task)
{
ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
- uint parallel_gc_threads = heap->gc_task_manager()->workers();
uint active_gc_threads = heap->gc_task_manager()->active_workers();
OopTaskQueueSet* qset = ParCompactionManager::stack_array();
ParallelTaskTerminator terminator(active_gc_threads, qset);
GCTaskQueue* q = GCTaskQueue::create();
- for(uint i=0; i<parallel_gc_threads; i++) {
+ for(uint i=0; i<active_gc_threads; i++) {
q->enqueue(new RefProcTaskProxy(task, i));
}
- if (task.marks_oops_alive()) {
- if (parallel_gc_threads>1) {
- for (uint j=0; j<active_gc_threads; j++) {
- q->enqueue(new StealMarkingTask(&terminator));
- }
+ if (task.marks_oops_alive() && (active_gc_threads>1)) {
+ for (uint j=0; j<active_gc_threads; j++) {
+ q->enqueue(new StealMarkingTask(&terminator));
}
}
PSParallelCompact::gc_task_manager()->execute_and_wait(q);
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -2112,7 +2112,10 @@
ReferenceProcessorStats stats;
ReferenceProcessorPhaseTimes pt(&_gc_timer, ref_processor()->max_num_queues());
+
if (ref_processor()->processing_is_mt()) {
+ ref_processor()->set_active_mt_degree(active_gc_threads);
+
RefProcTaskExecutor task_executor;
stats = ref_processor()->process_discovered_references(
is_alive_closure(), &mark_and_push_closure, &follow_stack_closure,
--- a/src/hotspot/share/gc/shared/barrierSet.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/shared/barrierSet.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -103,17 +103,17 @@
~BarrierSet() { }
template <class BarrierSetAssemblerT>
- BarrierSetAssembler* make_barrier_set_assembler() {
+ static BarrierSetAssembler* make_barrier_set_assembler() {
return NOT_ZERO(new BarrierSetAssemblerT()) ZERO_ONLY(NULL);
}
template <class BarrierSetC1T>
- BarrierSetC1* make_barrier_set_c1() {
+ static BarrierSetC1* make_barrier_set_c1() {
return COMPILER1_PRESENT(new BarrierSetC1T()) NOT_COMPILER1(NULL);
}
template <class BarrierSetC2T>
- BarrierSetC2* make_barrier_set_c2() {
+ static BarrierSetC2* make_barrier_set_c2() {
return COMPILER2_PRESENT(new BarrierSetC2T()) NOT_COMPILER2(NULL);
}
--- a/src/hotspot/share/gc/shared/barrierSetConfig.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/shared/barrierSetConfig.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -30,7 +30,9 @@
// Do something for each concrete barrier set part of the build.
#define FOR_EACH_CONCRETE_BARRIER_SET_DO(f) \
f(CardTableBarrierSet) \
- G1GC_ONLY(f(G1BarrierSet))
+ EPSILONGC_ONLY(f(EpsilonBarrierSet)) \
+ G1GC_ONLY(f(G1BarrierSet)) \
+ ZGC_ONLY(f(ZBarrierSet))
#define FOR_EACH_ABSTRACT_BARRIER_SET_DO(f) \
f(ModRef)
--- a/src/hotspot/share/gc/shared/barrierSetConfig.inline.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/shared/barrierSetConfig.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -30,8 +30,14 @@
#include "gc/shared/modRefBarrierSet.inline.hpp"
#include "gc/shared/cardTableBarrierSet.inline.hpp"
+#if INCLUDE_EPSILONGC
+#include "gc/epsilon/epsilonBarrierSet.hpp"
+#endif
#if INCLUDE_G1GC
-#include "gc/g1/g1BarrierSet.inline.hpp" // G1 support
+#include "gc/g1/g1BarrierSet.inline.hpp"
+#endif
+#if INCLUDE_ZGC
+#include "gc/z/zBarrierSet.inline.hpp"
#endif
#endif // SHARE_VM_GC_SHARED_BARRIERSETCONFIG_INLINE_HPP
--- a/src/hotspot/share/gc/shared/collectedHeap.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/shared/collectedHeap.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -526,6 +526,10 @@
fill_with_object_impl(start, words, zap);
}
+void CollectedHeap::fill_with_dummy_object(HeapWord* start, HeapWord* end, bool zap) {
+ CollectedHeap::fill_with_object(start, end, zap);
+}
+
HeapWord* CollectedHeap::allocate_new_tlab(size_t min_size,
size_t requested_size,
size_t* actual_size) {
--- a/src/hotspot/share/gc/shared/collectedHeap.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/shared/collectedHeap.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -89,6 +89,7 @@
// CMSHeap
// G1CollectedHeap
// ParallelScavengeHeap
+// ZCollectedHeap
//
class CollectedHeap : public CHeapObj<mtInternal> {
friend class VMStructs;
@@ -206,7 +207,9 @@
Serial,
Parallel,
CMS,
- G1
+ G1,
+ Epsilon,
+ Z
};
static inline size_t filler_array_max_size() {
@@ -347,6 +350,8 @@
fill_with_object(start, pointer_delta(end, start), zap);
}
+ virtual void fill_with_dummy_object(HeapWord* start, HeapWord* end, bool zap);
+
// Return the address "addr" aligned by "alignment_in_bytes" if such
// an address is below "end". Return NULL otherwise.
inline static HeapWord* align_allocation_or_fail(HeapWord* addr,
--- a/src/hotspot/share/gc/shared/gcCause.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/shared/gcCause.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -105,6 +105,21 @@
case _dcmd_gc_run:
return "Diagnostic Command";
+ case _z_timer:
+ return "Timer";
+
+ case _z_warmup:
+ return "Warmup";
+
+ case _z_allocation_rate:
+ return "Allocation Rate";
+
+ case _z_allocation_stall:
+ return "Allocation Stall";
+
+ case _z_proactive:
+ return "Proactive";
+
case _last_gc_cause:
return "ILLEGAL VALUE - last gc cause - ILLEGAL VALUE";
--- a/src/hotspot/share/gc/shared/gcCause.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/shared/gcCause.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -78,6 +78,12 @@
_dcmd_gc_run,
+ _z_timer,
+ _z_warmup,
+ _z_allocation_rate,
+ _z_allocation_stall,
+ _z_proactive,
+
_last_gc_cause
};
--- a/src/hotspot/share/gc/shared/gcConfig.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/shared/gcConfig.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -31,6 +31,9 @@
#if INCLUDE_CMSGC
#include "gc/cms/cmsArguments.hpp"
#endif
+#if INCLUDE_EPSILONGC
+#include "gc/epsilon/epsilonArguments.hpp"
+#endif
#if INCLUDE_G1GC
#include "gc/g1/g1Arguments.hpp"
#endif
@@ -40,6 +43,9 @@
#if INCLUDE_SERIALGC
#include "gc/serial/serialArguments.hpp"
#endif
+#if INCLUDE_ZGC
+#include "gc/z/zArguments.hpp"
+#endif
struct SupportedGC {
bool& _flag;
@@ -52,18 +58,22 @@
};
CMSGC_ONLY(static CMSArguments cmsArguments;)
+ EPSILONGC_ONLY(static EpsilonArguments epsilonArguments;)
G1GC_ONLY(static G1Arguments g1Arguments;)
PARALLELGC_ONLY(static ParallelArguments parallelArguments;)
SERIALGC_ONLY(static SerialArguments serialArguments;)
+ ZGC_ONLY(static ZArguments zArguments;)
// Table of supported GCs, for translating between command
// line flag, CollectedHeap::Name and GCArguments instance.
static const SupportedGC SupportedGCs[] = {
CMSGC_ONLY_ARG(SupportedGC(UseConcMarkSweepGC, CollectedHeap::CMS, cmsArguments, "concurrent mark sweep gc"))
+ EPSILONGC_ONLY_ARG(SupportedGC(UseEpsilonGC, CollectedHeap::Epsilon, epsilonArguments, "epsilon gc"))
G1GC_ONLY_ARG(SupportedGC(UseG1GC, CollectedHeap::G1, g1Arguments, "g1 gc"))
PARALLELGC_ONLY_ARG(SupportedGC(UseParallelGC, CollectedHeap::Parallel, parallelArguments, "parallel gc"))
PARALLELGC_ONLY_ARG(SupportedGC(UseParallelOldGC, CollectedHeap::Parallel, parallelArguments, "parallel gc"))
SERIALGC_ONLY_ARG(SupportedGC(UseSerialGC, CollectedHeap::Serial, serialArguments, "serial gc"))
+ ZGC_ONLY_ARG(SupportedGC(UseZGC, CollectedHeap::Z, zArguments, "z gc"))
};
#define FOR_EACH_SUPPORTED_GC(var) \
@@ -88,10 +98,12 @@
}
NOT_CMSGC( UNSUPPORTED_OPTION(UseConcMarkSweepGC));
+ NOT_EPSILONGC( UNSUPPORTED_OPTION(UseEpsilonGC);)
NOT_G1GC( UNSUPPORTED_OPTION(UseG1GC);)
NOT_PARALLELGC(UNSUPPORTED_OPTION(UseParallelGC);)
NOT_PARALLELGC(UNSUPPORTED_OPTION(UseParallelOldGC));
NOT_SERIALGC( UNSUPPORTED_OPTION(UseSerialGC);)
+ NOT_ZGC( UNSUPPORTED_OPTION(UseZGC);)
}
bool GCConfig::is_no_gc_selected() {
--- a/src/hotspot/share/gc/shared/gcConfiguration.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/shared/gcConfiguration.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -43,6 +43,10 @@
return ParNew;
}
+ if (UseZGC) {
+ return NA;
+ }
+
return DefNew;
}
@@ -59,6 +63,10 @@
return ParallelOld;
}
+ if (UseZGC) {
+ return Z;
+ }
+
return SerialOld;
}
--- a/src/hotspot/share/gc/shared/gcName.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/shared/gcName.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -38,6 +38,8 @@
ConcurrentMarkSweep,
G1Old,
G1Full,
+ Z,
+ NA,
GCNameEndSentinel
};
@@ -55,6 +57,8 @@
case ConcurrentMarkSweep: return "ConcurrentMarkSweep";
case G1Old: return "G1Old";
case G1Full: return "G1Full";
+ case Z: return "Z";
+ case NA: return "N/A";
default: ShouldNotReachHere(); return NULL;
}
}
--- a/src/hotspot/share/gc/shared/gcThreadLocalData.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/shared/gcThreadLocalData.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -40,6 +40,6 @@
// should consider placing frequently accessed fields first in
// T, so that field offsets relative to Thread are small, which
// often allows for a more compact instruction encoding.
-typedef uint64_t GCThreadLocalData[14]; // 112 bytes
+typedef uint64_t GCThreadLocalData[18]; // 144 bytes
#endif // SHARE_GC_SHARED_GCTHREADLOCALDATA_HPP
--- a/src/hotspot/share/gc/shared/gc_globals.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/shared/gc_globals.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -29,6 +29,9 @@
#if INCLUDE_CMSGC
#include "gc/cms/cms_globals.hpp"
#endif
+#if INCLUDE_EPSILONGC
+#include "gc/epsilon/epsilon_globals.hpp"
+#endif
#if INCLUDE_G1GC
#include "gc/g1/g1_globals.hpp"
#endif
@@ -38,6 +41,9 @@
#if INCLUDE_SERIALGC
#include "gc/serial/serial_globals.hpp"
#endif
+#if INCLUDE_ZGC
+#include "gc/z/z_globals.hpp"
+#endif
#define GC_FLAGS(develop, \
develop_pd, \
@@ -70,6 +76,22 @@
constraint, \
writeable)) \
\
+ EPSILONGC_ONLY(GC_EPSILON_FLAGS( \
+ develop, \
+ develop_pd, \
+ product, \
+ product_pd, \
+ diagnostic, \
+ diagnostic_pd, \
+ experimental, \
+ notproduct, \
+ manageable, \
+ product_rw, \
+ lp64_product, \
+ range, \
+ constraint, \
+ writeable)) \
+ \
G1GC_ONLY(GC_G1_FLAGS( \
develop, \
develop_pd, \
@@ -118,6 +140,22 @@
constraint, \
writeable)) \
\
+ ZGC_ONLY(GC_Z_FLAGS( \
+ develop, \
+ develop_pd, \
+ product, \
+ product_pd, \
+ diagnostic, \
+ diagnostic_pd, \
+ experimental, \
+ notproduct, \
+ manageable, \
+ product_rw, \
+ lp64_product, \
+ range, \
+ constraint, \
+ writeable)) \
+ \
/* gc */ \
\
product(bool, UseConcMarkSweepGC, false, \
@@ -135,6 +173,12 @@
product(bool, UseParallelOldGC, false, \
"Use the Parallel Old garbage collector") \
\
+ experimental(bool, UseEpsilonGC, false, \
+ "Use the Epsilon (no-op) garbage collector") \
+ \
+ experimental(bool, UseZGC, false, \
+ "Use the Z garbage collector") \
+ \
product(uint, ParallelGCThreads, 0, \
"Number of parallel threads parallel gc will use") \
constraint(ParallelGCThreadsConstraintFunc,AfterErgo) \
--- a/src/hotspot/share/gc/shared/oopStorage.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/shared/oopStorage.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -52,9 +52,7 @@
assert(_next == NULL, "deleting attached block");
}
-OopStorage::AllocateList::AllocateList(const AllocateEntry& (*get_entry)(const Block& block)) :
- _head(NULL), _tail(NULL), _get_entry(get_entry)
-{}
+OopStorage::AllocateList::AllocateList() : _head(NULL), _tail(NULL) {}
OopStorage::AllocateList::~AllocateList() {
// ~OopStorage() empties its lists before destroying them.
@@ -68,8 +66,8 @@
assert(_tail == NULL, "invariant");
_head = _tail = █
} else {
- _get_entry(block)._next = old;
- _get_entry(*old)._prev = █
+ block.allocate_entry()._next = old;
+ old->allocate_entry()._prev = █
_head = █
}
}
@@ -80,14 +78,14 @@
assert(_head == NULL, "invariant");
_head = _tail = █
} else {
- _get_entry(*old)._next = █
- _get_entry(block)._prev = old;
+ old->allocate_entry()._next = █
+ block.allocate_entry()._prev = old;
_tail = █
}
}
void OopStorage::AllocateList::unlink(const Block& block) {
- const AllocateEntry& block_entry = _get_entry(block);
+ const AllocateEntry& block_entry = block.allocate_entry();
const Block* prev_blk = block_entry._prev;
const Block* next_blk = block_entry._next;
block_entry._prev = NULL;
@@ -98,15 +96,15 @@
_head = _tail = NULL;
} else if (prev_blk == NULL) {
assert(_head == &block, "invariant");
- _get_entry(*next_blk)._prev = NULL;
+ next_blk->allocate_entry()._prev = NULL;
_head = next_blk;
} else if (next_blk == NULL) {
assert(_tail == &block, "invariant");
- _get_entry(*prev_blk)._next = NULL;
+ prev_blk->allocate_entry()._next = NULL;
_tail = prev_blk;
} else {
- _get_entry(*next_blk)._prev = prev_blk;
- _get_entry(*prev_blk)._next = next_blk;
+ next_blk->allocate_entry()._prev = prev_blk;
+ prev_blk->allocate_entry()._next = next_blk;
}
}
@@ -232,10 +230,6 @@
const_cast<OopStorage* volatile&>(_owner) = NULL;
}
-const OopStorage::AllocateEntry& OopStorage::Block::get_allocate_entry(const Block& block) {
- return block._allocate_entry;
-}
-
size_t OopStorage::Block::allocation_size() {
// _data must be first member, so aligning Block aligns _data.
STATIC_ASSERT(_data_pos == 0);
@@ -769,7 +763,7 @@
Mutex* active_mutex) :
_name(dup_name(name)),
_active_array(ActiveArray::create(initial_active_array_size)),
- _allocate_list(&Block::get_allocate_entry),
+ _allocate_list(),
_deferred_updates(NULL),
_allocate_mutex(allocate_mutex),
_active_mutex(active_mutex),
--- a/src/hotspot/share/gc/shared/oopStorage.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/shared/oopStorage.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -178,14 +178,13 @@
class AllocateList {
const Block* _head;
const Block* _tail;
- const AllocateEntry& (*_get_entry)(const Block& block);
// Noncopyable.
AllocateList(const AllocateList&);
AllocateList& operator=(const AllocateList&);
public:
- AllocateList(const AllocateEntry& (*get_entry)(const Block& block));
+ AllocateList();
~AllocateList();
Block* head();
--- a/src/hotspot/share/gc/shared/oopStorage.inline.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/shared/oopStorage.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -158,7 +158,7 @@
Block& operator=(const Block&);
public:
- static const AllocateEntry& get_allocate_entry(const Block& block);
+ const AllocateEntry& allocate_entry() const;
static size_t allocation_size();
static size_t allocation_alignment_shift();
@@ -214,19 +214,19 @@
}
inline OopStorage::Block* OopStorage::AllocateList::prev(Block& block) {
- return const_cast<Block*>(_get_entry(block)._prev);
+ return const_cast<Block*>(block.allocate_entry()._prev);
}
inline OopStorage::Block* OopStorage::AllocateList::next(Block& block) {
- return const_cast<Block*>(_get_entry(block)._next);
+ return const_cast<Block*>(block.allocate_entry()._next);
}
inline const OopStorage::Block* OopStorage::AllocateList::prev(const Block& block) const {
- return _get_entry(block)._prev;
+ return block.allocate_entry()._prev;
}
inline const OopStorage::Block* OopStorage::AllocateList::next(const Block& block) const {
- return _get_entry(block)._next;
+ return block.allocate_entry()._next;
}
template<typename Closure>
@@ -296,7 +296,11 @@
return SkipNullFn<F>(f);
}
-// Inline Block accesses for use in iteration inner loop.
+// Inline Block accesses for use in iteration loops.
+
+inline const OopStorage::AllocateEntry& OopStorage::Block::allocate_entry() const {
+ return _allocate_entry;
+}
inline void OopStorage::Block::check_index(unsigned index) const {
assert(index < ARRAY_SIZE(_data), "Index out of bounds: %u", index);
--- a/src/hotspot/share/gc/shared/plab.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/shared/plab.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -82,14 +82,14 @@
size_t PLAB::retire_internal() {
size_t result = 0;
if (_top < _hard_end) {
- CollectedHeap::fill_with_object(_top, _hard_end);
+ Universe::heap()->fill_with_dummy_object(_top, _hard_end, true);
result += invalidate();
}
return result;
}
void PLAB::add_undo_waste(HeapWord* obj, size_t word_sz) {
- CollectedHeap::fill_with_object(obj, word_sz);
+ Universe::heap()->fill_with_dummy_object(obj, obj + word_sz, true);
_undo_wasted += word_sz;
}
--- a/src/hotspot/share/gc/shared/specialized_oop_closures.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/shared/specialized_oop_closures.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -35,6 +35,9 @@
#if INCLUDE_SERIALGC
#include "gc/serial/serial_specialized_oop_closures.hpp"
#endif
+#if INCLUDE_ZGC
+#include "gc/z/z_specialized_oop_closures.hpp"
+#endif
// The following OopClosure types get specialized versions of
// "oop_oop_iterate" that invoke the closures' do_oop methods
@@ -67,7 +70,8 @@
SERIALGC_ONLY(SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_MS(f)) \
CMSGC_ONLY(SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_CMS(f)) \
G1GC_ONLY(SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_G1(f)) \
- G1GC_ONLY(SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_G1FULL(f))
+ G1GC_ONLY(SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_G1FULL(f)) \
+ ZGC_ONLY(SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_Z(f))
// We separate these out, because sometime the general one has
// a different definition from the specialized ones, and sometimes it
--- a/src/hotspot/share/gc/shared/threadLocalAllocBuffer.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/shared/threadLocalAllocBuffer.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -114,7 +114,7 @@
myThread()->incr_allocated_bytes(used_bytes());
}
- CollectedHeap::fill_with_object(top(), hard_end(), retire && zap);
+ Universe::heap()->fill_with_dummy_object(top(), hard_end(), retire && zap);
if (retire || ZeroTLAB) { // "Reset" the TLAB
set_start(NULL);
--- a/src/hotspot/share/gc/shared/vmStructs_gc.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/gc/shared/vmStructs_gc.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -37,6 +37,9 @@
#if INCLUDE_CMSGC
#include "gc/cms/vmStructs_cms.hpp"
#endif
+#if INCLUDE_EPSILONGC
+#include "gc/epsilon/vmStructs_epsilon.hpp"
+#endif
#if INCLUDE_G1GC
#include "gc/g1/vmStructs_g1.hpp"
#endif
@@ -47,6 +50,9 @@
#include "gc/serial/defNewGeneration.hpp"
#include "gc/serial/vmStructs_serial.hpp"
#endif
+#if INCLUDE_ZGC
+#include "gc/z/vmStructs_z.hpp"
+#endif
#define VM_STRUCTS_GC(nonstatic_field, \
volatile_nonstatic_field, \
@@ -55,6 +61,9 @@
CMSGC_ONLY(VM_STRUCTS_CMSGC(nonstatic_field, \
volatile_nonstatic_field, \
static_field)) \
+ EPSILONGC_ONLY(VM_STRUCTS_EPSILONGC(nonstatic_field, \
+ volatile_nonstatic_field, \
+ static_field)) \
G1GC_ONLY(VM_STRUCTS_G1GC(nonstatic_field, \
volatile_nonstatic_field, \
static_field)) \
@@ -64,6 +73,10 @@
SERIALGC_ONLY(VM_STRUCTS_SERIALGC(nonstatic_field, \
volatile_nonstatic_field, \
static_field)) \
+ ZGC_ONLY(VM_STRUCTS_ZGC(nonstatic_field, \
+ volatile_nonstatic_field, \
+ static_field)) \
+ \
/**********************************************************************************/ \
/* Generation and Space hierarchies */ \
/**********************************************************************************/ \
@@ -153,6 +166,9 @@
CMSGC_ONLY(VM_TYPES_CMSGC(declare_type, \
declare_toplevel_type, \
declare_integer_type)) \
+ EPSILONGC_ONLY(VM_TYPES_EPSILONGC(declare_type, \
+ declare_toplevel_type, \
+ declare_integer_type)) \
G1GC_ONLY(VM_TYPES_G1GC(declare_type, \
declare_toplevel_type, \
declare_integer_type)) \
@@ -162,6 +178,10 @@
SERIALGC_ONLY(VM_TYPES_SERIALGC(declare_type, \
declare_toplevel_type, \
declare_integer_type)) \
+ ZGC_ONLY(VM_TYPES_ZGC(declare_type, \
+ declare_toplevel_type, \
+ declare_integer_type)) \
+ \
/******************************************/ \
/* Generation and space hierarchies */ \
/* (needed for run-time type information) */ \
@@ -225,12 +245,16 @@
declare_constant_with_value) \
CMSGC_ONLY(VM_INT_CONSTANTS_CMSGC(declare_constant, \
declare_constant_with_value)) \
+ EPSILONGC_ONLY(VM_INT_CONSTANTS_EPSILONGC(declare_constant, \
+ declare_constant_with_value)) \
G1GC_ONLY(VM_INT_CONSTANTS_G1GC(declare_constant, \
declare_constant_with_value)) \
PARALLELGC_ONLY(VM_INT_CONSTANTS_PARALLELGC(declare_constant, \
declare_constant_with_value)) \
SERIALGC_ONLY(VM_INT_CONSTANTS_SERIALGC(declare_constant, \
declare_constant_with_value)) \
+ ZGC_ONLY(VM_INT_CONSTANTS_ZGC(declare_constant, \
+ declare_constant_with_value)) \
\
/********************************************/ \
/* Generation and Space Hierarchy Constants */ \
@@ -274,5 +298,7 @@
declare_constant(Generation::LogOfGenGrain) \
declare_constant(Generation::GenGrain) \
+#define VM_LONG_CONSTANTS_GC(declare_constant) \
+ ZGC_ONLY(VM_LONG_CONSTANTS_ZGC(declare_constant))
#endif // SHARE_GC_SHARED_VMSTRUCTS_GC_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/c1/zBarrierSetC1.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,247 @@
+/*
+ * 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 "c1/c1_LIR.hpp"
+#include "c1/c1_LIRGenerator.hpp"
+#include "c1/c1_CodeStubs.hpp"
+#include "gc/z/c1/zBarrierSetC1.hpp"
+#include "gc/z/zBarrierSet.hpp"
+#include "gc/z/zBarrierSetAssembler.hpp"
+#include "gc/z/zThreadLocalData.hpp"
+#include "utilities/macros.hpp"
+
+ZLoadBarrierStubC1::ZLoadBarrierStubC1(LIRAccess& access, LIR_Opr ref, address runtime_stub) :
+ _decorators(access.decorators()),
+ _ref_addr(access.resolved_addr()),
+ _ref(ref),
+ _tmp(LIR_OprFact::illegalOpr),
+ _patch_info(access.patch_emit_info()),
+ _runtime_stub(runtime_stub) {
+
+ // Allocate tmp register if needed
+ if (!_ref_addr->is_register()) {
+ assert(_ref_addr->is_address(), "Must be an address");
+ if (_ref_addr->as_address_ptr()->index()->is_valid() ||
+ _ref_addr->as_address_ptr()->disp() != 0) {
+ // Has index or displacement, need tmp register to load address into
+ _tmp = access.gen()->new_pointer_register();
+ } else {
+ // No index or displacement, address available in base register
+ _ref_addr = _ref_addr->as_address_ptr()->base();
+ }
+ }
+
+ assert(_ref->is_register(), "Must be a register");
+ assert(_ref_addr->is_register() != _tmp->is_register(), "Only one should be a register");
+}
+
+DecoratorSet ZLoadBarrierStubC1::decorators() const {
+ return _decorators;
+}
+
+LIR_Opr ZLoadBarrierStubC1::ref() const {
+ return _ref;
+}
+
+LIR_Opr ZLoadBarrierStubC1::ref_addr() const {
+ return _ref_addr;
+}
+
+LIR_Opr ZLoadBarrierStubC1::tmp() const {
+ return _tmp;
+}
+
+LIR_PatchCode ZLoadBarrierStubC1::patch_code() const {
+ return (_decorators & C1_NEEDS_PATCHING) != 0 ? lir_patch_normal : lir_patch_none;
+}
+
+CodeEmitInfo*& ZLoadBarrierStubC1::patch_info() {
+ return _patch_info;
+}
+
+address ZLoadBarrierStubC1::runtime_stub() const {
+ return _runtime_stub;
+}
+
+void ZLoadBarrierStubC1::visit(LIR_OpVisitState* visitor) {
+ if (_patch_info != NULL) {
+ visitor->do_slow_case(_patch_info);
+ } else {
+ visitor->do_slow_case();
+ }
+
+ visitor->do_input(_ref_addr);
+ visitor->do_output(_ref);
+
+ if (_tmp->is_valid()) {
+ visitor->do_temp(_tmp);
+ }
+}
+
+void ZLoadBarrierStubC1::emit_code(LIR_Assembler* ce) {
+ ZBarrierSet::assembler()->generate_c1_load_barrier_stub(ce, this);
+}
+
+#ifndef PRODUCT
+void ZLoadBarrierStubC1::print_name(outputStream* out) const {
+ out->print("ZLoadBarrierStubC1");
+}
+#endif // PRODUCT
+
+class LIR_OpZLoadBarrierTest : public LIR_Op {
+private:
+ LIR_Opr _opr;
+
+public:
+ LIR_OpZLoadBarrierTest(LIR_Opr opr) :
+ LIR_Op(),
+ _opr(opr) {}
+
+ virtual void visit(LIR_OpVisitState* state) {
+ state->do_input(_opr);
+ }
+
+ virtual void emit_code(LIR_Assembler* ce) {
+ ZBarrierSet::assembler()->generate_c1_load_barrier_test(ce, _opr);
+ }
+
+ virtual void print_instr(outputStream* out) const {
+ _opr->print(out);
+ out->print(" ");
+ }
+
+#ifndef PRODUCT
+ virtual const char* name() const {
+ return "lir_z_load_barrier_test";
+ }
+#endif // PRODUCT
+};
+
+static bool barrier_needed(LIRAccess& access) {
+ return ZBarrierSet::barrier_needed(access.decorators(), access.type());
+}
+
+ZBarrierSetC1::ZBarrierSetC1() :
+ _load_barrier_on_oop_field_preloaded_runtime_stub(NULL),
+ _load_barrier_on_weak_oop_field_preloaded_runtime_stub(NULL) {}
+
+address ZBarrierSetC1::load_barrier_on_oop_field_preloaded_runtime_stub(DecoratorSet decorators) const {
+ assert((decorators & ON_PHANTOM_OOP_REF) == 0, "Unsupported decorator");
+ //assert((decorators & ON_UNKNOWN_OOP_REF) == 0, "Unsupported decorator");
+
+ if ((decorators & ON_WEAK_OOP_REF) != 0) {
+ return _load_barrier_on_weak_oop_field_preloaded_runtime_stub;
+ } else {
+ return _load_barrier_on_oop_field_preloaded_runtime_stub;
+ }
+}
+
+#ifdef ASSERT
+#define __ access.gen()->lir(__FILE__, __LINE__)->
+#else
+#define __ access.gen()->lir()->
+#endif
+
+void ZBarrierSetC1::load_barrier(LIRAccess& access, LIR_Opr result) const {
+ // Fast path
+ __ append(new LIR_OpZLoadBarrierTest(result));
+
+ // Slow path
+ const address runtime_stub = load_barrier_on_oop_field_preloaded_runtime_stub(access.decorators());
+ CodeStub* const stub = new ZLoadBarrierStubC1(access, result, runtime_stub);
+ __ branch(lir_cond_notEqual, T_ADDRESS, stub);
+ __ branch_destination(stub->continuation());
+}
+
+#undef __
+
+void ZBarrierSetC1::load_at_resolved(LIRAccess& access, LIR_Opr result) {
+ BarrierSetC1::load_at_resolved(access, result);
+
+ if (barrier_needed(access)) {
+ load_barrier(access, result);
+ }
+}
+
+static void pre_load_barrier(LIRAccess& access) {
+ DecoratorSet decorators = access.decorators();
+
+ // Downgrade access to MO_UNORDERED
+ decorators = (decorators & ~MO_DECORATOR_MASK) | MO_UNORDERED;
+
+ // Remove C1_WRITE_ACCESS
+ decorators = (decorators & ~C1_WRITE_ACCESS);
+
+ // Generate synthetic load at
+ access.gen()->access_load_at(decorators,
+ access.type(),
+ access.base().item(),
+ access.offset().opr(),
+ access.gen()->new_register(access.type()),
+ NULL /* patch_emit_info */,
+ NULL /* load_emit_info */);
+}
+
+LIR_Opr ZBarrierSetC1::atomic_xchg_at_resolved(LIRAccess& access, LIRItem& value) {
+ if (barrier_needed(access)) {
+ pre_load_barrier(access);
+ }
+
+ return BarrierSetC1::atomic_xchg_at_resolved(access, value);
+}
+
+LIR_Opr ZBarrierSetC1::atomic_cmpxchg_at_resolved(LIRAccess& access, LIRItem& cmp_value, LIRItem& new_value) {
+ if (barrier_needed(access)) {
+ pre_load_barrier(access);
+ }
+
+ return BarrierSetC1::atomic_cmpxchg_at_resolved(access, cmp_value, new_value);
+}
+
+class ZLoadBarrierRuntimeStubCodeGenClosure : public StubAssemblerCodeGenClosure {
+private:
+ const DecoratorSet _decorators;
+
+public:
+ ZLoadBarrierRuntimeStubCodeGenClosure(DecoratorSet decorators) :
+ _decorators(decorators) {}
+
+ virtual OopMapSet* generate_code(StubAssembler* sasm) {
+ ZBarrierSet::assembler()->generate_c1_load_barrier_runtime_stub(sasm, _decorators);
+ return NULL;
+ }
+};
+
+static address generate_c1_runtime_stub(BufferBlob* blob, DecoratorSet decorators, const char* name) {
+ ZLoadBarrierRuntimeStubCodeGenClosure cl(decorators);
+ CodeBlob* const code_blob = Runtime1::generate_blob(blob, -1 /* stub_id */, name, false /* expect_oop_map*/, &cl);
+ return code_blob->code_begin();
+}
+
+void ZBarrierSetC1::generate_c1_runtime_stubs(BufferBlob* blob) {
+ _load_barrier_on_oop_field_preloaded_runtime_stub =
+ generate_c1_runtime_stub(blob, ON_STRONG_OOP_REF, "load_barrier_on_oop_field_preloaded_runtime_stub");
+ _load_barrier_on_weak_oop_field_preloaded_runtime_stub =
+ generate_c1_runtime_stub(blob, ON_WEAK_OOP_REF, "load_barrier_on_weak_oop_field_preloaded_runtime_stub");
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/c1/zBarrierSetC1.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,80 @@
+/*
+ * 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_GC_Z_C1_ZBARRIERSETC1_HPP
+#define SHARE_GC_Z_C1_ZBARRIERSETC1_HPP
+
+#include "c1/c1_CodeStubs.hpp"
+#include "c1/c1_IR.hpp"
+#include "c1/c1_LIR.hpp"
+#include "gc/shared/c1/barrierSetC1.hpp"
+#include "oops/accessDecorators.hpp"
+
+class ZLoadBarrierStubC1 : public CodeStub {
+private:
+ DecoratorSet _decorators;
+ LIR_Opr _ref_addr;
+ LIR_Opr _ref;
+ LIR_Opr _tmp;
+ CodeEmitInfo* _patch_info;
+ address _runtime_stub;
+
+public:
+ ZLoadBarrierStubC1(LIRAccess& access, LIR_Opr ref, address runtime_stub);
+
+ DecoratorSet decorators() const;
+ LIR_Opr ref() const;
+ LIR_Opr ref_addr() const;
+ LIR_Opr tmp() const;
+ LIR_PatchCode patch_code() const;
+ CodeEmitInfo*& patch_info();
+ address runtime_stub() const;
+
+ virtual void emit_code(LIR_Assembler* ce);
+ virtual void visit(LIR_OpVisitState* visitor);
+
+#ifndef PRODUCT
+ virtual void print_name(outputStream* out) const;
+#endif // PRODUCT
+};
+
+class ZBarrierSetC1 : public BarrierSetC1 {
+private:
+ address _load_barrier_on_oop_field_preloaded_runtime_stub;
+ address _load_barrier_on_weak_oop_field_preloaded_runtime_stub;
+
+ address load_barrier_on_oop_field_preloaded_runtime_stub(DecoratorSet decorators) const;
+ void load_barrier(LIRAccess& access, LIR_Opr result) const;
+
+protected:
+ virtual void load_at_resolved(LIRAccess& access, LIR_Opr result);
+ virtual LIR_Opr atomic_xchg_at_resolved(LIRAccess& access, LIRItem& value);
+ virtual LIR_Opr atomic_cmpxchg_at_resolved(LIRAccess& access, LIRItem& cmp_value, LIRItem& new_value);
+
+public:
+ ZBarrierSetC1();
+
+ virtual void generate_c1_runtime_stubs(BufferBlob* blob);
+};
+
+#endif // SHARE_GC_Z_C1_ZBARRIERSETC1_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,1480 @@
+/*
+ * 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 "opto/compile.hpp"
+#include "opto/castnode.hpp"
+#include "opto/graphKit.hpp"
+#include "opto/idealKit.hpp"
+#include "opto/loopnode.hpp"
+#include "opto/macro.hpp"
+#include "opto/node.hpp"
+#include "opto/type.hpp"
+#include "utilities/macros.hpp"
+#include "gc/z/c2/zBarrierSetC2.hpp"
+#include "gc/z/zThreadLocalData.hpp"
+#include "gc/z/zBarrierSetRuntime.hpp"
+
+ZBarrierSetC2State::ZBarrierSetC2State(Arena* comp_arena)
+ : _load_barrier_nodes(new (comp_arena) GrowableArray<LoadBarrierNode*>(comp_arena, 8, 0, NULL)) {}
+
+int ZBarrierSetC2State::load_barrier_count() const {
+ return _load_barrier_nodes->length();
+}
+
+void ZBarrierSetC2State::add_load_barrier_node(LoadBarrierNode * n) {
+ assert(!_load_barrier_nodes->contains(n), " duplicate entry in expand list");
+ _load_barrier_nodes->append(n);
+}
+
+void ZBarrierSetC2State::remove_load_barrier_node(LoadBarrierNode * n) {
+ // this function may be called twice for a node so check
+ // that the node is in the array before attempting to remove it
+ if (_load_barrier_nodes->contains(n)) {
+ _load_barrier_nodes->remove(n);
+ }
+}
+
+LoadBarrierNode* ZBarrierSetC2State::load_barrier_node(int idx) const {
+ return _load_barrier_nodes->at(idx);
+}
+
+void* ZBarrierSetC2::create_barrier_state(Arena* comp_arena) const {
+ return new(comp_arena) ZBarrierSetC2State(comp_arena);
+}
+
+ZBarrierSetC2State* ZBarrierSetC2::state() const {
+ return reinterpret_cast<ZBarrierSetC2State*>(Compile::current()->barrier_set_state());
+}
+
+bool ZBarrierSetC2::is_gc_barrier_node(Node* node) const {
+ return node->is_LoadBarrier();
+}
+
+void ZBarrierSetC2::register_potential_barrier_node(Node* node) const {
+ if (node->is_LoadBarrier()) {
+ state()->add_load_barrier_node(node->as_LoadBarrier());
+ }
+}
+
+void ZBarrierSetC2::unregister_potential_barrier_node(Node* node) const {
+ if (node->is_LoadBarrier()) {
+ state()->remove_load_barrier_node(node->as_LoadBarrier());
+ }
+}
+
+void ZBarrierSetC2::eliminate_useless_gc_barriers(Unique_Node_List &useful) const {
+ // Remove useless LoadBarrier nodes
+ ZBarrierSetC2State* s = state();
+ for (int i = s->load_barrier_count()-1; i >= 0; i--) {
+ LoadBarrierNode* n = s->load_barrier_node(i);
+ if (!useful.member(n)) {
+ unregister_potential_barrier_node(n);
+ }
+ }
+}
+
+void ZBarrierSetC2::enqueue_useful_gc_barrier(Unique_Node_List &worklist, Node* node) const {
+ if (node->is_LoadBarrier() && !node->as_LoadBarrier()->has_true_uses()) {
+ worklist.push(node);
+ }
+}
+
+void ZBarrierSetC2::find_dominating_barriers(PhaseIterGVN& igvn) {
+ // Look for dominating barriers on the same address only once all
+ // other loop opts are over: loop opts may cause a safepoint to be
+ // inserted between a barrier and its dominating barrier.
+ Compile* C = Compile::current();
+ ZBarrierSetC2* bs = (ZBarrierSetC2*)BarrierSet::barrier_set()->barrier_set_c2();
+ ZBarrierSetC2State* s = bs->state();
+ if (s->load_barrier_count() >= 2) {
+ Compile::TracePhase tp("idealLoop", &C->timers[Phase::_t_idealLoop]);
+ PhaseIdealLoop ideal_loop(igvn, true, false, true);
+ if (C->major_progress()) C->print_method(PHASE_PHASEIDEALLOOP_ITERATIONS, 2);
+ }
+}
+
+void ZBarrierSetC2::add_users_to_worklist(Unique_Node_List* worklist) const {
+ // Permanent temporary workaround
+ // Loadbarriers may have non-obvious dead uses keeping them alive during parsing. The use is
+ // removed by RemoveUseless (after parsing, before optimize) but the barriers won't be added to
+ // the worklist. Unless we add them explicitly they are not guaranteed to end up there.
+ ZBarrierSetC2State* s = state();
+
+ for (int i = 0; i < s->load_barrier_count(); i++) {
+ LoadBarrierNode* n = s->load_barrier_node(i);
+ worklist->push(n);
+ }
+}
+
+const TypeFunc* ZBarrierSetC2::load_barrier_Type() const {
+ const Type** fields;
+
+ // Create input types (domain)
+ fields = TypeTuple::fields(2);
+ fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;
+ fields[TypeFunc::Parms+1] = TypeOopPtr::BOTTOM;
+ const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
+
+ // Create result type (range)
+ fields = TypeTuple::fields(1);
+ fields[TypeFunc::Parms+0] = TypeInstPtr::BOTTOM;
+ const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
+
+ return TypeFunc::make(domain, range);
+}
+
+// == LoadBarrierNode ==
+
+LoadBarrierNode::LoadBarrierNode(Compile* C,
+ Node* c,
+ Node* mem,
+ Node* val,
+ Node* adr,
+ bool weak,
+ bool writeback,
+ bool oop_reload_allowed) :
+ MultiNode(Number_of_Inputs),
+ _weak(weak),
+ _writeback(writeback),
+ _oop_reload_allowed(oop_reload_allowed) {
+ init_req(Control, c);
+ init_req(Memory, mem);
+ init_req(Oop, val);
+ init_req(Address, adr);
+ init_req(Similar, C->top());
+
+ init_class_id(Class_LoadBarrier);
+ BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
+ bs->register_potential_barrier_node(this);
+}
+
+const Type *LoadBarrierNode::bottom_type() const {
+ const Type** floadbarrier = (const Type **)(Compile::current()->type_arena()->Amalloc_4((Number_of_Outputs)*sizeof(Type*)));
+ Node* in_oop = in(Oop);
+ floadbarrier[Control] = Type::CONTROL;
+ floadbarrier[Memory] = Type::MEMORY;
+ floadbarrier[Oop] = in_oop == NULL ? Type::TOP : in_oop->bottom_type();
+ return TypeTuple::make(Number_of_Outputs, floadbarrier);
+}
+
+const Type *LoadBarrierNode::Value(PhaseGVN *phase) const {
+ const Type** floadbarrier = (const Type **)(phase->C->type_arena()->Amalloc_4((Number_of_Outputs)*sizeof(Type*)));
+ const Type* val_t = phase->type(in(Oop));
+ floadbarrier[Control] = Type::CONTROL;
+ floadbarrier[Memory] = Type::MEMORY;
+ floadbarrier[Oop] = val_t;
+ return TypeTuple::make(Number_of_Outputs, floadbarrier);
+}
+
+bool LoadBarrierNode::is_dominator(PhaseIdealLoop* phase, bool linear_only, Node *d, Node *n) {
+ if (phase != NULL) {
+ return phase->is_dominator(d, n);
+ }
+
+ for (int i = 0; i < 10 && n != NULL; i++) {
+ n = IfNode::up_one_dom(n, linear_only);
+ if (n == d) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+LoadBarrierNode* LoadBarrierNode::has_dominating_barrier(PhaseIdealLoop* phase, bool linear_only, bool look_for_similar) {
+ Node* val = in(LoadBarrierNode::Oop);
+ if (in(Similar)->is_Proj() && in(Similar)->in(0)->is_LoadBarrier()) {
+ LoadBarrierNode* lb = in(Similar)->in(0)->as_LoadBarrier();
+ assert(lb->in(Address) == in(Address), "");
+ // Load barrier on Similar edge dominates so if it now has the Oop field it can replace this barrier.
+ if (lb->in(Oop) == in(Oop)) {
+ return lb;
+ }
+ // Follow chain of load barrier through Similar edges
+ while (!lb->in(Similar)->is_top()) {
+ lb = lb->in(Similar)->in(0)->as_LoadBarrier();
+ assert(lb->in(Address) == in(Address), "");
+ }
+ if (lb != in(Similar)->in(0)) {
+ return lb;
+ }
+ }
+ for (DUIterator_Fast imax, i = val->fast_outs(imax); i < imax; i++) {
+ Node* u = val->fast_out(i);
+ if (u != this && u->is_LoadBarrier() && u->in(Oop) == val && u->as_LoadBarrier()->has_true_uses()) {
+ Node* this_ctrl = in(LoadBarrierNode::Control);
+ Node* other_ctrl = u->in(LoadBarrierNode::Control);
+ if (is_dominator(phase, linear_only, other_ctrl, this_ctrl)) {
+ return u->as_LoadBarrier();
+ }
+ }
+ }
+
+ if (ZVerifyLoadBarriers || can_be_eliminated()) {
+ return NULL;
+ }
+
+ if (!look_for_similar) {
+ return NULL;
+ }
+
+ Node* addr = in(LoadBarrierNode::Address);
+ for (DUIterator_Fast imax, i = addr->fast_outs(imax); i < imax; i++) {
+ Node* u = addr->fast_out(i);
+ if (u != this && u->is_LoadBarrier() && u->as_LoadBarrier()->has_true_uses()) {
+ Node* this_ctrl = in(LoadBarrierNode::Control);
+ Node* other_ctrl = u->in(LoadBarrierNode::Control);
+ if (is_dominator(phase, linear_only, other_ctrl, this_ctrl)) {
+ ResourceMark rm;
+ Unique_Node_List wq;
+ wq.push(in(LoadBarrierNode::Control));
+ bool ok = true;
+ bool dom_found = false;
+ for (uint next = 0; next < wq.size(); ++next) {
+ Node *n = wq.at(next);
+ if (n->is_top()) {
+ return NULL;
+ }
+ assert(n->is_CFG(), "");
+ if (n->is_SafePoint()) {
+ ok = false;
+ break;
+ }
+ if (n == u) {
+ dom_found = true;
+ continue;
+ }
+ if (n->is_Region()) {
+ for (uint i = 1; i < n->req(); i++) {
+ Node* m = n->in(i);
+ if (m != NULL) {
+ wq.push(m);
+ }
+ }
+ } else {
+ Node* m = n->in(0);
+ if (m != NULL) {
+ wq.push(m);
+ }
+ }
+ }
+ if (ok) {
+ assert(dom_found, "");
+ return u->as_LoadBarrier();;
+ }
+ break;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+void LoadBarrierNode::push_dominated_barriers(PhaseIterGVN* igvn) const {
+ // change to that barrier may affect a dominated barrier so re-push those
+ Node* val = in(LoadBarrierNode::Oop);
+
+ for (DUIterator_Fast imax, i = val->fast_outs(imax); i < imax; i++) {
+ Node* u = val->fast_out(i);
+ if (u != this && u->is_LoadBarrier() && u->in(Oop) == val) {
+ Node* this_ctrl = in(Control);
+ Node* other_ctrl = u->in(Control);
+ if (is_dominator(NULL, false, this_ctrl, other_ctrl)) {
+ igvn->_worklist.push(u);
+ }
+ }
+
+ Node* addr = in(LoadBarrierNode::Address);
+ for (DUIterator_Fast imax, i = addr->fast_outs(imax); i < imax; i++) {
+ Node* u = addr->fast_out(i);
+ if (u != this && u->is_LoadBarrier() && u->in(Similar)->is_top()) {
+ Node* this_ctrl = in(Control);
+ Node* other_ctrl = u->in(Control);
+ if (is_dominator(NULL, false, this_ctrl, other_ctrl)) {
+ igvn->_worklist.push(u);
+ }
+ }
+ }
+ }
+}
+
+Node *LoadBarrierNode::Identity(PhaseGVN *phase) {
+ if (!phase->C->directive()->ZOptimizeLoadBarriersOption) {
+ return this;
+ }
+
+ bool redundant_addr = false;
+ LoadBarrierNode* dominating_barrier = has_dominating_barrier(NULL, true, false);
+ if (dominating_barrier != NULL) {
+ assert(dominating_barrier->in(Oop) == in(Oop), "");
+ return dominating_barrier;
+ }
+
+ return this;
+}
+
+Node *LoadBarrierNode::Ideal(PhaseGVN *phase, bool can_reshape) {
+ if (remove_dead_region(phase, can_reshape)) {
+ return this;
+ }
+
+ Node* val = in(Oop);
+ Node* mem = in(Memory);
+ Node* ctrl = in(Control);
+ Node* adr = in(Address);
+ assert(val->Opcode() != Op_LoadN, "");
+
+ if (mem->is_MergeMem()) {
+ Node* new_mem = mem->as_MergeMem()->memory_at(Compile::AliasIdxRaw);
+ set_req(Memory, new_mem);
+ if (mem->outcnt() == 0 && can_reshape) {
+ phase->is_IterGVN()->_worklist.push(mem);
+ }
+
+ return this;
+ }
+
+ bool optimizeLoadBarriers = phase->C->directive()->ZOptimizeLoadBarriersOption;
+ LoadBarrierNode* dominating_barrier = optimizeLoadBarriers ? has_dominating_barrier(NULL, !can_reshape, !phase->C->major_progress()) : NULL;
+ if (dominating_barrier != NULL && dominating_barrier->in(Oop) != in(Oop)) {
+ assert(in(Address) == dominating_barrier->in(Address), "");
+ set_req(Similar, dominating_barrier->proj_out(Oop));
+ return this;
+ }
+
+ bool eliminate = (optimizeLoadBarriers && !(val->is_Phi() || val->Opcode() == Op_LoadP || val->Opcode() == Op_GetAndSetP || val->is_DecodeN())) ||
+ (can_reshape && (dominating_barrier != NULL || !has_true_uses()));
+
+ if (eliminate) {
+ if (can_reshape) {
+ PhaseIterGVN* igvn = phase->is_IterGVN();
+ Node* out_ctrl = proj_out_or_null(Control);
+ Node* out_res = proj_out_or_null(Oop);
+
+ if (out_ctrl != NULL) {
+ igvn->replace_node(out_ctrl, ctrl);
+ }
+
+ // That transformation may cause the Similar edge on the load barrier to be invalid
+ fix_similar_in_uses(igvn);
+ if (out_res != NULL) {
+ if (dominating_barrier != NULL) {
+ igvn->replace_node(out_res, dominating_barrier->proj_out(Oop));
+ } else {
+ igvn->replace_node(out_res, val);
+ }
+ }
+ }
+
+ return new ConINode(TypeInt::ZERO);
+ }
+
+ // If the Similar edge is no longer a load barrier, clear it
+ Node* similar = in(Similar);
+ if (!similar->is_top() && !(similar->is_Proj() && similar->in(0)->is_LoadBarrier())) {
+ set_req(Similar, phase->C->top());
+ return this;
+ }
+
+ if (can_reshape) {
+ // If this barrier is linked through the Similar edge by a
+ // dominated barrier and both barriers have the same Oop field,
+ // the dominated barrier can go away, so push it for reprocessing.
+ // We also want to avoid a barrier to depend on another dominating
+ // barrier through its Similar edge that itself depend on another
+ // barrier through its Similar edge and rather have the first
+ // depend on the third.
+ PhaseIterGVN* igvn = phase->is_IterGVN();
+ Node* out_res = proj_out(Oop);
+ for (DUIterator_Fast imax, i = out_res->fast_outs(imax); i < imax; i++) {
+ Node* u = out_res->fast_out(i);
+ if (u->is_LoadBarrier() && u->in(Similar) == out_res &&
+ (u->in(Oop) == val || !u->in(Similar)->is_top())) {
+ igvn->_worklist.push(u);
+ }
+ }
+
+ push_dominated_barriers(igvn);
+ }
+
+ return NULL;
+}
+
+void LoadBarrierNode::fix_similar_in_uses(PhaseIterGVN* igvn) {
+ Node* out_res = proj_out_or_null(Oop);
+ if (out_res == NULL) {
+ return;
+ }
+
+ for (DUIterator_Fast imax, i = out_res->fast_outs(imax); i < imax; i++) {
+ Node* u = out_res->fast_out(i);
+ if (u->is_LoadBarrier() && u->in(Similar) == out_res) {
+ igvn->replace_input_of(u, Similar, igvn->C->top());
+ --i;
+ --imax;
+ }
+ }
+}
+
+bool LoadBarrierNode::has_true_uses() const {
+ Node* out_res = proj_out_or_null(Oop);
+ if (out_res == NULL) {
+ return false;
+ }
+
+ for (DUIterator_Fast imax, i = out_res->fast_outs(imax); i < imax; i++) {
+ Node* u = out_res->fast_out(i);
+ if (!u->is_LoadBarrier() || u->in(Similar) != out_res) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// == Accesses ==
+
+Node* ZBarrierSetC2::make_cas_loadbarrier(C2AtomicAccess& access) const {
+ assert(!UseCompressedOops, "Not allowed");
+ CompareAndSwapNode* cas = (CompareAndSwapNode*)access.raw_access();
+ PhaseGVN& gvn = access.kit()->gvn();
+ Compile* C = Compile::current();
+ GraphKit* kit = access.kit();
+
+ Node* in_ctrl = cas->in(MemNode::Control);
+ Node* in_mem = cas->in(MemNode::Memory);
+ Node* in_adr = cas->in(MemNode::Address);
+ Node* in_val = cas->in(MemNode::ValueIn);
+ Node* in_expected = cas->in(LoadStoreConditionalNode::ExpectedIn);
+
+ float likely = PROB_LIKELY(0.999);
+
+ const TypePtr *adr_type = gvn.type(in_adr)->isa_ptr();
+ Compile::AliasType* alias_type = C->alias_type(adr_type);
+ int alias_idx = C->get_alias_index(adr_type);
+
+ // Outer check - true: continue, false: load and check
+ Node* region = new RegionNode(3);
+ Node* phi = new PhiNode(region, TypeInt::BOOL);
+ Node* phi_mem = new PhiNode(region, Type::MEMORY, adr_type);
+
+ // Inner check - is the healed ref equal to the expected
+ Node* region2 = new RegionNode(3);
+ Node* phi2 = new PhiNode(region2, TypeInt::BOOL);
+ Node* phi_mem2 = new PhiNode(region2, Type::MEMORY, adr_type);
+
+ // CAS node returns 0 or 1
+ Node* cmp = gvn.transform(new CmpINode(cas, kit->intcon(0)));
+ Node* bol = gvn.transform(new BoolNode(cmp, BoolTest::ne))->as_Bool();
+ IfNode* iff = gvn.transform(new IfNode(in_ctrl, bol, likely, COUNT_UNKNOWN))->as_If();
+ Node* then = gvn.transform(new IfTrueNode(iff));
+ Node* elsen = gvn.transform(new IfFalseNode(iff));
+
+ Node* scmemproj1 = gvn.transform(new SCMemProjNode(cas));
+
+ kit->set_memory(scmemproj1, alias_idx);
+ phi_mem->init_req(1, scmemproj1);
+ phi_mem2->init_req(2, scmemproj1);
+
+ // CAS fail - reload and heal oop
+ Node* reload = kit->make_load(elsen, in_adr, TypeOopPtr::BOTTOM, T_OBJECT, MemNode::unordered);
+ Node* barrier = gvn.transform(new LoadBarrierNode(C, elsen, scmemproj1, reload, in_adr, false, true, false));
+ Node* barrierctrl = gvn.transform(new ProjNode(barrier, LoadBarrierNode::Control));
+ Node* barrierdata = gvn.transform(new ProjNode(barrier, LoadBarrierNode::Oop));
+
+ // Check load
+ Node* tmpX = gvn.transform(new CastP2XNode(NULL, barrierdata));
+ Node* in_expX = gvn.transform(new CastP2XNode(NULL, in_expected));
+ Node* cmp2 = gvn.transform(new CmpXNode(tmpX, in_expX));
+ Node *bol2 = gvn.transform(new BoolNode(cmp2, BoolTest::ne))->as_Bool();
+ IfNode* iff2 = gvn.transform(new IfNode(barrierctrl, bol2, likely, COUNT_UNKNOWN))->as_If();
+ Node* then2 = gvn.transform(new IfTrueNode(iff2));
+ Node* elsen2 = gvn.transform(new IfFalseNode(iff2));
+
+ // redo CAS
+ Node* cas2 = gvn.transform(new CompareAndSwapPNode(elsen2, kit->memory(alias_idx), in_adr, in_val, in_expected, cas->order()));
+ Node* scmemproj2 = gvn.transform(new SCMemProjNode(cas2));
+ kit->set_control(elsen2);
+ kit->set_memory(scmemproj2, alias_idx);
+
+ // Merge inner flow - check if healed oop was equal too expected.
+ region2->set_req(1, kit->control());
+ region2->set_req(2, then2);
+ phi2->set_req(1, cas2);
+ phi2->set_req(2, kit->intcon(0));
+ phi_mem2->init_req(1, scmemproj2);
+ kit->set_memory(phi_mem2, alias_idx);
+
+ // Merge outer flow - then check if first cas succeded
+ region->set_req(1, then);
+ region->set_req(2, region2);
+ phi->set_req(1, kit->intcon(1));
+ phi->set_req(2, phi2);
+ phi_mem->init_req(2, phi_mem2);
+ kit->set_memory(phi_mem, alias_idx);
+
+ gvn.transform(region2);
+ gvn.transform(phi2);
+ gvn.transform(phi_mem2);
+ gvn.transform(region);
+ gvn.transform(phi);
+ gvn.transform(phi_mem);
+
+ kit->set_control(region);
+ kit->insert_mem_bar(Op_MemBarCPUOrder);
+
+ return phi;
+}
+
+Node* ZBarrierSetC2::make_cmpx_loadbarrier(C2AtomicAccess& access) const {
+ CompareAndExchangePNode* cmpx = (CompareAndExchangePNode*)access.raw_access();
+ GraphKit* kit = access.kit();
+ PhaseGVN& gvn = kit->gvn();
+ Compile* C = Compile::current();
+
+ Node* in_ctrl = cmpx->in(MemNode::Control);
+ Node* in_mem = cmpx->in(MemNode::Memory);
+ Node* in_adr = cmpx->in(MemNode::Address);
+ Node* in_val = cmpx->in(MemNode::ValueIn);
+ Node* in_expected = cmpx->in(LoadStoreConditionalNode::ExpectedIn);
+
+ float likely = PROB_LIKELY(0.999);
+
+ const TypePtr *adr_type = cmpx->get_ptr_type();
+ Compile::AliasType* alias_type = C->alias_type(adr_type);
+ int alias_idx = C->get_alias_index(adr_type);
+
+ // Outer check - true: continue, false: load and check
+ Node* region = new RegionNode(3);
+ Node* phi = new PhiNode(region, adr_type);
+
+ // Inner check - is the healed ref equal to the expected
+ Node* region2 = new RegionNode(3);
+ Node* phi2 = new PhiNode(region2, adr_type);
+
+ // Check if cmpx succeded
+ Node* cmp = gvn.transform(new CmpPNode(cmpx, in_expected));
+ Node* bol = gvn.transform(new BoolNode(cmp, BoolTest::eq))->as_Bool();
+ IfNode* iff = gvn.transform(new IfNode(in_ctrl, bol, likely, COUNT_UNKNOWN))->as_If();
+ Node* then = gvn.transform(new IfTrueNode(iff));
+ Node* elsen = gvn.transform(new IfFalseNode(iff));
+
+ Node* scmemproj1 = gvn.transform(new SCMemProjNode(cmpx));
+ kit->set_memory(scmemproj1, alias_idx);
+
+ // CAS fail - reload and heal oop
+ Node* reload = kit->make_load(elsen, in_adr, TypeOopPtr::BOTTOM, T_OBJECT, MemNode::unordered);
+ Node* barrier = gvn.transform(new LoadBarrierNode(C, elsen, scmemproj1, reload, in_adr, false, true, false));
+ Node* barrierctrl = gvn.transform(new ProjNode(barrier, LoadBarrierNode::Control));
+ Node* barrierdata = gvn.transform(new ProjNode(barrier, LoadBarrierNode::Oop));
+
+ // Check load
+ Node* tmpX = gvn.transform(new CastP2XNode(NULL, barrierdata));
+ Node* in_expX = gvn.transform(new CastP2XNode(NULL, in_expected));
+ Node* cmp2 = gvn.transform(new CmpXNode(tmpX, in_expX));
+ Node *bol2 = gvn.transform(new BoolNode(cmp2, BoolTest::ne))->as_Bool();
+ IfNode* iff2 = gvn.transform(new IfNode(barrierctrl, bol2, likely, COUNT_UNKNOWN))->as_If();
+ Node* then2 = gvn.transform(new IfTrueNode(iff2));
+ Node* elsen2 = gvn.transform(new IfFalseNode(iff2));
+
+ // Redo CAS
+ Node* cmpx2 = gvn.transform(new CompareAndExchangePNode(elsen2, kit->memory(alias_idx), in_adr, in_val, in_expected, adr_type, cmpx->get_ptr_type(), cmpx->order()));
+ Node* scmemproj2 = gvn.transform(new SCMemProjNode(cmpx2));
+ kit->set_control(elsen2);
+ kit->set_memory(scmemproj2, alias_idx);
+
+ // Merge inner flow - check if healed oop was equal too expected.
+ region2->set_req(1, kit->control());
+ region2->set_req(2, then2);
+ phi2->set_req(1, cmpx2);
+ phi2->set_req(2, barrierdata);
+
+ // Merge outer flow - then check if first cas succeded
+ region->set_req(1, then);
+ region->set_req(2, region2);
+ phi->set_req(1, cmpx);
+ phi->set_req(2, phi2);
+
+ gvn.transform(region2);
+ gvn.transform(phi2);
+ gvn.transform(region);
+ gvn.transform(phi);
+
+ kit->set_control(region);
+ kit->set_memory(in_mem, alias_idx);
+ kit->insert_mem_bar(Op_MemBarCPUOrder);
+
+ return phi;
+}
+
+Node* ZBarrierSetC2::load_barrier(GraphKit* kit, Node* val, Node* adr, bool weak, bool writeback, bool oop_reload_allowed) const {
+ PhaseGVN& gvn = kit->gvn();
+ Node* barrier = new LoadBarrierNode(Compile::current(), kit->control(), kit->memory(TypeRawPtr::BOTTOM), val, adr, weak, writeback, oop_reload_allowed);
+ Node* transformed_barrier = gvn.transform(barrier);
+
+ if (transformed_barrier->is_LoadBarrier()) {
+ if (barrier == transformed_barrier) {
+ kit->set_control(gvn.transform(new ProjNode(barrier, LoadBarrierNode::Control)));
+ }
+ return gvn.transform(new ProjNode(transformed_barrier, LoadBarrierNode::Oop));
+ } else {
+ return val;
+ }
+}
+
+static bool barrier_needed(C2Access access) {
+ return ZBarrierSet::barrier_needed(access.decorators(), access.type());
+}
+
+Node* ZBarrierSetC2::load_at_resolved(C2Access& access, const Type* val_type) const {
+ Node* p = BarrierSetC2::load_at_resolved(access, val_type);
+ if (!barrier_needed(access)) {
+ return p;
+ }
+
+ bool conc_root = (access.decorators() & IN_CONCURRENT_ROOT) != 0;
+ bool weak = (access.decorators() & ON_WEAK_OOP_REF) != 0;
+
+ GraphKit* kit = access.kit();
+ PhaseGVN& gvn = kit->gvn();
+ Node* adr = access.addr().node();
+ Node* heap_base_oop = access.base();
+ bool unsafe = (access.decorators() & C2_UNSAFE_ACCESS) != 0;
+ if (unsafe) {
+ if (!ZVerifyLoadBarriers) {
+ p = load_barrier(kit, p, adr);
+ } else {
+ if (!TypePtr::NULL_PTR->higher_equal(gvn.type(heap_base_oop))) {
+ p = load_barrier(kit, p, adr);
+ } else {
+ IdealKit ideal(kit);
+ IdealVariable res(ideal);
+#define __ ideal.
+ __ declarations_done();
+ __ set(res, p);
+ __ if_then(heap_base_oop, BoolTest::ne, kit->null(), PROB_UNLIKELY(0.999)); {
+ kit->sync_kit(ideal);
+ p = load_barrier(kit, p, adr);
+ __ set(res, p);
+ __ sync_kit(kit);
+ } __ end_if();
+ kit->final_sync(ideal);
+ p = __ value(res);
+#undef __
+ }
+ }
+ return p;
+ } else {
+ return load_barrier(access.kit(), p, access.addr().node(), weak, true, true);
+ }
+}
+
+Node* ZBarrierSetC2::atomic_cmpxchg_val_at_resolved(C2AtomicAccess& access, Node* expected_val,
+ Node* new_val, const Type* val_type) const {
+ Node* result = BarrierSetC2::atomic_cmpxchg_val_at_resolved(access, expected_val, new_val, val_type);
+ if (!barrier_needed(access)) {
+ return result;
+ }
+
+ access.set_needs_pinning(false);
+ return make_cmpx_loadbarrier(access);
+}
+
+Node* ZBarrierSetC2::atomic_cmpxchg_bool_at_resolved(C2AtomicAccess& access, Node* expected_val,
+ Node* new_val, const Type* value_type) const {
+ Node* result = BarrierSetC2::atomic_cmpxchg_bool_at_resolved(access, expected_val, new_val, value_type);
+ if (!barrier_needed(access)) {
+ return result;
+ }
+
+ Node* load_store = access.raw_access();
+ bool weak_cas = (access.decorators() & C2_WEAK_CMPXCHG) != 0;
+ bool expected_is_null = (expected_val->get_ptr_type() == TypePtr::NULL_PTR);
+
+ if (!expected_is_null) {
+ if (weak_cas) {
+ access.set_needs_pinning(false);
+ load_store = make_cas_loadbarrier(access);
+ } else {
+ access.set_needs_pinning(false);
+ load_store = make_cas_loadbarrier(access);
+ }
+ }
+
+ return load_store;
+}
+
+Node* ZBarrierSetC2::atomic_xchg_at_resolved(C2AtomicAccess& access, Node* new_val, const Type* val_type) const {
+ Node* result = BarrierSetC2::atomic_xchg_at_resolved(access, new_val, val_type);
+ if (!barrier_needed(access)) {
+ return result;
+ }
+
+ Node* load_store = access.raw_access();
+ Node* adr = access.addr().node();
+
+ return load_barrier(access.kit(), load_store, adr, false, false, false);
+}
+
+// == Macro Expansion ==
+
+void ZBarrierSetC2::expand_loadbarrier_node(PhaseMacroExpand* phase, LoadBarrierNode* barrier) const {
+ Node* in_ctrl = barrier->in(LoadBarrierNode::Control);
+ Node* in_mem = barrier->in(LoadBarrierNode::Memory);
+ Node* in_val = barrier->in(LoadBarrierNode::Oop);
+ Node* in_adr = barrier->in(LoadBarrierNode::Address);
+
+ Node* out_ctrl = barrier->proj_out(LoadBarrierNode::Control);
+ Node* out_res = barrier->proj_out(LoadBarrierNode::Oop);
+
+ PhaseIterGVN &igvn = phase->igvn();
+
+ if (ZVerifyLoadBarriers) {
+ igvn.replace_node(out_res, in_val);
+ igvn.replace_node(out_ctrl, in_ctrl);
+ return;
+ }
+
+ if (barrier->can_be_eliminated()) {
+ // Clone and pin the load for this barrier below the dominating
+ // barrier: the load cannot be allowed to float above the
+ // dominating barrier
+ Node* load = in_val;
+
+ if (load->is_Load()) {
+ Node* new_load = load->clone();
+ Node* addp = new_load->in(MemNode::Address);
+ assert(addp->is_AddP() || addp->is_Phi() || addp->is_Load(), "bad address");
+ Node* cast = new CastPPNode(addp, igvn.type(addp), true);
+ Node* ctrl = NULL;
+ Node* similar = barrier->in(LoadBarrierNode::Similar);
+ if (similar->is_Phi()) {
+ // already expanded
+ ctrl = similar->in(0);
+ } else {
+ assert(similar->is_Proj() && similar->in(0)->is_LoadBarrier(), "unexpected graph shape");
+ ctrl = similar->in(0)->as_LoadBarrier()->proj_out(LoadBarrierNode::Control);
+ }
+ assert(ctrl != NULL, "bad control");
+ cast->set_req(0, ctrl);
+ igvn.transform(cast);
+ new_load->set_req(MemNode::Address, cast);
+ igvn.transform(new_load);
+
+ igvn.replace_node(out_res, new_load);
+ igvn.replace_node(out_ctrl, in_ctrl);
+ return;
+ }
+ // cannot eliminate
+ }
+
+ // There are two cases that require the basic loadbarrier
+ // 1) When the writeback of a healed oop must be avoided (swap)
+ // 2) When we must guarantee that no reload of is done (swap, cas, cmpx)
+ if (!barrier->is_writeback()) {
+ assert(!barrier->oop_reload_allowed(), "writeback barriers should be marked as requires oop");
+ }
+
+ if (!barrier->oop_reload_allowed()) {
+ expand_loadbarrier_basic(phase, barrier);
+ } else {
+ expand_loadbarrier_optimized(phase, barrier);
+ }
+}
+
+// Basic loadbarrier using conventional arg passing
+void ZBarrierSetC2::expand_loadbarrier_basic(PhaseMacroExpand* phase, LoadBarrierNode *barrier) const {
+ PhaseIterGVN &igvn = phase->igvn();
+
+ Node* in_ctrl = barrier->in(LoadBarrierNode::Control);
+ Node* in_mem = barrier->in(LoadBarrierNode::Memory);
+ Node* in_val = barrier->in(LoadBarrierNode::Oop);
+ Node* in_adr = barrier->in(LoadBarrierNode::Address);
+
+ Node* out_ctrl = barrier->proj_out(LoadBarrierNode::Control);
+ Node* out_res = barrier->proj_out(LoadBarrierNode::Oop);
+
+ float unlikely = PROB_UNLIKELY(0.999);
+ const Type* in_val_maybe_null_t = igvn.type(in_val);
+
+ Node* jthread = igvn.transform(new ThreadLocalNode());
+ Node* adr = phase->basic_plus_adr(jthread, in_bytes(ZThreadLocalData::address_bad_mask_offset()));
+ Node* bad_mask = igvn.transform(LoadNode::make(igvn, in_ctrl, in_mem, adr, TypeRawPtr::BOTTOM, TypeX_X, TypeX_X->basic_type(), MemNode::unordered));
+ Node* cast = igvn.transform(new CastP2XNode(in_ctrl, in_val));
+ Node* obj_masked = igvn.transform(new AndXNode(cast, bad_mask));
+ Node* cmp = igvn.transform(new CmpXNode(obj_masked, igvn.zerocon(TypeX_X->basic_type())));
+ Node *bol = igvn.transform(new BoolNode(cmp, BoolTest::ne))->as_Bool();
+ IfNode* iff = igvn.transform(new IfNode(in_ctrl, bol, unlikely, COUNT_UNKNOWN))->as_If();
+ Node* then = igvn.transform(new IfTrueNode(iff));
+ Node* elsen = igvn.transform(new IfFalseNode(iff));
+
+ Node* result_region;
+ Node* result_val;
+
+ result_region = new RegionNode(3);
+ result_val = new PhiNode(result_region, TypeInstPtr::BOTTOM);
+
+ result_region->set_req(1, elsen);
+ Node* res = igvn.transform(new CastPPNode(in_val, in_val_maybe_null_t));
+ res->init_req(0, elsen);
+ result_val->set_req(1, res);
+
+ const TypeFunc *tf = load_barrier_Type();
+ Node* call;
+ if (barrier->is_weak()) {
+ call = new CallLeafNode(tf,
+ ZBarrierSetRuntime::load_barrier_on_weak_oop_field_preloaded_addr(),
+ "ZBarrierSetRuntime::load_barrier_on_weak_oop_field_preloaded",
+ TypeRawPtr::BOTTOM);
+ } else {
+ call = new CallLeafNode(tf,
+ ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(),
+ "ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded",
+ TypeRawPtr::BOTTOM);
+ }
+
+ call->init_req(TypeFunc::Control, then);
+ call->init_req(TypeFunc::I_O , phase->top());
+ call->init_req(TypeFunc::Memory , in_mem);
+ call->init_req(TypeFunc::FramePtr, phase->top());
+ call->init_req(TypeFunc::ReturnAdr, phase->top());
+ call->init_req(TypeFunc::Parms+0, in_val);
+ if (barrier->is_writeback()) {
+ call->init_req(TypeFunc::Parms+1, in_adr);
+ } else {
+ // when slow path is called with a null adr, the healed oop will not be written back
+ call->init_req(TypeFunc::Parms+1, igvn.zerocon(T_OBJECT));
+ }
+ call = igvn.transform(call);
+
+ Node* ctrl = igvn.transform(new ProjNode(call, TypeFunc::Control));
+ res = igvn.transform(new ProjNode(call, TypeFunc::Parms));
+ res = igvn.transform(new CheckCastPPNode(ctrl, res, in_val_maybe_null_t));
+
+ result_region->set_req(2, ctrl);
+ result_val->set_req(2, res);
+
+ result_region = igvn.transform(result_region);
+ result_val = igvn.transform(result_val);
+
+ if (out_ctrl != NULL) { // added if cond
+ igvn.replace_node(out_ctrl, result_region);
+ }
+ igvn.replace_node(out_res, result_val);
+}
+
+// Optimized, low spill, loadbarrier variant using stub specialized on register used
+void ZBarrierSetC2::expand_loadbarrier_optimized(PhaseMacroExpand* phase, LoadBarrierNode *barrier) const {
+ PhaseIterGVN &igvn = phase->igvn();
+#ifdef PRINT_NODE_TRAVERSALS
+ Node* preceding_barrier_node = barrier->in(LoadBarrierNode::Oop);
+#endif
+
+ Node* in_ctrl = barrier->in(LoadBarrierNode::Control);
+ Node* in_mem = barrier->in(LoadBarrierNode::Memory);
+ Node* in_val = barrier->in(LoadBarrierNode::Oop);
+ Node* in_adr = barrier->in(LoadBarrierNode::Address);
+
+ Node* out_ctrl = barrier->proj_out(LoadBarrierNode::Control);
+ Node* out_res = barrier->proj_out(LoadBarrierNode::Oop);
+
+ assert(barrier->in(LoadBarrierNode::Oop) != NULL, "oop to loadbarrier node cannot be null");
+
+#ifdef PRINT_NODE_TRAVERSALS
+ tty->print("\n\n\nBefore barrier optimization:\n");
+ traverse(barrier, out_ctrl, out_res, -1);
+
+ tty->print("\nBefore barrier optimization: preceding_barrier_node\n");
+ traverse(preceding_barrier_node, out_ctrl, out_res, -1);
+#endif
+
+ float unlikely = PROB_UNLIKELY(0.999);
+
+ Node* jthread = igvn.transform(new ThreadLocalNode());
+ Node* adr = phase->basic_plus_adr(jthread, in_bytes(ZThreadLocalData::address_bad_mask_offset()));
+ Node* bad_mask = igvn.transform(LoadNode::make(igvn, in_ctrl, in_mem, adr,
+ TypeRawPtr::BOTTOM, TypeX_X, TypeX_X->basic_type(),
+ MemNode::unordered));
+ Node* cast = igvn.transform(new CastP2XNode(in_ctrl, in_val));
+ Node* obj_masked = igvn.transform(new AndXNode(cast, bad_mask));
+ Node* cmp = igvn.transform(new CmpXNode(obj_masked, igvn.zerocon(TypeX_X->basic_type())));
+ Node *bol = igvn.transform(new BoolNode(cmp, BoolTest::ne))->as_Bool();
+ IfNode* iff = igvn.transform(new IfNode(in_ctrl, bol, unlikely, COUNT_UNKNOWN))->as_If();
+ Node* then = igvn.transform(new IfTrueNode(iff));
+ Node* elsen = igvn.transform(new IfFalseNode(iff));
+
+ Node* slow_path_surrogate;
+ if (!barrier->is_weak()) {
+ slow_path_surrogate = igvn.transform(new LoadBarrierSlowRegNode(then, in_mem, in_adr, in_val->adr_type(),
+ (const TypePtr*) in_val->bottom_type(), MemNode::unordered));
+ } else {
+ slow_path_surrogate = igvn.transform(new LoadBarrierWeakSlowRegNode(then, in_mem, in_adr, in_val->adr_type(),
+ (const TypePtr*) in_val->bottom_type(), MemNode::unordered));
+ }
+
+ Node *new_loadp;
+ new_loadp = slow_path_surrogate;
+ // create the final region/phi pair to converge cntl/data paths to downstream code
+ Node* result_region = igvn.transform(new RegionNode(3));
+ result_region->set_req(1, then);
+ result_region->set_req(2, elsen);
+
+ Node* result_phi = igvn.transform(new PhiNode(result_region, TypeInstPtr::BOTTOM));
+ result_phi->set_req(1, new_loadp);
+ result_phi->set_req(2, barrier->in(LoadBarrierNode::Oop));
+
+ // finally, connect the original outputs to the barrier region and phi to complete the expansion/substitution
+ // igvn.replace_node(out_ctrl, result_region);
+ if (out_ctrl != NULL) { // added if cond
+ igvn.replace_node(out_ctrl, result_region);
+ }
+ igvn.replace_node(out_res, result_phi);
+
+ assert(barrier->outcnt() == 0,"LoadBarrier macro node has non-null outputs after expansion!");
+
+#ifdef PRINT_NODE_TRAVERSALS
+ tty->print("\nAfter barrier optimization: old out_ctrl\n");
+ traverse(out_ctrl, out_ctrl, out_res, -1);
+ tty->print("\nAfter barrier optimization: old out_res\n");
+ traverse(out_res, out_ctrl, out_res, -1);
+ tty->print("\nAfter barrier optimization: old barrier\n");
+ traverse(barrier, out_ctrl, out_res, -1);
+ tty->print("\nAfter barrier optimization: preceding_barrier_node\n");
+ traverse(preceding_barrier_node, result_region, result_phi, -1);
+#endif
+
+ return;
+}
+
+bool ZBarrierSetC2::expand_macro_nodes(PhaseMacroExpand* macro) const {
+ Compile* C = Compile::current();
+ PhaseIterGVN &igvn = macro->igvn();
+ ZBarrierSetC2State* s = state();
+ if (s->load_barrier_count() > 0) {
+#ifdef ASSERT
+ verify_gc_barriers(false);
+#endif
+ igvn.set_delay_transform(true);
+ int skipped = 0;
+ while (s->load_barrier_count() > skipped) {
+ int load_barrier_count = s->load_barrier_count();
+ LoadBarrierNode * n = s->load_barrier_node(load_barrier_count-1-skipped);
+ if (igvn.type(n) == Type::TOP || (n->in(0) != NULL && n->in(0)->is_top())) {
+ // node is unreachable, so don't try to expand it
+ s->remove_load_barrier_node(n);
+ continue;
+ }
+ if (!n->can_be_eliminated()) {
+ skipped++;
+ continue;
+ }
+ expand_loadbarrier_node(macro, n);
+ assert(s->load_barrier_count() < load_barrier_count, "must have deleted a node from load barrier list");
+ if (C->failing()) return true;
+ }
+ while (s->load_barrier_count() > 0) {
+ int load_barrier_count = s->load_barrier_count();
+ LoadBarrierNode* n = s->load_barrier_node(load_barrier_count - 1);
+ assert(!(igvn.type(n) == Type::TOP || (n->in(0) != NULL && n->in(0)->is_top())), "should have been processed already");
+ assert(!n->can_be_eliminated(), "should have been processed already");
+ expand_loadbarrier_node(macro, n);
+ assert(s->load_barrier_count() < load_barrier_count, "must have deleted a node from load barrier list");
+ if (C->failing()) return true;
+ }
+ igvn.set_delay_transform(false);
+ igvn.optimize();
+ if (C->failing()) return true;
+ }
+ return false;
+}
+
+// == Loop optimization ==
+
+static bool replace_with_dominating_barrier(PhaseIdealLoop* phase, LoadBarrierNode* lb, bool last_round) {
+ PhaseIterGVN &igvn = phase->igvn();
+ Compile* C = Compile::current();
+
+ LoadBarrierNode* lb2 = lb->has_dominating_barrier(phase, false, last_round);
+ if (lb2 != NULL) {
+ if (lb->in(LoadBarrierNode::Oop) != lb2->in(LoadBarrierNode::Oop)) {
+ assert(lb->in(LoadBarrierNode::Address) == lb2->in(LoadBarrierNode::Address), "");
+ igvn.replace_input_of(lb, LoadBarrierNode::Similar, lb2->proj_out(LoadBarrierNode::Oop));
+ C->set_major_progress();
+ } else {
+ // That transformation may cause the Similar edge on dominated load barriers to be invalid
+ lb->fix_similar_in_uses(&igvn);
+
+ Node* val = lb->proj_out(LoadBarrierNode::Oop);
+ assert(lb2->has_true_uses(), "");
+ assert(lb2->in(LoadBarrierNode::Oop) == lb->in(LoadBarrierNode::Oop), "");
+
+ phase->lazy_update(lb, lb->in(LoadBarrierNode::Control));
+ phase->lazy_replace(lb->proj_out(LoadBarrierNode::Control), lb->in(LoadBarrierNode::Control));
+ igvn.replace_node(val, lb2->proj_out(LoadBarrierNode::Oop));
+
+ return true;
+ }
+ }
+ return false;
+}
+
+static Node* find_dominating_memory(PhaseIdealLoop* phase, Node* mem, Node* dom, int i) {
+ assert(dom->is_Region() || i == -1, "");
+ Node* m = mem;
+ while(phase->is_dominator(dom, phase->has_ctrl(m) ? phase->get_ctrl(m) : m->in(0))) {
+ if (m->is_Mem()) {
+ assert(m->as_Mem()->adr_type() == TypeRawPtr::BOTTOM, "");
+ m = m->in(MemNode::Memory);
+ } else if (m->is_MergeMem()) {
+ m = m->as_MergeMem()->memory_at(Compile::AliasIdxRaw);
+ } else if (m->is_Phi()) {
+ if (m->in(0) == dom && i != -1) {
+ m = m->in(i);
+ break;
+ } else {
+ m = m->in(LoopNode::EntryControl);
+ }
+ } else if (m->is_Proj()) {
+ m = m->in(0);
+ } else if (m->is_SafePoint() || m->is_MemBar()) {
+ m = m->in(TypeFunc::Memory);
+ } else {
+#ifdef ASSERT
+ m->dump();
+#endif
+ ShouldNotReachHere();
+ }
+ }
+ return m;
+}
+
+static LoadBarrierNode* clone_load_barrier(PhaseIdealLoop* phase, LoadBarrierNode* lb, Node* ctl, Node* mem, Node* oop_in) {
+ PhaseIterGVN &igvn = phase->igvn();
+ Compile* C = Compile::current();
+ Node* the_clone = lb->clone();
+ the_clone->set_req(LoadBarrierNode::Control, ctl);
+ the_clone->set_req(LoadBarrierNode::Memory, mem);
+ if (oop_in != NULL) {
+ the_clone->set_req(LoadBarrierNode::Oop, oop_in);
+ }
+
+ LoadBarrierNode* new_lb = the_clone->as_LoadBarrier();
+ igvn.register_new_node_with_optimizer(new_lb);
+ IdealLoopTree *loop = phase->get_loop(new_lb->in(0));
+ phase->set_ctrl(new_lb, new_lb->in(0));
+ phase->set_loop(new_lb, loop);
+ phase->set_idom(new_lb, new_lb->in(0), phase->dom_depth(new_lb->in(0))+1);
+ if (!loop->_child) {
+ loop->_body.push(new_lb);
+ }
+
+ Node* proj_ctl = new ProjNode(new_lb, LoadBarrierNode::Control);
+ igvn.register_new_node_with_optimizer(proj_ctl);
+ phase->set_ctrl(proj_ctl, proj_ctl->in(0));
+ phase->set_loop(proj_ctl, loop);
+ phase->set_idom(proj_ctl, new_lb, phase->dom_depth(new_lb)+1);
+ if (!loop->_child) {
+ loop->_body.push(proj_ctl);
+ }
+
+ Node* proj_oop = new ProjNode(new_lb, LoadBarrierNode::Oop);
+ phase->register_new_node(proj_oop, new_lb);
+
+ if (!new_lb->in(LoadBarrierNode::Similar)->is_top()) {
+ LoadBarrierNode* similar = new_lb->in(LoadBarrierNode::Similar)->in(0)->as_LoadBarrier();
+ if (!phase->is_dominator(similar, ctl)) {
+ igvn.replace_input_of(new_lb, LoadBarrierNode::Similar, C->top());
+ }
+ }
+
+ return new_lb;
+}
+
+static void replace_barrier(PhaseIdealLoop* phase, LoadBarrierNode* lb, Node* new_val) {
+ PhaseIterGVN &igvn = phase->igvn();
+ Node* val = lb->proj_out(LoadBarrierNode::Oop);
+ igvn.replace_node(val, new_val);
+ phase->lazy_update(lb, lb->in(LoadBarrierNode::Control));
+ phase->lazy_replace(lb->proj_out(LoadBarrierNode::Control), lb->in(LoadBarrierNode::Control));
+}
+
+static bool split_barrier_thru_phi(PhaseIdealLoop* phase, LoadBarrierNode* lb) {
+ PhaseIterGVN &igvn = phase->igvn();
+ Compile* C = Compile::current();
+
+ if (lb->in(LoadBarrierNode::Oop)->is_Phi()) {
+ Node* oop_phi = lb->in(LoadBarrierNode::Oop);
+
+ if (oop_phi->in(2) == oop_phi) {
+ // Ignore phis with only one input
+ return false;
+ }
+
+ if (phase->is_dominator(phase->get_ctrl(lb->in(LoadBarrierNode::Address)),
+ oop_phi->in(0)) && phase->get_ctrl(lb->in(LoadBarrierNode::Address)) != oop_phi->in(0)) {
+ // That transformation may cause the Similar edge on dominated load barriers to be invalid
+ lb->fix_similar_in_uses(&igvn);
+
+ RegionNode* region = oop_phi->in(0)->as_Region();
+
+ int backedge = LoopNode::LoopBackControl;
+ if (region->is_Loop() && region->in(backedge)->is_Proj() && region->in(backedge)->in(0)->is_If()) {
+ Node* c = region->in(backedge)->in(0)->in(0);
+ assert(c->unique_ctrl_out() == region->in(backedge)->in(0), "");
+ Node* oop = lb->in(LoadBarrierNode::Oop)->in(backedge);
+ Node* oop_c = phase->has_ctrl(oop) ? phase->get_ctrl(oop) : oop;
+ if (!phase->is_dominator(oop_c, c)) {
+ return false;
+ }
+ }
+
+ // If the node on the backedge above the phi is the node itself - we have a self loop.
+ // Don't clone - this will be folded later.
+ if (oop_phi->in(LoopNode::LoopBackControl) == lb->proj_out(LoadBarrierNode::Oop)) {
+ return false;
+ }
+
+ bool is_strip_mined = region->is_CountedLoop() && region->as_CountedLoop()->is_strip_mined();
+ Node *phi = oop_phi->clone();
+
+ for (uint i = 1; i < region->req(); i++) {
+ Node* ctrl = region->in(i);
+ if (ctrl != C->top()) {
+ assert(!phase->is_dominator(ctrl, region) || region->is_Loop(), "");
+
+ Node* mem = lb->in(LoadBarrierNode::Memory);
+ Node* m = find_dominating_memory(phase, mem, region, i);
+
+ if (region->is_Loop() && i == LoopNode::LoopBackControl && ctrl->is_Proj() && ctrl->in(0)->is_If()) {
+ ctrl = ctrl->in(0)->in(0);
+ } else if (region->is_Loop() && is_strip_mined) {
+ // If this is a strip mined loop, control must move above OuterStripMinedLoop
+ assert(i == LoopNode::EntryControl, "check");
+ assert(ctrl->is_OuterStripMinedLoop(), "sanity");
+ ctrl = ctrl->as_OuterStripMinedLoop()->in(LoopNode::EntryControl);
+ }
+
+ LoadBarrierNode* new_lb = clone_load_barrier(phase, lb, ctrl, m, lb->in(LoadBarrierNode::Oop)->in(i));
+ Node* out_ctrl = new_lb->proj_out(LoadBarrierNode::Control);
+
+ if (is_strip_mined && (i == LoopNode::EntryControl)) {
+ assert(region->in(i)->is_OuterStripMinedLoop(), "");
+ igvn.replace_input_of(region->in(i), i, out_ctrl);
+ } else if (ctrl == region->in(i)) {
+ igvn.replace_input_of(region, i, out_ctrl);
+ } else {
+ Node* iff = region->in(i)->in(0);
+ igvn.replace_input_of(iff, 0, out_ctrl);
+ phase->set_idom(iff, out_ctrl, phase->dom_depth(out_ctrl)+1);
+ }
+ phi->set_req(i, new_lb->proj_out(LoadBarrierNode::Oop));
+ }
+ }
+ phase->register_new_node(phi, region);
+ replace_barrier(phase, lb, phi);
+
+ if (region->is_Loop()) {
+ // Load barrier moved to the back edge of the Loop may now
+ // have a safepoint on the path to the barrier on the Similar
+ // edge
+ igvn.replace_input_of(phi->in(LoopNode::LoopBackControl)->in(0), LoadBarrierNode::Similar, C->top());
+ Node* head = region->in(LoopNode::EntryControl);
+ phase->set_idom(region, head, phase->dom_depth(head)+1);
+ phase->recompute_dom_depth();
+ if (head->is_CountedLoop() && head->as_CountedLoop()->is_main_loop()) {
+ head->as_CountedLoop()->set_normal_loop();
+ }
+ }
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static bool move_out_of_loop(PhaseIdealLoop* phase, LoadBarrierNode* lb) {
+ PhaseIterGVN &igvn = phase->igvn();
+ IdealLoopTree *lb_loop = phase->get_loop(lb->in(0));
+ if (lb_loop != phase->ltree_root() && !lb_loop->_irreducible) {
+ Node* oop_ctrl = phase->get_ctrl(lb->in(LoadBarrierNode::Oop));
+ IdealLoopTree *oop_loop = phase->get_loop(oop_ctrl);
+ IdealLoopTree* adr_loop = phase->get_loop(phase->get_ctrl(lb->in(LoadBarrierNode::Address)));
+ if (!lb_loop->is_member(oop_loop) && !lb_loop->is_member(adr_loop)) {
+ // That transformation may cause the Similar edge on dominated load barriers to be invalid
+ lb->fix_similar_in_uses(&igvn);
+
+ Node* head = lb_loop->_head;
+ assert(head->is_Loop(), "");
+
+ if (phase->is_dominator(head, oop_ctrl)) {
+ assert(oop_ctrl->Opcode() == Op_CProj && oop_ctrl->in(0)->Opcode() == Op_NeverBranch, "");
+ assert(lb_loop->is_member(phase->get_loop(oop_ctrl->in(0)->in(0))), "");
+ return false;
+ }
+
+ if (head->is_CountedLoop()) {
+ CountedLoopNode* cloop = head->as_CountedLoop();
+ if (cloop->is_main_loop()) {
+ cloop->set_normal_loop();
+ }
+ // When we are moving barrier out of a counted loop,
+ // make sure we move it all the way out of the strip mined outer loop.
+ if (cloop->is_strip_mined()) {
+ head = cloop->outer_loop();
+ }
+ }
+
+ Node* mem = lb->in(LoadBarrierNode::Memory);
+ Node* m = find_dominating_memory(phase, mem, head, -1);
+
+ LoadBarrierNode* new_lb = clone_load_barrier(phase, lb, head->in(LoopNode::EntryControl), m, NULL);
+
+ assert(phase->idom(head) == head->in(LoopNode::EntryControl), "");
+ Node* proj_ctl = new_lb->proj_out(LoadBarrierNode::Control);
+ igvn.replace_input_of(head, LoopNode::EntryControl, proj_ctl);
+ phase->set_idom(head, proj_ctl, phase->dom_depth(proj_ctl) + 1);
+
+ replace_barrier(phase, lb, new_lb->proj_out(LoadBarrierNode::Oop));
+
+ phase->recompute_dom_depth();
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static bool common_barriers(PhaseIdealLoop* phase, LoadBarrierNode* lb) {
+ PhaseIterGVN &igvn = phase->igvn();
+ Node* in_val = lb->in(LoadBarrierNode::Oop);
+ for (DUIterator_Fast imax, i = in_val->fast_outs(imax); i < imax; i++) {
+ Node* u = in_val->fast_out(i);
+ if (u != lb && u->is_LoadBarrier() && u->as_LoadBarrier()->has_true_uses()) {
+ Node* this_ctrl = lb->in(LoadBarrierNode::Control);
+ Node* other_ctrl = u->in(LoadBarrierNode::Control);
+
+ Node* lca = phase->dom_lca(this_ctrl, other_ctrl);
+ bool ok = true;
+
+ Node* proj1 = NULL;
+ Node* proj2 = NULL;
+
+ while (this_ctrl != lca && ok) {
+ if (this_ctrl->in(0) != NULL &&
+ this_ctrl->in(0)->is_MultiBranch()) {
+ if (this_ctrl->in(0)->in(0) == lca) {
+ assert(proj1 == NULL, "");
+ assert(this_ctrl->is_Proj(), "");
+ proj1 = this_ctrl;
+ } else if (!(this_ctrl->in(0)->is_If() && this_ctrl->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none))) {
+ ok = false;
+ }
+ }
+ this_ctrl = phase->idom(this_ctrl);
+ }
+ while (other_ctrl != lca && ok) {
+ if (other_ctrl->in(0) != NULL &&
+ other_ctrl->in(0)->is_MultiBranch()) {
+ if (other_ctrl->in(0)->in(0) == lca) {
+ assert(other_ctrl->is_Proj(), "");
+ assert(proj2 == NULL, "");
+ proj2 = other_ctrl;
+ } else if (!(other_ctrl->in(0)->is_If() && other_ctrl->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none))) {
+ ok = false;
+ }
+ }
+ other_ctrl = phase->idom(other_ctrl);
+ }
+ assert(proj1 == NULL || proj2 == NULL || proj1->in(0) == proj2->in(0), "");
+ if (ok && proj1 && proj2 && proj1 != proj2 && proj1->in(0)->is_If()) {
+ // That transformation may cause the Similar edge on dominated load barriers to be invalid
+ lb->fix_similar_in_uses(&igvn);
+ u->as_LoadBarrier()->fix_similar_in_uses(&igvn);
+
+ Node* split = lca->unique_ctrl_out();
+ assert(split->in(0) == lca, "");
+
+ Node* mem = lb->in(LoadBarrierNode::Memory);
+ Node* m = find_dominating_memory(phase, mem, split, -1);
+ LoadBarrierNode* new_lb = clone_load_barrier(phase, lb, lca, m, NULL);
+
+ Node* proj_ctl = new_lb->proj_out(LoadBarrierNode::Control);
+ igvn.replace_input_of(split, 0, new_lb->proj_out(LoadBarrierNode::Control));
+ phase->set_idom(split, proj_ctl, phase->dom_depth(proj_ctl)+1);
+
+ Node* proj_oop = new_lb->proj_out(LoadBarrierNode::Oop);
+ replace_barrier(phase, lb, proj_oop);
+ replace_barrier(phase, u->as_LoadBarrier(), proj_oop);
+
+ phase->recompute_dom_depth();
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static void optimize_load_barrier(PhaseIdealLoop* phase, LoadBarrierNode* lb, bool last_round) {
+ Compile* C = Compile::current();
+
+ if (!C->directive()->ZOptimizeLoadBarriersOption) {
+ return;
+ }
+
+ if (lb->has_true_uses()) {
+ if (replace_with_dominating_barrier(phase, lb, last_round)) {
+ return;
+ }
+
+ if (split_barrier_thru_phi(phase, lb)) {
+ return;
+ }
+
+ if (move_out_of_loop(phase, lb)) {
+ return;
+ }
+
+ if (common_barriers(phase, lb)) {
+ return;
+ }
+ }
+}
+
+void ZBarrierSetC2::loop_optimize_gc_barrier(PhaseIdealLoop* phase, Node* node, bool last_round) {
+ if (node->is_LoadBarrier()) {
+ optimize_load_barrier(phase, node->as_LoadBarrier(), last_round);
+ }
+}
+
+// == Verification ==
+
+#ifdef ASSERT
+
+static bool look_for_barrier(Node* n, bool post_parse, VectorSet& visited) {
+ if (visited.test_set(n->_idx)) {
+ return true;
+ }
+
+ for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
+ Node* u = n->fast_out(i);
+ if (u->is_LoadBarrier()) {
+ } else if ((u->is_Phi() || u->is_CMove()) && !post_parse) {
+ if (!look_for_barrier(u, post_parse, visited)) {
+ return false;
+ }
+ } else if (u->Opcode() == Op_EncodeP || u->Opcode() == Op_DecodeN) {
+ if (!look_for_barrier(u, post_parse, visited)) {
+ return false;
+ }
+ } else if (u->Opcode() != Op_SCMemProj) {
+ tty->print("bad use"); u->dump();
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void ZBarrierSetC2::verify_gc_barriers(bool post_parse) const {
+ ZBarrierSetC2State* s = state();
+ Compile* C = Compile::current();
+ ResourceMark rm;
+ VectorSet visited(Thread::current()->resource_area());
+ for (int i = 0; i < s->load_barrier_count(); i++) {
+ LoadBarrierNode* n = s->load_barrier_node(i);
+
+ // The dominating barrier on the same address if it exists and
+ // this barrier must not be applied on the value from the same
+ // load otherwise the value is not reloaded before it's used the
+ // second time.
+ assert(n->in(LoadBarrierNode::Similar)->is_top() ||
+ (n->in(LoadBarrierNode::Similar)->in(0)->is_LoadBarrier() &&
+ n->in(LoadBarrierNode::Similar)->in(0)->in(LoadBarrierNode::Address) == n->in(LoadBarrierNode::Address) &&
+ n->in(LoadBarrierNode::Similar)->in(0)->in(LoadBarrierNode::Oop) != n->in(LoadBarrierNode::Oop)),
+ "broken similar edge");
+
+ assert(post_parse || n->as_LoadBarrier()->has_true_uses(),
+ "found unneeded load barrier");
+
+ // Several load barrier nodes chained through their Similar edge
+ // break the code that remove the barriers in final graph reshape.
+ assert(n->in(LoadBarrierNode::Similar)->is_top() ||
+ (n->in(LoadBarrierNode::Similar)->in(0)->is_LoadBarrier() &&
+ n->in(LoadBarrierNode::Similar)->in(0)->in(LoadBarrierNode::Similar)->is_top()),
+ "chain of Similar load barriers");
+
+ if (!n->in(LoadBarrierNode::Similar)->is_top()) {
+ ResourceMark rm;
+ Unique_Node_List wq;
+ Node* other = n->in(LoadBarrierNode::Similar)->in(0);
+ wq.push(n);
+ bool ok = true;
+ bool dom_found = false;
+ for (uint next = 0; next < wq.size(); ++next) {
+ Node *n = wq.at(next);
+ assert(n->is_CFG(), "");
+ assert(!n->is_SafePoint(), "");
+
+ if (n == other) {
+ continue;
+ }
+
+ if (n->is_Region()) {
+ for (uint i = 1; i < n->req(); i++) {
+ Node* m = n->in(i);
+ if (m != NULL) {
+ wq.push(m);
+ }
+ }
+ } else {
+ Node* m = n->in(0);
+ if (m != NULL) {
+ wq.push(m);
+ }
+ }
+ }
+ }
+
+ if (ZVerifyLoadBarriers) {
+ if ((n->is_Load() || n->is_LoadStore()) && n->bottom_type()->make_oopptr() != NULL) {
+ visited.Clear();
+ bool found = look_for_barrier(n, post_parse, visited);
+ if (!found) {
+ n->dump(1);
+ n->dump(-3);
+ stringStream ss;
+ C->method()->print_short_name(&ss);
+ tty->print_cr("-%s-", ss.as_string());
+ assert(found, "");
+ }
+ }
+ }
+ }
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,206 @@
+/*
+ * 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_GC_Z_C2_ZBARRIERSETC2_HPP
+#define SHARE_GC_Z_C2_ZBARRIERSETC2_HPP
+
+#include "gc/shared/c2/barrierSetC2.hpp"
+#include "memory/allocation.hpp"
+#include "opto/node.hpp"
+#include "utilities/growableArray.hpp"
+
+class LoadBarrierNode : public MultiNode {
+private:
+ bool _weak;
+ bool _writeback; // Controls if the barrier writes the healed oop back to memory
+ // A swap on a memory location must never write back the healed oop
+ bool _oop_reload_allowed; // Controls if the barrier are allowed to reload the oop from memory
+ // before healing, otherwise both the oop and the address must be passed to the
+ // barrier from the oop
+
+ static bool is_dominator(PhaseIdealLoop* phase, bool linear_only, Node *d, Node *n);
+ void push_dominated_barriers(PhaseIterGVN* igvn) const;
+
+public:
+ enum {
+ Control,
+ Memory,
+ Oop,
+ Address,
+ Number_of_Outputs = Address,
+ Similar,
+ Number_of_Inputs
+ };
+
+ LoadBarrierNode(Compile* C,
+ Node* c,
+ Node* mem,
+ Node* val,
+ Node* adr,
+ bool weak,
+ bool writeback,
+ bool oop_reload_allowed);
+
+ virtual int Opcode() const;
+ virtual const Type *bottom_type() const;
+ virtual const Type *Value(PhaseGVN *phase) const;
+ virtual Node *Identity(PhaseGVN *phase);
+ virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
+
+ LoadBarrierNode* has_dominating_barrier(PhaseIdealLoop* phase,
+ bool linear_only,
+ bool look_for_similar);
+
+ void fix_similar_in_uses(PhaseIterGVN* igvn);
+
+ bool has_true_uses() const;
+
+ bool can_be_eliminated() const {
+ return !in(Similar)->is_top();
+ }
+
+ bool is_weak() const {
+ return _weak;
+ }
+
+ bool is_writeback() const {
+ return _writeback;
+ }
+
+ bool oop_reload_allowed() const {
+ return _oop_reload_allowed;
+ }
+};
+
+class LoadBarrierSlowRegNode : public LoadPNode {
+public:
+ LoadBarrierSlowRegNode(Node *c,
+ Node *mem,
+ Node *adr,
+ const TypePtr *at,
+ const TypePtr* t,
+ MemOrd mo,
+ ControlDependency control_dependency = DependsOnlyOnTest)
+ : LoadPNode(c, mem, adr, at, t, mo, control_dependency) {}
+
+ virtual const char * name() {
+ return "LoadBarrierSlowRegNode";
+ }
+
+ virtual Node *Ideal(PhaseGVN *phase, bool can_reshape) {
+ return NULL;
+ }
+
+ virtual int Opcode() const;
+};
+
+class LoadBarrierWeakSlowRegNode : public LoadPNode {
+public:
+ LoadBarrierWeakSlowRegNode(Node *c,
+ Node *mem,
+ Node *adr,
+ const TypePtr *at,
+ const TypePtr* t,
+ MemOrd mo,
+ ControlDependency control_dependency = DependsOnlyOnTest)
+ : LoadPNode(c, mem, adr, at, t, mo, control_dependency) {}
+
+ virtual const char * name() {
+ return "LoadBarrierWeakSlowRegNode";
+ }
+
+ virtual Node *Ideal(PhaseGVN *phase, bool can_reshape) {
+ return NULL;
+ }
+
+ virtual int Opcode() const;
+};
+
+class ZBarrierSetC2State : public ResourceObj {
+private:
+ // List of load barrier nodes which need to be expanded before matching
+ GrowableArray<LoadBarrierNode*>* _load_barrier_nodes;
+
+public:
+ ZBarrierSetC2State(Arena* comp_arena);
+ int load_barrier_count() const;
+ void add_load_barrier_node(LoadBarrierNode* n);
+ void remove_load_barrier_node(LoadBarrierNode* n);
+ LoadBarrierNode* load_barrier_node(int idx) const;
+};
+
+class ZBarrierSetC2 : public BarrierSetC2 {
+private:
+ ZBarrierSetC2State* state() const;
+ Node* make_cas_loadbarrier(C2AtomicAccess& access) const;
+ Node* make_cmpx_loadbarrier(C2AtomicAccess& access) const;
+ void expand_loadbarrier_basic(PhaseMacroExpand* phase, LoadBarrierNode *barrier) const;
+ void expand_loadbarrier_node(PhaseMacroExpand* phase, LoadBarrierNode* barrier) const;
+ void expand_loadbarrier_optimized(PhaseMacroExpand* phase, LoadBarrierNode *barrier) const;
+ const TypeFunc* load_barrier_Type() const;
+
+protected:
+ virtual Node* load_at_resolved(C2Access& access, const Type* val_type) const;
+ virtual Node* atomic_cmpxchg_val_at_resolved(C2AtomicAccess& access,
+ Node* expected_val,
+ Node* new_val,
+ const Type* val_type) const;
+ virtual Node* atomic_cmpxchg_bool_at_resolved(C2AtomicAccess& access,
+ Node* expected_val,
+ Node* new_val,
+ const Type* value_type) const;
+ virtual Node* atomic_xchg_at_resolved(C2AtomicAccess& access,
+ Node* new_val,
+ const Type* val_type) const;
+
+public:
+ Node* load_barrier(GraphKit* kit,
+ Node* val,
+ Node* adr,
+ bool weak = false,
+ bool writeback = true,
+ bool oop_reload_allowed = true) const;
+
+ virtual void* create_barrier_state(Arena* comp_arena) const;
+ virtual bool is_gc_barrier_node(Node* node) const;
+ virtual void eliminate_gc_barrier(PhaseMacroExpand* macro, Node* node) const { }
+ virtual void eliminate_useless_gc_barriers(Unique_Node_List &useful) const;
+ virtual void add_users_to_worklist(Unique_Node_List* worklist) const;
+ virtual void enqueue_useful_gc_barrier(Unique_Node_List &worklist, Node* node) const;
+ virtual void register_potential_barrier_node(Node* node) const;
+ virtual void unregister_potential_barrier_node(Node* node) const;
+ virtual bool array_copy_requires_gc_barriers(BasicType type) const { return true; }
+ virtual Node* step_over_gc_barrier(Node* c) const { return c; }
+ // If the BarrierSetC2 state has kept macro nodes in its compilation unit state to be
+ // expanded later, then now is the time to do so.
+ virtual bool expand_macro_nodes(PhaseMacroExpand* macro) const;
+
+ static void find_dominating_barriers(PhaseIterGVN& igvn);
+ static void loop_optimize_gc_barrier(PhaseIdealLoop* phase, Node* node, bool last_round);
+
+#ifdef ASSERT
+ virtual void verify_gc_barriers(bool post_parse) const;
+#endif
+};
+
+#endif // SHARE_GC_Z_C2_ZBARRIERSETC2_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/vmStructs_z.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,38 @@
+/*
+ * 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 "gc/z/vmStructs_z.hpp"
+
+ZGlobalsForVMStructs::ZGlobalsForVMStructs() :
+ _ZGlobalPhase(&ZGlobalPhase),
+ _ZAddressGoodMask(&ZAddressGoodMask),
+ _ZAddressBadMask(&ZAddressBadMask),
+ _ZAddressWeakBadMask(&ZAddressWeakBadMask),
+ _ZObjectAlignmentSmallShift(&ZObjectAlignmentSmallShift),
+ _ZObjectAlignmentSmall(&ZObjectAlignmentSmall) {
+}
+
+ZGlobalsForVMStructs ZGlobalsForVMStructs::_instance;
+ZGlobalsForVMStructs* ZGlobalsForVMStructs::_instance_p = &ZGlobalsForVMStructs::_instance;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/vmStructs_z.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,121 @@
+/*
+ * 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
+ * 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_Z_VMSTRUCTS_Z_HPP
+#define SHARE_VM_GC_Z_VMSTRUCTS_Z_HPP
+
+#include "gc/z/zAddressRangeMap.hpp"
+#include "gc/z/zCollectedHeap.hpp"
+#include "gc/z/zHeap.hpp"
+#include "gc/z/zPageAllocator.hpp"
+#include "gc/z/zPhysicalMemory.hpp"
+#include "utilities/macros.hpp"
+
+// Expose some ZGC globals to the SA agent.
+class ZGlobalsForVMStructs {
+ static ZGlobalsForVMStructs _instance;
+
+public:
+ static ZGlobalsForVMStructs* _instance_p;
+
+ ZGlobalsForVMStructs();
+
+ uint32_t* _ZGlobalPhase;
+
+ uintptr_t* _ZAddressGoodMask;
+ uintptr_t* _ZAddressBadMask;
+ uintptr_t* _ZAddressWeakBadMask;
+
+ const int* _ZObjectAlignmentSmallShift;
+ const int* _ZObjectAlignmentSmall;
+};
+
+typedef ZAddressRangeMap<ZPageTableEntry, ZPageSizeMinShift> ZAddressRangeMapForPageTable;
+
+#define VM_STRUCTS_ZGC(nonstatic_field, volatile_nonstatic_field, static_field) \
+ static_field(ZGlobalsForVMStructs, _instance_p, ZGlobalsForVMStructs*) \
+ nonstatic_field(ZGlobalsForVMStructs, _ZGlobalPhase, uint32_t*) \
+ nonstatic_field(ZGlobalsForVMStructs, _ZAddressGoodMask, uintptr_t*) \
+ nonstatic_field(ZGlobalsForVMStructs, _ZAddressBadMask, uintptr_t*) \
+ nonstatic_field(ZGlobalsForVMStructs, _ZAddressWeakBadMask, uintptr_t*) \
+ nonstatic_field(ZGlobalsForVMStructs, _ZObjectAlignmentSmallShift, const int*) \
+ nonstatic_field(ZGlobalsForVMStructs, _ZObjectAlignmentSmall, const int*) \
+ \
+ nonstatic_field(ZCollectedHeap, _heap, ZHeap) \
+ \
+ nonstatic_field(ZHeap, _page_allocator, ZPageAllocator) \
+ nonstatic_field(ZHeap, _pagetable, ZPageTable) \
+ \
+ nonstatic_field(ZPage, _type, const uint8_t) \
+ nonstatic_field(ZPage, _virtual, const ZVirtualMemory) \
+ nonstatic_field(ZPage, _forwarding, ZForwardingTable) \
+ \
+ nonstatic_field(ZPageAllocator, _physical, ZPhysicalMemoryManager) \
+ nonstatic_field(ZPageAllocator, _used, size_t) \
+ \
+ nonstatic_field(ZPageTable, _map, ZAddressRangeMapForPageTable) \
+ \
+ nonstatic_field(ZAddressRangeMapForPageTable, _map, ZPageTableEntry* const) \
+ \
+ nonstatic_field(ZVirtualMemory, _start, uintptr_t) \
+ nonstatic_field(ZVirtualMemory, _end, uintptr_t) \
+ \
+ nonstatic_field(ZForwardingTable, _table, ZForwardingTableEntry*) \
+ nonstatic_field(ZForwardingTable, _size, size_t) \
+ \
+ nonstatic_field(ZPhysicalMemoryManager, _max_capacity, const size_t) \
+ nonstatic_field(ZPhysicalMemoryManager, _capacity, size_t)
+
+#define VM_INT_CONSTANTS_ZGC(declare_constant, declare_constant_with_value) \
+ declare_constant(ZPhaseRelocate) \
+ declare_constant(ZPageTypeSmall) \
+ declare_constant(ZPageTypeMedium) \
+ declare_constant(ZPageTypeLarge) \
+ declare_constant(ZObjectAlignmentMediumShift) \
+ declare_constant(ZObjectAlignmentLargeShift)
+
+#define VM_LONG_CONSTANTS_ZGC(declare_constant) \
+ declare_constant(ZPageSizeSmallShift) \
+ declare_constant(ZPageSizeMediumShift) \
+ declare_constant(ZPageSizeMinShift) \
+ declare_constant(ZAddressOffsetShift) \
+ declare_constant(ZAddressOffsetBits) \
+ declare_constant(ZAddressOffsetMask) \
+ declare_constant(ZAddressSpaceStart)
+
+#define VM_TYPES_ZGC(declare_type, declare_toplevel_type, declare_integer_type) \
+ declare_toplevel_type(ZGlobalsForVMStructs) \
+ declare_type(ZCollectedHeap, CollectedHeap) \
+ declare_toplevel_type(ZHeap) \
+ declare_toplevel_type(ZPage) \
+ declare_toplevel_type(ZPageAllocator) \
+ declare_toplevel_type(ZPageTable) \
+ declare_toplevel_type(ZPageTableEntry) \
+ declare_toplevel_type(ZAddressRangeMapForPageTable) \
+ declare_toplevel_type(ZVirtualMemory) \
+ declare_toplevel_type(ZForwardingTable) \
+ declare_toplevel_type(ZForwardingTableEntry) \
+ declare_toplevel_type(ZPhysicalMemoryManager)
+
+#endif // SHARE_VM_GC_Z_VMSTRUCTS_Z_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zAddress.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,48 @@
+/*
+ * 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 "gc/z/zAddress.inline.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "runtime/thread.hpp"
+
+void ZAddressMasks::set_good_mask(uintptr_t mask) {
+ uintptr_t old_bad_mask = ZAddressBadMask;
+ ZAddressGoodMask = mask;
+ ZAddressBadMask = ZAddressGoodMask ^ ZAddressMetadataMask;
+ ZAddressWeakBadMask = (ZAddressGoodMask | ZAddressMetadataRemapped | ZAddressMetadataFinalizable) ^ ZAddressMetadataMask;
+}
+
+void ZAddressMasks::initialize() {
+ ZAddressMetadataMarked = ZAddressMetadataMarked0;
+ set_good_mask(ZAddressMetadataRemapped);
+}
+
+void ZAddressMasks::flip_to_marked() {
+ ZAddressMetadataMarked ^= (ZAddressMetadataMarked0 | ZAddressMetadataMarked1);
+ set_good_mask(ZAddressMetadataMarked);
+}
+
+void ZAddressMasks::flip_to_remapped() {
+ set_good_mask(ZAddressMetadataRemapped);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zAddress.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,66 @@
+/*
+ * 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_GC_Z_ZADDRESS_HPP
+#define SHARE_GC_Z_ZADDRESS_HPP
+
+#include "memory/allocation.hpp"
+
+class ZAddress : public AllStatic {
+public:
+ static bool is_null(uintptr_t value);
+ static bool is_bad(uintptr_t value);
+ static bool is_good(uintptr_t value);
+ static bool is_good_or_null(uintptr_t value);
+ static bool is_weak_bad(uintptr_t value);
+ static bool is_weak_good(uintptr_t value);
+ static bool is_weak_good_or_null(uintptr_t value);
+ static bool is_marked(uintptr_t value);
+ static bool is_finalizable(uintptr_t value);
+ static bool is_remapped(uintptr_t value);
+
+ static uintptr_t address(uintptr_t value);
+ static uintptr_t offset(uintptr_t value);
+ static uintptr_t good(uintptr_t value);
+ static uintptr_t good_or_null(uintptr_t value);
+ static uintptr_t finalizable_good(uintptr_t value);
+ static uintptr_t marked(uintptr_t value);
+ static uintptr_t marked0(uintptr_t value);
+ static uintptr_t marked1(uintptr_t value);
+ static uintptr_t remapped(uintptr_t value);
+ static uintptr_t remapped_or_null(uintptr_t value);
+};
+
+class ZAddressMasks : public AllStatic {
+ friend class ZAddressTest;
+
+private:
+ static void set_good_mask(uintptr_t mask);
+
+public:
+ static void initialize();
+ static void flip_to_marked();
+ static void flip_to_remapped();
+};
+
+#endif // SHARE_GC_Z_ZADDRESS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zAddress.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZADDRESS_INLINE_HPP
+#define SHARE_GC_Z_ZADDRESS_INLINE_HPP
+
+#include "gc/z/zAddress.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "utilities/macros.hpp"
+#include OS_CPU_HEADER_INLINE(gc/z/zAddress)
+
+inline bool ZAddress::is_null(uintptr_t value) {
+ return value == 0;
+}
+
+inline bool ZAddress::is_bad(uintptr_t value) {
+ return value & ZAddressBadMask;
+}
+
+inline bool ZAddress::is_good(uintptr_t value) {
+ return !is_bad(value) && !is_null(value);
+}
+
+inline bool ZAddress::is_good_or_null(uintptr_t value) {
+ // Checking if an address is "not bad" is an optimized version of
+ // checking if it's "good or null", which eliminates an explicit
+ // null check. However, the implicit null check only checks that
+ // the mask bits are zero, not that the entire address is zero.
+ // This means that an address without mask bits would pass through
+ // the barrier as if it was null. This should be harmless as such
+ // addresses should ever be passed through the barrier.
+ const bool result = !is_bad(value);
+ assert((is_good(value) || is_null(value)) == result, "Bad address");
+ return result;
+}
+
+inline bool ZAddress::is_weak_bad(uintptr_t value) {
+ return value & ZAddressWeakBadMask;
+}
+
+inline bool ZAddress::is_weak_good(uintptr_t value) {
+ return !is_weak_bad(value) && !is_null(value);
+}
+
+inline bool ZAddress::is_weak_good_or_null(uintptr_t value) {
+ return !is_weak_bad(value);
+}
+
+inline bool ZAddress::is_marked(uintptr_t value) {
+ return value & ZAddressMetadataMarked;
+}
+
+inline bool ZAddress::is_finalizable(uintptr_t value) {
+ return value & ZAddressMetadataFinalizable;
+}
+
+inline bool ZAddress::is_remapped(uintptr_t value) {
+ return value & ZAddressMetadataRemapped;
+}
+
+inline uintptr_t ZAddress::offset(uintptr_t value) {
+ return value & ZAddressOffsetMask;
+}
+
+inline uintptr_t ZAddress::good(uintptr_t value) {
+ return address(offset(value) | ZAddressGoodMask);
+}
+
+inline uintptr_t ZAddress::good_or_null(uintptr_t value) {
+ return is_null(value) ? 0 : good(value);
+}
+
+inline uintptr_t ZAddress::finalizable_good(uintptr_t value) {
+ return address(offset(value) | ZAddressMetadataFinalizable | ZAddressGoodMask);
+}
+
+inline uintptr_t ZAddress::marked(uintptr_t value) {
+ return address(offset(value) | ZAddressMetadataMarked);
+}
+
+inline uintptr_t ZAddress::marked0(uintptr_t value) {
+ return address(offset(value) | ZAddressMetadataMarked0);
+}
+
+inline uintptr_t ZAddress::marked1(uintptr_t value) {
+ return address(offset(value) | ZAddressMetadataMarked1);
+}
+
+inline uintptr_t ZAddress::remapped(uintptr_t value) {
+ return address(offset(value) | ZAddressMetadataRemapped);
+}
+
+inline uintptr_t ZAddress::remapped_or_null(uintptr_t value) {
+ return is_null(value) ? 0 : remapped(value);
+}
+
+#endif // SHARE_GC_Z_ZADDRESS_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zAddressRangeMap.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,63 @@
+/*
+ * 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
+ * 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_Z_ZADDRESSRANGEMAP_HPP
+#define SHARE_GC_Z_ZADDRESSRANGEMAP_HPP
+
+#include "memory/allocation.hpp"
+
+template<typename T, size_t AddressRangeShift>
+class ZAddressRangeMapIterator;
+
+template <typename T, size_t AddressRangeShift>
+class ZAddressRangeMap {
+ friend class VMStructs;
+ friend class ZAddressRangeMapIterator<T, AddressRangeShift>;
+
+private:
+ T* const _map;
+
+ size_t index_for_addr(uintptr_t addr) const;
+ size_t size() const;
+
+public:
+ ZAddressRangeMap();
+ ~ZAddressRangeMap();
+
+ T get(uintptr_t addr) const;
+ void put(uintptr_t addr, T value);
+};
+
+template <typename T, size_t AddressRangeShift>
+class ZAddressRangeMapIterator : public StackObj {
+public:
+ const ZAddressRangeMap<T, AddressRangeShift>* const _map;
+ size_t _next;
+
+public:
+ ZAddressRangeMapIterator(const ZAddressRangeMap<T, AddressRangeShift>* map);
+
+ bool next(T* value);
+};
+
+#endif // SHARE_GC_Z_ZADDRESSRANGEMAP_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zAddressRangeMap.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef SHARE_GC_Z_ZADDRESSRANGEMAP_INLINE_HPP
+#define SHARE_GC_Z_ZADDRESSRANGEMAP_INLINE_HPP
+
+#include "gc/z/zAddress.inline.hpp"
+#include "gc/z/zAddressRangeMap.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "memory/allocation.inline.hpp"
+
+template <typename T, size_t AddressRangeShift>
+ZAddressRangeMap<T, AddressRangeShift>::ZAddressRangeMap() :
+ _map(MmapArrayAllocator<T>::allocate(size(), mtGC)) {}
+
+template <typename T, size_t AddressRangeShift>
+ZAddressRangeMap<T, AddressRangeShift>::~ZAddressRangeMap() {
+ MmapArrayAllocator<T>::free(_map, size());
+}
+
+template <typename T, size_t AddressRangeShift>
+size_t ZAddressRangeMap<T, AddressRangeShift>::index_for_addr(uintptr_t addr) const {
+ assert(!ZAddress::is_null(addr), "Invalid address");
+
+ const size_t index = ZAddress::offset(addr) >> AddressRangeShift;
+ assert(index < size(), "Invalid index");
+
+ return index;
+}
+
+template <typename T, size_t AddressRangeShift>
+size_t ZAddressRangeMap<T, AddressRangeShift>::size() const {
+ return ZAddressOffsetMax >> AddressRangeShift;
+}
+
+template <typename T, size_t AddressRangeShift>
+T ZAddressRangeMap<T, AddressRangeShift>::get(uintptr_t addr) const {
+ const uintptr_t index = index_for_addr(addr);
+ return _map[index];
+}
+
+template <typename T, size_t AddressRangeShift>
+void ZAddressRangeMap<T, AddressRangeShift>::put(uintptr_t addr, T value) {
+ const uintptr_t index = index_for_addr(addr);
+ _map[index] = value;
+}
+
+template <typename T, size_t AddressRangeShift>
+inline ZAddressRangeMapIterator<T, AddressRangeShift>::ZAddressRangeMapIterator(const ZAddressRangeMap<T, AddressRangeShift>* map) :
+ _map(map),
+ _next(0) {}
+
+template <typename T, size_t AddressRangeShift>
+inline bool ZAddressRangeMapIterator<T, AddressRangeShift>::next(T* value) {
+ if (_next < _map->size()) {
+ *value = _map->_map[_next++];
+ return true;
+ }
+
+ // End of map
+ return false;
+}
+
+#endif // SHARE_GC_Z_ZADDRESSRANGEMAP_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zAllocationFlags.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef SHARE_GC_Z_ZALLOCATIONFLAGS_HPP
+#define SHARE_GC_Z_ZALLOCATIONFLAGS_HPP
+
+#include "gc/z/zBitField.hpp"
+#include "memory/allocation.hpp"
+
+//
+// Allocation flags layout
+// -----------------------
+//
+// 7 4 3 2 1 0
+// +---+-+-+-+-+-+
+// |000|1|1|1|1|1|
+// +---+-+-+-+-+-+
+// | | | | | |
+// | | | | | * 0-0 Java Thread Flag (1-bit)
+// | | | | |
+// | | | | * 1-1 Worker Thread Flag (1-bit)
+// | | | |
+// | | | * 2-2 Non-Blocking Flag (1-bit)
+// | | |
+// | | * 3-3 Relocation Flag (1-bit)
+// | |
+// | * 4-4 No Reserve Flag (1-bit)
+// |
+// * 7-5 Unused (3-bits)
+//
+
+class ZAllocationFlags {
+private:
+ typedef ZBitField<uint8_t, bool, 0, 1> field_java_thread;
+ typedef ZBitField<uint8_t, bool, 1, 1> field_worker_thread;
+ typedef ZBitField<uint8_t, bool, 2, 1> field_non_blocking;
+ typedef ZBitField<uint8_t, bool, 3, 1> field_relocation;
+ typedef ZBitField<uint8_t, bool, 4, 1> field_no_reserve;
+
+ uint8_t _flags;
+
+public:
+ ZAllocationFlags() :
+ _flags(0) {}
+
+ void set_java_thread() {
+ _flags |= field_java_thread::encode(true);
+ }
+
+ void set_worker_thread() {
+ _flags |= field_worker_thread::encode(true);
+ }
+
+ void set_non_blocking() {
+ _flags |= field_non_blocking::encode(true);
+ }
+
+ void set_relocation() {
+ _flags |= field_relocation::encode(true);
+ }
+
+ void set_no_reserve() {
+ _flags |= field_no_reserve::encode(true);
+ }
+
+ bool java_thread() const {
+ return field_java_thread::decode(_flags);
+ }
+
+ bool worker_thread() const {
+ return field_worker_thread::decode(_flags);
+ }
+
+ bool non_blocking() const {
+ return field_non_blocking::decode(_flags);
+ }
+
+ bool relocation() const {
+ return field_relocation::decode(_flags);
+ }
+
+ bool no_reserve() const {
+ return field_no_reserve::decode(_flags);
+ }
+};
+
+#endif // SHARE_GC_Z_ZALLOCATIONFLAGS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zArguments.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,106 @@
+/*
+ * 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
+ * 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/z/zArguments.hpp"
+#include "gc/z/zCollectedHeap.hpp"
+#include "gc/z/zCollectorPolicy.hpp"
+#include "gc/z/zWorkers.hpp"
+#include "gc/shared/gcArguments.inline.hpp"
+#include "runtime/globals.hpp"
+#include "runtime/globals_extension.hpp"
+
+size_t ZArguments::conservative_max_heap_alignment() {
+ return 0;
+}
+
+void ZArguments::initialize() {
+ GCArguments::initialize();
+
+ // Enable NUMA by default
+ if (FLAG_IS_DEFAULT(UseNUMA)) {
+ FLAG_SET_DEFAULT(UseNUMA, true);
+ }
+
+ // Disable biased locking by default
+ if (FLAG_IS_DEFAULT(UseBiasedLocking)) {
+ FLAG_SET_DEFAULT(UseBiasedLocking, false);
+ }
+
+ // Select number of parallel threads
+ if (FLAG_IS_DEFAULT(ParallelGCThreads)) {
+ FLAG_SET_DEFAULT(ParallelGCThreads, ZWorkers::calculate_nparallel());
+ }
+
+ if (ParallelGCThreads == 0) {
+ vm_exit_during_initialization("The flag -XX:+UseZGC can not be combined with -XX:ParallelGCThreads=0");
+ }
+
+ // Select number of concurrent threads
+ if (FLAG_IS_DEFAULT(ConcGCThreads)) {
+ FLAG_SET_DEFAULT(ConcGCThreads, ZWorkers::calculate_nconcurrent());
+ }
+
+ if (ConcGCThreads == 0) {
+ vm_exit_during_initialization("The flag -XX:+UseZGC can not be combined with -XX:ConcGCThreads=0");
+ }
+
+#ifdef COMPILER2
+ // Enable loop strip mining by default
+ if (FLAG_IS_DEFAULT(UseCountedLoopSafepoints)) {
+ FLAG_SET_DEFAULT(UseCountedLoopSafepoints, true);
+ if (FLAG_IS_DEFAULT(LoopStripMiningIter)) {
+ FLAG_SET_DEFAULT(LoopStripMiningIter, 1000);
+ }
+ }
+#endif
+
+ // To avoid asserts in set_active_workers()
+ FLAG_SET_DEFAULT(UseDynamicNumberOfGCThreads, true);
+
+ // CompressedOops/UseCompressedClassPointers not supported
+ FLAG_SET_DEFAULT(UseCompressedOops, false);
+ FLAG_SET_DEFAULT(UseCompressedClassPointers, false);
+
+ // ClassUnloading not (yet) supported
+ FLAG_SET_DEFAULT(ClassUnloading, false);
+ FLAG_SET_DEFAULT(ClassUnloadingWithConcurrentMark, false);
+
+ // Verification before startup and after exit not (yet) supported
+ FLAG_SET_DEFAULT(VerifyDuringStartup, false);
+ FLAG_SET_DEFAULT(VerifyBeforeExit, false);
+
+ // Verification of stacks not (yet) supported, for the same reason
+ // we need fixup_partial_loads
+ DEBUG_ONLY(FLAG_SET_DEFAULT(VerifyStack, false));
+
+ // JVMCI not (yet) supported
+ if (EnableJVMCI) {
+ vm_exit_during_initialization("The flag -XX:+UseZGC can not be combined with -XX:+EnableJVMCI");
+ }
+}
+
+CollectedHeap* ZArguments::create_heap() {
+ return create_heap_with_policy<ZCollectedHeap, ZCollectorPolicy>();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zArguments.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef SHARE_GC_Z_ZARGUMENTS_HPP
+#define SHARE_GC_Z_ZARGUMENTS_HPP
+
+#include "gc/shared/gcArguments.hpp"
+
+class CollectedHeap;
+
+class ZArguments : public GCArguments {
+public:
+ virtual void initialize();
+ virtual size_t conservative_max_heap_alignment();
+ virtual CollectedHeap* create_heap();
+};
+
+#endif // SHARE_GC_Z_ZARGUMENTS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zArray.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZARRAY_HPP
+#define SHARE_GC_Z_ZARRAY_HPP
+
+#include "memory/allocation.hpp"
+
+template <typename T>
+class ZArray {
+private:
+ static const size_t initial_capacity = 32;
+
+ T* _array;
+ size_t _size;
+ size_t _capacity;
+
+ // Copy and assignment are not allowed
+ ZArray(const ZArray<T>& array);
+ ZArray<T>& operator=(const ZArray<T>& array);
+
+ void expand(size_t new_capacity);
+
+public:
+ ZArray();
+ ~ZArray();
+
+ size_t size() const;
+ bool is_empty() const;
+
+ T at(size_t index) const;
+
+ void add(T value);
+ void clear();
+};
+
+template <typename T, bool parallel>
+class ZArrayIteratorImpl : public StackObj {
+private:
+ ZArray<T>* const _array;
+ size_t _next;
+
+public:
+ ZArrayIteratorImpl(ZArray<T>* array);
+
+ bool next(T* elem);
+};
+
+// Iterator types
+#define ZARRAY_SERIAL false
+#define ZARRAY_PARALLEL true
+
+template <typename T>
+class ZArrayIterator : public ZArrayIteratorImpl<T, ZARRAY_SERIAL> {
+public:
+ ZArrayIterator(ZArray<T>* array) :
+ ZArrayIteratorImpl<T, ZARRAY_SERIAL>(array) {}
+};
+
+template <typename T>
+class ZArrayParallelIterator : public ZArrayIteratorImpl<T, ZARRAY_PARALLEL> {
+public:
+ ZArrayParallelIterator(ZArray<T>* array) :
+ ZArrayIteratorImpl<T, ZARRAY_PARALLEL>(array) {}
+};
+
+#endif // SHARE_GC_Z_ZARRAY_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zArray.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZARRAY_INLINE_HPP
+#define SHARE_GC_Z_ZARRAY_INLINE_HPP
+
+#include "gc/z/zArray.hpp"
+#include "memory/allocation.inline.hpp"
+#include "runtime/atomic.hpp"
+
+template <typename T>
+inline ZArray<T>::ZArray() :
+ _array(NULL),
+ _size(0),
+ _capacity(0) {}
+
+template <typename T>
+inline ZArray<T>::~ZArray() {
+ if (_array != NULL) {
+ FREE_C_HEAP_ARRAY(T, _array);
+ }
+}
+
+template <typename T>
+inline size_t ZArray<T>::size() const {
+ return _size;
+}
+
+template <typename T>
+inline bool ZArray<T>::is_empty() const {
+ return size() == 0;
+}
+
+template <typename T>
+inline T ZArray<T>::at(size_t index) const {
+ assert(index < _size, "Index out of bounds");
+ return _array[index];
+}
+
+template <typename T>
+inline void ZArray<T>::expand(size_t new_capacity) {
+ T* new_array = NEW_C_HEAP_ARRAY(T, new_capacity, mtGC);
+ if (_array != NULL) {
+ memcpy(new_array, _array, sizeof(T) * _capacity);
+ FREE_C_HEAP_ARRAY(T, _array);
+ }
+
+ _array = new_array;
+ _capacity = new_capacity;
+}
+
+template <typename T>
+inline void ZArray<T>::add(T value) {
+ if (_size == _capacity) {
+ const size_t new_capacity = (_capacity > 0) ? _capacity * 2 : initial_capacity;
+ expand(new_capacity);
+ }
+
+ _array[_size++] = value;
+}
+
+template <typename T>
+inline void ZArray<T>::clear() {
+ _size = 0;
+}
+
+template <typename T, bool parallel>
+inline ZArrayIteratorImpl<T, parallel>::ZArrayIteratorImpl(ZArray<T>* array) :
+ _array(array),
+ _next(0) {}
+
+template <typename T, bool parallel>
+inline bool ZArrayIteratorImpl<T, parallel>::next(T* elem) {
+ if (parallel) {
+ const size_t next = Atomic::add(1u, &_next) - 1u;
+ if (next < _array->size()) {
+ *elem = _array->at(next);
+ return true;
+ }
+ } else {
+ if (_next < _array->size()) {
+ *elem = _array->at(_next++);
+ return true;
+ }
+ }
+
+ // No more elements
+ return false;
+}
+
+#endif // SHARE_GC_Z_ZARRAY_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zBarrier.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2015, 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 "gc/z/zBarrier.inline.hpp"
+#include "gc/z/zHeap.inline.hpp"
+#include "gc/z/zOop.inline.hpp"
+#include "gc/z/zOopClosures.inline.hpp"
+#include "oops/oop.inline.hpp"
+#include "runtime/safepoint.hpp"
+#include "utilities/debug.hpp"
+
+bool ZBarrier::during_mark() {
+ return ZGlobalPhase == ZPhaseMark;
+}
+
+bool ZBarrier::during_relocate() {
+ return ZGlobalPhase == ZPhaseRelocate;
+}
+
+template <bool finalizable>
+bool ZBarrier::should_mark_through(uintptr_t addr) {
+ // Finalizable marked oops can still exists on the heap after marking
+ // has completed, in which case we just want to convert this into a
+ // good oop and not push it on the mark stack.
+ if (!during_mark()) {
+ assert(ZAddress::is_marked(addr), "Should be marked");
+ assert(ZAddress::is_finalizable(addr), "Should be finalizable");
+ return false;
+ }
+
+ // During marking, we mark through already marked oops to avoid having
+ // some large part of the object graph hidden behind a pushed, but not
+ // yet flushed, entry on a mutator mark stack. Always marking through
+ // allows the GC workers to proceed through the object graph even if a
+ // mutator touched an oop first, which in turn will reduce the risk of
+ // having to flush mark stacks multiple times to terminate marking.
+ //
+ // However, when doing finalizable marking we don't always want to mark
+ // through. First, marking through an already strongly marked oop would
+ // be wasteful, since we will then proceed to do finalizable marking on
+ // an object which is, or will be, marked strongly. Second, marking
+ // through an already finalizable marked oop would also be wasteful,
+ // since such oops can never end up on a mutator mark stack and can
+ // therefore not hide some part of the object graph from GC workers.
+ if (finalizable) {
+ return !ZAddress::is_marked(addr);
+ }
+
+ // Mark through
+ return true;
+}
+
+template <bool finalizable, bool publish>
+uintptr_t ZBarrier::mark(uintptr_t addr) {
+ uintptr_t good_addr;
+
+ if (ZAddress::is_marked(addr)) {
+ // Already marked, but try to mark though anyway
+ good_addr = ZAddress::good(addr);
+ } else if (ZAddress::is_remapped(addr)) {
+ // Already remapped, but also needs to be marked
+ good_addr = ZAddress::good(addr);
+ } else {
+ // Needs to be both remapped and marked
+ good_addr = remap(addr);
+ }
+
+ // Mark
+ if (should_mark_through<finalizable>(addr)) {
+ ZHeap::heap()->mark_object<finalizable, publish>(good_addr);
+ }
+
+ return good_addr;
+}
+
+uintptr_t ZBarrier::remap(uintptr_t addr) {
+ assert(!ZAddress::is_good(addr), "Should not be good");
+ assert(!ZAddress::is_weak_good(addr), "Should not be weak good");
+
+ if (ZHeap::heap()->is_relocating(addr)) {
+ // Forward
+ return ZHeap::heap()->forward_object(addr);
+ }
+
+ // Remap
+ return ZAddress::good(addr);
+}
+
+uintptr_t ZBarrier::relocate(uintptr_t addr) {
+ assert(!ZAddress::is_good(addr), "Should not be good");
+ assert(!ZAddress::is_weak_good(addr), "Should not be weak good");
+
+ if (ZHeap::heap()->is_relocating(addr)) {
+ // Relocate
+ return ZHeap::heap()->relocate_object(addr);
+ }
+
+ // Remap
+ return ZAddress::good(addr);
+}
+
+uintptr_t ZBarrier::relocate_or_mark(uintptr_t addr) {
+ return during_relocate() ? relocate(addr) : mark<Strong, Publish>(addr);
+}
+
+uintptr_t ZBarrier::relocate_or_remap(uintptr_t addr) {
+ return during_relocate() ? relocate(addr) : remap(addr);
+}
+
+//
+// Load barrier
+//
+uintptr_t ZBarrier::load_barrier_on_oop_slow_path(uintptr_t addr) {
+ return relocate_or_mark(addr);
+}
+
+void ZBarrier::load_barrier_on_oop_fields(oop o) {
+ assert(ZOop::is_good(o), "Should be good");
+ ZLoadBarrierOopClosure cl;
+ o->oop_iterate(&cl);
+}
+
+//
+// Weak load barrier
+//
+uintptr_t ZBarrier::weak_load_barrier_on_oop_slow_path(uintptr_t addr) {
+ return ZAddress::is_weak_good(addr) ? ZAddress::good(addr) : relocate_or_remap(addr);
+}
+
+uintptr_t ZBarrier::weak_load_barrier_on_weak_oop_slow_path(uintptr_t addr) {
+ const uintptr_t good_addr = weak_load_barrier_on_oop_slow_path(addr);
+ if (ZHeap::heap()->is_object_strongly_live(good_addr)) {
+ return good_addr;
+ }
+
+ // Not strongly live
+ return 0;
+}
+
+uintptr_t ZBarrier::weak_load_barrier_on_phantom_oop_slow_path(uintptr_t addr) {
+ const uintptr_t good_addr = weak_load_barrier_on_oop_slow_path(addr);
+ if (ZHeap::heap()->is_object_live(good_addr)) {
+ return good_addr;
+ }
+
+ // Not live
+ return 0;
+}
+
+//
+// Keep alive barrier
+//
+uintptr_t ZBarrier::keep_alive_barrier_on_weak_oop_slow_path(uintptr_t addr) {
+ const uintptr_t good_addr = weak_load_barrier_on_oop_slow_path(addr);
+ assert(ZHeap::heap()->is_object_strongly_live(good_addr), "Should be live");
+ return good_addr;
+}
+
+uintptr_t ZBarrier::keep_alive_barrier_on_phantom_oop_slow_path(uintptr_t addr) {
+ const uintptr_t good_addr = weak_load_barrier_on_oop_slow_path(addr);
+ assert(ZHeap::heap()->is_object_live(good_addr), "Should be live");
+ return good_addr;
+}
+
+//
+// Mark barrier
+//
+uintptr_t ZBarrier::mark_barrier_on_oop_slow_path(uintptr_t addr) {
+ return mark<Strong, Overflow>(addr);
+}
+
+uintptr_t ZBarrier::mark_barrier_on_finalizable_oop_slow_path(uintptr_t addr) {
+ const uintptr_t good_addr = mark<Finalizable, Overflow>(addr);
+ if (ZAddress::is_good(addr)) {
+ // If the oop was already strongly marked/good, then we do
+ // not want to downgrade it to finalizable marked/good.
+ return good_addr;
+ }
+
+ // Make the oop finalizable marked/good, instead of normal marked/good.
+ // This is needed because an object might first becomes finalizable
+ // marked by the GC, and then loaded by a mutator thread. In this case,
+ // the mutator thread must be able to tell that the object needs to be
+ // strongly marked. The finalizable bit in the oop exists to make sure
+ // that a load of a finalizable marked oop will fall into the barrier
+ // slow path so that we can mark the object as strongly reachable.
+ return ZAddress::finalizable_good(good_addr);
+}
+
+uintptr_t ZBarrier::mark_barrier_on_root_oop_slow_path(uintptr_t addr) {
+ assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
+ assert(during_mark(), "Invalid phase");
+
+ // Mark
+ return mark<Strong, Publish>(addr);
+}
+
+//
+// Relocate barrier
+//
+uintptr_t ZBarrier::relocate_barrier_on_root_oop_slow_path(uintptr_t addr) {
+ assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
+ assert(during_relocate(), "Invalid phase");
+
+ // Relocate
+ return relocate(addr);
+}
+
+//
+// Narrow oop variants, never used.
+//
+oop ZBarrier::load_barrier_on_oop_field(volatile narrowOop* p) {
+ ShouldNotReachHere();
+ return NULL;
+}
+
+oop ZBarrier::load_barrier_on_oop_field_preloaded(volatile narrowOop* p, oop o) {
+ ShouldNotReachHere();
+ return NULL;
+}
+
+void ZBarrier::load_barrier_on_oop_array(volatile narrowOop* p, size_t length) {
+ ShouldNotReachHere();
+}
+
+oop ZBarrier::load_barrier_on_weak_oop_field_preloaded(volatile narrowOop* p, oop o) {
+ ShouldNotReachHere();
+ return NULL;
+}
+
+oop ZBarrier::load_barrier_on_phantom_oop_field_preloaded(volatile narrowOop* p, oop o) {
+ ShouldNotReachHere();
+ return NULL;
+}
+
+oop ZBarrier::weak_load_barrier_on_oop_field_preloaded(volatile narrowOop* p, oop o) {
+ ShouldNotReachHere();
+ return NULL;
+}
+
+oop ZBarrier::weak_load_barrier_on_weak_oop_field_preloaded(volatile narrowOop* p, oop o) {
+ ShouldNotReachHere();
+ return NULL;
+}
+
+oop ZBarrier::weak_load_barrier_on_phantom_oop_field_preloaded(volatile narrowOop* p, oop o) {
+ ShouldNotReachHere();
+ return NULL;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zBarrier.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZBARRIER_HPP
+#define SHARE_GC_Z_ZBARRIER_HPP
+
+#include "memory/allocation.hpp"
+#include "oops/oop.hpp"
+
+typedef bool (*ZBarrierFastPath)(uintptr_t);
+typedef uintptr_t (*ZBarrierSlowPath)(uintptr_t);
+
+class ZBarrier : public AllStatic {
+private:
+ static const bool Strong = false;
+ static const bool Finalizable = true;
+
+ static const bool Publish = true;
+ static const bool Overflow = false;
+
+ template <ZBarrierFastPath fast_path, ZBarrierSlowPath slow_path> static oop barrier(volatile oop* p, oop o);
+ template <ZBarrierFastPath fast_path, ZBarrierSlowPath slow_path> static oop weak_barrier(volatile oop* p, oop o);
+ template <ZBarrierFastPath fast_path, ZBarrierSlowPath slow_path> static void root_barrier(oop* p, oop o);
+
+ static bool is_null_fast_path(uintptr_t addr);
+ static bool is_good_or_null_fast_path(uintptr_t addr);
+ static bool is_weak_good_or_null_fast_path(uintptr_t addr);
+
+ static bool is_resurrection_blocked(volatile oop* p, oop* o);
+
+ static bool during_mark();
+ static bool during_relocate();
+ template <bool finalizable> static bool should_mark_through(uintptr_t addr);
+ template <bool finalizable, bool publish> static uintptr_t mark(uintptr_t addr);
+ static uintptr_t remap(uintptr_t addr);
+ static uintptr_t relocate(uintptr_t addr);
+ static uintptr_t relocate_or_mark(uintptr_t addr);
+ static uintptr_t relocate_or_remap(uintptr_t addr);
+
+ static uintptr_t load_barrier_on_oop_slow_path(uintptr_t addr);
+
+ static uintptr_t weak_load_barrier_on_oop_slow_path(uintptr_t addr);
+ static uintptr_t weak_load_barrier_on_weak_oop_slow_path(uintptr_t addr);
+ static uintptr_t weak_load_barrier_on_phantom_oop_slow_path(uintptr_t addr);
+
+ static uintptr_t keep_alive_barrier_on_weak_oop_slow_path(uintptr_t addr);
+ static uintptr_t keep_alive_barrier_on_phantom_oop_slow_path(uintptr_t addr);
+
+ static uintptr_t mark_barrier_on_oop_slow_path(uintptr_t addr);
+ static uintptr_t mark_barrier_on_finalizable_oop_slow_path(uintptr_t addr);
+ static uintptr_t mark_barrier_on_root_oop_slow_path(uintptr_t addr);
+
+ static uintptr_t relocate_barrier_on_root_oop_slow_path(uintptr_t addr);
+
+public:
+ // Load barrier
+ static oop load_barrier_on_oop(oop o);
+ static oop load_barrier_on_oop_field(volatile oop* p);
+ static oop load_barrier_on_oop_field_preloaded(volatile oop* p, oop o);
+ static void load_barrier_on_oop_array(volatile oop* p, size_t length);
+ static void load_barrier_on_oop_fields(oop o);
+ static oop load_barrier_on_weak_oop_field_preloaded(volatile oop* p, oop o);
+ static oop load_barrier_on_phantom_oop_field_preloaded(volatile oop* p, oop o);
+
+ // Weak load barrier
+ static oop weak_load_barrier_on_oop_field_preloaded(volatile oop* p, oop o);
+ static oop weak_load_barrier_on_weak_oop(oop o);
+ static oop weak_load_barrier_on_weak_oop_field(volatile oop* p);
+ static oop weak_load_barrier_on_weak_oop_field_preloaded(volatile oop* p, oop o);
+ static oop weak_load_barrier_on_phantom_oop(oop o);
+ static oop weak_load_barrier_on_phantom_oop_field(volatile oop* p);
+ static oop weak_load_barrier_on_phantom_oop_field_preloaded(volatile oop* p, oop o);
+
+ // Is alive barrier
+ static bool is_alive_barrier_on_weak_oop(oop o);
+ static bool is_alive_barrier_on_phantom_oop(oop o);
+
+ // Keep alive barrier
+ static void keep_alive_barrier_on_weak_oop_field(volatile oop* p);
+ static void keep_alive_barrier_on_phantom_oop_field(volatile oop* p);
+
+ // Mark barrier
+ static void mark_barrier_on_oop_field(volatile oop* p, bool finalizable);
+ static void mark_barrier_on_oop_array(volatile oop* p, size_t length, bool finalizable);
+ static void mark_barrier_on_root_oop_field(oop* p);
+
+ // Relocate barrier
+ static void relocate_barrier_on_root_oop_field(oop* p);
+
+ // Narrow oop variants, never used.
+ static oop load_barrier_on_oop_field(volatile narrowOop* p);
+ static oop load_barrier_on_oop_field_preloaded(volatile narrowOop* p, oop o);
+ static void load_barrier_on_oop_array(volatile narrowOop* p, size_t length);
+ static oop load_barrier_on_weak_oop_field_preloaded(volatile narrowOop* p, oop o);
+ static oop load_barrier_on_phantom_oop_field_preloaded(volatile narrowOop* p, oop o);
+ static oop weak_load_barrier_on_oop_field_preloaded(volatile narrowOop* p, oop o);
+ static oop weak_load_barrier_on_weak_oop_field_preloaded(volatile narrowOop* p, oop o);
+ static oop weak_load_barrier_on_phantom_oop_field_preloaded(volatile narrowOop* p, oop o);
+};
+
+#endif // SHARE_GC_Z_ZBARRIER_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zBarrier.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZBARRIER_INLINE_HPP
+#define SHARE_GC_Z_ZBARRIER_INLINE_HPP
+
+#include "gc/z/zAddress.inline.hpp"
+#include "gc/z/zBarrier.hpp"
+#include "gc/z/zOop.inline.hpp"
+#include "gc/z/zResurrection.inline.hpp"
+#include "runtime/atomic.hpp"
+
+template <ZBarrierFastPath fast_path, ZBarrierSlowPath slow_path>
+inline oop ZBarrier::barrier(volatile oop* p, oop o) {
+ uintptr_t addr = ZOop::to_address(o);
+
+retry:
+ // Fast path
+ if (fast_path(addr)) {
+ return ZOop::to_oop(addr);
+ }
+
+ // Slow path
+ const uintptr_t good_addr = slow_path(addr);
+
+ // Self heal, but only if the address was actually updated by the slow path,
+ // which might not be the case, e.g. when marking through an already good oop.
+ if (p != NULL && good_addr != addr) {
+ const uintptr_t prev_addr = Atomic::cmpxchg(good_addr, (volatile uintptr_t*)p, addr);
+ if (prev_addr != addr) {
+ // Some other thread overwrote the oop. If this oop was updated by a
+ // weak barrier the new oop might not be good, in which case we need
+ // to re-apply this barrier.
+ addr = prev_addr;
+ goto retry;
+ }
+ }
+
+ return ZOop::to_oop(good_addr);
+}
+
+template <ZBarrierFastPath fast_path, ZBarrierSlowPath slow_path>
+inline oop ZBarrier::weak_barrier(volatile oop* p, oop o) {
+ const uintptr_t addr = ZOop::to_address(o);
+
+ // Fast path
+ if (fast_path(addr)) {
+ // Return the good address instead of the weak good address
+ // to ensure that the currently active heap view is used.
+ return ZOop::to_oop(ZAddress::good_or_null(addr));
+ }
+
+ // Slow path
+ uintptr_t good_addr = slow_path(addr);
+
+ // Self heal unless the address returned from the slow path is null,
+ // in which case resurrection was blocked and we must let the reference
+ // processor clear the oop. Mutators are not allowed to clear oops in
+ // these cases, since that would be similar to calling Reference.clear(),
+ // which would make the reference non-discoverable or silently dropped
+ // by the reference processor.
+ if (p != NULL && good_addr != 0) {
+ // The slow path returns a good/marked address, but we never mark oops
+ // in a weak load barrier so we always self heal with the remapped address.
+ const uintptr_t weak_good_addr = ZAddress::remapped(good_addr);
+ const uintptr_t prev_addr = Atomic::cmpxchg(weak_good_addr, (volatile uintptr_t*)p, addr);
+ if (prev_addr != addr) {
+ // Some other thread overwrote the oop. The new
+ // oop is guaranteed to be weak good or null.
+ assert(ZAddress::is_weak_good_or_null(prev_addr), "Bad weak overwrite");
+
+ // Return the good address instead of the weak good address
+ // to ensure that the currently active heap view is used.
+ good_addr = ZAddress::good_or_null(prev_addr);
+ }
+ }
+
+ return ZOop::to_oop(good_addr);
+}
+
+template <ZBarrierFastPath fast_path, ZBarrierSlowPath slow_path>
+inline void ZBarrier::root_barrier(oop* p, oop o) {
+ const uintptr_t addr = ZOop::to_address(o);
+
+ // Fast path
+ if (fast_path(addr)) {
+ return;
+ }
+
+ // Slow path
+ const uintptr_t good_addr = slow_path(addr);
+
+ // Non-atomic healing helps speed up root scanning. This is safe to do
+ // since we are always healing roots in a safepoint, which means we are
+ // never racing with mutators modifying roots while we are healing them.
+ // It's also safe in case multiple GC threads try to heal the same root,
+ // since they would always heal the root in the same way and it does not
+ // matter in which order it happens.
+ *p = ZOop::to_oop(good_addr);
+}
+
+inline bool ZBarrier::is_null_fast_path(uintptr_t addr) {
+ return ZAddress::is_null(addr);
+}
+
+inline bool ZBarrier::is_good_or_null_fast_path(uintptr_t addr) {
+ return ZAddress::is_good_or_null(addr);
+}
+
+inline bool ZBarrier::is_weak_good_or_null_fast_path(uintptr_t addr) {
+ return ZAddress::is_weak_good_or_null(addr);
+}
+
+inline bool ZBarrier::is_resurrection_blocked(volatile oop* p, oop* o) {
+ const bool is_blocked = ZResurrection::is_blocked();
+
+ // Reload oop after checking the resurrection blocked state. This is
+ // done to prevent a race where we first load an oop, which is logically
+ // null but not yet cleared, then this oop is cleared by the reference
+ // processor and resurrection is unblocked. At this point the mutator
+ // would see the unblocked state and pass this invalid oop through the
+ // normal barrier path, which would incorrectly try to mark this oop.
+ if (p != NULL) {
+ // First assign to reloaded_o to avoid compiler warning about
+ // implicit dereference of volatile oop.
+ const oop reloaded_o = *p;
+ *o = reloaded_o;
+ }
+
+ return is_blocked;
+}
+
+//
+// Load barrier
+//
+inline oop ZBarrier::load_barrier_on_oop(oop o) {
+ return load_barrier_on_oop_field_preloaded((oop*)NULL, o);
+}
+
+inline oop ZBarrier::load_barrier_on_oop_field(volatile oop* p) {
+ const oop o = *p;
+ return load_barrier_on_oop_field_preloaded(p, o);
+}
+
+inline oop ZBarrier::load_barrier_on_oop_field_preloaded(volatile oop* p, oop o) {
+ return barrier<is_good_or_null_fast_path, load_barrier_on_oop_slow_path>(p, o);
+}
+
+inline void ZBarrier::load_barrier_on_oop_array(volatile oop* p, size_t length) {
+ for (volatile const oop* const end = p + length; p < end; p++) {
+ load_barrier_on_oop_field(p);
+ }
+}
+
+inline oop ZBarrier::load_barrier_on_weak_oop_field_preloaded(volatile oop* p, oop o) {
+ if (is_resurrection_blocked(p, &o)) {
+ return weak_barrier<is_good_or_null_fast_path, weak_load_barrier_on_weak_oop_slow_path>(p, o);
+ }
+
+ return load_barrier_on_oop_field_preloaded(p, o);
+}
+
+inline oop ZBarrier::load_barrier_on_phantom_oop_field_preloaded(volatile oop* p, oop o) {
+ if (is_resurrection_blocked(p, &o)) {
+ return weak_barrier<is_good_or_null_fast_path, weak_load_barrier_on_phantom_oop_slow_path>(p, o);
+ }
+
+ return load_barrier_on_oop_field_preloaded(p, o);
+}
+
+//
+// Weak load barrier
+//
+inline oop ZBarrier::weak_load_barrier_on_oop_field_preloaded(volatile oop* p, oop o) {
+ return weak_barrier<is_weak_good_or_null_fast_path, weak_load_barrier_on_oop_slow_path>(p, o);
+}
+
+inline oop ZBarrier::weak_load_barrier_on_weak_oop(oop o) {
+ return weak_load_barrier_on_weak_oop_field_preloaded((oop*)NULL, o);
+}
+
+inline oop ZBarrier::weak_load_barrier_on_weak_oop_field(volatile oop* p) {
+ const oop o = *p;
+ return weak_load_barrier_on_weak_oop_field_preloaded(p, o);
+}
+
+inline oop ZBarrier::weak_load_barrier_on_weak_oop_field_preloaded(volatile oop* p, oop o) {
+ if (is_resurrection_blocked(p, &o)) {
+ return weak_barrier<is_good_or_null_fast_path, weak_load_barrier_on_weak_oop_slow_path>(p, o);
+ }
+
+ return weak_load_barrier_on_oop_field_preloaded(p, o);
+}
+
+inline oop ZBarrier::weak_load_barrier_on_phantom_oop(oop o) {
+ return weak_load_barrier_on_phantom_oop_field_preloaded((oop*)NULL, o);
+}
+
+inline oop ZBarrier::weak_load_barrier_on_phantom_oop_field(volatile oop* p) {
+ const oop o = *p;
+ return weak_load_barrier_on_phantom_oop_field_preloaded(p, o);
+}
+
+inline oop ZBarrier::weak_load_barrier_on_phantom_oop_field_preloaded(volatile oop* p, oop o) {
+ if (is_resurrection_blocked(p, &o)) {
+ return weak_barrier<is_good_or_null_fast_path, weak_load_barrier_on_phantom_oop_slow_path>(p, o);
+ }
+
+ return weak_load_barrier_on_oop_field_preloaded(p, o);
+}
+
+//
+// Is alive barrier
+//
+inline bool ZBarrier::is_alive_barrier_on_weak_oop(oop o) {
+ // Check if oop is logically non-null. This operation
+ // is only valid when resurrection is blocked.
+ assert(ZResurrection::is_blocked(), "Invalid phase");
+ return weak_load_barrier_on_weak_oop(o) != NULL;
+}
+
+inline bool ZBarrier::is_alive_barrier_on_phantom_oop(oop o) {
+ // Check if oop is logically non-null. This operation
+ // is only valid when resurrection is blocked.
+ assert(ZResurrection::is_blocked(), "Invalid phase");
+ return weak_load_barrier_on_phantom_oop(o) != NULL;
+}
+
+//
+// Keep alive barrier
+//
+inline void ZBarrier::keep_alive_barrier_on_weak_oop_field(volatile oop* p) {
+ // This operation is only valid when resurrection is blocked.
+ assert(ZResurrection::is_blocked(), "Invalid phase");
+ const oop o = *p;
+ barrier<is_good_or_null_fast_path, keep_alive_barrier_on_weak_oop_slow_path>(p, o);
+}
+
+inline void ZBarrier::keep_alive_barrier_on_phantom_oop_field(volatile oop* p) {
+ // This operation is only valid when resurrection is blocked.
+ assert(ZResurrection::is_blocked(), "Invalid phase");
+ const oop o = *p;
+ barrier<is_good_or_null_fast_path, keep_alive_barrier_on_phantom_oop_slow_path>(p, o);
+}
+
+//
+// Mark barrier
+//
+inline void ZBarrier::mark_barrier_on_oop_field(volatile oop* p, bool finalizable) {
+ // The fast path only checks for null since the GC worker
+ // threads doing marking wants to mark through good oops.
+ const oop o = *p;
+
+ if (finalizable) {
+ barrier<is_null_fast_path, mark_barrier_on_finalizable_oop_slow_path>(p, o);
+ } else {
+ barrier<is_null_fast_path, mark_barrier_on_oop_slow_path>(p, o);
+ }
+}
+
+inline void ZBarrier::mark_barrier_on_oop_array(volatile oop* p, size_t length, bool finalizable) {
+ for (volatile const oop* const end = p + length; p < end; p++) {
+ mark_barrier_on_oop_field(p, finalizable);
+ }
+}
+
+inline void ZBarrier::mark_barrier_on_root_oop_field(oop* p) {
+ const oop o = *p;
+ root_barrier<is_good_or_null_fast_path, mark_barrier_on_root_oop_slow_path>(p, o);
+}
+
+//
+// Relocate barrier
+//
+inline void ZBarrier::relocate_barrier_on_root_oop_field(oop* p) {
+ const oop o = *p;
+ root_barrier<is_good_or_null_fast_path, relocate_barrier_on_root_oop_slow_path>(p, o);
+}
+
+#endif // SHARE_GC_Z_ZBARRIER_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zBarrierSet.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,81 @@
+/*
+ * 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 "gc/z/c1/zBarrierSetC1.hpp"
+#include "gc/z/c2/zBarrierSetC2.hpp"
+#include "gc/z/zBarrierSet.hpp"
+#include "gc/z/zBarrierSetAssembler.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zHeap.inline.hpp"
+#include "gc/z/zThreadLocalData.hpp"
+#include "runtime/thread.hpp"
+
+ZBarrierSet::ZBarrierSet() :
+ BarrierSet(make_barrier_set_assembler<ZBarrierSetAssembler>(),
+ make_barrier_set_c1<ZBarrierSetC1>(),
+ make_barrier_set_c2<ZBarrierSetC2>(),
+ BarrierSet::FakeRtti(BarrierSet::ZBarrierSet)) {}
+
+ZBarrierSetAssembler* ZBarrierSet::assembler() {
+ BarrierSetAssembler* const bsa = BarrierSet::barrier_set()->barrier_set_assembler();
+ return reinterpret_cast<ZBarrierSetAssembler*>(bsa);
+}
+
+bool ZBarrierSet::barrier_needed(DecoratorSet decorators, BasicType type) {
+ assert((decorators & AS_RAW) == 0, "Unexpected decorator");
+ assert((decorators & AS_NO_KEEPALIVE) == 0, "Unexpected decorator");
+ //assert((decorators & ON_UNKNOWN_OOP_REF) == 0, "Unexpected decorator");
+
+ if (type == T_OBJECT || type == T_ARRAY) {
+ if (((decorators & IN_HEAP) != 0) ||
+ ((decorators & IN_CONCURRENT_ROOT) != 0) ||
+ ((decorators & ON_PHANTOM_OOP_REF) != 0)) {
+ // Barrier needed
+ return true;
+ }
+ }
+
+ // Barrier not neeed
+ return false;
+}
+
+void ZBarrierSet::on_thread_create(Thread* thread) {
+ // Create thread local data
+ ZThreadLocalData::create(thread);
+}
+
+void ZBarrierSet::on_thread_destroy(Thread* thread) {
+ // Destroy thread local data
+ ZThreadLocalData::destroy(thread);
+}
+
+void ZBarrierSet::on_thread_attach(JavaThread* thread) {
+ // Set thread local address bad mask
+ ZThreadLocalData::set_address_bad_mask(thread, ZAddressBadMask);
+}
+
+void ZBarrierSet::on_thread_detach(JavaThread* thread) {
+ // Flush and free any remaining mark stacks
+ ZHeap::heap()->mark_flush_and_free(thread);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zBarrierSet.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,109 @@
+/*
+ * 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_GC_Z_ZBARRIERSET_HPP
+#define SHARE_GC_Z_ZBARRIERSET_HPP
+
+#include "gc/shared/barrierSet.hpp"
+
+class ZBarrierSetAssembler;
+
+class ZBarrierSet : public BarrierSet {
+public:
+ ZBarrierSet();
+
+ static ZBarrierSetAssembler* assembler();
+ static bool barrier_needed(DecoratorSet decorators, BasicType type);
+
+ virtual void on_thread_create(Thread* thread);
+ virtual void on_thread_destroy(Thread* thread);
+ virtual void on_thread_attach(JavaThread* thread);
+ virtual void on_thread_detach(JavaThread* thread);
+
+ virtual void print_on(outputStream* st) const {}
+
+ template <DecoratorSet decorators, typename BarrierSetT = ZBarrierSet>
+ class AccessBarrier : public BarrierSet::AccessBarrier<decorators, BarrierSetT> {
+ private:
+ typedef BarrierSet::AccessBarrier<decorators, BarrierSetT> Raw;
+
+ template <DecoratorSet expected>
+ static void verify_decorators_present();
+
+ template <DecoratorSet expected>
+ static void verify_decorators_absent();
+
+ static oop* field_addr(oop base, ptrdiff_t offset);
+
+ template <typename T>
+ static oop load_barrier_on_oop_field_preloaded(T* addr, oop o);
+
+ template <typename T>
+ static oop load_barrier_on_unknown_oop_field_preloaded(oop base, ptrdiff_t offset, T* addr, oop o);
+
+ public:
+ //
+ // In heap
+ //
+ template <typename T>
+ static oop oop_load_in_heap(T* addr);
+ static oop oop_load_in_heap_at(oop base, ptrdiff_t offset);
+
+ template <typename T>
+ static oop oop_atomic_cmpxchg_in_heap(oop new_value, T* addr, oop compare_value);
+ static oop oop_atomic_cmpxchg_in_heap_at(oop new_value, oop base, ptrdiff_t offset, oop compare_value);
+
+ template <typename T>
+ static oop oop_atomic_xchg_in_heap(oop new_value, T* addr);
+ static oop oop_atomic_xchg_in_heap_at(oop new_value, oop base, ptrdiff_t offset);
+
+ template <typename T>
+ static bool oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
+ size_t length);
+
+ static void clone_in_heap(oop src, oop dst, size_t size);
+
+ //
+ // Not in heap
+ //
+ template <typename T>
+ static oop oop_load_not_in_heap(T* addr);
+
+ template <typename T>
+ static oop oop_atomic_cmpxchg_not_in_heap(oop new_value, T* addr, oop compare_value);
+
+ template <typename T>
+ static oop oop_atomic_xchg_not_in_heap(oop new_value, T* addr);
+ };
+};
+
+template<> struct BarrierSet::GetName<ZBarrierSet> {
+ static const BarrierSet::Name value = BarrierSet::ZBarrierSet;
+};
+
+template<> struct BarrierSet::GetType<BarrierSet::ZBarrierSet> {
+ typedef ::ZBarrierSet type;
+};
+
+#endif // SHARE_GC_Z_ZBARRIERSET_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zBarrierSet.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,243 @@
+/*
+ * 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
+ * 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_Z_ZBARRIERSET_INLINE_HPP
+#define SHARE_GC_Z_ZBARRIERSET_INLINE_HPP
+
+#include "gc/shared/accessBarrierSupport.inline.hpp"
+#include "gc/z/zBarrier.inline.hpp"
+#include "gc/z/zBarrierSet.hpp"
+#include "utilities/debug.hpp"
+
+template <DecoratorSet decorators, typename BarrierSetT>
+template <DecoratorSet expected>
+inline void ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::verify_decorators_present() {
+ if ((decorators & expected) == 0) {
+ fatal("Using unsupported access decorators");
+ }
+}
+
+template <DecoratorSet decorators, typename BarrierSetT>
+template <DecoratorSet expected>
+inline void ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::verify_decorators_absent() {
+ if ((decorators & expected) != 0) {
+ fatal("Using unsupported access decorators");
+ }
+}
+
+template <DecoratorSet decorators, typename BarrierSetT>
+inline oop* ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::field_addr(oop base, ptrdiff_t offset) {
+ assert(base != NULL, "Invalid base");
+ return reinterpret_cast<oop*>(reinterpret_cast<intptr_t>((void*)base) + offset);
+}
+
+template <DecoratorSet decorators, typename BarrierSetT>
+template <typename T>
+inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::load_barrier_on_oop_field_preloaded(T* addr, oop o) {
+ verify_decorators_absent<ON_UNKNOWN_OOP_REF>();
+
+ if (HasDecorator<decorators, AS_NO_KEEPALIVE>::value) {
+ if (HasDecorator<decorators, ON_STRONG_OOP_REF>::value) {
+ return ZBarrier::weak_load_barrier_on_oop_field_preloaded(addr, o);
+ } else if (HasDecorator<decorators, ON_WEAK_OOP_REF>::value) {
+ return ZBarrier::weak_load_barrier_on_weak_oop_field_preloaded(addr, o);
+ } else {
+ return ZBarrier::weak_load_barrier_on_phantom_oop_field_preloaded(addr, o);
+ }
+ } else {
+ if (HasDecorator<decorators, ON_STRONG_OOP_REF>::value) {
+ return ZBarrier::load_barrier_on_oop_field_preloaded(addr, o);
+ } else if (HasDecorator<decorators, ON_WEAK_OOP_REF>::value) {
+ return ZBarrier::load_barrier_on_weak_oop_field_preloaded(addr, o);
+ } else {
+ return ZBarrier::load_barrier_on_phantom_oop_field_preloaded(addr, o);
+ }
+ }
+}
+
+template <DecoratorSet decorators, typename BarrierSetT>
+template <typename T>
+inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::load_barrier_on_unknown_oop_field_preloaded(oop base, ptrdiff_t offset, T* addr, oop o) {
+ verify_decorators_present<ON_UNKNOWN_OOP_REF>();
+
+ const DecoratorSet decorators_known_strength =
+ AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength<decorators>(base, offset);
+
+ if (HasDecorator<decorators, AS_NO_KEEPALIVE>::value) {
+ if (decorators_known_strength & ON_STRONG_OOP_REF) {
+ return ZBarrier::weak_load_barrier_on_oop_field_preloaded(addr, o);
+ } else if (decorators_known_strength & ON_WEAK_OOP_REF) {
+ return ZBarrier::weak_load_barrier_on_weak_oop_field_preloaded(addr, o);
+ } else {
+ return ZBarrier::weak_load_barrier_on_phantom_oop_field_preloaded(addr, o);
+ }
+ } else {
+ if (decorators_known_strength & ON_STRONG_OOP_REF) {
+ return ZBarrier::load_barrier_on_oop_field_preloaded(addr, o);
+ } else if (decorators_known_strength & ON_WEAK_OOP_REF) {
+ return ZBarrier::load_barrier_on_weak_oop_field_preloaded(addr, o);
+ } else {
+ return ZBarrier::load_barrier_on_phantom_oop_field_preloaded(addr, o);
+ }
+ }
+}
+
+//
+// In heap
+//
+template <DecoratorSet decorators, typename BarrierSetT>
+template <typename T>
+inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_load_in_heap(T* addr) {
+ verify_decorators_absent<ON_UNKNOWN_OOP_REF>();
+
+ const oop o = Raw::oop_load_in_heap(addr);
+ return load_barrier_on_oop_field_preloaded(addr, o);
+}
+
+template <DecoratorSet decorators, typename BarrierSetT>
+inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_load_in_heap_at(oop base, ptrdiff_t offset) {
+ oop* const addr = field_addr(base, offset);
+ const oop o = Raw::oop_load_in_heap(addr);
+
+ if (HasDecorator<decorators, ON_UNKNOWN_OOP_REF>::value) {
+ return load_barrier_on_unknown_oop_field_preloaded(base, offset, addr, o);
+ }
+
+ return load_barrier_on_oop_field_preloaded(addr, o);
+}
+
+template <DecoratorSet decorators, typename BarrierSetT>
+template <typename T>
+inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_cmpxchg_in_heap(oop new_value, T* addr, oop compare_value) {
+ verify_decorators_present<ON_STRONG_OOP_REF>();
+ verify_decorators_absent<AS_NO_KEEPALIVE>();
+
+ ZBarrier::load_barrier_on_oop_field(addr);
+ return Raw::oop_atomic_cmpxchg_in_heap(new_value, addr, compare_value);
+}
+
+template <DecoratorSet decorators, typename BarrierSetT>
+inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_cmpxchg_in_heap_at(oop new_value, oop base, ptrdiff_t offset, oop compare_value) {
+ verify_decorators_present<ON_STRONG_OOP_REF | ON_UNKNOWN_OOP_REF>();
+ verify_decorators_absent<AS_NO_KEEPALIVE>();
+
+ // Through Unsafe.CompareAndExchangeObject()/CompareAndSetObject() we can recieve
+ // calls with ON_UNKNOWN_OOP_REF set. However, we treat these as ON_STRONG_OOP_REF,
+ // with the motivation that if you're doing Unsafe operations on a Reference.referent
+ // field, then you're on your own anyway.
+ ZBarrier::load_barrier_on_oop_field(field_addr(base, offset));
+ return Raw::oop_atomic_cmpxchg_in_heap_at(new_value, base, offset, compare_value);
+}
+
+template <DecoratorSet decorators, typename BarrierSetT>
+template <typename T>
+inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_xchg_in_heap(oop new_value, T* addr) {
+ verify_decorators_present<ON_STRONG_OOP_REF>();
+ verify_decorators_absent<AS_NO_KEEPALIVE>();
+
+ const oop o = Raw::oop_atomic_xchg_in_heap(new_value, addr);
+ return ZBarrier::load_barrier_on_oop(o);
+}
+
+template <DecoratorSet decorators, typename BarrierSetT>
+inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_xchg_in_heap_at(oop new_value, oop base, ptrdiff_t offset) {
+ verify_decorators_present<ON_STRONG_OOP_REF>();
+ verify_decorators_absent<AS_NO_KEEPALIVE>();
+
+ const oop o = Raw::oop_atomic_xchg_in_heap_at(new_value, base, offset);
+ return ZBarrier::load_barrier_on_oop(o);
+}
+
+template <DecoratorSet decorators, typename BarrierSetT>
+template <typename T>
+inline bool ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
+ size_t length) {
+ T* src = arrayOopDesc::obj_offset_to_raw(src_obj, src_offset_in_bytes, src_raw);
+ T* dst = arrayOopDesc::obj_offset_to_raw(dst_obj, dst_offset_in_bytes, dst_raw);
+
+ if (!HasDecorator<decorators, ARRAYCOPY_CHECKCAST>::value) {
+ // No check cast, bulk barrier and bulk copy
+ ZBarrier::load_barrier_on_oop_array(src, length);
+ return Raw::oop_arraycopy_in_heap(NULL, 0, src, NULL, 0, dst, length);
+ }
+
+ // Check cast and copy each elements
+ Klass* const dst_klass = objArrayOop(dst_obj)->element_klass();
+ for (const T* const end = src + length; src < end; src++, dst++) {
+ const oop elem = ZBarrier::load_barrier_on_oop_field(src);
+ if (!oopDesc::is_instanceof_or_null(elem, dst_klass)) {
+ // Check cast failed
+ return false;
+ }
+
+ // Cast is safe, since we know it's never a narrowOop
+ *(oop*)dst = elem;
+ }
+
+ return true;
+}
+
+template <DecoratorSet decorators, typename BarrierSetT>
+inline void ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::clone_in_heap(oop src, oop dst, size_t size) {
+ ZBarrier::load_barrier_on_oop_fields(src);
+ Raw::clone_in_heap(src, dst, size);
+}
+
+//
+// Not in heap
+//
+template <DecoratorSet decorators, typename BarrierSetT>
+template <typename T>
+inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_load_not_in_heap(T* addr) {
+ const oop o = Raw::oop_load_not_in_heap(addr);
+
+ if (HasDecorator<decorators, ON_PHANTOM_OOP_REF>::value) {
+ return load_barrier_on_oop_field_preloaded(addr, o);
+ }
+
+ verify_decorators_present<ON_STRONG_OOP_REF>();
+ verify_decorators_absent<AS_NO_KEEPALIVE>();
+
+ return o;
+}
+
+template <DecoratorSet decorators, typename BarrierSetT>
+template <typename T>
+inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_cmpxchg_not_in_heap(oop new_value, T* addr, oop compare_value) {
+ verify_decorators_present<ON_STRONG_OOP_REF>();
+ verify_decorators_absent<AS_NO_KEEPALIVE>();
+
+ return Raw::oop_atomic_cmpxchg_not_in_heap(new_value, addr, compare_value);
+}
+
+template <DecoratorSet decorators, typename BarrierSetT>
+template <typename T>
+inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_xchg_not_in_heap(oop new_value, T* addr) {
+ verify_decorators_present<ON_STRONG_OOP_REF>();
+ verify_decorators_absent<AS_NO_KEEPALIVE>();
+
+ return Raw::oop_atomic_xchg_not_in_heap(new_value, addr);
+}
+
+#endif // SHARE_GC_Z_ZBARRIERSET_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zBarrierSetAssembler.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -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.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zBarrierSetAssembler.hpp"
+#include "gc/z/zThreadLocalData.hpp"
+#include "runtime/thread.hpp"
+
+Address ZBarrierSetAssemblerBase::address_bad_mask_from_thread(Register thread) {
+ return Address(thread, ZThreadLocalData::address_bad_mask_offset());
+}
+
+Address ZBarrierSetAssemblerBase::address_bad_mask_from_jni_env(Register env) {
+ return Address(env, ZThreadLocalData::address_bad_mask_offset() - JavaThread::jni_environment_offset());
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zBarrierSetAssembler.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,41 @@
+/*
+ * 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_Z_ZBARRIERSETASSEMBLER_HPP
+#define SHARE_GC_Z_ZBARRIERSETASSEMBLER_HPP
+
+#include "asm/macroAssembler.hpp"
+#include "gc/shared/barrierSetAssembler.hpp"
+#include "oops/accessDecorators.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/macros.hpp"
+
+class ZBarrierSetAssemblerBase : public BarrierSetAssembler {
+public:
+ static Address address_bad_mask_from_thread(Register thread);
+ static Address address_bad_mask_from_jni_env(Register env);
+};
+
+#include CPU_HEADER(gc/z/zBarrierSetAssembler)
+
+#endif // SHARE_GC_Z_ZBARRIERSETASSEMBLER_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zBarrierSetRuntime.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,69 @@
+/*
+ * 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 "gc/z/zBarrier.inline.hpp"
+#include "gc/z/zBarrierSetRuntime.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
+
+JRT_LEAF(oopDesc*, ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded(oopDesc* o, oop* p))
+ return ZBarrier::load_barrier_on_oop_field_preloaded(p, o);
+JRT_END
+
+JRT_LEAF(oopDesc*, ZBarrierSetRuntime::load_barrier_on_weak_oop_field_preloaded(oopDesc* o, oop* p))
+ return ZBarrier::load_barrier_on_weak_oop_field_preloaded(p, o);
+JRT_END
+
+JRT_LEAF(oopDesc*, ZBarrierSetRuntime::load_barrier_on_phantom_oop_field_preloaded(oopDesc* o, oop* p))
+ return ZBarrier::load_barrier_on_phantom_oop_field_preloaded(p, o);
+JRT_END
+
+JRT_LEAF(void, ZBarrierSetRuntime::load_barrier_on_oop_array(oop* p, size_t length))
+ ZBarrier::load_barrier_on_oop_array(p, length);
+JRT_END
+
+address ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(DecoratorSet decorators) {
+ if (decorators & ON_PHANTOM_OOP_REF) {
+ return load_barrier_on_phantom_oop_field_preloaded_addr();
+ } else if (decorators & ON_WEAK_OOP_REF) {
+ return load_barrier_on_weak_oop_field_preloaded_addr();
+ } else {
+ return load_barrier_on_oop_field_preloaded_addr();
+ }
+}
+
+address ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr() {
+ return reinterpret_cast<address>(load_barrier_on_oop_field_preloaded);
+}
+
+address ZBarrierSetRuntime::load_barrier_on_weak_oop_field_preloaded_addr() {
+ return reinterpret_cast<address>(load_barrier_on_weak_oop_field_preloaded);
+}
+
+address ZBarrierSetRuntime::load_barrier_on_phantom_oop_field_preloaded_addr() {
+ return reinterpret_cast<address>(load_barrier_on_phantom_oop_field_preloaded);
+}
+
+address ZBarrierSetRuntime::load_barrier_on_oop_array_addr() {
+ return reinterpret_cast<address>(load_barrier_on_oop_array);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zBarrierSetRuntime.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,48 @@
+/*
+ * 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_Z_ZBARRIERSETRUNTIME_HPP
+#define SHARE_GC_Z_ZBARRIERSETRUNTIME_HPP
+
+#include "memory/allocation.hpp"
+#include "oops/accessDecorators.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class oopDesc;
+
+class ZBarrierSetRuntime : public AllStatic {
+private:
+ static oopDesc* load_barrier_on_oop_field_preloaded(oopDesc* o, oop* p);
+ static oopDesc* load_barrier_on_weak_oop_field_preloaded(oopDesc* o, oop* p);
+ static oopDesc* load_barrier_on_phantom_oop_field_preloaded(oopDesc* o, oop* p);
+ static void load_barrier_on_oop_array(oop* p, size_t length);
+
+public:
+ static address load_barrier_on_oop_field_preloaded_addr(DecoratorSet decorators);
+ static address load_barrier_on_oop_field_preloaded_addr();
+ static address load_barrier_on_weak_oop_field_preloaded_addr();
+ static address load_barrier_on_phantom_oop_field_preloaded_addr();
+ static address load_barrier_on_oop_array_addr();
+};
+
+#endif // SHARE_GC_Z_ZBARRIERSETRUNTIME_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zBitField.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef SHARE_GC_Z_ZBITFIELD_HPP
+#define SHARE_GC_Z_ZBITFIELD_HPP
+
+#include "memory/allocation.hpp"
+#include "utilities/debug.hpp"
+
+//
+// Example
+// -------
+//
+// typedef ZBitField<uint64_t, uint8_t, 0, 2, 3> field_word_aligned_size;
+// typedef ZBitField<uint64_t, uint32_t, 2, 30> field_length;
+//
+//
+// 6 3 3
+// 3 2 1 2 10
+// +-----------------------------------+---------------------------------+--+
+// |11111111 11111111 11111111 11111111|11111111 11111111 11111111 111111|11|
+// +-----------------------------------+---------------------------------+--+
+// | | |
+// | 31-2 field_length (30-bits) * |
+// | |
+// | 1-0 field_word_aligned_size (2-bits) *
+// |
+// * 63-32 Unused (32-bits)
+//
+//
+// field_word_aligned_size::encode(16) = 2
+// field_length::encode(2342) = 9368
+//
+// field_word_aligned_size::decode(9368 | 2) = 16
+// field_length::decode(9368 | 2) = 2342
+//
+
+template <typename ContainerType, typename ValueType, int FieldShift, int FieldBits, int ValueShift = 0>
+class ZBitField : public AllStatic {
+private:
+ static const int ContainerBits = sizeof(ContainerType) * BitsPerByte;
+
+ STATIC_ASSERT(FieldBits < ContainerBits);
+ STATIC_ASSERT(FieldShift + FieldBits <= ContainerBits);
+ STATIC_ASSERT(ValueShift + FieldBits <= ContainerBits);
+
+ static const ContainerType FieldMask = (((ContainerType)1 << FieldBits) - 1);
+
+public:
+ static ValueType decode(ContainerType container) {
+ return (ValueType)(((container >> FieldShift) & FieldMask) << ValueShift);
+ }
+
+ static ContainerType encode(ValueType value) {
+ assert(((ContainerType)value & (FieldMask << ValueShift)) == (ContainerType)value, "Invalid value");
+ return ((ContainerType)value >> ValueShift) << FieldShift;
+ }
+};
+
+#endif // SHARE_GC_Z_ZBITFIELD_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zBitMap.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+#ifndef SHARE_GC_Z_ZBITMAP_HPP
+#define SHARE_GC_Z_ZBITMAP_HPP
+
+#include "utilities/bitMap.hpp"
+
+class ZBitMap : public CHeapBitMap {
+private:
+ static bm_word_t bit_mask_pair(idx_t bit);
+
+ bool par_set_bit_pair_finalizable(idx_t bit, bool& inc_live);
+ bool par_set_bit_pair_strong(idx_t bit, bool& inc_live);
+
+public:
+ ZBitMap(idx_t size_in_bits);
+
+ bool par_set_bit_pair(idx_t bit, bool finalizable, bool& inc_live);
+};
+
+#endif // SHARE_GC_Z_ZBITMAP_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zBitMap.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+#ifndef SHARE_GC_Z_ZBITMAP_INLINE_HPP
+#define SHARE_GC_Z_ZBITMAP_INLINE_HPP
+
+#include "gc/z/zBitMap.hpp"
+#include "runtime/atomic.hpp"
+#include "utilities/bitMap.inline.hpp"
+#include "utilities/debug.hpp"
+
+inline ZBitMap::ZBitMap(idx_t size_in_bits) :
+ CHeapBitMap(size_in_bits, mtGC, false /* clear */) {}
+
+inline BitMap::bm_word_t ZBitMap::bit_mask_pair(idx_t bit) {
+ assert(bit_in_word(bit) < BitsPerWord - 1, "Invalid bit index");
+ return (bm_word_t)3 << bit_in_word(bit);
+}
+
+inline bool ZBitMap::par_set_bit_pair_finalizable(idx_t bit, bool& inc_live) {
+ inc_live = par_set_bit(bit);
+ return inc_live;
+}
+
+inline bool ZBitMap::par_set_bit_pair_strong(idx_t bit, bool& inc_live) {
+ verify_index(bit);
+ volatile bm_word_t* const addr = word_addr(bit);
+ const bm_word_t pair_mask = bit_mask_pair(bit);
+ bm_word_t old_val = *addr;
+
+ do {
+ const bm_word_t new_val = old_val | pair_mask;
+ if (new_val == old_val) {
+ inc_live = false;
+ return false; // Someone else beat us to it.
+ }
+ const bm_word_t cur_val = Atomic::cmpxchg(new_val, addr, old_val);
+ if (cur_val == old_val) {
+ const bm_word_t marked_mask = bit_mask(bit);
+ inc_live = !(old_val & marked_mask);
+ return true; // Success.
+ }
+ old_val = cur_val; // The value changed, try again.
+ } while (true);
+}
+
+inline bool ZBitMap::par_set_bit_pair(idx_t bit, bool finalizable, bool& inc_live) {
+ if (finalizable) {
+ return par_set_bit_pair_finalizable(bit, inc_live);
+ } else {
+ return par_set_bit_pair_strong(bit, inc_live);
+ }
+}
+
+#endif // SHARE_GC_Z_ZBITMAP_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zCPU.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2015, 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 "gc/z/zCPU.hpp"
+#include "logging/log.hpp"
+#include "memory/padded.inline.hpp"
+#include "runtime/os.hpp"
+#include "runtime/thread.inline.hpp"
+#include "utilities/debug.hpp"
+
+#define ZCPU_UNKNOWN_AFFINITY (Thread*)-1;
+#define ZCPU_UNKNOWN_SELF (Thread*)-2;
+
+PaddedEnd<ZCPU::ZCPUAffinity>* ZCPU::_affinity = NULL;
+__thread Thread* ZCPU::_self = ZCPU_UNKNOWN_SELF;
+__thread uint32_t ZCPU::_cpu = 0;
+
+void ZCPU::initialize() {
+ assert(_affinity == NULL, "Already initialized");
+ const uint32_t ncpus = count();
+
+ _affinity = PaddedArray<ZCPUAffinity, mtGC>::create_unfreeable(ncpus);
+
+ for (uint32_t i = 0; i < ncpus; i++) {
+ _affinity[i]._thread = ZCPU_UNKNOWN_AFFINITY;
+ }
+
+ log_info(gc, init)("CPUs: %u total, %u available",
+ os::processor_count(),
+ os::initial_active_processor_count());
+}
+
+uint32_t ZCPU::count() {
+ return os::processor_count();
+}
+
+uint32_t ZCPU::id() {
+ assert(_affinity != NULL, "Not initialized");
+
+ // Fast path
+ if (_affinity[_cpu]._thread == _self) {
+ return _cpu;
+ }
+
+ // Slow path
+ _self = Thread::current();
+ _cpu = os::processor_id();
+
+ // Update affinity table
+ _affinity[_cpu]._thread = _self;
+
+ return _cpu;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zCPU.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZCPU_HPP
+#define SHARE_GC_Z_ZCPU_HPP
+
+#include "memory/allocation.hpp"
+#include "memory/padded.hpp"
+
+class Thread;
+
+class ZCPU : public AllStatic {
+private:
+ struct ZCPUAffinity {
+ Thread* _thread;
+ };
+
+ static PaddedEnd<ZCPUAffinity>* _affinity;
+ static __thread Thread* _self;
+ static __thread uint32_t _cpu;
+
+public:
+ static void initialize();
+
+ static uint32_t count();
+ static uint32_t id();
+};
+
+#endif // SHARE_GC_Z_ZCPU_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zCollectedHeap.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,348 @@
+/*
+ * 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 "gc/shared/gcHeapSummary.hpp"
+#include "gc/z/zCollectedHeap.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zHeap.inline.hpp"
+#include "gc/z/zNMethodTable.hpp"
+#include "gc/z/zServiceability.hpp"
+#include "gc/z/zStat.hpp"
+#include "gc/z/zUtils.inline.hpp"
+#include "runtime/mutexLocker.hpp"
+
+ZCollectedHeap* ZCollectedHeap::heap() {
+ CollectedHeap* heap = Universe::heap();
+ assert(heap != NULL, "Uninitialized access to ZCollectedHeap::heap()");
+ assert(heap->kind() == CollectedHeap::Z, "Invalid name");
+ return (ZCollectedHeap*)heap;
+}
+
+ZCollectedHeap::ZCollectedHeap(ZCollectorPolicy* policy) :
+ _collector_policy(policy),
+ _soft_ref_policy(),
+ _barrier_set(),
+ _initialize(&_barrier_set),
+ _heap(),
+ _director(new ZDirector()),
+ _driver(new ZDriver()),
+ _stat(new ZStat()),
+ _runtime_workers() {}
+
+CollectedHeap::Name ZCollectedHeap::kind() const {
+ return CollectedHeap::Z;
+}
+
+const char* ZCollectedHeap::name() const {
+ return ZGCName;
+}
+
+jint ZCollectedHeap::initialize() {
+ if (!_heap.is_initialized()) {
+ return JNI_ENOMEM;
+ }
+
+ initialize_reserved_region((HeapWord*)ZAddressReservedStart(),
+ (HeapWord*)ZAddressReservedEnd());
+
+ return JNI_OK;
+}
+
+void ZCollectedHeap::initialize_serviceability() {
+ _heap.serviceability_initialize();
+}
+
+void ZCollectedHeap::stop() {
+ _director->stop();
+ _driver->stop();
+ _stat->stop();
+}
+
+CollectorPolicy* ZCollectedHeap::collector_policy() const {
+ return _collector_policy;
+}
+
+SoftRefPolicy* ZCollectedHeap::soft_ref_policy() {
+ return &_soft_ref_policy;
+}
+
+size_t ZCollectedHeap::max_capacity() const {
+ return _heap.max_capacity();
+}
+
+size_t ZCollectedHeap::capacity() const {
+ return _heap.capacity();
+}
+
+size_t ZCollectedHeap::used() const {
+ return _heap.used();
+}
+
+bool ZCollectedHeap::is_maximal_no_gc() const {
+ // Not supported
+ ShouldNotReachHere();
+ return false;
+}
+
+bool ZCollectedHeap::is_scavengable(oop obj) {
+ return false;
+}
+
+bool ZCollectedHeap::is_in(const void* p) const {
+ return is_in_reserved(p) && _heap.is_in((uintptr_t)p);
+}
+
+bool ZCollectedHeap::is_in_closed_subset(const void* p) const {
+ return is_in(p);
+}
+
+HeapWord* ZCollectedHeap::allocate_new_tlab(size_t min_size, size_t requested_size, size_t* actual_size) {
+ const size_t size_in_bytes = ZUtils::words_to_bytes(align_object_size(requested_size));
+ const uintptr_t addr = _heap.alloc_tlab(size_in_bytes);
+
+ if (addr != 0) {
+ *actual_size = requested_size;
+ }
+
+ return (HeapWord*)addr;
+}
+
+HeapWord* ZCollectedHeap::mem_allocate(size_t size, bool* gc_overhead_limit_was_exceeded) {
+ const size_t size_in_bytes = ZUtils::words_to_bytes(align_object_size(size));
+ return (HeapWord*)_heap.alloc_object(size_in_bytes);
+}
+
+MetaWord* ZCollectedHeap::satisfy_failed_metadata_allocation(ClassLoaderData* loader_data,
+ size_t size,
+ Metaspace::MetadataType mdtype) {
+ MetaWord* result;
+
+ // Start asynchronous GC
+ collect(GCCause::_metadata_GC_threshold);
+
+ // Expand and retry allocation
+ result = loader_data->metaspace_non_null()->expand_and_allocate(size, mdtype);
+ if (result != NULL) {
+ return result;
+ }
+
+ // Start synchronous GC
+ collect(GCCause::_metadata_GC_clear_soft_refs);
+
+ // Retry allocation
+ result = loader_data->metaspace_non_null()->allocate(size, mdtype);
+ if (result != NULL) {
+ return result;
+ }
+
+ // Expand and retry allocation
+ result = loader_data->metaspace_non_null()->expand_and_allocate(size, mdtype);
+ if (result != NULL) {
+ return result;
+ }
+
+ // Out of memory
+ return NULL;
+}
+
+void ZCollectedHeap::collect(GCCause::Cause cause) {
+ _driver->collect(cause);
+}
+
+void ZCollectedHeap::collect_as_vm_thread(GCCause::Cause cause) {
+ // These collection requests are ignored since ZGC can't run a synchronous
+ // GC cycle from within the VM thread. This is considered benign, since the
+ // only GC causes comming in here should be heap dumper and heap inspector.
+ // However, neither the heap dumper nor the heap inspector really need a GC
+ // to happen, but the result of their heap iterations might in that case be
+ // less accurate since they might include objects that would otherwise have
+ // been collected by a GC.
+ assert(Thread::current()->is_VM_thread(), "Should be the VM thread");
+ guarantee(cause == GCCause::_heap_dump ||
+ cause == GCCause::_heap_inspection, "Invalid cause");
+}
+
+void ZCollectedHeap::do_full_collection(bool clear_all_soft_refs) {
+ // Not supported
+ ShouldNotReachHere();
+}
+
+bool ZCollectedHeap::supports_tlab_allocation() const {
+ return true;
+}
+
+size_t ZCollectedHeap::tlab_capacity(Thread* ignored) const {
+ return _heap.tlab_capacity();
+}
+
+size_t ZCollectedHeap::tlab_used(Thread* ignored) const {
+ return _heap.tlab_used();
+}
+
+size_t ZCollectedHeap::max_tlab_size() const {
+ return _heap.max_tlab_size();
+}
+
+size_t ZCollectedHeap::unsafe_max_tlab_alloc(Thread* ignored) const {
+ return _heap.unsafe_max_tlab_alloc();
+}
+
+bool ZCollectedHeap::can_elide_tlab_store_barriers() const {
+ return false;
+}
+
+bool ZCollectedHeap::can_elide_initializing_store_barrier(oop new_obj) {
+ // Not supported
+ ShouldNotReachHere();
+ return true;
+}
+
+bool ZCollectedHeap::card_mark_must_follow_store() const {
+ // Not supported
+ ShouldNotReachHere();
+ return false;
+}
+
+GrowableArray<GCMemoryManager*> ZCollectedHeap::memory_managers() {
+ return GrowableArray<GCMemoryManager*>(1, 1, _heap.serviceability_memory_manager());
+}
+
+GrowableArray<MemoryPool*> ZCollectedHeap::memory_pools() {
+ return GrowableArray<MemoryPool*>(1, 1, _heap.serviceability_memory_pool());
+}
+
+void ZCollectedHeap::object_iterate(ObjectClosure* cl) {
+ _heap.object_iterate(cl);
+}
+
+void ZCollectedHeap::safe_object_iterate(ObjectClosure* cl) {
+ _heap.object_iterate(cl);
+}
+
+HeapWord* ZCollectedHeap::block_start(const void* addr) const {
+ return (HeapWord*)_heap.block_start((uintptr_t)addr);
+}
+
+size_t ZCollectedHeap::block_size(const HeapWord* addr) const {
+ size_t size_in_bytes = _heap.block_size((uintptr_t)addr);
+ return ZUtils::bytes_to_words(size_in_bytes);
+}
+
+bool ZCollectedHeap::block_is_obj(const HeapWord* addr) const {
+ return _heap.block_is_obj((uintptr_t)addr);
+}
+
+void ZCollectedHeap::register_nmethod(nmethod* nm) {
+ assert_locked_or_safepoint(CodeCache_lock);
+ ZNMethodTable::register_nmethod(nm);
+}
+
+void ZCollectedHeap::unregister_nmethod(nmethod* nm) {
+ assert_locked_or_safepoint(CodeCache_lock);
+ ZNMethodTable::unregister_nmethod(nm);
+}
+
+void ZCollectedHeap::verify_nmethod(nmethod* nm) {
+ // Does nothing
+}
+
+WorkGang* ZCollectedHeap::get_safepoint_workers() {
+ return _runtime_workers.workers();
+}
+
+jlong ZCollectedHeap::millis_since_last_gc() {
+ return ZStatCycle::time_since_last() / MILLIUNITS;
+}
+
+void ZCollectedHeap::gc_threads_do(ThreadClosure* tc) const {
+ tc->do_thread(_director);
+ tc->do_thread(_driver);
+ tc->do_thread(_stat);
+ _heap.worker_threads_do(tc);
+ _runtime_workers.threads_do(tc);
+}
+
+VirtualSpaceSummary ZCollectedHeap::create_heap_space_summary() {
+ const size_t capacity_in_words = capacity() / HeapWordSize;
+ const size_t max_capacity_in_words = max_capacity() / HeapWordSize;
+ return VirtualSpaceSummary(reserved_region().start(),
+ reserved_region().start() + capacity_in_words,
+ reserved_region().start() + max_capacity_in_words);
+}
+
+void ZCollectedHeap::prepare_for_verify() {
+ // Does nothing
+}
+
+void ZCollectedHeap::print_on(outputStream* st) const {
+ _heap.print_on(st);
+}
+
+void ZCollectedHeap::print_on_error(outputStream* st) const {
+ CollectedHeap::print_on_error(st);
+
+ st->print_cr("Address Space");
+ st->print_cr( " Start: " PTR_FORMAT, ZAddressSpaceStart);
+ st->print_cr( " End: " PTR_FORMAT, ZAddressSpaceEnd);
+ st->print_cr( " Size: " SIZE_FORMAT_W(-15) " (" PTR_FORMAT ")", ZAddressSpaceSize, ZAddressSpaceSize);
+ st->print_cr( "Heap");
+ st->print_cr( " GlobalPhase: %u", ZGlobalPhase);
+ st->print_cr( " GlobalSeqNum: %u", ZGlobalSeqNum);
+ st->print_cr( " Offset Max: " SIZE_FORMAT_W(-15) " (" PTR_FORMAT ")", ZAddressOffsetMax, ZAddressOffsetMax);
+ st->print_cr( " Page Size Small: " SIZE_FORMAT_W(-15) " (" PTR_FORMAT ")", ZPageSizeSmall, ZPageSizeSmall);
+ st->print_cr( " Page Size Medium: " SIZE_FORMAT_W(-15) " (" PTR_FORMAT ")", ZPageSizeMedium, ZPageSizeMedium);
+ st->print_cr( "Metadata Bits");
+ st->print_cr( " Good: " PTR_FORMAT, ZAddressGoodMask);
+ st->print_cr( " Bad: " PTR_FORMAT, ZAddressBadMask);
+ st->print_cr( " WeakBad: " PTR_FORMAT, ZAddressWeakBadMask);
+ st->print_cr( " Marked: " PTR_FORMAT, ZAddressMetadataMarked);
+ st->print_cr( " Remapped: " PTR_FORMAT, ZAddressMetadataRemapped);
+}
+
+void ZCollectedHeap::print_extended_on(outputStream* st) const {
+ _heap.print_extended_on(st);
+}
+
+void ZCollectedHeap::print_gc_threads_on(outputStream* st) const {
+ _director->print_on(st);
+ st->cr();
+ _driver->print_on(st);
+ st->cr();
+ _stat->print_on(st);
+ st->cr();
+ _heap.print_worker_threads_on(st);
+ _runtime_workers.print_threads_on(st);
+}
+
+void ZCollectedHeap::print_tracing_info() const {
+ // Does nothing
+}
+
+void ZCollectedHeap::verify(VerifyOption option /* ignored */) {
+ _heap.verify();
+}
+
+bool ZCollectedHeap::is_oop(oop object) const {
+ return CollectedHeap::is_oop(object) && _heap.is_oop(object);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zCollectedHeap.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,133 @@
+/*
+ * 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_GC_Z_ZCOLLECTEDHEAP_HPP
+#define SHARE_GC_Z_ZCOLLECTEDHEAP_HPP
+
+#include "gc/shared/collectedHeap.hpp"
+#include "gc/shared/softRefPolicy.hpp"
+#include "gc/z/zBarrierSet.hpp"
+#include "gc/z/zCollectorPolicy.hpp"
+#include "gc/z/zDirector.hpp"
+#include "gc/z/zDriver.hpp"
+#include "gc/z/zInitialize.hpp"
+#include "gc/z/zHeap.hpp"
+#include "gc/z/zRuntimeWorkers.hpp"
+#include "gc/z/zStat.hpp"
+
+class ZCollectedHeap : public CollectedHeap {
+ friend class VMStructs;
+
+private:
+ ZCollectorPolicy* _collector_policy;
+ SoftRefPolicy _soft_ref_policy;
+ ZBarrierSet _barrier_set;
+ ZInitialize _initialize;
+ ZHeap _heap;
+ ZDirector* _director;
+ ZDriver* _driver;
+ ZStat* _stat;
+ ZRuntimeWorkers _runtime_workers;
+
+ virtual HeapWord* allocate_new_tlab(size_t min_size,
+ size_t requested_size,
+ size_t* actual_size);
+
+public:
+ static ZCollectedHeap* heap();
+
+ using CollectedHeap::ensure_parsability;
+ using CollectedHeap::accumulate_statistics_all_tlabs;
+ using CollectedHeap::resize_all_tlabs;
+
+ ZCollectedHeap(ZCollectorPolicy* policy);
+ virtual Name kind() const;
+ virtual const char* name() const;
+ virtual jint initialize();
+ virtual void initialize_serviceability();
+ virtual void stop();
+
+ virtual CollectorPolicy* collector_policy() const;
+ virtual SoftRefPolicy* soft_ref_policy();
+
+ virtual size_t max_capacity() const;
+ virtual size_t capacity() const;
+ virtual size_t used() const;
+
+ virtual bool is_maximal_no_gc() const;
+ virtual bool is_scavengable(oop obj);
+ virtual bool is_in(const void* p) const;
+ virtual bool is_in_closed_subset(const void* p) const;
+
+ virtual HeapWord* mem_allocate(size_t size, bool* gc_overhead_limit_was_exceeded);
+ virtual MetaWord* satisfy_failed_metadata_allocation(ClassLoaderData* loader_data,
+ size_t size,
+ Metaspace::MetadataType mdtype);
+ virtual void collect(GCCause::Cause cause);
+ virtual void collect_as_vm_thread(GCCause::Cause cause);
+ virtual void do_full_collection(bool clear_all_soft_refs);
+
+ virtual bool supports_tlab_allocation() const;
+ virtual size_t tlab_capacity(Thread* thr) const;
+ virtual size_t tlab_used(Thread* thr) const;
+ virtual size_t max_tlab_size() const;
+ virtual size_t unsafe_max_tlab_alloc(Thread* thr) const;
+
+ virtual bool can_elide_tlab_store_barriers() const;
+ virtual bool can_elide_initializing_store_barrier(oop new_obj);
+ virtual bool card_mark_must_follow_store() const;
+
+ virtual GrowableArray<GCMemoryManager*> memory_managers();
+ virtual GrowableArray<MemoryPool*> memory_pools();
+
+ virtual void object_iterate(ObjectClosure* cl);
+ virtual void safe_object_iterate(ObjectClosure* cl);
+
+ virtual HeapWord* block_start(const void* addr) const;
+ virtual size_t block_size(const HeapWord* addr) const;
+ virtual bool block_is_obj(const HeapWord* addr) const;
+
+ virtual void register_nmethod(nmethod* nm);
+ virtual void unregister_nmethod(nmethod* nm);
+ virtual void verify_nmethod(nmethod* nmethod);
+
+ virtual WorkGang* get_safepoint_workers();
+
+ virtual jlong millis_since_last_gc();
+
+ virtual void gc_threads_do(ThreadClosure* tc) const;
+
+ virtual VirtualSpaceSummary create_heap_space_summary();
+
+ virtual void print_on(outputStream* st) const;
+ virtual void print_on_error(outputStream* st) const;
+ virtual void print_extended_on(outputStream* st) const;
+ virtual void print_gc_threads_on(outputStream* st) const;
+ virtual void print_tracing_info() const;
+
+ virtual void prepare_for_verify();
+ virtual void verify(VerifyOption option /* ignored */);
+ virtual bool is_oop(oop object) const;
+};
+
+#endif // SHARE_GC_Z_ZCOLLECTEDHEAP_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zCollectorPolicy.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,31 @@
+/*
+ * 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 "gc/z/zCollectorPolicy.hpp"
+#include "gc/z/zGlobals.hpp"
+
+void ZCollectorPolicy::initialize_alignments() {
+ _space_alignment = ZPageSizeMin;
+ _heap_alignment = _space_alignment;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zCollectorPolicy.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,34 @@
+/*
+ * 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_GC_Z_ZCOLLECTORPOLICY_HPP
+#define SHARE_GC_Z_ZCOLLECTORPOLICY_HPP
+
+#include "gc/shared/collectorPolicy.hpp"
+
+class ZCollectorPolicy : public CollectorPolicy {
+public:
+ virtual void initialize_alignments();
+};
+
+#endif // SHARE_GC_Z_ZCOLLECTORPOLICY_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zDebug.gdb Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,147 @@
+#
+# GDB functions for debugging the Z Garbage Collector
+#
+
+printf "Loading zDebug.gdb\n"
+
+# Print Klass*
+define zpk
+ printf "Klass: %s\n", (char*)((Klass*)($arg0))->_name->_body
+end
+
+# Print oop
+define zpo
+ set $obj = (oopDesc*)($arg0)
+
+ printf "Oop: 0x%016llx\tState: ", (uintptr_t)$obj
+ if ((uintptr_t)$obj & (uintptr_t)ZAddressGoodMask)
+ printf "Good "
+ if ((uintptr_t)$obj & (uintptr_t)ZAddressMetadataRemapped)
+ printf "(Remapped)"
+ else
+ if ((uintptr_t)$obj & (uintptr_t)ZAddressMetadataMarked)
+ printf "(Marked)"
+ else
+ printf "(Unknown)"
+ end
+ end
+ else
+ printf "Bad "
+ if ((uintptr_t)ZAddressGoodMask & (uintptr_t)ZAddressMetadataMarked)
+ # Should be marked
+ if ((uintptr_t)$obj & (uintptr_t)ZAddressMetadataRemapped)
+ printf "(Not Marked, Remapped)"
+ else
+ printf "(Not Marked, Not Remapped)"
+ end
+ else
+ if ((uintptr_t)ZAddressGoodMask & (uintptr_t)ZAddressMetadataRemapped)
+ # Should be remapped
+ if ((uintptr_t)$obj & (uintptr_t)ZAddressMetadataMarked)
+ printf "(Marked, Not Remapped)"
+ else
+ printf "(Not Marked, Not Remapped)"
+ end
+ else
+ # Unknown
+ printf "(Unknown)"
+ end
+ end
+ end
+ printf "\t Page: %llu\n", ((uintptr_t)$obj & ZAddressOffsetMask) >> ZPageSizeMinShift
+ x/16gx $obj
+ printf "Mark: 0x%016llx\tKlass: %s\n", (uintptr_t)$obj->_mark, (char*)$obj->_metadata->_klass->_name->_body
+end
+
+# Print heap page by pagetable index
+define zpp
+ set $page = (ZPage*)((uintptr_t)ZHeap::_heap._pagetable._map._map[($arg0)] & ~1)
+ printf "Page %p\n", $page
+ print *$page
+end
+
+# Print pagetable
+define zpt
+ printf "Pagetable (first 128 slots)\n"
+ x/128gx ZHeap::_heap._pagetable._map._map
+end
+
+# Print live map
+define __zmarked
+ set $livemap = $arg0
+ set $bit = $arg1
+ set $size = $livemap._bitmap._size
+ set $segment = $size / ZLiveMap::nsegments
+ set $segment_bit = 1 << $segment
+
+ printf "Segment is "
+ if !($livemap._segment_live_bits & $segment_bit)
+ printf "NOT "
+ end
+ printf "live (segment %d)\n", $segment
+
+ if $bit >= $size
+ print "Error: Bit %z out of bounds (bitmap size %z)\n", $bit, $size
+ else
+ set $word_index = $bit / 64
+ set $bit_index = $bit % 64
+ set $word = $livemap._bitmap._map[$word_index]
+ set $live_bit = $word & (1 << $bit_index)
+
+ printf "Object is "
+ if $live_bit == 0
+ printf "NOT "
+ end
+ printf "live (word index %d, bit index %d)\n", $word_index, $bit_index
+ end
+end
+
+define zmarked
+ set $addr = $arg0
+ set $obj = ((uintptr_t)$addr & ZAddressOffsetMask)
+ set $page_index = $obj >> ZPageSizeMinShift
+ set $page_entry = (uintptr_t)ZHeap::_heap._pagetable._map._map[$page_index]
+ set $page = (ZPage*)($page_entry & ~1)
+ set $page_start = (uintptr_t)$page._virtual._start
+ set $page_end = (uintptr_t)$page._virtual._end
+ set $page_seqnum = $page._livemap._seqnum
+ set $global_seqnum = ZGlobalSeqNum
+
+ if $obj < $page_start || $obj >= $page_end
+ printf "Error: %p not in page %p (start %p, end %p)\n", $obj, $page, $page_start, $page_end
+ else
+ printf "Page is "
+ if $page_seqnum != $global_seqnum
+ printf "NOT "
+ end
+ printf "live (page %p, page seqnum %d, global seqnum %d)\n", $page, $page_seqnum, $global_seqnum
+
+ #if $page_seqnum == $global_seqnum
+ set $offset = $obj - $page_start
+ set $bit = $offset / 8
+ __zmarked $page._livemap $bit
+ #end
+ end
+end
+
+# Print heap information
+define zph
+ printf "Address Space\n"
+ printf " Start: 0x%llx\n", ZAddressSpaceStart
+ printf " End: 0x%llx\n", ZAddressSpaceEnd
+ printf " Size: %-15llu (0x%llx)\n", ZAddressSpaceSize, ZAddressSpaceSize
+ printf "Heap\n"
+ printf " GlobalPhase: %u\n", ZGlobalPhase
+ printf " GlobalSeqNum: %u\n", ZGlobalSeqNum
+ printf " Offset Max: %-15llu (0x%llx)\n", ZAddressOffsetMax, ZAddressOffsetMax
+ printf " Page Size Small: %-15llu (0x%llx)\n", ZPageSizeSmall, ZPageSizeSmall
+ printf " Page Size Medium: %-15llu (0x%llx)\n", ZPageSizeMedium, ZPageSizeMedium
+ printf "Metadata Bits\n"
+ printf " Good: 0x%016llx\n", ZAddressGoodMask
+ printf " Bad: 0x%016llx\n", ZAddressBadMask
+ printf " WeakBad: 0x%016llx\n", ZAddressWeakBadMask
+ printf " Marked: 0x%016llx\n", ZAddressMetadataMarked
+ printf " Remapped: 0x%016llx\n", ZAddressMetadataRemapped
+end
+
+# End of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zDirector.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,222 @@
+/*
+ * 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 "gc/z/zCollectedHeap.hpp"
+#include "gc/z/zDirector.hpp"
+#include "gc/z/zHeap.inline.hpp"
+#include "gc/z/zStat.hpp"
+#include "gc/z/zUtils.hpp"
+#include "logging/log.hpp"
+
+const double ZDirector::one_in_1000 = 3.290527;
+
+ZDirector::ZDirector() :
+ _metronome(ZStatAllocRate::sample_hz) {
+ set_name("ZDirector");
+ create_and_start();
+}
+
+void ZDirector::sample_allocation_rate() const {
+ // Sample allocation rate. This is needed by rule_allocation_rate()
+ // below to estimate the time we have until we run out of memory.
+ const double bytes_per_second = ZStatAllocRate::sample_and_reset();
+
+ log_debug(gc, alloc)("Allocation Rate: %.3fMB/s, Avg: %.3f(+/-%.3f)MB/s",
+ bytes_per_second / M,
+ ZStatAllocRate::avg() / M,
+ ZStatAllocRate::avg_sd() / M);
+}
+
+bool ZDirector::is_first() const {
+ return ZStatCycle::ncycles() == 0;
+}
+
+bool ZDirector::is_warm() const {
+ return ZStatCycle::ncycles() >= 3;
+}
+
+bool ZDirector::rule_timer() const {
+ if (ZCollectionInterval == 0) {
+ // Rule disabled
+ return false;
+ }
+
+ // Perform GC if timer has expired.
+ const double time_since_last_gc = ZStatCycle::time_since_last();
+ const double time_until_gc = ZCollectionInterval - time_since_last_gc;
+
+ log_debug(gc, director)("Rule: Timer, Interval: %us, TimeUntilGC: %.3lfs",
+ ZCollectionInterval, time_until_gc);
+
+ return time_until_gc <= 0;
+}
+
+bool ZDirector::rule_warmup() const {
+ if (is_warm()) {
+ // Rule disabled
+ return false;
+ }
+
+ // Perform GC if heap usage passes 10/20/30% and no other GC has been
+ // performed yet. This allows us to get some early samples of the GC
+ // duration, which is needed by the other rules.
+ const size_t max_capacity = ZHeap::heap()->max_capacity();
+ const size_t used = ZHeap::heap()->used();
+ const double used_threshold_percent = (ZStatCycle::ncycles() + 1) * 0.1;
+ const size_t used_threshold = max_capacity * used_threshold_percent;
+
+ log_debug(gc, director)("Rule: Warmup %.0f%%, Used: " SIZE_FORMAT "MB, UsedThreshold: " SIZE_FORMAT "MB",
+ used_threshold_percent * 100, used / M, used_threshold / M);
+
+ return used >= used_threshold;
+}
+
+bool ZDirector::rule_allocation_rate() const {
+ if (is_first()) {
+ // Rule disabled
+ return false;
+ }
+
+ // Perform GC if the estimated max allocation rate indicates that we
+ // will run out of memory. The estimated max allocation rate is based
+ // on the moving average of the sampled allocation rate plus a safety
+ // margin based on variations in the allocation rate and unforseen
+ // allocation spikes.
+
+ // Calculate amount of free memory available to Java threads. Note that
+ // the heap reserve is not available to Java threads and is therefore not
+ // considered part of the free memory.
+ const size_t max_capacity = ZHeap::heap()->max_capacity();
+ const size_t max_reserve = ZHeap::heap()->max_reserve();
+ const size_t used = ZHeap::heap()->used();
+ const size_t free_with_reserve = max_capacity - used;
+ const size_t free = free_with_reserve - MIN2(free_with_reserve, max_reserve);
+
+ // Calculate time until OOM given the max allocation rate and the amount
+ // of free memory. The allocation rate is a moving average and we multiply
+ // that with an alllcation spike tolerance factor to guard against unforseen
+ // phase changes in the allocate rate. We then add ~3.3 sigma to account for
+ // the allocation rate variance, which means the probablility is 1 in 1000
+ // that a sample is outside of the confidence interval.
+ const double max_alloc_rate = (ZStatAllocRate::avg() * ZAllocationSpikeTolerance) + (ZStatAllocRate::avg_sd() * one_in_1000);
+ const double time_until_oom = free / (max_alloc_rate + 1.0); // Plus 1.0B/s to avoid division by zero
+
+ // Calculate max duration of a GC cycle. The duration of GC is a moving
+ // average, we add ~3.3 sigma to account for the GC duration variance.
+ const AbsSeq& duration_of_gc = ZStatCycle::normalized_duration();
+ const double max_duration_of_gc = duration_of_gc.davg() + (duration_of_gc.dsd() * one_in_1000);
+
+ // Calculate time until GC given the time until OOM and max duration of GC.
+ // We also deduct the sample interval, so that we don't overshoot the target
+ // time and end up starting the GC too late in the next interval.
+ const double sample_interval = 1.0 / ZStatAllocRate::sample_hz;
+ const double time_until_gc = time_until_oom - max_duration_of_gc - sample_interval;
+
+ log_debug(gc, director)("Rule: Allocation Rate, MaxAllocRate: %.3lfMB/s, Free: " SIZE_FORMAT "MB, MaxDurationOfGC: %.3lfs, TimeUntilGC: %.3lfs",
+ max_alloc_rate / M, free / M, max_duration_of_gc, time_until_gc);
+
+ return time_until_gc <= 0;
+}
+
+bool ZDirector::rule_proactive() const {
+ if (!ZProactive || !is_warm()) {
+ // Rule disabled
+ return false;
+ }
+
+ // Perform GC if the impact of doing so, in terms of application throughput
+ // reduction, is considered acceptable. This rule allows us to keep the heap
+ // size down and allow reference processing to happen even when we have a lot
+ // of free space on the heap.
+
+ // Only consider doing a proactive GC if the heap usage has grown by at least
+ // 10% of the max capacity since the previous GC, or more than 5 minutes has
+ // passed since the previous GC. This helps avoid superfluous GCs when running
+ // applications with very low allocation rate.
+ const size_t used_after_last_gc = ZStatHeap::used_at_relocate_end();
+ const size_t used_increase_threshold = ZHeap::heap()->max_capacity() * 0.10; // 10%
+ const size_t used_threshold = used_after_last_gc + used_increase_threshold;
+ const size_t used = ZHeap::heap()->used();
+ const double time_since_last_gc = ZStatCycle::time_since_last();
+ const double time_since_last_gc_threshold = 5 * 60; // 5 minutes
+ if (used < used_threshold && time_since_last_gc < time_since_last_gc_threshold) {
+ // Don't even consider doing a proactive GC
+ log_debug(gc, director)("Rule: Proactive, UsedUntilEnabled: " SIZE_FORMAT "MB, TimeUntilEnabled: %.3lfs",
+ (used_threshold - used) / M,
+ time_since_last_gc_threshold - time_since_last_gc);
+ return false;
+ }
+
+ const double assumed_throughput_drop_during_gc = 0.50; // 50%
+ const double acceptable_throughput_drop = 0.01; // 1%
+ const AbsSeq& duration_of_gc = ZStatCycle::normalized_duration();
+ const double max_duration_of_gc = duration_of_gc.davg() + (duration_of_gc.dsd() * one_in_1000);
+ const double acceptable_gc_interval = max_duration_of_gc * ((assumed_throughput_drop_during_gc / acceptable_throughput_drop) - 1.0);
+ const double time_until_gc = acceptable_gc_interval - time_since_last_gc;
+
+ log_debug(gc, director)("Rule: Proactive, AcceptableGCInterval: %.3lfs, TimeSinceLastGC: %.3lfs, TimeUntilGC: %.3lfs",
+ acceptable_gc_interval, time_since_last_gc, time_until_gc);
+
+ return time_until_gc <= 0;
+}
+
+GCCause::Cause ZDirector::make_gc_decision() const {
+ // Rule 0: Timer
+ if (rule_timer()) {
+ return GCCause::_z_timer;
+ }
+
+ // Rule 1: Warmup
+ if (rule_warmup()) {
+ return GCCause::_z_warmup;
+ }
+
+ // Rule 2: Allocation rate
+ if (rule_allocation_rate()) {
+ return GCCause::_z_allocation_rate;
+ }
+
+ // Rule 3: Proactive
+ if (rule_proactive()) {
+ return GCCause::_z_proactive;
+ }
+
+ // No GC
+ return GCCause::_no_gc;
+}
+
+void ZDirector::run_service() {
+ // Main loop
+ while (_metronome.wait_for_tick()) {
+ sample_allocation_rate();
+ const GCCause::Cause cause = make_gc_decision();
+ if (cause != GCCause::_no_gc) {
+ ZCollectedHeap::heap()->collect(cause);
+ }
+ }
+}
+
+void ZDirector::stop_service() {
+ _metronome.stop();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zDirector.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZDIRECTOR_HPP
+#define SHARE_GC_Z_ZDIRECTOR_HPP
+
+#include "gc/shared/concurrentGCThread.hpp"
+#include "gc/shared/gcCause.hpp"
+#include "gc/z/zMetronome.hpp"
+
+class ZDirector : public ConcurrentGCThread {
+private:
+ static const double one_in_1000;
+
+ ZMetronome _metronome;
+
+ void sample_allocation_rate() const;
+
+ bool is_first() const;
+ bool is_warm() const;
+
+ bool rule_timer() const;
+ bool rule_warmup() const;
+ bool rule_allocation_rate() const;
+ bool rule_proactive() const;
+ GCCause::Cause make_gc_decision() const;
+
+protected:
+ virtual void run_service();
+ virtual void stop_service();
+
+public:
+ ZDirector();
+};
+
+#endif // SHARE_GC_Z_ZDIRECTOR_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zDriver.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,403 @@
+/*
+ * 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 "gc/shared/gcId.hpp"
+#include "gc/shared/gcLocker.hpp"
+#include "gc/shared/isGCActiveMark.hpp"
+#include "gc/shared/vmGCOperations.hpp"
+#include "gc/z/zCollectedHeap.hpp"
+#include "gc/z/zDriver.hpp"
+#include "gc/z/zHeap.inline.hpp"
+#include "gc/z/zMessagePort.inline.hpp"
+#include "gc/z/zServiceability.hpp"
+#include "gc/z/zStat.hpp"
+#include "logging/log.hpp"
+#include "runtime/vm_operations.hpp"
+#include "runtime/vmThread.hpp"
+
+static const ZStatPhaseCycle ZPhaseCycle("Garbage Collection Cycle");
+static const ZStatPhasePause ZPhasePauseMarkStart("Pause Mark Start");
+static const ZStatPhaseConcurrent ZPhaseConcurrentMark("Concurrent Mark");
+static const ZStatPhaseConcurrent ZPhaseConcurrentMarkContinue("Concurrent Mark Continue");
+static const ZStatPhasePause ZPhasePauseMarkEnd("Pause Mark End");
+static const ZStatPhaseConcurrent ZPhaseConcurrentProcessNonStrongReferences("Concurrent Process Non-Strong References");
+static const ZStatPhaseConcurrent ZPhaseConcurrentResetRelocationSet("Concurrent Reset Relocation Set");
+static const ZStatPhaseConcurrent ZPhaseConcurrentDestroyDetachedPages("Concurrent Destroy Detached Pages");
+static const ZStatPhaseConcurrent ZPhaseConcurrentSelectRelocationSet("Concurrent Select Relocation Set");
+static const ZStatPhaseConcurrent ZPhaseConcurrentPrepareRelocationSet("Concurrent Prepare Relocation Set");
+static const ZStatPhasePause ZPhasePauseRelocateStart("Pause Relocate Start");
+static const ZStatPhaseConcurrent ZPhaseConcurrentRelocated("Concurrent Relocate");
+static const ZStatCriticalPhase ZCriticalPhaseGCLockerStall("GC Locker Stall", false /* verbose */);
+static const ZStatSampler ZSamplerJavaThreads("System", "Java Threads", ZStatUnitThreads);
+
+class ZOperationClosure : public StackObj {
+public:
+ virtual const char* name() const = 0;
+
+ virtual bool needs_inactive_gc_locker() const {
+ // An inactive GC locker is needed in operations where we change the good
+ // mask or move objects. Changing the good mask will invalidate all oops,
+ // which makes it conceptually the same thing as moving all objects.
+ return false;
+ }
+
+ virtual bool do_operation() = 0;
+};
+
+class VM_ZOperation : public VM_Operation {
+private:
+ ZOperationClosure* _cl;
+ uint _gc_id;
+ bool _gc_locked;
+ bool _success;
+
+public:
+ VM_ZOperation(ZOperationClosure* cl) :
+ _cl(cl),
+ _gc_id(GCId::current()),
+ _gc_locked(false),
+ _success(false) {}
+
+ virtual VMOp_Type type() const {
+ return VMOp_ZOperation;
+ }
+
+ virtual const char* name() const {
+ return _cl->name();
+ }
+
+ virtual bool doit_prologue() {
+ Heap_lock->lock();
+ return true;
+ }
+
+ virtual void doit() {
+ assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
+
+ ZStatSample(ZSamplerJavaThreads, Threads::number_of_threads());
+
+ // JVMTI support
+ SvcGCMarker sgcm(SvcGCMarker::OTHER);
+
+ // Setup GC id
+ GCIdMark gcid(_gc_id);
+
+ if (_cl->needs_inactive_gc_locker() && GCLocker::check_active_before_gc()) {
+ // GC locker is active, bail out
+ _gc_locked = true;
+ } else {
+ // Execute operation
+ IsGCActiveMark mark;
+ _success = _cl->do_operation();
+ }
+ }
+
+ virtual void doit_epilogue() {
+ Heap_lock->unlock();
+ }
+
+ bool gc_locked() {
+ return _gc_locked;
+ }
+
+ bool success() const {
+ return _success;
+ }
+};
+
+class ZMarkStartClosure : public ZOperationClosure {
+public:
+ virtual const char* name() const {
+ return "ZMarkStart";
+ }
+
+ virtual bool needs_inactive_gc_locker() const {
+ return true;
+ }
+
+ virtual bool do_operation() {
+ ZStatTimer timer(ZPhasePauseMarkStart);
+ ZServiceabilityMarkStartTracer tracer;
+
+ ZCollectedHeap::heap()->increment_total_collections(true /* full */);
+
+ ZHeap::heap()->mark_start();
+ return true;
+ }
+};
+
+class ZMarkEndClosure : public ZOperationClosure {
+public:
+ virtual const char* name() const {
+ return "ZMarkEnd";
+ }
+
+ virtual bool do_operation() {
+ ZStatTimer timer(ZPhasePauseMarkEnd);
+ ZServiceabilityMarkEndTracer tracer;
+
+ return ZHeap::heap()->mark_end();
+ }
+};
+
+class ZRelocateStartClosure : public ZOperationClosure {
+public:
+ virtual const char* name() const {
+ return "ZRelocateStart";
+ }
+
+ virtual bool needs_inactive_gc_locker() const {
+ return true;
+ }
+
+ virtual bool do_operation() {
+ ZStatTimer timer(ZPhasePauseRelocateStart);
+ ZServiceabilityRelocateStartTracer tracer;
+
+ ZHeap::heap()->relocate_start();
+ return true;
+ }
+};
+
+ZDriver::ZDriver() :
+ _gc_cycle_port(),
+ _gc_locker_port() {
+ set_name("ZDriver");
+ create_and_start();
+}
+
+bool ZDriver::vm_operation(ZOperationClosure* cl) {
+ for (;;) {
+ VM_ZOperation op(cl);
+ VMThread::execute(&op);
+ if (op.gc_locked()) {
+ // Wait for GC to become unlocked and restart the VM operation
+ ZStatTimer timer(ZCriticalPhaseGCLockerStall);
+ _gc_locker_port.wait();
+ continue;
+ }
+
+ // Notify VM operation completed
+ _gc_locker_port.ack();
+
+ return op.success();
+ }
+}
+
+void ZDriver::collect(GCCause::Cause cause) {
+ switch (cause) {
+ case GCCause::_wb_young_gc:
+ case GCCause::_wb_conc_mark:
+ case GCCause::_wb_full_gc:
+ case GCCause::_dcmd_gc_run:
+ case GCCause::_java_lang_system_gc:
+ case GCCause::_full_gc_alot:
+ case GCCause::_scavenge_alot:
+ case GCCause::_jvmti_force_gc:
+ case GCCause::_metadata_GC_clear_soft_refs:
+ // Start synchronous GC
+ _gc_cycle_port.send_sync(cause);
+ break;
+
+ case GCCause::_z_timer:
+ case GCCause::_z_warmup:
+ case GCCause::_z_allocation_rate:
+ case GCCause::_z_allocation_stall:
+ case GCCause::_z_proactive:
+ case GCCause::_metadata_GC_threshold:
+ // Start asynchronous GC
+ _gc_cycle_port.send_async(cause);
+ break;
+
+ case GCCause::_gc_locker:
+ // Restart VM operation previously blocked by the GC locker
+ _gc_locker_port.signal();
+ break;
+
+ default:
+ // Other causes not supported
+ fatal("Unsupported GC cause (%s)", GCCause::to_string(cause));
+ break;
+ }
+}
+
+GCCause::Cause ZDriver::start_gc_cycle() {
+ // Wait for GC request
+ return _gc_cycle_port.receive();
+}
+
+class ZSoftReferencePolicyScope : public StackObj {
+private:
+ bool should_clear_soft_reference(GCCause::Cause cause) const {
+ const bool clear = ZCollectedHeap::heap()->soft_ref_policy()->should_clear_all_soft_refs();
+
+ // Clear all soft reference if the policy says so, or if
+ // the GC cause indicates that we're running low on memory.
+ return clear ||
+ cause == GCCause::_z_allocation_stall ||
+ cause == GCCause::_metadata_GC_clear_soft_refs;
+ }
+
+ void clear_should_clear_soft_reference() const {
+ ZCollectedHeap::heap()->soft_ref_policy()->set_should_clear_all_soft_refs(false);
+ }
+
+public:
+ ZSoftReferencePolicyScope(GCCause::Cause cause) {
+ const bool clear = should_clear_soft_reference(cause);
+ ZHeap::heap()->set_soft_reference_policy(clear);
+ clear_should_clear_soft_reference();
+ }
+
+ ~ZSoftReferencePolicyScope() {
+ Universe::update_heap_info_at_gc();
+ }
+};
+
+class ZDriverCycleScope : public StackObj {
+private:
+ GCIdMark _gc_id;
+ GCCauseSetter _gc_cause_setter;
+ ZSoftReferencePolicyScope _soft_ref_policy;
+ ZStatTimer _timer;
+
+ bool should_boost_worker_threads(GCCause::Cause cause) const {
+ return cause == GCCause::_java_lang_system_gc ||
+ cause == GCCause::_z_allocation_stall;
+ }
+
+public:
+ ZDriverCycleScope(GCCause::Cause cause) :
+ _gc_id(),
+ _gc_cause_setter(ZCollectedHeap::heap(), cause),
+ _soft_ref_policy(cause),
+ _timer(ZPhaseCycle) {
+ // Update statistics
+ ZStatCycle::at_start();
+
+ // Set boost mode
+ const bool boost = should_boost_worker_threads(cause);
+ ZHeap::heap()->set_boost_worker_threads(boost);
+ }
+
+ ~ZDriverCycleScope() {
+ // Calculate boost factor
+ const double boost_factor = (double)ZHeap::heap()->nconcurrent_worker_threads() /
+ (double)ZHeap::heap()->nconcurrent_no_boost_worker_threads();
+
+ // Update statistics
+ ZStatCycle::at_end(boost_factor);
+ }
+};
+
+void ZDriver::run_gc_cycle(GCCause::Cause cause) {
+ ZDriverCycleScope scope(cause);
+
+ // Phase 1: Pause Mark Start
+ {
+ ZMarkStartClosure cl;
+ vm_operation(&cl);
+ }
+
+ // Phase 2: Concurrent Mark
+ {
+ ZStatTimer timer(ZPhaseConcurrentMark);
+ ZHeap::heap()->mark();
+ }
+
+ // Phase 3: Pause Mark End
+ {
+ ZMarkEndClosure cl;
+ while (!vm_operation(&cl)) {
+ // Phase 3.5: Concurrent Mark Continue
+ ZStatTimer timer(ZPhaseConcurrentMarkContinue);
+ ZHeap::heap()->mark();
+ }
+ }
+
+ // Phase 4: Concurrent Process Non-Strong References
+ {
+ ZStatTimer timer(ZPhaseConcurrentProcessNonStrongReferences);
+ ZHeap::heap()->process_non_strong_references();
+ }
+
+ // Phase 5: Concurrent Reset Relocation Set
+ {
+ ZStatTimer timer(ZPhaseConcurrentResetRelocationSet);
+ ZHeap::heap()->reset_relocation_set();
+ }
+
+ // Phase 6: Concurrent Destroy Detached Pages
+ {
+ ZStatTimer timer(ZPhaseConcurrentDestroyDetachedPages);
+ ZHeap::heap()->destroy_detached_pages();
+ }
+
+ // Phase 7: Concurrent Select Relocation Set
+ {
+ ZStatTimer timer(ZPhaseConcurrentSelectRelocationSet);
+ ZHeap::heap()->select_relocation_set();
+ }
+
+ // Phase 8: Prepare Relocation Set
+ {
+ ZStatTimer timer(ZPhaseConcurrentPrepareRelocationSet);
+ ZHeap::heap()->prepare_relocation_set();
+ }
+
+ // Phase 9: Pause Relocate Start
+ {
+ ZRelocateStartClosure cl;
+ vm_operation(&cl);
+ }
+
+ // Phase 10: Concurrent Relocate
+ {
+ ZStatTimer timer(ZPhaseConcurrentRelocated);
+ ZHeap::heap()->relocate();
+ }
+}
+
+void ZDriver::end_gc_cycle() {
+ // Notify GC cycle completed
+ _gc_cycle_port.ack();
+
+ // Check for out of memory condition
+ ZHeap::heap()->check_out_of_memory();
+}
+
+void ZDriver::run_service() {
+ // Main loop
+ while (!should_terminate()) {
+ const GCCause::Cause cause = start_gc_cycle();
+ if (cause != GCCause::_no_gc) {
+ run_gc_cycle(cause);
+ end_gc_cycle();
+ }
+ }
+}
+
+void ZDriver::stop_service() {
+ _gc_cycle_port.send_async(GCCause::_no_gc);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zDriver.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZDRIVER_HPP
+#define SHARE_GC_Z_ZDRIVER_HPP
+
+#include "gc/shared/concurrentGCThread.hpp"
+#include "gc/shared/gcCause.hpp"
+#include "gc/z/zMessagePort.hpp"
+
+class ZOperationClosure;
+
+class ZDriver : public ConcurrentGCThread {
+private:
+ ZMessagePort<GCCause::Cause> _gc_cycle_port;
+ ZRendezvousPort _gc_locker_port;
+
+ bool vm_operation(ZOperationClosure* cl);
+
+ GCCause::Cause start_gc_cycle();
+ void run_gc_cycle(GCCause::Cause cause);
+ void end_gc_cycle();
+
+protected:
+ virtual void run_service();
+ virtual void stop_service();
+
+public:
+ ZDriver();
+
+ void collect(GCCause::Cause cause);
+};
+
+#endif // SHARE_GC_Z_ZDRIVER_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zErrno.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015, 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 "gc/z/zErrno.hpp"
+
+#include <errno.h>
+#include <string.h>
+
+ZErrno::ZErrno() :
+ _error(errno) {}
+
+ZErrno::ZErrno(int error) :
+ _error(error) {}
+
+ZErrno::operator bool() const {
+ return _error != 0;
+}
+
+bool ZErrno::operator==(int error) const {
+ return _error == error;
+}
+
+bool ZErrno::operator!=(int error) const {
+ return _error != error;
+}
+
+const char* ZErrno::to_string() const {
+ return strerror(_error);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zErrno.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZERRNO_HPP
+#define SHARE_GC_Z_ZERRNO_HPP
+
+#include "memory/allocation.hpp"
+
+class ZErrno : public StackObj {
+private:
+ const int _error;
+
+public:
+ ZErrno();
+ ZErrno(int error);
+
+ operator bool() const;
+ bool operator==(int error) const;
+ bool operator!=(int error) const;
+ const char* to_string() const;
+};
+
+#endif // SHARE_GC_Z_ZERRNO_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zForwardingTable.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2015, 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 "gc/z/zForwardingTable.inline.hpp"
+#include "gc/z/zUtils.inline.hpp"
+#include "memory/allocation.inline.hpp"
+#include "utilities/debug.hpp"
+
+void ZForwardingTable::setup(size_t live_objects) {
+ assert(is_null(), "Should be empty");
+ assert(live_objects > 0, "Invalid size");
+
+ // Allocate table for linear probing. The size of the table must be
+ // a power of two to allow for quick and inexpensive indexing/masking.
+ // The table is sized to have a load factor of 50%, i.e. sized to have
+ // double the number of entries actuallly inserted.
+ _size = ZUtils::round_up_power_of_2(live_objects * 2);
+ _table = MallocArrayAllocator<ZForwardingTableEntry>::allocate(_size, mtGC);
+
+ // Clear table
+ memset(_table, ZForwardingTableEntry::empty(), _size * sizeof(ZForwardingTableEntry));
+}
+
+void ZForwardingTable::reset() {
+ // Free table
+ MallocArrayAllocator<ZForwardingTableEntry>::free(_table);
+ _table = NULL;
+ _size = 0;
+}
+
+void ZForwardingTable::verify(size_t object_max_count, size_t live_objects) const {
+ size_t count = 0;
+
+ for (size_t i = 0; i < _size; i++) {
+ const ZForwardingTableEntry entry = _table[i];
+ if (entry.is_empty()) {
+ // Skip empty entries
+ continue;
+ }
+
+ // Check from index
+ guarantee(entry.from_index() < object_max_count, "Invalid from index");
+
+ // Check for duplicates
+ for (size_t j = i + 1; j < _size; j++) {
+ const ZForwardingTableEntry other = _table[j];
+ guarantee(entry.from_index() != other.from_index(), "Duplicate from");
+ guarantee(entry.to_offset() != other.to_offset(), "Duplicate to");
+ }
+
+ count++;
+ }
+
+ // Check number of non-null entries
+ guarantee(live_objects == count, "Count mismatch");
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zForwardingTable.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,59 @@
+/*
+ * 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_GC_Z_ZFORWARDING_HPP
+#define SHARE_GC_Z_ZFORWARDING_HPP
+
+#include "gc/z/zForwardingTableEntry.hpp"
+#include "memory/allocation.hpp"
+
+typedef size_t ZForwardingTableCursor;
+
+class ZForwardingTable {
+ friend class VMStructs;
+ friend class ZForwardingTableTest;
+
+private:
+ ZForwardingTableEntry* _table;
+ size_t _size;
+
+ ZForwardingTableEntry at(ZForwardingTableCursor* cursor) const;
+ ZForwardingTableEntry first(uintptr_t from_index, ZForwardingTableCursor* cursor) const;
+ ZForwardingTableEntry next(ZForwardingTableCursor* cursor) const;
+
+public:
+ ZForwardingTable();
+ ~ZForwardingTable();
+
+ bool is_null() const;
+ void setup(size_t live_objects);
+ void reset();
+
+ ZForwardingTableEntry find(uintptr_t from_index) const;
+ ZForwardingTableEntry find(uintptr_t from_index, ZForwardingTableCursor* cursor) const;
+ uintptr_t insert(uintptr_t from_index, uintptr_t to_offset, ZForwardingTableCursor* cursor);
+
+ void verify(size_t object_max_count, size_t live_objects) const;
+};
+
+#endif // SHARE_GC_Z_ZFORWARDING_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zForwardingTable.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZFORWARDING_INLINE_HPP
+#define SHARE_GC_Z_ZFORWARDING_INLINE_HPP
+
+#include "gc/z/zForwardingTable.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zHash.inline.hpp"
+#include "runtime/atomic.hpp"
+#include "utilities/debug.hpp"
+
+inline ZForwardingTable::ZForwardingTable() :
+ _table(NULL),
+ _size(0) {}
+
+inline ZForwardingTable::~ZForwardingTable() {
+ assert(is_null(), "Should be empty");
+}
+
+inline ZForwardingTableEntry ZForwardingTable::at(ZForwardingTableCursor* cursor) const {
+ return _table[*cursor];
+}
+
+inline ZForwardingTableEntry ZForwardingTable::first(uintptr_t from_index, ZForwardingTableCursor* cursor) const {
+ const size_t mask = _size - 1;
+ const size_t hash = ZHash::uint32_to_uint32((uint32_t)from_index);
+ *cursor = hash & mask;
+ return at(cursor);
+}
+
+inline ZForwardingTableEntry ZForwardingTable::next(ZForwardingTableCursor* cursor) const {
+ const size_t mask = _size - 1;
+ *cursor = (*cursor + 1) & mask;
+ return at(cursor);
+}
+
+inline bool ZForwardingTable::is_null() const {
+ return _table == NULL;
+}
+
+inline ZForwardingTableEntry ZForwardingTable::find(uintptr_t from_index) const {
+ ZForwardingTableCursor dummy;
+ return find(from_index, &dummy);
+}
+
+inline ZForwardingTableEntry ZForwardingTable::find(uintptr_t from_index, ZForwardingTableCursor* cursor) const {
+ // Reading entries in the table races with the atomic cas done for
+ // insertion into the table. This is safe because each entry is at
+ // most updated once (from -1 to something else).
+ ZForwardingTableEntry entry = first(from_index, cursor);
+ while (!entry.is_empty()) {
+ if (entry.from_index() == from_index) {
+ // Match found, return matching entry
+ return entry;
+ }
+
+ entry = next(cursor);
+ }
+
+ // Match not found, return empty entry
+ return entry;
+}
+
+inline uintptr_t ZForwardingTable::insert(uintptr_t from_index, uintptr_t to_offset, ZForwardingTableCursor* cursor) {
+ const ZForwardingTableEntry new_entry(from_index, to_offset);
+ const ZForwardingTableEntry old_entry; // empty
+
+ for (;;) {
+ const ZForwardingTableEntry prev_entry = Atomic::cmpxchg(new_entry, _table + *cursor, old_entry);
+ if (prev_entry.is_empty()) {
+ // Success
+ return to_offset;
+ }
+
+ // Find next empty or matching entry
+ ZForwardingTableEntry entry = at(cursor);
+ while (!entry.is_empty()) {
+ if (entry.from_index() == from_index) {
+ // Match found, return already inserted address
+ return entry.to_offset();
+ }
+
+ entry = next(cursor);
+ }
+ }
+}
+
+#endif // SHARE_GC_Z_ZFORWARDING_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zForwardingTableEntry.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef SHARE_GC_Z_ZFORWARDINGTABLEENTRY_HPP
+#define SHARE_GC_Z_ZFORWARDINGTABLEENTRY_HPP
+
+#include "gc/z/zBitField.hpp"
+#include "memory/allocation.hpp"
+#include "metaprogramming/primitiveConversions.hpp"
+
+//
+// Forwarding table entry layout
+// -----------------------------
+//
+// 6 4 4 0
+// 3 2 1 0
+// +------------------------+-----------------------------------------------+
+// |11111111 11111111 111111|11 11111111 11111111 11111111 11111111 11111111|
+// +------------------------+-----------------------------------------------+
+// | |
+// | * 41-0 To Object Offset (42-bits)
+// |
+// * 63-42 From Object Index (22-bits)
+//
+
+class ZForwardingTableEntry {
+ friend struct PrimitiveConversions;
+
+private:
+ typedef ZBitField<uint64_t, size_t, 0, 42> field_to_offset;
+ typedef ZBitField<uint64_t, size_t, 42, 22> field_from_index;
+
+ uint64_t _entry;
+
+public:
+ ZForwardingTableEntry() :
+ _entry(empty()) {}
+
+ ZForwardingTableEntry(size_t from_index, size_t to_offset) :
+ _entry(field_from_index::encode(from_index) |
+ field_to_offset::encode(to_offset)) {}
+
+ static uintptr_t empty() {
+ return (uintptr_t)-1;
+ }
+
+ bool is_empty() const {
+ return _entry == empty();
+ }
+
+ size_t to_offset() const {
+ return field_to_offset::decode(_entry);
+ }
+
+ size_t from_index() const {
+ return field_from_index::decode(_entry);
+ }
+};
+
+// Needed to allow atomic operations on ZForwardingTableEntry
+template <>
+struct PrimitiveConversions::Translate<ZForwardingTableEntry> : public TrueType {
+ typedef ZForwardingTableEntry Value;
+ typedef uint64_t Decayed;
+
+ static Decayed decay(Value v) {
+ return v._entry;
+ }
+
+ static Value recover(Decayed d) {
+ ZForwardingTableEntry entry;
+ entry._entry = d;
+ return entry;
+ }
+};
+
+#endif // SHARE_GC_Z_ZFORWARDINGTABLEENTRY_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zFuture.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZFUTURE_HPP
+#define SHARE_GC_Z_ZFUTURE_HPP
+
+#include "memory/allocation.hpp"
+#include "runtime/semaphore.hpp"
+
+template <typename T>
+class ZFuture {
+private:
+ Semaphore _sema;
+ T _value;
+
+public:
+ void set(T value);
+ T get();
+};
+
+#endif // SHARE_GC_Z_ZFUTURE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zFuture.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZFUTURE_INLINE_HPP
+#define SHARE_GC_Z_ZFUTURE_INLINE_HPP
+
+#include "gc/z/zFuture.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
+#include "runtime/semaphore.inline.hpp"
+#include "runtime/thread.hpp"
+
+template <typename T>
+inline void ZFuture<T>::set(T value) {
+ // Set value
+ _value = value;
+
+ // Notify waiter
+ _sema.signal();
+}
+
+template <typename T>
+inline T ZFuture<T>::get() {
+ // Wait for notification
+ Thread* const thread = Thread::current();
+ if (thread->is_Java_thread()) {
+ _sema.wait_with_safepoint_check((JavaThread*)thread);
+ } else {
+ _sema.wait();
+ }
+
+ // Return value
+ return _value;
+}
+
+#endif // SHARE_GC_Z_ZFUTURE_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zGlobals.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015, 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 "gc/z/zGlobals.hpp"
+
+uint32_t ZGlobalPhase = ZPhaseRelocate;
+uint32_t ZGlobalSeqNum = 1;
+
+const int& ZObjectAlignmentSmallShift = LogMinObjAlignmentInBytes;
+const int& ZObjectAlignmentSmall = MinObjAlignmentInBytes;
+
+uintptr_t ZAddressGoodMask;
+uintptr_t ZAddressBadMask = 0;
+uintptr_t ZAddressWeakBadMask;
+
+uintptr_t ZAddressMetadataMarked;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zGlobals.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,155 @@
+/*
+ * 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_GC_Z_ZGLOBALS_HPP
+#define SHARE_GC_Z_ZGLOBALS_HPP
+
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/macros.hpp"
+#include OS_CPU_HEADER(gc/z/zGlobals)
+
+// Collector name
+const char* const ZGCName = "The Z Garbage Collector";
+
+// Global phase state
+extern uint32_t ZGlobalPhase;
+const uint32_t ZPhaseMark = 0;
+const uint32_t ZPhaseMarkCompleted = 1;
+const uint32_t ZPhaseRelocate = 2;
+
+// Global sequence number
+extern uint32_t ZGlobalSeqNum;
+
+// Page types
+const uint8_t ZPageTypeSmall = 0;
+const uint8_t ZPageTypeMedium = 1;
+const uint8_t ZPageTypeLarge = 2;
+
+// Page size shifts
+const size_t ZPageSizeSmallShift = ZPlatformPageSizeSmallShift;
+const size_t ZPageSizeMediumShift = ZPageSizeSmallShift + 4;
+const size_t ZPageSizeMinShift = ZPageSizeSmallShift;
+
+// Page sizes
+const size_t ZPageSizeSmall = (size_t)1 << ZPageSizeSmallShift;
+const size_t ZPageSizeMedium = (size_t)1 << ZPageSizeMediumShift;
+const size_t ZPageSizeMin = (size_t)1 << ZPageSizeMinShift;
+
+// Object size limits
+const size_t ZObjectSizeLimitSmall = (ZPageSizeSmall / 8); // Allow 12.5% waste
+const size_t ZObjectSizeLimitMedium = (ZPageSizeMedium / 8); // Allow 12.5% waste
+
+// Object alignment shifts
+extern const int& ZObjectAlignmentSmallShift;
+const int ZObjectAlignmentMediumShift = ZPageSizeMediumShift - 13; // 8192 objects per page
+const int ZObjectAlignmentLargeShift = ZPageSizeSmallShift;
+
+// Object alignments
+extern const int& ZObjectAlignmentSmall;
+const int ZObjectAlignmentMedium = 1 << ZObjectAlignmentMediumShift;
+const int ZObjectAlignmentLarge = 1 << ZObjectAlignmentLargeShift;
+
+// Pointer part of address
+const uintptr_t ZAddressOffsetShift = 0;
+const uintptr_t ZAddressOffsetBits = ZPlatformAddressOffsetBits;
+const uintptr_t ZAddressOffsetMask = (((uintptr_t)1 << ZAddressOffsetBits) - 1) << ZAddressOffsetShift;
+const size_t ZAddressOffsetMax = (uintptr_t)1 << ZAddressOffsetBits;
+
+// Metadata part of address
+const uintptr_t ZAddressMetadataShift = ZPlatformAddressMetadataShift;
+const uintptr_t ZAddressMetadataBits = 4;
+const uintptr_t ZAddressMetadataMask = (((uintptr_t)1 << ZAddressMetadataBits) - 1) << ZAddressMetadataShift;
+
+// Metadata types
+const uintptr_t ZAddressMetadataMarked0 = (uintptr_t)1 << (ZAddressMetadataShift + 0);
+const uintptr_t ZAddressMetadataMarked1 = (uintptr_t)1 << (ZAddressMetadataShift + 1);
+const uintptr_t ZAddressMetadataRemapped = (uintptr_t)1 << (ZAddressMetadataShift + 2);
+const uintptr_t ZAddressMetadataFinalizable = (uintptr_t)1 << (ZAddressMetadataShift + 3);
+
+// Address space start/end/size
+const uintptr_t ZAddressSpaceStart = ZPlatformAddressSpaceStart;
+const uintptr_t ZAddressSpaceSize = ZPlatformAddressSpaceSize;
+const uintptr_t ZAddressSpaceEnd = ZAddressSpaceStart + ZAddressSpaceSize;
+
+// Cache line size
+const size_t ZCacheLineSize = ZPlatformCacheLineSize;
+
+// Reserved start/end
+uintptr_t ZAddressReservedStart();
+uintptr_t ZAddressReservedEnd();
+
+//
+// Good/Bad mask states
+// --------------------
+//
+// GoodMask BadMask WeakGoodMask WeakBadMask
+// --------------------------------------------------------------
+// Marked0 001 110 101 010
+// Marked1 010 101 110 001
+// Remapped 100 011 100 011
+//
+
+// Good/bad masks
+extern uintptr_t ZAddressGoodMask;
+extern uintptr_t ZAddressBadMask;
+extern uintptr_t ZAddressWeakBadMask;
+
+// Marked state
+extern uintptr_t ZAddressMetadataMarked;
+
+// Address space for mark stack allocations
+const size_t ZMarkStackSpaceSizeShift = 40; // 1TB
+const size_t ZMarkStackSpaceSize = (size_t)1 << ZMarkStackSpaceSizeShift;
+const uintptr_t ZMarkStackSpaceStart = ZAddressSpaceEnd + ZMarkStackSpaceSize;
+const uintptr_t ZMarkStackSpaceEnd = ZMarkStackSpaceStart + ZMarkStackSpaceSize;
+const size_t ZMarkStackSpaceExpandSize = (size_t)1 << 25; // 32M
+
+// Mark stack and magazine sizes
+const size_t ZMarkStackSizeShift = 11; // 2K
+const size_t ZMarkStackSize = (size_t)1 << ZMarkStackSizeShift;
+const size_t ZMarkStackHeaderSize = (size_t)1 << 4; // 16B
+const size_t ZMarkStackSlots = (ZMarkStackSize - ZMarkStackHeaderSize) / sizeof(uintptr_t);
+const size_t ZMarkStackMagazineSize = (size_t)1 << 15; // 32K
+const size_t ZMarkStackMagazineSlots = (ZMarkStackMagazineSize / ZMarkStackSize) - 1;
+
+// Mark stripe size
+const size_t ZMarkStripeShift = ZPageSizeMinShift;
+
+// Max number of mark stripes
+const size_t ZMarkStripesMax = 16; // Must be a power of two
+
+// Mark cache size
+const size_t ZMarkCacheSize = 1024; // Must be a power of two
+
+// Partial array minimum size
+const size_t ZMarkPartialArrayMinSizeShift = 12; // 4K
+const size_t ZMarkPartialArrayMinSize = (size_t)1 << ZMarkPartialArrayMinSizeShift;
+
+// Max number of proactive/terminate flush attempts
+const size_t ZMarkProactiveFlushMax = 10;
+const size_t ZMarkTerminateFlushMax = 3;
+
+// Try complete mark timeout
+const uint64_t ZMarkCompleteTimeout = 1; // ms
+
+#endif // SHARE_GC_Z_ZGLOBALS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zHash.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZHASH_HPP
+#define SHARE_GC_Z_ZHASH_HPP
+
+#include "memory/allocation.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class ZHash : public AllStatic {
+public:
+ static uint32_t uint32_to_uint32(uint32_t key);
+ static uint32_t address_to_uint32(uintptr_t key);
+};
+
+#endif // SHARE_GC_Z_ZHASH_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zHash.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZHASH_INLINE_HPP
+#define SHARE_GC_Z_ZHASH_INLINE_HPP
+
+#include "gc/z/zHash.hpp"
+
+inline uint32_t ZHash::uint32_to_uint32(uint32_t key) {
+ key = ~key + (key << 15);
+ key = key ^ (key >> 12);
+ key = key + (key << 2);
+ key = key ^ (key >> 4);
+ key = key * 2057;
+ key = key ^ (key >> 16);
+ return key;
+}
+
+inline uint32_t ZHash::address_to_uint32(uintptr_t key) {
+ return uint32_to_uint32((uint32_t)(key >> 3));
+}
+
+#endif // SHARE_GC_Z_ZHASH_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zHeap.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,583 @@
+/*
+ * 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 "gc/shared/oopStorage.hpp"
+#include "gc/z/zAddress.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zHeap.inline.hpp"
+#include "gc/z/zHeapIterator.hpp"
+#include "gc/z/zList.inline.hpp"
+#include "gc/z/zLock.inline.hpp"
+#include "gc/z/zMark.inline.hpp"
+#include "gc/z/zOopClosures.inline.hpp"
+#include "gc/z/zPage.inline.hpp"
+#include "gc/z/zPageTable.inline.hpp"
+#include "gc/z/zRelocationSet.inline.hpp"
+#include "gc/z/zResurrection.hpp"
+#include "gc/z/zRootsIterator.hpp"
+#include "gc/z/zStat.hpp"
+#include "gc/z/zTask.hpp"
+#include "gc/z/zThread.hpp"
+#include "gc/z/zTracer.inline.hpp"
+#include "gc/z/zVirtualMemory.inline.hpp"
+#include "gc/z/zWorkers.inline.hpp"
+#include "logging/log.hpp"
+#include "memory/resourceArea.hpp"
+#include "oops/oop.inline.hpp"
+#include "runtime/safepoint.hpp"
+#include "runtime/thread.hpp"
+#include "utilities/align.hpp"
+#include "utilities/debug.hpp"
+
+static const ZStatSampler ZSamplerHeapUsedBeforeMark("Memory", "Heap Used Before Mark", ZStatUnitBytes);
+static const ZStatSampler ZSamplerHeapUsedAfterMark("Memory", "Heap Used After Mark", ZStatUnitBytes);
+static const ZStatSampler ZSamplerHeapUsedBeforeRelocation("Memory", "Heap Used Before Relocation", ZStatUnitBytes);
+static const ZStatSampler ZSamplerHeapUsedAfterRelocation("Memory", "Heap Used After Relocation", ZStatUnitBytes);
+static const ZStatCounter ZCounterUndoPageAllocation("Memory", "Undo Page Allocation", ZStatUnitOpsPerSecond);
+static const ZStatCounter ZCounterOutOfMemory("Memory", "Out Of Memory", ZStatUnitOpsPerSecond);
+
+ZHeap* ZHeap::_heap = NULL;
+
+ZHeap::ZHeap() :
+ _workers(),
+ _object_allocator(_workers.nworkers()),
+ _page_allocator(heap_min_size(), heap_max_size(), heap_max_reserve_size()),
+ _pagetable(),
+ _mark(&_workers, &_pagetable),
+ _reference_processor(&_workers),
+ _weak_roots_processor(&_workers),
+ _relocate(&_workers),
+ _relocation_set(),
+ _serviceability(heap_min_size(), heap_max_size()) {
+ // Install global heap instance
+ assert(_heap == NULL, "Already initialized");
+ _heap = this;
+
+ // Update statistics
+ ZStatHeap::set_at_initialize(heap_max_size(), heap_max_reserve_size());
+}
+
+size_t ZHeap::heap_min_size() const {
+ const size_t aligned_min_size = align_up(InitialHeapSize, ZPageSizeMin);
+ return MIN2(aligned_min_size, heap_max_size());
+}
+
+size_t ZHeap::heap_max_size() const {
+ const size_t aligned_max_size = align_up(MaxHeapSize, ZPageSizeMin);
+ return MIN2(aligned_max_size, ZAddressOffsetMax);
+}
+
+size_t ZHeap::heap_max_reserve_size() const {
+ // Reserve one small page per worker plus one shared medium page. This is still just
+ // an estimate and doesn't guarantee that we can't run out of memory during relocation.
+ const size_t max_reserve_size = (_workers.nworkers() * ZPageSizeSmall) + ZPageSizeMedium;
+ return MIN2(max_reserve_size, heap_max_size());
+}
+
+bool ZHeap::is_initialized() const {
+ return _page_allocator.is_initialized();
+}
+
+size_t ZHeap::min_capacity() const {
+ return heap_min_size();
+}
+
+size_t ZHeap::max_capacity() const {
+ return _page_allocator.max_capacity();
+}
+
+size_t ZHeap::capacity() const {
+ return _page_allocator.capacity();
+}
+
+size_t ZHeap::max_reserve() const {
+ return _page_allocator.max_reserve();
+}
+
+size_t ZHeap::used_high() const {
+ return _page_allocator.used_high();
+}
+
+size_t ZHeap::used_low() const {
+ return _page_allocator.used_low();
+}
+
+size_t ZHeap::used() const {
+ return _page_allocator.used();
+}
+
+size_t ZHeap::allocated() const {
+ return _page_allocator.allocated();
+}
+
+size_t ZHeap::reclaimed() const {
+ return _page_allocator.reclaimed();
+}
+
+size_t ZHeap::tlab_capacity() const {
+ return capacity();
+}
+
+size_t ZHeap::tlab_used() const {
+ return _object_allocator.used();
+}
+
+size_t ZHeap::max_tlab_size() const {
+ return ZObjectSizeLimitSmall;
+}
+
+size_t ZHeap::unsafe_max_tlab_alloc() const {
+ size_t size = _object_allocator.remaining();
+
+ if (size < MinTLABSize) {
+ // The remaining space in the allocator is not enough to
+ // fit the smallest possible TLAB. This means that the next
+ // TLAB allocation will force the allocator to get a new
+ // backing page anyway, which in turn means that we can then
+ // fit the larges possible TLAB.
+ size = max_tlab_size();
+ }
+
+ return MIN2(size, max_tlab_size());
+}
+
+bool ZHeap::is_in(uintptr_t addr) const {
+ if (addr < ZAddressReservedStart() || addr >= ZAddressReservedEnd()) {
+ return false;
+ }
+
+ const ZPage* const page = _pagetable.get(addr);
+ if (page != NULL) {
+ return page->is_in(addr);
+ }
+
+ return false;
+}
+
+uintptr_t ZHeap::block_start(uintptr_t addr) const {
+ const ZPage* const page = _pagetable.get(addr);
+ return page->block_start(addr);
+}
+
+size_t ZHeap::block_size(uintptr_t addr) const {
+ const ZPage* const page = _pagetable.get(addr);
+ return page->block_size(addr);
+}
+
+bool ZHeap::block_is_obj(uintptr_t addr) const {
+ const ZPage* const page = _pagetable.get(addr);
+ return page->block_is_obj(addr);
+}
+
+uint ZHeap::nconcurrent_worker_threads() const {
+ return _workers.nconcurrent();
+}
+
+uint ZHeap::nconcurrent_no_boost_worker_threads() const {
+ return _workers.nconcurrent_no_boost();
+}
+
+void ZHeap::set_boost_worker_threads(bool boost) {
+ _workers.set_boost(boost);
+}
+
+void ZHeap::worker_threads_do(ThreadClosure* tc) const {
+ _workers.threads_do(tc);
+}
+
+void ZHeap::print_worker_threads_on(outputStream* st) const {
+ _workers.print_threads_on(st);
+}
+
+void ZHeap::out_of_memory() {
+ ResourceMark rm;
+
+ ZStatInc(ZCounterOutOfMemory);
+ log_info(gc)("Out Of Memory (%s)", Thread::current()->name());
+}
+
+ZPage* ZHeap::alloc_page(uint8_t type, size_t size, ZAllocationFlags flags) {
+ ZPage* const page = _page_allocator.alloc_page(type, size, flags);
+ if (page != NULL) {
+ // Update pagetable
+ _pagetable.insert(page);
+ }
+
+ return page;
+}
+
+void ZHeap::undo_alloc_page(ZPage* page) {
+ assert(page->is_allocating(), "Invalid page state");
+
+ ZStatInc(ZCounterUndoPageAllocation);
+ log_trace(gc)("Undo page allocation, thread: " PTR_FORMAT " (%s), page: " PTR_FORMAT ", size: " SIZE_FORMAT,
+ ZThread::id(), ZThread::name(), p2i(page), page->size());
+
+ release_page(page, false /* reclaimed */);
+}
+
+bool ZHeap::retain_page(ZPage* page) {
+ return page->inc_refcount();
+}
+
+void ZHeap::release_page(ZPage* page, bool reclaimed) {
+ if (page->dec_refcount()) {
+ _page_allocator.free_page(page, reclaimed);
+ }
+}
+
+void ZHeap::flip_views() {
+ // For debugging only
+ if (ZUnmapBadViews) {
+ // Flip pages
+ ZPageTableIterator iter(&_pagetable);
+ for (ZPage* page; iter.next(&page);) {
+ if (!page->is_detached()) {
+ _page_allocator.flip_page(page);
+ }
+ }
+
+ // Flip pre-mapped memory
+ _page_allocator.flip_pre_mapped();
+ }
+}
+
+void ZHeap::mark_start() {
+ assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
+
+ // Update statistics
+ ZStatSample(ZSamplerHeapUsedBeforeMark, used());
+
+ // Retire TLABs
+ _object_allocator.retire_tlabs();
+
+ // Flip address view
+ ZAddressMasks::flip_to_marked();
+ flip_views();
+
+ // Reset allocated/reclaimed/used statistics
+ _page_allocator.reset_statistics();
+
+ // Reset encountered/dropped/enqueued statistics
+ _reference_processor.reset_statistics();
+
+ // Enter mark phase
+ ZGlobalPhase = ZPhaseMark;
+
+ // Reset marking information and mark roots
+ _mark.start();
+
+ // Update statistics
+ ZStatHeap::set_at_mark_start(capacity(), used());
+}
+
+void ZHeap::mark() {
+ _mark.mark();
+}
+
+void ZHeap::mark_flush_and_free(Thread* thread) {
+ _mark.flush_and_free(thread);
+}
+
+class ZFixupPartialLoadsTask : public ZTask {
+private:
+ ZThreadRootsIterator _thread_roots;
+
+public:
+ ZFixupPartialLoadsTask() :
+ ZTask("ZFixupPartialLoadsTask"),
+ _thread_roots() {}
+
+ virtual void work() {
+ ZMarkRootOopClosure cl;
+ _thread_roots.oops_do(&cl);
+ }
+};
+
+void ZHeap::fixup_partial_loads() {
+ ZFixupPartialLoadsTask task;
+ _workers.run_parallel(&task);
+}
+
+bool ZHeap::mark_end() {
+ assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
+
+ // C2 can generate code where a safepoint poll is inserted
+ // between a load and the associated load barrier. To handle
+ // this case we need to rescan the thread stack here to make
+ // sure such oops are marked.
+ fixup_partial_loads();
+
+ // Try end marking
+ if (!_mark.end()) {
+ // Marking not completed, continue concurrent mark
+ return false;
+ }
+
+ // Enter mark completed phase
+ ZGlobalPhase = ZPhaseMarkCompleted;
+
+ // Resize metaspace
+ MetaspaceGC::compute_new_size();
+
+ // Update statistics
+ ZStatSample(ZSamplerHeapUsedAfterMark, used());
+ ZStatHeap::set_at_mark_end(capacity(), allocated(), used());
+
+ // Block resurrection of weak/phantom references
+ ZResurrection::block();
+
+ // Process weak roots
+ _weak_roots_processor.process_weak_roots();
+
+ // Verification
+ if (VerifyBeforeGC || VerifyDuringGC || VerifyAfterGC) {
+ Universe::verify();
+ }
+
+ return true;
+}
+
+void ZHeap::set_soft_reference_policy(bool clear) {
+ _reference_processor.set_soft_reference_policy(clear);
+}
+
+void ZHeap::process_non_strong_references() {
+ // Process Soft/Weak/Final/PhantomReferences
+ _reference_processor.process_references();
+
+ // Process concurrent weak roots
+ _weak_roots_processor.process_concurrent_weak_roots();
+
+ // Unblock resurrection of weak/phantom references
+ ZResurrection::unblock();
+
+ // Enqueue Soft/Weak/Final/PhantomReferences. Note that this
+ // must be done after unblocking resurrection. Otherwise the
+ // Finalizer thread could call Reference.get() on the Finalizers
+ // that were just enqueued, which would incorrectly return null
+ // during the resurrection block window, since such referents
+ // are only Finalizable marked.
+ _reference_processor.enqueue_references();
+}
+
+void ZHeap::destroy_detached_pages() {
+ ZList<ZPage> list;
+
+ _page_allocator.flush_detached_pages(&list);
+
+ for (ZPage* page = list.remove_first(); page != NULL; page = list.remove_first()) {
+ // Remove pagetable entry
+ _pagetable.remove(page);
+
+ // Delete the page
+ _page_allocator.destroy_page(page);
+ }
+}
+
+void ZHeap::select_relocation_set() {
+ // Register relocatable pages with selector
+ ZRelocationSetSelector selector;
+ ZPageTableIterator iter(&_pagetable);
+ for (ZPage* page; iter.next(&page);) {
+ if (!page->is_relocatable()) {
+ // Not relocatable, don't register
+ continue;
+ }
+
+ if (page->is_marked()) {
+ // Register live page
+ selector.register_live_page(page);
+ } else {
+ // Register garbage page
+ selector.register_garbage_page(page);
+
+ // Reclaim page immediately
+ release_page(page, true /* reclaimed */);
+ }
+ }
+
+ // Select pages to relocate
+ selector.select(&_relocation_set);
+
+ // Update statistics
+ ZStatRelocation::set_at_select_relocation_set(selector.relocating());
+ ZStatHeap::set_at_select_relocation_set(selector.live(),
+ selector.garbage(),
+ reclaimed());
+}
+
+void ZHeap::prepare_relocation_set() {
+ ZRelocationSetIterator iter(&_relocation_set);
+ for (ZPage* page; iter.next(&page);) {
+ // Prepare for relocation
+ page->set_forwarding();
+
+ // Update pagetable
+ _pagetable.set_relocating(page);
+ }
+}
+
+void ZHeap::reset_relocation_set() {
+ ZRelocationSetIterator iter(&_relocation_set);
+ for (ZPage* page; iter.next(&page);) {
+ // Reset relocation information
+ page->reset_forwarding();
+
+ // Update pagetable
+ _pagetable.clear_relocating(page);
+ }
+}
+
+void ZHeap::relocate_start() {
+ assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
+
+ // Update statistics
+ ZStatSample(ZSamplerHeapUsedBeforeRelocation, used());
+
+ // Flip address view
+ ZAddressMasks::flip_to_remapped();
+ flip_views();
+
+ // Remap TLABs
+ _object_allocator.remap_tlabs();
+
+ // Enter relocate phase
+ ZGlobalPhase = ZPhaseRelocate;
+
+ // Update statistics
+ ZStatHeap::set_at_relocate_start(capacity(), allocated(), used());
+
+ // Remap/Relocate roots
+ _relocate.start();
+}
+
+uintptr_t ZHeap::relocate_object(uintptr_t addr) {
+ assert(ZGlobalPhase == ZPhaseRelocate, "Relocate not allowed");
+ ZPage* const page = _pagetable.get(addr);
+ const bool retained = retain_page(page);
+ const uintptr_t new_addr = page->relocate_object(addr);
+ if (retained) {
+ release_page(page, true /* reclaimed */);
+ }
+
+ return new_addr;
+}
+
+uintptr_t ZHeap::forward_object(uintptr_t addr) {
+ assert(ZGlobalPhase == ZPhaseMark ||
+ ZGlobalPhase == ZPhaseMarkCompleted, "Forward not allowed");
+ ZPage* const page = _pagetable.get(addr);
+ return page->forward_object(addr);
+}
+
+void ZHeap::relocate() {
+ // Relocate relocation set
+ const bool success = _relocate.relocate(&_relocation_set);
+
+ // Update statistics
+ ZStatSample(ZSamplerHeapUsedAfterRelocation, used());
+ ZStatRelocation::set_at_relocate_end(success);
+ ZStatHeap::set_at_relocate_end(capacity(), allocated(), reclaimed(),
+ used(), used_high(), used_low());
+}
+
+void ZHeap::object_iterate(ObjectClosure* cl) {
+ // Should only be called in a safepoint after mark end.
+ assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
+
+ ZHeapIterator iter;
+ iter.objects_do(cl);
+}
+
+void ZHeap::serviceability_initialize() {
+ _serviceability.initialize();
+}
+
+GCMemoryManager* ZHeap::serviceability_memory_manager() {
+ return _serviceability.memory_manager();
+}
+
+MemoryPool* ZHeap::serviceability_memory_pool() {
+ return _serviceability.memory_pool();
+}
+
+ZServiceabilityCounters* ZHeap::serviceability_counters() {
+ return _serviceability.counters();
+}
+
+void ZHeap::print_on(outputStream* st) const {
+ st->print_cr(" ZHeap used " SIZE_FORMAT "M, capacity " SIZE_FORMAT "M, max capacity " SIZE_FORMAT "M",
+ used() / M,
+ capacity() / M,
+ max_capacity() / M);
+ MetaspaceUtils::print_on(st);
+}
+
+void ZHeap::print_extended_on(outputStream* st) const {
+ print_on(st);
+ st->cr();
+
+ ZPageTableIterator iter(&_pagetable);
+ for (ZPage* page; iter.next(&page);) {
+ page->print_on(st);
+ }
+
+ st->cr();
+}
+
+class ZVerifyRootsTask : public ZTask {
+private:
+ ZRootsIterator _strong_roots;
+ ZWeakRootsIterator _weak_roots;
+
+public:
+ ZVerifyRootsTask() :
+ ZTask("ZVerifyRootsTask"),
+ _strong_roots(),
+ _weak_roots() {}
+
+ virtual void work() {
+ ZVerifyRootOopClosure cl;
+ _strong_roots.oops_do(&cl);
+ _weak_roots.oops_do(&cl);
+ }
+};
+
+void ZHeap::verify() {
+ // Heap verification can only be done between mark end and
+ // relocate start. This is the only window where all oop are
+ // good and the whole heap is in a consistent state.
+ guarantee(ZGlobalPhase == ZPhaseMarkCompleted, "Invalid phase");
+
+ {
+ ZVerifyRootsTask task;
+ _workers.run_parallel(&task);
+ }
+
+ {
+ ZVerifyObjectClosure cl;
+ object_iterate(&cl);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zHeap.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,171 @@
+/*
+ * 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_GC_Z_ZHEAP_HPP
+#define SHARE_GC_Z_ZHEAP_HPP
+
+#include "gc/shared/gcTimer.hpp"
+#include "gc/z/zAllocationFlags.hpp"
+#include "gc/z/zArray.hpp"
+#include "gc/z/zList.hpp"
+#include "gc/z/zLock.hpp"
+#include "gc/z/zMark.hpp"
+#include "gc/z/zObjectAllocator.hpp"
+#include "gc/z/zPage.hpp"
+#include "gc/z/zPageAllocator.hpp"
+#include "gc/z/zPageTable.hpp"
+#include "gc/z/zReferenceProcessor.hpp"
+#include "gc/z/zRelocate.hpp"
+#include "gc/z/zRelocationSet.hpp"
+#include "gc/z/zRelocationSetSelector.hpp"
+#include "gc/z/zRootsIterator.hpp"
+#include "gc/z/zWeakRootsProcessor.hpp"
+#include "gc/z/zServiceability.hpp"
+#include "gc/z/zWorkers.hpp"
+#include "memory/allocation.hpp"
+
+class ZHeap {
+ friend class VMStructs;
+
+private:
+ static ZHeap* _heap;
+
+ ZWorkers _workers;
+ ZObjectAllocator _object_allocator;
+ ZPageAllocator _page_allocator;
+ ZPageTable _pagetable;
+ ZMark _mark;
+ ZReferenceProcessor _reference_processor;
+ ZWeakRootsProcessor _weak_roots_processor;
+ ZRelocate _relocate;
+ ZRelocationSet _relocation_set;
+ ZServiceability _serviceability;
+
+ size_t heap_min_size() const;
+ size_t heap_max_size() const;
+ size_t heap_max_reserve_size() const;
+
+ void out_of_memory();
+ void flip_views();
+ void fixup_partial_loads();
+
+public:
+ static ZHeap* heap();
+
+ ZHeap();
+
+ bool is_initialized() const;
+
+ // Heap metrics
+ size_t min_capacity() const;
+ size_t max_capacity() const;
+ size_t capacity() const;
+ size_t max_reserve() const;
+ size_t used_high() const;
+ size_t used_low() const;
+ size_t used() const;
+ size_t allocated() const;
+ size_t reclaimed() const;
+
+ size_t tlab_capacity() const;
+ size_t tlab_used() const;
+ size_t max_tlab_size() const;
+ size_t unsafe_max_tlab_alloc() const;
+
+ bool is_in(uintptr_t addr) const;
+
+ // Block
+ uintptr_t block_start(uintptr_t addr) const;
+ size_t block_size(uintptr_t addr) const;
+ bool block_is_obj(uintptr_t addr) const;
+
+ // Workers
+ uint nconcurrent_worker_threads() const;
+ uint nconcurrent_no_boost_worker_threads() const;
+ void set_boost_worker_threads(bool boost);
+ void worker_threads_do(ThreadClosure* tc) const;
+ void print_worker_threads_on(outputStream* st) const;
+
+ // Reference processing
+ ReferenceDiscoverer* reference_discoverer();
+ void set_soft_reference_policy(bool clear);
+
+ // Non-strong reference processing
+ void process_non_strong_references();
+
+ // Page allocation
+ ZPage* alloc_page(uint8_t type, size_t size, ZAllocationFlags flags);
+ void undo_alloc_page(ZPage* page);
+ bool retain_page(ZPage* page);
+ void release_page(ZPage* page, bool reclaimed);
+
+ // Object allocation
+ uintptr_t alloc_tlab(size_t size);
+ uintptr_t alloc_object(size_t size);
+ uintptr_t alloc_object_for_relocation(size_t size);
+ void undo_alloc_object_for_relocation(uintptr_t addr, size_t size);
+ void check_out_of_memory();
+
+ // Marking
+ bool is_object_live(uintptr_t addr) const;
+ bool is_object_strongly_live(uintptr_t addr) const;
+ template <bool finalizable, bool publish> void mark_object(uintptr_t addr);
+ void mark_start();
+ void mark();
+ void mark_flush_and_free(Thread* thread);
+ bool mark_end();
+
+ // Post-marking & Pre-relocation
+ void destroy_detached_pages();
+
+ // Relocation set
+ void select_relocation_set();
+ void prepare_relocation_set();
+ void reset_relocation_set();
+
+ // Relocation
+ bool is_relocating(uintptr_t addr) const;
+ void relocate_start();
+ uintptr_t relocate_object(uintptr_t addr);
+ uintptr_t forward_object(uintptr_t addr);
+ void relocate();
+
+ // Iteration
+ void object_iterate(ObjectClosure* cl);
+
+ // Serviceability
+ void serviceability_initialize();
+ GCMemoryManager* serviceability_memory_manager();
+ MemoryPool* serviceability_memory_pool();
+ ZServiceabilityCounters* serviceability_counters();
+
+ // Printing
+ void print_on(outputStream* st) const;
+ void print_extended_on(outputStream* st) const;
+
+ // Verification
+ bool is_oop(oop object) const;
+ void verify();
+};
+
+#endif // SHARE_GC_Z_ZHEAP_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zHeap.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZHEAP_INLINE_HPP
+#define SHARE_GC_Z_ZHEAP_INLINE_HPP
+
+#include "gc/z/zAddress.inline.hpp"
+#include "gc/z/zHeap.hpp"
+#include "gc/z/zMark.inline.hpp"
+#include "gc/z/zOop.inline.hpp"
+#include "gc/z/zPage.inline.hpp"
+#include "gc/z/zPageTable.inline.hpp"
+#include "gc/z/zUtils.inline.hpp"
+#include "utilities/debug.hpp"
+
+inline ZHeap* ZHeap::heap() {
+ assert(_heap != NULL, "Not initialized");
+ return _heap;
+}
+
+inline ReferenceDiscoverer* ZHeap::reference_discoverer() {
+ return &_reference_processor;
+}
+
+inline bool ZHeap::is_relocating(uintptr_t addr) const {
+ return _pagetable.is_relocating(addr);
+}
+
+inline bool ZHeap::is_object_live(uintptr_t addr) const {
+ ZPage* page = _pagetable.get(addr);
+ return page->is_object_live(addr);
+}
+
+inline bool ZHeap::is_object_strongly_live(uintptr_t addr) const {
+ ZPage* page = _pagetable.get(addr);
+ return page->is_object_strongly_live(addr);
+}
+
+template <bool finalizable, bool publish>
+inline void ZHeap::mark_object(uintptr_t addr) {
+ assert(ZGlobalPhase == ZPhaseMark, "Mark not allowed");
+ _mark.mark_object<finalizable, publish>(addr);
+}
+
+inline uintptr_t ZHeap::alloc_tlab(size_t size) {
+ guarantee(size <= max_tlab_size(), "TLAB too large");
+ return _object_allocator.alloc_object(size);
+}
+
+inline uintptr_t ZHeap::alloc_object(size_t size) {
+ uintptr_t addr = _object_allocator.alloc_object(size);
+ assert(ZAddress::is_good_or_null(addr), "Bad address");
+
+ if (addr == 0) {
+ out_of_memory();
+ }
+
+ return addr;
+}
+
+inline uintptr_t ZHeap::alloc_object_for_relocation(size_t size) {
+ uintptr_t addr = _object_allocator.alloc_object_for_relocation(size);
+ assert(ZAddress::is_good_or_null(addr), "Bad address");
+ return addr;
+}
+
+inline void ZHeap::undo_alloc_object_for_relocation(uintptr_t addr, size_t size) {
+ ZPage* const page = _pagetable.get(addr);
+ _object_allocator.undo_alloc_object_for_relocation(page, addr, size);
+}
+
+inline void ZHeap::check_out_of_memory() {
+ _page_allocator.check_out_of_memory();
+}
+
+inline bool ZHeap::is_oop(oop object) const {
+ return ZOop::is_good(object);
+}
+
+#endif // SHARE_GC_Z_ZHEAP_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zHeapIterator.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 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 "gc/z/zAddressRangeMap.inline.hpp"
+#include "gc/z/zBarrier.inline.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zHeapIterator.hpp"
+#include "gc/z/zOop.inline.hpp"
+#include "gc/z/zRootsIterator.hpp"
+#include "oops/oop.inline.hpp"
+#include "utilities/bitMap.inline.hpp"
+#include "utilities/stack.inline.hpp"
+
+class ZHeapIteratorBitMap : public CHeapObj<mtGC> {
+private:
+ CHeapBitMap _map;
+
+public:
+ ZHeapIteratorBitMap(size_t size_in_bits) :
+ _map(size_in_bits) {}
+
+ bool try_set_bit(size_t index) {
+ if (_map.at(index)) {
+ return false;
+ }
+
+ _map.set_bit(index);
+ return true;
+ }
+};
+
+class ZHeapIteratorRootOopClosure : public OopClosure {
+private:
+ ZHeapIterator* const _iter;
+ ObjectClosure* const _cl;
+
+public:
+ ZHeapIteratorRootOopClosure(ZHeapIterator* iter, ObjectClosure* cl) :
+ _iter(iter),
+ _cl(cl) {}
+
+ virtual void do_oop(oop* p) {
+ // Load barrier needed here for the same reason we
+ // need fixup_partial_loads() in ZHeap::mark_end()
+ const oop obj = RootAccess<>::oop_load(p);
+ _iter->push(obj);
+ _iter->drain(_cl);
+ }
+
+ virtual void do_oop(narrowOop* p) {
+ ShouldNotReachHere();
+ }
+};
+
+class ZHeapIteratorPushOopClosure : public ExtendedOopClosure {
+private:
+ ZHeapIterator* const _iter;
+ const oop _base;
+
+public:
+ ZHeapIteratorPushOopClosure(ZHeapIterator* iter, oop base) :
+ _iter(iter),
+ _base(base) {}
+
+ void do_oop_nv(oop* p) {
+ const oop obj = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_load_at(_base, _base->field_offset(p));
+ _iter->push(obj);
+ }
+
+ void do_oop_nv(narrowOop* p) {
+ ShouldNotReachHere();
+ }
+
+ virtual void do_oop(oop* p) {
+ do_oop_nv(p);
+ }
+
+ virtual void do_oop(narrowOop* p) {
+ do_oop_nv(p);
+ }
+
+#ifdef ASSERT
+ virtual bool should_verify_oops() {
+ return false;
+ }
+#endif
+};
+
+ZHeapIterator::ZHeapIterator() :
+ _visit_stack(),
+ _visit_map() {}
+
+ZHeapIterator::~ZHeapIterator() {
+ ZVisitMapIterator iter(&_visit_map);
+ for (ZHeapIteratorBitMap* map; iter.next(&map);) {
+ delete map;
+ }
+}
+
+size_t ZHeapIterator::object_index_max() const {
+ return ZPageSizeMin >> ZObjectAlignmentSmallShift;
+}
+
+size_t ZHeapIterator::object_index(oop obj) const {
+ const uintptr_t addr = ZOop::to_address(obj);
+ const uintptr_t offset = ZAddress::offset(addr);
+ const uintptr_t mask = (1 << ZPageSizeMinShift) - 1;
+ return (offset & mask) >> ZObjectAlignmentSmallShift;
+}
+
+ZHeapIteratorBitMap* ZHeapIterator::object_map(oop obj) {
+ const uintptr_t addr = ZOop::to_address(obj);
+ ZHeapIteratorBitMap* map = _visit_map.get(addr);
+ if (map == NULL) {
+ map = new ZHeapIteratorBitMap(object_index_max());
+ _visit_map.put(addr, map);
+ }
+
+ return map;
+}
+
+void ZHeapIterator::push(oop obj) {
+ if (obj == NULL) {
+ // Ignore
+ return;
+ }
+
+ ZHeapIteratorBitMap* const map = object_map(obj);
+ const size_t index = object_index(obj);
+ if (!map->try_set_bit(index)) {
+ // Already pushed
+ return;
+ }
+
+ // Push
+ _visit_stack.push(obj);
+}
+
+void ZHeapIterator::drain(ObjectClosure* cl) {
+ while (!_visit_stack.is_empty()) {
+ const oop obj = _visit_stack.pop();
+
+ // Visit
+ cl->do_object(obj);
+
+ // Push members to visit
+ ZHeapIteratorPushOopClosure push_cl(this, obj);
+ obj->oop_iterate(&push_cl);
+ }
+}
+
+void ZHeapIterator::objects_do(ObjectClosure* cl) {
+ ZHeapIteratorRootOopClosure root_cl(this, cl);
+ ZRootsIterator roots;
+
+ // Follow roots. Note that we also visit the JVMTI weak tag map
+ // as if they where strong roots to make sure we visit all tagged
+ // objects, even those that might now have become unreachable.
+ // If we didn't do this the user would have expected to see
+ // ObjectFree events for unreachable objects in the tag map.
+ roots.oops_do(&root_cl, true /* visit_jvmti_weak_export */);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zHeapIterator.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef SHARE_GC_Z_ZHEAPITERATOR_HPP
+#define SHARE_GC_Z_ZHEAPITERATOR_HPP
+
+#include "gc/z/zAddressRangeMap.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "memory/allocation.hpp"
+#include "utilities/stack.hpp"
+
+class ZHeapIteratorBitMap;
+
+class ZHeapIterator : public StackObj {
+ friend class ZHeapIteratorRootOopClosure;
+ friend class ZHeapIteratorPushOopClosure;
+
+private:
+ typedef ZAddressRangeMap<ZHeapIteratorBitMap*, ZPageSizeMinShift> ZVisitMap;
+ typedef ZAddressRangeMapIterator<ZHeapIteratorBitMap*, ZPageSizeMinShift> ZVisitMapIterator;
+ typedef Stack<oop, mtGC> ZVisitStack;
+
+ ZVisitStack _visit_stack;
+ ZVisitMap _visit_map;
+
+ size_t object_index_max() const;
+ size_t object_index(oop obj) const;
+ ZHeapIteratorBitMap* object_map(oop obj);
+
+ void push(oop obj);
+ void drain(ObjectClosure* cl);
+
+public:
+ ZHeapIterator();
+ ~ZHeapIterator();
+
+ void objects_do(ObjectClosure* cl);
+};
+
+#endif // SHARE_GC_Z_ZHEAPITERATOR_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zInitialize.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,51 @@
+/*
+ * 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 "gc/z/zAddress.hpp"
+#include "gc/z/zBarrierSet.hpp"
+#include "gc/z/zCPU.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zInitialize.hpp"
+#include "gc/z/zLargePages.hpp"
+#include "gc/z/zNUMA.hpp"
+#include "gc/z/zStat.hpp"
+#include "gc/z/zTracer.hpp"
+#include "logging/log.hpp"
+#include "runtime/vm_version.hpp"
+
+ZInitialize::ZInitialize(ZBarrierSet* barrier_set) {
+ log_info(gc, init)("Initializing %s", ZGCName);
+ log_info(gc, init)("Version: %s (%s)",
+ Abstract_VM_Version::vm_release(),
+ Abstract_VM_Version::jdk_debug_level());
+
+ // Early initialization
+ ZAddressMasks::initialize();
+ ZNUMA::initialize();
+ ZCPU::initialize();
+ ZStatValue::initialize();
+ ZTracer::initialize();
+ ZLargePages::initialize();
+ ZBarrierSet::set_barrier_set(barrier_set);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zInitialize.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+#ifndef SHARE_GC_Z_ZINITIALIZE_HPP
+#define SHARE_GC_Z_ZINITIALIZE_HPP
+
+#include "memory/allocation.hpp"
+
+class ZBarrierSet;
+
+class ZInitialize {
+public:
+ ZInitialize(ZBarrierSet* barrier_set);
+};
+
+#endif // SHARE_GC_Z_ZINITIALIZE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zLargePages.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 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 "gc/z/zLargePages.hpp"
+#include "logging/log.hpp"
+#include "runtime/os.hpp"
+
+ZLargePages::State ZLargePages::_state;
+
+void ZLargePages::initialize() {
+ initialize_platform();
+
+ log_info(gc, init)("Memory: " JULONG_FORMAT "M", os::physical_memory() / M);
+ log_info(gc, init)("Large Page Support: %s", to_string());
+}
+
+const char* ZLargePages::to_string() {
+ switch (_state) {
+ case Explicit:
+ return "Enabled (Explicit)";
+
+ case Transparent:
+ return "Enabled (Transparent)";
+
+ default:
+ return "Disabled";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zLargePages.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef SHARE_GC_Z_ZLARGEPAGES_HPP
+#define SHARE_GC_Z_ZLARGEPAGES_HPP
+
+#include "memory/allocation.hpp"
+
+class ZLargePages : public AllStatic {
+private:
+ enum State {
+ Disabled,
+ Explicit,
+ Transparent
+ };
+
+ static State _state;
+
+ static void initialize_platform();
+
+public:
+ static void initialize();
+
+ static bool is_enabled();
+ static bool is_explicit();
+ static bool is_transparent();
+
+ static const char* to_string();
+};
+
+#endif // SHARE_GC_Z_ZLARGEPAGES_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zLargePages.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef SHARE_GC_Z_ZLARGEPAGES_INLINE_HPP
+#define SHARE_GC_Z_ZLARGEPAGES_INLINE_HPP
+
+#include "gc/z/zLargePages.hpp"
+
+inline bool ZLargePages::is_enabled() {
+ return _state != Disabled;
+}
+
+inline bool ZLargePages::is_explicit() {
+ return _state == Explicit;
+}
+
+inline bool ZLargePages::is_transparent() {
+ return _state == Transparent;
+}
+
+#endif // SHARE_GC_Z_ZLARGEPAGES_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zList.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZLIST_HPP
+#define SHARE_GC_Z_ZLIST_HPP
+
+#include "memory/allocation.hpp"
+#include "utilities/debug.hpp"
+
+template <typename T> class ZList;
+
+// Element in a double linked list
+template <typename T>
+class ZListNode {
+ friend class ZList<T>;
+
+private:
+ ZListNode* _next;
+ ZListNode* _prev;
+
+ ZListNode(ZListNode* next, ZListNode* prev) :
+ _next(next),
+ _prev(prev) {}
+
+ void set_unused() {
+ _next = NULL;
+ _prev = NULL;
+ }
+
+public:
+ ZListNode() {
+ set_unused();
+ }
+
+ ~ZListNode() {
+ set_unused();
+ }
+
+ bool is_unused() const {
+ return _next == NULL && _prev == NULL;
+ }
+};
+
+// Double-linked list
+template <typename T>
+class ZList {
+private:
+ ZListNode<T> _head;
+ size_t _size;
+
+ // Passing by value and assignment is not allowed
+ ZList(const ZList<T>& list);
+ ZList<T>& operator=(const ZList<T>& list);
+
+ void verify() const {
+ assert(_head._next->_prev == &_head, "List corrupt");
+ assert(_head._prev->_next == &_head, "List corrupt");
+ }
+
+ void insert(ZListNode<T>* before, ZListNode<T>* node) {
+ verify();
+
+ assert(node->is_unused(), "Already in a list");
+ node->_prev = before;
+ node->_next = before->_next;
+ before->_next = node;
+ node->_next->_prev = node;
+
+ _size++;
+ }
+
+ ZListNode<T>* cast_to_inner(T* elem) const {
+ return &elem->_node;
+ }
+
+ T* cast_to_outer(ZListNode<T>* node) const {
+ return (T*)((uintptr_t)node - offset_of(T, _node));
+ }
+
+public:
+ ZList() :
+ _head(&_head, &_head),
+ _size(0) {
+ verify();
+ }
+
+ size_t size() const {
+ verify();
+ return _size;
+ }
+
+ bool is_empty() const {
+ return _size == 0;
+ }
+
+ T* first() const {
+ return is_empty() ? NULL : cast_to_outer(_head._next);
+ }
+
+ T* last() const {
+ return is_empty() ? NULL : cast_to_outer(_head._prev);
+ }
+
+ T* next(T* elem) const {
+ verify();
+ ZListNode<T>* next = cast_to_inner(elem)->_next;
+ return (next == &_head) ? NULL : cast_to_outer(next);
+ }
+
+ T* prev(T* elem) const {
+ verify();
+ ZListNode<T>* prev = cast_to_inner(elem)->_prev;
+ return (prev == &_head) ? NULL : cast_to_outer(prev);
+ }
+
+ void insert_first(T* elem) {
+ insert(&_head, cast_to_inner(elem));
+ }
+
+ void insert_last(T* elem) {
+ insert(_head._prev, cast_to_inner(elem));
+ }
+
+ void insert_before(T* before, T* elem) {
+ insert(cast_to_inner(before)->_prev, cast_to_inner(elem));
+ }
+
+ void insert_after(T* after, T* elem) {
+ insert(cast_to_inner(after), cast_to_inner(elem));
+ }
+
+ void remove(T* elem) {
+ verify();
+
+ ZListNode<T>* const node = cast_to_inner(elem);
+ assert(!node->is_unused(), "Not in a list");
+
+ ZListNode<T>* const next = node->_next;
+ ZListNode<T>* const prev = node->_prev;
+ assert(next->_prev == node, "List corrupt");
+ assert(prev->_next == node, "List corrupt");
+
+ prev->_next = next;
+ next->_prev = prev;
+ node->set_unused();
+
+ _size--;
+ }
+
+ T* remove_first() {
+ T* elem = first();
+ if (elem != NULL) {
+ remove(elem);
+ }
+
+ return elem;
+ }
+
+ T* remove_last() {
+ T* elem = last();
+ if (elem != NULL) {
+ remove(elem);
+ }
+
+ return elem;
+ }
+
+ void transfer(ZList<T>* list) {
+ verify();
+
+ if (!list->is_empty()) {
+ list->_head._next->_prev = _head._prev;
+ list->_head._prev->_next = _head._prev->_next;
+
+ _head._prev->_next = list->_head._next;
+ _head._prev = list->_head._prev;
+
+ list->_head._next = &list->_head;
+ list->_head._prev = &list->_head;
+
+ _size += list->_size;
+ list->_size = 0;
+
+ list->verify();
+ verify();
+ }
+ }
+};
+
+template <typename T, bool forward>
+class ZListIteratorImpl : public StackObj {
+private:
+ ZList<T>* const _list;
+ T* _next;
+
+public:
+ ZListIteratorImpl(ZList<T>* list);
+
+ bool next(T** elem);
+};
+
+// Iterator types
+#define ZLIST_FORWARD true
+#define ZLIST_REVERSE false
+
+template <typename T>
+class ZListIterator : public ZListIteratorImpl<T, ZLIST_FORWARD> {
+public:
+ ZListIterator(ZList<T>* list) :
+ ZListIteratorImpl<T, ZLIST_FORWARD>(list) {}
+};
+
+template <typename T>
+class ZListReverseIterator : public ZListIteratorImpl<T, ZLIST_REVERSE> {
+public:
+ ZListReverseIterator(ZList<T>* list) :
+ ZListIteratorImpl<T, ZLIST_REVERSE>(list) {}
+};
+
+#endif // SHARE_GC_Z_ZLIST_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zList.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZLIST_INLINE_HPP
+#define SHARE_GC_Z_ZLIST_INLINE_HPP
+
+#include "gc/z/zList.hpp"
+
+template <typename T, bool forward>
+ZListIteratorImpl<T, forward>::ZListIteratorImpl(ZList<T>* list) :
+ _list(list),
+ _next(forward ? list->first() : list->last()) {}
+
+template <typename T, bool forward>
+bool ZListIteratorImpl<T, forward>::next(T** elem) {
+ if (_next != NULL) {
+ *elem = _next;
+ _next = forward ? _list->next(_next) : _list->prev(_next);
+ return true;
+ }
+
+ // No more elements
+ return false;
+}
+
+#endif // SHARE_GC_Z_ZLIST_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zLiveMap.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,123 @@
+/*
+ * 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 "gc/z/zHeap.inline.hpp"
+#include "gc/z/zLiveMap.inline.hpp"
+#include "gc/z/zStat.hpp"
+#include "gc/z/zThread.hpp"
+#include "logging/log.hpp"
+#include "runtime/atomic.hpp"
+#include "runtime/orderAccess.hpp"
+#include "utilities/debug.hpp"
+
+static const ZStatCounter ZCounterMarkSeqNumResetContention("Contention", "Mark SeqNum Reset Contention", ZStatUnitOpsPerSecond);
+static const ZStatCounter ZCounterMarkSegmentResetContention("Contention", "Mark Segment Reset Contention", ZStatUnitOpsPerSecond);
+
+ZLiveMap::ZLiveMap(uint32_t size) :
+ _seqnum(0),
+ _live_objects(0),
+ _live_bytes(0),
+ _segment_live_bits(0),
+ _segment_claim_bits(0),
+ // We need at least one bit per segment.
+ _bitmap(MAX2<size_t>(size, nsegments) * 2),
+ _shift(exact_log2(segment_size())) {}
+
+void ZLiveMap::reset(size_t index) {
+ const uint32_t seqnum_initializing = (uint32_t)-1;
+ bool contention = false;
+
+ // Multiple threads can enter here, make sure only one of them
+ // resets the marking information while the others busy wait.
+ for (uint32_t seqnum = _seqnum; seqnum != ZGlobalSeqNum; seqnum = _seqnum) {
+ if ((seqnum != seqnum_initializing) &&
+ (Atomic::cmpxchg(seqnum_initializing, &_seqnum, seqnum) == seqnum)) {
+ // Reset marking information
+ _live_bytes = 0;
+ _live_objects = 0;
+
+ // Clear segment claimed/live bits
+ segment_live_bits().clear();
+ segment_claim_bits().clear();
+
+ // Make sure the newly reset marking information is
+ // globally visible before updating the page seqnum.
+ OrderAccess::storestore();
+
+ // Update seqnum
+ assert(_seqnum == seqnum_initializing, "Invalid");
+ _seqnum = ZGlobalSeqNum;
+ break;
+ }
+
+ // Mark reset contention
+ if (!contention) {
+ // Count contention once, not every loop
+ ZStatInc(ZCounterMarkSeqNumResetContention);
+ contention = true;
+
+ log_trace(gc)("Mark seqnum reset contention, thread: " PTR_FORMAT " (%s), map: " PTR_FORMAT ", bit: " SIZE_FORMAT,
+ ZThread::id(), ZThread::name(), p2i(this), index);
+ }
+ }
+}
+
+void ZLiveMap::reset_segment(BitMap::idx_t segment) {
+ bool contention = false;
+
+ if (!claim_segment(segment)) {
+ // Already claimed, wait for live bit to be set
+ while (!is_segment_live(segment)) {
+ // Busy wait. The loadload barrier is needed to make
+ // sure we re-read the live bit every time we loop.
+ OrderAccess::loadload();
+
+ // Mark reset contention
+ if (!contention) {
+ // Count contention once, not every loop
+ ZStatInc(ZCounterMarkSegmentResetContention);
+ contention = true;
+
+ log_trace(gc)("Mark segment reset contention, thread: " PTR_FORMAT " (%s), map: " PTR_FORMAT ", segment: " SIZE_FORMAT,
+ ZThread::id(), ZThread::name(), p2i(this), segment);
+ }
+ }
+
+ // Segment is live
+ return;
+ }
+
+ // Segment claimed, clear it
+ const BitMap::idx_t start_index = segment_start(segment);
+ const BitMap::idx_t end_index = segment_end(segment);
+ if (segment_size() / BitsPerWord >= 32) {
+ _bitmap.clear_large_range(start_index, end_index);
+ } else {
+ _bitmap.clear_range(start_index, end_index);
+ }
+
+ // Set live bit
+ const bool success = set_segment_live_atomic(segment);
+ assert(success, "Should never fail");
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zLiveMap.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZLIVEMAP_HPP
+#define SHARE_GC_Z_ZLIVEMAP_HPP
+
+#include "gc/z/zBitMap.hpp"
+#include "memory/allocation.hpp"
+
+class ObjectClosure;
+
+class ZLiveMap {
+ friend class ZLiveMapTest;
+
+private:
+ static const size_t nsegments = 64;
+
+ volatile uint32_t _seqnum; // Mark sequence number
+ volatile uint32_t _live_objects; // Number of live objects
+ volatile size_t _live_bytes; // Number of live bytes
+ BitMap::bm_word_t _segment_live_bits; // Segment live bits
+ BitMap::bm_word_t _segment_claim_bits; // Segment claim bits
+ ZBitMap _bitmap; // Mark bitmap
+ const size_t _shift; // Segment shift
+
+ const BitMapView segment_live_bits() const;
+ const BitMapView segment_claim_bits() const;
+
+ BitMapView segment_live_bits();
+ BitMapView segment_claim_bits();
+
+ BitMap::idx_t segment_size() const;
+
+ BitMap::idx_t segment_start(BitMap::idx_t segment) const;
+ BitMap::idx_t segment_end(BitMap::idx_t segment) const;
+
+ bool is_segment_live(BitMap::idx_t segment) const;
+ bool set_segment_live_atomic(BitMap::idx_t segment);
+
+ BitMap::idx_t first_live_segment() const;
+ BitMap::idx_t next_live_segment(BitMap::idx_t segment) const;
+ BitMap::idx_t index_to_segment(BitMap::idx_t index) const;
+
+ bool claim_segment(BitMap::idx_t segment);
+
+ void reset(size_t index);
+ void reset_segment(BitMap::idx_t segment);
+
+ void iterate_segment(ObjectClosure* cl, BitMap::idx_t segment, uintptr_t page_start, size_t page_object_alignment_shift);
+
+public:
+ ZLiveMap(uint32_t size);
+
+ void reset();
+
+ bool is_marked() const;
+
+ uint32_t live_objects() const;
+ size_t live_bytes() const;
+
+ bool get(size_t index) const;
+ bool set_atomic(size_t index, bool finalizable, bool& inc_live);
+
+ void inc_live_atomic(uint32_t objects, size_t bytes);
+
+ void iterate(ObjectClosure* cl, uintptr_t page_start, size_t page_object_alignment_shift);
+};
+
+#endif // SHARE_GC_Z_ZLIVEMAP_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zLiveMap.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZLIVEMAP_INLINE_HPP
+#define SHARE_GC_Z_ZLIVEMAP_INLINE_HPP
+
+#include "gc/z/zBitMap.inline.hpp"
+#include "gc/z/zLiveMap.hpp"
+#include "gc/z/zMark.hpp"
+#include "gc/z/zOop.inline.hpp"
+#include "gc/z/zUtils.inline.hpp"
+#include "runtime/atomic.hpp"
+#include "utilities/bitMap.inline.hpp"
+#include "utilities/debug.hpp"
+
+inline void ZLiveMap::reset() {
+ _seqnum = 0;
+}
+
+inline bool ZLiveMap::is_marked() const {
+ return _seqnum == ZGlobalSeqNum;
+}
+
+inline uint32_t ZLiveMap::live_objects() const {
+ assert(ZGlobalPhase != ZPhaseMark, "Invalid phase");
+ return _live_objects;
+}
+
+inline size_t ZLiveMap::live_bytes() const {
+ assert(ZGlobalPhase != ZPhaseMark, "Invalid phase");
+ return _live_bytes;
+}
+
+inline const BitMapView ZLiveMap::segment_live_bits() const {
+ return BitMapView(const_cast<BitMap::bm_word_t*>(&_segment_live_bits), nsegments);
+}
+
+inline const BitMapView ZLiveMap::segment_claim_bits() const {
+ return BitMapView(const_cast<BitMap::bm_word_t*>(&_segment_claim_bits), nsegments);
+}
+
+inline BitMapView ZLiveMap::segment_live_bits() {
+ return BitMapView(&_segment_live_bits, nsegments);
+}
+
+inline BitMapView ZLiveMap::segment_claim_bits() {
+ return BitMapView(&_segment_claim_bits, nsegments);
+}
+
+inline bool ZLiveMap::is_segment_live(BitMap::idx_t segment) const {
+ return segment_live_bits().at(segment);
+}
+
+inline bool ZLiveMap::set_segment_live_atomic(BitMap::idx_t segment) {
+ return segment_live_bits().par_set_bit(segment);
+}
+
+inline bool ZLiveMap::claim_segment(BitMap::idx_t segment) {
+ return segment_claim_bits().par_set_bit(segment);
+}
+
+inline BitMap::idx_t ZLiveMap::first_live_segment() const {
+ return segment_live_bits().get_next_one_offset(0, nsegments);
+}
+
+inline BitMap::idx_t ZLiveMap::next_live_segment(BitMap::idx_t segment) const {
+ return segment_live_bits().get_next_one_offset(segment + 1, nsegments);
+}
+
+inline BitMap::idx_t ZLiveMap::segment_size() const {
+ return _bitmap.size() / nsegments;
+}
+
+inline BitMap::idx_t ZLiveMap::index_to_segment(BitMap::idx_t index) const {
+ return index >> _shift;
+}
+
+inline bool ZLiveMap::get(size_t index) const {
+ BitMap::idx_t segment = index_to_segment(index);
+ return is_marked() && // Page is marked
+ is_segment_live(segment) && // Segment is marked
+ _bitmap.at(index); // Object is marked
+}
+
+inline bool ZLiveMap::set_atomic(size_t index, bool finalizable, bool& inc_live) {
+ if (!is_marked()) {
+ // First object to be marked during this
+ // cycle, reset marking information.
+ reset(index);
+ }
+
+ const BitMap::idx_t segment = index_to_segment(index);
+ if (!is_segment_live(segment)) {
+ // First object to be marked in this segment during
+ // this cycle, reset segment bitmap.
+ reset_segment(segment);
+ }
+
+ return _bitmap.par_set_bit_pair(index, finalizable, inc_live);
+}
+
+inline void ZLiveMap::inc_live_atomic(uint32_t objects, size_t bytes) {
+ Atomic::add(objects, &_live_objects);
+ Atomic::add(bytes, &_live_bytes);
+}
+
+inline BitMap::idx_t ZLiveMap::segment_start(BitMap::idx_t segment) const {
+ return segment_size() * segment;
+}
+
+inline BitMap::idx_t ZLiveMap::segment_end(BitMap::idx_t segment) const {
+ return segment_start(segment) + segment_size();
+}
+
+inline void ZLiveMap::iterate_segment(ObjectClosure* cl, BitMap::idx_t segment, uintptr_t page_start, size_t page_object_alignment_shift) {
+ assert(is_segment_live(segment), "Must be");
+
+ const BitMap::idx_t start_index = segment_start(segment);
+ const BitMap::idx_t end_index = segment_end(segment);
+ BitMap::idx_t index = _bitmap.get_next_one_offset(start_index, end_index);
+
+ while (index < end_index) {
+ // Calculate object address
+ const uintptr_t addr = page_start + ((index / 2) << page_object_alignment_shift);
+
+ // Apply closure
+ cl->do_object(ZOop::to_oop(addr));
+
+ // Find next bit after this object
+ const size_t size = ZUtils::object_size(addr);
+ const uintptr_t next_addr = align_up(addr + size, 1 << page_object_alignment_shift);
+ const BitMap::idx_t next_index = ((next_addr - page_start) >> page_object_alignment_shift) * 2;
+ if (next_index >= end_index) {
+ // End of live map
+ break;
+ }
+
+ index = _bitmap.get_next_one_offset(next_index, end_index);
+ }
+}
+
+inline void ZLiveMap::iterate(ObjectClosure* cl, uintptr_t page_start, size_t page_object_alignment_shift) {
+ if (is_marked()) {
+ for (BitMap::idx_t segment = first_live_segment(); segment < nsegments; segment = next_live_segment(segment)) {
+ // For each live segment
+ iterate_segment(cl, segment, page_start, page_object_alignment_shift);
+ }
+ }
+}
+
+#endif // SHARE_GC_Z_ZLIVEMAP_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zLock.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZLOCK_HPP
+#define SHARE_GC_Z_ZLOCK_HPP
+
+#include "memory/allocation.hpp"
+#include <pthread.h>
+
+class ZLock {
+private:
+ pthread_mutex_t _lock;
+
+public:
+ ZLock();
+
+ void lock();
+ bool try_lock();
+ void unlock();
+};
+
+class ZLocker : public StackObj {
+private:
+ ZLock* const _lock;
+
+public:
+ ZLocker(ZLock* lock);
+ ~ZLocker();
+};
+
+#endif // SHARE_GC_Z_ZLOCK_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zLock.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZLOCK_INLINE_HPP
+#define SHARE_GC_Z_ZLOCK_INLINE_HPP
+
+#include "gc/z/zLock.hpp"
+
+inline ZLock::ZLock() {
+ pthread_mutex_init(&_lock, NULL);
+}
+
+inline void ZLock::lock() {
+ pthread_mutex_lock(&_lock);
+}
+
+inline bool ZLock::try_lock() {
+ return pthread_mutex_trylock(&_lock) == 0;
+}
+
+inline void ZLock::unlock() {
+ pthread_mutex_unlock(&_lock);
+}
+
+inline ZLocker::ZLocker(ZLock* lock) :
+ _lock(lock) {
+ _lock->lock();
+}
+
+inline ZLocker::~ZLocker() {
+ _lock->unlock();
+}
+
+#endif // SHARE_GC_Z_ZLOCK_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zMark.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,684 @@
+/*
+ * 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 "gc/z/zBarrier.inline.hpp"
+#include "gc/z/zMark.inline.hpp"
+#include "gc/z/zMarkCache.inline.hpp"
+#include "gc/z/zMarkStack.inline.hpp"
+#include "gc/z/zMarkTerminate.inline.hpp"
+#include "gc/z/zOopClosures.inline.hpp"
+#include "gc/z/zPage.hpp"
+#include "gc/z/zPageTable.inline.hpp"
+#include "gc/z/zRootsIterator.hpp"
+#include "gc/z/zStat.hpp"
+#include "gc/z/zTask.hpp"
+#include "gc/z/zThread.hpp"
+#include "gc/z/zUtils.inline.hpp"
+#include "gc/z/zWorkers.inline.hpp"
+#include "logging/log.hpp"
+#include "oops/objArrayOop.inline.hpp"
+#include "oops/oop.inline.hpp"
+#include "runtime/atomic.hpp"
+#include "runtime/handshake.hpp"
+#include "runtime/orderAccess.hpp"
+#include "runtime/prefetch.inline.hpp"
+#include "runtime/thread.hpp"
+#include "utilities/align.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/ticks.hpp"
+
+static const ZStatSubPhase ZSubPhaseConcurrentMark("Concurrent Mark");
+static const ZStatSubPhase ZSubPhaseConcurrentMarkTryFlush("Concurrent Mark Try Flush");
+static const ZStatSubPhase ZSubPhaseConcurrentMarkIdle("Concurrent Mark Idle");
+static const ZStatSubPhase ZSubPhaseConcurrentMarkTryTerminate("Concurrent Mark Try Terminate");
+static const ZStatSubPhase ZSubPhaseMarkTryComplete("Pause Mark Try Complete");
+
+ZMark::ZMark(ZWorkers* workers, ZPageTable* pagetable) :
+ _workers(workers),
+ _pagetable(pagetable),
+ _allocator(),
+ _stripes(),
+ _terminate(),
+ _work_terminateflush(true),
+ _work_nproactiveflush(0),
+ _work_nterminateflush(0),
+ _nproactiveflush(0),
+ _nterminateflush(0),
+ _ntrycomplete(0),
+ _ncontinue(0),
+ _nworkers(0) {}
+
+size_t ZMark::calculate_nstripes(uint nworkers) const {
+ // Calculate the number of stripes from the number of workers we use,
+ // where the number of stripes must be a power of two and we want to
+ // have at least one worker per stripe.
+ const size_t nstripes = ZUtils::round_down_power_of_2(nworkers);
+ return MIN2(nstripes, ZMarkStripesMax);
+}
+
+void ZMark::prepare_mark() {
+ // Increment global sequence number to invalidate
+ // marking information for all pages.
+ ZGlobalSeqNum++;
+
+ // Reset flush/continue counters
+ _nproactiveflush = 0;
+ _nterminateflush = 0;
+ _ntrycomplete = 0;
+ _ncontinue = 0;
+
+ // Set number of workers to use
+ _nworkers = _workers->nconcurrent();
+
+ // Set number of mark stripes to use, based on number
+ // of workers we will use in the concurrent mark phase.
+ const size_t nstripes = calculate_nstripes(_nworkers);
+ _stripes.set_nstripes(nstripes);
+
+ // Update statistics
+ ZStatMark::set_at_mark_start(nstripes);
+
+ // Print worker/stripe distribution
+ LogTarget(Debug, gc, marking) log;
+ if (log.is_enabled()) {
+ log.print("Mark Worker/Stripe Distribution");
+ for (uint worker_id = 0; worker_id < _nworkers; worker_id++) {
+ const ZMarkStripe* const stripe = _stripes.stripe_for_worker(_nworkers, worker_id);
+ const size_t stripe_id = _stripes.stripe_id(stripe);
+ log.print(" Worker %u(%u) -> Stripe " SIZE_FORMAT "(" SIZE_FORMAT ")",
+ worker_id, _nworkers, stripe_id, nstripes);
+ }
+ }
+}
+
+class ZMarkRootsTask : public ZTask {
+private:
+ ZMark* const _mark;
+ ZRootsIterator _roots;
+
+public:
+ ZMarkRootsTask(ZMark* mark) :
+ ZTask("ZMarkRootsTask"),
+ _mark(mark),
+ _roots() {}
+
+ virtual void work() {
+ ZMarkRootOopClosure cl;
+ _roots.oops_do(&cl);
+
+ // Flush and free worker stacks. Needed here since
+ // the set of workers executing during root scanning
+ // can be different from the set of workers executing
+ // during mark.
+ _mark->flush_and_free();
+ }
+};
+
+void ZMark::start() {
+ // Verification
+ if (ZVerifyMarking) {
+ verify_all_stacks_empty();
+ }
+
+ // Prepare for concurrent mark
+ prepare_mark();
+
+ // Mark roots
+ ZMarkRootsTask task(this);
+ _workers->run_parallel(&task);
+}
+
+void ZMark::prepare_work() {
+ assert(_nworkers == _workers->nconcurrent(), "Invalid number of workers");
+
+ // Set number of active workers
+ _terminate.reset(_nworkers);
+
+ // Reset flush counters
+ _work_nproactiveflush = _work_nterminateflush = 0;
+ _work_terminateflush = true;
+}
+
+void ZMark::finish_work() {
+ // Accumulate proactive/terminate flush counters
+ _nproactiveflush += _work_nproactiveflush;
+ _nterminateflush += _work_nterminateflush;
+}
+
+bool ZMark::is_array(uintptr_t addr) const {
+ return ZOop::to_oop(addr)->is_objArray();
+}
+
+void ZMark::push_partial_array(uintptr_t addr, size_t size, bool finalizable) {
+ assert(is_aligned(addr, ZMarkPartialArrayMinSize), "Address misaligned");
+ ZMarkThreadLocalStacks* const stacks = ZThreadLocalData::stacks(Thread::current());
+ ZMarkStripe* const stripe = _stripes.stripe_for_addr(addr);
+ const uintptr_t offset = ZAddress::offset(addr) >> ZMarkPartialArrayMinSizeShift;
+ const uintptr_t length = size / oopSize;
+ const ZMarkStackEntry entry(offset, length, finalizable);
+
+ log_develop_trace(gc, marking)("Array push partial: " PTR_FORMAT " (" SIZE_FORMAT "), stripe: " SIZE_FORMAT,
+ addr, size, _stripes.stripe_id(stripe));
+
+ stacks->push(&_allocator, &_stripes, stripe, entry, false /* publish */);
+}
+
+void ZMark::follow_small_array(uintptr_t addr, size_t size, bool finalizable) {
+ assert(size <= ZMarkPartialArrayMinSize, "Too large, should be split");
+ const size_t length = size / oopSize;
+
+ log_develop_trace(gc, marking)("Array follow small: " PTR_FORMAT " (" SIZE_FORMAT ")", addr, size);
+
+ ZBarrier::mark_barrier_on_oop_array((oop*)addr, length, finalizable);
+}
+
+void ZMark::follow_large_array(uintptr_t addr, size_t size, bool finalizable) {
+ assert(size <= (size_t)arrayOopDesc::max_array_length(T_OBJECT) * oopSize, "Too large");
+ assert(size > ZMarkPartialArrayMinSize, "Too small, should not be split");
+ const uintptr_t start = addr;
+ const uintptr_t end = start + size;
+
+ // Calculate the aligned middle start/end/size, where the middle start
+ // should always be greater than the start (hence the +1 below) to make
+ // sure we always do some follow work, not just split the array into pieces.
+ const uintptr_t middle_start = align_up(start + 1, ZMarkPartialArrayMinSize);
+ const size_t middle_size = align_down(end - middle_start, ZMarkPartialArrayMinSize);
+ const uintptr_t middle_end = middle_start + middle_size;
+
+ log_develop_trace(gc, marking)("Array follow large: " PTR_FORMAT "-" PTR_FORMAT" (" SIZE_FORMAT "), "
+ "middle: " PTR_FORMAT "-" PTR_FORMAT " (" SIZE_FORMAT ")",
+ start, end, size, middle_start, middle_end, middle_size);
+
+ // Push unaligned trailing part
+ if (end > middle_end) {
+ const uintptr_t trailing_addr = middle_end;
+ const size_t trailing_size = end - middle_end;
+ push_partial_array(trailing_addr, trailing_size, finalizable);
+ }
+
+ // Push aligned middle part(s)
+ uintptr_t partial_addr = middle_end;
+ while (partial_addr > middle_start) {
+ const size_t parts = 2;
+ const size_t partial_size = align_up((partial_addr - middle_start) / parts, ZMarkPartialArrayMinSize);
+ partial_addr -= partial_size;
+ push_partial_array(partial_addr, partial_size, finalizable);
+ }
+
+ // Follow leading part
+ assert(start < middle_start, "Miscalculated middle start");
+ const uintptr_t leading_addr = start;
+ const size_t leading_size = middle_start - start;
+ follow_small_array(leading_addr, leading_size, finalizable);
+}
+
+void ZMark::follow_array(uintptr_t addr, size_t size, bool finalizable) {
+ if (size <= ZMarkPartialArrayMinSize) {
+ follow_small_array(addr, size, finalizable);
+ } else {
+ follow_large_array(addr, size, finalizable);
+ }
+}
+
+void ZMark::follow_partial_array(ZMarkStackEntry entry, bool finalizable) {
+ const uintptr_t addr = ZAddress::good(entry.partial_array_offset() << ZMarkPartialArrayMinSizeShift);
+ const size_t size = entry.partial_array_length() * oopSize;
+
+ follow_array(addr, size, finalizable);
+}
+
+void ZMark::follow_array_object(objArrayOop obj, bool finalizable) {
+ const uintptr_t addr = (uintptr_t)obj->base();
+ const size_t size = (size_t)obj->length() * oopSize;
+
+ follow_array(addr, size, finalizable);
+}
+
+void ZMark::follow_object(oop obj, bool finalizable) {
+ if (finalizable) {
+ ZMarkBarrierOopClosure<true /* finalizable */> cl;
+ obj->oop_iterate(&cl);
+ } else {
+ ZMarkBarrierOopClosure<false /* finalizable */> cl;
+ obj->oop_iterate(&cl);
+ }
+}
+
+bool ZMark::try_mark_object(ZMarkCache* cache, uintptr_t addr, bool finalizable) {
+ ZPage* const page = _pagetable->get(addr);
+ if (page->is_allocating()) {
+ // Newly allocated objects are implicitly marked
+ return false;
+ }
+
+ // Try mark object
+ bool inc_live = false;
+ const bool success = page->mark_object(addr, finalizable, inc_live);
+ if (inc_live) {
+ // Update live objects/bytes for page. We use the aligned object
+ // size since that is the actual number of bytes used on the page
+ // and alignment paddings can never be reclaimed.
+ const size_t size = ZUtils::object_size(addr);
+ const size_t aligned_size = align_up(size, page->object_alignment());
+ cache->inc_live(page, aligned_size);
+ }
+
+ return success;
+}
+
+void ZMark::mark_and_follow(ZMarkCache* cache, ZMarkStackEntry entry) {
+ // Decode flags
+ const bool finalizable = entry.finalizable();
+ const bool partial_array = entry.partial_array();
+
+ if (partial_array) {
+ follow_partial_array(entry, finalizable);
+ return;
+ }
+
+ // Decode object address
+ const uintptr_t addr = entry.object_address();
+
+ if (!try_mark_object(cache, addr, finalizable)) {
+ // Already marked
+ return;
+ }
+
+ if (is_array(addr)) {
+ follow_array_object(objArrayOop(ZOop::to_oop(addr)), finalizable);
+ } else {
+ follow_object(ZOop::to_oop(addr), finalizable);
+ }
+}
+
+template <typename T>
+bool ZMark::drain(ZMarkStripe* stripe, ZMarkThreadLocalStacks* stacks, ZMarkCache* cache, T* timeout) {
+ ZMarkStackEntry entry;
+
+ // Drain stripe stacks
+ while (stacks->pop(&_allocator, &_stripes, stripe, entry)) {
+ mark_and_follow(cache, entry);
+
+ // Check timeout
+ if (timeout->has_expired()) {
+ // Timeout
+ return false;
+ }
+ }
+
+ // Success
+ return true;
+}
+
+template <typename T>
+bool ZMark::drain_and_flush(ZMarkStripe* stripe, ZMarkThreadLocalStacks* stacks, ZMarkCache* cache, T* timeout) {
+ const bool success = drain(stripe, stacks, cache, timeout);
+
+ // Flush and publish worker stacks
+ stacks->flush(&_allocator, &_stripes);
+
+ return success;
+}
+
+bool ZMark::try_steal(ZMarkStripe* stripe, ZMarkThreadLocalStacks* stacks) {
+ // Try to steal a stack from another stripe
+ for (ZMarkStripe* victim_stripe = _stripes.stripe_next(stripe);
+ victim_stripe != stripe;
+ victim_stripe = _stripes.stripe_next(victim_stripe)) {
+ ZMarkStack* const stack = victim_stripe->steal_stack();
+ if (stack != NULL) {
+ // Success, install the stolen stack
+ stacks->install(&_stripes, stripe, stack);
+ return true;
+ }
+ }
+
+ // Nothing to steal
+ return false;
+}
+
+void ZMark::idle() const {
+ ZStatTimer timer(ZSubPhaseConcurrentMarkIdle);
+ os::naked_short_sleep(1);
+}
+
+class ZMarkFlushAndFreeStacksClosure : public ThreadClosure {
+private:
+ ZMark* const _mark;
+ bool _flushed;
+
+public:
+ ZMarkFlushAndFreeStacksClosure(ZMark* mark) :
+ _mark(mark),
+ _flushed(false) {}
+
+ void do_thread(Thread* thread) {
+ if (_mark->flush_and_free(thread)) {
+ _flushed = true;
+ }
+ }
+
+ bool flushed() const {
+ return _flushed;
+ }
+};
+
+bool ZMark::flush(bool at_safepoint) {
+ ZMarkFlushAndFreeStacksClosure cl(this);
+ if (at_safepoint) {
+ Threads::threads_do(&cl);
+ } else {
+ Handshake::execute(&cl);
+ }
+
+ // Returns true if more work is available
+ return cl.flushed() || !_stripes.is_empty();
+}
+
+bool ZMark::try_flush(volatile size_t* nflush) {
+ // Only flush if handhakes are enabled
+ if (!ThreadLocalHandshakes) {
+ return false;
+ }
+
+ Atomic::inc(nflush);
+
+ ZStatTimer timer(ZSubPhaseConcurrentMarkTryFlush);
+ return flush(false /* at_safepoint */);
+}
+
+bool ZMark::try_proactive_flush() {
+ // Only do proactive flushes from worker 0
+ if (ZThread::worker_id() != 0) {
+ return false;
+ }
+
+ if (Atomic::load(&_work_nproactiveflush) == ZMarkProactiveFlushMax ||
+ Atomic::load(&_work_nterminateflush) != 0) {
+ // Limit reached or we're trying to terminate
+ return false;
+ }
+
+ return try_flush(&_work_nproactiveflush);
+}
+
+bool ZMark::try_terminate() {
+ ZStatTimer timer(ZSubPhaseConcurrentMarkTryTerminate);
+
+ if (_terminate.enter_stage0()) {
+ // Last thread entered stage 0, flush
+ if (Atomic::load(&_work_terminateflush) &&
+ Atomic::load(&_work_nterminateflush) != ZMarkTerminateFlushMax) {
+ // Exit stage 0 to allow other threads to continue marking
+ _terminate.exit_stage0();
+
+ // Flush before termination
+ if (!try_flush(&_work_nterminateflush)) {
+ // No more work available, skip further flush attempts
+ Atomic::store(false, &_work_terminateflush);
+ }
+
+ // Don't terminate, regardless of whether we successfully
+ // flushed out more work or not. We've already exited
+ // termination stage 0, to allow other threads to continue
+ // marking, so this thread has to return false and also
+ // make another round of attempted marking.
+ return false;
+ }
+ }
+
+ for (;;) {
+ if (_terminate.enter_stage1()) {
+ // Last thread entered stage 1, terminate
+ return true;
+ }
+
+ // Idle to give the other threads
+ // a chance to enter termination.
+ idle();
+
+ if (!_terminate.try_exit_stage1()) {
+ // All workers in stage 1, terminate
+ return true;
+ }
+
+ if (_terminate.try_exit_stage0()) {
+ // More work available, don't terminate
+ return false;
+ }
+ }
+}
+
+class ZMarkNoTimeout : public StackObj {
+public:
+ bool has_expired() {
+ return false;
+ }
+};
+
+void ZMark::work_without_timeout(ZMarkCache* cache, ZMarkStripe* stripe, ZMarkThreadLocalStacks* stacks) {
+ ZStatTimer timer(ZSubPhaseConcurrentMark);
+ ZMarkNoTimeout no_timeout;
+
+ for (;;) {
+ drain_and_flush(stripe, stacks, cache, &no_timeout);
+
+ if (try_steal(stripe, stacks)) {
+ // Stole work
+ continue;
+ }
+
+ if (try_proactive_flush()) {
+ // Work available
+ continue;
+ }
+
+ if (try_terminate()) {
+ // Terminate
+ break;
+ }
+ }
+}
+
+class ZMarkTimeout : public StackObj {
+private:
+ const Ticks _start;
+ const uint64_t _timeout;
+ const uint64_t _check_interval;
+ uint64_t _check_at;
+ uint64_t _check_count;
+ bool _expired;
+
+public:
+ ZMarkTimeout(uint64_t timeout_in_millis) :
+ _start(Ticks::now()),
+ _timeout(_start.value() + TimeHelper::millis_to_counter(timeout_in_millis)),
+ _check_interval(200),
+ _check_at(_check_interval),
+ _check_count(0),
+ _expired(false) {}
+
+ ~ZMarkTimeout() {
+ const Tickspan duration = Ticks::now() - _start;
+ log_debug(gc, marking)("Mark With Timeout (%s): %s, " UINT64_FORMAT " oops, %.3fms",
+ ZThread::name(), _expired ? "Expired" : "Completed",
+ _check_count, TimeHelper::counter_to_millis(duration.value()));
+ }
+
+ bool has_expired() {
+ if (++_check_count == _check_at) {
+ _check_at += _check_interval;
+ if ((uint64_t)Ticks::now().value() >= _timeout) {
+ // Timeout
+ _expired = true;
+ }
+ }
+
+ return _expired;
+ }
+};
+
+void ZMark::work_with_timeout(ZMarkCache* cache, ZMarkStripe* stripe, ZMarkThreadLocalStacks* stacks, uint64_t timeout_in_millis) {
+ ZStatTimer timer(ZSubPhaseMarkTryComplete);
+ ZMarkTimeout timeout(timeout_in_millis);
+
+ for (;;) {
+ if (!drain_and_flush(stripe, stacks, cache, &timeout)) {
+ // Timed out
+ break;
+ }
+
+ if (try_steal(stripe, stacks)) {
+ // Stole work
+ continue;
+ }
+
+ // Terminate
+ break;
+ }
+}
+
+void ZMark::work(uint64_t timeout_in_millis) {
+ ZMarkCache cache(_stripes.nstripes());
+ ZMarkStripe* const stripe = _stripes.stripe_for_worker(_nworkers, ZThread::worker_id());
+ ZMarkThreadLocalStacks* const stacks = ZThreadLocalData::stacks(Thread::current());
+
+ if (timeout_in_millis == 0) {
+ work_without_timeout(&cache, stripe, stacks);
+ } else {
+ work_with_timeout(&cache, stripe, stacks, timeout_in_millis);
+ }
+
+ // Make sure stacks have been flushed
+ assert(stacks->is_empty(&_stripes), "Should be empty");
+
+ // Free remaining stacks
+ stacks->free(&_allocator);
+}
+
+class ZMarkTask : public ZTask {
+private:
+ ZMark* const _mark;
+ const uint64_t _timeout_in_millis;
+
+public:
+ ZMarkTask(ZMark* mark, uint64_t timeout_in_millis = 0) :
+ ZTask("ZMarkTask"),
+ _mark(mark),
+ _timeout_in_millis(timeout_in_millis) {
+ _mark->prepare_work();
+ }
+
+ ~ZMarkTask() {
+ _mark->finish_work();
+ }
+
+ virtual void work() {
+ _mark->work(_timeout_in_millis);
+ }
+};
+
+void ZMark::mark() {
+ ZMarkTask task(this);
+ _workers->run_concurrent(&task);
+}
+
+bool ZMark::try_complete() {
+ _ntrycomplete++;
+
+ // Use nconcurrent number of worker threads to maintain the
+ // worker/stripe distribution used during concurrent mark.
+ ZMarkTask task(this, ZMarkCompleteTimeout);
+ _workers->run_concurrent(&task);
+
+ // Successful if all stripes are empty
+ return _stripes.is_empty();
+}
+
+bool ZMark::try_end() {
+ // Flush all mark stacks
+ if (!flush(true /* at_safepoint */)) {
+ // Mark completed
+ return true;
+ }
+
+ // Try complete marking by doing a limited
+ // amount of mark work in this phase.
+ return try_complete();
+}
+
+bool ZMark::end() {
+ // Try end marking
+ if (!try_end()) {
+ // Mark not completed
+ _ncontinue++;
+ return false;
+ }
+
+ // Verification
+ if (ZVerifyMarking) {
+ verify_all_stacks_empty();
+ }
+
+ // Update statistics
+ ZStatMark::set_at_mark_end(_nproactiveflush, _nterminateflush, _ntrycomplete, _ncontinue);
+
+ // Mark completed
+ return true;
+}
+
+void ZMark::flush_and_free() {
+ Thread* const thread = Thread::current();
+ flush_and_free(thread);
+}
+
+bool ZMark::flush_and_free(Thread* thread) {
+ ZMarkThreadLocalStacks* const stacks = ZThreadLocalData::stacks(thread);
+ const bool flushed = stacks->flush(&_allocator, &_stripes);
+ stacks->free(&_allocator);
+ return flushed;
+}
+
+class ZVerifyMarkStacksEmptyClosure : public ThreadClosure {
+private:
+ const ZMarkStripeSet* const _stripes;
+
+public:
+ ZVerifyMarkStacksEmptyClosure(const ZMarkStripeSet* stripes) :
+ _stripes(stripes) {}
+
+ void do_thread(Thread* thread) {
+ ZMarkThreadLocalStacks* const stacks = ZThreadLocalData::stacks(thread);
+ guarantee(stacks->is_empty(_stripes), "Should be empty");
+ }
+};
+
+void ZMark::verify_all_stacks_empty() const {
+ // Verify thread stacks
+ ZVerifyMarkStacksEmptyClosure cl(&_stripes);
+ Threads::threads_do(&cl);
+
+ // Verify stripe stacks
+ guarantee(_stripes.is_empty(), "Should be emtpy");
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zMark.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZMARK_HPP
+#define SHARE_GC_Z_ZMARK_HPP
+
+#include "gc/z/zMarkStack.hpp"
+#include "gc/z/zMarkTerminate.hpp"
+#include "oops/oopsHierarchy.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class Thread;
+class ZMarkCache;
+class ZPageTable;
+class ZWorkers;
+
+class ZMark {
+ friend class ZMarkRootsTask;
+ friend class ZMarkTask;
+ friend class ZMarkTryCompleteTask;
+
+private:
+ ZWorkers* const _workers;
+ ZPageTable* const _pagetable;
+ ZMarkStackAllocator _allocator;
+ ZMarkStripeSet _stripes;
+ ZMarkTerminate _terminate;
+ volatile bool _work_terminateflush;
+ volatile size_t _work_nproactiveflush;
+ volatile size_t _work_nterminateflush;
+ size_t _nproactiveflush;
+ size_t _nterminateflush;
+ size_t _ntrycomplete;
+ size_t _ncontinue;
+ uint _nworkers;
+
+ size_t calculate_nstripes(uint nworkers) const;
+ void prepare_mark();
+
+ bool is_array(uintptr_t addr) const;
+ void push_partial_array(uintptr_t addr, size_t size, bool finalizable);
+ void follow_small_array(uintptr_t addr, size_t size, bool finalizable);
+ void follow_large_array(uintptr_t addr, size_t size, bool finalizable);
+ void follow_array(uintptr_t addr, size_t size, bool finalizable);
+ void follow_partial_array(ZMarkStackEntry entry, bool finalizable);
+ void follow_array_object(objArrayOop obj, bool finalizable);
+ void follow_object(oop obj, bool finalizable);
+ bool try_mark_object(ZMarkCache* cache, uintptr_t addr, bool finalizable);
+ void mark_and_follow(ZMarkCache* cache, ZMarkStackEntry entry);
+
+ template <typename T> bool drain(ZMarkStripe* stripe,
+ ZMarkThreadLocalStacks* stacks,
+ ZMarkCache* cache,
+ T* timeout);
+ template <typename T> bool drain_and_flush(ZMarkStripe* stripe,
+ ZMarkThreadLocalStacks* stacks,
+ ZMarkCache* cache,
+ T* timeout);
+ bool try_steal(ZMarkStripe* stripe, ZMarkThreadLocalStacks* stacks);
+ void idle() const;
+ bool flush(bool at_safepoint);
+ bool try_proactive_flush();
+ bool try_flush(volatile size_t* nflush);
+ bool try_terminate();
+ bool try_complete();
+ bool try_end();
+
+ void prepare_work();
+ void finish_work();
+
+ void work_without_timeout(ZMarkCache* cache,
+ ZMarkStripe* stripe,
+ ZMarkThreadLocalStacks* stacks);
+ void work_with_timeout(ZMarkCache* cache,
+ ZMarkStripe* stripe,
+ ZMarkThreadLocalStacks* stacks,
+ uint64_t timeout_in_millis);
+ void work(uint64_t timeout_in_millis);
+
+ void verify_all_stacks_empty() const;
+
+public:
+ ZMark(ZWorkers* workers, ZPageTable* pagetable);
+
+ template <bool finalizable, bool publish> void mark_object(uintptr_t addr);
+
+ void start();
+ void mark();
+ bool end();
+
+ void flush_and_free();
+ bool flush_and_free(Thread* thread);
+};
+
+#endif // SHARE_GC_Z_ZMARK_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zMark.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,44 @@
+/*
+ * 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_GC_Z_ZMARK_INLINE_HPP
+#define SHARE_GC_Z_ZMARK_INLINE_HPP
+
+#include "gc/z/zAddress.inline.hpp"
+#include "gc/z/zMark.hpp"
+#include "gc/z/zMarkStack.inline.hpp"
+#include "gc/z/zThreadLocalData.hpp"
+#include "runtime/thread.hpp"
+#include "utilities/debug.hpp"
+
+template <bool finalizable, bool publish>
+inline void ZMark::mark_object(uintptr_t addr) {
+ assert(ZAddress::is_marked(addr), "Should be marked");
+ ZMarkThreadLocalStacks* const stacks = ZThreadLocalData::stacks(Thread::current());
+ ZMarkStripe* const stripe = _stripes.stripe_for_addr(addr);
+ ZMarkStackEntry entry(addr, finalizable);
+
+ stacks->push(&_allocator, &_stripes, stripe, entry, publish);
+}
+
+#endif // SHARE_GC_Z_ZMARK_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zMarkCache.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,41 @@
+/*
+ * 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 "gc/z/zMarkCache.inline.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+ZMarkCacheEntry::ZMarkCacheEntry() :
+ _page(NULL),
+ _objects(0),
+ _bytes(0) {}
+
+ZMarkCache::ZMarkCache(size_t nstripes) :
+ _shift(ZMarkStripeShift + exact_log2(nstripes)) {}
+
+ZMarkCache::~ZMarkCache() {
+ // Evict all entries
+ for (size_t i = 0; i < ZMarkCacheSize; i++) {
+ _cache[i].evict();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zMarkCache.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+#ifndef SHARE_GC_Z_ZMARKCACHE_HPP
+#define SHARE_GC_Z_ZMARKCACHE_HPP
+
+#include "gc/z/zGlobals.hpp"
+#include "memory/allocation.hpp"
+
+class ZPage;
+
+class ZMarkCacheEntry {
+private:
+ ZPage* _page;
+ uint32_t _objects;
+ size_t _bytes;
+
+public:
+ ZMarkCacheEntry();
+
+ void inc_live(ZPage* page, size_t bytes);
+ void evict();
+};
+
+class ZMarkCache : public StackObj {
+private:
+ const size_t _shift;
+ ZMarkCacheEntry _cache[ZMarkCacheSize];
+
+public:
+ ZMarkCache(size_t nstripes);
+ ~ZMarkCache();
+
+ void inc_live(ZPage* page, size_t bytes);
+};
+
+#endif // SHARE_GC_Z_ZMARKCACHE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zMarkCache.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+#ifndef SHARE_GC_Z_ZMARKCACHE_INLINE_HPP
+#define SHARE_GC_Z_ZMARKCACHE_INLINE_HPP
+
+#include "gc/z/zMarkCache.hpp"
+#include "gc/z/zPage.inline.hpp"
+
+inline void ZMarkCacheEntry::inc_live(ZPage* page, size_t bytes) {
+ if (_page == page) {
+ // Cache hit
+ _objects++;
+ _bytes += bytes;
+ } else {
+ // Cache miss
+ evict();
+ _page = page;
+ _objects = 1;
+ _bytes = bytes;
+ }
+}
+
+inline void ZMarkCacheEntry::evict() {
+ if (_page != NULL) {
+ // Write cached data out to page
+ _page->inc_live_atomic(_objects, _bytes);
+ _page = NULL;
+ }
+}
+
+inline void ZMarkCache::inc_live(ZPage* page, size_t bytes) {
+ const size_t mask = ZMarkCacheSize - 1;
+ const size_t index = (page->start() >> _shift) & mask;
+ _cache[index].inc_live(page, bytes);
+}
+
+#endif // SHARE_GC_Z_ZMARKCACHE_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zMarkStack.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,392 @@
+/*
+ * 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 "gc/z/zErrno.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zLock.inline.hpp"
+#include "gc/z/zMarkStack.inline.hpp"
+#include "logging/log.hpp"
+#include "runtime/atomic.hpp"
+#include "utilities/debug.hpp"
+
+#include <sys/mman.h>
+#include <sys/types.h>
+
+ZMarkStackSpace::ZMarkStackSpace() :
+ _expand_lock(),
+ _top(0),
+ _end(0) {
+ assert(ZMarkStacksMax >= ZMarkStackSpaceExpandSize, "ZMarkStacksMax too small");
+ assert(ZMarkStacksMax <= ZMarkStackSpaceSize, "ZMarkStacksMax too large");
+
+ // Reserve address space
+ const void* res = mmap((void*)ZMarkStackSpaceStart, ZMarkStackSpaceSize,
+ PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0);
+ if (res != (void*)ZMarkStackSpaceStart) {
+ log_error(gc, marking)("Failed to reserve address space for marking stacks");
+ return;
+ }
+
+ // Successfully initialized
+ _top = _end = ZMarkStackSpaceStart;
+}
+
+bool ZMarkStackSpace::is_initialized() const {
+ return _top != 0;
+}
+
+bool ZMarkStackSpace::expand() {
+ const size_t max = ZMarkStackSpaceStart + ZMarkStacksMax;
+ if (_end + ZMarkStackSpaceExpandSize > max) {
+ // Expansion limit reached
+ return false;
+ }
+
+ void* const res = mmap((void*)_end, ZMarkStackSpaceExpandSize,
+ PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE|MAP_FIXED, -1, 0);
+ if (res == MAP_FAILED) {
+ ZErrno err;
+ log_error(gc, marking)("Failed to map memory for marking stacks (%s)", err.to_string());
+ return false;
+ }
+
+ return true;
+}
+
+uintptr_t ZMarkStackSpace::alloc_space(size_t size) {
+ uintptr_t top = _top;
+
+ for (;;) {
+ const uintptr_t new_top = top + size;
+ if (new_top > _end) {
+ // Not enough space left
+ return 0;
+ }
+
+ const uintptr_t prev_top = Atomic::cmpxchg(new_top, &_top, top);
+ if (prev_top == top) {
+ // Success
+ return top;
+ }
+
+ // Retry
+ top = prev_top;
+ }
+}
+
+uintptr_t ZMarkStackSpace::expand_and_alloc_space(size_t size) {
+ ZLocker locker(&_expand_lock);
+
+ // Retry allocation before expanding
+ uintptr_t addr = alloc_space(size);
+ if (addr != 0) {
+ return addr;
+ }
+
+ // Expand stack space
+ if (!expand()) {
+ // We currently can't handle the situation where we
+ // are running out of mark stack space.
+ fatal("Mark stack overflow (allocated " SIZE_FORMAT "M, size " SIZE_FORMAT "M, max " SIZE_FORMAT "M),"
+ " use -XX:ZMarkStacksMax=? to increase this limit",
+ (_end - ZMarkStackSpaceStart) / M, size / M, ZMarkStacksMax / M);
+ return 0;
+ }
+
+ log_debug(gc, marking)("Expanding mark stack space: " SIZE_FORMAT "M->" SIZE_FORMAT "M",
+ (_end - ZMarkStackSpaceStart) / M,
+ (_end - ZMarkStackSpaceStart + ZMarkStackSpaceExpandSize) / M);
+
+ // Increment top before end to make sure another
+ // thread can't steal out newly expanded space.
+ addr = Atomic::add(size, &_top) - size;
+ _end += ZMarkStackSpaceExpandSize;
+
+ return addr;
+}
+
+uintptr_t ZMarkStackSpace::alloc(size_t size) {
+ const uintptr_t addr = alloc_space(size);
+ if (addr != 0) {
+ return addr;
+ }
+
+ return expand_and_alloc_space(size);
+}
+
+ZMarkStackAllocator::ZMarkStackAllocator() :
+ _freelist(),
+ _space() {
+ guarantee(sizeof(ZMarkStack) == ZMarkStackSize, "Size mismatch");
+ guarantee(sizeof(ZMarkStackMagazine) <= ZMarkStackSize, "Size mismatch");
+
+ // Prime free list to avoid an immediate space
+ // expansion when marking starts.
+ if (_space.is_initialized()) {
+ prime_freelist();
+ }
+}
+
+bool ZMarkStackAllocator::is_initialized() const {
+ return _space.is_initialized();
+}
+
+void ZMarkStackAllocator::prime_freelist() {
+ for (size_t size = 0; size < ZMarkStackSpaceExpandSize; size += ZMarkStackMagazineSize) {
+ const uintptr_t addr = _space.alloc(ZMarkStackMagazineSize);
+ ZMarkStackMagazine* const magazine = create_magazine_from_space(addr, ZMarkStackMagazineSize);
+ free_magazine(magazine);
+ }
+}
+
+ZMarkStackMagazine* ZMarkStackAllocator::create_magazine_from_space(uintptr_t addr, size_t size) {
+ assert(is_aligned(size, ZMarkStackSize), "Invalid size");
+
+ // Use first stack as magazine
+ ZMarkStackMagazine* const magazine = new ((void*)addr) ZMarkStackMagazine();
+ for (size_t i = ZMarkStackSize; i < size; i += ZMarkStackSize) {
+ ZMarkStack* const stack = new ((void*)(addr + i)) ZMarkStack();
+ const bool success = magazine->push(stack);
+ assert(success, "Magazine should never get full");
+ }
+
+ return magazine;
+}
+
+ZMarkStackMagazine* ZMarkStackAllocator::alloc_magazine() {
+ // Try allocating from the free list first
+ ZMarkStackMagazine* const magazine = _freelist.pop_atomic();
+ if (magazine != NULL) {
+ return magazine;
+ }
+
+ // Allocate new magazine
+ const uintptr_t addr = _space.alloc(ZMarkStackMagazineSize);
+ if (addr == 0) {
+ return NULL;
+ }
+
+ return create_magazine_from_space(addr, ZMarkStackMagazineSize);
+}
+
+void ZMarkStackAllocator::free_magazine(ZMarkStackMagazine* magazine) {
+ _freelist.push_atomic(magazine);
+}
+
+ZMarkStripe::ZMarkStripe() :
+ _published(),
+ _overflowed() {}
+
+ZMarkStripeSet::ZMarkStripeSet() :
+ _nstripes(0),
+ _nstripes_mask(0),
+ _stripes() {}
+
+void ZMarkStripeSet::set_nstripes(size_t nstripes) {
+ assert(is_power_of_2(nstripes), "Must be a power of two");
+ assert(is_power_of_2(ZMarkStripesMax), "Must be a power of two");
+ assert(nstripes >= 1, "Invalid number of stripes");
+ assert(nstripes <= ZMarkStripesMax, "Invalid number of stripes");
+
+ _nstripes = nstripes;
+ _nstripes_mask = nstripes - 1;
+
+ log_debug(gc, marking)("Using " SIZE_FORMAT " mark stripes", _nstripes);
+}
+
+bool ZMarkStripeSet::is_empty() const {
+ for (size_t i = 0; i < _nstripes; i++) {
+ if (!_stripes[i].is_empty()) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+ZMarkStripe* ZMarkStripeSet::stripe_for_worker(uint nworkers, uint worker_id) {
+ const size_t spillover_limit = (nworkers / _nstripes) * _nstripes;
+ size_t index;
+
+ if (worker_id < spillover_limit) {
+ // Not a spillover worker, use natural stripe
+ index = worker_id & _nstripes_mask;
+ } else {
+ // Distribute spillover workers evenly across stripes
+ const size_t spillover_nworkers = nworkers - spillover_limit;
+ const size_t spillover_worker_id = worker_id - spillover_limit;
+ const double spillover_chunk = (double)_nstripes / (double)spillover_nworkers;
+ index = spillover_worker_id * spillover_chunk;
+ }
+
+ assert(index < _nstripes, "Invalid index");
+ return &_stripes[index];
+}
+
+ZMarkThreadLocalStacks::ZMarkThreadLocalStacks() :
+ _magazine(NULL) {
+ for (size_t i = 0; i < ZMarkStripesMax; i++) {
+ _stacks[i] = NULL;
+ }
+}
+
+bool ZMarkThreadLocalStacks::is_empty(const ZMarkStripeSet* stripes) const {
+ for (size_t i = 0; i < stripes->nstripes(); i++) {
+ ZMarkStack* const stack = _stacks[i];
+ if (stack != NULL) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+ZMarkStack* ZMarkThreadLocalStacks::allocate_stack(ZMarkStackAllocator* allocator) {
+ if (_magazine == NULL) {
+ // Allocate new magazine
+ _magazine = allocator->alloc_magazine();
+ if (_magazine == NULL) {
+ return NULL;
+ }
+ }
+
+ ZMarkStack* stack = NULL;
+
+ if (!_magazine->pop(stack)) {
+ // Magazine is empty, convert magazine into a new stack
+ _magazine->~ZMarkStackMagazine();
+ stack = new ((void*)_magazine) ZMarkStack();
+ _magazine = NULL;
+ }
+
+ return stack;
+}
+
+void ZMarkThreadLocalStacks::free_stack(ZMarkStackAllocator* allocator, ZMarkStack* stack) {
+ for (;;) {
+ if (_magazine == NULL) {
+ // Convert stack into a new magazine
+ stack->~ZMarkStack();
+ _magazine = new ((void*)stack) ZMarkStackMagazine();
+ return;
+ }
+
+ if (_magazine->push(stack)) {
+ // Success
+ return;
+ }
+
+ // Free and uninstall full magazine
+ allocator->free_magazine(_magazine);
+ _magazine = NULL;
+ }
+}
+
+bool ZMarkThreadLocalStacks::push_slow(ZMarkStackAllocator* allocator,
+ ZMarkStripe* stripe,
+ ZMarkStack** stackp,
+ ZMarkStackEntry entry,
+ bool publish) {
+ ZMarkStack* stack = *stackp;
+
+ for (;;) {
+ if (stack == NULL) {
+ // Allocate and install new stack
+ *stackp = stack = allocate_stack(allocator);
+ if (stack == NULL) {
+ // Out of mark stack memory
+ return false;
+ }
+ }
+
+ if (stack->push(entry)) {
+ // Success
+ return true;
+ }
+
+ // Publish/Overflow and uninstall stack
+ stripe->publish_stack(stack, publish);
+ *stackp = stack = NULL;
+ }
+}
+
+bool ZMarkThreadLocalStacks::pop_slow(ZMarkStackAllocator* allocator,
+ ZMarkStripe* stripe,
+ ZMarkStack** stackp,
+ ZMarkStackEntry& entry) {
+ ZMarkStack* stack = *stackp;
+
+ for (;;) {
+ if (stack == NULL) {
+ // Try steal and install stack
+ *stackp = stack = stripe->steal_stack();
+ if (stack == NULL) {
+ // Nothing to steal
+ return false;
+ }
+ }
+
+ if (stack->pop(entry)) {
+ // Success
+ return true;
+ }
+
+ // Free and uninstall stack
+ free_stack(allocator, stack);
+ *stackp = stack = NULL;
+ }
+}
+
+bool ZMarkThreadLocalStacks::flush(ZMarkStackAllocator* allocator, ZMarkStripeSet* stripes) {
+ bool flushed = false;
+
+ // Flush all stacks
+ for (size_t i = 0; i < stripes->nstripes(); i++) {
+ ZMarkStripe* const stripe = stripes->stripe_at(i);
+ ZMarkStack** const stackp = &_stacks[i];
+ ZMarkStack* const stack = *stackp;
+ if (stack == NULL) {
+ continue;
+ }
+
+ // Free/Publish and uninstall stack
+ if (stack->is_empty()) {
+ free_stack(allocator, stack);
+ } else {
+ stripe->publish_stack(stack);
+ flushed = true;
+ }
+ *stackp = NULL;
+ }
+
+ return flushed;
+}
+
+void ZMarkThreadLocalStacks::free(ZMarkStackAllocator* allocator) {
+ // Free and uninstall magazine
+ if (_magazine != NULL) {
+ allocator->free_magazine(_magazine);
+ _magazine = NULL;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zMarkStack.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,192 @@
+/*
+ * 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.
+ */
+
+#ifndef SHARE_GC_Z_ZMARKSTACK_HPP
+#define SHARE_GC_Z_ZMARKSTACK_HPP
+
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zLock.hpp"
+#include "gc/z/zMarkStackEntry.hpp"
+#include "memory/allocation.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+template <typename T, size_t S>
+class ZStack {
+private:
+ size_t _top;
+ ZStack<T, S>* _next;
+ T _slots[S];
+
+ bool is_full() const;
+
+public:
+ ZStack();
+
+ bool is_empty() const;
+
+ bool push(T value);
+ bool pop(T& value);
+
+ ZStack<T, S>* next() const;
+ ZStack<T, S>** next_addr();
+};
+
+template <typename T>
+class ZStackList {
+private:
+ T* volatile _head;
+
+ T* encode_versioned_pointer(const T* stack, uint32_t version) const;
+ void decode_versioned_pointer(const T* vstack, T** stack, uint32_t* version) const;
+
+public:
+ ZStackList();
+
+ bool is_empty() const;
+
+ void push_atomic(T* stack);
+ T* pop_atomic();
+};
+
+typedef ZStack<ZMarkStackEntry, ZMarkStackSlots> ZMarkStack;
+typedef ZStackList<ZMarkStack> ZMarkStackList;
+typedef ZStack<ZMarkStack*, ZMarkStackMagazineSlots> ZMarkStackMagazine;
+typedef ZStackList<ZMarkStackMagazine> ZMarkStackMagazineList;
+
+class ZMarkStackSpace {
+private:
+ ZLock _expand_lock;
+ volatile uintptr_t _top;
+ volatile uintptr_t _end;
+
+ bool expand();
+
+ uintptr_t alloc_space(size_t size);
+ uintptr_t expand_and_alloc_space(size_t size);
+
+public:
+ ZMarkStackSpace();
+
+ bool is_initialized() const;
+
+ uintptr_t alloc(size_t size);
+};
+
+class ZMarkStackAllocator {
+private:
+ ZMarkStackMagazineList _freelist ATTRIBUTE_ALIGNED(ZCacheLineSize);
+ ZMarkStackSpace _space ATTRIBUTE_ALIGNED(ZCacheLineSize);
+
+ void prime_freelist();
+ ZMarkStackMagazine* create_magazine_from_space(uintptr_t addr, size_t size);
+
+public:
+ ZMarkStackAllocator();
+
+ bool is_initialized() const;
+
+ ZMarkStackMagazine* alloc_magazine();
+ void free_magazine(ZMarkStackMagazine* magazine);
+};
+
+class ZMarkStripe {
+private:
+ ZMarkStackList _published ATTRIBUTE_ALIGNED(ZCacheLineSize);
+ ZMarkStackList _overflowed ATTRIBUTE_ALIGNED(ZCacheLineSize);
+
+public:
+ ZMarkStripe();
+
+ bool is_empty() const;
+
+ void publish_stack(ZMarkStack* stack, bool publish = true);
+ ZMarkStack* steal_stack();
+};
+
+class ZMarkStripeSet {
+private:
+ size_t _nstripes;
+ size_t _nstripes_mask;
+ ZMarkStripe _stripes[ZMarkStripesMax];
+
+public:
+ ZMarkStripeSet();
+
+ size_t nstripes() const;
+ void set_nstripes(size_t nstripes);
+
+ bool is_empty() const;
+
+ size_t stripe_id(const ZMarkStripe* stripe) const;
+ ZMarkStripe* stripe_at(size_t index);
+ ZMarkStripe* stripe_next(ZMarkStripe* stripe);
+ ZMarkStripe* stripe_for_worker(uint nworkers, uint worker_id);
+ ZMarkStripe* stripe_for_addr(uintptr_t addr);
+};
+
+class ZMarkThreadLocalStacks {
+private:
+ ZMarkStackMagazine* _magazine;
+ ZMarkStack* _stacks[ZMarkStripesMax];
+
+ ZMarkStack* allocate_stack(ZMarkStackAllocator* allocator);
+ void free_stack(ZMarkStackAllocator* allocator, ZMarkStack* stack);
+
+ bool push_slow(ZMarkStackAllocator* allocator,
+ ZMarkStripe* stripe,
+ ZMarkStack** stackp,
+ ZMarkStackEntry entry,
+ bool publish);
+
+ bool pop_slow(ZMarkStackAllocator* allocator,
+ ZMarkStripe* stripe,
+ ZMarkStack** stackp,
+ ZMarkStackEntry& entry);
+
+public:
+ ZMarkThreadLocalStacks();
+
+ bool is_empty(const ZMarkStripeSet* stripes) const;
+
+ void install(ZMarkStripeSet* stripes,
+ ZMarkStripe* stripe,
+ ZMarkStack* stack);
+
+ bool push(ZMarkStackAllocator* allocator,
+ ZMarkStripeSet* stripes,
+ ZMarkStripe* stripe,
+ ZMarkStackEntry entry,
+ bool publish);
+
+ bool pop(ZMarkStackAllocator* allocator,
+ ZMarkStripeSet* stripes,
+ ZMarkStripe* stripe,
+ ZMarkStackEntry& entry);
+
+ bool flush(ZMarkStackAllocator* allocator,
+ ZMarkStripeSet* stripes);
+
+ void free(ZMarkStackAllocator* allocator);
+};
+
+#endif // SHARE_GC_Z_ZMARKSTACK_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zMarkStack.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,249 @@
+/*
+ * 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.
+ */
+
+#ifndef SHARE_GC_Z_ZMARKSTACK_INLINE_HPP
+#define SHARE_GC_Z_ZMARKSTACK_INLINE_HPP
+
+#include "gc/z/zMarkStack.hpp"
+#include "utilities/debug.hpp"
+#include "runtime/atomic.hpp"
+
+template <typename T, size_t S>
+inline ZStack<T, S>::ZStack() :
+ _top(0),
+ _next(NULL) {}
+
+template <typename T, size_t S>
+inline bool ZStack<T, S>::is_empty() const {
+ return _top == 0;
+}
+
+template <typename T, size_t S>
+inline bool ZStack<T, S>::is_full() const {
+ return _top == S;
+}
+
+template <typename T, size_t S>
+inline bool ZStack<T, S>::push(T value) {
+ if (is_full()) {
+ return false;
+ }
+
+ _slots[_top++] = value;
+ return true;
+}
+
+template <typename T, size_t S>
+inline bool ZStack<T, S>::pop(T& value) {
+ if (is_empty()) {
+ return false;
+ }
+
+ value = _slots[--_top];
+ return true;
+}
+
+template <typename T, size_t S>
+inline ZStack<T, S>* ZStack<T, S>::next() const {
+ return _next;
+}
+
+template <typename T, size_t S>
+inline ZStack<T, S>** ZStack<T, S>::next_addr() {
+ return &_next;
+}
+
+template <typename T>
+inline ZStackList<T>::ZStackList() :
+ _head(encode_versioned_pointer(NULL, 0)) {}
+
+template <typename T>
+inline T* ZStackList<T>::encode_versioned_pointer(const T* stack, uint32_t version) const {
+ uint64_t addr;
+
+ if (stack == NULL) {
+ addr = (uint32_t)-1;
+ } else {
+ addr = ((uint64_t)stack - ZMarkStackSpaceStart) >> ZMarkStackSizeShift;
+ }
+
+ return (T*)((addr << 32) | (uint64_t)version);
+}
+
+template <typename T>
+inline void ZStackList<T>::decode_versioned_pointer(const T* vstack, T** stack, uint32_t* version) const {
+ const uint64_t addr = (uint64_t)vstack >> 32;
+
+ if (addr == (uint32_t)-1) {
+ *stack = NULL;
+ } else {
+ *stack = (T*)((addr << ZMarkStackSizeShift) + ZMarkStackSpaceStart);
+ }
+
+ *version = (uint32_t)(uint64_t)vstack;
+}
+
+template <typename T>
+inline bool ZStackList<T>::is_empty() const {
+ const T* vstack = _head;
+ T* stack = NULL;
+ uint32_t version = 0;
+
+ decode_versioned_pointer(vstack, &stack, &version);
+ return stack == NULL;
+}
+
+template <typename T>
+inline void ZStackList<T>::push_atomic(T* stack) {
+ T* vstack = _head;
+ uint32_t version = 0;
+
+ for (;;) {
+ decode_versioned_pointer(vstack, stack->next_addr(), &version);
+ T* const new_vstack = encode_versioned_pointer(stack, version + 1);
+ T* const prev_vstack = Atomic::cmpxchg(new_vstack, &_head, vstack);
+ if (prev_vstack == vstack) {
+ // Success
+ break;
+ }
+
+ // Retry
+ vstack = prev_vstack;
+ }
+}
+
+template <typename T>
+inline T* ZStackList<T>::pop_atomic() {
+ T* vstack = _head;
+ T* stack = NULL;
+ uint32_t version = 0;
+
+ for (;;) {
+ decode_versioned_pointer(vstack, &stack, &version);
+ if (stack == NULL) {
+ return NULL;
+ }
+
+ T* const new_vstack = encode_versioned_pointer(stack->next(), version + 1);
+ T* const prev_vstack = Atomic::cmpxchg(new_vstack, &_head, vstack);
+ if (prev_vstack == vstack) {
+ // Success
+ return stack;
+ }
+
+ // Retry
+ vstack = prev_vstack;
+ }
+}
+
+inline bool ZMarkStripe::is_empty() const {
+ return _published.is_empty() && _overflowed.is_empty();
+}
+
+inline void ZMarkStripe::publish_stack(ZMarkStack* stack, bool publish) {
+ // A stack is published either on the published list or the overflowed
+ // list. The published list is used by mutators publishing stacks for GC
+ // workers to work on, while the overflowed list is used by GC workers
+ // to publish stacks that overflowed. The intention here is to avoid
+ // contention between mutators and GC workers as much as possible, while
+ // still allowing GC workers to help out and steal work from each other.
+ if (publish) {
+ _published.push_atomic(stack);
+ } else {
+ _overflowed.push_atomic(stack);
+ }
+}
+
+inline ZMarkStack* ZMarkStripe::steal_stack() {
+ // Steal overflowed stacks first, then published stacks
+ ZMarkStack* const stack = _overflowed.pop_atomic();
+ if (stack != NULL) {
+ return stack;
+ }
+
+ return _published.pop_atomic();
+}
+
+inline size_t ZMarkStripeSet::nstripes() const {
+ return _nstripes;
+}
+
+inline size_t ZMarkStripeSet::stripe_id(const ZMarkStripe* stripe) const {
+ const size_t index = ((uintptr_t)stripe - (uintptr_t)_stripes) / sizeof(ZMarkStripe);
+ assert(index < _nstripes, "Invalid index");
+ return index;
+}
+
+inline ZMarkStripe* ZMarkStripeSet::stripe_at(size_t index) {
+ assert(index < _nstripes, "Invalid index");
+ return &_stripes[index];
+}
+
+inline ZMarkStripe* ZMarkStripeSet::stripe_next(ZMarkStripe* stripe) {
+ const size_t index = (stripe_id(stripe) + 1) & _nstripes_mask;
+ assert(index < _nstripes, "Invalid index");
+ return &_stripes[index];
+}
+
+inline ZMarkStripe* ZMarkStripeSet::stripe_for_addr(uintptr_t addr) {
+ const size_t index = (addr >> ZMarkStripeShift) & _nstripes_mask;
+ assert(index < _nstripes, "Invalid index");
+ return &_stripes[index];
+}
+
+inline void ZMarkThreadLocalStacks::install(ZMarkStripeSet* stripes,
+ ZMarkStripe* stripe,
+ ZMarkStack* stack) {
+ ZMarkStack** const stackp = &_stacks[stripes->stripe_id(stripe)];
+ assert(*stackp == NULL, "Should be empty");
+ *stackp = stack;
+}
+
+inline bool ZMarkThreadLocalStacks::push(ZMarkStackAllocator* allocator,
+ ZMarkStripeSet* stripes,
+ ZMarkStripe* stripe,
+ ZMarkStackEntry entry,
+ bool publish) {
+ ZMarkStack** const stackp = &_stacks[stripes->stripe_id(stripe)];
+ ZMarkStack* const stack = *stackp;
+ if (stack != NULL && stack->push(entry)) {
+ return true;
+ }
+
+ return push_slow(allocator, stripe, stackp, entry, publish);
+}
+
+inline bool ZMarkThreadLocalStacks::pop(ZMarkStackAllocator* allocator,
+ ZMarkStripeSet* stripes,
+ ZMarkStripe* stripe,
+ ZMarkStackEntry& entry) {
+ ZMarkStack** const stackp = &_stacks[stripes->stripe_id(stripe)];
+ ZMarkStack* const stack = *stackp;
+ if (stack != NULL && stack->pop(entry)) {
+ return true;
+ }
+
+ return pop_slow(allocator, stripe, stackp, entry);
+}
+
+#endif // SHARE_GC_Z_ZMARKSTACK_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zMarkStackEntry.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef SHARE_GC_Z_ZMARKSTACKENTRY_HPP
+#define SHARE_GC_Z_ZMARKSTACKENTRY_HPP
+
+#include "gc/z/zBitField.hpp"
+#include "memory/allocation.hpp"
+
+//
+// Mark stack entry layout
+// -----------------------
+//
+// Object entry
+// ------------
+//
+// 6
+// 3 2 1 0
+// +---------------------------------------------------------------------+-+-+
+// |11111111 11111111 11111111 11111111 11111111 11111111 11111111 111111|1|1|
+// +---------------------------------------------------------------------+-+-+
+// | | |
+// | 1-1 Partial Array Flag (1-bit) * |
+// | |
+// | 0-0 Final Flag (1-bit) *
+// |
+// * 63-2 Object Address (62-bits)
+//
+//
+// Partial array entry
+// -------------------
+//
+// 6 3 3
+// 3 2 1 2 1 0
+// +------------------------------------+---------------------------------+-+-+
+// |11111111 11111111 11111111 11111111 |11111111 11111111 11111111 111111|1|1|
+// +------------------------------------+---------------------------------+-+-+
+// | | | |
+// | | 1-1 Partial Array Flag (1-bit) * |
+// | | |
+// | | 0-0 Final Flag (1-bit) *
+// | |
+// | * 31-2 Partial Array Length (30-bits)
+// |
+// * 63-32 Partial Array Address Offset (32-bits)
+//
+
+class ZMarkStackEntry {
+private:
+ typedef ZBitField<uint64_t, bool, 0, 1> field_finalizable;
+ typedef ZBitField<uint64_t, bool, 1, 1> field_partial_array;
+ typedef ZBitField<uint64_t, uintptr_t, 2, 62> field_object_address;
+ typedef ZBitField<uint64_t, size_t, 2, 30> field_partial_array_length;
+ typedef ZBitField<uint64_t, size_t, 32, 32> field_partial_array_offset;
+
+ uint64_t _entry;
+
+public:
+ ZMarkStackEntry() {
+ // This constructor is intentionally left emtpy and does not initialize
+ // _entry to allow it to be optimized out when instantiating ZMarkStack,
+ // which has a long array of ZMarkStackEntry elements, but doesn't care
+ // what _entry is initialized to.
+ }
+
+ ZMarkStackEntry(uintptr_t object_address, bool finalizable) :
+ _entry(field_object_address::encode(object_address) |
+ field_partial_array::encode(false) |
+ field_finalizable::encode(finalizable)) {}
+
+ ZMarkStackEntry(size_t partial_array_offset, size_t partial_array_length, bool finalizable) :
+ _entry(field_partial_array_offset::encode(partial_array_offset) |
+ field_partial_array_length::encode(partial_array_length) |
+ field_partial_array::encode(true) |
+ field_finalizable::encode(finalizable)) {}
+
+ bool finalizable() const {
+ return field_finalizable::decode(_entry);
+ }
+
+ bool partial_array() const {
+ return field_partial_array::decode(_entry);
+ }
+
+ size_t partial_array_offset() const {
+ return field_partial_array_offset::decode(_entry);
+ }
+
+ size_t partial_array_length() const {
+ return field_partial_array_length::decode(_entry);
+ }
+
+ uintptr_t object_address() const {
+ return field_object_address::decode(_entry);
+ }
+};
+
+#endif // SHARE_GC_Z_ZMARKSTACKENTRY_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zMarkTerminate.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,54 @@
+/*
+ * 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
+ * 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_Z_ZMARKTERMINATE_HPP
+#define SHARE_GC_Z_ZMARKTERMINATE_HPP
+
+#include "gc/z/zGlobals.hpp"
+#include "memory/allocation.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class ZMarkTerminate {
+private:
+ uint _nworkers;
+ volatile uint _nworking_stage0 ATTRIBUTE_ALIGNED(ZCacheLineSize);
+ volatile uint _nworking_stage1;
+
+ bool enter_stage(volatile uint* nworking_stage);
+ void exit_stage(volatile uint* nworking_stage);
+ bool try_exit_stage(volatile uint* nworking_stage);
+
+public:
+ ZMarkTerminate();
+
+ void reset(uint nworkers);
+
+ bool enter_stage0();
+ void exit_stage0();
+ bool try_exit_stage0();
+
+ bool enter_stage1();
+ bool try_exit_stage1();
+};
+
+#endif // SHARE_GC_Z_ZMARKTERMINATE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zMarkTerminate.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef SHARE_GC_Z_ZMARKTERMINATE_INLINE_HPP
+#define SHARE_GC_Z_ZMARKTERMINATE_INLINE_HPP
+
+#include "runtime/atomic.hpp"
+#include "runtime/orderAccess.hpp"
+
+inline ZMarkTerminate::ZMarkTerminate() :
+ _nworkers(0),
+ _nworking_stage0(0),
+ _nworking_stage1(0) {}
+
+inline bool ZMarkTerminate::enter_stage(volatile uint* nworking_stage) {
+ return Atomic::sub(1u, nworking_stage) == 0;
+}
+
+inline void ZMarkTerminate::exit_stage(volatile uint* nworking_stage) {
+ Atomic::add(1u, nworking_stage);
+}
+
+inline bool ZMarkTerminate::try_exit_stage(volatile uint* nworking_stage) {
+ uint nworking = Atomic::load(nworking_stage);
+
+ for (;;) {
+ if (nworking == 0) {
+ return false;
+ }
+
+ const uint new_nworking = nworking + 1;
+ const uint prev_nworking = Atomic::cmpxchg(new_nworking, nworking_stage, nworking);
+ if (prev_nworking == nworking) {
+ // Success
+ return true;
+ }
+
+ // Retry
+ nworking = prev_nworking;
+ }
+}
+
+inline void ZMarkTerminate::reset(uint nworkers) {
+ _nworkers = _nworking_stage0 = _nworking_stage1 = nworkers;
+}
+
+inline bool ZMarkTerminate::enter_stage0() {
+ return enter_stage(&_nworking_stage0);
+}
+
+inline void ZMarkTerminate::exit_stage0() {
+ exit_stage(&_nworking_stage0);
+}
+
+inline bool ZMarkTerminate::try_exit_stage0() {
+ return try_exit_stage(&_nworking_stage0);
+}
+
+inline bool ZMarkTerminate::enter_stage1() {
+ return enter_stage(&_nworking_stage1);
+}
+
+inline bool ZMarkTerminate::try_exit_stage1() {
+ return try_exit_stage(&_nworking_stage1);
+}
+
+#endif // SHARE_GC_Z_ZMARKTERMINATE_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zMemory.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2015, 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 "gc/z/zList.inline.hpp"
+#include "gc/z/zMemory.inline.hpp"
+#include "memory/allocation.inline.hpp"
+
+uintptr_t ZMemoryManager::alloc_from_front(size_t size) {
+ ZListIterator<ZMemory> iter(&_freelist);
+ for (ZMemory* area; iter.next(&area);) {
+ if (area->size() >= size) {
+ if (area->size() == size) {
+ // Exact match, remove area
+ const uintptr_t start = area->start();
+ _freelist.remove(area);
+ delete area;
+ return start;
+ } else {
+ // Larger than requested, shrink area
+ const uintptr_t start = area->start();
+ area->shrink_from_front(size);
+ return start;
+ }
+ }
+ }
+
+ // Out of memory
+ return UINTPTR_MAX;
+}
+
+uintptr_t ZMemoryManager::alloc_from_back(size_t size) {
+ ZListReverseIterator<ZMemory> iter(&_freelist);
+ for (ZMemory* area; iter.next(&area);) {
+ if (area->size() >= size) {
+ if (area->size() == size) {
+ // Exact match, remove area
+ const uintptr_t start = area->start();
+ _freelist.remove(area);
+ delete area;
+ return start;
+ } else {
+ // Larger than requested, shrink area
+ area->shrink_from_back(size);
+ return area->end();
+ }
+ }
+ }
+
+ // Out of memory
+ return UINTPTR_MAX;
+}
+
+void ZMemoryManager::free(uintptr_t start, size_t size) {
+ assert(start != UINTPTR_MAX, "Invalid address");
+ const uintptr_t end = start + size;
+
+ ZListIterator<ZMemory> iter(&_freelist);
+ for (ZMemory* area; iter.next(&area);) {
+ if (start < area->start()) {
+ ZMemory* const prev = _freelist.prev(area);
+ if (prev != NULL && start == prev->end()) {
+ if (end == area->start()) {
+ // Merge with prev and current area
+ prev->grow_from_back(size + area->size());
+ _freelist.remove(area);
+ delete area;
+ } else {
+ // Merge with prev area
+ prev->grow_from_back(size);
+ }
+ } else if (end == area->start()) {
+ // Merge with current area
+ area->grow_from_front(size);
+ } else {
+ // Insert new area before current area
+ assert(end < area->start(), "Areas must not overlap");
+ ZMemory* new_area = new ZMemory(start, size);
+ _freelist.insert_before(area, new_area);
+ }
+
+ // Done
+ return;
+ }
+ }
+
+ // Insert last
+ ZMemory* const last = _freelist.last();
+ if (last != NULL && start == last->end()) {
+ // Merge with last area
+ last->grow_from_back(size);
+ } else {
+ // Insert new area last
+ ZMemory* new_area = new ZMemory(start, size);
+ _freelist.insert_last(new_area);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zMemory.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZMEMORY_HPP
+#define SHARE_GC_Z_ZMEMORY_HPP
+
+#include "gc/z/zList.hpp"
+#include "memory/allocation.hpp"
+
+class ZMemory : public CHeapObj<mtGC> {
+ friend class ZList<ZMemory>;
+
+private:
+ uintptr_t _start;
+ uintptr_t _end;
+ ZListNode<ZMemory> _node;
+
+public:
+ ZMemory(uintptr_t start, size_t size);
+
+ uintptr_t start() const;
+ uintptr_t end() const;
+ size_t size() const;
+
+ void shrink_from_front(size_t size);
+ void shrink_from_back(size_t size);
+ void grow_from_front(size_t size);
+ void grow_from_back(size_t size);
+};
+
+class ZMemoryManager {
+private:
+ ZList<ZMemory> _freelist;
+
+public:
+ uintptr_t alloc_from_front(size_t size);
+ uintptr_t alloc_from_back(size_t size);
+ void free(uintptr_t start, size_t size);
+};
+
+#endif // SHARE_GC_Z_ZMEMORY_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zMemory.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZMEMORY_INLINE_HPP
+#define SHARE_GC_Z_ZMEMORY_INLINE_HPP
+
+#include "gc/z/zMemory.hpp"
+#include "utilities/debug.hpp"
+
+inline ZMemory::ZMemory(uintptr_t start, size_t size) :
+ _start(start),
+ _end(start + size) {}
+
+inline uintptr_t ZMemory::start() const {
+ return _start;
+}
+
+inline uintptr_t ZMemory::end() const {
+ return _end;
+}
+
+inline size_t ZMemory::size() const {
+ return end() - start();
+}
+
+inline void ZMemory::shrink_from_front(size_t size) {
+ assert(this->size() > size, "Too small");
+ _start += size;
+}
+
+inline void ZMemory::shrink_from_back(size_t size) {
+ assert(this->size() > size, "Too small");
+ _end -= size;
+}
+
+inline void ZMemory::grow_from_front(size_t size) {
+ assert(start() >= size, "Too big");
+ _start -= size;
+}
+
+inline void ZMemory::grow_from_back(size_t size) {
+ _end += size;
+}
+
+#endif // SHARE_GC_Z_ZMEMORY_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zMessagePort.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZMESSAGEPORT_HPP
+#define SHARE_GC_Z_ZMESSAGEPORT_HPP
+
+#include "gc/z/zFuture.hpp"
+#include "gc/z/zList.hpp"
+#include "memory/allocation.hpp"
+#include "runtime/mutex.hpp"
+
+template <typename T> class ZMessageRequest;
+
+template <typename T>
+class ZMessagePort {
+private:
+ typedef ZMessageRequest<T> Request;
+
+ Monitor _monitor;
+ bool _has_message;
+ T _message;
+ uint64_t _seqnum;
+ ZList<Request> _queue;
+
+public:
+ ZMessagePort();
+
+ void send_sync(T message);
+ void send_async(T message);
+
+ T receive();
+ void ack();
+};
+
+class ZRendezvousPort {
+private:
+ ZMessagePort<bool> _port;
+
+public:
+ void signal();
+ void wait();
+ void ack();
+};
+
+#endif // SHARE_GC_Z_ZMESSAGEPORT_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zMessagePort.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZMESSAGEPORT_INLINE_HPP
+#define SHARE_GC_Z_ZMESSAGEPORT_INLINE_HPP
+
+#include "gc/z/zMessagePort.hpp"
+#include "gc/z/zFuture.inline.hpp"
+#include "gc/z/zList.inline.hpp"
+#include "runtime/mutexLocker.hpp"
+
+template <typename T>
+class ZMessageRequest : public StackObj {
+ friend class ZList<ZMessageRequest>;
+
+private:
+ T _message;
+ uint64_t _seqnum;
+ ZFuture<T> _result;
+ ZListNode<ZMessageRequest> _node;
+
+public:
+ void initialize(T message, uint64_t seqnum) {
+ _message = message;
+ _seqnum = seqnum;
+ }
+
+ T message() const {
+ return _message;
+ }
+
+ uint64_t seqnum() const {
+ return _seqnum;
+ }
+
+ void wait() {
+ const T message = _result.get();
+ assert(message == _message, "Message mismatch");
+ }
+
+ void satisfy(T message) {
+ _result.set(message);
+ }
+};
+
+template <typename T>
+inline ZMessagePort<T>::ZMessagePort() :
+ _monitor(Monitor::leaf,
+ "ZMessagePort",
+ Monitor::_allow_vm_block_flag,
+ Monitor::_safepoint_check_never),
+ _has_message(false),
+ _seqnum(0),
+ _queue() {}
+
+template <typename T>
+inline void ZMessagePort<T>::send_sync(T message) {
+ Request request;
+
+ {
+ // Enqueue message
+ MonitorLockerEx ml(&_monitor, Monitor::_no_safepoint_check_flag);
+ request.initialize(message, _seqnum);
+ _queue.insert_last(&request);
+ ml.notify();
+ }
+
+ // Wait for completion
+ request.wait();
+}
+
+template <typename T>
+inline void ZMessagePort<T>::send_async(T message) {
+ MonitorLockerEx ml(&_monitor, Monitor::_no_safepoint_check_flag);
+ if (!_has_message) {
+ // Post message
+ _message = message;
+ _has_message = true;
+ ml.notify();
+ }
+}
+
+template <typename T>
+inline T ZMessagePort<T>::receive() {
+ MonitorLockerEx ml(&_monitor, Monitor::_no_safepoint_check_flag);
+
+ // Wait for message
+ while (!_has_message && _queue.is_empty()) {
+ ml.wait(Monitor::_no_safepoint_check_flag);
+ }
+
+ // Increment request sequence number
+ _seqnum++;
+
+ if (!_has_message) {
+ // Message available in the queue
+ _message = _queue.first()->message();
+ _has_message = true;
+ }
+
+ return _message;
+}
+
+template <typename T>
+inline void ZMessagePort<T>::ack() {
+ MonitorLockerEx ml(&_monitor, Monitor::_no_safepoint_check_flag);
+
+ if (!_has_message) {
+ // Nothing to ack
+ return;
+ }
+
+ // Satisfy requests (and duplicates) in queue
+ ZListIterator<Request> iter(&_queue);
+ for (Request* request; iter.next(&request);) {
+ if (request->message() == _message && request->seqnum() < _seqnum) {
+ // Dequeue and satisfy request. Note that the dequeue operation must
+ // happen first, since the request will immediately be deallocated
+ // once it has been satisfied.
+ _queue.remove(request);
+ request->satisfy(_message);
+ }
+ }
+
+ if (_queue.is_empty()) {
+ // Queue is empty
+ _has_message = false;
+ } else {
+ // Post first message in queue
+ _message = _queue.first()->message();
+ }
+}
+
+inline void ZRendezvousPort::signal() {
+ _port.send_sync(true /* ignored */);
+}
+
+inline void ZRendezvousPort::wait() {
+ _port.receive();
+}
+
+inline void ZRendezvousPort::ack() {
+ _port.ack();
+}
+
+#endif // SHARE_GC_Z_ZMESSAGEPORT_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zMetronome.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2015, 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 "gc/z/zMetronome.hpp"
+#include "runtime/mutexLocker.hpp"
+#include "runtime/timer.hpp"
+#include "utilities/ticks.hpp"
+
+ZMetronome::ZMetronome(uint64_t hz) :
+ _monitor(Monitor::leaf, "ZMetronome", false, Monitor::_safepoint_check_never),
+ _interval_ms(MILLIUNITS / hz),
+ _start_ms(0),
+ _nticks(0),
+ _stopped(false) {}
+
+uint64_t ZMetronome::nticks() const {
+ return _nticks;
+}
+
+bool ZMetronome::wait_for_tick() {
+ if (_nticks++ == 0) {
+ // First tick, set start time
+ const Ticks now = Ticks::now();
+ _start_ms = TimeHelper::counter_to_millis(now.value());
+ }
+
+ for (;;) {
+ // We might wake up spuriously from wait, so always recalculate
+ // the timeout after a wakeup to see if we need to wait again.
+ const Ticks now = Ticks::now();
+ const uint64_t now_ms = TimeHelper::counter_to_millis(now.value());
+ const uint64_t next_ms = _start_ms + (_interval_ms * _nticks);
+ const int64_t timeout_ms = next_ms - now_ms;
+
+ MonitorLockerEx ml(&_monitor, Monitor::_no_safepoint_check_flag);
+ if (!_stopped && timeout_ms > 0) {
+ // Wait
+ ml.wait(Monitor::_no_safepoint_check_flag, timeout_ms);
+ } else {
+ // Tick
+ return !_stopped;
+ }
+ }
+}
+
+void ZMetronome::stop() {
+ MonitorLockerEx ml(&_monitor, Monitor::_no_safepoint_check_flag);
+ _stopped = true;
+ ml.notify();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zMetronome.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZMETRONOME_HPP
+#define SHARE_GC_Z_ZMETRONOME_HPP
+
+#include "memory/allocation.hpp"
+#include "runtime/mutex.hpp"
+
+class ZMetronome : public StackObj {
+private:
+ Monitor _monitor;
+ const uint64_t _interval_ms;
+ uint64_t _start_ms;
+ uint64_t _nticks;
+ bool _stopped;
+
+public:
+ ZMetronome(uint64_t hz);
+
+ uint64_t nticks() const;
+ bool wait_for_tick();
+ void stop();
+};
+
+#endif // SHARE_GC_Z_ZMETRONOME_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zNMethodTable.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,465 @@
+/*
+ * 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
+ * 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 "code/relocInfo.hpp"
+#include "code/nativeInst.hpp"
+#include "code/nmethod.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zHash.inline.hpp"
+#include "gc/z/zNMethodTable.hpp"
+#include "logging/log.hpp"
+#include "memory/allocation.inline.hpp"
+#include "memory/resourceArea.hpp"
+#include "oops/oop.inline.hpp"
+#include "runtime/atomic.hpp"
+#include "utilities/debug.hpp"
+
+class ZNMethodWithImmediateOops {
+private:
+ nmethod* const _nm;
+ const size_t _nimmediate_oops;
+
+ static size_t header_size();
+
+ ZNMethodWithImmediateOops(nmethod* nm, const GrowableArray<oop*>& immediate_oops);
+
+public:
+ static ZNMethodWithImmediateOops* create(nmethod* nm, const GrowableArray<oop*>& immediate_oops);
+ static void destroy(ZNMethodWithImmediateOops* nmi);
+
+ nmethod* method() const;
+ size_t immediate_oops_count() const;
+ oop** immediate_oops_begin() const;
+ oop** immediate_oops_begin_safe() const;
+ oop** immediate_oops_end() const;
+};
+
+size_t ZNMethodWithImmediateOops::header_size() {
+ const size_t size = sizeof(ZNMethodWithImmediateOops);
+ assert(is_aligned(size, sizeof(oop*)), "Header misaligned");
+ return size;
+}
+
+ZNMethodWithImmediateOops::ZNMethodWithImmediateOops(nmethod* nm, const GrowableArray<oop*>& immediate_oops) :
+ _nm(nm),
+ _nimmediate_oops(immediate_oops.length()) {
+ // Save all immediate oops
+ for (size_t i = 0; i < _nimmediate_oops; i++) {
+ immediate_oops_begin()[i] = immediate_oops.at(i);
+ }
+}
+
+ZNMethodWithImmediateOops* ZNMethodWithImmediateOops::create(nmethod* nm, const GrowableArray<oop*>& immediate_oops) {
+ // Allocate memory for the ZNMethodWithImmediateOops object
+ // plus the immediate oop* array that follows right after.
+ const size_t size = header_size() + (sizeof(oop*) * immediate_oops.length());
+ void* const method_with_immediate_oops = NEW_C_HEAP_ARRAY(uint8_t, size, mtGC);
+ return ::new (method_with_immediate_oops) ZNMethodWithImmediateOops(nm, immediate_oops);
+}
+
+void ZNMethodWithImmediateOops::destroy(ZNMethodWithImmediateOops* nmi) {
+ FREE_C_HEAP_ARRAY(uint8_t, nmi);
+}
+
+nmethod* ZNMethodWithImmediateOops::method() const {
+ return _nm;
+}
+
+size_t ZNMethodWithImmediateOops::immediate_oops_count() const {
+ return _nimmediate_oops;
+}
+
+oop** ZNMethodWithImmediateOops::immediate_oops_begin() const {
+ // The immediate oop* array starts immediately after this object
+ return (oop**)((uintptr_t)this + header_size());
+}
+
+oop** ZNMethodWithImmediateOops::immediate_oops_begin_safe() const {
+ // Non-entrant nmethods have a jump instruction patched into the beginning
+ // of the verified entry point, which could have overwritten an immediate
+ // oop. If so, make sure we skip over that oop.
+ if (_nm->is_not_entrant()) {
+ oop* const first_immediate_oop = *immediate_oops_begin();
+ oop* const safe_begin = (oop*)(_nm->verified_entry_point() + NativeJump::instruction_size);
+ if (first_immediate_oop < safe_begin) {
+ // First immediate oop overwritten, skip it
+ return immediate_oops_begin() + 1;
+ }
+ }
+
+ // First immediate oop not overwritten
+ return immediate_oops_begin();
+}
+
+
+oop** ZNMethodWithImmediateOops::immediate_oops_end() const {
+ return immediate_oops_begin() + immediate_oops_count();
+}
+
+ZNMethodTableEntry* ZNMethodTable::_table = NULL;
+size_t ZNMethodTable::_size = 0;
+size_t ZNMethodTable::_nregistered = 0;
+size_t ZNMethodTable::_nunregistered = 0;
+volatile size_t ZNMethodTable::_claimed = 0;
+
+ZNMethodTableEntry ZNMethodTable::create_entry(nmethod* nm) {
+ GrowableArray<oop*> immediate_oops;
+ bool non_immediate_oops = false;
+
+ // Find all oops relocations
+ RelocIterator iter(nm);
+ while (iter.next()) {
+ if (iter.type() != relocInfo::oop_type) {
+ // Not an oop
+ continue;
+ }
+
+ oop_Relocation* r = iter.oop_reloc();
+
+ if (!r->oop_is_immediate()) {
+ // Non-immediate oop found
+ non_immediate_oops = true;
+ continue;
+ }
+
+ if (r->oop_value() != NULL) {
+ // Non-NULL immediate oop found. NULL oops can safely be
+ // ignored since the method will be re-registered if they
+ // are later patched to be non-NULL.
+ immediate_oops.push(r->oop_addr());
+ }
+ }
+
+ // oops_count() returns the number of oops in the oop table plus one
+ if (immediate_oops.is_empty() && nm->oops_count() == 1) {
+ // No oops found, return empty entry
+ return ZNMethodTableEntry();
+ }
+
+ if (immediate_oops.is_empty()) {
+ // No immediate oops found, return entry without immediate oops
+ return ZNMethodTableEntry(nm, non_immediate_oops);
+ }
+
+ // Return entry with immediate oops
+ return ZNMethodTableEntry(ZNMethodWithImmediateOops::create(nm, immediate_oops), non_immediate_oops);
+}
+
+void ZNMethodTable::destroy_entry(ZNMethodTableEntry entry) {
+ if (entry.immediate_oops()) {
+ ZNMethodWithImmediateOops::destroy(entry.method_with_immediate_oops());
+ }
+}
+
+nmethod* ZNMethodTable::method(ZNMethodTableEntry entry) {
+ return entry.immediate_oops() ? entry.method_with_immediate_oops()->method() : entry.method();
+}
+
+size_t ZNMethodTable::first_index(const nmethod* nm, size_t size) {
+ assert(is_power_of_2(size), "Invalid size");
+ const size_t mask = size - 1;
+ const size_t hash = ZHash::address_to_uint32((uintptr_t)nm);
+ return hash & mask;
+}
+
+size_t ZNMethodTable::next_index(size_t prev_index, size_t size) {
+ assert(is_power_of_2(size), "Invalid size");
+ const size_t mask = size - 1;
+ return (prev_index + 1) & mask;
+}
+
+bool ZNMethodTable::register_entry(ZNMethodTableEntry* table, size_t size, ZNMethodTableEntry entry) {
+ const nmethod* const nm = method(entry);
+ size_t index = first_index(nm, size);
+
+ for (;;) {
+ const ZNMethodTableEntry table_entry = table[index];
+
+ if (!table_entry.registered() && !table_entry.unregistered()) {
+ // Insert new entry
+ table[index] = entry;
+ return true;
+ }
+
+ if (table_entry.registered() && method(table_entry) == nm) {
+ // Replace existing entry
+ destroy_entry(table_entry);
+ table[index] = entry;
+ return false;
+ }
+
+ index = next_index(index, size);
+ }
+}
+
+bool ZNMethodTable::unregister_entry(ZNMethodTableEntry* table, size_t size, const nmethod* nm) {
+ if (size == 0) {
+ // Table is empty
+ return false;
+ }
+
+ size_t index = first_index(nm, size);
+
+ for (;;) {
+ const ZNMethodTableEntry table_entry = table[index];
+
+ if (!table_entry.registered() && !table_entry.unregistered()) {
+ // Entry not found
+ return false;
+ }
+
+ if (table_entry.registered() && method(table_entry) == nm) {
+ // Remove entry
+ destroy_entry(table_entry);
+ table[index] = ZNMethodTableEntry(true /* unregistered */);
+ return true;
+ }
+
+ index = next_index(index, size);
+ }
+}
+
+void ZNMethodTable::rebuild(size_t new_size) {
+ assert(is_power_of_2(new_size), "Invalid size");
+
+ log_debug(gc, nmethod)("Rebuilding NMethod Table: "
+ SIZE_FORMAT "->" SIZE_FORMAT " entries, "
+ SIZE_FORMAT "(%.0lf%%->%.0lf%%) registered, "
+ SIZE_FORMAT "(%.0lf%%->%.0lf%%) unregistered",
+ _size, new_size,
+ _nregistered, percent_of(_nregistered, _size), percent_of(_nregistered, new_size),
+ _nunregistered, percent_of(_nunregistered, _size), 0.0);
+
+ // Allocate new table
+ ZNMethodTableEntry* const new_table = new ZNMethodTableEntry[new_size];
+
+ // Transfer all registered entries
+ for (size_t i = 0; i < _size; i++) {
+ const ZNMethodTableEntry entry = _table[i];
+ if (entry.registered()) {
+ register_entry(new_table, new_size, entry);
+ }
+ }
+
+ // Delete old table
+ delete [] _table;
+
+ // Install new table
+ _table = new_table;
+ _size = new_size;
+ _nunregistered = 0;
+}
+
+void ZNMethodTable::rebuild_if_needed() {
+ // The hash table uses linear probing. To avoid wasting memory while
+ // at the same time maintaining good hash collision behavior we want
+ // to keep the table occupancy between 30% and 70%. The table always
+ // grows/shrinks by doubling/halving its size. Pruning of unregistered
+ // entries is done by rebuilding the table with or without resizing it.
+ const size_t min_size = 1024;
+ const size_t shrink_threshold = _size * 0.30;
+ const size_t prune_threshold = _size * 0.65;
+ const size_t grow_threshold = _size * 0.70;
+
+ if (_size == 0) {
+ // Initialize table
+ rebuild(min_size);
+ } else if (_nregistered < shrink_threshold && _size > min_size) {
+ // Shrink table
+ rebuild(_size / 2);
+ } else if (_nregistered + _nunregistered > grow_threshold) {
+ // Prune or grow table
+ if (_nregistered < prune_threshold) {
+ // Prune table
+ rebuild(_size);
+ } else {
+ // Grow table
+ rebuild(_size * 2);
+ }
+ }
+}
+
+void ZNMethodTable::log_register(const nmethod* nm, ZNMethodTableEntry entry) {
+ LogTarget(Trace, gc, nmethod) log;
+ if (!log.is_enabled()) {
+ return;
+ }
+
+ log.print("Register NMethod: %s.%s (" PTR_FORMAT "), "
+ "Compiler: %s, Oops: %d, ImmediateOops: " SIZE_FORMAT ", NonImmediateOops: %s",
+ nm->method()->method_holder()->external_name(),
+ nm->method()->name()->as_C_string(),
+ p2i(nm),
+ nm->compiler_name(),
+ nm->oops_count() - 1,
+ entry.immediate_oops() ? entry.method_with_immediate_oops()->immediate_oops_count() : 0,
+ BOOL_TO_STR(entry.non_immediate_oops()));
+
+ LogTarget(Trace, gc, nmethod, oops) log_oops;
+ if (!log_oops.is_enabled()) {
+ return;
+ }
+
+ // Print nmethod oops table
+ oop* const begin = nm->oops_begin();
+ oop* const end = nm->oops_end();
+ for (oop* p = begin; p < end; p++) {
+ log_oops.print(" Oop[" SIZE_FORMAT "] " PTR_FORMAT " (%s)",
+ (p - begin), p2i(*p), (*p)->klass()->external_name());
+ }
+
+ if (entry.immediate_oops()) {
+ // Print nmethod immediate oops
+ const ZNMethodWithImmediateOops* const nmi = entry.method_with_immediate_oops();
+ oop** const begin = nmi->immediate_oops_begin();
+ oop** const end = nmi->immediate_oops_end();
+ for (oop** p = begin; p < end; p++) {
+ log_oops.print(" ImmediateOop[" SIZE_FORMAT "] " PTR_FORMAT " @ " PTR_FORMAT " (%s)",
+ (p - begin), p2i(**p), p2i(*p), (**p)->klass()->external_name());
+ }
+ }
+}
+
+void ZNMethodTable::log_unregister(const nmethod* nm) {
+ LogTarget(Debug, gc, nmethod) log;
+ if (!log.is_enabled()) {
+ return;
+ }
+
+ log.print("Unregister NMethod: %s.%s (" PTR_FORMAT ")",
+ nm->method()->method_holder()->external_name(),
+ nm->method()->name()->as_C_string(),
+ p2i(nm));
+}
+
+size_t ZNMethodTable::registered_nmethods() {
+ return _nregistered;
+}
+
+size_t ZNMethodTable::unregistered_nmethods() {
+ return _nunregistered;
+}
+
+void ZNMethodTable::register_nmethod(nmethod* nm) {
+ ResourceMark rm;
+
+ // Create entry
+ const ZNMethodTableEntry entry = create_entry(nm);
+
+ log_register(nm, entry);
+
+ if (!entry.registered()) {
+ // Method doesn't have any oops, ignore it
+ return;
+ }
+
+ // Grow/Shrink/Prune table if needed
+ rebuild_if_needed();
+
+ // Insert new entry
+ if (register_entry(_table, _size, entry)) {
+ // New entry registered. When register_entry() instead returns
+ // false the nmethod was already in the table so we do not want
+ // to increase number of registered entries in that case.
+ _nregistered++;
+ }
+}
+
+void ZNMethodTable::unregister_nmethod(nmethod* nm) {
+ ResourceMark rm;
+
+ log_unregister(nm);
+
+ // Remove entry
+ if (unregister_entry(_table, _size, nm)) {
+ // Entry was unregistered. When unregister_entry() instead returns
+ // false the nmethod was not in the table (because it didn't have
+ // any oops) so we do not want to decrease the number of registered
+ // entries in that case.
+ _nregistered--;
+ _nunregistered++;
+ }
+}
+
+void ZNMethodTable::gc_prologue() {
+ _claimed = 0;
+}
+
+void ZNMethodTable::gc_epilogue() {
+ assert(_claimed >= _size, "Failed to claim all table entries");
+}
+
+void ZNMethodTable::entry_oops_do(ZNMethodTableEntry entry, OopClosure* cl) {
+ nmethod* const nm = method(entry);
+ if (!nm->is_alive()) {
+ // No need to visit oops
+ return;
+ }
+
+ // Process oops table
+ oop* const begin = nm->oops_begin();
+ oop* const end = nm->oops_end();
+ for (oop* p = begin; p < end; p++) {
+ if (*p != Universe::non_oop_word()) {
+ cl->do_oop(p);
+ }
+ }
+
+ if (entry.immediate_oops()) {
+ // Process immediate oops
+ const ZNMethodWithImmediateOops* const nmi = entry.method_with_immediate_oops();
+ oop** const begin = nmi->immediate_oops_begin_safe();
+ oop** const end = nmi->immediate_oops_end();
+ for (oop** p = begin; p < end; p++) {
+ cl->do_oop(*p);
+ }
+ }
+
+ if (entry.non_immediate_oops()) {
+ // Process non-immediate oops
+ nm->fix_oop_relocations();
+ }
+}
+
+void ZNMethodTable::oops_do(OopClosure* cl) {
+ for (;;) {
+ // Claim table partition. Each partition is currently sized to span
+ // two cache lines. This number is just a guess, but seems to work well.
+ const size_t partition_size = (ZCacheLineSize * 2) / sizeof(ZNMethodTableEntry);
+ const size_t partition_start = MIN2(Atomic::add(partition_size, &_claimed) - partition_size, _size);
+ const size_t partition_end = MIN2(partition_start + partition_size, _size);
+ if (partition_start == partition_end) {
+ // End of table
+ break;
+ }
+
+ // Process table partition
+ for (size_t i = partition_start; i < partition_end; i++) {
+ const ZNMethodTableEntry entry = _table[i];
+ if (entry.registered()) {
+ entry_oops_do(entry, cl);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zNMethodTable.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,71 @@
+/*
+ * 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
+ * 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_Z_ZNMETHODTABLE_HPP
+#define SHARE_GC_Z_ZNMETHODTABLE_HPP
+
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zNMethodTableEntry.hpp"
+#include "memory/allocation.hpp"
+
+class ZNMethodTable : public AllStatic {
+private:
+ static ZNMethodTableEntry* _table;
+ static size_t _size;
+ static size_t _nregistered;
+ static size_t _nunregistered;
+ static volatile size_t _claimed ATTRIBUTE_ALIGNED(ZCacheLineSize);
+
+ static ZNMethodTableEntry create_entry(nmethod* nm);
+ static void destroy_entry(ZNMethodTableEntry entry);
+
+ static nmethod* method(ZNMethodTableEntry entry);
+
+ static size_t first_index(const nmethod* nm, size_t size);
+ static size_t next_index(size_t prev_index, size_t size);
+
+ static bool register_entry(ZNMethodTableEntry* table, size_t size, ZNMethodTableEntry entry);
+ static bool unregister_entry(ZNMethodTableEntry* table, size_t size, const nmethod* nm);
+
+ static void rebuild(size_t new_size);
+ static void rebuild_if_needed();
+
+ static void log_register(const nmethod* nm, ZNMethodTableEntry entry);
+ static void log_unregister(const nmethod* nm);
+
+ static void entry_oops_do(ZNMethodTableEntry entry, OopClosure* cl);
+
+public:
+ static size_t registered_nmethods();
+ static size_t unregistered_nmethods();
+
+ static void register_nmethod(nmethod* nm);
+ static void unregister_nmethod(nmethod* nm);
+
+ static void gc_prologue();
+ static void gc_epilogue();
+
+ static void oops_do(OopClosure* cl);
+};
+
+#endif // SHARE_GC_Z_ZNMETHODTABLE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zNMethodTableEntry.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef SHARE_GC_Z_ZNMETHODTABLEENTRY_HPP
+#define SHARE_GC_Z_ZNMETHODTABLEENTRY_HPP
+
+#include "gc/z/zBitField.hpp"
+#include "memory/allocation.hpp"
+
+//
+// NMethod table entry layout
+// --------------------------
+//
+// 6
+// 3 3 2 1 0
+// +--------------------------------------------------------------------+-+-+-+
+// |11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111|1|1|1|
+// +--------------------------------------------------------------------+-+-+-+
+// | | | |
+// | 2-2 Non-immediate Oops Flag (1-bits) * | |
+// | | |
+// | 1-1 Immediate Oops/Unregistered Flag (1-bits) * |
+// | |
+// | 0-0 Registered Flag (1-bits) *
+// |
+// * 63-3 NMethod/ZNMethodWithImmediateOops Address (61-bits)
+//
+
+class nmethod;
+class ZNMethodWithImmediateOops;
+
+class ZNMethodTableEntry : public CHeapObj<mtGC> {
+private:
+ typedef ZBitField<uint64_t, bool, 0, 1> field_registered;
+ typedef ZBitField<uint64_t, bool, 1, 1> field_unregistered;
+ typedef ZBitField<uint64_t, bool, 1, 1> field_immediate_oops;
+ typedef ZBitField<uint64_t, bool, 2, 1> field_non_immediate_oops;
+ typedef ZBitField<uint64_t, nmethod*, 3, 61, 3> field_method;
+ typedef ZBitField<uint64_t, ZNMethodWithImmediateOops*, 3, 61, 3> field_method_with_immediate_oops;
+
+ uint64_t _entry;
+
+public:
+ ZNMethodTableEntry(bool unregistered = false) :
+ _entry(field_unregistered::encode(unregistered) |
+ field_registered::encode(false)) {}
+
+ ZNMethodTableEntry(nmethod* method, bool non_immediate_oops) :
+ _entry(field_method::encode(method) |
+ field_non_immediate_oops::encode(non_immediate_oops) |
+ field_immediate_oops::encode(false) |
+ field_registered::encode(true)) {}
+
+ ZNMethodTableEntry(ZNMethodWithImmediateOops* method_with_immediate_oops, bool non_immediate_oops) :
+ _entry(field_method_with_immediate_oops::encode(method_with_immediate_oops) |
+ field_non_immediate_oops::encode(non_immediate_oops) |
+ field_immediate_oops::encode(true) |
+ field_registered::encode(true)) {}
+
+ bool registered() const {
+ return field_registered::decode(_entry);
+ }
+
+ bool unregistered() const {
+ return field_unregistered::decode(_entry);
+ }
+
+ bool immediate_oops() const {
+ return field_immediate_oops::decode(_entry);
+ }
+
+ bool non_immediate_oops() const {
+ return field_non_immediate_oops::decode(_entry);
+ }
+
+ nmethod* method() const {
+ return field_method::decode(_entry);
+ }
+
+ ZNMethodWithImmediateOops* method_with_immediate_oops() const {
+ return field_method_with_immediate_oops::decode(_entry);
+ }
+};
+
+#endif // SHARE_GC_Z_ZNMETHODTABLEENTRY_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zNUMA.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,54 @@
+/*
+ * 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 "gc/z/zNUMA.hpp"
+#include "logging/log.hpp"
+#include "runtime/os.hpp"
+
+bool ZNUMA::_enabled;
+
+void ZNUMA::initialize() {
+ initialize_platform();
+
+ log_info(gc, init)("NUMA Support: %s", to_string());
+ if (is_enabled()) {
+ log_info(gc, init)("NUMA Nodes: %u", count());
+ }
+}
+
+bool ZNUMA::is_enabled() {
+ return _enabled;
+}
+
+void ZNUMA::memory_interleave(uintptr_t addr, size_t size) {
+ if (!_enabled) {
+ // NUMA support not enabled
+ return;
+ }
+
+ os::numa_make_global((char*)addr, size);
+}
+
+const char* ZNUMA::to_string() {
+ return _enabled ? "Enabled" : "Disabled";
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zNUMA.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+#ifndef SHARE_GC_Z_ZNUMA_HPP
+#define SHARE_GC_Z_ZNUMA_HPP
+
+#include "memory/allocation.hpp"
+
+class ZNUMA : public AllStatic {
+private:
+ static bool _enabled;
+
+ static void initialize_platform();
+
+public:
+ static void initialize();
+ static bool is_enabled();
+
+ static uint32_t count();
+ static uint32_t id();
+
+ static uint32_t memory_id(uintptr_t addr);
+ static void memory_interleave(uintptr_t addr, size_t size);
+
+ static const char* to_string();
+};
+
+#endif // SHARE_GC_Z_ZNUMA_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zObjectAllocator.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,348 @@
+/*
+ * 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 "gc/shared/threadLocalAllocBuffer.inline.hpp"
+#include "gc/z/zCollectedHeap.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zHeap.inline.hpp"
+#include "gc/z/zObjectAllocator.hpp"
+#include "gc/z/zPage.inline.hpp"
+#include "gc/z/zStat.hpp"
+#include "gc/z/zThread.hpp"
+#include "gc/z/zUtils.inline.hpp"
+#include "logging/log.hpp"
+#include "runtime/atomic.hpp"
+#include "runtime/safepoint.hpp"
+#include "runtime/thread.hpp"
+#include "runtime/threadSMR.hpp"
+#include "utilities/align.hpp"
+#include "utilities/debug.hpp"
+
+static const ZStatCounter ZCounterUndoObjectAllocationSucceeded("Memory", "Undo Object Allocation Succeeded", ZStatUnitOpsPerSecond);
+static const ZStatCounter ZCounterUndoObjectAllocationFailed("Memory", "Undo Object Allocation Failed", ZStatUnitOpsPerSecond);
+static const ZStatSubPhase ZSubPhasePauseRetireTLABS("Pause Retire TLABS");
+static const ZStatSubPhase ZSubPhasePauseRemapTLABS("Pause Remap TLABS");
+
+ZObjectAllocator::ZObjectAllocator(uint nworkers) :
+ _nworkers(nworkers),
+ _used(0),
+ _shared_medium_page(NULL),
+ _shared_small_page(NULL),
+ _worker_small_page(NULL) {}
+
+ZPage* ZObjectAllocator::alloc_page(uint8_t type, size_t size, ZAllocationFlags flags) {
+ ZPage* const page = ZHeap::heap()->alloc_page(type, size, flags);
+ if (page != NULL) {
+ // Increment used bytes
+ Atomic::add(size, _used.addr());
+ }
+
+ return page;
+}
+
+uintptr_t ZObjectAllocator::alloc_object_in_shared_page(ZPage** shared_page,
+ uint8_t page_type,
+ size_t page_size,
+ size_t size,
+ ZAllocationFlags flags) {
+ uintptr_t addr = 0;
+ ZPage* page = *shared_page;
+
+ if (page != NULL) {
+ addr = page->alloc_object_atomic(size);
+ }
+
+ if (addr == 0) {
+ // Allocate new page
+ ZPage* const new_page = alloc_page(page_type, page_size, flags);
+ if (new_page != NULL) {
+ // Allocate object before installing the new page
+ addr = new_page->alloc_object(size);
+
+ retry:
+ // Install new page
+ ZPage* const prev_page = Atomic::cmpxchg(new_page, shared_page, page);
+ if (prev_page != page) {
+ if (prev_page == NULL) {
+ // Previous page was retired, retry installing the new page
+ page = prev_page;
+ goto retry;
+ }
+
+ // Another page already installed, try allocation there first
+ const uintptr_t prev_addr = prev_page->alloc_object_atomic(size);
+ if (prev_addr == 0) {
+ // Allocation failed, retry installing the new page
+ page = prev_page;
+ goto retry;
+ }
+
+ // Allocation succeeded in already installed page
+ addr = prev_addr;
+
+ // Undo new page allocation
+ ZHeap::heap()->undo_alloc_page(new_page);
+ }
+ }
+ }
+
+ return addr;
+}
+
+uintptr_t ZObjectAllocator::alloc_large_object(size_t size, ZAllocationFlags flags) {
+ assert(ZThread::is_java(), "Should be a Java thread");
+
+ uintptr_t addr = 0;
+
+ // Allocate new large page
+ const size_t page_size = align_up(size, ZPageSizeMin);
+ ZPage* const page = alloc_page(ZPageTypeLarge, page_size, flags);
+ if (page != NULL) {
+ // Allocate the object
+ addr = page->alloc_object(size);
+ }
+
+ return addr;
+}
+
+uintptr_t ZObjectAllocator::alloc_medium_object(size_t size, ZAllocationFlags flags) {
+ return alloc_object_in_shared_page(_shared_medium_page.addr(), ZPageTypeMedium, ZPageSizeMedium, size, flags);
+}
+
+uintptr_t ZObjectAllocator::alloc_small_object_from_nonworker(size_t size, ZAllocationFlags flags) {
+ assert(ZThread::is_java() || ZThread::is_vm(), "Should be a Java or VM thread");
+
+ if (flags.relocation() && flags.java_thread() && UseTLAB) {
+ // For relocations from Java threads, try TLAB allocation first
+ const uintptr_t addr = (uintptr_t)Thread::current()->tlab().allocate(ZUtils::bytes_to_words(size));
+ if (addr != 0) {
+ return addr;
+ }
+ }
+
+ // Non-worker small page allocation can never use the reserve
+ flags.set_no_reserve();
+
+ return alloc_object_in_shared_page(_shared_small_page.addr(), ZPageTypeSmall, ZPageSizeSmall, size, flags);
+}
+
+uintptr_t ZObjectAllocator::alloc_small_object_from_worker(size_t size, ZAllocationFlags flags) {
+ assert(ZThread::is_worker(), "Should be a worker thread");
+
+ ZPage* page = _worker_small_page.get();
+ uintptr_t addr = 0;
+
+ if (page != NULL) {
+ addr = page->alloc_object(size);
+ }
+
+ if (addr == 0) {
+ // Allocate new page
+ page = alloc_page(ZPageTypeSmall, ZPageSizeSmall, flags);
+ if (page != NULL) {
+ addr = page->alloc_object(size);
+ }
+ _worker_small_page.set(page);
+ }
+
+ return addr;
+}
+
+uintptr_t ZObjectAllocator::alloc_small_object(size_t size, ZAllocationFlags flags) {
+ if (flags.worker_thread()) {
+ return alloc_small_object_from_worker(size, flags);
+ } else {
+ return alloc_small_object_from_nonworker(size, flags);
+ }
+}
+
+uintptr_t ZObjectAllocator::alloc_object(size_t size, ZAllocationFlags flags) {
+ if (size <= ZObjectSizeLimitSmall) {
+ // Small
+ return alloc_small_object(size, flags);
+ } else if (size <= ZObjectSizeLimitMedium) {
+ // Medium
+ return alloc_medium_object(size, flags);
+ } else {
+ // Large
+ return alloc_large_object(size, flags);
+ }
+}
+
+uintptr_t ZObjectAllocator::alloc_object(size_t size) {
+ assert(ZThread::is_java(), "Must be a Java thread");
+
+ ZAllocationFlags flags;
+ flags.set_java_thread();
+ flags.set_no_reserve();
+
+ if (!ZStallOnOutOfMemory) {
+ flags.set_non_blocking();
+ }
+
+ return alloc_object(size, flags);
+}
+
+uintptr_t ZObjectAllocator::alloc_object_for_relocation(size_t size) {
+ assert(ZThread::is_java() || ZThread::is_worker() || ZThread::is_vm(), "Unknown thread");
+
+ ZAllocationFlags flags;
+ flags.set_relocation();
+ flags.set_non_blocking();
+
+ if (ZThread::is_worker()) {
+ flags.set_worker_thread();
+ } else if (ZThread::is_java()) {
+ flags.set_java_thread();
+ }
+
+ return alloc_object(size, flags);
+}
+
+bool ZObjectAllocator::undo_alloc_large_object(ZPage* page) {
+ assert(page->type() == ZPageTypeLarge, "Invalid page type");
+
+ // Undo page allocation
+ ZHeap::heap()->undo_alloc_page(page);
+ return true;
+}
+
+bool ZObjectAllocator::undo_alloc_medium_object(ZPage* page, uintptr_t addr, size_t size) {
+ assert(page->type() == ZPageTypeMedium, "Invalid page type");
+
+ // Try atomic undo on shared page
+ return page->undo_alloc_object_atomic(addr, size);
+}
+
+bool ZObjectAllocator::undo_alloc_small_object_from_nonworker(ZPage* page, uintptr_t addr, size_t size) {
+ assert(page->type() == ZPageTypeSmall, "Invalid page type");
+
+ if (ZThread::is_java()) {
+ // Try undo allocation in TLAB
+ if (Thread::current()->tlab().undo_allocate((HeapWord*)addr, ZUtils::bytes_to_words(size))) {
+ return true;
+ }
+ }
+
+ // Try atomic undo on shared page
+ return page->undo_alloc_object_atomic(addr, size);
+}
+
+bool ZObjectAllocator::undo_alloc_small_object_from_worker(ZPage* page, uintptr_t addr, size_t size) {
+ assert(page->type() == ZPageTypeSmall, "Invalid page type");
+ assert(page == _worker_small_page.get(), "Invalid page");
+
+ // Non-atomic undo on worker-local page
+ const bool success = page->undo_alloc_object(addr, size);
+ assert(success, "Should always succeed");
+ return success;
+}
+
+bool ZObjectAllocator::undo_alloc_small_object(ZPage* page, uintptr_t addr, size_t size) {
+ if (ZThread::is_worker()) {
+ return undo_alloc_small_object_from_worker(page, addr, size);
+ } else {
+ return undo_alloc_small_object_from_nonworker(page, addr, size);
+ }
+}
+
+bool ZObjectAllocator::undo_alloc_object(ZPage* page, uintptr_t addr, size_t size) {
+ const uint8_t type = page->type();
+
+ if (type == ZPageTypeSmall) {
+ return undo_alloc_small_object(page, addr, size);
+ } else if (type == ZPageTypeMedium) {
+ return undo_alloc_medium_object(page, addr, size);
+ } else {
+ return undo_alloc_large_object(page);
+ }
+}
+
+void ZObjectAllocator::undo_alloc_object_for_relocation(ZPage* page, uintptr_t addr, size_t size) {
+ if (undo_alloc_object(page, addr, size)) {
+ ZStatInc(ZCounterUndoObjectAllocationSucceeded);
+ } else {
+ ZStatInc(ZCounterUndoObjectAllocationFailed);
+ log_trace(gc)("Failed to undo object allocation: " PTR_FORMAT ", Size: " SIZE_FORMAT ", Thread: " PTR_FORMAT " (%s)",
+ addr, size, ZThread::id(), ZThread::name());
+ }
+}
+
+size_t ZObjectAllocator::used() const {
+ size_t total_used = 0;
+
+ ZPerCPUConstIterator<size_t> iter(&_used);
+ for (const size_t* cpu_used; iter.next(&cpu_used);) {
+ total_used += *cpu_used;
+ }
+
+ return total_used;
+}
+
+size_t ZObjectAllocator::remaining() const {
+ assert(ZThread::is_java(), "Should be a Java thread");
+
+ ZPage* page = _shared_small_page.get();
+ if (page != NULL) {
+ return page->remaining();
+ }
+
+ return 0;
+}
+
+void ZObjectAllocator::retire_tlabs() {
+ ZStatTimer timer(ZSubPhasePauseRetireTLABS);
+ assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
+
+ // Retire TLABs
+ if (UseTLAB) {
+ ZCollectedHeap* heap = ZCollectedHeap::heap();
+ heap->accumulate_statistics_all_tlabs();
+ heap->ensure_parsability(true /* retire_tlabs */);
+ heap->resize_all_tlabs();
+ }
+
+ // Reset used
+ _used.set_all(0);
+
+ // Reset allocation pages
+ _shared_medium_page.set(NULL);
+ _shared_small_page.set_all(NULL);
+ _worker_small_page.set_all(NULL);
+}
+
+static void remap_tlab_address(HeapWord** p) {
+ *p = (HeapWord*)ZAddress::good_or_null((uintptr_t)*p);
+}
+
+void ZObjectAllocator::remap_tlabs() {
+ ZStatTimer timer(ZSubPhasePauseRemapTLABS);
+ assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
+
+ if (UseTLAB) {
+ for (JavaThreadIteratorWithHandle iter; JavaThread* thread = iter.next(); ) {
+ thread->tlab().addresses_do(remap_tlab_address);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zObjectAllocator.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,79 @@
+/*
+ * 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_GC_Z_ZOBJECTALLOCATOR_HPP
+#define SHARE_GC_Z_ZOBJECTALLOCATOR_HPP
+
+#include "gc/z/zAllocationFlags.hpp"
+#include "gc/z/zPage.hpp"
+#include "gc/z/zValue.hpp"
+#include "memory/allocation.hpp"
+
+class ZObjectAllocator {
+private:
+ const uint _nworkers;
+ ZPerCPU<size_t> _used;
+ ZContended<ZPage*> _shared_medium_page;
+ ZPerCPU<ZPage*> _shared_small_page;
+ ZPerWorker<ZPage*> _worker_small_page;
+
+ ZPage* alloc_page(uint8_t type, size_t size, ZAllocationFlags flags);
+
+ // Allocate an object in a shared page. Allocate and
+ // atomically install a new page if neccesary.
+ uintptr_t alloc_object_in_shared_page(ZPage** shared_page,
+ uint8_t page_type,
+ size_t page_size,
+ size_t size,
+ ZAllocationFlags flags);
+
+ uintptr_t alloc_large_object(size_t size, ZAllocationFlags flags);
+ uintptr_t alloc_medium_object(size_t size, ZAllocationFlags flags);
+ uintptr_t alloc_small_object_from_nonworker(size_t size, ZAllocationFlags flags);
+ uintptr_t alloc_small_object_from_worker(size_t size, ZAllocationFlags flags);
+ uintptr_t alloc_small_object(size_t size, ZAllocationFlags flags);
+ uintptr_t alloc_object(size_t size, ZAllocationFlags flags);
+
+ bool undo_alloc_large_object(ZPage* page);
+ bool undo_alloc_medium_object(ZPage* page, uintptr_t addr, size_t size);
+ bool undo_alloc_small_object_from_nonworker(ZPage* page, uintptr_t addr, size_t size);
+ bool undo_alloc_small_object_from_worker(ZPage* page, uintptr_t addr, size_t size);
+ bool undo_alloc_small_object(ZPage* page, uintptr_t addr, size_t size);
+ bool undo_alloc_object(ZPage* page, uintptr_t addr, size_t size);
+
+public:
+ ZObjectAllocator(uint nworkers);
+
+ uintptr_t alloc_object(size_t size);
+
+ uintptr_t alloc_object_for_relocation(size_t size);
+ void undo_alloc_object_for_relocation(ZPage* page, uintptr_t addr, size_t size);
+
+ size_t used() const;
+ size_t remaining() const;
+
+ void retire_tlabs();
+ void remap_tlabs();
+};
+
+#endif // SHARE_GC_Z_ZOBJECTALLOCATOR_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zOop.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+#ifndef SHARE_GC_Z_ZOOP_HPP
+#define SHARE_GC_Z_ZOOP_HPP
+
+#include "memory/allocation.hpp"
+#include "oops/oopsHierarchy.hpp"
+
+class ZOop : public AllStatic {
+public:
+ static oop to_oop(uintptr_t value);
+ static uintptr_t to_address(oop o);
+
+ static bool is_good(oop o);
+ static bool is_good_or_null(oop o);
+
+ static oop good(oop);
+};
+
+#endif // SHARE_GC_Z_ZOOP_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zOop.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+#ifndef SHARE_GC_Z_ZOOP_INLINE_HPP
+#define SHARE_GC_Z_ZOOP_INLINE_HPP
+
+#include "gc/z/zAddress.inline.hpp"
+#include "gc/z/zOop.hpp"
+#include "oops/oopsHierarchy.hpp"
+
+inline oop ZOop::to_oop(uintptr_t value) {
+ return cast_to_oop(value);
+}
+
+inline uintptr_t ZOop::to_address(oop o) {
+ return cast_from_oop<uintptr_t>(o);
+}
+
+inline bool ZOop::is_good(oop o) {
+ return ZAddress::is_good(to_address(o));
+}
+
+inline bool ZOop::is_good_or_null(oop o) {
+ return ZAddress::is_good_or_null(to_address(o));
+}
+
+inline oop ZOop::good(oop o) {
+ return to_oop(ZAddress::good(to_address(o)));
+}
+
+#endif // SHARE_GC_Z_ZOOP_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zOopClosures.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2015, 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 "gc/z/zHeap.hpp"
+#include "gc/z/zOopClosures.inline.hpp"
+#include "gc/z/zOop.inline.hpp"
+#include "memory/iterator.inline.hpp"
+#include "oops/access.inline.hpp"
+#include "oops/oop.inline.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+static void z_verify_loaded_object(const oop* p, const oop obj) {
+ guarantee(ZOop::is_good_or_null(obj),
+ "Bad oop " PTR_FORMAT " found at " PTR_FORMAT ", expected " PTR_FORMAT,
+ p2i(obj), p2i(p), p2i(ZOop::good(obj)));
+ guarantee(oopDesc::is_oop_or_null(obj),
+ "Bad object " PTR_FORMAT " found at " PTR_FORMAT,
+ p2i(obj), p2i(p));
+}
+
+ZVerifyHeapOopClosure::ZVerifyHeapOopClosure(oop base)
+ : _base(base) {}
+
+void ZVerifyHeapOopClosure::do_oop(oop* p) {
+ guarantee(ZHeap::heap()->is_in((uintptr_t)p), "oop* " PTR_FORMAT " not in heap", p2i(p));
+
+ const oop obj = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_load_at(_base, _base->field_offset(p));
+ z_verify_loaded_object(p, obj);
+}
+
+void ZVerifyHeapOopClosure::do_oop(narrowOop* p) {
+ ShouldNotReachHere();
+}
+
+void ZVerifyRootOopClosure::do_oop(oop* p) {
+ guarantee(!ZHeap::heap()->is_in((uintptr_t)p), "oop* " PTR_FORMAT " in heap", p2i(p));
+
+ const oop obj = RootAccess<>::oop_load(p);
+ z_verify_loaded_object(p, obj);
+}
+
+void ZVerifyRootOopClosure::do_oop(narrowOop* p) {
+ ShouldNotReachHere();
+}
+
+void ZVerifyObjectClosure::do_object(oop o) {
+ ZVerifyHeapOopClosure cl(o);
+ o->oop_iterate(&cl);
+}
+
+// Generate Z specialized oop_oop_iterate functions.
+SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_Z(ALL_KLASS_OOP_OOP_ITERATE_DEFN)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zOopClosures.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,120 @@
+/*
+ * 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_GC_Z_ZOOPCLOSURES_HPP
+#define SHARE_GC_Z_ZOOPCLOSURES_HPP
+
+#include "memory/iterator.hpp"
+
+class ZLoadBarrierOopClosure : public ExtendedOopClosure {
+public:
+ void do_oop_nv(oop* p);
+ void do_oop_nv(narrowOop* p);
+
+ virtual void do_oop(oop* p);
+ virtual void do_oop(narrowOop* p);
+
+#ifdef ASSERT
+ virtual bool should_verify_oops() {
+ return false;
+ }
+#endif
+};
+
+class ZMarkRootOopClosure : public OopClosure {
+public:
+ virtual void do_oop(oop* p);
+ virtual void do_oop(narrowOop* p);
+};
+
+class ZRelocateRootOopClosure : public OopClosure {
+public:
+ virtual void do_oop(oop* p);
+ virtual void do_oop(narrowOop* p);
+};
+
+template <bool finalizable>
+class ZMarkBarrierOopClosure : public ExtendedOopClosure {
+public:
+ ZMarkBarrierOopClosure();
+
+ void do_oop_nv(oop* p);
+ void do_oop_nv(narrowOop* p);
+
+ virtual void do_oop(oop* p);
+ virtual void do_oop(narrowOop* p);
+
+#ifdef ASSERT
+ virtual bool should_verify_oops() {
+ return false;
+ }
+#endif
+};
+
+class ZPhantomIsAliveObjectClosure : public BoolObjectClosure {
+public:
+ virtual bool do_object_b(oop o);
+};
+
+class ZPhantomKeepAliveOopClosure : public OopClosure {
+public:
+ virtual void do_oop(oop* p);
+ virtual void do_oop(narrowOop* p);
+};
+
+class ZPhantomCleanOopClosure : public OopClosure {
+public:
+ virtual void do_oop(oop* p);
+ virtual void do_oop(narrowOop* p);
+};
+
+class ZVerifyHeapOopClosure : public ExtendedOopClosure {
+private:
+ const oop _base;
+
+public:
+ ZVerifyHeapOopClosure(oop base);
+
+ virtual void do_oop(oop* p);
+ virtual void do_oop(narrowOop* p);
+
+#ifdef ASSERT
+ // Verification handled by the closure itself.
+ virtual bool should_verify_oops() {
+ return false;
+ }
+#endif
+};
+
+class ZVerifyRootOopClosure : public OopClosure {
+public:
+ virtual void do_oop(oop* p);
+ virtual void do_oop(narrowOop* p);
+};
+
+class ZVerifyObjectClosure : public ObjectClosure {
+public:
+ virtual void do_object(oop o);
+};
+
+#endif // SHARE_GC_Z_ZOOPCLOSURES_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zOopClosures.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,123 @@
+/*
+ * 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_GC_Z_ZOOPCLOSURES_INLINE_HPP
+#define SHARE_GC_Z_ZOOPCLOSURES_INLINE_HPP
+
+#include "gc/z/zBarrier.inline.hpp"
+#include "gc/z/zHeap.inline.hpp"
+#include "gc/z/zOop.inline.hpp"
+#include "gc/z/zOopClosures.hpp"
+#include "oops/oop.inline.hpp"
+#include "runtime/atomic.hpp"
+#include "utilities/debug.hpp"
+
+inline void ZLoadBarrierOopClosure::do_oop_nv(oop* p) {
+ ZBarrier::load_barrier_on_oop_field(p);
+}
+
+inline void ZLoadBarrierOopClosure::do_oop_nv(narrowOop* p) {
+ ShouldNotReachHere();
+}
+
+inline void ZLoadBarrierOopClosure::do_oop(oop* p) {
+ do_oop_nv(p);
+}
+
+inline void ZLoadBarrierOopClosure::do_oop(narrowOop* p) {
+ do_oop_nv(p);
+}
+
+inline void ZMarkRootOopClosure::do_oop(oop* p) {
+ ZBarrier::mark_barrier_on_root_oop_field(p);
+}
+
+inline void ZMarkRootOopClosure::do_oop(narrowOop* p) {
+ ShouldNotReachHere();
+}
+
+inline void ZRelocateRootOopClosure::do_oop(oop* p) {
+ ZBarrier::relocate_barrier_on_root_oop_field(p);
+}
+
+inline void ZRelocateRootOopClosure::do_oop(narrowOop* p) {
+ ShouldNotReachHere();
+}
+
+template <bool finalizable>
+inline ZMarkBarrierOopClosure<finalizable>::ZMarkBarrierOopClosure() :
+ ExtendedOopClosure(finalizable ? NULL : ZHeap::heap()->reference_discoverer()) {}
+
+template <bool finalizable>
+inline void ZMarkBarrierOopClosure<finalizable>::do_oop_nv(oop* p) {
+ ZBarrier::mark_barrier_on_oop_field(p, finalizable);
+}
+
+template <bool finalizable>
+inline void ZMarkBarrierOopClosure<finalizable>::do_oop_nv(narrowOop* p) {
+ ShouldNotReachHere();
+}
+
+template <bool finalizable>
+inline void ZMarkBarrierOopClosure<finalizable>::do_oop(oop* p) {
+ do_oop_nv(p);
+}
+
+template <bool finalizable>
+inline void ZMarkBarrierOopClosure<finalizable>::do_oop(narrowOop* p) {
+ do_oop_nv(p);
+}
+
+inline bool ZPhantomIsAliveObjectClosure::do_object_b(oop o) {
+ return ZBarrier::is_alive_barrier_on_phantom_oop(o);
+}
+
+inline void ZPhantomKeepAliveOopClosure::do_oop(oop* p) {
+ ZBarrier::keep_alive_barrier_on_phantom_oop_field(p);
+}
+
+inline void ZPhantomKeepAliveOopClosure::do_oop(narrowOop* p) {
+ ShouldNotReachHere();
+}
+
+inline void ZPhantomCleanOopClosure::do_oop(oop* p) {
+ // Read the oop once, to make sure the liveness check
+ // and the later clearing uses the same value.
+ const oop obj = *(volatile oop*)p;
+ if (ZBarrier::is_alive_barrier_on_phantom_oop(obj)) {
+ ZBarrier::keep_alive_barrier_on_phantom_oop_field(p);
+ } else {
+ // The destination could have been modified/reused, in which case
+ // we don't want to clear it. However, no one could write the same
+ // oop here again (the object would be strongly live and we would
+ // not consider clearing such oops), so therefore we don't have an
+ // ABA problem here.
+ Atomic::cmpxchg(oop(NULL), p, obj);
+ }
+}
+
+inline void ZPhantomCleanOopClosure::do_oop(narrowOop* p) {
+ ShouldNotReachHere();
+}
+
+#endif // SHARE_GC_Z_ZOOPCLOSURES_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zPage.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2015, 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 "gc/shared/collectedHeap.hpp"
+#include "gc/z/zAddress.inline.hpp"
+#include "gc/z/zForwardingTable.inline.hpp"
+#include "gc/z/zHeap.inline.hpp"
+#include "gc/z/zLiveMap.inline.hpp"
+#include "gc/z/zMark.hpp"
+#include "gc/z/zPage.inline.hpp"
+#include "gc/z/zPhysicalMemory.inline.hpp"
+#include "gc/z/zStat.hpp"
+#include "gc/z/zThread.hpp"
+#include "gc/z/zUtils.inline.hpp"
+#include "logging/log.hpp"
+#include "runtime/orderAccess.hpp"
+#include "utilities/align.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+static const ZStatCounter ZCounterRelocationContention("Contention", "Relocation Contention", ZStatUnitOpsPerSecond);
+
+ZPage::ZPage(uint8_t type, ZVirtualMemory vmem, ZPhysicalMemory pmem) :
+ _type(type),
+ _pinned(0),
+ _numa_id((uint8_t)-1),
+ _seqnum(0),
+ _virtual(vmem),
+ _top(start()),
+ _livemap(object_max_count()),
+ _refcount(0),
+ _forwarding(),
+ _physical(pmem) {
+ assert(!_physical.is_null(), "Should not be null");
+ assert(!_virtual.is_null(), "Should not be null");
+ assert((type == ZPageTypeSmall && size() == ZPageSizeSmall) ||
+ (type == ZPageTypeMedium && size() == ZPageSizeMedium) ||
+ (type == ZPageTypeLarge && is_aligned(size(), ZPageSizeMin)),
+ "Page type/size mismatch");
+}
+
+ZPage::~ZPage() {
+ assert(!is_active(), "Should not be active");
+ assert(is_detached(), "Should be detached");
+}
+
+void ZPage::reset() {
+ assert(!is_active(), "Should not be active");
+ assert(!is_pinned(), "Should not be pinned");
+ assert(!is_detached(), "Should not be detached");
+
+ _seqnum = ZGlobalSeqNum;
+ _top = start();
+ _livemap.reset();
+
+ // Make sure we don't make the page active before
+ // the reset of the above fields are visible.
+ OrderAccess::storestore();
+
+ _refcount = 1;
+}
+
+uintptr_t ZPage::relocate_object_inner(uintptr_t from_index, uintptr_t from_offset) {
+ ZForwardingTableCursor cursor;
+
+ // Lookup address in forwarding table
+ const ZForwardingTableEntry entry = _forwarding.find(from_index, &cursor);
+ if (entry.from_index() == from_index) {
+ // Already relocated, return new address
+ return entry.to_offset();
+ }
+
+ // Not found in forwarding table, relocate object
+ assert(is_object_marked(from_offset), "Should be marked");
+
+ if (is_pinned()) {
+ // In-place forward
+ return _forwarding.insert(from_index, from_offset, &cursor);
+ }
+
+ // Allocate object
+ const uintptr_t from_good = ZAddress::good(from_offset);
+ const size_t size = ZUtils::object_size(from_good);
+ const uintptr_t to_good = ZHeap::heap()->alloc_object_for_relocation(size);
+ if (to_good == 0) {
+ // Failed, in-place forward
+ return _forwarding.insert(from_index, from_offset, &cursor);
+ }
+
+ // Copy object
+ ZUtils::object_copy(from_good, to_good, size);
+
+ // Update forwarding table
+ const uintptr_t to_offset = ZAddress::offset(to_good);
+ const uintptr_t to_offset_final = _forwarding.insert(from_index, to_offset, &cursor);
+ if (to_offset_final == to_offset) {
+ // Relocation succeeded
+ return to_offset;
+ }
+
+ // Relocation contention
+ ZStatInc(ZCounterRelocationContention);
+ log_trace(gc)("Relocation contention, thread: " PTR_FORMAT " (%s), page: " PTR_FORMAT
+ ", entry: " SIZE_FORMAT ", oop: " PTR_FORMAT ", size: " SIZE_FORMAT,
+ ZThread::id(), ZThread::name(), p2i(this), cursor, from_good, size);
+
+ // Try undo allocation
+ ZHeap::heap()->undo_alloc_object_for_relocation(to_good, size);
+
+ return to_offset_final;
+}
+
+uintptr_t ZPage::relocate_object(uintptr_t from) {
+ assert(ZHeap::heap()->is_relocating(from), "Should be relocating");
+
+ const uintptr_t from_offset = ZAddress::offset(from);
+ const uintptr_t from_index = (from_offset - start()) >> object_alignment_shift();
+ const uintptr_t to_offset = relocate_object_inner(from_index, from_offset);
+ if (from_offset == to_offset) {
+ // In-place forwarding, pin page
+ set_pinned();
+ }
+
+ return ZAddress::good(to_offset);
+}
+
+uintptr_t ZPage::forward_object(uintptr_t from) {
+ assert(ZHeap::heap()->is_relocating(from), "Should be relocated");
+
+ // Lookup address in forwarding table
+ const uintptr_t from_offset = ZAddress::offset(from);
+ const uintptr_t from_index = (from_offset - start()) >> object_alignment_shift();
+ const ZForwardingTableEntry entry = _forwarding.find(from_index);
+ assert(entry.from_index() == from_index, "Should be forwarded");
+
+ return ZAddress::good(entry.to_offset());
+}
+
+void ZPage::print_on(outputStream* out) const {
+ out->print_cr(" %-6s " PTR_FORMAT " " PTR_FORMAT " " PTR_FORMAT " %s%s%s%s%s%s",
+ type_to_string(), start(), top(), end(),
+ is_allocating() ? " Allocating" : "",
+ is_relocatable() ? " Relocatable" : "",
+ is_forwarding() ? " Forwarding" : "",
+ is_pinned() ? " Pinned" : "",
+ is_detached() ? " Detached" : "",
+ !is_active() ? " Inactive" : "");
+}
+
+void ZPage::print() const {
+ print_on(tty);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zPage.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,130 @@
+/*
+ * 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_GC_Z_ZPAGE_HPP
+#define SHARE_GC_Z_ZPAGE_HPP
+
+#include "gc/z/zForwardingTable.hpp"
+#include "gc/z/zList.hpp"
+#include "gc/z/zLiveMap.hpp"
+#include "gc/z/zPhysicalMemory.hpp"
+#include "gc/z/zVirtualMemory.hpp"
+#include "memory/allocation.hpp"
+
+class ZPage : public CHeapObj<mtGC> {
+ friend class VMStructs;
+ friend class ZList<ZPage>;
+
+private:
+ // Always hot
+ const uint8_t _type; // Page type
+ volatile uint8_t _pinned; // Pinned flag
+ uint8_t _numa_id; // NUMA node affinity
+ uint32_t _seqnum; // Allocation sequence number
+ const ZVirtualMemory _virtual; // Virtual start/end address
+ volatile uintptr_t _top; // Virtual top address
+ ZLiveMap _livemap; // Live map
+
+ // Hot when relocated and cached
+ volatile uint32_t _refcount; // Page reference count
+ ZForwardingTable _forwarding; // Forwarding table
+ ZPhysicalMemory _physical; // Physical memory for page
+ ZListNode<ZPage> _node; // Page list node
+
+ const char* type_to_string() const;
+ uint32_t object_max_count() const;
+ uintptr_t relocate_object_inner(uintptr_t from_index, uintptr_t from_offset);
+
+ bool is_object_marked(uintptr_t addr) const;
+ bool is_object_strongly_marked(uintptr_t addr) const;
+
+public:
+ ZPage(uint8_t type, ZVirtualMemory vmem, ZPhysicalMemory pmem);
+ ~ZPage();
+
+ size_t object_alignment_shift() const;
+ size_t object_alignment() const;
+
+ uint8_t type() const;
+ uintptr_t start() const;
+ uintptr_t end() const;
+ size_t size() const;
+ uintptr_t top() const;
+ size_t remaining() const;
+
+ uint8_t numa_id();
+
+ ZPhysicalMemory& physical_memory();
+ const ZVirtualMemory& virtual_memory() const;
+
+ void reset();
+
+ bool inc_refcount();
+ bool dec_refcount();
+
+ bool is_in(uintptr_t addr) const;
+
+ uintptr_t block_start(uintptr_t addr) const;
+ size_t block_size(uintptr_t addr) const;
+ bool block_is_obj(uintptr_t addr) const;
+
+ bool is_active() const;
+ bool is_allocating() const;
+ bool is_relocatable() const;
+ bool is_detached() const;
+
+ bool is_mapped() const;
+ void set_pre_mapped();
+
+ bool is_pinned() const;
+ void set_pinned();
+
+ bool is_forwarding() const;
+ void set_forwarding();
+ void reset_forwarding();
+ void verify_forwarding() const;
+
+ bool is_marked() const;
+ bool is_object_live(uintptr_t addr) const;
+ bool is_object_strongly_live(uintptr_t addr) const;
+ bool mark_object(uintptr_t addr, bool finalizable, bool& inc_live);
+
+ void inc_live_atomic(uint32_t objects, size_t bytes);
+ size_t live_bytes() const;
+
+ void object_iterate(ObjectClosure* cl);
+
+ uintptr_t alloc_object(size_t size);
+ uintptr_t alloc_object_atomic(size_t size);
+
+ bool undo_alloc_object(uintptr_t addr, size_t size);
+ bool undo_alloc_object_atomic(uintptr_t addr, size_t size);
+
+ uintptr_t relocate_object(uintptr_t from);
+ uintptr_t forward_object(uintptr_t from);
+
+ void print_on(outputStream* out) const;
+ void print() const;
+};
+
+#endif // SHARE_GC_Z_ZPAGE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zPage.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,369 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZPAGE_INLINE_HPP
+#define SHARE_GC_Z_ZPAGE_INLINE_HPP
+
+#include "gc/z/zAddress.inline.hpp"
+#include "gc/z/zForwardingTable.inline.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zLiveMap.inline.hpp"
+#include "gc/z/zMark.hpp"
+#include "gc/z/zNUMA.hpp"
+#include "gc/z/zPage.hpp"
+#include "gc/z/zPhysicalMemory.inline.hpp"
+#include "gc/z/zUtils.inline.hpp"
+#include "gc/z/zVirtualMemory.inline.hpp"
+#include "oops/oop.inline.hpp"
+#include "runtime/atomic.hpp"
+#include "utilities/align.hpp"
+#include "utilities/debug.hpp"
+
+inline const char* ZPage::type_to_string() const {
+ switch (type()) {
+ case ZPageTypeSmall:
+ return "Small";
+
+ case ZPageTypeMedium:
+ return "Medium";
+
+ default:
+ assert(type() == ZPageTypeLarge, "Invalid page type");
+ return "Large";
+ }
+}
+
+inline uint32_t ZPage::object_max_count() const {
+ switch (type()) {
+ case ZPageTypeLarge:
+ // A large page can only contain a single
+ // object aligned to the start of the page.
+ return 1;
+
+ default:
+ return (uint32_t)(size() >> object_alignment_shift());
+ }
+}
+
+inline size_t ZPage::object_alignment_shift() const {
+ switch (type()) {
+ case ZPageTypeSmall:
+ return ZObjectAlignmentSmallShift;
+
+ case ZPageTypeMedium:
+ return ZObjectAlignmentMediumShift;
+
+ default:
+ assert(type() == ZPageTypeLarge, "Invalid page type");
+ return ZObjectAlignmentLargeShift;
+ }
+}
+
+inline size_t ZPage::object_alignment() const {
+ switch (type()) {
+ case ZPageTypeSmall:
+ return ZObjectAlignmentSmall;
+
+ case ZPageTypeMedium:
+ return ZObjectAlignmentMedium;
+
+ default:
+ assert(type() == ZPageTypeLarge, "Invalid page type");
+ return ZObjectAlignmentLarge;
+ }
+}
+
+inline uint8_t ZPage::type() const {
+ return _type;
+}
+
+inline uintptr_t ZPage::start() const {
+ return _virtual.start();
+}
+
+inline uintptr_t ZPage::end() const {
+ return _virtual.end();
+}
+
+inline size_t ZPage::size() const {
+ return _virtual.size();
+}
+
+inline uintptr_t ZPage::top() const {
+ return _top;
+}
+
+inline size_t ZPage::remaining() const {
+ return end() - top();
+}
+
+inline ZPhysicalMemory& ZPage::physical_memory() {
+ return _physical;
+}
+
+inline const ZVirtualMemory& ZPage::virtual_memory() const {
+ return _virtual;
+}
+
+inline uint8_t ZPage::numa_id() {
+ if (_numa_id == (uint8_t)-1) {
+ _numa_id = (uint8_t)ZNUMA::memory_id(ZAddress::good(start()));
+ }
+
+ return _numa_id;
+}
+
+inline bool ZPage::inc_refcount() {
+ for (uint32_t prev_refcount = _refcount; prev_refcount > 0; prev_refcount = _refcount) {
+ if (Atomic::cmpxchg(prev_refcount + 1, &_refcount, prev_refcount) == prev_refcount) {
+ return true;
+ }
+ }
+ return false;
+}
+
+inline bool ZPage::dec_refcount() {
+ assert(is_active(), "Should be active");
+ return Atomic::sub(1u, &_refcount) == 0;
+}
+
+inline bool ZPage::is_in(uintptr_t addr) const {
+ const uintptr_t offset = ZAddress::offset(addr);
+ return offset >= start() && offset < top();
+}
+
+inline uintptr_t ZPage::block_start(uintptr_t addr) const {
+ if (block_is_obj(addr)) {
+ return addr;
+ } else {
+ return ZAddress::good(top());
+ }
+}
+
+inline size_t ZPage::block_size(uintptr_t addr) const {
+ if (block_is_obj(addr)) {
+ return ZUtils::object_size(addr);
+ } else {
+ return end() - top();
+ }
+}
+
+inline bool ZPage::block_is_obj(uintptr_t addr) const {
+ return ZAddress::offset(addr) < top();
+}
+
+inline bool ZPage::is_active() const {
+ return _refcount > 0;
+}
+
+inline bool ZPage::is_allocating() const {
+ return is_active() && _seqnum == ZGlobalSeqNum;
+}
+
+inline bool ZPage::is_relocatable() const {
+ return is_active() && _seqnum < ZGlobalSeqNum;
+}
+
+inline bool ZPage::is_detached() const {
+ return _physical.is_null();
+}
+
+inline bool ZPage::is_mapped() const {
+ return _seqnum > 0;
+}
+
+inline void ZPage::set_pre_mapped() {
+ // The _seqnum variable is also used to signal that the virtual and physical
+ // memory has been mapped. So, we need to set it to non-zero when the memory
+ // has been pre-mapped.
+ _seqnum = 1;
+}
+
+inline bool ZPage::is_pinned() const {
+ return _pinned;
+}
+
+inline void ZPage::set_pinned() {
+ _pinned = 1;
+}
+
+inline bool ZPage::is_forwarding() const {
+ return !_forwarding.is_null();
+}
+
+inline void ZPage::set_forwarding() {
+ assert(is_marked(), "Should be marked");
+ _forwarding.setup(_livemap.live_objects());
+}
+
+inline void ZPage::reset_forwarding() {
+ _forwarding.reset();
+ _pinned = 0;
+}
+
+inline void ZPage::verify_forwarding() const {
+ _forwarding.verify(object_max_count(), _livemap.live_objects());
+}
+
+inline bool ZPage::is_marked() const {
+ assert(is_relocatable(), "Invalid page state");
+ return _livemap.is_marked();
+}
+
+inline bool ZPage::is_object_marked(uintptr_t addr) const {
+ const size_t index = ((ZAddress::offset(addr) - start()) >> object_alignment_shift()) * 2;
+ return _livemap.get(index);
+}
+
+inline bool ZPage::is_object_strongly_marked(uintptr_t addr) const {
+ const size_t index = ((ZAddress::offset(addr) - start()) >> object_alignment_shift()) * 2;
+ return _livemap.get(index + 1);
+}
+
+inline bool ZPage::is_object_live(uintptr_t addr) const {
+ return is_allocating() || is_object_marked(addr);
+}
+
+inline bool ZPage::is_object_strongly_live(uintptr_t addr) const {
+ return is_allocating() || is_object_strongly_marked(addr);
+}
+
+inline bool ZPage::mark_object(uintptr_t addr, bool finalizable, bool& inc_live) {
+ assert(ZAddress::is_marked(addr), "Invalid address");
+ assert(is_relocatable(), "Invalid page state");
+ assert(is_in(addr), "Invalid address");
+
+ // Set mark bit
+ const size_t index = ((ZAddress::offset(addr) - start()) >> object_alignment_shift()) * 2;
+ return _livemap.set_atomic(index, finalizable, inc_live);
+}
+
+inline void ZPage::inc_live_atomic(uint32_t objects, size_t bytes) {
+ _livemap.inc_live_atomic(objects, bytes);
+}
+
+inline size_t ZPage::live_bytes() const {
+ assert(is_marked(), "Should be marked");
+ return _livemap.live_bytes();
+}
+
+inline void ZPage::object_iterate(ObjectClosure* cl) {
+ _livemap.iterate(cl, ZAddress::good(start()), object_alignment_shift());
+}
+
+inline uintptr_t ZPage::alloc_object(size_t size) {
+ assert(is_allocating(), "Invalid state");
+
+ const size_t aligned_size = align_up(size, object_alignment());
+ const uintptr_t addr = top();
+ const uintptr_t new_top = addr + aligned_size;
+
+ if (new_top > end()) {
+ // Not enough space left
+ return 0;
+ }
+
+ _top = new_top;
+
+ // Fill alignment padding if needed
+ if (aligned_size != size) {
+ ZUtils::insert_filler_object(addr + size, aligned_size - size);
+ }
+
+ return ZAddress::good(addr);
+}
+
+inline uintptr_t ZPage::alloc_object_atomic(size_t size) {
+ assert(is_allocating(), "Invalid state");
+
+ const size_t aligned_size = align_up(size, object_alignment());
+ uintptr_t addr = top();
+
+ for (;;) {
+ const uintptr_t new_top = addr + aligned_size;
+ if (new_top > end()) {
+ // Not enough space left
+ return 0;
+ }
+
+ const uintptr_t prev_top = Atomic::cmpxchg(new_top, &_top, addr);
+ if (prev_top == addr) {
+ // Fill alignment padding if needed
+ if (aligned_size != size) {
+ ZUtils::insert_filler_object(addr + size, aligned_size - size);
+ }
+
+ // Success
+ return ZAddress::good(addr);
+ }
+
+ // Retry
+ addr = prev_top;
+ }
+}
+
+inline bool ZPage::undo_alloc_object(uintptr_t addr, size_t size) {
+ assert(is_allocating(), "Invalid state");
+
+ const uintptr_t offset = ZAddress::offset(addr);
+ const size_t aligned_size = align_up(size, object_alignment());
+ const uintptr_t old_top = top();
+ const uintptr_t new_top = old_top - aligned_size;
+
+ if (new_top != offset) {
+ // Failed to undo allocation, not the last allocated object
+ return false;
+ }
+
+ _top = new_top;
+
+ // Success
+ return true;
+}
+
+inline bool ZPage::undo_alloc_object_atomic(uintptr_t addr, size_t size) {
+ assert(is_allocating(), "Invalid state");
+
+ const uintptr_t offset = ZAddress::offset(addr);
+ const size_t aligned_size = align_up(size, object_alignment());
+ uintptr_t old_top = top();
+
+ for (;;) {
+ const uintptr_t new_top = old_top - aligned_size;
+ if (new_top != offset) {
+ // Failed to undo allocation, not the last allocated object
+ return false;
+ }
+
+ const uintptr_t prev_top = Atomic::cmpxchg(new_top, &_top, old_top);
+ if (prev_top == old_top) {
+ // Success
+ return true;
+ }
+
+ // Retry
+ old_top = prev_top;
+ }
+}
+
+#endif // SHARE_GC_Z_ZPAGE_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zPageAllocator.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,471 @@
+/*
+ * Copyright (c) 2015, 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 "gc/z/zAddress.inline.hpp"
+#include "gc/z/zCollectedHeap.hpp"
+#include "gc/z/zFuture.inline.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zLock.inline.hpp"
+#include "gc/z/zPage.inline.hpp"
+#include "gc/z/zPageAllocator.hpp"
+#include "gc/z/zPageCache.inline.hpp"
+#include "gc/z/zPreMappedMemory.inline.hpp"
+#include "gc/z/zStat.hpp"
+#include "gc/z/zTracer.inline.hpp"
+#include "runtime/init.hpp"
+
+static const ZStatCounter ZCounterAllocationRate("Memory", "Allocation Rate", ZStatUnitBytesPerSecond);
+static const ZStatCriticalPhase ZCriticalPhaseAllocationStall("Allocation Stall");
+
+class ZPageAllocRequest : public StackObj {
+ friend class ZList<ZPageAllocRequest>;
+
+private:
+ const uint8_t _type;
+ const size_t _size;
+ const ZAllocationFlags _flags;
+ const unsigned int _total_collections;
+ ZListNode<ZPageAllocRequest> _node;
+ ZFuture<ZPage*> _result;
+
+public:
+ ZPageAllocRequest(uint8_t type, size_t size, ZAllocationFlags flags, unsigned int total_collections) :
+ _type(type),
+ _size(size),
+ _flags(flags),
+ _total_collections(total_collections) {}
+
+ uint8_t type() const {
+ return _type;
+ }
+
+ size_t size() const {
+ return _size;
+ }
+
+ ZAllocationFlags flags() const {
+ return _flags;
+ }
+
+ unsigned int total_collections() const {
+ return _total_collections;
+ }
+
+ ZPage* wait() {
+ return _result.get();
+ }
+
+ void satisfy(ZPage* page) {
+ _result.set(page);
+ }
+};
+
+ZPage* const ZPageAllocator::gc_marker = (ZPage*)-1;
+
+ZPageAllocator::ZPageAllocator(size_t min_capacity, size_t max_capacity, size_t max_reserve) :
+ _virtual(),
+ _physical(max_capacity, ZPageSizeMin),
+ _cache(),
+ _pre_mapped(_virtual, _physical, min_capacity),
+ _max_reserve(max_reserve),
+ _used_high(0),
+ _used_low(0),
+ _used(0),
+ _allocated(0),
+ _reclaimed(0),
+ _queue(),
+ _detached() {}
+
+bool ZPageAllocator::is_initialized() const {
+ return _physical.is_initialized() &&
+ _virtual.is_initialized() &&
+ _pre_mapped.is_initialized();
+}
+
+size_t ZPageAllocator::max_capacity() const {
+ return _physical.max_capacity();
+}
+
+size_t ZPageAllocator::capacity() const {
+ return _physical.capacity();
+}
+
+size_t ZPageAllocator::max_reserve() const {
+ return _max_reserve;
+}
+
+size_t ZPageAllocator::used_high() const {
+ return _used_high;
+}
+
+size_t ZPageAllocator::used_low() const {
+ return _used_low;
+}
+
+size_t ZPageAllocator::used() const {
+ return _used;
+}
+
+size_t ZPageAllocator::allocated() const {
+ return _allocated;
+}
+
+size_t ZPageAllocator::reclaimed() const {
+ return _reclaimed > 0 ? (size_t)_reclaimed : 0;
+}
+
+void ZPageAllocator::reset_statistics() {
+ assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
+ _allocated = 0;
+ _reclaimed = 0;
+ _used_high = _used_low = _used;
+}
+
+void ZPageAllocator::increase_used(size_t size, bool relocation) {
+ if (relocation) {
+ // Allocating a page for the purpose of relocation has a
+ // negative contribution to the number of relcaimed bytes.
+ _reclaimed -= size;
+ }
+ _allocated += size;
+ _used += size;
+ if (_used > _used_high) {
+ _used_high = _used;
+ }
+}
+
+void ZPageAllocator::decrease_used(size_t size, bool reclaimed) {
+ if (reclaimed) {
+ // Only pages explicitly released with the reclaimed flag set
+ // counts as reclaimed bytes. This flag is typically true when
+ // a worker releases a page after relocation, and is typically
+ // false when we release a page to undo an allocation.
+ _reclaimed += size;
+ }
+ _used -= size;
+ if (_used < _used_low) {
+ _used_low = _used;
+ }
+}
+
+size_t ZPageAllocator::available(ZAllocationFlags flags) const {
+ size_t available = max_capacity() - used();
+ assert(_physical.available() + _pre_mapped.available() + _cache.available() == available, "Should be equal");
+
+ if (flags.no_reserve()) {
+ // The memory reserve should not be considered free
+ available -= MIN2(available, max_reserve());
+ }
+
+ return available;
+}
+
+ZPage* ZPageAllocator::create_page(uint8_t type, size_t size) {
+ // Allocate physical memory
+ const ZPhysicalMemory pmem = _physical.alloc(size);
+ if (pmem.is_null()) {
+ // Out of memory
+ return NULL;
+ }
+
+ // Allocate virtual memory
+ const ZVirtualMemory vmem = _virtual.alloc(size);
+ if (vmem.is_null()) {
+ // Out of address space
+ _physical.free(pmem);
+ return NULL;
+ }
+
+ // Allocate page
+ return new ZPage(type, vmem, pmem);
+}
+
+void ZPageAllocator::flush_pre_mapped() {
+ if (_pre_mapped.available() == 0) {
+ return;
+ }
+
+ // Detach the memory mapping.
+ detach_memory(_pre_mapped.virtual_memory(), _pre_mapped.physical_memory());
+
+ _pre_mapped.clear();
+}
+
+void ZPageAllocator::map_page(ZPage* page) {
+ // Map physical memory
+ _physical.map(page->physical_memory(), page->start());
+}
+
+void ZPageAllocator::detach_page(ZPage* page) {
+ // Detach the memory mapping.
+ detach_memory(page->virtual_memory(), page->physical_memory());
+
+ // Add to list of detached pages
+ _detached.insert_last(page);
+}
+
+void ZPageAllocator::destroy_page(ZPage* page) {
+ assert(page->is_detached(), "Invalid page state");
+
+ // Free virtual memory
+ {
+ ZLocker locker(&_lock);
+ _virtual.free(page->virtual_memory());
+ }
+
+ delete page;
+}
+
+void ZPageAllocator::flush_detached_pages(ZList<ZPage>* list) {
+ ZLocker locker(&_lock);
+ list->transfer(&_detached);
+}
+
+void ZPageAllocator::flush_cache(size_t size) {
+ ZList<ZPage> list;
+
+ _cache.flush(&list, size);
+
+ for (ZPage* page = list.remove_first(); page != NULL; page = list.remove_first()) {
+ detach_page(page);
+ }
+}
+
+void ZPageAllocator::check_out_of_memory_during_initialization() {
+ if (!is_init_completed()) {
+ vm_exit_during_initialization("java.lang.OutOfMemoryError", "Java heap too small");
+ }
+}
+
+ZPage* ZPageAllocator::alloc_page_common_inner(uint8_t type, size_t size, ZAllocationFlags flags) {
+ const size_t available_total = available(flags);
+ if (available_total < size) {
+ // Not enough free memory
+ return NULL;
+ }
+
+ // Try allocating from the page cache
+ ZPage* const cached_page = _cache.alloc_page(type, size);
+ if (cached_page != NULL) {
+ return cached_page;
+ }
+
+ // Try allocate from the pre-mapped memory
+ ZPage* const pre_mapped_page = _pre_mapped.alloc_page(type, size);
+ if (pre_mapped_page != NULL) {
+ return pre_mapped_page;
+ }
+
+ // Flush any remaining pre-mapped memory so that
+ // subsequent allocations can use the physical memory.
+ flush_pre_mapped();
+
+ // Check if physical memory is available
+ const size_t available_physical = _physical.available();
+ if (available_physical < size) {
+ // Flush cache to free up more physical memory
+ flush_cache(size - available_physical);
+ }
+
+ // Create new page and allocate physical memory
+ return create_page(type, size);
+}
+
+ZPage* ZPageAllocator::alloc_page_common(uint8_t type, size_t size, ZAllocationFlags flags) {
+ ZPage* const page = alloc_page_common_inner(type, size, flags);
+ if (page == NULL) {
+ // Out of memory
+ return NULL;
+ }
+
+ // Update used statistics
+ increase_used(size, flags.relocation());
+
+ // Send trace event
+ ZTracer::tracer()->report_page_alloc(size, used(), available(flags), _cache.available(), flags);
+
+ return page;
+}
+
+ZPage* ZPageAllocator::alloc_page_blocking(uint8_t type, size_t size, ZAllocationFlags flags) {
+ // Prepare to block
+ ZPageAllocRequest request(type, size, flags, ZCollectedHeap::heap()->total_collections());
+
+ _lock.lock();
+
+ // Try non-blocking allocation
+ ZPage* page = alloc_page_common(type, size, flags);
+ if (page == NULL) {
+ // Allocation failed, enqueue request
+ _queue.insert_last(&request);
+ }
+
+ _lock.unlock();
+
+ if (page == NULL) {
+ // Allocation failed
+ ZStatTimer timer(ZCriticalPhaseAllocationStall);
+
+ // We can only block if VM is fully initialized
+ check_out_of_memory_during_initialization();
+
+ do {
+ // Start asynchronous GC
+ ZCollectedHeap::heap()->collect(GCCause::_z_allocation_stall);
+
+ // Wait for allocation to complete or fail
+ page = request.wait();
+ } while (page == gc_marker);
+ }
+
+ return page;
+}
+
+ZPage* ZPageAllocator::alloc_page_nonblocking(uint8_t type, size_t size, ZAllocationFlags flags) {
+ ZLocker locker(&_lock);
+ return alloc_page_common(type, size, flags);
+}
+
+ZPage* ZPageAllocator::alloc_page(uint8_t type, size_t size, ZAllocationFlags flags) {
+ ZPage* const page = flags.non_blocking()
+ ? alloc_page_nonblocking(type, size, flags)
+ : alloc_page_blocking(type, size, flags);
+ if (page == NULL) {
+ // Out of memory
+ return NULL;
+ }
+
+ // Map page if needed
+ if (!page->is_mapped()) {
+ map_page(page);
+ }
+
+ // Reset page. This updates the page's sequence number and must
+ // be done after page allocation, which potentially blocked in
+ // a safepoint where the global sequence number was updated.
+ page->reset();
+
+ // Update allocation statistics. Exclude worker threads to avoid
+ // artificial inflation of the allocation rate due to relocation.
+ if (!flags.worker_thread()) {
+ // Note that there are two allocation rate counters, which have
+ // different purposes and are sampled at different frequencies.
+ const size_t bytes = page->size();
+ ZStatInc(ZCounterAllocationRate, bytes);
+ ZStatInc(ZStatAllocRate::counter(), bytes);
+ }
+
+ return page;
+}
+
+void ZPageAllocator::satisfy_alloc_queue() {
+ for (;;) {
+ ZPageAllocRequest* const request = _queue.first();
+ if (request == NULL) {
+ // Allocation queue is empty
+ return;
+ }
+
+ ZPage* const page = alloc_page_common(request->type(), request->size(), request->flags());
+ if (page == NULL) {
+ // Allocation could not be satisfied, give up
+ return;
+ }
+
+ // Allocation succeeded, dequeue and satisfy request. Note that
+ // the dequeue operation must happen first, since the request
+ // will immediately be deallocated once it has been satisfied.
+ _queue.remove(request);
+ request->satisfy(page);
+ }
+}
+
+void ZPageAllocator::detach_memory(const ZVirtualMemory& vmem, ZPhysicalMemory& pmem) {
+ const uintptr_t addr = vmem.start();
+
+ // Unmap physical memory
+ _physical.unmap(pmem, addr);
+
+ // Free physical memory
+ _physical.free(pmem);
+
+ // Clear physical mapping
+ pmem.clear();
+}
+
+void ZPageAllocator::flip_page(ZPage* page) {
+ const ZPhysicalMemory& pmem = page->physical_memory();
+ const uintptr_t addr = page->start();
+
+ // Flip physical mapping
+ _physical.flip(pmem, addr);
+}
+
+void ZPageAllocator::flip_pre_mapped() {
+ if (_pre_mapped.available() == 0) {
+ // Nothing to flip
+ return;
+ }
+
+ const ZPhysicalMemory& pmem = _pre_mapped.physical_memory();
+ const ZVirtualMemory& vmem = _pre_mapped.virtual_memory();
+
+ // Flip physical mapping
+ _physical.flip(pmem, vmem.start());
+}
+
+void ZPageAllocator::free_page(ZPage* page, bool reclaimed) {
+ ZLocker locker(&_lock);
+
+ // Update used statistics
+ decrease_used(page->size(), reclaimed);
+
+ // Cache page
+ _cache.free_page(page);
+
+ // Try satisfy blocked allocations
+ satisfy_alloc_queue();
+}
+
+void ZPageAllocator::check_out_of_memory() {
+ ZLocker locker(&_lock);
+
+ ZPageAllocRequest* const first = _queue.first();
+ if (first == NULL) {
+ // Allocation queue is empty
+ return;
+ }
+
+ // Fail the allocation request if it was enqueued before the
+ // last GC cycle started, otherwise start a new GC cycle.
+ if (first->total_collections() < ZCollectedHeap::heap()->total_collections()) {
+ // Out of memory, fail all enqueued requests
+ for (ZPageAllocRequest* request = _queue.remove_first(); request != NULL; request = _queue.remove_first()) {
+ request->satisfy(NULL);
+ }
+ } else {
+ // Start another GC cycle, keep all enqueued requests
+ first->satisfy(gc_marker);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zPageAllocator.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZPAGEALLOCATOR_HPP
+#define SHARE_GC_Z_ZPAGEALLOCATOR_HPP
+
+#include "gc/z/zAllocationFlags.hpp"
+#include "gc/z/zList.hpp"
+#include "gc/z/zLock.hpp"
+#include "gc/z/zPageCache.hpp"
+#include "gc/z/zPhysicalMemory.hpp"
+#include "gc/z/zPreMappedMemory.hpp"
+#include "gc/z/zVirtualMemory.hpp"
+#include "memory/allocation.hpp"
+
+class ZPageAllocRequest;
+
+class ZPageAllocator {
+ friend class VMStructs;
+
+private:
+ ZLock _lock;
+ ZVirtualMemoryManager _virtual;
+ ZPhysicalMemoryManager _physical;
+ ZPageCache _cache;
+ ZPreMappedMemory _pre_mapped;
+ const size_t _max_reserve;
+ size_t _used_high;
+ size_t _used_low;
+ size_t _used;
+ size_t _allocated;
+ ssize_t _reclaimed;
+ ZList<ZPageAllocRequest> _queue;
+ ZList<ZPage> _detached;
+
+ static ZPage* const gc_marker;
+
+ void increase_used(size_t size, bool relocation);
+ void decrease_used(size_t size, bool reclaimed);
+
+ size_t available(ZAllocationFlags flags) const;
+
+ ZPage* create_page(uint8_t type, size_t size);
+ void map_page(ZPage* page);
+ void detach_page(ZPage* page);
+ void flush_pre_mapped();
+ void flush_cache(size_t size);
+
+ void check_out_of_memory_during_initialization();
+
+ ZPage* alloc_page_common_inner(uint8_t type, size_t size, ZAllocationFlags flags);
+ ZPage* alloc_page_common(uint8_t type, size_t size, ZAllocationFlags flags);
+ ZPage* alloc_page_blocking(uint8_t type, size_t size, ZAllocationFlags flags);
+ ZPage* alloc_page_nonblocking(uint8_t type, size_t size, ZAllocationFlags flags);
+
+ void satisfy_alloc_queue();
+
+ void detach_memory(const ZVirtualMemory& vmem, ZPhysicalMemory& pmem);
+
+public:
+ ZPageAllocator(size_t min_capacity, size_t max_capacity, size_t max_reserve);
+
+ bool is_initialized() const;
+
+ size_t max_capacity() const;
+ size_t capacity() const;
+ size_t max_reserve() const;
+ size_t used_high() const;
+ size_t used_low() const;
+ size_t used() const;
+ size_t allocated() const;
+ size_t reclaimed() const;
+
+ void reset_statistics();
+
+ ZPage* alloc_page(uint8_t type, size_t size, ZAllocationFlags flags);
+ void flip_page(ZPage* page);
+ void free_page(ZPage* page, bool reclaimed);
+ void destroy_page(ZPage* page);
+
+ void flush_detached_pages(ZList<ZPage>* list);
+
+ void flip_pre_mapped();
+
+ void check_out_of_memory();
+};
+
+#endif // SHARE_GC_Z_ZPAGEALLOCATOR_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zPageCache.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2015, 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 "gc/z/zList.inline.hpp"
+#include "gc/z/zNUMA.hpp"
+#include "gc/z/zPage.inline.hpp"
+#include "gc/z/zPageCache.hpp"
+#include "gc/z/zStat.hpp"
+#include "logging/log.hpp"
+
+static const ZStatCounter ZCounterPageCacheHitL1("Memory", "Page Cache Hit L1", ZStatUnitOpsPerSecond);
+static const ZStatCounter ZCounterPageCacheHitL2("Memory", "Page Cache Hit L2", ZStatUnitOpsPerSecond);
+static const ZStatCounter ZCounterPageCacheMiss("Memory", "Page Cache Miss", ZStatUnitOpsPerSecond);
+static const ZStatCounter ZCounterPageCacheFlush("Memory", "Page Cache Flush", ZStatUnitBytesPerSecond);
+
+ZPageCache::ZPageCache() :
+ _available(0),
+ _small(),
+ _medium(),
+ _large() {}
+
+ZPage* ZPageCache::alloc_small_page() {
+ const uint32_t numa_id = ZNUMA::id();
+ const uint32_t numa_count = ZNUMA::count();
+
+ // Try NUMA local page cache
+ ZPage* const l1_page = _small.get(numa_id).remove_first();
+ if (l1_page != NULL) {
+ ZStatInc(ZCounterPageCacheHitL1);
+ return l1_page;
+ }
+
+ // Try NUMA remote page cache(s)
+ uint32_t remote_numa_id = numa_id + 1;
+ const uint32_t remote_numa_count = numa_count - 1;
+ for (uint32_t i = 0; i < remote_numa_count; i++) {
+ if (remote_numa_id == numa_count) {
+ remote_numa_id = 0;
+ }
+
+ ZPage* const l2_page = _small.get(remote_numa_id).remove_first();
+ if (l2_page != NULL) {
+ ZStatInc(ZCounterPageCacheHitL2);
+ return l2_page;
+ }
+
+ remote_numa_id++;
+ }
+
+ ZStatInc(ZCounterPageCacheMiss);
+ return NULL;
+}
+
+ZPage* ZPageCache::alloc_medium_page() {
+ ZPage* const l1_page = _medium.remove_first();
+ if (l1_page != NULL) {
+ ZStatInc(ZCounterPageCacheHitL1);
+ return l1_page;
+ }
+
+ ZStatInc(ZCounterPageCacheMiss);
+ return NULL;
+}
+
+ZPage* ZPageCache::alloc_large_page(size_t size) {
+ // Find a page with the right size
+ ZListIterator<ZPage> iter(&_large);
+ for (ZPage* l1_page; iter.next(&l1_page);) {
+ if (l1_page->size() == size) {
+ // Page found
+ _large.remove(l1_page);
+ ZStatInc(ZCounterPageCacheHitL1);
+ return l1_page;
+ }
+ }
+
+ ZStatInc(ZCounterPageCacheMiss);
+ return NULL;
+}
+
+ZPage* ZPageCache::alloc_page(uint8_t type, size_t size) {
+ ZPage* page;
+
+ if (type == ZPageTypeSmall) {
+ page = alloc_small_page();
+ } else if (type == ZPageTypeMedium) {
+ page = alloc_medium_page();
+ } else {
+ page = alloc_large_page(size);
+ }
+
+ if (page != NULL) {
+ _available -= page->size();
+ }
+
+ return page;
+}
+
+void ZPageCache::free_page(ZPage* page) {
+ assert(!page->is_active(), "Invalid page state");
+ assert(!page->is_pinned(), "Invalid page state");
+ assert(!page->is_detached(), "Invalid page state");
+
+ const uint8_t type = page->type();
+ if (type == ZPageTypeSmall) {
+ _small.get(page->numa_id()).insert_first(page);
+ } else if (type == ZPageTypeMedium) {
+ _medium.insert_first(page);
+ } else {
+ _large.insert_first(page);
+ }
+
+ _available += page->size();
+}
+
+void ZPageCache::flush_list(ZList<ZPage>* from, size_t requested, ZList<ZPage>* to, size_t* flushed) {
+ while (*flushed < requested) {
+ // Flush least recently used
+ ZPage* const page = from->remove_last();
+ if (page == NULL) {
+ break;
+ }
+
+ *flushed += page->size();
+ to->insert_last(page);
+ }
+}
+
+void ZPageCache::flush_per_numa_lists(ZPerNUMA<ZList<ZPage> >* from, size_t requested, ZList<ZPage>* to, size_t* flushed) {
+ const uint32_t numa_count = ZNUMA::count();
+ uint32_t numa_empty = 0;
+ uint32_t numa_next = 0;
+
+ // Flush lists round-robin
+ while (*flushed < requested) {
+ ZPage* const page = from->get(numa_next).remove_last();
+
+ if (++numa_next == numa_count) {
+ numa_next = 0;
+ }
+
+ if (page == NULL) {
+ // List is empty
+ if (++numa_empty == numa_count) {
+ // All lists are empty
+ break;
+ }
+
+ // Try next list
+ continue;
+ }
+
+ // Flush page
+ numa_empty = 0;
+ *flushed += page->size();
+ to->insert_last(page);
+ }
+}
+
+void ZPageCache::flush(ZList<ZPage>* to, size_t requested) {
+ size_t flushed = 0;
+
+ // Prefer flushing large, then medium and last small pages
+ flush_list(&_large, requested, to, &flushed);
+ flush_list(&_medium, requested, to, &flushed);
+ flush_per_numa_lists(&_small, requested, to, &flushed);
+
+ ZStatInc(ZCounterPageCacheFlush, flushed);
+
+ log_info(gc, heap)("Page Cache Flushed: "
+ SIZE_FORMAT "M requested, "
+ SIZE_FORMAT "M(" SIZE_FORMAT "M->" SIZE_FORMAT "M) flushed",
+ requested / M, flushed / M , _available / M, (_available - flushed) / M);
+
+ _available -= flushed;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zPageCache.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZPAGECACHE_HPP
+#define SHARE_GC_Z_ZPAGECACHE_HPP
+
+#include "gc/z/zList.hpp"
+#include "gc/z/zPage.hpp"
+#include "gc/z/zValue.hpp"
+#include "memory/allocation.hpp"
+
+class ZPageCache {
+private:
+ size_t _available;
+
+ ZPerNUMA<ZList<ZPage> > _small;
+ ZList<ZPage> _medium;
+ ZList<ZPage> _large;
+
+ ZPage* alloc_small_page();
+ ZPage* alloc_medium_page();
+ ZPage* alloc_large_page(size_t size);
+
+ void flush_list(ZList<ZPage>* from, size_t requested, ZList<ZPage>* to, size_t* flushed);
+ void flush_per_numa_lists(ZPerNUMA<ZList<ZPage> >* from, size_t requested, ZList<ZPage>* to, size_t* flushed);
+
+public:
+ ZPageCache();
+
+ size_t available() const;
+
+ ZPage* alloc_page(uint8_t type, size_t size);
+ void free_page(ZPage* page);
+
+ void flush(ZList<ZPage>* to, size_t requested);
+};
+
+#endif // SHARE_GC_Z_ZPAGECACHE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zPageCache.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZPAGECACHE_INLINE_HPP
+#define SHARE_GC_Z_ZPAGECACHE_INLINE_HPP
+
+#include "gc/z/zPageCache.hpp"
+
+inline size_t ZPageCache::available() const {
+ return _available;
+}
+
+#endif // SHARE_GC_Z_ZPAGECACHE_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zPageTable.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2015, 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 "gc/z/zPage.inline.hpp"
+#include "gc/z/zPageTable.inline.hpp"
+#include "runtime/orderAccess.hpp"
+#include "utilities/debug.hpp"
+
+ZPageTable::ZPageTable() :
+ _map() {}
+
+ZPageTableEntry ZPageTable::get_entry(ZPage* page) const {
+ const uintptr_t addr = ZAddress::good(page->start());
+ return _map.get(addr);
+}
+
+void ZPageTable::put_entry(ZPage* page, ZPageTableEntry entry) {
+ // Make sure a newly created page is globally visible before
+ // updating the pagetable.
+ OrderAccess::storestore();
+
+ const uintptr_t start = ZAddress::good(page->start());
+ const uintptr_t end = start + page->size();
+ for (uintptr_t addr = start; addr < end; addr += ZPageSizeMin) {
+ _map.put(addr, entry);
+ }
+}
+
+void ZPageTable::insert(ZPage* page) {
+ assert(get_entry(page).page() == NULL ||
+ get_entry(page).page() == page, "Invalid entry");
+
+ // Cached pages stays in the pagetable and we must not re-insert
+ // those when they get re-allocated because they might also be
+ // relocating and we don't want to clear their relocating bit.
+ if (get_entry(page).page() == NULL) {
+ ZPageTableEntry entry(page, false /* relocating */);
+ put_entry(page, entry);
+ }
+
+ assert(get_entry(page).page() == page, "Invalid entry");
+}
+
+void ZPageTable::remove(ZPage* page) {
+ assert(get_entry(page).page() == page, "Invalid entry");
+
+ ZPageTableEntry entry;
+ put_entry(page, entry);
+
+ assert(get_entry(page).page() == NULL, "Invalid entry");
+}
+
+void ZPageTable::set_relocating(ZPage* page) {
+ assert(get_entry(page).page() == page, "Invalid entry");
+ assert(!get_entry(page).relocating(), "Invalid entry");
+
+ ZPageTableEntry entry(page, true /* relocating */);
+ put_entry(page, entry);
+
+ assert(get_entry(page).page() == page, "Invalid entry");
+ assert(get_entry(page).relocating(), "Invalid entry");
+}
+
+void ZPageTable::clear_relocating(ZPage* page) {
+ assert(get_entry(page).page() == page, "Invalid entry");
+ assert(get_entry(page).relocating(), "Invalid entry");
+
+ ZPageTableEntry entry(page, false /* relocating */);
+ put_entry(page, entry);
+
+ assert(get_entry(page).page() == page, "Invalid entry");
+ assert(!get_entry(page).relocating(), "Invalid entry");
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zPageTable.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,67 @@
+/*
+ * 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_GC_Z_ZPAGETABLE_HPP
+#define SHARE_GC_Z_ZPAGETABLE_HPP
+
+#include "gc/z/zAddressRangeMap.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zPageTableEntry.hpp"
+#include "memory/allocation.hpp"
+
+class ZPage;
+
+class ZPageTable {
+ friend class VMStructs;
+ friend class ZPageTableIterator;
+
+private:
+ ZAddressRangeMap<ZPageTableEntry, ZPageSizeMinShift> _map;
+
+ ZPageTableEntry get_entry(ZPage* page) const;
+ void put_entry(ZPage* page, ZPageTableEntry entry);
+
+public:
+ ZPageTable();
+
+ ZPage* get(uintptr_t addr) const;
+ void insert(ZPage* page);
+ void remove(ZPage* page);
+
+ bool is_relocating(uintptr_t addr) const;
+ void set_relocating(ZPage* page);
+ void clear_relocating(ZPage* page);
+};
+
+class ZPageTableIterator : public StackObj {
+private:
+ ZAddressRangeMapIterator<ZPageTableEntry, ZPageSizeMinShift> _iter;
+ ZPage* _prev;
+
+public:
+ ZPageTableIterator(const ZPageTable* pagetable);
+
+ bool next(ZPage** page);
+};
+
+#endif // SHARE_GC_Z_ZPAGETABLE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zPageTable.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZPAGETABLE_INLINE_HPP
+#define SHARE_GC_Z_ZPAGETABLE_INLINE_HPP
+
+#include "gc/z/zAddress.inline.hpp"
+#include "gc/z/zAddressRangeMap.inline.hpp"
+#include "gc/z/zPageTable.hpp"
+
+inline ZPage* ZPageTable::get(uintptr_t addr) const {
+ return _map.get(addr).page();
+}
+
+inline bool ZPageTable::is_relocating(uintptr_t addr) const {
+ return _map.get(addr).relocating();
+}
+
+inline ZPageTableIterator::ZPageTableIterator(const ZPageTable* pagetable) :
+ _iter(&pagetable->_map),
+ _prev(NULL) {}
+
+inline bool ZPageTableIterator::next(ZPage** page) {
+ ZPageTableEntry entry;
+
+ while (_iter.next(&entry)) {
+ ZPage* const next = entry.page();
+ if (next != NULL && next != _prev) {
+ // Next page found
+ *page = _prev = next;
+ return true;
+ }
+ }
+
+ // No more pages
+ return false;
+}
+
+#endif // SHARE_GC_Z_ZPAGETABLE_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zPageTableEntry.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef SHARE_GC_Z_ZPAGETABLEENTRY_HPP
+#define SHARE_GC_Z_ZPAGETABLEENTRY_HPP
+
+#include "gc/z/zBitField.hpp"
+#include "memory/allocation.hpp"
+
+//
+// Page table entry layout
+// -----------------------
+//
+// 6
+// 3 1 0
+// +----------------------------------------------------------------------+-+
+// |11111111 11111111 11111111 11111111 11111111 11111111 11111111 1111111|1|
+// +----------------------------------------------------------------------+-+
+// | |
+// | 0-0 Relocating Flag (1-bit) *
+// |
+// |
+// |
+// * 63-1 Page address (63-bits)
+//
+
+class ZPage;
+
+class ZPageTableEntry {
+private:
+ typedef ZBitField<uint64_t, bool, 0, 1> field_relocating;
+ typedef ZBitField<uint64_t, ZPage*, 1, 63, 1> field_page;
+
+ uint64_t _entry;
+
+public:
+ ZPageTableEntry() :
+ _entry(0) {}
+
+ ZPageTableEntry(ZPage* page, bool relocating) :
+ _entry(field_page::encode(page) |
+ field_relocating::encode(relocating)) {}
+
+ bool relocating() const {
+ return field_relocating::decode(_entry);
+ }
+
+ ZPage* page() const {
+ return field_page::decode(_entry);
+ }
+};
+
+#endif // SHARE_GC_Z_ZPAGETABLEENTRY_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zPhysicalMemory.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2015, 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 "gc/z/zPhysicalMemory.inline.hpp"
+#include "logging/log.hpp"
+#include "memory/allocation.inline.hpp"
+#include "services/memTracker.hpp"
+#include "utilities/debug.hpp"
+
+ZPhysicalMemory::ZPhysicalMemory() :
+ _nsegments(0),
+ _segments(NULL) {}
+
+ZPhysicalMemory::ZPhysicalMemory(size_t size) :
+ _nsegments(0),
+ _segments(NULL) {
+ add_segment(ZPhysicalMemorySegment(0, size));
+}
+
+ZPhysicalMemory::ZPhysicalMemory(const ZPhysicalMemorySegment& segment) :
+ _nsegments(0),
+ _segments(NULL) {
+ add_segment(segment);
+}
+
+size_t ZPhysicalMemory::size() const {
+ size_t size = 0;
+
+ for (size_t i = 0; i < _nsegments; i++) {
+ size += _segments[i].size();
+ }
+
+ return size;
+}
+
+void ZPhysicalMemory::add_segment(ZPhysicalMemorySegment segment) {
+ // Try merge with last segment
+ if (_nsegments > 0) {
+ ZPhysicalMemorySegment& last = _segments[_nsegments - 1];
+ assert(last.end() <= segment.start(), "Segments added out of order");
+ if (last.end() == segment.start()) {
+ // Merge
+ last.expand(segment.size());
+ return;
+ }
+ }
+
+ // Make room for a new segment
+ const size_t size = sizeof(ZPhysicalMemorySegment) * (_nsegments + 1);
+ _segments = (ZPhysicalMemorySegment*)ReallocateHeap((char*)_segments, size, mtGC);
+
+ // Add new segment
+ _segments[_nsegments] = segment;
+ _nsegments++;
+}
+
+ZPhysicalMemory ZPhysicalMemory::split(size_t split_size) {
+ // Only splitting of single-segment instances have been implemented.
+ assert(nsegments() == 1, "Can only have one segment");
+ assert(split_size <= size(), "Invalid size");
+ return ZPhysicalMemory(_segments[0].split(split_size));
+}
+
+void ZPhysicalMemory::clear() {
+ if (_segments != NULL) {
+ FreeHeap(_segments);
+ _segments = NULL;
+ _nsegments = 0;
+ }
+}
+
+ZPhysicalMemoryManager::ZPhysicalMemoryManager(size_t max_capacity, size_t granule_size) :
+ _backing(max_capacity, granule_size),
+ _max_capacity(max_capacity),
+ _capacity(0),
+ _used(0) {}
+
+bool ZPhysicalMemoryManager::is_initialized() const {
+ return _backing.is_initialized();
+}
+
+bool ZPhysicalMemoryManager::ensure_available(size_t size) {
+ const size_t unused_capacity = _capacity - _used;
+ if (unused_capacity >= size) {
+ // Enough unused capacity available
+ return true;
+ }
+
+ const size_t expand_with = size - unused_capacity;
+ const size_t new_capacity = _capacity + expand_with;
+ if (new_capacity > _max_capacity) {
+ // Can not expand beyond max capacity
+ return false;
+ }
+
+ // Expand
+ if (!_backing.expand(_capacity, new_capacity)) {
+ log_error(gc)("Failed to expand Java heap with " SIZE_FORMAT "%s",
+ byte_size_in_proper_unit(expand_with),
+ proper_unit_for_byte_size(expand_with));
+ return false;
+ }
+
+ _capacity = new_capacity;
+
+ return true;
+}
+
+void ZPhysicalMemoryManager::nmt_commit(ZPhysicalMemory pmem, uintptr_t offset) {
+ const uintptr_t addr = _backing.nmt_address(offset);
+ const size_t size = pmem.size();
+ MemTracker::record_virtual_memory_commit((void*)addr, size, CALLER_PC);
+}
+
+void ZPhysicalMemoryManager::nmt_uncommit(ZPhysicalMemory pmem, uintptr_t offset) {
+ if (MemTracker::tracking_level() > NMT_minimal) {
+ const uintptr_t addr = _backing.nmt_address(offset);
+ const size_t size = pmem.size();
+
+ Tracker tracker(Tracker::uncommit);
+ tracker.record((address)addr, size);
+ }
+}
+
+ZPhysicalMemory ZPhysicalMemoryManager::alloc(size_t size) {
+ if (!ensure_available(size)) {
+ // Not enough memory available
+ return ZPhysicalMemory();
+ }
+
+ _used += size;
+ return _backing.alloc(size);
+}
+
+void ZPhysicalMemoryManager::free(ZPhysicalMemory pmem) {
+ _backing.free(pmem);
+ _used -= pmem.size();
+}
+
+void ZPhysicalMemoryManager::map(ZPhysicalMemory pmem, uintptr_t offset) {
+ // Map page
+ _backing.map(pmem, offset);
+
+ // Update native memory tracker
+ nmt_commit(pmem, offset);
+}
+
+void ZPhysicalMemoryManager::unmap(ZPhysicalMemory pmem, uintptr_t offset) {
+ // Update native memory tracker
+ nmt_uncommit(pmem, offset);
+
+ // Unmap page
+ _backing.unmap(pmem, offset);
+}
+
+void ZPhysicalMemoryManager::flip(ZPhysicalMemory pmem, uintptr_t offset) {
+ _backing.flip(pmem, offset);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zPhysicalMemory.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZPHYSICALMEMORY_HPP
+#define SHARE_GC_Z_ZPHYSICALMEMORY_HPP
+
+#include "memory/allocation.hpp"
+#include OS_CPU_HEADER(gc/z/zPhysicalMemoryBacking)
+
+class ZPhysicalMemorySegment {
+private:
+ uintptr_t _start;
+ uintptr_t _end;
+
+public:
+ ZPhysicalMemorySegment(uintptr_t start, size_t size);
+
+ uintptr_t start() const;
+ uintptr_t end() const;
+ size_t size() const;
+
+ void expand(size_t size);
+ ZPhysicalMemorySegment split(size_t size);
+};
+
+class ZPhysicalMemory {
+private:
+ size_t _nsegments;
+ ZPhysicalMemorySegment* _segments;
+
+public:
+ ZPhysicalMemory();
+ ZPhysicalMemory(size_t size);
+ ZPhysicalMemory(const ZPhysicalMemorySegment& segment);
+
+ bool is_null() const;
+ size_t size() const;
+
+ size_t nsegments() const;
+ ZPhysicalMemorySegment segment(size_t index) const;
+ void add_segment(ZPhysicalMemorySegment segment);
+
+ ZPhysicalMemory split(size_t size);
+ void clear();
+};
+
+class ZPhysicalMemoryManager {
+ friend class VMStructs;
+
+private:
+ ZPhysicalMemoryBacking _backing;
+ const size_t _max_capacity;
+ size_t _capacity;
+ size_t _used;
+
+ bool ensure_available(size_t size);
+
+ void nmt_commit(ZPhysicalMemory pmem, uintptr_t offset);
+ void nmt_uncommit(ZPhysicalMemory pmem, uintptr_t offset);
+
+public:
+ ZPhysicalMemoryManager(size_t max_capacity, size_t granule_size);
+
+ bool is_initialized() const;
+
+ size_t max_capacity() const;
+ size_t capacity() const;
+ size_t used() const;
+ size_t available() const;
+
+ ZPhysicalMemory alloc(size_t size);
+ void free(ZPhysicalMemory pmem);
+
+ void map(ZPhysicalMemory pmem, uintptr_t offset);
+ void unmap(ZPhysicalMemory pmem, uintptr_t offset);
+ void flip(ZPhysicalMemory pmem, uintptr_t offset);
+};
+
+#endif // SHARE_GC_Z_ZPHYSICALMEMORY_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zPhysicalMemory.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZPHYSICALMEMORY_INLINE_HPP
+#define SHARE_GC_Z_ZPHYSICALMEMORY_INLINE_HPP
+
+#include "gc/z/zPhysicalMemory.hpp"
+#include "utilities/debug.hpp"
+
+inline ZPhysicalMemorySegment::ZPhysicalMemorySegment(uintptr_t start, size_t size) :
+ _start(start),
+ _end(start + size) {}
+
+inline uintptr_t ZPhysicalMemorySegment::start() const {
+ return _start;
+}
+
+inline uintptr_t ZPhysicalMemorySegment::end() const {
+ return _end;
+}
+
+inline size_t ZPhysicalMemorySegment::size() const {
+ return end() - start();
+}
+
+inline void ZPhysicalMemorySegment::expand(size_t size) {
+ _end += size;
+}
+
+inline ZPhysicalMemorySegment ZPhysicalMemorySegment::split(size_t split_size) {
+ assert(split_size <= size(), "Invalid size");
+ ZPhysicalMemorySegment segment(_start, split_size);
+ _start += split_size;
+ return segment;
+}
+
+inline bool ZPhysicalMemory::is_null() const {
+ return _nsegments == 0;
+}
+
+inline size_t ZPhysicalMemory::nsegments() const {
+ return _nsegments;
+}
+
+inline ZPhysicalMemorySegment ZPhysicalMemory::segment(size_t index) const {
+ assert(index < _nsegments, "Invalid segment index");
+ return _segments[index];
+}
+
+inline size_t ZPhysicalMemoryManager::max_capacity() const {
+ return _max_capacity;
+}
+
+inline size_t ZPhysicalMemoryManager::capacity() const {
+ return _capacity;
+}
+
+inline size_t ZPhysicalMemoryManager::used() const {
+ return _used;
+}
+
+inline size_t ZPhysicalMemoryManager::available() const {
+ return _max_capacity - _used;
+}
+
+#endif // SHARE_GC_Z_ZPHYSICALMEMORY_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zPreMappedMemory.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,83 @@
+/*
+ * 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 "gc/z/zPage.inline.hpp"
+#include "gc/z/zPhysicalMemory.inline.hpp"
+#include "gc/z/zPreMappedMemory.inline.hpp"
+#include "gc/z/zVirtualMemory.inline.hpp"
+#include "logging/log.hpp"
+
+ZPreMappedMemory::ZPreMappedMemory(ZVirtualMemoryManager &vmm, ZPhysicalMemoryManager &pmm, size_t size) :
+ _vmem(),
+ _pmem(),
+ _initialized(false) {
+ if (!vmm.is_initialized() || !pmm.is_initialized()) {
+ // Not initialized
+ return;
+ }
+
+ // Pre-mapping and pre-touching memory can take a long time. Log a message
+ // to help the user understand why the JVM might seem slow to start.
+ log_info(gc, init)("Pre-touching: %s", AlwaysPreTouch ? "Enabled" : "Disabled");
+ log_info(gc, init)("Pre-mapping: " SIZE_FORMAT "M", size / M);
+
+ _pmem = pmm.alloc(size);
+ if (_pmem.is_null()) {
+ // Out of memory
+ return;
+ }
+
+ _vmem = vmm.alloc(size, true /* alloc_from_front */);
+ if (_vmem.is_null()) {
+ // Out of address space
+ pmm.free(_pmem);
+ return;
+ }
+
+ // Map physical memory
+ pmm.map(_pmem, _vmem.start());
+
+ _initialized = true;
+}
+
+ZPage* ZPreMappedMemory::alloc_page(uint8_t type, size_t size) {
+ if (size > available()) {
+ // Not enough pre-mapped memory
+ return NULL;
+ }
+
+ // Take a chunk of the pre-mapped memory
+ const ZPhysicalMemory pmem = _pmem.split(size);
+ const ZVirtualMemory vmem = _vmem.split(size);
+
+ ZPage* const page = new ZPage(type, vmem, pmem);
+ page->set_pre_mapped();
+
+ return page;
+}
+
+void ZPreMappedMemory::clear() {
+ assert(_pmem.is_null(), "Should be detached");
+ _vmem.clear();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zPreMappedMemory.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+#ifndef SHARE_GC_Z_ZPREMAPPEDMEMORY_HPP
+#define SHARE_GC_Z_ZPREMAPPEDMEMORY_HPP
+
+#include "gc/z/zPhysicalMemory.hpp"
+#include "gc/z/zVirtualMemory.hpp"
+#include "memory/allocation.hpp"
+
+class ZPage;
+
+class ZPreMappedMemory {
+private:
+ ZVirtualMemory _vmem;
+ ZPhysicalMemory _pmem;
+ bool _initialized;
+
+public:
+ ZPreMappedMemory(ZVirtualMemoryManager &vmm, ZPhysicalMemoryManager &pmm, size_t size);
+
+ bool is_initialized() const;
+
+ ZPhysicalMemory& physical_memory();
+ const ZVirtualMemory& virtual_memory() const;
+
+ size_t available() const;
+
+ ZPage* alloc_page(uint8_t type, size_t size);
+
+ void clear();
+};
+
+#endif // SHARE_GC_Z_ZPREMAPPEDMEMORY_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zPreMappedMemory.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+#ifndef SHARE_GC_Z_ZPREMAPPEDMEMORY_INLINE_HPP
+#define SHARE_GC_Z_ZPREMAPPEDMEMORY_INLINE_HPP
+
+#include "gc/z/zPreMappedMemory.hpp"
+
+inline bool ZPreMappedMemory::is_initialized() const {
+ return _initialized;
+}
+
+inline ZPhysicalMemory& ZPreMappedMemory::physical_memory() {
+ return _pmem;
+}
+
+inline const ZVirtualMemory& ZPreMappedMemory::virtual_memory() const {
+ return _vmem;
+}
+
+inline size_t ZPreMappedMemory::available() const {
+ return _vmem.size();
+}
+
+#endif // SHARE_GC_Z_ZPREMAPPEDMEMORY_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zReferenceProcessor.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,429 @@
+/*
+ * 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 "classfile/javaClasses.inline.hpp"
+#include "gc/shared/referencePolicy.hpp"
+#include "gc/shared/referenceProcessorStats.hpp"
+#include "gc/z/zHeap.inline.hpp"
+#include "gc/z/zOopClosures.inline.hpp"
+#include "gc/z/zReferenceProcessor.hpp"
+#include "gc/z/zStat.hpp"
+#include "gc/z/zTask.hpp"
+#include "gc/z/zTracer.inline.hpp"
+#include "gc/z/zUtils.inline.hpp"
+#include "memory/universe.hpp"
+#include "runtime/mutexLocker.hpp"
+#include "runtime/os.hpp"
+
+static const ZStatSubPhase ZSubPhaseConcurrentReferencesProcess("Concurrent References Process");
+static const ZStatSubPhase ZSubPhaseConcurrentReferencesEnqueue("Concurrent References Enqueue");
+
+ZReferenceProcessor::ZReferenceProcessor(ZWorkers* workers) :
+ _workers(workers),
+ _soft_reference_policy(NULL),
+ _encountered_count(),
+ _discovered_count(),
+ _enqueued_count(),
+ _discovered_list(NULL),
+ _pending_list(NULL),
+ _pending_list_tail(_pending_list.addr()) {}
+
+void ZReferenceProcessor::set_soft_reference_policy(bool clear) {
+ static AlwaysClearPolicy always_clear_policy;
+ static LRUMaxHeapPolicy lru_max_heap_policy;
+
+ if (clear) {
+ log_info(gc, ref)("Clearing All Soft References");
+ _soft_reference_policy = &always_clear_policy;
+ } else {
+ _soft_reference_policy = &lru_max_heap_policy;
+ }
+
+ _soft_reference_policy->setup();
+}
+
+void ZReferenceProcessor::update_soft_reference_clock() const {
+ const jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
+ java_lang_ref_SoftReference::set_clock(now);
+}
+
+bool ZReferenceProcessor::is_reference_inactive(oop obj) const {
+ // A non-null next field means the reference is inactive
+ return java_lang_ref_Reference::next(obj) != NULL;
+}
+
+ReferenceType ZReferenceProcessor::reference_type(oop obj) const {
+ return InstanceKlass::cast(obj->klass())->reference_type();
+}
+
+const char* ZReferenceProcessor::reference_type_name(ReferenceType type) const {
+ switch (type) {
+ case REF_SOFT:
+ return "Soft";
+
+ case REF_WEAK:
+ return "Weak";
+
+ case REF_FINAL:
+ return "Final";
+
+ case REF_PHANTOM:
+ return "Phantom";
+
+ default:
+ ShouldNotReachHere();
+ return NULL;
+ }
+}
+
+volatile oop* ZReferenceProcessor::reference_referent_addr(oop obj) const {
+ return (volatile oop*)java_lang_ref_Reference::referent_addr_raw(obj);
+}
+
+oop ZReferenceProcessor::reference_referent(oop obj) const {
+ return *reference_referent_addr(obj);
+}
+
+bool ZReferenceProcessor::is_referent_alive_or_null(oop obj, ReferenceType type) const {
+ volatile oop* const p = reference_referent_addr(obj);
+
+ // Check if the referent is alive or null, in which case we don't want to discover
+ // the reference. It can only be null if the application called Reference.enqueue()
+ // or Reference.clear().
+ if (type == REF_PHANTOM) {
+ const oop o = ZBarrier::weak_load_barrier_on_phantom_oop_field(p);
+ return o == NULL || ZHeap::heap()->is_object_live(ZOop::to_address(o));
+ } else {
+ const oop o = ZBarrier::weak_load_barrier_on_weak_oop_field(p);
+ return o == NULL || ZHeap::heap()->is_object_strongly_live(ZOop::to_address(o));
+ }
+}
+
+bool ZReferenceProcessor::is_referent_softly_alive(oop obj, ReferenceType type) const {
+ if (type != REF_SOFT) {
+ // Not a soft reference
+ return false;
+ }
+
+ // Ask soft reference policy
+ const jlong clock = java_lang_ref_SoftReference::clock();
+ assert(clock != 0, "Clock not initialized");
+ assert(_soft_reference_policy != NULL, "Policy not initialized");
+ return !_soft_reference_policy->should_clear_reference(obj, clock);
+}
+
+bool ZReferenceProcessor::should_drop_reference(oop obj, ReferenceType type) const {
+ // This check is racing with a call to Reference.clear() from the application.
+ // If the application clears the reference after this check it will still end
+ // up on the pending list, and there's nothing we can do about that without
+ // changing the Reference.clear() API. This check is also racing with a call
+ // to Reference.enqueue() from the application, which is unproblematic, since
+ // the application wants the reference to be enqueued anyway.
+ const oop o = reference_referent(obj);
+ if (o == NULL) {
+ // Reference has been cleared, by a call to Reference.enqueue()
+ // or Reference.clear() from the application, which means we
+ // should drop the reference.
+ return true;
+ }
+
+ // Check if the referent is still alive, in which case we should
+ // drop the reference.
+ if (type == REF_PHANTOM) {
+ return ZBarrier::is_alive_barrier_on_phantom_oop(o);
+ } else {
+ return ZBarrier::is_alive_barrier_on_weak_oop(o);
+ }
+}
+
+bool ZReferenceProcessor::should_mark_referent(ReferenceType type) const {
+ // Referents of final references (and its reachable sub graph) are
+ // always marked finalizable during discovery. This avoids the problem
+ // of later having to mark those objects if the referent is still final
+ // reachable during processing.
+ return type == REF_FINAL;
+}
+
+bool ZReferenceProcessor::should_clear_referent(ReferenceType type) const {
+ // Referents that were not marked must be cleared
+ return !should_mark_referent(type);
+}
+
+void ZReferenceProcessor::keep_referent_alive(oop obj, ReferenceType type) const {
+ volatile oop* const p = reference_referent_addr(obj);
+ if (type == REF_PHANTOM) {
+ ZBarrier::keep_alive_barrier_on_phantom_oop_field(p);
+ } else {
+ ZBarrier::keep_alive_barrier_on_weak_oop_field(p);
+ }
+}
+
+bool ZReferenceProcessor::discover_reference(oop obj, ReferenceType type) {
+ if (!RegisterReferences) {
+ // Reference processing disabled
+ return false;
+ }
+
+ log_trace(gc, ref)("Encountered Reference: " PTR_FORMAT " (%s)", p2i(obj), reference_type_name(type));
+
+ // Update statistics
+ _encountered_count.get()[type]++;
+
+ if (is_reference_inactive(obj) ||
+ is_referent_alive_or_null(obj, type) ||
+ is_referent_softly_alive(obj, type)) {
+ // Not discovered
+ return false;
+ }
+
+ discover(obj, type);
+
+ // Discovered
+ return true;
+}
+
+void ZReferenceProcessor::discover(oop obj, ReferenceType type) {
+ log_trace(gc, ref)("Discovered Reference: " PTR_FORMAT " (%s)", p2i(obj), reference_type_name(type));
+
+ // Update statistics
+ _discovered_count.get()[type]++;
+
+ // Mark referent finalizable
+ if (should_mark_referent(type)) {
+ oop* const referent_addr = (oop*)java_lang_ref_Reference::referent_addr_raw(obj);
+ ZBarrier::mark_barrier_on_oop_field(referent_addr, true /* finalizable */);
+ }
+
+ // Add reference to discovered list
+ assert(java_lang_ref_Reference::discovered(obj) == NULL, "Already discovered");
+ oop* const list = _discovered_list.addr();
+ java_lang_ref_Reference::set_discovered(obj, *list);
+ *list = obj;
+}
+
+oop ZReferenceProcessor::drop(oop obj, ReferenceType type) {
+ log_trace(gc, ref)("Dropped Reference: " PTR_FORMAT " (%s)", p2i(obj), reference_type_name(type));
+
+ // Keep referent alive
+ keep_referent_alive(obj, type);
+
+ // Unlink and return next in list
+ const oop next = java_lang_ref_Reference::discovered(obj);
+ java_lang_ref_Reference::set_discovered(obj, NULL);
+ return next;
+}
+
+oop* ZReferenceProcessor::keep(oop obj, ReferenceType type) {
+ log_trace(gc, ref)("Enqueued Reference: " PTR_FORMAT " (%s)", p2i(obj), reference_type_name(type));
+
+ // Update statistics
+ _enqueued_count.get()[type]++;
+
+ // Clear referent
+ if (should_clear_referent(type)) {
+ java_lang_ref_Reference::set_referent(obj, NULL);
+ }
+
+ // Make reference inactive by self-looping the next field. We could be racing with a
+ // call to Reference.enqueue() from the application, which is why we are using a CAS
+ // to make sure we change the next field only if it is NULL. A failing CAS means the
+ // reference has already been enqueued. However, we don't check the result of the CAS,
+ // since we still have no option other than keeping the reference on the pending list.
+ // It's ok to have the reference both on the pending list and enqueued at the same
+ // time (the pending list is linked through the discovered field, while the reference
+ // queue is linked through the next field). When the ReferenceHandler thread later
+ // calls Reference.enqueue() we detect that it has already been enqueued and drop it.
+ oop* const next_addr = (oop*)java_lang_ref_Reference::next_addr_raw(obj);
+ Atomic::cmpxchg(obj, next_addr, oop(NULL));
+
+ // Return next in list
+ return (oop*)java_lang_ref_Reference::discovered_addr_raw(obj);
+}
+
+void ZReferenceProcessor::work() {
+ // Process discovered references
+ oop* const list = _discovered_list.addr();
+ oop* p = list;
+
+ while (*p != NULL) {
+ const oop obj = *p;
+ const ReferenceType type = reference_type(obj);
+
+ if (should_drop_reference(obj, type)) {
+ *p = drop(obj, type);
+ } else {
+ p = keep(obj, type);
+ }
+ }
+
+ // Prepend discovered references to internal pending list
+ if (*list != NULL) {
+ *p = Atomic::xchg(*list, _pending_list.addr());
+ if (*p == NULL) {
+ // First to prepend to list, record tail
+ _pending_list_tail = p;
+ }
+
+ // Clear discovered list
+ *list = NULL;
+ }
+}
+
+bool ZReferenceProcessor::is_empty() const {
+ ZPerWorkerConstIterator<oop> iter(&_discovered_list);
+ for (const oop* list; iter.next(&list);) {
+ if (*list != NULL) {
+ return false;
+ }
+ }
+
+ if (_pending_list.get() != NULL) {
+ return false;
+ }
+
+ return true;
+}
+
+void ZReferenceProcessor::reset_statistics() {
+ assert(is_empty(), "Should be empty");
+
+ // Reset encountered
+ ZPerWorkerIterator<Counters> iter_encountered(&_encountered_count);
+ for (Counters* counters; iter_encountered.next(&counters);) {
+ for (int i = REF_SOFT; i <= REF_PHANTOM; i++) {
+ (*counters)[i] = 0;
+ }
+ }
+
+ // Reset discovered
+ ZPerWorkerIterator<Counters> iter_discovered(&_discovered_count);
+ for (Counters* counters; iter_discovered.next(&counters);) {
+ for (int i = REF_SOFT; i <= REF_PHANTOM; i++) {
+ (*counters)[i] = 0;
+ }
+ }
+
+ // Reset enqueued
+ ZPerWorkerIterator<Counters> iter_enqueued(&_enqueued_count);
+ for (Counters* counters; iter_enqueued.next(&counters);) {
+ for (int i = REF_SOFT; i <= REF_PHANTOM; i++) {
+ (*counters)[i] = 0;
+ }
+ }
+}
+
+void ZReferenceProcessor::collect_statistics() {
+ Counters encountered = {};
+ Counters discovered = {};
+ Counters enqueued = {};
+
+ // Sum encountered
+ ZPerWorkerConstIterator<Counters> iter_encountered(&_encountered_count);
+ for (const Counters* counters; iter_encountered.next(&counters);) {
+ for (int i = REF_SOFT; i <= REF_PHANTOM; i++) {
+ encountered[i] += (*counters)[i];
+ }
+ }
+
+ // Sum discovered
+ ZPerWorkerConstIterator<Counters> iter_discovered(&_discovered_count);
+ for (const Counters* counters; iter_discovered.next(&counters);) {
+ for (int i = REF_SOFT; i <= REF_PHANTOM; i++) {
+ discovered[i] += (*counters)[i];
+ }
+ }
+
+ // Sum enqueued
+ ZPerWorkerConstIterator<Counters> iter_enqueued(&_enqueued_count);
+ for (const Counters* counters; iter_enqueued.next(&counters);) {
+ for (int i = REF_SOFT; i <= REF_PHANTOM; i++) {
+ enqueued[i] += (*counters)[i];
+ }
+ }
+
+ // Update statistics
+ ZStatReferences::set_soft(encountered[REF_SOFT], discovered[REF_SOFT], enqueued[REF_SOFT]);
+ ZStatReferences::set_weak(encountered[REF_WEAK], discovered[REF_WEAK], enqueued[REF_WEAK]);
+ ZStatReferences::set_final(encountered[REF_FINAL], discovered[REF_FINAL], enqueued[REF_FINAL]);
+ ZStatReferences::set_phantom(encountered[REF_PHANTOM], discovered[REF_PHANTOM], enqueued[REF_PHANTOM]);
+
+ // Trace statistics
+ const ReferenceProcessorStats stats(discovered[REF_SOFT],
+ discovered[REF_WEAK],
+ discovered[REF_FINAL],
+ discovered[REF_PHANTOM]);
+ ZTracer::tracer()->report_gc_reference_stats(stats);
+}
+
+class ZReferenceProcessorTask : public ZTask {
+private:
+ ZReferenceProcessor* const _reference_processor;
+
+public:
+ ZReferenceProcessorTask(ZReferenceProcessor* reference_processor) :
+ ZTask("ZReferenceProcessorTask"),
+ _reference_processor(reference_processor) {}
+
+ virtual void work() {
+ _reference_processor->work();
+ }
+};
+
+void ZReferenceProcessor::process_references() {
+ ZStatTimer timer(ZSubPhaseConcurrentReferencesProcess);
+
+ // Process discovered lists
+ ZReferenceProcessorTask task(this);
+ _workers->run_concurrent(&task);
+
+ // Update soft reference clock
+ update_soft_reference_clock();
+
+ // Collect, log and trace statistics
+ collect_statistics();
+}
+
+void ZReferenceProcessor::enqueue_references() {
+ ZStatTimer timer(ZSubPhaseConcurrentReferencesEnqueue);
+
+ if (_pending_list.get() == NULL) {
+ // Nothing to enqueue
+ return;
+ }
+
+ {
+ // Heap_lock protects external pending list
+ MonitorLockerEx ml(Heap_lock);
+
+ // Prepend internal pending list to external pending list
+ *_pending_list_tail = Universe::swap_reference_pending_list(_pending_list.get());
+
+ // Notify ReferenceHandler thread
+ ml.notify_all();
+ }
+
+ // Reset internal pending list
+ _pending_list.set(NULL);
+ _pending_list_tail = _pending_list.addr();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zReferenceProcessor.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,83 @@
+/*
+ * 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_GC_Z_ZREFERENCEPROCESSOR_HPP
+#define SHARE_GC_Z_ZREFERENCEPROCESSOR_HPP
+
+#include "gc/shared/referenceDiscoverer.hpp"
+#include "gc/z/zValue.hpp"
+
+class ReferencePolicy;
+class ZWorkers;
+
+class ZReferenceProcessor : public ReferenceDiscoverer {
+ friend class ZReferenceProcessorTask;
+
+private:
+ static const size_t reference_type_count = REF_PHANTOM + 1;
+ typedef size_t Counters[reference_type_count];
+
+ ZWorkers* const _workers;
+ ReferencePolicy* _soft_reference_policy;
+ ZPerWorker<Counters> _encountered_count;
+ ZPerWorker<Counters> _discovered_count;
+ ZPerWorker<Counters> _enqueued_count;
+ ZPerWorker<oop> _discovered_list;
+ ZContended<oop> _pending_list;
+ oop* _pending_list_tail;
+
+ void update_soft_reference_clock() const;
+
+ ReferenceType reference_type(oop obj) const;
+ const char* reference_type_name(ReferenceType type) const;
+ volatile oop* reference_referent_addr(oop obj) const;
+ oop reference_referent(oop obj) const;
+ bool is_reference_inactive(oop obj) const;
+ bool is_referent_alive_or_null(oop obj, ReferenceType type) const;
+ bool is_referent_softly_alive(oop obj, ReferenceType type) const;
+ bool should_drop_reference(oop obj, ReferenceType type) const;
+ bool should_mark_referent(ReferenceType type) const;
+ bool should_clear_referent(ReferenceType type) const;
+ void keep_referent_alive(oop obj, ReferenceType type) const;
+
+ void discover(oop obj, ReferenceType type);
+ oop drop(oop obj, ReferenceType type);
+ oop* keep(oop obj, ReferenceType type);
+
+ bool is_empty() const;
+
+ void work();
+ void collect_statistics();
+
+public:
+ ZReferenceProcessor(ZWorkers* workers);
+
+ void set_soft_reference_policy(bool clear);
+ void reset_statistics();
+
+ virtual bool discover_reference(oop reference, ReferenceType type);
+ void process_references();
+ void enqueue_references();
+};
+
+#endif // SHARE_GC_Z_ZREFERENCEPROCESSOR_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zRelocate.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2015, 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 "gc/z/zHeap.hpp"
+#include "gc/z/zOopClosures.inline.hpp"
+#include "gc/z/zPage.hpp"
+#include "gc/z/zRelocate.hpp"
+#include "gc/z/zRelocationSet.inline.hpp"
+#include "gc/z/zRootsIterator.hpp"
+#include "gc/z/zTask.hpp"
+#include "gc/z/zWorkers.hpp"
+
+ZRelocate::ZRelocate(ZWorkers* workers) :
+ _workers(workers) {}
+
+class ZRelocateRootsTask : public ZTask {
+private:
+ ZRootsIterator _roots;
+
+public:
+ ZRelocateRootsTask() :
+ ZTask("ZRelocateRootsTask"),
+ _roots() {}
+
+ virtual void work() {
+ // During relocation we need to visit the JVMTI
+ // export weak roots to rehash the JVMTI tag map
+ ZRelocateRootOopClosure cl;
+ _roots.oops_do(&cl, true /* visit_jvmti_weak_export */);
+ }
+};
+
+void ZRelocate::start() {
+ ZRelocateRootsTask task;
+ _workers->run_parallel(&task);
+}
+
+class ZRelocateObjectClosure : public ObjectClosure {
+private:
+ ZPage* const _page;
+
+public:
+ ZRelocateObjectClosure(ZPage* page) :
+ _page(page) {}
+
+ virtual void do_object(oop o) {
+ _page->relocate_object(ZOop::to_address(o));
+ }
+};
+
+bool ZRelocate::work(ZRelocationSetParallelIterator* iter) {
+ bool success = true;
+
+ // Relocate pages in the relocation set
+ for (ZPage* page; iter->next(&page);) {
+ // Relocate objects in page
+ ZRelocateObjectClosure cl(page);
+ page->object_iterate(&cl);
+
+ if (ZVerifyForwarding) {
+ page->verify_forwarding();
+ }
+
+ if (page->is_pinned()) {
+ // Relocation failed, page is now pinned
+ success = false;
+ } else {
+ // Relocation succeeded, release page
+ ZHeap::heap()->release_page(page, true /* reclaimed */);
+ }
+ }
+
+ return success;
+}
+
+class ZRelocateTask : public ZTask {
+private:
+ ZRelocate* const _relocate;
+ ZRelocationSetParallelIterator _iter;
+ bool _failed;
+
+public:
+ ZRelocateTask(ZRelocate* relocate, ZRelocationSet* relocation_set) :
+ ZTask("ZRelocateTask"),
+ _relocate(relocate),
+ _iter(relocation_set),
+ _failed(false) {}
+
+ virtual void work() {
+ if (!_relocate->work(&_iter)) {
+ _failed = true;
+ }
+ }
+
+ bool failed() const {
+ return _failed;
+ }
+};
+
+bool ZRelocate::relocate(ZRelocationSet* relocation_set) {
+ ZRelocateTask task(this, relocation_set);
+ _workers->run_concurrent(&task);
+ return !task.failed();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zRelocate.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZRELOCATE_HPP
+#define SHARE_GC_Z_ZRELOCATE_HPP
+
+#include "gc/z/zRelocationSet.hpp"
+#include "gc/z/zWorkers.hpp"
+#include "memory/allocation.hpp"
+
+class ZRelocate {
+ friend class ZRelocateTask;
+
+private:
+ ZWorkers* const _workers;
+
+ bool work(ZRelocationSetParallelIterator* iter);
+
+public:
+ ZRelocate(ZWorkers* workers);
+
+ void start();
+ bool relocate(ZRelocationSet* relocation_set);
+};
+
+#endif // SHARE_GC_Z_ZRELOCATE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zRelocationSet.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 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 "gc/z/zRelocationSet.hpp"
+#include "memory/allocation.inline.hpp"
+
+ZRelocationSet::ZRelocationSet() :
+ _pages(NULL),
+ _npages(0) {}
+
+void ZRelocationSet::populate(const ZPage* const* group0, size_t ngroup0,
+ const ZPage* const* group1, size_t ngroup1) {
+ _npages = ngroup0 + ngroup1;
+ _pages = REALLOC_C_HEAP_ARRAY(ZPage*, _pages, _npages, mtGC);
+
+ if (_pages != NULL) {
+ if (group0 != NULL) {
+ memcpy(_pages, group0, ngroup0 * sizeof(ZPage*));
+ }
+ if (group1 != NULL) {
+ memcpy(_pages + ngroup0, group1, ngroup1 * sizeof(ZPage*));
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zRelocationSet.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef SHARE_GC_Z_ZRELOCATIONSET_HPP
+#define SHARE_GC_Z_ZRELOCATIONSET_HPP
+
+#include "memory/allocation.hpp"
+
+class ZPage;
+
+class ZRelocationSet {
+ template <bool> friend class ZRelocationSetIteratorImpl;
+
+private:
+ ZPage** _pages;
+ size_t _npages;
+
+public:
+ ZRelocationSet();
+
+ void populate(const ZPage* const* group0, size_t ngroup0,
+ const ZPage* const* group1, size_t ngroup1);
+};
+
+template <bool parallel>
+class ZRelocationSetIteratorImpl : public StackObj {
+private:
+ ZRelocationSet* const _relocation_set;
+ size_t _next;
+
+public:
+ ZRelocationSetIteratorImpl(ZRelocationSet* relocation_set);
+
+ bool next(ZPage** page);
+};
+
+// Iterator types
+#define ZRELOCATIONSET_SERIAL false
+#define ZRELOCATIONSET_PARALLEL true
+
+class ZRelocationSetIterator : public ZRelocationSetIteratorImpl<ZRELOCATIONSET_SERIAL> {
+public:
+ ZRelocationSetIterator(ZRelocationSet* relocation_set) :
+ ZRelocationSetIteratorImpl<ZRELOCATIONSET_SERIAL>(relocation_set) {}
+};
+
+class ZRelocationSetParallelIterator : public ZRelocationSetIteratorImpl<ZRELOCATIONSET_PARALLEL> {
+public:
+ ZRelocationSetParallelIterator(ZRelocationSet* relocation_set) :
+ ZRelocationSetIteratorImpl<ZRELOCATIONSET_PARALLEL>(relocation_set) {}
+};
+
+#endif // SHARE_GC_Z_ZRELOCATIONSET_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zRelocationSet.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef SHARE_GC_Z_ZRELOCATIONSET_INLINE_HPP
+#define SHARE_GC_Z_ZRELOCATIONSET_INLINE_HPP
+
+#include "gc/z/zRelocationSet.hpp"
+#include "runtime/atomic.hpp"
+
+template <bool parallel>
+inline ZRelocationSetIteratorImpl<parallel>::ZRelocationSetIteratorImpl(ZRelocationSet* relocation_set) :
+ _relocation_set(relocation_set),
+ _next(0) {}
+
+template <bool parallel>
+inline bool ZRelocationSetIteratorImpl<parallel>::next(ZPage** page) {
+ const size_t npages = _relocation_set->_npages;
+
+ if (parallel) {
+ if (_next < npages) {
+ const size_t next = Atomic::add(1u, &_next) - 1u;
+ if (next < npages) {
+ *page = _relocation_set->_pages[next];
+ return true;
+ }
+ }
+ } else {
+ if (_next < npages) {
+ *page = _relocation_set->_pages[_next++];
+ return true;
+ }
+ }
+
+ return false;
+}
+
+#endif // SHARE_GC_Z_ZRELOCATIONSET_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zRelocationSetSelector.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 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 "gc/z/zArray.inline.hpp"
+#include "gc/z/zPage.inline.hpp"
+#include "gc/z/zRelocationSet.hpp"
+#include "gc/z/zRelocationSetSelector.hpp"
+#include "logging/log.hpp"
+#include "runtime/globals.hpp"
+#include "utilities/debug.hpp"
+
+ZRelocationSetSelectorGroup::ZRelocationSetSelectorGroup(const char* name,
+ size_t page_size,
+ size_t object_size_limit) :
+ _name(name),
+ _page_size(page_size),
+ _object_size_limit(object_size_limit),
+ _fragmentation_limit(page_size * (ZFragmentationLimit / 100)),
+ _registered_pages(),
+ _sorted_pages(NULL),
+ _nselected(0),
+ _relocating(0),
+ _fragmentation(0) {}
+
+ZRelocationSetSelectorGroup::~ZRelocationSetSelectorGroup() {
+ FREE_C_HEAP_ARRAY(const ZPage*, _sorted_pages);
+}
+
+void ZRelocationSetSelectorGroup::register_live_page(const ZPage* page, size_t garbage) {
+ if (garbage > _fragmentation_limit) {
+ _registered_pages.add(page);
+ } else {
+ _fragmentation += garbage;
+ }
+}
+
+void ZRelocationSetSelectorGroup::semi_sort() {
+ // Semi-sort registered pages by live bytes in ascending order
+ const size_t npartitions_shift = 11;
+ const size_t npartitions = (size_t)1 << npartitions_shift;
+ const size_t partition_size = _page_size >> npartitions_shift;
+ const size_t partition_size_shift = exact_log2(partition_size);
+ const size_t npages = _registered_pages.size();
+
+ size_t partition_slots[npartitions];
+ size_t partition_finger[npartitions];
+
+ // Allocate destination array
+ _sorted_pages = REALLOC_C_HEAP_ARRAY(const ZPage*, _sorted_pages, npages, mtGC);
+ debug_only(memset(_sorted_pages, 0, npages * sizeof(ZPage*)));
+
+ // Calculate partition slots
+ memset(partition_slots, 0, sizeof(partition_slots));
+ ZArrayIterator<const ZPage*> iter1(&_registered_pages);
+ for (const ZPage* page; iter1.next(&page);) {
+ const size_t index = page->live_bytes() >> partition_size_shift;
+ partition_slots[index]++;
+ }
+
+ // Calculate accumulated partition slots and fingers
+ size_t prev_partition_slots = 0;
+ for (size_t i = 0; i < npartitions; i++) {
+ partition_slots[i] += prev_partition_slots;
+ partition_finger[i] = prev_partition_slots;
+ prev_partition_slots = partition_slots[i];
+ }
+
+ // Sort pages into partitions
+ ZArrayIterator<const ZPage*> iter2(&_registered_pages);
+ for (const ZPage* page; iter2.next(&page);) {
+ const size_t index = page->live_bytes() >> partition_size_shift;
+ const size_t finger = partition_finger[index]++;
+ assert(_sorted_pages[finger] == NULL, "Invalid finger");
+ _sorted_pages[finger] = page;
+ }
+}
+
+void ZRelocationSetSelectorGroup::select() {
+ // Calculate the number of pages to relocate by successively including pages in
+ // a candidate relocation set and calculate the maximum space requirement for
+ // their live objects.
+ const size_t npages = _registered_pages.size();
+ size_t selected_from = 0;
+ size_t selected_to = 0;
+ size_t from_size = 0;
+
+ semi_sort();
+
+ for (size_t from = 1; from <= npages; from++) {
+ // Add page to the candidate relocation set
+ from_size += _sorted_pages[from - 1]->live_bytes();
+
+ // Calculate the maximum number of pages needed by the candidate relocation set.
+ // By subtracting the object size limit from the pages size we get the maximum
+ // number of pages that the relocation set is guaranteed to fit in, regardless
+ // of in which order the objects are relocated.
+ const size_t to = ceil((double)(from_size) / (double)(_page_size - _object_size_limit));
+
+ // Calculate the relative difference in reclaimable space compared to our
+ // currently selected final relocation set. If this number is larger than the
+ // acceptable fragmentation limit, then the current candidate relocation set
+ // becomes our new final relocation set.
+ const size_t diff_from = from - selected_from;
+ const size_t diff_to = to - selected_to;
+ const double diff_reclaimable = 100 - percent_of(diff_to, diff_from);
+ if (diff_reclaimable > ZFragmentationLimit) {
+ selected_from = from;
+ selected_to = to;
+ }
+
+ log_trace(gc, reloc)("Candidate Relocation Set (%s Pages): "
+ SIZE_FORMAT "->" SIZE_FORMAT ", %.1f%% relative defragmentation, %s",
+ _name, from, to, diff_reclaimable, (selected_from == from) ? "Selected" : "Rejected");
+ }
+
+ // Finalize selection
+ _nselected = selected_from;
+
+ // Update statistics
+ _relocating = from_size;
+ for (size_t i = _nselected; i < npages; i++) {
+ const ZPage* const page = _sorted_pages[i];
+ _fragmentation += page->size() - page->live_bytes();
+ }
+
+ log_debug(gc, reloc)("Relocation Set (%s Pages): " SIZE_FORMAT "->" SIZE_FORMAT ", " SIZE_FORMAT " skipped",
+ _name, selected_from, selected_to, npages - _nselected);
+}
+
+const ZPage* const* ZRelocationSetSelectorGroup::selected() const {
+ return _sorted_pages;
+}
+
+size_t ZRelocationSetSelectorGroup::nselected() const {
+ return _nselected;
+}
+
+size_t ZRelocationSetSelectorGroup::relocating() const {
+ return _relocating;
+}
+
+size_t ZRelocationSetSelectorGroup::fragmentation() const {
+ return _fragmentation;
+}
+
+ZRelocationSetSelector::ZRelocationSetSelector() :
+ _small("Small", ZPageSizeSmall, ZObjectSizeLimitSmall),
+ _medium("Medium", ZPageSizeMedium, ZObjectSizeLimitMedium),
+ _live(0),
+ _garbage(0),
+ _fragmentation(0) {}
+
+void ZRelocationSetSelector::register_live_page(const ZPage* page) {
+ const uint8_t type = page->type();
+ const size_t live = page->live_bytes();
+ const size_t garbage = page->size() - live;
+
+ if (type == ZPageTypeSmall) {
+ _small.register_live_page(page, garbage);
+ } else if (type == ZPageTypeMedium) {
+ _medium.register_live_page(page, garbage);
+ } else {
+ _fragmentation += garbage;
+ }
+
+ _live += live;
+ _garbage += garbage;
+}
+
+void ZRelocationSetSelector::register_garbage_page(const ZPage* page) {
+ _garbage += page->size();
+}
+
+void ZRelocationSetSelector::select(ZRelocationSet* relocation_set) {
+ // Select pages to relocate. The resulting relocation set will be
+ // sorted such that medium pages comes first, followed by small
+ // pages. Pages within each page group will be semi-sorted by live
+ // bytes in ascending order. Relocating pages in this order allows
+ // us to start reclaiming memory more quickly.
+
+ // Select pages from each group
+ _medium.select();
+ _small.select();
+
+ // Populate relocation set
+ relocation_set->populate(_medium.selected(), _medium.nselected(),
+ _small.selected(), _small.nselected());
+}
+
+size_t ZRelocationSetSelector::live() const {
+ return _live;
+}
+
+size_t ZRelocationSetSelector::garbage() const {
+ return _garbage;
+}
+
+size_t ZRelocationSetSelector::relocating() const {
+ return _small.relocating() + _medium.relocating();
+}
+
+size_t ZRelocationSetSelector::fragmentation() const {
+ return _fragmentation + _small.fragmentation() + _medium.fragmentation();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zRelocationSetSelector.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef SHARE_GC_Z_ZRELOCATIONSETSELECTOR_HPP
+#define SHARE_GC_Z_ZRELOCATIONSETSELECTOR_HPP
+
+#include "gc/z/zArray.hpp"
+#include "memory/allocation.hpp"
+
+class ZPage;
+class ZRelocationSet;
+
+class ZRelocationSetSelectorGroup {
+private:
+ const char* const _name;
+ const size_t _page_size;
+ const size_t _object_size_limit;
+ const size_t _fragmentation_limit;
+
+ ZArray<const ZPage*> _registered_pages;
+ const ZPage** _sorted_pages;
+ size_t _nselected;
+ size_t _relocating;
+ size_t _fragmentation;
+
+ void semi_sort();
+
+public:
+ ZRelocationSetSelectorGroup(const char* name,
+ size_t page_size,
+ size_t object_size_limit);
+ ~ZRelocationSetSelectorGroup();
+
+ void register_live_page(const ZPage* page, size_t garbage);
+ void select();
+
+ const ZPage* const* selected() const;
+ size_t nselected() const;
+ size_t relocating() const;
+ size_t fragmentation() const;
+};
+
+class ZRelocationSetSelector : public StackObj {
+private:
+ ZRelocationSetSelectorGroup _small;
+ ZRelocationSetSelectorGroup _medium;
+ size_t _live;
+ size_t _garbage;
+ size_t _fragmentation;
+
+public:
+ ZRelocationSetSelector();
+
+ void register_live_page(const ZPage* page);
+ void register_garbage_page(const ZPage* page);
+ void select(ZRelocationSet* relocation_set);
+
+ size_t live() const;
+ size_t garbage() const;
+ size_t relocating() const;
+ size_t fragmentation() const;
+};
+
+#endif // SHARE_GC_Z_ZRELOCATIONSETSELECTOR_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zResurrection.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,42 @@
+/*
+ * 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 "gc/z/zResurrection.hpp"
+#include "runtime/orderAccess.hpp"
+#include "runtime/safepoint.hpp"
+#include "utilities/debug.hpp"
+
+volatile bool ZResurrection::_blocked = false;
+
+void ZResurrection::block() {
+ assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
+ _blocked = true;
+}
+
+void ZResurrection::unblock() {
+ // We use a storestore barrier to make sure all healed
+ // oops are visible before we unblock resurrection.
+ OrderAccess::storestore();
+ _blocked = false;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zResurrection.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+#ifndef SHARE_GC_Z_ZRESURRECTION_HPP
+#define SHARE_GC_Z_ZRESURRECTION_HPP
+
+#include "memory/allocation.hpp"
+
+class ZResurrection : public AllStatic {
+private:
+ static volatile bool _blocked;
+
+public:
+ static bool is_blocked();
+ static void block();
+ static void unblock();
+};
+
+#endif // SHARE_GC_Z_ZRESURRECTION_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zResurrection.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+#ifndef SHARE_GC_Z_ZRESURRECTION_INLINE_HPP
+#define SHARE_GC_Z_ZRESURRECTION_INLINE_HPP
+
+#include "gc/z/zResurrection.hpp"
+#include "runtime/orderAccess.hpp"
+
+inline bool ZResurrection::is_blocked() {
+ // We use a loadload barrier to make sure we are not
+ // seeing oops from a time when resurrection was blocked.
+ const bool blocked = _blocked;
+ OrderAccess::loadload();
+ return blocked;
+}
+
+#endif // SHARE_GC_Z_ZRESURRECTION_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zRootsIterator.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,433 @@
+/*
+ * 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 "classfile/classLoaderData.hpp"
+#include "classfile/stringTable.hpp"
+#include "classfile/symbolTable.hpp"
+#include "classfile/systemDictionary.hpp"
+#include "code/codeCache.hpp"
+#include "compiler/oopMap.hpp"
+#include "gc/shared/oopStorageParState.inline.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zNMethodTable.hpp"
+#include "gc/z/zOopClosures.inline.hpp"
+#include "gc/z/zRootsIterator.hpp"
+#include "gc/z/zStat.hpp"
+#include "gc/z/zThreadLocalData.hpp"
+#include "memory/resourceArea.hpp"
+#include "memory/universe.hpp"
+#include "prims/jvmtiExport.hpp"
+#include "runtime/atomic.hpp"
+#include "runtime/jniHandles.hpp"
+#include "runtime/thread.hpp"
+#include "runtime/safepoint.hpp"
+#include "runtime/synchronizer.hpp"
+#include "services/management.hpp"
+#include "utilities/debug.hpp"
+#if INCLUDE_JFR
+#include "jfr/jfr.hpp"
+#endif
+
+static const ZStatSubPhase ZSubPhasePauseRootsSetup("Pause Roots Setup");
+static const ZStatSubPhase ZSubPhasePauseRoots("Pause Roots");
+static const ZStatSubPhase ZSubPhasePauseRootsTeardown("Pause Roots Teardown");
+static const ZStatSubPhase ZSubPhasePauseRootsUniverse("Pause Roots Universe");
+static const ZStatSubPhase ZSubPhasePauseRootsVMWeakHandles("Pause Roots VMWeakHandles");
+static const ZStatSubPhase ZSubPhasePauseRootsJNIHandles("Pause Roots JNIHandles");
+static const ZStatSubPhase ZSubPhasePauseRootsJNIWeakHandles("Pause Roots JNIWeakHandles");
+static const ZStatSubPhase ZSubPhasePauseRootsObjectSynchronizer("Pause Roots ObjectSynchronizer");
+static const ZStatSubPhase ZSubPhasePauseRootsManagement("Pause Roots Management");
+static const ZStatSubPhase ZSubPhasePauseRootsJVMTIExport("Pause Roots JVMTIExport");
+static const ZStatSubPhase ZSubPhasePauseRootsJVMTIWeakExport("Pause Roots JVMTIWeakExport");
+static const ZStatSubPhase ZSubPhasePauseRootsJFRWeak("Pause Roots JRFWeak");
+static const ZStatSubPhase ZSubPhasePauseRootsSystemDictionary("Pause Roots SystemDictionary");
+static const ZStatSubPhase ZSubPhasePauseRootsClassLoaderDataGraph("Pause Roots ClassLoaderDataGraph");
+static const ZStatSubPhase ZSubPhasePauseRootsThreads("Pause Roots Threads");
+static const ZStatSubPhase ZSubPhasePauseRootsCodeCache("Pause Roots CodeCache");
+static const ZStatSubPhase ZSubPhasePauseRootsStringTable("Pause Roots StringTable");
+
+static const ZStatSubPhase ZSubPhasePauseWeakRootsSetup("Pause Weak Roots Setup");
+static const ZStatSubPhase ZSubPhasePauseWeakRoots("Pause Weak Roots");
+static const ZStatSubPhase ZSubPhasePauseWeakRootsTeardown("Pause Weak Roots Teardown");
+static const ZStatSubPhase ZSubPhasePauseWeakRootsVMWeakHandles("Pause Weak Roots VMWeakHandles");
+static const ZStatSubPhase ZSubPhasePauseWeakRootsJNIWeakHandles("Pause Weak Roots JNIWeakHandles");
+static const ZStatSubPhase ZSubPhasePauseWeakRootsJVMTIWeakExport("Pause Weak Roots JVMTIWeakExport");
+static const ZStatSubPhase ZSubPhasePauseWeakRootsJFRWeak("Pause Weak Roots JFRWeak");
+static const ZStatSubPhase ZSubPhasePauseWeakRootsSymbolTable("Pause Weak Roots SymbolTable");
+static const ZStatSubPhase ZSubPhasePauseWeakRootsStringTable("Pause Weak Roots StringTable");
+
+static const ZStatSubPhase ZSubPhaseConcurrentWeakRoots("Concurrent Weak Roots");
+static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsVMWeakHandles("Concurrent Weak Roots VMWeakHandles");
+static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsJNIWeakHandles("Concurrent Weak Roots JNIWeakHandles");
+static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsStringTable("Concurrent Weak Roots StringTable");
+
+template <typename T, void (T::*F)(OopClosure*)>
+ZSerialOopsDo<T, F>::ZSerialOopsDo(T* iter) :
+ _iter(iter),
+ _claimed(false) {}
+
+template <typename T, void (T::*F)(OopClosure*)>
+void ZSerialOopsDo<T, F>::oops_do(OopClosure* cl) {
+ if (!_claimed && Atomic::cmpxchg(true, &_claimed, false) == false) {
+ (_iter->*F)(cl);
+ }
+}
+
+template <typename T, void (T::*F)(OopClosure*)>
+ZParallelOopsDo<T, F>::ZParallelOopsDo(T* iter) :
+ _iter(iter),
+ _completed(false) {}
+
+template <typename T, void (T::*F)(OopClosure*)>
+void ZParallelOopsDo<T, F>::oops_do(OopClosure* cl) {
+ if (!_completed) {
+ (_iter->*F)(cl);
+ if (!_completed) {
+ _completed = true;
+ }
+ }
+}
+
+template <typename T, void (T::*F)(BoolObjectClosure*, OopClosure*)>
+ZSerialWeakOopsDo<T, F>::ZSerialWeakOopsDo(T* iter) :
+ _iter(iter),
+ _claimed(false) {}
+
+template <typename T, void (T::*F)(BoolObjectClosure*, OopClosure*)>
+void ZSerialWeakOopsDo<T, F>::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* cl) {
+ if (!_claimed && Atomic::cmpxchg(true, &_claimed, false) == false) {
+ (_iter->*F)(is_alive, cl);
+ }
+}
+
+template <typename T, void (T::*F)(BoolObjectClosure*, OopClosure*)>
+ZParallelWeakOopsDo<T, F>::ZParallelWeakOopsDo(T* iter) :
+ _iter(iter),
+ _completed(false) {}
+
+template <typename T, void (T::*F)(BoolObjectClosure*, OopClosure*)>
+void ZParallelWeakOopsDo<T, F>::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* cl) {
+ if (!_completed) {
+ (_iter->*F)(is_alive, cl);
+ if (!_completed) {
+ _completed = true;
+ }
+ }
+}
+
+ZRootsIterator::ZRootsIterator() :
+ _vm_weak_handles_iter(SystemDictionary::vm_weak_oop_storage()),
+ _jni_handles_iter(JNIHandles::global_handles()),
+ _jni_weak_handles_iter(JNIHandles::weak_global_handles()),
+ _string_table_iter(StringTable::weak_storage()),
+ _universe(this),
+ _object_synchronizer(this),
+ _management(this),
+ _jvmti_export(this),
+ _jvmti_weak_export(this),
+ _jfr_weak(this),
+ _system_dictionary(this),
+ _vm_weak_handles(this),
+ _jni_handles(this),
+ _jni_weak_handles(this),
+ _class_loader_data_graph(this),
+ _threads(this),
+ _code_cache(this),
+ _string_table(this) {
+ assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
+ ZStatTimer timer(ZSubPhasePauseRootsSetup);
+ Threads::change_thread_claim_parity();
+ ClassLoaderDataGraph::clear_claimed_marks();
+ COMPILER2_PRESENT(DerivedPointerTable::clear());
+ CodeCache::gc_prologue();
+ ZNMethodTable::gc_prologue();
+}
+
+ZRootsIterator::~ZRootsIterator() {
+ ZStatTimer timer(ZSubPhasePauseRootsTeardown);
+ ResourceMark rm;
+ ZNMethodTable::gc_epilogue();
+ CodeCache::gc_epilogue();
+ JvmtiExport::gc_epilogue();
+ COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
+ Threads::assert_all_threads_claimed();
+}
+
+void ZRootsIterator::do_universe(OopClosure* cl) {
+ ZStatTimer timer(ZSubPhasePauseRootsUniverse);
+ Universe::oops_do(cl);
+}
+
+void ZRootsIterator::do_vm_weak_handles(OopClosure* cl) {
+ ZStatTimer timer(ZSubPhasePauseRootsVMWeakHandles);
+ _vm_weak_handles_iter.oops_do(cl);
+}
+
+void ZRootsIterator::do_jni_handles(OopClosure* cl) {
+ ZStatTimer timer(ZSubPhasePauseRootsJNIHandles);
+ _jni_handles_iter.oops_do(cl);
+}
+
+void ZRootsIterator::do_jni_weak_handles(OopClosure* cl) {
+ ZStatTimer timer(ZSubPhasePauseRootsJNIWeakHandles);
+ _jni_weak_handles_iter.oops_do(cl);
+}
+
+void ZRootsIterator::do_object_synchronizer(OopClosure* cl) {
+ ZStatTimer timer(ZSubPhasePauseRootsObjectSynchronizer);
+ ObjectSynchronizer::oops_do(cl);
+}
+
+void ZRootsIterator::do_management(OopClosure* cl) {
+ ZStatTimer timer(ZSubPhasePauseRootsManagement);
+ Management::oops_do(cl);
+}
+
+void ZRootsIterator::do_jvmti_export(OopClosure* cl) {
+ ZStatTimer timer(ZSubPhasePauseRootsJVMTIExport);
+ JvmtiExport::oops_do(cl);
+}
+
+void ZRootsIterator::do_jvmti_weak_export(OopClosure* cl) {
+ ZStatTimer timer(ZSubPhasePauseRootsJVMTIWeakExport);
+ AlwaysTrueClosure always_alive;
+ JvmtiExport::weak_oops_do(&always_alive, cl);
+}
+
+void ZRootsIterator::do_jfr_weak(OopClosure* cl) {
+#if INCLUDE_JFR
+ ZStatTimer timer(ZSubPhasePauseRootsJFRWeak);
+ AlwaysTrueClosure always_alive;
+ Jfr::weak_oops_do(&always_alive, cl);
+#endif
+}
+
+void ZRootsIterator::do_system_dictionary(OopClosure* cl) {
+ ZStatTimer timer(ZSubPhasePauseRootsSystemDictionary);
+ SystemDictionary::oops_do(cl);
+}
+
+void ZRootsIterator::do_class_loader_data_graph(OopClosure* cl) {
+ ZStatTimer timer(ZSubPhasePauseRootsClassLoaderDataGraph);
+ CLDToOopClosure cld_cl(cl);
+ ClassLoaderDataGraph::cld_do(&cld_cl);
+}
+
+class ZRootsIteratorThreadClosure : public ThreadClosure {
+private:
+ OopClosure* const _cl;
+
+public:
+ ZRootsIteratorThreadClosure(OopClosure* cl) :
+ _cl(cl) {}
+
+ virtual void do_thread(Thread* thread) {
+ if (thread->is_Java_thread()) {
+ // Update thread local adddress bad mask
+ ZThreadLocalData::set_address_bad_mask(thread, ZAddressBadMask);
+ }
+
+ // Process thread oops
+ thread->oops_do(_cl, NULL);
+ }
+};
+
+void ZRootsIterator::do_threads(OopClosure* cl) {
+ ZStatTimer timer(ZSubPhasePauseRootsThreads);
+ ResourceMark rm;
+ ZRootsIteratorThreadClosure thread_cl(cl);
+ Threads::possibly_parallel_threads_do(true, &thread_cl);
+}
+
+void ZRootsIterator::do_code_cache(OopClosure* cl) {
+ ZStatTimer timer(ZSubPhasePauseRootsCodeCache);
+ ZNMethodTable::oops_do(cl);
+}
+
+void ZRootsIterator::do_string_table(OopClosure* cl) {
+ ZStatTimer timer(ZSubPhasePauseRootsStringTable);
+ _string_table_iter.oops_do(cl);
+}
+
+void ZRootsIterator::oops_do(OopClosure* cl, bool visit_jvmti_weak_export) {
+ ZStatTimer timer(ZSubPhasePauseRoots);
+ _universe.oops_do(cl);
+ _object_synchronizer.oops_do(cl);
+ _management.oops_do(cl);
+ _jvmti_export.oops_do(cl);
+ _system_dictionary.oops_do(cl);
+ _jni_handles.oops_do(cl);
+ _class_loader_data_graph.oops_do(cl);
+ _threads.oops_do(cl);
+ _code_cache.oops_do(cl);
+ if (!ZWeakRoots) {
+ _jvmti_weak_export.oops_do(cl);
+ _jfr_weak.oops_do(cl);
+ _vm_weak_handles.oops_do(cl);
+ _jni_weak_handles.oops_do(cl);
+ _string_table.oops_do(cl);
+ } else {
+ if (visit_jvmti_weak_export) {
+ _jvmti_weak_export.oops_do(cl);
+ }
+ }
+}
+
+ZWeakRootsIterator::ZWeakRootsIterator() :
+ _vm_weak_handles_iter(SystemDictionary::vm_weak_oop_storage()),
+ _jni_weak_handles_iter(JNIHandles::weak_global_handles()),
+ _string_table_iter(StringTable::weak_storage()),
+ _jvmti_weak_export(this),
+ _jfr_weak(this),
+ _vm_weak_handles(this),
+ _jni_weak_handles(this),
+ _symbol_table(this),
+ _string_table(this) {
+ assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
+ ZStatTimer timer(ZSubPhasePauseWeakRootsSetup);
+ SymbolTable::clear_parallel_claimed_index();
+}
+
+ZWeakRootsIterator::~ZWeakRootsIterator() {
+ ZStatTimer timer(ZSubPhasePauseWeakRootsTeardown);
+}
+
+void ZWeakRootsIterator::do_vm_weak_handles(BoolObjectClosure* is_alive, OopClosure* cl) {
+ ZStatTimer timer(ZSubPhasePauseWeakRootsVMWeakHandles);
+ _vm_weak_handles_iter.weak_oops_do(is_alive, cl);
+}
+
+void ZWeakRootsIterator::do_jni_weak_handles(BoolObjectClosure* is_alive, OopClosure* cl) {
+ ZStatTimer timer(ZSubPhasePauseWeakRootsJNIWeakHandles);
+ _jni_weak_handles_iter.weak_oops_do(is_alive, cl);
+}
+
+void ZWeakRootsIterator::do_jvmti_weak_export(BoolObjectClosure* is_alive, OopClosure* cl) {
+ ZStatTimer timer(ZSubPhasePauseWeakRootsJVMTIWeakExport);
+ JvmtiExport::weak_oops_do(is_alive, cl);
+}
+
+void ZWeakRootsIterator::do_jfr_weak(BoolObjectClosure* is_alive, OopClosure* cl) {
+#if INCLUDE_JFR
+ ZStatTimer timer(ZSubPhasePauseWeakRootsJFRWeak);
+ Jfr::weak_oops_do(is_alive, cl);
+#endif
+}
+
+void ZWeakRootsIterator::do_symbol_table(BoolObjectClosure* is_alive, OopClosure* cl) {
+ ZStatTimer timer(ZSubPhasePauseWeakRootsSymbolTable);
+ int dummy;
+ SymbolTable::possibly_parallel_unlink(&dummy, &dummy);
+}
+
+void ZWeakRootsIterator::do_string_table(BoolObjectClosure* is_alive, OopClosure* cl) {
+ ZStatTimer timer(ZSubPhasePauseWeakRootsStringTable);
+ _string_table_iter.weak_oops_do(is_alive, cl);
+}
+
+void ZWeakRootsIterator::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* cl) {
+ ZStatTimer timer(ZSubPhasePauseWeakRoots);
+ if (ZSymbolTableUnloading) {
+ _symbol_table.weak_oops_do(is_alive, cl);
+ }
+ if (ZWeakRoots) {
+ _jvmti_weak_export.weak_oops_do(is_alive, cl);
+ _jfr_weak.weak_oops_do(is_alive, cl);
+ if (!ZConcurrentVMWeakHandles) {
+ _vm_weak_handles.weak_oops_do(is_alive, cl);
+ }
+ if (!ZConcurrentJNIWeakGlobalHandles) {
+ _jni_weak_handles.weak_oops_do(is_alive, cl);
+ }
+ if (!ZConcurrentStringTable) {
+ _string_table.weak_oops_do(is_alive, cl);
+ }
+ }
+}
+
+void ZWeakRootsIterator::oops_do(OopClosure* cl) {
+ AlwaysTrueClosure always_alive;
+ weak_oops_do(&always_alive, cl);
+}
+
+ZConcurrentWeakRootsIterator::ZConcurrentWeakRootsIterator() :
+ _vm_weak_handles_iter(SystemDictionary::vm_weak_oop_storage()),
+ _jni_weak_handles_iter(JNIHandles::weak_global_handles()),
+ _string_table_iter(StringTable::weak_storage()),
+ _vm_weak_handles(this),
+ _jni_weak_handles(this),
+ _string_table(this) {}
+
+void ZConcurrentWeakRootsIterator::do_vm_weak_handles(OopClosure* cl) {
+ ZStatTimer timer(ZSubPhaseConcurrentWeakRootsVMWeakHandles);
+ _vm_weak_handles_iter.oops_do(cl);
+}
+
+void ZConcurrentWeakRootsIterator::do_jni_weak_handles(OopClosure* cl) {
+ ZStatTimer timer(ZSubPhaseConcurrentWeakRootsJNIWeakHandles);
+ _jni_weak_handles_iter.oops_do(cl);
+}
+
+void ZConcurrentWeakRootsIterator::do_string_table(OopClosure* cl) {
+ ZStatTimer timer(ZSubPhaseConcurrentWeakRootsStringTable);
+ _string_table_iter.oops_do(cl);
+}
+
+void ZConcurrentWeakRootsIterator::oops_do(OopClosure* cl) {
+ ZStatTimer timer(ZSubPhaseConcurrentWeakRoots);
+ if (ZWeakRoots) {
+ if (ZConcurrentVMWeakHandles) {
+ _vm_weak_handles.oops_do(cl);
+ }
+ if (ZConcurrentJNIWeakGlobalHandles) {
+ _jni_weak_handles.oops_do(cl);
+ }
+ if (ZConcurrentStringTable) {
+ _string_table.oops_do(cl);
+ }
+ }
+}
+
+ZThreadRootsIterator::ZThreadRootsIterator() :
+ _threads(this) {
+ assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
+ ZStatTimer timer(ZSubPhasePauseRootsSetup);
+ Threads::change_thread_claim_parity();
+}
+
+ZThreadRootsIterator::~ZThreadRootsIterator() {
+ ZStatTimer timer(ZSubPhasePauseRootsTeardown);
+ Threads::assert_all_threads_claimed();
+}
+
+void ZThreadRootsIterator::do_threads(OopClosure* cl) {
+ ZStatTimer timer(ZSubPhasePauseRootsThreads);
+ ResourceMark rm;
+ Threads::possibly_parallel_oops_do(true, cl, NULL);
+}
+
+void ZThreadRootsIterator::oops_do(OopClosure* cl) {
+ ZStatTimer timer(ZSubPhasePauseRoots);
+ _threads.oops_do(cl);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zRootsIterator.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,184 @@
+/*
+ * 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_GC_Z_ZROOTSITERATOR_HPP
+#define SHARE_GC_Z_ZROOTSITERATOR_HPP
+
+#include "gc/shared/oopStorageParState.hpp"
+#include "memory/allocation.hpp"
+#include "memory/iterator.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+typedef OopStorage::ParState<false /* concurrent */, false /* is_const */> ZOopStorageIterator;
+typedef OopStorage::ParState<true /* concurrent */, false /* is_const */> ZConcurrentOopStorageIterator;
+
+template <typename T, void (T::*F)(OopClosure*)>
+class ZSerialOopsDo {
+private:
+ T* const _iter;
+ volatile bool _claimed;
+
+public:
+ ZSerialOopsDo(T* iter);
+ void oops_do(OopClosure* cl);
+};
+
+template <typename T, void (T::*F)(OopClosure*)>
+class ZParallelOopsDo {
+private:
+ T* const _iter;
+ volatile bool _completed;
+
+public:
+ ZParallelOopsDo(T* iter);
+ void oops_do(OopClosure* cl);
+};
+
+template <typename T, void (T::*F)(BoolObjectClosure*, OopClosure*)>
+class ZSerialWeakOopsDo {
+private:
+ T* const _iter;
+ volatile bool _claimed;
+
+public:
+ ZSerialWeakOopsDo(T* iter);
+ void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* cl);
+};
+
+template <typename T, void (T::*F)(BoolObjectClosure*, OopClosure*)>
+class ZParallelWeakOopsDo {
+private:
+ T* const _iter;
+ volatile bool _completed;
+
+public:
+ ZParallelWeakOopsDo(T* iter);
+ void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* cl);
+};
+
+class ZRootsIterator {
+private:
+ ZOopStorageIterator _vm_weak_handles_iter;
+ ZOopStorageIterator _jni_handles_iter;
+ ZOopStorageIterator _jni_weak_handles_iter;
+ ZOopStorageIterator _string_table_iter;
+
+ void do_universe(OopClosure* cl);
+ void do_vm_weak_handles(OopClosure* cl);
+ void do_jni_handles(OopClosure* cl);
+ void do_jni_weak_handles(OopClosure* cl);
+ void do_object_synchronizer(OopClosure* cl);
+ void do_management(OopClosure* cl);
+ void do_jvmti_export(OopClosure* cl);
+ void do_jvmti_weak_export(OopClosure* cl);
+ void do_jfr_weak(OopClosure* cl);
+ void do_system_dictionary(OopClosure* cl);
+ void do_class_loader_data_graph(OopClosure* cl);
+ void do_threads(OopClosure* cl);
+ void do_code_cache(OopClosure* cl);
+ void do_string_table(OopClosure* cl);
+
+ ZSerialOopsDo<ZRootsIterator, &ZRootsIterator::do_universe> _universe;
+ ZSerialOopsDo<ZRootsIterator, &ZRootsIterator::do_object_synchronizer> _object_synchronizer;
+ ZSerialOopsDo<ZRootsIterator, &ZRootsIterator::do_management> _management;
+ ZSerialOopsDo<ZRootsIterator, &ZRootsIterator::do_jvmti_export> _jvmti_export;
+ ZSerialOopsDo<ZRootsIterator, &ZRootsIterator::do_jvmti_weak_export> _jvmti_weak_export;
+ ZSerialOopsDo<ZRootsIterator, &ZRootsIterator::do_jfr_weak> _jfr_weak;
+ ZSerialOopsDo<ZRootsIterator, &ZRootsIterator::do_system_dictionary> _system_dictionary;
+ ZParallelOopsDo<ZRootsIterator, &ZRootsIterator::do_vm_weak_handles> _vm_weak_handles;
+ ZParallelOopsDo<ZRootsIterator, &ZRootsIterator::do_jni_handles> _jni_handles;
+ ZParallelOopsDo<ZRootsIterator, &ZRootsIterator::do_jni_weak_handles> _jni_weak_handles;
+ ZParallelOopsDo<ZRootsIterator, &ZRootsIterator::do_class_loader_data_graph> _class_loader_data_graph;
+ ZParallelOopsDo<ZRootsIterator, &ZRootsIterator::do_threads> _threads;
+ ZParallelOopsDo<ZRootsIterator, &ZRootsIterator::do_code_cache> _code_cache;
+ ZParallelOopsDo<ZRootsIterator, &ZRootsIterator::do_string_table> _string_table;
+
+public:
+ ZRootsIterator();
+ ~ZRootsIterator();
+
+ void oops_do(OopClosure* cl, bool visit_jvmti_weak_export = false);
+};
+
+class ZWeakRootsIterator {
+private:
+ ZOopStorageIterator _vm_weak_handles_iter;
+ ZOopStorageIterator _jni_weak_handles_iter;
+ ZOopStorageIterator _string_table_iter;
+
+ void do_vm_weak_handles(BoolObjectClosure* is_alive, OopClosure* cl);
+ void do_jni_weak_handles(BoolObjectClosure* is_alive, OopClosure* cl);
+ void do_jvmti_weak_export(BoolObjectClosure* is_alive, OopClosure* cl);
+ void do_jfr_weak(BoolObjectClosure* is_alive, OopClosure* cl);
+ void do_symbol_table(BoolObjectClosure* is_alive, OopClosure* cl);
+ void do_string_table(BoolObjectClosure* is_alive, OopClosure* cl);
+
+ ZSerialWeakOopsDo<ZWeakRootsIterator, &ZWeakRootsIterator::do_jvmti_weak_export> _jvmti_weak_export;
+ ZSerialWeakOopsDo<ZWeakRootsIterator, &ZWeakRootsIterator::do_jfr_weak> _jfr_weak;
+ ZParallelWeakOopsDo<ZWeakRootsIterator, &ZWeakRootsIterator::do_vm_weak_handles> _vm_weak_handles;
+ ZParallelWeakOopsDo<ZWeakRootsIterator, &ZWeakRootsIterator::do_jni_weak_handles> _jni_weak_handles;
+ ZParallelWeakOopsDo<ZWeakRootsIterator, &ZWeakRootsIterator::do_symbol_table> _symbol_table;
+ ZParallelWeakOopsDo<ZWeakRootsIterator, &ZWeakRootsIterator::do_string_table> _string_table;
+
+public:
+ ZWeakRootsIterator();
+ ~ZWeakRootsIterator();
+
+ void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* cl);
+ void oops_do(OopClosure* cl);
+};
+
+class ZConcurrentWeakRootsIterator {
+private:
+ ZConcurrentOopStorageIterator _vm_weak_handles_iter;
+ ZConcurrentOopStorageIterator _jni_weak_handles_iter;
+ ZConcurrentOopStorageIterator _string_table_iter;
+
+ void do_vm_weak_handles(OopClosure* cl);
+ void do_jni_weak_handles(OopClosure* cl);
+ void do_string_table(OopClosure* cl);
+
+ ZParallelOopsDo<ZConcurrentWeakRootsIterator, &ZConcurrentWeakRootsIterator::do_vm_weak_handles> _vm_weak_handles;
+ ZParallelOopsDo<ZConcurrentWeakRootsIterator, &ZConcurrentWeakRootsIterator::do_jni_weak_handles> _jni_weak_handles;
+ ZParallelOopsDo<ZConcurrentWeakRootsIterator, &ZConcurrentWeakRootsIterator::do_string_table> _string_table;
+
+public:
+ ZConcurrentWeakRootsIterator();
+
+ void oops_do(OopClosure* cl);
+};
+
+class ZThreadRootsIterator {
+private:
+ void do_threads(OopClosure* cl);
+
+ ZParallelOopsDo<ZThreadRootsIterator, &ZThreadRootsIterator::do_threads> _threads;
+
+public:
+ ZThreadRootsIterator();
+ ~ZThreadRootsIterator();
+
+ void oops_do(OopClosure* cl);
+};
+
+#endif // SHARE_GC_Z_ZROOTSITERATOR_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zRuntimeWorkers.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,54 @@
+/*
+ * 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 "gc/z/zRuntimeWorkers.hpp"
+
+ZRuntimeWorkers::ZRuntimeWorkers() :
+ _workers("RuntimeWorker",
+ nworkers(),
+ false /* are_GC_task_threads */,
+ false /* are_ConcurrentGC_threads */) {
+
+ log_info(gc, init)("Runtime Workers: %u parallel", nworkers());
+
+ // Initialize worker threads
+ _workers.initialize_workers();
+ _workers.update_active_workers(nworkers());
+}
+
+uint ZRuntimeWorkers::nworkers() const {
+ return ParallelGCThreads;
+}
+
+WorkGang* ZRuntimeWorkers::workers() {
+ return &_workers;
+}
+
+void ZRuntimeWorkers::threads_do(ThreadClosure* tc) const {
+ _workers.threads_do(tc);
+}
+
+void ZRuntimeWorkers::print_threads_on(outputStream* st) const {
+ _workers.print_worker_threads_on(st);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zRuntimeWorkers.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,44 @@
+/*
+ * 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_Z_ZRUNTIMEWORKERS_HPP
+#define SHARE_GC_Z_ZRUNTIMEWORKERS_HPP
+
+#include "gc/shared/workgroup.hpp"
+
+class ZRuntimeWorkers {
+private:
+ WorkGang _workers;
+
+ uint nworkers() const;
+
+public:
+ ZRuntimeWorkers();
+
+ WorkGang* workers();
+
+ void threads_do(ThreadClosure* tc) const;
+ void print_threads_on(outputStream* st) const;
+};
+
+#endif // SHARE_GC_Z_ZRUNTIMEWORKERS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zServiceability.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,156 @@
+/*
+ * 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
+ * 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/generationCounters.hpp"
+#include "gc/shared/hSpaceCounters.hpp"
+#include "gc/z/zCollectedHeap.hpp"
+#include "gc/z/zHeap.inline.hpp"
+#include "gc/z/zServiceability.hpp"
+#include "memory/metaspaceCounters.hpp"
+#include "runtime/perfData.hpp"
+
+class ZOldGenerationCounters : public GenerationCounters {
+public:
+ ZOldGenerationCounters(const char* name, size_t min_capacity, size_t max_capacity) :
+ // The "1, 1" parameters are for the n-th generation (=1) with 1 space.
+ GenerationCounters(name,
+ 1 /* ordinal */,
+ 1 /* spaces */,
+ min_capacity /* min_capacity */,
+ max_capacity /* max_capacity */,
+ min_capacity /* curr_capacity */) {}
+
+ virtual void update_all() {
+ size_t committed = ZHeap::heap()->capacity();
+ _current_size->set_value(committed);
+ }
+};
+
+// Class to expose perf counters used by jstat.
+class ZServiceabilityCounters : public CHeapObj<mtGC> {
+private:
+ ZOldGenerationCounters _old_collection_counters;
+ HSpaceCounters _old_space_counters;
+
+public:
+ ZServiceabilityCounters(size_t min_capacity, size_t max_capacity);
+
+ void update_sizes();
+};
+
+ZServiceabilityCounters::ZServiceabilityCounters(size_t min_capacity, size_t max_capacity) :
+ // generation.1
+ _old_collection_counters("old",
+ min_capacity,
+ max_capacity),
+ // generation.1.space.0
+ _old_space_counters(_old_collection_counters.name_space(),
+ "space",
+ 0 /* ordinal */,
+ max_capacity /* max_capacity */,
+ min_capacity /* init_capacity */) {}
+
+void ZServiceabilityCounters::update_sizes() {
+ if (UsePerfData) {
+ size_t capacity = ZHeap::heap()->capacity();
+ size_t used = MIN2(ZHeap::heap()->used(), capacity);
+
+ _old_space_counters.update_capacity(capacity);
+ _old_space_counters.update_used(used);
+
+ _old_collection_counters.update_all();
+
+ MetaspaceCounters::update_performance_counters();
+ CompressedClassSpaceCounters::update_performance_counters();
+ }
+}
+
+ZServiceabilityMemoryPool::ZServiceabilityMemoryPool(size_t min_capacity, size_t max_capacity) :
+ CollectedMemoryPool("ZHeap",
+ min_capacity,
+ max_capacity,
+ true /* support_usage_threshold */) {}
+
+size_t ZServiceabilityMemoryPool::used_in_bytes() {
+ return ZHeap::heap()->used();
+}
+
+MemoryUsage ZServiceabilityMemoryPool::get_memory_usage() {
+ const size_t committed = ZHeap::heap()->capacity();
+ const size_t used = MIN2(ZHeap::heap()->used(), committed);
+
+ return MemoryUsage(initial_size(), used, committed, max_size());
+}
+
+ZServiceabilityMemoryManager::ZServiceabilityMemoryManager(ZServiceabilityMemoryPool* pool)
+ : GCMemoryManager("ZGC", "end of major GC") {
+ add_pool(pool);
+}
+
+ZServiceability::ZServiceability(size_t min_capacity, size_t max_capacity) :
+ _min_capacity(min_capacity),
+ _max_capacity(max_capacity),
+ _memory_pool(_min_capacity, _max_capacity),
+ _memory_manager(&_memory_pool),
+ _counters(NULL) {}
+
+void ZServiceability::initialize() {
+ _counters = new ZServiceabilityCounters(_min_capacity, _max_capacity);
+}
+
+MemoryPool* ZServiceability::memory_pool() {
+ return &_memory_pool;
+}
+
+GCMemoryManager* ZServiceability::memory_manager() {
+ return &_memory_manager;
+}
+
+ZServiceabilityCounters* ZServiceability::counters() {
+ return _counters;
+}
+
+ZServiceabilityMemoryUsageTracker::~ZServiceabilityMemoryUsageTracker() {
+ MemoryService::track_memory_usage();
+}
+
+ZServiceabilityManagerStatsTracer::ZServiceabilityManagerStatsTracer(bool is_gc_begin, bool is_gc_end) :
+ _stats(ZHeap::heap()->serviceability_memory_manager(),
+ ZCollectedHeap::heap()->gc_cause() /* cause */,
+ is_gc_begin /* recordGCBeginTime */,
+ is_gc_begin /* recordPreGCUsage */,
+ true /* recordPeakUsage */,
+ is_gc_end /* recordPostGCusage */,
+ true /* recordAccumulatedGCTime */,
+ is_gc_end /* recordGCEndTime */,
+ is_gc_end /* countCollection */) {}
+
+ZServiceabilityCountersTracer::ZServiceabilityCountersTracer() {
+ // Nothing to trace with TraceCollectorStats, since ZGC has
+ // neither a young collector or a full collector.
+}
+
+ZServiceabilityCountersTracer::~ZServiceabilityCountersTracer() {
+ ZHeap::heap()->serviceability_counters()->update_sizes();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zServiceability.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef SHARE_GC_Z_ZSERVICEABILITY_HPP
+#define SHARE_GC_Z_ZSERVICEABILITY_HPP
+
+#include "memory/allocation.hpp"
+#include "services/memoryManager.hpp"
+#include "services/memoryPool.hpp"
+#include "services/memoryService.hpp"
+
+class ZServiceabilityCounters;
+
+class ZServiceabilityMemoryPool : public CollectedMemoryPool {
+public:
+ ZServiceabilityMemoryPool(size_t min_capacity, size_t max_capacity);
+
+ virtual size_t used_in_bytes();
+ virtual MemoryUsage get_memory_usage();
+};
+
+class ZServiceabilityMemoryManager : public GCMemoryManager {
+public:
+ ZServiceabilityMemoryManager(ZServiceabilityMemoryPool* pool);
+};
+
+class ZServiceability {
+private:
+ const size_t _min_capacity;
+ const size_t _max_capacity;
+ ZServiceabilityMemoryPool _memory_pool;
+ ZServiceabilityMemoryManager _memory_manager;
+ ZServiceabilityCounters* _counters;
+
+public:
+ ZServiceability(size_t min_capacity, size_t max_capacity);
+
+ void initialize();
+
+ MemoryPool* memory_pool();
+ GCMemoryManager* memory_manager();
+ ZServiceabilityCounters* counters();
+};
+
+class ZServiceabilityMemoryUsageTracker {
+public:
+ ~ZServiceabilityMemoryUsageTracker();
+};
+
+class ZServiceabilityManagerStatsTracer {
+private:
+ TraceMemoryManagerStats _stats;
+
+public:
+ ZServiceabilityManagerStatsTracer(bool is_gc_begin, bool is_gc_end);
+};
+
+class ZServiceabilityCountersTracer {
+public:
+ ZServiceabilityCountersTracer();
+ ~ZServiceabilityCountersTracer();
+};
+
+template <bool IsGCStart, bool IsGCEnd>
+class ZServiceabilityTracer : public StackObj {
+private:
+ ZServiceabilityMemoryUsageTracker _memory_usage_tracker;
+ ZServiceabilityManagerStatsTracer _manager_stats_tracer;
+ ZServiceabilityCountersTracer _counters_tracer;
+
+public:
+ ZServiceabilityTracer() :
+ _memory_usage_tracker(),
+ _manager_stats_tracer(IsGCStart, IsGCEnd),
+ _counters_tracer() {}
+};
+
+typedef ZServiceabilityTracer<true, false> ZServiceabilityMarkStartTracer;
+typedef ZServiceabilityTracer<false, false> ZServiceabilityMarkEndTracer;
+typedef ZServiceabilityTracer<false, true> ZServiceabilityRelocateStartTracer;
+
+#endif // SHARE_GC_Z_ZSERVICEABILITY_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zStat.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,1366 @@
+/*
+ * 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 "gc/z/zCollectedHeap.hpp"
+#include "gc/z/zCPU.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zHeap.inline.hpp"
+#include "gc/z/zLargePages.inline.hpp"
+#include "gc/z/zNMethodTable.hpp"
+#include "gc/z/zNUMA.hpp"
+#include "gc/z/zStat.hpp"
+#include "gc/z/zTracer.inline.hpp"
+#include "gc/z/zUtils.hpp"
+#include "memory/resourceArea.hpp"
+#include "runtime/atomic.hpp"
+#include "runtime/os.hpp"
+#include "runtime/timer.hpp"
+#include "utilities/align.hpp"
+#include "utilities/compilerWarnings.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/ticks.hpp"
+
+//
+// Stat sampler/counter data
+//
+struct ZStatSamplerData {
+ uint64_t _nsamples;
+ uint64_t _sum;
+ uint64_t _max;
+
+ ZStatSamplerData() :
+ _nsamples(0),
+ _sum(0),
+ _max(0) {}
+
+ void add(const ZStatSamplerData& new_sample) {
+ _nsamples += new_sample._nsamples;
+ _sum += new_sample._nsamples;
+ _max = MAX2(_max, new_sample._max);
+ }
+};
+
+struct ZStatCounterData {
+ uint64_t _counter;
+
+ ZStatCounterData() :
+ _counter(0) {}
+};
+
+//
+// Stat sampler history
+//
+template <size_t size>
+class ZStatSamplerHistoryInterval {
+private:
+ size_t _next;
+ ZStatSamplerData _samples[size];
+ ZStatSamplerData _accumulated;
+ ZStatSamplerData _total;
+
+public:
+ ZStatSamplerHistoryInterval() :
+ _next(0),
+ _samples(),
+ _total(),
+ _accumulated() {}
+
+ bool add(const ZStatSamplerData& new_sample) {
+ // Insert sample
+ const ZStatSamplerData old_sample = _samples[_next];
+ _samples[_next] = new_sample;
+
+ // Adjust accumulated
+ _accumulated._nsamples += new_sample._nsamples;
+ _accumulated._sum += new_sample._sum;
+ _accumulated._max = MAX2(_accumulated._max, new_sample._max);
+
+ // Adjust total
+ _total._nsamples -= old_sample._nsamples;
+ _total._sum -= old_sample._sum;
+ _total._nsamples += new_sample._nsamples;
+ _total._sum += new_sample._sum;
+ if (_total._max < new_sample._max) {
+ // Found new max
+ _total._max = new_sample._max;
+ } else if (_total._max == old_sample._max) {
+ // Removed old max, reset and find new max
+ _total._max = 0;
+ for (size_t i = 0; i < size; i++) {
+ if (_total._max < _samples[i]._max) {
+ _total._max = _samples[i]._max;
+ }
+ }
+ }
+
+ // Adjust next
+ if (++_next == size) {
+ _next = 0;
+
+ // Clear accumulated
+ const ZStatSamplerData zero;
+ _accumulated = zero;
+
+ // Became full
+ return true;
+ }
+
+ // Not yet full
+ return false;
+ }
+
+ const ZStatSamplerData& total() const {
+ return _total;
+ }
+
+ const ZStatSamplerData& accumulated() const {
+ return _accumulated;
+ }
+};
+
+class ZStatSamplerHistory : public CHeapObj<mtGC> {
+private:
+ ZStatSamplerHistoryInterval<10> _10seconds;
+ ZStatSamplerHistoryInterval<60> _10minutes;
+ ZStatSamplerHistoryInterval<60> _10hours;
+ ZStatSamplerData _total;
+
+ uint64_t avg(uint64_t sum, uint64_t nsamples) const {
+ return (nsamples > 0) ? sum / nsamples : 0;
+ }
+
+public:
+ ZStatSamplerHistory() :
+ _10seconds(),
+ _10minutes(),
+ _10hours(),
+ _total() {}
+
+ void add(const ZStatSamplerData& new_sample) {
+ if (_10seconds.add(new_sample)) {
+ if (_10minutes.add(_10seconds.total())) {
+ if (_10hours.add(_10minutes.total())) {
+ _total.add(_10hours.total());
+ }
+ }
+ }
+ }
+
+ uint64_t avg_10_seconds() const {
+ const uint64_t sum = _10seconds.total()._sum;
+ const uint64_t nsamples = _10seconds.total()._nsamples;
+ return avg(sum, nsamples);
+ }
+
+ uint64_t avg_10_minutes() const {
+ const uint64_t sum = _10seconds.accumulated()._sum +
+ _10minutes.total()._sum;
+ const uint64_t nsamples = _10seconds.accumulated()._nsamples +
+ _10minutes.total()._nsamples;
+ return avg(sum, nsamples);
+ }
+
+ uint64_t avg_10_hours() const {
+ const uint64_t sum = _10seconds.accumulated()._sum +
+ _10minutes.accumulated()._sum +
+ _10hours.total()._sum;
+ const uint64_t nsamples = _10seconds.accumulated()._nsamples +
+ _10minutes.accumulated()._nsamples +
+ _10hours.total()._nsamples;
+ return avg(sum, nsamples);
+ }
+
+ uint64_t avg_total() const {
+ const uint64_t sum = _10seconds.accumulated()._sum +
+ _10minutes.accumulated()._sum +
+ _10hours.accumulated()._sum +
+ _total._sum;
+ const uint64_t nsamples = _10seconds.accumulated()._nsamples +
+ _10minutes.accumulated()._nsamples +
+ _10hours.accumulated()._nsamples +
+ _total._nsamples;
+ return avg(sum, nsamples);
+ }
+
+ uint64_t max_10_seconds() const {
+ return _10seconds.total()._max;
+ }
+
+ uint64_t max_10_minutes() const {
+ return MAX2(_10seconds.accumulated()._max,
+ _10minutes.total()._max);
+ }
+
+ uint64_t max_10_hours() const {
+ return MAX3(_10seconds.accumulated()._max,
+ _10minutes.accumulated()._max,
+ _10hours.total()._max);
+ }
+
+ uint64_t max_total() const {
+ return MAX4(_10seconds.accumulated()._max,
+ _10minutes.accumulated()._max,
+ _10hours.accumulated()._max,
+ _total._max);
+ }
+};
+
+//
+// Stat unit printers
+//
+void ZStatUnitTime(LogTargetHandle log, const ZStatSampler& sampler, const ZStatSamplerHistory& history) {
+ log.print(" %10s: %-40s "
+ "%9.3f / %-9.3f "
+ "%9.3f / %-9.3f "
+ "%9.3f / %-9.3f "
+ "%9.3f / %-9.3f ms",
+ sampler.group(),
+ sampler.name(),
+ TimeHelper::counter_to_millis(history.avg_10_seconds()),
+ TimeHelper::counter_to_millis(history.max_10_seconds()),
+ TimeHelper::counter_to_millis(history.avg_10_minutes()),
+ TimeHelper::counter_to_millis(history.max_10_minutes()),
+ TimeHelper::counter_to_millis(history.avg_10_hours()),
+ TimeHelper::counter_to_millis(history.max_10_hours()),
+ TimeHelper::counter_to_millis(history.avg_total()),
+ TimeHelper::counter_to_millis(history.max_total()));
+}
+
+void ZStatUnitBytes(LogTargetHandle log, const ZStatSampler& sampler, const ZStatSamplerHistory& history) {
+ log.print(" %10s: %-40s "
+ UINT64_FORMAT_W(9) " / " UINT64_FORMAT_W(-9) " "
+ UINT64_FORMAT_W(9) " / " UINT64_FORMAT_W(-9) " "
+ UINT64_FORMAT_W(9) " / " UINT64_FORMAT_W(-9) " "
+ UINT64_FORMAT_W(9) " / " UINT64_FORMAT_W(-9) " MB",
+ sampler.group(),
+ sampler.name(),
+ history.avg_10_seconds() / M,
+ history.max_10_seconds() / M,
+ history.avg_10_minutes() / M,
+ history.max_10_minutes() / M,
+ history.avg_10_hours() / M,
+ history.max_10_hours() / M,
+ history.avg_total() / M,
+ history.max_total() / M);
+}
+
+void ZStatUnitThreads(LogTargetHandle log, const ZStatSampler& sampler, const ZStatSamplerHistory& history) {
+ log.print(" %10s: %-40s "
+ UINT64_FORMAT_W(9) " / " UINT64_FORMAT_W(-9) " "
+ UINT64_FORMAT_W(9) " / " UINT64_FORMAT_W(-9) " "
+ UINT64_FORMAT_W(9) " / " UINT64_FORMAT_W(-9) " "
+ UINT64_FORMAT_W(9) " / " UINT64_FORMAT_W(-9) " threads",
+ sampler.group(),
+ sampler.name(),
+ history.avg_10_seconds(),
+ history.max_10_seconds(),
+ history.avg_10_minutes(),
+ history.max_10_minutes(),
+ history.avg_10_hours(),
+ history.max_10_hours(),
+ history.avg_total(),
+ history.max_total());
+}
+
+void ZStatUnitBytesPerSecond(LogTargetHandle log, const ZStatSampler& sampler, const ZStatSamplerHistory& history) {
+ log.print(" %10s: %-40s "
+ UINT64_FORMAT_W(9) " / " UINT64_FORMAT_W(-9) " "
+ UINT64_FORMAT_W(9) " / " UINT64_FORMAT_W(-9) " "
+ UINT64_FORMAT_W(9) " / " UINT64_FORMAT_W(-9) " "
+ UINT64_FORMAT_W(9) " / " UINT64_FORMAT_W(-9) " MB/s",
+ sampler.group(),
+ sampler.name(),
+ history.avg_10_seconds() / M,
+ history.max_10_seconds() / M,
+ history.avg_10_minutes() / M,
+ history.max_10_minutes() / M,
+ history.avg_10_hours() / M,
+ history.max_10_hours() / M,
+ history.avg_total() / M,
+ history.max_total() / M);
+}
+
+void ZStatUnitOpsPerSecond(LogTargetHandle log, const ZStatSampler& sampler, const ZStatSamplerHistory& history) {
+ log.print(" %10s: %-40s "
+ UINT64_FORMAT_W(9) " / " UINT64_FORMAT_W(-9) " "
+ UINT64_FORMAT_W(9) " / " UINT64_FORMAT_W(-9) " "
+ UINT64_FORMAT_W(9) " / " UINT64_FORMAT_W(-9) " "
+ UINT64_FORMAT_W(9) " / " UINT64_FORMAT_W(-9) " ops/s",
+ sampler.group(),
+ sampler.name(),
+ history.avg_10_seconds(),
+ history.max_10_seconds(),
+ history.avg_10_minutes(),
+ history.max_10_minutes(),
+ history.avg_10_hours(),
+ history.max_10_hours(),
+ history.avg_total(),
+ history.max_total());
+}
+
+//
+// Stat value
+//
+uintptr_t ZStatValue::_base = 0;
+uint32_t ZStatValue::_cpu_offset = 0;
+
+ZStatValue::ZStatValue(const char* group,
+ const char* name,
+ uint32_t id,
+ uint32_t size) :
+ _group(group),
+ _name(name),
+ _id(id),
+ _offset(_cpu_offset) {
+ assert(_base == 0, "Already initialized");
+ _cpu_offset += size;
+}
+
+template <typename T>
+T* ZStatValue::get_cpu_local(uint32_t cpu) const {
+ assert(_base != 0, "Not initialized");
+ const uintptr_t cpu_base = _base + (_cpu_offset * cpu);
+ const uintptr_t value_addr = cpu_base + _offset;
+ return (T*)value_addr;
+}
+
+void ZStatValue::initialize() {
+ // Finalize and align CPU offset
+ _cpu_offset = align_up(_cpu_offset, ZCacheLineSize);
+
+ // Allocation aligned memory
+ const size_t size = _cpu_offset * ZCPU::count();
+ _base = ZUtils::alloc_aligned(ZCacheLineSize, size);
+ memset((void*)_base, 0, size);
+}
+
+const char* ZStatValue::group() const {
+ return _group;
+}
+
+const char* ZStatValue::name() const {
+ return _name;
+}
+
+uint32_t ZStatValue::id() const {
+ return _id;
+}
+
+//
+// Stat iterable value
+//
+template <typename T> uint32_t ZStatIterableValue<T>::_count = 0;
+template <typename T> T* ZStatIterableValue<T>::_first = NULL;
+
+template <typename T>
+ZStatIterableValue<T>::ZStatIterableValue(const char* group,
+ const char* name,
+ uint32_t size) :
+ ZStatValue(group, name, _count++, size),
+ _next(insert()) {}
+
+template <typename T>
+T* ZStatIterableValue<T>::insert() const {
+ T** current = &_first;
+
+ while (*current != NULL) {
+ // First sort by group, then by name
+ const int group_cmp = strcmp((*current)->group(), group());
+ const int name_cmp = strcmp((*current)->name(), name());
+ if ((group_cmp > 0) || (group_cmp == 0 && name_cmp > 0)) {
+ break;
+ }
+
+ current = &(*current)->_next;
+ }
+
+ T* const next = *current;
+ *current = (T*)this;
+ return next;
+}
+
+//
+// Stat sampler
+//
+ZStatSampler::ZStatSampler(const char* group, const char* name, ZStatUnitPrinter printer) :
+ ZStatIterableValue(group, name, sizeof(ZStatSamplerData)),
+ _printer(printer) {}
+
+ZStatSamplerData* ZStatSampler::get() const {
+ return get_cpu_local<ZStatSamplerData>(ZCPU::id());
+}
+
+ZStatSamplerData ZStatSampler::collect_and_reset() const {
+ ZStatSamplerData all;
+
+ const uint32_t ncpus = ZCPU::count();
+ for (uint32_t i = 0; i < ncpus; i++) {
+ ZStatSamplerData* const cpu_data = get_cpu_local<ZStatSamplerData>(i);
+ if (cpu_data->_nsamples > 0) {
+ const uint64_t nsamples = Atomic::xchg((uint64_t)0, &cpu_data->_nsamples);
+ const uint64_t sum = Atomic::xchg((uint64_t)0, &cpu_data->_sum);
+ const uint64_t max = Atomic::xchg((uint64_t)0, &cpu_data->_max);
+ all._nsamples += nsamples;
+ all._sum += sum;
+ if (all._max < max) {
+ all._max = max;
+ }
+ }
+ }
+
+ return all;
+}
+
+ZStatUnitPrinter ZStatSampler::printer() const {
+ return _printer;
+}
+
+//
+// Stat counter
+//
+ZStatCounter::ZStatCounter(const char* group, const char* name, ZStatUnitPrinter printer) :
+ ZStatIterableValue(group, name, sizeof(ZStatCounterData)),
+ _sampler(group, name, printer) {}
+
+ZStatCounterData* ZStatCounter::get() const {
+ return get_cpu_local<ZStatCounterData>(ZCPU::id());
+}
+
+void ZStatCounter::sample_and_reset() const {
+ uint64_t counter = 0;
+
+ const uint32_t ncpus = ZCPU::count();
+ for (uint32_t i = 0; i < ncpus; i++) {
+ ZStatCounterData* const cpu_data = get_cpu_local<ZStatCounterData>(i);
+ counter += Atomic::xchg((uint64_t)0, &cpu_data->_counter);
+ }
+
+ ZStatSample(_sampler, counter);
+}
+
+//
+// Stat unsampled counter
+//
+ZStatUnsampledCounter::ZStatUnsampledCounter(const char* name) :
+ ZStatIterableValue("Unsampled", name, sizeof(ZStatCounterData)) {}
+
+ZStatCounterData* ZStatUnsampledCounter::get() const {
+ return get_cpu_local<ZStatCounterData>(ZCPU::id());
+}
+
+ZStatCounterData ZStatUnsampledCounter::collect_and_reset() const {
+ ZStatCounterData all;
+
+ const uint32_t ncpus = ZCPU::count();
+ for (uint32_t i = 0; i < ncpus; i++) {
+ ZStatCounterData* const cpu_data = get_cpu_local<ZStatCounterData>(i);
+ all._counter += Atomic::xchg((uint64_t)0, &cpu_data->_counter);
+ }
+
+ return all;
+}
+
+//
+// Stat MMU (Mimimum Mutator Utilization)
+//
+ZStatMMUPause::ZStatMMUPause() :
+ _start(0.0),
+ _end(0.0) {}
+
+ZStatMMUPause::ZStatMMUPause(const Ticks& start, const Ticks& end) :
+ _start(TimeHelper::counter_to_millis(start.value())),
+ _end(TimeHelper::counter_to_millis(end.value())) {}
+
+double ZStatMMUPause::end() const {
+ return _end;
+}
+
+double ZStatMMUPause::overlap(double start, double end) const {
+ const double start_max = MAX2(start, _start);
+ const double end_min = MIN2(end, _end);
+
+ if (end_min > start_max) {
+ // Overlap found
+ return end_min - start_max;
+ }
+
+ // No overlap
+ return 0.0;
+}
+
+size_t ZStatMMU::_next = 0;
+size_t ZStatMMU::_npauses = 0;
+ZStatMMUPause ZStatMMU::_pauses[200];
+double ZStatMMU::_mmu_2ms = 100.0;
+double ZStatMMU::_mmu_5ms = 100.0;
+double ZStatMMU::_mmu_10ms = 100.0;
+double ZStatMMU::_mmu_20ms = 100.0;
+double ZStatMMU::_mmu_50ms = 100.0;
+double ZStatMMU::_mmu_100ms = 100.0;
+
+const ZStatMMUPause& ZStatMMU::pause(size_t index) {
+ return _pauses[(_next - index - 1) % ARRAY_SIZE(_pauses)];
+}
+
+double ZStatMMU::calculate_mmu(double time_slice) {
+ const double end = pause(0).end();
+ const double start = end - time_slice;
+ double time_paused = 0.0;
+
+ // Find all overlapping pauses
+ for (size_t i = 0; i < _npauses; i++) {
+ const double overlap = pause(i).overlap(start, end);
+ if (overlap == 0.0) {
+ // No overlap
+ break;
+ }
+
+ time_paused += overlap;
+ }
+
+ // Calculate MMU
+ const double time_mutator = time_slice - time_paused;
+ return percent_of(time_mutator, time_slice);
+}
+
+void ZStatMMU::register_pause(const Ticks& start, const Ticks& end) {
+ // Add pause
+ const size_t index = _next++ % ARRAY_SIZE(_pauses);
+ _pauses[index] = ZStatMMUPause(start, end);
+ _npauses = MIN2(_npauses + 1, ARRAY_SIZE(_pauses));
+
+ // Recalculate MMUs
+ _mmu_2ms = MIN2(_mmu_2ms, calculate_mmu(2));
+ _mmu_5ms = MIN2(_mmu_5ms, calculate_mmu(5));
+ _mmu_10ms = MIN2(_mmu_10ms, calculate_mmu(10));
+ _mmu_20ms = MIN2(_mmu_20ms, calculate_mmu(20));
+ _mmu_50ms = MIN2(_mmu_50ms, calculate_mmu(50));
+ _mmu_100ms = MIN2(_mmu_100ms, calculate_mmu(100));
+}
+
+void ZStatMMU::print() {
+ log_info(gc, mmu)(
+ "MMU: 2ms/%.1f%%, 5ms/%.1f%%, 10ms/%.1f%%, 20ms/%.1f%%, 50ms/%.1f%%, 100ms/%.1f%%",
+ _mmu_2ms, _mmu_5ms, _mmu_10ms, _mmu_20ms, _mmu_50ms, _mmu_100ms);
+}
+
+//
+// Stat phases
+//
+ConcurrentGCTimer ZStatPhase::_timer;
+
+ZStatPhase::ZStatPhase(const char* group, const char* name) :
+ _sampler(group, name, ZStatUnitTime) {}
+
+void ZStatPhase::log_start(LogTargetHandle log, bool thread) const {
+ if (!log.is_enabled()) {
+ return;
+ }
+
+ if (thread) {
+ ResourceMark rm;
+ log.print("%s (%s)", name(), Thread::current()->name());
+ } else {
+ log.print("%s", name());
+ }
+}
+
+void ZStatPhase::log_end(LogTargetHandle log, const Tickspan& duration, bool thread) const {
+ if (!log.is_enabled()) {
+ return;
+ }
+
+ if (thread) {
+ ResourceMark rm;
+ log.print("%s (%s) %.3fms", name(), Thread::current()->name(), TimeHelper::counter_to_millis(duration.value()));
+ } else {
+ log.print("%s %.3fms", name(), TimeHelper::counter_to_millis(duration.value()));
+ }
+}
+
+ConcurrentGCTimer* ZStatPhase::timer() {
+ return &_timer;
+}
+
+const char* ZStatPhase::name() const {
+ return _sampler.name();
+}
+
+ZStatPhaseCycle::ZStatPhaseCycle(const char* name) :
+ ZStatPhase("Collector", name) {}
+
+void ZStatPhaseCycle::register_start(const Ticks& start) const {
+ timer()->register_gc_start(start);
+
+ ZTracer::tracer()->report_gc_start(ZCollectedHeap::heap()->gc_cause(), start);
+
+ ZCollectedHeap::heap()->print_heap_before_gc();
+ ZCollectedHeap::heap()->trace_heap_before_gc(ZTracer::tracer());
+
+ log_info(gc, start)("Garbage Collection (%s)",
+ GCCause::to_string(ZCollectedHeap::heap()->gc_cause()));
+}
+
+#define ZUSED_FMT SIZE_FORMAT "M(%.0lf%%)"
+#define ZUSED_ARGS(size, max_capacity) ((size) / M), (percent_of<size_t>(size, max_capacity))
+
+void ZStatPhaseCycle::register_end(const Ticks& start, const Ticks& end) const {
+ timer()->register_gc_end(end);
+
+ ZCollectedHeap::heap()->print_heap_after_gc();
+ ZCollectedHeap::heap()->trace_heap_after_gc(ZTracer::tracer());
+
+ ZTracer::tracer()->report_gc_end(end, timer()->time_partitions());
+
+ const Tickspan duration = end - start;
+ ZStatSample(_sampler, duration.value());
+
+ ZStatLoad::print();
+ ZStatMMU::print();
+ ZStatMark::print();
+ ZStatRelocation::print();
+ ZStatNMethods::print();
+ ZStatReferences::print();
+ ZStatHeap::print();
+
+ log_info(gc)("Garbage Collection (%s) " ZUSED_FMT "->" ZUSED_FMT,
+ GCCause::to_string(ZCollectedHeap::heap()->gc_cause()),
+ ZUSED_ARGS(ZStatHeap::used_at_mark_start(), ZStatHeap::max_capacity()),
+ ZUSED_ARGS(ZStatHeap::used_at_relocate_end(), ZStatHeap::max_capacity()));
+}
+
+Tickspan ZStatPhasePause::_max;
+
+ZStatPhasePause::ZStatPhasePause(const char* name) :
+ ZStatPhase("Phase", name) {}
+
+const Tickspan& ZStatPhasePause::max() {
+ return _max;
+}
+
+void ZStatPhasePause::register_start(const Ticks& start) const {
+ timer()->register_gc_pause_start(name(), start);
+
+ LogTarget(Debug, gc, phases, start) log;
+ log_start(log);
+}
+
+void ZStatPhasePause::register_end(const Ticks& start, const Ticks& end) const {
+ timer()->register_gc_pause_end(end);
+
+ const Tickspan duration = end - start;
+ ZStatSample(_sampler, duration.value());
+
+ // Track max pause time
+ if (_max < duration) {
+ _max = duration;
+ }
+
+ // Track minimum mutator utilization
+ ZStatMMU::register_pause(start, end);
+
+ LogTarget(Info, gc, phases) log;
+ log_end(log, duration);
+}
+
+ZStatPhaseConcurrent::ZStatPhaseConcurrent(const char* name) :
+ ZStatPhase("Phase", name) {}
+
+void ZStatPhaseConcurrent::register_start(const Ticks& start) const {
+ timer()->register_gc_concurrent_start(name(), start);
+
+ LogTarget(Debug, gc, phases, start) log;
+ log_start(log);
+}
+
+void ZStatPhaseConcurrent::register_end(const Ticks& start, const Ticks& end) const {
+ timer()->register_gc_concurrent_end(end);
+
+ const Tickspan duration = end - start;
+ ZStatSample(_sampler, duration.value());
+
+ LogTarget(Info, gc, phases) log;
+ log_end(log, duration);
+}
+
+ZStatSubPhase::ZStatSubPhase(const char* name) :
+ ZStatPhase("Subphase", name) {}
+
+void ZStatSubPhase::register_start(const Ticks& start) const {
+ LogTarget(Debug, gc, phases, start) log;
+ log_start(log, true /* thread */);
+}
+
+void ZStatSubPhase::register_end(const Ticks& start, const Ticks& end) const {
+ ZTracer::tracer()->report_thread_phase(*this, start, end);
+
+ const Tickspan duration = end - start;
+ ZStatSample(_sampler, duration.value());
+
+ LogTarget(Debug, gc, phases) log;
+ log_end(log, duration, true /* thread */);
+}
+
+ZStatCriticalPhase::ZStatCriticalPhase(const char* name, bool verbose) :
+ ZStatPhase("Critical", name),
+ _counter("Critical", name, ZStatUnitOpsPerSecond),
+ _verbose(verbose) {}
+
+void ZStatCriticalPhase::register_start(const Ticks& start) const {
+ LogTarget(Debug, gc, start) log;
+ log_start(log, true /* thread */);
+}
+
+void ZStatCriticalPhase::register_end(const Ticks& start, const Ticks& end) const {
+ ZTracer::tracer()->report_thread_phase(*this, start, end);
+
+ const Tickspan duration = end - start;
+ ZStatSample(_sampler, duration.value());
+ ZStatInc(_counter);
+
+ if (_verbose) {
+ LogTarget(Info, gc) log;
+ log_end(log, duration, true /* thread */);
+ } else {
+ LogTarget(Debug, gc) log;
+ log_end(log, duration, true /* thread */);
+ }
+}
+
+//
+// Stat sample/inc
+//
+void ZStatSample(const ZStatSampler& sampler, uint64_t value, bool trace) {
+ ZStatSamplerData* const cpu_data = sampler.get();
+ Atomic::add(1u, &cpu_data->_nsamples);
+ Atomic::add(value, &cpu_data->_sum);
+
+ uint64_t max = cpu_data->_max;
+ for (;;) {
+ if (max >= value) {
+ // Not max
+ break;
+ }
+
+ const uint64_t new_max = value;
+ const uint64_t prev_max = Atomic::cmpxchg(new_max, &cpu_data->_max, max);
+ if (prev_max == max) {
+ // Success
+ break;
+ }
+
+ // Retry
+ max = prev_max;
+ }
+
+ if (trace) {
+ ZTracer::tracer()->report_stat_sampler(sampler, value);
+ }
+}
+
+void ZStatInc(const ZStatCounter& counter, uint64_t increment, bool trace) {
+ ZStatCounterData* const cpu_data = counter.get();
+ const uint64_t value = Atomic::add(increment, &cpu_data->_counter);
+
+ if (trace) {
+ ZTracer::tracer()->report_stat_counter(counter, increment, value);
+ }
+}
+
+void ZStatInc(const ZStatUnsampledCounter& counter, uint64_t increment) {
+ ZStatCounterData* const cpu_data = counter.get();
+ Atomic::add(increment, &cpu_data->_counter);
+}
+
+//
+// Stat allocation rate
+//
+const ZStatUnsampledCounter ZStatAllocRate::_counter("Allocation Rate");
+TruncatedSeq ZStatAllocRate::_rate(ZStatAllocRate::sample_window_sec * ZStatAllocRate::sample_hz);
+TruncatedSeq ZStatAllocRate::_rate_avg(ZStatAllocRate::sample_window_sec * ZStatAllocRate::sample_hz);
+
+const ZStatUnsampledCounter& ZStatAllocRate::counter() {
+ return _counter;
+}
+
+uint64_t ZStatAllocRate::sample_and_reset() {
+ const ZStatCounterData bytes_per_sample = _counter.collect_and_reset();
+ const uint64_t bytes_per_second = bytes_per_sample._counter * sample_hz;
+
+ _rate.add(bytes_per_second);
+ _rate_avg.add(_rate.avg());
+
+ return bytes_per_second;
+}
+
+double ZStatAllocRate::avg() {
+ return _rate.avg();
+}
+
+double ZStatAllocRate::avg_sd() {
+ return _rate_avg.sd();
+}
+
+//
+// Stat thread
+//
+ZStat::ZStat() :
+ _metronome(sample_hz) {
+ set_name("ZStat");
+ create_and_start();
+}
+
+void ZStat::sample_and_collect(ZStatSamplerHistory* history) const {
+ // Sample counters
+ for (const ZStatCounter* counter = ZStatCounter::first(); counter != NULL; counter = counter->next()) {
+ counter->sample_and_reset();
+ }
+
+ // Collect samples
+ for (const ZStatSampler* sampler = ZStatSampler::first(); sampler != NULL; sampler = sampler->next()) {
+ ZStatSamplerHistory& sampler_history = history[sampler->id()];
+ sampler_history.add(sampler->collect_and_reset());
+ }
+}
+
+bool ZStat::should_print(LogTargetHandle log) const {
+ return log.is_enabled() && (_metronome.nticks() % ZStatisticsInterval == 0);
+}
+
+void ZStat::print(LogTargetHandle log, const ZStatSamplerHistory* history) const {
+ // Print
+ log.print("=== Garbage Collection Statistics =======================================================================================================================");
+ log.print(" Last 10s Last 10m Last 10h Total");
+ log.print(" Avg / Max Avg / Max Avg / Max Avg / Max");
+
+ for (const ZStatSampler* sampler = ZStatSampler::first(); sampler != NULL; sampler = sampler->next()) {
+ const ZStatSamplerHistory& sampler_history = history[sampler->id()];
+ const ZStatUnitPrinter printer = sampler->printer();
+ printer(log, *sampler, sampler_history);
+ }
+
+ log.print("=========================================================================================================================================================");
+}
+
+void ZStat::run_service() {
+ ZStatSamplerHistory* const history = new ZStatSamplerHistory[ZStatSampler::count()];
+ LogTarget(Info, gc, stats) log;
+
+ // Main loop
+ while (_metronome.wait_for_tick()) {
+ sample_and_collect(history);
+ if (should_print(log)) {
+ print(log, history);
+ }
+ }
+
+ delete [] history;
+}
+
+void ZStat::stop_service() {
+ _metronome.stop();
+}
+
+//
+// Stat table
+//
+class ZStatTablePrinter {
+private:
+ static const size_t _buffer_size = 256;
+
+ const size_t _column0_width;
+ const size_t _columnN_width;
+ char _buffer[_buffer_size];
+
+public:
+ class ZColumn {
+ private:
+ char* const _buffer;
+ const size_t _position;
+ const size_t _width;
+ const size_t _width_next;
+
+ ZColumn next() const {
+ // Insert space between columns
+ _buffer[_position + _width] = ' ';
+ return ZColumn(_buffer, _position + _width + 1, _width_next, _width_next);
+ }
+
+ size_t print(size_t position, const char* fmt, va_list va) {
+ const int res = jio_vsnprintf(_buffer + position, _buffer_size - position, fmt, va);
+ if (res < 0) {
+ return 0;
+ }
+
+ return (size_t)res;
+ }
+
+ public:
+ ZColumn(char* buffer, size_t position, size_t width, size_t width_next) :
+ _buffer(buffer),
+ _position(position),
+ _width(width),
+ _width_next(width_next) {}
+
+ ZColumn left(const char* fmt, ...) ATTRIBUTE_PRINTF(2, 3) {
+ va_list va;
+
+ va_start(va, fmt);
+ const size_t written = print(_position, fmt, va);
+ va_end(va);
+
+ if (written < _width) {
+ // Fill empty space
+ memset(_buffer + _position + written, ' ', _width - written);
+ }
+
+ return next();
+ }
+
+ ZColumn right(const char* fmt, ...) ATTRIBUTE_PRINTF(2, 3) {
+ va_list va;
+
+ va_start(va, fmt);
+ const size_t written = print(_position, fmt, va);
+ va_end(va);
+
+ if (written > _width) {
+ // Line too long
+ return fill('?');
+ }
+
+ if (written < _width) {
+ // Short line, move all to right
+ memmove(_buffer + _position + _width - written, _buffer + _position, written);
+
+ // Fill empty space
+ memset(_buffer + _position, ' ', _width - written);
+ }
+
+ return next();
+ }
+
+ ZColumn center(const char* fmt, ...) ATTRIBUTE_PRINTF(2, 3) {
+ va_list va;
+
+ va_start(va, fmt);
+ const size_t written = print(_position, fmt, va);
+ va_end(va);
+
+ if (written > _width) {
+ // Line too long
+ return fill('?');
+ }
+
+ if (written < _width) {
+ // Short line, move all to center
+ const size_t start_space = (_width - written) / 2;
+ const size_t end_space = _width - written - start_space;
+ memmove(_buffer + _position + start_space, _buffer + _position, written);
+
+ // Fill empty spaces
+ memset(_buffer + _position, ' ', start_space);
+ memset(_buffer + _position + start_space + written, ' ', end_space);
+ }
+
+ return next();
+ }
+
+ ZColumn fill(char filler = ' ') {
+ memset(_buffer + _position, filler, _width);
+ return next();
+ }
+
+ const char* end() {
+ _buffer[_position] = '\0';
+ return _buffer;
+ }
+ };
+
+public:
+ ZStatTablePrinter(size_t column0_width, size_t columnN_width) :
+ _column0_width(column0_width),
+ _columnN_width(columnN_width) {}
+
+ ZColumn operator()() {
+ return ZColumn(_buffer, 0, _column0_width, _columnN_width);
+ }
+};
+
+//
+// Stat cycle
+//
+uint64_t ZStatCycle::_ncycles = 0;
+Ticks ZStatCycle::_start_of_last;
+Ticks ZStatCycle::_end_of_last;
+NumberSeq ZStatCycle::_normalized_duration(0.3 /* alpha */);
+
+void ZStatCycle::at_start() {
+ _start_of_last = Ticks::now();
+}
+
+void ZStatCycle::at_end(double boost_factor) {
+ _end_of_last = Ticks::now();
+ _ncycles++;
+
+ // Calculate normalized cycle duration. The measured duration is
+ // normalized using the boost factor to avoid artificial deflation
+ // of the duration when boost mode is enabled.
+ const double duration = (_end_of_last - _start_of_last).seconds();
+ const double normalized_duration = duration * boost_factor;
+ _normalized_duration.add(normalized_duration);
+}
+
+uint64_t ZStatCycle::ncycles() {
+ return _ncycles;
+}
+
+const AbsSeq& ZStatCycle::normalized_duration() {
+ return _normalized_duration;
+}
+
+double ZStatCycle::time_since_last() {
+ if (_ncycles == 0) {
+ // Return time since VM start-up
+ return os::elapsedTime();
+ }
+
+ const Ticks now = Ticks::now();
+ const Tickspan time_since_last = now - _end_of_last;
+ return time_since_last.seconds();
+}
+
+//
+// Stat load
+//
+void ZStatLoad::print() {
+ double loadavg[3] = {};
+ os::loadavg(loadavg, ARRAY_SIZE(loadavg));
+ log_info(gc, load)("Load: %.2f/%.2f/%.2f", loadavg[0], loadavg[1], loadavg[2]);
+}
+
+//
+// Stat mark
+//
+size_t ZStatMark::_nstripes;
+size_t ZStatMark::_nproactiveflush;
+size_t ZStatMark::_nterminateflush;
+size_t ZStatMark::_ntrycomplete;
+size_t ZStatMark::_ncontinue;
+
+void ZStatMark::set_at_mark_start(size_t nstripes) {
+ _nstripes = nstripes;
+}
+
+void ZStatMark::set_at_mark_end(size_t nproactiveflush,
+ size_t nterminateflush,
+ size_t ntrycomplete,
+ size_t ncontinue) {
+ _nproactiveflush = nproactiveflush;
+ _nterminateflush = nterminateflush;
+ _ntrycomplete = ntrycomplete;
+ _ncontinue = ncontinue;
+}
+
+void ZStatMark::print() {
+ log_info(gc, marking)("Mark: "
+ SIZE_FORMAT " stripe(s), "
+ SIZE_FORMAT " proactive flush(es), "
+ SIZE_FORMAT " terminate flush(es), "
+ SIZE_FORMAT " completion(s), "
+ SIZE_FORMAT " continuation(s) ",
+ _nstripes,
+ _nproactiveflush,
+ _nterminateflush,
+ _ntrycomplete,
+ _ncontinue);
+}
+
+//
+// Stat relocation
+//
+size_t ZStatRelocation::_relocating;
+bool ZStatRelocation::_success;
+
+void ZStatRelocation::set_at_select_relocation_set(size_t relocating) {
+ _relocating = relocating;
+}
+
+void ZStatRelocation::set_at_relocate_end(bool success) {
+ _success = success;
+}
+
+void ZStatRelocation::print() {
+ if (_success) {
+ log_info(gc, reloc)("Relocation: Successful, " SIZE_FORMAT "M relocated", _relocating / M);
+ } else {
+ log_info(gc, reloc)("Relocation: Incomplete");
+ }
+}
+
+//
+// Stat nmethods
+//
+void ZStatNMethods::print() {
+ log_info(gc, nmethod)("NMethods: " SIZE_FORMAT " registered, " SIZE_FORMAT " unregistered",
+ ZNMethodTable::registered_nmethods(),
+ ZNMethodTable::unregistered_nmethods());
+}
+
+//
+// Stat references
+//
+ZStatReferences::ZCount ZStatReferences::_soft;
+ZStatReferences::ZCount ZStatReferences::_weak;
+ZStatReferences::ZCount ZStatReferences::_final;
+ZStatReferences::ZCount ZStatReferences::_phantom;
+
+void ZStatReferences::set(ZCount* count, size_t encountered, size_t discovered, size_t enqueued) {
+ count->encountered = encountered;
+ count->discovered = discovered;
+ count->enqueued = enqueued;
+}
+
+void ZStatReferences::set_soft(size_t encountered, size_t discovered, size_t enqueued) {
+ set(&_soft, encountered, discovered, enqueued);
+}
+
+void ZStatReferences::set_weak(size_t encountered, size_t discovered, size_t enqueued) {
+ set(&_weak, encountered, discovered, enqueued);
+}
+
+void ZStatReferences::set_final(size_t encountered, size_t discovered, size_t enqueued) {
+ set(&_final, encountered, discovered, enqueued);
+}
+
+void ZStatReferences::set_phantom(size_t encountered, size_t discovered, size_t enqueued) {
+ set(&_phantom, encountered, discovered, enqueued);
+}
+
+void ZStatReferences::print(const char* name, const ZStatReferences::ZCount& ref) {
+ log_info(gc, ref)("%s: "
+ SIZE_FORMAT " encountered, "
+ SIZE_FORMAT " discovered, "
+ SIZE_FORMAT " enqueued",
+ name,
+ ref.encountered,
+ ref.discovered,
+ ref.enqueued);
+}
+
+void ZStatReferences::print() {
+ print("Soft", _soft);
+ print("Weak", _weak);
+ print("Final", _final);
+ print("Phantom", _phantom);
+}
+
+//
+// Stat heap
+//
+ZStatHeap::ZAtInitialize ZStatHeap::_at_initialize;
+ZStatHeap::ZAtMarkStart ZStatHeap::_at_mark_start;
+ZStatHeap::ZAtMarkEnd ZStatHeap::_at_mark_end;
+ZStatHeap::ZAtRelocateStart ZStatHeap::_at_relocate_start;
+ZStatHeap::ZAtRelocateEnd ZStatHeap::_at_relocate_end;
+
+#define ZSIZE_NA "%9s", "-"
+#define ZSIZE_ARGS(size) SIZE_FORMAT_W(8) "M (%.0lf%%)", \
+ ((size) / M), (percent_of<size_t>(size, _at_initialize.max_capacity))
+
+size_t ZStatHeap::available(size_t used) {
+ return _at_initialize.max_capacity - used;
+}
+
+size_t ZStatHeap::reserve(size_t used) {
+ return MIN2(_at_initialize.max_reserve, available(used));
+}
+
+size_t ZStatHeap::free(size_t used) {
+ return available(used) - reserve(used);
+}
+
+void ZStatHeap::set_at_initialize(size_t max_capacity,
+ size_t max_reserve) {
+ _at_initialize.max_capacity = max_capacity;
+ _at_initialize.max_reserve = max_reserve;
+}
+
+void ZStatHeap::set_at_mark_start(size_t capacity,
+ size_t used) {
+ _at_mark_start.capacity = capacity;
+ _at_mark_start.reserve = reserve(used);
+ _at_mark_start.used = used;
+ _at_mark_start.free = free(used);
+}
+
+void ZStatHeap::set_at_mark_end(size_t capacity,
+ size_t allocated,
+ size_t used) {
+ _at_mark_end.capacity = capacity;
+ _at_mark_end.reserve = reserve(used);
+ _at_mark_end.allocated = allocated;
+ _at_mark_end.used = used;
+ _at_mark_end.free = free(used);
+}
+
+void ZStatHeap::set_at_select_relocation_set(size_t live,
+ size_t garbage,
+ size_t reclaimed) {
+ _at_mark_end.live = live;
+ _at_mark_end.garbage = garbage;
+
+ _at_relocate_start.garbage = garbage - reclaimed;
+ _at_relocate_start.reclaimed = reclaimed;
+}
+
+void ZStatHeap::set_at_relocate_start(size_t capacity,
+ size_t allocated,
+ size_t used) {
+ _at_relocate_start.capacity = capacity;
+ _at_relocate_start.reserve = reserve(used);
+ _at_relocate_start.allocated = allocated;
+ _at_relocate_start.used = used;
+ _at_relocate_start.free = free(used);
+}
+
+void ZStatHeap::set_at_relocate_end(size_t capacity,
+ size_t allocated,
+ size_t reclaimed,
+ size_t used,
+ size_t used_high,
+ size_t used_low) {
+ _at_relocate_end.capacity = capacity;
+ _at_relocate_end.capacity_high = capacity;
+ _at_relocate_end.capacity_low = _at_mark_start.capacity;
+ _at_relocate_end.reserve = reserve(used);
+ _at_relocate_end.reserve_high = reserve(used_low);
+ _at_relocate_end.reserve_low = reserve(used_high);
+ _at_relocate_end.garbage = _at_mark_end.garbage - reclaimed;
+ _at_relocate_end.allocated = allocated;
+ _at_relocate_end.reclaimed = reclaimed;
+ _at_relocate_end.used = used;
+ _at_relocate_end.used_high = used_high;
+ _at_relocate_end.used_low = used_low;
+ _at_relocate_end.free = free(used);
+ _at_relocate_end.free_high = free(used_low);
+ _at_relocate_end.free_low = free(used_high);
+}
+
+size_t ZStatHeap::max_capacity() {
+ return _at_initialize.max_capacity;
+}
+
+size_t ZStatHeap::used_at_mark_start() {
+ return _at_mark_start.used;
+}
+
+size_t ZStatHeap::used_at_relocate_end() {
+ return _at_relocate_end.used;
+}
+
+void ZStatHeap::print() {
+ ZStatTablePrinter table(10, 18);
+ log_info(gc, heap)("%s", table()
+ .fill()
+ .center("Mark Start")
+ .center("Mark End")
+ .center("Relocate Start")
+ .center("Relocate End")
+ .center("High")
+ .center("Low")
+ .end());
+ log_info(gc, heap)("%s", table()
+ .right("Capacity:")
+ .left(ZSIZE_ARGS(_at_mark_start.capacity))
+ .left(ZSIZE_ARGS(_at_mark_end.capacity))
+ .left(ZSIZE_ARGS(_at_relocate_start.capacity))
+ .left(ZSIZE_ARGS(_at_relocate_end.capacity))
+ .left(ZSIZE_ARGS(_at_relocate_end.capacity_high))
+ .left(ZSIZE_ARGS(_at_relocate_end.capacity_low))
+ .end());
+ log_info(gc, heap)("%s", table()
+ .right("Reserve:")
+ .left(ZSIZE_ARGS(_at_mark_start.reserve))
+ .left(ZSIZE_ARGS(_at_mark_end.reserve))
+ .left(ZSIZE_ARGS(_at_relocate_start.reserve))
+ .left(ZSIZE_ARGS(_at_relocate_end.reserve))
+ .left(ZSIZE_ARGS(_at_relocate_end.reserve_high))
+ .left(ZSIZE_ARGS(_at_relocate_end.reserve_low))
+ .end());
+ log_info(gc, heap)("%s", table()
+ .right("Free:")
+ .left(ZSIZE_ARGS(_at_mark_start.free))
+ .left(ZSIZE_ARGS(_at_mark_end.free))
+ .left(ZSIZE_ARGS(_at_relocate_start.free))
+ .left(ZSIZE_ARGS(_at_relocate_end.free))
+ .left(ZSIZE_ARGS(_at_relocate_end.free_high))
+ .left(ZSIZE_ARGS(_at_relocate_end.free_low))
+ .end());
+ log_info(gc, heap)("%s", table()
+ .right("Used:")
+ .left(ZSIZE_ARGS(_at_mark_start.used))
+ .left(ZSIZE_ARGS(_at_mark_end.used))
+ .left(ZSIZE_ARGS(_at_relocate_start.used))
+ .left(ZSIZE_ARGS(_at_relocate_end.used))
+ .left(ZSIZE_ARGS(_at_relocate_end.used_high))
+ .left(ZSIZE_ARGS(_at_relocate_end.used_low))
+ .end());
+ log_info(gc, heap)("%s", table()
+ .right("Live:")
+ .left(ZSIZE_NA)
+ .left(ZSIZE_ARGS(_at_mark_end.live))
+ .left(ZSIZE_ARGS(_at_mark_end.live /* Same as at mark end */))
+ .left(ZSIZE_ARGS(_at_mark_end.live /* Same as at mark end */))
+ .left(ZSIZE_NA)
+ .left(ZSIZE_NA)
+ .end());
+ log_info(gc, heap)("%s", table()
+ .right("Allocated:")
+ .left(ZSIZE_NA)
+ .left(ZSIZE_ARGS(_at_mark_end.allocated))
+ .left(ZSIZE_ARGS(_at_relocate_start.allocated))
+ .left(ZSIZE_ARGS(_at_relocate_end.allocated))
+ .left(ZSIZE_NA)
+ .left(ZSIZE_NA)
+ .end());
+ log_info(gc, heap)("%s", table()
+ .right("Garbage:")
+ .left(ZSIZE_NA)
+ .left(ZSIZE_ARGS(_at_mark_end.garbage))
+ .left(ZSIZE_ARGS(_at_relocate_start.garbage))
+ .left(ZSIZE_ARGS(_at_relocate_end.garbage))
+ .left(ZSIZE_NA)
+ .left(ZSIZE_NA)
+ .end());
+ log_info(gc, heap)("%s", table()
+ .right("Reclaimed:")
+ .left(ZSIZE_NA)
+ .left(ZSIZE_NA)
+ .left(ZSIZE_ARGS(_at_relocate_start.reclaimed))
+ .left(ZSIZE_ARGS(_at_relocate_end.reclaimed))
+ .left(ZSIZE_NA)
+ .left(ZSIZE_NA)
+ .end());
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zStat.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,519 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZSTAT_HPP
+#define SHARE_GC_Z_ZSTAT_HPP
+
+#include "gc/shared/concurrentGCThread.hpp"
+#include "gc/shared/gcTimer.hpp"
+#include "gc/z/zMetronome.hpp"
+#include "logging/logHandle.hpp"
+#include "memory/allocation.hpp"
+#include "utilities/numberSeq.hpp"
+#include "utilities/ticks.hpp"
+
+class ZPage;
+class ZStatSampler;
+class ZStatSamplerHistory;
+struct ZStatCounterData;
+struct ZStatSamplerData;
+
+//
+// Stat unit printers
+//
+typedef void (*ZStatUnitPrinter)(LogTargetHandle log, const ZStatSampler&, const ZStatSamplerHistory&);
+
+void ZStatUnitTime(LogTargetHandle log, const ZStatSampler& sampler, const ZStatSamplerHistory& history);
+void ZStatUnitBytes(LogTargetHandle log, const ZStatSampler& sampler, const ZStatSamplerHistory& history);
+void ZStatUnitThreads(LogTargetHandle log, const ZStatSampler& sampler, const ZStatSamplerHistory& history);
+void ZStatUnitBytesPerSecond(LogTargetHandle log, const ZStatSampler& sampler, const ZStatSamplerHistory& history);
+void ZStatUnitOpsPerSecond(LogTargetHandle log, const ZStatSampler& sampler, const ZStatSamplerHistory& history);
+
+//
+// Stat value
+//
+class ZStatValue {
+private:
+ static uintptr_t _base;
+ static uint32_t _cpu_offset;
+
+ const char* const _group;
+ const char* const _name;
+ const uint32_t _id;
+ const uint32_t _offset;
+
+protected:
+ ZStatValue(const char* group,
+ const char* name,
+ uint32_t id,
+ uint32_t size);
+
+ template <typename T> T* get_cpu_local(uint32_t cpu) const;
+
+public:
+ static void initialize();
+
+ const char* group() const;
+ const char* name() const;
+ uint32_t id() const;
+};
+
+//
+// Stat iterable value
+//
+template <typename T>
+class ZStatIterableValue : public ZStatValue {
+private:
+ static uint32_t _count;
+ static T* _first;
+
+ T* _next;
+
+ T* insert() const;
+
+protected:
+ ZStatIterableValue(const char* group,
+ const char* name,
+ uint32_t size);
+
+public:
+ static uint32_t count() {
+ return _count;
+ }
+
+ static T* first() {
+ return _first;
+ }
+
+ T* next() const {
+ return _next;
+ }
+};
+
+//
+// Stat sampler
+//
+class ZStatSampler : public ZStatIterableValue<ZStatSampler> {
+private:
+ const ZStatUnitPrinter _printer;
+
+public:
+ ZStatSampler(const char* group,
+ const char* name,
+ ZStatUnitPrinter printer);
+
+ ZStatSamplerData* get() const;
+ ZStatSamplerData collect_and_reset() const;
+
+ ZStatUnitPrinter printer() const;
+};
+
+//
+// Stat counter
+//
+class ZStatCounter : public ZStatIterableValue<ZStatCounter> {
+private:
+ const ZStatSampler _sampler;
+
+public:
+ ZStatCounter(const char* group,
+ const char* name,
+ ZStatUnitPrinter printer);
+
+ ZStatCounterData* get() const;
+ void sample_and_reset() const;
+};
+
+//
+// Stat unsampled counter
+//
+class ZStatUnsampledCounter : public ZStatIterableValue<ZStatUnsampledCounter> {
+public:
+ ZStatUnsampledCounter(const char* name);
+
+ ZStatCounterData* get() const;
+ ZStatCounterData collect_and_reset() const;
+};
+
+//
+// Stat MMU (Mimimum Mutator Utilization)
+//
+class ZStatMMUPause {
+private:
+ double _start;
+ double _end;
+
+public:
+ ZStatMMUPause();
+ ZStatMMUPause(const Ticks& start, const Ticks& end);
+
+ double end() const;
+ double overlap(double start, double end) const;
+};
+
+class ZStatMMU {
+private:
+ static size_t _next;
+ static size_t _npauses;
+ static ZStatMMUPause _pauses[200]; // Record the last 200 pauses
+
+ static double _mmu_2ms;
+ static double _mmu_5ms;
+ static double _mmu_10ms;
+ static double _mmu_20ms;
+ static double _mmu_50ms;
+ static double _mmu_100ms;
+
+ static const ZStatMMUPause& pause(size_t index);
+ static double calculate_mmu(double time_slice);
+
+public:
+ static void register_pause(const Ticks& start, const Ticks& end);
+
+ static void print();
+};
+
+//
+// Stat phases
+//
+class ZStatPhase {
+private:
+ static ConcurrentGCTimer _timer;
+
+protected:
+ const ZStatSampler _sampler;
+
+ ZStatPhase(const char* group, const char* name);
+
+ void log_start(LogTargetHandle log, bool thread = false) const;
+ void log_end(LogTargetHandle log, const Tickspan& duration, bool thread = false) const;
+
+public:
+ static ConcurrentGCTimer* timer();
+
+ const char* name() const;
+
+ virtual void register_start(const Ticks& start) const = 0;
+ virtual void register_end(const Ticks& start, const Ticks& end) const = 0;
+};
+
+class ZStatPhaseCycle : public ZStatPhase {
+public:
+ ZStatPhaseCycle(const char* name);
+
+ virtual void register_start(const Ticks& start) const;
+ virtual void register_end(const Ticks& start, const Ticks& end) const;
+};
+
+class ZStatPhasePause : public ZStatPhase {
+private:
+ static Tickspan _max; // Max pause time
+
+public:
+ ZStatPhasePause(const char* name);
+
+ static const Tickspan& max();
+
+ virtual void register_start(const Ticks& start) const;
+ virtual void register_end(const Ticks& start, const Ticks& end) const;
+};
+
+class ZStatPhaseConcurrent : public ZStatPhase {
+public:
+ ZStatPhaseConcurrent(const char* name);
+
+ virtual void register_start(const Ticks& start) const;
+ virtual void register_end(const Ticks& start, const Ticks& end) const;
+};
+
+class ZStatSubPhase : public ZStatPhase {
+public:
+ ZStatSubPhase(const char* name);
+
+ virtual void register_start(const Ticks& start) const;
+ virtual void register_end(const Ticks& start, const Ticks& end) const;
+};
+
+class ZStatCriticalPhase : public ZStatPhase {
+private:
+ const ZStatCounter _counter;
+ const bool _verbose;
+
+public:
+ ZStatCriticalPhase(const char* name, bool verbose = true);
+
+ virtual void register_start(const Ticks& start) const;
+ virtual void register_end(const Ticks& start, const Ticks& end) const;
+};
+
+//
+// Stat timer
+//
+class ZStatTimer : public StackObj {
+private:
+ const ZStatPhase& _phase;
+ const Ticks _start;
+
+public:
+ ZStatTimer(const ZStatPhase& phase) :
+ _phase(phase),
+ _start(Ticks::now()) {
+ _phase.register_start(_start);
+ }
+
+ ~ZStatTimer() {
+ const Ticks end = Ticks::now();
+ _phase.register_end(_start, end);
+ }
+};
+
+//
+// Stat sample/increment
+//
+void ZStatSample(const ZStatSampler& sampler, uint64_t value, bool trace = ZStatisticsForceTrace);
+void ZStatInc(const ZStatCounter& counter, uint64_t increment = 1, bool trace = ZStatisticsForceTrace);
+void ZStatInc(const ZStatUnsampledCounter& counter, uint64_t increment = 1);
+
+//
+// Stat allocation rate
+//
+class ZStatAllocRate : public AllStatic {
+private:
+ static const ZStatUnsampledCounter _counter;
+ static TruncatedSeq _rate; // B/s
+ static TruncatedSeq _rate_avg; // B/s
+
+public:
+ static const uint64_t sample_window_sec = 1; // seconds
+ static const uint64_t sample_hz = 10;
+
+ static const ZStatUnsampledCounter& counter();
+ static uint64_t sample_and_reset();
+
+ static double avg();
+ static double avg_sd();
+};
+
+//
+// Stat thread
+//
+class ZStat : public ConcurrentGCThread {
+private:
+ static const uint64_t sample_hz = 1;
+
+ ZMetronome _metronome;
+
+ void sample_and_collect(ZStatSamplerHistory* history) const;
+ bool should_print(LogTargetHandle log) const;
+ void print(LogTargetHandle log, const ZStatSamplerHistory* history) const;
+
+protected:
+ virtual void run_service();
+ virtual void stop_service();
+
+public:
+ ZStat();
+};
+
+//
+// Stat cycle
+//
+class ZStatCycle : public AllStatic {
+private:
+ static uint64_t _ncycles;
+ static Ticks _start_of_last;
+ static Ticks _end_of_last;
+ static NumberSeq _normalized_duration;
+
+public:
+ static void at_start();
+ static void at_end(double boost_factor);
+
+ static uint64_t ncycles();
+ static const AbsSeq& normalized_duration();
+ static double time_since_last();
+};
+
+//
+// Stat load
+//
+class ZStatLoad : public AllStatic {
+public:
+ static void print();
+};
+
+//
+// Stat mark
+//
+class ZStatMark : public AllStatic {
+private:
+ static size_t _nstripes;
+ static size_t _nproactiveflush;
+ static size_t _nterminateflush;
+ static size_t _ntrycomplete;
+ static size_t _ncontinue;
+
+public:
+ static void set_at_mark_start(size_t nstripes);
+ static void set_at_mark_end(size_t nproactiveflush,
+ size_t nterminateflush,
+ size_t ntrycomplete,
+ size_t ncontinue);
+
+ static void print();
+};
+
+//
+// Stat relocation
+//
+class ZStatRelocation : public AllStatic {
+private:
+ static size_t _relocating;
+ static bool _success;
+
+public:
+ static void set_at_select_relocation_set(size_t relocating);
+ static void set_at_relocate_end(bool success);
+
+ static void print();
+};
+
+//
+// Stat nmethods
+//
+class ZStatNMethods : public AllStatic {
+public:
+ static void print();
+};
+
+//
+// Stat references
+//
+class ZStatReferences : public AllStatic {
+private:
+ static struct ZCount {
+ size_t encountered;
+ size_t discovered;
+ size_t enqueued;
+ } _soft, _weak, _final, _phantom;
+
+ static void set(ZCount* count, size_t encountered, size_t discovered, size_t enqueued);
+ static void print(const char* name, const ZCount& ref);
+
+public:
+ static void set_soft(size_t encountered, size_t discovered, size_t enqueued);
+ static void set_weak(size_t encountered, size_t discovered, size_t enqueued);
+ static void set_final(size_t encountered, size_t discovered, size_t enqueued);
+ static void set_phantom(size_t encountered, size_t discovered, size_t enqueued);
+
+ static void print();
+};
+
+//
+// Stat heap
+//
+class ZStatHeap : public AllStatic {
+private:
+ static struct ZAtInitialize {
+ size_t max_capacity;
+ size_t max_reserve;
+ } _at_initialize;
+
+ static struct ZAtMarkStart {
+ size_t capacity;
+ size_t reserve;
+ size_t used;
+ size_t free;
+ } _at_mark_start;
+
+ static struct ZAtMarkEnd {
+ size_t capacity;
+ size_t reserve;
+ size_t allocated;
+ size_t used;
+ size_t free;
+ size_t live;
+ size_t garbage;
+ } _at_mark_end;
+
+ static struct ZAtRelocateStart {
+ size_t capacity;
+ size_t reserve;
+ size_t garbage;
+ size_t allocated;
+ size_t reclaimed;
+ size_t used;
+ size_t free;
+ } _at_relocate_start;
+
+ static struct ZAtRelocateEnd {
+ size_t capacity;
+ size_t capacity_high;
+ size_t capacity_low;
+ size_t reserve;
+ size_t reserve_high;
+ size_t reserve_low;
+ size_t garbage;
+ size_t allocated;
+ size_t reclaimed;
+ size_t used;
+ size_t used_high;
+ size_t used_low;
+ size_t free;
+ size_t free_high;
+ size_t free_low;
+ } _at_relocate_end;
+
+ static size_t available(size_t used);
+ static size_t reserve(size_t used);
+ static size_t free(size_t used);
+
+public:
+ static void set_at_initialize(size_t max_capacity,
+ size_t max_reserve);
+ static void set_at_mark_start(size_t capacity,
+ size_t used);
+ static void set_at_mark_end(size_t capacity,
+ size_t allocated,
+ size_t used);
+ static void set_at_select_relocation_set(size_t live,
+ size_t garbage,
+ size_t reclaimed);
+ static void set_at_relocate_start(size_t capacity,
+ size_t allocated,
+ size_t used);
+ static void set_at_relocate_end(size_t capacity,
+ size_t allocated,
+ size_t reclaimed,
+ size_t used,
+ size_t used_high,
+ size_t used_low);
+
+ static size_t max_capacity();
+ static size_t used_at_mark_start();
+ static size_t used_at_relocate_end();
+
+ static void print();
+};
+
+#endif // SHARE_GC_Z_ZSTAT_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zTask.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 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 "gc/z/zTask.hpp"
+#include "gc/z/zThread.hpp"
+
+ZTask::GangTask::GangTask(ZTask* ztask, const char* name) :
+ AbstractGangTask(name),
+ _ztask(ztask) {}
+
+void ZTask::GangTask::work(uint worker_id) {
+ ZThread::set_worker_id(worker_id);
+ _ztask->work();
+ ZThread::clear_worker_id();
+}
+
+ZTask::ZTask(const char* name) :
+ _gang_task(this, name) {}
+
+const char* ZTask::name() const {
+ return _gang_task.name();
+}
+
+AbstractGangTask* ZTask::gang_task() {
+ return &_gang_task;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zTask.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef SHARE_GC_Z_ZTASK_HPP
+#define SHARE_GC_Z_ZTASK_HPP
+
+#include "gc/shared/workgroup.hpp"
+#include "memory/allocation.hpp"
+
+class ZTask : public StackObj {
+private:
+ class GangTask : public AbstractGangTask {
+ private:
+ ZTask* const _ztask;
+
+ public:
+ GangTask(ZTask* ztask, const char* name);
+
+ virtual void work(uint worker_id);
+ };
+
+ GangTask _gang_task;
+
+public:
+ ZTask(const char* name);
+
+ const char* name() const;
+ AbstractGangTask* gang_task();
+
+ virtual void work() = 0;
+};
+
+#endif // SHARE_GC_Z_ZTASK_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zThread.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2015, 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 "gc/z/zThread.hpp"
+#include "runtime/thread.hpp"
+#include "utilities/debug.hpp"
+
+__thread bool ZThread::_initialized;
+__thread uintptr_t ZThread::_id;
+__thread bool ZThread::_is_vm;
+__thread bool ZThread::_is_java;
+__thread bool ZThread::_is_worker;
+__thread uint ZThread::_worker_id;
+
+void ZThread::initialize() {
+ assert(!_initialized, "Already initialized");
+ const Thread* const thread = Thread::current();
+ _initialized = true;
+ _id = (uintptr_t)thread;
+ _is_vm = thread->is_VM_thread();
+ _is_java = thread->is_Java_thread();
+ _is_worker = thread->is_Worker_thread();
+ _worker_id = (uint)-1;
+}
+
+const char* ZThread::name() {
+ const Thread* const thread = Thread::current();
+ if (thread->is_Named_thread()) {
+ const NamedThread* const named = (const NamedThread*)thread;
+ return named->name();
+ } else if (thread->is_Java_thread()) {
+ return "Java";
+ }
+
+ return "Unknown";
+}
+
+bool ZThread::has_worker_id() {
+ return _initialized &&
+ _is_worker &&
+ _worker_id != (uint)-1;
+}
+
+void ZThread::set_worker_id(uint worker_id) {
+ ensure_initialized();
+ assert(!has_worker_id(), "Worker id already initialized");
+ _worker_id = worker_id;
+}
+
+void ZThread::clear_worker_id() {
+ assert(has_worker_id(), "Worker id not initialized");
+ _worker_id = (uint)-1;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zThread.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZTHREAD_HPP
+#define SHARE_GC_Z_ZTHREAD_HPP
+
+#include "memory/allocation.hpp"
+#include "utilities/debug.hpp"
+
+class ZThread : public AllStatic {
+ friend class ZTask;
+
+private:
+ static __thread bool _initialized;
+ static __thread uintptr_t _id;
+ static __thread bool _is_vm;
+ static __thread bool _is_java;
+ static __thread bool _is_worker;
+ static __thread uint _worker_id;
+
+ static void initialize();
+
+ static void ensure_initialized() {
+ if (!_initialized) {
+ initialize();
+ }
+ }
+
+ static bool has_worker_id();
+ static void set_worker_id(uint worker_id);
+ static void clear_worker_id();
+
+public:
+ static const char* name();
+
+ static uintptr_t id() {
+ ensure_initialized();
+ return _id;
+ }
+
+ static bool is_vm() {
+ ensure_initialized();
+ return _is_vm;
+ }
+
+ static bool is_java() {
+ ensure_initialized();
+ return _is_java;
+ }
+
+ static bool is_worker() {
+ ensure_initialized();
+ return _is_worker;
+ }
+
+ static uint worker_id() {
+ assert(has_worker_id(), "Worker id not initialized");
+ return _worker_id;
+ }
+};
+
+#endif // SHARE_GC_Z_ZTHREAD_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zThreadLocalData.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -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_GC_Z_ZTHREADLOCALDATA_HPP
+#define SHARE_GC_Z_ZTHREADLOCALDATA_HPP
+
+#include "gc/z/zMarkStack.hpp"
+#include "runtime/thread.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/sizes.hpp"
+
+class ZThreadLocalData {
+private:
+ uintptr_t _address_bad_mask;
+ ZMarkThreadLocalStacks _stacks;
+
+ ZThreadLocalData() :
+ _address_bad_mask(0),
+ _stacks() {}
+
+ static ZThreadLocalData* data(Thread* thread) {
+ return thread->gc_data<ZThreadLocalData>();
+ }
+
+public:
+ static void create(Thread* thread) {
+ new (data(thread)) ZThreadLocalData();
+ }
+
+ static void destroy(Thread* thread) {
+ data(thread)->~ZThreadLocalData();
+ }
+
+ static void set_address_bad_mask(Thread* thread, uintptr_t mask) {
+ data(thread)->_address_bad_mask = mask;
+ }
+
+ static ZMarkThreadLocalStacks* stacks(Thread* thread) {
+ return &data(thread)->_stacks;
+ }
+
+ static ByteSize address_bad_mask_offset() {
+ return Thread::gc_data_offset() + byte_offset_of(ZThreadLocalData, _address_bad_mask);
+ }
+};
+
+#endif // SHARE_GC_Z_ZTHREADLOCALDATA_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zTracer.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,110 @@
+/*
+ * 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 "gc/z/zStat.hpp"
+#include "gc/z/zTracer.hpp"
+#include "gc/shared/gcId.hpp"
+#include "gc/shared/gcLocker.hpp"
+#include "jfr/jfrEvents.hpp"
+#include "runtime/safepointVerifiers.hpp"
+
+ZTracer* ZTracer::_tracer = NULL;
+
+ZTracer::ZTracer() :
+ GCTracer(Z) {}
+
+void ZTracer::initialize() {
+ _tracer = new (ResourceObj::C_HEAP, mtGC) ZTracer();
+}
+
+void ZTracer::send_stat_counter(uint32_t counter_id, uint64_t increment, uint64_t value) {
+ NoSafepointVerifier nsv(true, !SafepointSynchronize::is_at_safepoint());
+
+ EventZStatisticsCounter e;
+ if (e.should_commit()) {
+ e.set_id(counter_id);
+ e.set_increment(increment);
+ e.set_value(value);
+ e.commit();
+ }
+}
+
+void ZTracer::send_stat_sampler(uint32_t sampler_id, uint64_t value) {
+ NoSafepointVerifier nsv(true, !SafepointSynchronize::is_at_safepoint());
+
+ EventZStatisticsSampler e;
+ if (e.should_commit()) {
+ e.set_id(sampler_id);
+ e.set_value(value);
+ e.commit();
+ }
+}
+
+void ZTracer::send_thread_phase(const char* name, const Ticks& start, const Ticks& end) {
+ NoSafepointVerifier nsv(true, !SafepointSynchronize::is_at_safepoint());
+
+ EventZThreadPhase e(UNTIMED);
+ if (e.should_commit()) {
+ e.set_gcId(GCId::current_or_undefined());
+ e.set_name(name);
+ e.set_starttime(start);
+ e.set_endtime(end);
+ e.commit();
+ }
+}
+
+void ZTracer::send_page_alloc(size_t size, size_t used, size_t free, size_t cache, bool nonblocking, bool noreserve) {
+ NoSafepointVerifier nsv(true, !SafepointSynchronize::is_at_safepoint());
+
+ EventZPageAllocation e;
+ if (e.should_commit()) {
+ e.set_pageSize(size);
+ e.set_usedAfter(used);
+ e.set_freeAfter(free);
+ e.set_inCacheAfter(cache);
+ e.set_nonBlocking(nonblocking);
+ e.set_noReserve(noreserve);
+ e.commit();
+ }
+}
+
+void ZTracer::report_stat_counter(const ZStatCounter& counter, uint64_t increment, uint64_t value) {
+ send_stat_counter(counter.id(), increment, value);
+}
+
+void ZTracer::report_stat_sampler(const ZStatSampler& sampler, uint64_t value) {
+ send_stat_sampler(sampler.id(), value);
+}
+
+void ZTracer::report_thread_phase(const ZStatPhase& phase, const Ticks& start, const Ticks& end) {
+ send_thread_phase(phase.name(), start, end);
+}
+
+void ZTracer::report_thread_phase(const char* name, const Ticks& start, const Ticks& end) {
+ send_thread_phase(name, start, end);
+}
+
+void ZTracer::report_page_alloc(size_t size, size_t used, size_t free, size_t cache, ZAllocationFlags flags) {
+ send_page_alloc(size, used, free, cache, flags.non_blocking(), flags.no_reserve());
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zTracer.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+#ifndef SHARE_GC_Z_ZTRACER_HPP
+#define SHARE_GC_Z_ZTRACER_HPP
+
+#include "gc/shared/gcTrace.hpp"
+#include "gc/z/zAllocationFlags.hpp"
+
+class ZStatCounter;
+class ZStatPhase;
+class ZStatSampler;
+
+class ZTracer : public GCTracer {
+private:
+ static ZTracer* _tracer;
+
+ ZTracer();
+
+ void send_stat_counter(uint32_t counter_id, uint64_t increment, uint64_t value);
+ void send_stat_sampler(uint32_t sampler_id, uint64_t value);
+ void send_thread_phase(const char* name, const Ticks& start, const Ticks& end);
+ void send_page_alloc(size_t size, size_t used, size_t free, size_t cache, bool nonblocking, bool noreserve);
+
+public:
+ static ZTracer* tracer();
+ static void initialize();
+
+ void report_stat_counter(const ZStatCounter& counter, uint64_t increment, uint64_t value);
+ void report_stat_sampler(const ZStatSampler& sampler, uint64_t value);
+ void report_thread_phase(const ZStatPhase& phase, const Ticks& start, const Ticks& end);
+ void report_thread_phase(const char* name, const Ticks& start, const Ticks& end);
+ void report_page_alloc(size_t size, size_t used, size_t free, size_t cache, ZAllocationFlags flags);
+};
+
+class ZTraceThreadPhase : public StackObj {
+private:
+ const Ticks _start;
+ const char* const _name;
+
+public:
+ ZTraceThreadPhase(const char* name);
+ ~ZTraceThreadPhase();
+};
+
+#endif // SHARE_GC_Z_ZTRACER_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zTracer.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+#ifndef SHARE_GC_Z_ZTRACER_INLINE_HPP
+#define SHARE_GC_Z_ZTRACER_INLINE_HPP
+
+#include "gc/z/zTracer.hpp"
+
+inline ZTracer* ZTracer::tracer() {
+ return _tracer;
+}
+
+inline ZTraceThreadPhase::ZTraceThreadPhase(const char* name) :
+ _start(Ticks::now()),
+ _name(name) {}
+
+inline ZTraceThreadPhase::~ZTraceThreadPhase() {
+ ZTracer::tracer()->report_thread_phase(_name, _start, Ticks::now());
+}
+
+#endif // SHARE_GC_Z_ZTRACER_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zUtils.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015, 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 "gc/shared/collectedHeap.hpp"
+#include "gc/z/zAddress.inline.hpp"
+#include "gc/z/zUtils.inline.hpp"
+#include "utilities/debug.hpp"
+
+#include <stdlib.h>
+
+uintptr_t ZUtils::alloc_aligned(size_t alignment, size_t size) {
+ void* res = NULL;
+
+ if (posix_memalign(&res, alignment, size) != 0) {
+ fatal("posix_memalign() failed");
+ }
+
+ memset(res, 0, size);
+
+ return (uintptr_t)res;
+}
+
+void ZUtils::insert_filler_object(uintptr_t addr, size_t size) {
+ const size_t fill_size_in_words = bytes_to_words(size);
+ if (fill_size_in_words >= CollectedHeap::min_fill_size()) {
+ CollectedHeap::fill_with_objects((HeapWord*)ZAddress::good(addr), fill_size_in_words);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zUtils.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZUTILS_HPP
+#define SHARE_GC_Z_ZUTILS_HPP
+
+#include "memory/allocation.hpp"
+
+class ZUtils : public AllStatic {
+public:
+ // Allocation
+ static uintptr_t alloc_aligned(size_t alignment, size_t size);
+
+ // Power of two
+ static size_t round_up_power_of_2(size_t value);
+ static size_t round_down_power_of_2(size_t value);
+
+ // Size convertion
+ static size_t bytes_to_words(size_t size_in_words);
+ static size_t words_to_bytes(size_t size_in_words);
+
+ // Object
+ static size_t object_size(uintptr_t addr);
+ static void object_copy(uintptr_t from, uintptr_t to, size_t size);
+
+ // Filler
+ static void insert_filler_object(uintptr_t addr, size_t size);
+};
+
+#endif // SHARE_GC_Z_ZUTILS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zUtils.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZUTILS_INLINE_HPP
+#define SHARE_GC_Z_ZUTILS_INLINE_HPP
+
+#include "gc/z/zOop.inline.hpp"
+#include "gc/z/zUtils.hpp"
+#include "oops/oop.inline.hpp"
+#include "utilities/align.hpp"
+#include "utilities/copy.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+inline size_t ZUtils::round_up_power_of_2(size_t value) {
+ assert(value != 0, "Invalid value");
+
+ if (is_power_of_2(value)) {
+ return value;
+ }
+
+ return (size_t)1 << (log2_intptr(value) + 1);
+}
+
+inline size_t ZUtils::round_down_power_of_2(size_t value) {
+ assert(value != 0, "Invalid value");
+ return (size_t)1 << log2_intptr(value);
+}
+
+inline size_t ZUtils::bytes_to_words(size_t size_in_bytes) {
+ assert(is_aligned(size_in_bytes, BytesPerWord), "Size not word aligned");
+ return size_in_bytes >> LogBytesPerWord;
+}
+
+inline size_t ZUtils::words_to_bytes(size_t size_in_words) {
+ return size_in_words << LogBytesPerWord;
+}
+
+inline size_t ZUtils::object_size(uintptr_t addr) {
+ return words_to_bytes(ZOop::to_oop(addr)->size());
+}
+
+inline void ZUtils::object_copy(uintptr_t from, uintptr_t to, size_t size) {
+ Copy::aligned_disjoint_words((HeapWord*)from, (HeapWord*)to, bytes_to_words(size));
+}
+
+#endif // SHARE_GC_Z_ZUTILS_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zValue.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,323 @@
+/*
+ * 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_GC_Z_ZVALUE_HPP
+#define SHARE_GC_Z_ZVALUE_HPP
+
+#include "memory/allocation.hpp"
+#include "gc/z/zCPU.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zNUMA.hpp"
+#include "gc/z/zThread.hpp"
+#include "gc/z/zUtils.hpp"
+#include "utilities/align.hpp"
+
+template <typename S>
+class ZValueStorage : public AllStatic {
+private:
+ static uintptr_t _top;
+ static uintptr_t _end;
+
+public:
+ static const size_t offset = 4 * K;
+
+ static uintptr_t alloc(size_t size) {
+ guarantee(size <= offset, "Allocation too large");
+
+ // Allocate entry in existing memory block
+ const uintptr_t addr = align_up(_top, S::alignment());
+ _top = addr + size;
+
+ if (_top < _end) {
+ // Success
+ return addr;
+ }
+
+ // Allocate new block of memory
+ const size_t block_alignment = offset;
+ const size_t block_size = offset * S::count();
+ _top = ZUtils::alloc_aligned(block_alignment, block_size);
+ _end = _top + offset;
+
+ // Retry allocation
+ return alloc(size);
+ }
+};
+
+template <typename T> uintptr_t ZValueStorage<T>::_end = 0;
+template <typename T> uintptr_t ZValueStorage<T>::_top = 0;
+
+class ZContendedStorage : public ZValueStorage<ZContendedStorage> {
+public:
+ static size_t alignment() {
+ return ZCacheLineSize;
+ }
+
+ static uint32_t count() {
+ return 1;
+ }
+
+ static uint32_t id() {
+ return 0;
+ }
+};
+
+class ZPerCPUStorage : public ZValueStorage<ZPerCPUStorage> {
+public:
+ static size_t alignment() {
+ return sizeof(uintptr_t);
+ }
+
+ static uint32_t count() {
+ return ZCPU::count();
+ }
+
+ static uint32_t id() {
+ return ZCPU::id();
+ }
+};
+
+class ZPerNUMAStorage : public ZValueStorage<ZPerNUMAStorage> {
+public:
+ static size_t alignment() {
+ return sizeof(uintptr_t);
+ }
+
+ static uint32_t count() {
+ return ZNUMA::count();
+ }
+
+ static uint32_t id() {
+ return ZNUMA::id();
+ }
+};
+
+class ZPerWorkerStorage : public ZValueStorage<ZPerWorkerStorage> {
+public:
+ static size_t alignment() {
+ return sizeof(uintptr_t);
+ }
+
+ static uint32_t count() {
+ return MAX2(ParallelGCThreads, ConcGCThreads);
+ }
+
+ static uint32_t id() {
+ return ZThread::worker_id();
+ }
+};
+
+template <typename S, typename T>
+class ZValueIterator;
+
+template <typename S, typename T>
+class ZValue {
+private:
+ const uintptr_t _addr;
+
+ uintptr_t value_addr(uint32_t value_id) const {
+ return _addr + (value_id * S::offset);
+ }
+
+public:
+ ZValue() :
+ _addr(S::alloc(sizeof(T))) {
+ // Initialize all instances
+ ZValueIterator<S, T> iter(this);
+ for (T* addr; iter.next(&addr);) {
+ ::new (addr) T;
+ }
+ }
+
+ ZValue(const T& value) :
+ _addr(S::alloc(sizeof(T))) {
+ // Initialize all instances
+ ZValueIterator<S, T> iter(this);
+ for (T* addr; iter.next(&addr);) {
+ ::new (addr) T(value);
+ }
+ }
+
+ // Not implemented
+ ZValue(const ZValue<S, T>& value);
+ ZValue<S, T>& operator=(const ZValue<S, T>& value);
+
+ const T* addr(uint32_t value_id = S::id()) const {
+ return reinterpret_cast<const T*>(value_addr(value_id));
+ }
+
+ T* addr(uint32_t value_id = S::id()) {
+ return reinterpret_cast<T*>(value_addr(value_id));
+ }
+
+ const T& get(uint32_t value_id = S::id()) const {
+ return *addr(value_id);
+ }
+
+ T& get(uint32_t value_id = S::id()) {
+ return *addr(value_id);
+ }
+
+ void set(const T& value, uint32_t value_id = S::id()) {
+ get(value_id) = value;
+ }
+
+ void set_all(const T& value) {
+ ZValueIterator<S, T> iter(this);
+ for (T* addr; iter.next(&addr);) {
+ *addr = value;
+ }
+ }
+};
+
+template <typename T>
+class ZContended : public ZValue<ZContendedStorage, T> {
+public:
+ ZContended() :
+ ZValue<ZContendedStorage, T>() {}
+
+ ZContended(const T& value) :
+ ZValue<ZContendedStorage, T>(value) {}
+
+ using ZValue<ZContendedStorage, T>::operator=;
+};
+
+template <typename T>
+class ZPerCPU : public ZValue<ZPerCPUStorage, T> {
+public:
+ ZPerCPU() :
+ ZValue<ZPerCPUStorage, T>() {}
+
+ ZPerCPU(const T& value) :
+ ZValue<ZPerCPUStorage, T>(value) {}
+
+ using ZValue<ZPerCPUStorage, T>::operator=;
+};
+
+template <typename T>
+class ZPerNUMA : public ZValue<ZPerNUMAStorage, T> {
+public:
+ ZPerNUMA() :
+ ZValue<ZPerNUMAStorage, T>() {}
+
+ ZPerNUMA(const T& value) :
+ ZValue<ZPerNUMAStorage, T>(value) {}
+
+ using ZValue<ZPerNUMAStorage, T>::operator=;
+};
+
+template <typename T>
+class ZPerWorker : public ZValue<ZPerWorkerStorage, T> {
+public:
+ ZPerWorker() :
+ ZValue<ZPerWorkerStorage, T>() {}
+
+ ZPerWorker(const T& value) :
+ ZValue<ZPerWorkerStorage, T>(value) {}
+
+ using ZValue<ZPerWorkerStorage, T>::operator=;
+};
+
+template <typename S, typename T>
+class ZValueIterator {
+private:
+ ZValue<S, T>* const _value;
+ uint32_t _value_id;
+
+public:
+ ZValueIterator(ZValue<S, T>* value) :
+ _value(value),
+ _value_id(0) {}
+
+ bool next(T** value) {
+ if (_value_id < S::count()) {
+ *value = _value->addr(_value_id++);
+ return true;
+ }
+ return false;
+ }
+};
+
+template <typename T>
+class ZPerCPUIterator : public ZValueIterator<ZPerCPUStorage, T> {
+public:
+ ZPerCPUIterator(ZPerCPU<T>* value) :
+ ZValueIterator<ZPerCPUStorage, T>(value) {}
+};
+
+template <typename T>
+class ZPerNUMAIterator : public ZValueIterator<ZPerNUMAStorage, T> {
+public:
+ ZPerNUMAIterator(ZPerNUMA<T>* value) :
+ ZValueIterator<ZPerNUMAStorage, T>(value) {}
+};
+
+template <typename T>
+class ZPerWorkerIterator : public ZValueIterator<ZPerWorkerStorage, T> {
+public:
+ ZPerWorkerIterator(ZPerWorker<T>* value) :
+ ZValueIterator<ZPerWorkerStorage, T>(value) {}
+};
+
+template <typename S, typename T>
+class ZValueConstIterator {
+private:
+ const ZValue<S, T>* const _value;
+ uint32_t _value_id;
+
+public:
+ ZValueConstIterator(const ZValue<S, T>* value) :
+ _value(value),
+ _value_id(0) {}
+
+ bool next(const T** value) {
+ if (_value_id < S::count()) {
+ *value = _value->addr(_value_id++);
+ return true;
+ }
+ return false;
+ }
+};
+
+template <typename T>
+class ZPerCPUConstIterator : public ZValueConstIterator<ZPerCPUStorage, T> {
+public:
+ ZPerCPUConstIterator(const ZPerCPU<T>* value) :
+ ZValueConstIterator<ZPerCPUStorage, T>(value) {}
+};
+
+template <typename T>
+class ZPerNUMAConstIterator : public ZValueConstIterator<ZPerNUMAStorage, T> {
+public:
+ ZPerNUMAConstIterator(const ZPerNUMA<T>* value) :
+ ZValueConstIterator<ZPerNUMAStorage, T>(value) {}
+};
+
+template <typename T>
+class ZPerWorkerConstIterator : public ZValueConstIterator<ZPerWorkerStorage, T> {
+public:
+ ZPerWorkerConstIterator(const ZPerWorker<T>* value) :
+ ZValueConstIterator<ZPerWorkerStorage, T>(value) {}
+};
+
+#endif // SHARE_GC_Z_ZVALUE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zVirtualMemory.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2015, 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 "gc/z/zGlobals.hpp"
+#include "gc/z/zVirtualMemory.inline.hpp"
+#include "services/memTracker.hpp"
+
+ZVirtualMemoryManager::ZVirtualMemoryManager() :
+ _manager(),
+ _initialized(false) {
+ // Reserve address space
+ if (!reserve(ZAddressSpaceStart, ZAddressSpaceSize)) {
+ return;
+ }
+
+ // Make the complete address view free
+ _manager.free(0, ZAddressOffsetMax);
+
+ // Register address space with native memory tracker
+ nmt_reserve(ZAddressSpaceStart, ZAddressSpaceSize);
+
+ // Successfully initialized
+ _initialized = true;
+}
+
+void ZVirtualMemoryManager::nmt_reserve(uintptr_t start, size_t size) {
+ MemTracker::record_virtual_memory_reserve((void*)start, size, CALLER_PC);
+ MemTracker::record_virtual_memory_type((void*)start, mtJavaHeap);
+}
+
+bool ZVirtualMemoryManager::is_initialized() const {
+ return _initialized;
+}
+
+ZVirtualMemory ZVirtualMemoryManager::alloc(size_t size, bool alloc_from_front) {
+ uintptr_t start;
+
+ if (alloc_from_front || size <= ZPageSizeSmall) {
+ // Small page
+ start = _manager.alloc_from_front(size);
+ } else {
+ // Medium/Large page
+ start = _manager.alloc_from_back(size);
+ }
+
+ return ZVirtualMemory(start, size);
+}
+
+void ZVirtualMemoryManager::free(ZVirtualMemory vmem) {
+ _manager.free(vmem.start(), vmem.size());
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zVirtualMemory.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,66 @@
+/*
+ * 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_GC_Z_ZVIRTUALMEMORY_HPP
+#define SHARE_GC_Z_ZVIRTUALMEMORY_HPP
+
+#include "gc/z/zMemory.hpp"
+#include "memory/allocation.hpp"
+
+class ZVirtualMemory {
+ friend class VMStructs;
+
+private:
+ uintptr_t _start;
+ uintptr_t _end;
+
+public:
+ ZVirtualMemory();
+ ZVirtualMemory(uintptr_t start, size_t size);
+
+ bool is_null() const;
+ uintptr_t start() const;
+ uintptr_t end() const;
+ size_t size() const;
+ ZVirtualMemory split(size_t size);
+ void clear();
+};
+
+class ZVirtualMemoryManager {
+private:
+ ZMemoryManager _manager;
+ bool _initialized;
+
+ bool reserve(uintptr_t start, size_t size);
+ void nmt_reserve(uintptr_t start, size_t size);
+
+public:
+ ZVirtualMemoryManager();
+
+ bool is_initialized() const;
+
+ ZVirtualMemory alloc(size_t size, bool alloc_from_front = false);
+ void free(ZVirtualMemory vmem);
+};
+
+#endif // SHARE_GC_Z_ZVIRTUALMEMORY_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zVirtualMemory.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZVIRTUALMEMORY_INLINE_HPP
+#define SHARE_GC_Z_ZVIRTUALMEMORY_INLINE_HPP
+
+#include "gc/z/zMemory.inline.hpp"
+#include "gc/z/zVirtualMemory.hpp"
+
+inline ZVirtualMemory::ZVirtualMemory() :
+ _start(UINTPTR_MAX),
+ _end(UINTPTR_MAX) {}
+
+inline ZVirtualMemory::ZVirtualMemory(uintptr_t start, size_t size) :
+ _start(start),
+ _end(start + size) {}
+
+inline bool ZVirtualMemory::is_null() const {
+ return _start == UINTPTR_MAX;
+}
+
+inline uintptr_t ZVirtualMemory::start() const {
+ return _start;
+}
+
+inline uintptr_t ZVirtualMemory::end() const {
+ return _end;
+}
+
+inline size_t ZVirtualMemory::size() const {
+ return _end - _start;
+}
+
+inline ZVirtualMemory ZVirtualMemory::split(size_t split_size) {
+ assert(split_size <= size(), "precondition");
+ ZVirtualMemory mem(_start, split_size);
+ _start += split_size;
+ return mem;
+}
+
+inline void ZVirtualMemory::clear() {
+ _start = UINTPTR_MAX;
+ _end = UINTPTR_MAX;
+}
+
+#endif // SHARE_GC_Z_ZVIRTUALMEMORY_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zWeakRootsProcessor.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,74 @@
+/*
+ * 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 "gc/z/zHeap.inline.hpp"
+#include "gc/z/zOopClosures.inline.hpp"
+#include "gc/z/zStat.hpp"
+#include "gc/z/zTask.hpp"
+#include "gc/z/zThread.hpp"
+#include "runtime/jniHandles.hpp"
+
+ZWeakRootsProcessor::ZWeakRootsProcessor(ZWorkers* workers) :
+ _workers(workers) {}
+
+class ZProcessWeakRootsTask : public ZTask {
+private:
+ ZWeakRootsIterator _weak_roots;
+
+public:
+ ZProcessWeakRootsTask() :
+ ZTask("ZProcessWeakRootsTask"),
+ _weak_roots() {}
+
+ virtual void work() {
+ ZPhantomIsAliveObjectClosure is_alive;
+ ZPhantomKeepAliveOopClosure keep_alive;
+ _weak_roots.weak_oops_do(&is_alive, &keep_alive);
+ }
+};
+
+void ZWeakRootsProcessor::process_weak_roots() {
+ ZProcessWeakRootsTask task;
+ _workers->run_parallel(&task);
+}
+
+class ZProcessConcurrentWeakRootsTask : public ZTask {
+private:
+ ZConcurrentWeakRootsIterator _concurrent_weak_roots;
+
+public:
+ ZProcessConcurrentWeakRootsTask() :
+ ZTask("ZProcessConccurentWeakRootsTask"),
+ _concurrent_weak_roots() {}
+
+ virtual void work() {
+ ZPhantomCleanOopClosure cl;
+ _concurrent_weak_roots.oops_do(&cl);
+ }
+};
+
+void ZWeakRootsProcessor::process_concurrent_weak_roots() {
+ ZProcessConcurrentWeakRootsTask task;
+ _workers->run_concurrent(&task);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zWeakRootsProcessor.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,42 @@
+/*
+ * 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
+ * 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_Z_ZWEAKROOTSPROCESSOR_HPP
+#define SHARE_GC_Z_ZWEAKROOTSPROCESSOR_HPP
+
+#include "gc/z/zValue.hpp"
+
+class ZWorkers;
+
+class ZWeakRootsProcessor {
+private:
+ ZWorkers* const _workers;
+
+public:
+ ZWeakRootsProcessor(ZWorkers* workers);
+
+ void process_weak_roots();
+ void process_concurrent_weak_roots();
+};
+
+#endif // SHARE_GC_Z_ZWEAKROOTSPROCESSOR_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zWorkers.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2015, 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 "gc/z/zTask.hpp"
+#include "gc/z/zWorkers.inline.hpp"
+#include "runtime/os.hpp"
+#include "runtime/mutexLocker.hpp"
+#include "runtime/safepoint.hpp"
+
+uint ZWorkers::calculate_ncpus(double share_in_percent) {
+ return ceil(os::initial_active_processor_count() * share_in_percent / 100.0);
+}
+
+uint ZWorkers::calculate_nparallel() {
+ // Use 60% of the CPUs, rounded up. We would like to use as many threads as
+ // possible to increase parallelism. However, using a thread count that is
+ // close to the number of processors tends to lead to over-provisioning and
+ // scheduling latency issues. Using 60% of the active processors appears to
+ // be a fairly good balance.
+ return calculate_ncpus(60.0);
+}
+
+uint ZWorkers::calculate_nconcurrent() {
+ // Use 12.5% of the CPUs, rounded up. The number of concurrent threads we
+ // would like to use heavily depends on the type of workload we are running.
+ // Using too many threads will have a nagative impact on the application
+ // throughput, while using too few threads will prolong the GC-cycle and
+ // we then risk being out-run by the application. Using 12.5% of the active
+ // processors appears to be a fairly good balance.
+ return calculate_ncpus(12.5);
+}
+
+class ZWorkersWarmupTask : public ZTask {
+private:
+ const uint _nworkers;
+ uint _started;
+ Monitor _monitor;
+
+public:
+ ZWorkersWarmupTask(uint nworkers) :
+ ZTask("ZWorkersWarmupTask"),
+ _nworkers(nworkers),
+ _started(0),
+ _monitor(Monitor::leaf, "ZWorkersWarmup", false, Monitor::_safepoint_check_never) {}
+
+ virtual void work() {
+ // Wait for all threads to start
+ MonitorLockerEx ml(&_monitor, Monitor::_no_safepoint_check_flag);
+ if (++_started == _nworkers) {
+ // All threads started
+ ml.notify_all();
+ } else {
+ while (_started != _nworkers) {
+ ml.wait(Monitor::_no_safepoint_check_flag);
+ }
+ }
+ }
+};
+
+ZWorkers::ZWorkers() :
+ _boost(false),
+ _workers("ZWorker",
+ nworkers(),
+ true /* are_GC_task_threads */,
+ true /* are_ConcurrentGC_threads */) {
+
+ log_info(gc, init)("Workers: %u parallel, %u concurrent", nparallel(), nconcurrent());
+
+ // Initialize worker threads
+ _workers.initialize_workers();
+ _workers.update_active_workers(nworkers());
+ if (_workers.active_workers() != nworkers()) {
+ vm_exit_during_initialization("Failed to create ZWorkers");
+ }
+
+ // Warm up worker threads by having them execute a dummy task.
+ // This helps reduce latency in early GC pauses, which otherwise
+ // would have to take on any warmup costs.
+ ZWorkersWarmupTask task(nworkers());
+ run(&task, nworkers());
+}
+
+void ZWorkers::set_boost(bool boost) {
+ if (boost) {
+ log_debug(gc)("Boosting workers");
+ }
+
+ _boost = boost;
+}
+
+void ZWorkers::run(ZTask* task, uint nworkers) {
+ log_debug(gc, task)("Executing Task: %s, Active Workers: %u", task->name(), nworkers);
+ _workers.update_active_workers(nworkers);
+ _workers.run_task(task->gang_task());
+}
+
+void ZWorkers::run_parallel(ZTask* task) {
+ assert(SafepointSynchronize::is_at_safepoint(), "Should be at a safepoint");
+ run(task, nparallel());
+}
+
+void ZWorkers::run_concurrent(ZTask* task) {
+ run(task, nconcurrent());
+}
+
+void ZWorkers::threads_do(ThreadClosure* tc) const {
+ _workers.threads_do(tc);
+}
+
+void ZWorkers::print_threads_on(outputStream* st) const {
+ _workers.print_worker_threads_on(st);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zWorkers.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZWORKERS_HPP
+#define SHARE_GC_Z_ZWORKERS_HPP
+
+#include "gc/shared/workgroup.hpp"
+#include "memory/allocation.hpp"
+
+class ZTask;
+
+class ZWorkers {
+private:
+ bool _boost;
+ WorkGang _workers;
+
+ static uint calculate_ncpus(double share_in_percent);
+
+ void run(ZTask* task, uint nworkers);
+
+public:
+ static uint calculate_nparallel();
+ static uint calculate_nconcurrent();
+
+ ZWorkers();
+
+ uint nparallel() const;
+ uint nparallel_no_boost() const;
+ uint nconcurrent() const;
+ uint nconcurrent_no_boost() const;
+ uint nworkers() const;
+
+ void set_boost(bool boost);
+
+ void run_parallel(ZTask* task);
+ void run_concurrent(ZTask* task);
+
+ void threads_do(ThreadClosure* tc) const;
+ void print_threads_on(outputStream* st) const;
+};
+
+#endif // SHARE_GC_Z_ZWORKERS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zWorkers.inline.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_ZWORKERS_INLINE_HPP
+#define SHARE_GC_Z_ZWORKERS_INLINE_HPP
+
+#include "gc/z/zWorkers.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+inline uint ZWorkers::nparallel() const {
+ return _boost ? nworkers() : nparallel_no_boost();
+}
+
+inline uint ZWorkers::nparallel_no_boost() const {
+ return ParallelGCThreads;
+}
+
+inline uint ZWorkers::nconcurrent() const {
+ return _boost ? nworkers() : nconcurrent_no_boost();
+}
+
+inline uint ZWorkers::nconcurrent_no_boost() const {
+ return ConcGCThreads;
+}
+
+inline uint ZWorkers::nworkers() const {
+ return MAX2(ParallelGCThreads, ConcGCThreads);
+}
+
+#endif // SHARE_GC_Z_ZWORKERS_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/z_globals.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,103 @@
+/*
+ * 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_Z_Z_GLOBALS_HPP
+#define SHARE_GC_Z_Z_GLOBALS_HPP
+
+#define GC_Z_FLAGS(develop, \
+ develop_pd, \
+ product, \
+ product_pd, \
+ diagnostic, \
+ diagnostic_pd, \
+ experimental, \
+ notproduct, \
+ manageable, \
+ product_rw, \
+ lp64_product, \
+ range, \
+ constraint, \
+ writeable) \
+ \
+ product(ccstr, ZPath, NULL, \
+ "Filesystem path for Java heap backing storage " \
+ "(must be a tmpfs or a hugetlbfs filesystem)") \
+ \
+ product(double, ZAllocationSpikeTolerance, 2.0, \
+ "Allocation spike tolerance factor") \
+ \
+ product(double, ZFragmentationLimit, 25.0, \
+ "Maximum allowed heap fragmentation") \
+ \
+ product(bool, ZStallOnOutOfMemory, true, \
+ "Allow Java threads to stall and wait for GC to complete " \
+ "instead of immediately throwing an OutOfMemoryError") \
+ \
+ product(size_t, ZMarkStacksMax, NOT_LP64(512*M) LP64_ONLY(8*G), \
+ "Maximum number of bytes allocated for marking stacks") \
+ range(32*M, NOT_LP64(512*M) LP64_ONLY(1024*G)) \
+ \
+ product(uint, ZCollectionInterval, 0, \
+ "Force GC at a fixed time interval (in seconds)") \
+ \
+ product(uint, ZStatisticsInterval, 10, \
+ "Time between statistics print outs (in seconds)") \
+ range(1, (uint)-1) \
+ \
+ diagnostic(bool, ZStatisticsForceTrace, false, \
+ "Force tracing of ZStats") \
+ \
+ diagnostic(bool, ZProactive, true, \
+ "Enable proactive GC cycles") \
+ \
+ diagnostic(bool, ZUnmapBadViews, false, \
+ "Unmap bad (inactive) heap views") \
+ \
+ diagnostic(bool, ZVerifyMarking, false, \
+ "Verify marking stacks") \
+ \
+ diagnostic(bool, ZVerifyForwarding, false, \
+ "Verify forwarding tables") \
+ \
+ diagnostic(bool, ZSymbolTableUnloading, false, \
+ "Unload unused VM symbols") \
+ \
+ diagnostic(bool, ZWeakRoots, true, \
+ "Treat JNI WeakGlobalRefs and StringTable as weak roots") \
+ \
+ diagnostic(bool, ZConcurrentStringTable, true, \
+ "Clean StringTable concurrently") \
+ \
+ diagnostic(bool, ZConcurrentVMWeakHandles, true, \
+ "Clean VM WeakHandles concurrently") \
+ \
+ diagnostic(bool, ZConcurrentJNIWeakGlobalHandles, true, \
+ "Clean JNI WeakGlobalRefs concurrently") \
+ \
+ diagnostic(bool, ZOptimizeLoadBarriers, true, \
+ "Apply load barrier optimizations") \
+ \
+ develop(bool, ZVerifyLoadBarriers, false, \
+ "Verify that reference loads are followed by barriers")
+
+#endif // SHARE_GC_Z_Z_GLOBALS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/z_specialized_oop_closures.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#ifndef SHARE_GC_Z_Z_SPECIALIZED_OOP_CLOSURES_HPP
+#define SHARE_GC_Z_Z_SPECIALIZED_OOP_CLOSURES_HPP
+
+class ZLoadBarrierOopClosure;
+template <bool> class ZMarkBarrierOopClosure;
+
+#define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_Z(f) \
+ f(ZLoadBarrierOopClosure,_nv) \
+ f(ZMarkBarrierOopClosure<true>,_nv) \
+ f(ZMarkBarrierOopClosure<false>,_nv)
+
+#endif // SHARE_GC_Z_Z_SPECIALIZED_OOP_CLOSURES_HPP
--- a/src/hotspot/share/jfr/metadata/metadata.xml Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/jfr/metadata/metadata.xml Wed Jun 13 11:01:25 2018 -0700
@@ -885,6 +885,39 @@
<Field type="uint" name="newRatio" label="New Ratio" description="The size of the young generation relative to the tenured generation" />
</Event>
+ <Event name="ZPageAllocation" category="Java Application" label="ZPage Allocation" description="Allocation of a ZPage" thread="true" stackTrace="false">
+ <Field type="ulong" contentType="bytes" name="pageSize" label="Page Size" />
+ <Field type="ulong" contentType="bytes" name="usedAfter" label="Used After" />
+ <Field type="ulong" contentType="bytes" name="freeAfter" label="Free After" />
+ <Field type="ulong" contentType="bytes" name="inCacheAfter" label="In Cache After" />
+ <Field type="boolean" name="nonBlocking" label="Non-blocking" />
+ <Field type="boolean" name="noReserve" label="No Reserve" />
+ </Event>
+
+ <Event name="ZThreadPhase" category="Java Virtual Machine, GC, Detailed" label="ZGC Thread Phase" thread="true">
+ <Field type="uint" name="gcId" label="GC Identifier" relation="GcId"/>
+ <Field type="string" name="name" label="Name" />
+ </Event>
+
+ <Event name="ZStatisticsCounter" category="Java Virtual Machine, GC, Detailed" label="Z Statistics Counter" thread="true">
+ <Field type="ZStatisticsCounterType" name="id" label="Id" />
+ <Field type="ulong" name="increment" label="Increment" />
+ <Field type="ulong" name="value" label="Value" />
+ </Event>
+
+ <Event name="ZStatisticsSampler" category="Java Virtual Machine, GC, Detailed" label="Z Statistics Sampler" thread="true">
+ <Field type="ZStatisticsSamplerType" name="id" label="Id" />
+ <Field type="ulong" name="value" label="Value" />
+ </Event>
+
+ <Type name="ZStatisticsCounterType" label="Z Statistics Counter">
+ <Field type="string" name="counter" label="Counter" />
+ </Type>
+
+ <Type name="ZStatisticsSamplerType" label="Z Statistics Sampler">
+ <Field type="string" name="sampler" label="Sampler" />
+ </Type>
+
<Type name="Thread" label="Thread">
<Field type="string" name="osName" label="OS Thread Name" />
<Field type="long" name="osThreadId" label="OS Thread Id" />
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -59,6 +59,9 @@
#include "gc/g1/g1HeapRegionTraceType.hpp"
#include "gc/g1/g1YCTypes.hpp"
#endif
+#if INCLUDE_ZGC
+#include "gc/z/zStat.hpp"
+#endif
// implementation for the static registration function exposed in the api
bool JfrSerializer::register_serializer(JfrTypeId id, bool require_safepoint, bool permit_cache, JfrSerializer* cs) {
@@ -346,3 +349,27 @@
writer.write(thread_group_id);
JfrThreadGroup::serialize(&writer, thread_group_id);
}
+
+void ZStatisticsCounterTypeConstant::serialize(JfrCheckpointWriter& writer) {
+#if INCLUDE_ZGC
+ writer.write_count(ZStatCounter::count());
+ for (ZStatCounter* counter = ZStatCounter::first(); counter != NULL; counter = counter->next()) {
+ writer.write_key(counter->id());
+ writer.write(counter->name());
+ }
+#else
+ writer.write_count(0);
+#endif
+}
+
+void ZStatisticsSamplerTypeConstant::serialize(JfrCheckpointWriter& writer) {
+#if INCLUDE_ZGC
+ writer.write_count(ZStatSampler::count());
+ for (ZStatSampler* sampler = ZStatSampler::first(); sampler != NULL; sampler = sampler->next()) {
+ writer.write_key(sampler->id());
+ writer.write(sampler->name());
+ }
+#else
+ writer.write_count(0);
+#endif
+}
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -135,4 +135,14 @@
void serialize(JfrCheckpointWriter& writer);
};
+class ZStatisticsCounterTypeConstant : public JfrSerializer {
+ public:
+ void serialize(JfrCheckpointWriter& writer);
+};
+
+class ZStatisticsSamplerTypeConstant : public JfrSerializer {
+ public:
+ void serialize(JfrCheckpointWriter& writer);
+};
+
#endif // SHARE_VM_JFR_CHECKPOINT_CONSTANT_JFRCONSTANT_HPP
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeManager.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeManager.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -195,7 +195,7 @@
bool JfrTypeManager::initialize() {
// register non-safepointing type serialization
- for (size_t i = 0; i < 16; ++i) {
+ for (size_t i = 0; i < 18; ++i) {
switch (i) {
case 0: register_serializer(TYPE_FLAGVALUEORIGIN, false, true, new FlagValueOriginConstant()); break;
case 1: register_serializer(TYPE_INFLATECAUSE, false, true, new MonitorInflateCauseConstant()); break;
@@ -213,6 +213,8 @@
case 13: register_serializer(TYPE_CODEBLOBTYPE, false, true, new CodeBlobTypeConstant()); break;
case 14: register_serializer(TYPE_VMOPERATIONTYPE, false, true, new VMOperationTypeConstant()); break;
case 15: register_serializer(TYPE_THREADSTATE, false, true, new ThreadStateConstant()); break;
+ case 16: register_serializer(TYPE_ZSTATISTICSCOUNTERTYPE, false, true, new ZStatisticsCounterTypeConstant()); break;
+ case 17: register_serializer(TYPE_ZSTATISTICSSAMPLERTYPE, false, true, new ZStatisticsSamplerTypeConstant()); break;
default:
guarantee(false, "invariant");
}
--- a/src/hotspot/share/logging/logPrefix.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/logging/logPrefix.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -62,9 +62,11 @@
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, humongous)) \
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ihop)) \
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, liveness)) \
+ LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, load)) \
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, marking)) \
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, metaspace)) \
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, mmu)) \
+ LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, nmethod)) \
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, phases)) \
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, phases, ref)) \
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, phases, start)) \
@@ -75,6 +77,7 @@
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, remset, tracking)) \
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ref)) \
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ref, start)) \
+ LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, reloc)) \
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, start)) \
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, stringtable)) \
LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, sweep)) \
--- a/src/hotspot/share/logging/logTag.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/logging/logTag.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -62,6 +62,7 @@
LOG_TAG(datacreation) \
LOG_TAG(decoder) \
LOG_TAG(defaultmethods) \
+ LOG_TAG(director) \
LOG_TAG(dump) \
LOG_TAG(ergo) \
LOG_TAG(exceptions) \
@@ -105,6 +106,7 @@
LOG_TAG(obsolete) \
LOG_TAG(oom) \
LOG_TAG(oopmap) \
+ LOG_TAG(oops) \
LOG_TAG(oopstorage) \
LOG_TAG(os) \
LOG_TAG(pagesize) \
@@ -121,6 +123,7 @@
LOG_TAG(redefine) \
LOG_TAG(refine) \
LOG_TAG(region) \
+ LOG_TAG(reloc) \
LOG_TAG(remset) \
LOG_TAG(purge) \
LOG_TAG(resolve) \
--- a/src/hotspot/share/memory/metaspace.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/memory/metaspace.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -229,6 +229,7 @@
// Manages the metaspace portion belonging to a class loader
class ClassLoaderMetaspace : public CHeapObj<mtClass> {
friend class CollectedHeap; // For expand_and_allocate()
+ friend class ZCollectedHeap; // For expand_and_allocate()
friend class Metaspace;
friend class MetaspaceUtils;
friend class metaspace::PrintCLDMetaspaceInfoClosure;
--- a/src/hotspot/share/memory/metaspaceShared.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/memory/metaspaceShared.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -1910,6 +1910,11 @@
return archived_oop;
}
+oop MetaspaceShared::materialize_archived_object(oop obj) {
+ assert(obj != NULL, "sanity");
+ return G1CollectedHeap::heap()->materialize_archived_object(obj);
+}
+
void MetaspaceShared::archive_klass_objects(Thread* THREAD) {
int i;
for (i = 0; i < _global_klass_objects->length(); i++) {
@@ -1980,7 +1985,7 @@
"Archived heap object is not allowed");
assert(MetaspaceShared::open_archive_heap_region_mapped(),
"Open archive heap region is not mapped");
- RootAccess<IN_ARCHIVE_ROOT>::oop_store(p, CompressedOops::decode_not_null(o));
+ *p = CompressedOops::decode_not_null(o);
}
}
--- a/src/hotspot/share/memory/metaspaceShared.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/memory/metaspaceShared.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -111,6 +111,7 @@
}
static oop find_archived_heap_object(oop obj);
static oop archive_heap_object(oop obj, Thread* THREAD);
+ static oop materialize_archived_object(oop obj);
static void archive_klass_objects(Thread* THREAD);
#endif
--- a/src/hotspot/share/oops/access.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/oops/access.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -379,8 +379,7 @@
(location_decorators ^ IN_ROOT) == 0 ||
(location_decorators ^ IN_HEAP) == 0 ||
(location_decorators ^ (IN_HEAP | IN_HEAP_ARRAY)) == 0 ||
- (location_decorators ^ (IN_ROOT | IN_CONCURRENT_ROOT)) == 0 ||
- (location_decorators ^ (IN_ROOT | IN_ARCHIVE_ROOT)) == 0
+ (location_decorators ^ (IN_ROOT | IN_CONCURRENT_ROOT)) == 0
));
}
--- a/src/hotspot/share/oops/accessDecorators.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/oops/accessDecorators.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -192,10 +192,8 @@
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;
+ IN_ROOT | IN_CONCURRENT_ROOT;
// == Value Decorators ==
// * OOP_NOT_NULL: This property can make certain barriers faster such as compressing oops.
@@ -245,9 +243,7 @@
((IN_HEAP_ARRAY & barrier_strength_default) != 0 ? IN_HEAP : INTERNAL_EMPTY);
static const DecoratorSet conc_root_is_root = heap_array_is_in_heap |
((IN_CONCURRENT_ROOT & heap_array_is_in_heap) != 0 ? IN_ROOT : INTERNAL_EMPTY);
- static const DecoratorSet archive_root_is_root = conc_root_is_root |
- ((IN_ARCHIVE_ROOT & conc_root_is_root) != 0 ? IN_ROOT : INTERNAL_EMPTY);
- static const DecoratorSet value = archive_root_is_root | BT_BUILDTIME_DECORATORS;
+ static const DecoratorSet value = conc_root_is_root | BT_BUILDTIME_DECORATORS;
};
// This function implements the above DecoratorFixup rules, but without meta
@@ -268,9 +264,7 @@
((IN_HEAP_ARRAY & barrier_strength_default) != 0 ? IN_HEAP : INTERNAL_EMPTY);
DecoratorSet conc_root_is_root = heap_array_is_in_heap |
((IN_CONCURRENT_ROOT & heap_array_is_in_heap) != 0 ? IN_ROOT : INTERNAL_EMPTY);
- DecoratorSet archive_root_is_root = conc_root_is_root |
- ((IN_ARCHIVE_ROOT & conc_root_is_root) != 0 ? IN_ROOT : INTERNAL_EMPTY);
- DecoratorSet value = archive_root_is_root | BT_BUILDTIME_DECORATORS;
+ DecoratorSet value = conc_root_is_root | BT_BUILDTIME_DECORATORS;
return value;
}
}
--- a/src/hotspot/share/oops/cpCache.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/oops/cpCache.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -32,6 +32,7 @@
#include "logging/log.hpp"
#include "memory/metadataFactory.hpp"
#include "memory/metaspaceClosure.hpp"
+#include "memory/metaspaceShared.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "oops/access.inline.hpp"
@@ -743,16 +744,15 @@
#if INCLUDE_CDS_JAVA_HEAP
oop ConstantPoolCache::archived_references() {
- // Loading an archive root forces the oop to become strongly reachable.
- // For example, if it is loaded during concurrent marking in a SATB
- // collector, it will be enqueued to the SATB queue, effectively
- // shading the previously white object gray.
- return RootAccess<IN_ARCHIVE_ROOT>::oop_load(&_archived_references);
+ if (CompressedOops::is_null(_archived_references)) {
+ return NULL;
+ }
+ return MetaspaceShared::materialize_archived_object(CompressedOops::decode_not_null(_archived_references));
}
void ConstantPoolCache::set_archived_references(oop o) {
assert(DumpSharedSpaces, "called only during runtime");
- RootAccess<IN_ARCHIVE_ROOT>::oop_store(&_archived_references, o);
+ _archived_references = CompressedOops::encode(o);
}
#endif
--- a/src/hotspot/share/oops/klass.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/oops/klass.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -529,20 +529,19 @@
Handle module_handle(THREAD, ((module_entry != NULL) ? module_entry->module() : (oop)NULL));
if (this->has_raw_archived_mirror()) {
+ ResourceMark rm;
log_debug(cds, mirror)("%s has raw archived mirror", external_name());
if (MetaspaceShared::open_archive_heap_region_mapped()) {
- oop m = archived_java_mirror();
- log_debug(cds, mirror)("Archived mirror is: " PTR_FORMAT, p2i(m));
- if (m != NULL) {
- // mirror is archived, restore
- assert(MetaspaceShared::is_archive_object(m), "must be archived mirror object");
- Handle m_h(THREAD, m);
- java_lang_Class::restore_archived_mirror(this, m_h, loader, module_handle, protection_domain, CHECK);
+ bool present = java_lang_Class::restore_archived_mirror(this, loader, module_handle,
+ protection_domain,
+ CHECK);
+ if (present) {
return;
}
}
// No archived mirror data
+ log_debug(cds, mirror)("No archived mirror data for %s", external_name());
_java_mirror = NULL;
this->clear_has_raw_archived_mirror();
}
@@ -558,18 +557,10 @@
#if INCLUDE_CDS_JAVA_HEAP
// Used at CDS dump time to access the archived mirror. No GC barrier.
oop Klass::archived_java_mirror_raw() {
- assert(DumpSharedSpaces, "called only during runtime");
assert(has_raw_archived_mirror(), "must have raw archived mirror");
return CompressedOops::decode(_archived_mirror);
}
-// Used at CDS runtime to get the archived mirror from shared class. Uses GC barrier.
-oop Klass::archived_java_mirror() {
- assert(UseSharedSpaces, "UseSharedSpaces expected.");
- assert(has_raw_archived_mirror(), "must have raw archived mirror");
- return RootAccess<IN_ARCHIVE_ROOT>::oop_load(&_archived_mirror);
-}
-
// No GC barrier
void Klass::set_archived_java_mirror_raw(oop m) {
assert(DumpSharedSpaces, "called only during runtime");
--- a/src/hotspot/share/oops/klass.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/oops/klass.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -244,7 +244,6 @@
void set_java_mirror(Handle m);
oop archived_java_mirror_raw() NOT_CDS_JAVA_HEAP_RETURN_(NULL); // no GC barrier
- oop archived_java_mirror() NOT_CDS_JAVA_HEAP_RETURN_(NULL); // accessor with GC barrier
void set_archived_java_mirror_raw(oop m) NOT_CDS_JAVA_HEAP_RETURN; // no GC barrier
// Temporary mirror switch used by RedefineClasses
--- a/src/hotspot/share/opto/classes.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/opto/classes.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -47,11 +47,17 @@
#include "opto/rootnode.hpp"
#include "opto/subnode.hpp"
#include "opto/vectornode.hpp"
+#include "utilities/macros.hpp"
+#if INCLUDE_ZGC
+#include "gc/z/c2/zBarrierSetC2.hpp"
+#endif
// ----------------------------------------------------------------------------
// Build a table of virtual functions to map from Nodes to dense integer
// opcode names.
int Node::Opcode() const { return Op_Node; }
#define macro(x) int x##Node::Opcode() const { return Op_##x; }
+#define optionalmacro(x)
#include "classes.hpp"
#undef macro
+#undef optionalmacro
--- a/src/hotspot/share/opto/classes.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/opto/classes.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -22,6 +22,8 @@
*
*/
+#include "utilities/macros.hpp"
+
// The giant table of Node classes.
// One entry per class, sorted by class name.
@@ -186,6 +188,14 @@
macro(LoadN)
macro(LoadRange)
macro(LoadS)
+#if INCLUDE_ZGC
+#define zgcmacro(x) macro(x)
+#else
+#define zgcmacro(x) optionalmacro(x)
+#endif
+zgcmacro(LoadBarrier)
+zgcmacro(LoadBarrierSlowReg)
+zgcmacro(LoadBarrierWeakSlowReg)
macro(Lock)
macro(Loop)
macro(LoopLimit)
--- a/src/hotspot/share/opto/compile.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/opto/compile.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -75,9 +75,13 @@
#include "runtime/timer.hpp"
#include "utilities/align.hpp"
#include "utilities/copy.hpp"
+#include "utilities/macros.hpp"
#if INCLUDE_G1GC
#include "gc/g1/g1ThreadLocalData.hpp"
#endif // INCLUDE_G1GC
+#if INCLUDE_ZGC
+#include "gc/z/c2/zBarrierSetC2.hpp"
+#endif
// -------------------- Compile::mach_constant_base_node -----------------------
@@ -2163,6 +2167,11 @@
#endif
+#ifdef ASSERT
+ BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
+ bs->verify_gc_barriers(true);
+#endif
+
ResourceMark rm;
int loop_opts_cnt;
@@ -2335,6 +2344,12 @@
}
}
+#if INCLUDE_ZGC
+ if (UseZGC) {
+ ZBarrierSetC2::find_dominating_barriers(igvn);
+ }
+#endif
+
if (failing()) return;
// Ensure that major progress is now clear
@@ -2361,6 +2376,7 @@
{
TracePhase tp("macroExpand", &timers[_t_macroExpand]);
PhaseMacroExpand mex(igvn);
+ print_method(PHASE_BEFORE_MACRO_EXPANSION, 2);
if (mex.expand_macro_nodes()) {
assert(failing(), "must bail out w/ explicit message");
return;
@@ -2890,6 +2906,10 @@
case Op_LoadL_unaligned:
case Op_LoadPLocked:
case Op_LoadP:
+#if INCLUDE_ZGC
+ case Op_LoadBarrierSlowReg:
+ case Op_LoadBarrierWeakSlowReg:
+#endif
case Op_LoadN:
case Op_LoadRange:
case Op_LoadS: {
--- a/src/hotspot/share/opto/compile.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/opto/compile.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -54,6 +54,7 @@
class ConnectionGraph;
class InlineTree;
class Int_Array;
+class LoadBarrierNode;
class Matcher;
class MachConstantNode;
class MachConstantBaseNode;
@@ -359,9 +360,6 @@
const char* _stub_name; // Name of stub or adapter being compiled, or NULL
address _stub_entry_point; // Compile code entry for generated stub, or NULL
- // For GC
- void* _barrier_set_state;
-
// Control of this compilation.
int _num_loop_opts; // Number of iterations for doing loop optimiztions
int _max_inline_size; // Max inline size for this compilation
@@ -410,6 +408,7 @@
// Compilation environment.
Arena _comp_arena; // Arena with lifetime equivalent to Compile
+ void* _barrier_set_state; // Potential GC barrier state for Compile
ciEnv* _env; // CI interface
DirectiveSet* _directive; // Compiler directive
CompileLog* _log; // from CompilerThread
--- a/src/hotspot/share/opto/escape.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/opto/escape.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -38,9 +38,13 @@
#include "opto/phaseX.hpp"
#include "opto/movenode.hpp"
#include "opto/rootnode.hpp"
+#include "utilities/macros.hpp"
#if INCLUDE_G1GC
#include "gc/g1/g1ThreadLocalData.hpp"
#endif // INCLUDE_G1GC
+#if INCLUDE_ZGC
+#include "gc/z/c2/zBarrierSetC2.hpp"
+#endif
ConnectionGraph::ConnectionGraph(Compile * C, PhaseIterGVN *igvn) :
_nodes(C->comp_arena(), C->unique(), C->unique(), NULL),
@@ -449,6 +453,10 @@
break;
}
case Op_LoadP:
+#if INCLUDE_ZGC
+ case Op_LoadBarrierSlowReg:
+ case Op_LoadBarrierWeakSlowReg:
+#endif
case Op_LoadN:
case Op_LoadPLocked: {
add_objload_to_connection_graph(n, delayed_worklist);
@@ -483,6 +491,13 @@
add_local_var_and_edge(n, PointsToNode::NoEscape,
n->in(0), delayed_worklist);
}
+#if INCLUDE_ZGC
+ else if (UseZGC) {
+ if (n->as_Proj()->_con == LoadBarrierNode::Oop && n->in(0)->is_LoadBarrier()) {
+ add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(0)->in(LoadBarrierNode::Oop), delayed_worklist);
+ }
+ }
+#endif
break;
}
case Op_Rethrow: // Exception object escapes
@@ -651,6 +666,10 @@
break;
}
case Op_LoadP:
+#if INCLUDE_ZGC
+ case Op_LoadBarrierSlowReg:
+ case Op_LoadBarrierWeakSlowReg:
+#endif
case Op_LoadN:
case Op_LoadPLocked: {
// Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
@@ -690,6 +709,14 @@
add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(0), NULL);
break;
}
+#if INCLUDE_ZGC
+ else if (UseZGC) {
+ if (n->as_Proj()->_con == LoadBarrierNode::Oop && n->in(0)->is_LoadBarrier()) {
+ add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(0)->in(LoadBarrierNode::Oop), NULL);
+ break;
+ }
+ }
+#endif
ELSE_FAIL("Op_Proj");
}
case Op_Rethrow: // Exception object escapes
@@ -3163,7 +3190,8 @@
op == Op_CastP2X || op == Op_StoreCM ||
op == Op_FastLock || op == Op_AryEq || op == Op_StrComp || op == Op_HasNegatives ||
op == Op_StrCompressedCopy || op == Op_StrInflatedCopy ||
- op == Op_StrEquals || op == Op_StrIndexOf || op == Op_StrIndexOfChar)) {
+ op == Op_StrEquals || op == Op_StrIndexOf || op == Op_StrIndexOfChar ||
+ BarrierSet::barrier_set()->barrier_set_c2()->is_gc_barrier_node(use))) {
n->dump();
use->dump();
assert(false, "EA: missing allocation reference path");
--- a/src/hotspot/share/opto/idealKit.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/opto/idealKit.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -488,13 +488,13 @@
//----------------------------- make_call ----------------------------
// Trivial runtime call
-void IdealKit::make_leaf_call(const TypeFunc *slow_call_type,
- address slow_call,
- const char *leaf_name,
- Node* parm0,
- Node* parm1,
- Node* parm2,
- Node* parm3) {
+Node* IdealKit::make_leaf_call(const TypeFunc *slow_call_type,
+ address slow_call,
+ const char *leaf_name,
+ Node* parm0,
+ Node* parm1,
+ Node* parm2,
+ Node* parm3) {
// We only handle taking in RawMem and modifying RawMem
const TypePtr* adr_type = TypeRawPtr::BOTTOM;
@@ -532,6 +532,12 @@
assert(C->alias_type(call->adr_type()) == C->alias_type(adr_type),
"call node must be constructed correctly");
+ Node* res = NULL;
+ if (slow_call_type->range()->cnt() > TypeFunc::Parms) {
+ assert(slow_call_type->range()->cnt() == TypeFunc::Parms+1, "only one return value");
+ res = transform(new ProjNode(call, TypeFunc::Parms));
+ }
+ return res;
}
void IdealKit::make_leaf_call_no_fp(const TypeFunc *slow_call_type,
--- a/src/hotspot/share/opto/idealKit.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/opto/idealKit.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -242,13 +242,13 @@
int adr_idx);
// Trivial call
- void make_leaf_call(const TypeFunc *slow_call_type,
- address slow_call,
- const char *leaf_name,
- Node* parm0,
- Node* parm1 = NULL,
- Node* parm2 = NULL,
- Node* parm3 = NULL);
+ Node* make_leaf_call(const TypeFunc *slow_call_type,
+ address slow_call,
+ const char *leaf_name,
+ Node* parm0,
+ Node* parm1 = NULL,
+ Node* parm2 = NULL,
+ Node* parm3 = NULL);
void make_leaf_call_no_fp(const TypeFunc *slow_call_type,
address slow_call,
--- a/src/hotspot/share/opto/lcm.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/opto/lcm.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -169,6 +169,8 @@
case Op_LoadI:
case Op_LoadL:
case Op_LoadP:
+ case Op_LoadBarrierSlowReg:
+ case Op_LoadBarrierWeakSlowReg:
case Op_LoadN:
case Op_LoadS:
case Op_LoadKlass:
--- a/src/hotspot/share/opto/loopnode.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/opto/loopnode.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -25,6 +25,8 @@
#include "precompiled.hpp"
#include "ci/ciMethodData.hpp"
#include "compiler/compileLog.hpp"
+#include "gc/shared/barrierSet.hpp"
+#include "gc/shared/c2/barrierSetC2.hpp"
#include "libadt/vectset.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
@@ -213,7 +215,8 @@
if (nb_ctl_proj > 1) {
break;
}
- assert(parent_ctl->is_Start() || parent_ctl->is_MemBar() || parent_ctl->is_Call(), "unexpected node");
+ assert(parent_ctl->is_Start() || parent_ctl->is_MemBar() || parent_ctl->is_Call() ||
+ BarrierSet::barrier_set()->barrier_set_c2()->is_gc_barrier_node(parent_ctl), "unexpected node");
assert(idom(ctl) == parent_ctl, "strange");
next = idom(parent_ctl);
}
@@ -2635,7 +2638,7 @@
//----------------------------build_and_optimize-------------------------------
// Create a PhaseLoop. Build the ideal Loop tree. Map each Ideal Node to
// its corresponding LoopNode. If 'optimize' is true, do some loop cleanups.
-void PhaseIdealLoop::build_and_optimize(bool do_split_ifs, bool skip_loop_opts) {
+void PhaseIdealLoop::build_and_optimize(bool do_split_ifs, bool skip_loop_opts, bool last_round) {
ResourceMark rm;
int old_progress = C->major_progress();
@@ -2877,8 +2880,11 @@
// that require basic-block info (like cloning through Phi's)
if( SplitIfBlocks && do_split_ifs ) {
visited.Clear();
- split_if_with_blocks( visited, nstack );
+ split_if_with_blocks( visited, nstack, last_round );
NOT_PRODUCT( if( VerifyLoopOptimizations ) verify(); );
+ if (last_round) {
+ C->set_major_progress();
+ }
}
if (!C->major_progress() && do_expensive_nodes && process_expensive_nodes()) {
@@ -4131,6 +4137,8 @@
case Op_LoadL:
case Op_LoadS:
case Op_LoadP:
+ case Op_LoadBarrierSlowReg:
+ case Op_LoadBarrierWeakSlowReg:
case Op_LoadN:
case Op_LoadRange:
case Op_LoadD_unaligned:
--- a/src/hotspot/share/opto/loopnode.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/opto/loopnode.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -912,7 +912,7 @@
}
// build the loop tree and perform any requested optimizations
- void build_and_optimize(bool do_split_if, bool skip_loop_opts);
+ void build_and_optimize(bool do_split_if, bool skip_loop_opts, bool last_round = false);
// Dominators for the sea of nodes
void Dominators();
@@ -922,13 +922,13 @@
Node *dom_lca_internal( Node *n1, Node *n2 ) const;
// Compute the Ideal Node to Loop mapping
- PhaseIdealLoop( PhaseIterGVN &igvn, bool do_split_ifs, bool skip_loop_opts = false) :
+ PhaseIdealLoop( PhaseIterGVN &igvn, bool do_split_ifs, bool skip_loop_opts = false, bool last_round = false) :
PhaseTransform(Ideal_Loop),
_igvn(igvn),
_dom_lca_tags(arena()), // Thread::resource_area
_verify_me(NULL),
_verify_only(false) {
- build_and_optimize(do_split_ifs, skip_loop_opts);
+ build_and_optimize(do_split_ifs, skip_loop_opts, last_round);
}
// Verify that verify_me made the same decisions as a fresh run.
@@ -1227,9 +1227,9 @@
// Check for aggressive application of 'split-if' optimization,
// using basic block level info.
- void split_if_with_blocks ( VectorSet &visited, Node_Stack &nstack );
+ void split_if_with_blocks ( VectorSet &visited, Node_Stack &nstack, bool last_round );
Node *split_if_with_blocks_pre ( Node *n );
- void split_if_with_blocks_post( Node *n );
+ void split_if_with_blocks_post( Node *n, bool last_round );
Node *has_local_phi_input( Node *n );
// Mark an IfNode as being dominated by a prior test,
// without actually altering the CFG (and hence IDOM info).
--- a/src/hotspot/share/opto/loopopts.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/opto/loopopts.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -40,6 +40,10 @@
#include "opto/opaquenode.hpp"
#include "opto/rootnode.hpp"
#include "opto/subnode.hpp"
+#include "utilities/macros.hpp"
+#if INCLUDE_ZGC
+#include "gc/z/c2/zBarrierSetC2.hpp"
+#endif
//=============================================================================
//------------------------------split_thru_phi---------------------------------
@@ -1126,11 +1130,11 @@
// Do the real work in a non-recursive function. CFG hackery wants to be
// in the post-order, so it can dirty the I-DOM info and not use the dirtied
// info.
-void PhaseIdealLoop::split_if_with_blocks_post(Node *n) {
+void PhaseIdealLoop::split_if_with_blocks_post(Node *n, bool last_round) {
// Cloning Cmp through Phi's involves the split-if transform.
// FastLock is not used by an If
- if (n->is_Cmp() && !n->is_FastLock()) {
+ if (n->is_Cmp() && !n->is_FastLock() && !last_round) {
Node *n_ctrl = get_ctrl(n);
// Determine if the Node has inputs from some local Phi.
// Returns the block to clone thru.
@@ -1377,12 +1381,18 @@
get_loop(get_ctrl(n)) == get_loop(get_ctrl(n->in(1))) ) {
_igvn.replace_node( n, n->in(1) );
}
+
+#if INCLUDE_ZGC
+ if (UseZGC) {
+ ZBarrierSetC2::loop_optimize_gc_barrier(this, n, last_round);
+ }
+#endif
}
//------------------------------split_if_with_blocks---------------------------
// Check for aggressive application of 'split-if' optimization,
// using basic block level info.
-void PhaseIdealLoop::split_if_with_blocks( VectorSet &visited, Node_Stack &nstack ) {
+void PhaseIdealLoop::split_if_with_blocks(VectorSet &visited, Node_Stack &nstack, bool last_round) {
Node *n = C->root();
visited.set(n->_idx); // first, mark node as visited
// Do pre-visit work for root
@@ -1407,7 +1417,7 @@
// All of n's children have been processed, complete post-processing.
if (cnt != 0 && !n->is_Con()) {
assert(has_node(n), "no dead nodes");
- split_if_with_blocks_post( n );
+ split_if_with_blocks_post( n, last_round );
}
if (nstack.is_empty()) {
// Finished all nodes on stack.
@@ -1743,6 +1753,23 @@
}
}
+static void clone_outer_loop_helper(Node* n, const IdealLoopTree *loop, const IdealLoopTree* outer_loop,
+ const Node_List &old_new, Unique_Node_List& wq, PhaseIdealLoop* phase,
+ bool check_old_new) {
+ for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
+ Node* u = n->fast_out(j);
+ assert(check_old_new || old_new[u->_idx] == NULL, "shouldn't have been cloned");
+ if (!u->is_CFG() && (!check_old_new || old_new[u->_idx] == NULL)) {
+ Node* c = phase->get_ctrl(u);
+ IdealLoopTree* u_loop = phase->get_loop(c);
+ assert(!loop->is_member(u_loop), "can be in outer loop or out of both loops only");
+ if (outer_loop->is_member(u_loop)) {
+ wq.push(u);
+ }
+ }
+ }
+}
+
void PhaseIdealLoop::clone_outer_loop(LoopNode* head, CloneLoopMode mode, IdealLoopTree *loop,
IdealLoopTree* outer_loop, int dd, Node_List &old_new,
Node_List& extra_data_nodes) {
@@ -1847,6 +1874,22 @@
_igvn.register_new_node_with_optimizer(new_sfpt);
_igvn.register_new_node_with_optimizer(new_cle_out);
}
+ // Some other transformation may have pessimistically assign some
+ // data nodes to the outer loop. Set their control so they are out
+ // of the outer loop.
+ ResourceMark rm;
+ Unique_Node_List wq;
+ for (uint i = 0; i < extra_data_nodes.size(); i++) {
+ Node* old = extra_data_nodes.at(i);
+ clone_outer_loop_helper(old, loop, outer_loop, old_new, wq, this, true);
+ }
+ Node* new_ctrl = cl->outer_loop_exit();
+ assert(get_loop(new_ctrl) != outer_loop, "must be out of the loop nest");
+ for (uint i = 0; i < wq.size(); i++) {
+ Node* n = wq.at(i);
+ set_ctrl(n, new_ctrl);
+ clone_outer_loop_helper(n, loop, outer_loop, old_new, wq, this, false);
+ }
} else {
Node *newhead = old_new[loop->_head->_idx];
set_idom(newhead, newhead->in(LoopNode::EntryControl), dd);
@@ -1947,7 +1990,7 @@
}
ResourceArea *area = Thread::current()->resource_area();
- Node_List extra_data_nodes(area);
+ Node_List extra_data_nodes(area); // data nodes in the outer strip mined loop
clone_outer_loop(head, mode, loop, outer_loop, dd, old_new, extra_data_nodes);
// Step 3: Now fix control uses. Loop varying control uses have already
--- a/src/hotspot/share/opto/macro.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/opto/macro.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -2574,7 +2574,9 @@
assert(n->Opcode() == Op_LoopLimit ||
n->Opcode() == Op_Opaque1 ||
n->Opcode() == Op_Opaque2 ||
- n->Opcode() == Op_Opaque3, "unknown node type in macro list");
+ n->Opcode() == Op_Opaque3 ||
+ BarrierSet::barrier_set()->barrier_set_c2()->is_gc_barrier_node(n),
+ "unknown node type in macro list");
}
assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count");
progress = progress || success;
@@ -2656,7 +2658,7 @@
while (macro_idx >= 0) {
Node * n = C->macro_node(macro_idx);
assert(n->is_macro(), "only macro nodes expected here");
- if (_igvn.type(n) == Type::TOP || n->in(0)->is_top() ) {
+ if (_igvn.type(n) == Type::TOP || (n->in(0) != NULL && n->in(0)->is_top())) {
// node is unreachable, so don't try to expand it
C->remove_macro_node(n);
} else if (n->is_ArrayCopy()){
@@ -2674,7 +2676,7 @@
int macro_count = C->macro_count();
Node * n = C->macro_node(macro_count-1);
assert(n->is_macro(), "only macro nodes expected here");
- if (_igvn.type(n) == Type::TOP || n->in(0)->is_top() ) {
+ if (_igvn.type(n) == Type::TOP || (n->in(0) != NULL && n->in(0)->is_top())) {
// node is unreachable, so don't try to expand it
C->remove_macro_node(n);
continue;
--- a/src/hotspot/share/opto/matcher.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/opto/matcher.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -41,6 +41,9 @@
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
#include "utilities/align.hpp"
+#if INCLUDE_ZGC
+#include "gc/z/zBarrierSetRuntime.hpp"
+#endif // INCLUDE_ZGC
OptoReg::Name OptoReg::c_frame_pointer;
@@ -2062,6 +2065,7 @@
mstack.set_state(Post_Visit);
set_visited(n); // Flag as visited now
bool mem_op = false;
+ int mem_addr_idx = MemNode::Address;
switch( nop ) { // Handle some opcodes special
case Op_Phi: // Treat Phis as shared roots
@@ -2150,6 +2154,17 @@
case Op_SafePoint:
mem_op = true;
break;
+#if INCLUDE_ZGC
+ case Op_CallLeaf:
+ if (UseZGC) {
+ if (n->as_Call()->entry_point() == ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr() ||
+ n->as_Call()->entry_point() == ZBarrierSetRuntime::load_barrier_on_weak_oop_field_preloaded_addr()) {
+ mem_op = true;
+ mem_addr_idx = TypeFunc::Parms+1;
+ }
+ break;
+ }
+#endif
default:
if( n->is_Store() ) {
// Do match stores, despite no ideal reg
@@ -2199,7 +2214,7 @@
#endif
// Clone addressing expressions as they are "free" in memory access instructions
- if (mem_op && i == MemNode::Address && mop == Op_AddP &&
+ if (mem_op && i == mem_addr_idx && mop == Op_AddP &&
// When there are other uses besides address expressions
// put it on stack and mark as shared.
!is_visited(m)) {
--- a/src/hotspot/share/opto/memnode.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/opto/memnode.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -44,7 +44,11 @@
#include "opto/regmask.hpp"
#include "utilities/align.hpp"
#include "utilities/copy.hpp"
+#include "utilities/macros.hpp"
#include "utilities/vmError.hpp"
+#if INCLUDE_ZGC
+#include "gc/z/c2/zBarrierSetC2.hpp"
+#endif
// Portions of code courtesy of Clifford Click
@@ -891,6 +895,14 @@
// a load node that reads from the source array so we may be able to
// optimize out the ArrayCopy node later.
Node* LoadNode::can_see_arraycopy_value(Node* st, PhaseGVN* phase) const {
+#if INCLUDE_ZGC
+ if (UseZGC) {
+ if (bottom_type()->make_oopptr() != NULL) {
+ return NULL;
+ }
+ }
+#endif
+
Node* ld_adr = in(MemNode::Address);
intptr_t ld_off = 0;
AllocateNode* ld_alloc = AllocateNode::Ideal_allocation(ld_adr, phase, ld_off);
@@ -1574,7 +1586,7 @@
// Is there a dominating load that loads the same value? Leave
// anything that is not a load of a field/array element (like
// barriers etc.) alone
- if (in(0) != NULL && adr_type() != TypeRawPtr::BOTTOM && can_reshape) {
+ if (in(0) != NULL && !adr_type()->isa_rawptr() && can_reshape) {
for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) {
Node *use = mem->fast_out(i);
if (use != this &&
@@ -2968,6 +2980,16 @@
return NULL;
}
+#if INCLUDE_ZGC
+ if (UseZGC) {
+ if (req() == (Precedent+1) && in(MemBarNode::Precedent)->in(0) != NULL && in(MemBarNode::Precedent)->in(0)->is_LoadBarrier()) {
+ Node* load_node = in(MemBarNode::Precedent)->in(0)->in(LoadBarrierNode::Oop);
+ set_req(MemBarNode::Precedent, load_node);
+ return this;
+ }
+ }
+#endif
+
bool progress = false;
// Eliminate volatile MemBars for scalar replaced objects.
if (can_reshape && req() == (Precedent+1)) {
--- a/src/hotspot/share/opto/node.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/opto/node.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -1130,7 +1130,7 @@
if (this->is_Store()) {
// Condition for back-to-back stores folding.
return n->Opcode() == op && n->in(MemNode::Memory) == this;
- } else if (this->is_Load() || this->is_DecodeN()) {
+ } else if (this->is_Load() || this->is_DecodeN() || this->is_Phi()) {
// Condition for removing an unused LoadNode or DecodeNNode from the MemBarAcquire precedence input
return n->Opcode() == Op_MemBarAcquire;
} else if (op == Op_AddL) {
--- a/src/hotspot/share/opto/node.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/opto/node.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -80,6 +80,9 @@
class JumpNode;
class JumpProjNode;
class LoadNode;
+class LoadBarrierNode;
+class LoadBarrierSlowRegNode;
+class LoadBarrierWeakSlowRegNode;
class LoadStoreNode;
class LockNode;
class LoopNode;
@@ -634,6 +637,7 @@
DEFINE_CLASS_ID(MemBar, Multi, 3)
DEFINE_CLASS_ID(Initialize, MemBar, 0)
DEFINE_CLASS_ID(MemBarStoreStore, MemBar, 1)
+ DEFINE_CLASS_ID(LoadBarrier, Multi, 4)
DEFINE_CLASS_ID(Mach, Node, 1)
DEFINE_CLASS_ID(MachReturn, Mach, 0)
@@ -680,6 +684,8 @@
DEFINE_CLASS_ID(Mem, Node, 4)
DEFINE_CLASS_ID(Load, Mem, 0)
DEFINE_CLASS_ID(LoadVector, Load, 0)
+ DEFINE_CLASS_ID(LoadBarrierSlowReg, Load, 1)
+ DEFINE_CLASS_ID(LoadBarrierWeakSlowReg, Load, 2)
DEFINE_CLASS_ID(Store, Mem, 1)
DEFINE_CLASS_ID(StoreVector, Store, 0)
DEFINE_CLASS_ID(LoadStore, Mem, 2)
@@ -819,6 +825,9 @@
DEFINE_CLASS_QUERY(JumpProj)
DEFINE_CLASS_QUERY(Load)
DEFINE_CLASS_QUERY(LoadStore)
+ DEFINE_CLASS_QUERY(LoadBarrier)
+ DEFINE_CLASS_QUERY(LoadBarrierSlowReg)
+ DEFINE_CLASS_QUERY(LoadBarrierWeakSlowReg)
DEFINE_CLASS_QUERY(Lock)
DEFINE_CLASS_QUERY(Loop)
DEFINE_CLASS_QUERY(Mach)
--- a/src/hotspot/share/opto/opcodes.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/opto/opcodes.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -28,6 +28,7 @@
// Build a table of class names as strings. Used both for debugging printouts
// and in the ADL machine descriptions.
#define macro(x) #x,
+#define optionalmacro(x) macro(x)
const char *NodeClassNames[] = {
"Node",
"Set",
@@ -48,3 +49,4 @@
"_last_class_name",
};
#undef macro
+#undef optionalmacro
--- a/src/hotspot/share/opto/opcodes.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/opto/opcodes.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -27,6 +27,7 @@
// Build a big enum of class names to give them dense integer indices
#define macro(x) Op_##x,
+#define optionalmacro(x) macro(x)
enum Opcodes {
Op_Node = 0,
macro(Set) // Instruction selection match rule
@@ -47,6 +48,7 @@
_last_opcode
};
#undef macro
+#undef optionalmacro
// Table of names, indexed by Opcode
extern const char *NodeClassNames[];
--- a/src/hotspot/share/opto/phasetype.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/opto/phasetype.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -52,6 +52,7 @@
PHASE_MATCHING,
PHASE_INCREMENTAL_INLINE,
PHASE_INCREMENTAL_BOXING_INLINE,
+ PHASE_BEFORE_MACRO_EXPANSION,
PHASE_END,
PHASE_FAILURE,
@@ -88,6 +89,7 @@
case PHASE_MATCHING: return "After matching";
case PHASE_INCREMENTAL_INLINE: return "Incremental Inline";
case PHASE_INCREMENTAL_BOXING_INLINE: return "Incremental Boxing Inline";
+ case PHASE_BEFORE_MACRO_EXPANSION: return "Before macro expansion";
case PHASE_END: return "End";
case PHASE_FAILURE: return "Failure";
default:
--- a/src/hotspot/share/opto/vectornode.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/opto/vectornode.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -252,6 +252,8 @@
case Op_LoadI: case Op_LoadL:
case Op_LoadF: case Op_LoadD:
case Op_LoadP: case Op_LoadN:
+ case Op_LoadBarrierSlowReg:
+ case Op_LoadBarrierWeakSlowReg:
*start = 0;
*end = 0; // no vector operands
break;
--- a/src/hotspot/share/prims/jvmti.xml Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/prims/jvmti.xml Wed Jun 13 11:01:25 2018 -0700
@@ -1799,10 +1799,10 @@
<function id="StopThread" num="7">
<synopsis>Stop Thread</synopsis>
<description>
- Send the specified asynchronous exception to the specified thread
- (similar to <code>java.lang.Thread.stop</code>).
+ Send the specified asynchronous exception to the specified thread.
Normally, this function is used to kill the specified thread with an
- instance of the exception <code>ThreadDeath</code>.
+ instance of the exception <code>ThreadDeath</code>, similar to
+ <code>java.lang.Thread.stop</code>.
</description>
<origin>jvmdi</origin>
<capabilities>
--- a/src/hotspot/share/prims/jvmtiTagMap.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/prims/jvmtiTagMap.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -59,6 +59,9 @@
#include "runtime/vmThread.hpp"
#include "runtime/vm_operations.hpp"
#include "utilities/macros.hpp"
+#if INCLUDE_ZGC
+#include "gc/z/zGlobals.hpp"
+#endif
// JvmtiTagHashmapEntry
//
@@ -178,6 +181,8 @@
// hash a given key (oop) with the specified size
static unsigned int hash(oop key, int size) {
+ ZGC_ONLY(assert(ZAddressMetadataShift >= sizeof(unsigned int) * BitsPerByte, "cast removes the metadata bits");)
+
// shift right to get better distribution (as these bits will be zero
// with aligned addresses)
unsigned int addr = (unsigned int)(cast_from_oop<intptr_t>(key));
--- a/src/hotspot/share/prims/whitebox.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/prims/whitebox.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -347,7 +347,12 @@
ParallelScavengeHeap* psh = ParallelScavengeHeap::heap();
return !psh->is_in_young(p);
}
-#endif // INCLUDE_PARALLELGC
+#endif
+#if INCLUDE_ZGC
+ if (UseZGC) {
+ return Universe::heap()->is_in(p);
+ }
+#endif
GenCollectedHeap* gch = GenCollectedHeap::heap();
return !gch->is_in_young(p);
WB_END
--- a/src/hotspot/share/runtime/arguments.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/runtime/arguments.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -1266,9 +1266,13 @@
char stripped_argname[BUFLEN+1]; // +1 for '\0'
jio_snprintf(stripped_argname, arg_len+1, "%s", argname); // +1 for '\0'
if (is_obsolete_flag(stripped_argname, &since)) {
- char version[256];
- since.to_string(version, sizeof(version));
- warning("Ignoring option %s; support was removed in %s", stripped_argname, version);
+ if (strcmp(stripped_argname, "UseAppCDS") != 0) {
+ char version[256];
+ since.to_string(version, sizeof(version));
+ warning("Ignoring option %s; support was removed in %s", stripped_argname, version);
+ } else {
+ warning("Ignoring obsolete option UseAppCDS; AppCDS is automatically enabled");
+ }
return true;
}
#ifndef PRODUCT
--- a/src/hotspot/share/runtime/jniHandles.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/runtime/jniHandles.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -327,7 +327,11 @@
VerifyJNIHandles verify_handle;
oops_do(&verify_handle);
- weak_oops_do(&verify_handle);
+
+ // JNI weaks are handled concurrently in ZGC, so they can't be verified here
+ if (!UseZGC) {
+ weak_oops_do(&verify_handle);
+ }
}
// This method is implemented here to avoid circular includes between
--- a/src/hotspot/share/runtime/stackValue.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/runtime/stackValue.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -29,6 +29,9 @@
#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/stackValue.hpp"
+#if INCLUDE_ZGC
+#include "gc/z/zBarrier.inline.hpp"
+#endif
StackValue* StackValue::create_stack_value(const frame* fr, const RegisterMap* reg_map, ScopeValue* sv) {
if (sv->is_location()) {
@@ -119,6 +122,13 @@
val = (oop)NULL;
}
#endif
+#if INCLUDE_ZGC
+ // Deoptimization must make sure all oop have passed load barrier
+ if (UseZGC) {
+ val = ZBarrier::load_barrier_on_oop_field_preloaded((oop*)value_addr, val);
+ }
+#endif
+
Handle h(Thread::current(), val); // Wrap a handle around the oop
return new StackValue(h);
}
--- a/src/hotspot/share/runtime/stubCodeGenerator.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/runtime/stubCodeGenerator.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, 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
@@ -71,7 +71,7 @@
}
StubCodeGenerator::~StubCodeGenerator() {
- if (_print_code) {
+ if (PRODUCT_ONLY(_print_code) NOT_PRODUCT(true)) {
CodeBuffer* cbuf = _masm->code();
CodeBlob* blob = CodeCache::find_blob_unsafe(cbuf->insts()->start());
if (blob != NULL) {
@@ -86,9 +86,19 @@
void StubCodeGenerator::stub_epilog(StubCodeDesc* cdesc) {
if (_print_code) {
+ CodeStrings cs;
+ ptrdiff_t offset = 0;
+#ifndef PRODUCT
+ // Find the code strings in the outer CodeBuffer.
+ CodeBuffer *outer_cbuf = _masm->code_section()->outer();
+ cs = outer_cbuf->strings();
+ // The offset from the start of the outer CodeBuffer to the start
+ // of this stub.
+ offset = cdesc->begin() - outer_cbuf->insts()->start();
+#endif
cdesc->print();
tty->cr();
- Disassembler::decode(cdesc->begin(), cdesc->end());
+ Disassembler::decode(cdesc->begin(), cdesc->end(), NULL, cs, offset);
tty->cr();
}
}
--- a/src/hotspot/share/runtime/vmStructs.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/runtime/vmStructs.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -1271,6 +1271,7 @@
declare_integer_type(intptr_t) \
declare_unsigned_integer_type(uintx) \
declare_unsigned_integer_type(uintptr_t) \
+ declare_unsigned_integer_type(uint8_t) \
declare_unsigned_integer_type(uint32_t) \
declare_unsigned_integer_type(uint64_t) \
\
@@ -2602,6 +2603,12 @@
#define VM_LONG_CONSTANTS(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
\
+ /****************/ \
+ /* GC constants */ \
+ /****************/ \
+ \
+ VM_LONG_CONSTANTS_GC(declare_constant) \
+ \
/*********************/ \
/* MarkOop constants */ \
/*********************/ \
--- a/src/hotspot/share/runtime/vm_operations.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/runtime/vm_operations.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -69,6 +69,7 @@
template(CMS_Final_Remark) \
template(G1CollectForAllocation) \
template(G1CollectFull) \
+ template(ZOperation) \
template(HandshakeOneThread) \
template(HandshakeAllThreads) \
template(HandshakeFallback) \
--- a/src/hotspot/share/services/memTracker.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/services/memTracker.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -241,6 +241,11 @@
}
}
+#ifdef _AIX
+ // See JDK-8202772 - temporarily disable thread stack tracking on AIX.
+ static inline void record_thread_stack(void* addr, size_t size) {}
+ static inline void release_thread_stack(void* addr, size_t size) {}
+#else
static inline void record_thread_stack(void* addr, size_t size) {
if (tracking_level() < NMT_summary) return;
if (addr != NULL) {
@@ -260,6 +265,7 @@
VirtualMemoryTracker::remove_released_region((address)addr, size);
}
}
+#endif
// Query lock is used to synchronize the access to tracking data.
// So far, it is only used by JCmd query, but it may be used by
--- a/src/hotspot/share/utilities/exceptions.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/utilities/exceptions.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -37,6 +37,7 @@
#include "runtime/os.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/threadCritical.hpp"
+#include "runtime/atomic.hpp"
#include "utilities/events.hpp"
#include "utilities/exceptions.hpp"
@@ -151,6 +152,10 @@
count_out_of_memory_exceptions(h_exception);
}
+ if (h_exception->is_a(SystemDictionary::LinkageError_klass())) {
+ Atomic::inc(&_linkage_errors);
+ }
+
assert(h_exception->is_a(SystemDictionary::Throwable_klass()), "exception is not a subclass of java/lang/Throwable");
// set the pending exception
@@ -425,6 +430,7 @@
// Exception counting for hs_err file
volatile int Exceptions::_stack_overflow_errors = 0;
+volatile int Exceptions::_linkage_errors = 0;
volatile int Exceptions::_out_of_memory_error_java_heap_errors = 0;
volatile int Exceptions::_out_of_memory_error_metaspace_errors = 0;
volatile int Exceptions::_out_of_memory_error_class_metaspace_errors = 0;
@@ -458,6 +464,9 @@
if (_stack_overflow_errors > 0) {
st->print_cr("StackOverflowErrors=%d", _stack_overflow_errors);
}
+ if (_linkage_errors > 0) {
+ st->print_cr("LinkageErrors=%d", _linkage_errors);
+ }
}
// Implementation of ExceptionMark
--- a/src/hotspot/share/utilities/exceptions.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/utilities/exceptions.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -108,6 +108,9 @@
static volatile int _out_of_memory_error_java_heap_errors;
static volatile int _out_of_memory_error_metaspace_errors;
static volatile int _out_of_memory_error_class_metaspace_errors;
+
+ // Count linkage errors
+ static volatile int _linkage_errors;
public:
// this enum is defined to indicate whether it is safe to
// ignore the encoding scheme of the original message string.
--- a/src/hotspot/share/utilities/macros.hpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/hotspot/share/utilities/macros.hpp Wed Jun 13 11:01:25 2018 -0700
@@ -149,6 +149,24 @@
#define NOT_CMSGC_RETURN_(code) { return code; }
#endif // INCLUDE_CMSGC
+#ifndef INCLUDE_EPSILONGC
+#define INCLUDE_EPSILONGC 1
+#endif // INCLUDE_EPSILONGC
+
+#if INCLUDE_EPSILONGC
+#define EPSILONGC_ONLY(x) x
+#define EPSILONGC_ONLY_ARG(arg) arg,
+#define NOT_EPSILONGC(x)
+#define NOT_EPSILONGC_RETURN /* next token must be ; */
+#define NOT_EPSILONGC_RETURN_(code) /* next token must be ; */
+#else
+#define EPSILONGC_ONLY(x)
+#define EPSILONGC_ONLY_ARG(arg)
+#define NOT_EPSILONGC(x) x
+#define NOT_EPSILONGC_RETURN {}
+#define NOT_EPSILONGC_RETURN_(code) { return code; }
+#endif // INCLUDE_EPSILONGC
+
#ifndef INCLUDE_G1GC
#define INCLUDE_G1GC 1
#endif // INCLUDE_G1GC
@@ -203,7 +221,25 @@
#define NOT_SERIALGC_RETURN_(code) { return code; }
#endif // INCLUDE_SERIALGC
-#if INCLUDE_CMSGC || INCLUDE_G1GC || INCLUDE_PARALLELGC
+#ifndef INCLUDE_ZGC
+#define INCLUDE_ZGC 1
+#endif // INCLUDE_ZGC
+
+#if INCLUDE_ZGC
+#define ZGC_ONLY(x) x
+#define ZGC_ONLY_ARG(arg) arg,
+#define NOT_ZGC(x)
+#define NOT_ZGC_RETURN /* next token must be ; */
+#define NOT_ZGC_RETURN_(code) /* next token must be ; */
+#else
+#define ZGC_ONLY(x)
+#define ZGC_ONLY_ARG(arg)
+#define NOT_ZGC(x) x
+#define NOT_ZGC_RETURN {}
+#define NOT_ZGC_RETURN_(code) { return code; }
+#endif // INCLUDE_ZGC
+
+#if INCLUDE_CMSGC || INCLUDE_EPSILONGC || INCLUDE_G1GC || INCLUDE_PARALLELGC || INCLUDE_ZGC
#define INCLUDE_NOT_ONLY_SERIALGC 1
#else
#define INCLUDE_NOT_ONLY_SERIALGC 0
--- a/src/java.base/share/classes/java/lang/System.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.base/share/classes/java/lang/System.java Wed Jun 13 11:01:25 2018 -0700
@@ -607,8 +607,9 @@
* <tr><th scope="row">{@code java.home}</th>
* <td>Java installation directory</td></tr>
* <tr><th scope="row">{@code java.vm.specification.version}</th>
- * <td>Java Virtual Machine specification version which may be
- * interpreted as a {@link Runtime.Version}</td></tr>
+ * <td>Java Virtual Machine specification version, whose value is the
+ * {@linkplain Runtime.Version#feature feature} element of the
+ * {@linkplain Runtime#version() runtime version}</td></tr>
* <tr><th scope="row">{@code java.vm.specification.vendor}</th>
* <td>Java Virtual Machine specification vendor</td></tr>
* <tr><th scope="row">{@code java.vm.specification.name}</th>
@@ -621,8 +622,9 @@
* <tr><th scope="row">{@code java.vm.name}</th>
* <td>Java Virtual Machine implementation name</td></tr>
* <tr><th scope="row">{@code java.specification.version}</th>
- * <td>Java Runtime Environment specification version which may be
- * interpreted as a {@link Runtime.Version}</td></tr>
+ * <td>Java Runtime Environment specification version, whose value is
+ * the {@linkplain Runtime.Version#feature feature} element of the
+ * {@linkplain Runtime#version() runtime version}</td></tr>
* <tr><th scope="row">{@code java.specification.vendor}</th>
* <td>Java Runtime Environment specification vendor</td></tr>
* <tr><th scope="row">{@code java.specification.name}</th>
--- a/src/java.base/share/classes/java/lang/Thread.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.base/share/classes/java/lang/Thread.java Wed Jun 13 11:01:25 2018 -0700
@@ -938,26 +938,6 @@
}
/**
- * Throws {@code UnsupportedOperationException}.
- *
- * @param obj ignored
- *
- * @deprecated This method was originally designed to force a thread to stop
- * and throw a given {@code Throwable} as an exception. It was
- * inherently unsafe (see {@link #stop()} for details), and furthermore
- * could be used to generate exceptions that the target thread was
- * not prepared to handle.
- * For more information, see
- * <a href="{@docRoot}/java.base/java/lang/doc-files/threadPrimitiveDeprecation.html">Why
- * are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
- * This method is subject to removal in a future version of Java SE.
- */
- @Deprecated(since="1.2", forRemoval=true)
- public final synchronized void stop(Throwable obj) {
- throw new UnsupportedOperationException();
- }
-
- /**
* Interrupts this thread.
*
* <p> Unless the current thread is interrupting itself, which is
@@ -1062,29 +1042,6 @@
private native boolean isInterrupted(boolean ClearInterrupted);
/**
- * Throws {@link NoSuchMethodError}.
- *
- * @deprecated This method was originally designed to destroy this
- * thread without any cleanup. Any monitors it held would have
- * remained locked. However, the method was never implemented.
- * If it were to be implemented, it would be deadlock-prone in
- * much the manner of {@link #suspend}. If the target thread held
- * a lock protecting a critical system resource when it was
- * destroyed, no thread could ever access this resource again.
- * If another thread ever attempted to lock this resource, deadlock
- * would result. Such deadlocks typically manifest themselves as
- * "frozen" processes. For more information, see
- * <a href="{@docRoot}/java.base/java/lang/doc-files/threadPrimitiveDeprecation.html">
- * Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
- * This method is subject to removal in a future version of Java SE.
- * @throws NoSuchMethodError always
- */
- @Deprecated(since="1.5", forRemoval=true)
- public void destroy() {
- throw new NoSuchMethodError();
- }
-
- /**
* Tests if this thread is alive. A thread is alive if it has
* been started and has not yet died.
*
--- a/src/java.base/share/classes/java/lang/doc-files/threadPrimitiveDeprecation.html Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.base/share/classes/java/lang/doc-files/threadPrimitiveDeprecation.html Wed Jun 13 11:01:25 2018 -0700
@@ -62,21 +62,6 @@
</ol>
In sum, it just isn't practical.
<hr>
-<h3>What about <code>Thread.stop(Throwable)</code>?</h3>
-<p>In addition to all of the problems noted above, this method may
-be used to generate exceptions that its target thread is unprepared
-to handle (including checked exceptions that the thread could not
-possibly throw, were it not for this method). For example, the
-following method is behaviorally identical to Java's
-<code>throw</code> operation, but circumvents the compiler's
-attempts to guarantee that the calling method has declared all of
-the checked exceptions that it may throw:</p>
-<pre>
- static void sneakyThrow(Throwable t) {
- Thread.currentThread().stop(t);
- }
-</pre>
-<hr>
<h3>What should I use instead of <code>Thread.stop</code>?</h3>
<p>Most uses of <code>stop</code> should be replaced by code that
simply modifies some variable to indicate that the target thread
@@ -339,13 +324,6 @@
described above, it needn't call <code>notify</code> as well, but it
still must be synchronized. This ensures that the target thread
won't miss an interrupt due to a race condition.
-<hr>
-<h3>What about <code>Thread.destroy</code>?</h3>
-<code>Thread.destroy</code> was never implemented and has been
-deprecated. If it were implemented, it would be deadlock-prone in
-the manner of <code>Thread.suspend</code>. (In fact, it is roughly
-equivalent to <code>Thread.suspend</code> without the possibility
-of a subsequent <code>Thread.resume</code>.)
<p><!-- Body text ends here --></p>
</body>
</html>
--- a/src/java.base/share/classes/java/time/chrono/JapaneseEra.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.base/share/classes/java/time/chrono/JapaneseEra.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -123,14 +123,19 @@
*/
public static final JapaneseEra SHOWA = new JapaneseEra(1, LocalDate.of(1926, 12, 25));
/**
- * The singleton instance for the 'Heisei' era (1989-01-08 - current)
+ * The singleton instance for the 'Heisei' era (1989-01-08 - 2019-04-30)
* which has the value 2.
*/
public static final JapaneseEra HEISEI = new JapaneseEra(2, LocalDate.of(1989, 1, 8));
+ /**
+ * The singleton instance for the 'NewEra' era (2019-05-01 - current)
+ * which has the value 3.
+ */
+ private static final JapaneseEra NEWERA = new JapaneseEra(3, LocalDate.of(2019, 5, 1));
// The number of predefined JapaneseEra constants.
// There may be a supplemental era defined by the property.
- private static final int N_ERA_CONSTANTS = HEISEI.getValue() + ERA_OFFSET;
+ private static final int N_ERA_CONSTANTS = NEWERA.getValue() + ERA_OFFSET;
/**
* Serialization version.
@@ -148,6 +153,7 @@
KNOWN_ERAS[1] = TAISHO;
KNOWN_ERAS[2] = SHOWA;
KNOWN_ERAS[3] = HEISEI;
+ KNOWN_ERAS[4] = NEWERA;
for (int i = N_ERA_CONSTANTS; i < ERA_CONFIG.length; i++) {
CalendarDate date = ERA_CONFIG[i].getSinceDate();
LocalDate isoDate = LocalDate.of(date.getYear(), date.getMonth(), date.getDayOfMonth());
--- a/src/java.base/share/classes/java/util/JapaneseImperialCalendar.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.base/share/classes/java/util/JapaneseImperialCalendar.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -50,6 +50,7 @@
* 2 Taisho 1912-07-30T00:00:00 local time
* 3 Showa 1926-12-25T00:00:00 local time
* 4 Heisei 1989-01-08T00:00:00 local time
+ * 5 NewEra 2019-05-01T00:00:00 local time
* ------------------------------------------------------
* }</pre>
*
@@ -71,8 +72,10 @@
* </pre>
* where
* <dl>
- * <dt>{@code <name>:}<dd>the full name of the new era (non-ASCII characters allowed)
- * <dt>{@code <abbr>:}<dd>the abbreviation of the new era (non-ASCII characters allowed)
+ * <dt>{@code <name>:}<dd>the full name of the new era (non-ASCII characters allowed,
+ * either in platform's native encoding or in Unicode escape notation, {@code \\uXXXX})
+ * <dt>{@code <abbr>:}<dd>the abbreviation of the new era (non-ASCII characters allowed,
+ * either in platform's native encoding or in Unicode escape notation, {@code \\uXXXX})
* <dt>{@code <time['u']>:}<dd>the start time of the new era represented by
* milliseconds from 1970-01-01T00:00:00 local time or UTC if {@code 'u'} is
* appended to the milliseconds value. (ASCII digits only)
@@ -125,6 +128,11 @@
*/
public static final int HEISEI = 4;
+ /**
+ * The ERA constant designating the NewEra era.
+ */
+ private static final int NEWERA = 5;
+
private static final int EPOCH_OFFSET = 719163; // Fixed date of January 1, 1970 (Gregorian)
// Useful millisecond constants. Although ONE_DAY and ONE_WEEK can fit
@@ -155,6 +163,9 @@
// Fixed date of the first date of each era.
private static final long[] sinceFixedDates;
+ // The current era
+ private static final int currentEra;
+
/*
* <pre>
* Greatest Least
@@ -251,13 +262,18 @@
// eras[BEFORE_MEIJI] and sinceFixedDate[BEFORE_MEIJI] are the
// same as Gregorian.
int index = BEFORE_MEIJI;
+ int current = index;
sinceFixedDates[index] = gcal.getFixedDate(BEFORE_MEIJI_ERA.getSinceDate());
eras[index++] = BEFORE_MEIJI_ERA;
for (Era e : es) {
+ if(e.getSince(TimeZone.NO_TIMEZONE) < System.currentTimeMillis()) {
+ current = index;
+ }
CalendarDate d = e.getSinceDate();
sinceFixedDates[index] = gcal.getFixedDate(d);
eras[index++] = e;
}
+ currentEra = current;
LEAST_MAX_VALUES[ERA] = MAX_VALUES[ERA] = eras.length - 1;
@@ -1743,12 +1759,12 @@
}
} else if (transitionYear) {
if (jdate.getYear() == 1) {
- // As of Heisei (since Meiji) there's no case
+ // As of NewEra (since Meiji) there's no case
// that there are multiple transitions in a
// year. Historically there was such
// case. There might be such case again in the
// future.
- if (era > HEISEI) {
+ if (era > NEWERA) {
CalendarDate pd = eras[era - 1].getSinceDate();
if (normalizedYear == pd.getYear()) {
d.setMonth(pd.getMonth()).setDayOfMonth(pd.getDayOfMonth());
@@ -1883,7 +1899,7 @@
year = isSet(YEAR) ? internalGet(YEAR) : 1;
} else {
if (isSet(YEAR)) {
- era = eras.length - 1;
+ era = currentEra;
year = internalGet(YEAR);
} else {
// Equivalent to 1970 (Gregorian)
@@ -2367,7 +2383,7 @@
* default ERA is the current era, but a zero (unset) ERA means before Meiji.
*/
private int internalGetEra() {
- return isSet(ERA) ? internalGet(ERA) : eras.length - 1;
+ return isSet(ERA) ? internalGet(ERA) : currentEra;
}
/**
--- a/src/java.base/share/classes/javax/crypto/CipherSpi.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.base/share/classes/javax/crypto/CipherSpi.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -755,6 +755,7 @@
return 0;
}
int outLenNeeded = engineGetOutputSize(inLen);
+
if (output.remaining() < outLenNeeded) {
throw new ShortBufferException("Need at least " + outLenNeeded
+ " bytes of space in output buffer");
@@ -762,98 +763,77 @@
boolean a1 = input.hasArray();
boolean a2 = output.hasArray();
-
- if (a1 && a2) {
- byte[] inArray = input.array();
- int inOfs = input.arrayOffset() + inPos;
- byte[] outArray = output.array();
+ int total = 0;
+ byte[] inArray, outArray;
+ if (a2) { // output has an accessible byte[]
+ outArray = output.array();
int outPos = output.position();
int outOfs = output.arrayOffset() + outPos;
- int n;
- if (isUpdate) {
- n = engineUpdate(inArray, inOfs, inLen, outArray, outOfs);
- } else {
- n = engineDoFinal(inArray, inOfs, inLen, outArray, outOfs);
- }
- input.position(inLimit);
- output.position(outPos + n);
- return n;
- } else if (!a1 && a2) {
- int outPos = output.position();
- byte[] outArray = output.array();
- int outOfs = output.arrayOffset() + outPos;
- byte[] inArray = new byte[getTempArraySize(inLen)];
- int total = 0;
- do {
- int chunk = Math.min(inLen, inArray.length);
- if (chunk > 0) {
- input.get(inArray, 0, chunk);
+
+ if (a1) { // input also has an accessible byte[]
+ inArray = input.array();
+ int inOfs = input.arrayOffset() + inPos;
+ if (isUpdate) {
+ total = engineUpdate(inArray, inOfs, inLen, outArray, outOfs);
+ } else {
+ total = engineDoFinal(inArray, inOfs, inLen, outArray, outOfs);
}
- int n;
- if (isUpdate || (inLen != chunk)) {
- n = engineUpdate(inArray, 0, chunk, outArray, outOfs);
- } else {
- n = engineDoFinal(inArray, 0, chunk, outArray, outOfs);
- }
- total += n;
- outOfs += n;
- inLen -= chunk;
- } while (inLen > 0);
- output.position(outPos + total);
- return total;
- } else { // output is not backed by an accessible byte[]
- byte[] inArray;
- int inOfs;
- if (a1) {
- inArray = input.array();
- inOfs = input.arrayOffset() + inPos;
- } else {
+ input.position(inLimit);
+ } else { // input does not have accessible byte[]
inArray = new byte[getTempArraySize(inLen)];
- inOfs = 0;
+ do {
+ int chunk = Math.min(inLen, inArray.length);
+ if (chunk > 0) {
+ input.get(inArray, 0, chunk);
+ }
+ int n;
+ if (isUpdate || (inLen > chunk)) {
+ n = engineUpdate(inArray, 0, chunk, outArray, outOfs);
+ } else {
+ n = engineDoFinal(inArray, 0, chunk, outArray, outOfs);
+ }
+ total += n;
+ outOfs += n;
+ inLen -= chunk;
+ } while (inLen > 0);
}
- byte[] outArray = new byte[getTempArraySize(outLenNeeded)];
- int outSize = outArray.length;
- int total = 0;
- boolean resized = false;
- do {
- int chunk =
- Math.min(inLen, (outSize == 0? inArray.length : outSize));
- if (!a1 && !resized && chunk > 0) {
- input.get(inArray, 0, chunk);
- inOfs = 0;
+ output.position(outPos + total);
+ } else { // output does not have an accessible byte[]
+ if (a1) { // but input has an accessible byte[]
+ inArray = input.array();
+ int inOfs = input.arrayOffset() + inPos;
+ if (isUpdate) {
+ outArray = engineUpdate(inArray, inOfs, inLen);
+ } else {
+ outArray = engineDoFinal(inArray, inOfs, inLen);
+ }
+ input.position(inLimit);
+ if (outArray != null && outArray.length != 0) {
+ output.put(outArray);
+ total = outArray.length;
}
- try {
+ } else { // input also does not have an accessible byte[]
+ inArray = new byte[getTempArraySize(inLen)];
+ do {
+ int chunk = Math.min(inLen, inArray.length);
+ if (chunk > 0) {
+ input.get(inArray, 0, chunk);
+ }
int n;
- if (isUpdate || (inLen != chunk)) {
- n = engineUpdate(inArray, inOfs, chunk, outArray, 0);
+ if (isUpdate || (inLen > chunk)) {
+ outArray = engineUpdate(inArray, 0, chunk);
} else {
- n = engineDoFinal(inArray, inOfs, chunk, outArray, 0);
+ outArray = engineDoFinal(inArray, 0, chunk);
}
- resized = false;
- inOfs += chunk;
+ if (outArray != null && outArray.length != 0) {
+ output.put(outArray);
+ total += outArray.length;
+ }
inLen -= chunk;
- if (n > 0) {
- output.put(outArray, 0, n);
- total += n;
- }
- } catch (ShortBufferException e) {
- if (resized) {
- // we just resized the output buffer, but it still
- // did not work. Bug in the provider, abort
- throw (ProviderException)new ProviderException
- ("Could not determine buffer size").initCause(e);
- }
- // output buffer is too small, realloc and try again
- resized = true;
- outSize = engineGetOutputSize(chunk);
- outArray = new byte[outSize];
- }
- } while (inLen > 0);
- if (a1) {
- input.position(inLimit);
+ } while (inLen > 0);
}
- return total;
}
+ return total;
}
/**
--- a/src/java.base/share/classes/sun/text/resources/FormatData.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.base/share/classes/sun/text/resources/FormatData.java Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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,6 +106,7 @@
"T",
"S",
"H",
+ "N", // NewEra
};
// Japanese imperial calendar era strings
@@ -115,6 +116,7 @@
"Taisho",
"Showa",
"Heisei",
+ "NewEra", // NewEra
};
return new Object[][] {
--- a/src/java.base/share/classes/sun/text/resources/JavaTimeSupplementary.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.base/share/classes/sun/text/resources/JavaTimeSupplementary.java Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2016, 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
@@ -159,6 +159,7 @@
"Taisho",
"Showa",
"Heisei",
+ "NewEra", // New Era
};
final String[] sharedShortEras = {
--- a/src/java.base/share/classes/sun/util/calendar/Era.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.base/share/classes/sun/util/calendar/Era.java Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2014, 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
@@ -48,6 +48,7 @@
* Taisho 1912-07-30T00:00:00 local time
* Showa 1926-12-25T00:00:00 local time
* Heisei 1989-01-08T00:00:00 local time
+ * NewEra 2019-05-01T00:00:00 local time
* -----------------------------------------------------------------------
* }</pre>
*
--- a/src/java.base/share/classes/sun/util/calendar/LocalGregorianCalendar.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.base/share/classes/sun/util/calendar/LocalGregorianCalendar.java Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, 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
@@ -27,6 +27,8 @@
import java.security.AccessController;
import java.util.TimeZone;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import sun.security.action.GetPropertyAction;
/**
@@ -41,11 +43,12 @@
new Era("Taisho", "T", -1812153600000L, true),
new Era("Showa", "S", -1357603200000L, true),
new Era("Heisei", "H", 600220800000L, true),
+ new Era("NewEra", "N", 1556668800000L, true),
};
private static boolean isValidEra(Era newEra, Era[] eras) {
Era last = eras[eras.length - 1];
- if (last.getSinceDate().getYear() >= newEra.getSinceDate().getYear()) {
+ if (last.getSince(null) >= newEra.getSince(null)) {
return false;
}
// The new era name should be unique. Its abbr may not.
@@ -173,7 +176,7 @@
return null;
}
String key = keyvalue[0].trim();
- String value = keyvalue[1].trim();
+ String value = convertUnicodeEscape(keyvalue[1].trim());
switch (key) {
case "name":
eraName = value;
@@ -203,6 +206,17 @@
return new Era(eraName, abbr, since, localTime);
}
+ private static String convertUnicodeEscape(String src) {
+ Matcher m = Pattern.compile("\\\\u([0-9a-fA-F]{4})").matcher(src);
+ StringBuilder sb = new StringBuilder();
+ while (m.find()) {
+ m.appendReplacement(sb,
+ Character.toString((char)Integer.parseUnsignedInt(m.group(1), 16)));
+ }
+ m.appendTail(sb);
+ return sb.toString();
+ }
+
private LocalGregorianCalendar(String name, Era[] eras) {
this.name = name;
this.eras = eras;
--- a/src/java.base/share/classes/sun/util/locale/provider/CalendarNameProviderImpl.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.base/share/classes/sun/util/locale/provider/CalendarNameProviderImpl.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -35,8 +35,8 @@
import sun.util.calendar.Era;
/**
- * Concrete implementation of the {@link java.util.spi.CalendarDataProvider
- * CalendarDataProvider} class for the JRE LocaleProviderAdapter.
+ * Concrete implementation of the {@link java.util.spi.CalendarNameProvider
+ * CalendarNameProvider} class for the JRE LocaleProviderAdapter.
*
* @author Masayoshi Okutsu
* @author Naoto Sato
@@ -77,28 +77,43 @@
if (field == DAY_OF_WEEK || field == YEAR) {
--value;
}
- if (value < 0 || value > strings.length) {
+ if (value < 0) {
return null;
- } else if (value == strings.length) {
+ } else if (value >= strings.length) {
if (field == ERA && "japanese".equals(calendarType)) {
- // get the supplemental era, if any, specified through
- // the property "jdk.calendar.japanese.supplemental.era"
- // which is always the last element.
Era[] jeras = CalendarSystem.forName("japanese").getEras();
- if (jeras.length == value) {
- Era supEra = jeras[value - 1]; // 0-based index
- if (javatime) {
- return getBaseStyle(style) == NARROW_FORMAT ?
- supEra.getAbbreviation() :
- supEra.getName();
- } else {
- return (style & LONG) != 0 ?
- supEra.getName() :
- supEra.getAbbreviation();
+ if (value <= jeras.length) {
+ // Localized era name could not be retrieved from this provider.
+ // This can occur either for NewEra or SupEra.
+ //
+ // If it's CLDR provider, try COMPAT first, which is guaranteed to have
+ // the name for NewEra.
+ if (type == LocaleProviderAdapter.Type.CLDR) {
+ lr = LocaleProviderAdapter.forJRE().getLocaleResources(locale);
+ key = getResourceKeyFor(LocaleProviderAdapter.Type.JRE,
+ calendarType, field, style, javatime);
+ strings =
+ javatime ? lr.getJavaTimeNames(key) : lr.getCalendarNames(key);
}
+ if (strings == null || value >= strings.length) {
+ // Get the default name for SupEra
+ Era supEra = jeras[value - 1]; // 0-based index
+ if (javatime) {
+ return getBaseStyle(style) == NARROW_FORMAT ?
+ supEra.getAbbreviation() :
+ supEra.getName();
+ } else {
+ return (style & LONG) != 0 ?
+ supEra.getName() :
+ supEra.getAbbreviation();
+ }
+ }
+ } else {
+ return null;
}
+ } else {
+ return null;
}
- return null;
}
name = strings[value];
// If name is empty in standalone, try its `format' style.
@@ -180,7 +195,7 @@
return map;
}
- private int getBaseStyle(int style) {
+ private static int getBaseStyle(int style) {
return style & ~(SHORT_STANDALONE - SHORT_FORMAT);
}
@@ -261,6 +276,11 @@
}
private String getResourceKey(String type, int field, int style, boolean javatime) {
+ return getResourceKeyFor(this.type, type, field, style, javatime);
+ }
+
+ private static String getResourceKeyFor(LocaleProviderAdapter.Type adapterType,
+ String type, int field, int style, boolean javatime) {
int baseStyle = getBaseStyle(style);
boolean isStandalone = (style != baseStyle);
@@ -284,7 +304,7 @@
// JRE and CLDR use different resource key conventions
// due to historical reasons. (JRE DateFormatSymbols.getEras returns
// abbreviations while other getShort*() return abbreviations.)
- if (this.type == LocaleProviderAdapter.Type.JRE) {
+ if (adapterType == LocaleProviderAdapter.Type.JRE) {
if (javatime) {
if (baseStyle == LONG) {
key.append("long.");
@@ -336,7 +356,7 @@
return key.length() > 0 ? key.toString() : null;
}
- private String toStyleName(int baseStyle) {
+ private static String toStyleName(int baseStyle) {
switch (baseStyle) {
case SHORT:
return "Abbreviations";
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/legal/c-libutl.md Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,35 @@
+## c-libutl 20160225
+
+### c-libutl License
+```
+
+This software is distributed under the terms of the BSD license.
+
+== BSD LICENSE ===============================================================
+
+ (C) 2009 by Remo Dentato (rdentato@gmail.com)
+
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+http://opensource.org/licenses/bsd-license.php
+
+```
Binary file src/java.base/share/lib/security/cacerts has changed
--- a/src/java.base/share/native/libjava/jni_util.c Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.base/share/native/libjava/jni_util.c Wed Jun 13 11:01:25 2018 -0700
@@ -838,8 +838,11 @@
CHECK_NULL(String_getBytes_ID);
String_init_ID = (*env)->GetMethodID(env, strClazz,
"<init>", "([BLjava/lang/String;)V");
+ CHECK_NULL(String_init_ID);
String_coder_ID = (*env)->GetFieldID(env, strClazz, "coder", "B");
+ CHECK_NULL(String_coder_ID);
String_value_ID = (*env)->GetFieldID(env, strClazz, "value", "[B");
+ CHECK_NULL(String_value_ID);
}
JNIEXPORT jstring
--- a/src/java.compiler/share/classes/javax/annotation/processing/Messager.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.compiler/share/classes/javax/annotation/processing/Messager.java Wed Jun 13 11:01:25 2018 -0700
@@ -25,7 +25,6 @@
package javax.annotation.processing;
-import javax.annotation.*;
import javax.tools.Diagnostic;
import javax.lang.model.element.*;
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/CFileDialog.m Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/CFileDialog.m Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2014, 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
@@ -46,7 +46,7 @@
canChooseDirectories:(BOOL)inChooseDirectories
withEnv:(JNIEnv*)env;
{
- if (self == [super init]) {
+ if (self = [super init]) {
fHasFileFilter = inHasFilter;
fFileDialog = JNFNewGlobalRef(env, inDialog);
fDirectory = inPath;
@@ -92,7 +92,7 @@
- (void)safeSaveOrLoad {
NSSavePanel *thePanel = nil;
- /*
+ /*
* 8013553: turns off extension hiding for the native file dialog.
* This way is used because setExtensionHidden(NO) doesn't work
* as expected.
--- a/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEG.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEG.java Wed Jun 13 11:01:25 2018 -0700
@@ -187,13 +187,7 @@
public static final int JCS_RGB = 2; // red/green/blue
public static final int JCS_YCbCr = 3; // Y/Cb/Cr (also known as YUV)
public static final int JCS_CMYK = 4; // C/M/Y/K
- public static final int JCS_YCC = 5; // PhotoYCC
- public static final int JCS_RGBA = 6; // RGB-Alpha
- public static final int JCS_YCbCrA = 7; // Y/Cb/Cr/Alpha
- // 8 and 9 were old "Legacy" codes which the old code never identified
- // on reading anyway. Support for writing them is being dropped, too.
- public static final int JCS_YCCA = 10; // PhotoYCC-Alpha
- public static final int JCS_YCCK = 11; // Y/Cb/Cr/K
+ public static final int JCS_YCCK = 5; // Y/Cb/Cr/K
public static final int NUM_JCS_CODES = JCS_YCCK+1;
@@ -212,22 +206,6 @@
public static class JCS {
public static final ColorSpace sRGB =
ColorSpace.getInstance(ColorSpace.CS_sRGB);
-
- private static ColorSpace YCC = null;
- private static boolean yccInited = false;
-
- public static ColorSpace getYCC() {
- if (!yccInited) {
- try {
- YCC = ColorSpace.getInstance(ColorSpace.CS_PYCC);
- } catch (IllegalArgumentException e) {
- // PYCC.pf may not always be installed
- } finally {
- yccInited = true;
- }
- }
- return YCC;
- }
}
// Default value for ImageWriteParam
--- a/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java Wed Jun 13 11:01:25 2018 -0700
@@ -933,21 +933,6 @@
case JPEG.JCS_RGB:
list.add(raw);
list.add(getImageType(JPEG.JCS_GRAYSCALE));
- list.add(getImageType(JPEG.JCS_YCC));
- break;
- case JPEG.JCS_RGBA:
- list.add(raw);
- break;
- case JPEG.JCS_YCC:
- if (raw != null) { // Might be null if PYCC.pf not installed
- list.add(raw);
- list.add(getImageType(JPEG.JCS_RGB));
- }
- break;
- case JPEG.JCS_YCCA:
- if (raw != null) { // Might be null if PYCC.pf not installed
- list.add(raw);
- }
break;
case JPEG.JCS_YCbCr:
// As there is no YCbCr ColorSpace, we can't support
@@ -972,12 +957,6 @@
}
list.add(getImageType(JPEG.JCS_GRAYSCALE));
- list.add(getImageType(JPEG.JCS_YCC));
- break;
- case JPEG.JCS_YCbCrA: // Default is to convert to RGBA
- // As there is no YCbCr ColorSpace, we can't support
- // the raw type.
- list.add(getImageType(JPEG.JCS_RGBA));
break;
}
@@ -1065,36 +1044,6 @@
throw new IIOException("Incompatible color conversion");
}
break;
- case JPEG.JCS_RGBA:
- // No conversions available; image must be RGBA
- if ((csType != ColorSpace.TYPE_RGB) ||
- (cm.getNumComponents() != numComponents)) {
- throw new IIOException("Incompatible color conversion");
- }
- break;
- case JPEG.JCS_YCC:
- {
- ColorSpace YCC = JPEG.JCS.getYCC();
- if (YCC == null) { // We can't do YCC at all
- throw new IIOException("Incompatible color conversion");
- }
- if ((cs != YCC) &&
- (cm.getNumComponents() == numComponents)) {
- convert = new ColorConvertOp(YCC, cs, null);
- }
- }
- break;
- case JPEG.JCS_YCCA:
- {
- ColorSpace YCC = JPEG.JCS.getYCC();
- // No conversions available; image must be YCCA
- if ((YCC == null) || // We can't do YCC at all
- (cs != YCC) ||
- (cm.getNumComponents() != numComponents)) {
- throw new IIOException("Incompatible color conversion");
- }
- }
- break;
default:
// Anything else we can't handle at all
throw new IIOException("Incompatible color conversion");
@@ -1929,36 +1878,6 @@
DataBuffer.TYPE_BYTE,
false,
false);
- case JPEG.JCS_RGBA:
- return ImageTypeSpecifier.createPacked(JPEG.JCS.sRGB,
- 0xff000000,
- 0x00ff0000,
- 0x0000ff00,
- 0x000000ff,
- DataBuffer.TYPE_INT,
- false);
- case JPEG.JCS_YCC:
- if (JPEG.JCS.getYCC() != null) {
- return ImageTypeSpecifier.createInterleaved(
- JPEG.JCS.getYCC(),
- JPEG.bandOffsets[2],
- DataBuffer.TYPE_BYTE,
- false,
- false);
- } else {
- return null;
- }
- case JPEG.JCS_YCCA:
- if (JPEG.JCS.getYCC() != null) {
- return ImageTypeSpecifier.createInterleaved(
- JPEG.JCS.getYCC(),
- JPEG.bandOffsets[3],
- DataBuffer.TYPE_BYTE,
- true,
- false);
- } else {
- return null;
- }
default:
return null;
}
--- a/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java Wed Jun 13 11:01:25 2018 -0700
@@ -754,115 +754,47 @@
}
break;
case ColorSpace.TYPE_RGB:
- if (!alpha) {
- if (jfif != null) {
+ if (jfif != null) {
+ outCsType = JPEG.JCS_YCbCr;
+ if (JPEG.isNonStandardICC(cs)
+ || ((cs instanceof ICC_ColorSpace)
+ && (jfif.iccSegment != null))) {
+ iccProfile =
+ ((ICC_ColorSpace) cs).getProfile();
+ }
+ } else if (adobe != null) {
+ switch (adobe.transform) {
+ case JPEG.ADOBE_UNKNOWN:
+ outCsType = JPEG.JCS_RGB;
+ break;
+ case JPEG.ADOBE_YCC:
outCsType = JPEG.JCS_YCbCr;
- if (JPEG.isNonStandardICC(cs)
- || ((cs instanceof ICC_ColorSpace)
- && (jfif.iccSegment != null))) {
- iccProfile =
- ((ICC_ColorSpace) cs).getProfile();
- }
- } else if (adobe != null) {
- switch (adobe.transform) {
- case JPEG.ADOBE_UNKNOWN:
- outCsType = JPEG.JCS_RGB;
- break;
- case JPEG.ADOBE_YCC:
+ break;
+ default:
+ warningOccurred
+ (WARNING_IMAGE_METADATA_ADOBE_MISMATCH);
+ newAdobeTransform = JPEG.ADOBE_UNKNOWN;
+ outCsType = JPEG.JCS_RGB;
+ break;
+ }
+ } else {
+ // consult the ids
+ int outCS = sof.getIDencodedCSType();
+ // if they don't resolve it,
+ // consult the sampling factors
+ if (outCS != JPEG.JCS_UNKNOWN) {
+ outCsType = outCS;
+ } else {
+ boolean subsampled =
+ isSubsampled(sof.componentSpecs);
+ if (subsampled) {
outCsType = JPEG.JCS_YCbCr;
- break;
- default:
- warningOccurred
- (WARNING_IMAGE_METADATA_ADOBE_MISMATCH);
- newAdobeTransform = JPEG.ADOBE_UNKNOWN;
- outCsType = JPEG.JCS_RGB;
- break;
- }
- } else {
- // consult the ids
- int outCS = sof.getIDencodedCSType();
- // if they don't resolve it,
- // consult the sampling factors
- if (outCS != JPEG.JCS_UNKNOWN) {
- outCsType = outCS;
} else {
- boolean subsampled =
- isSubsampled(sof.componentSpecs);
- if (subsampled) {
- outCsType = JPEG.JCS_YCbCr;
- } else {
- outCsType = JPEG.JCS_RGB;
- }
- }
- }
- } else { // RGBA
- if (jfif != null) {
- ignoreJFIF = true;
- warningOccurred
- (WARNING_IMAGE_METADATA_JFIF_MISMATCH);
- }
- if (adobe != null) {
- if (adobe.transform
- != JPEG.ADOBE_UNKNOWN) {
- newAdobeTransform = JPEG.ADOBE_UNKNOWN;
- warningOccurred
- (WARNING_IMAGE_METADATA_ADOBE_MISMATCH);
- }
- outCsType = JPEG.JCS_RGBA;
- } else {
- // consult the ids
- int outCS = sof.getIDencodedCSType();
- // if they don't resolve it,
- // consult the sampling factors
- if (outCS != JPEG.JCS_UNKNOWN) {
- outCsType = outCS;
- } else {
- boolean subsampled =
- isSubsampled(sof.componentSpecs);
- outCsType = subsampled ?
- JPEG.JCS_YCbCrA : JPEG.JCS_RGBA;
+ outCsType = JPEG.JCS_RGB;
}
}
}
break;
- case ColorSpace.TYPE_3CLR:
- if (cs == JPEG.JCS.getYCC()) {
- if (!alpha) {
- if (jfif != null) {
- convertTosRGB = true;
- convertOp =
- new ColorConvertOp(cs,
- JPEG.JCS.sRGB,
- null);
- outCsType = JPEG.JCS_YCbCr;
- } else if (adobe != null) {
- if (adobe.transform
- != JPEG.ADOBE_YCC) {
- newAdobeTransform = JPEG.ADOBE_YCC;
- warningOccurred
- (WARNING_IMAGE_METADATA_ADOBE_MISMATCH);
- }
- outCsType = JPEG.JCS_YCC;
- } else {
- outCsType = JPEG.JCS_YCC;
- }
- } else { // PhotoYCCA
- if (jfif != null) {
- ignoreJFIF = true;
- warningOccurred
- (WARNING_IMAGE_METADATA_JFIF_MISMATCH);
- } else if (adobe != null) {
- if (adobe.transform
- != JPEG.ADOBE_UNKNOWN) {
- newAdobeTransform
- = JPEG.ADOBE_UNKNOWN;
- warningOccurred
- (WARNING_IMAGE_METADATA_ADOBE_MISMATCH);
- }
- }
- outCsType = JPEG.JCS_YCCA;
- }
- }
}
}
} // else no dest, metadata, not an image. Defaults ok
@@ -1564,27 +1496,10 @@
retval = JPEG.JCS_GRAYSCALE;
break;
case ColorSpace.TYPE_RGB:
- if (alpha) {
- retval = JPEG.JCS_RGBA;
- } else {
- retval = JPEG.JCS_RGB;
- }
+ retval = JPEG.JCS_RGB;
break;
case ColorSpace.TYPE_YCbCr:
- if (alpha) {
- retval = JPEG.JCS_YCbCrA;
- } else {
- retval = JPEG.JCS_YCbCr;
- }
- break;
- case ColorSpace.TYPE_3CLR:
- if (cs == JPEG.JCS.getYCC()) {
- if (alpha) {
- retval = JPEG.JCS_YCCA;
- } else {
- retval = JPEG.JCS_YCC;
- }
- }
+ retval = JPEG.JCS_YCbCr;
break;
case ColorSpace.TYPE_CMYK:
retval = JPEG.JCS_CMYK;
@@ -1604,27 +1519,10 @@
retval = JPEG.JCS_GRAYSCALE;
break;
case ColorSpace.TYPE_RGB:
- if (alpha) {
- retval = JPEG.JCS_RGBA;
- } else {
- retval = JPEG.JCS_RGB;
- }
+ retval = JPEG.JCS_RGB;
break;
case ColorSpace.TYPE_YCbCr:
- if (alpha) {
- retval = JPEG.JCS_YCbCrA;
- } else {
- retval = JPEG.JCS_YCbCr;
- }
- break;
- case ColorSpace.TYPE_3CLR:
- if (cs == JPEG.JCS.getYCC()) {
- if (alpha) {
- retval = JPEG.JCS_YCCA;
- } else {
- retval = JPEG.JCS_YCC;
- }
- }
+ retval = JPEG.JCS_YCbCr;
break;
case ColorSpace.TYPE_CMYK:
retval = JPEG.JCS_CMYK;
@@ -1651,27 +1549,10 @@
retval = JPEG.JCS_GRAYSCALE;
break;
case ColorSpace.TYPE_RGB:
- if (alpha) {
- retval = JPEG.JCS_YCbCrA;
- } else {
- retval = JPEG.JCS_YCbCr;
- }
+ retval = JPEG.JCS_YCbCr;
break;
case ColorSpace.TYPE_YCbCr:
- if (alpha) {
- retval = JPEG.JCS_YCbCrA;
- } else {
- retval = JPEG.JCS_YCbCr;
- }
- break;
- case ColorSpace.TYPE_3CLR:
- if (cs == JPEG.JCS.getYCC()) {
- if (alpha) {
- retval = JPEG.JCS_YCCA;
- } else {
- retval = JPEG.JCS_YCC;
- }
- }
+ retval = JPEG.JCS_YCbCr;
break;
case ColorSpace.TYPE_CMYK:
retval = JPEG.JCS_YCCK;
--- a/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java Wed Jun 13 11:01:25 2018 -0700
@@ -73,7 +73,11 @@
public boolean canEncodeImage(ImageTypeSpecifier type) {
SampleModel sampleModel = type.getSampleModel();
+ ColorModel cm = type.getColorModel();
+ if (cm.hasAlpha()) {
+ return false;
+ }
// Find the maximum bit depth across all channels
int[] sampleSize = sampleModel.getSampleSize();
int bitDepth = sampleSize[0];
--- a/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java Wed Jun 13 11:01:25 2018 -0700
@@ -491,17 +491,6 @@
wantJFIF = false;
}
break;
- case ColorSpace.TYPE_3CLR:
- if (cs == JPEG.JCS.getYCC()) {
- wantJFIF = false;
- componentIDs[0] = (byte) 'Y';
- componentIDs[1] = (byte) 'C';
- componentIDs[2] = (byte) 'c';
- if (hasAlpha) {
- componentIDs[3] = (byte) 'A';
- }
- }
- break;
case ColorSpace.TYPE_YCbCr:
if (hasExtraComponents) { // e.g. K or alpha
wantJFIF = false;
--- a/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/SOFMarkerSegment.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/SOFMarkerSegment.java Wed Jun 13 11:01:25 2018 -0700
@@ -182,29 +182,11 @@
switch(componentSpecs.length) {
case 3:
if ((componentSpecs[0].componentId == 'R')
- &&(componentSpecs[0].componentId == 'G')
- &&(componentSpecs[0].componentId == 'B')) {
+ &&(componentSpecs[1].componentId == 'G')
+ &&(componentSpecs[2].componentId == 'B')) {
return JPEG.JCS_RGB;
}
- if ((componentSpecs[0].componentId == 'Y')
- &&(componentSpecs[0].componentId == 'C')
- &&(componentSpecs[0].componentId == 'c')) {
- return JPEG.JCS_YCC;
- }
break;
- case 4:
- if ((componentSpecs[0].componentId == 'R')
- &&(componentSpecs[0].componentId == 'G')
- &&(componentSpecs[0].componentId == 'B')
- &&(componentSpecs[0].componentId == 'A')) {
- return JPEG.JCS_RGBA;
- }
- if ((componentSpecs[0].componentId == 'Y')
- &&(componentSpecs[0].componentId == 'C')
- &&(componentSpecs[0].componentId == 'c')
- &&(componentSpecs[0].componentId == 'A')) {
- return JPEG.JCS_YCCA;
- }
}
return JPEG.JCS_UNKNOWN;
--- a/src/java.desktop/share/classes/java/awt/Robot.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/java/awt/Robot.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -29,10 +29,10 @@
import java.awt.event.KeyEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.BaseMultiResolutionImage;
-import java.awt.image.MultiResolutionImage;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.awt.image.DirectColorModel;
+import java.awt.image.MultiResolutionImage;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.awt.peer.RobotPeer;
@@ -41,7 +41,7 @@
import sun.awt.ComponentFactory;
import sun.awt.SunToolkit;
import sun.awt.image.SunWritableRaster;
-import sun.swing.SwingUtilities2;
+import sun.java2d.SunGraphicsEnvironment;
/**
* This class is used to generate native system input events
@@ -505,7 +505,7 @@
.getLocalGraphicsEnvironment()
.getDefaultScreenDevice().
getDefaultConfiguration();
- gc = SwingUtilities2.getGraphicsConfigurationAtPoint(
+ gc = SunGraphicsEnvironment.getGraphicsConfigurationAtPoint(
gc, screenRect.getCenterX(), screenRect.getCenterY());
AffineTransform tx = gc.getDefaultTransform();
--- a/src/java.desktop/share/classes/java/awt/desktop/AboutEvent.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/java/awt/desktop/AboutEvent.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -25,6 +25,9 @@
package java.awt.desktop;
+import java.awt.Desktop;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
/**
* Event sent when the application is asked to open its about window.
@@ -34,12 +37,19 @@
* @since 9
*/
public final class AboutEvent extends AppEvent {
+
private static final long serialVersionUID = -5987180734802756477L;
/**
- * Constructs an {@code AboutEvent}
+ * Constructs an {@code AboutEvent}.
+ *
+ * @throws HeadlessException if {@link GraphicsEnvironment#isHeadless()}
+ * returns {@code true}
+ * @throws UnsupportedOperationException if Desktop API is not supported on
+ * the current platform
+ * @see Desktop#isDesktopSupported()
+ * @see java.awt.GraphicsEnvironment#isHeadless
*/
public AboutEvent() {
}
-
}
--- a/src/java.desktop/share/classes/java/awt/desktop/AppEvent.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/java/awt/desktop/AppEvent.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -26,11 +26,13 @@
package java.awt.desktop;
import java.awt.Desktop;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
import java.util.EventObject;
/**
* AppEvents are sent to listeners and handlers installed on the
- * {@link java.awt.Desktop}.
+ * {@link java.awt.Desktop} instance of the current desktop context.
*
* @since 9
*/
@@ -38,8 +40,17 @@
private static final long serialVersionUID = -5958503993556009432L;
+ /**
+ * Constructs an {@code AppEvent}.
+ *
+ * @throws HeadlessException if {@link GraphicsEnvironment#isHeadless()}
+ * returns {@code true}
+ * @throws UnsupportedOperationException if Desktop API is not supported on
+ * the current platform
+ * @see Desktop#isDesktopSupported()
+ * @see java.awt.GraphicsEnvironment#isHeadless
+ */
AppEvent() {
super(Desktop.getDesktop());
}
-
}
--- a/src/java.desktop/share/classes/java/awt/desktop/AppForegroundEvent.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/java/awt/desktop/AppForegroundEvent.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -25,6 +25,9 @@
package java.awt.desktop;
+import java.awt.Desktop;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
/**
* Event sent when the application has become the foreground app, and when it is
@@ -36,12 +39,19 @@
* @since 9
*/
public final class AppForegroundEvent extends AppEvent {
+
private static final long serialVersionUID = -5513582555740533911L;
/**
- * Constructs an {@code AppForegroundEvent}
+ * Constructs an {@code AppForegroundEvent}.
+ *
+ * @throws HeadlessException if {@link GraphicsEnvironment#isHeadless()}
+ * returns {@code true}
+ * @throws UnsupportedOperationException if Desktop API is not supported on
+ * the current platform
+ * @see Desktop#isDesktopSupported()
+ * @see java.awt.GraphicsEnvironment#isHeadless
*/
public AppForegroundEvent() {
}
-
}
--- a/src/java.desktop/share/classes/java/awt/desktop/AppHiddenEvent.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/java/awt/desktop/AppHiddenEvent.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -25,6 +25,9 @@
package java.awt.desktop;
+import java.awt.Desktop;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
/**
* Event sent when the application has been hidden or shown.
@@ -35,12 +38,19 @@
* @since 9
*/
public final class AppHiddenEvent extends AppEvent {
+
private static final long serialVersionUID = 2637465279476429224L;
/**
- * Constructs an {@code AppHiddenEvent}
+ * Constructs an {@code AppHiddenEvent}.
+ *
+ * @throws HeadlessException if {@link GraphicsEnvironment#isHeadless()}
+ * returns {@code true}
+ * @throws UnsupportedOperationException if Desktop API is not supported on
+ * the current platform
+ * @see Desktop#isDesktopSupported()
+ * @see java.awt.GraphicsEnvironment#isHeadless
*/
public AppHiddenEvent() {
}
-
}
--- a/src/java.desktop/share/classes/java/awt/desktop/AppReopenedEvent.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/java/awt/desktop/AppReopenedEvent.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -25,6 +25,9 @@
package java.awt.desktop;
+import java.awt.Desktop;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
/**
* Event sent when the application is asked to re-open itself.
@@ -34,12 +37,19 @@
* @since 9
*/
public final class AppReopenedEvent extends AppEvent {
+
private static final long serialVersionUID = 1503238361530407990L;
/**
- * Constructs an {@code AppReopenedEvent}
+ * Constructs an {@code AppReopenedEvent}.
+ *
+ * @throws HeadlessException if {@link GraphicsEnvironment#isHeadless()}
+ * returns {@code true}
+ * @throws UnsupportedOperationException if Desktop API is not supported on
+ * the current platform
+ * @see Desktop#isDesktopSupported()
+ * @see java.awt.GraphicsEnvironment#isHeadless
*/
public AppReopenedEvent() {
}
-
}
--- a/src/java.desktop/share/classes/java/awt/desktop/FilesEvent.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/java/awt/desktop/FilesEvent.java Wed Jun 13 11:01:25 2018 -0700
@@ -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,30 +25,41 @@
package java.awt.desktop;
+import java.awt.Desktop;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
-
/**
* Auxiliary event containing a list of files.
*
* @since 9
*/
public class FilesEvent extends AppEvent {
+
private static final long serialVersionUID = 5271763715462312871L;
final List<File> files;
/**
- * Constructs a {@code FilesEvent}
- * @param files files
+ * Constructs a {@code FilesEvent}.
+ *
+ * @param files the list of files
+ * @throws HeadlessException if {@link GraphicsEnvironment#isHeadless()}
+ * returns {@code true}
+ * @throws UnsupportedOperationException if Desktop API is not supported on
+ * the current platform
+ * @see Desktop#isDesktopSupported()
+ * @see java.awt.GraphicsEnvironment#isHeadless
*/
FilesEvent(final List<File> files) {
this.files = files;
}
/**
- * Gets the list of files
+ * Gets the list of files.
+ *
* @return the list of files
*/
public List<File> getFiles() {
@@ -56,5 +67,4 @@
? null
: new ArrayList<>(files);
}
-
}
--- a/src/java.desktop/share/classes/java/awt/desktop/OpenFilesEvent.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/java/awt/desktop/OpenFilesEvent.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -25,10 +25,12 @@
package java.awt.desktop;
+import java.awt.Desktop;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
import java.io.File;
import java.util.List;
-
/**
* Event sent when the app is asked to open a list of files.
*
@@ -37,13 +39,21 @@
* @since 9
*/
public final class OpenFilesEvent extends FilesEvent {
+
private static final long serialVersionUID = -3982871005867718956L;
final String searchTerm;
/**
- * Constructs an {@code OpenFilesEvent}
- * @param files files
- * @param searchTerm searchTerm
+ * Constructs an {@code OpenFilesEvent}.
+ *
+ * @param files the list of files
+ * @param searchTerm the search term
+ * @throws HeadlessException if {@link GraphicsEnvironment#isHeadless()}
+ * returns {@code true}
+ * @throws UnsupportedOperationException if Desktop API is not supported on
+ * the current platform
+ * @see Desktop#isDesktopSupported()
+ * @see java.awt.GraphicsEnvironment#isHeadless
*/
public OpenFilesEvent(final List<File> files, final String searchTerm) {
super(files);
@@ -57,7 +67,7 @@
* term that was used to find the files. This is for example the case
* on Mac OS X, when the files were opened using the Spotlight search
* menu or a Finder search window.
- *
+ * <p>
* This is useful for highlighting the search term in the documents when
* they are opened.
*
@@ -66,5 +76,4 @@
public String getSearchTerm() {
return searchTerm;
}
-
}
--- a/src/java.desktop/share/classes/java/awt/desktop/OpenURIEvent.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/java/awt/desktop/OpenURIEvent.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -25,9 +25,11 @@
package java.awt.desktop;
+import java.awt.Desktop;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
import java.net.URI;
-
/**
* Event sent when the app is asked to open a {@code URI}.
*
@@ -36,12 +38,20 @@
* @since 9
*/
public final class OpenURIEvent extends AppEvent {
+
private static final long serialVersionUID = 221209100935933476L;
final URI uri;
/**
- * Constructs an {@code OpenURIEvent}
- * @param uri {@code URI}
+ * Constructs an {@code OpenURIEvent}.
+ *
+ * @param uri the {@code URI} the app was asked to open
+ * @throws HeadlessException if {@link GraphicsEnvironment#isHeadless()}
+ * returns {@code true}
+ * @throws UnsupportedOperationException if Desktop API is not supported on
+ * the current platform
+ * @see Desktop#isDesktopSupported()
+ * @see java.awt.GraphicsEnvironment#isHeadless
*/
public OpenURIEvent(final URI uri) {
this.uri = uri;
@@ -54,5 +64,4 @@
public URI getURI() {
return uri;
}
-
}
--- a/src/java.desktop/share/classes/java/awt/desktop/PreferencesEvent.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/java/awt/desktop/PreferencesEvent.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -25,6 +25,9 @@
package java.awt.desktop;
+import java.awt.Desktop;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
/**
* Event sent when the application is asked to open its preferences window.
@@ -34,12 +37,19 @@
* @since 9
*/
public final class PreferencesEvent extends AppEvent {
+
private static final long serialVersionUID = -6398607097086476160L;
/**
- * Constructs a {@code PreferencesEvent}
+ * Constructs a {@code PreferencesEvent}.
+ *
+ * @throws HeadlessException if {@link GraphicsEnvironment#isHeadless()}
+ * returns {@code true}
+ * @throws UnsupportedOperationException if Desktop API is not supported on
+ * the current platform
+ * @see Desktop#isDesktopSupported()
+ * @see java.awt.GraphicsEnvironment#isHeadless
*/
public PreferencesEvent() {
}
-
}
--- a/src/java.desktop/share/classes/java/awt/desktop/PrintFilesEvent.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/java/awt/desktop/PrintFilesEvent.java Wed Jun 13 11:01:25 2018 -0700
@@ -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,13 +23,14 @@
* questions.
*/
-
package java.awt.desktop;
+import java.awt.Desktop;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
import java.io.File;
import java.util.List;
-
/**
* Event sent when the app is asked to print a list of files.
*
@@ -37,14 +38,21 @@
* @since 9
*/
public final class PrintFilesEvent extends FilesEvent {
+
private static final long serialVersionUID = -5752560876153618618L;
/**
- * Constructs a {@code PrintFilesEvent}
- * @param files files
+ * Constructs a {@code PrintFilesEvent}.
+ *
+ * @param files the list of files
+ * @throws HeadlessException if {@link GraphicsEnvironment#isHeadless()}
+ * returns {@code true}
+ * @throws UnsupportedOperationException if Desktop API is not supported on
+ * the current platform
+ * @see Desktop#isDesktopSupported()
+ * @see java.awt.GraphicsEnvironment#isHeadless
*/
public PrintFilesEvent(final List<File> files) {
super(files);
}
-
}
--- a/src/java.desktop/share/classes/java/awt/desktop/QuitEvent.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/java/awt/desktop/QuitEvent.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -25,6 +25,10 @@
package java.awt.desktop;
+import java.awt.Desktop;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
+
/**
* Event sent when the application is asked to quit.
*
@@ -37,7 +41,14 @@
private static final long serialVersionUID = -256100795532403146L;
/**
- * Constructs a {@code QuitEvent}
+ * Constructs a {@code QuitEvent}.
+ *
+ * @throws HeadlessException if {@link GraphicsEnvironment#isHeadless()}
+ * returns {@code true}
+ * @throws UnsupportedOperationException if Desktop API is not supported on
+ * the current platform
+ * @see Desktop#isDesktopSupported()
+ * @see java.awt.GraphicsEnvironment#isHeadless
*/
public QuitEvent() {
}
--- a/src/java.desktop/share/classes/java/awt/desktop/ScreenSleepEvent.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/java/awt/desktop/ScreenSleepEvent.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -22,8 +22,13 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
package java.awt.desktop;
+import java.awt.Desktop;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
+
/**
* Event sent when the displays attached to the system enter and exit power save
* sleep.
@@ -38,7 +43,14 @@
private static final long serialVersionUID = 7521606180376544150L;
/**
- * Constructs a ScreenSleepEvent
+ * Constructs a {@code ScreenSleepEvent}.
+ *
+ * @throws HeadlessException if {@link GraphicsEnvironment#isHeadless()}
+ * returns {@code true}
+ * @throws UnsupportedOperationException if Desktop API is not supported on
+ * the current platform
+ * @see Desktop#isDesktopSupported()
+ * @see java.awt.GraphicsEnvironment#isHeadless
*/
public ScreenSleepEvent() {
}
--- a/src/java.desktop/share/classes/java/awt/desktop/SystemSleepEvent.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/java/awt/desktop/SystemSleepEvent.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -25,6 +25,10 @@
package java.awt.desktop;
+import java.awt.Desktop;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
+
/**
* Event sent when the system enters and exits power save sleep.
*
@@ -38,7 +42,14 @@
private static final long serialVersionUID = 11372269824930549L;
/**
- * Constructs a SystemSleepEvent
+ * Constructs a {@code SystemSleepEvent}.
+ *
+ * @throws HeadlessException if {@link GraphicsEnvironment#isHeadless()}
+ * returns {@code true}
+ * @throws UnsupportedOperationException if Desktop API is not supported on
+ * the current platform
+ * @see Desktop#isDesktopSupported()
+ * @see java.awt.GraphicsEnvironment#isHeadless
*/
public SystemSleepEvent() {
}
--- a/src/java.desktop/share/classes/java/awt/desktop/UserSessionEvent.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/java/awt/desktop/UserSessionEvent.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -22,8 +22,13 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
package java.awt.desktop;
+import java.awt.Desktop;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
+
/**
* Event sent when the user session has been changed.
*
@@ -66,9 +71,15 @@
}
/**
- * Constructs a {@code UserSessionEvent}
+ * Constructs a {@code UserSessionEvent}.
*
- * @param reason of session change
+ * @param reason the reason of the user session change
+ * @throws HeadlessException if {@link GraphicsEnvironment#isHeadless()}
+ * returns {@code true}
+ * @throws UnsupportedOperationException if Desktop API is not supported on
+ * the current platform
+ * @see Desktop#isDesktopSupported()
+ * @see java.awt.GraphicsEnvironment#isHeadless
*/
public UserSessionEvent(Reason reason) {
this.reason = reason;
--- a/src/java.desktop/share/classes/javax/print/ServiceUI.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/javax/print/ServiceUI.java Wed Jun 13 11:01:25 2018 -0700
@@ -25,8 +25,6 @@
package javax.print;
-import java.awt.Dialog;
-import java.awt.Frame;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
@@ -35,11 +33,11 @@
import javax.print.attribute.Attribute;
import javax.print.attribute.AttributeSet;
+import javax.print.attribute.standard.DialogOwner;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Destination;
import javax.print.attribute.standard.Fidelity;
-import sun.print.DialogOwner;
import sun.print.ServiceDialog;
import sun.print.SunAlternateMedia;
@@ -185,6 +183,7 @@
DialogOwner dlgOwner = (DialogOwner)attributes.get(DialogOwner.class);
Window owner = (dlgOwner != null) ? dlgOwner.getOwner() : null;
+ boolean setOnTop = (dlgOwner != null) && (owner == null);
Rectangle gcBounds = (gc == null) ? GraphicsEnvironment.
getLocalGraphicsEnvironment().getDefaultScreenDevice().
@@ -192,21 +191,17 @@
x += gcBounds.x;
y += gcBounds.y;
- ServiceDialog dialog;
- if (owner instanceof Frame) {
- dialog = new ServiceDialog(gc,
- x,
- y,
- services, defaultIndex,
- flavor, attributes,
- (Frame)owner);
- } else {
- dialog = new ServiceDialog(gc,
- x,
- y,
- services, defaultIndex,
- flavor, attributes,
- (Dialog)owner);
+ ServiceDialog dialog = new ServiceDialog(gc,
+ x,
+ y,
+ services, defaultIndex,
+ flavor, attributes,
+ owner);
+ if (setOnTop) {
+ try {
+ dialog.setAlwaysOnTop(true);
+ } catch (SecurityException e) {
+ }
}
Rectangle dlgBounds = dialog.getBounds();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/classes/javax/print/attribute/standard/DialogOwner.java Wed Jun 13 11:01:25 2018 -0700
@@ -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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package javax.print.attribute.standard;
+
+import java.awt.Window;
+import javax.print.attribute.Attribute;
+import javax.print.attribute.PrintRequestAttribute;
+import sun.print.DialogOwnerAccessor;
+
+/**
+ * An attribute class used to support requesting a print or page setup dialog
+ * be kept displayed on top of all windows or some specific window.
+ * <p>
+ * Constructed without any arguments it will request that a print or page
+ * setup dialog be configured as if the application directly was to specify
+ * {@code java.awt.Window.setAlwaysOnTop(true)}, subject to permission checks.
+ * <p>
+ * Constructed with a {@link java.awt.Window} parameter, it requests that
+ * the dialog be owned by the specified window.
+ *
+ * @since 11
+ */
+public final class DialogOwner implements PrintRequestAttribute {
+
+ private static class Accessor extends DialogOwnerAccessor {
+
+ public long getOwnerID(DialogOwner owner) {
+ return owner.getID();
+ }
+ }
+
+ static private Accessor accessor = new Accessor();
+ static {
+ DialogOwnerAccessor.setAccessor(accessor);
+ }
+
+ private static final long serialVersionUID = -1901909867156076547L;
+
+ private Window owner;
+ private transient long id;
+
+ /**
+ * Constructs an instance which can be used to request
+ * {@code java.awt.Window.setAlwaysOnTop(true)} behaviour.
+ * This should be used where there is no application preferred owner window.
+ * Whether this has any effect depends on if always on top is supported
+ * for this platform and the particular dialog to be displayed.
+ */
+ public DialogOwner() {
+ }
+
+ /**
+ * Constructs an instance which can be used to request that the
+ * specified {@link java.awt.Window} be the owner of the dialog.
+ * @param owner window.
+ */
+ public DialogOwner(Window owner) {
+ this.owner = owner;
+ }
+
+ /**
+ * Constructs an instance which requests that the dialog be displayed
+ * as if it were a child of a native platform window, specified
+ * using its opqaue platform identifier or handle.
+ * This is useful mainly for the case where the id represents a window
+ * which may not be an AWT {@code Window}, but instead was created by
+ * another UI toolkit, such as OpenJFX.
+ * Any effect is platform dependent.
+ * @param id a native window identifier or handle
+ */
+ DialogOwner(long id) {
+ this.id = id;
+ }
+
+ /**
+ * Returns a native platform id or handle, if one was specified,
+ * otherwise, zero.
+ * @return a native platform id.
+ */
+ long getID() {
+ return id;
+ }
+
+ /**
+ * Returns a {@code Window owner}, if one was specified,
+ * otherwise {@code null}.
+ * @return an owner window.
+ */
+ public Window getOwner() {
+ return owner;
+ }
+
+ /**
+ * Get the printing attribute class which is to be used as the "category"
+ * for this printing attribute value.
+ * <p>
+ * For class {@code DialogOwner}, the category is class
+ * {@code DialogOwner} itself.
+ *
+ * @return printing attribute class (category), an instance of class
+ * {@link Class java.lang.Class}
+ */
+ public final Class<? extends Attribute> getCategory() {
+ return DialogOwner.class;
+ }
+
+ /**
+ * Get the name of the category of which this attribute value is an
+ * instance.
+ * <p>
+ * For class {@code DialogOwner}, the category name is
+ * {@code "dialog-owner"}.
+ *
+ */
+ public final String getName() {
+ return "dialog-owner";
+
+ }
+}
--- a/src/java.desktop/share/classes/sun/applet/AppletClassLoader.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/sun/applet/AppletClassLoader.java Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 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,31 +25,28 @@
package sun.applet;
-import java.lang.NullPointerException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.net.SocketPermission;
-import java.net.URLConnection;
-import java.net.MalformedURLException;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
+import java.io.BufferedInputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FilePermission;
import java.io.IOException;
-import java.io.BufferedInputStream;
import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLConnection;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.NoSuchElementException;
-import java.security.AccessController;
-import java.security.AccessControlContext;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedExceptionAction;
-import java.security.PrivilegedActionException;
-import java.security.CodeSource;
-import java.security.Permission;
-import java.security.PermissionCollection;
+
import sun.awt.AppContext;
import sun.awt.SunToolkit;
import sun.net.www.ParseUtil;
@@ -151,13 +148,10 @@
try {
return super.loadClass(name, resolve);
} catch (ClassNotFoundException e) {
- //printError(name, e.getException());
throw e;
} catch (RuntimeException e) {
- //printError(name, e);
throw e;
} catch (Error e) {
- //printError(name, e);
throw e;
}
}
@@ -825,30 +819,6 @@
{
return jdk12AppletInfo.get(clazz.toString());
}
-
- private static AppletMessageHandler mh =
- new AppletMessageHandler("appletclassloader");
-
- /*
- * Prints a class loading error message.
- */
- private static void printError(String name, Throwable e) {
- String s = null;
- if (e == null) {
- s = mh.getMessage("filenotfound", name);
- } else if (e instanceof IOException) {
- s = mh.getMessage("fileioexception", name);
- } else if (e instanceof ClassFormatError) {
- s = mh.getMessage("fileformat", name);
- } else if (e instanceof ThreadDeath) {
- s = mh.getMessage("filedeath", name);
- } else if (e instanceof Error) {
- s = mh.getMessage("fileerror", e.toString(), name);
- }
- if (s != null) {
- System.err.println(s);
- }
- }
}
/*
--- a/src/java.desktop/share/classes/sun/applet/AppletEvent.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 1997, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.applet;
-
-import java.util.EventObject;
-
-
-/**
- * AppletEvent class.
- *
- * @author Sunita Mani
- *
- * @deprecated The Applet API is deprecated. See the
- * <a href="../../java/applet/package-summary.html"> java.applet package
- * documentation</a> for further information.
- */
-@SuppressWarnings("serial") // JDK-implementation class
-@Deprecated(since = "9")
-public class AppletEvent extends EventObject {
-
- private Object arg;
- private int id;
-
-
- public AppletEvent(Object source, int id, Object argument) {
- super(source);
- this.arg = argument;
- this.id = id;
- }
-
- public int getID() {
- return id;
- }
-
- public Object getArgument() {
- return arg;
- }
-
- public String toString() {
- String str = getClass().getName() + "[source=" + source + " + id="+ id;
- if (arg != null) {
- str += " + arg=" + arg;
- }
- str += " ]";
- return str;
- }
-}
--- a/src/java.desktop/share/classes/sun/applet/AppletEventMulticaster.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-/*
- * Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved.
- * 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.applet;
-
-import java.util.EventListener;
-import java.io.Serializable;
-import java.io.ObjectOutputStream;
-import java.io.IOException;
-
-/**
- * AppletEventMulticaster class. This class manages an immutable
- * structure consisting of a chain of AppletListeners and is
- * responsible for dispatching events to them.
- *
- * @author Sunita Mani
- *
- * @deprecated The Applet API is deprecated. See the
- * <a href="../../java/applet/package-summary.html"> java.applet package
- * documentation</a> for further information.
- */
-@Deprecated(since = "9")
-public class AppletEventMulticaster implements AppletListener {
-
- private final AppletListener a, b;
-
- public AppletEventMulticaster(AppletListener a, AppletListener b) {
- this.a = a; this.b = b;
- }
-
- public void appletStateChanged(AppletEvent e) {
- a.appletStateChanged(e);
- b.appletStateChanged(e);
- }
-
- /**
- * Adds Applet-listener-a with Applet-listener-b and
- * returns the resulting multicast listener.
- * @param a Applet-listener-a
- * @param b Applet-listener-b
- */
- public static AppletListener add(AppletListener a, AppletListener b) {
- return addInternal(a, b);
- }
-
- /**
- * Removes the old Applet-listener from Applet-listener-l and
- * returns the resulting multicast listener.
- * @param l Applet-listener-l
- * @param oldl the Applet-listener being removed
- */
- public static AppletListener remove(AppletListener l, AppletListener oldl) {
- return removeInternal(l, oldl);
- }
-
- /**
- * Returns the resulting multicast listener from adding listener-a
- * and listener-b together.
- * If listener-a is null, it returns listener-b;
- * If listener-b is null, it returns listener-a
- * If neither are null, then it creates and returns
- * a new AppletEventMulticaster instance which chains a with b.
- * @param a event listener-a
- * @param b event listener-b
- */
- private static AppletListener addInternal(AppletListener a, AppletListener b) {
- if (a == null) return b;
- if (b == null) return a;
- return new AppletEventMulticaster(a, b);
- }
-
-
- /**
- * Removes a listener from this multicaster and returns the
- * resulting multicast listener.
- * @param oldl the listener to be removed
- */
- protected AppletListener remove(AppletListener oldl) {
- if (oldl == a) return b;
- if (oldl == b) return a;
- AppletListener a2 = removeInternal(a, oldl);
- AppletListener b2 = removeInternal(b, oldl);
- if (a2 == a && b2 == b) {
- return this; // it's not here
- }
- return addInternal(a2, b2);
- }
-
-
- /**
- * Returns the resulting multicast listener after removing the
- * old listener from listener-l.
- * If listener-l equals the old listener OR listener-l is null,
- * returns null.
- * Else if listener-l is an instance of AppletEventMulticaster
- * then it removes the old listener from it.
- * Else, returns listener l.
- * @param l the listener being removed from
- * @param oldl the listener being removed
- */
- private static AppletListener removeInternal(AppletListener l, AppletListener oldl) {
- if (l == oldl || l == null) {
- return null;
- } else if (l instanceof AppletEventMulticaster) {
- return ((AppletEventMulticaster)l).remove(oldl);
- } else {
- return l; // it's not here
- }
- }
-}
--- a/src/java.desktop/share/classes/sun/applet/AppletIOException.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 1996, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.applet;
-
-import java.io.IOException;
-
-/**
- * An applet IO exception.
- *
- * @author Koji Uno
- *
- * @deprecated The Applet API is deprecated. See the
- * <a href="../../java/applet/package-summary.html"> java.applet package
- * documentation</a> for further information.
- */
-@SuppressWarnings("serial") // JDK implementation class
-@Deprecated(since = "9")
-public class AppletIOException extends IOException {
- private String key = null;
- private Object msgobj = null;
-
- public AppletIOException(String key) {
- super(key);
- this.key = key;
-
- }
- public AppletIOException(String key, Object arg) {
- this(key);
- msgobj = arg;
- }
-
- public String getLocalizedMessage() {
- if( msgobj != null)
- return amh.getMessage(key, msgobj);
- else
- return amh.getMessage(key);
- }
-
- private static AppletMessageHandler amh = new AppletMessageHandler("appletioexception");
-
-}
--- a/src/java.desktop/share/classes/sun/applet/AppletIllegalArgumentException.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 1996, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.applet;
-
-/**
- * An applet security exception.
- *
- * @author Arthur van Hoff
- *
- * @deprecated The Applet API is deprecated. See the
- * <a href="../../java/applet/package-summary.html"> java.applet package
- * documentation</a> for further information.
- */
-@SuppressWarnings("serial") // JDK implementation class
-@Deprecated(since = "9")
-public class AppletIllegalArgumentException extends IllegalArgumentException {
- private String key = null;
-
- public AppletIllegalArgumentException(String key) {
- super(key);
- this.key = key;
-
- }
-
- public String getLocalizedMessage() {
- return amh.getMessage(key);
- }
-
- private static AppletMessageHandler amh = new AppletMessageHandler("appletillegalargumentexception");
-}
--- a/src/java.desktop/share/classes/sun/applet/AppletImageRef.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 1995, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.applet;
-
-import java.awt.Toolkit;
-import java.awt.Image;
-import java.lang.ref.SoftReference;
-import sun.awt.image.URLImageSource;
-import java.net.URL;
-
-@Deprecated(since = "9")
-class AppletImageRef {
- private SoftReference<Image> soft = null;
-
- URL url;
-
- /**
- * Returns a pointer to the object referenced by this Ref. If the object
- * has been thrown away by the garbage collector, it will be
- * reconstituted. This method does everything necessary to ensure that the garbage
- * collector throws things away in Least Recently Used(LRU) order. Applications should
- * never override this method. The get() method effectively caches calls to
- * reconstitute().
- */
- public synchronized Image get() {
- Image t = check();
- if (t == null) {
- t = reconstitute();
- setThing(t);
- }
- return t;
- }
-
- /**
- * Create the Ref
- */
- AppletImageRef(URL url) {
- this.url = url;
- }
-
- /**
- * Flushes the cached object. Forces the next invocation of get() to
- * invoke reconstitute().
- */
- public synchronized void flush() {
- SoftReference<Image> s = soft;
- if (s != null) s.clear();
- soft = null;
- }
-
- /**
- * Sets the thing to the specified object.
- * @param thing the specified object
- */
- public synchronized void setThing(Image thing) {
- flush();
- soft = new SoftReference<>(thing);
- }
-
- /**
- * Checks to see what object is being pointed at by this Ref and returns it.
- */
- public synchronized Image check() {
- SoftReference<Image> s = soft;
- if (s == null) return null;
- return s.get();
- }
-
- /**
- * Reconsitute the image. Only called when the ref has been flushed.
- */
- public Image reconstitute() {
- Image img = Toolkit.getDefaultToolkit().createImage(new URLImageSource(url));
- return img;
- }
-}
--- a/src/java.desktop/share/classes/sun/applet/AppletListener.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved.
- * 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.applet;
-
-import java.util.EventListener;
-
-/**
- * Applet Listener interface. This interface is to be implemented
- * by objects interested in AppletEvents.
- *
- * @author Sunita Mani
- *
- * @deprecated The Applet API is deprecated. See the
- * <a href="../../java/applet/package-summary.html"> java.applet package
- * documentation</a> for further information.
- */
-@Deprecated(since = "9")
-public interface AppletListener extends EventListener {
- public void appletStateChanged(AppletEvent e);
-}
--- a/src/java.desktop/share/classes/sun/applet/AppletMessageHandler.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 1996, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.applet;
-
-import java.util.ResourceBundle;
-import java.util.MissingResourceException;
-import java.text.MessageFormat;
-
-/**
- * An hanlder of localized messages.
- *
- * @author Koji Uno
- */
-class AppletMessageHandler {
- private static ResourceBundle rb;
- private String baseKey = null;
-
- static {
- try {
- rb = ResourceBundle.getBundle
- ("sun.applet.resources.MsgAppletViewer");
- } catch (MissingResourceException e) {
- System.out.println(e.getMessage());
- System.exit(1);
- }
- }
-
- AppletMessageHandler(String baseKey) {
- this.baseKey = baseKey;
- }
-
- String getMessage(String key) {
- return rb.getString(getQualifiedKey(key));
- }
-
- String getMessage(String key, Object arg){
- String basemsgfmt = rb.getString(getQualifiedKey(key));
- MessageFormat msgfmt = new MessageFormat(basemsgfmt);
- Object msgobj[] = new Object[1];
- if (arg == null) {
- arg = "null"; // mimic java.io.PrintStream.print(String)
- }
- msgobj[0] = arg;
- return msgfmt.format(msgobj);
- }
-
- String getMessage(String key, Object arg1, Object arg2) {
- String basemsgfmt = rb.getString(getQualifiedKey(key));
- MessageFormat msgfmt = new MessageFormat(basemsgfmt);
- Object msgobj[] = new Object[2];
- if (arg1 == null) {
- arg1 = "null";
- }
- if (arg2 == null) {
- arg2 = "null";
- }
- msgobj[0] = arg1;
- msgobj[1] = arg2;
- return msgfmt.format(msgobj);
- }
-
- String getMessage(String key, Object arg1, Object arg2, Object arg3) {
- String basemsgfmt = rb.getString(getQualifiedKey(key));
- MessageFormat msgfmt = new MessageFormat(basemsgfmt);
- Object msgobj[] = new Object[3];
- if (arg1 == null) {
- arg1 = "null";
- }
- if (arg2 == null) {
- arg2 = "null";
- }
- if (arg3 == null) {
- arg3 = "null";
- }
- msgobj[0] = arg1;
- msgobj[1] = arg2;
- msgobj[2] = arg3;
- return msgfmt.format(msgobj);
- }
-
- String getMessage(String key, Object arg[]) {
- String basemsgfmt = rb.getString(getQualifiedKey(key));
- MessageFormat msgfmt = new MessageFormat(basemsgfmt);
- return msgfmt.format(arg);
- }
-
- String getQualifiedKey(String subKey) {
- return baseKey + "." + subKey;
- }
-}
--- a/src/java.desktop/share/classes/sun/applet/AppletObjectInputStream.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 1996, 1997, Oracle and/or its affiliates. All rights reserved.
- * 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-/*
- * COPYRIGHT goes here
- */
-
-package sun.applet;
-
-import java.io.*;
-import java.lang.reflect.Array;
-
-/**
- * This subclass of ObjectInputStream delegates loading of classes to
- * an existing ClassLoader.
- *
- * @deprecated The Applet API is deprecated. See the
- * <a href="../../java/applet/package-summary.html"> java.applet package
- * documentation</a> for further information.
- */
-@Deprecated(since = "9")
-class AppletObjectInputStream extends ObjectInputStream
-{
- private AppletClassLoader loader;
-
- /**
- * Loader must be non-null;
- */
-
- public AppletObjectInputStream(InputStream in, AppletClassLoader loader)
- throws IOException, StreamCorruptedException {
-
- super(in);
- if (loader == null) {
- throw new AppletIllegalArgumentException("appletillegalargumentexception.objectinputstream");
-
- }
- this.loader = loader;
- }
-
- /**
- * Make a primitive array class
- */
-
- private Class<?> primitiveType(char type) {
- switch (type) {
- case 'B': return byte.class;
- case 'C': return char.class;
- case 'D': return double.class;
- case 'F': return float.class;
- case 'I': return int.class;
- case 'J': return long.class;
- case 'S': return short.class;
- case 'Z': return boolean.class;
- default: return null;
- }
- }
-
- /**
- * Use the given ClassLoader rather than using the system class
- */
- protected Class<?> resolveClass(ObjectStreamClass classDesc)
- throws IOException, ClassNotFoundException {
-
- String cname = classDesc.getName();
- if (cname.startsWith("[")) {
- // An array
- Class<?> component; // component class
- int dcount; // dimension
- for (dcount=1; cname.charAt(dcount)=='['; dcount++) ;
- if (cname.charAt(dcount) == 'L') {
- component = loader.loadClass(cname.substring(dcount+1,
- cname.length()-1));
- } else {
- if (cname.length() != dcount+1) {
- throw new ClassNotFoundException(cname);// malformed
- }
- component = primitiveType(cname.charAt(dcount));
- }
- int dim[] = new int[dcount];
- for (int i=0; i<dcount; i++) {
- dim[i]=0;
- }
- return Array.newInstance(component, dim).getClass();
- } else {
- return loader.loadClass(cname);
- }
- }
-}
--- a/src/java.desktop/share/classes/sun/applet/AppletPanel.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1270 +0,0 @@
-/*
- * Copyright (c) 1995, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.applet;
-
-import java.applet.*;
-import java.awt.*;
-import java.awt.event.*;
-import java.io.*;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.JarURLConnection;
-import java.net.SocketPermission;
-import java.net.URL;
-import java.security.*;
-import java.util.*;
-import java.util.Locale;
-import java.util.concurrent.LinkedBlockingQueue;
-import sun.awt.AWTAccessor;
-import sun.awt.AppContext;
-import sun.awt.EmbeddedFrame;
-import sun.awt.SunToolkit;
-import sun.awt.util.PerformanceLogger;
-import sun.security.util.SecurityConstants;
-
-/**
- * Applet panel class. The panel manages and manipulates the
- * applet as it is being loaded. It forks a separate thread in a new
- * thread group to call the applet's init(), start(), stop(), and
- * destroy() methods.
- *
- * @deprecated The Applet API is deprecated. See the
- * <a href="../../java/applet/package-summary.html"> java.applet package
- * documentation</a> for further information.
- *
- * @author Arthur van Hoff
- */
-@SuppressWarnings({"serial"}) // JDK implementation class
-@Deprecated(since = "9")
-public
-abstract class AppletPanel extends Panel implements AppletStub, Runnable {
-
- /**
- * The applet (if loaded).
- */
- Applet applet;
-
-
- /**
- * The classloader for the applet.
- */
- protected AppletClassLoader loader;
-
- /* applet event ids */
- public static final int APPLET_DISPOSE = 0;
- public static final int APPLET_LOAD = 1;
- public static final int APPLET_INIT = 2;
- public static final int APPLET_START = 3;
- public static final int APPLET_STOP = 4;
- public static final int APPLET_DESTROY = 5;
- public static final int APPLET_QUIT = 6;
- public static final int APPLET_ERROR = 7;
-
- /* send to the parent to force relayout */
- public static final int APPLET_RESIZE = 51234;
-
- /* sent to a (distant) parent to indicate that the applet is being
- * loaded or as completed loading
- */
- public static final int APPLET_LOADING = 51235;
- public static final int APPLET_LOADING_COMPLETED = 51236;
-
- /**
- * The current status. One of:
- * APPLET_DISPOSE,
- * APPLET_LOAD,
- * APPLET_INIT,
- * APPLET_START,
- * APPLET_STOP,
- * APPLET_DESTROY,
- * APPLET_ERROR.
- */
- protected int status;
-
- /**
- * The thread for the applet.
- */
- protected Thread handler;
-
-
- /**
- * The initial applet size.
- */
- Dimension defaultAppletSize = new Dimension(10, 10);
-
- /**
- * The current applet size.
- */
- Dimension currentAppletSize = new Dimension(10, 10);
-
- /**
- * The thread to use during applet loading
- */
-
- Thread loaderThread = null;
-
- /**
- * Flag to indicate that a loading has been cancelled
- */
- boolean loadAbortRequest = false;
-
- /* abstract classes */
- protected abstract String getCode();
- protected abstract String getJarFiles();
-
- @Override
- public abstract int getWidth();
- @Override
- public abstract int getHeight();
- public abstract boolean hasInitialFocus();
-
- private static int threadGroupNumber = 0;
-
- protected void setupAppletAppContext() {
- // do nothing
- }
-
- /*
- * Creates a thread to run the applet. This method is called
- * each time an applet is loaded and reloaded.
- */
- synchronized void createAppletThread() {
- // Create a thread group for the applet, and start a new
- // thread to load the applet.
- String nm = "applet-" + getCode();
- loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey());
- loader.grab(); // Keep this puppy around!
-
- // 4668479: Option to turn off codebase lookup in AppletClassLoader
- // during resource requests. [stanley.ho]
- String param = getParameter("codebase_lookup");
-
- if (param != null && param.equals("false"))
- loader.setCodebaseLookup(false);
- else
- loader.setCodebaseLookup(true);
-
-
- ThreadGroup appletGroup = loader.getThreadGroup();
- handler = new Thread(appletGroup, this, "thread " + nm, 0, false);
- // set the context class loader for this thread
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- @Override
- public Object run() {
- handler.setContextClassLoader(loader);
- return null;
- }
- });
- handler.start();
- }
-
- void joinAppletThread() throws InterruptedException {
- if (handler != null) {
- handler.join();
- handler = null;
- }
- }
-
- void release() {
- if (loader != null) {
- loader.release();
- loader = null;
- }
- }
-
- /**
- * Construct an applet viewer and start the applet.
- */
- public void init() {
- try {
- // Get the width (if any)
- defaultAppletSize.width = getWidth();
- currentAppletSize.width = defaultAppletSize.width;
-
- // Get the height (if any)
- defaultAppletSize.height = getHeight();
- currentAppletSize.height = defaultAppletSize.height;
-
- } catch (NumberFormatException e) {
- // Turn on the error flag and let TagAppletPanel
- // do the right thing.
- status = APPLET_ERROR;
- showAppletStatus("badattribute.exception");
- showAppletLog("badattribute.exception");
- showAppletException(e);
- }
-
- setLayout(new BorderLayout());
-
- createAppletThread();
- }
-
- /**
- * Minimum size
- */
- @Override
- @SuppressWarnings("deprecation")
- public Dimension minimumSize() {
- return new Dimension(defaultAppletSize.width,
- defaultAppletSize.height);
- }
-
- /**
- * Preferred size
- */
- @Override
- @SuppressWarnings("deprecation")
- public Dimension preferredSize() {
- return new Dimension(currentAppletSize.width,
- currentAppletSize.height);
- }
-
- private AppletListener listeners;
-
- /**
- * AppletEvent Queue
- */
- private LinkedBlockingQueue<Integer> queue = null;
-
- public synchronized void addAppletListener(AppletListener l) {
- listeners = AppletEventMulticaster.add(listeners, l);
- }
-
- public synchronized void removeAppletListener(AppletListener l) {
- listeners = AppletEventMulticaster.remove(listeners, l);
- }
-
- /**
- * Dispatch event to the listeners..
- */
- public void dispatchAppletEvent(int id, Object argument) {
- //System.out.println("SEND= " + id);
- if (listeners != null) {
- AppletEvent evt = new AppletEvent(this, id, argument);
- listeners.appletStateChanged(evt);
- }
- }
-
- /**
- * Send an event. Queue it for execution by the handler thread.
- */
- public void sendEvent(int id) {
- synchronized(this) {
- if (queue == null) {
- //System.out.println("SEND0= " + id);
- queue = new LinkedBlockingQueue<>();
- }
- boolean inserted = queue.add(id);
- notifyAll();
- }
- if (id == APPLET_QUIT) {
- try {
- joinAppletThread(); // Let the applet event handler exit
- } catch (InterruptedException e) {
- }
-
- // AppletClassLoader.release() must be called by a Thread
- // not within the applet's ThreadGroup
- if (loader == null)
- loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey());
- release();
- }
- }
-
- /**
- * Get an event from the queue.
- */
- synchronized AppletEvent getNextEvent() throws InterruptedException {
- while (queue == null || queue.isEmpty()) {
- wait();
- }
- int eventId = queue.take();
- return new AppletEvent(this, eventId, null);
- }
-
- boolean emptyEventQueue() {
- if ((queue == null) || (queue.isEmpty()))
- return true;
- else
- return false;
- }
-
- /**
- * This kludge is specific to get over AccessControlException thrown during
- * Applet.stop() or destroy() when static thread is suspended. Set a flag
- * in AppletClassLoader to indicate that an
- * AccessControlException for RuntimePermission "modifyThread" or
- * "modifyThreadGroup" had occurred.
- */
- private void setExceptionStatus(AccessControlException e) {
- Permission p = e.getPermission();
- if (p instanceof RuntimePermission) {
- if (p.getName().startsWith("modifyThread")) {
- if (loader == null)
- loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey());
- loader.setExceptionStatus();
- }
- }
- }
-
- /**
- * Execute applet events.
- * Here is the state transition diagram
- *
- * <pre>{@literal
- * Note: (XXX) is the action
- * APPLET_XXX is the state
- * (applet code loaded) --> APPLET_LOAD -- (applet init called)--> APPLET_INIT --
- * (applet start called) --> APPLET_START -- (applet stop called) --> APPLET_STOP --
- * (applet destroyed called) --> APPLET_DESTROY --> (applet gets disposed) -->
- * APPLET_DISPOSE --> ...
- * }</pre>
- *
- * In the legacy lifecycle model. The applet gets loaded, inited and started. So it stays
- * in the APPLET_START state unless the applet goes away(refresh page or leave the page).
- * So the applet stop method called and the applet enters APPLET_STOP state. Then if the applet
- * is revisited, it will call applet start method and enter the APPLET_START state and stay there.
- *
- * In the modern lifecycle model. When the applet first time visited, it is same as legacy lifecycle
- * model. However, when the applet page goes away. It calls applet stop method and enters APPLET_STOP
- * state and then applet destroyed method gets called and enters APPLET_DESTROY state.
- *
- * This code is also called by AppletViewer. In AppletViewer "Restart" menu, the applet is jump from
- * APPLET_STOP to APPLET_DESTROY and to APPLET_INIT .
- *
- * Also, the applet can jump from APPLET_INIT state to APPLET_DESTROY (in Netscape/Mozilla case).
- * Same as APPLET_LOAD to
- * APPLET_DISPOSE since all of this are triggered by browser.
- *
- */
- @Override
- public void run() {
-
- Thread curThread = Thread.currentThread();
- if (curThread == loaderThread) {
- // if we are in the loader thread, cause
- // loading to occur. We may exit this with
- // status being APPLET_DISPOSE, APPLET_ERROR,
- // or APPLET_LOAD
- runLoader();
- return;
- }
-
- boolean disposed = false;
- while (!disposed && !curThread.isInterrupted()) {
- AppletEvent evt;
- try {
- evt = getNextEvent();
- } catch (InterruptedException e) {
- showAppletStatus("bail");
- return;
- }
-
- //showAppletStatus("EVENT = " + evt.getID());
- try {
- switch (evt.getID()) {
- case APPLET_LOAD:
- if (!okToLoad()) {
- break;
- }
- // This complexity allows loading of applets to be
- // interruptable. The actual thread loading runs
- // in a separate thread, so it can be interrupted
- // without harming the applet thread.
- // So that we don't have to worry about
- // concurrency issues, the main applet thread waits
- // until the loader thread terminates.
- // (one way or another).
- if (loaderThread == null) {
- setLoaderThread(new Thread(null, this,
- "AppletLoader", 0, false));
- loaderThread.start();
- // we get to go to sleep while this runs
- loaderThread.join();
- setLoaderThread(null);
- } else {
- // REMIND: issue an error -- this case should never
- // occur.
- }
- break;
-
- case APPLET_INIT:
- // AppletViewer "Restart" will jump from destroy method to
- // init, that is why we need to check status w/ APPLET_DESTROY
- if (status != APPLET_LOAD && status != APPLET_DESTROY) {
- showAppletStatus("notloaded");
- break;
- }
- applet.resize(defaultAppletSize);
-
- if (PerformanceLogger.loggingEnabled()) {
- PerformanceLogger.setTime("Applet Init");
- PerformanceLogger.outputLog();
- }
- applet.init();
-
- //Need the default(fallback) font to be created in this AppContext
- Font f = getFont();
- if (f == null ||
- "dialog".equals(f.getFamily().toLowerCase(Locale.ENGLISH)) &&
- f.getSize() == 12 && f.getStyle() == Font.PLAIN) {
- setFont(new Font(Font.DIALOG, Font.PLAIN, 12));
- }
-
- // Validate the applet in event dispatch thread
- // to avoid deadlock.
- try {
- final AppletPanel p = this;
- Runnable r = new Runnable() {
- @Override
- public void run() {
- p.validate();
- }
- };
- AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
- }
- catch(InterruptedException ie) {
- }
- catch(InvocationTargetException ite) {
- }
-
- status = APPLET_INIT;
- showAppletStatus("inited");
- break;
-
- case APPLET_START:
- {
- if (status != APPLET_INIT && status != APPLET_STOP) {
- showAppletStatus("notinited");
- break;
- }
- applet.resize(currentAppletSize);
- applet.start();
-
- // Validate and show the applet in event dispatch thread
- // to avoid deadlock.
- try {
- final AppletPanel p = this;
- final Applet a = applet;
- Runnable r = new Runnable() {
- @Override
- public void run() {
- p.validate();
- a.setVisible(true);
-
- // Fix for BugTraq ID 4041703.
- // Set the default focus for an applet.
- if (hasInitialFocus()) {
- setDefaultFocus();
- }
- }
- };
- AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
- }
- catch(InterruptedException ie) {
- }
- catch(InvocationTargetException ite) {
- }
-
- status = APPLET_START;
- showAppletStatus("started");
- break;
- }
-
- case APPLET_STOP:
- if (status != APPLET_START) {
- showAppletStatus("notstarted");
- break;
- }
- status = APPLET_STOP;
-
- // Hide the applet in event dispatch thread
- // to avoid deadlock.
- try {
- final Applet a = applet;
- Runnable r = new Runnable() {
- @Override
- public void run() {
- a.setVisible(false);
- }
- };
- AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
- }
- catch(InterruptedException ie) {
- }
- catch(InvocationTargetException ite) {
- }
-
-
- // During Applet.stop(), any AccessControlException on an involved Class remains in
- // the "memory" of the AppletClassLoader. If the same instance of the ClassLoader is
- // reused, the same exception will occur during class loading. Set the AppletClassLoader's
- // exceptionStatusSet flag to allow recognition of what had happened
- // when reusing AppletClassLoader object.
- try {
- applet.stop();
- } catch (java.security.AccessControlException e) {
- setExceptionStatus(e);
- // rethrow exception to be handled as it normally would be.
- throw e;
- }
- showAppletStatus("stopped");
- break;
-
- case APPLET_DESTROY:
- if (status != APPLET_STOP && status != APPLET_INIT) {
- showAppletStatus("notstopped");
- break;
- }
- status = APPLET_DESTROY;
-
- // During Applet.destroy(), any AccessControlException on an involved Class remains in
- // the "memory" of the AppletClassLoader. If the same instance of the ClassLoader is
- // reused, the same exception will occur during class loading. Set the AppletClassLoader's
- // exceptionStatusSet flag to allow recognition of what had happened
- // when reusing AppletClassLoader object.
- try {
- applet.destroy();
- } catch (java.security.AccessControlException e) {
- setExceptionStatus(e);
- // rethrow exception to be handled as it normally would be.
- throw e;
- }
- showAppletStatus("destroyed");
- break;
-
- case APPLET_DISPOSE:
- if (status != APPLET_DESTROY && status != APPLET_LOAD) {
- showAppletStatus("notdestroyed");
- break;
- }
- status = APPLET_DISPOSE;
-
- try {
- final Applet a = applet;
- Runnable r = new Runnable() {
- @Override
- public void run() {
- remove(a);
- }
- };
- AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
- }
- catch(InterruptedException ie)
- {
- }
- catch(InvocationTargetException ite)
- {
- }
- applet = null;
- showAppletStatus("disposed");
- disposed = true;
- break;
-
- case APPLET_QUIT:
- return;
- }
- } catch (Exception e) {
- status = APPLET_ERROR;
- if (e.getMessage() != null) {
- showAppletStatus("exception2", e.getClass().getName(),
- e.getMessage());
- } else {
- showAppletStatus("exception", e.getClass().getName());
- }
- showAppletException(e);
- } catch (ThreadDeath e) {
- showAppletStatus("death");
- return;
- } catch (Error e) {
- status = APPLET_ERROR;
- if (e.getMessage() != null) {
- showAppletStatus("error2", e.getClass().getName(),
- e.getMessage());
- } else {
- showAppletStatus("error", e.getClass().getName());
- }
- showAppletException(e);
- }
- clearLoadAbortRequest();
- }
- }
-
- /**
- * Gets most recent focus owner component associated with the given window.
- * It does that without calling Window.getMostRecentFocusOwner since it
- * provides its own logic contradicting with setDefautlFocus. Instead, it
- * calls KeyboardFocusManager directly.
- */
- private Component getMostRecentFocusOwnerForWindow(Window w) {
- return AWTAccessor.getKeyboardFocusManagerAccessor()
- .getMostRecentFocusOwner(w);
- }
-
- /*
- * Fix for BugTraq ID 4041703.
- * Set the focus to a reasonable default for an Applet.
- */
- private void setDefaultFocus() {
- Component toFocus = null;
- Container parent = getParent();
-
- if(parent != null) {
- if (parent instanceof Window) {
- toFocus = getMostRecentFocusOwnerForWindow((Window)parent);
- if (toFocus == parent || toFocus == null) {
- toFocus = parent.getFocusTraversalPolicy().
- getInitialComponent((Window)parent);
- }
- } else if (parent.isFocusCycleRoot()) {
- toFocus = parent.getFocusTraversalPolicy().
- getDefaultComponent(parent);
- }
- }
-
- if (toFocus != null) {
- if (parent instanceof EmbeddedFrame) {
- ((EmbeddedFrame) parent).synthesizeWindowActivation(true);
- }
- // EmbeddedFrame might have focus before the applet was added.
- // Thus after its activation the most recent focus owner will be
- // restored. We need the applet's initial focusabled component to
- // be focused here.
- toFocus.requestFocusInWindow();
- }
- }
-
- /**
- * Load the applet into memory.
- * Runs in a seperate (and interruptible) thread from the rest of the
- * applet event processing so that it can be gracefully interrupted from
- * things like HotJava.
- */
- @SuppressWarnings("deprecation")
- private void runLoader() {
- if (status != APPLET_DISPOSE) {
- showAppletStatus("notdisposed");
- return;
- }
-
- dispatchAppletEvent(APPLET_LOADING, null);
-
- // REMIND -- might be cool to visually indicate loading here --
- // maybe do animation?
- status = APPLET_LOAD;
-
- // Create a class loader
- loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey());
-
- // Load the archives if present.
- // REMIND - this probably should be done in a separate thread,
- // or at least the additional archives (epll).
-
- String code = getCode();
-
- // setup applet AppContext
- // this must be called before loadJarFiles
- setupAppletAppContext();
-
- try {
- loadJarFiles(loader);
- applet = createApplet(loader);
- } catch (ClassNotFoundException e) {
- status = APPLET_ERROR;
- showAppletStatus("notfound", code);
- showAppletLog("notfound", code);
- showAppletException(e);
- return;
- } catch (InstantiationException e) {
- status = APPLET_ERROR;
- showAppletStatus("nocreate", code);
- showAppletLog("nocreate", code);
- showAppletException(e);
- return;
- } catch (IllegalAccessException e) {
- status = APPLET_ERROR;
- showAppletStatus("noconstruct", code);
- showAppletLog("noconstruct", code);
- showAppletException(e);
- // sbb -- I added a return here
- return;
- } catch (Exception e) {
- status = APPLET_ERROR;
- showAppletStatus("exception", e.getMessage());
- showAppletException(e);
- return;
- } catch (ThreadDeath e) {
- status = APPLET_ERROR;
- showAppletStatus("death");
- return;
- } catch (Error e) {
- status = APPLET_ERROR;
- showAppletStatus("error", e.getMessage());
- showAppletException(e);
- return;
- } finally {
- // notify that loading is no longer going on
- dispatchAppletEvent(APPLET_LOADING_COMPLETED, null);
- }
-
- // Fixed #4508194: NullPointerException thrown during
- // quick page switch
- //
- if (applet != null)
- {
- // Stick it in the frame
- applet.setStub(this);
- applet.hide();
- add("Center", applet);
- showAppletStatus("loaded");
- validate();
- }
- }
-
- protected Applet createApplet(final AppletClassLoader loader) throws ClassNotFoundException,
- IllegalAccessException, IOException, InstantiationException, InterruptedException {
- String code = getCode();
-
- if (code != null) {
- applet = (Applet)loader.loadCode(code).newInstance();
- } else {
- String msg = "nocode";
- status = APPLET_ERROR;
- showAppletStatus(msg);
- showAppletLog(msg);
- repaint();
- }
-
- // Determine the JDK level that the applet targets.
- // This is critical for enabling certain backward
- // compatibility switch if an applet is a JDK 1.1
- // applet. [stanley.ho]
- findAppletJDKLevel(applet);
-
- if (Thread.interrupted()) {
- try {
- status = APPLET_DISPOSE; // APPLET_ERROR?
- applet = null;
- // REMIND: This may not be exactly the right thing: the
- // status is set by the stop button and not necessarily
- // here.
- showAppletStatus("death");
- } finally {
- Thread.currentThread().interrupt(); // resignal interrupt
- }
- return null;
- }
- return applet;
- }
-
- protected void loadJarFiles(AppletClassLoader loader) throws IOException,
- InterruptedException {
- // Load the archives if present.
- // REMIND - this probably should be done in a separate thread,
- // or at least the additional archives (epll).
- String jarFiles = getJarFiles();
-
- if (jarFiles != null) {
- StringTokenizer st = new StringTokenizer(jarFiles, ",", false);
- while(st.hasMoreTokens()) {
- String tok = st.nextToken().trim();
- try {
- loader.addJar(tok);
- } catch (IllegalArgumentException e) {
- // bad archive name
- continue;
- }
- }
- }
- }
-
- /**
- * Request that the loading of the applet be stopped.
- */
- protected synchronized void stopLoading() {
- // REMIND: fill in the body
- if (loaderThread != null) {
- //System.out.println("Interrupting applet loader thread: " + loaderThread);
- loaderThread.interrupt();
- } else {
- setLoadAbortRequest();
- }
- }
-
-
- protected synchronized boolean okToLoad() {
- return !loadAbortRequest;
- }
-
- protected synchronized void clearLoadAbortRequest() {
- loadAbortRequest = false;
- }
-
- protected synchronized void setLoadAbortRequest() {
- loadAbortRequest = true;
- }
-
-
- private synchronized void setLoaderThread(Thread loaderThread) {
- this.loaderThread = loaderThread;
- }
-
- /**
- * Return true when the applet has been started.
- */
- @Override
- public boolean isActive() {
- return status == APPLET_START;
- }
-
-
- private EventQueue appEvtQ = null;
- /**
- * Is called when the applet wants to be resized.
- */
- @Override
- public void appletResize(int width, int height) {
- currentAppletSize.width = width;
- currentAppletSize.height = height;
- final Dimension currentSize = new Dimension(currentAppletSize.width,
- currentAppletSize.height);
-
- if(loader != null) {
- AppContext appCtxt = loader.getAppContext();
- if(appCtxt != null)
- appEvtQ = (java.awt.EventQueue)appCtxt.get(AppContext.EVENT_QUEUE_KEY);
- }
-
- final AppletPanel ap = this;
- if (appEvtQ != null){
- appEvtQ.postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(),
- new Runnable() {
- @Override
- public void run() {
- if (ap != null) {
- ap.dispatchAppletEvent(
- APPLET_RESIZE,
- currentSize);
- }
- }
- }));
- }
- }
-
- @Override
- public void setBounds(int x, int y, int width, int height) {
- super.setBounds(x, y, width, height);
- currentAppletSize.width = width;
- currentAppletSize.height = height;
- }
-
- public Applet getApplet() {
- return applet;
- }
-
- /**
- * Status line. Called by the AppletPanel to provide
- * feedback on the Applet's state.
- */
- protected void showAppletStatus(String status) {
- getAppletContext().showStatus(amh.getMessage(status));
- }
-
- protected void showAppletStatus(String status, Object arg) {
- getAppletContext().showStatus(amh.getMessage(status, arg));
- }
- protected void showAppletStatus(String status, Object arg1, Object arg2) {
- getAppletContext().showStatus(amh.getMessage(status, arg1, arg2));
- }
-
- /**
- * Called by the AppletPanel to print to the log.
- */
- protected void showAppletLog(String msg) {
- System.out.println(amh.getMessage(msg));
- }
-
- protected void showAppletLog(String msg, Object arg) {
- System.out.println(amh.getMessage(msg, arg));
- }
-
- /**
- * Called by the AppletPanel to provide
- * feedback when an exception has happened.
- */
- protected void showAppletException(Throwable t) {
- t.printStackTrace();
- repaint();
- }
-
- /**
- * Get caching key for classloader cache
- */
- public String getClassLoaderCacheKey()
- {
- /**
- * Fixed #4501142: Classloader sharing policy doesn't
- * take "archive" into account. This will be overridden
- * by Java Plug-in. [stanleyh]
- */
- return getCodeBase().toString();
- }
-
- /**
- * The class loaders
- */
- private static HashMap<String, AppletClassLoader> classloaders = new HashMap<>();
-
- /**
- * Flush a class loader.
- */
- public static synchronized void flushClassLoader(String key) {
- classloaders.remove(key);
- }
-
- /**
- * Flush all class loaders.
- */
- public static synchronized void flushClassLoaders() {
- classloaders = new HashMap<>();
- }
-
- /**
- * This method actually creates an AppletClassLoader.
- *
- * It can be override by subclasses (such as the Plug-in)
- * to provide different classloaders.
- */
- protected AppletClassLoader createClassLoader(final URL codebase) {
- return new AppletClassLoader(codebase);
- }
-
- /**
- * Get a class loader. Create in a restricted context
- */
- synchronized AppletClassLoader getClassLoader(final URL codebase, final String key) {
- AppletClassLoader c = classloaders.get(key);
- if (c == null) {
- AccessControlContext acc =
- getAccessControlContext(codebase);
- c = AccessController.doPrivileged(
- new PrivilegedAction<AppletClassLoader>() {
- @Override
- public AppletClassLoader run() {
- AppletClassLoader ac = createClassLoader(codebase);
- /* Should the creation of the classloader be
- * within the class synchronized block? Since
- * this class is used by the plugin, take care
- * to avoid deadlocks, or specialize
- * AppletPanel within the plugin. It may take
- * an arbitrary amount of time to create a
- * class loader (involving getting Jar files
- * etc.) and may block unrelated applets from
- * finishing createAppletThread (due to the
- * class synchronization). If
- * createAppletThread does not finish quickly,
- * the applet cannot process other messages,
- * particularly messages such as destroy
- * (which timeout when called from the browser).
- */
- synchronized (getClass()) {
- AppletClassLoader res = classloaders.get(key);
- if (res == null) {
- classloaders.put(key, ac);
- return ac;
- } else {
- return res;
- }
- }
- }
- },acc);
- }
- return c;
- }
-
- /**
- * get the context for the AppletClassLoader we are creating.
- * the context is granted permission to create the class loader,
- * connnect to the codebase, and whatever else the policy grants
- * to all codebases.
- */
- private AccessControlContext getAccessControlContext(final URL codebase) {
-
- PermissionCollection perms = AccessController.doPrivileged(
- new PrivilegedAction<PermissionCollection>() {
- @Override
- public PermissionCollection run() {
- Policy p = java.security.Policy.getPolicy();
- if (p != null) {
- return p.getPermissions(new CodeSource(null,
- (java.security.cert.Certificate[]) null));
- } else {
- return null;
- }
- }
- });
-
- if (perms == null)
- perms = new Permissions();
-
- //XXX: this is needed to be able to create the classloader itself!
-
- perms.add(SecurityConstants.CREATE_CLASSLOADER_PERMISSION);
-
- Permission p;
- java.net.URLConnection urlConnection = null;
- try {
- urlConnection = codebase.openConnection();
- p = urlConnection.getPermission();
- } catch (java.io.IOException ioe) {
- p = null;
- }
-
- if (p != null)
- perms.add(p);
-
- if (p instanceof FilePermission) {
-
- String path = p.getName();
-
- int endIndex = path.lastIndexOf(File.separatorChar);
-
- if (endIndex != -1) {
- path = path.substring(0, endIndex+1);
-
- if (path.endsWith(File.separator)) {
- path += "-";
- }
- perms.add(new FilePermission(path,
- SecurityConstants.FILE_READ_ACTION));
- }
- } else {
- URL locUrl = codebase;
- if (urlConnection instanceof JarURLConnection) {
- locUrl = ((JarURLConnection)urlConnection).getJarFileURL();
- }
- String host = locUrl.getHost();
- if (host != null && (host.length() > 0))
- perms.add(new SocketPermission(host,
- SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION));
- }
-
- ProtectionDomain domain =
- new ProtectionDomain(new CodeSource(codebase,
- (java.security.cert.Certificate[]) null), perms);
- AccessControlContext acc =
- new AccessControlContext(new ProtectionDomain[] { domain });
-
- return acc;
- }
-
- public Thread getAppletHandlerThread() {
- return handler;
- }
-
- public int getAppletWidth() {
- return currentAppletSize.width;
- }
-
- public int getAppletHeight() {
- return currentAppletSize.height;
- }
-
- public static void changeFrameAppContext(Frame frame, AppContext newAppContext)
- {
- // Fixed #4754451: Applet can have methods running on main
- // thread event queue.
- //
- // The cause of this bug is that the frame of the applet
- // is created in main thread group. Thus, when certain
- // AWT/Swing events are generated, the events will be
- // dispatched through the wrong event dispatch thread.
- //
- // To fix this, we rearrange the AppContext with the frame,
- // so the proper event queue will be looked up.
- //
- // Swing also maintains a Frame list for the AppContext,
- // so we will have to rearrange it as well.
-
- // Check if frame's AppContext has already been set properly
- AppContext oldAppContext = SunToolkit.targetToAppContext(frame);
-
- if (oldAppContext == newAppContext)
- return;
-
- // Synchronization on Window.class is needed for locking the
- // critical section of the window list in AppContext.
- synchronized (Window.class)
- {
- WeakReference<Window> weakRef = null;
- // Remove frame from the Window list in wrong AppContext
- {
- // Lookup current frame's AppContext
- @SuppressWarnings("unchecked")
- Vector<WeakReference<Window>> windowList =
- (Vector<WeakReference<Window>>)oldAppContext.get(Window.class);
- if (windowList != null) {
- for (WeakReference<Window> ref : windowList) {
- if (ref.get() == frame) {
- weakRef = ref;
- break;
- }
- }
- // Remove frame from wrong AppContext
- if (weakRef != null)
- windowList.remove(weakRef);
- }
- }
-
- // Put the frame into the applet's AppContext map
- SunToolkit.insertTargetMapping(frame, newAppContext);
-
- // Insert frame into the Window list in the applet's AppContext map
- {
- @SuppressWarnings("unchecked")
- Vector<WeakReference<Window>> windowList =
- (Vector<WeakReference<Window>>)newAppContext.get(Window.class);
- if (windowList == null) {
- windowList = new Vector<WeakReference<Window>>();
- newAppContext.put(Window.class, windowList);
- }
- // use the same weakRef here as it is used elsewhere
- windowList.add(weakRef);
- }
- }
- }
-
- // Flag to indicate if applet is targeted for JDK 1.1.
- private boolean jdk11Applet = false;
-
- // Flag to indicate if applet is targeted for JDK 1.2.
- private boolean jdk12Applet = false;
-
- /**
- * Determine JDK level of an applet.
- */
- private void findAppletJDKLevel(Applet applet)
- {
- // To determine the JDK level of an applet, the
- // most reliable way is to check the major version
- // of the applet class file.
-
- // synchronized on applet class object, so calling from
- // different instances of the same applet will be
- // serialized.
- Class<?> appletClass = applet.getClass();
-
- synchronized(appletClass) {
- // Determine if the JDK level of an applet has been
- // checked before.
- Boolean jdk11Target = loader.isJDK11Target(appletClass);
- Boolean jdk12Target = loader.isJDK12Target(appletClass);
-
- // if applet JDK level has been checked before, retrieve
- // value and return.
- if (jdk11Target != null || jdk12Target != null) {
- jdk11Applet = (jdk11Target == null) ? false : jdk11Target.booleanValue();
- jdk12Applet = (jdk12Target == null) ? false : jdk12Target.booleanValue();
- return;
- }
-
- String name = appletClass.getName();
-
- // first convert any '.' to '/'
- name = name.replace('.', '/');
-
- // append .class
- final String resourceName = name + ".class";
-
- byte[] classHeader = new byte[8];
-
- try (InputStream is = AccessController.doPrivileged(
- (PrivilegedAction<InputStream>) () -> loader.getResourceAsStream(resourceName))) {
-
- // Read the first 8 bytes of the class file
- int byteRead = is.read(classHeader, 0, 8);
-
- // return if the header is not read in entirely
- // for some reasons.
- if (byteRead != 8)
- return;
- }
- catch (IOException e) {
- return;
- }
-
- // Check major version in class file header
- int major_version = readShort(classHeader, 6);
-
- // Major version in class file is as follows:
- // 45 - JDK 1.1
- // 46 - JDK 1.2
- // 47 - JDK 1.3
- // 48 - JDK 1.4
- // 49 - JDK 1.5
- if (major_version < 46)
- jdk11Applet = true;
- else if (major_version == 46)
- jdk12Applet = true;
-
- // Store applet JDK level in AppContext for later lookup,
- // e.g. page switch.
- loader.setJDK11Target(appletClass, jdk11Applet);
- loader.setJDK12Target(appletClass, jdk12Applet);
- }
- }
-
- /**
- * Return true if applet is targeted to JDK 1.1.
- */
- protected boolean isJDK11Applet() {
- return jdk11Applet;
- }
-
- /**
- * Return true if applet is targeted to JDK1.2.
- */
- protected boolean isJDK12Applet() {
- return jdk12Applet;
- }
-
- /**
- * Read short from byte array.
- */
- private int readShort(byte[] b, int off) {
- int hi = readByte(b[off]);
- int lo = readByte(b[off + 1]);
- return (hi << 8) | lo;
- }
-
- private int readByte(byte b) {
- return ((int)b) & 0xFF;
- }
-
-
- private static AppletMessageHandler amh = new AppletMessageHandler("appletpanel");
-}
--- a/src/java.desktop/share/classes/sun/applet/AppletProps.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,227 +0,0 @@
-/*
- * Copyright (c) 1995, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.applet;
-
-import java.awt.*;
-import java.io.*;
-import java.util.Properties;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedExceptionAction;
-import java.security.PrivilegedActionException;
-
-import sun.security.action.*;
-
-@SuppressWarnings("serial") // JDK implementation class
-@Deprecated(since = "9")
-class AppletProps extends Frame {
-
- TextField proxyHost;
- TextField proxyPort;
- Choice accessMode;
-
- @SuppressWarnings("deprecation")
- AppletProps() {
- setTitle(amh.getMessage("title"));
- Panel p = new Panel();
- p.setLayout(new GridLayout(0, 2));
-
- p.add(new Label(amh.getMessage("label.http.server", "Http proxy server:")));
- p.add(proxyHost = new TextField());
-
- p.add(new Label(amh.getMessage("label.http.proxy")));
- p.add(proxyPort = new TextField());
-
- p.add(new Label(amh.getMessage("label.class")));
- p.add(accessMode = new Choice());
- accessMode.addItem(amh.getMessage("choice.class.item.restricted"));
- accessMode.addItem(amh.getMessage("choice.class.item.unrestricted"));
-
- add("Center", p);
- p = new Panel();
- p.add(new Button(amh.getMessage("button.apply")));
- p.add(new Button(amh.getMessage("button.reset")));
- p.add(new Button(amh.getMessage("button.cancel")));
- add("South", p);
- move(200, 150);
- pack();
- reset();
- }
-
- void reset() {
- AppletSecurity security = (AppletSecurity) System.getSecurityManager();
- if (security != null)
- security.reset();
-
- String proxyhost = AccessController.doPrivileged(
- new GetPropertyAction("http.proxyHost"));
- String proxyport = AccessController.doPrivileged(
- new GetPropertyAction("http.proxyPort"));
-
- Boolean tmp = AccessController.doPrivileged(
- new GetBooleanAction("package.restrict.access.sun"));
-
- boolean packageRestrict = tmp.booleanValue();
- if (packageRestrict) {
- accessMode.select(amh.getMessage("choice.class.item.restricted"));
- } else {
- accessMode.select(amh.getMessage("choice.class.item.unrestricted"));
- }
-
- if (proxyhost != null) {
- proxyHost.setText(proxyhost);
- proxyPort.setText(proxyport);
- } else {
- proxyHost.setText("");
- proxyPort.setText("");
- }
- }
-
- @SuppressWarnings("deprecation")
- void apply() {
- String proxyHostValue = proxyHost.getText().trim();
- String proxyPortValue = proxyPort.getText().trim();
-
- // Get properties
- final Properties props = AccessController.doPrivileged(
- new PrivilegedAction<Properties>() {
- public Properties run() {
- return System.getProperties();
- }
- });
-
- if (proxyHostValue.length() != 0) {
- /* 4066402 */
- /* Check for parsable value in proxy port number field before */
- /* applying. Display warning to user until parsable value is */
- /* entered. */
- int proxyPortNumber = 0;
- try {
- proxyPortNumber = Integer.parseInt(proxyPortValue);
- } catch (NumberFormatException e) {}
-
- if (proxyPortNumber <= 0) {
- proxyPort.selectAll();
- proxyPort.requestFocus();
- (new AppletPropsErrorDialog(this,
- amh.getMessage("title.invalidproxy"),
- amh.getMessage("label.invalidproxy"),
- amh.getMessage("button.ok"))).show();
- return;
- }
- /* end 4066402 */
-
- props.put("http.proxyHost", proxyHostValue);
- props.put("http.proxyPort", proxyPortValue);
- } else {
- props.put("http.proxyHost", "");
- }
-
- if (amh.getMessage("choice.class.item.restricted").equals(accessMode.getSelectedItem())) {
- props.put("package.restrict.access.sun", "true");
- } else {
- props.put("package.restrict.access.sun", "false");
- }
-
- // Save properties
- try {
- reset();
- AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
- public Object run() throws IOException {
- File dotAV = Main.theUserPropertiesFile;
- FileOutputStream out = new FileOutputStream(dotAV);
- Properties avProps = new Properties();
- for (int i = 0; i < Main.avDefaultUserProps.length; i++) {
- String avKey = Main.avDefaultUserProps[i][0];
- avProps.setProperty(avKey, props.getProperty(avKey));
- }
- avProps.store(out, amh.getMessage("prop.store"));
- out.close();
- return null;
- }
- });
- hide();
- } catch (java.security.PrivilegedActionException e) {
- System.out.println(amh.getMessage("apply.exception",
- e.getException()));
- // XXX what's the general feeling on stack traces to System.out?
- e.printStackTrace();
- reset();
- }
- }
-
- @SuppressWarnings("deprecation")
- public boolean action(Event evt, Object obj) {
- if (amh.getMessage("button.apply").equals(obj)) {
- apply();
- return true;
- }
- if (amh.getMessage("button.reset").equals(obj)) {
- reset();
- return true;
- }
- if (amh.getMessage("button.cancel").equals(obj)) {
- reset();
- hide();
- return true;
- }
- return false;
- }
-
- private static AppletMessageHandler amh = new AppletMessageHandler("appletprops");
-
-}
-
-/* 4066432 */
-/* Dialog class to display property-related errors to user */
-@SuppressWarnings("serial") // JDK implementation class
-@Deprecated(since = "9")
-class AppletPropsErrorDialog extends Dialog {
- @SuppressWarnings("deprecation")
- public AppletPropsErrorDialog(Frame parent, String title, String message,
- String buttonText) {
- super(parent, title, true);
- Panel p = new Panel();
- add("Center", new Label(message));
- p.add(new Button(buttonText));
- add("South", p);
- pack();
-
- Dimension dDim = size();
- Rectangle fRect = parent.bounds();
- move(fRect.x + ((fRect.width - dDim.width) / 2),
- fRect.y + ((fRect.height - dDim.height) / 2));
- }
-
- @SuppressWarnings("deprecation")
- public boolean action(Event event, Object object) {
- hide();
- dispose();
- return true;
- }
-}
-
-/* end 4066432 */
--- a/src/java.desktop/share/classes/sun/applet/AppletResourceLoader.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 1996, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.applet;
-
-import java.net.URL;
-import java.awt.Image;
-
-/**
- * Part of this class still remains only to support legacy, 100%-impure
- * applications such as HotJava 1.0.1.
- */
-@Deprecated
-public class AppletResourceLoader {
- public static Image getImage(URL url) {
- return AppletViewer.getCachedImage(url);
- }
-
- public static void flushImages() {
- AppletViewer.flushImageCache();
- }
-}
--- a/src/java.desktop/share/classes/sun/applet/AppletSecurityException.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 1995, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.applet;
-
-/**
- * An applet security exception.
- *
- * @author Arthur van Hoff
- */
-@SuppressWarnings("serial") // JDK-implementation class
-public
-class AppletSecurityException extends SecurityException {
- private String key = null;
- private Object msgobj[] = null;
-
- public AppletSecurityException(String name) {
- super(name);
- this.key = name;
- }
-
- public AppletSecurityException(String name, String arg) {
- this(name);
- msgobj = new Object[1];
- msgobj[0] = (Object)arg;
- }
-
- public AppletSecurityException(String name, String arg1, String arg2) {
- this(name);
- msgobj = new Object[2];
- msgobj[0] = (Object)arg1;
- msgobj[1] = (Object)arg2;
- }
-
- public String getLocalizedMessage() {
- if( msgobj != null)
- return amh.getMessage(key, msgobj);
- else
- return amh.getMessage(key);
- }
-
- private static AppletMessageHandler amh = new AppletMessageHandler("appletsecurityexception");
-
-}
--- a/src/java.desktop/share/classes/sun/applet/AppletViewer.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1312 +0,0 @@
-/*
- * Copyright (c) 1995, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.applet;
-
-import java.util.*;
-import java.io.*;
-import java.awt.*;
-import java.awt.event.*;
-import java.awt.print.*;
-import javax.print.attribute.*;
-import java.applet.*;
-import java.net.URL;
-import java.net.SocketPermission;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import sun.awt.SunToolkit;
-import sun.awt.AppContext;
-
-/**
- * A frame to show the applet tag in.
- */
-@SuppressWarnings("serial") // JDK-implementation class
-@Deprecated(since = "9")
-final class TextFrame extends Frame {
-
- /**
- * Create the tag frame.
- */
- @SuppressWarnings("deprecation")
- TextFrame(int x, int y, String title, String text) {
- setTitle(title);
- TextArea txt = new TextArea(20, 60);
- txt.setText(text);
- txt.setEditable(false);
-
- add("Center", txt);
-
- Panel p = new Panel();
- add("South", p);
- Button b = new Button(amh.getMessage("button.dismiss", "Dismiss"));
- p.add(b);
-
- class ActionEventListener implements ActionListener {
- @Override
- public void actionPerformed(ActionEvent evt) {
- dispose();
- }
- }
- b.addActionListener(new ActionEventListener());
-
- pack();
- move(x, y);
- setVisible(true);
-
- WindowListener windowEventListener = new WindowAdapter() {
-
- @Override
- public void windowClosing(WindowEvent evt) {
- dispose();
- }
- };
-
- addWindowListener(windowEventListener);
- }
- private static AppletMessageHandler amh = new AppletMessageHandler("textframe");
-
-}
-
-/**
- * Lets us construct one using unix-style one shot behaviors.
- */
-@Deprecated(since = "9")
-final class StdAppletViewerFactory implements AppletViewerFactory {
-
- @Override
- public AppletViewer createAppletViewer(int x, int y,
- URL doc, Hashtable<String, String> atts) {
- return new AppletViewer(x, y, doc, atts, System.out, this);
- }
-
- @Override
- public MenuBar getBaseMenuBar() {
- return new MenuBar();
- }
-
- @Override
- public boolean isStandalone() {
- return true;
- }
-}
-
-/**
- * The applet viewer makes it possible to run a Java applet without using a browser.
- * For details on the syntax that <B>appletviewer</B> supports, see
- * <a href="../../../docs/tooldocs/appletviewertags.html">AppletViewer Tags</a>.
- * (The document named appletviewertags.html in the JDK's docs/tooldocs directory,
- * once the JDK docs have been installed.)
- *
- * @deprecated The Applet API is deprecated. See the
- * <a href="../../java/applet/package-summary.html"> java.applet package
- * documentation</a> for further information.
- */
-@SuppressWarnings({"serial"}) // JDK-implementation class
-@Deprecated(since = "9")
-public class AppletViewer extends Frame implements AppletContext, Printable {
-
- /**
- * Some constants...
- */
- private static String defaultSaveFile = "Applet.ser";
-
- /**
- * The panel in which the applet is being displayed.
- */
- AppletViewerPanel panel;
-
- /**
- * The status line.
- */
- Label label;
-
- /**
- * output status messages to this stream
- */
-
- PrintStream statusMsgStream;
-
- /**
- * For cloning
- */
- AppletViewerFactory factory;
-
- @Deprecated(since = "9")
- private final class UserActionListener implements ActionListener {
- @Override
- public void actionPerformed(ActionEvent evt) {
- processUserAction(evt);
- }
- }
-
- /**
- * Create the applet viewer.
- */
- public AppletViewer(int x, int y, URL doc, Hashtable<String, String> atts,
- PrintStream statusMsgStream, AppletViewerFactory factory) {
- this.factory = factory;
- this.statusMsgStream = statusMsgStream;
- setTitle(amh.getMessage("tool.title", atts.get("code")));
-
- MenuBar mb = factory.getBaseMenuBar();
-
- Menu m = new Menu(amh.getMessage("menu.applet"));
-
- addMenuItem(m, "menuitem.restart");
- addMenuItem(m, "menuitem.reload");
- addMenuItem(m, "menuitem.stop");
- addMenuItem(m, "menuitem.save");
- addMenuItem(m, "menuitem.start");
- addMenuItem(m, "menuitem.clone");
- m.add(new MenuItem("-"));
- addMenuItem(m, "menuitem.tag");
- addMenuItem(m, "menuitem.info");
- addMenuItem(m, "menuitem.edit").disable();
- addMenuItem(m, "menuitem.encoding");
- m.add(new MenuItem("-"));
- addMenuItem(m, "menuitem.print");
- m.add(new MenuItem("-"));
- addMenuItem(m, "menuitem.props");
- m.add(new MenuItem("-"));
- addMenuItem(m, "menuitem.close");
- if (factory.isStandalone()) {
- addMenuItem(m, "menuitem.quit");
- }
-
- mb.add(m);
-
- setMenuBar(mb);
-
- add("Center", panel = new AppletViewerPanel(doc, atts));
- add("South", label = new Label(amh.getMessage("label.hello")));
- panel.init();
- appletPanels.addElement(panel);
-
- pack();
- move(x, y);
- setVisible(true);
-
- WindowListener windowEventListener = new WindowAdapter() {
-
- @Override
- public void windowClosing(WindowEvent evt) {
- appletClose();
- }
-
- @Override
- public void windowIconified(WindowEvent evt) {
- appletStop();
- }
-
- @Override
- public void windowDeiconified(WindowEvent evt) {
- appletStart();
- }
- };
-
- @Deprecated(since = "9")
- class AppletEventListener implements AppletListener
- {
- final Frame frame;
-
- public AppletEventListener(Frame frame)
- {
- this.frame = frame;
- }
-
- @Override
- @SuppressWarnings("deprecation")
- public void appletStateChanged(AppletEvent evt)
- {
- AppletPanel src = (AppletPanel)evt.getSource();
-
- switch (evt.getID()) {
- case AppletPanel.APPLET_RESIZE: {
- if(src != null) {
- resize(preferredSize());
- validate();
- }
- break;
- }
- case AppletPanel.APPLET_LOADING_COMPLETED: {
- Applet a = src.getApplet(); // sun.applet.AppletPanel
-
- // Fixed #4754451: Applet can have methods running on main
- // thread event queue.
- //
- // The cause of this bug is that the frame of the applet
- // is created in main thread group. Thus, when certain
- // AWT/Swing events are generated, the events will be
- // dispatched through the wrong event dispatch thread.
- //
- // To fix this, we rearrange the AppContext with the frame,
- // so the proper event queue will be looked up.
- //
- // Swing also maintains a Frame list for the AppContext,
- // so we will have to rearrange it as well.
- //
- if (a != null)
- AppletPanel.changeFrameAppContext(frame, SunToolkit.targetToAppContext(a));
- else
- AppletPanel.changeFrameAppContext(frame, AppContext.getAppContext());
-
- break;
- }
- }
- }
- };
-
- addWindowListener(windowEventListener);
- panel.addAppletListener(new AppletEventListener(this));
-
- // Start the applet
- showStatus(amh.getMessage("status.start"));
- initEventQueue();
- }
-
- // XXX 99/9/10 probably should be "private"
- public MenuItem addMenuItem(Menu m, String s) {
- MenuItem mItem = new MenuItem(amh.getMessage(s));
- mItem.addActionListener(new UserActionListener());
- return m.add(mItem);
- }
-
- /**
- * Send the initial set of events to the appletviewer event queue.
- * On start-up the current behaviour is to load the applet and call
- * Applet.init() and Applet.start().
- */
- private void initEventQueue() {
- // appletviewer.send.event is an undocumented and unsupported system
- // property which is used exclusively for testing purposes.
- String eventList = System.getProperty("appletviewer.send.event");
-
- if (eventList == null) {
- // Add the standard events onto the event queue.
- panel.sendEvent(AppletPanel.APPLET_LOAD);
- panel.sendEvent(AppletPanel.APPLET_INIT);
- panel.sendEvent(AppletPanel.APPLET_START);
- } else {
- // We're testing AppletViewer. Force the specified set of events
- // onto the event queue, wait for the events to be processed, and
- // exit.
-
- // The list of events that will be executed is provided as a
- // ","-separated list. No error-checking will be done on the list.
- String [] events = splitSeparator(",", eventList);
-
- for (int i = 0; i < events.length; i++) {
- System.out.println("Adding event to queue: " + events[i]);
- if (events[i].equals("dispose"))
- panel.sendEvent(AppletPanel.APPLET_DISPOSE);
- else if (events[i].equals("load"))
- panel.sendEvent(AppletPanel.APPLET_LOAD);
- else if (events[i].equals("init"))
- panel.sendEvent(AppletPanel.APPLET_INIT);
- else if (events[i].equals("start"))
- panel.sendEvent(AppletPanel.APPLET_START);
- else if (events[i].equals("stop"))
- panel.sendEvent(AppletPanel.APPLET_STOP);
- else if (events[i].equals("destroy"))
- panel.sendEvent(AppletPanel.APPLET_DESTROY);
- else if (events[i].equals("quit"))
- panel.sendEvent(AppletPanel.APPLET_QUIT);
- else if (events[i].equals("error"))
- panel.sendEvent(AppletPanel.APPLET_ERROR);
- else
- // non-fatal error if we get an unrecognized event
- System.out.println("Unrecognized event name: " + events[i]);
- }
-
- while (!panel.emptyEventQueue()) ;
- appletSystemExit();
- }
- }
-
- /**
- * Split a string based on the presence of a specified separator. Returns
- * an array of arbitrary length. The end of each element in the array is
- * indicated by the separator of the end of the string. If there is a
- * separator immediately before the end of the string, the final element
- * will be empty. None of the strings will contain the separator. Useful
- * when separating strings such as "foo/bar/bas" using separator "/".
- *
- * @param sep The separator.
- * @param s The string to split.
- * @return An array of strings. Each string in the array is determined
- * by the location of the provided sep in the original string,
- * s. Whitespace not stripped.
- */
- private String [] splitSeparator(String sep, String s) {
- Vector<String> v = new Vector<>();
- int tokenStart = 0;
- int tokenEnd = 0;
-
- while ((tokenEnd = s.indexOf(sep, tokenStart)) != -1) {
- v.addElement(s.substring(tokenStart, tokenEnd));
- tokenStart = tokenEnd+1;
- }
- // Add the final element.
- v.addElement(s.substring(tokenStart));
-
- String [] retVal = new String[v.size()];
- v.copyInto(retVal);
- return retVal;
- }
-
- /*
- * Methods for java.applet.AppletContext
- */
-
- private static Map<URL, AudioClip> audioClips = new HashMap<>();
-
- /**
- * Get an audio clip.
- */
- @Override
- public AudioClip getAudioClip(URL url) {
- checkConnect(url);
- synchronized (audioClips) {
- AudioClip clip = audioClips.get(url);
- if (clip == null) {
- audioClips.put(url, clip = new AppletAudioClip(url));
- }
- return clip;
- }
- }
-
- private static Map<URL, AppletImageRef> imageRefs = new HashMap<>();
-
- /**
- * Get an image.
- */
- @Override
- public Image getImage(URL url) {
- return getCachedImage(url);
- }
-
- /**
- * Get an image.
- */
- static Image getCachedImage(URL url) {
- // System.getSecurityManager().checkConnection(url.getHost(), url.getPort());
- synchronized (imageRefs) {
- AppletImageRef ref = imageRefs.get(url);
- if (ref == null) {
- ref = new AppletImageRef(url);
- imageRefs.put(url, ref);
- }
- return ref.get();
- }
- }
-
- /**
- * Flush the image cache.
- */
- static void flushImageCache() {
- imageRefs.clear();
- }
-
- static Vector<AppletPanel> appletPanels = new Vector<>();
-
- /**
- * Get an applet by name.
- */
- @Override
- public Applet getApplet(String name) {
- AppletSecurity security = (AppletSecurity)System.getSecurityManager();
- name = name.toLowerCase();
- SocketPermission panelSp =
- new SocketPermission(panel.getCodeBase().getHost(), "connect");
- for (Enumeration<AppletPanel> e = appletPanels.elements() ; e.hasMoreElements() ;) {
- AppletPanel p = e.nextElement();
- String param = p.getParameter("name");
- if (param != null) {
- param = param.toLowerCase();
- }
- if (name.equals(param) &&
- p.getDocumentBase().equals(panel.getDocumentBase())) {
-
- SocketPermission sp =
- new SocketPermission(p.getCodeBase().getHost(), "connect");
-
- if (panelSp.implies(sp)) {
- return p.applet;
- }
- }
- }
- return null;
- }
-
- /**
- * Return an enumeration of all the accessible
- * applets on this page.
- */
- @Override
- public Enumeration<Applet> getApplets() {
- AppletSecurity security = (AppletSecurity)System.getSecurityManager();
- Vector<Applet> v = new Vector<>();
- SocketPermission panelSp =
- new SocketPermission(panel.getCodeBase().getHost(), "connect");
-
- for (Enumeration<AppletPanel> e = appletPanels.elements() ; e.hasMoreElements() ;) {
- AppletPanel p = e.nextElement();
- if (p.getDocumentBase().equals(panel.getDocumentBase())) {
-
- SocketPermission sp =
- new SocketPermission(p.getCodeBase().getHost(), "connect");
- if (panelSp.implies(sp)) {
- v.addElement(p.applet);
- }
- }
- }
- return v.elements();
- }
-
- /**
- * Ignore.
- */
- @Override
- public void showDocument(URL url) {
- }
-
- /**
- * Ignore.
- */
- @Override
- public void showDocument(URL url, String target) {
- }
-
- /**
- * Show status.
- */
- @Override
- public void showStatus(String status) {
- label.setText(status);
- }
-
- @Override
- public void setStream(String key, InputStream stream)throws IOException{
- // We do nothing.
- }
-
- @Override
- public InputStream getStream(String key){
- // We do nothing.
- return null;
- }
-
- @Override
- public Iterator<String> getStreamKeys(){
- // We do nothing.
- return null;
- }
-
- /**
- * System parameters.
- */
- static Hashtable<String, String> systemParam = new Hashtable<>();
-
- static {
- systemParam.put("codebase", "codebase");
- systemParam.put("code", "code");
- systemParam.put("alt", "alt");
- systemParam.put("width", "width");
- systemParam.put("height", "height");
- systemParam.put("align", "align");
- systemParam.put("vspace", "vspace");
- systemParam.put("hspace", "hspace");
- }
-
- /**
- * Print the HTML tag.
- */
- public static void printTag(PrintStream out, Hashtable<String, String> atts) {
- out.print("<applet");
-
- String v = atts.get("codebase");
- if (v != null) {
- out.print(" codebase=\"" + v + "\"");
- }
-
- v = atts.get("code");
- if (v == null) {
- v = "applet.class";
- }
- out.print(" code=\"" + v + "\"");
- v = atts.get("width");
- if (v == null) {
- v = "150";
- }
- out.print(" width=" + v);
-
- v = atts.get("height");
- if (v == null) {
- v = "100";
- }
- out.print(" height=" + v);
-
- v = atts.get("name");
- if (v != null) {
- out.print(" name=\"" + v + "\"");
- }
- out.println(">");
-
- // A very slow sorting algorithm
- int len = atts.size();
- String params[] = new String[len];
- len = 0;
- for (Enumeration<String> e = atts.keys() ; e.hasMoreElements() ;) {
- String param = e.nextElement();
- int i = 0;
- for (; i < len ; i++) {
- if (params[i].compareTo(param) >= 0) {
- break;
- }
- }
- System.arraycopy(params, i, params, i + 1, len - i);
- params[i] = param;
- len++;
- }
-
- for (int i = 0 ; i < len ; i++) {
- String param = params[i];
- if (systemParam.get(param) == null) {
- out.println("<param name=" + param +
- " value=\"" + atts.get(param) + "\">");
- }
- }
- out.println("</applet>");
- }
-
- /**
- * Make sure the atrributes are uptodate.
- */
- @SuppressWarnings("deprecation")
- public void updateAtts() {
- Dimension d = panel.size();
- Insets in = panel.insets();
- panel.atts.put("width",
- Integer.toString(d.width - (in.left + in.right)));
- panel.atts.put("height",
- Integer.toString(d.height - (in.top + in.bottom)));
- }
-
- /**
- * Restart the applet.
- */
- void appletRestart() {
- panel.sendEvent(AppletPanel.APPLET_STOP);
- panel.sendEvent(AppletPanel.APPLET_DESTROY);
- panel.sendEvent(AppletPanel.APPLET_INIT);
- panel.sendEvent(AppletPanel.APPLET_START);
- }
-
- /**
- * Reload the applet.
- */
- void appletReload() {
- panel.sendEvent(AppletPanel.APPLET_STOP);
- panel.sendEvent(AppletPanel.APPLET_DESTROY);
- panel.sendEvent(AppletPanel.APPLET_DISPOSE);
-
- /**
- * Fixed #4501142: Classloader sharing policy doesn't
- * take "archive" into account. This will be overridden
- * by Java Plug-in. [stanleyh]
- */
- AppletPanel.flushClassLoader(panel.getClassLoaderCacheKey());
-
- /*
- * Make sure we don't have two threads running through the event queue
- * at the same time.
- */
- try {
- panel.joinAppletThread();
- panel.release();
- } catch (InterruptedException e) {
- return; // abort the reload
- }
-
- panel.createAppletThread();
- panel.sendEvent(AppletPanel.APPLET_LOAD);
- panel.sendEvent(AppletPanel.APPLET_INIT);
- panel.sendEvent(AppletPanel.APPLET_START);
- }
-
- /**
- * Save the applet to a well known file (for now) as a serialized object
- */
- @SuppressWarnings("deprecation")
- void appletSave() {
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
-
- @Override
- public Object run() {
- // XXX: this privileged block should be made smaller
- // by initializing a private static variable with "user.dir"
-
- // Applet needs to be stopped for serialization to succeed.
- // Since panel.sendEvent only queues the event, there is a
- // chance that the event will not be processed before
- // serialization begins. However, by sending the event before
- // FileDialog is created, enough time is given such that this
- // situation is unlikely to ever occur.
-
- panel.sendEvent(AppletPanel.APPLET_STOP);
- FileDialog fd = new FileDialog(AppletViewer.this,
- amh.getMessage("appletsave.filedialogtitle"),
- FileDialog.SAVE);
- // needed for a bug under Solaris...
- fd.setDirectory(System.getProperty("user.dir"));
- fd.setFile(defaultSaveFile);
- fd.show();
- String fname = fd.getFile();
- if (fname == null) {
- // Restart applet if Save is cancelled.
- panel.sendEvent(AppletPanel.APPLET_START);
- return null; // cancelled
- }
- String dname = fd.getDirectory();
- File file = new File(dname, fname);
-
- try (FileOutputStream fos = new FileOutputStream(file);
- BufferedOutputStream bos = new BufferedOutputStream(fos);
- ObjectOutputStream os = new ObjectOutputStream(bos)) {
-
- showStatus(amh.getMessage("appletsave.err1", panel.applet.toString(), file.toString()));
- os.writeObject(panel.applet);
- } catch (IOException ex) {
- System.err.println(amh.getMessage("appletsave.err2", ex));
- } finally {
- panel.sendEvent(AppletPanel.APPLET_START);
- }
- return null;
- }
- });
- }
-
- /**
- * Clone the viewer and the applet.
- */
- @SuppressWarnings("deprecation")
- void appletClone() {
- Point p = location();
- updateAtts();
- @SuppressWarnings("unchecked")
- Hashtable<String, String> tmp = (Hashtable<String, String>) panel.atts.clone();
- factory.createAppletViewer(p.x + XDELTA, p.y + YDELTA,
- panel.documentURL, tmp);
- }
-
- /**
- * Show the applet tag.
- */
- @SuppressWarnings("deprecation")
- void appletTag() {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- updateAtts();
- printTag(new PrintStream(out), panel.atts);
- showStatus(amh.getMessage("applettag"));
-
- Point p = location();
- new TextFrame(p.x + XDELTA, p.y + YDELTA, amh.getMessage("applettag.textframe"), out.toString());
- }
-
- /**
- * Show the applet info.
- */
- @SuppressWarnings("deprecation")
- void appletInfo() {
- String str = panel.applet.getAppletInfo();
- if (str == null) {
- str = amh.getMessage("appletinfo.applet");
- }
- str += "\n\n";
-
- String atts[][] = panel.applet.getParameterInfo();
- if (atts != null) {
- for (int i = 0 ; i < atts.length ; i++) {
- str += atts[i][0] + " -- " + atts[i][1] + " -- " + atts[i][2] + "\n";
- }
- } else {
- str += amh.getMessage("appletinfo.param");
- }
-
- Point p = location();
- new TextFrame(p.x + XDELTA, p.y + YDELTA, amh.getMessage("appletinfo.textframe"), str);
-
- }
-
- /**
- * Show character encoding type
- */
- void appletCharacterEncoding() {
- showStatus(amh.getMessage("appletencoding", encoding));
- }
-
- /**
- * Edit the applet.
- */
- void appletEdit() {
- }
-
- /**
- * Print the applet.
- */
- void appletPrint() {
- PrinterJob pj = PrinterJob.getPrinterJob();
-
- if (pj != null) {
- PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
- if (pj.printDialog(aset)) {
- pj.setPrintable(this);
- try {
- pj.print(aset);
- statusMsgStream.println(amh.getMessage("appletprint.finish"));
- } catch (PrinterException e) {
- statusMsgStream.println(amh.getMessage("appletprint.fail"));
- }
- } else {
- statusMsgStream.println(amh.getMessage("appletprint.cancel"));
- }
- } else {
- statusMsgStream.println(amh.getMessage("appletprint.fail"));
- }
- }
-
- @Override
- public int print(Graphics graphics, PageFormat pf, int pageIndex) {
- if (pageIndex > 0) {
- return Printable.NO_SUCH_PAGE;
- } else {
- Graphics2D g2d = (Graphics2D)graphics;
- g2d.translate(pf.getImageableX(), pf.getImageableY());
- panel.applet.printAll(graphics);
- return Printable.PAGE_EXISTS;
- }
- }
-
- /**
- * Properties.
- */
- static AppletProps props;
- public static synchronized void networkProperties() {
- if (props == null) {
- props = new AppletProps();
- }
- props.addNotify();
- props.setVisible(true);
- }
-
- /**
- * Start the applet.
- */
- void appletStart() {
- panel.sendEvent(AppletPanel.APPLET_START);
- }
-
- /**
- * Stop the applet.
- */
- void appletStop() {
- panel.sendEvent(AppletPanel.APPLET_STOP);
- }
-
- /**
- * Shutdown a viewer.
- * Stop, Destroy, Dispose and Quit a viewer
- */
- private void appletShutdown(AppletPanel p) {
- p.sendEvent(AppletPanel.APPLET_STOP);
- p.sendEvent(AppletPanel.APPLET_DESTROY);
- p.sendEvent(AppletPanel.APPLET_DISPOSE);
- p.sendEvent(AppletPanel.APPLET_QUIT);
- }
-
- /**
- * Close this viewer.
- * Stop, Destroy, Dispose and Quit an AppletView, then
- * reclaim resources and exit the program if this is
- * the last applet.
- */
- void appletClose() {
-
- // The caller thread is event dispatch thread, so
- // spawn a new thread to avoid blocking the event queue
- // when calling appletShutdown.
- //
- final AppletPanel p = panel;
-
- new Thread(null, new Runnable()
- {
- @Override
- public void run()
- {
- appletShutdown(p);
- appletPanels.removeElement(p);
- dispose();
-
- if (countApplets() == 0) {
- appletSystemExit();
- }
- }
- },
- "AppletCloser", 0, false).start();
- }
-
- /**
- * Exit the program.
- * Exit from the program (if not stand alone) - do no clean-up
- */
- private void appletSystemExit() {
- if (factory.isStandalone())
- System.exit(0);
- }
-
- /**
- * Quit all viewers.
- * Shutdown all viewers properly then
- * exit from the program (if not stand alone)
- */
- protected void appletQuit()
- {
- // The caller thread is event dispatch thread, so
- // spawn a new thread to avoid blocking the event queue
- // when calling appletShutdown.
- //
- new Thread(null, new Runnable()
- {
- @Override
- public void run()
- {
- for (Enumeration<AppletPanel> e = appletPanels.elements() ; e.hasMoreElements() ;) {
- AppletPanel p = e.nextElement();
- appletShutdown(p);
- }
- appletSystemExit();
- }
- },
- "AppletQuit", 0, false).start();
- }
-
- /**
- * Handle events.
- */
- public void processUserAction(ActionEvent evt) {
-
- String label = ((MenuItem)evt.getSource()).getLabel();
-
- if (amh.getMessage("menuitem.restart").equals(label)) {
- appletRestart();
- return;
- }
-
- if (amh.getMessage("menuitem.reload").equals(label)) {
- appletReload();
- return;
- }
-
- if (amh.getMessage("menuitem.clone").equals(label)) {
- appletClone();
- return;
- }
-
- if (amh.getMessage("menuitem.stop").equals(label)) {
- appletStop();
- return;
- }
-
- if (amh.getMessage("menuitem.save").equals(label)) {
- appletSave();
- return;
- }
-
- if (amh.getMessage("menuitem.start").equals(label)) {
- appletStart();
- return;
- }
-
- if (amh.getMessage("menuitem.tag").equals(label)) {
- appletTag();
- return;
- }
-
- if (amh.getMessage("menuitem.info").equals(label)) {
- appletInfo();
- return;
- }
-
- if (amh.getMessage("menuitem.encoding").equals(label)) {
- appletCharacterEncoding();
- return;
- }
-
- if (amh.getMessage("menuitem.edit").equals(label)) {
- appletEdit();
- return;
- }
-
- if (amh.getMessage("menuitem.print").equals(label)) {
- appletPrint();
- return;
- }
-
- if (amh.getMessage("menuitem.props").equals(label)) {
- networkProperties();
- return;
- }
-
- if (amh.getMessage("menuitem.close").equals(label)) {
- appletClose();
- return;
- }
-
- if (factory.isStandalone() && amh.getMessage("menuitem.quit").equals(label)) {
- appletQuit();
- return;
- }
- //statusMsgStream.println("evt = " + evt);
- }
-
- /**
- * How many applets are running?
- */
-
- public static int countApplets() {
- return appletPanels.size();
- }
-
-
- /**
- * The current character.
- */
- static int c;
-
- /**
- * Scan spaces.
- */
- public static void skipSpace(Reader in) throws IOException {
- while ((c >= 0) &&
- ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r'))) {
- c = in.read();
- }
- }
-
- /**
- * Scan identifier
- */
- public static String scanIdentifier(Reader in) throws IOException {
- StringBuilder sb = new StringBuilder();
- while (true) {
- if (((c >= 'a') && (c <= 'z')) ||
- ((c >= 'A') && (c <= 'Z')) ||
- ((c >= '0') && (c <= '9')) || (c == '_')) {
- sb.append((char) c);
- c = in.read();
- } else {
- return sb.toString();
- }
- }
- }
-
- /**
- * Scan tag
- */
- public static Hashtable<String, String> scanTag(Reader in) throws IOException {
- Hashtable<String, String> atts = new Hashtable<>();
- skipSpace(in);
- while (c >= 0 && c != '>') {
- String att = scanIdentifier(in);
- String val = "";
- skipSpace(in);
- if (c == '=') {
- int quote = -1;
- c = in.read();
- skipSpace(in);
- if ((c == '\'') || (c == '\"')) {
- quote = c;
- c = in.read();
- }
- StringBuilder sb = new StringBuilder();
- while ((c > 0) &&
- (((quote < 0) && (c != ' ') && (c != '\t') &&
- (c != '\n') && (c != '\r') && (c != '>'))
- || ((quote >= 0) && (c != quote)))) {
- sb.append((char) c);
- c = in.read();
- }
- if (c == quote) {
- c = in.read();
- }
- skipSpace(in);
- val = sb.toString();
- }
- //statusMsgStream.println("PUT " + att + " = '" + val + "'");
- if (! val.equals("")) {
- atts.put(att.toLowerCase(java.util.Locale.ENGLISH), val);
- }
- while (true) {
- if ((c == '>') || (c < 0) ||
- ((c >= 'a') && (c <= 'z')) ||
- ((c >= 'A') && (c <= 'Z')) ||
- ((c >= '0') && (c <= '9')) || (c == '_'))
- break;
- c = in.read();
- }
- //skipSpace(in);
- }
- return atts;
- }
-
- /* values used for placement of AppletViewer's frames */
- private static int x = 0;
- private static int y = 0;
- private static final int XDELTA = 30;
- private static final int YDELTA = XDELTA;
-
- static String encoding = null;
-
- private static Reader makeReader(InputStream is) {
- if (encoding != null) {
- try {
- return new BufferedReader(new InputStreamReader(is, encoding));
- } catch (IOException x) { }
- }
- InputStreamReader r = new InputStreamReader(is);
- encoding = r.getEncoding();
- return new BufferedReader(r);
- }
-
- /**
- * Scan an html file for {@code <applet>} tags
- */
- public static void parse(URL url, String enc) throws IOException {
- encoding = enc;
- parse(url, System.out, new StdAppletViewerFactory());
- }
-
- public static void parse(URL url) throws IOException {
- parse(url, System.out, new StdAppletViewerFactory());
- }
-
- public static void parse(URL url, PrintStream statusMsgStream,
- AppletViewerFactory factory) throws IOException {
- // <OBJECT> <EMBED> tag flags
- boolean isAppletTag = false;
- boolean isObjectTag = false;
- boolean isEmbedTag = false;
-
- // warning messages
- String requiresNameWarning = amh.getMessage("parse.warning.requiresname");
- String paramOutsideWarning = amh.getMessage("parse.warning.paramoutside");
- String appletRequiresCodeWarning = amh.getMessage("parse.warning.applet.requirescode");
- String appletRequiresHeightWarning = amh.getMessage("parse.warning.applet.requiresheight");
- String appletRequiresWidthWarning = amh.getMessage("parse.warning.applet.requireswidth");
- String objectRequiresCodeWarning = amh.getMessage("parse.warning.object.requirescode");
- String objectRequiresHeightWarning = amh.getMessage("parse.warning.object.requiresheight");
- String objectRequiresWidthWarning = amh.getMessage("parse.warning.object.requireswidth");
- String embedRequiresCodeWarning = amh.getMessage("parse.warning.embed.requirescode");
- String embedRequiresHeightWarning = amh.getMessage("parse.warning.embed.requiresheight");
- String embedRequiresWidthWarning = amh.getMessage("parse.warning.embed.requireswidth");
- String appNotLongerSupportedWarning = amh.getMessage("parse.warning.appnotLongersupported");
-
- java.net.URLConnection conn = url.openConnection();
- Reader in = makeReader(conn.getInputStream());
- /* The original URL may have been redirected - this
- * sets it to whatever URL/codebase we ended up getting
- */
- url = conn.getURL();
-
- int ydisp = 1;
- Hashtable<String, String> atts = null;
-
- while(true) {
- c = in.read();
- if (c == -1)
- break;
-
- if (c == '<') {
- c = in.read();
- if (c == '/') {
- c = in.read();
- String nm = scanIdentifier(in);
- if (nm.equalsIgnoreCase("applet") ||
- nm.equalsIgnoreCase("object") ||
- nm.equalsIgnoreCase("embed")) {
-
- // We can't test for a code tag until </OBJECT>
- // because it is a parameter, not an attribute.
- if(isObjectTag) {
- if (atts.get("code") == null && atts.get("object") == null) {
- statusMsgStream.println(objectRequiresCodeWarning);
- atts = null;
- }
- }
-
- if (atts != null) {
- // XXX 5/18 In general this code just simply
- // shouldn't be part of parsing. It's presence
- // causes things to be a little too much of a
- // hack.
- factory.createAppletViewer(x, y, url, atts);
- x += XDELTA;
- y += YDELTA;
- // make sure we don't go too far!
- Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
- if ((x > d.width - 300) || (y > d.height - 300)) {
- x = 0;
- y = 2 * ydisp * YDELTA;
- ydisp++;
- }
- }
- atts = null;
- isAppletTag = false;
- isObjectTag = false;
- isEmbedTag = false;
- }
- }
- else {
- String nm = scanIdentifier(in);
- if (nm.equalsIgnoreCase("param")) {
- Hashtable<String, String> t = scanTag(in);
- String att = t.get("name");
- if (att == null) {
- statusMsgStream.println(requiresNameWarning);
- } else {
- String val = t.get("value");
- if (val == null) {
- statusMsgStream.println(requiresNameWarning);
- } else if (atts != null) {
- atts.put(att.toLowerCase(), val);
- } else {
- statusMsgStream.println(paramOutsideWarning);
- }
- }
- }
- else if (nm.equalsIgnoreCase("applet")) {
- isAppletTag = true;
- atts = scanTag(in);
- if (atts.get("code") == null && atts.get("object") == null) {
- statusMsgStream.println(appletRequiresCodeWarning);
- atts = null;
- } else if (atts.get("width") == null) {
- statusMsgStream.println(appletRequiresWidthWarning);
- atts = null;
- } else if (atts.get("height") == null) {
- statusMsgStream.println(appletRequiresHeightWarning);
- atts = null;
- }
- }
- else if (nm.equalsIgnoreCase("object")) {
- isObjectTag = true;
- atts = scanTag(in);
- // The <OBJECT> attribute codebase isn't what
- // we want. If its defined, remove it.
- if(atts.get("codebase") != null) {
- atts.remove("codebase");
- }
-
- if (atts.get("width") == null) {
- statusMsgStream.println(objectRequiresWidthWarning);
- atts = null;
- } else if (atts.get("height") == null) {
- statusMsgStream.println(objectRequiresHeightWarning);
- atts = null;
- }
- }
- else if (nm.equalsIgnoreCase("embed")) {
- isEmbedTag = true;
- atts = scanTag(in);
-
- if (atts.get("code") == null && atts.get("object") == null) {
- statusMsgStream.println(embedRequiresCodeWarning);
- atts = null;
- } else if (atts.get("width") == null) {
- statusMsgStream.println(embedRequiresWidthWarning);
- atts = null;
- } else if (atts.get("height") == null) {
- statusMsgStream.println(embedRequiresHeightWarning);
- atts = null;
- }
- }
- else if (nm.equalsIgnoreCase("app")) {
- statusMsgStream.println(appNotLongerSupportedWarning);
- Hashtable<String, String> atts2 = scanTag(in);
- nm = atts2.get("class");
- if (nm != null) {
- atts2.remove("class");
- atts2.put("code", nm + ".class");
- }
- nm = atts2.get("src");
- if (nm != null) {
- atts2.remove("src");
- atts2.put("codebase", nm);
- }
- if (atts2.get("width") == null) {
- atts2.put("width", "100");
- }
- if (atts2.get("height") == null) {
- atts2.put("height", "100");
- }
- printTag(statusMsgStream, atts2);
- statusMsgStream.println();
- }
- }
- }
- }
- in.close();
- }
-
- /**
- * Old main entry point.
- *
- * @deprecated
- */
- @Deprecated
- public static void main(String argv[]) {
- // re-route everything to the new main entry point
- Main.main(argv);
- }
-
- private static AppletMessageHandler amh = new AppletMessageHandler("appletviewer");
-
- private static void checkConnect(URL url)
- {
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- try {
- java.security.Permission perm =
- url.openConnection().getPermission();
- if (perm != null)
- security.checkPermission(perm);
- else
- security.checkConnect(url.getHost(), url.getPort());
- } catch (java.io.IOException ioe) {
- security.checkConnect(url.getHost(), url.getPort());
- }
- }
- }
-}
--- a/src/java.desktop/share/classes/sun/applet/AppletViewerFactory.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 1996, Oracle and/or its affiliates. All rights reserved.
- * 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-/*
- * AppletViewerFactory.java
- */
-
-package sun.applet;
-
-import java.util.Hashtable;
-import java.net.URL;
-import java.awt.MenuBar;
-
-@Deprecated(since = "9")
-public interface AppletViewerFactory {
- public AppletViewer createAppletViewer(int x, int y, URL doc,
- Hashtable<String, String> atts);
- public MenuBar getBaseMenuBar();
- public boolean isStandalone();
-}
--- a/src/java.desktop/share/classes/sun/applet/AppletViewerPanel.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,221 +0,0 @@
-/*
- * Copyright (c) 1995, 2005, Oracle and/or its affiliates. All rights reserved.
- * 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.applet;
-
-import java.util.*;
-import java.io.*;
-import java.net.URL;
-import java.net.MalformedURLException;
-import java.awt.*;
-import java.applet.*;
-
-
-/**
- * Sample applet panel class. The panel manages and manipulates the
- * applet as it is being loaded. It forks a seperate thread in a new
- * thread group to call the applet's init(), start(), stop(), and
- * destroy() methods.
- *
- * @author Arthur van Hoff
- *
- * @deprecated The Applet API is deprecated. See the
- * <a href="../../java/applet/package-summary.html"> java.applet package
- * documentation</a> for further information.
- */
-@Deprecated(since = "9")
-class AppletViewerPanel extends AppletPanel {
-
- /* Are we debugging? */
- static boolean debug = false;
-
- /**
- * The document url.
- */
- URL documentURL;
-
- /**
- * The base url.
- */
- URL baseURL;
-
- /**
- * The attributes of the applet.
- */
- Hashtable<String, String> atts;
-
- /*
- * JDK 1.1 serialVersionUID
- */
- private static final long serialVersionUID = 8890989370785545619L;
-
- /**
- * Construct an applet viewer and start the applet.
- */
- AppletViewerPanel(URL documentURL, Hashtable<String, String> atts) {
- this.documentURL = documentURL;
- this.atts = atts;
-
- String att = getParameter("codebase");
- if (att != null) {
- if (!att.endsWith("/")) {
- att += "/";
- }
- try {
- baseURL = new URL(documentURL, att);
- } catch (MalformedURLException e) {
- }
- }
- if (baseURL == null) {
- String file = documentURL.getFile();
- int i = file.lastIndexOf('/');
- if (i >= 0 && i < file.length() - 1) {
- try {
- baseURL = new URL(documentURL, file.substring(0, i + 1));
- } catch (MalformedURLException e) {
- }
- }
- }
-
- // when all is said & done, baseURL shouldn't be null
- if (baseURL == null)
- baseURL = documentURL;
-
-
- }
-
- /**
- * Get an applet parameter.
- */
- public String getParameter(String name) {
- return atts.get(name.toLowerCase());
- }
-
- /**
- * Get the document url.
- */
- public URL getDocumentBase() {
- return documentURL;
-
- }
-
- /**
- * Get the base url.
- */
- public URL getCodeBase() {
- return baseURL;
- }
-
- /**
- * Get the width.
- */
- public int getWidth() {
- String w = getParameter("width");
- if (w != null) {
- return Integer.valueOf(w).intValue();
- }
- return 0;
- }
-
-
- /**
- * Get the height.
- */
- public int getHeight() {
- String h = getParameter("height");
- if (h != null) {
- return Integer.valueOf(h).intValue();
- }
- return 0;
- }
-
- /**
- * Get initial_focus
- */
- public boolean hasInitialFocus()
- {
-
- // 6234219: Do not set initial focus on an applet
- // during startup if applet is targeted for
- // JDK 1.1/1.2. [stanley.ho]
- if (isJDK11Applet() || isJDK12Applet())
- return false;
-
- String initialFocus = getParameter("initial_focus");
-
- if (initialFocus != null)
- {
- if (initialFocus.toLowerCase().equals("false"))
- return false;
- }
-
- return true;
- }
-
- /**
- * Get the code parameter
- */
- public String getCode() {
- return getParameter("code");
- }
-
-
- /**
- * Return the list of jar files if specified.
- * Otherwise return null.
- */
- public String getJarFiles() {
- return getParameter("archive");
- }
-
- /**
- * Return the value of the object param
- */
- public String getSerializedObject() {
- return getParameter("object");// another name?
- }
-
-
- /**
- * Get the applet context. For now this is
- * also implemented by the AppletPanel class.
- */
- @SuppressWarnings("deprecation")
- public AppletContext getAppletContext() {
- return (AppletContext)getParent();
- }
-
- static void debug(String s) {
- if(debug)
- System.err.println("AppletViewerPanel:::" + s);
- }
-
- static void debug(String s, Throwable t) {
- if(debug) {
- t.printStackTrace();
- debug(s);
- }
- }
-}
--- a/src/java.desktop/share/classes/sun/applet/Main.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,460 +0,0 @@
-/*
- * Copyright (c) 1999, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.applet;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.net.URL;
-import java.net.MalformedURLException;
-import java.util.Enumeration;
-import java.util.Properties;
-import java.util.Vector;
-import sun.net.www.ParseUtil;
-
-/**
- * The main entry point into AppletViewer.
- *
- * @deprecated The Applet API is deprecated. See the
- * <a href="../../java/applet/package-summary.html"> java.applet package
- * documentation</a> for further information.
- */
-@Deprecated(since = "9")
-public class Main {
- /**
- * The file which contains all of the AppletViewer specific properties.
- */
- static File theUserPropertiesFile;
-
- /**
- * The default key/value pairs for the required user-specific properties.
- */
- static final String [][] avDefaultUserProps = {
- // There's a bootstrapping problem here. If we don't have a proxyHost,
- // then we will not be able to connect to a URL outside the firewall;
- // however, there's no way for us to set the proxyHost without starting
- // AppletViewer. This problem existed before the re-write.
- {"http.proxyHost", ""},
- {"http.proxyPort", "80"},
- {"package.restrict.access.sun", "true"}
- };
-
- static {
- File userHome = new File(System.getProperty("user.home"));
- // make sure we can write to this location
- userHome.canWrite();
-
- theUserPropertiesFile = new File(userHome, ".appletviewer");
- }
-
- // i18n
- private static AppletMessageHandler amh = new AppletMessageHandler("appletviewer");
-
- /**
- * Member variables set according to options passed in to AppletViewer.
- */
- private boolean helpFlag = false;
- private String encoding = null;
- private boolean noSecurityFlag = false;
- private static boolean cmdLineTestFlag = false;
-
- /**
- * The list of valid URLs passed in to AppletViewer.
- */
- private static Vector<URL> urlList = new Vector<>(1);
-
- // This is used in init(). Getting rid of this is desirable but depends
- // on whether the property that uses it is necessary/standard.
- public static final String theVersion = System.getProperty("java.version");
-
- /**
- * The main entry point into AppletViewer.
- */
- public static void main(String [] args) {
- Main m = new Main();
- int ret = m.run(args);
-
- // Exit immediately if we got some sort of error along the way.
- // For debugging purposes, if we have passed in "-XcmdLineTest" we
- // force a premature exit.
- if ((ret != 0) || (cmdLineTestFlag))
- System.exit(ret);
- }
-
- private int run(String [] args) {
- // DECODE ARGS
- try {
- System.err.println(lookup("deprecated"));
- System.err.flush();
- if (args.length == 0) {
- usage();
- return 0;
- }
- for (int i = 0; i < args.length; ) {
- int j = decodeArg(args, i);
- if (j == 0) {
- throw new ParseException(lookup("main.err.unrecognizedarg",
- args[i]));
- }
- i += j;
- }
- } catch (ParseException e) {
- System.err.println(e.getMessage());
- return 1;
- }
-
- // CHECK ARGUMENTS
- if (helpFlag) {
- usage();
- return 0;
- }
-
- if (urlList.size() == 0) {
- System.err.println(lookup("main.err.inputfile"));
- return 1;
- }
-
- // INSTALL THE SECURITY MANAGER (if necessary)
- if (!noSecurityFlag && (System.getSecurityManager() == null))
- init();
-
- // LAUNCH APPLETVIEWER FOR EACH URL
- for (int i = 0; i < urlList.size(); i++) {
- try {
- // XXX 5/17 this parsing method should be changed/fixed so that
- // it doesn't do both parsing of the html file and launching of
- // the AppletPanel
- AppletViewer.parse(urlList.elementAt(i), encoding);
- } catch (IOException e) {
- System.err.println(lookup("main.err.io", e.getMessage()));
- return 1;
- }
- }
- return 0;
- }
-
- private static void usage() {
- System.out.println(lookup("usage"));
- }
-
- /**
- * Decode a single argument in an array and return the number of elements
- * used.
- *
- * @param args The array of arguments.
- * @param i The argument to decode.
- * @return The number of array elements used when the argument was
- * decoded.
- * @exception ParseException
- * Thrown when there is a problem with something in the
- * argument array.
- */
- private int decodeArg(String [] args, int i) throws ParseException {
- String arg = args[i];
- int argc = args.length;
-
- if ("-help".equalsIgnoreCase(arg) || "-?".equals(arg)) {
- helpFlag = true;
- return 1;
- } else if ("-encoding".equals(arg) && (i < argc - 1)) {
- if (encoding != null)
- throw new ParseException(lookup("main.err.dupoption", arg));
- encoding = args[++i];
- return 2;
- } else if ("-Xnosecurity".equals(arg)) {
- // This is an undocumented (and, in the future, unsupported)
- // flag which prevents AppletViewer from installing its own
- // SecurityManager.
-
- System.err.println();
- System.err.println(lookup("main.warn.nosecmgr"));
- System.err.println();
-
- noSecurityFlag = true;
- return 1;
- } else if ("-XcmdLineTest".equals(arg)) {
- // This is an internal flag which should be used for command-line
- // testing. It instructs AppletViewer to force a premature exit
- // immediately after the applet has been launched.
- cmdLineTestFlag = true;
- return 1;
- } else if (arg.startsWith("-")) {
- throw new ParseException(lookup("main.err.unsupportedopt", arg));
- } else {
- // we found what we hope is a url
- URL url = parseURL(arg);
- if (url != null) {
- urlList.addElement(url);
- return 1;
- }
- }
- return 0;
- }
-
- /**
- * Following the relevant RFC, construct a valid URL based on the passed in
- * string.
- *
- * @param url a string which represents either a relative or absolute URL.
- * @return a URL when the passed in string can be interpreted according
- * to the RFC, {@code null} otherwise.
- * @exception ParseException
- * Thrown when we are unable to construct a proper URL from the
- * passed in string.
- */
- private URL parseURL(String url) throws ParseException {
- URL u = null;
- // prefix of the urls with 'file' scheme
- String prefix = "file:";
-
- try {
- if (url.indexOf(':') <= 1)
- {
- // appletviewer accepts only unencoded filesystem paths
- u = ParseUtil.fileToEncodedURL(new File(url));
- } else if (url.startsWith(prefix) &&
- url.length() != prefix.length() &&
- !(new File(url.substring(prefix.length())).isAbsolute()))
- {
- // relative file URL, like this "file:index.html"
- // ensure that this file URL is absolute
- // ParseUtil.fileToEncodedURL should be done last (see 6329251)
- String path = ParseUtil.fileToEncodedURL(new File(System.getProperty("user.dir"))).getPath() +
- url.substring(prefix.length());
- u = new URL("file", "", path);
- } else {
- // appletviewer accepts only encoded urls
- u = new URL(url);
- }
- } catch (MalformedURLException e) {
- throw new ParseException(lookup("main.err.badurl",
- url, e.getMessage()));
- }
-
- return u;
- }
-
- private void init() {
- // GET APPLETVIEWER USER-SPECIFIC PROPERTIES
- Properties avProps = getAVProps();
-
- // ADD OTHER RANDOM PROPERTIES
- // XXX 5/18 need to revisit why these are here, is there some
- // standard for what is available?
-
- // Standard browser properties
- avProps.put("browser", "sun.applet.AppletViewer");
- avProps.put("browser.version", "1.06");
- avProps.put("browser.vendor", "Oracle Corporation");
- avProps.put("http.agent", "Java(tm) 2 SDK, Standard Edition v" + theVersion);
-
- // Define which packages can be extended by applets
- // XXX 5/19 probably not needed, not checked in AppletSecurity
- avProps.put("package.restrict.definition.java", "true");
- avProps.put("package.restrict.definition.sun", "true");
-
- // Define which properties can be read by applets.
- // A property named by "key" can be read only when its twin
- // property "key.applet" is true. The following ten properties
- // are open by default. Any other property can be explicitly
- // opened up by the browser user by calling appletviewer with
- // -J-Dkey.applet=true
- avProps.put("java.version.applet", "true");
- avProps.put("java.vendor.applet", "true");
- avProps.put("java.vendor.url.applet", "true");
- avProps.put("java.class.version.applet", "true");
- avProps.put("os.name.applet", "true");
- avProps.put("os.version.applet", "true");
- avProps.put("os.arch.applet", "true");
- avProps.put("file.separator.applet", "true");
- avProps.put("path.separator.applet", "true");
- avProps.put("line.separator.applet", "true");
-
- // Read in the System properties. If something is going to be
- // over-written, warn about it.
- Properties sysProps = System.getProperties();
- for (Enumeration<?> e = sysProps.propertyNames(); e.hasMoreElements(); ) {
- String key = (String) e.nextElement();
- String val = sysProps.getProperty(key);
- String oldVal;
- if ((oldVal = (String) avProps.setProperty(key, val)) != null)
- System.err.println(lookup("main.warn.prop.overwrite", key,
- oldVal, val));
- }
-
- // INSTALL THE PROPERTY LIST
- System.setProperties(avProps);
-
- // Create and install the security manager
- if (!noSecurityFlag) {
- System.setSecurityManager(new AppletSecurity());
- } else {
- System.err.println(lookup("main.nosecmgr"));
- }
-
- // REMIND: Create and install a socket factory!
- }
-
- /**
- * Read the AppletViewer user-specific properties. Typically, these
- * properties should reside in the file $USER/.appletviewer. If this file
- * does not exist, one will be created. Information for this file will
- * be gleaned from $USER/.hotjava/properties. If that file does not exist,
- * then default values will be used.
- *
- * @return A Properties object containing all of the AppletViewer
- * user-specific properties.
- */
- private Properties getAVProps() {
- Properties avProps = new Properties();
-
- File dotAV = theUserPropertiesFile;
- if (dotAV.exists()) {
- // we must have already done the conversion
- if (dotAV.canRead()) {
- // just read the file
- avProps = getAVProps(dotAV);
- } else {
- // send out warning and use defaults
- System.err.println(lookup("main.warn.cantreadprops",
- dotAV.toString()));
- avProps = setDefaultAVProps();
- }
- } else {
- // create the $USER/.appletviewer file
-
- // see if $USER/.hotjava/properties exists
- File userHome = new File(System.getProperty("user.home"));
- File dotHJ = new File(userHome, ".hotjava");
- dotHJ = new File(dotHJ, "properties");
- if (dotHJ.exists()) {
- // just read the file
- avProps = getAVProps(dotHJ);
- } else {
- // send out warning and use defaults
- System.err.println(lookup("main.warn.cantreadprops",
- dotHJ.toString()));
- avProps = setDefaultAVProps();
- }
-
- // SAVE THE FILE
- try (FileOutputStream out = new FileOutputStream(dotAV)) {
- avProps.store(out, lookup("main.prop.store"));
- } catch (IOException e) {
- System.err.println(lookup("main.err.prop.cantsave",
- dotAV.toString()));
- }
- }
- return avProps;
- }
-
- /**
- * Set the AppletViewer user-specific properties to be the default values.
- *
- * @return A Properties object containing all of the AppletViewer
- * user-specific properties, set to the default values.
- */
- private Properties setDefaultAVProps() {
- Properties avProps = new Properties();
- for (int i = 0; i < avDefaultUserProps.length; i++) {
- avProps.setProperty(avDefaultUserProps[i][0],
- avDefaultUserProps[i][1]);
- }
- return avProps;
- }
-
- /**
- * Given a file, find only the properties that are setable by AppletViewer.
- *
- * @param inFile A Properties file from which we select the properties of
- * interest.
- * @return A Properties object containing all of the AppletViewer
- * user-specific properties.
- */
- private Properties getAVProps(File inFile) {
- Properties avProps = new Properties();
-
- // read the file
- Properties tmpProps = new Properties();
- try (FileInputStream in = new FileInputStream(inFile)) {
- tmpProps.load(new BufferedInputStream(in));
- } catch (IOException e) {
- System.err.println(lookup("main.err.prop.cantread", inFile.toString()));
- }
-
- // pick off the properties we care about
- for (int i = 0; i < avDefaultUserProps.length; i++) {
- String value = tmpProps.getProperty(avDefaultUserProps[i][0]);
- if (value != null) {
- // the property exists in the file, so replace the default
- avProps.setProperty(avDefaultUserProps[i][0], value);
- } else {
- // just use the default
- avProps.setProperty(avDefaultUserProps[i][0],
- avDefaultUserProps[i][1]);
- }
- }
- return avProps;
- }
-
- /**
- * Methods for easier i18n handling.
- */
-
- private static String lookup(String key) {
- return amh.getMessage(key);
- }
-
- private static String lookup(String key, String arg0) {
- return amh.getMessage(key, arg0);
- }
-
- private static String lookup(String key, String arg0, String arg1) {
- return amh.getMessage(key, arg0, arg1);
- }
-
- private static String lookup(String key, String arg0, String arg1,
- String arg2) {
- return amh.getMessage(key, arg0, arg1, arg2);
- }
-
- @SuppressWarnings("serial") // JDK implementation class
- class ParseException extends RuntimeException
- {
- public ParseException(String msg) {
- super(msg);
- }
-
- public ParseException(Throwable t) {
- super(t.getMessage());
- this.t = t;
- }
-
- Throwable t = null;
- }
-}
--- a/src/java.desktop/share/classes/sun/applet/resources/MsgAppletViewer.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,200 +0,0 @@
-/*
- * Copyright (c) 1996, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-package sun.applet.resources;
-
-import java.util.ListResourceBundle;
-
-public class MsgAppletViewer extends ListResourceBundle {
-
- public Object[][] getContents() {
- Object[][] temp = new Object[][] {
- {"textframe.button.dismiss", "Dismiss"},
- {"appletviewer.tool.title", "Applet Viewer: {0}"},
- {"appletviewer.menu.applet", "Applet"},
- {"appletviewer.menuitem.restart", "Restart"},
- {"appletviewer.menuitem.reload", "Reload"},
- {"appletviewer.menuitem.stop", "Stop"},
- {"appletviewer.menuitem.save", "Save..."},
- {"appletviewer.menuitem.start", "Start"},
- {"appletviewer.menuitem.clone", "Clone..."},
- {"appletviewer.menuitem.tag", "Tag..."},
- {"appletviewer.menuitem.info", "Info..."},
- {"appletviewer.menuitem.edit", "Edit"},
- {"appletviewer.menuitem.encoding", "Character Encoding"},
- {"appletviewer.menuitem.print", "Print..."},
- {"appletviewer.menuitem.props", "Properties..."},
- {"appletviewer.menuitem.close", "Close"},
- {"appletviewer.menuitem.quit", "Quit"},
- {"appletviewer.label.hello", "Hello..."},
- {"appletviewer.status.start", "starting applet..."},
- {"appletviewer.appletsave.filedialogtitle","Serialize Applet into File"},
- {"appletviewer.appletsave.err1", "serializing an {0} to {1}"},
- {"appletviewer.appletsave.err2", "in appletSave: {0}"},
- {"appletviewer.applettag", "Tag shown"},
- {"appletviewer.applettag.textframe", "Applet HTML Tag"},
- {"appletviewer.appletinfo.applet", "-- no applet info --"},
- {"appletviewer.appletinfo.param", "-- no parameter info --"},
- {"appletviewer.appletinfo.textframe", "Applet Info"},
- {"appletviewer.appletprint.fail", "Printing failed."},
- {"appletviewer.appletprint.finish", "Finished printing."},
- {"appletviewer.appletprint.cancel", "Printing cancelled."},
- {"appletviewer.appletencoding", "Character Encoding: {0}"},
- {"appletviewer.parse.warning.requiresname", "Warning: <param name=... value=...> tag requires name attribute."},
- {"appletviewer.parse.warning.paramoutside", "Warning: <param> tag outside <applet> ... </applet>."},
- {"appletviewer.parse.warning.applet.requirescode", "Warning: <applet> tag requires code attribute."},
- {"appletviewer.parse.warning.applet.requiresheight", "Warning: <applet> tag requires height attribute."},
- {"appletviewer.parse.warning.applet.requireswidth", "Warning: <applet> tag requires width attribute."},
- {"appletviewer.parse.warning.object.requirescode", "Warning: <object> tag requires code attribute."},
- {"appletviewer.parse.warning.object.requiresheight", "Warning: <object> tag requires height attribute."},
- {"appletviewer.parse.warning.object.requireswidth", "Warning: <object> tag requires width attribute."},
- {"appletviewer.parse.warning.embed.requirescode", "Warning: <embed> tag requires code attribute."},
- {"appletviewer.parse.warning.embed.requiresheight", "Warning: <embed> tag requires height attribute."},
- {"appletviewer.parse.warning.embed.requireswidth", "Warning: <embed> tag requires width attribute."},
- {"appletviewer.parse.warning.appnotLongersupported", "Warning: <app> tag no longer supported, use <applet> instead:"},
- {"appletviewer.deprecated", "Warning: Applet API and AppletViewer are deprecated."},
- {"appletviewer.usage", "Usage: appletviewer <options> url(s)\n\nwhere <options> include:\n -encoding <encoding> Specify character encoding used by HTML files\n -J<runtime flag> Pass argument to the java interpreter\n\nThe -J option is non-standard and subject to change without notice."},
- {"appletviewer.main.err.unsupportedopt", "Unsupported option: {0}"},
- {"appletviewer.main.err.unrecognizedarg", "Unrecognized argument: {0}"},
- {"appletviewer.main.err.dupoption", "Duplicate use of option: {0}"},
- {"appletviewer.main.err.inputfile", "No input files specified."},
- {"appletviewer.main.err.badurl", "Bad URL: {0} ( {1} )"},
- {"appletviewer.main.err.io", "I/O exception while reading: {0}"},
- {"appletviewer.main.err.readablefile", "Make sure that {0} is a file and is readable."},
- {"appletviewer.main.err.correcturl", "Is {0} the correct URL?"},
- {"appletviewer.main.prop.store", "User-specific properties for AppletViewer"},
- {"appletviewer.main.err.prop.cantread", "Can''t read user properties file: {0}"},
- {"appletviewer.main.err.prop.cantsave", "Can''t save user properties file: {0}"},
- {"appletviewer.main.warn.nosecmgr", "Warning: disabling security."},
- {"appletviewer.main.debug.cantfinddebug", "Can''t find the debugger!"},
- {"appletviewer.main.debug.cantfindmain", "Can''t find main method in the debugger!"},
- {"appletviewer.main.debug.exceptionindebug", "Exception in the debugger!"},
- {"appletviewer.main.debug.cantaccess", "Can''t access the debugger!"},
- {"appletviewer.main.nosecmgr", "Warning: SecurityManager not installed!"},
- {"appletviewer.main.warning", "Warning: No applets were started. Make sure the input contains an <applet> tag."},
- {"appletviewer.main.warn.prop.overwrite", "Warning: Temporarily overwriting system property at user''s request: key: {0} old value: {1} new value: {2}"},
- {"appletviewer.main.warn.cantreadprops", "Warning: Can''t read AppletViewer properties file: {0} Using defaults."},
- {"appletioexception.loadclass.throw.interrupted", "class loading interrupted: {0}"},
- {"appletioexception.loadclass.throw.notloaded", "class not loaded: {0}"},
- {"appletclassloader.loadcode.verbose", "Opening stream to: {0} to get {1}"},
- {"appletclassloader.filenotfound", "File not found when looking for: {0}"},
- {"appletclassloader.fileformat", "File format exception when loading: {0}"},
- {"appletclassloader.fileioexception", "I/O exception when loading: {0}"},
- {"appletclassloader.fileexception", "{0} exception when loading: {1}"},
- {"appletclassloader.filedeath", "{0} killed when loading: {1}"},
- {"appletclassloader.fileerror", "{0} error when loading: {1}"},
- {"appletclassloader.findclass.verbose.openstream", "Opening stream to: {0} to get {1}"},
- {"appletclassloader.getresource.verbose.forname", "AppletClassLoader.getResource for name: {0}"},
- {"appletclassloader.getresource.verbose.found", "Found resource: {0} as a system resource"},
- {"appletclassloader.getresourceasstream.verbose", "Found resource: {0} as a system resource"},
- {"appletpanel.runloader.err", "Either object or code parameter!"},
- {"appletpanel.runloader.exception", "exception while deserializing {0}"},
- {"appletpanel.destroyed", "Applet destroyed."},
- {"appletpanel.loaded", "Applet loaded."},
- {"appletpanel.started", "Applet started."},
- {"appletpanel.inited", "Applet initialized."},
- {"appletpanel.stopped", "Applet stopped."},
- {"appletpanel.disposed", "Applet disposed."},
- {"appletpanel.nocode", "APPLET tag missing CODE parameter."},
- {"appletpanel.notfound", "load: class {0} not found."},
- {"appletpanel.nocreate", "load: {0} can''t be instantiated."},
- {"appletpanel.noconstruct", "load: {0} is not public or has no public constructor."},
- {"appletpanel.death", "killed"},
- {"appletpanel.exception", "exception: {0}."},
- {"appletpanel.exception2", "exception: {0}: {1}."},
- {"appletpanel.error", "error: {0}."},
- {"appletpanel.error2", "error: {0}: {1}."},
- {"appletpanel.notloaded", "Init: applet not loaded."},
- {"appletpanel.notinited", "Start: applet not initialized."},
- {"appletpanel.notstarted", "Stop: applet not started."},
- {"appletpanel.notstopped", "Destroy: applet not stopped."},
- {"appletpanel.notdestroyed", "Dispose: applet not destroyed."},
- {"appletpanel.notdisposed", "Load: applet not disposed."},
- {"appletpanel.bail", "Interrupted: bailing out."},
- {"appletpanel.filenotfound", "File not found when looking for: {0}"},
- {"appletpanel.fileformat", "File format exception when loading: {0}"},
- {"appletpanel.fileioexception", "I/O exception when loading: {0}"},
- {"appletpanel.fileexception", "{0} exception when loading: {1}"},
- {"appletpanel.filedeath", "{0} killed when loading: {1}"},
- {"appletpanel.fileerror", "{0} error when loading: {1}"},
- {"appletpanel.badattribute.exception", "HTML parsing: incorrect value for width/height attribute"},
- {"appletillegalargumentexception.objectinputstream", "AppletObjectInputStream requires non-null loader"},
- {"appletprops.title", "AppletViewer Properties"},
- {"appletprops.label.http.server", "Http proxy server:"},
- {"appletprops.label.http.proxy", "Http proxy port:"},
- {"appletprops.label.network", "Network access:"},
- {"appletprops.choice.network.item.none", "None"},
- {"appletprops.choice.network.item.applethost", "Applet Host"},
- {"appletprops.choice.network.item.unrestricted", "Unrestricted"},
- {"appletprops.label.class", "Class access:"},
- {"appletprops.choice.class.item.restricted", "Restricted"},
- {"appletprops.choice.class.item.unrestricted", "Unrestricted"},
- {"appletprops.label.unsignedapplet", "Allow unsigned applets:"},
- {"appletprops.choice.unsignedapplet.no", "No"},
- {"appletprops.choice.unsignedapplet.yes", "Yes"},
- {"appletprops.button.apply", "Apply"},
- {"appletprops.button.cancel", "Cancel"},
- {"appletprops.button.reset", "Reset"},
- {"appletprops.apply.exception", "Failed to save properties: {0}"},
- /* 4066432 */
- {"appletprops.title.invalidproxy", "Invalid Entry"},
- {"appletprops.label.invalidproxy", "Proxy Port must be a positive integer value."},
- {"appletprops.button.ok", "OK"},
- /* end 4066432 */
- {"appletprops.prop.store", "User-specific properties for AppletViewer"},
- {"appletsecurityexception.checkcreateclassloader", "Security Exception: classloader"},
- {"appletsecurityexception.checkaccess.thread", "Security Exception: thread"},
- {"appletsecurityexception.checkaccess.threadgroup", "Security Exception: threadgroup: {0}"},
- {"appletsecurityexception.checkexit", "Security Exception: exit: {0}"},
- {"appletsecurityexception.checkexec", "Security Exception: exec: {0}"},
- {"appletsecurityexception.checklink", "Security Exception: link: {0}"},
- {"appletsecurityexception.checkpropsaccess", "Security Exception: properties"},
- {"appletsecurityexception.checkpropsaccess.key", "Security Exception: properties access {0}"},
- {"appletsecurityexception.checkread.exception1", "Security Exception: {0}, {1}"},
- {"appletsecurityexception.checkread.exception2", "Security Exception: file.read: {0}"},
- {"appletsecurityexception.checkread", "Security Exception: file.read: {0} == {1}"},
- {"appletsecurityexception.checkwrite.exception", "Security Exception: {0}, {1}"},
- {"appletsecurityexception.checkwrite", "Security Exception: file.write: {0} == {1}"},
- {"appletsecurityexception.checkread.fd", "Security Exception: fd.read"},
- {"appletsecurityexception.checkwrite.fd", "Security Exception: fd.write"},
- {"appletsecurityexception.checklisten", "Security Exception: socket.listen: {0}"},
- {"appletsecurityexception.checkaccept", "Security Exception: socket.accept: {0}:{1}"},
- {"appletsecurityexception.checkconnect.networknone", "Security Exception: socket.connect: {0}->{1}"},
- {"appletsecurityexception.checkconnect.networkhost1", "Security Exception: Couldn''t connect to {0} with origin from {1}."},
- {"appletsecurityexception.checkconnect.networkhost2", "Security Exception: Couldn''t resolve IP for host {0} or for {1}. "},
- {"appletsecurityexception.checkconnect.networkhost3", "Security Exception: Could not resolve IP for host {0}. See the trustProxy property."},
- {"appletsecurityexception.checkconnect", "Security Exception: connect: {0}->{1}"},
- {"appletsecurityexception.checkpackageaccess", "Security Exception: cannot access package: {0}"},
- {"appletsecurityexception.checkpackagedefinition", "Security Exception: cannot define package: {0}"},
- {"appletsecurityexception.cannotsetfactory", "Security Exception: cannot set factory"},
- {"appletsecurityexception.checkgetprintjob", "Security Exception: getPrintJob"},
- {"appletsecurityexception.checksecurityaccess", "Security Exception: security operation: {0}"},
- {"appletsecurityexception.getsecuritycontext.unknown", "unknown class loader type. unable to check for getContext"},
- {"appletsecurityexception.checkread.unknown", "unknown class loader type. unable to check for checking read {0}"},
- {"appletsecurityexception.checkconnect.unknown", "unknown class loader type. unable to check for checking connect"},
- };
-
- return temp;
- }
-}
--- a/src/java.desktop/share/classes/sun/applet/resources/MsgAppletViewer_de.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,203 +0,0 @@
-/*
- * Copyright (c) 1996, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-package sun.applet.resources;
-
-import java.util.ListResourceBundle;
-
-public class MsgAppletViewer_de extends ListResourceBundle {
-
- public Object[][] getContents() {
- Object[][] temp = new Object[][] {
- {"textframe.button.dismiss", "Verwerfen"},
- {"appletviewer.tool.title", "Applet Viewer: {0}"},
- {"appletviewer.menu.applet", "Applet"},
- {"appletviewer.menuitem.restart", "Neu starten"},
- {"appletviewer.menuitem.reload", "Neu laden"},
- {"appletviewer.menuitem.stop", "Stoppen"},
- {"appletviewer.menuitem.save", "Speichern..."},
- {"appletviewer.menuitem.start", "Starten..."},
- {"appletviewer.menuitem.clone", "Klonen..."},
- {"appletviewer.menuitem.tag", "Tag..."},
- {"appletviewer.menuitem.info", "Informationen..."},
- {"appletviewer.menuitem.edit", "Bearbeiten"},
- {"appletviewer.menuitem.encoding", "Zeichencodierung"},
- {"appletviewer.menuitem.print", "Drucken..."},
- {"appletviewer.menuitem.props", "Eigenschaften..."},
- {"appletviewer.menuitem.close", "Schlie\u00DFen"},
- {"appletviewer.menuitem.quit", "Beenden"},
- {"appletviewer.label.hello", "Hallo..."},
- {"appletviewer.status.start", "Applet wird gestartet..."},
- {"appletviewer.appletsave.filedialogtitle","Applet in Datei serialisieren"},
- {"appletviewer.appletsave.err1", "{0} in {1} serialisieren"},
- {"appletviewer.appletsave.err2", "in appletSave: {0}"},
- {"appletviewer.applettag", "Angezeigtes Tag"},
- {"appletviewer.applettag.textframe", "Applet-HTML-Tag"},
- {"appletviewer.appletinfo.applet", "-- keine Applet-Informationen --"},
- {"appletviewer.appletinfo.param", "-- keine Parameterinformationen --"},
- {"appletviewer.appletinfo.textframe", "Applet-Informationen"},
- {"appletviewer.appletprint.fail", "Druck nicht erfolgreich."},
- {"appletviewer.appletprint.finish", "Druck abgeschlossen."},
- {"appletviewer.appletprint.cancel", "Druck abgebrochen."},
- {"appletviewer.appletencoding", "Zeichencodierung: {0}"},
- {"appletviewer.parse.warning.requiresname", "Warnung: F\u00FCr <param name=... value=...>-Tag ist ein \"name\"-Attribut erforderlich."},
- {"appletviewer.parse.warning.paramoutside", "Warnung: <param>-Tag au\u00DFerhalb von <applet> ... </applet>."},
- {"appletviewer.parse.warning.applet.requirescode", "Warnung: F\u00FCr <applet>-Tag ist ein \"code\"-Attribut erforderlich."},
- {"appletviewer.parse.warning.applet.requiresheight", "Warnung: F\u00FCr <applet>-Tag ist ein \"height\"-Attribut erforderlich."},
- {"appletviewer.parse.warning.applet.requireswidth", "Warnung: F\u00FCr <applet>-Tag ist ein \"width\"-Attribut erforderlich."},
- {"appletviewer.parse.warning.object.requirescode", "Warnung: F\u00FCr <object>-Tag ist ein \"code\"-Attribut erforderlich."},
- {"appletviewer.parse.warning.object.requiresheight", "Warnung: F\u00FCr <object>-Tag ist ein \"height\"-Attribut erforderlich."},
- {"appletviewer.parse.warning.object.requireswidth", "Warnung: F\u00FCr <object>-Tag ist ein \"width\"-Attribut erforderlich."},
- {"appletviewer.parse.warning.embed.requirescode", "Warnung: F\u00FCr <embed>-Tag ist ein \"code\"-Attribut erforderlich."},
- {"appletviewer.parse.warning.embed.requiresheight", "Warnung: F\u00FCr <embed>-Tag ist ein \"height\"-Attribut erforderlich."},
- {"appletviewer.parse.warning.embed.requireswidth", "Warnung: F\u00FCr <embed>-Tag ist ein \"width\"-Attribut erforderlich."},
- {"appletviewer.parse.warning.appnotLongersupported", "Warnung: <app>-Tag wird nicht mehr unterst\u00FCtzt. Verwenden Sie stattdessen <applet>:"},
- {"appletviewer.deprecated", "Warnung: Applet-API und AppletViewer sind veraltet."},
- {"appletviewer.usage", "Verwendung: appletviewer <Optionen> url(s)\n\nwobei die <Optionen> Folgendes umfassen:\n -encoding <Codierung> Zeichencodierung f\u00FCr HTML-Dateien angeben\n -J<Laufzeitkennzeichen> Argument an den Java-Interpreter \u00FCbergeben\n\nDie Option \"-J\" ist nicht standardm\u00E4\u00DFig und kann ohne vorherige Ank\u00FCndigung ge\u00E4ndert werden."},
- {"appletviewer.main.err.unsupportedopt", "Nicht unterst\u00FCtzte Option: {0}"},
- {"appletviewer.main.err.unrecognizedarg", "Unbekanntes Argument: {0}"},
- {"appletviewer.main.err.dupoption", "Doppelte Verwendung von Option: {0}"},
- {"appletviewer.main.err.inputfile", "Keine Eingabedateien angegeben."},
- {"appletviewer.main.err.badurl", "Ung\u00FCltige URL: {0} ( {1} )"},
- {"appletviewer.main.err.io", "I/O-Ausnahme beim Lesen von: {0}"},
- {"appletviewer.main.err.readablefile", "Stellen Sie sicher, dass {0} eine lesbare Datei ist."},
- {"appletviewer.main.err.correcturl", "Ist {0} die richtige URL?"},
- {"appletviewer.main.prop.store", "Benutzerspezifische Eigenschaften f\u00FCr AppletViewer"},
- {"appletviewer.main.err.prop.cantread", "Benutzereigenschaftendatei kann nicht gelesen werden: {0}"},
- {"appletviewer.main.err.prop.cantsave", "Benutzereigenschaftendatei kann nicht gespeichert werden: {0}"},
- {"appletviewer.main.warn.nosecmgr", "Warnung: Sicherheit wird deaktiviert."},
- {"appletviewer.main.debug.cantfinddebug", "Debugger kann nicht gefunden werden."},
- {"appletviewer.main.debug.cantfindmain", "Hauptmethode im Debugger kann nicht gefunden werden."},
- {"appletviewer.main.debug.exceptionindebug", "Ausnahme im Debugger."},
- {"appletviewer.main.debug.cantaccess", "Zugriff auf Debugger nicht m\u00F6glich."},
- {"appletviewer.main.nosecmgr", "Warnung: SecurityManager nicht installiert."},
- {"appletviewer.main.warning", "Warnung: Es wurden keine Applets gestartet. Stellen Sie sicher, dass die Eingabe ein <applet>-Tag enth\u00E4lt."},
- {"appletviewer.main.warn.prop.overwrite", "Warnung: Systemeigenschaft wird tempor\u00E4r aufgrund von Benutzeranforderung \u00FCberschrieben: Schl\u00FCssel: {0} Alter Wert: {1} Neuer Wert: {2}"},
- {"appletviewer.main.warn.cantreadprops", "Warnung: AppletViewer-Eigenschaftendatei kann nicht gelesen werden: {0} Standardwerte werden verwendet."},
- {"appletioexception.loadclass.throw.interrupted", "Laden der Klasse unterbrochen: {0}"},
- {"appletioexception.loadclass.throw.notloaded", "Klasse nicht geladen: {0}"},
- {"appletclassloader.loadcode.verbose", "\u00D6ffnen von Stream zu: {0}, um {1} abzurufen"},
- {"appletclassloader.filenotfound", "Datei nicht gefunden beim Suchen nach: {0}"},
- {"appletclassloader.fileformat", "Dateiformatausnahme beim Laden von: {0}"},
- {"appletclassloader.fileioexception", "I/O-Ausnahme beim Laden von: {0}"},
- {"appletclassloader.fileexception", "{0}-Ausnahme beim Laden von: {1}"},
- {"appletclassloader.filedeath", "{0} abgebrochen beim Laden von: {1}"},
- {"appletclassloader.fileerror", "{0}-Fehler beim Laden von: {1}"},
- {"appletclassloader.findclass.verbose.openstream", "\u00D6ffnen von Stream zu: {0}, um {1} abzurufen"},
- {"appletclassloader.getresource.verbose.forname", "AppletClassLoader.getResource f\u00FCr Name: {0}"},
- {"appletclassloader.getresource.verbose.found", "Ressource {0} als Systemressource gefunden"},
- {"appletclassloader.getresourceasstream.verbose", "Ressource {0} als Systemressource gefunden"},
- {"appletpanel.runloader.err", "Objekt oder Codeparameter."},
- {"appletpanel.runloader.exception", "Ausnahme beim Deserialisieren von {0}"},
- {"appletpanel.destroyed", "Applet zerst\u00F6rt."},
- {"appletpanel.loaded", "Applet geladen."},
- {"appletpanel.started", "Applet gestartet."},
- {"appletpanel.inited", "Applet initialisiert."},
- {"appletpanel.stopped", "Applet gestoppt."},
- {"appletpanel.disposed", "Applet verworfen."},
- {"appletpanel.nocode", "Bei APPLET-Tag fehlt CODE-Parameter."},
- {"appletpanel.notfound", "Laden: Klasse {0} nicht gefunden."},
- {"appletpanel.nocreate", "Laden: {0} kann nicht instanziiert werden."},
- {"appletpanel.noconstruct", "Laden: {0} ist nicht \"public\" oder hat keinen \"public\"-Constructor."},
- {"appletpanel.death", "abgebrochen"},
- {"appletpanel.exception", "Ausnahme: {0}."},
- {"appletpanel.exception2", "Ausnahme: {0}: {1}."},
- {"appletpanel.error", "Fehler: {0}."},
- {"appletpanel.error2", "Fehler: {0}: {1}."},
- {"appletpanel.notloaded", "Init.: Applet nicht geladen."},
- {"appletpanel.notinited", "Starten: Applet nicht initialisiert."},
- {"appletpanel.notstarted", "Stoppen: Applet nicht gestartet."},
- {"appletpanel.notstopped", "Zerst\u00F6ren: Applet nicht gestoppt."},
- {"appletpanel.notdestroyed", "Verwerfen: Applet nicht zerst\u00F6rt."},
- {"appletpanel.notdisposed", "Laden: Applet nicht verworfen."},
- {"appletpanel.bail", "Unterbrochen: Zur\u00FCckziehen."},
- {"appletpanel.filenotfound", "Datei nicht gefunden beim Suchen nach: {0}"},
- {"appletpanel.fileformat", "Dateiformatausnahme beim Laden von: {0}"},
- {"appletpanel.fileioexception", "I/O-Ausnahme beim Laden von: {0}"},
- {"appletpanel.fileexception", "{0}-Ausnahme beim Laden von: {1}"},
- {"appletpanel.filedeath", "{0} abgebrochen beim Laden von: {1}"},
- {"appletpanel.fileerror", "{0}-Fehler beim Laden von: {1}"},
- {"appletpanel.badattribute.exception", "HTML-Parsing: Falscher Wert f\u00FCr \"width/height\"-Attribut"},
- {"appletillegalargumentexception.objectinputstream", "AppletObjectInputStream erfordert Loader ungleich null"},
- {"appletprops.title", "AppletViewer-Eigenschaften"},
- {"appletprops.label.http.server", "HTTP-Proxyserver:"},
- {"appletprops.label.http.proxy", "HTTP-Proxyport:"},
- {"appletprops.label.network", "Netzwerkzugriff:"},
- {"appletprops.choice.network.item.none", "Keine"},
- {"appletprops.choice.network.item.applethost", "Applet-Host"},
- {"appletprops.choice.network.item.unrestricted", "Uneingeschr\u00E4nkt"},
- {"appletprops.label.class", "Klassenzugriff:"},
- {"appletprops.choice.class.item.restricted", "Eingeschr\u00E4nkt"},
- {"appletprops.choice.class.item.unrestricted", "Uneingeschr\u00E4nkt"},
- {"appletprops.label.unsignedapplet", "Nicht signierte Applets zulassen:"},
- {"appletprops.choice.unsignedapplet.no", "Nein"},
- {"appletprops.choice.unsignedapplet.yes", "Ja"},
- {"appletprops.button.apply", "Anwenden"},
- {"appletprops.button.cancel", "Abbrechen"},
- {"appletprops.button.reset", "Zur\u00FCcksetzen"},
- {"appletprops.apply.exception", "Eigenschaften konnten nicht gespeichert werden: {0}"},
- /* 4066432 */
- {"appletprops.title.invalidproxy", "Ung\u00FCltiger Eintrag"},
- {"appletprops.label.invalidproxy", "Proxyport muss ein positiver Ganzzahlwert sein."},
- {"appletprops.button.ok", "OK"},
- /* end 4066432 */
- {"appletprops.prop.store", "Benutzerspezifische Eigenschaften f\u00FCr AppletViewer"},
- {"appletsecurityexception.checkcreateclassloader", "Sicherheitsausnahme: Class Loader"},
- {"appletsecurityexception.checkaccess.thread", "Sicherheitsausnahme: Thread"},
- {"appletsecurityexception.checkaccess.threadgroup", "Sicherheitsausnahme: Threadgruppe: {0}"},
- {"appletsecurityexception.checkexit", "Sicherheitsausnahme: Beenden: {0}"},
- {"appletsecurityexception.checkexec", "Sicherheitsausnahme: Ausf\u00FChrung: {0}"},
- {"appletsecurityexception.checklink", "Sicherheitsausnahme: Link: {0}"},
- {"appletsecurityexception.checkpropsaccess", "Sicherheitsausnahme: Eigenschaften"},
- {"appletsecurityexception.checkpropsaccess.key", "Sicherheitsausnahme: Eigenschaftszugriff {0}"},
- {"appletsecurityexception.checkread.exception1", "Sicherheitsausnahme: {0}, {1}"},
- {"appletsecurityexception.checkread.exception2", "Sicherheitsausnahme: file.read: {0}"},
- {"appletsecurityexception.checkread", "Sicherheitsausnahme: file.read: {0} == {1}"},
- {"appletsecurityexception.checkwrite.exception", "Sicherheitsausnahme: {0}, {1}"},
- {"appletsecurityexception.checkwrite", "Sicherheitsausnahme: file.write: {0} == {1}"},
- {"appletsecurityexception.checkread.fd", "Sicherheitsausnahme: fd.read"},
- {"appletsecurityexception.checkwrite.fd", "Sicherheitsausnahme: fd.write"},
- {"appletsecurityexception.checklisten", "Sicherheitsausnahme: socket.listen: {0}"},
- {"appletsecurityexception.checkaccept", "Sicherheitsausnahme: socket.accept: {0}:{1}"},
- {"appletsecurityexception.checkconnect.networknone", "Sicherheitsausnahme: socket.connect: {0}->{1}"},
- {"appletsecurityexception.checkconnect.networkhost1", "Sicherheitsausnahme: Verbindung mit {0} mit Ursprung aus {1} konnte nicht hergestellt werden."},
- {"appletsecurityexception.checkconnect.networkhost2", "Sicherheitsausnahme: IP f\u00FCr Host {0} oder f\u00FCr {1} konnte nicht aufgel\u00F6st werden. "},
- {"appletsecurityexception.checkconnect.networkhost3", "Sicherheitsausnahme: IP f\u00FCr Host {0} konnte nicht aufgel\u00F6st werden. Siehe trustProxy-Eigenschaft."},
- {"appletsecurityexception.checkconnect", "Sicherheitsausnahme: Verbinden: {0}->{1}"},
- {"appletsecurityexception.checkpackageaccess", "Sicherheitsausnahme: Zugriff auf Package nicht m\u00F6glich: {0}"},
- {"appletsecurityexception.checkpackagedefinition", "Sicherheitsausnahme: Package kann nicht definiert werden: {0}"},
- {"appletsecurityexception.cannotsetfactory", "Sicherheitsausnahme: Factory kann nicht festgelegt werden"},
- {"appletsecurityexception.checkmemberaccess", "Sicherheitsausnahme: Mitgliedszugriff pr\u00FCfen"},
- {"appletsecurityexception.checkgetprintjob", "Sicherheitsausnahme: getPrintJob"},
- {"appletsecurityexception.checksystemclipboardaccess", "Sicherheitsausnahme: getSystemClipboard"},
- {"appletsecurityexception.checkawteventqueueaccess", "Sicherheitsausnahme: getEventQueue"},
- {"appletsecurityexception.checksecurityaccess", "Sicherheitsausnahme: Sicherheitsvorgang: {0}"},
- {"appletsecurityexception.getsecuritycontext.unknown", "Unbekannter Class Loader-Typ. Pr\u00FCfen auf getContext nicht m\u00F6glich"},
- {"appletsecurityexception.checkread.unknown", "Unbekannter Class Loader-Typ. Pr\u00FCfen auf checkRead {0} nicht m\u00F6glich"},
- {"appletsecurityexception.checkconnect.unknown", "Unbekannter Class Loader-Typ. Pr\u00FCfen auf checkConnect nicht m\u00F6glich"},
- };
-
- return temp;
- }
-}
--- a/src/java.desktop/share/classes/sun/applet/resources/MsgAppletViewer_es.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,203 +0,0 @@
-/*
- * Copyright (c) 1996, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-package sun.applet.resources;
-
-import java.util.ListResourceBundle;
-
-public class MsgAppletViewer_es extends ListResourceBundle {
-
- public Object[][] getContents() {
- Object[][] temp = new Object[][] {
- {"textframe.button.dismiss", "Descartar"},
- {"appletviewer.tool.title", "Visor de Applet: {0}"},
- {"appletviewer.menu.applet", "Applet"},
- {"appletviewer.menuitem.restart", "Reiniciar"},
- {"appletviewer.menuitem.reload", "Volver a Cargar"},
- {"appletviewer.menuitem.stop", "Parar"},
- {"appletviewer.menuitem.save", "Guardar..."},
- {"appletviewer.menuitem.start", "Iniciar"},
- {"appletviewer.menuitem.clone", "Clonar..."},
- {"appletviewer.menuitem.tag", "Etiqueta..."},
- {"appletviewer.menuitem.info", "Informaci\u00F3n..."},
- {"appletviewer.menuitem.edit", "Editar"},
- {"appletviewer.menuitem.encoding", "Codificaci\u00F3n de Caracteres"},
- {"appletviewer.menuitem.print", "Imprimir..."},
- {"appletviewer.menuitem.props", "Propiedades..."},
- {"appletviewer.menuitem.close", "Cerrar"},
- {"appletviewer.menuitem.quit", "Salir"},
- {"appletviewer.label.hello", "Hola..."},
- {"appletviewer.status.start", "iniciando applet..."},
- {"appletviewer.appletsave.filedialogtitle","Serializar Applet en Archivo"},
- {"appletviewer.appletsave.err1", "serializando {0} en {1}"},
- {"appletviewer.appletsave.err2", "en appletSave: {0}"},
- {"appletviewer.applettag", "Etiqueta Mostrada"},
- {"appletviewer.applettag.textframe", "Etiqueta HTML de Applet"},
- {"appletviewer.appletinfo.applet", "-- ninguna informaci\u00F3n de applet --"},
- {"appletviewer.appletinfo.param", "-- ninguna informaci\u00F3n de par\u00E1metros --"},
- {"appletviewer.appletinfo.textframe", "Informaci\u00F3n del Applet"},
- {"appletviewer.appletprint.fail", "Fallo de impresi\u00F3n."},
- {"appletviewer.appletprint.finish", "Impresi\u00F3n terminada."},
- {"appletviewer.appletprint.cancel", "Impresi\u00F3n cancelada."},
- {"appletviewer.appletencoding", "Codificaci\u00F3n de Caracteres: {0}"},
- {"appletviewer.parse.warning.requiresname", "Advertencia: la etiqueta <param name=... value=...> requiere un atributo name."},
- {"appletviewer.parse.warning.paramoutside", "Advertencia: la etiqueta <param> est\u00E1 fuera de <applet> ... </applet>."},
- {"appletviewer.parse.warning.applet.requirescode", "Advertencia: la etiqueta <applet> requiere el atributo code."},
- {"appletviewer.parse.warning.applet.requiresheight", "Advertencia: la etiqueta <applet> requiere el atributo height."},
- {"appletviewer.parse.warning.applet.requireswidth", "Advertencia: la etiqueta <applet> requiere el atributo width."},
- {"appletviewer.parse.warning.object.requirescode", "Advertencia: la etiqueta <object> requiere el atributo code."},
- {"appletviewer.parse.warning.object.requiresheight", "Advertencia: la etiqueta <object> requiere el atributo height."},
- {"appletviewer.parse.warning.object.requireswidth", "Advertencia: la etiqueta <object> requiere el atributo width."},
- {"appletviewer.parse.warning.embed.requirescode", "Advertencia: la etiqueta <embed> requiere el atributo code."},
- {"appletviewer.parse.warning.embed.requiresheight", "Advertencia: la etiqueta <embed> requiere el atributo height."},
- {"appletviewer.parse.warning.embed.requireswidth", "Advertencia: la etiqueta <embed> requiere el atributo width."},
- {"appletviewer.parse.warning.appnotLongersupported", "Advertencia: la etiqueta <app> ya no est\u00E1 soportada, utilice <applet> en su lugar:"},
- {"appletviewer.deprecated", "Advertencia: la API de applet y AppletViewer est\u00E1n en desuso."},
- {"appletviewer.usage", "Sintaxis: appletviewer <opciones> url(s)\n\ndonde <opciones> incluye:\n -encoding <codificaci\u00F3n> Especificar la codificaci\u00F3n de caracteres utilizada por los archivos HTML\n -J<indicador de tiempo de ejecuci\u00F3n> Transferir argumento al int\u00E9rprete de Java\n\nLa opci\u00F3n -J es no est\u00E1ndar y est\u00E1 sujeta a cambios sin previo aviso."},
- {"appletviewer.main.err.unsupportedopt", "Opci\u00F3n no soportada: {0}"},
- {"appletviewer.main.err.unrecognizedarg", "Argumento no reconocido: {0}"},
- {"appletviewer.main.err.dupoption", "Uso duplicado de la opci\u00F3n: {0}"},
- {"appletviewer.main.err.inputfile", "No se ha especificado ning\u00FAn archivo de entrada."},
- {"appletviewer.main.err.badurl", "URL Err\u00F3nea: {0} ( {1} )"},
- {"appletviewer.main.err.io", "Excepci\u00F3n de E/S durante la lectura: {0}"},
- {"appletviewer.main.err.readablefile", "Aseg\u00FArese de que {0} es un archivo y que se puede leer."},
- {"appletviewer.main.err.correcturl", "\u00BFEs {0} la URL correcta?"},
- {"appletviewer.main.prop.store", "Propiedades Espec\u00EDficas del Usuario para AppletViewer"},
- {"appletviewer.main.err.prop.cantread", "No se puede leer el archivo de propiedades del usuario: {0}"},
- {"appletviewer.main.err.prop.cantsave", "No se puede guardar el archivo de propiedades del usuario: {0}"},
- {"appletviewer.main.warn.nosecmgr", "Advertencia: desactivando seguridad."},
- {"appletviewer.main.debug.cantfinddebug", "No se ha encontrado el depurador."},
- {"appletviewer.main.debug.cantfindmain", "No se ha encontrado el m\u00E9todo principal en el depurador."},
- {"appletviewer.main.debug.exceptionindebug", "Excepci\u00F3n en el depurador."},
- {"appletviewer.main.debug.cantaccess", "No se puede acceder al depurador."},
- {"appletviewer.main.nosecmgr", "Advertencia: no se ha instalado SecurityManager."},
- {"appletviewer.main.warning", "Advertencia: no se ha iniciado ning\u00FAn applet. Aseg\u00FArese de que la entrada contiene una etiqueta <applet>."},
- {"appletviewer.main.warn.prop.overwrite", "Advertencia: se sobrescribir\u00E1 temporalmente la propiedad del sistema cuando lo solicite el usuario: clave: {0} valor anterior: {1} nuevo valor: {2}"},
- {"appletviewer.main.warn.cantreadprops", "Advertencia: no se puede leer el archivo de propiedades de AppletViewer: {0}. Utilizando valores por defecto."},
- {"appletioexception.loadclass.throw.interrupted", "carga de clase interrumpida: {0}"},
- {"appletioexception.loadclass.throw.notloaded", "clase no cargada: {0}"},
- {"appletclassloader.loadcode.verbose", "Abriendo flujo a: {0} para obtener {1}"},
- {"appletclassloader.filenotfound", "No se ha encontrado el archivo al buscar: {0}"},
- {"appletclassloader.fileformat", "Excepci\u00F3n de formato de archivo al cargar: {0}"},
- {"appletclassloader.fileioexception", "Excepci\u00F3n de E/S al cargar: {0}"},
- {"appletclassloader.fileexception", "Excepci\u00F3n de {0} al cargar: {1}"},
- {"appletclassloader.filedeath", "{0} interrumpido al cargar: {1}"},
- {"appletclassloader.fileerror", "error de {0} al cargar: {1}"},
- {"appletclassloader.findclass.verbose.openstream", "Abriendo flujo a: {0} para obtener {1}"},
- {"appletclassloader.getresource.verbose.forname", "AppletClassLoader.getResource para nombre: {0}"},
- {"appletclassloader.getresource.verbose.found", "Recurso encontrado: {0} como un recurso de sistema"},
- {"appletclassloader.getresourceasstream.verbose", "Recurso encontrado: {0} como un recurso de sistema"},
- {"appletpanel.runloader.err", "Par\u00E1metro de c\u00F3digo u objeto."},
- {"appletpanel.runloader.exception", "excepci\u00F3n al deserializar {0}"},
- {"appletpanel.destroyed", "Applet destruido."},
- {"appletpanel.loaded", "Applet cargado."},
- {"appletpanel.started", "Applet iniciado."},
- {"appletpanel.inited", "Applet inicializado."},
- {"appletpanel.stopped", "Applet parado."},
- {"appletpanel.disposed", "Applet desechado."},
- {"appletpanel.nocode", "Falta el par\u00E1metro CODE en la etiqueta APPLET."},
- {"appletpanel.notfound", "cargar: clase {0} no encontrada."},
- {"appletpanel.nocreate", "cargar: {0} no se puede instanciar."},
- {"appletpanel.noconstruct", "cargar: {0} no es p\u00FAblico o no tiene un constructor p\u00FAblico."},
- {"appletpanel.death", "interrumpido"},
- {"appletpanel.exception", "excepci\u00F3n: {0}."},
- {"appletpanel.exception2", "excepci\u00F3n: {0}: {1}."},
- {"appletpanel.error", "error: {0}."},
- {"appletpanel.error2", "error: {0}: {1}."},
- {"appletpanel.notloaded", "Iniciaci\u00F3n: applet no cargado."},
- {"appletpanel.notinited", "Iniciar: applet no inicializado."},
- {"appletpanel.notstarted", "Parar: applet no iniciado."},
- {"appletpanel.notstopped", "Destruir: applet no parado."},
- {"appletpanel.notdestroyed", "Desechar: applet no destruido."},
- {"appletpanel.notdisposed", "Cargar: applet no desechado."},
- {"appletpanel.bail", "Interrumpido: rescatando."},
- {"appletpanel.filenotfound", "No se ha encontrado el archivo al buscar: {0}"},
- {"appletpanel.fileformat", "Excepci\u00F3n de formato de archivo al cargar: {0}"},
- {"appletpanel.fileioexception", "Excepci\u00F3n de E/S al cargar: {0}"},
- {"appletpanel.fileexception", "Excepci\u00F3n de {0} al cargar: {1}"},
- {"appletpanel.filedeath", "{0} interrumpido al cargar: {1}"},
- {"appletpanel.fileerror", "error de {0} al cargar: {1}"},
- {"appletpanel.badattribute.exception", "An\u00E1lisis HTML: valor incorrecto para el atributo width/height."},
- {"appletillegalargumentexception.objectinputstream", "AppletObjectInputStream requiere un cargador no nulo"},
- {"appletprops.title", "Propiedades de AppletViewer"},
- {"appletprops.label.http.server", "Servidor Proxy HTTP:"},
- {"appletprops.label.http.proxy", "Puerto Proxy HTTP:"},
- {"appletprops.label.network", "Acceso de Red:"},
- {"appletprops.choice.network.item.none", "Ninguno"},
- {"appletprops.choice.network.item.applethost", "Host del Applet"},
- {"appletprops.choice.network.item.unrestricted", "No Restringido"},
- {"appletprops.label.class", "Acceso de Clase:"},
- {"appletprops.choice.class.item.restricted", "Restringido"},
- {"appletprops.choice.class.item.unrestricted", "No Restringido"},
- {"appletprops.label.unsignedapplet", "Permitir Applets no Firmados:"},
- {"appletprops.choice.unsignedapplet.no", "No"},
- {"appletprops.choice.unsignedapplet.yes", "S\u00ED"},
- {"appletprops.button.apply", "Aplicar"},
- {"appletprops.button.cancel", "Cancelar"},
- {"appletprops.button.reset", "Restablecer"},
- {"appletprops.apply.exception", "Fallo al guardar las propiedades: {0}"},
- /* 4066432 */
- {"appletprops.title.invalidproxy", "Entrada no V\u00E1lida"},
- {"appletprops.label.invalidproxy", "El puerto proxy debe ser un valor entero positivo."},
- {"appletprops.button.ok", "Aceptar"},
- /* end 4066432 */
- {"appletprops.prop.store", "Propiedades espec\u00EDficas del usuario para AppletViewer"},
- {"appletsecurityexception.checkcreateclassloader", "Excepci\u00F3n de Seguridad: classloader"},
- {"appletsecurityexception.checkaccess.thread", "Excepci\u00F3n de Seguridad: thread"},
- {"appletsecurityexception.checkaccess.threadgroup", "Excepci\u00F3n de Seguridad: threadgroup: {0}"},
- {"appletsecurityexception.checkexit", "Excepci\u00F3n de Seguridad: salir: {0}"},
- {"appletsecurityexception.checkexec", "Excepci\u00F3n de Seguridad: ejecutar: {0}"},
- {"appletsecurityexception.checklink", "Excepci\u00F3n de Seguridad: enlace: {0}"},
- {"appletsecurityexception.checkpropsaccess", "Excepci\u00F3n de Seguridad: propiedades"},
- {"appletsecurityexception.checkpropsaccess.key", "Excepci\u00F3n de Seguridad: acceso a propiedades {0}"},
- {"appletsecurityexception.checkread.exception1", "Excepci\u00F3n de Seguridad: {0}, {1}"},
- {"appletsecurityexception.checkread.exception2", "Excepci\u00F3n de Seguridad: file.read: {0}"},
- {"appletsecurityexception.checkread", "Excepci\u00F3n de Seguridad: file.read: {0} == {1}"},
- {"appletsecurityexception.checkwrite.exception", "Excepci\u00F3n de Seguridad: {0}, {1}"},
- {"appletsecurityexception.checkwrite", "Excepci\u00F3n de Seguridad: file.write: {0} == {1}"},
- {"appletsecurityexception.checkread.fd", "Excepci\u00F3n de Seguridad: fd.read"},
- {"appletsecurityexception.checkwrite.fd", "Excepci\u00F3n de Seguridad: fd.write"},
- {"appletsecurityexception.checklisten", "Excepci\u00F3n de Seguridad: socket.listen: {0}"},
- {"appletsecurityexception.checkaccept", "Excepci\u00F3n de Seguridad: socket.accept: {0}:{1}"},
- {"appletsecurityexception.checkconnect.networknone", "Excepci\u00F3n de Seguridad: socket.connect: {0}->{1}"},
- {"appletsecurityexception.checkconnect.networkhost1", "Excepci\u00F3n de Seguridad: no se puede conectar a {0} con origen de {1}."},
- {"appletsecurityexception.checkconnect.networkhost2", "Excepci\u00F3n de Seguridad: no se puede resolver la IP para el host {0} o para {1}. "},
- {"appletsecurityexception.checkconnect.networkhost3", "Excepci\u00F3n de Seguridad: no se puede resolver la IP para el host {0}. Consulte la propiedad trustProxy."},
- {"appletsecurityexception.checkconnect", "Excepci\u00F3n de Seguridad: conexi\u00F3n: {0}->{1}"},
- {"appletsecurityexception.checkpackageaccess", "Excepci\u00F3n de Seguridad: no se puede acceder al paquete: {0}"},
- {"appletsecurityexception.checkpackagedefinition", "Excepci\u00F3n de Seguridad: no se puede definir el paquete: {0}"},
- {"appletsecurityexception.cannotsetfactory", "Excepci\u00F3n de Seguridad: no se puede definir el valor de f\u00E1brica"},
- {"appletsecurityexception.checkmemberaccess", "Excepci\u00F3n de Seguridad: comprobar el acceso de miembro"},
- {"appletsecurityexception.checkgetprintjob", "Excepci\u00F3n de Seguridad: getPrintJob"},
- {"appletsecurityexception.checksystemclipboardaccess", "Excepci\u00F3n de Seguridad: getSystemClipboard"},
- {"appletsecurityexception.checkawteventqueueaccess", "Excepci\u00F3n de Seguridad: getEventQueue"},
- {"appletsecurityexception.checksecurityaccess", "Excepci\u00F3n de Seguridad: operaci\u00F3n de seguridad: {0}"},
- {"appletsecurityexception.getsecuritycontext.unknown", "tipo de cargador de clase desconocido. no se puede comprobar para getContext"},
- {"appletsecurityexception.checkread.unknown", "tipo de cargador de clase desconocido. no se puede comprobar para lectura de comprobaci\u00F3n {0}"},
- {"appletsecurityexception.checkconnect.unknown", "tipo de cargador de clase desconocido. no se puede comprobar para conexi\u00F3n de comprobaci\u00F3n"},
- };
-
- return temp;
- }
-}
--- a/src/java.desktop/share/classes/sun/applet/resources/MsgAppletViewer_fr.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,203 +0,0 @@
-/*
- * Copyright (c) 1996, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-package sun.applet.resources;
-
-import java.util.ListResourceBundle;
-
-public class MsgAppletViewer_fr extends ListResourceBundle {
-
- public Object[][] getContents() {
- Object[][] temp = new Object[][] {
- {"textframe.button.dismiss", "Abandonner"},
- {"appletviewer.tool.title", "Visualiseur d''applets : {0}"},
- {"appletviewer.menu.applet", "Applet"},
- {"appletviewer.menuitem.restart", "Red\u00E9marrer"},
- {"appletviewer.menuitem.reload", "Recharger"},
- {"appletviewer.menuitem.stop", "Arr\u00EAter"},
- {"appletviewer.menuitem.save", "Enregistrer..."},
- {"appletviewer.menuitem.start", "D\u00E9marrer"},
- {"appletviewer.menuitem.clone", "Cloner..."},
- {"appletviewer.menuitem.tag", "Baliser..."},
- {"appletviewer.menuitem.info", "Informations..."},
- {"appletviewer.menuitem.edit", "Modifier"},
- {"appletviewer.menuitem.encoding", "Encodage de caract\u00E8res"},
- {"appletviewer.menuitem.print", "Imprimer..."},
- {"appletviewer.menuitem.props", "Propri\u00E9t\u00E9s..."},
- {"appletviewer.menuitem.close", "Fermer"},
- {"appletviewer.menuitem.quit", "Quitter"},
- {"appletviewer.label.hello", "Bonjour..."},
- {"appletviewer.status.start", "d\u00E9marrage de l'applet..."},
- {"appletviewer.appletsave.filedialogtitle","S\u00E9rialiser l'applet dans le fichier"},
- {"appletviewer.appletsave.err1", "S\u00E9rialisation de {0} vers {1}"},
- {"appletviewer.appletsave.err2", "dans appletSave : {0}"},
- {"appletviewer.applettag", "Balise affich\u00E9e"},
- {"appletviewer.applettag.textframe", "Balise HTML d'applet"},
- {"appletviewer.appletinfo.applet", "-- aucune information d'applet --"},
- {"appletviewer.appletinfo.param", "-- aucune information de param\u00E8tre --"},
- {"appletviewer.appletinfo.textframe", "Informations d'applet"},
- {"appletviewer.appletprint.fail", "Echec de l'impression."},
- {"appletviewer.appletprint.finish", "Impression termin\u00E9e."},
- {"appletviewer.appletprint.cancel", "Impression annul\u00E9e."},
- {"appletviewer.appletencoding", "Encodage de caract\u00E8res : {0}"},
- {"appletviewer.parse.warning.requiresname", "Avertissement : la balise <param name=... value=...> requiert un attribut de nom."},
- {"appletviewer.parse.warning.paramoutside", "Avertissement : la balise <param> est en dehors des balises <applet> ... </applet>."},
- {"appletviewer.parse.warning.applet.requirescode", "Avertissement : la balise <applet> requiert un attribut de code."},
- {"appletviewer.parse.warning.applet.requiresheight", "Avertissement : la balise <applet> requiert un attribut de hauteur."},
- {"appletviewer.parse.warning.applet.requireswidth", "Avertissement : la balise <applet> requiert un attribut de largeur."},
- {"appletviewer.parse.warning.object.requirescode", "Avertissement : la balise <object> requiert un attribut de code."},
- {"appletviewer.parse.warning.object.requiresheight", "Avertissement : la balise <object> requiert un attribut de hauteur."},
- {"appletviewer.parse.warning.object.requireswidth", "Avertissement : la balise <object> requiert un attribut de largeur."},
- {"appletviewer.parse.warning.embed.requirescode", "Avertissement : la balise <embed> requiert un attribut de code."},
- {"appletviewer.parse.warning.embed.requiresheight", "Avertissement : la balise <embed> requiert un attribut de hauteur."},
- {"appletviewer.parse.warning.embed.requireswidth", "Avertissement : la balise <embed> requiert un attribut de largeur."},
- {"appletviewer.parse.warning.appnotLongersupported", "Avertissement : la balise <app> n'est plus prise en charge, utilisez <applet> \u00E0 la place :"},
- {"appletviewer.deprecated", "Avertissement : l'API d'applet et AppletViewer sont en phase d'abandon."},
- {"appletviewer.usage", "Syntaxe : appletviewer <options> url(s)\n\no\u00F9 <options> inclut :\n -encoding <encoding> Indiquer l'encodage de caract\u00E8res utilis\u00E9 par les fichiers HTML\n -J<runtime flag> Transmettre l'argument \u00E0 l'interpr\u00E9teur Java\n\nL'option -J n'est pas standard et elle peut \u00EAtre modifi\u00E9e sans pr\u00E9avis."},
- {"appletviewer.main.err.unsupportedopt", "Option non prise en charge : {0}"},
- {"appletviewer.main.err.unrecognizedarg", "Argument non reconnu : {0}"},
- {"appletviewer.main.err.dupoption", "Utilisation en double de l''option : {0}"},
- {"appletviewer.main.err.inputfile", "Aucun fichier d'entr\u00E9e indiqu\u00E9."},
- {"appletviewer.main.err.badurl", "URL incorrecte : {0} ({1})"},
- {"appletviewer.main.err.io", "Exception d''E/S lors de la lecture : {0}"},
- {"appletviewer.main.err.readablefile", "Assurez-vous que {0} est un fichier accessible en lecture."},
- {"appletviewer.main.err.correcturl", "L''\u00E9l\u00E9ment {0} est-il l''URL correcte ?"},
- {"appletviewer.main.prop.store", "Propri\u00E9t\u00E9s utilisateur pour AppletViewer"},
- {"appletviewer.main.err.prop.cantread", "Impossible de lire le fichier de propri\u00E9t\u00E9s utilisateur : {0}"},
- {"appletviewer.main.err.prop.cantsave", "Impossible d''enregistrer le fichier de propri\u00E9t\u00E9s utilisateur : {0}"},
- {"appletviewer.main.warn.nosecmgr", "Avertissement : d\u00E9sactivation de la s\u00E9curit\u00E9."},
- {"appletviewer.main.debug.cantfinddebug", "D\u00E9bogueur introuvable."},
- {"appletviewer.main.debug.cantfindmain", "La m\u00E9thode principale est introuvable dans le d\u00E9bogueur."},
- {"appletviewer.main.debug.exceptionindebug", "Exception d\u00E9tect\u00E9e dans le d\u00E9bogueur."},
- {"appletviewer.main.debug.cantaccess", "Impossible d'acc\u00E9der au d\u00E9bogueur."},
- {"appletviewer.main.nosecmgr", "Avertissement : SecurityManager n'est pas install\u00E9."},
- {"appletviewer.main.warning", "Avertissement : aucune applet n'a \u00E9t\u00E9 d\u00E9marr\u00E9e. Assurez-vous que l'entr\u00E9e contient une balise <applet>."},
- {"appletviewer.main.warn.prop.overwrite", "Avertissement : remplacement temporaire de la propri\u00E9t\u00E9 syst\u00E8me \u00E0 la demande de l''utilisateur - Cl\u00E9 : {0}, ancienne valeur : {1}, nouvelle valeur : {2}"},
- {"appletviewer.main.warn.cantreadprops", "Avertissement : impossible de lire le fichier de propri\u00E9t\u00E9s d''AppletViewer : {0} Utilisation des valeurs par d\u00E9faut."},
- {"appletioexception.loadclass.throw.interrupted", "chargement de classe interrompu : {0}"},
- {"appletioexception.loadclass.throw.notloaded", "classe non charg\u00E9e : {0}"},
- {"appletclassloader.loadcode.verbose", "Ouverture du flux de donn\u00E9es dans {0} pour obtenir {1}"},
- {"appletclassloader.filenotfound", "Fichier introuvable lors de la recherche de {0}"},
- {"appletclassloader.fileformat", "Exception de format de fichier d\u00E9tect\u00E9e lors du chargement de : {0}"},
- {"appletclassloader.fileioexception", "Exception d''E/S lors du chargement de : {0}"},
- {"appletclassloader.fileexception", "Exception {0} lors du chargement de : {1}"},
- {"appletclassloader.filedeath", "Fermeture de {0} lors du chargement de : {1}"},
- {"appletclassloader.fileerror", "Erreur {0} lors du chargement de : {1}"},
- {"appletclassloader.findclass.verbose.openstream", "Ouverture du flux de donn\u00E9es dans {0} pour obtenir {1}"},
- {"appletclassloader.getresource.verbose.forname", "AppletClassLoader.getResource pour le nom : {0}"},
- {"appletclassloader.getresource.verbose.found", "Ressource {0} trouv\u00E9e en tant que ressource syst\u00E8me"},
- {"appletclassloader.getresourceasstream.verbose", "Ressource {0} trouv\u00E9e en tant que ressource syst\u00E8me"},
- {"appletpanel.runloader.err", "Param\u00E8tre d'objet ou de code."},
- {"appletpanel.runloader.exception", "exception lors de la d\u00E9s\u00E9rialisation de {0}"},
- {"appletpanel.destroyed", "Applet d\u00E9truite."},
- {"appletpanel.loaded", "Applet charg\u00E9e."},
- {"appletpanel.started", "Applet d\u00E9marr\u00E9e."},
- {"appletpanel.inited", "Applet initialis\u00E9e."},
- {"appletpanel.stopped", "Applet arr\u00EAt\u00E9e."},
- {"appletpanel.disposed", "Applet \u00E9limin\u00E9e."},
- {"appletpanel.nocode", "Param\u00E8tre CODE manquant dans la balise APPLET."},
- {"appletpanel.notfound", "Charger : la classe {0} est introuvable."},
- {"appletpanel.nocreate", "Charger : impossible d''instantier {0}."},
- {"appletpanel.noconstruct", "Charger : l''\u00E9l\u00E9ment {0} n''est pas public ou ne poss\u00E8de aucun constructeur public."},
- {"appletpanel.death", "arr\u00EAt\u00E9"},
- {"appletpanel.exception", "exception : {0}."},
- {"appletpanel.exception2", "exception : {0} : {1}."},
- {"appletpanel.error", "erreur : {0}."},
- {"appletpanel.error2", "erreur : {0} : {1}."},
- {"appletpanel.notloaded", "Initialiser : applet non charg\u00E9e."},
- {"appletpanel.notinited", "D\u00E9marrer : applet non initialis\u00E9e."},
- {"appletpanel.notstarted", "Arr\u00EAter : applet non d\u00E9marr\u00E9e."},
- {"appletpanel.notstopped", "D\u00E9truire : applet non arr\u00EAt\u00E9e."},
- {"appletpanel.notdestroyed", "Eliminer : applet non d\u00E9truite."},
- {"appletpanel.notdisposed", "Charger : applet non \u00E9limin\u00E9e."},
- {"appletpanel.bail", "Interrompu : r\u00E9solution."},
- {"appletpanel.filenotfound", "Fichier introuvable lors de la recherche de {0}"},
- {"appletpanel.fileformat", "Exception de format de fichier d\u00E9tect\u00E9e lors du chargement de : {0}"},
- {"appletpanel.fileioexception", "Exception d''E/S lors du chargement de : {0}"},
- {"appletpanel.fileexception", "Exception {0} lors du chargement de : {1}"},
- {"appletpanel.filedeath", "Fermeture de {0} lors du chargement de : {1}"},
- {"appletpanel.fileerror", "Erreur {0} lors du chargement de : {1}"},
- {"appletpanel.badattribute.exception", "Analyse HTML : valeur incorrecte pour l'attribut de largeur/hauteur"},
- {"appletillegalargumentexception.objectinputstream", "AppletObjectInputStream requiert un chargeur non NULL"},
- {"appletprops.title", "Propri\u00E9t\u00E9s d'AppletViewer"},
- {"appletprops.label.http.server", "Serveur proxy HTTP :"},
- {"appletprops.label.http.proxy", "Port proxy HTTP :"},
- {"appletprops.label.network", "Acc\u00E8s au r\u00E9seau :"},
- {"appletprops.choice.network.item.none", "Aucun"},
- {"appletprops.choice.network.item.applethost", "H\u00F4te de l'applet"},
- {"appletprops.choice.network.item.unrestricted", "Sans restriction"},
- {"appletprops.label.class", "Acc\u00E8s \u00E0 la classe :"},
- {"appletprops.choice.class.item.restricted", "Avec restriction"},
- {"appletprops.choice.class.item.unrestricted", "Sans restriction"},
- {"appletprops.label.unsignedapplet", "Autoriser les applets non sign\u00E9es :"},
- {"appletprops.choice.unsignedapplet.no", "Non"},
- {"appletprops.choice.unsignedapplet.yes", "Oui"},
- {"appletprops.button.apply", "Appliquer"},
- {"appletprops.button.cancel", "Annuler"},
- {"appletprops.button.reset", "R\u00E9initialiser"},
- {"appletprops.apply.exception", "Echec de l''enregistrement des propri\u00E9t\u00E9s : {0}"},
- /* 4066432 */
- {"appletprops.title.invalidproxy", "Entr\u00E9e non valide"},
- {"appletprops.label.invalidproxy", "Le port proxy doit \u00EAtre un entier positif."},
- {"appletprops.button.ok", "OK"},
- /* end 4066432 */
- {"appletprops.prop.store", "Propri\u00E9t\u00E9s utilisateur pour AppletViewer"},
- {"appletsecurityexception.checkcreateclassloader", "Exception de s\u00E9curit\u00E9 : chargeur de classe"},
- {"appletsecurityexception.checkaccess.thread", "Exception de s\u00E9curit\u00E9 : thread"},
- {"appletsecurityexception.checkaccess.threadgroup", "Exception de s\u00E9curit\u00E9 : groupe de threads : {0}"},
- {"appletsecurityexception.checkexit", "Exception de s\u00E9curit\u00E9 : sortie : {0}"},
- {"appletsecurityexception.checkexec", "Exception de s\u00E9curit\u00E9 : ex\u00E9cution : {0}"},
- {"appletsecurityexception.checklink", "Exception de s\u00E9curit\u00E9 : lien : {0}"},
- {"appletsecurityexception.checkpropsaccess", "Exception de s\u00E9curit\u00E9 : propri\u00E9t\u00E9s"},
- {"appletsecurityexception.checkpropsaccess.key", "Exception de s\u00E9curit\u00E9 : acc\u00E8s aux propri\u00E9t\u00E9s {0}"},
- {"appletsecurityexception.checkread.exception1", "Exception de s\u00E9curit\u00E9 : {0}, {1}"},
- {"appletsecurityexception.checkread.exception2", "Exception de s\u00E9curit\u00E9 : file.read : {0}"},
- {"appletsecurityexception.checkread", "Exception de s\u00E9curit\u00E9 : file.read : {0} == {1}"},
- {"appletsecurityexception.checkwrite.exception", "Exception de s\u00E9curit\u00E9 : {0}, {1}"},
- {"appletsecurityexception.checkwrite", "Exception de s\u00E9curit\u00E9 : file.write : {0} == {1}"},
- {"appletsecurityexception.checkread.fd", "Exception de s\u00E9curit\u00E9 : fd.read"},
- {"appletsecurityexception.checkwrite.fd", "Exception de s\u00E9curit\u00E9 : fd.write"},
- {"appletsecurityexception.checklisten", "Exception de s\u00E9curit\u00E9 : socket.listen : {0}"},
- {"appletsecurityexception.checkaccept", "Exception de s\u00E9curit\u00E9 : socket.accept : {0} : {1}"},
- {"appletsecurityexception.checkconnect.networknone", "Exception de s\u00E9curit\u00E9 : socket.connect : {0} -> {1}"},
- {"appletsecurityexception.checkconnect.networkhost1", "Exception de s\u00E9curit\u00E9 : impossible de se connecter \u00E0 {0} dont l''origine est {1}."},
- {"appletsecurityexception.checkconnect.networkhost2", "Exception de s\u00E9curit\u00E9 : impossible de r\u00E9soudre l''adresse IP pour l''h\u00F4te {0} ou pour {1}. "},
- {"appletsecurityexception.checkconnect.networkhost3", "Exception de s\u00E9curit\u00E9 : impossible de r\u00E9soudre l''adresse IP pour l''h\u00F4te {0}. Voir la propri\u00E9t\u00E9 trustProxy."},
- {"appletsecurityexception.checkconnect", "Exception de s\u00E9curit\u00E9 : connexion : {0} -> {1}"},
- {"appletsecurityexception.checkpackageaccess", "Exception de s\u00E9curit\u00E9 : impossible d''acc\u00E9der au package : {0}"},
- {"appletsecurityexception.checkpackagedefinition", "Exception de s\u00E9curit\u00E9 : impossible de d\u00E9finir le package : {0}"},
- {"appletsecurityexception.cannotsetfactory", "Exception de s\u00E9curit\u00E9 : impossible de d\u00E9finir la fabrique"},
- {"appletsecurityexception.checkmemberaccess", "Exception de s\u00E9curit\u00E9 : v\u00E9rifier l'acc\u00E8s des membres"},
- {"appletsecurityexception.checkgetprintjob", "Exception de s\u00E9curit\u00E9 : getPrintJob"},
- {"appletsecurityexception.checksystemclipboardaccess", "Exception de s\u00E9curit\u00E9 : getSystemClipboard"},
- {"appletsecurityexception.checkawteventqueueaccess", "Exception de s\u00E9curit\u00E9 : getEventQueue"},
- {"appletsecurityexception.checksecurityaccess", "Exception de s\u00E9curit\u00E9 : op\u00E9ration de s\u00E9curit\u00E9 : {0}"},
- {"appletsecurityexception.getsecuritycontext.unknown", "type de chargeur de classe inconnu, impossible de rechercher getContext"},
- {"appletsecurityexception.checkread.unknown", "type de chargeur de classe inconnu, impossible de rechercher la v\u00E9rification de lecture {0}"},
- {"appletsecurityexception.checkconnect.unknown", "type de chargeur de classe inconnu, impossible de rechercher la v\u00E9rification de connexion"},
- };
-
- return temp;
- }
-}
--- a/src/java.desktop/share/classes/sun/applet/resources/MsgAppletViewer_it.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,203 +0,0 @@
-/*
- * Copyright (c) 1996, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-package sun.applet.resources;
-
-import java.util.ListResourceBundle;
-
-public class MsgAppletViewer_it extends ListResourceBundle {
-
- public Object[][] getContents() {
- Object[][] temp = new Object[][] {
- {"textframe.button.dismiss", "Chiudi"},
- {"appletviewer.tool.title", "Visualizzatore applet: {0}"},
- {"appletviewer.menu.applet", "Applet"},
- {"appletviewer.menuitem.restart", "Riavvia"},
- {"appletviewer.menuitem.reload", "Ricarica"},
- {"appletviewer.menuitem.stop", "Arresta"},
- {"appletviewer.menuitem.save", "Salva..."},
- {"appletviewer.menuitem.start", "Avvia"},
- {"appletviewer.menuitem.clone", "Copia..."},
- {"appletviewer.menuitem.tag", "Tag..."},
- {"appletviewer.menuitem.info", "Informazioni..."},
- {"appletviewer.menuitem.edit", "Modifica"},
- {"appletviewer.menuitem.encoding", "Codifica caratteri"},
- {"appletviewer.menuitem.print", "Stampa..."},
- {"appletviewer.menuitem.props", "Propriet\u00E0..."},
- {"appletviewer.menuitem.close", "Chiudi"},
- {"appletviewer.menuitem.quit", "Esci"},
- {"appletviewer.label.hello", "Benvenuti..."},
- {"appletviewer.status.start", "avvio applet in corso..."},
- {"appletviewer.appletsave.filedialogtitle","Serializza applet in file"},
- {"appletviewer.appletsave.err1", "serializzazione di {0} in {1}"},
- {"appletviewer.appletsave.err2", "in appletSave: {0}"},
- {"appletviewer.applettag", "Tag visualizzata"},
- {"appletviewer.applettag.textframe", "Applet tag HTML"},
- {"appletviewer.appletinfo.applet", "-- nessuna informazione sull'applet --"},
- {"appletviewer.appletinfo.param", "-- nessuna informazione sul parametro --"},
- {"appletviewer.appletinfo.textframe", "Informazioni applet"},
- {"appletviewer.appletprint.fail", "Stampa non riuscita."},
- {"appletviewer.appletprint.finish", "Stampa completata."},
- {"appletviewer.appletprint.cancel", "Stampa annullata."},
- {"appletviewer.appletencoding", "Codifica caratteri: {0}"},
- {"appletviewer.parse.warning.requiresname", "Avvertenza: la tag <param name=... value=...> richiede un attributo name."},
- {"appletviewer.parse.warning.paramoutside", "Avvertenza: la tag <param> non rientra in <applet>... </applet>."},
- {"appletviewer.parse.warning.applet.requirescode", "Avvertenza: la tag <applet> richiede un attributo code."},
- {"appletviewer.parse.warning.applet.requiresheight", "Avvertenza: la tag <applet> richiede un attributo height."},
- {"appletviewer.parse.warning.applet.requireswidth", "Avvertenza: la tag <applet> richiede un attributo width."},
- {"appletviewer.parse.warning.object.requirescode", "Avvertenza: la tag <object> richiede un attributo code."},
- {"appletviewer.parse.warning.object.requiresheight", "Avvertenza: la tag <object> richiede un attributo height."},
- {"appletviewer.parse.warning.object.requireswidth", "Avvertenza: la tag <object> richiede un attributo width."},
- {"appletviewer.parse.warning.embed.requirescode", "Avvertenza: la tag <embed> richiede un attributo code."},
- {"appletviewer.parse.warning.embed.requiresheight", "Avvertenza: la tag <embed> richiede un attributo height."},
- {"appletviewer.parse.warning.embed.requireswidth", "Avvertenza: la tag <embed> richiede un attributo width."},
- {"appletviewer.parse.warning.appnotLongersupported", "Avvertenza: la tag <app> non \u00E8 pi\u00F9 supportata. Utilizzare <applet>:"},
- {"appletviewer.deprecated", "Avvertenza: l'API dell'applet e AppletViewer non sono pi\u00F9 validi."},
- {"appletviewer.usage", "Uso: appletviewer <options> url(s)\n\ndove <options> includono:\n -encoding <encoding> Specifica la codifica dei caratteri utilizzata dai file HTML\n -J<runtime flag> Passa l'argomento all'interpreter Java\n\nL'opzione -J non \u00E8 standard ed \u00E8 soggetta a modifica senza preavviso."},
- {"appletviewer.main.err.unsupportedopt", "Opzione non supportata: {0}"},
- {"appletviewer.main.err.unrecognizedarg", "Argomento non riconosciuto: {0}"},
- {"appletviewer.main.err.dupoption", "Uso duplicato dell''opzione: {0}"},
- {"appletviewer.main.err.inputfile", "Nessun file di input specificato."},
- {"appletviewer.main.err.badurl", "URL non valido: {0} ( {1} )"},
- {"appletviewer.main.err.io", "Eccezione I/O durante la lettura di {0}"},
- {"appletviewer.main.err.readablefile", "Assicurarsi che {0} sia un file e che sia leggibile."},
- {"appletviewer.main.err.correcturl", "{0} \u00E8 l''URL corretto?"},
- {"appletviewer.main.prop.store", "Propriet\u00E0 specifiche dell'utente per AppletViewer"},
- {"appletviewer.main.err.prop.cantread", "Impossibile leggere il file delle propriet\u00E0 utente: {0}"},
- {"appletviewer.main.err.prop.cantsave", "Impossibile salvare il file delle propriet\u00E0 utente: {0}"},
- {"appletviewer.main.warn.nosecmgr", "Avvertenza: la sicurezza verr\u00E0 disabilitata."},
- {"appletviewer.main.debug.cantfinddebug", "Impossibile trovare il debugger."},
- {"appletviewer.main.debug.cantfindmain", "Impossibile trovare il metodo principale nel debugger."},
- {"appletviewer.main.debug.exceptionindebug", "Eccezione nel debugger."},
- {"appletviewer.main.debug.cantaccess", "Impossibile accedere al debugger."},
- {"appletviewer.main.nosecmgr", "Avvertenza: SecurityManager non installato."},
- {"appletviewer.main.warning", "Avvertenza: nessuna applet avviata. Assicurarsi che l'input contenga una tag <applet>."},
- {"appletviewer.main.warn.prop.overwrite", "Avvertenza: la propriet\u00E0 di sistema verr\u00E0 sovrascritta temporaneamente su richiesta dell''utente. Chiave {0}, valore precedente {1}, nuovo valore {2}."},
- {"appletviewer.main.warn.cantreadprops", "Avvertenza: impossibile leggere il file delle propriet\u00E0 AppletViewer {0}. Verranno utilizzate le impostazioni predefinite."},
- {"appletioexception.loadclass.throw.interrupted", "caricamento della classe interrotto: {0}"},
- {"appletioexception.loadclass.throw.notloaded", "classe non caricata: {0}"},
- {"appletclassloader.loadcode.verbose", "Apertura del flusso per {0} per recuperare {1}"},
- {"appletclassloader.filenotfound", "File non trovato durante la ricerca di {0}"},
- {"appletclassloader.fileformat", "Eccezione di formato file durante il caricamento di {0}"},
- {"appletclassloader.fileioexception", "Eccezione I/O durante il caricamento di {0}"},
- {"appletclassloader.fileexception", "Eccezione {0} durante il caricamento di {1}"},
- {"appletclassloader.filedeath", "{0} terminato durante il caricamento di {1}"},
- {"appletclassloader.fileerror", "Errore {0} durante il caricamento di {1}"},
- {"appletclassloader.findclass.verbose.openstream", "Apertura del flusso per {0} per recuperare {1}"},
- {"appletclassloader.getresource.verbose.forname", "AppletClassLoader.getResource per il nome: {0}"},
- {"appletclassloader.getresource.verbose.found", "\u00C8 stata trovata la risorsa {0} come risorsa di sistema"},
- {"appletclassloader.getresourceasstream.verbose", "\u00C8 stata trovata la risorsa {0} come risorsa di sistema"},
- {"appletpanel.runloader.err", "Parametro di oggetto o di codice."},
- {"appletpanel.runloader.exception", "eccezione durante la deserializzazione di {0}"},
- {"appletpanel.destroyed", "Applet rimossa."},
- {"appletpanel.loaded", "Applet caricata."},
- {"appletpanel.started", "Applet avviata."},
- {"appletpanel.inited", "Applet inizializzata."},
- {"appletpanel.stopped", "Applet arrestata."},
- {"appletpanel.disposed", "Applet eliminata."},
- {"appletpanel.nocode", "Nella tag APPLET manca il parametro CODE."},
- {"appletpanel.notfound", "caricamento: classe {0} non trovata."},
- {"appletpanel.nocreate", "caricamento: impossibile creare un''istanza di {0}."},
- {"appletpanel.noconstruct", "caricamento: {0} non \u00E8 pubblico o non ha un costruttore pubblico."},
- {"appletpanel.death", "terminato"},
- {"appletpanel.exception", "eccezione: {0}"},
- {"appletpanel.exception2", "eccezione: {0}: {1}."},
- {"appletpanel.error", "errore: {0}."},
- {"appletpanel.error2", "errore: {0}: {1}."},
- {"appletpanel.notloaded", "Inizializzazione: applet non caricata."},
- {"appletpanel.notinited", "Avvio: applet non inizializzata."},
- {"appletpanel.notstarted", "Arresto: applet non avviata."},
- {"appletpanel.notstopped", "Rimozione: applet non arrestata."},
- {"appletpanel.notdestroyed", "Eliminazione: applet non rimossa."},
- {"appletpanel.notdisposed", "Caricamento: applet non eliminata."},
- {"appletpanel.bail", "Interrotto: chiusura."},
- {"appletpanel.filenotfound", "File non trovato durante la ricerca di {0}"},
- {"appletpanel.fileformat", "Eccezione di formato file durante il caricamento di {0}"},
- {"appletpanel.fileioexception", "Eccezione I/O durante il caricamento di {0}"},
- {"appletpanel.fileexception", "Eccezione {0} durante il caricamento di {1}"},
- {"appletpanel.filedeath", "{0} terminato durante il caricamento di {1}"},
- {"appletpanel.fileerror", "Errore {0} durante il caricamento di {1}"},
- {"appletpanel.badattribute.exception", "Analisi HTML: valore errato per l'attributo width/height"},
- {"appletillegalargumentexception.objectinputstream", "AppletObjectInputStream richiede un loader non nullo"},
- {"appletprops.title", "Propriet\u00E0 AppletViewer"},
- {"appletprops.label.http.server", "Server proxy http:"},
- {"appletprops.label.http.proxy", "Porta proxy http:"},
- {"appletprops.label.network", "Accesso alla rete:"},
- {"appletprops.choice.network.item.none", "Nessuno"},
- {"appletprops.choice.network.item.applethost", "Host applet"},
- {"appletprops.choice.network.item.unrestricted", "Non limitato"},
- {"appletprops.label.class", "Accesso alla classe:"},
- {"appletprops.choice.class.item.restricted", "Limitato"},
- {"appletprops.choice.class.item.unrestricted", "Non limitato"},
- {"appletprops.label.unsignedapplet", "Consenti applet senza firma:"},
- {"appletprops.choice.unsignedapplet.no", "No"},
- {"appletprops.choice.unsignedapplet.yes", "S\u00EC"},
- {"appletprops.button.apply", "Applica"},
- {"appletprops.button.cancel", "Annulla"},
- {"appletprops.button.reset", "Reimposta"},
- {"appletprops.apply.exception", "Salvataggio delle propriet\u00E0 non riuscito: {0}"},
- /* 4066432 */
- {"appletprops.title.invalidproxy", "Voce non valida"},
- {"appletprops.label.invalidproxy", "La porta del proxy deve essere un valore intero positivo."},
- {"appletprops.button.ok", "OK"},
- /* end 4066432 */
- {"appletprops.prop.store", "Propriet\u00E0 specifiche dell'utente per AppletViewer"},
- {"appletsecurityexception.checkcreateclassloader", "Eccezione di sicurezza: classloader"},
- {"appletsecurityexception.checkaccess.thread", "Eccezione di sicurezza: thread"},
- {"appletsecurityexception.checkaccess.threadgroup", "Eccezione di sicurezza: threadgroup: {0}"},
- {"appletsecurityexception.checkexit", "Eccezione di sicurezza: exit: {0}"},
- {"appletsecurityexception.checkexec", "Eccezione di sicurezza: exec: {0}"},
- {"appletsecurityexception.checklink", "Eccezione di sicurezza: link: {0}"},
- {"appletsecurityexception.checkpropsaccess", "Eccezione di sicurezza: properties"},
- {"appletsecurityexception.checkpropsaccess.key", "Eccezione di sicurezza: properties access {0}"},
- {"appletsecurityexception.checkread.exception1", "Eccezione di sicurezza: {0}, {1}"},
- {"appletsecurityexception.checkread.exception2", "Eccezione di sicurezza: file.read: {0}"},
- {"appletsecurityexception.checkread", "Eccezione di sicurezza: file.read: {0} == {1}"},
- {"appletsecurityexception.checkwrite.exception", "Eccezione di sicurezza: {0}, {1}"},
- {"appletsecurityexception.checkwrite", "Eccezione di sicurezza: file.write: {0} == {1}"},
- {"appletsecurityexception.checkread.fd", "Eccezione di sicurezza: fd.read"},
- {"appletsecurityexception.checkwrite.fd", "Eccezione di sicurezza: fd.write"},
- {"appletsecurityexception.checklisten", "Eccezione di sicurezza: socket.listen: {0}"},
- {"appletsecurityexception.checkaccept", "Eccezione di sicurezza: socket.accept: {0}:{1}"},
- {"appletsecurityexception.checkconnect.networknone", "Eccezione di sicurezza: socket.connect: {0}->{1}"},
- {"appletsecurityexception.checkconnect.networkhost1", "Eccezione di sicurezza: impossibile connettersi a {0} con origine da {1}."},
- {"appletsecurityexception.checkconnect.networkhost2", "Eccezione di sicurezza: impossibile risolvere l''IP per l''host {0} o per {1}. "},
- {"appletsecurityexception.checkconnect.networkhost3", "Eccezione di sicurezza: impossibile non risolvere l''IP per l''host {0}. Vedere la propriet\u00E0 trustProxy."},
- {"appletsecurityexception.checkconnect", "Eccezione di sicurezza: connect: {0}->{1}"},
- {"appletsecurityexception.checkpackageaccess", "Eccezione di sicurezza: impossibile accedere al package {0}"},
- {"appletsecurityexception.checkpackagedefinition", "Eccezione di sicurezza: impossibile definire il package {0}"},
- {"appletsecurityexception.cannotsetfactory", "Eccezione di sicurezza: impossibile impostare il factory"},
- {"appletsecurityexception.checkmemberaccess", "Eccezione di sicurezza: controllare l'accesso dei membri"},
- {"appletsecurityexception.checkgetprintjob", "Eccezione di sicurezza: getPrintJob"},
- {"appletsecurityexception.checksystemclipboardaccess", "Eccezione di sicurezza: getSystemClipboard"},
- {"appletsecurityexception.checkawteventqueueaccess", "Eccezione di sicurezza: getEventQueue"},
- {"appletsecurityexception.checksecurityaccess", "Eccezione di sicurezza: operazione di sicurezza {0}"},
- {"appletsecurityexception.getsecuritycontext.unknown", "tipo di loader della classe sconosciuto. Impossibile verificare la presenza di getContext."},
- {"appletsecurityexception.checkread.unknown", "tipo di loader della classe sconosciuto. Impossibile verificare la presenza della lettura di controllo {0}."},
- {"appletsecurityexception.checkconnect.unknown", "tipo di loader della classe sconosciuto. Impossibile verificare la presenza della connessione di controllo."},
- };
-
- return temp;
- }
-}
--- a/src/java.desktop/share/classes/sun/applet/resources/MsgAppletViewer_ja.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,203 +0,0 @@
-/*
- * Copyright (c) 1996, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-package sun.applet.resources;
-
-import java.util.ListResourceBundle;
-
-public class MsgAppletViewer_ja extends ListResourceBundle {
-
- public Object[][] getContents() {
- Object[][] temp = new Object[][] {
- {"textframe.button.dismiss", "\u53D6\u6D88"},
- {"appletviewer.tool.title", "\u30A2\u30D7\u30EC\u30C3\u30C8\u30FB\u30D3\u30E5\u30FC\u30A2: {0}"},
- {"appletviewer.menu.applet", "\u30A2\u30D7\u30EC\u30C3\u30C8"},
- {"appletviewer.menuitem.restart", "\u518D\u8D77\u52D5"},
- {"appletviewer.menuitem.reload", "\u518D\u30ED\u30FC\u30C9"},
- {"appletviewer.menuitem.stop", "\u505C\u6B62"},
- {"appletviewer.menuitem.save", "\u4FDD\u5B58..."},
- {"appletviewer.menuitem.start", "\u958B\u59CB"},
- {"appletviewer.menuitem.clone", "\u30AF\u30ED\u30FC\u30F3..."},
- {"appletviewer.menuitem.tag", "\u30BF\u30B0..."},
- {"appletviewer.menuitem.info", "\u60C5\u5831..."},
- {"appletviewer.menuitem.edit", "\u7DE8\u96C6"},
- {"appletviewer.menuitem.encoding", "\u6587\u5B57\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0"},
- {"appletviewer.menuitem.print", "\u5370\u5237..."},
- {"appletviewer.menuitem.props", "\u30D7\u30ED\u30D1\u30C6\u30A3..."},
- {"appletviewer.menuitem.close", "\u9589\u3058\u308B"},
- {"appletviewer.menuitem.quit", "\u7D42\u4E86"},
- {"appletviewer.label.hello", "Hello..."},
- {"appletviewer.status.start", "\u30A2\u30D7\u30EC\u30C3\u30C8\u3092\u958B\u59CB\u3057\u3066\u3044\u307E\u3059..."},
- {"appletviewer.appletsave.filedialogtitle","\u30A2\u30D7\u30EC\u30C3\u30C8\u3092\u30D5\u30A1\u30A4\u30EB\u306B\u30B7\u30EA\u30A2\u30E9\u30A4\u30BA"},
- {"appletviewer.appletsave.err1", "{0}\u3092{1}\u306B\u30B7\u30EA\u30A2\u30E9\u30A4\u30BA"},
- {"appletviewer.appletsave.err2", "appletSave\u5185: {0}"},
- {"appletviewer.applettag", "\u30BF\u30B0\u306E\u8868\u793A"},
- {"appletviewer.applettag.textframe", "\u30A2\u30D7\u30EC\u30C3\u30C8HTML\u30BF\u30B0"},
- {"appletviewer.appletinfo.applet", "-- \u30A2\u30D7\u30EC\u30C3\u30C8\u60C5\u5831\u306A\u3057 --"},
- {"appletviewer.appletinfo.param", "-- \u30D1\u30E9\u30E1\u30FC\u30BF\u60C5\u5831\u306A\u3057 --"},
- {"appletviewer.appletinfo.textframe", "\u30A2\u30D7\u30EC\u30C3\u30C8\u60C5\u5831"},
- {"appletviewer.appletprint.fail", "\u5370\u5237\u304C\u5931\u6557\u3057\u307E\u3057\u305F\u3002"},
- {"appletviewer.appletprint.finish", "\u5370\u5237\u3092\u7D42\u4E86\u3057\u307E\u3057\u305F\u3002"},
- {"appletviewer.appletprint.cancel", "\u5370\u5237\u304C\u53D6\u308A\u6D88\u3055\u308C\u307E\u3057\u305F\u3002"},
- {"appletviewer.appletencoding", "\u6587\u5B57\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0: {0}"},
- {"appletviewer.parse.warning.requiresname", "\u8B66\u544A: <param name=... value=...>\u30BF\u30B0\u306Bname\u5C5E\u6027\u304C\u5FC5\u8981\u3067\u3059\u3002"},
- {"appletviewer.parse.warning.paramoutside", "\u8B66\u544A: <param>\u30BF\u30B0\u304C<applet> ... </applet>\u306E\u5916\u5074\u3067\u3059\u3002"},
- {"appletviewer.parse.warning.applet.requirescode", "\u8B66\u544A: <applet>\u30BF\u30B0\u306Bcode\u5C5E\u6027\u304C\u5FC5\u8981\u3067\u3059\u3002"},
- {"appletviewer.parse.warning.applet.requiresheight", "\u8B66\u544A: <applet>\u30BF\u30B0\u306Bheight\u5C5E\u6027\u304C\u5FC5\u8981\u3067\u3059\u3002"},
- {"appletviewer.parse.warning.applet.requireswidth", "\u8B66\u544A: <applet>\u30BF\u30B0\u306Bwidth\u5C5E\u6027\u304C\u5FC5\u8981\u3067\u3059\u3002"},
- {"appletviewer.parse.warning.object.requirescode", "\u8B66\u544A: <object>\u30BF\u30B0\u306Bcode\u5C5E\u6027\u304C\u5FC5\u8981\u3067\u3059\u3002"},
- {"appletviewer.parse.warning.object.requiresheight", "\u8B66\u544A: <object>\u30BF\u30B0\u306Bheight\u5C5E\u6027\u304C\u5FC5\u8981\u3067\u3059\u3002"},
- {"appletviewer.parse.warning.object.requireswidth", "\u8B66\u544A: <object>\u30BF\u30B0\u306Bwidth\u5C5E\u6027\u304C\u5FC5\u8981\u3067\u3059\u3002"},
- {"appletviewer.parse.warning.embed.requirescode", "\u8B66\u544A: <embed>\u30BF\u30B0\u306Bcode\u5C5E\u6027\u304C\u5FC5\u8981\u3067\u3059\u3002"},
- {"appletviewer.parse.warning.embed.requiresheight", "\u8B66\u544A: <embed>\u30BF\u30B0\u306Bheight\u5C5E\u6027\u304C\u5FC5\u8981\u3067\u3059\u3002"},
- {"appletviewer.parse.warning.embed.requireswidth", "\u8B66\u544A: <embed>\u30BF\u30B0\u306Bwidth\u5C5E\u6027\u304C\u5FC5\u8981\u3067\u3059\u3002"},
- {"appletviewer.parse.warning.appnotLongersupported", "\u8B66\u544A: <app>\u30BF\u30B0\u306F\u73FE\u5728\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002\u304B\u308F\u308A\u306B<applet>\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002"},
- {"appletviewer.deprecated", "\u8B66\u544A: \u30A2\u30D7\u30EC\u30C3\u30C8API\u304A\u3088\u3073AppletViewer\u306F\u975E\u63A8\u5968\u3067\u3059\u3002"},
- {"appletviewer.usage", "\u4F7F\u7528\u65B9\u6CD5: appletviewer <options> url(s)\n\n<options>\u306B\u306F\u6B21\u306E\u3082\u306E\u304C\u3042\u308A\u307E\u3059:\n -encoding <encoding> HTML\u30D5\u30A1\u30A4\u30EB\u306B\u3088\u3063\u3066\u4F7F\u7528\u3055\u308C\u308B\u6587\u5B57\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u3092\u6307\u5B9A\u3059\u308B\n -J<runtime flag> \u5F15\u6570\u3092Java\u30A4\u30F3\u30BF\u30D7\u30EA\u30BF\u306B\u6E21\u3059\n\n-J\u306F\u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u3042\u308A\u3001\u4E88\u544A\u306A\u3057\u306B\u5909\u66F4\u3055\u308C\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002"},
- {"appletviewer.main.err.unsupportedopt", "\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u306A\u3044\u30AA\u30D7\u30B7\u30E7\u30F3: {0}"},
- {"appletviewer.main.err.unrecognizedarg", "\u8A8D\u8B58\u3055\u308C\u306A\u3044\u5F15\u6570: {0}"},
- {"appletviewer.main.err.dupoption", "\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u4F7F\u7528\u304C\u91CD\u8907\u3057\u3066\u3044\u307E\u3059: {0}"},
- {"appletviewer.main.err.inputfile", "\u5165\u529B\u30D5\u30A1\u30A4\u30EB\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002"},
- {"appletviewer.main.err.badurl", "\u4E0D\u6B63\u306AURL: {0} ( {1} )"},
- {"appletviewer.main.err.io", "\u8AAD\u8FBC\u307F\u4E2D\u306E\u5165\u51FA\u529B\u4F8B\u5916\u3067\u3059: {0}"},
- {"appletviewer.main.err.readablefile", "{0}\u304C\u30D5\u30A1\u30A4\u30EB\u3067\u3042\u308A\u3001\u8AAD\u8FBC\u307F\u53EF\u80FD\u3067\u3042\u308B\u3053\u3068\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002"},
- {"appletviewer.main.err.correcturl", "{0}\u306F\u6B63\u3057\u3044URL\u3067\u3059\u304B\u3002"},
- {"appletviewer.main.prop.store", "AppletViewer\u7528\u306E\u30E6\u30FC\u30B6\u30FC\u304C\u6307\u5B9A\u3057\u305F\u30D7\u30ED\u30D1\u30C6\u30A3"},
- {"appletviewer.main.err.prop.cantread", "\u30E6\u30FC\u30B6\u30FC\u30FB\u30D7\u30ED\u30D1\u30C6\u30A3\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u8AAD\u307F\u8FBC\u3081\u307E\u305B\u3093: {0}"},
- {"appletviewer.main.err.prop.cantsave", "\u30E6\u30FC\u30B6\u30FC\u30FB\u30D7\u30ED\u30D1\u30C6\u30A3\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u4FDD\u5B58\u3067\u304D\u307E\u305B\u3093: {0}"},
- {"appletviewer.main.warn.nosecmgr", "\u8B66\u544A: \u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u3092\u7121\u52B9\u5316\u3057\u307E\u3059\u3002"},
- {"appletviewer.main.debug.cantfinddebug", "\u30C7\u30D0\u30C3\u30AC\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002"},
- {"appletviewer.main.debug.cantfindmain", "\u30C7\u30D0\u30C3\u30AC\u306E\u30E1\u30A4\u30F3\u30FB\u30E1\u30BD\u30C3\u30C9\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002"},
- {"appletviewer.main.debug.exceptionindebug", "\u30C7\u30D0\u30C3\u30AC\u306B\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002"},
- {"appletviewer.main.debug.cantaccess", "\u30C7\u30D0\u30C3\u30AC\u306B\u30A2\u30AF\u30BB\u30B9\u3067\u304D\u307E\u305B\u3093\u3002"},
- {"appletviewer.main.nosecmgr", "\u8B66\u544A: SecurityManager\u304C\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002"},
- {"appletviewer.main.warning", "\u8B66\u544A: \u30A2\u30D7\u30EC\u30C3\u30C8\u304C\u958B\u59CB\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u5165\u529B\u306B<applet>\u30BF\u30B0\u304C\u3042\u308B\u3053\u3068\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002"},
- {"appletviewer.main.warn.prop.overwrite", "\u8B66\u544A: \u30E6\u30FC\u30B6\u30FC\u306E\u30EA\u30AF\u30A8\u30B9\u30C8\u3067\u30B7\u30B9\u30C6\u30E0\u30FB\u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u4E00\u6642\u7684\u306B\u4E0A\u66F8\u304D\u3057\u307E\u3059: \u30AD\u30FC: {0} \u53E4\u3044\u5024: {1} \u65B0\u3057\u3044\u5024: {2}"},
- {"appletviewer.main.warn.cantreadprops", "\u8B66\u544A: AppletViewer\u30D7\u30ED\u30D1\u30C6\u30A3\u30FB\u30D5\u30A1\u30A4\u30EB{0}\u3092\u8AAD\u307F\u8FBC\u3081\u307E\u305B\u3093\u3002\u30C7\u30D5\u30A9\u30EB\u30C8\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002"},
- {"appletioexception.loadclass.throw.interrupted", "\u30AF\u30E9\u30B9\u306E\u30ED\u30FC\u30C9\u304C\u4E2D\u65AD\u3057\u307E\u3057\u305F: {0}"},
- {"appletioexception.loadclass.throw.notloaded", "\u30AF\u30E9\u30B9\u304C\u30ED\u30FC\u30C9\u3055\u308C\u307E\u305B\u3093: {0}"},
- {"appletclassloader.loadcode.verbose", "{1}\u3092\u53D6\u5F97\u3059\u308B\u305F\u3081\u306E{0}\u3078\u306E\u30B9\u30C8\u30EA\u30FC\u30E0\u3092\u958B\u304D\u307E\u3059"},
- {"appletclassloader.filenotfound", "{0}\u306E\u691C\u7D22\u4E2D\u306B\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093"},
- {"appletclassloader.fileformat", "{0}\u306E\u30ED\u30FC\u30C9\u4E2D\u306B\u30D5\u30A1\u30A4\u30EB\u5F62\u5F0F\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F"},
- {"appletclassloader.fileioexception", "{0}\u306E\u30ED\u30FC\u30C9\u4E2D\u306B\u5165\u51FA\u529B\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F"},
- {"appletclassloader.fileexception", "{1}\u306E\u30ED\u30FC\u30C9\u4E2D\u306B{0}\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F"},
- {"appletclassloader.filedeath", "{1}\u306E\u30ED\u30FC\u30C9\u4E2D\u306B{0}\u304C\u5F37\u5236\u7D42\u4E86\u3057\u307E\u3057\u305F"},
- {"appletclassloader.fileerror", "{1}\u306E\u30ED\u30FC\u30C9\u4E2D\u306B{0}\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F"},
- {"appletclassloader.findclass.verbose.openstream", "{1}\u3092\u53D6\u5F97\u3059\u308B\u305F\u3081\u306E{0}\u3078\u306E\u30B9\u30C8\u30EA\u30FC\u30E0\u3092\u958B\u304D\u307E\u3059"},
- {"appletclassloader.getresource.verbose.forname", "\u540D\u524D{0}\u306EAppletClassLoader.getResource\u3067\u3059"},
- {"appletclassloader.getresource.verbose.found", "\u30EA\u30BD\u30FC\u30B9{0}\u304C\u30B7\u30B9\u30C6\u30E0\u30FB\u30EA\u30BD\u30FC\u30B9\u3068\u3057\u3066\u691C\u51FA\u3055\u308C\u307E\u3057\u305F"},
- {"appletclassloader.getresourceasstream.verbose", "\u30EA\u30BD\u30FC\u30B9{0}\u304C\u30B7\u30B9\u30C6\u30E0\u30FB\u30EA\u30BD\u30FC\u30B9\u3068\u3057\u3066\u691C\u51FA\u3055\u308C\u307E\u3057\u305F"},
- {"appletpanel.runloader.err", "\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u307E\u305F\u306F\u30B3\u30FC\u30C9\u30FB\u30D1\u30E9\u30E1\u30FC\u30BF\u306E\u3044\u305A\u308C\u304B\u3067\u3059\u3002"},
- {"appletpanel.runloader.exception", "{0}\u306E\u30C7\u30B7\u30EA\u30A2\u30E9\u30A4\u30BA\u4E2D\u306B\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F"},
- {"appletpanel.destroyed", "\u30A2\u30D7\u30EC\u30C3\u30C8\u304C\u7834\u68C4\u3055\u308C\u307E\u3057\u305F\u3002"},
- {"appletpanel.loaded", "\u30A2\u30D7\u30EC\u30C3\u30C8\u304C\u30ED\u30FC\u30C9\u3055\u308C\u307E\u3057\u305F\u3002"},
- {"appletpanel.started", "\u30A2\u30D7\u30EC\u30C3\u30C8\u304C\u958B\u59CB\u3055\u308C\u307E\u3057\u305F\u3002"},
- {"appletpanel.inited", "\u30A2\u30D7\u30EC\u30C3\u30C8\u304C\u521D\u671F\u5316\u3055\u308C\u307E\u3057\u305F\u3002"},
- {"appletpanel.stopped", "\u30A2\u30D7\u30EC\u30C3\u30C8\u304C\u505C\u6B62\u3055\u308C\u307E\u3057\u305F\u3002"},
- {"appletpanel.disposed", "\u30A2\u30D7\u30EC\u30C3\u30C8\u304C\u7834\u68C4\u3055\u308C\u307E\u3057\u305F\u3002"},
- {"appletpanel.nocode", "APPLET\u30BF\u30B0\u306BCODE\u30D1\u30E9\u30E1\u30FC\u30BF\u304C\u3042\u308A\u307E\u305B\u3093\u3002"},
- {"appletpanel.notfound", "\u30ED\u30FC\u30C9: \u30AF\u30E9\u30B9{0}\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002"},
- {"appletpanel.nocreate", "\u30ED\u30FC\u30C9: {0}\u3092\u30A4\u30F3\u30B9\u30BF\u30F3\u30B9\u5316\u3067\u304D\u307E\u305B\u3093\u3002"},
- {"appletpanel.noconstruct", "\u30ED\u30FC\u30C9: {0}\u306Fpublic\u3067\u306A\u3044\u304B\u3001public\u30B3\u30F3\u30B9\u30C8\u30E9\u30AF\u30BF\u3092\u6301\u3063\u3066\u3044\u307E\u305B\u3093\u3002"},
- {"appletpanel.death", "\u5F37\u5236\u7D42\u4E86\u3055\u308C\u307E\u3057\u305F"},
- {"appletpanel.exception", "\u4F8B\u5916: {0}\u3002"},
- {"appletpanel.exception2", "\u4F8B\u5916: {0}: {1}\u3002"},
- {"appletpanel.error", "\u30A8\u30E9\u30FC: {0}\u3002"},
- {"appletpanel.error2", "\u30A8\u30E9\u30FC: {0}: {1}\u3002"},
- {"appletpanel.notloaded", "\u521D\u671F\u5316: \u30A2\u30D7\u30EC\u30C3\u30C8\u304C\u30ED\u30FC\u30C9\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002"},
- {"appletpanel.notinited", "\u958B\u59CB: \u30A2\u30D7\u30EC\u30C3\u30C8\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002"},
- {"appletpanel.notstarted", "\u505C\u6B62: \u30A2\u30D7\u30EC\u30C3\u30C8\u304C\u958B\u59CB\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002"},
- {"appletpanel.notstopped", "\u7834\u68C4: \u30A2\u30D7\u30EC\u30C3\u30C8\u304C\u505C\u6B62\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002"},
- {"appletpanel.notdestroyed", "\u7834\u68C4: \u30A2\u30D7\u30EC\u30C3\u30C8\u304C\u7834\u68C4\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002"},
- {"appletpanel.notdisposed", "\u30ED\u30FC\u30C9: \u30A2\u30D7\u30EC\u30C3\u30C8\u304C\u7834\u68C4\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002"},
- {"appletpanel.bail", "\u4E2D\u65AD\u6E08: \u7D42\u4E86\u3057\u3066\u3044\u307E\u3059\u3002"},
- {"appletpanel.filenotfound", "{0}\u306E\u691C\u7D22\u4E2D\u306B\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093"},
- {"appletpanel.fileformat", "{0}\u306E\u30ED\u30FC\u30C9\u4E2D\u306B\u30D5\u30A1\u30A4\u30EB\u5F62\u5F0F\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F"},
- {"appletpanel.fileioexception", "{0}\u306E\u30ED\u30FC\u30C9\u4E2D\u306B\u5165\u51FA\u529B\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F"},
- {"appletpanel.fileexception", "{1}\u306E\u30ED\u30FC\u30C9\u4E2D\u306B{0}\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F"},
- {"appletpanel.filedeath", "{1}\u306E\u30ED\u30FC\u30C9\u4E2D\u306B{0}\u304C\u5F37\u5236\u7D42\u4E86\u3057\u307E\u3057\u305F"},
- {"appletpanel.fileerror", "{1}\u306E\u30ED\u30FC\u30C9\u4E2D\u306B{0}\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F"},
- {"appletpanel.badattribute.exception", "HTML\u89E3\u6790: width\u307E\u305F\u306Fheight\u5C5E\u6027\u306E\u5024\u304C\u4E0D\u6B63\u3067\u3059"},
- {"appletillegalargumentexception.objectinputstream", "AppletObjectInputStream\u306F\u975Enull\u306E\u30ED\u30FC\u30C0\u30FC\u304C\u5FC5\u8981\u3067\u3059"},
- {"appletprops.title", "AppletViewer\u30D7\u30ED\u30D1\u30C6\u30A3"},
- {"appletprops.label.http.server", "Http\u30D7\u30ED\u30AD\u30B7\u30FB\u30B5\u30FC\u30D0\u30FC:"},
- {"appletprops.label.http.proxy", "Http\u30D7\u30ED\u30AD\u30B7\u30FB\u30DD\u30FC\u30C8:"},
- {"appletprops.label.network", "\u30CD\u30C3\u30C8\u30EF\u30FC\u30AF\u30FB\u30A2\u30AF\u30BB\u30B9:"},
- {"appletprops.choice.network.item.none", "\u306A\u3057"},
- {"appletprops.choice.network.item.applethost", "\u30A2\u30D7\u30EC\u30C3\u30C8\u30FB\u30DB\u30B9\u30C8"},
- {"appletprops.choice.network.item.unrestricted", "\u5236\u9650\u306A\u3057"},
- {"appletprops.label.class", "\u30AF\u30E9\u30B9\u30FB\u30A2\u30AF\u30BB\u30B9:"},
- {"appletprops.choice.class.item.restricted", "\u5236\u9650\u4ED8\u304D"},
- {"appletprops.choice.class.item.unrestricted", "\u5236\u9650\u306A\u3057"},
- {"appletprops.label.unsignedapplet", "\u7F72\u540D\u3055\u308C\u3066\u3044\u306A\u3044\u30A2\u30D7\u30EC\u30C3\u30C8\u3092\u8A31\u53EF:"},
- {"appletprops.choice.unsignedapplet.no", "\u3044\u3044\u3048"},
- {"appletprops.choice.unsignedapplet.yes", "\u306F\u3044"},
- {"appletprops.button.apply", "\u9069\u7528"},
- {"appletprops.button.cancel", "\u53D6\u6D88"},
- {"appletprops.button.reset", "\u30EA\u30BB\u30C3\u30C8"},
- {"appletprops.apply.exception", "\u30D7\u30ED\u30D1\u30C6\u30A3{0}\u306E\u4FDD\u5B58\u306B\u5931\u6557\u3057\u307E\u3057\u305F"},
- /* 4066432 */
- {"appletprops.title.invalidproxy", "\u30A8\u30F3\u30C8\u30EA\u304C\u7121\u52B9\u3067\u3059"},
- {"appletprops.label.invalidproxy", "\u30D7\u30ED\u30AD\u30B7\u30FB\u30DD\u30FC\u30C8\u306F\u6B63\u306E\u6574\u6570\u5024\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002"},
- {"appletprops.button.ok", "OK"},
- /* end 4066432 */
- {"appletprops.prop.store", "AppletViewer\u7528\u306E\u30E6\u30FC\u30B6\u30FC\u304C\u6307\u5B9A\u3057\u305F\u30D7\u30ED\u30D1\u30C6\u30A3"},
- {"appletsecurityexception.checkcreateclassloader", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: \u30AF\u30E9\u30B9\u30ED\u30FC\u30C0\u30FC"},
- {"appletsecurityexception.checkaccess.thread", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: \u30B9\u30EC\u30C3\u30C9"},
- {"appletsecurityexception.checkaccess.threadgroup", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: \u30B9\u30EC\u30C3\u30C9\u30B0\u30EB\u30FC\u30D7: {0}"},
- {"appletsecurityexception.checkexit", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: \u7D42\u4E86: {0}"},
- {"appletsecurityexception.checkexec", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: \u5B9F\u884C: {0}"},
- {"appletsecurityexception.checklink", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: \u30EA\u30F3\u30AF: {0}"},
- {"appletsecurityexception.checkpropsaccess", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: \u30D7\u30ED\u30D1\u30C6\u30A3"},
- {"appletsecurityexception.checkpropsaccess.key", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: \u30D7\u30ED\u30D1\u30C6\u30A3\u30FB\u30A2\u30AF\u30BB\u30B9{0}"},
- {"appletsecurityexception.checkread.exception1", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: {0}, {1}"},
- {"appletsecurityexception.checkread.exception2", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: file.read: {0}"},
- {"appletsecurityexception.checkread", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: file.read: {0} == {1}"},
- {"appletsecurityexception.checkwrite.exception", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: {0}, {1}"},
- {"appletsecurityexception.checkwrite", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: file.write: {0} == {1}"},
- {"appletsecurityexception.checkread.fd", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: fd.read"},
- {"appletsecurityexception.checkwrite.fd", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: fd.write"},
- {"appletsecurityexception.checklisten", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: socket.listen: {0}"},
- {"appletsecurityexception.checkaccept", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: socket.accept: {0}:{1}"},
- {"appletsecurityexception.checkconnect.networknone", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: socket.connect: {0}->{1}"},
- {"appletsecurityexception.checkconnect.networkhost1", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: {1}\u306E\u8D77\u70B9\u3092\u4F7F\u7528\u3057\u3066{0}\u306B\u63A5\u7D9A\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002"},
- {"appletsecurityexception.checkconnect.networkhost2", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: \u30DB\u30B9\u30C8{0}\u307E\u305F\u306F{1}\u306EIP\u3092\u89E3\u6C7A\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002 "},
- {"appletsecurityexception.checkconnect.networkhost3", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: \u30DB\u30B9\u30C8{0}\u306EIP\u3092\u89E3\u6C7A\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002trustProxy\u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002"},
- {"appletsecurityexception.checkconnect", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: \u63A5\u7D9A: {0}->{1}"},
- {"appletsecurityexception.checkpackageaccess", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: \u30D1\u30C3\u30B1\u30FC\u30B8\u306B\u30A2\u30AF\u30BB\u30B9\u3067\u304D\u307E\u305B\u3093: {0}"},
- {"appletsecurityexception.checkpackagedefinition", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: \u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u5B9A\u7FA9\u3067\u304D\u307E\u305B\u3093: {0}"},
- {"appletsecurityexception.cannotsetfactory", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: \u30D5\u30A1\u30AF\u30C8\u30EA\u3092\u8A2D\u5B9A\u3067\u304D\u307E\u305B\u3093"},
- {"appletsecurityexception.checkmemberaccess", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: \u30E1\u30F3\u30D0\u30FC\u30FB\u30A2\u30AF\u30BB\u30B9\u306E\u78BA\u8A8D"},
- {"appletsecurityexception.checkgetprintjob", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: getPrintJob"},
- {"appletsecurityexception.checksystemclipboardaccess", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: getSystemClipboard"},
- {"appletsecurityexception.checkawteventqueueaccess", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: getEventQueue"},
- {"appletsecurityexception.checksecurityaccess", "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u4F8B\u5916: \u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u64CD\u4F5C: {0}"},
- {"appletsecurityexception.getsecuritycontext.unknown", "\u4E0D\u660E\u306A\u30AF\u30E9\u30B9\u30ED\u30FC\u30C0\u30FC\u30FB\u30BF\u30A4\u30D7\u3067\u3059\u3002getContext\u3092\u78BA\u8A8D\u3067\u304D\u307E\u305B\u3093"},
- {"appletsecurityexception.checkread.unknown", "\u4E0D\u660E\u306A\u30AF\u30E9\u30B9\u30ED\u30FC\u30C0\u30FC\u30FB\u30BF\u30A4\u30D7\u3067\u3059\u3002{0}\u306E\u8AAD\u53D6\u308A\u30C1\u30A7\u30C3\u30AF\u3092\u78BA\u8A8D\u3067\u304D\u307E\u305B\u3093"},
- {"appletsecurityexception.checkconnect.unknown", "\u4E0D\u660E\u306A\u30AF\u30E9\u30B9\u30ED\u30FC\u30C0\u30FC\u30FB\u30BF\u30A4\u30D7\u3067\u3059\u3002\u63A5\u7D9A\u30C1\u30A7\u30C3\u30AF\u3092\u78BA\u8A8D\u3067\u304D\u307E\u305B\u3093"},
- };
-
- return temp;
- }
-}
--- a/src/java.desktop/share/classes/sun/applet/resources/MsgAppletViewer_ko.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,203 +0,0 @@
-/*
- * Copyright (c) 1996, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-package sun.applet.resources;
-
-import java.util.ListResourceBundle;
-
-public class MsgAppletViewer_ko extends ListResourceBundle {
-
- public Object[][] getContents() {
- Object[][] temp = new Object[][] {
- {"textframe.button.dismiss", "\uD574\uC81C"},
- {"appletviewer.tool.title", "\uC560\uD50C\uB9BF \uBDF0\uC5B4: {0}"},
- {"appletviewer.menu.applet", "\uC560\uD50C\uB9BF"},
- {"appletviewer.menuitem.restart", "\uC7AC\uC2DC\uC791"},
- {"appletviewer.menuitem.reload", "\uC7AC\uB85C\uB4DC"},
- {"appletviewer.menuitem.stop", "\uC815\uC9C0"},
- {"appletviewer.menuitem.save", "\uC800\uC7A5..."},
- {"appletviewer.menuitem.start", "\uC2DC\uC791"},
- {"appletviewer.menuitem.clone", "\uBCF5\uC81C..."},
- {"appletviewer.menuitem.tag", "\uD0DC\uADF8 \uC9C0\uC815..."},
- {"appletviewer.menuitem.info", "\uC815\uBCF4..."},
- {"appletviewer.menuitem.edit", "\uD3B8\uC9D1"},
- {"appletviewer.menuitem.encoding", "\uBB38\uC790 \uC778\uCF54\uB529"},
- {"appletviewer.menuitem.print", "\uC778\uC1C4..."},
- {"appletviewer.menuitem.props", "\uC18D\uC131..."},
- {"appletviewer.menuitem.close", "\uB2EB\uAE30"},
- {"appletviewer.menuitem.quit", "\uC885\uB8CC"},
- {"appletviewer.label.hello", "\uC2DC\uC791..."},
- {"appletviewer.status.start", "\uC560\uD50C\uB9BF\uC744 \uC2DC\uC791\uD558\uB294 \uC911..."},
- {"appletviewer.appletsave.filedialogtitle","\uD30C\uC77C\uB85C \uC560\uD50C\uB9BF \uC9C1\uB82C\uD654"},
- {"appletviewer.appletsave.err1", "{0}\uC744(\uB97C) {1}(\uC73C)\uB85C \uC9C1\uB82C\uD654\uD558\uB294 \uC911"},
- {"appletviewer.appletsave.err2", "appletSave\uC5D0 \uC624\uB958 \uBC1C\uC0DD: {0}"},
- {"appletviewer.applettag", "\uD0DC\uADF8\uAC00 \uD45C\uC2DC\uB428"},
- {"appletviewer.applettag.textframe", "\uC560\uD50C\uB9BF HTML \uD0DC\uADF8"},
- {"appletviewer.appletinfo.applet", "-- \uC560\uD50C\uB9BF \uC815\uBCF4 \uC5C6\uC74C --"},
- {"appletviewer.appletinfo.param", "-- \uB9E4\uAC1C\uBCC0\uC218 \uC815\uBCF4 \uC5C6\uC74C --"},
- {"appletviewer.appletinfo.textframe", "\uC560\uD50C\uB9BF \uC815\uBCF4"},
- {"appletviewer.appletprint.fail", "\uC778\uC1C4\uB97C \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4."},
- {"appletviewer.appletprint.finish", "\uC778\uC1C4\uB97C \uC644\uB8CC\uD588\uC2B5\uB2C8\uB2E4."},
- {"appletviewer.appletprint.cancel", "\uC778\uC1C4\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4."},
- {"appletviewer.appletencoding", "\uBB38\uC790 \uC778\uCF54\uB529: {0}"},
- {"appletviewer.parse.warning.requiresname", "\uACBD\uACE0: <param name=... value=...> \uD0DC\uADF8\uC5D0\uB294 name \uC18D\uC131\uC774 \uD544\uC694\uD569\uB2C8\uB2E4."},
- {"appletviewer.parse.warning.paramoutside", "\uACBD\uACE0: <param> \uD0DC\uADF8\uAC00 <applet> ... </applet> \uBC16\uC5D0 \uC788\uC2B5\uB2C8\uB2E4."},
- {"appletviewer.parse.warning.applet.requirescode", "\uACBD\uACE0: <applet> \uD0DC\uADF8\uC5D0\uB294 code \uC18D\uC131\uC774 \uD544\uC694\uD569\uB2C8\uB2E4."},
- {"appletviewer.parse.warning.applet.requiresheight", "\uACBD\uACE0: <applet> \uD0DC\uADF8\uC5D0\uB294 height \uC18D\uC131\uC774 \uD544\uC694\uD569\uB2C8\uB2E4."},
- {"appletviewer.parse.warning.applet.requireswidth", "\uACBD\uACE0: <applet> \uD0DC\uADF8\uC5D0\uB294 width \uC18D\uC131\uC774 \uD544\uC694\uD569\uB2C8\uB2E4."},
- {"appletviewer.parse.warning.object.requirescode", "\uACBD\uACE0: <object> \uD0DC\uADF8\uC5D0\uB294 code \uC18D\uC131\uC774 \uD544\uC694\uD569\uB2C8\uB2E4."},
- {"appletviewer.parse.warning.object.requiresheight", "\uACBD\uACE0: <object> \uD0DC\uADF8\uC5D0\uB294 height \uC18D\uC131\uC774 \uD544\uC694\uD569\uB2C8\uB2E4."},
- {"appletviewer.parse.warning.object.requireswidth", "\uACBD\uACE0: <object> \uD0DC\uADF8\uC5D0\uB294 width \uC18D\uC131\uC774 \uD544\uC694\uD569\uB2C8\uB2E4."},
- {"appletviewer.parse.warning.embed.requirescode", "\uACBD\uACE0: <embed> \uD0DC\uADF8\uC5D0\uB294 code \uC18D\uC131\uC774 \uD544\uC694\uD569\uB2C8\uB2E4."},
- {"appletviewer.parse.warning.embed.requiresheight", "\uACBD\uACE0: <embed> \uD0DC\uADF8\uC5D0\uB294 height \uC18D\uC131\uC774 \uD544\uC694\uD569\uB2C8\uB2E4."},
- {"appletviewer.parse.warning.embed.requireswidth", "\uACBD\uACE0: <embed> \uD0DC\uADF8\uC5D0\uB294 width \uC18D\uC131\uC774 \uD544\uC694\uD569\uB2C8\uB2E4."},
- {"appletviewer.parse.warning.appnotLongersupported", "\uACBD\uACE0: <app> \uD0DC\uADF8\uB294 \uB354 \uC774\uC0C1 \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uB300\uC2E0 <applet>\uC744 \uC0AC\uC6A9\uD558\uC2ED\uC2DC\uC624."},
- {"appletviewer.deprecated", "\uACBD\uACE0: \uC560\uD50C\uB9BF API \uBC0F AppletViewer\uAC00 \uC0AC\uC6A9\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."},
- {"appletviewer.usage", "\uC0AC\uC6A9\uBC95: appletviewer <options> url(s)\n\n\uC5EC\uAE30\uC11C <options>\uB294 \uB2E4\uC74C\uACFC \uAC19\uC2B5\uB2C8\uB2E4.\n -encoding <encoding> HTML \uD30C\uC77C\uC5D0 \uC0AC\uC6A9\uB420 \uBB38\uC790 \uC778\uCF54\uB529\uC744 \uC9C0\uC815\uD569\uB2C8\uB2E4.\n -J<runtime flag> Java \uC778\uD130\uD504\uB9AC\uD130\uB85C \uC778\uC218\uB97C \uC804\uB2EC\uD569\uB2C8\uB2E4.\n\n-J \uC635\uC158\uC740 \uD45C\uC900\uC774 \uC544\uB2C8\uBA70 \uC608\uACE0 \uC5C6\uC774 \uBCC0\uACBD\uB420 \uC218 \uC788\uC2B5\uB2C8\uB2E4."},
- {"appletviewer.main.err.unsupportedopt", "\uC9C0\uC6D0\uB418\uC9C0 \uC54A\uB294 \uC635\uC158: {0}"},
- {"appletviewer.main.err.unrecognizedarg", "\uC54C \uC218 \uC5C6\uB294 \uC778\uC218: {0}"},
- {"appletviewer.main.err.dupoption", "\uC911\uBCF5\uB41C \uC635\uC158 \uC0AC\uC6A9: {0}"},
- {"appletviewer.main.err.inputfile", "\uC9C0\uC815\uB41C \uC785\uB825 \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."},
- {"appletviewer.main.err.badurl", "\uC798\uBABB\uB41C URL: {0}({1})"},
- {"appletviewer.main.err.io", "\uC77D\uB294 \uC911 I/O \uC608\uC678\uC0AC\uD56D \uBC1C\uC0DD: {0}"},
- {"appletviewer.main.err.readablefile", "{0}\uC774(\uAC00) \uD30C\uC77C\uC774\uBA70 \uC77D\uAE30 \uAC00\uB2A5\uD55C \uC0C1\uD0DC\uC778\uC9C0 \uD655\uC778\uD558\uC2ED\uC2DC\uC624."},
- {"appletviewer.main.err.correcturl", "{0}\uC774(\uAC00) \uC62C\uBC14\uB978 URL\uC785\uB2C8\uAE4C?"},
- {"appletviewer.main.prop.store", "\uC0AC\uC6A9\uC790 \uAD00\uB828 AppletViewer \uC18D\uC131"},
- {"appletviewer.main.err.prop.cantread", "\uC0AC\uC6A9\uC790 \uC18D\uC131 \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC74C: {0}"},
- {"appletviewer.main.err.prop.cantsave", "\uC0AC\uC6A9\uC790 \uC18D\uC131 \uD30C\uC77C\uC744 \uC800\uC7A5\uD560 \uC218 \uC5C6\uC74C: {0}"},
- {"appletviewer.main.warn.nosecmgr", "\uACBD\uACE0: \uBCF4\uC548\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD558\uB294 \uC911\uC785\uB2C8\uB2E4."},
- {"appletviewer.main.debug.cantfinddebug", "\uB514\uBC84\uAC70\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4!"},
- {"appletviewer.main.debug.cantfindmain", "\uB514\uBC84\uAC70\uC5D0\uC11C \uAE30\uBCF8 \uBA54\uC18C\uB4DC\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4!"},
- {"appletviewer.main.debug.exceptionindebug", "\uB514\uBC84\uAC70\uC5D0 \uC608\uC678\uC0AC\uD56D\uC774 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4!"},
- {"appletviewer.main.debug.cantaccess", "\uB514\uBC84\uAC70\uC5D0 \uC561\uC138\uC2A4\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4!"},
- {"appletviewer.main.nosecmgr", "\uACBD\uACE0: SecurityManager\uAC00 \uC124\uCE58\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4!"},
- {"appletviewer.main.warning", "\uACBD\uACE0: \uC2DC\uC791\uB41C \uC560\uD50C\uB9BF\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. <applet> \uD0DC\uADF8\uAC00 \uC785\uB825\uB418\uC5C8\uB294\uC9C0 \uD655\uC778\uD558\uC2ED\uC2DC\uC624."},
- {"appletviewer.main.warn.prop.overwrite", "\uACBD\uACE0: \uC0AC\uC6A9\uC790\uC758 \uC694\uCCAD\uC5D0 \uB530\uB77C \uC77C\uC2DC\uC801\uC73C\uB85C \uC2DC\uC2A4\uD15C \uC18D\uC131\uC744 \uACB9\uCCD0 \uC4F0\uB294 \uC911: \uD0A4: {0}, \uC774\uC804 \uAC12: {1}, \uC0C8 \uAC12: {2}"},
- {"appletviewer.main.warn.cantreadprops", "\uACBD\uACE0: AppletViewer \uC18D\uC131 \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC74C: {0}. \uAE30\uBCF8\uAC12\uC744 \uC0AC\uC6A9\uD558\uB294 \uC911\uC785\uB2C8\uB2E4."},
- {"appletioexception.loadclass.throw.interrupted", "\uD074\uB798\uC2A4 \uB85C\uB4DC\uAC00 \uC911\uB2E8\uB428: {0}"},
- {"appletioexception.loadclass.throw.notloaded", "\uD074\uB798\uC2A4\uAC00 \uB85C\uB4DC\uB418\uC9C0 \uC54A\uC74C: {0}"},
- {"appletclassloader.loadcode.verbose", "{1}\uC744(\uB97C) \uAC00\uC838\uC624\uAE30 \uC704\uD574 {0}\uC5D0 \uB300\uD55C \uC2A4\uD2B8\uB9BC\uC744 \uC5EC\uB294 \uC911"},
- {"appletclassloader.filenotfound", "{0}\uC744(\uB97C) \uAC80\uC0C9\uD558\uB294 \uC911 \uD30C\uC77C\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4."},
- {"appletclassloader.fileformat", "\uB85C\uB4DC \uC911 \uD30C\uC77C \uD615\uC2DD \uC608\uC678\uC0AC\uD56D \uBC1C\uC0DD: {0}"},
- {"appletclassloader.fileioexception", "\uB85C\uB4DC \uC911 I/O \uC608\uC678\uC0AC\uD56D \uBC1C\uC0DD: {0}"},
- {"appletclassloader.fileexception", "\uB85C\uB4DC \uC911 {0} \uC608\uC678\uC0AC\uD56D \uBC1C\uC0DD: {1}"},
- {"appletclassloader.filedeath", "\uB85C\uB4DC \uC911 {0}\uC774(\uAC00) \uC885\uB8CC\uB428: {1}"},
- {"appletclassloader.fileerror", "\uB85C\uB4DC \uC911 {0} \uC624\uB958 \uBC1C\uC0DD: {1}"},
- {"appletclassloader.findclass.verbose.openstream", "{1}\uC744(\uB97C) \uAC00\uC838\uC624\uAE30 \uC704\uD574 {0}\uC5D0 \uB300\uD55C \uC2A4\uD2B8\uB9BC\uC744 \uC5EC\uB294 \uC911"},
- {"appletclassloader.getresource.verbose.forname", "\uC774\uB984\uC5D0 \uB300\uD55C AppletClassLoader.getResource: {0}"},
- {"appletclassloader.getresource.verbose.found", "\uC2DC\uC2A4\uD15C \uB9AC\uC18C\uC2A4\uB85C {0} \uB9AC\uC18C\uC2A4\uB97C \uCC3E\uC558\uC2B5\uB2C8\uB2E4."},
- {"appletclassloader.getresourceasstream.verbose", "\uC2DC\uC2A4\uD15C \uB9AC\uC18C\uC2A4\uB85C {0} \uB9AC\uC18C\uC2A4\uB97C \uCC3E\uC558\uC2B5\uB2C8\uB2E4."},
- {"appletpanel.runloader.err", "\uAC1D\uCCB4 \uB610\uB294 \uCF54\uB4DC \uB9E4\uAC1C\uBCC0\uC218\uC785\uB2C8\uB2E4!"},
- {"appletpanel.runloader.exception", "{0}\uC758 \uC9C1\uB82C\uD654\uB97C \uD574\uC81C\uD558\uB294 \uC911 \uC608\uC678\uC0AC\uD56D\uC774 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4."},
- {"appletpanel.destroyed", "\uC560\uD50C\uB9BF\uC774 \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4."},
- {"appletpanel.loaded", "\uC560\uD50C\uB9BF\uC774 \uB85C\uB4DC\uB418\uC5C8\uC2B5\uB2C8\uB2E4."},
- {"appletpanel.started", "\uC560\uD50C\uB9BF\uC774 \uC2DC\uC791\uB418\uC5C8\uC2B5\uB2C8\uB2E4."},
- {"appletpanel.inited", "\uC560\uD50C\uB9BF\uC774 \uCD08\uAE30\uD654\uB418\uC5C8\uC2B5\uB2C8\uB2E4."},
- {"appletpanel.stopped", "\uC560\uD50C\uB9BF\uC774 \uC815\uC9C0\uB418\uC5C8\uC2B5\uB2C8\uB2E4."},
- {"appletpanel.disposed", "\uC560\uD50C\uB9BF\uC774 \uBC30\uCE58\uB418\uC5C8\uC2B5\uB2C8\uB2E4."},
- {"appletpanel.nocode", "APPLET \uD0DC\uADF8\uC5D0 CODE \uB9E4\uAC1C\uBCC0\uC218\uAC00 \uB204\uB77D\uB418\uC5C8\uC2B5\uB2C8\uB2E4."},
- {"appletpanel.notfound", "\uB85C\uB4DC: {0} \uD074\uB798\uC2A4\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."},
- {"appletpanel.nocreate", "\uB85C\uB4DC: {0}\uC744(\uB97C) \uC778\uC2A4\uD134\uC2A4\uD654\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."},
- {"appletpanel.noconstruct", "\uB85C\uB4DC: {0}\uC740(\uB294) \uACF5\uC6A9\uC774 \uC544\uB2C8\uAC70\uB098 \uACF5\uC6A9 \uC0DD\uC131\uC790\uB97C \uD3EC\uD568\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."},
- {"appletpanel.death", "\uC885\uB8CC\uB428"},
- {"appletpanel.exception", "\uC608\uC678\uC0AC\uD56D: {0}."},
- {"appletpanel.exception2", "\uC608\uC678\uC0AC\uD56D: {0}: {1}."},
- {"appletpanel.error", "\uC624\uB958: {0}."},
- {"appletpanel.error2", "\uC624\uB958: {0}: {1}."},
- {"appletpanel.notloaded", "\uCD08\uAE30\uD654: \uC560\uD50C\uB9BF\uC774 \uB85C\uB4DC\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4."},
- {"appletpanel.notinited", "\uC2DC\uC791: \uC560\uD50C\uB9BF\uC774 \uCD08\uAE30\uD654\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4."},
- {"appletpanel.notstarted", "\uC815\uC9C0: \uC560\uD50C\uB9BF\uC774 \uC2DC\uC791\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4."},
- {"appletpanel.notstopped", "\uC0AD\uC81C: \uC560\uD50C\uB9BF\uC774 \uC815\uC9C0\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4."},
- {"appletpanel.notdestroyed", "\uBC30\uCE58: \uC560\uD50C\uB9BF\uC774 \uC0AD\uC81C\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4."},
- {"appletpanel.notdisposed", "\uB85C\uB4DC: \uC560\uD50C\uB9BF\uC774 \uBC30\uCE58\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4."},
- {"appletpanel.bail", "\uC911\uB2E8\uB428: \uC911\uB2E8\uD558\uB294 \uC911\uC785\uB2C8\uB2E4."},
- {"appletpanel.filenotfound", "{0}\uC744(\uB97C) \uAC80\uC0C9\uD558\uB294 \uC911 \uD30C\uC77C\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4."},
- {"appletpanel.fileformat", "\uB85C\uB4DC \uC911 \uD30C\uC77C \uD615\uC2DD \uC608\uC678\uC0AC\uD56D \uBC1C\uC0DD: {0}"},
- {"appletpanel.fileioexception", "\uB85C\uB4DC \uC911 I/O \uC608\uC678\uC0AC\uD56D \uBC1C\uC0DD: {0}"},
- {"appletpanel.fileexception", "\uB85C\uB4DC \uC911 {0} \uC608\uC678\uC0AC\uD56D \uBC1C\uC0DD: {1}"},
- {"appletpanel.filedeath", "\uB85C\uB4DC \uC911 {0}\uC774(\uAC00) \uC885\uB8CC\uB428: {1}"},
- {"appletpanel.fileerror", "\uB85C\uB4DC \uC911 {0} \uC624\uB958 \uBC1C\uC0DD: {1}"},
- {"appletpanel.badattribute.exception", "HTML \uAD6C\uBB38\uBD84\uC11D \uC911: width/height \uC18D\uC131\uC5D0 \uB300\uD55C \uAC12\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."},
- {"appletillegalargumentexception.objectinputstream", "AppletObjectInputStream\uC5D0 \uB110\uC774 \uC544\uB2CC \uB85C\uB354\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4."},
- {"appletprops.title", "AppletViewer \uC18D\uC131"},
- {"appletprops.label.http.server", "HTTP \uD504\uB85D\uC2DC \uC11C\uBC84:"},
- {"appletprops.label.http.proxy", "HTTP \uD504\uB85D\uC2DC \uD3EC\uD2B8:"},
- {"appletprops.label.network", "\uB124\uD2B8\uC6CC\uD06C \uC561\uC138\uC2A4:"},
- {"appletprops.choice.network.item.none", "\uC5C6\uC74C"},
- {"appletprops.choice.network.item.applethost", "\uC560\uD50C\uB9BF \uD638\uC2A4\uD2B8"},
- {"appletprops.choice.network.item.unrestricted", "\uC81C\uD55C\uB418\uC9C0 \uC54A\uC74C"},
- {"appletprops.label.class", "\uD074\uB798\uC2A4 \uC561\uC138\uC2A4:"},
- {"appletprops.choice.class.item.restricted", "\uC81C\uD55C\uB428"},
- {"appletprops.choice.class.item.unrestricted", "\uC81C\uD55C\uB418\uC9C0 \uC54A\uC74C"},
- {"appletprops.label.unsignedapplet", "\uC11C\uBA85\uB418\uC9C0 \uC54A\uC740 \uC560\uD50C\uB9BF \uD5C8\uC6A9:"},
- {"appletprops.choice.unsignedapplet.no", "\uC544\uB2C8\uC624"},
- {"appletprops.choice.unsignedapplet.yes", "\uC608"},
- {"appletprops.button.apply", "\uC801\uC6A9"},
- {"appletprops.button.cancel", "\uCDE8\uC18C"},
- {"appletprops.button.reset", "\uC7AC\uC124\uC815"},
- {"appletprops.apply.exception", "\uC18D\uC131 \uC800\uC7A5 \uC2E4\uD328: {0}"},
- /* 4066432 */
- {"appletprops.title.invalidproxy", "\uBD80\uC801\uD569\uD55C \uD56D\uBAA9"},
- {"appletprops.label.invalidproxy", "\uD504\uB85D\uC2DC \uD3EC\uD2B8\uB294 \uC591\uC758 \uC815\uC218 \uAC12\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4."},
- {"appletprops.button.ok", "\uD655\uC778"},
- /* end 4066432 */
- {"appletprops.prop.store", "\uC0AC\uC6A9\uC790 \uAD00\uB828 AppletViewer \uC18D\uC131"},
- {"appletsecurityexception.checkcreateclassloader", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: \uD074\uB798\uC2A4 \uB85C\uB354"},
- {"appletsecurityexception.checkaccess.thread", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: \uC2A4\uB808\uB4DC"},
- {"appletsecurityexception.checkaccess.threadgroup", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: \uC2A4\uB808\uB4DC \uADF8\uB8F9: {0}"},
- {"appletsecurityexception.checkexit", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: \uC885\uB8CC: {0}"},
- {"appletsecurityexception.checkexec", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: \uC2E4\uD589: {0}"},
- {"appletsecurityexception.checklink", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: \uB9C1\uD06C: {0}"},
- {"appletsecurityexception.checkpropsaccess", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: \uC18D\uC131"},
- {"appletsecurityexception.checkpropsaccess.key", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: \uC18D\uC131 \uC561\uC138\uC2A4 {0}"},
- {"appletsecurityexception.checkread.exception1", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: {0}, {1}"},
- {"appletsecurityexception.checkread.exception2", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: file.read: {0}"},
- {"appletsecurityexception.checkread", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: file.read: {0} == {1}"},
- {"appletsecurityexception.checkwrite.exception", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: {0}, {1}"},
- {"appletsecurityexception.checkwrite", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: file.write: {0} == {1}"},
- {"appletsecurityexception.checkread.fd", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: fd.read"},
- {"appletsecurityexception.checkwrite.fd", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: fd.write"},
- {"appletsecurityexception.checklisten", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: socket.listen: {0}"},
- {"appletsecurityexception.checkaccept", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: socket.accept: {0}:{1}"},
- {"appletsecurityexception.checkconnect.networknone", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: socket.connect: {0}->{1}"},
- {"appletsecurityexception.checkconnect.networkhost1", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: {1}\uC5D0\uC11C {0}\uC5D0 \uC811\uC18D\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."},
- {"appletsecurityexception.checkconnect.networkhost2", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: {0} \uD638\uC2A4\uD2B8 \uB610\uB294 {1}\uC5D0 \uB300\uD55C IP\uB97C \uBD84\uC11D\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. "},
- {"appletsecurityexception.checkconnect.networkhost3", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: {0} \uD638\uC2A4\uD2B8\uC5D0 \uB300\uD55C IP\uB97C \uBD84\uC11D\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. trustProxy \uC18D\uC131\uC744 \uCC38\uC870\uD558\uC2ED\uC2DC\uC624."},
- {"appletsecurityexception.checkconnect", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: \uC811\uC18D: {0}->{1}"},
- {"appletsecurityexception.checkpackageaccess", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: \uD328\uD0A4\uC9C0\uC5D0 \uC561\uC138\uC2A4\uD560 \uC218 \uC5C6\uC74C: {0}"},
- {"appletsecurityexception.checkpackagedefinition", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: \uD328\uD0A4\uC9C0\uB97C \uC815\uC758\uD560 \uC218 \uC5C6\uC74C: {0}"},
- {"appletsecurityexception.cannotsetfactory", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: \uD329\uD1A0\uB9AC\uB97C \uC124\uC815\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."},
- {"appletsecurityexception.checkmemberaccess", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: \uBA64\uBC84 \uC561\uC138\uC2A4\uB97C \uD655\uC778\uD558\uC2ED\uC2DC\uC624."},
- {"appletsecurityexception.checkgetprintjob", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: getPrintJob"},
- {"appletsecurityexception.checksystemclipboardaccess", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: getSystemClipboard"},
- {"appletsecurityexception.checkawteventqueueaccess", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: getEventQueue"},
- {"appletsecurityexception.checksecurityaccess", "\uBCF4\uC548 \uC608\uC678\uC0AC\uD56D: \uBCF4\uC548 \uC791\uC5C5: {0}"},
- {"appletsecurityexception.getsecuritycontext.unknown", "\uC54C \uC218 \uC5C6\uB294 \uD074\uB798\uC2A4 \uB85C\uB354 \uC720\uD615\uC785\uB2C8\uB2E4. getContext\uB97C \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."},
- {"appletsecurityexception.checkread.unknown", "\uC54C \uC218 \uC5C6\uB294 \uD074\uB798\uC2A4 \uB85C\uB354 \uC720\uD615\uC785\uB2C8\uB2E4. {0} \uC77D\uAE30\uB97C \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."},
- {"appletsecurityexception.checkconnect.unknown", "\uC54C \uC218 \uC5C6\uB294 \uD074\uB798\uC2A4 \uB85C\uB354 \uC720\uD615\uC785\uB2C8\uB2E4. \uC811\uC18D\uC744 \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."},
- };
-
- return temp;
- }
-}
--- a/src/java.desktop/share/classes/sun/applet/resources/MsgAppletViewer_pt_BR.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,203 +0,0 @@
-/*
- * Copyright (c) 1996, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-package sun.applet.resources;
-
-import java.util.ListResourceBundle;
-
-public class MsgAppletViewer_pt_BR extends ListResourceBundle {
-
- public Object[][] getContents() {
- Object[][] temp = new Object[][] {
- {"textframe.button.dismiss", "Rejeitar"},
- {"appletviewer.tool.title", "Visualizador do Applet: {0}"},
- {"appletviewer.menu.applet", "Applet"},
- {"appletviewer.menuitem.restart", "Reiniciar"},
- {"appletviewer.menuitem.reload", "Recarregar"},
- {"appletviewer.menuitem.stop", "Interromper"},
- {"appletviewer.menuitem.save", "Salvar"},
- {"appletviewer.menuitem.start", "Iniciar"},
- {"appletviewer.menuitem.clone", "Clonar..."},
- {"appletviewer.menuitem.tag", "Tag..."},
- {"appletviewer.menuitem.info", "Informa\u00E7\u00F5es..."},
- {"appletviewer.menuitem.edit", "Editar"},
- {"appletviewer.menuitem.encoding", "Codifica\u00E7\u00E3o do Caractere"},
- {"appletviewer.menuitem.print", "Imprimir..."},
- {"appletviewer.menuitem.props", "Propriedades..."},
- {"appletviewer.menuitem.close", "Fechar"},
- {"appletviewer.menuitem.quit", "Sair"},
- {"appletviewer.label.hello", "Ol\u00E1..."},
- {"appletviewer.status.start", "iniciando o applet..."},
- {"appletviewer.appletsave.filedialogtitle","Serializar Applet no Arquivo"},
- {"appletviewer.appletsave.err1", "serializando um {0} para {1}"},
- {"appletviewer.appletsave.err2", "no appletSave: {0}"},
- {"appletviewer.applettag", "Tag mostrada"},
- {"appletviewer.applettag.textframe", "Tag HTML do Applet"},
- {"appletviewer.appletinfo.applet", "-- nenhuma informa\u00E7\u00E3o do applet --"},
- {"appletviewer.appletinfo.param", "-- sem informa\u00E7\u00E3o de par\u00E2metro --"},
- {"appletviewer.appletinfo.textframe", "Informa\u00E7\u00F5es do Applet"},
- {"appletviewer.appletprint.fail", "Falha na impress\u00E3o."},
- {"appletviewer.appletprint.finish", "Impress\u00E3o finalizada."},
- {"appletviewer.appletprint.cancel", "Impress\u00E3o cancelada."},
- {"appletviewer.appletencoding", "Codifica\u00E7\u00E3o de Caractere: {0}"},
- {"appletviewer.parse.warning.requiresname", "Advert\u00EAncia: a tag <param name=... value=...> requer um atributo de nome."},
- {"appletviewer.parse.warning.paramoutside", "Advert\u00EAncia: a tag <param> externa <applet> ... </applet>."},
- {"appletviewer.parse.warning.applet.requirescode", "Advert\u00EAncia: a tag <applet> requer um atributo de c\u00F3digo."},
- {"appletviewer.parse.warning.applet.requiresheight", "Advert\u00EAncia: a tag <applet> requer um atributo de altura."},
- {"appletviewer.parse.warning.applet.requireswidth", "Advert\u00EAncia: a tag <applet> requer um atributo de largura."},
- {"appletviewer.parse.warning.object.requirescode", "Advert\u00EAncia: a tag <object> requer um atributo de c\u00F3digo."},
- {"appletviewer.parse.warning.object.requiresheight", "Advert\u00EAncia: a tag <object> requer um atributo de altura."},
- {"appletviewer.parse.warning.object.requireswidth", "Advert\u00EAncia: a tag <object> requer um atributo de largura."},
- {"appletviewer.parse.warning.embed.requirescode", "Advert\u00EAncia: a tag <embed> requer um atributo de c\u00F3digo."},
- {"appletviewer.parse.warning.embed.requiresheight", "Advert\u00EAncia: a tag <embed> requer um atributo de altura."},
- {"appletviewer.parse.warning.embed.requireswidth", "Advert\u00EAncia: a tag <embed> requer um atributo de largura."},
- {"appletviewer.parse.warning.appnotLongersupported", "Advert\u00EAncia: a tag <app> n\u00E3o \u00E9 mais suportada; use <applet>:"},
- {"appletviewer.deprecated", "Advert\u00EAncia: A API do e o AppletViewer est\u00E3o obsoletos."},
- {"appletviewer.usage", "Uso: appletviewer <op\u00E7\u00F5es> url(s)\n\nem que as <op\u00E7\u00F5es> incluem:\n -encoding <codifica\u00E7\u00E3o> Especifica a codifica\u00E7\u00E3o de caractere usada pelos arquivos HTML\n -J<flag de runtime> Informa o argumento ao intepretador java\n\nA op\u00E7\u00E3o -J n\u00E3o \u00E9 padr\u00E3o e est\u00E1 sujeita \u00E0 altera\u00E7\u00E3o sem notifica\u00E7\u00E3o."},
- {"appletviewer.main.err.unsupportedopt", "Op\u00E7\u00E3o n\u00E3o suportada: {0}"},
- {"appletviewer.main.err.unrecognizedarg", "Argumento n\u00E3o reconhecido: {0}"},
- {"appletviewer.main.err.dupoption", "Uso duplicado da op\u00E7\u00E3o: {0}"},
- {"appletviewer.main.err.inputfile", "Nenhum arquivo de entrada especificado."},
- {"appletviewer.main.err.badurl", "URL Inv\u00E1lido: {0} ( {1} )"},
- {"appletviewer.main.err.io", "Exce\u00E7\u00E3o de E/S ao ler: {0}"},
- {"appletviewer.main.err.readablefile", "Certifique-se de que {0} seja um arquivo e seja leg\u00EDvel."},
- {"appletviewer.main.err.correcturl", "O URL {0} est\u00E1 correto?"},
- {"appletviewer.main.prop.store", "Propriedades espec\u00EDficas do usu\u00E1rio do AppletViewer"},
- {"appletviewer.main.err.prop.cantread", "N\u00E3o \u00E9 poss\u00EDvel ler o arquivo de propriedades do usu\u00E1rio: {0}"},
- {"appletviewer.main.err.prop.cantsave", "N\u00E3o \u00E9 poss\u00EDvel salvar o arquivo de propriedades do usu\u00E1rio: {0}"},
- {"appletviewer.main.warn.nosecmgr", "Advert\u00EAncia: desativando a seguran\u00E7a."},
- {"appletviewer.main.debug.cantfinddebug", "N\u00E3o \u00E9 poss\u00EDvel localizar o depurador!"},
- {"appletviewer.main.debug.cantfindmain", "N\u00E3o \u00E9 poss\u00EDvel localizar o m\u00E9todo main no depurador!"},
- {"appletviewer.main.debug.exceptionindebug", "Exce\u00E7\u00E3o no depurador!"},
- {"appletviewer.main.debug.cantaccess", "N\u00E3o \u00E9 poss\u00EDvel acessar o depurador!"},
- {"appletviewer.main.nosecmgr", "Advert\u00EAncia: SecurityManager n\u00E3o instalado!"},
- {"appletviewer.main.warning", "Advert\u00EAncia: Nenhum applet iniciado. Certifique-se de que a entrada contenha uma tag <applet>."},
- {"appletviewer.main.warn.prop.overwrite", "Advert\u00EAncia: Substituindo a propriedade do sistema temporariamente a pedido do usu\u00E1rio: chave: {0} valor antigo: {1} valor novo: {2}"},
- {"appletviewer.main.warn.cantreadprops", "Advert\u00EAncia: N\u00E3o \u00E9 poss\u00EDvel ler o arquivo de propriedades AppletViewer: {0} Usando padr\u00F5es."},
- {"appletioexception.loadclass.throw.interrupted", "carregamento de classe interrompido: {0}"},
- {"appletioexception.loadclass.throw.notloaded", "classe n\u00E3o carregada: {0}"},
- {"appletclassloader.loadcode.verbose", "Fluxo de abertura para: {0} para obter {1}"},
- {"appletclassloader.filenotfound", "Arquivo n\u00E3o encontrado ao procurar: {0}"},
- {"appletclassloader.fileformat", "Exce\u00E7\u00E3o de formato do arquivo ao carregar: {0}"},
- {"appletclassloader.fileioexception", "Exce\u00E7\u00E3o de E/S ao carregar: {0}"},
- {"appletclassloader.fileexception", "exce\u00E7\u00E3o de {0} ao carregar: {1}"},
- {"appletclassloader.filedeath", "{0} eliminado ao carregar: {1}"},
- {"appletclassloader.fileerror", "erro de {0} ao carregar: {1}"},
- {"appletclassloader.findclass.verbose.openstream", "Fluxo de abertura para: {0} para obter {1}"},
- {"appletclassloader.getresource.verbose.forname", "AppletClassLoader.getResource do nome: {0}"},
- {"appletclassloader.getresource.verbose.found", "Recurso encontrado: {0} como um recurso do sistema"},
- {"appletclassloader.getresourceasstream.verbose", "Recurso encontrado: {0} como um recurso do sistema"},
- {"appletpanel.runloader.err", "Par\u00E2metro de c\u00F3digo ou objeto!"},
- {"appletpanel.runloader.exception", "exce\u00E7\u00E3o ao desserializar {0}"},
- {"appletpanel.destroyed", "Applet destru\u00EDdo."},
- {"appletpanel.loaded", "Applet carregado."},
- {"appletpanel.started", "Applet iniciado."},
- {"appletpanel.inited", "Applet inicializado."},
- {"appletpanel.stopped", "Applet interrompido."},
- {"appletpanel.disposed", "Applet descartado."},
- {"appletpanel.nocode", "A tag APPLET n\u00E3o encontrou o par\u00E2metro CODE."},
- {"appletpanel.notfound", "carga: classe {0} n\u00E3o encontrada."},
- {"appletpanel.nocreate", "carga: {0} n\u00E3o pode ser instanciada."},
- {"appletpanel.noconstruct", "carga: {0} n\u00E3o \u00E9 p\u00FAblica ou n\u00E3o tem construtor p\u00FAblico."},
- {"appletpanel.death", "eliminado"},
- {"appletpanel.exception", "exce\u00E7\u00E3o: {0}."},
- {"appletpanel.exception2", "exce\u00E7\u00E3o: {0}: {1}."},
- {"appletpanel.error", "erro: {0}."},
- {"appletpanel.error2", "erro: {0}: {1}."},
- {"appletpanel.notloaded", "Inic: applet n\u00E3o carregado."},
- {"appletpanel.notinited", "Iniciar: applet n\u00E3o inicializado."},
- {"appletpanel.notstarted", "Interromper: applet n\u00E3o inicializado."},
- {"appletpanel.notstopped", "Destruir: applet n\u00E3o interrompido."},
- {"appletpanel.notdestroyed", "Descartar: applet n\u00E3o destru\u00EDdo."},
- {"appletpanel.notdisposed", "Carregar: applet n\u00E3o descartado."},
- {"appletpanel.bail", "Interrompido: esvaziando."},
- {"appletpanel.filenotfound", "Arquivo n\u00E3o encontrado ao procurar: {0}"},
- {"appletpanel.fileformat", "Exce\u00E7\u00E3o de formato do arquivo ao carregar: {0}"},
- {"appletpanel.fileioexception", "Exce\u00E7\u00E3o de E/S ao carregar: {0}"},
- {"appletpanel.fileexception", "exce\u00E7\u00E3o de {0} ao carregar: {1}"},
- {"appletpanel.filedeath", "{0} eliminado ao carregar: {1}"},
- {"appletpanel.fileerror", "erro de {0} ao carregar: {1}"},
- {"appletpanel.badattribute.exception", "Parsing de HTML: valor incorreto do atributo de largura/altura"},
- {"appletillegalargumentexception.objectinputstream", "AppletObjectInputStream requer um carregador n\u00E3o nulo"},
- {"appletprops.title", "Propriedades do AppletViewer"},
- {"appletprops.label.http.server", "Servidor proxy Http:"},
- {"appletprops.label.http.proxy", "Porta proxy Http:"},
- {"appletprops.label.network", "Acesso de rede:"},
- {"appletprops.choice.network.item.none", "Nenhum"},
- {"appletprops.choice.network.item.applethost", "Host do Applet"},
- {"appletprops.choice.network.item.unrestricted", "Irrestrito"},
- {"appletprops.label.class", "Acesso \u00E0 classe:"},
- {"appletprops.choice.class.item.restricted", "Restrito"},
- {"appletprops.choice.class.item.unrestricted", "Irrestrito"},
- {"appletprops.label.unsignedapplet", "Permitir applets n\u00E3o assinados:"},
- {"appletprops.choice.unsignedapplet.no", "N\u00E3o"},
- {"appletprops.choice.unsignedapplet.yes", "Sim"},
- {"appletprops.button.apply", "Aplicar"},
- {"appletprops.button.cancel", "Cancelar"},
- {"appletprops.button.reset", "Redefinir"},
- {"appletprops.apply.exception", "Falha ao salvar as propriedades: {0}"},
- /* 4066432 */
- {"appletprops.title.invalidproxy", "Entrada Inv\u00E1lida"},
- {"appletprops.label.invalidproxy", "A Porta Proxy deve ser um valor inteiro positivo."},
- {"appletprops.button.ok", "OK"},
- /* end 4066432 */
- {"appletprops.prop.store", "Propriedades espec\u00EDficas do usu\u00E1rio do AppletViewer"},
- {"appletsecurityexception.checkcreateclassloader", "Exce\u00E7\u00E3o de Seguran\u00E7a: carregador de classes"},
- {"appletsecurityexception.checkaccess.thread", "Exce\u00E7\u00E3o de Seguran\u00E7a: thread"},
- {"appletsecurityexception.checkaccess.threadgroup", "Exce\u00E7\u00E3o de Seguran\u00E7a: grupo de threads: {0}"},
- {"appletsecurityexception.checkexit", "Exce\u00E7\u00E3o de Seguran\u00E7a: sa\u00EDda: {0}"},
- {"appletsecurityexception.checkexec", "Exce\u00E7\u00E3o de Seguran\u00E7a: exec.: {0}"},
- {"appletsecurityexception.checklink", "Exce\u00E7\u00E3o de Seguran\u00E7a: link: {0}"},
- {"appletsecurityexception.checkpropsaccess", "Exce\u00E7\u00E3o de Seguran\u00E7a: propriedades"},
- {"appletsecurityexception.checkpropsaccess.key", "Exce\u00E7\u00E3o de Seguran\u00E7a: acesso \u00E0s propriedades {0}"},
- {"appletsecurityexception.checkread.exception1", "Exce\u00E7\u00E3o de Seguran\u00E7a: {0}, {1}"},
- {"appletsecurityexception.checkread.exception2", "Exce\u00E7\u00E3o de Seguran\u00E7a: file.read: {0}"},
- {"appletsecurityexception.checkread", "Exce\u00E7\u00E3o de Seguran\u00E7a: file.read: {0} == {1}"},
- {"appletsecurityexception.checkwrite.exception", "Exce\u00E7\u00E3o de Seguran\u00E7a: {0}, {1}"},
- {"appletsecurityexception.checkwrite", "Exce\u00E7\u00E3o de Seguran\u00E7a: file.write: {0} == {1}"},
- {"appletsecurityexception.checkread.fd", "Exce\u00E7\u00E3o de Seguran\u00E7a: fd.read"},
- {"appletsecurityexception.checkwrite.fd", "Exce\u00E7\u00E3o de Seguran\u00E7a: fd.write"},
- {"appletsecurityexception.checklisten", "Exce\u00E7\u00E3o de Seguran\u00E7a: socket.listen: {0}"},
- {"appletsecurityexception.checkaccept", "Exce\u00E7\u00E3o de Seguran\u00E7a: socket.accept: {0}:{1}"},
- {"appletsecurityexception.checkconnect.networknone", "Exce\u00E7\u00E3o de Seguran\u00E7a: socket.connect: {0}->{1}"},
- {"appletsecurityexception.checkconnect.networkhost1", "Exce\u00E7\u00E3o de Seguran\u00E7a: N\u00E3o foi poss\u00EDvel estabelecer conex\u00E3o com {0} com a origem de {1}."},
- {"appletsecurityexception.checkconnect.networkhost2", "Exce\u00E7\u00E3o de Seguran\u00E7a: N\u00E3o foi poss\u00EDvel resolver o IP para o host {0} ou para {1}. "},
- {"appletsecurityexception.checkconnect.networkhost3", "Exce\u00E7\u00E3o de Seguran\u00E7a: N\u00E3o foi poss\u00EDvel resolver o IP para o host {0}. Consulte a propriedade trustProxy."},
- {"appletsecurityexception.checkconnect", "Exce\u00E7\u00E3o de Seguran\u00E7a: conectar: {0}->{1}"},
- {"appletsecurityexception.checkpackageaccess", "Exce\u00E7\u00E3o de Seguran\u00E7a: n\u00E3o \u00E9 poss\u00EDvel acessar o pacote: {0}"},
- {"appletsecurityexception.checkpackagedefinition", "Exce\u00E7\u00E3o de Seguran\u00E7a: n\u00E3o \u00E9 poss\u00EDvel definir o pacote: {0}"},
- {"appletsecurityexception.cannotsetfactory", "Exce\u00E7\u00E3o de Seguran\u00E7a: n\u00E3o \u00E9 poss\u00EDvel definir o factory"},
- {"appletsecurityexception.checkmemberaccess", "Exce\u00E7\u00E3o de Seguran\u00E7a: verificar acesso do membro"},
- {"appletsecurityexception.checkgetprintjob", "Exce\u00E7\u00E3o de Seguran\u00E7a: getPrintJob"},
- {"appletsecurityexception.checksystemclipboardaccess", "Exce\u00E7\u00E3o de Seguran\u00E7a: getSystemClipboard"},
- {"appletsecurityexception.checkawteventqueueaccess", "Exce\u00E7\u00E3o de Seguran\u00E7a: getEventQueue"},
- {"appletsecurityexception.checksecurityaccess", "Exce\u00E7\u00E3o de Seguran\u00E7a: opera\u00E7\u00E3o de seguran\u00E7a: {0}"},
- {"appletsecurityexception.getsecuritycontext.unknown", "tipo de carregador de classe desconhecido. n\u00E3o \u00E9 poss\u00EDvel verificar getContext"},
- {"appletsecurityexception.checkread.unknown", "tipo de carregador de classe desconhecido. n\u00E3o \u00E9 poss\u00EDvel verificar a leitura {0}"},
- {"appletsecurityexception.checkconnect.unknown", "tipo de carregador de classe desconhecido. n\u00E3o \u00E9 poss\u00EDvel verificar a conex\u00E3o"},
- };
-
- return temp;
- }
-}
--- a/src/java.desktop/share/classes/sun/applet/resources/MsgAppletViewer_sv.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,203 +0,0 @@
-/*
- * Copyright (c) 1996, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-package sun.applet.resources;
-
-import java.util.ListResourceBundle;
-
-public class MsgAppletViewer_sv extends ListResourceBundle {
-
- public Object[][] getContents() {
- Object[][] temp = new Object[][] {
- {"textframe.button.dismiss", "St\u00E4ng"},
- {"appletviewer.tool.title", "Applet Viewer: {0}"},
- {"appletviewer.menu.applet", "Applet"},
- {"appletviewer.menuitem.restart", "Starta om"},
- {"appletviewer.menuitem.reload", "Ladda om"},
- {"appletviewer.menuitem.stop", "Stopp"},
- {"appletviewer.menuitem.save", "Spara..."},
- {"appletviewer.menuitem.start", "Starta"},
- {"appletviewer.menuitem.clone", "Klona..."},
- {"appletviewer.menuitem.tag", "Tagg..."},
- {"appletviewer.menuitem.info", "Information..."},
- {"appletviewer.menuitem.edit", "Redigera"},
- {"appletviewer.menuitem.encoding", "Teckenkodning"},
- {"appletviewer.menuitem.print", "Skriv ut..."},
- {"appletviewer.menuitem.props", "Egenskaper..."},
- {"appletviewer.menuitem.close", "St\u00E4ng"},
- {"appletviewer.menuitem.quit", "Avsluta"},
- {"appletviewer.label.hello", "Hej..."},
- {"appletviewer.status.start", "startar applet..."},
- {"appletviewer.appletsave.filedialogtitle","Serialisera applet till fil"},
- {"appletviewer.appletsave.err1", "serialiserar {0} till {1}"},
- {"appletviewer.appletsave.err2", "i appletSave: {0}"},
- {"appletviewer.applettag", "Tagg visas"},
- {"appletviewer.applettag.textframe", "HTML-tagg f\u00F6r applet"},
- {"appletviewer.appletinfo.applet", "-- ingen appletinformation --"},
- {"appletviewer.appletinfo.param", "-- ingen parameterinformation --"},
- {"appletviewer.appletinfo.textframe", "Appletinformation"},
- {"appletviewer.appletprint.fail", "Kunde inte skriva ut."},
- {"appletviewer.appletprint.finish", "Utskriften klar."},
- {"appletviewer.appletprint.cancel", "Utskriften avbruten."},
- {"appletviewer.appletencoding", "Teckenkodning: {0}"},
- {"appletviewer.parse.warning.requiresname", "Varning: <param name=... value=...>-taggen kr\u00E4ver ett namnattribut."},
- {"appletviewer.parse.warning.paramoutside", "Varning: <param>-taggen finns utanf\u00F6r <applet> ... </applet>."},
- {"appletviewer.parse.warning.applet.requirescode", "Varning: <applet>-taggen kr\u00E4ver ett kodattribut."},
- {"appletviewer.parse.warning.applet.requiresheight", "Varning: <applet>-taggen kr\u00E4ver ett h\u00F6jdattribut."},
- {"appletviewer.parse.warning.applet.requireswidth", "Varning: <applet>-taggen kr\u00E4ver ett breddattribut."},
- {"appletviewer.parse.warning.object.requirescode", "Varning: <object>-taggen kr\u00E4ver ett kodattribut."},
- {"appletviewer.parse.warning.object.requiresheight", "Varning: <object>-taggen kr\u00E4ver ett h\u00F6jdattribut."},
- {"appletviewer.parse.warning.object.requireswidth", "Varning: <object>-taggen kr\u00E4ver ett breddattribut."},
- {"appletviewer.parse.warning.embed.requirescode", "Varning: <embed>-taggen kr\u00E4ver ett kodattribut."},
- {"appletviewer.parse.warning.embed.requiresheight", "Varning: <embed>-taggen kr\u00E4ver ett h\u00F6jdattribut."},
- {"appletviewer.parse.warning.embed.requireswidth", "Varning: <embed>-taggen kr\u00E4ver ett breddattribut."},
- {"appletviewer.parse.warning.appnotLongersupported", "Varning: <app>-taggen st\u00F6ds inte l\u00E4ngre, anv\u00E4nd <applet> ist\u00E4llet:"},
- {"appletviewer.deprecated", "Varning: Applet-API:t och AppletViewer \u00E4r inaktuella."},
- {"appletviewer.usage", "Syntax: appletviewer <options> url(s)\n\nd\u00E4r <options> \u00E4r:\n -encoding <encoding> Ange teckenkodning som anv\u00E4nds av HTML-filer\n -J<runtime flag> \u00D6verf\u00F6r argument till java-tolken\n\nAlternativet -J \u00E4r inte standard och kan \u00E4ndras utan f\u00F6reg\u00E5ende meddelande."},
- {"appletviewer.main.err.unsupportedopt", "Alternativ som inte st\u00F6ds: {0}"},
- {"appletviewer.main.err.unrecognizedarg", "Ok\u00E4nt argument: {0}"},
- {"appletviewer.main.err.dupoption", "Duplicerat alternativ: {0}"},
- {"appletviewer.main.err.inputfile", "Inga angivna indatafiler."},
- {"appletviewer.main.err.badurl", "Felaktig URL: {0} ( {1} )"},
- {"appletviewer.main.err.io", "I/O-undantag vid l\u00E4sning: {0}"},
- {"appletviewer.main.err.readablefile", "Kontrollera att {0} \u00E4r en fil som \u00E4r l\u00E4sbar."},
- {"appletviewer.main.err.correcturl", "\u00C4r {0} den korrekta URL:en?"},
- {"appletviewer.main.prop.store", "Anv\u00E4ndarspecifika egenskaper f\u00F6r AppletViewer"},
- {"appletviewer.main.err.prop.cantread", "Kan inte l\u00E4sa egenskapsfilen: {0}"},
- {"appletviewer.main.err.prop.cantsave", "Kan inte spara egenskapsfilen: {0}"},
- {"appletviewer.main.warn.nosecmgr", "Varning! S\u00E4kerheten avaktiveras."},
- {"appletviewer.main.debug.cantfinddebug", "Hittar inte fels\u00F6kningsprogrammet!"},
- {"appletviewer.main.debug.cantfindmain", "Hittar inte huvudmetoden i fels\u00F6kningsprogrammet!"},
- {"appletviewer.main.debug.exceptionindebug", "Undantag i fels\u00F6kningsprogrammet!"},
- {"appletviewer.main.debug.cantaccess", "Det finns ingen \u00E5tkomst till fels\u00F6kningsprogrammet!"},
- {"appletviewer.main.nosecmgr", "Varning: SecurityManager har inte installerats!"},
- {"appletviewer.main.warning", "Varning: Inga appletar har startats. Kontrollera att indata inneh\u00E5ller <applet>-tagg."},
- {"appletviewer.main.warn.prop.overwrite", "Varning: Skriver tillf\u00E4lligt \u00F6ver systemegenskap enligt beg\u00E4ran fr\u00E5n anv\u00E4ndare: nyckel: {0} tidigare v\u00E4rde: {1} nytt v\u00E4rde: {2}"},
- {"appletviewer.main.warn.cantreadprops", "Varning: Kan inte l\u00E4sa egenskapsfil f\u00F6r AppletViewer: {0} Standardv\u00E4rden anv\u00E4nds."},
- {"appletioexception.loadclass.throw.interrupted", "klassladdning avbr\u00F6ts: {0}"},
- {"appletioexception.loadclass.throw.notloaded", "klass inte laddad: {0}"},
- {"appletclassloader.loadcode.verbose", "\u00D6ppnar str\u00F6m till: {0} f\u00F6r h\u00E4mtning av {1}"},
- {"appletclassloader.filenotfound", "Hittade inte fil vid s\u00F6kning efter: {0}"},
- {"appletclassloader.fileformat", "Undantag av filformat vid laddning av: {0}"},
- {"appletclassloader.fileioexception", "I/O-undantag vid laddning: {0}"},
- {"appletclassloader.fileexception", "{0} undantag vid laddning: {1}"},
- {"appletclassloader.filedeath", "{0} avslutad vid laddning: {1}"},
- {"appletclassloader.fileerror", "{0} fel vid laddning: {1}"},
- {"appletclassloader.findclass.verbose.openstream", "\u00D6ppnar str\u00F6m till: {0} f\u00F6r h\u00E4mtning av {1}"},
- {"appletclassloader.getresource.verbose.forname", "AppletClassLoader.getResource f\u00F6r namnet: {0}"},
- {"appletclassloader.getresource.verbose.found", "Hittade resursen: {0} som systemresurs"},
- {"appletclassloader.getresourceasstream.verbose", "Hittade resursen: {0} som systemresurs"},
- {"appletpanel.runloader.err", "Antingen objekt- eller kodparameter!"},
- {"appletpanel.runloader.exception", "undantag vid avserialisering {0}"},
- {"appletpanel.destroyed", "Applet raderad."},
- {"appletpanel.loaded", "Applet laddad."},
- {"appletpanel.started", "Applet startad."},
- {"appletpanel.inited", "Applet initierad."},
- {"appletpanel.stopped", "Applet stoppad."},
- {"appletpanel.disposed", "Applet kasserad."},
- {"appletpanel.nocode", "APPLET-tagg saknar CODE-parameter."},
- {"appletpanel.notfound", "load: hittade inte klassen {0}."},
- {"appletpanel.nocreate", "load: {0} kan inte instansieras."},
- {"appletpanel.noconstruct", "load: {0} \u00E4r inte allm\u00E4n eller saknar allm\u00E4n konstruktor."},
- {"appletpanel.death", "avslutad"},
- {"appletpanel.exception", "undantag: {0}."},
- {"appletpanel.exception2", "undantag: {0}: {1}."},
- {"appletpanel.error", "fel: {0}."},
- {"appletpanel.error2", "fel {0}: {1}."},
- {"appletpanel.notloaded", "Initiera: applet \u00E4r inte laddad."},
- {"appletpanel.notinited", "Starta: applet \u00E4r inte initierad."},
- {"appletpanel.notstarted", "Stoppa: applet har inte startats."},
- {"appletpanel.notstopped", "Radera: applet har inte stoppats."},
- {"appletpanel.notdestroyed", "Kassera: applet har inte raderats."},
- {"appletpanel.notdisposed", "Ladda: applet har inte kasserats."},
- {"appletpanel.bail", "Avbruten."},
- {"appletpanel.filenotfound", "Hittade inte fil vid s\u00F6kning efter: {0}"},
- {"appletpanel.fileformat", "Undantag av filformat vid laddning av: {0}"},
- {"appletpanel.fileioexception", "I/O-undantag vid laddning: {0}"},
- {"appletpanel.fileexception", "{0} undantag vid laddning: {1}"},
- {"appletpanel.filedeath", "{0} avslutad vid laddning: {1}"},
- {"appletpanel.fileerror", "{0} fel vid laddning: {1}"},
- {"appletpanel.badattribute.exception", "HTML-tolkning: felaktigt v\u00E4rde f\u00F6r bredd-/h\u00F6jdattribut"},
- {"appletillegalargumentexception.objectinputstream", "AppletObjectInputStream kr\u00E4ver laddare med icke-null"},
- {"appletprops.title", "AppletViewer-egenskaper"},
- {"appletprops.label.http.server", "HTTP-proxyserver:"},
- {"appletprops.label.http.proxy", "HTTP-proxyport:"},
- {"appletprops.label.network", "N\u00E4tverks\u00E5tkomst:"},
- {"appletprops.choice.network.item.none", "Ingen"},
- {"appletprops.choice.network.item.applethost", "Appletv\u00E4rd"},
- {"appletprops.choice.network.item.unrestricted", "Obegr\u00E4nsad"},
- {"appletprops.label.class", "Klass\u00E5tkomst:"},
- {"appletprops.choice.class.item.restricted", "Begr\u00E4nsad"},
- {"appletprops.choice.class.item.unrestricted", "Obegr\u00E4nsad"},
- {"appletprops.label.unsignedapplet", "Till\u00E5t osignerade appletar:"},
- {"appletprops.choice.unsignedapplet.no", "Nej"},
- {"appletprops.choice.unsignedapplet.yes", "Ja"},
- {"appletprops.button.apply", "Anv\u00E4nd"},
- {"appletprops.button.cancel", "Avbryt"},
- {"appletprops.button.reset", "\u00C5terst\u00E4ll"},
- {"appletprops.apply.exception", "Kunde inte spara egenskaper: {0}"},
- /* 4066432 */
- {"appletprops.title.invalidproxy", "Ogiltig post"},
- {"appletprops.label.invalidproxy", "Proxyport m\u00E5ste vara ett positivt heltal."},
- {"appletprops.button.ok", "OK"},
- /* end 4066432 */
- {"appletprops.prop.store", "Anv\u00E4ndarspecifika egenskaper f\u00F6r AppletViewer"},
- {"appletsecurityexception.checkcreateclassloader", "S\u00E4kerhetsundantag: klassladdare"},
- {"appletsecurityexception.checkaccess.thread", "S\u00E4kerhetsundantag: tr\u00E5d"},
- {"appletsecurityexception.checkaccess.threadgroup", "S\u00E4kerhetsundantag: tr\u00E5dgrupp: {0}"},
- {"appletsecurityexception.checkexit", "S\u00E4kerhetsundantag: utg\u00E5ng: {0}"},
- {"appletsecurityexception.checkexec", "S\u00E4kerhetsundantag: exec: {0}"},
- {"appletsecurityexception.checklink", "S\u00E4kerhetsundantag: l\u00E4nk: {0}"},
- {"appletsecurityexception.checkpropsaccess", "S\u00E4kerhetsundantag: egenskaper"},
- {"appletsecurityexception.checkpropsaccess.key", "S\u00E4kerhetsundantag: egenskaps\u00E5tkomst {0}"},
- {"appletsecurityexception.checkread.exception1", "S\u00E4kerhetsundantag: {0}, {1}"},
- {"appletsecurityexception.checkread.exception2", "S\u00E4kerhetsundantag: file.read: {0}"},
- {"appletsecurityexception.checkread", "S\u00E4kerhetsundantag: file.read: {0} == {1}"},
- {"appletsecurityexception.checkwrite.exception", "S\u00E4kerhetsundantag: {0}, {1}"},
- {"appletsecurityexception.checkwrite", "S\u00E4kerhetsundantag: file.write: {0} == {1}"},
- {"appletsecurityexception.checkread.fd", "S\u00E4kerhetsundantag: fd.read"},
- {"appletsecurityexception.checkwrite.fd", "S\u00E4kerhetsundantag: fd.write"},
- {"appletsecurityexception.checklisten", "S\u00E4kerhetsundantag: socket.listen: {0}"},
- {"appletsecurityexception.checkaccept", "S\u00E4kerhetsundantag: socket.accept: {0}:{1}"},
- {"appletsecurityexception.checkconnect.networknone", "S\u00E4kerhetsundantag: socket.connect: {0}->{1}"},
- {"appletsecurityexception.checkconnect.networkhost1", "S\u00E4kerhetsundantag: Kunde inte ansluta till {0} med ursprung fr\u00E5n {1}."},
- {"appletsecurityexception.checkconnect.networkhost2", "S\u00E4kerhetsundantag: Kunde inte matcha IP f\u00F6r v\u00E4rd {0} eller f\u00F6r {1}. "},
- {"appletsecurityexception.checkconnect.networkhost3", "S\u00E4kerhetsundantag: Kunde inte matcha IP f\u00F6r v\u00E4rd {0}. Se egenskapen trustProxy."},
- {"appletsecurityexception.checkconnect", "S\u00E4kerhetsundantag: connect: {0}->{1}"},
- {"appletsecurityexception.checkpackageaccess", "S\u00E4kerhetsundantag: ingen \u00E5tkomst till paket: {0}"},
- {"appletsecurityexception.checkpackagedefinition", "S\u00E4kerhetsundantag: kan inte definiera paket: {0}"},
- {"appletsecurityexception.cannotsetfactory", "S\u00E4kerhetsundantag: kan inte ange fabrik"},
- {"appletsecurityexception.checkmemberaccess", "S\u00E4kerhetsundantag: kontrollera medlems\u00E5tkomst"},
- {"appletsecurityexception.checkgetprintjob", "S\u00E4kerhetsundantag: getPrintJob"},
- {"appletsecurityexception.checksystemclipboardaccess", "S\u00E4kerhetsundantag: getSystemClipboard"},
- {"appletsecurityexception.checkawteventqueueaccess", "S\u00E4kerhetsundantag: getEventQueue"},
- {"appletsecurityexception.checksecurityaccess", "S\u00E4kerhetsundantag: s\u00E4kerhets\u00E5tg\u00E4rd: {0}"},
- {"appletsecurityexception.getsecuritycontext.unknown", "ok\u00E4nd typ av klassladdare. kan inte kontrollera getContext"},
- {"appletsecurityexception.checkread.unknown", "ok\u00E4nd typ av klassladdare. kan inte kontrollera kontroll\u00E4sning {0}"},
- {"appletsecurityexception.checkconnect.unknown", "ok\u00E4nd typ av klassladdare. kan inte kontrollera kontrollanslutning"},
- };
-
- return temp;
- }
-}
--- a/src/java.desktop/share/classes/sun/applet/resources/MsgAppletViewer_zh_CN.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,203 +0,0 @@
-/*
- * Copyright (c) 1996, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-package sun.applet.resources;
-
-import java.util.ListResourceBundle;
-
-public class MsgAppletViewer_zh_CN extends ListResourceBundle {
-
- public Object[][] getContents() {
- Object[][] temp = new Object[][] {
- {"textframe.button.dismiss", "\u5173\u95ED"},
- {"appletviewer.tool.title", "\u5C0F\u5E94\u7528\u7A0B\u5E8F\u67E5\u770B\u5668: {0}"},
- {"appletviewer.menu.applet", "\u5C0F\u5E94\u7528\u7A0B\u5E8F"},
- {"appletviewer.menuitem.restart", "\u91CD\u65B0\u542F\u52A8"},
- {"appletviewer.menuitem.reload", "\u91CD\u65B0\u52A0\u8F7D"},
- {"appletviewer.menuitem.stop", "\u505C\u6B62"},
- {"appletviewer.menuitem.save", "\u4FDD\u5B58..."},
- {"appletviewer.menuitem.start", "\u542F\u52A8"},
- {"appletviewer.menuitem.clone", "\u514B\u9686..."},
- {"appletviewer.menuitem.tag", "\u6807\u8BB0..."},
- {"appletviewer.menuitem.info", "\u4FE1\u606F..."},
- {"appletviewer.menuitem.edit", "\u7F16\u8F91"},
- {"appletviewer.menuitem.encoding", "\u5B57\u7B26\u7F16\u7801"},
- {"appletviewer.menuitem.print", "\u6253\u5370..."},
- {"appletviewer.menuitem.props", "\u5C5E\u6027..."},
- {"appletviewer.menuitem.close", "\u5173\u95ED"},
- {"appletviewer.menuitem.quit", "\u9000\u51FA"},
- {"appletviewer.label.hello", "\u60A8\u597D..."},
- {"appletviewer.status.start", "\u6B63\u5728\u542F\u52A8\u5C0F\u5E94\u7528\u7A0B\u5E8F..."},
- {"appletviewer.appletsave.filedialogtitle","\u5C06\u5C0F\u5E94\u7528\u7A0B\u5E8F\u5E8F\u5217\u5316\u4E3A\u6587\u4EF6"},
- {"appletviewer.appletsave.err1", "\u5C06{0}\u5E8F\u5217\u5316\u4E3A{1}"},
- {"appletviewer.appletsave.err2", "\u5728 appletSave \u4E2D: {0}"},
- {"appletviewer.applettag", "\u663E\u793A\u7684\u6807\u8BB0"},
- {"appletviewer.applettag.textframe", "\u5C0F\u5E94\u7528\u7A0B\u5E8F HTML \u6807\u8BB0"},
- {"appletviewer.appletinfo.applet", "-- \u6CA1\u6709\u5C0F\u5E94\u7528\u7A0B\u5E8F\u4FE1\u606F --"},
- {"appletviewer.appletinfo.param", "-- \u6CA1\u6709\u53C2\u6570\u4FE1\u606F --"},
- {"appletviewer.appletinfo.textframe", "\u5C0F\u5E94\u7528\u7A0B\u5E8F\u4FE1\u606F"},
- {"appletviewer.appletprint.fail", "\u6253\u5370\u5931\u8D25\u3002"},
- {"appletviewer.appletprint.finish", "\u5DF2\u5B8C\u6210\u6253\u5370\u3002"},
- {"appletviewer.appletprint.cancel", "\u6253\u5370\u5DF2\u53D6\u6D88\u3002"},
- {"appletviewer.appletencoding", "\u5B57\u7B26\u7F16\u7801: {0}"},
- {"appletviewer.parse.warning.requiresname", "\u8B66\u544A: <param name=... value=...> \u6807\u8BB0\u9700\u8981\u540D\u79F0\u5C5E\u6027\u3002"},
- {"appletviewer.parse.warning.paramoutside", "\u8B66\u544A: <param> \u6807\u8BB0\u5728 <applet> ... </applet> \u5916\u90E8\u3002"},
- {"appletviewer.parse.warning.applet.requirescode", "\u8B66\u544A: <applet> \u6807\u8BB0\u9700\u8981\u4EE3\u7801\u5C5E\u6027\u3002"},
- {"appletviewer.parse.warning.applet.requiresheight", "\u8B66\u544A: <applet> \u6807\u8BB0\u9700\u8981\u9AD8\u5EA6\u5C5E\u6027\u3002"},
- {"appletviewer.parse.warning.applet.requireswidth", "\u8B66\u544A: <applet> \u6807\u8BB0\u9700\u8981\u5BBD\u5EA6\u5C5E\u6027\u3002"},
- {"appletviewer.parse.warning.object.requirescode", "\u8B66\u544A: <object> \u6807\u8BB0\u9700\u8981\u4EE3\u7801\u5C5E\u6027\u3002"},
- {"appletviewer.parse.warning.object.requiresheight", "\u8B66\u544A: <object> \u6807\u8BB0\u9700\u8981\u9AD8\u5EA6\u5C5E\u6027\u3002"},
- {"appletviewer.parse.warning.object.requireswidth", "\u8B66\u544A: <object> \u6807\u8BB0\u9700\u8981\u5BBD\u5EA6\u5C5E\u6027\u3002"},
- {"appletviewer.parse.warning.embed.requirescode", "\u8B66\u544A: <embed> \u6807\u8BB0\u9700\u8981\u4EE3\u7801\u5C5E\u6027\u3002"},
- {"appletviewer.parse.warning.embed.requiresheight", "\u8B66\u544A: <embed> \u6807\u8BB0\u9700\u8981\u9AD8\u5EA6\u5C5E\u6027\u3002"},
- {"appletviewer.parse.warning.embed.requireswidth", "\u8B66\u544A: <embed> \u6807\u8BB0\u9700\u8981\u5BBD\u5EA6\u5C5E\u6027\u3002"},
- {"appletviewer.parse.warning.appnotLongersupported", "\u8B66\u544A: \u4E0D\u518D\u652F\u6301 <app> \u6807\u8BB0, \u8BF7\u6539\u7528 <applet>:"},
- {"appletviewer.deprecated", "\u8B66\u544A: \u5C0F\u5E94\u7528\u7A0B\u5E8F API \u548C AppletViewer \u5DF2\u8FC7\u65F6\u3002"},
- {"appletviewer.usage", "\u7528\u6CD5: appletviewer <options> url(s)\n\n\u5176\u4E2D <options> \u5305\u62EC:\n -encoding <encoding> \u6307\u5B9A HTML \u6587\u4EF6\u4F7F\u7528\u7684\u5B57\u7B26\u7F16\u7801\n -J<runtime flag> \u5C06\u53C2\u6570\u4F20\u9012\u5230 java \u89E3\u91CA\u5668\n\n-J \u9009\u9879\u662F\u975E\u6807\u51C6\u9009\u9879, \u5982\u6709\u66F4\u6539, \u6055\u4E0D\u53E6\u884C\u901A\u77E5\u3002"},
- {"appletviewer.main.err.unsupportedopt", "\u4E0D\u652F\u6301\u7684\u9009\u9879: {0}"},
- {"appletviewer.main.err.unrecognizedarg", "\u65E0\u6CD5\u8BC6\u522B\u7684\u53C2\u6570: {0}"},
- {"appletviewer.main.err.dupoption", "\u91CD\u590D\u4F7F\u7528\u9009\u9879: {0}"},
- {"appletviewer.main.err.inputfile", "\u672A\u6307\u5B9A\u8F93\u5165\u6587\u4EF6\u3002"},
- {"appletviewer.main.err.badurl", "\u9519\u8BEF URL: {0} ({1})"},
- {"appletviewer.main.err.io", "\u8BFB\u53D6{0}\u65F6\u51FA\u73B0 I/O \u5F02\u5E38\u9519\u8BEF"},
- {"appletviewer.main.err.readablefile", "\u786E\u4FDD{0}\u662F\u6587\u4EF6\u4E14\u53EF\u8BFB\u3002"},
- {"appletviewer.main.err.correcturl", "{0} \u662F\u5426\u662F\u6B63\u786E\u7684 URL?"},
- {"appletviewer.main.prop.store", "AppletViewer \u7684\u7528\u6237\u7279\u5B9A\u5C5E\u6027"},
- {"appletviewer.main.err.prop.cantread", "\u65E0\u6CD5\u8BFB\u53D6\u7528\u6237\u5C5E\u6027\u6587\u4EF6: {0}"},
- {"appletviewer.main.err.prop.cantsave", "\u65E0\u6CD5\u4FDD\u5B58\u7528\u6237\u5C5E\u6027\u6587\u4EF6: {0}"},
- {"appletviewer.main.warn.nosecmgr", "\u8B66\u544A: \u7981\u7528\u5B89\u5168\u3002"},
- {"appletviewer.main.debug.cantfinddebug", "\u627E\u4E0D\u5230\u8C03\u8BD5\u5668!"},
- {"appletviewer.main.debug.cantfindmain", "\u5728\u8C03\u8BD5\u5668\u4E2D\u627E\u4E0D\u5230 main \u65B9\u6CD5!"},
- {"appletviewer.main.debug.exceptionindebug", "\u8C03\u8BD5\u5668\u4E2D\u5B58\u5728\u5F02\u5E38\u9519\u8BEF!"},
- {"appletviewer.main.debug.cantaccess", "\u65E0\u6CD5\u8BBF\u95EE\u8C03\u8BD5\u5668!"},
- {"appletviewer.main.nosecmgr", "\u8B66\u544A: \u672A\u5B89\u88C5 SecurityManager!"},
- {"appletviewer.main.warning", "\u8B66\u544A: \u672A\u542F\u52A8\u5C0F\u5E94\u7528\u7A0B\u5E8F\u3002\u786E\u4FDD\u8F93\u5165\u5305\u542B <applet> \u6807\u8BB0\u3002"},
- {"appletviewer.main.warn.prop.overwrite", "\u8B66\u544A: \u6839\u636E\u7528\u6237\u8BF7\u6C42\u4E34\u65F6\u8986\u76D6\u7CFB\u7EDF\u5C5E\u6027: \u5173\u952E\u5B57: {0}, \u65E7\u503C: {1}, \u65B0\u503C: {2}"},
- {"appletviewer.main.warn.cantreadprops", "\u8B66\u544A: \u65E0\u6CD5\u8BFB\u53D6 AppletViewer \u5C5E\u6027\u6587\u4EF6: {0}\u3002\u8BF7\u4F7F\u7528\u9ED8\u8BA4\u503C\u3002"},
- {"appletioexception.loadclass.throw.interrupted", "\u7C7B\u52A0\u8F7D\u4E2D\u65AD: {0}"},
- {"appletioexception.loadclass.throw.notloaded", "\u672A\u52A0\u8F7D\u7C7B: {0}"},
- {"appletclassloader.loadcode.verbose", "\u6253\u5F00\u5230{0}\u7684\u6D41\u4EE5\u83B7\u53D6{1}"},
- {"appletclassloader.filenotfound", "\u67E5\u627E\u65F6\u627E\u4E0D\u5230\u6587\u4EF6: {0}"},
- {"appletclassloader.fileformat", "\u52A0\u8F7D\u65F6\u51FA\u73B0\u6587\u4EF6\u683C\u5F0F\u5F02\u5E38\u9519\u8BEF: {0}"},
- {"appletclassloader.fileioexception", "\u52A0\u8F7D\u65F6\u51FA\u73B0 I/O \u5F02\u5E38\u9519\u8BEF: {0}"},
- {"appletclassloader.fileexception", "\u52A0\u8F7D\u65F6\u51FA\u73B0{0}\u5F02\u5E38\u9519\u8BEF: {1}"},
- {"appletclassloader.filedeath", "\u52A0\u8F7D\u65F6\u5DF2\u7EC8\u6B62{0}: {1}"},
- {"appletclassloader.fileerror", "\u52A0\u8F7D\u65F6\u51FA\u73B0{0}\u9519\u8BEF: {1}"},
- {"appletclassloader.findclass.verbose.openstream", "\u6253\u5F00\u5230{0}\u7684\u6D41\u4EE5\u83B7\u53D6{1}"},
- {"appletclassloader.getresource.verbose.forname", "\u540D\u79F0\u7684 AppletClassLoader.getResource: {0}"},
- {"appletclassloader.getresource.verbose.found", "\u5DF2\u627E\u5230\u4F5C\u4E3A\u7CFB\u7EDF\u8D44\u6E90\u7684\u8D44\u6E90{0}"},
- {"appletclassloader.getresourceasstream.verbose", "\u5DF2\u627E\u5230\u4F5C\u4E3A\u7CFB\u7EDF\u8D44\u6E90\u7684\u8D44\u6E90{0}"},
- {"appletpanel.runloader.err", "\u5BF9\u8C61\u6216\u4EE3\u7801\u53C2\u6570!"},
- {"appletpanel.runloader.exception", "\u53CD\u5E8F\u5217\u5316{0}\u65F6\u51FA\u73B0\u5F02\u5E38\u9519\u8BEF"},
- {"appletpanel.destroyed", "\u5DF2\u9500\u6BC1\u5C0F\u5E94\u7528\u7A0B\u5E8F\u3002"},
- {"appletpanel.loaded", "\u5DF2\u52A0\u8F7D\u5C0F\u5E94\u7528\u7A0B\u5E8F\u3002"},
- {"appletpanel.started", "\u5DF2\u542F\u52A8\u5C0F\u5E94\u7528\u7A0B\u5E8F\u3002"},
- {"appletpanel.inited", "\u5DF2\u521D\u59CB\u5316\u5C0F\u5E94\u7528\u7A0B\u5E8F\u3002"},
- {"appletpanel.stopped", "\u5DF2\u505C\u6B62\u5C0F\u5E94\u7528\u7A0B\u5E8F\u3002"},
- {"appletpanel.disposed", "\u5DF2\u5904\u7406\u5C0F\u5E94\u7528\u7A0B\u5E8F\u3002"},
- {"appletpanel.nocode", "APPLET \u6807\u8BB0\u7F3A\u5C11 CODE \u53C2\u6570\u3002"},
- {"appletpanel.notfound", "\u52A0\u8F7D: \u627E\u4E0D\u5230\u7C7B{0}\u3002"},
- {"appletpanel.nocreate", "\u52A0\u8F7D: \u65E0\u6CD5\u5B9E\u4F8B\u5316{0}\u3002"},
- {"appletpanel.noconstruct", "\u52A0\u8F7D: {0}\u4E0D\u662F\u516C\u5171\u7684, \u6216\u8005\u6CA1\u6709\u516C\u5171\u6784\u9020\u5668\u3002"},
- {"appletpanel.death", "\u5DF2\u7EC8\u6B62"},
- {"appletpanel.exception", "\u5F02\u5E38\u9519\u8BEF: {0}\u3002"},
- {"appletpanel.exception2", "\u5F02\u5E38\u9519\u8BEF: {0}: {1}\u3002"},
- {"appletpanel.error", "\u9519\u8BEF: {0}\u3002"},
- {"appletpanel.error2", "\u9519\u8BEF: {0}: {1}\u3002"},
- {"appletpanel.notloaded", "\u521D\u59CB\u5316: \u672A\u52A0\u8F7D\u5C0F\u5E94\u7528\u7A0B\u5E8F\u3002"},
- {"appletpanel.notinited", "\u542F\u52A8: \u672A\u521D\u59CB\u5316\u5C0F\u5E94\u7528\u7A0B\u5E8F\u3002"},
- {"appletpanel.notstarted", "\u505C\u6B62: \u672A\u542F\u52A8\u5C0F\u5E94\u7528\u7A0B\u5E8F\u3002"},
- {"appletpanel.notstopped", "\u9500\u6BC1: \u672A\u505C\u6B62\u5C0F\u5E94\u7528\u7A0B\u5E8F\u3002"},
- {"appletpanel.notdestroyed", "\u5904\u7406: \u672A\u9500\u6BC1\u5C0F\u5E94\u7528\u7A0B\u5E8F\u3002"},
- {"appletpanel.notdisposed", "\u52A0\u8F7D: \u672A\u5904\u7406\u5C0F\u5E94\u7528\u7A0B\u5E8F\u3002"},
- {"appletpanel.bail", "\u5DF2\u4E2D\u65AD: \u79BB\u5F00\u3002"},
- {"appletpanel.filenotfound", "\u67E5\u627E\u65F6\u627E\u4E0D\u5230\u6587\u4EF6: {0}"},
- {"appletpanel.fileformat", "\u52A0\u8F7D\u65F6\u51FA\u73B0\u6587\u4EF6\u683C\u5F0F\u5F02\u5E38\u9519\u8BEF: {0}"},
- {"appletpanel.fileioexception", "\u52A0\u8F7D\u65F6\u51FA\u73B0 I/O \u5F02\u5E38\u9519\u8BEF: {0}"},
- {"appletpanel.fileexception", "\u52A0\u8F7D\u65F6\u51FA\u73B0{0}\u5F02\u5E38\u9519\u8BEF: {1}"},
- {"appletpanel.filedeath", "\u52A0\u8F7D\u65F6\u5DF2\u7EC8\u6B62{0}: {1}"},
- {"appletpanel.fileerror", "\u52A0\u8F7D\u65F6\u51FA\u73B0{0}\u9519\u8BEF: {1}"},
- {"appletpanel.badattribute.exception", "HTML \u89E3\u6790: \u5BBD\u5EA6/\u9AD8\u5EA6\u5C5E\u6027\u7684\u503C\u4E0D\u6B63\u786E"},
- {"appletillegalargumentexception.objectinputstream", "AppletObjectInputStream \u9700\u8981\u975E\u7A7A\u52A0\u8F7D\u5668"},
- {"appletprops.title", "AppletViewer \u5C5E\u6027"},
- {"appletprops.label.http.server", "Http \u4EE3\u7406\u670D\u52A1\u5668:"},
- {"appletprops.label.http.proxy", "Http \u4EE3\u7406\u7AEF\u53E3:"},
- {"appletprops.label.network", "\u7F51\u7EDC\u8BBF\u95EE\u6743\u9650:"},
- {"appletprops.choice.network.item.none", "\u65E0"},
- {"appletprops.choice.network.item.applethost", "\u5C0F\u5E94\u7528\u7A0B\u5E8F\u4E3B\u673A"},
- {"appletprops.choice.network.item.unrestricted", "\u4E0D\u53D7\u9650\u5236"},
- {"appletprops.label.class", "\u7C7B\u8BBF\u95EE\u6743\u9650:"},
- {"appletprops.choice.class.item.restricted", "\u53D7\u9650\u5236"},
- {"appletprops.choice.class.item.unrestricted", "\u4E0D\u53D7\u9650\u5236"},
- {"appletprops.label.unsignedapplet", "\u5141\u8BB8\u672A\u7B7E\u540D\u5C0F\u5E94\u7528\u7A0B\u5E8F:"},
- {"appletprops.choice.unsignedapplet.no", "\u5426"},
- {"appletprops.choice.unsignedapplet.yes", "\u662F"},
- {"appletprops.button.apply", "\u5E94\u7528"},
- {"appletprops.button.cancel", "\u53D6\u6D88"},
- {"appletprops.button.reset", "\u91CD\u7F6E"},
- {"appletprops.apply.exception", "\u65E0\u6CD5\u4FDD\u5B58\u5C5E\u6027: {0}"},
- /* 4066432 */
- {"appletprops.title.invalidproxy", "\u6761\u76EE\u65E0\u6548"},
- {"appletprops.label.invalidproxy", "\u4EE3\u7406\u7AEF\u53E3\u5FC5\u987B\u662F\u4E00\u4E2A\u6B63\u6574\u6570\u503C\u3002"},
- {"appletprops.button.ok", "\u786E\u5B9A"},
- /* end 4066432 */
- {"appletprops.prop.store", "AppletViewer \u7684\u7528\u6237\u7279\u5B9A\u5C5E\u6027"},
- {"appletsecurityexception.checkcreateclassloader", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: \u7C7B\u52A0\u8F7D\u5668"},
- {"appletsecurityexception.checkaccess.thread", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: \u7EBF\u7A0B"},
- {"appletsecurityexception.checkaccess.threadgroup", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: \u7EBF\u7A0B\u7EC4: {0}"},
- {"appletsecurityexception.checkexit", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: \u9000\u51FA: {0}"},
- {"appletsecurityexception.checkexec", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: \u6267\u884C: {0}"},
- {"appletsecurityexception.checklink", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: \u94FE\u63A5: {0}"},
- {"appletsecurityexception.checkpropsaccess", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: \u5C5E\u6027"},
- {"appletsecurityexception.checkpropsaccess.key", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: \u5C5E\u6027\u8BBF\u95EE{0}"},
- {"appletsecurityexception.checkread.exception1", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: {0}, {1}"},
- {"appletsecurityexception.checkread.exception2", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: file.read: {0}"},
- {"appletsecurityexception.checkread", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: file.read: {0} == {1}"},
- {"appletsecurityexception.checkwrite.exception", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: {0}, {1}"},
- {"appletsecurityexception.checkwrite", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: file.write: {0} == {1}"},
- {"appletsecurityexception.checkread.fd", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: fd.read"},
- {"appletsecurityexception.checkwrite.fd", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: fd.write"},
- {"appletsecurityexception.checklisten", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: socket.listen: {0}"},
- {"appletsecurityexception.checkaccept", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: socket.accept: {0}:{1}"},
- {"appletsecurityexception.checkconnect.networknone", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: socket.connect: {0}->{1}"},
- {"appletsecurityexception.checkconnect.networkhost1", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: \u65E0\u6CD5\u8FDE\u63A5\u5230\u6E90\u81EA{1}\u7684{0}\u3002"},
- {"appletsecurityexception.checkconnect.networkhost2", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: \u65E0\u6CD5\u89E3\u6790\u4E3B\u673A{0}\u6216{1}\u7684 IP\u3002"},
- {"appletsecurityexception.checkconnect.networkhost3", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: \u65E0\u6CD5\u89E3\u6790\u4E3B\u673A{0}\u7684 IP\u3002\u8BF7\u53C2\u9605 trustProxy \u5C5E\u6027\u3002"},
- {"appletsecurityexception.checkconnect", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: \u8FDE\u63A5: {0}->{1}"},
- {"appletsecurityexception.checkpackageaccess", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: \u65E0\u6CD5\u8BBF\u95EE\u7A0B\u5E8F\u5305: {0}"},
- {"appletsecurityexception.checkpackagedefinition", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: \u65E0\u6CD5\u5B9A\u4E49\u7A0B\u5E8F\u5305: {0}"},
- {"appletsecurityexception.cannotsetfactory", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: \u65E0\u6CD5\u8BBE\u7F6E\u5DE5\u5382"},
- {"appletsecurityexception.checkmemberaccess", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: \u68C0\u67E5\u6210\u5458\u8BBF\u95EE\u6743\u9650"},
- {"appletsecurityexception.checkgetprintjob", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: getPrintJob"},
- {"appletsecurityexception.checksystemclipboardaccess", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: getSystemClipboard"},
- {"appletsecurityexception.checkawteventqueueaccess", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: getEventQueue"},
- {"appletsecurityexception.checksecurityaccess", "\u5B89\u5168\u5F02\u5E38\u9519\u8BEF: \u5B89\u5168\u64CD\u4F5C: {0}"},
- {"appletsecurityexception.getsecuritycontext.unknown", "\u7C7B\u52A0\u8F7D\u5668\u7C7B\u578B\u672A\u77E5\u3002\u65E0\u6CD5\u68C0\u67E5 getContext"},
- {"appletsecurityexception.checkread.unknown", "\u7C7B\u52A0\u8F7D\u5668\u7C7B\u578B\u672A\u77E5\u3002\u65E0\u6CD5\u4E3A\u68C0\u67E5\u8BFB\u53D6\u6743\u9650{0}\u800C\u8FDB\u884C\u68C0\u67E5"},
- {"appletsecurityexception.checkconnect.unknown", "\u7C7B\u52A0\u8F7D\u5668\u7C7B\u578B\u672A\u77E5\u3002\u65E0\u6CD5\u4E3A\u68C0\u67E5\u8FDE\u63A5\u800C\u8FDB\u884C\u68C0\u67E5"},
- };
-
- return temp;
- }
-}
--- a/src/java.desktop/share/classes/sun/applet/resources/MsgAppletViewer_zh_TW.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,203 +0,0 @@
-/*
- * Copyright (c) 1996, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-package sun.applet.resources;
-
-import java.util.ListResourceBundle;
-
-public class MsgAppletViewer_zh_TW extends ListResourceBundle {
-
- public Object[][] getContents() {
- Object[][] temp = new Object[][] {
- {"textframe.button.dismiss", "\u95DC\u9589"},
- {"appletviewer.tool.title", "Applet \u6AA2\u8996\u5668: {0}"},
- {"appletviewer.menu.applet", "Applet"},
- {"appletviewer.menuitem.restart", "\u91CD\u65B0\u555F\u52D5"},
- {"appletviewer.menuitem.reload", "\u91CD\u65B0\u8F09\u5165"},
- {"appletviewer.menuitem.stop", "\u505C\u6B62"},
- {"appletviewer.menuitem.save", "\u5132\u5B58..."},
- {"appletviewer.menuitem.start", "\u555F\u52D5"},
- {"appletviewer.menuitem.clone", "\u8907\u88FD..."},
- {"appletviewer.menuitem.tag", "\u6A19\u8A18..."},
- {"appletviewer.menuitem.info", "\u8CC7\u8A0A..."},
- {"appletviewer.menuitem.edit", "\u7DE8\u8F2F"},
- {"appletviewer.menuitem.encoding", "\u5B57\u5143\u7DE8\u78BC"},
- {"appletviewer.menuitem.print", "\u5217\u5370..."},
- {"appletviewer.menuitem.props", "\u5C6C\u6027..."},
- {"appletviewer.menuitem.close", "\u95DC\u9589"},
- {"appletviewer.menuitem.quit", "\u7D50\u675F"},
- {"appletviewer.label.hello", "\u60A8\u597D..."},
- {"appletviewer.status.start", "\u6B63\u5728\u555F\u52D5 Applet..."},
- {"appletviewer.appletsave.filedialogtitle","\u5C07 Applet \u5E8F\u5217\u5316\u70BA\u6A94\u6848"},
- {"appletviewer.appletsave.err1", "\u5C07 {0} \u5E8F\u5217\u5316\u70BA {1}"},
- {"appletviewer.appletsave.err2", "\u5728 appletSave \u4E2D: {0}"},
- {"appletviewer.applettag", "\u986F\u793A\u7684\u6A19\u8A18"},
- {"appletviewer.applettag.textframe", "Applet HTML \u6A19\u8A18"},
- {"appletviewer.appletinfo.applet", "-- \u7121 Applet \u8CC7\u8A0A --"},
- {"appletviewer.appletinfo.param", "-- \u7121\u53C3\u6578\u8CC7\u8A0A --"},
- {"appletviewer.appletinfo.textframe", "Applet \u8CC7\u8A0A"},
- {"appletviewer.appletprint.fail", "\u5217\u5370\u5931\u6557\u3002"},
- {"appletviewer.appletprint.finish", "\u5B8C\u6210\u5217\u5370\u3002"},
- {"appletviewer.appletprint.cancel", "\u5217\u5370\u53D6\u6D88\u3002"},
- {"appletviewer.appletencoding", "\u5B57\u5143\u7DE8\u78BC: {0}"},
- {"appletviewer.parse.warning.requiresname", "\u8B66\u544A: <\u53C3\u6578\u540D\u7A31=... \u503C=...> \u6A19\u8A18\u9700\u8981\u540D\u7A31\u5C6C\u6027\u3002"},
- {"appletviewer.parse.warning.paramoutside", "\u8B66\u544A: <param> \u6A19\u8A18\u5728 <applet> ... </applet> \u4E4B\u5916\u3002"},
- {"appletviewer.parse.warning.applet.requirescode", "\u8B66\u544A: <applet> \u6A19\u8A18\u9700\u8981\u4EE3\u78BC\u5C6C\u6027\u3002"},
- {"appletviewer.parse.warning.applet.requiresheight", "\u8B66\u544A: <applet> \u6A19\u8A18\u9700\u8981\u9AD8\u5EA6\u5C6C\u6027\u3002"},
- {"appletviewer.parse.warning.applet.requireswidth", "\u8B66\u544A: <applet> \u6A19\u8A18\u9700\u8981\u5BEC\u5EA6\u5C6C\u6027\u3002"},
- {"appletviewer.parse.warning.object.requirescode", "\u8B66\u544A: <object> \u6A19\u8A18\u9700\u8981\u4EE3\u78BC\u5C6C\u6027\u3002"},
- {"appletviewer.parse.warning.object.requiresheight", "\u8B66\u544A: <object> \u6A19\u8A18\u9700\u8981\u9AD8\u5EA6\u5C6C\u6027\u3002"},
- {"appletviewer.parse.warning.object.requireswidth", "\u8B66\u544A: <object> \u6A19\u8A18\u9700\u8981\u5BEC\u5EA6\u5C6C\u6027\u3002"},
- {"appletviewer.parse.warning.embed.requirescode", "\u8B66\u544A: <embed> \u6A19\u8A18\u9700\u8981\u4EE3\u78BC\u5C6C\u6027\u3002"},
- {"appletviewer.parse.warning.embed.requiresheight", "\u8B66\u544A: <embed> \u6A19\u8A18\u9700\u8981\u9AD8\u5EA6\u5C6C\u6027\u3002"},
- {"appletviewer.parse.warning.embed.requireswidth", "\u8B66\u544A: <embed> \u6A19\u8A18\u9700\u8981\u5BEC\u5EA6\u5C6C\u6027\u3002"},
- {"appletviewer.parse.warning.appnotLongersupported", "\u8B66\u544A: \u4E0D\u518D\u652F\u63F4 <app> \u6A19\u8A18\uFF0C\u8ACB\u6539\u7528 <applet>:"},
- {"appletviewer.deprecated", "\u8B66\u544A: \u5DF2\u4E0D\u518D\u4F7F\u7528 Applet API \u548C AppletViewer\u3002"},
- {"appletviewer.usage", "\u7528\u6CD5: appletviewer <options> url(s)\n\n\u5176\u4E2D\u7684 <options> \u5305\u62EC:\n -encoding <encoding> \u6307\u5B9A HTML \u6A94\u6848\u4F7F\u7528\u7684\u5B57\u5143\u7DE8\u78BC\n -J<runtime flag> \u5C07\u5F15\u6578\u50B3\u9001\u81F3 Java \u89E3\u8B6F\u5668\n\n-J \u9078\u9805\u4E0D\u662F\u6A19\u6E96\u9078\u9805\uFF0C\u82E5\u6709\u8B8A\u66F4\u4E0D\u53E6\u884C\u901A\u77E5\u3002"},
- {"appletviewer.main.err.unsupportedopt", "\u4E0D\u652F\u63F4\u7684\u9078\u9805: {0}"},
- {"appletviewer.main.err.unrecognizedarg", "\u7121\u6CD5\u8FA8\u8B58\u7684\u5F15\u6578: {0}"},
- {"appletviewer.main.err.dupoption", "\u91CD\u8907\u4F7F\u7528\u9078\u9805: {0}"},
- {"appletviewer.main.err.inputfile", "\u672A\u6307\u5B9A\u8F38\u5165\u6A94\u6848\u3002"},
- {"appletviewer.main.err.badurl", "\u932F\u8AA4\u7684 URL: {0} ( {1} )"},
- {"appletviewer.main.err.io", "\u8B80\u53D6\u6642\u767C\u751F I/O \u7570\u5E38\u72C0\u6CC1: {0}"},
- {"appletviewer.main.err.readablefile", "\u78BA\u8A8D {0} \u70BA\u6A94\u6848\u4E14\u53EF\u8B80\u53D6\u3002"},
- {"appletviewer.main.err.correcturl", "{0} \u662F\u5426\u70BA\u6B63\u78BA\u7684 URL\uFF1F"},
- {"appletviewer.main.prop.store", "AppletViewer \u7684\u4F7F\u7528\u8005\u7279\u5B9A\u5C6C\u6027"},
- {"appletviewer.main.err.prop.cantread", "\u7121\u6CD5\u8B80\u53D6\u4F7F\u7528\u8005\u5C6C\u6027\u6A94\u6848: {0}"},
- {"appletviewer.main.err.prop.cantsave", "\u7121\u6CD5\u5132\u5B58\u4F7F\u7528\u8005\u5C6C\u6027\u6A94\u6848: {0}"},
- {"appletviewer.main.warn.nosecmgr", "\u8B66\u544A: \u505C\u7528\u5B89\u5168\u529F\u80FD\u3002"},
- {"appletviewer.main.debug.cantfinddebug", "\u627E\u4E0D\u5230\u9664\u932F\u7A0B\u5F0F\uFF01"},
- {"appletviewer.main.debug.cantfindmain", "\u5728\u9664\u932F\u7A0B\u5F0F\u4E2D\u627E\u4E0D\u5230\u4E3B\u8981\u65B9\u6CD5\uFF01"},
- {"appletviewer.main.debug.exceptionindebug", "\u9664\u932F\u7A0B\u5F0F\u767C\u751F\u7570\u5E38\u72C0\u6CC1\uFF01"},
- {"appletviewer.main.debug.cantaccess", "\u7121\u6CD5\u5B58\u53D6\u9664\u932F\u7A0B\u5F0F\uFF01"},
- {"appletviewer.main.nosecmgr", "\u8B66\u544A: \u672A\u5B89\u88DD SecurityManager\uFF01"},
- {"appletviewer.main.warning", "\u8B66\u544A: \u672A\u555F\u52D5 Applet\u3002\u8ACB\u78BA\u8A8D\u8F38\u5165\u5305\u542B <applet> \u6A19\u8A18\u3002"},
- {"appletviewer.main.warn.prop.overwrite", "\u8B66\u544A: \u4F9D\u7167\u4F7F\u7528\u8005\u8981\u6C42\uFF0C\u66AB\u6642\u8986\u5BEB\u7CFB\u7D71\u5C6C\u6027: \u7D22\u5F15\u9375: {0} \u820A\u503C: {1} \u65B0\u503C: {2}"},
- {"appletviewer.main.warn.cantreadprops", "\u8B66\u544A: \u7121\u6CD5\u8B80\u53D6 AppletViewer \u5C6C\u6027\u6A94\u6848: {0} \u4F7F\u7528\u9810\u8A2D\u503C\u3002"},
- {"appletioexception.loadclass.throw.interrupted", "\u985E\u5225\u8F09\u5165\u4E2D\u65B7: {0}"},
- {"appletioexception.loadclass.throw.notloaded", "\u672A\u8F09\u5165\u985E\u5225: {0}"},
- {"appletclassloader.loadcode.verbose", "\u958B\u555F {0} \u7684\u4E32\u6D41\u4EE5\u53D6\u5F97 {1}"},
- {"appletclassloader.filenotfound", "\u5C0B\u627E {0} \u6642\u627E\u4E0D\u5230\u6A94\u6848"},
- {"appletclassloader.fileformat", "\u8F09\u5165\u6642\u767C\u751F\u6A94\u6848\u683C\u5F0F\u7570\u5E38\u72C0\u6CC1: {0}"},
- {"appletclassloader.fileioexception", "\u8F09\u5165\u6642\u767C\u751F I/O \u7570\u5E38\u72C0\u6CC1: {0}"},
- {"appletclassloader.fileexception", "\u8F09\u5165\u6642\u767C\u751F {0} \u7570\u5E38\u72C0\u6CC1: {1}"},
- {"appletclassloader.filedeath", "\u8F09\u5165\u6642\u522A\u9664 {0}: {1}"},
- {"appletclassloader.fileerror", "\u8F09\u5165\u6642\u767C\u751F {0} \u932F\u8AA4: {1}"},
- {"appletclassloader.findclass.verbose.openstream", "\u958B\u555F {0} \u7684\u4E32\u6D41\u4EE5\u53D6\u5F97 {1}"},
- {"appletclassloader.getresource.verbose.forname", "AppletClassLoader.getResource \u7684\u540D\u7A31: {0}"},
- {"appletclassloader.getresource.verbose.found", "\u627E\u5230\u8CC7\u6E90: {0} \u4F5C\u70BA\u7CFB\u7D71\u8CC7\u6E90"},
- {"appletclassloader.getresourceasstream.verbose", "\u627E\u5230\u8CC7\u6E90: {0} \u4F5C\u70BA\u7CFB\u7D71\u8CC7\u6E90"},
- {"appletpanel.runloader.err", "\u7269\u4EF6\u6216\u4EE3\u78BC\u53C3\u6578\uFF01"},
- {"appletpanel.runloader.exception", "\u9084\u539F\u5E8F\u5217\u5316 {0} \u6642\u767C\u751F\u7570\u5E38\u72C0\u6CC1"},
- {"appletpanel.destroyed", "\u5DF2\u640D\u6BC0 Applet\u3002"},
- {"appletpanel.loaded", "\u5DF2\u8F09\u5165 Applet\u3002"},
- {"appletpanel.started", "\u5DF2\u555F\u7528 Applet\u3002"},
- {"appletpanel.inited", "\u5DF2\u8D77\u59CB Applet\u3002"},
- {"appletpanel.stopped", "\u5DF2\u505C\u6B62 Applet\u3002"},
- {"appletpanel.disposed", "\u5DF2\u8655\u7F6E Applet\u3002"},
- {"appletpanel.nocode", "APPLET \u6A19\u8A18\u907A\u6F0F CODE \u53C3\u6578\u3002"},
- {"appletpanel.notfound", "\u8F09\u5165: \u627E\u4E0D\u5230\u985E\u5225 {0}\u3002"},
- {"appletpanel.nocreate", "\u8F09\u5165: \u7121\u6CD5\u5EFA\u7ACB {0}\u3002"},
- {"appletpanel.noconstruct", "\u8F09\u5165: {0} \u975E\u516C\u7528\u6216\u6C92\u6709\u516C\u7528\u5EFA\u69CB\u5B50\u3002"},
- {"appletpanel.death", "\u5DF2\u522A\u9664"},
- {"appletpanel.exception", "\u7570\u5E38\u72C0\u6CC1: {0}\u3002"},
- {"appletpanel.exception2", "\u7570\u5E38\u72C0\u6CC1: {0}: {1}\u3002"},
- {"appletpanel.error", "\u932F\u8AA4: {0}\u3002"},
- {"appletpanel.error2", "\u932F\u8AA4: {0}: {1}\u3002"},
- {"appletpanel.notloaded", "\u8D77\u59CB: \u672A\u8F09\u5165 Applet\u3002"},
- {"appletpanel.notinited", "\u555F\u52D5: \u672A\u8D77\u59CB Applet\u3002"},
- {"appletpanel.notstarted", "\u505C\u6B62: \u672A\u555F\u52D5 Applet\u3002"},
- {"appletpanel.notstopped", "\u640D\u6BC0: \u672A\u505C\u6B62 Applet\u3002"},
- {"appletpanel.notdestroyed", "\u8655\u7F6E: \u672A\u640D\u6BC0 Applet\u3002"},
- {"appletpanel.notdisposed", "\u8F09\u5165: \u672A\u8655\u7F6E Applet\u3002"},
- {"appletpanel.bail", "\u5DF2\u4E2D\u65B7: \u6B63\u5728\u7D50\u675F\u3002"},
- {"appletpanel.filenotfound", "\u5C0B\u627E {0} \u6642\u627E\u4E0D\u5230\u6A94\u6848"},
- {"appletpanel.fileformat", "\u8F09\u5165\u6642\u767C\u751F\u6A94\u6848\u683C\u5F0F\u7570\u5E38\u72C0\u6CC1: {0}"},
- {"appletpanel.fileioexception", "\u8F09\u5165\u6642\u767C\u751F I/O \u7570\u5E38\u72C0\u6CC1: {0}"},
- {"appletpanel.fileexception", "\u8F09\u5165\u6642\u767C\u751F {0} \u7570\u5E38\u72C0\u6CC1: {1}"},
- {"appletpanel.filedeath", "\u8F09\u5165\u6642\u522A\u9664 {0}: {1}"},
- {"appletpanel.fileerror", "\u8F09\u5165\u6642\u767C\u751F {0} \u932F\u8AA4: {1}"},
- {"appletpanel.badattribute.exception", "HTML \u5256\u6790: \u5BEC\u5EA6/\u9AD8\u5EA6\u5C6C\u6027\u7684\u503C\u4E0D\u6B63\u78BA"},
- {"appletillegalargumentexception.objectinputstream", "AppletObjectInputStream \u9700\u8981\u975E\u7A7A\u503C\u8F09\u5165\u5668"},
- {"appletprops.title", "AppletViewer \u5C6C\u6027"},
- {"appletprops.label.http.server", "Http \u4EE3\u7406\u4E3B\u6A5F\u4F3A\u670D\u5668:"},
- {"appletprops.label.http.proxy", "Http \u4EE3\u7406\u4E3B\u6A5F\u9023\u63A5\u57E0:"},
- {"appletprops.label.network", "\u7DB2\u8DEF\u5B58\u53D6:"},
- {"appletprops.choice.network.item.none", "\u7121"},
- {"appletprops.choice.network.item.applethost", "Applet \u4E3B\u6A5F"},
- {"appletprops.choice.network.item.unrestricted", "\u4E0D\u53D7\u9650\u5236"},
- {"appletprops.label.class", "\u985E\u5225\u5B58\u53D6:"},
- {"appletprops.choice.class.item.restricted", "\u53D7\u9650\u5236"},
- {"appletprops.choice.class.item.unrestricted", "\u4E0D\u53D7\u9650\u5236"},
- {"appletprops.label.unsignedapplet", "\u5141\u8A31\u672A\u7C3D\u7F72\u7684 Applet:"},
- {"appletprops.choice.unsignedapplet.no", "\u5426"},
- {"appletprops.choice.unsignedapplet.yes", "\u662F"},
- {"appletprops.button.apply", "\u5957\u7528"},
- {"appletprops.button.cancel", "\u53D6\u6D88"},
- {"appletprops.button.reset", "\u91CD\u8A2D"},
- {"appletprops.apply.exception", "\u7121\u6CD5\u5132\u5B58\u5C6C\u6027: {0}"},
- /* 4066432 */
- {"appletprops.title.invalidproxy", "\u7121\u6548\u7684\u9805\u76EE"},
- {"appletprops.label.invalidproxy", "\u4EE3\u7406\u4E3B\u6A5F\u9023\u63A5\u57E0\u5FC5\u9808\u662F\u6B63\u6574\u6578\u503C\u3002"},
- {"appletprops.button.ok", "\u78BA\u5B9A"},
- /* end 4066432 */
- {"appletprops.prop.store", "AppletViewer \u7684\u4F7F\u7528\u8005\u7279\u5B9A\u5C6C\u6027"},
- {"appletsecurityexception.checkcreateclassloader", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: classloader"},
- {"appletsecurityexception.checkaccess.thread", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: thread"},
- {"appletsecurityexception.checkaccess.threadgroup", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: threadgroup: {0}"},
- {"appletsecurityexception.checkexit", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: exit: {0}"},
- {"appletsecurityexception.checkexec", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: exec: {0}"},
- {"appletsecurityexception.checklink", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: link: {0}"},
- {"appletsecurityexception.checkpropsaccess", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: \u5C6C\u6027"},
- {"appletsecurityexception.checkpropsaccess.key", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: \u5C6C\u6027\u5B58\u53D6 {0}"},
- {"appletsecurityexception.checkread.exception1", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: {0}\uFF0C{1}"},
- {"appletsecurityexception.checkread.exception2", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: file.read: {0}"},
- {"appletsecurityexception.checkread", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: file.read: {0} == {1}"},
- {"appletsecurityexception.checkwrite.exception", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: {0}\uFF0C{1}"},
- {"appletsecurityexception.checkwrite", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: file.write: {0} == {1}"},
- {"appletsecurityexception.checkread.fd", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: fd.read"},
- {"appletsecurityexception.checkwrite.fd", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: fd.write"},
- {"appletsecurityexception.checklisten", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: socket.listen: {0}"},
- {"appletsecurityexception.checkaccept", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: socket.accept: {0}:{1}"},
- {"appletsecurityexception.checkconnect.networknone", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: socket.connect: {0}->{1}"},
- {"appletsecurityexception.checkconnect.networkhost1", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: \u7121\u6CD5\u5F9E\u4F86\u6E90 {1} \u9023\u7DDA\u81F3 {0}\u3002"},
- {"appletsecurityexception.checkconnect.networkhost2", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: \u7121\u6CD5\u89E3\u6790\u4E3B\u6A5F {0} \u6216 {1} \u7684 IP\u3002"},
- {"appletsecurityexception.checkconnect.networkhost3", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: \u7121\u6CD5\u89E3\u6790\u4E3B\u6A5F {0} \u7684 IP\u3002\u8ACB\u53C3\u95B1 trustProxy \u5C6C\u6027\u3002"},
- {"appletsecurityexception.checkconnect", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: connect: {0}->{1}"},
- {"appletsecurityexception.checkpackageaccess", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: \u7121\u6CD5\u5B58\u53D6\u5957\u88DD\u7A0B\u5F0F: {0}"},
- {"appletsecurityexception.checkpackagedefinition", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: \u7121\u6CD5\u5B9A\u7FA9\u5957\u88DD\u7A0B\u5F0F: {0}"},
- {"appletsecurityexception.cannotsetfactory", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: \u7121\u6CD5\u8A2D\u5B9A\u8655\u7406\u7AD9"},
- {"appletsecurityexception.checkmemberaccess", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: \u6AA2\u67E5\u6210\u54E1\u5B58\u53D6"},
- {"appletsecurityexception.checkgetprintjob", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: getPrintJob"},
- {"appletsecurityexception.checksystemclipboardaccess", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: getSystemClipboard"},
- {"appletsecurityexception.checkawteventqueueaccess", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: getEventQueue"},
- {"appletsecurityexception.checksecurityaccess", "\u5B89\u5168\u7570\u5E38\u72C0\u6CC1: \u5B89\u5168\u4F5C\u696D: {0}"},
- {"appletsecurityexception.getsecuritycontext.unknown", "\u4E0D\u660E\u7684\u985E\u5225\u8F09\u5165\u5668\u985E\u578B\u3002\u7121\u6CD5\u6AA2\u67E5 getContext"},
- {"appletsecurityexception.checkread.unknown", "\u4E0D\u660E\u7684\u985E\u5225\u8F09\u5165\u5668\u985E\u578B\u3002\u7121\u6CD5\u6AA2\u67E5 read {0}"},
- {"appletsecurityexception.checkconnect.unknown", "\u4E0D\u660E\u7684\u985E\u5225\u8F09\u5165\u5668\u985E\u578B\u3002\u7121\u6CD5\u6AA2\u67E5\u9023\u7DDA"},
- };
-
- return temp;
- }
-}
--- a/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, 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
@@ -33,40 +33,26 @@
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
+import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
-import java.awt.font.TextAttribute;
+import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.peer.ComponentPeer;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FilenameFilter;
import java.io.InputStreamReader;
-import java.io.IOException;
-import java.text.AttributedCharacterIterator;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
+import java.security.AccessController;
import java.util.Locale;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import java.util.StringTokenizer;
import java.util.TreeMap;
-import java.util.Vector;
-import java.util.concurrent.ConcurrentHashMap;
-import sun.awt.AppContext;
+
import sun.awt.DisplayChangedListener;
-import sun.awt.FontConfiguration;
import sun.awt.SunDisplayChanger;
-import sun.font.CompositeFontDescriptor;
-import sun.font.Font2D;
import sun.font.FontManager;
import sun.font.FontManagerFactory;
import sun.font.FontManagerForSGE;
-import sun.font.NativeFont;
-import java.security.AccessController;
+import sun.java2d.pipe.Region;
import sun.security.action.GetPropertyAction;
/**
@@ -389,4 +375,48 @@
return -1;
}
}
+
+ /**
+ * Returns the graphics configuration which bounds contain the given point.
+ *
+ * @param current the default configuration which is checked in the first
+ * place
+ * @param x the x coordinate of the given point
+ * @param y the y coordinate of the given point
+ * @return the graphics configuration
+ */
+ public static GraphicsConfiguration getGraphicsConfigurationAtPoint(
+ GraphicsConfiguration current, double x, double y) {
+ if (current.getBounds().contains(x, y)) {
+ return current;
+ }
+ GraphicsEnvironment env = getLocalGraphicsEnvironment();
+ for (GraphicsDevice device : env.getScreenDevices()) {
+ GraphicsConfiguration config = device.getDefaultConfiguration();
+ if (config.getBounds().contains(x, y)) {
+ return config;
+ }
+ }
+ return current;
+ }
+
+ /**
+ * Converts coordinates from the user's space to the device space using
+ * appropriate device transformation.
+ *
+ * @param x coordinate in the user space
+ * @param y coordinate in the user space
+ * @return the point which uses device space(pixels)
+ */
+ public static Point convertToDeviceSpace(double x, double y) {
+ GraphicsConfiguration gc = getLocalGraphicsEnvironment()
+ .getDefaultScreenDevice().getDefaultConfiguration();
+ gc = getGraphicsConfigurationAtPoint(gc, x, y);
+
+ AffineTransform tx = gc.getDefaultTransform();
+ x = Region.clipRound(x * tx.getScaleX());
+ y = Region.clipRound(y * tx.getScaleY());
+
+ return new Point((int) x, (int) y);
+ }
}
--- a/src/java.desktop/share/classes/sun/print/DialogOnTop.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.print;
-
-import javax.print.attribute.Attribute;
-import javax.print.attribute.PrintRequestAttribute;
-
-/*
- * An implementation class used to request the dialog be set always-on-top.
- * It needs to be read and honoured by the dialog code which will use
- * java.awt.Window.setAlwaysOnTop(true) in cases where it is supported.
- */
-public class DialogOnTop implements PrintRequestAttribute {
-
- private static final long serialVersionUID = -1901909867156076547L;
-
- long id;
-
- public DialogOnTop() {
- }
-
- public DialogOnTop(long id) {
- this.id = id;
- }
-
- public final Class<? extends Attribute> getCategory() {
- return DialogOnTop.class;
- }
-
- public long getID() {
- return id;
- }
-
- public final String getName() {
- return "dialog-on-top";
- }
-
- public String toString() {
- return "dialog-on-top";
- }
-}
--- a/src/java.desktop/share/classes/sun/print/DialogOwner.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2007, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.print;
-
-import java.awt.Dialog;
-import javax.print.attribute.Attribute;
-import javax.print.attribute.PrintRequestAttribute;
-import java.awt.Frame;
-import java.awt.Window;
-
-/**
- * Class DialogOwner is a printing attribute class that identifies
- * the window that owns the print dialog.
- *
- * <P>
- * <B>IPP Compatibility:</B> This is not an IPP attribute.
- * <P>
- *
- */
-@SuppressWarnings("serial") // JDK-implementation class
-public final class DialogOwner
- implements PrintRequestAttribute {
-
- private Window dlgOwner;
-
- /**
- * Construct a new dialog owner attribute with the given frame.
- *
- * @param frame the frame that owns the print dialog
- */
- public DialogOwner(Frame frame) {
- dlgOwner = frame;
- }
-
- /**
- * Construct a new dialog owner attribute with the given dialog.
- *
- * @param dialog the dialog that owns the print dialog
- */
- public DialogOwner(Dialog dialog) {
- dlgOwner = dialog;
- }
-
- /**
- * Returns the string table for class DialogOwner.
- */
- public Window getOwner() {
- return dlgOwner;
- }
-
-
- /**
- * Get the printing attribute class which is to be used as the "category"
- * for this printing attribute value.
- * <P>
- * For class DialogOwner the category is class
- * DialogOwner itself.
- *
- * @return Printing attribute class (category), an instance of class
- * {@link java.lang.Class java.lang.Class}.
- */
- public Class<? extends Attribute> getCategory() {
- return DialogOwner.class;
- }
-
-
- /**
- * Get the name of the category of which this attribute value is an
- * instance.
- * <P>
- * For class DialogOwner the category name is
- * {@code "dialog-owner"}.
- *
- * @return Attribute category name.
- */
- public String getName() {
- return "dialog-owner";
- }
-
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/classes/sun/print/DialogOwnerAccessor.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,47 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.print;
+
+import javax.print.attribute.standard.DialogOwner;
+
+public abstract class DialogOwnerAccessor {
+
+ public abstract long getOwnerID(DialogOwner owner);
+
+ public static DialogOwnerAccessor accessor = null;
+
+ public static void setAccessor(DialogOwnerAccessor acc) {
+ accessor = acc;
+ }
+
+ public static long getID(DialogOwner owner) {
+ if (accessor == null || owner == null) {
+ return 0;
+ } else {
+ return accessor.getOwnerID(owner);
+ }
+ }
+}
--- a/src/java.desktop/share/classes/sun/print/PrintJob2D.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/sun/print/PrintJob2D.java Wed Jun 13 11:01:25 2018 -0700
@@ -60,6 +60,7 @@
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.Destination;
import javax.print.attribute.standard.DialogTypeSelection;
+import javax.print.attribute.standard.DialogOwner;
import javax.print.attribute.standard.JobName;
import javax.print.attribute.standard.MediaSize;
import javax.print.attribute.standard.PrintQuality;
--- a/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java Wed Jun 13 11:01:25 2018 -0700
@@ -74,6 +74,7 @@
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.Destination;
import javax.print.attribute.standard.DialogTypeSelection;
+import javax.print.attribute.standard.DialogOwner;
import javax.print.attribute.standard.Fidelity;
import javax.print.attribute.standard.JobName;
import javax.print.attribute.standard.JobSheets;
@@ -830,17 +831,24 @@
int x = gcBounds.x+50;
int y = gcBounds.y+50;
ServiceDialog pageDialog;
+ boolean setOnTop = false;
if (onTop != null) {
attributes.add(onTop);
+ Window owner = onTop.getOwner();
+ if (owner != null) {
+ w = owner; // use the one specifed by the app
+ } else if (DialogOwnerAccessor.getID(onTop) == 0) {
+ setOnTop = true;
+ }
}
- if (w instanceof Frame) {
pageDialog = new ServiceDialog(gc, x, y, service,
DocFlavor.SERVICE_FORMATTED.PAGEABLE,
- attributes,(Frame)w);
- } else {
- pageDialog = new ServiceDialog(gc, x, y, service,
- DocFlavor.SERVICE_FORMATTED.PAGEABLE,
- attributes, (Dialog)w);
+ attributes, w);
+ if (setOnTop) {
+ try {
+ pageDialog.setAlwaysOnTop(true);
+ } catch (SecurityException e) {
+ }
}
Rectangle dlgBounds = pageDialog.getBounds();
@@ -988,8 +996,7 @@
* (it might be set in java.awt.PrintJob.printDialog)
*/
if (attributes.get(DialogOwner.class) == null) {
- attributes.add(w instanceof Frame ? new DialogOwner((Frame)w) :
- new DialogOwner((Dialog)w));
+ attributes.add(new DialogOwner(w));
}
} else {
grCfg = GraphicsEnvironment.getLocalGraphicsEnvironment().
@@ -2581,7 +2588,7 @@
}
}
- private DialogOnTop onTop = null;
+ private DialogOwner onTop = null;
private long parentWindowID = 0L;
@@ -2597,9 +2604,9 @@
private void setParentWindowID(PrintRequestAttributeSet attrs) {
parentWindowID = 0L;
- onTop = (DialogOnTop)attrs.get(DialogOnTop.class);
+ onTop = (DialogOwner)attrs.get(DialogOwner.class);
if (onTop != null) {
- parentWindowID = onTop.getID();
+ parentWindowID = DialogOwnerAccessor.getID(onTop);
}
}
}
--- a/src/java.desktop/share/classes/sun/print/ServiceDialog.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/sun/print/ServiceDialog.java Wed Jun 13 11:01:25 2018 -0700
@@ -38,6 +38,7 @@
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Toolkit;
+import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
@@ -136,33 +137,13 @@
int defaultServiceIndex,
DocFlavor flavor,
PrintRequestAttributeSet attributes,
- Dialog dialog)
+ Window window)
{
- super(dialog, getMsg("dialog.printtitle"), true, gc);
+ super(window, getMsg("dialog.printtitle"), Dialog.DEFAULT_MODALITY_TYPE, gc);
initPrintDialog(x, y, services, defaultServiceIndex,
flavor, attributes);
}
-
-
- /**
- * Constructor for the "standard" print dialog (containing all relevant
- * tabs)
- */
- public ServiceDialog(GraphicsConfiguration gc,
- int x, int y,
- PrintService[] services,
- int defaultServiceIndex,
- DocFlavor flavor,
- PrintRequestAttributeSet attributes,
- Frame frame)
- {
- super(frame, getMsg("dialog.printtitle"), true, gc);
- initPrintDialog(x, y, services, defaultServiceIndex,
- flavor, attributes);
- }
-
-
/**
* Initialize print dialog.
*/
@@ -184,8 +165,22 @@
isAWT = true;
}
- if (attributes.get(DialogOnTop.class) != null) {
- setAlwaysOnTop(true);
+ if (attributes.get(DialogOwner.class) != null) {
+ DialogOwner owner = (DialogOwner)attributes.get(DialogOwner.class);
+ /* When the ServiceDialog is constructed the caller of the
+ * constructor checks for this attribute and if it specifies a
+ * window then it will use that in the constructor instead of
+ * inferring one from keyboard focus.
+ * In this case the owner of the dialog is the same as that
+ * specified in the attribute and we do not need to set the
+ * on top property
+ */
+ if ((getOwner() == null) || (owner.getOwner() != getOwner())) {
+ try {
+ setAlwaysOnTop(true);
+ } catch (SecurityException e) {
+ }
+ }
}
Container c = getContentPane();
c.setLayout(new BorderLayout());
@@ -244,28 +239,13 @@
PrintService ps,
DocFlavor flavor,
PrintRequestAttributeSet attributes,
- Dialog dialog)
+ Window window)
{
- super(dialog, getMsg("dialog.pstitle"), true, gc);
+ super(window, getMsg("dialog.pstitle"), Dialog.DEFAULT_MODALITY_TYPE, gc);
initPageDialog(x, y, ps, flavor, attributes);
}
/**
- * Constructor for the solitary "page setup" dialog
- */
- public ServiceDialog(GraphicsConfiguration gc,
- int x, int y,
- PrintService ps,
- DocFlavor flavor,
- PrintRequestAttributeSet attributes,
- Frame frame)
- {
- super(frame, getMsg("dialog.pstitle"), true, gc);
- initPageDialog(x, y, ps, flavor, attributes);
- }
-
-
- /**
* Initialize "page setup" dialog
*/
void initPageDialog(int x, int y,
@@ -278,8 +258,15 @@
this.asOriginal = attributes;
this.asCurrent = new HashPrintRequestAttributeSet(attributes);
- if (attributes.get(DialogOnTop.class) != null) {
- setAlwaysOnTop(true);
+ if (attributes.get(DialogOwner.class) != null) {
+ /* See comments in same block in initPrintDialog */
+ DialogOwner owner = (DialogOwner)attributes.get(DialogOwner.class);
+ if ((getOwner() == null) || (owner.getOwner() != getOwner())) {
+ try {
+ setAlwaysOnTop(true);
+ } catch (SecurityException e) {
+ }
+ }
}
Container c = getContentPane();
--- a/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2015, 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
@@ -52,6 +52,7 @@
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
+import sun.java2d.pipe.Region;
import sun.print.ProxyPrintGraphics;
import sun.awt.*;
import java.io.*;
@@ -2241,35 +2242,6 @@
}
/**
- *
- * Returns the graphics configuration which bounds contain the given
- * point
- *
- * @param current the default configuration which is checked in the first place
- * @param x the x coordinate of the given point
- * @param y the y coordinate of the given point
- * @return the graphics configuration
- */
- public static GraphicsConfiguration getGraphicsConfigurationAtPoint(GraphicsConfiguration current, double x, double y) {
-
- if (current.getBounds().contains(x, y)) {
- return current;
- }
-
- GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
- GraphicsDevice[] devices = env.getScreenDevices();
-
- for (GraphicsDevice device : devices) {
- GraphicsConfiguration config = device.getDefaultConfiguration();
- if (config.getBounds().contains(x, y)) {
- return config;
- }
- }
-
- return current;
- }
-
- /**
* Used to listen to "blit" repaints in RepaintManager.
*/
public interface RepaintListener {
--- a/src/java.desktop/share/legal/freetype.md Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/legal/freetype.md Wed Jun 13 11:01:25 2018 -0700
@@ -1,4 +1,4 @@
-## The FreeType Project: Freetype v2.9
+## The FreeType Project: Freetype v2.9.1
### FreeType Notice
--- a/src/java.desktop/share/native/libfreetype/UPDATING.txt Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/UPDATING.txt Wed Jun 13 11:01:25 2018 -0700
@@ -12,6 +12,8 @@
Before attempting compilation be sure to diff the JDK copy and the freetype copy
of src/java.desktop/share/native/libfreetype/include/freetype/config/ftoption.h
and re-apply the same edits made for the JDK option file.
+Also modules the JDK does not include must be commented out in
+src/java.desktop/share/native/libfreetype/include/freetype/config/ftmodule.h.
Notably JDK is not using GZIP or LZW or BDF support which are on by default
for the freetype distribution.
If you don't make the edits the build will fail due to not copying the relevant
--- a/src/java.desktop/share/native/libfreetype/include/freetype/config/ftconfig.h Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/config/ftconfig.h Wed Jun 13 11:01:25 2018 -0700
@@ -422,9 +422,9 @@
#endif /* !FT_BASE_DEF */
- /* When compiling FreeType as a DLL, some systems/compilers need a */
- /* special attribute in front OR after the return type of function */
- /* declarations. */
+ /* When compiling FreeType as a DLL or DSO with hidden visibility */
+ /* some systems/compilers need a special attribute in front OR after */
+ /* the return type of function declarations. */
/* */
/* Two macros are used within the FreeType source code to define */
/* exported library functions: FT_EXPORT and FT_EXPORT_DEF. */
@@ -455,19 +455,28 @@
/* */
#ifndef FT_EXPORT
-#ifdef __cplusplus
+#ifdef FT2_BUILD_LIBRARY
+
+#if defined( _WIN32 ) && ( defined( _DLL ) || defined( DLL_EXPORT ) )
+#define FT_EXPORT( x ) __declspec( dllexport ) x
+#elif defined( __GNUC__ ) && __GNUC__ >= 4
+#define FT_EXPORT( x ) __attribute__(( visibility( "default" ) )) x
+#elif defined( __cplusplus )
#define FT_EXPORT( x ) extern "C" x
#else
#define FT_EXPORT( x ) extern x
#endif
-#ifdef _MSC_VER
-#undef FT_EXPORT
-#ifdef _DLL
-#define FT_EXPORT( x ) __declspec( dllexport ) x
#else
+
+#if defined( FT2_DLLIMPORT )
#define FT_EXPORT( x ) __declspec( dllimport ) x
+#elif defined( __cplusplus )
+#define FT_EXPORT( x ) extern "C" x
+#else
+#define FT_EXPORT( x ) extern x
#endif
+
#endif
#endif /* !FT_EXPORT */
--- a/src/java.desktop/share/native/libfreetype/include/freetype/config/ftoption.h Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/config/ftoption.h Wed Jun 13 11:01:25 2018 -0700
@@ -82,6 +82,10 @@
/* to control the various font drivers and modules. The controllable */
/* properties are listed in the section @properties. */
/* */
+ /* You have to undefine this configuration option on platforms that lack */
+ /* the concept of environment variables (and thus don't have the */
+ /* `getenv' function), for example Windows CE. */
+ /* */
/* `FREETYPE_PROPERTIES' has the following syntax form (broken here into */
/* multiple lines for better readability). */
/* */
--- a/src/java.desktop/share/native/libfreetype/include/freetype/freetype.h Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/freetype.h Wed Jun 13 11:01:25 2018 -0700
@@ -724,11 +724,12 @@
/* Same as FT_ENCODING_JOHAB. Deprecated. */
/* */
/* <Note> */
- /* By default, FreeType automatically synthesizes a Unicode charmap */
- /* for PostScript fonts, using their glyph name dictionaries. */
- /* However, it also reports the encodings defined explicitly in the */
- /* font file, for the cases when they are needed, with the Adobe */
- /* values as well. */
+ /* By default, FreeType enables a Unicode charmap and tags it with */
+ /* FT_ENCODING_UNICODE when it is either provided or can be generated */
+ /* from PostScript glyph name dictionaries in the font file. */
+ /* All other encodings are considered legacy and tagged only if */
+ /* explicitly defined in the font file. Otherwise, FT_ENCODING_NONE */
+ /* is used. */
/* */
/* FT_ENCODING_NONE is set by the BDF and PCF drivers if the charmap */
/* is neither Unicode nor ISO-8859-1 (otherwise it is set to */
@@ -1175,7 +1176,7 @@
/* interpolating between them. Supported formats are Adobe MM, */
/* TrueType GX, and OpenType variation fonts. */
/* */
- /* See the multiple-masters specific API for details. */
+ /* See section @multiple_masters for API details. */
/* */
/* FT_FACE_FLAG_GLYPH_NAMES :: */
/* The face contains glyph names, which can be retrieved using */
@@ -2062,8 +2063,8 @@
/* data :: A pointer to the parameter data. */
/* */
/* <Note> */
- /* The ID and function of parameters are driver-specific. See the */
- /* various FT_PARAM_TAG_XXX flags for more information. */
+ /* The ID and function of parameters are driver-specific. See */
+ /* section @parameter_tags for more information. */
/* */
typedef struct FT_Parameter_
{
@@ -2833,6 +2834,10 @@
/* since its glyph indices are not listed in any of the font's */
/* charmaps. */
/* */
+ /* If no active cmap is set up (i.e., `face->charmap' is zero), the */
+ /* call to @FT_Get_Char_Index is omitted, and the function behaves */
+ /* identically to @FT_Load_Glyph. */
+ /* */
FT_EXPORT( FT_Error )
FT_Load_Char( FT_Face face,
FT_ULong char_code,
@@ -3065,7 +3070,7 @@
*
* Advance widths are rounded to integer values; however, using the
* `lsb_delta' and `rsb_delta' fields of @FT_GlyphSlotRec, it is
- * possible to get fractional advance widths for sub-pixel positioning
+ * possible to get fractional advance widths for subpixel positioning
* (which is recommended to use).
*
* If configuration option AF_CONFIG_OPTION_TT_SIZE_METRICS is active,
@@ -3204,13 +3209,13 @@
/* opacity). */
/* */
/* FT_RENDER_MODE_LCD :: */
- /* This mode corresponds to horizontal RGB and BGR sub-pixel */
+ /* This mode corresponds to horizontal RGB and BGR subpixel */
/* displays like LCD screens. It produces 8-bit bitmaps that are */
/* 3~times the width of the original glyph outline in pixels, and */
/* which use the @FT_PIXEL_MODE_LCD mode. */
/* */
/* FT_RENDER_MODE_LCD_V :: */
- /* This mode corresponds to vertical RGB and BGR sub-pixel displays */
+ /* This mode corresponds to vertical RGB and BGR subpixel displays */
/* (like PDA screens, rotated LCD displays, etc.). It produces */
/* 8-bit bitmaps that are 3~times the height of the original */
/* glyph outline in pixels and use the @FT_PIXEL_MODE_LCD_V mode. */
@@ -4552,7 +4557,7 @@
*/
#define FREETYPE_MAJOR 2
#define FREETYPE_MINOR 9
-#define FREETYPE_PATCH 0
+#define FREETYPE_PATCH 1
/*************************************************************************/
--- a/src/java.desktop/share/native/libfreetype/include/freetype/ftdriver.h Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftdriver.h Wed Jun 13 11:01:25 2018 -0700
@@ -111,9 +111,9 @@
*
* One of the reasons to not hint horizontally is antialiasing for LCD
* screens: The pixel geometry of modern displays supplies three
- * vertical sub-pixels as the eye moves horizontally across each visible
+ * vertical subpixels as the eye moves horizontally across each visible
* pixel. On devices where we can be certain this characteristic is
- * present a rasterizer can take advantage of the sub-pixels to add
+ * present a rasterizer can take advantage of the subpixels to add
* increments of weight. In Western writing systems this turns out to
* be the more critical direction anyway; the weights and spacing of
* vertical stems (see above) are central to Armenian, Cyrillic, Greek,
--- a/src/java.desktop/share/native/libfreetype/include/freetype/ftgasp.h Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftgasp.h Wed Jun 13 11:01:25 2018 -0700
@@ -29,6 +29,9 @@
#endif
+FT_BEGIN_HEADER
+
+
/***************************************************************************
*
* @section:
@@ -131,6 +134,8 @@
/* */
+FT_END_HEADER
+
#endif /* FTGASP_H_ */
--- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftobjs.h Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftobjs.h Wed Jun 13 11:01:25 2018 -0700
@@ -155,7 +155,7 @@
} FT_CMapRec;
- /* typecase any pointer to a charmap handle */
+ /* typecast any pointer to a charmap handle */
#define FT_CMAP( x ) ( (FT_CMap)( x ) )
/* obvious macros */
--- a/src/java.desktop/share/native/libfreetype/src/autofit/afblue.c Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/src/autofit/afblue.c Wed Jun 13 11:01:25 2018 -0700
@@ -166,6 +166,10 @@
'\0',
'\xE2', '\xB4', '\x84', ' ', '\xE2', '\xB4', '\x85', ' ', '\xE2', '\xB4', '\x94', ' ', '\xE2', '\xB4', '\x95', ' ', '\xE2', '\xB4', '\x81', ' ', '\xE2', '\xB4', '\x82', ' ', '\xE2', '\xB4', '\x98', ' ', '\xE2', '\xB4', '\x9D', /* ⴄ ⴅ ⴔ ⴕ ⴁ ⴂ ⴘ ⴝ */
'\0',
+ '\xE1', '\xB2', '\x9C', ' ', '\xE1', '\xB2', '\x9F', ' ', '\xE1', '\xB2', '\xB3', ' ', '\xE1', '\xB2', '\xB8', ' ', '\xE1', '\xB2', '\x92', ' ', '\xE1', '\xB2', '\x94', ' ', '\xE1', '\xB2', '\x9D', ' ', '\xE1', '\xB2', '\xB4', /* Ნ Ჟ Ჳ Ჸ Გ Ე Ო Ჴ */
+ '\0',
+ '\xE1', '\xB2', '\x98', ' ', '\xE1', '\xB2', '\xB2', ' ', '\xE1', '\xB2', '\x9D', ' ', '\xE1', '\xB2', '\xA9', ' ', '\xE1', '\xB2', '\x9B', ' ', '\xE1', '\xB2', '\xA8', ' ', '\xE1', '\xB2', '\xAF', ' ', '\xE1', '\xB2', '\xBD', /* Ი Ჲ Ო Ჩ Მ Შ Ჯ Ჽ */
+ '\0',
'\xE2', '\xB0', '\x85', ' ', '\xE2', '\xB0', '\x94', ' ', '\xE2', '\xB0', '\xAA', ' ', '\xE2', '\xB0', '\x84', ' ', '\xE2', '\xB0', '\x82', ' ', '\xE2', '\xB0', '\x8A', ' ', '\xE2', '\xB0', '\xAB', ' ', '\xE2', '\xB0', '\x8B', /* Ⰵ Ⱄ Ⱚ Ⰴ Ⰲ Ⰺ Ⱛ Ⰻ */
'\0',
'\xE2', '\xB0', '\x85', ' ', '\xE2', '\xB0', '\x84', ' ', '\xE2', '\xB0', '\x82', ' ', '\xE2', '\xB0', '\xAA', ' ', '\xE2', '\xB0', '\x9E', ' ', '\xE2', '\xB0', '\xA1', ' ', '\xE2', '\xB0', '\x8A', ' ', '\xE2', '\xB0', '\x94', /* Ⰵ Ⰴ Ⰲ Ⱚ Ⱎ Ⱑ Ⰺ Ⱄ */
@@ -539,6 +543,8 @@
{ AF_BLUE_STRING_GEORGIAN_MKHEDRULI_BOTTOM, 0 },
{ AF_BLUE_STRING_GEORGIAN_MKHEDRULI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP },
{ AF_BLUE_STRING_GEORGIAN_MKHEDRULI_DESCENDER, 0 },
+ { AF_BLUE_STRING_GEORGIAN_MTAVRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
+ { AF_BLUE_STRING_GEORGIAN_MTAVRULI_BOTTOM, 0 },
{ AF_BLUE_STRING_MAX, 0 },
{ AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
{ AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_BOTTOM, 0 },
--- a/src/java.desktop/share/native/libfreetype/src/autofit/afblue.dat Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/src/autofit/afblue.dat Wed Jun 13 11:01:25 2018 -0700
@@ -242,6 +242,11 @@
AF_BLUE_STRING_GEORGIAN_NUSKHURI_DESCENDER
"ⴄ ⴅ ⴔ ⴕ ⴁ ⴂ ⴘ ⴝ"
+ AF_BLUE_STRING_GEORGIAN_MTAVRULI_TOP
+ "Ნ Ჟ Ჳ Ჸ Გ Ე Ო Ჴ"
+ AF_BLUE_STRING_GEORGIAN_MTAVRULI_BOTTOM
+ "Ი Ჲ Ო Ჩ Მ Შ Ჯ Ჽ"
+
AF_BLUE_STRING_GLAGOLITIC_CAPITAL_TOP
"Ⰵ Ⱄ Ⱚ Ⰴ Ⰲ Ⰺ Ⱛ Ⰻ"
AF_BLUE_STRING_GLAGOLITIC_CAPITAL_BOTTOM
@@ -795,13 +800,14 @@
{ AF_BLUE_STRING_ETHIOPIC_BOTTOM, 0 }
{ AF_BLUE_STRING_MAX, 0 }
- // blue zones for Mtavruli are missing (not yet defined in Unicode)
AF_BLUE_STRINGSET_GEOR
{ AF_BLUE_STRING_GEORGIAN_MKHEDRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
AF_BLUE_PROPERTY_LATIN_X_HEIGHT }
{ AF_BLUE_STRING_GEORGIAN_MKHEDRULI_BOTTOM, 0 }
{ AF_BLUE_STRING_GEORGIAN_MKHEDRULI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }
{ AF_BLUE_STRING_GEORGIAN_MKHEDRULI_DESCENDER, 0 }
+ { AF_BLUE_STRING_GEORGIAN_MTAVRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
+ { AF_BLUE_STRING_GEORGIAN_MTAVRULI_BOTTOM, 0 }
{ AF_BLUE_STRING_MAX, 0 }
AF_BLUE_STRINGSET_GEOK
--- a/src/java.desktop/share/native/libfreetype/src/autofit/afblue.h Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/src/autofit/afblue.h Wed Jun 13 11:01:25 2018 -0700
@@ -147,119 +147,121 @@
AF_BLUE_STRING_GEORGIAN_NUSKHURI_BOTTOM = 1813,
AF_BLUE_STRING_GEORGIAN_NUSKHURI_ASCENDER = 1845,
AF_BLUE_STRING_GEORGIAN_NUSKHURI_DESCENDER = 1877,
- AF_BLUE_STRING_GLAGOLITIC_CAPITAL_TOP = 1909,
- AF_BLUE_STRING_GLAGOLITIC_CAPITAL_BOTTOM = 1941,
- AF_BLUE_STRING_GLAGOLITIC_SMALL_TOP = 1973,
- AF_BLUE_STRING_GLAGOLITIC_SMALL_BOTTOM = 2005,
- AF_BLUE_STRING_GOTHIC_TOP = 2037,
- AF_BLUE_STRING_GOTHIC_BOTTOM = 2077,
- AF_BLUE_STRING_GREEK_CAPITAL_TOP = 2097,
- AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM = 2118,
- AF_BLUE_STRING_GREEK_SMALL_BETA_TOP = 2136,
- AF_BLUE_STRING_GREEK_SMALL = 2154,
- AF_BLUE_STRING_GREEK_SMALL_DESCENDER = 2178,
- AF_BLUE_STRING_GUJARATI_TOP = 2202,
- AF_BLUE_STRING_GUJARATI_BOTTOM = 2234,
- AF_BLUE_STRING_GUJARATI_ASCENDER = 2266,
- AF_BLUE_STRING_GUJARATI_DESCENDER = 2316,
- AF_BLUE_STRING_GUJARATI_DIGIT_TOP = 2349,
- AF_BLUE_STRING_GURMUKHI_BASE = 2369,
- AF_BLUE_STRING_GURMUKHI_HEAD = 2401,
- AF_BLUE_STRING_GURMUKHI_TOP = 2433,
- AF_BLUE_STRING_GURMUKHI_BOTTOM = 2465,
- AF_BLUE_STRING_GURMUKHI_DIGIT_TOP = 2497,
- AF_BLUE_STRING_HEBREW_TOP = 2517,
- AF_BLUE_STRING_HEBREW_BOTTOM = 2541,
- AF_BLUE_STRING_HEBREW_DESCENDER = 2559,
- AF_BLUE_STRING_KANNADA_TOP = 2574,
- AF_BLUE_STRING_KANNADA_BOTTOM = 2618,
- AF_BLUE_STRING_KAYAH_LI_TOP = 2650,
- AF_BLUE_STRING_KAYAH_LI_BOTTOM = 2674,
- AF_BLUE_STRING_KAYAH_LI_ASCENDER = 2694,
- AF_BLUE_STRING_KAYAH_LI_DESCENDER = 2702,
- AF_BLUE_STRING_KAYAH_LI_LARGE_DESCENDER = 2714,
- AF_BLUE_STRING_KHMER_TOP = 2735,
- AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP = 2759,
- AF_BLUE_STRING_KHMER_BOTTOM = 2799,
- AF_BLUE_STRING_KHMER_DESCENDER = 2831,
- AF_BLUE_STRING_KHMER_LARGE_DESCENDER = 2865,
- AF_BLUE_STRING_KHMER_SYMBOLS_WAXING_TOP = 2952,
- AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM = 2960,
- AF_BLUE_STRING_LAO_TOP = 2968,
- AF_BLUE_STRING_LAO_BOTTOM = 3000,
- AF_BLUE_STRING_LAO_ASCENDER = 3032,
- AF_BLUE_STRING_LAO_LARGE_ASCENDER = 3048,
- AF_BLUE_STRING_LAO_DESCENDER = 3060,
- AF_BLUE_STRING_LATIN_CAPITAL_TOP = 3084,
- AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM = 3100,
- AF_BLUE_STRING_LATIN_SMALL_F_TOP = 3116,
- AF_BLUE_STRING_LATIN_SMALL_TOP = 3130,
- AF_BLUE_STRING_LATIN_SMALL_BOTTOM = 3146,
- AF_BLUE_STRING_LATIN_SMALL_DESCENDER = 3162,
- AF_BLUE_STRING_LATIN_SUBS_CAPITAL_TOP = 3172,
- AF_BLUE_STRING_LATIN_SUBS_CAPITAL_BOTTOM = 3192,
- AF_BLUE_STRING_LATIN_SUBS_SMALL_F_TOP = 3212,
- AF_BLUE_STRING_LATIN_SUBS_SMALL = 3232,
- AF_BLUE_STRING_LATIN_SUBS_SMALL_DESCENDER = 3268,
- AF_BLUE_STRING_LATIN_SUPS_CAPITAL_TOP = 3288,
- AF_BLUE_STRING_LATIN_SUPS_CAPITAL_BOTTOM = 3319,
- AF_BLUE_STRING_LATIN_SUPS_SMALL_F_TOP = 3348,
- AF_BLUE_STRING_LATIN_SUPS_SMALL = 3374,
- AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER = 3399,
- AF_BLUE_STRING_LISU_TOP = 3410,
- AF_BLUE_STRING_LISU_BOTTOM = 3442,
- AF_BLUE_STRING_MALAYALAM_TOP = 3474,
- AF_BLUE_STRING_MALAYALAM_BOTTOM = 3518,
- AF_BLUE_STRING_MYANMAR_TOP = 3550,
- AF_BLUE_STRING_MYANMAR_BOTTOM = 3582,
- AF_BLUE_STRING_MYANMAR_ASCENDER = 3614,
- AF_BLUE_STRING_MYANMAR_DESCENDER = 3642,
- AF_BLUE_STRING_NKO_TOP = 3674,
- AF_BLUE_STRING_NKO_BOTTOM = 3698,
- AF_BLUE_STRING_NKO_SMALL_TOP = 3713,
- AF_BLUE_STRING_NKO_SMALL_BOTTOM = 3722,
- AF_BLUE_STRING_OL_CHIKI = 3734,
- AF_BLUE_STRING_OLD_TURKIC_TOP = 3758,
- AF_BLUE_STRING_OLD_TURKIC_BOTTOM = 3773,
- AF_BLUE_STRING_OSAGE_CAPITAL_TOP = 3793,
- AF_BLUE_STRING_OSAGE_CAPITAL_BOTTOM = 3833,
- AF_BLUE_STRING_OSAGE_CAPITAL_DESCENDER = 3863,
- AF_BLUE_STRING_OSAGE_SMALL_TOP = 3878,
- AF_BLUE_STRING_OSAGE_SMALL_BOTTOM = 3918,
- AF_BLUE_STRING_OSAGE_SMALL_ASCENDER = 3958,
- AF_BLUE_STRING_OSAGE_SMALL_DESCENDER = 3983,
- AF_BLUE_STRING_OSMANYA_TOP = 3998,
- AF_BLUE_STRING_OSMANYA_BOTTOM = 4038,
- AF_BLUE_STRING_SAURASHTRA_TOP = 4078,
- AF_BLUE_STRING_SAURASHTRA_BOTTOM = 4110,
- AF_BLUE_STRING_SHAVIAN_TOP = 4130,
- AF_BLUE_STRING_SHAVIAN_BOTTOM = 4140,
- AF_BLUE_STRING_SHAVIAN_DESCENDER = 4165,
- AF_BLUE_STRING_SHAVIAN_SMALL_TOP = 4175,
- AF_BLUE_STRING_SHAVIAN_SMALL_BOTTOM = 4210,
- AF_BLUE_STRING_SINHALA_TOP = 4225,
- AF_BLUE_STRING_SINHALA_BOTTOM = 4257,
- AF_BLUE_STRING_SINHALA_DESCENDER = 4289,
- AF_BLUE_STRING_SUNDANESE_TOP = 4333,
- AF_BLUE_STRING_SUNDANESE_BOTTOM = 4357,
- AF_BLUE_STRING_SUNDANESE_DESCENDER = 4389,
- AF_BLUE_STRING_TAI_VIET_TOP = 4397,
- AF_BLUE_STRING_TAI_VIET_BOTTOM = 4417,
- AF_BLUE_STRING_TAMIL_TOP = 4429,
- AF_BLUE_STRING_TAMIL_BOTTOM = 4461,
- AF_BLUE_STRING_TELUGU_TOP = 4493,
- AF_BLUE_STRING_TELUGU_BOTTOM = 4521,
- AF_BLUE_STRING_THAI_TOP = 4549,
- AF_BLUE_STRING_THAI_BOTTOM = 4573,
- AF_BLUE_STRING_THAI_ASCENDER = 4601,
- AF_BLUE_STRING_THAI_LARGE_ASCENDER = 4613,
- AF_BLUE_STRING_THAI_DESCENDER = 4625,
- AF_BLUE_STRING_THAI_LARGE_DESCENDER = 4641,
- AF_BLUE_STRING_THAI_DIGIT_TOP = 4649,
- AF_BLUE_STRING_TIFINAGH = 4661,
- AF_BLUE_STRING_VAI_TOP = 4693,
- AF_BLUE_STRING_VAI_BOTTOM = 4725,
- af_blue_1_1 = 4756,
+ AF_BLUE_STRING_GEORGIAN_MTAVRULI_TOP = 1909,
+ AF_BLUE_STRING_GEORGIAN_MTAVRULI_BOTTOM = 1941,
+ AF_BLUE_STRING_GLAGOLITIC_CAPITAL_TOP = 1973,
+ AF_BLUE_STRING_GLAGOLITIC_CAPITAL_BOTTOM = 2005,
+ AF_BLUE_STRING_GLAGOLITIC_SMALL_TOP = 2037,
+ AF_BLUE_STRING_GLAGOLITIC_SMALL_BOTTOM = 2069,
+ AF_BLUE_STRING_GOTHIC_TOP = 2101,
+ AF_BLUE_STRING_GOTHIC_BOTTOM = 2141,
+ AF_BLUE_STRING_GREEK_CAPITAL_TOP = 2161,
+ AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM = 2182,
+ AF_BLUE_STRING_GREEK_SMALL_BETA_TOP = 2200,
+ AF_BLUE_STRING_GREEK_SMALL = 2218,
+ AF_BLUE_STRING_GREEK_SMALL_DESCENDER = 2242,
+ AF_BLUE_STRING_GUJARATI_TOP = 2266,
+ AF_BLUE_STRING_GUJARATI_BOTTOM = 2298,
+ AF_BLUE_STRING_GUJARATI_ASCENDER = 2330,
+ AF_BLUE_STRING_GUJARATI_DESCENDER = 2380,
+ AF_BLUE_STRING_GUJARATI_DIGIT_TOP = 2413,
+ AF_BLUE_STRING_GURMUKHI_BASE = 2433,
+ AF_BLUE_STRING_GURMUKHI_HEAD = 2465,
+ AF_BLUE_STRING_GURMUKHI_TOP = 2497,
+ AF_BLUE_STRING_GURMUKHI_BOTTOM = 2529,
+ AF_BLUE_STRING_GURMUKHI_DIGIT_TOP = 2561,
+ AF_BLUE_STRING_HEBREW_TOP = 2581,
+ AF_BLUE_STRING_HEBREW_BOTTOM = 2605,
+ AF_BLUE_STRING_HEBREW_DESCENDER = 2623,
+ AF_BLUE_STRING_KANNADA_TOP = 2638,
+ AF_BLUE_STRING_KANNADA_BOTTOM = 2682,
+ AF_BLUE_STRING_KAYAH_LI_TOP = 2714,
+ AF_BLUE_STRING_KAYAH_LI_BOTTOM = 2738,
+ AF_BLUE_STRING_KAYAH_LI_ASCENDER = 2758,
+ AF_BLUE_STRING_KAYAH_LI_DESCENDER = 2766,
+ AF_BLUE_STRING_KAYAH_LI_LARGE_DESCENDER = 2778,
+ AF_BLUE_STRING_KHMER_TOP = 2799,
+ AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP = 2823,
+ AF_BLUE_STRING_KHMER_BOTTOM = 2863,
+ AF_BLUE_STRING_KHMER_DESCENDER = 2895,
+ AF_BLUE_STRING_KHMER_LARGE_DESCENDER = 2929,
+ AF_BLUE_STRING_KHMER_SYMBOLS_WAXING_TOP = 3016,
+ AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM = 3024,
+ AF_BLUE_STRING_LAO_TOP = 3032,
+ AF_BLUE_STRING_LAO_BOTTOM = 3064,
+ AF_BLUE_STRING_LAO_ASCENDER = 3096,
+ AF_BLUE_STRING_LAO_LARGE_ASCENDER = 3112,
+ AF_BLUE_STRING_LAO_DESCENDER = 3124,
+ AF_BLUE_STRING_LATIN_CAPITAL_TOP = 3148,
+ AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM = 3164,
+ AF_BLUE_STRING_LATIN_SMALL_F_TOP = 3180,
+ AF_BLUE_STRING_LATIN_SMALL_TOP = 3194,
+ AF_BLUE_STRING_LATIN_SMALL_BOTTOM = 3210,
+ AF_BLUE_STRING_LATIN_SMALL_DESCENDER = 3226,
+ AF_BLUE_STRING_LATIN_SUBS_CAPITAL_TOP = 3236,
+ AF_BLUE_STRING_LATIN_SUBS_CAPITAL_BOTTOM = 3256,
+ AF_BLUE_STRING_LATIN_SUBS_SMALL_F_TOP = 3276,
+ AF_BLUE_STRING_LATIN_SUBS_SMALL = 3296,
+ AF_BLUE_STRING_LATIN_SUBS_SMALL_DESCENDER = 3332,
+ AF_BLUE_STRING_LATIN_SUPS_CAPITAL_TOP = 3352,
+ AF_BLUE_STRING_LATIN_SUPS_CAPITAL_BOTTOM = 3383,
+ AF_BLUE_STRING_LATIN_SUPS_SMALL_F_TOP = 3412,
+ AF_BLUE_STRING_LATIN_SUPS_SMALL = 3438,
+ AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER = 3463,
+ AF_BLUE_STRING_LISU_TOP = 3474,
+ AF_BLUE_STRING_LISU_BOTTOM = 3506,
+ AF_BLUE_STRING_MALAYALAM_TOP = 3538,
+ AF_BLUE_STRING_MALAYALAM_BOTTOM = 3582,
+ AF_BLUE_STRING_MYANMAR_TOP = 3614,
+ AF_BLUE_STRING_MYANMAR_BOTTOM = 3646,
+ AF_BLUE_STRING_MYANMAR_ASCENDER = 3678,
+ AF_BLUE_STRING_MYANMAR_DESCENDER = 3706,
+ AF_BLUE_STRING_NKO_TOP = 3738,
+ AF_BLUE_STRING_NKO_BOTTOM = 3762,
+ AF_BLUE_STRING_NKO_SMALL_TOP = 3777,
+ AF_BLUE_STRING_NKO_SMALL_BOTTOM = 3786,
+ AF_BLUE_STRING_OL_CHIKI = 3798,
+ AF_BLUE_STRING_OLD_TURKIC_TOP = 3822,
+ AF_BLUE_STRING_OLD_TURKIC_BOTTOM = 3837,
+ AF_BLUE_STRING_OSAGE_CAPITAL_TOP = 3857,
+ AF_BLUE_STRING_OSAGE_CAPITAL_BOTTOM = 3897,
+ AF_BLUE_STRING_OSAGE_CAPITAL_DESCENDER = 3927,
+ AF_BLUE_STRING_OSAGE_SMALL_TOP = 3942,
+ AF_BLUE_STRING_OSAGE_SMALL_BOTTOM = 3982,
+ AF_BLUE_STRING_OSAGE_SMALL_ASCENDER = 4022,
+ AF_BLUE_STRING_OSAGE_SMALL_DESCENDER = 4047,
+ AF_BLUE_STRING_OSMANYA_TOP = 4062,
+ AF_BLUE_STRING_OSMANYA_BOTTOM = 4102,
+ AF_BLUE_STRING_SAURASHTRA_TOP = 4142,
+ AF_BLUE_STRING_SAURASHTRA_BOTTOM = 4174,
+ AF_BLUE_STRING_SHAVIAN_TOP = 4194,
+ AF_BLUE_STRING_SHAVIAN_BOTTOM = 4204,
+ AF_BLUE_STRING_SHAVIAN_DESCENDER = 4229,
+ AF_BLUE_STRING_SHAVIAN_SMALL_TOP = 4239,
+ AF_BLUE_STRING_SHAVIAN_SMALL_BOTTOM = 4274,
+ AF_BLUE_STRING_SINHALA_TOP = 4289,
+ AF_BLUE_STRING_SINHALA_BOTTOM = 4321,
+ AF_BLUE_STRING_SINHALA_DESCENDER = 4353,
+ AF_BLUE_STRING_SUNDANESE_TOP = 4397,
+ AF_BLUE_STRING_SUNDANESE_BOTTOM = 4421,
+ AF_BLUE_STRING_SUNDANESE_DESCENDER = 4453,
+ AF_BLUE_STRING_TAI_VIET_TOP = 4461,
+ AF_BLUE_STRING_TAI_VIET_BOTTOM = 4481,
+ AF_BLUE_STRING_TAMIL_TOP = 4493,
+ AF_BLUE_STRING_TAMIL_BOTTOM = 4525,
+ AF_BLUE_STRING_TELUGU_TOP = 4557,
+ AF_BLUE_STRING_TELUGU_BOTTOM = 4585,
+ AF_BLUE_STRING_THAI_TOP = 4613,
+ AF_BLUE_STRING_THAI_BOTTOM = 4637,
+ AF_BLUE_STRING_THAI_ASCENDER = 4665,
+ AF_BLUE_STRING_THAI_LARGE_ASCENDER = 4677,
+ AF_BLUE_STRING_THAI_DESCENDER = 4689,
+ AF_BLUE_STRING_THAI_LARGE_DESCENDER = 4705,
+ AF_BLUE_STRING_THAI_DIGIT_TOP = 4713,
+ AF_BLUE_STRING_TIFINAGH = 4725,
+ AF_BLUE_STRING_VAI_TOP = 4757,
+ AF_BLUE_STRING_VAI_BOTTOM = 4789,
+ af_blue_1_1 = 4820,
#ifdef AF_CONFIG_OPTION_CJK
AF_BLUE_STRING_CJK_TOP = af_blue_1_1 + 1,
AF_BLUE_STRING_CJK_BOTTOM = af_blue_1_1 + 203,
@@ -336,41 +338,41 @@
AF_BLUE_STRINGSET_DSRT = 75,
AF_BLUE_STRINGSET_ETHI = 80,
AF_BLUE_STRINGSET_GEOR = 83,
- AF_BLUE_STRINGSET_GEOK = 88,
- AF_BLUE_STRINGSET_GLAG = 95,
- AF_BLUE_STRINGSET_GOTH = 100,
- AF_BLUE_STRINGSET_GREK = 103,
- AF_BLUE_STRINGSET_GUJR = 110,
- AF_BLUE_STRINGSET_GURU = 116,
- AF_BLUE_STRINGSET_HEBR = 122,
- AF_BLUE_STRINGSET_KALI = 126,
- AF_BLUE_STRINGSET_KHMR = 132,
- AF_BLUE_STRINGSET_KHMS = 138,
- AF_BLUE_STRINGSET_KNDA = 141,
- AF_BLUE_STRINGSET_LAO = 144,
- AF_BLUE_STRINGSET_LATN = 150,
- AF_BLUE_STRINGSET_LATB = 157,
- AF_BLUE_STRINGSET_LATP = 164,
- AF_BLUE_STRINGSET_LISU = 171,
- AF_BLUE_STRINGSET_MLYM = 174,
- AF_BLUE_STRINGSET_MYMR = 177,
- AF_BLUE_STRINGSET_NKOO = 182,
- AF_BLUE_STRINGSET_NONE = 187,
- AF_BLUE_STRINGSET_OLCK = 188,
- AF_BLUE_STRINGSET_ORKH = 191,
- AF_BLUE_STRINGSET_OSGE = 194,
- AF_BLUE_STRINGSET_OSMA = 202,
- AF_BLUE_STRINGSET_SAUR = 205,
- AF_BLUE_STRINGSET_SHAW = 208,
- AF_BLUE_STRINGSET_SINH = 214,
- AF_BLUE_STRINGSET_SUND = 218,
- AF_BLUE_STRINGSET_TAML = 222,
- AF_BLUE_STRINGSET_TAVT = 225,
- AF_BLUE_STRINGSET_TELU = 228,
- AF_BLUE_STRINGSET_TFNG = 231,
- AF_BLUE_STRINGSET_THAI = 234,
- AF_BLUE_STRINGSET_VAII = 242,
- af_blue_2_1 = 245,
+ AF_BLUE_STRINGSET_GEOK = 90,
+ AF_BLUE_STRINGSET_GLAG = 97,
+ AF_BLUE_STRINGSET_GOTH = 102,
+ AF_BLUE_STRINGSET_GREK = 105,
+ AF_BLUE_STRINGSET_GUJR = 112,
+ AF_BLUE_STRINGSET_GURU = 118,
+ AF_BLUE_STRINGSET_HEBR = 124,
+ AF_BLUE_STRINGSET_KALI = 128,
+ AF_BLUE_STRINGSET_KHMR = 134,
+ AF_BLUE_STRINGSET_KHMS = 140,
+ AF_BLUE_STRINGSET_KNDA = 143,
+ AF_BLUE_STRINGSET_LAO = 146,
+ AF_BLUE_STRINGSET_LATN = 152,
+ AF_BLUE_STRINGSET_LATB = 159,
+ AF_BLUE_STRINGSET_LATP = 166,
+ AF_BLUE_STRINGSET_LISU = 173,
+ AF_BLUE_STRINGSET_MLYM = 176,
+ AF_BLUE_STRINGSET_MYMR = 179,
+ AF_BLUE_STRINGSET_NKOO = 184,
+ AF_BLUE_STRINGSET_NONE = 189,
+ AF_BLUE_STRINGSET_OLCK = 190,
+ AF_BLUE_STRINGSET_ORKH = 193,
+ AF_BLUE_STRINGSET_OSGE = 196,
+ AF_BLUE_STRINGSET_OSMA = 204,
+ AF_BLUE_STRINGSET_SAUR = 207,
+ AF_BLUE_STRINGSET_SHAW = 210,
+ AF_BLUE_STRINGSET_SINH = 216,
+ AF_BLUE_STRINGSET_SUND = 220,
+ AF_BLUE_STRINGSET_TAML = 224,
+ AF_BLUE_STRINGSET_TAVT = 227,
+ AF_BLUE_STRINGSET_TELU = 230,
+ AF_BLUE_STRINGSET_TFNG = 233,
+ AF_BLUE_STRINGSET_THAI = 236,
+ AF_BLUE_STRINGSET_VAII = 244,
+ af_blue_2_1 = 247,
#ifdef AF_CONFIG_OPTION_CJK
AF_BLUE_STRINGSET_HANI = af_blue_2_1 + 0,
af_blue_2_1_1 = af_blue_2_1 + 2,
--- a/src/java.desktop/share/native/libfreetype/src/autofit/afranges.c Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/src/autofit/afranges.c Wed Jun 13 11:01:25 2018 -0700
@@ -91,7 +91,7 @@
AF_UNIRANGE_REC( 0x06E7, 0x06E8 ),
AF_UNIRANGE_REC( 0x06EA, 0x06ED ),
AF_UNIRANGE_REC( 0x08D4, 0x08E1 ),
- AF_UNIRANGE_REC( 0x08E3, 0x08FF ),
+ AF_UNIRANGE_REC( 0x08D3, 0x08FF ),
AF_UNIRANGE_REC( 0xFBB2, 0xFBC1 ),
AF_UNIRANGE_REC( 0xFE70, 0xFE70 ),
AF_UNIRANGE_REC( 0xFE72, 0xFE72 ),
@@ -163,6 +163,7 @@
AF_UNIRANGE_REC( 0x09C1, 0x09C4 ),
AF_UNIRANGE_REC( 0x09CD, 0x09CD ),
AF_UNIRANGE_REC( 0x09E2, 0x09E3 ),
+ AF_UNIRANGE_REC( 0x09FE, 0x09FE ),
AF_UNIRANGE_REC( 0, 0 )
};
@@ -190,6 +191,7 @@
{
AF_UNIRANGE_REC( 0x11100, 0x11102 ),
AF_UNIRANGE_REC( 0x11127, 0x11134 ),
+ AF_UNIRANGE_REC( 0x11146, 0x11146 ),
AF_UNIRANGE_REC( 0, 0 )
};
@@ -304,6 +306,7 @@
AF_UNIRANGE_REC( 0x0953, 0x0957 ),
AF_UNIRANGE_REC( 0x0962, 0x0963 ),
AF_UNIRANGE_REC( 0xA8E0, 0xA8F1 ),
+ AF_UNIRANGE_REC( 0xA8FF, 0xA8FF ),
AF_UNIRANGE_REC( 0, 0 )
};
@@ -338,11 +341,8 @@
const AF_Script_UniRangeRec af_geor_uniranges[] =
{
- AF_UNIRANGE_REC( 0x10D0, 0x10FF ), /* Georgian (Mkhedruli) */
-#if 0
- /* the following range is proposed for inclusion in Unicode */
- AF_UNIRANGE_REC( 0x1C90, 0x1CBF ), /* Georgian (Mtavruli) */
-#endif
+ AF_UNIRANGE_REC( 0x10D0, 0x10FF ), /* Georgian (Mkhedruli) */
+ AF_UNIRANGE_REC( 0x1C90, 0x1CBF ), /* Georgian Extended (Mtavruli) */
AF_UNIRANGE_REC( 0, 0 )
};
@@ -355,8 +355,8 @@
const AF_Script_UniRangeRec af_geok_uniranges[] =
{
/* Khutsuri */
- AF_UNIRANGE_REC( 0x10A0, 0x10CD ), /* Georgian (Asomtavruli) */
- AF_UNIRANGE_REC( 0x2D00, 0x2D2D ), /* Georgian (Nuskhuri) */
+ AF_UNIRANGE_REC( 0x10A0, 0x10CD ), /* Georgian (Asomtavruli) */
+ AF_UNIRANGE_REC( 0x2D00, 0x2D2D ), /* Georgian Supplement (Nuskhuri) */
AF_UNIRANGE_REC( 0, 0 )
};
@@ -425,6 +425,7 @@
AF_UNIRANGE_REC( 0x0AC1, 0x0AC8 ),
AF_UNIRANGE_REC( 0x0ACD, 0x0ACD ),
AF_UNIRANGE_REC( 0x0AE2, 0x0AE3 ),
+ AF_UNIRANGE_REC( 0x0AFA, 0x0AFF ),
AF_UNIRANGE_REC( 0, 0 )
};
@@ -655,7 +656,8 @@
const AF_Script_UniRangeRec af_mlym_nonbase_uniranges[] =
{
- AF_UNIRANGE_REC( 0x0D01, 0x0D01 ),
+ AF_UNIRANGE_REC( 0x0D00, 0x0D01 ),
+ AF_UNIRANGE_REC( 0x0D3B, 0x0D3C ),
AF_UNIRANGE_REC( 0x0D4D, 0x0D4E ),
AF_UNIRANGE_REC( 0x0D62, 0x0D63 ),
AF_UNIRANGE_REC( 0, 0 )
@@ -697,6 +699,7 @@
const AF_Script_UniRangeRec af_nkoo_nonbase_uniranges[] =
{
AF_UNIRANGE_REC( 0x07EB, 0x07F5 ),
+ AF_UNIRANGE_REC( 0x07FD, 0x07FD ),
AF_UNIRANGE_REC( 0, 0 )
};
@@ -856,6 +859,7 @@
const AF_Script_UniRangeRec af_telu_nonbase_uniranges[] =
{
AF_UNIRANGE_REC( 0x0C00, 0x0C00 ),
+ AF_UNIRANGE_REC( 0x0C04, 0x0C04 ),
AF_UNIRANGE_REC( 0x0C3E, 0x0C40 ),
AF_UNIRANGE_REC( 0x0C46, 0x0C56 ),
AF_UNIRANGE_REC( 0x0C62, 0x0C63 ),
@@ -1006,10 +1010,13 @@
AF_UNIRANGE_REC( 0xFE30, 0xFE4F ), /* CJK Compatibility Forms */
AF_UNIRANGE_REC( 0xFF00, 0xFFEF ), /* Halfwidth and Fullwidth Forms */
AF_UNIRANGE_REC( 0x1B000, 0x1B0FF ), /* Kana Supplement */
+ AF_UNIRANGE_REC( 0x1B100, 0x1B12F ), /* Kana Extended-A */
AF_UNIRANGE_REC( 0x1D300, 0x1D35F ), /* Tai Xuan Hing Symbols */
AF_UNIRANGE_REC( 0x20000, 0x2A6DF ), /* CJK Unified Ideographs Extension B */
AF_UNIRANGE_REC( 0x2A700, 0x2B73F ), /* CJK Unified Ideographs Extension C */
AF_UNIRANGE_REC( 0x2B740, 0x2B81F ), /* CJK Unified Ideographs Extension D */
+ AF_UNIRANGE_REC( 0x2B820, 0x2CEAF ), /* CJK Unified Ideographs Extension E */
+ AF_UNIRANGE_REC( 0x2CEB0, 0x2EBEF ), /* CJK Unified Ideographs Extension F */
AF_UNIRANGE_REC( 0x2F800, 0x2FA1F ), /* CJK Compatibility Ideographs Supplement */
AF_UNIRANGE_REC( 0, 0 )
};
--- a/src/java.desktop/share/native/libfreetype/src/autofit/afscript.h Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/src/autofit/afscript.h Wed Jun 13 11:01:25 2018 -0700
@@ -137,7 +137,7 @@
"Georgian (Mkhedruli)",
HB_SCRIPT_GEORGIAN,
HINTING_BOTTOM_TO_TOP,
- "\xE1\x83\x98 \xE1\x83\x94 \xE1\x83\x90" ) /* ი ე ა */
+ "\xE1\x83\x98 \xE1\x83\x94 \xE1\x83\x90 \xE1\xB2\xBF" ) /* ი ე ა Ი */
SCRIPT( geok, GEOK,
"Georgian (Khutsuri)",
--- a/src/java.desktop/share/native/libfreetype/src/autofit/aftypes.h Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/src/autofit/aftypes.h Wed Jun 13 11:01:25 2018 -0700
@@ -76,9 +76,9 @@
typedef struct AF_WidthRec_
{
- FT_Pos org; /* original position/width in font units */
- FT_Pos cur; /* current/scaled position/width in device sub-pixels */
- FT_Pos fit; /* current/fitted position/width in device sub-pixels */
+ FT_Pos org; /* original position/width in font units */
+ FT_Pos cur; /* current/scaled position/width in device subpixels */
+ FT_Pos fit; /* current/fitted position/width in device subpixels */
} AF_WidthRec, *AF_Width;
--- a/src/java.desktop/share/native/libfreetype/src/base/ftbitmap.c Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/src/base/ftbitmap.c Wed Jun 13 11:01:25 2018 -0700
@@ -237,7 +237,7 @@
unsigned char* out = buffer;
unsigned char* limit = bitmap->buffer + pitch * bitmap->rows;
- unsigned int delta = new_pitch - pitch;
+ unsigned int delta = new_pitch - len;
FT_MEM_ZERO( out, new_pitch * ypixels );
@@ -247,8 +247,10 @@
{
FT_MEM_COPY( out, in, len );
in += pitch;
- out += pitch;
+ out += len;
+ /* we use FT_QALLOC_MULT, which doesn't zero out the buffer; */
+ /* consequently, we have to manually zero out the remaining bytes */
FT_MEM_ZERO( out, delta );
out += delta;
}
@@ -261,14 +263,14 @@
unsigned char* out = buffer;
unsigned char* limit = bitmap->buffer + pitch * bitmap->rows;
- unsigned int delta = new_pitch - pitch;
+ unsigned int delta = new_pitch - len;
while ( in < limit )
{
FT_MEM_COPY( out, in, len );
in += pitch;
- out += pitch;
+ out += len;
FT_MEM_ZERO( out, delta );
out += delta;
--- a/src/java.desktop/share/native/libfreetype/src/base/ftlcdfil.c Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/src/base/ftlcdfil.c Wed Jun 13 11:01:25 2018 -0700
@@ -77,7 +77,7 @@
/* take care of bitmap flow */
- if ( pitch > 0 )
+ if ( pitch > 0 && height > 0 )
origin += pitch * (FT_Int)( height - 1 );
/* horizontal in-place FIR filter */
@@ -192,7 +192,7 @@
/* take care of bitmap flow */
- if ( pitch > 0 )
+ if ( pitch > 0 && height > 0 )
origin += pitch * (FT_Int)( height - 1 );
/* horizontal in-place intra-pixel filter */
--- a/src/java.desktop/share/native/libfreetype/src/base/ftoutln.c Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/src/base/ftoutln.c Wed Jun 13 11:01:25 2018 -0700
@@ -286,12 +286,13 @@
FT_TRACE5(( "FT_Outline_Decompose: Done\n", n ));
return FT_Err_Ok;
+ Invalid_Outline:
+ error = FT_THROW( Invalid_Outline );
+ /* fall through */
+
Exit:
FT_TRACE5(( "FT_Outline_Decompose: Error 0x%x\n", error ));
return error;
-
- Invalid_Outline:
- return FT_THROW( Invalid_Outline );
}
--- a/src/java.desktop/share/native/libfreetype/src/cff/cffload.c Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/src/cff/cffload.c Wed Jun 13 11:01:25 2018 -0700
@@ -1933,6 +1933,24 @@
else if ( priv->initial_random_seed == 0 )
priv->initial_random_seed = 987654321;
+ /* some sanitizing to avoid overflows later on; */
+ /* the upper limits are ad-hoc values */
+ if ( priv->blue_shift > 1000 || priv->blue_shift < 0 )
+ {
+ FT_TRACE2(( "cff_load_private_dict:"
+ " setting unlikely BlueShift value %d to default (7)\n",
+ priv->blue_shift ));
+ priv->blue_shift = 7;
+ }
+
+ if ( priv->blue_fuzz > 1000 || priv->blue_fuzz < 0 )
+ {
+ FT_TRACE2(( "cff_load_private_dict:"
+ " setting unlikely BlueFuzz value %d to default (1)\n",
+ priv->blue_fuzz ));
+ priv->blue_fuzz = 1;
+ }
+
Exit:
/* clean up */
cff_blend_clear( subfont ); /* clear blend stack */
--- a/src/java.desktop/share/native/libfreetype/src/psaux/psintrp.c Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/src/psaux/psintrp.c Wed Jun 13 11:01:25 2018 -0700
@@ -852,7 +852,8 @@
curY = ADD_INT32( curY, cf2_stack_popFixed( opStack ) );
- cf2_glyphpath_moveTo( &glyphPath, curX, curY );
+ if ( !decoder->flex_state )
+ cf2_glyphpath_moveTo( &glyphPath, curX, curY );
break;
@@ -2674,7 +2675,8 @@
curX = ADD_INT32( curX, cf2_stack_popFixed( opStack ) );
- cf2_glyphpath_moveTo( &glyphPath, curX, curY );
+ if ( !decoder->flex_state )
+ cf2_glyphpath_moveTo( &glyphPath, curX, curY );
break;
--- a/src/java.desktop/share/native/libfreetype/src/pshinter/pshglob.c Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/src/pshinter/pshglob.c Wed Jun 13 11:01:25 2018 -0700
@@ -227,8 +227,8 @@
}
- /* Re-read blue zones from the original fonts and store them into out */
- /* private structure. This function re-orders, sanitizes and */
+ /* Re-read blue zones from the original fonts and store them into our */
+ /* private structure. This function re-orders, sanitizes, and */
/* fuzz-expands the zones as well. */
static void
psh_blues_set_zones( PSH_Blues target,
--- a/src/java.desktop/share/native/libfreetype/src/sfnt/sfobjs.c Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/src/sfnt/sfobjs.c Wed Jun 13 11:01:25 2018 -0700
@@ -1144,6 +1144,8 @@
FT_Bool has_outline;
FT_Bool is_apple_sbit;
FT_Bool is_apple_sbix;
+ FT_Bool has_CBLC;
+ FT_Bool has_CBDT;
FT_Bool ignore_typographic_family = FALSE;
FT_Bool ignore_typographic_subfamily = FALSE;
@@ -1224,6 +1226,13 @@
goto Exit;
}
+ has_CBLC = !face->goto_table( face, TTAG_CBLC, stream, 0 );
+ has_CBDT = !face->goto_table( face, TTAG_CBDT, stream, 0 );
+
+ /* Ignore outlines for CBLC/CBDT fonts. */
+ if ( has_CBLC || has_CBDT )
+ has_outline = FALSE;
+
/* OpenType 1.8.2 introduced limits to this value; */
/* however, they make sense for older SFNT fonts also */
if ( face->header.Units_Per_EM < 16 ||
--- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmap.c Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmap.c Wed Jun 13 11:01:25 2018 -0700
@@ -222,10 +222,10 @@
/***** The following charmap lookup and iteration functions all *****/
/***** assume that the value `charcode' fulfills the following. *****/
/***** *****/
- /***** - For one byte characters, `charcode' is simply the *****/
+ /***** - For one-byte characters, `charcode' is simply the *****/
/***** character code. *****/
/***** *****/
- /***** - For two byte characters, `charcode' is the 2-byte *****/
+ /***** - For two-byte characters, `charcode' is the 2-byte *****/
/***** character code in big endian format. More precisely: *****/
/***** *****/
/***** (charcode >> 8) is the first byte value *****/
@@ -252,11 +252,11 @@
/* subs 518 SUBHEAD[NSUBS] sub-headers array */
/* glyph_ids 518+NSUB*8 USHORT[] glyph ID array */
/* */
- /* The `keys' table is used to map charcode high-bytes to sub-headers. */
+ /* The `keys' table is used to map charcode high bytes to sub-headers. */
/* The value of `NSUBS' is the number of sub-headers defined in the */
/* table and is computed by finding the maximum of the `keys' table. */
/* */
- /* Note that for any n, `keys[n]' is a byte offset within the `subs' */
+ /* Note that for any `n', `keys[n]' is a byte offset within the `subs' */
/* table, i.e., it is the corresponding sub-header index multiplied */
/* by 8. */
/* */
@@ -269,8 +269,8 @@
/* delta 4 SHORT see below */
/* offset 6 USHORT see below */
/* */
- /* A sub-header defines, for each high-byte, the range of valid */
- /* low-bytes within the charmap. Note that the range defined by `first' */
+ /* A sub-header defines, for each high byte, the range of valid */
+ /* low bytes within the charmap. Note that the range defined by `first' */
/* and `count' must be completely included in the interval [0..255] */
/* according to the specification. */
/* */
@@ -360,7 +360,7 @@
/* check range within 0..255 */
if ( valid->level >= FT_VALIDATE_PARANOID )
{
- if ( first_code >= 256 || first_code + code_count > 256 )
+ if ( first_code >= 256 || code_count > 256 - first_code )
FT_INVALID_DATA;
}
@@ -412,7 +412,7 @@
{
FT_UInt char_lo = (FT_UInt)( char_code & 0xFF );
FT_UInt char_hi = (FT_UInt)( char_code >> 8 );
- FT_Byte* p = table + 6; /* keys table */
+ FT_Byte* p = table + 6; /* keys table */
FT_Byte* subs = table + 518; /* subheaders table */
FT_Byte* sub;
@@ -425,8 +425,8 @@
sub = subs; /* jump to first sub-header */
/* check that the sub-header for this byte is 0, which */
- /* indicates that it is really a valid one-byte value */
- /* Otherwise, return 0 */
+ /* indicates that it is really a valid one-byte value; */
+ /* otherwise, return 0 */
/* */
p += char_lo * 2;
if ( TT_PEEK_USHORT( p ) != 0 )
@@ -445,6 +445,7 @@
if ( sub == subs )
goto Exit;
}
+
result = sub;
}
@@ -517,6 +518,13 @@
FT_UInt pos, idx;
+ if ( char_lo >= start + count && charcode <= 0xFF )
+ {
+ /* this happens only for a malformed cmap */
+ charcode = 0x100;
+ continue;
+ }
+
if ( offset == 0 )
{
if ( charcode == 0x100 )
@@ -549,19 +557,18 @@
}
}
}
+
+ /* if unsuccessful, avoid `charcode' leaving */
+ /* the current 256-character block */
+ if ( count )
+ charcode--;
}
- /* If `charcode' is <= 0xFF, retry with `charcode + 1'. If */
- /* `charcode' is 0x100 after the loop, do nothing since we have */
- /* just reached the first sub-header for two-byte character codes. */
- /* */
- /* For all other cases, we jump to the next sub-header and adjust */
- /* `charcode' accordingly. */
+ /* If `charcode' is <= 0xFF, retry with `charcode + 1'. */
+ /* Otherwise jump to the next 256-character block and retry. */
Next_SubHeader:
if ( charcode <= 0xFF )
charcode++;
- else if ( charcode == 0x100 )
- ;
else
charcode = FT_PAD_FLOOR( charcode, 0x100 ) + 0x100;
}
--- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttpost.c Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttpost.c Wed Jun 13 11:01:25 2018 -0700
@@ -473,8 +473,8 @@
/* idx :: The glyph index. */
/* */
/* <InOut> */
- /* PSname :: The address of a string pointer. Will be NULL in case */
- /* of error, otherwise it is a pointer to the glyph name. */
+ /* PSname :: The address of a string pointer. Undefined in case of */
+ /* error, otherwise it is a pointer to the glyph name. */
/* */
/* You must not modify the returned string! */
/* */
--- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttsbit.c Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttsbit.c Wed Jun 13 11:01:25 2018 -0700
@@ -1514,7 +1514,7 @@
FT_FRAME_EXIT();
if ( glyph_start == glyph_end )
- return FT_THROW( Invalid_Argument );
+ return FT_THROW( Missing_Bitmap );
if ( glyph_start > glyph_end ||
glyph_end - glyph_start < 8 ||
face->ebdt_size - strike_offset < glyph_end )
--- a/src/java.desktop/share/native/libfreetype/src/smooth/ftgrays.c Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/src/smooth/ftgrays.c Wed Jun 13 11:01:25 2018 -0700
@@ -404,7 +404,7 @@
/* need to define them to "float" or "double" when experimenting with */
/* new algorithms */
- typedef long TPos; /* sub-pixel coordinate */
+ typedef long TPos; /* subpixel coordinate */
typedef int TCoord; /* integer scanline/pixel coordinate */
typedef int TArea; /* cell areas, coordinate products */
--- a/src/java.desktop/share/native/libfreetype/src/truetype/ttgload.c Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttgload.c Wed Jun 13 11:01:25 2018 -0700
@@ -1219,7 +1219,7 @@
* Theoretically, a glyph's bytecode can toggle ClearType's
* `backward compatibility' mode, which would allow modification
* of the advance width. In reality, however, applications
- * neither allow nor expect modified advance widths if sub-pixel
+ * neither allow nor expect modified advance widths if subpixel
* rendering is active.
*
*/
@@ -2709,6 +2709,10 @@
( load_flags & FT_LOAD_NO_BITMAP ) == 0 &&
IS_DEFAULT_INSTANCE )
{
+ FT_Fixed x_scale = size->root.metrics.x_scale;
+ FT_Fixed y_scale = size->root.metrics.y_scale;
+
+
error = load_sbit_image( size, glyph, glyph_index, load_flags );
if ( FT_ERR_EQ( error, Missing_Bitmap ) )
{
@@ -2716,9 +2720,13 @@
/* if we have a bitmap-only font, return an empty glyph */
if ( !FT_IS_SCALABLE( glyph->face ) )
{
- TT_Face face = (TT_Face)glyph->face;
- FT_Short left_bearing = 0, top_bearing = 0;
- FT_UShort advance_width = 0, advance_height = 0;
+ TT_Face face = (TT_Face)glyph->face;
+
+ FT_Short left_bearing = 0;
+ FT_Short top_bearing = 0;
+
+ FT_UShort advance_width = 0;
+ FT_UShort advance_height = 0;
/* to return an empty glyph, however, we need metrics data */
@@ -2744,13 +2752,13 @@
glyph->metrics.width = 0;
glyph->metrics.height = 0;
- glyph->metrics.horiBearingX = left_bearing;
+ glyph->metrics.horiBearingX = FT_MulFix( left_bearing, x_scale );
glyph->metrics.horiBearingY = 0;
- glyph->metrics.horiAdvance = advance_width;
+ glyph->metrics.horiAdvance = FT_MulFix( advance_width, x_scale );
glyph->metrics.vertBearingX = 0;
- glyph->metrics.vertBearingY = top_bearing;
- glyph->metrics.vertAdvance = advance_height;
+ glyph->metrics.vertBearingY = FT_MulFix( top_bearing, y_scale );
+ glyph->metrics.vertAdvance = FT_MulFix( advance_height, y_scale );
glyph->format = FT_GLYPH_FORMAT_BITMAP;
glyph->bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
@@ -2781,13 +2789,11 @@
/* sanity checks: if `xxxAdvance' in the sbit metric */
/* structure isn't set, use `linearXXXAdvance' */
if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance )
- glyph->metrics.horiAdvance =
- FT_MulFix( glyph->linearHoriAdvance,
- size->metrics->x_scale );
+ glyph->metrics.horiAdvance = FT_MulFix( glyph->linearHoriAdvance,
+ x_scale );
if ( !glyph->metrics.vertAdvance && glyph->linearVertAdvance )
- glyph->metrics.vertAdvance =
- FT_MulFix( glyph->linearVertAdvance,
- size->metrics->y_scale );
+ glyph->metrics.vertAdvance = FT_MulFix( glyph->linearVertAdvance,
+ y_scale );
}
return FT_Err_Ok;
--- a/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.c Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.c Wed Jun 13 11:01:25 2018 -0700
@@ -1733,17 +1733,13 @@
/* based on the [min,def,max] values for the axis to be [-1,0,1]. */
/* Then, if there's an `avar' table, we renormalize this range. */
- FT_TRACE5(( "%d design coordinate%s:\n",
- num_coords,
- num_coords == 1 ? "" : "s" ));
-
a = mmvar->axis;
for ( i = 0; i < num_coords; i++, a++ )
{
FT_Fixed coord = coords[i];
- FT_TRACE5(( " %.5f\n", coord / 65536.0 ));
+ FT_TRACE5(( " %d: %.5f\n", i, coord / 65536.0 ));
if ( coord > a->maximum || coord < a->minimum )
{
FT_TRACE1((
@@ -2043,12 +2039,15 @@
FT_TRACE2(( "loaded\n" ));
- FT_TRACE5(( "number of GX style axes: %d\n", fvar_head.axisCount ));
+ FT_TRACE5(( "%d variation ax%s\n",
+ fvar_head.axisCount,
+ fvar_head.axisCount == 1 ? "is" : "es" ));
if ( FT_NEW( face->blend ) )
goto Exit;
- num_axes = fvar_head.axisCount;
+ num_axes = fvar_head.axisCount;
+ face->blend->num_axis = num_axes;
}
else
num_axes = face->blend->num_axis;
@@ -2142,6 +2141,10 @@
{
GX_FVar_Axis axis_rec;
+#ifdef FT_DEBUG_LEVEL_TRACE
+ int invalid = 0;
+#endif
+
if ( FT_STREAM_READ_FIELDS( fvaraxis_fields, &axis_rec ) )
goto Exit;
@@ -2162,22 +2165,31 @@
if ( a->minimum > a->def ||
a->def > a->maximum )
{
- FT_TRACE2(( "TT_Get_MM_Var:"
- " invalid \"%s\" axis record; disabling\n",
- a->name ));
-
a->minimum = a->def;
a->maximum = a->def;
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+ invalid = 1;
+#endif
}
- FT_TRACE5(( " \"%s\":"
- " minimum=%.5f, default=%.5f, maximum=%.5f,"
- " flags=0x%04X\n",
+#ifdef FT_DEBUG_LEVEL_TRACE
+ if ( i == 0 )
+ FT_TRACE5(( " idx tag "
+ /* " XXX `XXXX'" */
+ " minimum default maximum flags\n" ));
+ /* " XXXX.XXXXX XXXX.XXXXX XXXX.XXXXX 0xXXXX" */
+
+ FT_TRACE5(( " %3d `%s'"
+ " %10.5f %10.5f %10.5f 0x%04X%s\n",
+ i,
a->name,
a->minimum / 65536.0,
a->def / 65536.0,
a->maximum / 65536.0,
- *axis_flags ));
+ *axis_flags,
+ invalid ? " (invalid, disabled)" : "" ));
+#endif
a++;
axis_flags++;
@@ -2202,6 +2214,10 @@
goto Exit;
}
+ FT_TRACE5(( "%d instance%s\n",
+ fvar_head.instanceCount,
+ fvar_head.instanceCount == 1 ? "" : "s" ));
+
ns = mmvar->namedstyle;
nsc = face->blend->normalized_stylecoords;
for ( i = 0; i < fvar_head.instanceCount; i++, ns++ )
@@ -2224,6 +2240,52 @@
else
ns->psid = 0xFFFF;
+#ifdef FT_DEBUG_LEVEL_TRACE
+ {
+ SFNT_Service sfnt = (SFNT_Service)face->sfnt;
+
+ FT_String* strname = NULL;
+ FT_String* psname = NULL;
+
+ FT_ULong pos;
+
+
+ pos = FT_STREAM_POS();
+
+ if ( ns->strid != 0xFFFF )
+ {
+ (void)sfnt->get_name( face,
+ (FT_UShort)ns->strid,
+ &strname );
+ if ( strname && !ft_strcmp( strname, ".notdef" ) )
+ strname = NULL;
+ }
+
+ if ( ns->psid != 0xFFFF )
+ {
+ (void)sfnt->get_name( face,
+ (FT_UShort)ns->psid,
+ &psname );
+ if ( psname && !ft_strcmp( psname, ".notdef" ) )
+ psname = NULL;
+ }
+
+ (void)FT_STREAM_SEEK( pos );
+
+ FT_TRACE5(( " instance %d (%s%s%s, %s%s%s)\n",
+ i,
+ strname ? "name: `" : "",
+ strname ? strname : "unnamed",
+ strname ? "'" : "",
+ psname ? "PS name: `" : "",
+ psname ? psname : "no PS name",
+ psname ? "'" : "" ));
+
+ FT_FREE( strname );
+ FT_FREE( psname );
+ }
+#endif /* FT_DEBUG_LEVEL_TRACE */
+
ft_var_to_normalized( face, num_axes, ns->coords, nsc );
nsc += num_axes;
@@ -2381,11 +2443,12 @@
num_coords = mmvar->num_axis;
}
- FT_TRACE5(( "normalized design coordinates:\n" ));
+ FT_TRACE5(( "TT_Set_MM_Blend:\n"
+ " normalized design coordinates:\n" ));
for ( i = 0; i < num_coords; i++ )
{
- FT_TRACE5(( " %.5f\n", coords[i] / 65536.0 ));
+ FT_TRACE5(( " %.5f\n", coords[i] / 65536.0 ));
if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L )
{
FT_TRACE1(( "TT_Set_MM_Blend: normalized design coordinate %.5f\n"
@@ -2761,8 +2824,9 @@
}
}
- /* return value -1 indicates `no change' */
- if ( !have_diff )
+ /* return value -1 indicates `no change'; */
+ /* we can exit early if `normalizedcoords' is already computed */
+ if ( blend->normalizedcoords && !have_diff )
return -1;
if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) )
@@ -2771,6 +2835,8 @@
if ( !face->blend->avar_loaded )
ft_var_load_avar( face );
+ FT_TRACE5(( "TT_Set_Var_Design:\n"
+ " normalized design coordinates:\n" ));
ft_var_to_normalized( face, num_coords, blend->coords, normalized );
error = tt_set_mm_blend( face, mmvar->num_axis, normalized, 0 );
--- a/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.c Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.c Wed Jun 13 11:01:25 2018 -0700
@@ -2165,7 +2165,7 @@
val = ADD_LONG( distance,
exc->threshold - exc->phase + compensation ) &
-exc->period;
- val += exc->phase;
+ val = ADD_LONG( val, exc->phase );
if ( val < 0 )
val = exc->phase;
}
@@ -2174,7 +2174,7 @@
val = NEG_LONG( SUB_LONG( exc->threshold - exc->phase + compensation,
distance ) &
-exc->period );
- val -= exc->phase;
+ val = SUB_LONG( val, exc->phase );
if ( val > 0 )
val = -exc->phase;
}
@@ -2216,7 +2216,7 @@
val = ( ADD_LONG( distance,
exc->threshold - exc->phase + compensation ) /
exc->period ) * exc->period;
- val += exc->phase;
+ val = ADD_LONG( val, exc->phase );
if ( val < 0 )
val = exc->phase;
}
@@ -2225,7 +2225,7 @@
val = NEG_LONG( ( SUB_LONG( exc->threshold - exc->phase + compensation,
distance ) /
exc->period ) * exc->period );
- val -= exc->phase;
+ val = SUB_LONG( val, exc->phase );
if ( val > 0 )
val = -exc->phase;
}
@@ -2954,7 +2954,7 @@
static void
Ins_CEILING( FT_Long* args )
{
- args[0] = FT_PIX_CEIL( args[0] );
+ args[0] = FT_PIX_CEIL_LONG( args[0] );
}
@@ -3289,7 +3289,10 @@
if ( args[0] < 0 )
exc->error = FT_THROW( Bad_Argument );
else
- exc->GS.loop = args[0];
+ {
+ /* we heuristically limit the number of loops to 16 bits */
+ exc->GS.loop = args[0] > 0xFFFFL ? 0xFFFFL : args[0];
+ }
}
@@ -5782,6 +5785,7 @@
FT_F26Dot6 distance;
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
FT_F26Dot6 control_value_cutin = 0;
+ FT_F26Dot6 delta;
if ( SUBPIXEL_HINTING_INFINALITY )
@@ -5817,11 +5821,15 @@
distance = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 );
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+ delta = SUB_LONG( distance, args[1] );
+ if ( delta < 0 )
+ delta = NEG_LONG( delta );
+
/* subpixel hinting - make MSIRP respect CVT cut-in; */
- if ( SUBPIXEL_HINTING_INFINALITY &&
- exc->ignore_x_mode &&
- exc->GS.freeVector.x != 0 &&
- FT_ABS( SUB_LONG( distance, args[1] ) ) >= control_value_cutin )
+ if ( SUBPIXEL_HINTING_INFINALITY &&
+ exc->ignore_x_mode &&
+ exc->GS.freeVector.x != 0 &&
+ delta >= control_value_cutin )
distance = args[1];
#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
@@ -5869,16 +5877,18 @@
if ( SUBPIXEL_HINTING_INFINALITY &&
exc->ignore_x_mode &&
exc->GS.freeVector.x != 0 )
- distance = Round_None(
- exc,
- cur_dist,
- exc->tt_metrics.compensations[0] ) - cur_dist;
+ distance = SUB_LONG(
+ Round_None( exc,
+ cur_dist,
+ exc->tt_metrics.compensations[0] ),
+ cur_dist );
else
#endif
- distance = exc->func_round(
- exc,
- cur_dist,
- exc->tt_metrics.compensations[0] ) - cur_dist;
+ distance = SUB_LONG(
+ exc->func_round( exc,
+ cur_dist,
+ exc->tt_metrics.compensations[0] ),
+ cur_dist );
}
else
distance = 0;
@@ -5978,7 +5988,14 @@
if ( ( exc->opcode & 1 ) != 0 ) /* rounding and control cut-in flag */
{
- if ( FT_ABS( distance - org_dist ) > control_value_cutin )
+ FT_F26Dot6 delta;
+
+
+ delta = SUB_LONG( distance, org_dist );
+ if ( delta < 0 )
+ delta = NEG_LONG( delta );
+
+ if ( delta > control_value_cutin )
distance = org_dist;
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
@@ -6176,7 +6193,7 @@
minimum_distance = exc->GS.minimum_distance;
control_value_cutin = exc->GS.control_value_cutin;
point = (FT_UShort)args[0];
- cvtEntry = (FT_ULong)( args[1] + 1 );
+ cvtEntry = (FT_ULong)( ADD_LONG( args[1], 1 ) );
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
if ( SUBPIXEL_HINTING_INFINALITY &&
@@ -6259,6 +6276,9 @@
if ( exc->GS.gep0 == exc->GS.gep1 )
{
+ FT_F26Dot6 delta;
+
+
/* XXX: According to Greg Hitchcock, the following wording is */
/* the right one: */
/* */
@@ -6271,7 +6291,11 @@
/* `ttinst2.doc', version 1.66, is thus incorrect since */
/* it implies `>=' instead of `>'. */
- if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin )
+ delta = SUB_LONG( cvt_dist, org_dist );
+ if ( delta < 0 )
+ delta = NEG_LONG( delta );
+
+ if ( delta > control_value_cutin )
cvt_dist = org_dist;
}
@@ -6289,7 +6313,14 @@
exc->ignore_x_mode &&
exc->GS.gep0 == exc->GS.gep1 )
{
- if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin )
+ FT_F26Dot6 delta;
+
+
+ delta = SUB_LONG( cvt_dist, org_dist );
+ if ( delta < 0 )
+ delta = NEG_LONG( delta );
+
+ if ( delta > control_value_cutin )
cvt_dist = org_dist;
}
#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
@@ -7532,8 +7563,16 @@
return;
}
- for ( i = 0; i < num_axes; i++ )
- args[i] = coords[i] >> 2; /* convert 16.16 to 2.14 format */
+ if ( coords )
+ {
+ for ( i = 0; i < num_axes; i++ )
+ args[i] = coords[i] >> 2; /* convert 16.16 to 2.14 format */
+ }
+ else
+ {
+ for ( i = 0; i < num_axes; i++ )
+ args[i] = 0;
+ }
}
@@ -8487,8 +8526,8 @@
LNo_Error_:
FT_TRACE4(( " %d instruction%s executed\n",
- ins_counter == 1 ? "" : "s",
- ins_counter ));
+ ins_counter,
+ ins_counter == 1 ? "" : "s" ));
return FT_Err_Ok;
LErrorCodeOverflow_:
--- a/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.c Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.c Wed Jun 13 11:01:25 2018 -0700
@@ -147,7 +147,7 @@
{
#define TRICK_NAMES_MAX_CHARACTERS 19
-#define TRICK_NAMES_COUNT 23
+#define TRICK_NAMES_COUNT 26
static const char trick_names[TRICK_NAMES_COUNT]
[TRICK_NAMES_MAX_CHARACTERS + 1] =
@@ -167,12 +167,15 @@
"DFGirl-W6-WIN-BF", /* dftt-h6.ttf; version 1.00, 1993 */
"DFGothic-EB", /* DynaLab Inc. 1992-1995 */
"DFGyoSho-Lt", /* DynaLab Inc. 1992-1995 */
+ "DFHei-Md-HK-BF", /* maybe DynaLab Inc. */
"DFHSGothic-W5", /* DynaLab Inc. 1992-1995 */
"DFHSMincho-W3", /* DynaLab Inc. 1992-1995 */
"DFHSMincho-W7", /* DynaLab Inc. 1992-1995 */
"DFKaiSho-SB", /* dfkaisb.ttf */
"DFKaiShu",
+ "DFKaiShu-Md-HK-BF", /* maybe DynaLab Inc. */
"DFKai-SB", /* kaiu.ttf; version 3.00, 1998 [DFKaiShu-SB-Estd-BF] */
+ "DFMing-Bd-HK-BF", /* maybe DynaLab Inc. */
"DLC", /* dftt-m7.ttf; version 1.00, 1993 [DLCMingBold] */
/* dftt-f5.ttf; version 1.00, 1993 [DLCFongSung] */
"DLCHayMedium", /* dftt-b5.ttf; version 1.00, 1993 */
@@ -270,7 +273,7 @@
tt_check_trickyness_sfnt_ids( TT_Face face )
{
#define TRICK_SFNT_IDS_PER_FACE 3
-#define TRICK_SFNT_IDS_NUM_FACES 26
+#define TRICK_SFNT_IDS_NUM_FACES 29
static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES]
[TRICK_SFNT_IDS_PER_FACE] = {
@@ -299,6 +302,11 @@
{ 0xCE5956E9UL, 0x0000BC85UL }, /* fpgm */
{ 0x8272F416UL, 0x00000045UL } /* prep */
},
+ { /* DFHei-Md-HK-BF */
+ { 0x1257EB46UL, 0x00000350UL }, /* cvt */
+ { 0xF699D160UL, 0x0000715FUL }, /* fpgm */
+ { 0xD222F568UL, 0x000003BCUL } /* prep */
+ },
{ /* DFHSGothic-W5 */
{ 0x1262EB4EUL, 0x00000350UL }, /* cvt */
{ 0xE86A5D64UL, 0x00007940UL }, /* fpgm */
@@ -324,6 +332,16 @@
{ 0xA6E78C01UL, 0x00008998UL }, /* fpgm */
{ 0x13A42602UL, 0x0000007EUL } /* prep */
},
+ { /* DFKaiShu-Md-HK-BF */
+ { 0x11E5EAD4UL, 0x00000360UL }, /* cvt */
+ { 0x9DB282B2UL, 0x0000C06EUL }, /* fpgm */
+ { 0x53E6D7CAUL, 0x00000082UL } /* prep */
+ },
+ { /* DFMing-Bd-HK-BF */
+ { 0x1243EB18UL, 0x00000350UL }, /* cvt */
+ { 0xBA0A8C30UL, 0x000074ADUL }, /* fpgm */
+ { 0xF3D83409UL, 0x0000037BUL } /* prep */
+ },
{ /* DLCLiShu */
{ 0x07DCF546UL, 0x00000308UL }, /* cvt */
{ 0x40FE7C90UL, 0x00008E2AUL }, /* fpgm */
--- a/src/java.desktop/share/native/libfreetype/src/type1/t1load.c Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libfreetype/src/type1/t1load.c Wed Jun 13 11:01:25 2018 -0700
@@ -2493,6 +2493,24 @@
type1->encoding.num_chars = loader.num_chars;
}
+ /* some sanitizing to avoid overflows later on; */
+ /* the upper limits are ad-hoc values */
+ if ( priv->blue_shift > 1000 || priv->blue_shift < 0 )
+ {
+ FT_TRACE2(( "T1_Open_Face:"
+ " setting unlikely BlueShift value %d to default (7)\n",
+ priv->blue_shift ));
+ priv->blue_shift = 7;
+ }
+
+ if ( priv->blue_fuzz > 1000 || priv->blue_fuzz < 0 )
+ {
+ FT_TRACE2(( "T1_Open_Face:"
+ " setting unlikely BlueFuzz value %d to default (1)\n",
+ priv->blue_fuzz ));
+ priv->blue_fuzz = 1;
+ }
+
Exit:
t1_done_loader( &loader );
return error;
--- a/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c Wed Jun 13 11:01:25 2018 -0700
@@ -1762,11 +1762,6 @@
}
}
break;
-#ifdef YCCALPHA
- case JCS_YCC:
- cinfo->out_color_space = JCS_YCC;
- break;
-#endif
case JCS_YCCK:
if ((cinfo->saw_Adobe_marker) && (cinfo->Adobe_transform != 2)) {
/*
--- a/src/java.desktop/share/native/libjavajpeg/jpegdecoder.c Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/share/native/libjavajpeg/jpegdecoder.c Wed Jun 13 11:01:25 2018 -0700
@@ -569,11 +569,7 @@
/* select buffered-image mode if it is a progressive JPEG only */
buffered_mode = cinfo.buffered_image = jpeg_has_multiple_scans(&cinfo);
grayscale = (cinfo.out_color_space == JCS_GRAYSCALE);
-#ifdef YCCALPHA
- hasalpha = (cinfo.out_color_space == JCS_RGBA);
-#else
hasalpha = 0;
-#endif
/* We can ignore the return value from jpeg_read_header since
* (a) suspension is not possible with the stdio data source, and
* (nor with the Java input source)
--- a/src/java.desktop/unix/classes/sun/print/IPPPrintService.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/unix/classes/sun/print/IPPPrintService.java Wed Jun 13 11:01:25 2018 -0700
@@ -25,6 +25,8 @@
package sun.print;
+import java.awt.GraphicsEnvironment;
+import java.awt.Toolkit;
import javax.print.attribute.*;
import javax.print.attribute.standard.*;
import javax.print.DocFlavor;
@@ -1071,6 +1073,11 @@
catList.add(PrinterResolution.class);
}
+ if (GraphicsEnvironment.isHeadless() == false) {
+ catList.add(DialogOwner.class);
+ catList.add(DialogTypeSelection.class);
+ }
+
supportedCats = new Class<?>[catList.size()];
catList.toArray(supportedCats);
Class<?>[] copyCats = new Class<?>[supportedCats.length];
@@ -1392,10 +1399,38 @@
}
}
return false;
- } if (attr.getCategory() == PrinterResolution.class) {
+ } else if (attr.getCategory() == PrinterResolution.class) {
if (attr instanceof PrinterResolution) {
return isSupportedResolution((PrinterResolution)attr);
}
+ } else if (attr.getCategory() == DialogOwner.class) {
+ DialogOwner owner = (DialogOwner)attr;
+ // ID not supported on any dialog type on Unix platforms.
+ if (DialogOwnerAccessor.getID(owner) != 0) {
+ return false;
+ }
+ // On Mac we have no control over the native dialog.
+ DialogTypeSelection dst = (attributes == null) ? null :
+ (DialogTypeSelection)attributes.get(DialogTypeSelection.class);
+ if (PrintServiceLookupProvider.isMac() &&
+ dst == DialogTypeSelection.NATIVE) {
+ return false;
+ }
+ // The other case is always a Swing dialog on all Unix platforms.
+ // So we only need to check that the toolkit supports
+ // always on top.
+ if (owner.getOwner() != null) {
+ return true;
+ } else {
+ return Toolkit.getDefaultToolkit().isAlwaysOnTopSupported();
+ }
+ } else if (attr.getCategory() == DialogTypeSelection.class) {
+ if (PrintServiceLookupProvider.isMac()) {
+ return true;
+ } else {
+ DialogTypeSelection dst = (DialogTypeSelection)attr;
+ return attr == DialogTypeSelection.COMMON;
+ }
}
return true;
}
--- a/src/java.desktop/unix/classes/sun/print/UnixPrintService.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/unix/classes/sun/print/UnixPrintService.java Wed Jun 13 11:01:25 2018 -0700
@@ -31,6 +31,8 @@
import java.util.ArrayList;
import java.util.Locale;
+import java.awt.GraphicsEnvironment;
+import java.awt.Toolkit;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintService;
@@ -54,6 +56,8 @@
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.CopiesSupported;
import javax.print.attribute.standard.Destination;
+import javax.print.attribute.standard.DialogOwner;
+import javax.print.attribute.standard.DialogTypeSelection;
import javax.print.attribute.standard.Fidelity;
import javax.print.attribute.standard.Media;
import javax.print.attribute.standard.MediaPrintableArea;
@@ -619,10 +623,15 @@
}
public Class<?>[] getSupportedAttributeCategories() {
- int totalCats = otherAttrCats.length;
- Class<?>[] cats = new Class<?>[totalCats];
- System.arraycopy(otherAttrCats, 0, cats, 0, otherAttrCats.length);
- return cats;
+ ArrayList<Class<?>> categList = new ArrayList<>(otherAttrCats.length);
+ for (Class<?> c : otherAttrCats) {
+ categList.add(c);
+ }
+ if (GraphicsEnvironment.isHeadless() == false) {
+ categList.add(DialogOwner.class);
+ categList.add(DialogTypeSelection.class);
+ }
+ return categList.toArray(new Class<?>[categList.size()]);
}
public boolean
@@ -1023,6 +1032,24 @@
flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
return false;
}
+ } else if (attr.getCategory() == DialogOwner.class) {
+ DialogOwner owner = (DialogOwner)attr;
+ // ID not supported on any dialog type on Unix platforms.
+ if (DialogOwnerAccessor.getID(owner) != 0) {
+ return false;
+ }
+ // UnixPrintService is not used on Mac, so this is
+ // always some Unix system that does not have CUPS/IPP
+ // Which means we always use a Swing dialog and we need
+ // only check if alwaysOnTop is supported by the toolkit.
+ if (owner.getOwner() != null) {
+ return true;
+ } else {
+ return Toolkit.getDefaultToolkit().isAlwaysOnTopSupported();
+ }
+ } else if (attr.getCategory() == DialogTypeSelection.class) {
+ DialogTypeSelection dts = (DialogTypeSelection)attr;
+ return dts == DialogTypeSelection.COMMON;
}
return true;
}
--- a/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java Wed Jun 13 11:01:25 2018 -0700
@@ -79,6 +79,7 @@
import javax.print.attribute.standard.SheetCollate;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.Destination;
+import javax.print.attribute.standard.DialogOwner;
import javax.print.attribute.standard.OrientationRequested;
import javax.print.attribute.standard.Media;
import javax.print.attribute.standard.MediaSizeName;
@@ -95,7 +96,6 @@
import sun.print.Win32PrintService;
import sun.print.PrintServiceLookupProvider;
import sun.print.ServiceDialog;
-import sun.print.DialogOwner;
import java.awt.Frame;
import java.io.FilePermission;
--- a/src/java.desktop/windows/classes/sun/awt/windows/WRobotPeer.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/windows/classes/sun/awt/windows/WRobotPeer.java Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2014, 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
@@ -25,9 +25,13 @@
package sun.awt.windows;
-import java.awt.*;
+import java.awt.GraphicsDevice;
+import java.awt.Point;
+import java.awt.Rectangle;
import java.awt.peer.RobotPeer;
+import sun.java2d.SunGraphicsEnvironment;
+
final class WRobotPeer extends WObjectPeer implements RobotPeer
{
WRobotPeer() {
@@ -48,7 +52,8 @@
public native void mouseMoveImpl(int x, int y);
@Override
public void mouseMove(int x, int y) {
- mouseMoveImpl(x, y);
+ Point point = SunGraphicsEnvironment.convertToDeviceSpace(x, y);
+ mouseMoveImpl(point.x, point.y);
}
@Override
public native void mousePress(int buttons);
--- a/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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,8 +61,8 @@
import sun.awt.Win32GraphicsConfig;
import sun.awt.Win32GraphicsDevice;
import sun.awt.Win32GraphicsEnvironment;
+import sun.java2d.SunGraphicsEnvironment;
import sun.java2d.pipe.Region;
-import sun.swing.SwingUtilities2;
import sun.util.logging.PlatformLogger;
public class WWindowPeer extends WPanelPeer implements WindowPeer,
@@ -659,7 +659,8 @@
int cx = x + width / 2;
int cy = y + height / 2;
GraphicsConfiguration current = getGraphicsConfiguration();
- GraphicsConfiguration other = SwingUtilities2.getGraphicsConfigurationAtPoint(current, cx, cy);
+ GraphicsConfiguration other = SunGraphicsEnvironment
+ .getGraphicsConfigurationAtPoint(current, cx, cy);
if (!current.equals(other)) {
AffineTransform tx = other.getDefaultTransform();
double otherScaleX = tx.getScaleX();
--- a/src/java.desktop/windows/classes/sun/print/Win32PrintService.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/windows/classes/sun/print/Win32PrintService.java Wed Jun 13 11:01:25 2018 -0700
@@ -25,6 +25,8 @@
package sun.print;
+import java.awt.GraphicsEnvironment;
+import java.awt.Toolkit;
import java.awt.Window;
import java.awt.print.PrinterJob;
import java.io.File;
@@ -54,6 +56,8 @@
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.CopiesSupported;
import javax.print.attribute.standard.Destination;
+import javax.print.attribute.standard.DialogOwner;
+import javax.print.attribute.standard.DialogTypeSelection;
import javax.print.attribute.standard.Fidelity;
import javax.print.attribute.standard.Media;
import javax.print.attribute.standard.MediaSizeName;
@@ -1042,6 +1046,10 @@
categList.add(PrinterResolution.class);
}
+ if (GraphicsEnvironment.isHeadless() == false) {
+ categList.add(DialogOwner.class);
+ categList.add(DialogTypeSelection.class);
+ }
return categList.toArray(new Class<?>[categList.size()]);
}
@@ -1585,6 +1593,23 @@
(isColorSup && (attr == ColorSupported.NOT_SUPPORTED))) {
return false;
}
+ } else if (category == DialogTypeSelection.class) {
+ return true; // isHeadless was checked by category support
+ } else if (category == DialogOwner.class) {
+ DialogOwner owner = (DialogOwner)attr;
+ DialogTypeSelection dts = (attributes == null) ? null :
+ (DialogTypeSelection)attributes.get(DialogTypeSelection.class);
+ if (dts == DialogTypeSelection.NATIVE) {
+ return DialogOwnerAccessor.getID(owner) != 0;
+ } else {
+ if (DialogOwnerAccessor.getID(owner) != 0) {
+ return false;
+ } else if (owner.getOwner() != null) {
+ return true;
+ } else {
+ return Toolkit.getDefaultToolkit().isAlwaysOnTopSupported();
+ }
+ }
}
return true;
}
--- a/src/java.desktop/windows/native/libawt/java2d/windows/GDIRenderer.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/windows/native/libawt/java2d/windows/GDIRenderer.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, 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
@@ -85,7 +85,11 @@
*pNpoints = outpoints;
}
if (outpoints > POLYTEMPSIZE) {
- pPoints = (POINT *) SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, sizeof(POINT), outpoints);
+ try {
+ pPoints = (POINT *) SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, sizeof(POINT), outpoints);
+ } catch (const std::bad_alloc&) {
+ return NULL;
+ }
}
BOOL isempty = fixend;
for (int i = 0; i < npoints; i++) {
--- a/src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2014, 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
@@ -873,7 +873,13 @@
int numSizes = ::DeviceCapabilities(printerName, printerPort,
DC_PAPERS, NULL, NULL);
if (numSizes > 0) {
- LPTSTR papers = (LPTSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, numSizes, sizeof(WORD));
+ LPTSTR papers;
+ try {
+ papers = (LPTSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, numSizes, sizeof(WORD));
+ } catch (const std::bad_alloc&) {
+ papers = NULL;
+ }
+
if (papers != NULL &&
::DeviceCapabilities(printerName, printerPort,
DC_PAPERS, papers, NULL) != -1) {
--- a/src/java.desktop/windows/native/libawt/windows/awt_Robot.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Robot.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -43,62 +43,20 @@
{
}
-#ifndef SPI_GETMOUSESPEED
-#define SPI_GETMOUSESPEED 112
-#endif
-
-#ifndef SPI_SETMOUSESPEED
-#define SPI_SETMOUSESPEED 113
-#endif
+static int signum(int i) {
+ // special version of signum which returns 1 when value is 0
+ return i >= 0 ? 1 : -1;
+}
void AwtRobot::MouseMove( jint x, jint y)
{
- // Fix for Bug 4288230. See Q193003 from MSDN.
- int oldAccel[3], newAccel[3];
- INT_PTR oldSpeed, newSpeed;
- BOOL bResult;
-
- // The following values set mouse ballistics to 1 mickey/pixel.
- newAccel[0] = 0;
- newAccel[1] = 0;
- newAccel[2] = 0;
- newSpeed = 10;
-
- // Save the Current Mouse Acceleration Constants
- bResult = SystemParametersInfo(SPI_GETMOUSE,0,oldAccel,0);
- bResult = SystemParametersInfo(SPI_GETMOUSESPEED, 0, &oldSpeed,0);
- // Set the new Mouse Acceleration Constants (Disabled).
- bResult = SystemParametersInfo(SPI_SETMOUSE,0,newAccel,SPIF_SENDCHANGE);
- bResult = SystemParametersInfo(SPI_SETMOUSESPEED, 0,
- // 4504963: Though the third argument to SystemParameterInfo is
- // declared as a PVOID, as of Windows 2000 it is apparently
- // interpreted as an int. (The MSDN docs for SPI_SETMOUSESPEED
- // say that it's an integer between 1 and 20, the default being
- // 10). Instead of passing the @ of the desired value, the
- // value itself is now passed, cast as a PVOID so as to
- // compile. -bchristi 10/02/2001
- (PVOID)newSpeed,
- SPIF_SENDCHANGE);
-
- int primaryIndex = AwtWin32GraphicsDevice::GetDefaultDeviceIndex();
- Devices::InstanceAccess devices;
- AwtWin32GraphicsDevice *device = devices->GetDevice(primaryIndex);
-
- x = (device == NULL) ? x : device->ScaleUpX(x);
- y = (device == NULL) ? y : device->ScaleUpY(y);
-
- POINT curPos;
- ::GetCursorPos(&curPos);
- x -= curPos.x;
- y -= curPos.y;
-
- mouse_event(MOUSEEVENTF_MOVE,x,y,0,0);
- // Move the cursor to the desired coordinates.
-
- // Restore the old Mouse Acceleration Constants.
- bResult = SystemParametersInfo(SPI_SETMOUSE,0, oldAccel, SPIF_SENDCHANGE);
- bResult = SystemParametersInfo(SPI_SETMOUSESPEED, 0, (PVOID)oldSpeed,
- SPIF_SENDCHANGE);
+ INPUT mouseInput = {0};
+ mouseInput.type = INPUT_MOUSE;
+ mouseInput.mi.time = 0;
+ mouseInput.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
+ mouseInput.mi.dx = (x * 65536 /::GetSystemMetrics(SM_CXSCREEN)) + signum(x);
+ mouseInput.mi.dy = (y * 65536 /::GetSystemMetrics(SM_CYSCREEN)) + signum(y);
+ ::SendInput(1, &mouseInput, sizeof(mouseInput));
}
void AwtRobot::MousePress( jint buttonMask )
--- a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -53,8 +53,8 @@
"sun.security.jgss.wrapper.NativeGSSFactory";
private static final String LIB_PROP = "sun.security.jgss.lib";
private static final String DEBUG_PROP = "sun.security.nativegss.debug";
- private static HashMap<String, String> MECH_MAP;
- static final Provider INSTANCE = new SunNativeProvider();
+ private static final HashMap<String, String> MECH_MAP;
+ static final Provider INSTANCE;
static boolean DEBUG;
static void debug(String message) {
if (DEBUG) {
@@ -117,6 +117,8 @@
return null;
}
});
+ // initialize INSTANCE after MECH_MAP is constructed
+ INSTANCE = new SunNativeProvider();
}
public SunNativeProvider() {
--- a/src/jdk.accessibility/windows/native/libwindowsaccessbridge/WinAccessBridge.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/src/jdk.accessibility/windows/native/libwindowsaccessbridge/WinAccessBridge.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -452,7 +452,7 @@
*/
BOOL
WinAccessBridge::receiveAQueuedPackage() {
- AccessBridgeQueueElement *element;
+ AccessBridgeQueueElement *element = NULL;
PrintDebugString("in WinAccessBridge::receiveAQueuedPackage()");
@@ -464,15 +464,6 @@
QueueReturns result = messageQueue->remove(&element);
- PrintDebugString(" 'element->buffer' contains:");
- DEBUG_CODE(PackageType *type = (PackageType *) element->buffer);
- DEBUG_CODE(FocusGainedPackageTag *pkg = (FocusGainedPackageTag *) (((char *) element->buffer) + sizeof(PackageType)));
- DEBUG_CODE(PrintDebugString(" PackageType = %X", *type));
-#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
- DEBUG_CODE(PrintDebugString(" EventPackage: vmID = %X, event = %p, source = %p", pkg->vmID, pkg->Event, pkg->AccessibleContextSource));
-#else // JOBJECT64 is jlong (64 bit)
- DEBUG_CODE(PrintDebugString(" EventPackage: vmID = %X, event = %016I64X, source = %016I64X", pkg->vmID, pkg->Event, pkg->AccessibleContextSource));
-#endif
switch (result) {
case cQueueBroken:
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java Wed Jun 13 11:01:25 2018 -0700
@@ -181,7 +181,8 @@
DIAMOND_WITH_ANONYMOUS_CLASS_CREATION(JDK9, Fragments.FeatureDiamondAndAnonClass, DiagKind.NORMAL),
UNDERSCORE_IDENTIFIER(MIN, JDK8),
PRIVATE_INTERFACE_METHODS(JDK9, Fragments.FeaturePrivateIntfMethods, DiagKind.PLURAL),
- LOCAL_VARIABLE_TYPE_INFERENCE(JDK10);
+ LOCAL_VARIABLE_TYPE_INFERENCE(JDK10),
+ IMPORT_ON_DEMAND_OBSERVABLE_PACKAGES(JDK1_2, JDK8);
enum DiagKind {
NORMAL,
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Wed Jun 13 11:01:25 2018 -0700
@@ -2562,7 +2562,9 @@
Type argType = arityMismatch ?
syms.errType :
actuals.head;
- setSyntheticVariableType(params.head, argType);
+ if (params.head.isImplicitlyTyped()) {
+ setSyntheticVariableType(params.head, argType);
+ }
params.head.sym = null;
actuals = actuals.isEmpty() ?
actuals :
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Wed Jun 13 11:01:25 2018 -0700
@@ -3650,17 +3650,8 @@
OUTER: for (JCImport imp : toplevel.getImports()) {
if (!imp.staticImport && TreeInfo.name(imp.qualid) == names.asterisk) {
TypeSymbol tsym = ((JCFieldAccess)imp.qualid).selected.type.tsym;
- if (toplevel.modle.visiblePackages != null) {
- //TODO - unclear: selects like javax.* will get resolved from the current module
- //(as javax is not an exported package from any module). And as javax in the current
- //module typically does not contain any classes or subpackages, we need to go through
- //the visible packages to find a sub-package:
- for (PackageSymbol known : toplevel.modle.visiblePackages.values()) {
- if (Convert.packagePart(known.fullname) == tsym.flatName())
- continue OUTER;
- }
- }
- if (tsym.kind == PCK && tsym.members().isEmpty() && !tsym.exists()) {
+ if (tsym.kind == PCK && tsym.members().isEmpty() &&
+ !(Feature.IMPORT_ON_DEMAND_OBSERVABLE_PACKAGES.allowedInSource(source) && tsym.exists())) {
log.error(DiagnosticFlag.RESOLVE_ERROR, imp.pos, Errors.DoesntExist(tsym));
}
}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Wed Jun 13 11:01:25 2018 -0700
@@ -164,11 +164,18 @@
JCMemberReference result = new JCMemberReference(t.mode, t.name, expr, typeargs) {
@Override
public void setOverloadKind(OverloadKind overloadKind) {
- super.setOverloadKind(overloadKind);
- if (t.getOverloadKind() == null) {
+ OverloadKind previous = t.getOverloadKind();
+ if (previous == null) {
t.setOverloadKind(overloadKind);
+ } else {
+ Assert.check(previous == overloadKind);
}
}
+
+ @Override
+ public OverloadKind getOverloadKind() {
+ return t.getOverloadKind();
+ }
};
result.pos = t.pos;
return result;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Jun 13 11:01:25 2018 -0700
@@ -2012,7 +2012,7 @@
}
}
return null;
- }, sym -> sym.kind == Kind.TYP, false, typeNotFound);
+ }, sym -> sym.kind == Kind.TYP, typeNotFound);
}
};
@@ -2049,18 +2049,11 @@
PackageSymbol pack = syms.lookupPackage(env.toplevel.modle, name);
if (allowModules && isImportOnDemand(env, name)) {
- pack.complete();
- if (!pack.exists()) {
- Name nameAndDot = name.append('.', names.empty);
- boolean prefixOfKnown =
- env.toplevel.modle.visiblePackages.values()
- .stream()
- .anyMatch(p -> p.fullname.startsWith(nameAndDot));
-
+ if (pack.members().isEmpty()) {
return lookupInvisibleSymbol(env, name, syms::getPackagesForName, syms::enterPackage, sym -> {
sym.complete();
- return sym.exists();
- }, prefixOfKnown, pack);
+ return !sym.members().isEmpty();
+ }, pack);
}
}
@@ -2087,7 +2080,6 @@
Function<Name, Iterable<S>> get,
BiFunction<ModuleSymbol, Name, S> load,
Predicate<S> validate,
- boolean suppressError,
Symbol defaultResult) {
//even if a class/package cannot be found in the current module and among packages in modules
//it depends on that are exported for any or this module, the class/package may exist internally
@@ -2097,7 +2089,7 @@
for (S sym : candidates) {
if (validate.test(sym))
- return createInvisibleSymbolError(env, suppressError, sym);
+ return createInvisibleSymbolError(env, sym);
}
Set<ModuleSymbol> recoverableModules = new HashSet<>(syms.getAllModules());
@@ -2117,7 +2109,7 @@
S sym = load.apply(ms, name);
if (sym != null && validate.test(sym)) {
- return createInvisibleSymbolError(env, suppressError, sym);
+ return createInvisibleSymbolError(env, sym);
}
}
}
@@ -2126,11 +2118,11 @@
return defaultResult;
}
- private Symbol createInvisibleSymbolError(Env<AttrContext> env, boolean suppressError, Symbol sym) {
+ private Symbol createInvisibleSymbolError(Env<AttrContext> env, Symbol sym) {
if (symbolPackageVisible(env, sym)) {
return new AccessError(env, null, sym);
} else {
- return new InvisibleSymbolError(env, suppressError, sym);
+ return new InvisibleSymbolError(env, false, sym);
}
}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Wed Jun 13 11:01:25 2018 -0700
@@ -1702,6 +1702,7 @@
}
for (JCVariableDecl param: params) {
if (param.vartype != null && isRestrictedLocalVarTypeName(param.vartype)) {
+ param.startPos = TreeInfo.getStartPos(param.vartype);
param.vartype = null;
}
}
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java Wed Jun 13 11:01:25 2018 -0700
@@ -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,9 +33,11 @@
import sun.jvm.hotspot.code.*;
import sun.jvm.hotspot.compiler.*;
import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.gc.epsilon.*;
import sun.jvm.hotspot.gc.parallel.*;
import sun.jvm.hotspot.gc.shared.*;
import sun.jvm.hotspot.gc.g1.*;
+import sun.jvm.hotspot.gc.z.*;
import sun.jvm.hotspot.interpreter.*;
import sun.jvm.hotspot.memory.*;
import sun.jvm.hotspot.oops.*;
@@ -1108,6 +1110,13 @@
anno = "PSOldGen ";
bad = false;
}
+ } else if (collHeap instanceof EpsilonHeap) {
+ anno = "Epsilon ";
+ bad = false;
+ } else if (collHeap instanceof ZCollectedHeap) {
+ ZCollectedHeap heap = (ZCollectedHeap) collHeap;
+ anno = "ZHeap ";
+ bad = false;
} else {
// Optimistically assume the oop isn't bad
anno = "[Unknown generation] ";
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/epsilon/EpsilonHeap.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ *
+ */
+
+package sun.jvm.hotspot.gc.epsilon;
+
+import java.io.*;
+import java.util.*;
+
+import sun.jvm.hotspot.gc.shared.*;
+import sun.jvm.hotspot.code.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.memory.*;
+
+public class EpsilonHeap extends CollectedHeap {
+
+ private static AddressField spaceField;
+ private static Field virtualSpaceField;
+ private ContiguousSpace space;
+ private VirtualSpace virtualSpace;
+
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static void initialize(TypeDataBase db) {
+ Type type = db.lookupType("EpsilonHeap");
+ spaceField = type.getAddressField("_space");
+ virtualSpaceField = type.getField("_virtual_space");
+ }
+
+ public EpsilonHeap(Address addr) {
+ super(addr);
+ space = new ContiguousSpace(spaceField.getValue(addr));
+ virtualSpace = new VirtualSpace(addr.addOffsetTo(virtualSpaceField.getOffset()));
+ }
+
+ @Override
+ public CollectedHeapName kind() {
+ return CollectedHeapName.EPSILON;
+ }
+
+ public ContiguousSpace space() {
+ return space;
+ }
+
+ @Override
+ public void printOn(PrintStream tty) {
+ MemRegion mr = reservedRegion();
+ tty.println("Epsilon heap");
+ tty.println(" reserved: [" + mr.start() + ", " + mr.end() + "]");
+ tty.println(" committed: [" + virtualSpace.low() + ", " + virtualSpace.high() + "]");
+ tty.println(" used: [" + space.bottom() + ", " + space.top() + "]");
+ }
+
+}
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/CollectedHeap.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/CollectedHeap.java Wed Jun 13 11:01:25 2018 -0700
@@ -75,6 +75,14 @@
public abstract CollectedHeapName kind();
+ public String oopAddressDescription(OopHandle handle) {
+ return handle.toString();
+ }
+
+ public OopHandle oop_load_at(OopHandle handle, long offset) {
+ return handle.getOopHandleAt(offset);
+ }
+
public void print() { printOn(System.out); }
public void printOn(PrintStream tty) {
MemRegion mr = reservedRegion();
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/CollectedHeapName.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/CollectedHeapName.java Wed Jun 13 11:01:25 2018 -0700
@@ -35,6 +35,8 @@
public static final CollectedHeapName PARALLEL = new CollectedHeapName("Parallel");
public static final CollectedHeapName CMS = new CollectedHeapName("CMS");
public static final CollectedHeapName G1 = new CollectedHeapName("G1");
+ public static final CollectedHeapName EPSILON = new CollectedHeapName("Epsilon");
+ public static final CollectedHeapName Z = new CollectedHeapName("Z");
public String toString() {
return name;
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GCCause.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GCCause.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -61,6 +61,12 @@
_dcmd_gc_run ("Diagnostic Command"),
+ _z_timer ("Timer"),
+ _z_warmup ("Warmup"),
+ _z_allocation_rate ("Allocation Rate"),
+ _z_allocation_stall ("Allocation Stall"),
+ _z_proactive ("Proactive"),
+
_last_gc_cause ("ILLEGAL VALUE - last gc cause - ILLEGAL VALUE");
private final String value;
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GCName.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GCName.java Wed Jun 13 11:01:25 2018 -0700
@@ -37,6 +37,8 @@
ConcurrentMarkSweep ("ConcurrentMarkSweep"),
G1Old ("G1Old"),
G1Full ("G1Full"),
+ Z ("Z"),
+ NA ("N/A"),
GCNameEndSentinel ("GCNameEndSentinel");
private final String value;
@@ -48,4 +50,3 @@
return value;
}
}
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZAddress.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ *
+ */
+
+package sun.jvm.hotspot.gc.z;
+
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.runtime.VM;
+
+class ZAddress {
+ static long as_long(Address value) {
+ if (value == null) {
+ return 0;
+ }
+ return value.asLongValue();
+ };
+
+ static boolean is_null(Address value) {
+ return value == null;
+ }
+
+ static boolean is_weak_bad(Address value) {
+ return (as_long(value) & ZGlobals.ZAddressWeakBadMask()) != 0;
+ }
+
+ static boolean is_weak_good(Address value) {
+ return !is_weak_bad(value) && !is_null(value);
+ }
+
+ static boolean is_weak_good_or_null(Address value) {
+ return !is_weak_bad(value);
+ }
+
+ static long offset(Address address) {
+ return as_long(address) & ZGlobals.ZAddressOffsetMask;
+ }
+
+ static Address address(long value) {
+ VM vm = VM.getVM();
+ if (vm.getOS().equals("solaris") && vm.getCPU().equals("sparc")) {
+ value |= ZGlobals.ZAddressSpaceStart;
+ }
+
+ return ZOop.to_address(value);
+ }
+
+ static Address good(Address value) {
+ return address(offset(value) | ZGlobals.ZAddressGoodMask());
+ }
+
+ static Address good_or_null(Address value) {
+ return is_null(value) ? value : good(value);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZAddressRangeMapForPageTable.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ *
+ */
+
+package sun.jvm.hotspot.gc.z;
+
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.runtime.VM;
+import sun.jvm.hotspot.runtime.VMObject;
+import sun.jvm.hotspot.types.AddressField;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.TypeDataBase;
+
+public class ZAddressRangeMapForPageTable extends VMObject {
+ private static AddressField mapField;
+
+ private static long AddressRangeShift = ZGlobals.ZPageSizeMinShift;
+
+ static {
+ VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase()));
+ }
+
+ static private synchronized void initialize(TypeDataBase db) {
+ Type type = db.lookupType("ZAddressRangeMapForPageTable");
+
+ mapField = type.getAddressField("_map");
+ }
+
+ public ZAddressRangeMapForPageTable(Address addr) {
+ super(addr);
+ }
+
+ private Address map() {
+ return mapField.getValue(addr);
+ }
+
+ private long index_for_addr(Address addr) {
+ long index = ZAddress.offset(addr) >> AddressRangeShift;
+
+ return index;
+ }
+
+ Address get(Address addr) {
+ long index = index_for_addr(addr);
+
+ return map().getAddressAt(index * VM.getVM().getBytesPerLong());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZBarrier.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ *
+ */
+
+package sun.jvm.hotspot.gc.z;
+
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.runtime.VM;
+
+class ZBarrier {
+ private static boolean is_weak_good_or_null_fast_path(Address addr) {
+ return ZAddress.is_weak_good_or_null(addr);
+ }
+
+ private static Address weak_load_barrier_on_oop_slow_path(Address addr) {
+ return ZAddress.is_weak_good(addr) ? ZAddress.good(addr) : relocate_or_remap(addr);
+ }
+
+ private static boolean during_relocate() {
+ return ZGlobals.ZGlobalPhase() == ZGlobals.ZPhaseRelocate;
+ }
+
+ private static Address relocate(Address addr) {
+ ZHeap heap = zheap();
+ if (heap.is_relocating(addr)) {
+ // Forward
+ return heap.relocate_object(addr);
+ }
+
+ // Remap
+ return ZAddress.good(addr);
+ }
+
+ private static ZHeap zheap() {
+ ZCollectedHeap zCollectedHeap = (ZCollectedHeap)VM.getVM().getUniverse().heap();
+ return zCollectedHeap.heap();
+ }
+
+ private static Address remap(Address addr) {
+ ZHeap heap = zheap();
+ if (heap.is_relocating(addr)) {
+ // Forward
+ return heap.forward_object(addr);
+ }
+
+ // Remap
+ return ZAddress.good(addr);
+ }
+
+ private static Address relocate_or_remap(Address addr) {
+ return during_relocate() ? relocate(addr) : remap(addr);
+ }
+
+ static Address weak_barrier(Address o) {
+ // Fast path
+ if (is_weak_good_or_null_fast_path(o)) {
+ // Return the good address instead of the weak good address
+ // to ensure that the currently active heap view is used.
+ return ZAddress.good_or_null(o);
+ }
+
+ // Slow path
+ return weak_load_barrier_on_oop_slow_path(o);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZCollectedHeap.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,95 @@
+/*
+ * 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
+ * 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.
+ *
+ */
+
+package sun.jvm.hotspot.gc.z;
+
+import java.io.PrintStream;
+
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.debugger.OopHandle;
+import sun.jvm.hotspot.gc.shared.CollectedHeap;
+import sun.jvm.hotspot.gc.shared.CollectedHeapName;
+import sun.jvm.hotspot.runtime.VM;
+import sun.jvm.hotspot.runtime.VMObjectFactory;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.TypeDataBase;
+
+// Mirror class for ZCollectedHeap.
+
+public class ZCollectedHeap extends CollectedHeap {
+
+ private static long zHeapFieldOffset;
+
+ static {
+ VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase()));
+ }
+
+ private static synchronized void initialize(TypeDataBase db) {
+ Type type = db.lookupType("ZCollectedHeap");
+
+ zHeapFieldOffset = type.getAddressField("_heap").getOffset();
+ }
+
+ public ZHeap heap() {
+ Address heapAddr = addr.addOffsetTo(zHeapFieldOffset);
+ return (ZHeap)VMObjectFactory.newObject(ZHeap.class, heapAddr);
+ }
+
+ @Override
+ public CollectedHeapName kind() {
+ return CollectedHeapName.Z;
+ }
+
+ @Override
+ public void printOn(PrintStream tty) {
+ heap().printOn(tty);
+ }
+
+ public ZCollectedHeap(Address addr) {
+ super(addr);
+ }
+
+ public OopHandle oop_load_at(OopHandle handle, long offset) {
+ assert(!VM.getVM().isCompressedOopsEnabled());
+
+ Address oopAddress = handle.getAddressAt(offset);
+
+ oopAddress = ZBarrier.weak_barrier(oopAddress);
+ if (oopAddress == null) {
+ return null;
+ }
+
+ return oopAddress.addOffsetToAsOopHandle(0);
+ }
+
+ public String oopAddressDescription(OopHandle handle) {
+ Address origOop = ZOop.to_address(handle);
+ Address loadBarrieredOop = ZBarrier.weak_barrier(origOop);
+ if (!origOop.equals(loadBarrieredOop)) {
+ return origOop + " (" + loadBarrieredOop.toString() + ")";
+ } else {
+ return handle.toString();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZForwardingTable.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ *
+ */
+
+package sun.jvm.hotspot.gc.z;
+
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.runtime.VM;
+import sun.jvm.hotspot.runtime.VMObject;
+import sun.jvm.hotspot.types.AddressField;
+import sun.jvm.hotspot.types.CIntegerField;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.TypeDataBase;
+
+public class ZForwardingTable extends VMObject {
+ private static AddressField tableField;
+ private static CIntegerField sizeField;
+
+ static {
+ VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase()));
+ }
+
+ static private synchronized void initialize(TypeDataBase db) {
+ Type type = db.lookupType("ZForwardingTable");
+
+ tableField = type.getAddressField("_table");
+ sizeField = type.getCIntegerField("_size");
+ }
+
+ public ZForwardingTable(Address addr) {
+ super(addr);
+ }
+
+ Address table() {
+ return tableField.getAddress(addr);
+ }
+
+ long size() {
+ return sizeField.getJLong(addr);
+ }
+
+ ZForwardingTableEntry at(ZForwardingTableCursor cursor) {
+ return new ZForwardingTableEntry(table().getAddressAt(cursor._value * VM.getVM().getBytesPerLong()));
+ }
+
+ ZForwardingTableEntry first(long from_index, ZForwardingTableCursor cursor) {
+ long mask = size() - 1;
+ long hash = ZHash.uint32_to_uint32(from_index);
+ cursor._value = hash & mask;
+ return at(cursor);
+ }
+
+ ZForwardingTableEntry next(ZForwardingTableCursor cursor) {
+ long mask = size() - 1;
+ cursor._value = (cursor._value + 1) & mask;
+ return at(cursor);
+ }
+
+ ZForwardingTableEntry find(long from_index, ZForwardingTableCursor cursor) {
+ // Reading entries in the table races with the atomic cas done for
+ // insertion into the table. This is safe because each entry is at
+ // most updated once (from -1 to something else).
+ ZForwardingTableEntry entry = first(from_index, cursor);
+ while (!entry.is_empty()) {
+ if (entry.from_index() == from_index) {
+ // Match found, return matching entry
+ return entry;
+ }
+
+ entry = next(cursor);
+ }
+
+ // Match not found, return empty entry
+ return entry;
+ }
+
+ ZForwardingTableEntry find(long from_index) {
+ ZForwardingTableCursor dummy = new ZForwardingTableCursor();
+ return find(from_index, dummy);
+ }
+
+ void dump() {
+ long s = size();
+ long count = 0;
+ System.out.println("Dumping ZForwardingTable[" + s + "]:");
+ ZForwardingTableCursor cursor = new ZForwardingTableCursor();
+ for (long i = 0; i < s; i++) {
+ cursor._value = i;
+ ZForwardingTableEntry entry = at(cursor);
+ if (!entry.is_empty()) {
+ long hash = ZHash.uint32_to_uint32(entry.from_index());
+ System.out.println(i + " " + count + " " + entry + " hash: " + hash + " masked_hash: " + (hash & (s - 1)));
+ count++;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZForwardingTableCursor.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ *
+ */
+
+package sun.jvm.hotspot.gc.z;
+
+class ZForwardingTableCursor {
+ long _value;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZForwardingTableEntry.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ *
+ */
+
+package sun.jvm.hotspot.gc.z;
+
+import sun.jvm.hotspot.debugger.Address;
+
+class ZForwardingTableEntry {
+ private Address entry;
+
+ ZForwardingTableEntry(Address addr) {
+ entry = addr;
+ }
+
+ private static long empty() {
+ return ~0L;
+ }
+
+ boolean is_empty() {
+ return entry.asLongValue() == empty();
+ }
+
+ Address to_offset() {
+ return entry.andWithMask((1L << 42) - 1);
+ }
+
+ long from_index() {
+ return entry.asLongValue() >>> 42;
+ }
+
+ public String toString() {
+ return entry + " - from_index: " + from_index() + " to_offset: " + to_offset();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZGlobals.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,118 @@
+/*
+ * 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.
+ *
+ */
+
+package sun.jvm.hotspot.gc.z;
+
+import sun.jvm.hotspot.runtime.VM;
+import sun.jvm.hotspot.types.Field;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.TypeDataBase;
+
+public class ZGlobals {
+ private static Field instanceField;
+
+ // Global phase state
+ public static int ZPhaseRelocate;
+
+ public static byte ZPageTypeSmall;
+ public static byte ZPageTypeMedium;
+ public static byte ZPageTypeLarge;
+
+ // Page size shifts
+ public static long ZPageSizeSmallShift;
+ public static long ZPageSizeMediumShift;
+ public static long ZPageSizeMinShift;
+
+ // Object alignment shifts
+ public static int ZObjectAlignmentMediumShift;
+ public static int ZObjectAlignmentLargeShift;
+
+ // Pointer part of address
+ public static long ZAddressOffsetShift;
+
+ // Pointer part of address
+ public static long ZAddressOffsetBits;
+ public static long ZAddressOffsetMask;
+
+ // Address space start/end/size
+ public static long ZAddressSpaceStart;
+
+ static {
+ VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase()));
+ }
+
+ static private synchronized void initialize(TypeDataBase db) {
+ Type type = db.lookupType("ZGlobalsForVMStructs");
+
+ instanceField = type.getField("_instance_p");
+
+ ZPhaseRelocate = db.lookupIntConstant("ZPhaseRelocate").intValue();
+
+ ZPageTypeSmall = db.lookupIntConstant("ZPageTypeSmall").byteValue();
+ ZPageTypeMedium = db.lookupIntConstant("ZPageTypeMedium").byteValue();
+ ZPageTypeLarge = db.lookupIntConstant("ZPageTypeLarge").byteValue();
+
+ ZPageSizeSmallShift = db.lookupLongConstant("ZPageSizeSmallShift").longValue();
+ ZPageSizeMediumShift = db.lookupLongConstant("ZPageSizeMediumShift").longValue();
+ ZPageSizeMinShift = db.lookupLongConstant("ZPageSizeMinShift").longValue();
+
+ ZObjectAlignmentMediumShift = db.lookupIntConstant("ZObjectAlignmentMediumShift").intValue();
+ ZObjectAlignmentLargeShift = db.lookupIntConstant("ZObjectAlignmentLargeShift").intValue();;
+
+ ZAddressOffsetShift = db.lookupLongConstant("ZAddressOffsetShift").longValue();
+
+ ZAddressOffsetBits = db.lookupLongConstant("ZAddressOffsetBits").longValue();
+ ZAddressOffsetMask = db.lookupLongConstant("ZAddressOffsetMask").longValue();
+
+ ZAddressSpaceStart = db.lookupLongConstant("ZAddressSpaceStart").longValue();
+ }
+
+ private static ZGlobalsForVMStructs instance() {
+ return new ZGlobalsForVMStructs(instanceField.getAddress());
+ }
+
+ public static int ZGlobalPhase() {
+ return instance().ZGlobalPhase();
+ }
+
+ public static long ZAddressGoodMask() {
+ return instance().ZAddressGoodMask();
+ }
+
+ public static long ZAddressBadMask() {
+ return instance().ZAddressBadMask();
+ }
+
+ public static long ZAddressWeakBadMask() {
+ return instance().ZAddressWeakBadMask();
+ }
+
+ public static int ZObjectAlignmentSmallShift() {
+ return instance().ZObjectAlignmentSmallShift();
+ }
+
+ public static int ZObjectAlignmentSmall() {
+ return instance().ZObjectAlignmentSmall();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZGlobalsForVMStructs.java Wed Jun 13 11:01:25 2018 -0700
@@ -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.
+ *
+ */
+
+package sun.jvm.hotspot.gc.z;
+
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.runtime.VM;
+import sun.jvm.hotspot.runtime.VMObject;
+import sun.jvm.hotspot.types.AddressField;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.TypeDataBase;
+
+class ZGlobalsForVMStructs extends VMObject {
+ private static AddressField ZGlobalPhaseField;
+ private static AddressField ZAddressGoodMaskField;
+ private static AddressField ZAddressBadMaskField;
+ private static AddressField ZAddressWeakBadMaskField;
+ private static AddressField ZObjectAlignmentSmallShiftField;
+ private static AddressField ZObjectAlignmentSmallField;
+
+ static {
+ VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase()));
+ }
+
+ static private synchronized void initialize(TypeDataBase db) {
+ Type type = db.lookupType("ZGlobalsForVMStructs");
+
+ ZGlobalPhaseField = type.getAddressField("_ZGlobalPhase");
+ ZAddressGoodMaskField = type.getAddressField("_ZAddressGoodMask");
+ ZAddressBadMaskField = type.getAddressField("_ZAddressBadMask");
+ ZAddressWeakBadMaskField = type.getAddressField("_ZAddressWeakBadMask");
+ ZObjectAlignmentSmallShiftField = type.getAddressField("_ZObjectAlignmentSmallShift");
+ ZObjectAlignmentSmallField = type.getAddressField("_ZObjectAlignmentSmall");
+ }
+
+ ZGlobalsForVMStructs(Address addr) {
+ super(addr);
+ }
+
+ int ZGlobalPhase() {
+ return ZGlobalPhaseField.getValue(addr).getJIntAt(0);
+ }
+
+ long ZAddressGoodMask() {
+ return ZAddressGoodMaskField.getValue(addr).getJLongAt(0);
+ }
+
+ long ZAddressBadMask() {
+ return ZAddressBadMaskField.getValue(addr).getJLongAt(0);
+ }
+
+ long ZAddressWeakBadMask() {
+ return ZAddressWeakBadMaskField.getValue(addr).getJLongAt(0);
+ }
+
+ int ZObjectAlignmentSmallShift() {
+ return ZObjectAlignmentSmallShiftField.getValue(addr).getJIntAt(0);
+ }
+
+ int ZObjectAlignmentSmall() {
+ return ZObjectAlignmentSmallField.getValue(addr).getJIntAt(0);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZHash.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 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.
+ *
+ */
+
+package sun.jvm.hotspot.gc.z;
+
+class ZHash {
+ private static long uint32(long value) {
+ return value & 0xFFFFFFFFL;
+ }
+
+ static long uint32_to_uint32(long key) {
+ key = uint32(~key + (key << 15));
+ key = uint32(key ^ (key >> 12));
+ key = uint32(key + (key << 2));
+ key = uint32(key ^ (key >> 4));
+ key = uint32(key * 2057);
+ key = uint32(key ^ (key >> 16));
+ return key;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZHeap.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,99 @@
+/*
+ * 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
+ * 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.
+ *
+ */
+
+package sun.jvm.hotspot.gc.z;
+
+import java.io.PrintStream;
+
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.runtime.VM;
+import sun.jvm.hotspot.runtime.VMObject;
+import sun.jvm.hotspot.runtime.VMObjectFactory;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.TypeDataBase;
+
+// Mirror class for ZHeap
+
+public class ZHeap extends VMObject {
+
+ private static long pageAllocatorFieldOffset;
+ private static long pageTableFieldOffset;
+
+ static {
+ VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase()));
+ }
+
+ private static synchronized void initialize(TypeDataBase db) {
+ Type type = db.lookupType("ZHeap");
+
+ pageAllocatorFieldOffset = type.getAddressField("_page_allocator").getOffset();
+ pageTableFieldOffset = type.getAddressField("_pagetable").getOffset();
+ }
+
+ public ZHeap(Address addr) {
+ super(addr);
+ }
+
+ private ZPageAllocator pageAllocator() {
+ Address pageAllocatorAddr = addr.addOffsetTo(pageAllocatorFieldOffset);
+ return (ZPageAllocator)VMObjectFactory.newObject(ZPageAllocator.class, pageAllocatorAddr);
+ }
+
+ ZPageTable pageTable() {
+ return (ZPageTable)VMObjectFactory.newObject(ZPageTable.class, addr.addOffsetTo(pageTableFieldOffset));
+ }
+
+ public long maxCapacity() {
+ return pageAllocator().maxCapacity();
+ }
+
+ public long capacity() {
+ return pageAllocator().capacity();
+ }
+
+ public long used() {
+ return pageAllocator().used();
+ }
+
+ boolean is_relocating(Address o) {
+ return pageTable().is_relocating(o);
+ }
+
+ Address forward_object(Address addr) {
+ ZPage page = pageTable().get(addr);
+ return page.forward_object(addr);
+ }
+
+ Address relocate_object(Address addr) {
+ ZPage page = pageTable().get(addr);
+ return page.relocate_object(addr);
+ }
+
+ public void printOn(PrintStream tty) {
+ tty.print(" ZHeap ");
+ tty.print("used " + (used() / 1024 / 1024) + "M, ");
+ tty.print("capacity " + (capacity() / 1024 / 1024) + "M, ");
+ tty.println("max capacity " + (maxCapacity() / 1024 / 1024) + "M");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZOop.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ *
+ */
+
+package sun.jvm.hotspot.gc.z;
+
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.debugger.OopHandle;
+import sun.jvm.hotspot.runtime.VM;
+
+class ZOop {
+ private static final long MSB = ~0L ^ (~0L >>> 1);
+
+ private static Address msbAddress() {
+ return VM.getVM().getUniverse().heap().start().orWithMask(MSB).andWithMask(MSB);
+ }
+
+ static Address to_address(long value) {
+ // If the value of an Address becomes 0, null is returned instead of an Address.
+ // Start with a one-bit address and as a last step, remove that bit.
+ Address oneAddress = msbAddress();
+ return oneAddress.orWithMask(value).xorWithMask(ZAddress.as_long(oneAddress));
+ }
+
+ static Address to_address(OopHandle oop) {
+ return to_address(ZAddress.as_long(oop));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZPage.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ *
+ */
+
+package sun.jvm.hotspot.gc.z;
+
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.runtime.VM;
+import sun.jvm.hotspot.runtime.VMObject;
+import sun.jvm.hotspot.runtime.VMObjectFactory;
+import sun.jvm.hotspot.types.CIntegerField;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.TypeDataBase;
+
+public class ZPage extends VMObject {
+ private static CIntegerField typeField;
+ private static long virtualFieldOffset;
+ private static long forwardingFieldOffset;
+
+ static {
+ VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase()));
+ }
+
+ static private synchronized void initialize(TypeDataBase db) {
+ Type type = db.lookupType("ZPage");
+
+ typeField = type.getCIntegerField("_type");
+ virtualFieldOffset = type.getField("_virtual").getOffset();
+ forwardingFieldOffset = type.getField("_forwarding").getOffset();
+ }
+
+ public ZPage(Address addr) {
+ super(addr);
+ }
+
+ private byte type() {
+ return typeField.getJByte(addr);
+ }
+
+ private ZVirtualMemory virtual() {
+ return (ZVirtualMemory)VMObjectFactory.newObject(ZVirtualMemory.class, addr.addOffsetTo(virtualFieldOffset));
+ }
+
+ private ZForwardingTable forwarding() {
+ return (ZForwardingTable)VMObjectFactory.newObject(ZForwardingTable.class, addr.addOffsetTo(forwardingFieldOffset));
+ }
+
+ private long start() {
+ return virtual().start();
+ }
+
+ Address forward_object(Address from) {
+ // Lookup address in forwarding table
+ long from_offset = ZAddress.offset(from);
+ long from_index = (from_offset - start()) >> object_alignment_shift();
+ ZForwardingTableEntry entry = forwarding().find(from_index);
+ assert(!entry.is_empty());
+ assert(entry.from_index() == from_index);
+
+ return ZAddress.good(entry.to_offset());
+ }
+
+ Address relocate_object(Address from) {
+ // Lookup address in forwarding table
+ long from_offset = ZAddress.offset(from);
+ long from_index = (from_offset - start()) >> object_alignment_shift();
+ ZForwardingTableEntry entry = forwarding().find(from_index);
+ if (!entry.is_empty() && entry.from_index() == from_index) {
+ return ZAddress.good(entry.to_offset());
+ }
+
+ // There's no relocate operation in the SA.
+ // Mimic object pinning and return the good view of the from object.
+ return ZAddress.good(from);
+ }
+
+
+ long object_alignment_shift() {
+ if (type() == ZGlobals.ZPageTypeSmall) {
+ return ZGlobals.ZObjectAlignmentSmallShift();
+ } else if (type() == ZGlobals.ZPageTypeMedium) {
+ return ZGlobals.ZObjectAlignmentMediumShift;
+ } else {
+ assert(type() == ZGlobals.ZPageTypeLarge);
+ return ZGlobals.ZObjectAlignmentLargeShift;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZPageAllocator.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 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.
+ *
+ */
+
+package sun.jvm.hotspot.gc.z;
+
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.runtime.VM;
+import sun.jvm.hotspot.runtime.VMObject;
+import sun.jvm.hotspot.runtime.VMObjectFactory;
+import sun.jvm.hotspot.types.AddressField;
+import sun.jvm.hotspot.types.CIntegerField;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.TypeDataBase;
+
+// Mirror class for ZPageAllocator
+
+public class ZPageAllocator extends VMObject {
+
+ private static AddressField physicalField;
+ private static CIntegerField usedField;
+
+ static {
+ VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase()));
+ }
+
+ static private synchronized void initialize(TypeDataBase db) {
+ Type type = db.lookupType("ZPageAllocator");
+
+ physicalField = type.getAddressField("_physical");
+ usedField = type.getCIntegerField("_used");
+ }
+
+ private ZPhysicalMemoryManager physical() {
+ Address physicalAddr = physicalField.getValue(addr);
+ return (ZPhysicalMemoryManager)VMObjectFactory.newObject(ZPhysicalMemoryManager.class, physicalAddr);
+ }
+
+ public long maxCapacity() {
+ return physical().maxCapacity();
+ }
+
+ public long capacity() {
+ return physical().capacity();
+ }
+
+ public long used() {
+ return usedField.getValue(addr);
+ }
+
+ public ZPageAllocator(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZPageTable.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ *
+ */
+
+package sun.jvm.hotspot.gc.z;
+
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.runtime.VM;
+import sun.jvm.hotspot.runtime.VMObject;
+import sun.jvm.hotspot.runtime.VMObjectFactory;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.TypeDataBase;
+
+public class ZPageTable extends VMObject {
+ private static long mapFieldOffset;
+
+ static {
+ VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase()));
+ }
+
+ static private synchronized void initialize(TypeDataBase db) {
+ Type type = db.lookupType("ZPageTable");
+
+ mapFieldOffset = type.getAddressField("_map").getOffset();
+ }
+
+ public ZPageTable(Address addr) {
+ super(addr);
+ }
+
+ private ZAddressRangeMapForPageTable map() {
+ return (ZAddressRangeMapForPageTable)VMObjectFactory.newObject(ZAddressRangeMapForPageTable.class, addr.addOffsetTo(mapFieldOffset));
+ }
+
+ private ZPageTableEntry getEntry(Address o) {
+ return new ZPageTableEntry(map().get(o));
+ }
+
+ ZPage get(Address o) {
+ return getEntry(o).page();
+ }
+
+ boolean is_relocating(Address o) {
+ return getEntry(o).relocating();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZPageTableEntry.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ *
+ */
+
+package sun.jvm.hotspot.gc.z;
+
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.runtime.VMObjectFactory;
+
+class ZPageTableEntry {
+ Address entry;
+
+ ZPageTableEntry(Address address) {
+ entry = address;
+ }
+
+ ZPage page() {
+ return (ZPage)VMObjectFactory.newObject(ZPage.class, entry.andWithMask(~1L));
+ }
+
+ boolean relocating() {
+ return (entry.asLongValue() & 1) == 1;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZPhysicalMemoryManager.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 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.
+ *
+ */
+
+package sun.jvm.hotspot.gc.z;
+
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.runtime.VM;
+import sun.jvm.hotspot.runtime.VMObject;
+import sun.jvm.hotspot.types.CIntegerField;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.TypeDataBase;
+
+// Mirror class for ZPhysicalMemoryManager
+
+public class ZPhysicalMemoryManager extends VMObject {
+
+ private static CIntegerField capacityField;
+
+ private static CIntegerField maxCapacityField;
+
+ static {
+ VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase()));
+ }
+
+ private static synchronized void initialize(TypeDataBase db) {
+ Type type = db.lookupType("ZPhysicalMemoryManager");
+
+ capacityField = type.getCIntegerField("_capacity");
+ maxCapacityField = type.getCIntegerField("_max_capacity");
+ }
+
+ public long capacity() {
+ return capacityField.getValue(addr);
+ }
+
+ public long maxCapacity() {
+ return maxCapacityField.getValue(addr);
+ }
+
+ public ZPhysicalMemoryManager(Address addr) {
+ super(addr);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZVirtualMemory.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ *
+ */
+
+package sun.jvm.hotspot.gc.z;
+
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.runtime.VM;
+import sun.jvm.hotspot.runtime.VMObject;
+import sun.jvm.hotspot.types.CIntegerField;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.TypeDataBase;
+
+public class ZVirtualMemory extends VMObject {
+ private static CIntegerField startField;
+ private static CIntegerField endField;
+
+ static {
+ VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase()));
+ }
+
+ static private synchronized void initialize(TypeDataBase db) {
+ Type type = db.lookupType("ZVirtualMemory");
+
+ startField = type.getCIntegerField("_start");
+ endField = type.getCIntegerField("_end");
+ }
+
+ public ZVirtualMemory(Address addr) {
+ super(addr);
+ }
+
+ long start() {
+ return startField.getJLong(addr);
+ }
+
+ long end() {
+ return endField.getJLong(addr);
+ }
+}
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/Universe.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/Universe.java Wed Jun 13 11:01:25 2018 -0700
@@ -24,17 +24,27 @@
package sun.jvm.hotspot.memory;
-import java.io.*;
-import java.util.*;
-import sun.jvm.hotspot.debugger.*;
+import java.io.PrintStream;
+import java.util.Observable;
+import java.util.Observer;
+
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.debugger.OopHandle;
import sun.jvm.hotspot.gc.cms.CMSHeap;
+import sun.jvm.hotspot.gc.epsilon.EpsilonHeap;
+import sun.jvm.hotspot.gc.g1.G1CollectedHeap;
+import sun.jvm.hotspot.gc.parallel.ParallelScavengeHeap;
import sun.jvm.hotspot.gc.serial.SerialHeap;
-import sun.jvm.hotspot.gc.shared.*;
-import sun.jvm.hotspot.gc.g1.G1CollectedHeap;
-import sun.jvm.hotspot.gc.parallel.*;
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.types.*;
-import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.gc.shared.CollectedHeap;
+import sun.jvm.hotspot.gc.z.ZCollectedHeap;
+import sun.jvm.hotspot.oops.Oop;
+import sun.jvm.hotspot.runtime.BasicType;
+import sun.jvm.hotspot.runtime.VM;
+import sun.jvm.hotspot.runtime.VirtualConstructor;
+import sun.jvm.hotspot.types.AddressField;
+import sun.jvm.hotspot.types.CIntegerField;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.TypeDataBase;
public class Universe {
@@ -72,16 +82,34 @@
});
}
+ private static boolean typeExists(TypeDataBase db, String type) {
+ try {
+ db.lookupType(type);
+ } catch (RuntimeException e) {
+ return false;
+ }
+ return true;
+ }
+
+ private static void addHeapTypeIfInDB(TypeDataBase db, Class heapClass) {
+ String heapName = heapClass.getSimpleName();
+ if (typeExists(db, heapName)) {
+ heapConstructor.addMapping(heapName, heapClass);
+ }
+ }
+
private static synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("Universe");
collectedHeapField = type.getAddressField("_collectedHeap");
heapConstructor = new VirtualConstructor(db);
- heapConstructor.addMapping("CMSHeap", CMSHeap.class);
- heapConstructor.addMapping("SerialHeap", SerialHeap.class);
- heapConstructor.addMapping("ParallelScavengeHeap", ParallelScavengeHeap.class);
- heapConstructor.addMapping("G1CollectedHeap", G1CollectedHeap.class);
+ addHeapTypeIfInDB(db, CMSHeap.class);
+ addHeapTypeIfInDB(db, SerialHeap.class);
+ addHeapTypeIfInDB(db, ParallelScavengeHeap.class);
+ addHeapTypeIfInDB(db, G1CollectedHeap.class);
+ addHeapTypeIfInDB(db, EpsilonHeap.class);
+ addHeapTypeIfInDB(db, ZCollectedHeap.class);
mainThreadGroupField = type.getOopField("_main_thread_group");
systemThreadGroupField = type.getOopField("_system_thread_group");
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java Wed Jun 13 11:01:25 2018 -0700
@@ -34,6 +34,7 @@
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.gc.cms.*;
import sun.jvm.hotspot.gc.shared.*;
+import sun.jvm.hotspot.gc.epsilon.*;
import sun.jvm.hotspot.gc.g1.*;
import sun.jvm.hotspot.gc.parallel.*;
import sun.jvm.hotspot.memory.*;
@@ -438,11 +439,13 @@
} else if (heap instanceof G1CollectedHeap) {
G1CollectedHeap g1h = (G1CollectedHeap) heap;
g1h.heapRegionIterate(lrc);
+ } else if (heap instanceof EpsilonHeap) {
+ EpsilonHeap eh = (EpsilonHeap) heap;
+ liveRegions.add(eh.space().top());
+ liveRegions.add(eh.space().bottom());
} else {
if (Assert.ASSERTS_ENABLED) {
- Assert.that(false, "Expecting GenCollectedHeap, G1CollectedHeap, " +
- "or ParallelScavengeHeap, but got " +
- heap.getClass().getName());
+ Assert.that(false, "Unexpected CollectedHeap type: " + heap.getClass().getName());
}
}
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Oop.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Oop.java Wed Jun 13 11:01:25 2018 -0700
@@ -164,7 +164,7 @@
tty.print("null");
} else {
obj.printValueOn(tty);
- tty.print(" @ " + obj.getHandle());
+ tty.print(" @ " + VM.getVM().getUniverse().heap().oopAddressDescription(obj.getHandle()));
}
}
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/OopField.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/OopField.java Wed Jun 13 11:01:25 2018 -0700
@@ -54,7 +54,8 @@
if (!isVMField() && !obj.isInstance() && !obj.isArray()) {
throw new InternalError(obj.toString());
}
- return obj.getHandle().getOopHandleAt(getOffset());
+
+ return VM.getVM().getUniverse().heap().oop_load_at(obj.getHandle(), getOffset());
}
public Oop getValue(VMObject obj) {
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VMOps.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VMOps.java Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 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
@@ -54,6 +54,7 @@
CMS_Initial_Mark,
CMS_Final_Remark,
G1CollectFull,
+ ZOperation,
G1CollectForAllocation,
G1IncCollectionPause,
EnableBiasedLocking,
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/HeapSummary.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/HeapSummary.java Wed Jun 13 11:01:25 2018 -0700
@@ -25,10 +25,12 @@
package sun.jvm.hotspot.tools;
import java.util.*;
+import sun.jvm.hotspot.gc.epsilon.*;
import sun.jvm.hotspot.gc.g1.*;
import sun.jvm.hotspot.gc.parallel.*;
import sun.jvm.hotspot.gc.serial.*;
import sun.jvm.hotspot.gc.shared.*;
+import sun.jvm.hotspot.gc.z.*;
import sun.jvm.hotspot.debugger.JVMDebugger;
import sun.jvm.hotspot.memory.*;
import sun.jvm.hotspot.oops.*;
@@ -124,6 +126,12 @@
printValMB("used = ", oldGen.used());
printValMB("free = ", oldFree);
System.out.println(alignment + (double)oldGen.used() * 100.0 / oldGen.capacity() + "% used");
+ } else if (heap instanceof EpsilonHeap) {
+ EpsilonHeap eh = (EpsilonHeap) heap;
+ printSpace(eh.space());
+ } else if (heap instanceof ZCollectedHeap) {
+ ZCollectedHeap zheap = (ZCollectedHeap) heap;
+ zheap.printOn(System.out);
} else {
throw new RuntimeException("unknown CollectedHeap type : " + heap.getClass());
}
@@ -161,6 +169,20 @@
return;
}
+ l = getFlagValue("UseEpsilonGC", flagMap);
+ if (l == 1L) {
+ System.out.println("Epsilon (no-op) GC");
+ return;
+ }
+
+ l = getFlagValue("UseZGC", flagMap);
+ if (l == 1L) {
+ System.out.print("ZGC ");
+ l = getFlagValue("ParallelGCThreads", flagMap);
+ System.out.println("with " + l + " thread(s)");
+ return;
+ }
+
System.out.println("Mark Sweep Compact GC");
}
--- a/src/jdk.jdi/share/classes/com/sun/jdi/ThreadReference.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/jdk.jdi/share/classes/com/sun/jdi/ThreadReference.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -118,7 +118,6 @@
* @throws InvalidTypeException if <code>throwable</code> is not
* an instance of java.lang.Throwable in the target VM.
* @throws VMCannotBeModifiedException if the VirtualMachine is read-only - see {@link VirtualMachine#canBeModified()}.
- * @see java.lang.Thread#stop(Throwable)
*/
@SuppressWarnings("javadoc")
void stop(ObjectReference throwable) throws InvalidTypeException;
--- a/src/jdk.jfr/share/conf/jfr/default.jfc Wed Jun 13 09:57:59 2018 -0700
+++ b/src/jdk.jfr/share/conf/jfr/default.jfc Wed Jun 13 11:01:25 2018 -0700
@@ -614,6 +614,25 @@
<setting name="enabled">true</setting>
</event>
+ <event name="jdk.ZPageAllocation">
+ <setting name="enabled">true</setting>
+ <setting name="threshold">10 ms</setting>
+ </event>
+
+ <event name="jdk.ZThreadPhase">
+ <setting name="enabled">true</setting>
+ <setting name="threshold">0 ms</setting>
+ </event>
+
+ <event name="jdk.ZStatisticsCounter">
+ <setting name="enabled">true</setting>
+ <setting name="threshold">10 ms</setting>
+ </event>
+
+ <event name="jdk.ZStatisticsSampler">
+ <setting name="enabled">true</setting>
+ <setting name="threshold">10 ms</setting>
+ </event>
--- a/src/jdk.jfr/share/conf/jfr/profile.jfc Wed Jun 13 09:57:59 2018 -0700
+++ b/src/jdk.jfr/share/conf/jfr/profile.jfc Wed Jun 13 11:01:25 2018 -0700
@@ -614,6 +614,25 @@
<setting name="enabled">true</setting>
</event>
+ <event name="jdk.ZPageAllocation">
+ <setting name="enabled">true</setting>
+ <setting name="threshold">10 ms</setting>
+ </event>
+
+ <event name="jdk.ZThreadPhase">
+ <setting name="enabled">true</setting>
+ <setting name="threshold">0 ms</setting>
+ </event>
+
+ <event name="jdk.ZStatisticsCounter">
+ <setting name="threshold">10 ms</setting>
+ <setting name="enabled">true</setting>
+ </event>
+
+ <event name="jdk.ZStatisticsSampler">
+ <setting name="enabled">true</setting>
+ <setting name="threshold">10 ms</setting>
+ </event>
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_ja.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_ja.java Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -91,6 +91,7 @@
"\u5927\u6b63", // Taisho
"\u662d\u548c", // Showa
"\u5e73\u6210", // Heisei
+ "\u65b0\u5143\u53f7", // NewEra
};
final String[] rocEras = {
"\u6c11\u56fd\u524d",
--- a/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_ja.java Wed Jun 13 09:57:59 2018 -0700
+++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/JavaTimeSupplementary_ja.java Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2016, 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
@@ -154,6 +154,7 @@
"\u5927\u6b63",
"\u662d\u548c",
"\u5e73\u6210",
+ "\u65b0\u5143\u53f7", // NewEra
};
final String[] sharedJavaTimeShortEras = {
--- a/test/hotspot/gtest/gc/shared/test_oopStorage.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/gtest/gc/shared/test_oopStorage.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -1203,7 +1203,7 @@
class OopStorageAllocateListTest : public OopStorageBlockCollectionTest {};
TEST_F(OopStorageAllocateListTest, empty_list) {
- AllocateList list(&OopBlock::get_allocate_entry);
+ AllocateList list;
EXPECT_TRUE(is_list_empty(list));
EXPECT_EQ(NULL_BLOCK, list.head());
@@ -1212,7 +1212,7 @@
}
TEST_F(OopStorageAllocateListTest, push_back) {
- AllocateList list(&OopBlock::get_allocate_entry);
+ AllocateList list;
for (size_t i = 0; i < nvalues; ++i) {
list.push_back(*values[i]);
@@ -1242,7 +1242,7 @@
}
TEST_F(OopStorageAllocateListTest, push_front) {
- AllocateList list(&OopBlock::get_allocate_entry);
+ AllocateList list;
for (size_t i = 0; i < nvalues; ++i) {
list.push_front(*values[i]);
@@ -1273,7 +1273,7 @@
class OopStorageAllocateListTestWithList : public OopStorageAllocateListTest {
public:
- OopStorageAllocateListTestWithList() : list(&OopBlock::get_allocate_entry) {
+ OopStorageAllocateListTestWithList() : list() {
for (size_t i = 0; i < nvalues; ++i) {
list.push_back(*values[i]);
}
@@ -1345,7 +1345,7 @@
}
TEST_F(OopStorageAllocateListTest, single) {
- AllocateList list(&OopBlock::get_allocate_entry);
+ AllocateList list;
list.push_back(*values[0]);
EXPECT_EQ(NULL_BLOCK, list.next(*values[0]));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/gc/z/test_zAddress.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zAddress.inline.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "unittest.hpp"
+
+class ZAddressTest : public ::testing::Test {
+protected:
+ static void is_good_bit(uintptr_t bit_mask) {
+ // Setup
+ uintptr_t mask_before = ZAddressGoodMask;
+
+ ZAddressMasks::set_good_mask(bit_mask);
+
+ // Test that a pointer with only the given bit is considered good.
+ EXPECT_EQ(ZAddress::is_good(ZAddressMetadataMarked0), (bit_mask == ZAddressMetadataMarked0));
+ EXPECT_EQ(ZAddress::is_good(ZAddressMetadataMarked1), (bit_mask == ZAddressMetadataMarked1));
+ EXPECT_EQ(ZAddress::is_good(ZAddressMetadataRemapped), (bit_mask == ZAddressMetadataRemapped));
+
+ // Test that a pointer with the given bit and some extra bits is considered good.
+ EXPECT_EQ(ZAddress::is_good(ZAddressMetadataMarked0 | 0x8),(bit_mask == ZAddressMetadataMarked0));
+ EXPECT_EQ(ZAddress::is_good(ZAddressMetadataMarked1 | 0x8), (bit_mask == ZAddressMetadataMarked1));
+ EXPECT_EQ(ZAddress::is_good(ZAddressMetadataRemapped | 0x8), (bit_mask == ZAddressMetadataRemapped));
+
+ // Test that null is not considered good.
+ EXPECT_FALSE(ZAddress::is_good(0));
+
+ // Teardown
+ ZAddressMasks::set_good_mask(mask_before);
+ }
+
+ static void is_good_or_null_bit(uintptr_t bit_mask) {
+ // Setup
+ uintptr_t mask_before = ZAddressGoodMask;
+
+ ZAddressMasks::set_good_mask(bit_mask);
+
+ // Test that a pointer with only the given bit is considered good.
+ EXPECT_EQ(ZAddress::is_good_or_null(ZAddressMetadataMarked0), (bit_mask == ZAddressMetadataMarked0));
+ EXPECT_EQ(ZAddress::is_good_or_null(ZAddressMetadataMarked1), (bit_mask == ZAddressMetadataMarked1));
+ EXPECT_EQ(ZAddress::is_good_or_null(ZAddressMetadataRemapped), (bit_mask == ZAddressMetadataRemapped));
+
+ // Test that a pointer with the given bit and some extra bits is considered good.
+ EXPECT_EQ(ZAddress::is_good_or_null(ZAddressMetadataMarked0 | 0x8), (bit_mask == ZAddressMetadataMarked0));
+ EXPECT_EQ(ZAddress::is_good_or_null(ZAddressMetadataMarked1 | 0x8), (bit_mask == ZAddressMetadataMarked1));
+ EXPECT_EQ(ZAddress::is_good_or_null(ZAddressMetadataRemapped | 0x8), (bit_mask == ZAddressMetadataRemapped));
+
+ // Test that null is considered good_or_null.
+ EXPECT_TRUE(ZAddress::is_good_or_null(0));
+
+ // Teardown
+ ZAddressMasks::set_good_mask(mask_before);
+ }
+
+ static void finalizable() {
+ // Setup
+ ZAddressMasks::initialize();
+ ZAddressMasks::flip_to_marked();
+
+ // Test that a normal good pointer is good and weak good, but not finalizable
+ const uintptr_t addr1 = ZAddress::good(1);
+ EXPECT_FALSE(ZAddress::is_finalizable(addr1));
+ EXPECT_TRUE(ZAddress::is_marked(addr1));
+ EXPECT_FALSE(ZAddress::is_remapped(addr1));
+ EXPECT_TRUE(ZAddress::is_weak_good(addr1));
+ EXPECT_TRUE(ZAddress::is_weak_good_or_null(addr1));
+ EXPECT_TRUE(ZAddress::is_good(addr1));
+ EXPECT_TRUE(ZAddress::is_good_or_null(addr1));
+
+ // Test that a finalizable good pointer is finalizable and weak good, but not good
+ const uintptr_t addr2 = ZAddress::finalizable_good(1);
+ EXPECT_TRUE(ZAddress::is_finalizable(addr2));
+ EXPECT_TRUE(ZAddress::is_marked(addr2));
+ EXPECT_FALSE(ZAddress::is_remapped(addr2));
+ EXPECT_TRUE(ZAddress::is_weak_good(addr2));
+ EXPECT_TRUE(ZAddress::is_weak_good_or_null(addr2));
+ EXPECT_FALSE(ZAddress::is_good(addr2));
+ EXPECT_FALSE(ZAddress::is_good_or_null(addr2));
+
+ // Flip to remapped and test that it's no longer weak good
+ ZAddressMasks::flip_to_remapped();
+ EXPECT_TRUE(ZAddress::is_finalizable(addr2));
+ EXPECT_TRUE(ZAddress::is_marked(addr2));
+ EXPECT_FALSE(ZAddress::is_remapped(addr2));
+ EXPECT_FALSE(ZAddress::is_weak_good(addr2));
+ EXPECT_FALSE(ZAddress::is_weak_good_or_null(addr2));
+ EXPECT_FALSE(ZAddress::is_good(addr2));
+ EXPECT_FALSE(ZAddress::is_good_or_null(addr2));
+ }
+};
+
+TEST_F(ZAddressTest, is_good) {
+ is_good_bit(ZAddressMetadataMarked0);
+ is_good_bit(ZAddressMetadataMarked1);
+ is_good_bit(ZAddressMetadataRemapped);
+}
+
+TEST_F(ZAddressTest, is_good_or_null) {
+ is_good_or_null_bit(ZAddressMetadataMarked0);
+ is_good_or_null_bit(ZAddressMetadataMarked1);
+ is_good_or_null_bit(ZAddressMetadataRemapped);
+}
+
+TEST_F(ZAddressTest, is_weak_good_or_null) {
+#define check_is_weak_good_or_null(value) \
+ EXPECT_EQ(ZAddress::is_weak_good_or_null(value), \
+ (ZAddress::is_good_or_null(value) || ZAddress::is_remapped(value))) \
+ << "is_good_or_null: " << ZAddress::is_good_or_null(value) \
+ << " is_remaped: " << ZAddress::is_remapped(value) \
+ << " is_good_or_null_or_remapped: " << ZAddress::is_weak_good_or_null(value)
+
+ check_is_weak_good_or_null((uintptr_t)NULL);
+ check_is_weak_good_or_null(ZAddressMetadataMarked0);
+ check_is_weak_good_or_null(ZAddressMetadataMarked1);
+ check_is_weak_good_or_null(ZAddressMetadataRemapped);
+ check_is_weak_good_or_null((uintptr_t)0x123);
+}
+
+TEST_F(ZAddressTest, finalizable) {
+ finalizable();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/gc/z/test_zArray.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zArray.inline.hpp"
+#include "unittest.hpp"
+
+TEST(ZArrayTest, test_add) {
+ ZArray<int> a;
+
+ // Add elements
+ for (int i = 0; i < 10; i++) {
+ a.add(i);
+ }
+
+ // Check size
+ ASSERT_EQ(a.size(), 10u);
+
+ // Check elements
+ for (int i = 0; i < 10; i++) {
+ EXPECT_EQ(a.at(i), i);
+ }
+}
+
+TEST(ZArrayTest, test_clear) {
+ ZArray<int> a;
+
+ // Add elements
+ for (int i = 0; i < 10; i++) {
+ a.add(i);
+ }
+
+ // Check size
+ ASSERT_EQ(a.size(), 10u);
+ ASSERT_EQ(a.is_empty(), false);
+
+ // Clear elements
+ a.clear();
+
+ // Check size
+ ASSERT_EQ(a.size(), 0u);
+ ASSERT_EQ(a.is_empty(), true);
+
+ // Add element
+ a.add(11);
+
+ // Check size
+ ASSERT_EQ(a.size(), 1u);
+ ASSERT_EQ(a.is_empty(), false);
+
+ // Clear elements
+ a.clear();
+
+ // Check size
+ ASSERT_EQ(a.size(), 0u);
+ ASSERT_EQ(a.is_empty(), true);
+}
+
+TEST(ZArrayTest, test_iterator) {
+ ZArray<int> a;
+
+ // Add elements
+ for (int i = 0; i < 10; i++) {
+ a.add(i);
+ }
+
+ // Iterate
+ int count = 0;
+ ZArrayIterator<int> iter(&a);
+ for (int value; iter.next(&value);) {
+ ASSERT_EQ(a.at(count), count);
+ count++;
+ }
+
+ // Check count
+ ASSERT_EQ(count, 10);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/gc/z/test_zBitField.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zBitField.hpp"
+#include "unittest.hpp"
+
+TEST(ZBitFieldTest, test) {
+ typedef ZBitField<uint64_t, bool, 0, 1> field_bool;
+ typedef ZBitField<uint64_t, uint8_t, 1, 8> field_uint8;
+ typedef ZBitField<uint64_t, uint16_t, 2, 16> field_uint16;
+ typedef ZBitField<uint64_t, uint32_t, 32, 32> field_uint32;
+ typedef ZBitField<uint64_t, uint64_t, 0, 63> field_uint64;
+ typedef ZBitField<uint64_t, void*, 1, 61, 3> field_pointer;
+
+ uint64_t entry;
+
+ {
+ const bool value = false;
+ entry = field_bool::encode(value);
+ EXPECT_EQ(field_bool::decode(entry), value) << "Should be equal";
+ }
+
+ {
+ const bool value = true;
+ entry = field_bool::encode(value);
+ EXPECT_EQ(field_bool::decode(entry), value) << "Should be equal";
+ }
+
+ {
+ const uint8_t value = ~(uint8_t)0;
+ entry = field_uint8::encode(value);
+ EXPECT_EQ(field_uint8::decode(entry), value) << "Should be equal";
+ }
+
+ {
+ const uint16_t value = ~(uint16_t)0;
+ entry = field_uint16::encode(value);
+ EXPECT_EQ(field_uint16::decode(entry), value) << "Should be equal";
+ }
+
+ {
+ const uint32_t value = ~(uint32_t)0;
+ entry = field_uint32::encode(value);
+ EXPECT_EQ(field_uint32::decode(entry), value) << "Should be equal";
+ }
+
+ {
+ const uint64_t value = ~(uint64_t)0 >> 1;
+ entry = field_uint64::encode(value);
+ EXPECT_EQ(field_uint64::decode(entry), value) << "Should be equal";
+ }
+
+ {
+ void* const value = (void*)(~(uintptr_t)0 << 3);
+ entry = field_pointer::encode(value);
+ EXPECT_EQ(field_pointer::decode(entry), value) << "Should be equal";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/gc/z/test_zBitMap.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zBitMap.inline.hpp"
+#include "unittest.hpp"
+
+class ZBitMapTest : public ::testing::Test {
+protected:
+ static void test_set_pair_unset(size_t size, bool finalizable) {
+ ZBitMap bitmap(size);
+
+ for (BitMap::idx_t i = 0; i < size - 1; i++) {
+ if ((i + 1) % BitsPerWord == 0) {
+ // Can't set pairs of bits in different words.
+ continue;
+ }
+
+ // ZBitMaps are not cleared when constructed.
+ bitmap.clear();
+
+ bool inc_live = false;
+
+ bool ret = bitmap.par_set_bit_pair(i, finalizable, inc_live);
+ EXPECT_TRUE(ret) << "Failed to set bit";
+ EXPECT_TRUE(inc_live) << "Should have set inc_live";
+
+ // First bit should always be set
+ EXPECT_TRUE(bitmap.at(i)) << "Should be set";
+
+ // Second bit should only be set when marking strong
+ EXPECT_NE(bitmap.at(i + 1), finalizable);
+ }
+ }
+
+ static void test_set_pair_set(size_t size, bool finalizable) {
+ ZBitMap bitmap(size);
+
+ for (BitMap::idx_t i = 0; i < size - 1; i++) {
+ if ((i + 1) % BitsPerWord == 0) {
+ // Can't set pairs of bits in different words.
+ continue;
+ }
+
+ // Fill the bitmap with ones.
+ bitmap.set_range(0, size);
+
+ bool inc_live = false;
+
+ bool ret = bitmap.par_set_bit_pair(i, finalizable, inc_live);
+ EXPECT_FALSE(ret) << "Should not succeed setting bit";
+ EXPECT_FALSE(inc_live) << "Should not have set inc_live";
+
+ // Both bits were pre-set.
+ EXPECT_TRUE(bitmap.at(i)) << "Should be set";
+ EXPECT_TRUE(bitmap.at(i + 1)) << "Should be set";
+ }
+ }
+
+ static void test_set_pair_set(bool finalizable) {
+ test_set_pair_set(2, finalizable);
+ test_set_pair_set(62, finalizable);
+ test_set_pair_set(64, finalizable);
+ test_set_pair_set(66, finalizable);
+ test_set_pair_set(126, finalizable);
+ test_set_pair_set(128, finalizable);
+ }
+
+ static void test_set_pair_unset(bool finalizable) {
+ test_set_pair_unset(2, finalizable);
+ test_set_pair_unset(62, finalizable);
+ test_set_pair_unset(64, finalizable);
+ test_set_pair_unset(66, finalizable);
+ test_set_pair_unset(126, finalizable);
+ test_set_pair_unset(128, finalizable);
+ }
+
+};
+
+TEST_F(ZBitMapTest, test_set_pair_set) {
+ test_set_pair_set(false);
+ test_set_pair_set(true);
+}
+
+TEST_F(ZBitMapTest, test_set_pair_unset) {
+ test_set_pair_unset(false);
+ test_set_pair_unset(true);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/gc/z/test_zForwardingTable.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zForwardingTable.inline.hpp"
+#include "unittest.hpp"
+
+using namespace testing;
+
+#define CAPTURE_DELIM "\n"
+#define CAPTURE1(expression) #expression << " evaluates to " << expression
+#define CAPTURE2(e0, e1) CAPTURE1(e0) << CAPTURE_DELIM << CAPTURE1(e1)
+
+#define CAPTURE(expression) CAPTURE1(expression)
+
+class ZForwardingTableTest : public Test {
+public:
+ // Helper functions
+
+ static bool is_power_of_2(size_t value) {
+ return ::is_power_of_2((intptr_t)value);
+ }
+
+ class SequenceToFromIndex : AllStatic {
+ public:
+ static uintptr_t even(uint32_t sequence_number) {
+ return sequence_number * 2;
+ }
+ static uintptr_t odd(uint32_t sequence_number) {
+ return even(sequence_number) + 1;
+ }
+ static uintptr_t one_to_one(uint32_t sequence_number) {
+ return sequence_number;
+ }
+ };
+
+ // Test functions
+
+ static void setup(ZForwardingTable& table) {
+ EXPECT_PRED1(is_power_of_2, table._size) << CAPTURE(table._size);
+ }
+
+ static void find_empty(ZForwardingTable& table) {
+ size_t size = table._size;
+ size_t entries_to_check = size * 2;
+
+ for (uint32_t i = 0; i < entries_to_check; i++) {
+ uintptr_t from_index = SequenceToFromIndex::one_to_one(i);
+
+ EXPECT_TRUE(table.find(from_index).is_empty()) << CAPTURE2(from_index, size);
+ }
+
+ EXPECT_TRUE(table.find(uintptr_t(-1)).is_empty()) << CAPTURE(size);
+ }
+
+ static void find_full(ZForwardingTable& table) {
+ size_t size = table._size;
+ size_t entries_to_populate = size;
+
+ // Populate
+ for (uint32_t i = 0; i < entries_to_populate; i++) {
+ uintptr_t from_index = SequenceToFromIndex::one_to_one(i);
+
+ ZForwardingTableCursor cursor;
+ ZForwardingTableEntry entry = table.find(from_index, &cursor);
+ ASSERT_TRUE(entry.is_empty()) << CAPTURE2(from_index, size);
+
+ table.insert(from_index, from_index, &cursor);
+ }
+
+ // Verify
+ for (uint32_t i = 0; i < entries_to_populate; i++) {
+ uintptr_t from_index = SequenceToFromIndex::one_to_one(i);
+
+ ZForwardingTableEntry entry = table.find(from_index);
+ ASSERT_FALSE(entry.is_empty()) << CAPTURE2(from_index, size);
+
+ ASSERT_EQ(entry.from_index(), from_index) << CAPTURE(size);
+ ASSERT_EQ(entry.to_offset(), from_index) << CAPTURE(size);
+ }
+ }
+
+ static void find_every_other(ZForwardingTable& table) {
+ size_t size = table._size;
+ size_t entries_to_populate = size / 2;
+
+ // Populate even from indices
+ for (uint32_t i = 0; i < entries_to_populate; i++) {
+ uintptr_t from_index = SequenceToFromIndex::even(i);
+
+ ZForwardingTableCursor cursor;
+ ZForwardingTableEntry entry = table.find(from_index, &cursor);
+ ASSERT_TRUE(entry.is_empty()) << CAPTURE2(from_index, size);
+
+ table.insert(from_index, from_index, &cursor);
+ }
+
+ // Verify populated even indices
+ for (uint32_t i = 0; i < entries_to_populate; i++) {
+ uintptr_t from_index = SequenceToFromIndex::even(i);
+
+ ZForwardingTableCursor cursor;
+ ZForwardingTableEntry entry = table.find(from_index, &cursor);
+ ASSERT_FALSE(entry.is_empty()) << CAPTURE2(from_index, size);
+
+ ASSERT_EQ(entry.from_index(), from_index) << CAPTURE(size);
+ ASSERT_EQ(entry.to_offset(), from_index) << CAPTURE(size);
+ }
+
+ // Verify empty odd indices
+ //
+ // This check could be done on a larger range of sequence numbers,
+ // but currently entries_to_populate is used.
+ for (uint32_t i = 0; i < entries_to_populate; i++) {
+ uintptr_t from_index = SequenceToFromIndex::odd(i);
+
+ ZForwardingTableEntry entry = table.find(from_index);
+
+ ASSERT_TRUE(entry.is_empty()) << CAPTURE2(from_index, size);
+ }
+ }
+
+ static void test(void (*function)(ZForwardingTable&), uint32_t size) {
+ // Setup
+ ZForwardingTable table;
+ table.setup(size);
+ ASSERT_FALSE(table.is_null());
+
+ // Actual test function
+ (*function)(table);
+
+ // Teardown
+ table.reset();
+ ASSERT_TRUE(table.is_null());
+ }
+
+ // Run the given function with a few different input values.
+ static void test(void (*function)(ZForwardingTable&)) {
+ test(function, 1);
+ test(function, 2);
+ test(function, 3);
+ test(function, 4);
+ test(function, 7);
+ test(function, 8);
+ test(function, 1023);
+ test(function, 1024);
+ test(function, 1025);
+ }
+};
+
+TEST_F(ZForwardingTableTest, setup) {
+ test(&ZForwardingTableTest::setup);
+}
+
+TEST_F(ZForwardingTableTest, find_empty) {
+ test(&ZForwardingTableTest::find_empty);
+}
+
+TEST_F(ZForwardingTableTest, find_full) {
+ test(&ZForwardingTableTest::find_full);
+}
+
+TEST_F(ZForwardingTableTest, find_every_other) {
+ test(&ZForwardingTableTest::find_every_other);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/gc/z/test_zList.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zList.inline.hpp"
+#include "unittest.hpp"
+
+#ifndef PRODUCT
+
+class ZTestEntry {
+ friend class ZList<ZTestEntry>;
+
+private:
+ const int _id;
+ ZListNode<ZTestEntry> _node;
+
+public:
+ ZTestEntry(int id) :
+ _id(id),
+ _node() {}
+
+ int id() const {
+ return _id;
+ }
+};
+
+class ZListTest : public ::testing::Test {
+protected:
+ static void assert_sorted(ZList<ZTestEntry>* list) {
+ // Iterate forward
+ {
+ int count = list->first()->id();
+ ZListIterator<ZTestEntry> iter(list);
+ for (ZTestEntry* entry; iter.next(&entry);) {
+ ASSERT_EQ(entry->id(), count);
+ count++;
+ }
+ }
+
+ // Iterate backward
+ {
+ int count = list->last()->id();
+ ZListReverseIterator<ZTestEntry> iter(list);
+ for (ZTestEntry* entry; iter.next(&entry);) {
+ EXPECT_EQ(entry->id(), count);
+ count--;
+ }
+ }
+ }
+};
+
+TEST_F(ZListTest, test_insert) {
+ ZList<ZTestEntry> list;
+ ZTestEntry e0(0);
+ ZTestEntry e1(1);
+ ZTestEntry e2(2);
+ ZTestEntry e3(3);
+ ZTestEntry e4(4);
+ ZTestEntry e5(5);
+
+ list.insert_first(&e2);
+ list.insert_before(&e2, &e1);
+ list.insert_after(&e2, &e3);
+ list.insert_last(&e4);
+ list.insert_first(&e0);
+ list.insert_last(&e5);
+
+ EXPECT_EQ(list.size(), 6u);
+ assert_sorted(&list);
+}
+
+TEST_F(ZListTest, test_remove) {
+ // Remove first
+ {
+ ZList<ZTestEntry> list;
+ ZTestEntry e0(0);
+ ZTestEntry e1(1);
+ ZTestEntry e2(2);
+ ZTestEntry e3(3);
+ ZTestEntry e4(4);
+ ZTestEntry e5(5);
+
+ list.insert_last(&e0);
+ list.insert_last(&e1);
+ list.insert_last(&e2);
+ list.insert_last(&e3);
+ list.insert_last(&e4);
+ list.insert_last(&e5);
+
+ EXPECT_EQ(list.size(), 6u);
+
+ for (int i = 0; i < 6; i++) {
+ ZTestEntry* e = list.remove_first();
+ EXPECT_EQ(e->id(), i);
+ }
+
+ EXPECT_EQ(list.size(), 0u);
+ }
+
+ // Remove last
+ {
+ ZList<ZTestEntry> list;
+ ZTestEntry e0(0);
+ ZTestEntry e1(1);
+ ZTestEntry e2(2);
+ ZTestEntry e3(3);
+ ZTestEntry e4(4);
+ ZTestEntry e5(5);
+
+ list.insert_last(&e0);
+ list.insert_last(&e1);
+ list.insert_last(&e2);
+ list.insert_last(&e3);
+ list.insert_last(&e4);
+ list.insert_last(&e5);
+
+ EXPECT_EQ(list.size(), 6u);
+
+ for (int i = 5; i >= 0; i--) {
+ ZTestEntry* e = list.remove_last();
+ EXPECT_EQ(e->id(), i);
+ }
+
+ EXPECT_EQ(list.size(), 0u);
+ }
+}
+
+TEST_F(ZListTest, test_transfer) {
+ // Transfer empty to empty
+ {
+ ZList<ZTestEntry> list0;
+ ZList<ZTestEntry> list1;
+
+ EXPECT_TRUE(list0.is_empty());
+ EXPECT_TRUE(list1.is_empty());
+
+ list0.transfer(&list1);
+
+ EXPECT_TRUE(list0.is_empty());
+ EXPECT_TRUE(list1.is_empty());
+ }
+
+ // Transfer non-empty to empty
+ {
+ ZList<ZTestEntry> list0;
+ ZList<ZTestEntry> list1;
+ ZTestEntry e0(0);
+ ZTestEntry e1(1);
+ ZTestEntry e2(2);
+ ZTestEntry e3(3);
+ ZTestEntry e4(4);
+ ZTestEntry e5(5);
+
+ list1.insert_last(&e0);
+ list1.insert_last(&e1);
+ list1.insert_last(&e2);
+ list1.insert_last(&e3);
+ list1.insert_last(&e4);
+ list1.insert_last(&e5);
+
+ EXPECT_EQ(list0.size(), 0u);
+ EXPECT_EQ(list1.size(), 6u);
+
+ list0.transfer(&list1);
+
+ EXPECT_EQ(list0.size(), 6u);
+ EXPECT_EQ(list1.size(), 0u);
+
+ assert_sorted(&list0);
+ }
+
+ // Transfer non-empty to non-empty
+ {
+ ZList<ZTestEntry> list0;
+ ZList<ZTestEntry> list1;
+ ZTestEntry e0(0);
+ ZTestEntry e1(1);
+ ZTestEntry e2(2);
+ ZTestEntry e3(3);
+ ZTestEntry e4(4);
+ ZTestEntry e5(5);
+
+ list0.insert_last(&e0);
+ list0.insert_last(&e1);
+ list0.insert_last(&e2);
+
+ list1.insert_last(&e3);
+ list1.insert_last(&e4);
+ list1.insert_last(&e5);
+
+ EXPECT_EQ(list0.size(), 3u);
+ EXPECT_EQ(list1.size(), 3u);
+
+ list0.transfer(&list1);
+
+ EXPECT_EQ(list0.size(), 6u);
+ EXPECT_EQ(list1.size(), 0u);
+
+ assert_sorted(&list0);
+ }
+}
+
+#endif // PRODUCT
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/gc/z/test_zLiveMap.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zLiveMap.inline.hpp"
+#include "unittest.hpp"
+
+class ZLiveMapTest : public ::testing::Test {
+protected:
+ static void strongly_live_for_large_zpage() {
+ // Large ZPages only have room for one object.
+ ZLiveMap livemap(1);
+
+ bool inc_live;
+ uintptr_t object = 0u;
+
+ // Mark the object strong.
+ livemap.set_atomic(object, false /* finalizable */, inc_live);
+
+ // Check that both bits are in the same segment.
+ ASSERT_EQ(livemap.index_to_segment(0), livemap.index_to_segment(1));
+
+ // Check that the object was marked.
+ ASSERT_TRUE(livemap.get(0));
+
+ // Check that the object was strongly marked.
+ ASSERT_TRUE(livemap.get(1));
+
+ ASSERT_TRUE(inc_live);
+ }
+};
+
+TEST_F(ZLiveMapTest, strongly_live_for_large_zpage) {
+ strongly_live_for_large_zpage();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/gc/z/test_zPhysicalMemory.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zPhysicalMemory.inline.hpp"
+#include "utilities/debug.hpp"
+#include "unittest.hpp"
+
+#if defined(AMD64)
+
+TEST(ZPhysicalMemorySegmentTest, split) {
+ const size_t SegmentSize = 2 * M;
+
+ ZPhysicalMemorySegment seg(0, 10 * SegmentSize);
+
+ ZPhysicalMemorySegment seg_split0 = seg.split(0 * SegmentSize);
+ EXPECT_EQ(seg_split0.size(), 0 * SegmentSize);
+ EXPECT_EQ( seg.size(), 10 * SegmentSize);
+
+ ZPhysicalMemorySegment seg_split1 = seg.split(5 * SegmentSize);
+ EXPECT_EQ(seg_split1.size(), 5 * SegmentSize);
+ EXPECT_EQ( seg.size(), 5 * SegmentSize);
+
+ ZPhysicalMemorySegment seg_split2 = seg.split(5 * SegmentSize);
+ EXPECT_EQ(seg_split2.size(), 5 * SegmentSize);
+ EXPECT_EQ( seg.size(), 0 * SegmentSize);
+
+ ZPhysicalMemorySegment seg_split3 = seg.split(0 * SegmentSize);
+ EXPECT_EQ(seg_split3.size(), 0 * SegmentSize);
+ EXPECT_EQ( seg.size(), 0 * SegmentSize);
+}
+
+TEST(ZPhysicalMemoryTest, split) {
+ const size_t SegmentSize = 2 * M;
+
+ ZPhysicalMemoryManager pmem_manager(10 * SegmentSize, SegmentSize);
+
+ ZPhysicalMemory pmem = pmem_manager.alloc(8 * SegmentSize);
+ EXPECT_EQ(pmem.nsegments(), 1u) << "wrong number of segments";
+
+ ZPhysicalMemory split0_pmem = pmem.split(SegmentSize);
+ EXPECT_EQ(split0_pmem.nsegments(), 1u);
+ EXPECT_EQ( pmem.nsegments(), 1u);
+ EXPECT_EQ(split0_pmem.size(), 1 * SegmentSize);
+ EXPECT_EQ( pmem.size(), 7 * SegmentSize);
+
+ ZPhysicalMemory split1_pmem = pmem.split(2 * SegmentSize);
+ EXPECT_EQ(split1_pmem.nsegments(), 1u);
+ EXPECT_EQ( pmem.nsegments(), 1u);
+ EXPECT_EQ(split1_pmem.size(), 2 * SegmentSize);
+ EXPECT_EQ( pmem.size(), 5 * SegmentSize);
+
+ ZPhysicalMemory split2_pmem = pmem.split(5 * SegmentSize);
+ EXPECT_EQ(split2_pmem.nsegments(), 1u);
+ EXPECT_EQ( pmem.nsegments(), 1u);
+ EXPECT_EQ(split2_pmem.size(), 5 * SegmentSize);
+ EXPECT_EQ( pmem.size(), 0 * SegmentSize);
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/gc/z/test_zUtils.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zUtils.inline.hpp"
+#include "unittest.hpp"
+
+#include <limits>
+
+template <typename T>
+static T max_alignment() {
+ T max = std::numeric_limits<T>::max();
+ return max ^ (max >> 1);
+}
+
+TEST(ZUtilsTest, round_up_power_of_2) {
+ EXPECT_EQ(ZUtils::round_up_power_of_2(1u), 1u);
+ EXPECT_EQ(ZUtils::round_up_power_of_2(2u), 2u);
+ EXPECT_EQ(ZUtils::round_up_power_of_2(3u), 4u);
+ EXPECT_EQ(ZUtils::round_up_power_of_2(4u), 4u);
+ EXPECT_EQ(ZUtils::round_up_power_of_2(5u), 8u);
+ EXPECT_EQ(ZUtils::round_up_power_of_2(6u), 8u);
+ EXPECT_EQ(ZUtils::round_up_power_of_2(7u), 8u);
+ EXPECT_EQ(ZUtils::round_up_power_of_2(8u), 8u);
+ EXPECT_EQ(ZUtils::round_up_power_of_2(9u), 16u);
+ EXPECT_EQ(ZUtils::round_up_power_of_2(10u), 16u);
+ EXPECT_EQ(ZUtils::round_up_power_of_2(1023u), 1024u);
+ EXPECT_EQ(ZUtils::round_up_power_of_2(1024u), 1024u);
+ EXPECT_EQ(ZUtils::round_up_power_of_2(1025u), 2048u);
+
+ const size_t max = max_alignment<size_t>();
+ EXPECT_EQ(ZUtils::round_up_power_of_2(max - 1), max);
+ EXPECT_EQ(ZUtils::round_up_power_of_2(max), max);
+}
+
+TEST(ZUtilsTest, round_down_power_of_2) {
+ EXPECT_EQ(ZUtils::round_down_power_of_2(1u), 1u);
+ EXPECT_EQ(ZUtils::round_down_power_of_2(2u), 2u);
+ EXPECT_EQ(ZUtils::round_down_power_of_2(3u), 2u);
+ EXPECT_EQ(ZUtils::round_down_power_of_2(4u), 4u);
+ EXPECT_EQ(ZUtils::round_down_power_of_2(5u), 4u);
+ EXPECT_EQ(ZUtils::round_down_power_of_2(6u), 4u);
+ EXPECT_EQ(ZUtils::round_down_power_of_2(7u), 4u);
+ EXPECT_EQ(ZUtils::round_down_power_of_2(8u), 8u);
+ EXPECT_EQ(ZUtils::round_down_power_of_2(9u), 8u);
+ EXPECT_EQ(ZUtils::round_down_power_of_2(10u), 8u);
+ EXPECT_EQ(ZUtils::round_down_power_of_2(1023u), 512u);
+ EXPECT_EQ(ZUtils::round_down_power_of_2(1024u), 1024u);
+ EXPECT_EQ(ZUtils::round_down_power_of_2(1025u), 1024u);
+
+ const size_t max = max_alignment<size_t>();
+ EXPECT_EQ(ZUtils::round_down_power_of_2(max), max);
+ EXPECT_EQ(ZUtils::round_down_power_of_2(max - 1), max / 2);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/gc/z/test_zVirtualMemory.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zVirtualMemory.inline.hpp"
+#include "utilities/debug.hpp"
+#include "unittest.hpp"
+
+TEST(ZVirtualMemory, split) {
+ const size_t PageSize = 2 * M;
+
+ ZVirtualMemory mem(0, 10 * PageSize);
+
+ ZVirtualMemory mem_split0 = mem.split(0 * PageSize);
+ EXPECT_EQ(mem_split0.size(), 0 * PageSize);
+ EXPECT_EQ( mem.size(), 10 * PageSize);
+
+ ZVirtualMemory mem_split1 = mem.split(5u * PageSize);
+ EXPECT_EQ(mem_split1.size(), 5 * PageSize);
+ EXPECT_EQ( mem.size(), 5 * PageSize);
+
+ ZVirtualMemory mem_split2 = mem.split(5u * PageSize);
+ EXPECT_EQ(mem_split2.size(), 5 * PageSize);
+ EXPECT_EQ( mem.size(), 0 * PageSize);
+
+ ZVirtualMemory mem_split3 = mem.split(0 * PageSize);
+ EXPECT_EQ(mem_split3.size(), 0 * PageSize);
+}
--- a/test/hotspot/gtest/runtime/test_committed_virtualmemory.cpp Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/gtest/runtime/test_committed_virtualmemory.cpp Wed Jun 13 11:01:25 2018 -0700
@@ -38,6 +38,8 @@
class CommittedVirtualMemoryTest {
public:
static void test() {
+#ifndef _AIX
+ // See JDK-8202772: temporarily disabled.
Thread* thr = Thread::current();
address stack_end = thr->stack_end();
size_t stack_size = thr->stack_size();
@@ -81,6 +83,7 @@
ASSERT_TRUE(i >= 1);
ASSERT_TRUE(found_stack_top);
ASSERT_TRUE(found_i_addr);
+#endif // !_AIX
}
static void check_covered_pages(address addr, size_t size, address base, size_t touch_pages, int* page_num) {
--- a/test/hotspot/jtreg/ProblemList-graal.txt Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/ProblemList-graal.txt Wed Jun 13 11:01:25 2018 -0700
@@ -143,3 +143,9 @@
vmTestbase/nsk/jvmti/AttachOnDemand/attach024/TestDescription.java 8195630 generic-all
vmTestbase/nsk/jvmti/unit/FollowReferences/followref003/TestDescription.java 8202342 generic-all
+
+vmTestbase/nsk/jvmti/scenarios/hotswap/HS102/hs102t002/TestDescription.java 8204506 macosx-all
+
+compiler/stable/TestStableShort.java 8204346 generic-all
+compiler/stable/TestStableUShort.java 8204346 generic-all
+compiler/stable/TestStableUByte.java 8204346 generic-all
--- a/test/hotspot/jtreg/TEST.ROOT Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/TEST.ROOT Wed Jun 13 11:01:25 2018 -0700
@@ -45,6 +45,8 @@
vm.gc.Serial \
vm.gc.Parallel \
vm.gc.ConcMarkSweep \
+ vm.gc.Epsilon \
+ vm.gc.Z \
vm.jvmci \
vm.emulatedClient \
vm.cpu.features \
--- a/test/hotspot/jtreg/TEST.groups Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/TEST.groups Wed Jun 13 11:01:25 2018 -0700
@@ -174,12 +174,14 @@
-:tier1_gc
tier1_gc_1 = \
+ gc/epsilon/ \
gc/g1/ \
-gc/g1/ihop/TestIHOPErgo.java
tier1_gc_2 = \
sanity/ExecuteInternalVMTests.java \
gc/ \
+ -gc/epsilon/ \
-gc/g1/ \
-gc/logging/TestUnifiedLoggingSwitchStress.java \
-gc/stress \
--- a/test/hotspot/jtreg/compiler/aot/AotCompiler.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/compiler/aot/AotCompiler.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -185,17 +185,17 @@
if (Platform.isX64()) {
@Artifact(organization = "jpg.infra.builddeps",
name = "devkit-windows_x64",
- revision = "VS2013SP4+1.0",
+ revision = "VS2017-15.5.5+1.0",
extension = "tar.gz")
class DevkitWindowsX64 { }
String artifactName = "jpg.infra.builddeps."
+ "devkit-windows_x64-"
- + "VS2013SP4+1.0";
+ + "VS2017-15.5.5+1.0";
Path devkit = ArtifactResolver.resolve(DevkitWindowsX64.class)
.get(artifactName);
linker = devkit.resolve("VC")
.resolve("bin")
- .resolve("amd64")
+ .resolve("x64")
.resolve("link.exe");
}
} else if (Platform.isOSX()) {
@@ -221,13 +221,13 @@
if (Platform.isSparc()) {
@Artifact(organization = "jpg.infra.builddeps",
name = "devkit-solaris_sparcv9",
- revision = "SS12u4-Solaris11u1+1.0",
+ revision = "SS12u4-Solaris11u1+1.1",
extension = "tar.gz")
class DevkitSolarisSparc { }
String artifactName = "jpg.infra.builddeps."
+ "devkit-solaris_sparcv9-"
- + "SS12u4-Solaris11u1+1.0";
+ + "SS12u4-Solaris11u1+1.1";
Path devkit = ArtifactResolver.resolve(DevkitSolarisSparc.class)
.get(artifactName);
linker = devkit.resolve("SS12u4-Solaris11u1")
@@ -285,13 +285,13 @@
} else if (Platform.isX64()) {
@Artifact(organization = "jpg.infra.builddeps",
name = "devkit-linux_x64",
- revision = "gcc4.9.2-OEL6.4+1.1",
+ revision = "gcc7.3.0-OEL6.4+1.0",
extension = "tar.gz")
class DevkitLinuxX64 { }
String artifactName = "jpg.infra.builddeps."
+ "devkit-linux_x64-"
- + "gcc4.9.2-OEL6.4+1.1";
+ + "gcc7.3.0-OEL6.4+1.0";
Path devkit = ArtifactResolver.resolve(DevkitLinuxX64.class)
.get(artifactName);
linker = devkit.resolve("bin")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/gcbarriers/UnsafeIntrinsicsTest.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,376 @@
+/*
+ * Copyright (c) 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.
+ */
+
+/*
+ * @test
+ * @bug 8059022
+ * @modules java.base/jdk.internal.misc:+open
+ * @summary Validate barriers after Unsafe getObject, CAS and swap (GetAndSet)
+ * @requires vm.gc.Z & !vm.graal.enabled
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -XX:+UnlockDiagnosticVMOptions -XX:+ZUnmapBadViews -XX:ZCollectionInterval=1 -XX:-CreateCoredumpOnCrash -XX:CompileCommand=dontinline,*::mergeImpl* compiler.gcbarriers.UnsafeIntrinsicsTest
+ */
+
+package compiler.gcbarriers;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Random;
+import sun.misc.Unsafe;
+
+public class UnsafeIntrinsicsTest {
+
+ /*
+ * This test triggers the loadbarriers by allocating a lot, keeping the objects alive and then
+ * letting them die in a way that maximizes fragmentation.
+ *
+ * All subtests (OperationType's) could run in parallel.
+ */
+
+ static int node_count = 133700;
+ static int thread_count = 4;
+ static int time = Integer.getInteger("time", 4); // seconds per subtest
+
+ static Runner r = new Runner(null, 1, 1, Runner.OperationType.CAS);
+
+ static Node first_node;
+ int epoch = 0;
+
+ public static void main(String[] args) {
+ UnsafeIntrinsicsTest t = new UnsafeIntrinsicsTest();
+
+ t.testWithLocalData(Runner.OperationType.CAS);
+ t.testWithLocalData(Runner.OperationType.Weak_CAS);
+ t.testWithLocalData(Runner.OperationType.CMPX);
+
+ t.testWithSharedData(Runner.OperationType.Swap);
+ t.testWithSharedData(Runner.OperationType.Load);
+ }
+
+ public UnsafeIntrinsicsTest() {
+
+ }
+
+ public void testWithLocalData(Runner.OperationType optype) {
+ System.out.println("Testing " + optype.name() + " with " + thread_count +" thread and " + node_count + " nodes");
+
+ // start mutator threads
+ ArrayList<Thread> thread_list = new ArrayList<Thread>();
+ Random r = new Random(System.nanoTime());
+ for (int i = 0; i < thread_count; i++) {
+
+ setup(); // each thread has its own circle of nodes
+ Thread t = new Thread(new Runner(first_node, time, r.nextLong(), optype));
+ t.start();
+ thread_list.add(t);
+ }
+
+ waitForCompletion(thread_list);
+ countNodes();
+ }
+
+ public void testWithSharedData(Runner.OperationType optype) {
+ System.out.println("Testing " + optype.name() + " with " + thread_count +" thread and " + node_count + " nodes");
+
+ setup(); // All nodes are shared between threads
+ ArrayList<Thread> thread_list = new ArrayList<Thread>();
+ Random r = new Random(System.nanoTime());
+ for (int i = 0; i < thread_count; i++) {
+ Thread t = new Thread(new Runner(first_node, time, r.nextLong(), optype));
+ t.start();
+ thread_list.add(t);
+ }
+
+ waitForCompletion(thread_list);
+ countNodes();
+ }
+
+ public void waitForCompletion(ArrayList<Thread> thread_list) {
+ // do some waiting
+ try {
+ Thread.sleep(time*1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ // wait for all thread to terminate
+ for (int i = 0; i < thread_count; i++) {
+ try {
+ thread_list.get(i).join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ void countNodes() {
+ epoch++;
+ int count = 0;
+ Node node = first_node;
+ while (node.number() < epoch) {
+ node.setNumber(epoch);
+ count++;
+ node = node.next();
+ }
+ System.out.println("Program end, found " + count + " nodes");
+ }
+
+ // Create a circular linked list
+ public void setup() {
+ first_node = new Node();
+ Node last_node = first_node;
+ for (int i = 0; i < node_count; i++) {
+ last_node = new Node(last_node);
+ }
+ first_node.setNext(last_node);
+ }
+}
+
+class Runner implements Runnable {
+
+ OperationType type;
+ Node current;
+ Random r;
+ long time;
+ long seed;
+
+ long milage = 0;
+ long created = 0;
+ long skipped = 0;
+ int iterations = 0;
+
+ static final jdk.internal.misc.Unsafe UNSAFE;
+ static final long offset;
+
+ public enum OperationType {
+ Load("Load"),
+ Swap("Swap"),
+ CAS("CAS"),
+ Weak_CAS("Weak-CAS"),
+ CMPX("CMPX");
+
+ private String name;
+ private OperationType(String name) { this.name = name; }
+ }
+
+ static {
+ try {
+ Field f = jdk.internal.misc.Unsafe.class.getDeclaredField("theUnsafe");
+ f.setAccessible(true);
+ UNSAFE = (jdk.internal.misc.Unsafe) f.get(null);
+ offset = UNSAFE.objectFieldOffset(Node.class.getDeclaredField("next"));
+ } catch (Exception e) {
+ throw new RuntimeException("Unable to get Unsafe instance.", e);
+ }
+ }
+
+ public Runner(Node start, int testtime, long seed, OperationType type) {
+ current = start;
+ time = testtime*1000000000L;
+ r = new Random(seed);
+ this.type = type;
+ }
+
+ @Override
+ public void run() {
+ long starttime = System.nanoTime();
+ while((System.nanoTime() - starttime) < time) {
+ iterations++;
+ // Run a bit
+ int run_length = r.nextInt() & 0xfff;
+ for (int i = 0; i < run_length; i++) {
+ current = current.next();
+ milage++;
+ }
+ // find a start node
+ Node startNode = current;
+ Node expectedNext = startNode.next;
+
+ // Run a bit more
+ int skip_length = (r.nextInt() & 0xff) + 1;
+ for (int i = 0; i < skip_length; i++) {
+ current = current.next();
+ skipped++;
+ }
+
+ // create a branch
+ int branch_length = (r.nextInt() & 0xff) + 1;
+ created += branch_length;
+ Node head = makeBranch(current, branch_length);
+
+ // complete circle, but continue to run on old path
+ boolean test_fail = ((iterations & 0x1) == 0);
+ Node current = merge(startNode, expectedNext, head, test_fail);
+ }
+ System.out.println("Milage: " + milage + " Skipped: " + skipped + " Created: " + created + " iterations: " + iterations);
+ }
+
+ /*
+ * The reason for the duplicated code that is wrapping the unsafe operations is that we want
+ * to test the operations individually. They must not interfere with each other - checking a field
+ * will heal that reference and no operation after can trigger the barrier.
+ *
+ * All mergeImpl*-method are prevented from being inlined.
+ */
+
+ private Node merge(Node startNode, Node expectedNext, Node head, boolean test_fail) {
+ switch (type) {
+ case Load:
+ return mergeImplLoad(startNode, expectedNext, head);
+ case Swap:
+ return mergeImplSwap(startNode, expectedNext, head);
+ case CAS:
+ if (test_fail) {
+ return mergeImplCASFail(startNode, expectedNext, head);
+ } else {
+ return mergeImplCAS(startNode, expectedNext, head);
+ }
+ case Weak_CAS:
+ if (test_fail) {
+ return mergeImplWeakCASFail(startNode, expectedNext, head);
+ } else {
+ return mergeImplWeakCAS(startNode, expectedNext, head);
+ }
+ case CMPX:
+ if (test_fail) {
+ return mergeImplCMPXFail(startNode, expectedNext, head);
+ } else {
+ return mergeImplCMPX(startNode, expectedNext, head);
+ }
+ default:
+ throw new Error("Unimplemented");
+ }
+ }
+
+ private Node mergeImplLoad(Node startNode, Node expectedNext, Node head) {
+ // Atomic load version
+ Node temp = (Node) UNSAFE.getObject(startNode, offset);
+ startNode.setNext(head);
+ return temp;
+ }
+
+ private Node mergeImplSwap(Node startNode, Node expectedNext, Node head) {
+ // Swap version
+ return (Node) UNSAFE.getAndSetObject(startNode, offset, head);
+ }
+
+ private Node mergeImplCAS(Node startNode, Node expectedNext, Node head) {
+ // CAS - should always be true within a single thread - no other thread can have overwritten
+ if (!UNSAFE.compareAndSetObject(startNode, offset, expectedNext, head)) {
+ throw new Error("CAS should always succeed on thread local objects, check you barrier implementation");
+ }
+ return expectedNext; // continue on old circle
+ }
+
+ private Node mergeImplCASFail(Node startNode, Node expectedNext, Node head) {
+ // Force a fail
+ if (UNSAFE.compareAndSetObject(startNode, offset, "fail", head)) {
+ throw new Error("This CAS should always fail, check you barrier implementation");
+ }
+ if (startNode.next() != expectedNext) {
+ throw new Error("Shouldn't have changed");
+ }
+ return current;
+ }
+
+ private Node mergeImplWeakCAS(Node startNode, Node expectedNext, Node head) {
+ // Weak CAS - should always be true within a single thread - no other thread can have overwritten
+ if (!UNSAFE.weakCompareAndSetObject(startNode, offset, expectedNext, head)) {
+ throw new Error("Weak CAS should always succeed on thread local objects, check you barrier implementation");
+ }
+ return expectedNext; // continue on old circle
+ }
+
+ private Node mergeImplWeakCASFail(Node startNode, Node expectedNext, Node head) {
+ // Force a fail
+ if (UNSAFE.weakCompareAndSetObject(startNode, offset, "fail", head)) {
+ throw new Error("This weak CAS should always fail, check you barrier implementation");
+ }
+ if (startNode.next() != expectedNext) {
+ throw new Error("Shouldn't have changed");
+ }
+ return current;
+ }
+
+ private Node mergeImplCMPX(Node startNode, Node expectedNext, Node head) {
+ // CmpX - should always be true within a single thread - no other thread can have overwritten
+ Object res = UNSAFE.compareAndExchangeObject(startNode, offset, expectedNext, head);
+ if (!res.equals(expectedNext)) {
+ throw new Error("Fail CmpX should always succeed on thread local objects, check you barrier implementation");
+ }
+ return expectedNext; // continue on old circle
+ }
+
+ private Node mergeImplCMPXFail(Node startNode, Node expectedNext, Node head) {
+ Object res = UNSAFE.compareAndExchangeObject(startNode, offset, head, head);
+ if (startNode.next() != expectedNext) {
+ throw new Error("Shouldn't have changed");
+ }
+ if (head == expectedNext) {
+ throw new Error("Test malfunction");
+ }
+ if (!res.equals(expectedNext)) {
+ throw new Error("This CmpX should have returned 'expectedNext' when it failed");
+ }
+ if (res.equals(head)) {
+ throw new Error("This CmpX shouldn't have returned head when it failed. count: "+ iterations);
+ }
+
+ return current;
+ }
+
+ // Create a new branch that will replace a part of the circle
+ public Node makeBranch(Node end_node, int count) {
+ Node head = end_node;
+ for (int i = 0; i < count; i++) {
+ head = new Node(head);
+ }
+ return head;
+ }
+}
+
+class Node {
+ Node next;
+ int number = 0;
+
+ public int number() {
+ return number;
+ }
+
+ public void setNumber(int v) {
+ number = v;
+ }
+
+ public Node() {
+ }
+
+ public Node(Node link) {
+ next = link;
+ }
+
+ public void setNext(Node next) {
+ this.next = next;
+ }
+ public Node next() {
+ return next;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/loopstripmining/UnexpectedNodeInOuterLoopWhenCloning.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2018, Red Hat, Inc. All rights reserved.
+ * 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 8202747
+ * @summary C2: assert(mode == ControlAroundStripMined && use == sfpt) failed: missed a node
+ *
+ * @run main/othervm -Xcomp -Xbatch -XX:CompileOnly=UnexpectedNodeInOuterLoopWhenCloning -XX:-TieredCompilation UnexpectedNodeInOuterLoopWhenCloning
+ *
+ */
+
+public class UnexpectedNodeInOuterLoopWhenCloning {
+
+ public static final int N = 400;
+
+ public static double dFld=0.37026;
+ public static int iArrFld[]=new int[N];
+
+ public static void vMeth() {
+
+ int i5=6, i6=-42538, i7=-209, i8=163, i10=-4, i11=191;
+ boolean b=true;
+ double dArr[]=new double[N];
+
+ for (i5 = 3; i5 < 245; i5++) {
+ i7 = 7;
+ while (--i7 > 0) {
+ iArrFld[i7] = -11995;
+ if (b) continue;
+ }
+ for (i8 = 1; i8 < 7; ++i8) {
+ for (i10 = 1; i10 < 2; i10++) {
+ dFld -= i6;
+ i11 += i7;
+ }
+ }
+ }
+ }
+
+ public static void main(String[] strArr) {
+ UnexpectedNodeInOuterLoopWhenCloning _instance = new UnexpectedNodeInOuterLoopWhenCloning();
+ _instance.vMeth();
+ }
+}
--- a/test/hotspot/jtreg/gc/TestAllocateHeapAt.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/gc/TestAllocateHeapAt.java Wed Jun 13 11:01:25 2018 -0700
@@ -24,6 +24,7 @@
/* @test TestAllocateHeapAt.java
* @key gc
* @summary Test to check allocation of Java Heap with AllocateHeapAt option
+ * @requires vm.gc != "Z"
* @library /test/lib
* @modules java.base/jdk.internal.misc
*/
--- a/test/hotspot/jtreg/gc/TestAllocateHeapAtError.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/gc/TestAllocateHeapAtError.java Wed Jun 13 11:01:25 2018 -0700
@@ -24,6 +24,7 @@
/* @test TestAllocateHeapAtError.java
* @key gc
* @summary Test to check correct handling of non-existent directory passed to AllocateHeapAt option
+ * @requires vm.gc != "Z"
* @library /test/lib
* @modules java.base/jdk.internal.misc
*/
@@ -75,4 +76,3 @@
output.shouldNotHaveExitValue(0);
}
}
-
--- a/test/hotspot/jtreg/gc/TestAllocateHeapAtMultiple.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/gc/TestAllocateHeapAtMultiple.java Wed Jun 13 11:01:25 2018 -0700
@@ -26,7 +26,7 @@
* @summary Test to check allocation of Java Heap with AllocateHeapAt option. Has multiple sub-tests to cover different code paths.
* @library /test/lib
* @modules java.base/jdk.internal.misc
- * @requires vm.bits == "64"
+ * @requires vm.bits == "64" & vm.gc != "Z"
*/
import jdk.test.lib.JDKToolFinder;
--- a/test/hotspot/jtreg/gc/TestSoftReferencesBehaviorOnOOME.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/gc/TestSoftReferencesBehaviorOnOOME.java Wed Jun 13 11:01:25 2018 -0700
@@ -25,6 +25,7 @@
* @test TestSoftReferencesBehaviorOnOOME
* @key gc
* @summary Tests that all SoftReferences has been cleared at time of OOM.
+ * @requires vm.gc != "Z"
* @library /test/lib
* @modules java.base/jdk.internal.misc
* @run main/othervm -Xmx128m TestSoftReferencesBehaviorOnOOME 512 2k
--- a/test/hotspot/jtreg/gc/TestVerifyDuringStartup.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/gc/TestVerifyDuringStartup.java Wed Jun 13 11:01:25 2018 -0700
@@ -25,6 +25,7 @@
* @key gc
* @bug 8010463 8011343 8011898
* @summary Simple test run with -XX:+VerifyDuringStartup -XX:-UseTLAB to verify 8010463
+ * @requires vm.gc != "Z"
* @library /test/lib
* @modules java.base/jdk.internal.misc
*/
--- a/test/hotspot/jtreg/gc/TestVerifySilently.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/gc/TestVerifySilently.java Wed Jun 13 11:01:25 2018 -0700
@@ -25,6 +25,7 @@
* @key gc
* @bug 8032771
* @summary Test silent verification.
+ * @requires vm.gc != "Z"
* @library /test/lib
* @modules java.base/jdk.internal.misc
*/
--- a/test/hotspot/jtreg/gc/arguments/TestDisableDefaultGC.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestDisableDefaultGC.java Wed Jun 13 11:01:25 2018 -0700
@@ -43,6 +43,8 @@
"-XX:-UseParallelGC",
"-XX:-UseG1GC",
"-XX:-UseConcMarkSweepGC",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:-UseZGC",
"-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldMatch("Garbage collector not selected");
--- a/test/hotspot/jtreg/gc/arguments/TestMaxMinHeapFreeRatioFlags.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestMaxMinHeapFreeRatioFlags.java Wed Jun 13 11:01:25 2018 -0700
@@ -25,6 +25,7 @@
* @test TestMaxMinHeapFreeRatioFlags
* @key gc
* @summary Verify that heap size changes according to max and min heap free ratios.
+ * @requires vm.gc != "Z"
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/gc/arguments/TestNewRatioFlag.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestNewRatioFlag.java Wed Jun 13 11:01:25 2018 -0700
@@ -26,6 +26,7 @@
* @key gc
* @bug 8025166
* @summary Verify that heap devided among generations according to NewRatio
+ * @requires vm.gc != "Z"
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/gc/arguments/TestNewSizeFlags.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestNewSizeFlags.java Wed Jun 13 11:01:25 2018 -0700
@@ -26,6 +26,7 @@
* @key gc
* @bug 8025166
* @summary Verify that young gen size conforms values specified by NewSize, MaxNewSize and Xmn options
+ * @requires vm.gc != "Z"
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/gc/arguments/TestShrinkHeapInSteps.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestShrinkHeapInSteps.java Wed Jun 13 11:01:25 2018 -0700
@@ -25,6 +25,7 @@
* @test TestShrinkHeapInSteps
* @key gc
* @summary Verify that -XX:-ShrinkHeapInSteps works properly.
+ * @requires vm.gc != "Z"
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/gc/arguments/TestSurvivorRatioFlag.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestSurvivorRatioFlag.java Wed Jun 13 11:01:25 2018 -0700
@@ -25,6 +25,7 @@
* @test TestSurvivorRatioFlag
* @key gc
* @summary Verify that actual survivor ratio is equal to specified SurvivorRatio value
+ * @requires vm.gc != "Z"
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/gc/arguments/TestTargetSurvivorRatioFlag.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestTargetSurvivorRatioFlag.java Wed Jun 13 11:01:25 2018 -0700
@@ -27,6 +27,7 @@
* @summary Verify that option TargetSurvivorRatio affects survivor space occupancy after minor GC.
* @requires (vm.opt.ExplicitGCInvokesConcurrent == null) | (vm.opt.ExplicitGCInvokesConcurrent == false)
* @requires (vm.opt.UseJVMCICompiler == null) | (vm.opt.UseJVMCICompiler == false)
+ * @requires vm.gc != "Z"
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/gc/arguments/TestVerifyBeforeAndAfterGCFlags.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/gc/arguments/TestVerifyBeforeAndAfterGCFlags.java Wed Jun 13 11:01:25 2018 -0700
@@ -28,6 +28,7 @@
* @summary Runs an simple application (GarbageProducer) with various
combinations of -XX:{+|-}Verify{After|Before}GC flags and checks that
output contain or doesn't contain expected patterns
+ * @requires vm.gc != "Z"
* @modules java.base/jdk.internal.misc
* @modules java.management
* @library /test/lib
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestAlwaysPretouch.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ * 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 TestAlwaysPretouch
+ * @key gc
+ * @requires vm.gc.Epsilon
+ * @summary Basic sanity test for Epsilon
+ * @run main/othervm -Xmx1g -XX:+AlwaysPreTouch -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestAlwaysPretouch
+ */
+
+public class TestAlwaysPretouch {
+ public static void main(String[] args) throws Exception {
+ // everything should happen before entry point
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestByteArrays.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ * 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 TestByteArrays
+ * @key gc
+ * @requires vm.gc.Epsilon
+ * @summary Epsilon is able to allocate arrays, and does not corrupt their state
+ *
+ * @run main/othervm -Xmx1g -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestByteArrays
+ * @run main/othervm -Xmx1g -Xint -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestByteArrays
+ * @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestByteArrays
+ * @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:TieredStopAtLevel=1 -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestByteArrays
+ * @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:-TieredCompilation -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestByteArrays
+ *
+ * @run main/othervm -Xmx1g -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestByteArrays
+ * @run main/othervm -Xmx1g -Xint -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestByteArrays
+ * @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestByteArrays
+ * @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:TieredStopAtLevel=1 -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestByteArrays
+ * @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:-TieredCompilation -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestByteArrays
+ */
+
+import java.util.Random;
+
+public class TestByteArrays {
+
+ static long SEED = Long.getLong("seed", System.nanoTime());
+ static int COUNT = Integer.getInteger("count", 3000); // ~500 MB allocation
+
+ static byte[][] arr;
+
+ public static void main(String[] args) throws Exception {
+ Random r = new Random(SEED);
+
+ arr = new byte[COUNT * 100][];
+ for (int c = 0; c < COUNT; c++) {
+ arr[c] = new byte[c * 100];
+ for (int v = 0; v < c; v++) {
+ arr[c][v] = (byte)(r.nextInt(255) & 0xFF);
+ }
+ }
+
+ r = new Random(SEED);
+ for (int c = 0; c < COUNT; c++) {
+ byte[] b = arr[c];
+ if (b.length != (c * 100)) {
+ throw new IllegalStateException("Failure: length = " + b.length + ", need = " + (c*100));
+ }
+ for (int v = 0; v < c; v++) {
+ byte actual = b[v];
+ byte expected = (byte)(r.nextInt(255) & 0xFF);
+ if (actual != expected) {
+ throw new IllegalStateException("Failure: expected = " + expected + ", actual = " + actual);
+ }
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestDieDefault.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ * 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 TestDieDefault
+ * @key gc
+ * @requires vm.gc.Epsilon
+ * @summary Epsilon GC should die on heap exhaustion
+ * @library /test/lib
+ * @run main TestDieDefault
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class TestDieDefault {
+
+ public static void passWith(String... args) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
+ OutputAnalyzer out = new OutputAnalyzer(pb.start());
+ out.shouldNotContain("OutOfMemoryError");
+ out.shouldHaveExitValue(0);
+ }
+
+ public static void failWith(String... args) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
+ OutputAnalyzer out = new OutputAnalyzer(pb.start());
+ out.shouldContain("OutOfMemoryError");
+ if (out.getExitValue() == 0) {
+ throw new IllegalStateException("Should have failed with non-zero exit code");
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ passWith("-Xmx128m",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseEpsilonGC",
+ "-Dcount=1",
+ TestDieDefault.Workload.class.getName());
+
+ failWith("-Xmx128m",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseEpsilonGC",
+ TestDieDefault.Workload.class.getName());
+
+ failWith("-Xmx128m",
+ "-Xint",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseEpsilonGC",
+ TestDieDefault.Workload.class.getName());
+
+ failWith("-Xmx128m",
+ "-Xbatch",
+ "-Xcomp",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseEpsilonGC",
+ TestDieDefault.Workload.class.getName());
+
+ failWith("-Xmx128m",
+ "-Xbatch",
+ "-Xcomp",
+ "-XX:TieredStopAtLevel=1",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseEpsilonGC",
+ TestDieDefault.Workload.class.getName());
+
+ failWith("-Xmx128m",
+ "-Xbatch",
+ "-Xcomp",
+ "-XX:-TieredCompilation",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseEpsilonGC",
+ TestDieDefault.Workload.class.getName());
+ }
+
+ public static class Workload {
+ static int COUNT = Integer.getInteger("count", 1_000_000_000); // ~24 GB allocation
+
+ static volatile Object sink;
+
+ public static void main(String... args) {
+ for (int c = 0; c < COUNT; c++) {
+ sink = new Object();
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestDieWithHeapDump.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ * 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 TestDieWithHeapDump
+ * @key gc
+ * @requires vm.gc.Epsilon
+ * @summary Epsilon GC should die on heap exhaustion with error handler attached
+ * @library /test/lib
+ * @run main TestDieWithHeapDump
+ */
+
+import java.io.*;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class TestDieWithHeapDump {
+
+ public static void passWith(String... args) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
+ OutputAnalyzer out = new OutputAnalyzer(pb.start());
+ out.shouldNotContain("OutOfMemoryError");
+ out.shouldHaveExitValue(0);
+ }
+
+ public static void failWith(String... args) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
+ Process p = pb.start();
+ OutputAnalyzer out = new OutputAnalyzer(p);
+ out.shouldContain("OutOfMemoryError");
+ if (out.getExitValue() == 0) {
+ throw new IllegalStateException("Should have failed with non-zero exit code");
+ }
+ String heapDump = "java_pid" + p.pid() + ".hprof";
+ if (!new File(heapDump).exists()) {
+ throw new IllegalStateException("Should have produced the heap dump at: " + heapDump);
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ passWith("-Xmx128m",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseEpsilonGC",
+ "-Dcount=1",
+ "-XX:+HeapDumpOnOutOfMemoryError",
+ TestDieWithHeapDump.Workload.class.getName());
+
+ failWith("-Xmx128m",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseEpsilonGC",
+ "-XX:+HeapDumpOnOutOfMemoryError",
+ TestDieWithHeapDump.Workload.class.getName());
+
+ failWith("-Xmx128m",
+ "-Xint",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseEpsilonGC",
+ "-XX:+HeapDumpOnOutOfMemoryError",
+ TestDieWithHeapDump.Workload.class.getName());
+
+ failWith("-Xmx128m",
+ "-Xbatch",
+ "-Xcomp",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseEpsilonGC",
+ "-XX:+HeapDumpOnOutOfMemoryError",
+ TestDieWithHeapDump.Workload.class.getName());
+
+ failWith("-Xmx128m",
+ "-Xbatch",
+ "-Xcomp",
+ "-XX:TieredStopAtLevel=1",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseEpsilonGC",
+ "-XX:+HeapDumpOnOutOfMemoryError",
+ TestDieWithHeapDump.Workload.class.getName());
+
+ failWith("-Xmx128m",
+ "-Xbatch",
+ "-Xcomp",
+ "-XX:-TieredCompilation",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseEpsilonGC",
+ "-XX:+HeapDumpOnOutOfMemoryError",
+ TestDieWithHeapDump.Workload.class.getName());
+ }
+
+ public static class Workload {
+ static int COUNT = Integer.getInteger("count", 1_000_000_000); // ~24 GB allocation
+
+ static volatile Object sink;
+
+ public static void main(String... args) {
+ for (int c = 0; c < COUNT; c++) {
+ sink = new Object();
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestDieWithOnError.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ * 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 TestDieWithOnError
+ * @key gc
+ * @requires vm.gc.Epsilon
+ * @summary Epsilon GC should die on heap exhaustion with error handler attached
+ * @library /test/lib
+ * @run main TestDieWithOnError
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class TestDieWithOnError {
+
+ static String ON_ERR_MSG = "Epsilon error handler message";
+
+ public static void passWith(String... args) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
+ OutputAnalyzer out = new OutputAnalyzer(pb.start());
+ out.shouldNotContain("OutOfMemoryError");
+ out.stdoutShouldNotMatch("^" + ON_ERR_MSG);
+ out.shouldHaveExitValue(0);
+ }
+
+ public static void failWith(String... args) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
+ OutputAnalyzer out = new OutputAnalyzer(pb.start());
+ out.shouldContain("OutOfMemoryError");
+ if (out.getExitValue() == 0) {
+ throw new IllegalStateException("Should have failed with non-zero exit code");
+ }
+ out.stdoutShouldMatch("^" + ON_ERR_MSG);
+ }
+
+ public static void main(String[] args) throws Exception {
+ passWith("-Xmx128m",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseEpsilonGC",
+ "-Dcount=1",
+ "-XX:OnOutOfMemoryError=echo " + ON_ERR_MSG,
+ TestDieWithOnError.Workload.class.getName());
+
+ failWith("-Xmx128m",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseEpsilonGC",
+ "-XX:OnOutOfMemoryError=echo " + ON_ERR_MSG,
+ TestDieWithOnError.Workload.class.getName());
+
+ failWith("-Xmx128m",
+ "-Xint",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseEpsilonGC",
+ "-XX:OnOutOfMemoryError=echo " + ON_ERR_MSG,
+ TestDieWithOnError.Workload.class.getName());
+
+ failWith("-Xmx128m",
+ "-Xbatch",
+ "-Xcomp",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseEpsilonGC",
+ "-XX:OnOutOfMemoryError=echo " + ON_ERR_MSG,
+ TestDieWithOnError.Workload.class.getName());
+
+ failWith("-Xmx128m",
+ "-Xbatch",
+ "-Xcomp",
+ "-XX:TieredStopAtLevel=1",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseEpsilonGC",
+ "-XX:OnOutOfMemoryError=echo " + ON_ERR_MSG,
+ TestDieWithOnError.Workload.class.getName());
+
+ failWith("-Xmx128m",
+ "-Xbatch",
+ "-Xcomp",
+ "-XX:-TieredCompilation",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UseEpsilonGC",
+ "-XX:OnOutOfMemoryError=echo " + ON_ERR_MSG,
+ TestDieWithOnError.Workload.class.getName());
+ }
+
+ public static class Workload {
+ static int COUNT = Integer.getInteger("count", 1_000_000_000); // ~24 GB allocation
+
+ static volatile Object sink;
+
+ public static void main(String... args) {
+ for (int c = 0; c < COUNT; c++) {
+ sink = new Object();
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestElasticTLAB.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ * 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 TestElasticTLAB
+ * @key gc
+ * @requires vm.gc.Epsilon
+ * @summary Epsilon is able to work with/without elastic TLABs
+ *
+ * @run main/othervm -Xmx1g -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -XX:-EpsilonElasticTLAB TestElasticTLAB
+ * @run main/othervm -Xmx1g -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -XX:+EpsilonElasticTLAB -XX:EpsilonTLABElasticity=1 TestElasticTLAB
+ * @run main/othervm -Xmx1g -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -XX:+EpsilonElasticTLAB -XX:EpsilonTLABElasticity=1.1 TestElasticTLAB
+ * @run main/othervm -Xmx1g -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -XX:+EpsilonElasticTLAB -XX:EpsilonTLABElasticity=2.0 TestElasticTLAB
+ * @run main/othervm -Xmx1g -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -XX:+EpsilonElasticTLAB -XX:EpsilonTLABElasticity=42 TestElasticTLAB
+ * @run main/othervm -Xmx1g -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -XX:+EpsilonElasticTLAB -XX:EpsilonTLABElasticity=100 TestElasticTLAB
+ */
+
+import java.util.Random;
+
+public class TestElasticTLAB {
+
+ static long SEED = Long.getLong("seed", System.nanoTime());
+ static int COUNT = Integer.getInteger("count", 3000); // ~500 MB allocation
+
+ static byte[][] arr;
+
+ public static void main(String[] args) throws Exception {
+ Random r = new Random(SEED);
+
+ arr = new byte[COUNT * 100][];
+ for (int c = 0; c < COUNT; c++) {
+ arr[c] = new byte[c * 100];
+ for (int v = 0; v < c; v++) {
+ arr[c][v] = (byte)(r.nextInt(255) & 0xFF);
+ }
+ }
+
+ r = new Random(SEED);
+ for (int c = 0; c < COUNT; c++) {
+ byte[] b = arr[c];
+ if (b.length != (c * 100)) {
+ throw new IllegalStateException("Failure: length = " + b.length + ", need = " + (c*100));
+ }
+ for (int v = 0; v < c; v++) {
+ byte actual = b[v];
+ byte expected = (byte)(r.nextInt(255) & 0xFF);
+ if (actual != expected) {
+ throw new IllegalStateException("Failure: expected = " + expected + ", actual = " + actual);
+ }
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestElasticTLABDecay.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ * 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 TestElasticTLABDecay
+ * @key gc
+ * @requires vm.gc.Epsilon
+ * @summary Epsilon is able to work with/without elastic TLABs
+ *
+ * @run main/othervm -Xmx1g -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -XX:+EpsilonElasticTLAB -XX:-EpsilonElasticTLABDecay TestElasticTLABDecay
+ * @run main/othervm -Xmx1g -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -XX:+EpsilonElasticTLAB -XX:+EpsilonElasticTLABDecay -XX:EpsilonTLABDecayTime=1 TestElasticTLABDecay
+ * @run main/othervm -Xmx1g -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -XX:+EpsilonElasticTLAB -XX:+EpsilonElasticTLABDecay -XX:EpsilonTLABDecayTime=100 TestElasticTLABDecay
+ */
+
+import java.util.Random;
+
+public class TestElasticTLABDecay {
+
+ static long SEED = Long.getLong("seed", System.nanoTime());
+ static int COUNT = Integer.getInteger("count", 3000); // ~500 MB allocation
+
+ static byte[][] arr;
+
+ public static void main(String[] args) throws Exception {
+ Random r = new Random(SEED);
+
+ arr = new byte[COUNT * 100][];
+ for (int c = 0; c < COUNT; c++) {
+ arr[c] = new byte[c * 100];
+ for (int v = 0; v < c; v++) {
+ arr[c][v] = (byte)(r.nextInt(255) & 0xFF);
+ }
+ Thread.sleep(5);
+ }
+
+ r = new Random(SEED);
+ for (int c = 0; c < COUNT; c++) {
+ byte[] b = arr[c];
+ if (b.length != (c * 100)) {
+ throw new IllegalStateException("Failure: length = " + b.length + ", need = " + (c*100));
+ }
+ for (int v = 0; v < c; v++) {
+ byte actual = b[v];
+ byte expected = (byte)(r.nextInt(255) & 0xFF);
+ if (actual != expected) {
+ throw new IllegalStateException("Failure: expected = " + expected + ", actual = " + actual);
+ }
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestEpsilonEnabled.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ * 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 TestAlwaysPretouch
+ * @key gc
+ * @requires vm.gc.Epsilon
+ * @summary Basic sanity test for Epsilon
+ * @library /test/lib
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestEpsilonEnabled
+ */
+
+import jdk.test.lib.Platform;
+import java.lang.management.GarbageCollectorMXBean;
+import java.lang.management.ManagementFactory;
+
+public class TestEpsilonEnabled {
+ public static void main(String[] args) throws Exception {
+ if (!isEpsilonEnabled()) {
+ throw new IllegalStateException("Debug builds should have Epsilon enabled");
+ }
+ }
+
+ public static boolean isEpsilonEnabled() {
+ for (GarbageCollectorMXBean bean : ManagementFactory.getGarbageCollectorMXBeans()) {
+ if (bean.getName().contains("Epsilon")) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestHelloWorld.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ * 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 TestHelloWorld
+ * @key gc
+ * @requires vm.gc.Epsilon
+ * @summary Basic sanity test for Epsilon
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestHelloWorld
+ */
+
+public class TestHelloWorld {
+ public static void main(String[] args) throws Exception {
+ System.out.println("Hello World");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestLogTrace.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ * 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 TestLogTrace
+ * @key gc
+ * @requires vm.gc.Epsilon
+ * @summary Test that tracing does not crash Epsilon
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xlog:gc*=trace TestLogTrace
+ */
+
+public class TestLogTrace {
+ public static void main(String[] args) throws Exception {
+ System.out.println("Hello World");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestManyThreads.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ * 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 TestManyThreads
+ * @key gc
+ * @requires vm.gc.Epsilon
+ * @summary Test allocations from many threads
+ *
+ * @run main/othervm -Xmx128m -Xss512k -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestManyThreads
+ * @run main/othervm -Xmx128m -Xss512k -Xint -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestManyThreads
+ * @run main/othervm -Xmx128m -Xss512k -Xbatch -Xcomp -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestManyThreads
+ * @run main/othervm -Xmx128m -Xss512k -Xbatch -Xcomp -XX:TieredStopAtLevel=1 -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestManyThreads
+ * @run main/othervm -Xmx128m -Xss512k -Xbatch -Xcomp -XX:-TieredCompilation -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestManyThreads
+ *
+ * @run main/othervm -Xmx128m -Xss512k -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestManyThreads
+ * @run main/othervm -Xmx128m -Xss512k -Xint -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestManyThreads
+ * @run main/othervm -Xmx128m -Xss512k -Xbatch -Xcomp -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestManyThreads
+ * @run main/othervm -Xmx128m -Xss512k -Xbatch -Xcomp -XX:TieredStopAtLevel=1 -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestManyThreads
+ * @run main/othervm -Xmx128m -Xss512k -Xbatch -Xcomp -XX:-TieredCompilation -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestManyThreads
+ */
+
+import java.util.concurrent.atomic.*;
+
+public class TestManyThreads {
+
+ static int COUNT = Integer.getInteger("count", 128); // 128 * 4M max tlabs = 512M, would overflow without TLAB sizing
+
+ static volatile Object sink;
+ static volatile Throwable failed;
+ static final AtomicInteger allocated = new AtomicInteger();
+
+ public static void workload() {
+ try {
+ sink = new Object();
+ allocated.incrementAndGet();
+ Thread.sleep(3600 * 1000);
+ } catch (Throwable e) {
+ failed = e;
+ }
+ }
+
+ public static void main(String[] args) throws Throwable {
+ for (int c = 0; c < COUNT; c++) {
+ Thread t = new Thread(TestManyThreads::workload);
+ t.setDaemon(true);
+ t.start();
+ }
+
+ while ((failed == null) && (allocated.get() != COUNT)) {
+ Thread.sleep(100);
+ }
+
+ if (failed != null) {
+ throw failed;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestMemoryMXBeans.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ *
+ * 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 TestMemoryMXBeans
+ * @key gc
+ * @requires vm.gc.Epsilon
+ * @summary Test JMX memory beans
+ * @modules java.base/jdk.internal.misc
+ * java.management
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xmx1g TestMemoryMXBeans -1 1024
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xms1g -Xmx1g TestMemoryMXBeans 1024 1024
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xms128m -Xmx1g TestMemoryMXBeans 128 1024
+ */
+
+import java.lang.management.*;
+import java.util.*;
+
+public class TestMemoryMXBeans {
+
+ static volatile Object sink;
+
+ public static void main(String[] args) throws Exception {
+ if (args.length < 2) {
+ throw new IllegalStateException("Should provide expected heap sizes");
+ }
+
+ long initSize = 1L * Integer.parseInt(args[0]) * 1024 * 1024;
+ long maxSize = 1L * Integer.parseInt(args[1]) * 1024 * 1024;
+
+ testMemoryBean(initSize, maxSize);
+ testAllocs();
+ }
+
+ public static void testMemoryBean(long initSize, long maxSize) {
+ MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
+ long heapInit = memoryMXBean.getHeapMemoryUsage().getInit();
+ long heapMax = memoryMXBean.getHeapMemoryUsage().getMax();
+ long nonHeapInit = memoryMXBean.getNonHeapMemoryUsage().getInit();
+ long nonHeapMax = memoryMXBean.getNonHeapMemoryUsage().getMax();
+
+ if (initSize > 0 && heapInit != initSize) {
+ throw new IllegalStateException("Init heap size is wrong: " + heapInit + " vs " + initSize);
+ }
+ if (maxSize > 0 && heapMax != maxSize) {
+ throw new IllegalStateException("Max heap size is wrong: " + heapMax + " vs " + maxSize);
+ }
+ }
+
+ public static void testAllocs() {
+ MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
+
+ // Do lazy inits first:
+ long heapUsed1 = memoryMXBean.getHeapMemoryUsage().getUsed();
+ sink = new int[1024*1024];
+ long heapUsed2 = memoryMXBean.getHeapMemoryUsage().getUsed();
+
+ // Compute how much we waste during the calls themselves:
+ heapUsed1 = memoryMXBean.getHeapMemoryUsage().getUsed();
+ heapUsed2 = memoryMXBean.getHeapMemoryUsage().getUsed();
+ long adj = heapUsed2 - heapUsed1;
+
+ heapUsed1 = memoryMXBean.getHeapMemoryUsage().getUsed();
+ sink = new int[1024*1024];
+ heapUsed2 = memoryMXBean.getHeapMemoryUsage().getUsed();
+
+ long diff = heapUsed2 - heapUsed1 - adj;
+ long min = 8 + 4*1024*1024;
+ long max = 16 + 4*1024*1024;
+ if (!(min <= diff && diff <= max)) {
+ throw new IllegalStateException("Allocation did not change used space right: " + diff + " should be in [" + min + ", " + max + "]");
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestMemoryPools.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ * 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 TestMemoryPools
+ * @key gc
+ * @requires vm.gc.Epsilon
+ * @summary Test JMX memory pools
+ * @modules java.base/jdk.internal.misc
+ * java.management
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xmx1g -Xms1g TestMemoryPools
+ */
+
+import java.lang.management.*;
+import java.util.*;
+
+public class TestMemoryPools {
+
+ public static void main(String[] args) throws Exception {
+ List<MemoryManagerMXBean> mms = ManagementFactory.getMemoryManagerMXBeans();
+ if (mms == null) {
+ throw new RuntimeException("getMemoryManagerMXBeans is null");
+ }
+ if (mms.isEmpty()) {
+ throw new RuntimeException("getMemoryManagerMXBeans is empty");
+ }
+ for (MemoryManagerMXBean mmBean : mms) {
+ String[] names = mmBean.getMemoryPoolNames();
+ if (names == null) {
+ throw new RuntimeException("getMemoryPoolNames() is null");
+ }
+ if (names.length == 0) {
+ throw new RuntimeException("getMemoryPoolNames() is empty");
+ }
+ for (String name : names) {
+ if (name == null) {
+ throw new RuntimeException("pool name is null");
+ }
+ if (name.length() == 0) {
+ throw new RuntimeException("pool name is empty");
+ }
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestObjects.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ * 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 TestObjects
+ * @key gc
+ * @requires vm.gc.Epsilon
+ * @summary Epsilon is able to allocate objects, and does not corrupt their state
+ *
+ * @run main/othervm -Xmx128m -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestObjects
+ * @run main/othervm -Xmx128m -Xint -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestObjects
+ * @run main/othervm -Xmx128m -Xbatch -Xcomp -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestObjects
+ * @run main/othervm -Xmx128m -Xbatch -Xcomp -XX:TieredStopAtLevel=1 -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestObjects
+ * @run main/othervm -Xmx128m -Xbatch -Xcomp -XX:-TieredCompilation -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestObjects
+ *
+ * @run main/othervm -Xmx128m -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestObjects
+ * @run main/othervm -Xmx128m -Xint -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestObjects
+ * @run main/othervm -Xmx128m -Xbatch -Xcomp -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestObjects
+ * @run main/othervm -Xmx128m -Xbatch -Xcomp -XX:TieredStopAtLevel=1 -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestObjects
+ * @run main/othervm -Xmx128m -Xbatch -Xcomp -XX:-TieredCompilation -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestObjects
+ */
+
+import java.util.Random;
+
+public class TestObjects {
+
+ static long SEED = Long.getLong("seed", System.nanoTime());
+ static int COUNT = Integer.getInteger("count", 1_000_000); // ~24 MB allocation
+
+ static MyObject[] arr;
+
+ public static void main(String[] args) throws Exception {
+ Random r = new Random(SEED);
+
+ arr = new MyObject[COUNT];
+ for (int c = 0; c < COUNT; c++) {
+ arr[c] = new MyObject(r.nextInt());
+ }
+
+ r = new Random(SEED);
+ for (int c = 0; c < COUNT; c++) {
+ int expected = r.nextInt();
+ int actual = arr[c].id();
+ if (expected != actual) {
+ throw new IllegalStateException("Failure: expected = " + expected + ", actual = " + actual);
+ }
+ }
+ }
+
+ public static class MyObject {
+ int id;
+ public MyObject(int id) {
+ this.id = id;
+ }
+ public int id() {
+ return id;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestPrintHeapSteps.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ * 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 TestPrintSteps
+ * @key gc
+ * @requires vm.gc.Epsilon
+ * @summary Tests -XX:EpsilonPrintHeapSteps works
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xlog:gc -XX:EpsilonPrintHeapSteps=0 TestPrintHeapSteps
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xlog:gc -XX:EpsilonPrintHeapSteps=1 TestPrintHeapSteps
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xlog:gc -XX:EpsilonPrintHeapSteps=1000 TestPrintHeapSteps
+ */
+
+public class TestPrintHeapSteps {
+ public static void main(String[] args) throws Exception {
+ System.out.println("Hello World");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestRefArrays.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ * 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 TestRefArrays
+ * @key gc
+ * @requires vm.gc.Epsilon
+ * @summary Epsilon is able to allocate arrays, and does not corrupt their state
+ * @library /test/lib
+ *
+ * @run main/othervm -Xmx1g -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestRefArrays
+ * @run main/othervm -Xmx1g -Xint -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestRefArrays
+ * @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestRefArrays
+ * @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:TieredStopAtLevel=1 -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestRefArrays
+ * @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:-TieredCompilation -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestRefArrays
+ *
+ * @run main/othervm -Xmx1g -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestRefArrays
+ * @run main/othervm -Xmx1g -Xint -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestRefArrays
+ * @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestRefArrays
+ * @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:TieredStopAtLevel=1 -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestRefArrays
+ * @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:-TieredCompilation -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestRefArrays
+ */
+
+import java.util.Random;
+
+public class TestRefArrays {
+
+ static long SEED = Long.getLong("seed", System.nanoTime());
+ static int COUNT = Integer.getInteger("count", 1000); // ~500 MB allocation
+
+ static MyObject[][] arr;
+
+ public static void main(String[] args) throws Exception {
+ Random r = new Random(SEED);
+
+ arr = new MyObject[COUNT * 100][];
+ for (int c = 0; c < COUNT; c++) {
+ arr[c] = new MyObject[c * 100];
+ for (int v = 0; v < c; v++) {
+ arr[c][v] = new MyObject(r.nextInt());
+ }
+ }
+
+ r = new Random(SEED);
+ for (int c = 0; c < COUNT; c++) {
+ MyObject[] b = arr[c];
+ if (b.length != (c * 100)) {
+ throw new IllegalStateException("Failure: length = " + b.length + ", need = " + (c*100));
+ }
+ for (int v = 0; v < c; v++) {
+ int actual = b[v].id();
+ int expected = r.nextInt();
+ if (actual != expected) {
+ throw new IllegalStateException("Failure: expected = " + expected + ", actual = " + actual);
+ }
+ }
+ }
+ }
+
+ public static class MyObject {
+ int id;
+ public MyObject(int id) {
+ this.id = id;
+ }
+ public int id() {
+ return id;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestUpdateCountersSteps.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ * 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 TestUpdateCountersSteps
+ * @key gc
+ * @requires vm.gc.Epsilon
+ * @summary Test EpsilonUpdateCountersStep works
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xlog:gc -XX:EpsilonUpdateCountersStep=1 TestUpdateCountersSteps
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xlog:gc -XX:EpsilonUpdateCountersStep=10 TestUpdateCountersSteps
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xlog:gc -XX:EpsilonUpdateCountersStep=100 TestUpdateCountersSteps
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xlog:gc -XX:EpsilonUpdateCountersStep=1000 TestUpdateCountersSteps
+ */
+
+public class TestUpdateCountersSteps {
+ public static void main(String[] args) throws Exception {
+ System.out.println("Hello World");
+ }
+}
--- a/test/hotspot/jtreg/gc/logging/TestUnifiedLoggingSwitchStress.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/gc/logging/TestUnifiedLoggingSwitchStress.java Wed Jun 13 11:01:25 2018 -0700
@@ -42,6 +42,7 @@
* @key gc stress
* @summary Switches gc log level on fly while stressing memory/gc
* @requires !vm.flightRecorder
+ * @requires vm.gc != "Z"
* @library /test/lib /
* @modules java.management java.base/jdk.internal.misc
*
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/stress/gcbasher/TestGCBasherWithZ.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ *
+ */
+
+import java.io.IOException;
+
+/*
+ * @test TestGCBasherWithZ
+ * @key gc stress
+ * @requires vm.gc.Z
+ * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @summary Stress ZGC
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx384m -server -XX:+UnlockExperimentalVMOptions -XX:+UseZGC TestGCBasherWithZ 120000
+ */
+public class TestGCBasherWithZ {
+ public static void main(String[] args) throws IOException {
+ TestGCBasher.main(args);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/stress/gcold/TestGCOldWithZ.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,37 @@
+/*
+ * 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
+ * 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 TestGCOldWithZ
+ * @key gc
+ * @requires vm.gc.Z
+ * @summary Stress the Z
+ * @run main/othervm -Xmx384M -XX:+UnlockExperimentalVMOptions -XX:+UseZGC TestGCOldWithZ 50 1 20 10 10000
+ * @run main/othervm -Xmx256m -XX:+UnlockExperimentalVMOptions -XX:+UseZGC TestGCOldWithZ 50 5 20 1 5000
+ */
+public class TestGCOldWithZ {
+ public static void main(String[] args) {
+ TestGCOld.main(args);
+ }
+}
--- a/test/hotspot/jtreg/gc/survivorAlignment/TestAllocationInEden.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/gc/survivorAlignment/TestAllocationInEden.java Wed Jun 13 11:01:25 2018 -0700
@@ -26,6 +26,7 @@
* @bug 8031323
* @summary Verify that object's alignment in eden space is not affected by
* SurvivorAlignmentInBytes option.
+ * @requires vm.gc != "Z"
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromEdenToTenured.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromEdenToTenured.java Wed Jun 13 11:01:25 2018 -0700
@@ -26,6 +26,7 @@
* @bug 8031323
* @summary Verify that objects promoted from eden space to tenured space during
* full GC are not aligned to SurvivorAlignmentInBytes value.
+ * @requires vm.gc != "Z"
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterFullGC.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterFullGC.java Wed Jun 13 11:01:25 2018 -0700
@@ -26,6 +26,7 @@
* @bug 8031323
* @summary Verify that objects promoted from survivor space to tenured space
* during full GC are not aligned to SurvivorAlignmentInBytes value.
+ * @requires vm.gc != "Z"
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java Wed Jun 13 11:01:25 2018 -0700
@@ -27,6 +27,7 @@
* @summary Verify that objects promoted from survivor space to tenured space
* when their age exceeded tenuring threshold are not aligned to
* SurvivorAlignmentInBytes value.
+ * @requires vm.gc != "Z"
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionToSurvivor.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionToSurvivor.java Wed Jun 13 11:01:25 2018 -0700
@@ -26,6 +26,7 @@
* @bug 8031323
* @summary Verify that objects promoted from eden space to survivor space after
* minor GC are aligned to SurvivorAlignmentInBytes.
+ * @requires vm.gc != "Z"
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/gc/whitebox/TestWBGC.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/gc/whitebox/TestWBGC.java Wed Jun 13 11:01:25 2018 -0700
@@ -25,6 +25,7 @@
* @test TestWBGC
* @bug 8055098
* @summary Test verify that WB methods isObjectInOldGen and youngGC works correctly.
+ * @requires vm.gc != "Z"
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/runtime/6981737/Test6981737.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/runtime/6981737/Test6981737.java Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2017, 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
@@ -23,7 +23,7 @@
/*
* @test Test6981737.java
- * @bug 6981737
+ * @bug 6981737 8204565
* @summary check for correct vm properties
* @run main Test6981737
* @author kamg
@@ -33,13 +33,12 @@
/**
* Check the 'vendor' properties and java.vm.specification.version property.
- * In jdk9 onwards they should be "Oracle..." and "<major_version>"
*/
public static void main(String[] args) throws Exception {
String vendor_re = "Oracle Corporation";
- int major_version = Runtime.version().major();
- String vm_spec_version_re = Integer.toString(major_version);
+ int feature_version = Runtime.version().feature();
+ String vm_spec_version_re = Integer.toString(feature_version);
verifyProperty("java.vm.specification.vendor", vendor_re);
verifyProperty("java.specification.vendor", vendor_re);
--- a/test/hotspot/jtreg/runtime/Metaspace/PrintMetaspaceDcmd.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/runtime/Metaspace/PrintMetaspaceDcmd.java Wed Jun 13 11:01:25 2018 -0700
@@ -30,6 +30,7 @@
* @test
* @key metaspace jcmd
* @summary Test the VM.metaspace command
+ * @requires vm.gc != "Z"
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/runtime/appcds/CommandLineFlagComboNegative.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/runtime/appcds/CommandLineFlagComboNegative.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -71,6 +71,8 @@
"Class data sharing is inconsistent with other specified options", 1) );
testTable.add( new TestVector("-XX:+UseCompressedClassPointers", "-XX:-UseCompressedClassPointers",
"Class data sharing is inconsistent with other specified options", 1) );
+ testTable.add( new TestVector("-XX:-UseAppCDS", "-XX:+UseAppCDS",
+ "Ignoring obsolete option UseAppCDS; AppCDS is automatically enabled", 0) );
}
}
--- a/test/hotspot/jtreg/runtime/memory/LargePages/TestLargePagesFlags.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/runtime/memory/LargePages/TestLargePagesFlags.java Wed Jun 13 11:01:25 2018 -0700
@@ -23,6 +23,7 @@
/* @test TestLargePagesFlags
* @summary Tests how large pages are choosen depending on the given large pages flag combinations.
+ * @requires vm.gc != "Z"
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/serviceability/dcmd/gc/RunGCTest.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/serviceability/dcmd/gc/RunGCTest.java Wed Jun 13 11:01:25 2018 -0700
@@ -36,6 +36,7 @@
/*
* @test
* @summary Test of diagnostic command GC.run
+ * @requires vm.gc != "Z"
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.compiler
--- a/test/hotspot/jtreg/serviceability/sa/TestUniverse.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/serviceability/sa/TestUniverse.java Wed Jun 13 11:01:25 2018 -0700
@@ -36,12 +36,25 @@
/*
* @test
* @summary Test the 'universe' command of jhsdb clhsdb.
+ * @requires vm.gc != "Z"
* @bug 8190307
* @library /test/lib
* @build jdk.test.lib.apps.*
* @build sun.hotspot.WhiteBox
* @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. TestUniverse
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. TestUniverse withoutZ
+ */
+
+/*
+ * @test
+ * @summary Test the 'universe' command of jhsdb clhsdb.
+ * @requires vm.gc == "Z"
+ * @bug 8190307
+ * @library /test/lib
+ * @build jdk.test.lib.apps.*
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. TestUniverse withZ
*/
public class TestUniverse {
@@ -84,6 +97,9 @@
p.destroyForcibly();
throw new Error("Problem awaiting the child process: " + ie, ie);
}
+ if (gc.contains("UseZGC")) {
+ output.shouldContain("ZHeap");
+ }
output.shouldHaveExitValue(0);
System.out.println(output.getOutput());
@@ -106,13 +122,19 @@
output.shouldContain("PSYoungGen");
output.shouldContain("eden");
}
-
+ if (gc.contains("UseEpsilonGC")) {
+ output.shouldContain("Epsilon heap");
+ output.shouldContain("reserved");
+ output.shouldContain("committed");
+ output.shouldContain("used");
+ }
}
public static void test(String gc) throws Exception {
LingeredApp app = null;
try {
List<String> vmArgs = new ArrayList<String>();
+ vmArgs.add("-XX:+UnlockExperimentalVMOptions"); // unlock experimental GCs
vmArgs.add(gc);
app = LingeredApp.startApp(vmArgs);
System.out.println ("Started LingeredApp with the GC option " + gc +
@@ -136,9 +158,13 @@
test("-XX:+UseG1GC");
test("-XX:+UseParallelGC");
test("-XX:+UseSerialGC");
- if (!Compiler.isGraalEnabled()) { // Graal does not support CMS
- test("-XX:+UseConcMarkSweepGC");
+ if (!Compiler.isGraalEnabled()) { // Graal does not support all GCs
+ test("-XX:+UseConcMarkSweepGC");
+ if (args[0].equals("withZ")) {
+ test("-XX:+UseZGC");
+ }
}
+ test("-XX:+UseEpsilonGC");
} catch (Exception e) {
throw new Error("Test failed with " + e);
}
--- a/test/hotspot/jtreg/serviceability/tmtools/jstat/GcCapacityTest.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/serviceability/tmtools/jstat/GcCapacityTest.java Wed Jun 13 11:01:25 2018 -0700
@@ -27,6 +27,7 @@
* @test
* @summary Test checks the consistency of the output
* displayed with jstat -gccapacity.
+ * @requires vm.gc != "Z"
* @modules java.base/jdk.internal.misc
* @library /test/lib
* @library ../share
--- a/test/hotspot/jtreg/serviceability/tmtools/jstat/GcCauseTest01.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/serviceability/tmtools/jstat/GcCauseTest01.java Wed Jun 13 11:01:25 2018 -0700
@@ -32,6 +32,7 @@
* @library /test/lib
* @library ../share
* @requires vm.opt.ExplicitGCInvokesConcurrent != true
+ * @requires vm.gc != "Z"
* @run main/othervm -XX:+UsePerfData -Xmx128M GcCauseTest01
*/
import utils.*;
--- a/test/hotspot/jtreg/serviceability/tmtools/jstat/GcCauseTest02.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/serviceability/tmtools/jstat/GcCauseTest02.java Wed Jun 13 11:01:25 2018 -0700
@@ -28,6 +28,7 @@
* test forces debuggee application eat ~70% of heap and runs jstat.
* jstat should show actual usage of old gen (OC/OU ~= old gen usage).
* @requires vm.opt.ExplicitGCInvokesConcurrent != true
+ * @requires vm.gc != "Z"
* @modules java.base/jdk.internal.misc
* @library /test/lib
* @library ../share
--- a/test/hotspot/jtreg/serviceability/tmtools/jstat/GcCauseTest03.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/serviceability/tmtools/jstat/GcCauseTest03.java Wed Jun 13 11:01:25 2018 -0700
@@ -27,6 +27,7 @@
* Test scenario:
* test forces debuggee application call System.gc(), runs jstat and checks that
* cause of last garbage collection displayed by jstat (LGCC) is 'System.gc()'.
+ * @requires vm.gc != "Z"
* @modules java.base/jdk.internal.misc
* @library /test/lib
* @library ../share
--- a/test/hotspot/jtreg/serviceability/tmtools/jstat/GcNewTest.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/serviceability/tmtools/jstat/GcNewTest.java Wed Jun 13 11:01:25 2018 -0700
@@ -29,6 +29,7 @@
* test several times provokes garbage collection in the debuggee application and after each garbage
* collection runs jstat. jstat should show that after garbage collection number of GC events and garbage
* collection time increase.
+ * @requires vm.gc != "Z"
* @modules java.base/jdk.internal.misc
* @library /test/lib
* @library ../share
--- a/test/hotspot/jtreg/serviceability/tmtools/jstat/GcTest01.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/serviceability/tmtools/jstat/GcTest01.java Wed Jun 13 11:01:25 2018 -0700
@@ -35,6 +35,7 @@
* @library /test/lib
* @library ../share
* @requires vm.opt.ExplicitGCInvokesConcurrent != true
+ * @requires vm.gc != "Z"
* @run main/othervm -XX:+UsePerfData -Xmx128M GcTest01
*/
import utils.*;
--- a/test/hotspot/jtreg/serviceability/tmtools/jstat/GcTest02.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/serviceability/tmtools/jstat/GcTest02.java Wed Jun 13 11:01:25 2018 -0700
@@ -28,6 +28,7 @@
* test forces debuggee application eat ~70% of heap and runs jstat.
* jstat should show actual usage of old gen (OC/OU ~= old gen usage).
* @requires vm.opt.ExplicitGCInvokesConcurrent != true
+ * @requires vm.gc != "Z"
* @modules java.base/jdk.internal.misc
* @library /test/lib
* @library ../share
--- a/test/hotspot/jtreg/vmTestbase/metaspace/shrink_grow/CompressedClassSpaceSize/TestDescription.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/vmTestbase/metaspace/shrink_grow/CompressedClassSpaceSize/TestDescription.java Wed Jun 13 11:01:25 2018 -0700
@@ -29,6 +29,7 @@
* VM Testbase keywords: [monitoring, quarantine]
* VM Testbase comments: JDK-8058967
*
+ * @requires vm.opt.final.ClassUnloading
* @library /vmTestbase /test/lib
* @run driver jdk.test.lib.FileInstaller . .
* @run main/othervm
--- a/test/hotspot/jtreg/vmTestbase/metaspace/shrink_grow/ShrinkGrowTest/ShrinkGrowTest.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/vmTestbase/metaspace/shrink_grow/ShrinkGrowTest/ShrinkGrowTest.java Wed Jun 13 11:01:25 2018 -0700
@@ -27,6 +27,7 @@
*
* @summary converted from VM Testbase metaspace/shrink_grow/ShrinkGrowTest.
*
+ * @requires vm.opt.final.ClassUnloading
* @library /vmTestbase /test/lib
* @run driver jdk.test.lib.FileInstaller . .
* @run main/othervm
--- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/referringObjects/referringObjects001/referringObjects001.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/referringObjects/referringObjects001/referringObjects001.java Wed Jun 13 11:01:25 2018 -0700
@@ -51,6 +51,7 @@
* create references of all possible types to single object, ObjectReference.referringObjects should return only
* referrers with supported type(Strong, PhantomReference, SoftReference, WeakReference)
*
+ * @requires vm.gc != "Z"
* @library /vmTestbase
* /test/lib
* @run driver jdk.test.lib.FileInstaller . .
@@ -151,6 +152,11 @@
else
expectedInstanceCount = 0;
+ // Note! This test is broken, in the sense that it incorrectly assumes
+ // that no GC can happen before it walks the heap. In practice, it seems
+ // to only affect this test when using ZGC. However, this test will also
+ // fail when using other GCs if an explicit GC is done here.
+
checkDebugeeAnswer_instanceCounts(className, expectedInstanceCount, objectsToFilter);
checkDebugeeAnswer_instances_referringObjects(objectsToFilter, className, expectedInstanceCount, includedInReferrersCount, referrerCount);
--- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/instances/instances003/instances003.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/instances/instances003/instances003.java Wed Jun 13 11:01:25 2018 -0700
@@ -41,6 +41,7 @@
* done
* Test is executed for following sublcasses of ObjectReference: StringReference, ThreadReference, ClassLoaderReference
*
+ * @requires vm.gc != "Z"
* @library /vmTestbase
* /test/lib
* @run driver jdk.test.lib.FileInstaller . .
@@ -125,6 +126,11 @@
":" + referrerCount + ":" + referrerType +
(referrerType.equals(ObjectInstancesManager.WEAK_REFERENCE) ? "|" + ObjectInstancesManager.STRONG_REFERENCE : ""));
+ // Note! This test is broken, in the sense that it incorrectly assumes
+ // that no GC can happen before it walks the heap. In practice, it seems
+ // to only affect this test when using ZGC. However, this test will also
+ // fail when using other GCs if an explicit GC is done here.
+
// the instance counts should not be affected by creating multiple references
checkDebugeeAnswer_instanceCounts(className, createInstanceCount, objectsToFilter);
--- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Instances/instances001/instances001.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/ReferenceType/Instances/instances001/instances001.java Wed Jun 13 11:01:25 2018 -0700
@@ -60,6 +60,7 @@
* Finally, debugger sends debuggee signal to quit, waits for it exits
* and exits too with the proper exit code.
*
+ * @requires vm.gc != "Z"
* @library /vmTestbase /test/hotspot/jtreg/vmTestbase
* /test/lib
* @run driver jdk.test.lib.FileInstaller . .
@@ -156,6 +157,10 @@
long typeID = debuggee.getReferenceTypeID(createTypeSignature(testClassName));
+ // Note! This test is broken, in the sense that it incorrectly assumes
+ // that no GC can happen before it walks the heap. In practice, it seems
+ // to only affect this test when using ZGC. However, this test will also
+ // fail when using other GCs if an explicit GC is done here.
// create command with maxInstances=1, only 1 instance should be returned
testClass(typeID, 1, 1, false, 0);
--- a/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/InstanceCounts/instanceCounts001/instanceCounts001.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdwp/VirtualMachine/InstanceCounts/instanceCounts001/instanceCounts001.java Wed Jun 13 11:01:25 2018 -0700
@@ -61,6 +61,7 @@
* Finally, debugger sends debuggee signal to quit, waits for it exits
* and exits too with the proper exit code.
*
+ * @requires vm.gc != "Z"
* @library /vmTestbase /test/hotspot/jtreg/vmTestbase
* /test/lib
* @run driver jdk.test.lib.FileInstaller . .
@@ -164,6 +165,11 @@
if (!isDebuggeeReady())
return;
+ // Note! This test is broken, in the sense that it incorrectly assumes
+ // that no GC can happen before it walks the heap. In practice, it seems
+ // to only affect this test when using ZGC. However, this test will also
+ // fail when using other GCs if an explicit GC is done here.
+
int expectedCount = instanceCounts001a.expectedCount;
String classNames[];
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/general_functions/GF08/gf08t001/TestDriver.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/general_functions/GF08/gf08t001/TestDriver.java Wed Jun 13 11:01:25 2018 -0700
@@ -69,9 +69,10 @@
Boolean isExplicitGCInvokesConcurrentOn = wb.getBooleanVMFlag("ExplicitGCInvokesConcurrent");
Boolean isUseG1GCon = wb.getBooleanVMFlag("UseG1GC");
Boolean isUseConcMarkSweepGCon = wb.getBooleanVMFlag("UseConcMarkSweepGC");
+ Boolean isUseZGCon = wb.getBooleanVMFlag("UseZGC");
String keyPhrase;
- if (isExplicitGCInvokesConcurrentOn && (isUseG1GCon || isUseConcMarkSweepGCon)) {
+ if ((isExplicitGCInvokesConcurrentOn && (isUseG1GCon || isUseConcMarkSweepGCon)) || isUseZGCon) {
keyPhrase = "GC";
} else {
keyPhrase = "Pause Full";
--- a/test/jdk/ProblemList.txt Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/ProblemList.txt Wed Jun 13 11:01:25 2018 -0700
@@ -822,8 +822,6 @@
# core_tools
-tools/launcher/SourceMode.java 8204588 linux-all,macosx-all
-
tools/pack200/CommandLineTests.java 8059906 generic-all
tools/jimage/JImageExtractTest.java 8198405,8198819 generic-all
--- a/test/jdk/TEST.ROOT Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/TEST.ROOT Wed Jun 13 11:01:25 2018 -0700
@@ -18,7 +18,7 @@
# Tests that must run in othervm mode
othervm.dirs=java/awt java/beans javax/accessibility javax/imageio javax/sound javax/swing javax/print \
-sun/applet com/apple/laf com/sun/java/accessibility com/sun/java/swing sanity/client demo/jfc \
+com/apple/laf com/sun/java/accessibility com/sun/java/swing sanity/client demo/jfc \
javax/management com/sun/awt sun/awt sun/java2d javax/xml/jaxp/testng/validation java/lang/ProcessHandle
# Tests that cannot run concurrently
@@ -37,6 +37,7 @@
requires.properties= \
sun.arch.data.model \
java.runtime.name \
+ vm.gc.Z \
vm.graal.enabled \
vm.cds
--- a/test/jdk/TEST.groups Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/TEST.groups Wed Jun 13 11:01:25 2018 -0700
@@ -30,7 +30,7 @@
:tier1_part1 \
:tier1_part2 \
:tier1_part3
-
+
tier1_part1 = \
:jdk_lang
@@ -74,7 +74,7 @@
tier2_part3 = \
:jdk_net
-
+
tier3 = \
:jdk_rmi \
:jdk_beans \
@@ -354,8 +354,7 @@
com/sun/awt \
com/apple/eawt \
com/apple/laf \
- sun/awt \
- sun/applet
+ sun/awt
jdk_2d = \
javax/print \
--- a/test/jdk/com/sun/jdi/OomDebugTest.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/com/sun/jdi/OomDebugTest.java Wed Jun 13 11:01:25 2018 -0700
@@ -29,6 +29,7 @@
*
* @author Severin Gehwolf <sgehwolf@redhat.com>
*
+ * @requires vm.gc != "Z"
* @library ..
* @run build TestScaffold VMConnection TargetListener TargetAdapter
* @run compile -g OomDebugTest.java
--- a/test/jdk/com/sun/management/OperatingSystemMXBean/GetCommittedVirtualMemorySize.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/com/sun/management/OperatingSystemMXBean/GetCommittedVirtualMemorySize.java Wed Jun 13 11:01:25 2018 -0700
@@ -25,6 +25,7 @@
* @test
* @bug 4858522 6191542
* @summary Basic unit test of OperatingSystemMXBean.getCommittedVirtualMemorySize()
+ * @requires vm.gc != "Z"
* @author Steve Bohne
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/Desktop/DesktopEventsExceptions/DesktopEventsExceptions.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,95 @@
+/*
+ * 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.awt.Desktop;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
+import java.awt.desktop.AboutEvent;
+import java.awt.desktop.AppForegroundEvent;
+import java.awt.desktop.AppHiddenEvent;
+import java.awt.desktop.AppReopenedEvent;
+import java.awt.desktop.OpenFilesEvent;
+import java.awt.desktop.OpenURIEvent;
+import java.awt.desktop.PreferencesEvent;
+import java.awt.desktop.PrintFilesEvent;
+import java.awt.desktop.QuitEvent;
+import java.awt.desktop.ScreenSleepEvent;
+import java.awt.desktop.SystemSleepEvent;
+import java.awt.desktop.UserSessionEvent;
+import java.awt.desktop.UserSessionEvent.Reason;
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @test
+ * @bug 8203224
+ * @summary tests that the correct exceptions are thrown by the events classes
+ * in {code java.awt.desktop} package
+ * @run main/othervm DesktopEventsExceptions
+ * @run main/othervm -Djava.awt.headless=true DesktopEventsExceptions
+ */
+public final class DesktopEventsExceptions {
+
+ public static void main(final String[] args) {
+ // Each element of the list will creates one object to test
+ final List<Runnable> constructors = List.of(
+ AboutEvent::new,
+ AppForegroundEvent::new,
+ AppHiddenEvent::new,
+ AppReopenedEvent::new,
+ QuitEvent::new,
+ ScreenSleepEvent::new,
+ SystemSleepEvent::new,
+ PreferencesEvent::new,
+ () -> new PrintFilesEvent(Collections.emptyList()),
+ () -> new UserSessionEvent(Reason.UNSPECIFIED),
+ () -> new OpenFilesEvent(Collections.emptyList(), ""),
+ () -> new OpenURIEvent(new File("").toURI())
+ );
+
+ for (final Runnable test : constructors) {
+ try {
+ test.run();
+ checkHeadless(true);
+ checkSupported(true);
+ } catch (HeadlessException ex) {
+ checkHeadless(false);
+ } catch (UnsupportedOperationException ex) {
+ checkSupported(false);
+ }
+ }
+ }
+
+ private static void checkSupported(final boolean isSupported) {
+ if (isSupported != Desktop.isDesktopSupported()) {
+ throw new RuntimeException();
+ }
+ }
+
+ private static void checkHeadless(final boolean isHeadless) {
+ if (isHeadless == GraphicsEnvironment.isHeadless()) {
+ throw new RuntimeException();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/Robot/MouseLocationOnScreen/MouseLocationOnScreen.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,131 @@
+/*
+ * 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.awt.AWTException;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.MouseInfo;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Robot;
+
+/**
+ * @test
+ * @key headful
+ * @bug 8196030
+ * @summary checks that Robot and MouseInfo use the same coordinates
+ */
+public final class MouseLocationOnScreen {
+
+ public static void main(final String[] args) throws AWTException {
+ GraphicsEnvironment lge =
+ GraphicsEnvironment.getLocalGraphicsEnvironment();
+
+ for (final GraphicsDevice device : lge.getScreenDevices()) {
+ GraphicsConfiguration dc = device.getDefaultConfiguration();
+ Robot robot = new Robot(device);
+
+ Rectangle bounds = dc.getBounds();
+ int x1 = bounds.x;
+ int x2 = x1 + bounds.width - 1;
+ int y1 = bounds.y;
+ int y2 = y1 + bounds.height - 1;
+
+ // We'll check all edge (two pixels in a width) of the each screen
+ edge(robot, device, x1, y1, x2, y1); // top
+ edge(robot, device, x1, y1 + 1, x2, y1 + 1); // top
+
+ edge(robot, device, x2, y1, x2, y2); // right
+ edge(robot, device, x2 - 1, y1, x2 - 1, y2); // right
+
+ edge(robot, device, x1, y1, x1, y2); // left
+ edge(robot, device, x1 + 1, y1, x1 + 1, y2); // left
+
+ edge(robot, device, x1, y2, x2, y2); // bottom
+ edge(robot, device, x1, y2 - 1, x2, y2 - 1); // bottom
+
+ // We'll check crossing of diagonals of each screen
+ cross(robot, device, x1, y1, x2, y2); // cross left-bottom
+ cross(robot, device, x1, y2, x2, y1); // cross left-top
+ }
+ }
+
+ /**
+ * This method checks the coordinates which were passed to robot and
+ * returned by MouseInfo. Note that this method will be called for each
+ * pixel and for performance reasons we try will try to skip waitForIdle()
+ * a few times.
+ */
+ static void validate(Robot robot, GraphicsDevice device, int x, int y) {
+ int attempt = 0;
+ while (true) {
+ attempt++;
+ Point actLoc = MouseInfo.getPointerInfo().getLocation();
+ GraphicsDevice actDevice = MouseInfo.getPointerInfo().getDevice();
+
+ if (actLoc.x != x || actLoc.y != y || actDevice != device) {
+ if (attempt <= 10) {
+ if (attempt >= 8) {
+ robot.waitForIdle();
+ }
+ continue;
+ }
+ System.err.println("Expected device: " + device);
+ System.err.println("Actual device: " + actDevice);
+ System.err.println("Expected X: " + x);
+ System.err.println("Actual X: " + actLoc.x);
+ System.err.println("Expected Y: " + y);
+ System.err.println("Actual Y: " + actLoc.y);
+ throw new RuntimeException();
+ }
+ return;
+ }
+ }
+
+ private static void edge(Robot robot, GraphicsDevice device,
+ int x1, int y1, int x2, int y2) {
+ for (int x = x1; x <= x2; x++) {
+ for (int y = y1; y <= y2; y++) {
+ robot.mouseMove(x, y);
+ validate(robot, device, x, y);
+ }
+ }
+ }
+
+ private static void cross(Robot robot, GraphicsDevice device,
+ int x0, int y0, int x1, int y1) {
+ float dmax = (float) Math.max(Math.abs(x1 - x0), Math.abs(y1 - y0));
+ float dx = (x1 - x0) / dmax;
+ float dy = (y1 - y0) / dmax;
+
+ robot.mouseMove(x0, y0);
+ validate(robot, device, x0, y0);
+ for (int i = 1; i <= dmax; i++) {
+ int x = (int) (x0 + dx * i);
+ int y = (int) (y0 + dy * i);
+ robot.mouseMove(x, y);
+ validate(robot, device, x, y);
+ }
+ }
+}
--- a/test/jdk/java/awt/font/MonospacedGlyphWidth/MonospacedGlyphWidthTest.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/java/awt/font/MonospacedGlyphWidth/MonospacedGlyphWidthTest.java Wed Jun 13 11:01:25 2018 -0700
@@ -22,10 +22,11 @@
*/
/* @test
- * @bug 8073400 8198412
+ * @bug 8073400 8198412 8204126
* @summary Some Monospaced logical fonts have a different width
* @author Dmitry Markov
* @run main MonospacedGlyphWidthTest
+ * @requires (os.family == "windows" | os.family == "mac")
*/
import java.awt.Font;
import java.awt.GraphicsEnvironment;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/print/Dialog/DialogOwnerTest.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,289 @@
+/*
+ * 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 8203796
+ @run main/manual DialogOwnerTest
+ @summary Test DialogOwner API
+*/
+
+import java.util.ArrayList;
+import java.util.List;
+import java.awt.GraphicsConfiguration;
+import java.awt.GridLayout;
+import java.awt.Window;
+import java.awt.event.ActionEvent;
+import java.awt.print.PrinterJob;
+import javax.print.PrintService;
+import javax.print.PrintServiceLookup;
+import javax.print.ServiceUI;
+import javax.print.attribute.HashPrintRequestAttributeSet;
+import javax.print.attribute.PrintRequestAttributeSet;
+import javax.print.attribute.standard.DialogOwner;
+import javax.print.attribute.standard.DialogTypeSelection;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+
+public class DialogOwnerTest extends JPanel {
+
+ static final int NONE = 0x0;
+ static final int PRINT = 0x1;
+ static final int PAGE = 0x2;
+ static final int SWING2D = 0x4;
+ static final int NATIVE2D = 0x8;
+ static final int SERVICEUI = 0x10;
+
+ static final int ONTOP = 0x20;
+ static final int OWNED = 0x40;
+
+ static PrintService[] services =
+ PrintServiceLookup.lookupPrintServices(null, null);
+
+ public static void main(String[] args) {
+ if (services.length == 0) {
+ System.out.println("No printers, exiting");
+ return;
+ } else {
+ service = PrinterJob.getPrinterJob().getPrintService();
+ }
+ SwingUtilities.invokeLater(() -> {
+ createUI();
+ });
+ while (!testFinished) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e){
+ }
+ }
+ if (!testPassed) {
+ throw new RuntimeException("TEST FAILED.");
+ }
+ }
+
+
+ static final String otherText =
+ "This window is used to test on top behaviour\n" +
+ "For tests that are 'Owned' or 'On Top' the dialog\n" +
+ "must always stay above this window. Verify this\n " +
+ "by moving the dialog so that it partially obscures\n" +
+ "this window and then trying to raise this window.";
+
+ static final String instructions =
+ " Instructions\n" +
+ "This tests that a print dialog stays on top of either another\n" +
+ "window, or on top of all windows.\n" +
+ "For Owned tests the window titled 'Owner Window' should always \n" +
+ "stay behind the print dialog.\n" +
+ "For On Top tests all windows should stay behind the owner window.\n" +
+ "This test tracks if you have checked all the scenarios and will\n" +
+ "not allow the test to pass unless you have visited them all.\n";
+
+ static PrintService service;
+
+ public DialogOwnerTest() {
+ super();
+ //setLayout(new GridLayout(24, 1));
+ }
+
+ static boolean isNative(int flags) {
+ return (flags & NATIVE2D) != 0;
+ }
+
+ static boolean isCommon(int flags) {
+ return (flags & SWING2D) != 0;
+ }
+
+ static boolean is2D(int flags) {
+ return (flags & SWING2D|NATIVE2D) != 0;
+ }
+
+ static boolean isPage(int flags) {
+ return (flags & PAGE ) != 0;
+ }
+
+ static JFrame frame;
+ static JFrame other;
+ static JButton pass;
+ static ArrayList<JPanel> panelList = new ArrayList<JPanel>();
+ static volatile boolean testPassed, testFinished;
+
+ int testCount = 0;
+ List<String> testList = new ArrayList<String>();
+
+ static void createUI() {
+ other = new JFrame("Owner Window");
+ JTextArea otherTextArea = new JTextArea(otherText, 10, 40);
+ other.add(otherTextArea);
+ other.pack();
+ other.setVisible(true);
+ other.setLocation(800, 100);
+
+ frame = new JFrame("Test Dialog Owner");
+ frame.pack();
+ JTextArea instructionsPanel = new JTextArea(instructions, 10, 50);
+ instructionsPanel.setEditable(false);
+ frame.add("North", instructionsPanel);
+ DialogOwnerTest test = new DialogOwnerTest();
+
+ test.addTest("Owned Swing Print", OWNED, frame, PRINT|SWING2D);
+ test.addTest("On Top Swing Print", ONTOP, null, PRINT|SWING2D);
+
+ test.addTest("Owned Swing Page", OWNED, frame, PAGE|SWING2D);
+ test.addTest("On Top Swing Page", ONTOP, null, PAGE|SWING2D);
+
+ test.addTest("Owned javax.print", OWNED, frame, PRINT|SERVICEUI);
+ test.addTest("On Top javax.print", OWNED, null, PRINT|SERVICEUI);
+
+ test.addTest("Owned Native Print", OWNED, frame, PRINT|NATIVE2D);
+ test.addTest("On Top Native Print", OWNED, null, PRINT|NATIVE2D);
+
+ test.addTest("Owned Native Page", OWNED, frame, PAGE|NATIVE2D);
+ test.addTest("On Top Native Page", OWNED, null, PAGE|NATIVE2D);
+
+ test.setLayout(new GridLayout(panelList.size()+2, 1));
+
+ pass = new JButton("Pass");
+ pass.setEnabled(false);
+ pass.addActionListener((ActionEvent e) -> {
+ if (test.testList.size() > 0) {
+ return;
+ }
+ frame.dispose();
+ other.dispose();
+ System.out.println("User says test passed.");
+ testPassed = true;
+ testFinished = true;
+ });
+
+ JButton fail = new JButton("Fail");
+ fail.addActionListener((ActionEvent e) -> {
+ frame.dispose();
+ other.dispose();
+ System.out.println("User says test failed.");
+ testPassed = false;
+ testFinished = true;
+ });
+
+ JPanel p = new JPanel();
+ p.add(pass);
+ p.add(fail);
+ test.add(p);
+
+
+ for (JPanel panel : panelList) {
+ test.add(panel);
+ }
+
+ frame.add("Center", test);
+ frame.pack();
+ frame.setLocation(0,0);
+ frame.setVisible(true);
+ }
+
+ boolean isSupported(PrintRequestAttributeSet aset,
+ int ownerFlags, Window owner, int dlgFlags) {
+
+ boolean supported = true;
+ DialogOwner ownerAttr = null;
+ if (ownerFlags != NONE) {
+ if (ownerFlags == ONTOP) {
+ ownerAttr = new DialogOwner();
+ } else if (ownerFlags == OWNED) {
+ ownerAttr = new DialogOwner(owner);
+ }
+ aset.add(ownerAttr);
+ }
+ if (is2D(dlgFlags)) {
+ DialogTypeSelection dst = null;
+ if (isNative(dlgFlags)) {
+ dst = DialogTypeSelection.NATIVE;
+ } else if (isCommon(dlgFlags)) {
+ dst = DialogTypeSelection.COMMON;
+ }
+ if (dst != null &&
+ !service.isAttributeValueSupported(dst, null, aset)) {
+ //System.out.println("This DialogType not supported");
+ supported = false;
+ }
+ if (dst != null) {
+ aset.add(dst);
+ }
+ if (ownerAttr != null &&
+ !service.isAttributeValueSupported(ownerAttr, null, aset)) {
+ //System.out.println("This DialogOwner not supported");
+ supported = false;
+ }
+ }
+ return supported;
+ }
+
+ void addTest(String title, int ownerFlags, Window owner, int dlgFlags) {
+
+ PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
+ if (!isSupported(aset, ownerFlags, owner, dlgFlags)) {
+ return;
+ }
+
+ // if we are here then this is supportable and worth testing
+ // and the attribute set is configured.
+
+ String label = title + " Dialog";
+ JButton button = new JButton(label);
+ JCheckBox tested = new JCheckBox("Tested");
+ tested.setEnabled(false);
+ JPanel panel = new JPanel();
+ panel.add(tested);
+ panel.add(button);
+ panelList.add(panel);
+ //add(panel);
+ testList.add(title);
+ if (++testCount != testList.size()) {
+ throw new RuntimeException("Test titles must be unique");
+ }
+
+ button.addActionListener((ActionEvent e) -> {
+ tested.setSelected(true);
+ testList.remove(title);
+ if (testList.isEmpty()) {
+ pass.setEnabled(true);
+ }
+
+ if (is2D(dlgFlags)) {
+ PrinterJob job = PrinterJob.getPrinterJob();
+ if (isPage(dlgFlags)) {
+ job.pageDialog(aset);
+ } else {
+ job.printDialog(aset);
+ }
+ } else {
+ GraphicsConfiguration gc = null;
+ int x = 0, y = 0;
+ ServiceUI.printDialog(gc, x, y, services, services[0], null,aset);
+ }
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/Package/PackageFromManifest.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,300 @@
+/*
+ * 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 8201528
+ * @summary The test will create JAR file(s) with the manifest file
+ * that customized package versioning information (different info for
+ * same package if multiple jars). Then verify package versioning info
+ * @library /lib/testlibrary
+ * @library /test/lib
+ * @run main PackageFromManifest setup test
+ * @run main PackageFromManifest runJar test1.jar
+ * @run main PackageFromManifest runJar test1.jar test2.jar foo.Foo1
+ * @run main PackageFromManifest runJar test1.jar test2.jar foo.Foo2
+ * @run main/othervm PackageFromManifest runUrlLoader test1.jar
+ * @run main/othervm PackageFromManifest runUrlLoader test1.jar test2.jar foo.Foo1
+ * @run main/othervm PackageFromManifest runUrlLoader test1.jar test2.jar foo.Foo2
+ */
+
+import jdk.test.lib.compiler.CompilerUtils;
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.util.FileUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.jar.Manifest;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * This test accept at least two input parameters, first one is run type like
+ * 'setup', 'runJar', 'runTest', 'runUrlLoader', the rest parameters are options
+ * to each run type. 'setup' run type should be placed at first since it will
+ * create necessary jars for the rest tests. 'runTest' will be called in test
+ * logic only, it should not be used in @run
+ *
+ * #1 test will do setup only to generate required jars before other tests run
+ * PackageFromManifest setup test
+ *
+ * #2 test will run against single jar file to verify package versioning
+ * PackageFromManifest runJar test1.jar
+ *
+ * #4 test will run against two jar files, load class foo.Foo1 first, then
+ * verify package versioning
+ * PackageFromManifest runJar test1.jar test2.jar foo.Foo1
+ *
+ * #5 test will run against two jar files, load class foo.Foo2 first, then
+ * verify package versioning
+ * PackageFromManifest runJar test1.jar test2.jar foo.Foo2
+ *
+ * #3 test will use URLCLassLoader to load single jar file, then verify
+ * package versioning
+ * PackageFromManifest runUrlLoader test1.jar
+ *
+ * #6 test will use URLCLassLoader to load two jars, load class foo.Foo1 first,
+ * then verify package versioning
+ * PackageFromManifest runUrlLoader test1.jar test2.jar foo.Foo1
+ *
+ * #7 test will use URLCLassLoader to load two jars, load class foo.Foo2 first,
+ * then verify package versioning
+ * PackageFromManifest runUrlLoader test1.jar test2.jar foo.Foo2
+ */
+public class PackageFromManifest {
+
+ private static final String PACKAGE_NAME = "foo";
+ private static final String TEST_JAR_FILE1 = "test1.jar";
+ private static final String TEST_JAR_FILE2 = "test2.jar";
+ private static final String TEST_SUFFIX1 = "1";
+ private static final String TEST_SUFFIX2 = "2";
+ private static final String TEST_CLASS_PREFIX = "Foo";
+ private static final String TEST_CLASS_NAME1 =
+ TEST_CLASS_PREFIX + TEST_SUFFIX1;
+ private static final String TEST_CLASS_NAME2 =
+ TEST_CLASS_PREFIX + TEST_SUFFIX2;
+ private static final String MANIFEST_FILE = "test.mf";
+ private static final String SPEC_TITLE = "testSpecTitle";
+ private static final String SPEC_VENDOR = "testSpecVendor";
+ private static final String IMPL_TITLE = "testImplTitle";
+ private static final String IMPL_VENDOR = "testImplVendor";
+ private static final Path WORKING_PATH = Paths.get(".");
+
+ public static void main(String[] args) throws Exception {
+ if (args != null && args.length > 1) {
+ String runType = args[0];
+ String[] options = Arrays.copyOfRange(args, 1, args.length);
+ switch (runType) {
+ case "setup":
+ setup();
+ break;
+ case "runTest":
+ runTest(options);
+ break;
+ case "runJar":
+ runJar(options);
+ break;
+ case "runUrlLoader":
+ testUrlLoader(options);
+ break;
+ default:
+ throw new RuntimeException("Invalid run type : " + runType);
+ }
+ } else {
+ throw new RuntimeException("Invalid input arguments");
+ }
+ }
+
+ private static void createTestClass(String name) throws IOException {
+ List<String> content = new ArrayList<>();
+ content.add("package " + PACKAGE_NAME + ";");
+ content.add("public class " + name + " {");
+ content.add("}");
+
+ Path javaFile = WORKING_PATH.resolve(name + ".java");
+
+ Files.write(javaFile, content);
+
+ CompilerUtils.compile(WORKING_PATH, WORKING_PATH);
+
+ // clean up created java file
+ Files.delete(javaFile);
+ }
+
+ private static void createManifest(String suffix) throws IOException {
+ List<String> content = new ArrayList<>();
+ content.add("Manifest-version: 1.1");
+ content.add("Name: " + PACKAGE_NAME + "/");
+ content.add("Specification-Title: " + SPEC_TITLE + suffix);
+ content.add("Specification-Version: " + suffix);
+ content.add("Specification-Vendor: " + SPEC_VENDOR + suffix);
+ content.add("Implementation-Title: " + IMPL_TITLE + suffix);
+ content.add("Implementation-Version: " + suffix);
+ content.add("Implementation-Vendor: " + IMPL_VENDOR + suffix);
+
+ Files.write(WORKING_PATH.resolve(MANIFEST_FILE), content);
+ }
+
+ private static void buildJar(String jarFileName, boolean isIncludeSelf)
+ throws IOException {
+ try (InputStream is = Files.newInputStream(Paths.get(MANIFEST_FILE))) {
+ if (isIncludeSelf) {
+ Path selfPath = WORKING_PATH
+ .resolve("PackageFromManifest.class");
+ if (!Files.exists(selfPath)) {
+ Files.copy(Paths.get(System.getProperty("test.classes"))
+ .resolve("PackageFromManifest.class"), selfPath);
+ }
+ JarUtils.createJarFile(Paths.get(jarFileName), new Manifest(is),
+ WORKING_PATH, selfPath,
+ WORKING_PATH.resolve(PACKAGE_NAME));
+ } else {
+ JarUtils.createJarFile(Paths.get(jarFileName), new Manifest(is),
+ WORKING_PATH, WORKING_PATH.resolve(PACKAGE_NAME));
+ }
+ }
+
+ // clean up build files
+ FileUtils.deleteFileTreeWithRetry(WORKING_PATH.resolve(PACKAGE_NAME));
+ Files.delete(WORKING_PATH.resolve(MANIFEST_FILE));
+ }
+
+ private static void runJar(String[] options) throws Exception {
+ String[] cmds;
+ String classPath = Stream.of(options).takeWhile(s -> s.endsWith(".jar"))
+ .collect(Collectors.joining(File.pathSeparator));
+ if (options.length == 1) {
+ cmds = new String[] { "-cp", classPath, "PackageFromManifest",
+ "runTest", "single" };
+ } else {
+ cmds = new String[] { "-cp", classPath, "PackageFromManifest",
+ "runTest", options[options.length - 1] };
+ }
+
+ ProcessTools.executeTestJava(cmds).outputTo(System.out)
+ .errorTo(System.err).shouldHaveExitValue(0);
+ }
+
+ private static void runTest(String[] options)
+ throws ClassNotFoundException {
+ String option = options[0];
+ if (option.equalsIgnoreCase("single")) {
+ runTest(Class.forName(PACKAGE_NAME + "." + TEST_CLASS_NAME1)
+ .getPackage(), TEST_SUFFIX1);
+ } else {
+ // Load one specified class first
+ System.out.println("Load " + Class.forName(option) + " first");
+
+ String suffix = option.endsWith(TEST_SUFFIX1) ?
+ TEST_SUFFIX1 :
+ TEST_SUFFIX2;
+
+ runTest(Class.forName(PACKAGE_NAME + "." + TEST_CLASS_NAME1)
+ .getPackage(), suffix);
+ runTest(Class.forName(PACKAGE_NAME + "." + TEST_CLASS_NAME2)
+ .getPackage(), suffix);
+ }
+ }
+
+ private static void runTest(Package testPackage, String suffix) {
+ checkValue("Package Name", PACKAGE_NAME, testPackage.getName());
+ checkValue("Spec Title", SPEC_TITLE + suffix,
+ testPackage.getSpecificationTitle());
+ checkValue("Spec Vendor", SPEC_VENDOR + suffix,
+ testPackage.getSpecificationVendor());
+ checkValue("Spec Version", suffix,
+ testPackage.getSpecificationVersion());
+ checkValue("Impl Title", IMPL_TITLE + suffix,
+ testPackage.getImplementationTitle());
+ checkValue("Impl Vendor", IMPL_VENDOR + suffix,
+ testPackage.getImplementationVendor());
+ checkValue("Impl Version", suffix,
+ testPackage.getImplementationVersion());
+ }
+
+ private static void checkValue(String name, String expect, String actual) {
+ if (!expect.equals(actual)) {
+ throw new RuntimeException(
+ "Failed, unexpected value for " + name + ", expect: "
+ + expect + ", actual: " + actual);
+ } else {
+ System.out.println(name + " : " + actual);
+ }
+ }
+
+ private static void setup() throws IOException {
+ if (!Files.exists(WORKING_PATH.resolve(TEST_JAR_FILE1))) {
+ createTestClass(TEST_CLASS_NAME1);
+ createManifest(TEST_SUFFIX1);
+ buildJar(TEST_JAR_FILE1, true);
+ }
+
+ if (!Files.exists(WORKING_PATH.resolve(TEST_JAR_FILE2))) {
+ createTestClass(TEST_CLASS_NAME2);
+ createManifest(TEST_SUFFIX2);
+ buildJar(TEST_JAR_FILE2, false);
+ }
+ }
+
+ private static void testUrlLoader(String[] options)
+ throws ClassNotFoundException {
+ URLClassLoader cl = new URLClassLoader(
+ Stream.of(options).takeWhile(s -> s.endsWith(".jar")).map(s -> {
+ try {
+ return WORKING_PATH.resolve(s).toUri().toURL();
+ } catch (MalformedURLException e) {
+ return null;
+ }
+ }).toArray(URL[]::new));
+ if (options.length == 1) {
+ runTest(Class
+ .forName(PACKAGE_NAME + "." + TEST_CLASS_NAME1, true, cl)
+ .getPackage(), TEST_SUFFIX1);
+ } else {
+ // Load one specified class first
+ System.out.println("Load " + Class
+ .forName(options[options.length - 1], true, cl) + " first");
+
+ String suffix = options[options.length - 1].endsWith(TEST_SUFFIX1) ?
+ TEST_SUFFIX1 :
+ TEST_SUFFIX2;
+
+ runTest(Class
+ .forName(PACKAGE_NAME + "." + TEST_CLASS_NAME1, true, cl)
+ .getPackage(), suffix);
+ runTest(Class
+ .forName(PACKAGE_NAME + "." + TEST_CLASS_NAME2, true, cl)
+ .getPackage(), suffix);
+ }
+ }
+}
--- a/test/jdk/java/lang/System/Versions.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/java/lang/System/Versions.java Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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 4989690 6259855 6706299
+ * @bug 4989690 6259855 6706299 8204565
* @summary Check that version-related system property invariants hold.
* @author Martin Buchholz
*/
@@ -72,13 +72,17 @@
public static void main(String [] args) throws Exception {
String classVersion = getProperty("java.class.version");
String javaVersion = getProperty("java.version");
- String VMVersion = getProperty("java.vm.version");
String runtimeVersion = getProperty("java.runtime.version");
String specVersion = getProperty("java.specification.version");
+ String vmSpecVersion = getProperty("java.vm.specification.version");
+ String featureVersion = Integer.toString(Runtime.version().feature());
if (! (javaVersion.startsWith(specVersion) &&
- runtimeVersion.startsWith(specVersion)))
+ runtimeVersion.startsWith(specVersion) &&
+ specVersion.equals(featureVersion) &&
+ vmSpecVersion.equals(featureVersion))) {
throw new Exception("Invalid version-related system properties");
+ }
//----------------------------------------------------------------
// Check that java.class.version is correct.
--- a/test/jdk/java/lang/Thread/StopThrowable.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @bug 7059085
- * @summary Check that Thread.stop(Throwable) throws UOE
- * @run testng StopThrowable
- */
-
-import org.testng.annotations.Test;
-
-import java.util.concurrent.CountDownLatch;
-
-public class StopThrowable {
-
- @Test(expectedExceptions=UnsupportedOperationException.class)
- public void testStopSelf() {
- Thread.currentThread().stop(new ThreadDeath());
- }
-
- private static void awaitUnchecked(CountDownLatch latch) {
- try {
- latch.await();
- } catch (InterruptedException e) {
- // should not happen
- throw new RuntimeException(e);
- }
- }
-
- @Test(expectedExceptions=UnsupportedOperationException.class)
- public void testStopOther() throws Throwable {
- CountDownLatch ready = new CountDownLatch(1);
- CountDownLatch done = new CountDownLatch(1);
- Thread t = new Thread( () -> { ready.countDown(); awaitUnchecked(done); } );
- t.start();
- try {
- ready.await();
- t.stop(new ThreadDeath());
- } finally {
- done.countDown();
- }
- }
-
- @Test(expectedExceptions=UnsupportedOperationException.class)
- public void testNull() {
- Thread.currentThread().stop(null);
- }
-}
--- a/test/jdk/java/lang/management/ManagementFactory/MXBeanException.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/java/lang/management/ManagementFactory/MXBeanException.java Wed Jun 13 11:01:25 2018 -0700
@@ -27,6 +27,7 @@
* @summary Check if a RuntimeException is wrapped by RuntimeMBeanException
* only once.
*
+ * @requires vm.gc != "Z"
* @author Mandy Chung
*
* @build MXBeanException
--- a/test/jdk/java/lang/management/MemoryMXBean/MemoryTest.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/java/lang/management/MemoryMXBean/MemoryTest.java Wed Jun 13 11:01:25 2018 -0700
@@ -26,6 +26,7 @@
* @bug 4530538
* @summary Basic unit test of MemoryMXBean.getMemoryPools() and
* MemoryMXBean.getMemoryManager().
+ * @requires vm.gc != "Z"
* @author Mandy Chung
*
* @modules jdk.management
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/management/MemoryMXBean/MemoryTestZGC.sh Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,50 @@
+#
+# Copyright (c) 2003, 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.
+#
+
+#
+# @test
+# @requires vm.gc.Z
+# @run compile MemoryTest.java
+# @run shell MemoryTestZGC.sh
+#
+
+#Set appropriate jdk
+
+if [ ! -z "${TESTJAVA}" ] ; then
+ jdk="$TESTJAVA"
+else
+ echo "--Error: TESTJAVA must be defined as the pathname of a jdk to test."
+ exit 1
+fi
+
+runOne()
+{
+ echo "runOne $@"
+ $TESTJAVA/bin/java ${TESTVMOPTS} -classpath $TESTCLASSES $@ || exit 2
+}
+
+# Test MemoryTest with ZGC. ZGC is a single generation GC, which means
+# it has one memory manager and one memory pool.
+runOne -XX:+UnlockExperimentalVMOptions -XX:+UseZGC MemoryTest 1 1
+
+exit 0
--- a/test/jdk/java/rmi/transport/dgcDeadLock/TestImpl.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/java/rmi/transport/dgcDeadLock/TestImpl.java Wed Jun 13 11:01:25 2018 -0700
@@ -26,7 +26,6 @@
import java.rmi.*;
import sun.rmi.transport.*;
-import sun.rmi.*;
import java.io.*;
import java.lang.reflect.*;
import java.rmi.dgc.*;
--- a/test/jdk/java/text/Format/DateFormat/WeekDateTest.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/java/text/Format/DateFormat/WeekDateTest.java Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2013, 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
@@ -137,20 +137,28 @@
Calendar jcal = Calendar.getInstance(TimeZone.getTimeZone("GMT"),
new Locale("ja", "JP", "JP"));
+ String format = "2-W01-2"; // 2019-12-31 == N1-12-31
+ int expectedYear = 2019;
+ // Check the current era, Heisei or NewEra
+ if (System.currentTimeMillis() < 1556668800000L) {
+ format = "21-W01-3"; // 2008-12-31 == H20-12-31
+ expectedYear = 2008;
+ }
jcal.setFirstDayOfWeek(MONDAY);
jcal.setMinimalDaysInFirstWeek(4);
SimpleDateFormat sdf = new SimpleDateFormat("Y-'W'ww-u");
sdf.setCalendar(jcal);
- Date d = sdf.parse("21-W01-3"); // 2008-12-31 == H20-12-31
+ Date d = sdf.parse(format);
GregorianCalendar gcal = newCalendar();
gcal.setTime(d);
- if (gcal.get(YEAR) != 2008
+ if (gcal.get(YEAR) != expectedYear
|| gcal.get(MONTH) != DECEMBER
|| gcal.get(DAY_OF_MONTH) != 31) {
- String s = String.format("noWeekDateSupport: got %04d-%02d-%02d, expected 2008-12-31%n",
+ String s = String.format("noWeekDateSupport: got %04d-%02d-%02d, expected %4d-12-31%n",
gcal.get(YEAR),
gcal.get(MONTH)+1,
- gcal.get(DAY_OF_MONTH));
+ gcal.get(DAY_OF_MONTH),
+ expectedYear);
throw new RuntimeException(s);
}
}
--- a/test/jdk/java/time/tck/java/time/chrono/TCKJapaneseChronology.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/java/time/tck/java/time/chrono/TCKJapaneseChronology.java Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ o 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
@@ -111,6 +111,7 @@
*/
@Test
public class TCKJapaneseChronology {
+ private static final int YDIFF_NEWERA = 2018;
private static final int YDIFF_HEISEI = 1988;
private static final int YDIFF_MEIJI = 1867;
private static final int YDIFF_SHOWA = 1925;
@@ -173,6 +174,7 @@
@DataProvider(name="createByEra")
Object[][] data_createByEra() {
return new Object[][] {
+ {JapaneseEra.of(3), 2020 - YDIFF_NEWERA, 2, 29, 60, LocalDate.of(2020, 2, 29)}, // NEWERA
{JapaneseEra.HEISEI, 1996 - YDIFF_HEISEI, 2, 29, 60, LocalDate.of(1996, 2, 29)},
{JapaneseEra.HEISEI, 2000 - YDIFF_HEISEI, 2, 29, 60, LocalDate.of(2000, 2, 29)},
{JapaneseEra.MEIJI, 1874 - YDIFF_MEIJI, 2, 28, 59, LocalDate.of(1874, 2, 28)},
@@ -365,8 +367,11 @@
@DataProvider(name="prolepticYear")
Object[][] data_prolepticYear() {
return new Object[][] {
+ {3, JapaneseEra.of(3), 1, 1 + YDIFF_NEWERA, false}, // NEWERA
+ {3, JapaneseEra.of(3), 102, 102 + YDIFF_NEWERA, true}, // NEWERA
+
{2, JapaneseEra.HEISEI, 1, 1 + YDIFF_HEISEI, false},
- {2, JapaneseEra.HEISEI, 100, 100 + YDIFF_HEISEI, true},
+ {2, JapaneseEra.HEISEI, 4, 4 + YDIFF_HEISEI, true},
{-1, JapaneseEra.MEIJI, 9, 9 + YDIFF_MEIJI, true},
{-1, JapaneseEra.MEIJI, 10, 10 + YDIFF_MEIJI, false},
@@ -548,6 +553,7 @@
{ JapaneseEra.TAISHO, 0, "Taisho"},
{ JapaneseEra.SHOWA, 1, "Showa"},
{ JapaneseEra.HEISEI, 2, "Heisei"},
+ { JapaneseEra.of(3), 3, "NewEra"}, // NEWERA
};
}
@@ -562,7 +568,7 @@
@Test
public void test_Japanese_badEras() {
- int badEras[] = {-1000, -998, -997, -2, 3, 4, 1000};
+ int badEras[] = {-1000, -998, -997, -2, 4, 5, 1000};
for (int badEra : badEras) {
try {
Era era = JapaneseChronology.INSTANCE.eraOf(badEra);
@@ -683,6 +689,7 @@
{JapaneseChronology.INSTANCE.date(1989, 1, 7), "Japanese Showa 64-01-07"},
{JapaneseChronology.INSTANCE.date(1989, 1, 8), "Japanese Heisei 1-01-08"},
{JapaneseChronology.INSTANCE.date(2012, 12, 6), "Japanese Heisei 24-12-06"},
+ {JapaneseChronology.INSTANCE.date(2020, 1, 6), "Japanese NewEra 2-01-06"},
};
}
--- a/test/jdk/java/time/tck/java/time/chrono/TCKJapaneseEra.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/java/time/tck/java/time/chrono/TCKJapaneseEra.java Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, 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
@@ -79,6 +79,7 @@
@DataProvider(name = "JapaneseEras")
Object[][] data_of_eras() {
return new Object[][] {
+ {JapaneseEra.of(3), "NewEra", 3}, // NEWERA
{JapaneseEra.HEISEI, "Heisei", 2},
{JapaneseEra.SHOWA, "Showa", 1},
{JapaneseEra.TAISHO, "Taisho", 0},
@@ -91,7 +92,7 @@
return new Object[][] {
{-2},
{-3},
- {3},
+ {4},
{Integer.MIN_VALUE},
{Integer.MAX_VALUE},
};
--- a/test/jdk/java/time/tck/java/time/zone/TCKZoneRules.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/java/time/tck/java/time/zone/TCKZoneRules.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -112,11 +112,13 @@
return ZoneId.of("Europe/London").getRules();
}
+ @Test
public void test_London() {
ZoneRules test = europeLondon();
assertEquals(test.isFixedOffset(), false);
}
+ @Test
public void test_London_preTimeZones() {
ZoneRules test = europeLondon();
ZonedDateTime old = createZDT(1800, 1, 1, ZoneOffset.UTC);
@@ -129,6 +131,7 @@
assertEquals(test.isDaylightSavings(instant), false);
}
+ @Test
public void test_London_getOffset() {
ZoneRules test = europeLondon();
assertEquals(test.getOffset(createInstant(2008, 1, 1, ZoneOffset.UTC)), OFFSET_ZERO);
@@ -145,6 +148,7 @@
assertEquals(test.getOffset(createInstant(2008, 12, 1, ZoneOffset.UTC)), OFFSET_ZERO);
}
+ @Test
public void test_London_getOffset_toDST() {
ZoneRules test = europeLondon();
assertEquals(test.getOffset(createInstant(2008, 3, 24, ZoneOffset.UTC)), OFFSET_ZERO);
@@ -160,6 +164,7 @@
assertEquals(test.getOffset(createInstant(2008, 3, 30, 1, 0, 0, 0, ZoneOffset.UTC)), OFFSET_PONE);
}
+ @Test
public void test_London_getOffset_fromDST() {
ZoneRules test = europeLondon();
assertEquals(test.getOffset(createInstant(2008, 10, 24, ZoneOffset.UTC)), OFFSET_PONE);
@@ -175,6 +180,7 @@
assertEquals(test.getOffset(createInstant(2008, 10, 26, 1, 0, 0, 0, ZoneOffset.UTC)), OFFSET_ZERO);
}
+ @Test
public void test_London_getOffsetInfo() {
ZoneRules test = europeLondon();
checkOffset(test, createLDT(2008, 1, 1), OFFSET_ZERO, 1);
@@ -191,6 +197,7 @@
checkOffset(test, createLDT(2008, 12, 1), OFFSET_ZERO, 1);
}
+ @Test
public void test_London_getOffsetInfo_toDST() {
ZoneRules test = europeLondon();
checkOffset(test, createLDT(2008, 3, 24), OFFSET_ZERO, 1);
@@ -206,6 +213,7 @@
checkOffset(test, LocalDateTime.of(2008, 3, 30, 2, 0, 0, 0), OFFSET_PONE, 1);
}
+ @Test
public void test_London_getOffsetInfo_fromDST() {
ZoneRules test = europeLondon();
checkOffset(test, createLDT(2008, 10, 24), OFFSET_PONE, 1);
@@ -221,6 +229,7 @@
checkOffset(test, LocalDateTime.of(2008, 10, 26, 2, 0, 0, 0), OFFSET_ZERO, 1);
}
+ @Test
public void test_London_getOffsetInfo_gap() {
ZoneRules test = europeLondon();
final LocalDateTime dateTime = LocalDateTime.of(2008, 3, 30, 1, 0, 0, 0);
@@ -246,6 +255,7 @@
assertEquals(trans.hashCode(), otherTrans.hashCode());
}
+ @Test
public void test_London_getOffsetInfo_overlap() {
ZoneRules test = europeLondon();
final LocalDateTime dateTime = LocalDateTime.of(2008, 10, 26, 1, 0, 0, 0);
@@ -272,6 +282,7 @@
assertEquals(trans.hashCode(), otherTrans.hashCode());
}
+ @Test
public void test_London_getStandardOffset() {
ZoneRules test = europeLondon();
ZonedDateTime zdt = createZDT(1840, 1, 1, ZoneOffset.UTC);
@@ -288,6 +299,7 @@
}
}
+ @Test
public void test_London_getTransitions() {
ZoneRules test = europeLondon();
List<ZoneOffsetTransition> trans = test.getTransitions();
@@ -365,6 +377,7 @@
assertEquals(it.hasNext(), false);
}
+ @Test
public void test_London_getTransitionRules() {
ZoneRules test = europeLondon();
List<ZoneOffsetTransitionRule> rules = test.getTransitionRules();
@@ -392,6 +405,7 @@
}
//-----------------------------------------------------------------------
+ @Test
public void test_London_nextTransition_historic() {
ZoneRules test = europeLondon();
List<ZoneOffsetTransition> trans = test.getTransitions();
@@ -408,6 +422,7 @@
}
}
+ @Test
public void test_London_nextTransition_rulesBased() {
ZoneRules test = europeLondon();
List<ZoneOffsetTransitionRule> rules = test.getTransitionRules();
@@ -429,6 +444,7 @@
}
}
+ @Test
public void test_London_nextTransition_lastYear() {
ZoneRules test = europeLondon();
List<ZoneOffsetTransitionRule> rules = test.getTransitionRules();
@@ -437,6 +453,7 @@
}
//-----------------------------------------------------------------------
+ @Test
public void test_London_previousTransition_historic() {
ZoneRules test = europeLondon();
List<ZoneOffsetTransition> trans = test.getTransitions();
@@ -455,6 +472,7 @@
}
}
+ @Test
public void test_London_previousTransition_rulesBased() {
ZoneRules test = europeLondon();
List<ZoneOffsetTransitionRule> rules = test.getTransitionRules();
@@ -492,11 +510,13 @@
return ZoneId.of("Europe/Paris").getRules();
}
+ @Test
public void test_Paris() {
ZoneRules test = europeParis();
assertEquals(test.isFixedOffset(), false);
}
+ @Test
public void test_Paris_preTimeZones() {
ZoneRules test = europeParis();
ZonedDateTime old = createZDT(1800, 1, 1, ZoneOffset.UTC);
@@ -509,6 +529,7 @@
assertEquals(test.isDaylightSavings(instant), false);
}
+ @Test
public void test_Paris_getOffset() {
ZoneRules test = europeParis();
assertEquals(test.getOffset(createInstant(2008, 1, 1, ZoneOffset.UTC)), OFFSET_PONE);
@@ -525,6 +546,7 @@
assertEquals(test.getOffset(createInstant(2008, 12, 1, ZoneOffset.UTC)), OFFSET_PONE);
}
+ @Test
public void test_Paris_getOffset_toDST() {
ZoneRules test = europeParis();
assertEquals(test.getOffset(createInstant(2008, 3, 24, ZoneOffset.UTC)), OFFSET_PONE);
@@ -540,6 +562,7 @@
assertEquals(test.getOffset(createInstant(2008, 3, 30, 1, 0, 0, 0, ZoneOffset.UTC)), OFFSET_PTWO);
}
+ @Test
public void test_Paris_getOffset_fromDST() {
ZoneRules test = europeParis();
assertEquals(test.getOffset(createInstant(2008, 10, 24, ZoneOffset.UTC)), OFFSET_PTWO);
@@ -555,6 +578,7 @@
assertEquals(test.getOffset(createInstant(2008, 10, 26, 1, 0, 0, 0, ZoneOffset.UTC)), OFFSET_PONE);
}
+ @Test
public void test_Paris_getOffsetInfo() {
ZoneRules test = europeParis();
checkOffset(test, createLDT(2008, 1, 1), OFFSET_PONE, 1);
@@ -571,6 +595,7 @@
checkOffset(test, createLDT(2008, 12, 1), OFFSET_PONE, 1);
}
+ @Test
public void test_Paris_getOffsetInfo_toDST() {
ZoneRules test = europeParis();
checkOffset(test, createLDT(2008, 3, 24), OFFSET_PONE, 1);
@@ -586,6 +611,7 @@
checkOffset(test, LocalDateTime.of(2008, 3, 30, 3, 0, 0, 0), OFFSET_PTWO, 1);
}
+ @Test
public void test_Paris_getOffsetInfo_fromDST() {
ZoneRules test = europeParis();
checkOffset(test, createLDT(2008, 10, 24), OFFSET_PTWO, 1);
@@ -601,6 +627,7 @@
checkOffset(test, LocalDateTime.of(2008, 10, 26, 3, 0, 0, 0), OFFSET_PONE, 1);
}
+ @Test
public void test_Paris_getOffsetInfo_gap() {
ZoneRules test = europeParis();
final LocalDateTime dateTime = LocalDateTime.of(2008, 3, 30, 2, 0, 0, 0);
@@ -624,6 +651,7 @@
assertEquals(trans.hashCode(), otherTrans.hashCode());
}
+ @Test
public void test_Paris_getOffsetInfo_overlap() {
ZoneRules test = europeParis();
final LocalDateTime dateTime = LocalDateTime.of(2008, 10, 26, 2, 0, 0, 0);
@@ -648,6 +676,7 @@
assertEquals(trans.hashCode(), otherTrans.hashCode());
}
+ @Test
public void test_Paris_getStandardOffset() {
ZoneRules test = europeParis();
ZonedDateTime zdt = createZDT(1840, 1, 1, ZoneOffset.UTC);
@@ -675,11 +704,13 @@
return ZoneId.of("America/New_York").getRules();
}
+ @Test
public void test_NewYork() {
ZoneRules test = americaNewYork();
assertEquals(test.isFixedOffset(), false);
}
+ @Test
public void test_NewYork_preTimeZones() {
ZoneRules test = americaNewYork();
ZonedDateTime old = createZDT(1800, 1, 1, ZoneOffset.UTC);
@@ -692,6 +723,7 @@
assertEquals(test.isDaylightSavings(instant), false);
}
+ @Test
public void test_NewYork_getOffset() {
ZoneRules test = americaNewYork();
ZoneOffset offset = ZoneOffset.ofHours(-5);
@@ -721,6 +753,7 @@
assertEquals(test.getOffset(createInstant(2008, 12, 28, offset)), ZoneOffset.ofHours(-5));
}
+ @Test
public void test_NewYork_getOffset_toDST() {
ZoneRules test = americaNewYork();
ZoneOffset offset = ZoneOffset.ofHours(-5);
@@ -736,6 +769,7 @@
assertEquals(test.getOffset(createInstant(2008, 3, 9, 2, 0, 0, 0, offset)), ZoneOffset.ofHours(-4));
}
+ @Test
public void test_NewYork_getOffset_fromDST() {
ZoneRules test = americaNewYork();
ZoneOffset offset = ZoneOffset.ofHours(-4);
@@ -751,6 +785,7 @@
assertEquals(test.getOffset(createInstant(2008, 11, 2, 2, 0, 0, 0, offset)), ZoneOffset.ofHours(-5));
}
+ @Test
public void test_NewYork_getOffsetInfo() {
ZoneRules test = americaNewYork();
checkOffset(test, createLDT(2008, 1, 1), ZoneOffset.ofHours(-5), 1);
@@ -779,6 +814,7 @@
checkOffset(test, createLDT(2008, 12, 28), ZoneOffset.ofHours(-5), 1);
}
+ @Test
public void test_NewYork_getOffsetInfo_toDST() {
ZoneRules test = americaNewYork();
checkOffset(test, createLDT(2008, 3, 8), ZoneOffset.ofHours(-5), 1);
@@ -793,6 +829,7 @@
checkOffset(test, LocalDateTime.of(2008, 3, 9, 3, 0, 0, 0), ZoneOffset.ofHours(-4), 1);
}
+ @Test
public void test_NewYork_getOffsetInfo_fromDST() {
ZoneRules test = americaNewYork();
checkOffset(test, createLDT(2008, 11, 1), ZoneOffset.ofHours(-4), 1);
@@ -807,6 +844,7 @@
checkOffset(test, LocalDateTime.of(2008, 11, 2, 2, 0, 0, 0), ZoneOffset.ofHours(-5), 1);
}
+ @Test
public void test_NewYork_getOffsetInfo_gap() {
ZoneRules test = americaNewYork();
final LocalDateTime dateTime = LocalDateTime.of(2008, 3, 9, 2, 0, 0, 0);
@@ -830,6 +868,7 @@
assertEquals(trans.hashCode(), otherTrans.hashCode());
}
+ @Test
public void test_NewYork_getOffsetInfo_overlap() {
ZoneRules test = americaNewYork();
final LocalDateTime dateTime = LocalDateTime.of(2008, 11, 2, 1, 0, 0, 0);
@@ -854,6 +893,7 @@
assertEquals(trans.hashCode(), otherTrans.hashCode());
}
+ @Test
public void test_NewYork_getStandardOffset() {
ZoneRules test = americaNewYork();
ZonedDateTime dateTime = createZDT(1860, 1, 1, ZoneOffset.UTC);
@@ -875,6 +915,7 @@
return ZoneId.of("Asia/Kathmandu").getRules();
}
+ @Test
public void test_Kathmandu_nextTransition_historic() {
ZoneRules test = asiaKathmandu();
List<ZoneOffsetTransition> trans = test.getTransitions();
@@ -891,6 +932,7 @@
}
}
+ @Test
public void test_Kathmandu_nextTransition_noRules() {
ZoneRules test = asiaKathmandu();
List<ZoneOffsetTransition> trans = test.getTransitions();
@@ -906,6 +948,7 @@
return ZoneId.of("Pacific/Apia").getRules();
}
+ @Test
public void test_Apia_nextTransition_historic() {
ZoneRules test = pacificApia();
List<ZoneOffsetTransition> trans = test.getTransitions();
@@ -922,6 +965,7 @@
}
}
+ @Test
public void test_Apia_jumpOverInternationalDateLine_M10_to_P14() {
// transition occurred at 2011-12-30T00:00-10:00
ZoneRules test = pacificApia();
@@ -940,6 +984,7 @@
assertEquals(zdt.plusHours(2).toLocalDateTime(), LocalDateTime.of(2011, 12, 31, 1, 0));
}
+ @Test
public void test_Apia_jumpForwardOverInternationalDateLine_P12_to_M12() {
// transition occurred at 1892-07-04T00:00+12:33:04
ZoneRules test = pacificApia();
@@ -974,6 +1019,7 @@
//-----------------------------------------------------------------------
// of()
//-----------------------------------------------------------------------
+ @Test
public void test_of(){
//used for standard offset
ZoneOffset stdOffset1 = ZoneOffset.UTC;
@@ -1049,6 +1095,7 @@
//-----------------------------------------------------------------------
// equals() / hashCode()
//-----------------------------------------------------------------------
+ @Test
public void test_equals() {
ZoneRules test1 = europeLondon();
ZoneRules test2 = europeParis();
@@ -1065,14 +1112,17 @@
assertEquals(test2.hashCode() == test2b.hashCode(), true);
}
+ @Test
public void test_equals_null() {
assertEquals(europeLondon().equals(null), false);
}
+ @Test
public void test_equals_notZoneRules() {
assertEquals(europeLondon().equals("Europe/London"), false);
}
+ @Test
public void test_toString() {
assertEquals(europeLondon().toString().contains("ZoneRules"), true);
}
--- a/test/jdk/java/time/test/java/time/chrono/TestJapaneseChronology.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/java/time/test/java/time/chrono/TestJapaneseChronology.java Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 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
@@ -58,6 +58,8 @@
{ JapaneseEra.SHOWA, 1, 12, 25, 1926 },
{ JapaneseEra.SHOWA, 64, 1, 7, 1989 },
{ JapaneseEra.HEISEI, 1, 1, 8, 1989 },
+ { JapaneseEra.HEISEI, 31, 4, 30, 2019 },
+ { JapaneseEra.of(3), 1, 5, 1, 2019 }, // NEWERA
};
}
@@ -74,6 +76,8 @@
{ JapaneseEra.SHOWA, 64, 7, 1, 7 },
{ JapaneseEra.HEISEI, 1, 1, 1, 8 },
{ JapaneseEra.HEISEI, 2, 8, 1, 8 },
+ { JapaneseEra.HEISEI, 31, 120, 4, 30 },
+ { JapaneseEra.of(3), 1, 1, 5, 1 }, // NEWERA
};
}
@@ -81,8 +85,8 @@
Object[][] rangeData() {
return new Object[][] {
// field, minSmallest, minLargest, maxSmallest, maxLargest
- { ChronoField.ERA, -1, -1, 2, 2},
- { ChronoField.YEAR_OF_ERA, 1, 1, 15, 999999999-1989 }, // depends on the current era
+ { ChronoField.ERA, -1, -1, 3, 3},
+ { ChronoField.YEAR_OF_ERA, 1, 1, 15, 999999999-2019}, // depends on the current era
{ ChronoField.DAY_OF_YEAR, 1, 1, 7, 366},
{ ChronoField.YEAR, 1873, 1873, 999999999, 999999999},
};
@@ -105,7 +109,9 @@
{ JapaneseEra.SHOWA, 65, 1, 1 },
{ JapaneseEra.HEISEI, 1, 1, 7 },
{ JapaneseEra.HEISEI, 1, 2, 29 },
- { JapaneseEra.HEISEI, Year.MAX_VALUE, 12, 31 },
+ { JapaneseEra.HEISEI, 31, 5, 1 },
+ { JapaneseEra.of(3), 1, 4, 30 }, // NEWERA
+ { JapaneseEra.of(3), Year.MAX_VALUE, 12, 31 }, // NEWERA
};
}
@@ -124,7 +130,10 @@
{ JapaneseEra.SHOWA, 65 },
{ JapaneseEra.HEISEI, -1 },
{ JapaneseEra.HEISEI, 0 },
- { JapaneseEra.HEISEI, Year.MAX_VALUE },
+ { JapaneseEra.HEISEI, 32 },
+ { JapaneseEra.of(3), -1 }, // NEWERA
+ { JapaneseEra.of(3), 0 }, // NEWERA
+ { JapaneseEra.of(3), Year.MAX_VALUE }, // NEWERA
};
}
@@ -141,6 +150,9 @@
{ JapaneseEra.SHOWA, 64, 8 },
{ JapaneseEra.HEISEI, 1, 360 },
{ JapaneseEra.HEISEI, 2, 366 },
+ { JapaneseEra.HEISEI, 31, 121 },
+ { JapaneseEra.of(3), 1, 246 }, // NEWERA
+ { JapaneseEra.of(3), 2, 367 }, // NEWERA
};
}
--- a/test/jdk/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2016, 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
@@ -775,8 +775,10 @@
{HijrahDate.of(1350,5,15), "Japanese Showa 6-09-28"},
{HijrahDate.of(1434,5,1), "Japanese Heisei 25-03-13"},
{HijrahDate.of(1436,1,1), "Japanese Heisei 26-10-25"},
- {HijrahDate.of(1500,6,12), "Japanese Heisei 89-05-05"},
- {HijrahDate.of(1550,3,11), "Japanese Heisei 137-08-11"},
+ {HijrahDate.of(1440,8,25), "Japanese Heisei 31-04-30"},
+ {HijrahDate.of(1440,8,26), "Japanese NewEra 1-05-01"},
+ {HijrahDate.of(1500,6,12), "Japanese NewEra 59-05-05"},
+ {HijrahDate.of(1550,3,11), "Japanese NewEra 107-08-11"},
};
}
--- a/test/jdk/java/util/Calendar/Bug8007038.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/java/util/Calendar/Bug8007038.java Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 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
@@ -46,7 +46,7 @@
private static final int[][] eraMinMax = {
{GregorianCalendar.BC, GregorianCalendar.AD},
{0, 1},
- {0, 4},
+ {0, 5},
{0, 1},
{0, 1},
{0, 1},
--- a/test/jdk/java/util/Calendar/Builder/BuilderTest.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/java/util/Calendar/Builder/BuilderTest.java Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 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
@@ -27,6 +27,7 @@
* @summary Unit test for Calendar.Builder.
*/
+import java.time.LocalDateTime;
import java.util.*;
import static java.util.Calendar.*;
@@ -132,7 +133,11 @@
.setFields(YEAR, 1, DAY_OF_YEAR, 1).build();
expected = Calendar.getInstance(jaJPJP);
expected.clear();
- expected.set(1, JANUARY, 8);
+ if (LocalDateTime.now().isBefore(LocalDateTime.of(2019, 5, 1, 0, 0))) {
+ expected.set(1, JANUARY, 8);
+ } else {
+ expected.set(1, MAY, 1);
+ }
check(cal, expected);
// setLocale
calb = builder();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/util/Calendar/JapaneseEraNameTest.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,65 @@
+/*
+ * 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 8202088
+ * @summary Test the localized Japanese new era name (May 1st. 2019-)
+ * is retrieved no matter CLDR provider contains the name or not.
+ * @modules jdk.localedata
+ * @run testng/othervm JapaneseEraNameTest
+ * @run testng/othervm -Djava.locale.providers=CLDR JapaneseEraNameTest
+ */
+
+import static java.util.Calendar.*;
+import static java.util.Locale.*;
+import java.util.Calendar;
+import java.util.Locale;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import static org.testng.Assert.assertEquals;
+
+@Test
+public class JapaneseEraNameTest {
+ static final Calendar c = new Calendar.Builder()
+ .setCalendarType("japanese")
+ .setFields(ERA, 5, YEAR, 1, MONTH, MAY, DAY_OF_MONTH, 1)
+ .build();
+
+ @DataProvider(name="names")
+ Object[][] names() {
+ return new Object[][] {
+ // type, locale, name
+ { LONG, JAPAN, "\u65b0\u5143\u53f7" }, // NewEra
+ { LONG, US, "NewEra" },
+ { SHORT, JAPAN, "N" },
+ { SHORT, US, "N" },
+ };
+ }
+
+ @Test(dataProvider="names")
+ public void testJapaneseNewEraName(int type, Locale locale, String expected) {
+ assertEquals(c.getDisplayName(ERA, type, locale), expected);
+ }
+}
--- a/test/jdk/java/util/Calendar/NarrowNamesTest.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/java/util/Calendar/NarrowNamesTest.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -21,6 +21,7 @@
* questions.
*/
+import java.time.LocalDateTime;
import java.util.*;
import static java.util.GregorianCalendar.*;
@@ -49,7 +50,9 @@
HOUR_OF_DAY, 10);
test(US, AM_PM, "p",
HOUR_OF_DAY, 23);
- test(JAJPJP, DAY_OF_WEEK, "\u65e5",
+ test(JAJPJP, DAY_OF_WEEK,
+ LocalDateTime.now().isBefore(LocalDateTime.of(2019, 5, 1, 0, 0)) ?
+ "\u65e5" : "\u706b", // "Sun" for HEISEI, "Tue" for NEWERA
YEAR, 24, MONTH, DECEMBER, DAY_OF_MONTH, 23);
test(THTH, MONTH, NARROW_STANDALONE, "\u0e18.\u0e04.",
YEAR, 2555, MONTH, DECEMBER, DAY_OF_MONTH, 5);
--- a/test/jdk/java/util/Calendar/SupplementalJapaneseEraTest.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/java/util/Calendar/SupplementalJapaneseEraTest.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -50,8 +50,8 @@
public class SupplementalJapaneseEraTest {
private static final Locale WAREKI_LOCALE = Locale.forLanguageTag("ja-JP-u-ca-japanese");
- private static final String NEW_ERA_NAME = "NewEra";
- private static final String NEW_ERA_ABBR = "N.E.";
+ private static final String SUP_ERA_NAME = "SupEra";
+ private static final String SUP_ERA_ABBR = "S.E.";
private static int errors = 0;
public static void main(String[] args) {
@@ -62,6 +62,7 @@
Calendar cal = new Calendar.Builder()
.setCalendarType("japanese")
.setTimeZone(TimeZone.getTimeZone("GMT"))
+ .setFields(ERA, 5)
.setDate(200, FEBRUARY, 11)
.build();
System.out.println(cal.getTimeInMillis());
@@ -95,10 +96,9 @@
private static void testProperty() {
Calendar jcal = new Calendar.Builder()
.setCalendarType("japanese")
- .setFields(YEAR, 1, DAY_OF_YEAR, 1)
+ .setFields(ERA, 6, YEAR, 1, DAY_OF_YEAR, 1)
.build();
Date firstDayOfEra = jcal.getTime();
-
jcal.set(ERA, jcal.get(ERA) - 1); // previous era
jcal.set(YEAR, 1);
jcal.set(DAY_OF_YEAR, 1);
@@ -113,7 +113,7 @@
// test long era name
sdf = new SimpleDateFormat("GGGG y-MM-dd", WAREKI_LOCALE);
got = sdf.format(firstDayOfEra);
- expected = NEW_ERA_NAME + " 1-02-11";
+ expected = SUP_ERA_NAME + " 1-02-11";
if (!expected.equals(got)) {
System.err.printf("GGGG y-MM-dd: got=\"%s\", expected=\"%s\"%n", got, expected);
errors++;
@@ -122,7 +122,7 @@
// test era abbreviation
sdf = new SimpleDateFormat("G y-MM-dd", WAREKI_LOCALE);
got = sdf.format(firstDayOfEra);
- expected = NEW_ERA_ABBR+" 1-02-11";
+ expected = SUP_ERA_ABBR + " 1-02-11";
if (!expected.equals(got)) {
System.err.printf("G y-MM-dd: got=\"%s\", expected=\"%s\"%n", got, expected);
errors++;
@@ -139,30 +139,30 @@
// test java.time.chrono.JapaneseEra
JapaneseDate jdate = JapaneseDate.of(year, 2, 11);
got = jdate.toString();
- expected = "Japanese " + NEW_ERA_NAME + " 1-02-11";
+ expected = "Japanese " + SUP_ERA_NAME + " 1-02-11";
if (!expected.equals(got)) {
System.err.printf("JapaneseDate: got=\"%s\", expected=\"%s\"%n", got, expected);
errors++;
}
JapaneseEra jera = jdate.getEra();
got = jera.getDisplayName(TextStyle.FULL, Locale.US);
- if (!NEW_ERA_NAME.equals(got)) {
- System.err.printf("JapaneseEra (FULL): got=\"%s\", expected=\"%s\"%n", got, NEW_ERA_NAME);
+ if (!SUP_ERA_NAME.equals(got)) {
+ System.err.printf("JapaneseEra (FULL): got=\"%s\", expected=\"%s\"%n", got, SUP_ERA_NAME);
errors++;
}
got = jera.getDisplayName(TextStyle.SHORT, Locale.US);
- if (!NEW_ERA_NAME.equals(got)) {
- System.err.printf("JapaneseEra (SHORT): got=\"%s\", expected=\"%s\"%n", got, NEW_ERA_NAME);
+ if (!SUP_ERA_NAME.equals(got)) {
+ System.err.printf("JapaneseEra (SHORT): got=\"%s\", expected=\"%s\"%n", got, SUP_ERA_NAME);
errors++;
}
got = jera.getDisplayName(TextStyle.NARROW, Locale.US);
- if (!NEW_ERA_ABBR.equals(got)) {
- System.err.printf("JapaneseEra (NARROW): got=\"%s\", expected=\"%s\"%n", got, NEW_ERA_ABBR);
+ if (!SUP_ERA_ABBR.equals(got)) {
+ System.err.printf("JapaneseEra (NARROW): got=\"%s\", expected=\"%s\"%n", got, SUP_ERA_ABBR);
errors++;
}
got = jera.getDisplayName(TextStyle.NARROW_STANDALONE, Locale.US);
- if (!NEW_ERA_ABBR.equals(got)) {
- System.err.printf("JapaneseEra (NARROW_STANDALONE): got=\"%s\", expected=\"%s\"%n", got, NEW_ERA_ABBR);
+ if (!SUP_ERA_ABBR.equals(got)) {
+ System.err.printf("JapaneseEra (NARROW_STANDALONE): got=\"%s\", expected=\"%s\"%n", got, SUP_ERA_ABBR);
errors++;
}
@@ -172,7 +172,7 @@
.withLocale(Locale.US)
.withChronology(JapaneseChronology.INSTANCE)
.format(jdate);
- expected = NEW_ERA_NAME + " " + NEW_ERA_NAME + " " + NEW_ERA_ABBR;
+ expected = SUP_ERA_NAME + " " + SUP_ERA_NAME + " " + SUP_ERA_ABBR;
if (!expected.equals(got)) {
System.err.printf("java.time formatter full/short/narrow names: got=\"%s\", expected=\"%s\"%n", got, expected);
errors++;
--- a/test/jdk/java/util/Calendar/SupplementalJapaneseEraTest.sh Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/java/util/Calendar/SupplementalJapaneseEraTest.sh Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -34,8 +34,8 @@
SINCE=`${TESTJAVA}/bin/java -cp "${TESTCLASSES}" SupplementalJapaneseEraTest -s`
echo "Tests with valid property values..."
-for P in "name=NewEra,abbr=N.E.,since=$SINCE" \
- "name = NewEra, abbr = N.E., since = $SINCE"
+for P in "name=SupEra,abbr=S.E.,since=$SINCE" \
+ "name = SupEra, abbr = S.E., since = $SINCE"
do
if ${TESTJAVA}/bin/java ${TESTVMOPTS} -cp "${TESTCLASSES}" \
-D$PROPERTY="$P" SupplementalJapaneseEraTest -t; then
@@ -51,17 +51,17 @@
ERA=`${TESTJAVA}/bin/java -cp "${TESTCLASSES}" SupplementalJapaneseEraTest -e`
echo "Tests with invalid property values..."
-for P in "foo=Bar,name=NewEra,abbr=N.E.,since=$SINCE" \
- "=NewEra,abbr=N.E.,since=$SINCE" \
- "=,abbr=N.E.,since=$SINCE" \
- "name,abbr=N.E.,since=$SINCE" \
- "abbr=N.E.,since=$SINCE" \
- "name=NewEra,since=$SINCE" \
- "name=,abbr=N.E.,since=$SINCE" \
- "name=NewEra,abbr=,since=$SINCE" \
- "name=NewEra,abbr=N.E." \
- "name=NewEra,abbr=N.E.,since=0" \
- "name=NewEra,abbr=N.E.,since=9223372036854775808" # Long.MAX_VALUE+1
+for P in "foo=Bar,name=SupEra,abbr=S.E.,since=$SINCE" \
+ "=SupEra,abbr=S.E.,since=$SINCE" \
+ "=,abbr=S.E.,since=$SINCE" \
+ "name,abbr=S.E.,since=$SINCE" \
+ "abbr=S.E.,since=$SINCE" \
+ "name=SupEra,since=$SINCE" \
+ "name=,abbr=S.E.,since=$SINCE" \
+ "name=SupEra,abbr=,since=$SINCE" \
+ "name=SupEra,abbr=S.E." \
+ "name=SupEra,abbr=S.E.,since=0" \
+ "name=SupEra,abbr=S.E.,since=9223372036854775808" # Long.MAX_VALUE+1
do
if ${TESTJAVA}/bin/java ${TESTVMOPTS} -cp "${TESTCLASSES}" \
-D$PROPERTY="$P" SupplementalJapaneseEraTest -b "$ERA"; then
--- a/test/jdk/java/util/Calendar/ZoneOffsets.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/java/util/Calendar/ZoneOffsets.java Wed Jun 13 11:01:25 2018 -0700
@@ -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
@@ -192,6 +192,7 @@
cal2.setTimeZone(tz2);
cal2.clear();
cal2.set(2005, MARCH, 11);
+ adjustJapaneseEra(cal2);
// test5: set only ZONE_OFFSET in non-lenient
cal2.set(ZONE_OFFSET, gmtOffset);
if (t1 != cal2.getTime().getTime() || dst != cal2.get(DST_OFFSET)) {
@@ -201,6 +202,7 @@
cal2.setTimeZone(tz3);
cal2.clear();
cal2.set(2005, MARCH, 11);
+ adjustJapaneseEra(cal2);
// test6: set only DST_OFFSET in non-lenient
cal2.set(DST_OFFSET, dstOffset);
if (t1 != cal2.getTime().getTime() || gmt != cal2.get(ZONE_OFFSET)) {
@@ -210,6 +212,7 @@
cal2.setTimeZone(tz2);
cal2.clear();
cal2.set(2005, MARCH, 11);
+ adjustJapaneseEra(cal2);
// test7: set both ZONE_OFFSET and DST_OFFSET in non-lenient
cal2.set(ZONE_OFFSET, gmtOffset);
cal2.set(DST_OFFSET, dstOffset);
@@ -220,6 +223,7 @@
cal2.setTimeZone(tz3);
cal2.clear();
cal2.set(2005, MARCH, 11);
+ adjustJapaneseEra(cal2);
// test8: set both ZONE_OFFSET and DST_OFFSET in non-lenient
cal2.set(ZONE_OFFSET, gmtOffset);
cal2.set(DST_OFFSET, dstOffset);
@@ -234,4 +238,16 @@
+ ", gmtOffset=" + gmtOffset + ", dstOffset=" + dstOffset
+ ", cal1 time=" + t1 + ", cal2 time=" + cal2.getTime().getTime());
}
+
+ private static void adjustJapaneseEra(Calendar cal) {
+ // In case of Japanese calendar, explicitly set the last era; NEWERA so that
+ // year 2005 won't throw exception
+ if (!cal.isLenient() &&
+ cal.getCalendarType().equals("japanese") &&
+ System.currentTimeMillis() < 1556668800000L) { // Current time not in NEWERA
+ cal.set(Calendar.ERA, 5);
+ cal.add(Calendar.YEAR, -30); // -30: Subtract year-length of HEISEI era
+ }
+ return;
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/crypto/CipherSpi/TestGCMWithByteBuffer.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,165 @@
+/*
+ * 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 8178374
+ * @summary Test GCM decryption with various types of input/output
+ * ByteBuffer objects
+ * @key randomness
+ */
+
+import java.nio.ByteBuffer;
+import java.security.*;
+import java.util.Random;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.AEADBadTagException;
+import javax.crypto.spec.*;
+
+public class TestGCMWithByteBuffer {
+
+ private static Random random = new SecureRandom();
+ private static int dataSize = 4096; // see javax.crypto.CipherSpi
+ private static int multiples = 3;
+
+ public static void main(String args[]) throws Exception {
+ Provider[] provs = Security.getProviders();
+ for (Provider p : provs) {
+ try {
+ Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", p);
+ test(cipher);
+ } catch (NoSuchAlgorithmException nsae) {
+ // skip testing due to no support
+ continue;
+ }
+ }
+ }
+
+ private static void test(Cipher cipher) throws Exception {
+ System.out.println("Testing " + cipher.getProvider());
+
+ boolean failedOnce = false;
+ Exception failedReason = null;
+
+ int tagLen = 96; // in bits
+ byte[] keyBytes = new byte[16];
+ random.nextBytes(keyBytes);
+ byte[] dataChunk = new byte[dataSize];
+ random.nextBytes(dataChunk);
+
+ SecretKey key = new SecretKeySpec(keyBytes, "AES");
+ // re-use key bytes as IV as the real test is buffer calculation
+ GCMParameterSpec s = new GCMParameterSpec(tagLen, keyBytes);
+
+ /*
+ * Iterate through various sizes to make sure that the code works with
+ * internal temp buffer size 4096.
+ */
+ for (int t = 1; t <= multiples; t++) {
+ int size = t * dataSize;
+
+ System.out.println("\nTesting data size: " + size);
+
+ try {
+ decrypt(cipher, key, s, dataChunk, t,
+ ByteBuffer.allocate(dataSize),
+ ByteBuffer.allocate(size),
+ ByteBuffer.allocateDirect(dataSize),
+ ByteBuffer.allocateDirect(size));
+ } catch (Exception e) {
+ System.out.println("\tFailed with data size " + size);
+ failedOnce = true;
+ failedReason = e;
+ }
+ }
+ if (failedOnce) {
+ throw failedReason;
+ }
+ System.out.println("\n=> Passed...");
+ }
+
+ private enum TestVariant {
+ HEAP_HEAP, HEAP_DIRECT, DIRECT_HEAP, DIRECT_DIRECT
+ };
+
+ private static void decrypt(Cipher cipher, SecretKey key,
+ GCMParameterSpec s, byte[] dataChunk, int multiples,
+ ByteBuffer heapIn, ByteBuffer heapOut, ByteBuffer directIn,
+ ByteBuffer directOut) throws Exception {
+
+ ByteBuffer inBB = null;
+ ByteBuffer outBB = null;
+
+ // try various combinations of input/output
+ for (TestVariant tv : TestVariant.values()) {
+ System.out.println(" " + tv);
+
+ switch (tv) {
+ case HEAP_HEAP:
+ inBB = heapIn;
+ outBB = heapOut;
+ break;
+ case HEAP_DIRECT:
+ inBB = heapIn;
+ outBB = directOut;
+ break;
+ case DIRECT_HEAP:
+ inBB = directIn;
+ outBB = heapOut;
+ break;
+ case DIRECT_DIRECT:
+ inBB = directIn;
+ outBB = directOut;
+ break;
+ }
+
+ // prepare input and output buffers
+ inBB.clear();
+ inBB.put(dataChunk);
+
+ outBB.clear();
+
+ try {
+ // Always re-init the Cipher object so cipher is in
+ // a good state for future testing
+ cipher.init(Cipher.DECRYPT_MODE, key, s);
+
+ for (int i = 0; i < multiples; i++) {
+ inBB.flip();
+ cipher.update(inBB, outBB);
+ if (inBB.hasRemaining()) {
+ throw new Exception("buffer not empty");
+ }
+ }
+ // finish decryption and process all data buffered
+ cipher.doFinal(inBB, outBB);
+ throw new RuntimeException("Error: doFinal completed without exception");
+ } catch (AEADBadTagException ex) {
+ System.out.println("Expected AEADBadTagException thrown");
+ continue;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/imageio/plugins/jpeg/TestWriteARGBJPEG.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,86 @@
+/*
+ * 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 8204187
+ * @run main TestWriteARGBJPEG
+ * @summary verify JPEG Alpha support is as reported.
+ */
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.io.ByteArrayOutputStream;
+import java.awt.image.BufferedImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriter;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.spi.ImageWriterSpi;
+import javax.imageio.stream.MemoryCacheImageOutputStream;
+
+public class TestWriteARGBJPEG {
+ public static void main(String args[]) throws IOException {
+
+ BufferedImage bi =
+ new BufferedImage(10,10,BufferedImage.TYPE_INT_ARGB);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ // There should be no exception from the next line
+ // which internally should be relying on the canEncodeImage
+ // method which we'll also test directly.
+ boolean ret = ImageIO.write(bi, "jpeg", baos);
+ System.out.println("ImageIO.write(..) returned " + ret);
+
+ ImageTypeSpecifier its = new ImageTypeSpecifier(bi);
+ Iterator<ImageWriter> writers = ImageIO.getImageWriters(its, "jpeg");
+ boolean hasWriter = writers.hasNext();
+ // If this can't write it, an exception will be thrown.
+ if (writers.hasNext()) {
+ System.out.println("A writer was found.");
+ ImageWriter iw = writers.next();
+ MemoryCacheImageOutputStream mos =
+ new MemoryCacheImageOutputStream(baos);
+ iw.setOutput(mos);
+ iw.write(bi);
+ }
+
+ // Now Let's also ask the default JPEG writer's SPI if it
+ // can write an ARGB image.
+ ImageWriter iw = ImageIO.getImageWritersByFormatName("jpeg").next();
+ ImageWriterSpi iwSpi = iw.getOriginatingProvider();
+ boolean canEncode = iwSpi.canEncodeImage(bi);
+ System.out.println("SPI canEncodeImage returned " + canEncode);
+
+ // Now let's see if it is telling the truth.
+ try {
+ MemoryCacheImageOutputStream mos =
+ new MemoryCacheImageOutputStream(baos);
+ iw.setOutput(mos);
+ iw.write(bi);
+ } catch (IOException e) {
+ if (canEncode) {
+ throw e;
+ }
+ }
+ }
+}
--- a/test/jdk/javax/imageio/plugins/shared/BitDepth.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/javax/imageio/plugins/shared/BitDepth.java Wed Jun 13 11:01:25 2018 -0700
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 4413109 4418221 6607198 8147448
+ * @bug 4413109 4418221 6607198 8147448 8204187
* @run main BitDepth
* @summary Checks that ImageIO writers for standard formats can handle
* various BufferedImage RGB types. An optional list of arguments
@@ -197,6 +197,7 @@
if (!writers.hasNext()) {
System.out.println("\tNo writers available for type " + biTypeNames[type]
+ " BufferedImage!");
+ return null;
} else {
ImageWriter writer = writers.next();
try (ImageOutputStream out = ImageIO.createImageOutputStream(file)) {
@@ -205,7 +206,7 @@
} catch (Exception e) {
System.out.println("\tCan't write a type " + biTypeNames[type]
+ " BufferedImage!");
- return null;
+ throw new RuntimeException(e);
}
}
--- a/test/jdk/javax/swing/JLayer/8041982/bug8041982.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/javax/swing/JLayer/8041982/bug8041982.java Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 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
@@ -53,7 +53,7 @@
private class BusyLayer extends LayerUI<JComponent> {
private volatile boolean animated = true;
- private Icon icon = new ImageIcon(bug8041982.class.getResource("cupanim.gif"));
+ private Icon icon = new ImageIcon(bug8041982.class.getResource("duke.gif"));
private int imageUpdateCount;
@Override
Binary file test/jdk/javax/swing/JLayer/8041982/cupanim.gif has changed
Binary file test/jdk/javax/swing/JLayer/8041982/duke.gif has changed
--- a/test/jdk/javax/swing/JSlider/4987336/bug4987336.html Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/javax/swing/JSlider/4987336/bug4987336.html Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
<!--
- Copyright (c) 2007, 2013, 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
@@ -24,7 +24,7 @@
<html>
<body>
<applet code="bug4987336.class" width=600 height=400></applet>
-There are four Sliders. Each of them has a label with animated gif (a cup of coffee)
+There are four Sliders. Each of them has a label with animated gif (a waving duke)
and a label with static image.
Check that for every LAF animation works for all Sliders.
--- a/test/jdk/javax/swing/JSlider/4987336/bug4987336.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/javax/swing/JSlider/4987336/bug4987336.java Wed Jun 13 11:01:25 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2008, 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
@@ -37,7 +37,7 @@
public class bug4987336 extends JApplet {
private static final String IMAGE_RES = "box.gif";
- private static final String ANIM_IMAGE_RES = "cupanim.gif";
+ private static final String ANIM_IMAGE_RES = "duke.gif";
public void init() {
JPanel pnLafs = new JPanel();
Binary file test/jdk/javax/swing/JSlider/4987336/cupanim.gif has changed
Binary file test/jdk/javax/swing/JSlider/4987336/duke.gif has changed
--- a/test/jdk/lib/security/cacerts/VerifyCACerts.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/lib/security/cacerts/VerifyCACerts.java Wed Jun 13 11:01:25 2018 -0700
@@ -24,7 +24,7 @@
/**
* @test
- * @bug 8189131 8198240 8191844 8189949 8191031
+ * @bug 8189131 8198240 8191844 8189949 8191031 8196141 8204923
* @requires java.runtime.name ~= "OpenJDK.*"
* @summary Check root CA entries in cacerts file
*/
@@ -42,7 +42,7 @@
+ File.separator + "security" + File.separator + "cacerts";
// The numbers of certs now.
- private static final int COUNT = 70;
+ private static final int COUNT = 75;
// map of cert alias to SHA-256 fingerprint
private static final Map<String, String> FINGERPRINT_MAP
@@ -128,6 +128,8 @@
"3F:9F:27:D5:83:20:4B:9E:09:C8:A3:D2:06:6C:4B:57:D3:A2:47:9C:36:93:65:08:80:50:56:98:10:5D:BC:E9");
put("verisigntsaca [jdk]",
"CB:6B:05:D9:E8:E5:7C:D8:82:B1:0B:4D:B7:0D:E4:BB:1D:E4:2B:A4:8A:7B:D0:31:8B:63:5B:F6:E7:78:1A:9D");
+ put("verisignclass2g2ca [jdk]",
+ "3A:43:E2:20:FE:7F:3E:A9:65:3D:1E:21:74:2E:AC:2B:75:C2:0F:D8:98:03:05:BC:50:2C:AF:8C:2D:9B:41:A1");
put("verisignclass3ca [jdk]",
"A4:B6:B3:99:6F:C2:F3:06:B3:FD:86:81:BD:63:41:3D:8C:50:09:CC:4F:A3:29:C2:CC:F0:E2:FA:1B:14:03:05");
put("verisignclass3g2ca [jdk]",
@@ -188,6 +190,14 @@
"F1:C1:B5:0A:E5:A2:0D:D8:03:0E:C9:F6:BC:24:82:3D:D3:67:B5:25:57:59:B4:E7:1B:61:FC:E9:F7:37:5D:73");
put("xrampglobalca [jdk]",
"CE:CD:DC:90:50:99:D8:DA:DF:C5:B1:D2:09:B7:37:CB:E2:C1:8C:FB:2C:10:C0:FF:0B:CF:0D:32:86:FC:1A:A2");
+ put("godaddyrootg2ca [jdk]",
+ "45:14:0B:32:47:EB:9C:C8:C5:B4:F0:D7:B5:30:91:F7:32:92:08:9E:6E:5A:63:E2:74:9D:D3:AC:A9:19:8E:DA");
+ put("godaddyclass2ca [jdk]",
+ "C3:84:6B:F2:4B:9E:93:CA:64:27:4C:0E:C6:7C:1E:CC:5E:02:4F:FC:AC:D2:D7:40:19:35:0E:81:FE:54:6A:E4");
+ put("starfieldclass2ca [jdk]",
+ "14:65:FA:20:53:97:B8:76:FA:A6:F0:A9:95:8E:55:90:E4:0F:CC:7F:AA:4F:B7:C2:C8:67:75:21:FB:5F:B6:58");
+ put("starfieldrootg2ca [jdk]",
+ "2C:E1:CB:0B:F9:D2:F9:E1:02:99:3F:BE:21:51:52:C3:B2:DD:0C:AB:DE:1C:68:E5:31:9B:83:91:54:DB:B7:F5");
}
};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/GoDaddyCA.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,346 @@
+/*
+ * 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 8196141
+ * @summary Interoperability tests with GoDaddy/Starfield CA
+ * @build ValidatePathWithParams
+ * @run main/othervm -Djava.security.debug=certpath GoDaddyCA OCSP
+ * @run main/othervm -Djava.security.debug=certpath GoDaddyCA CRL
+ */
+
+/*
+ * Obtain test artifacts for GoDaddy/Starfield CAs from:
+ *
+ * Go Daddy Root Certificate Authority - G2:
+ * valid: https://valid.gdig2.catest.godaddy.com/
+ * expired: https://expired.gdig2.catest.godaddy.com/
+ * revoked: https://revoked.gdig2.catest.godaddy.com/
+ *
+ * Starfield Root Certificate Authority - G2:
+ * valid: https://valid.sfig2.catest.starfieldtech.com/
+ * expired: https://expired.sfig2.catest.starfieldtech.com/
+ * revoked: https://revoked.sfig2.catest.starfieldtech.com/
+ */
+public class GoDaddyCA {
+
+ public static void main(String[] args) throws Exception {
+
+ ValidatePathWithParams pathValidator = new ValidatePathWithParams(null);
+
+ if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) {
+ // CRL check
+ pathValidator.enableCRLCheck();
+ } else {
+ // OCSP check by default
+ pathValidator.enableOCSPCheck();
+ }
+
+ new GoDaddyGdig2().runTest(pathValidator);
+ new GoDaddySfig2().runTest(pathValidator);
+ }
+}
+
+class GoDaddyGdig2 {
+
+ // Owner: CN=Go Daddy Secure Certificate Authority - G2,
+ // OU=http://certs.godaddy.com/repository/, O="GoDaddy.com, Inc.",
+ // L=Scottsdale, ST=Arizona, C=US
+ // Issuer: CN=Go Daddy Root Certificate Authority - G2, O="GoDaddy.com, Inc.",
+ // L=Scottsdale, ST=Arizona, C=US
+ private static final String INT = "-----BEGIN CERTIFICATE-----\n"
+ + "MIIE0DCCA7igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx\n"
+ + "EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT\n"
+ + "EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp\n"
+ + "ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAwMFoXDTMxMDUwMzA3\n"
+ + "MDAwMFowgbQxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH\n"
+ + "EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UE\n"
+ + "CxMkaHR0cDovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQD\n"
+ + "EypHbyBEYWRkeSBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEi\n"
+ + "MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC54MsQ1K92vdSTYuswZLiBCGzD\n"
+ + "BNliF44v/z5lz4/OYuY8UhzaFkVLVat4a2ODYpDOD2lsmcgaFItMzEUz6ojcnqOv\n"
+ + "K/6AYZ15V8TPLvQ/MDxdR/yaFrzDN5ZBUY4RS1T4KL7QjL7wMDge87Am+GZHY23e\n"
+ + "cSZHjzhHU9FGHbTj3ADqRay9vHHZqm8A29vNMDp5T19MR/gd71vCxJ1gO7GyQ5HY\n"
+ + "pDNO6rPWJ0+tJYqlxvTV0KaudAVkV4i1RFXULSo6Pvi4vekyCgKUZMQWOlDxSq7n\n"
+ + "eTOvDCAHf+jfBDnCaQJsY1L6d8EbyHSHyLmTGFBUNUtpTrw700kuH9zB0lL7AgMB\n"
+ + "AAGjggEaMIIBFjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV\n"
+ + "HQ4EFgQUQMK9J47MNIMwojPX+2yz8LQsgM4wHwYDVR0jBBgwFoAUOpqFBxBnKLbv\n"
+ + "9r0FQW4gwZTaD94wNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v\n"
+ + "b2NzcC5nb2RhZGR5LmNvbS8wNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2NybC5n\n"
+ + "b2RhZGR5LmNvbS9nZHJvb3QtZzIuY3JsMEYGA1UdIAQ/MD0wOwYEVR0gADAzMDEG\n"
+ + "CCsGAQUFBwIBFiVodHRwczovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkv\n"
+ + "MA0GCSqGSIb3DQEBCwUAA4IBAQAIfmyTEMg4uJapkEv/oV9PBO9sPpyIBslQj6Zz\n"
+ + "91cxG7685C/b+LrTW+C05+Z5Yg4MotdqY3MxtfWoSKQ7CC2iXZDXtHwlTxFWMMS2\n"
+ + "RJ17LJ3lXubvDGGqv+QqG+6EnriDfcFDzkSnE3ANkR/0yBOtg2DZ2HKocyQetawi\n"
+ + "DsoXiWJYRBuriSUBAA/NxBti21G00w9RKpv0vHP8ds42pM3Z2Czqrpv1KrKQ0U11\n"
+ + "GIo/ikGQI31bS/6kA1ibRrLDYGCD+H1QQc7CoZDDu+8CL9IVVO5EFdkKrqeKM+2x\n"
+ + "LXY2JtwE65/3YR8V3Idv7kaWKK2hJn0KCacuBKONvPi8BDAB\n"
+ + "-----END CERTIFICATE-----";
+
+ // 1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=Delaware/businessCategory=Private
+ // Organization/serialNumber=5510922, C=US, ST=Arizona, L=Scottsdale, O=GoDaddy INC., CN=valid.gdig2.catest.godaddy.com
+ private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+ "MIIHbzCCBlegAwIBAgIIC3Go9uPeseowDQYJKoZIhvcNAQELBQAwgbQxCzAJBgNV\n" +
+ "BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRow\n" +
+ "GAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UECxMkaHR0cDovL2NlcnRz\n" +
+ "LmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQDEypHbyBEYWRkeSBTZWN1\n" +
+ "cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwHhcNMTcwOTE1MjMyMzAyWhcN\n" +
+ "MTkwOTE1MjMyMzAyWjCB1TETMBEGCysGAQQBgjc8AgEDEwJVUzEZMBcGCysGAQQB\n" +
+ "gjc8AgECEwhEZWxhd2FyZTEdMBsGA1UEDxMUUHJpdmF0ZSBPcmdhbml6YXRpb24x\n" +
+ "EDAOBgNVBAUTBzU1MTA5MjIxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25h\n" +
+ "MRMwEQYDVQQHEwpTY290dHNkYWxlMRUwEwYDVQQKEwxHb0RhZGR5IElOQy4xJzAl\n" +
+ "BgNVBAMTHnZhbGlkLmdkaWcyLmNhdGVzdC5nb2RhZGR5LmNvbTCCASIwDQYJKoZI\n" +
+ "hvcNAQEBBQADggEPADCCAQoCggEBAO3xTbLfdIHiG1MIsBCz0oIg5vBxlzZyK5Rw\n" +
+ "DM6A/TWUDelFWyYj6fZDXYyHby4nAK9ibfhiT2f+q+5lEslye5Mt9gC39pZbpHE2\n" +
+ "eyJgmtNgmPGq15pf/87JE697BRwp9CWJP3yNYeamFl/F2THZOqlXCiSRbIGZ5TsZ\n" +
+ "sVb1vjFPmh249Ujw1zSThY9hA669Cyp3xb4iTowjCqdNYqbn22Jbk0SEXPYzLMf0\n" +
+ "mlY8xZ/e/8NxzJgev3N1LR3bPEijLYDZeZJ6WKc75pqNvgo8A+dEeX9bxFkCnstY\n" +
+ "6Iq0HTJua0TTD6V585YXNm4Z5OxjBE5kPkkFfwW0bb5dRZp86HUCAwEAAaOCA2Aw\n" +
+ "ggNcMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC\n" +
+ "MA4GA1UdDwEB/wQEAwIFoDA1BgNVHR8ELjAsMCqgKKAmhiRodHRwOi8vY3JsLmdv\n" +
+ "ZGFkZHkuY29tL2dkaWcyczMtOS5jcmwwXAYDVR0gBFUwUzBIBgtghkgBhv1tAQcX\n" +
+ "AzA5MDcGCCsGAQUFBwIBFitodHRwOi8vY2VydGlmaWNhdGVzLmdvZGFkZHkuY29t\n" +
+ "L3JlcG9zaXRvcnkvMAcGBWeBDAEBMHYGCCsGAQUFBwEBBGowaDAkBggrBgEFBQcw\n" +
+ "AYYYaHR0cDovL29jc3AuZ29kYWRkeS5jb20vMEAGCCsGAQUFBzAChjRodHRwOi8v\n" +
+ "Y2VydGlmaWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvZ2RpZzIuY3J0MB8G\n" +
+ "A1UdIwQYMBaAFEDCvSeOzDSDMKIz1/tss/C0LIDOME0GA1UdEQRGMESCHnZhbGlk\n" +
+ "LmdkaWcyLmNhdGVzdC5nb2RhZGR5LmNvbYIid3d3LnZhbGlkLmdkaWcyLmNhdGVz\n" +
+ "dC5nb2RhZGR5LmNvbTAdBgNVHQ4EFgQUKSs41O+5SnkjAEaNyHk6sxq5sn8wggF/\n" +
+ "BgorBgEEAdZ5AgQCBIIBbwSCAWsBaQB3AFYUBpov18Ls0/XhvUSyPsdGdrm8mRFc\n" +
+ "wO+UmFXWidDdAAABXofbjGMAAAQDAEgwRgIhAPZEqPZAlYpSTx+R/+7mOUa+BcBz\n" +
+ "U1JHZDpcy98am0glAiEA1u2FxjgAa4L5HVGYV2LSQZIltGRJ8mBT8V0JVsdm3dsA\n" +
+ "dgDuS723dc5guuFCaR+r4Z5mow9+X7By2IMAxHuJeqj9ywAAAV6H25ASAAAEAwBH\n" +
+ "MEUCIQCFowkRXyR8gkX8cL7RbPSwiKCHy/1I1WVzpinmrHlZFQIgE5nShGeK7cqT\n" +
+ "j2C9FfrPc/Axe3/pzAFxD/BNQD1RO5sAdgCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb\n" +
+ "37jjd80OyA3cEAAAAV6H25GdAAAEAwBHMEUCIBQrE+FqILUhI0wdp2X+lf/e3UG1\n" +
+ "gyxHmSVeN2+CkrXPAiEA1mIIVmLNURGyI8wnZ5KRnBPOKYM2MC54RJ8CFrEHIz4w\n" +
+ "DQYJKoZIhvcNAQELBQADggEBADInvf3eS6SgQ1qxPx4RT2hPeU5frlWJWcOWUdZB\n" +
+ "6mVNcmUQMkYnjkg8+PQ782HGP0DvAfcIRDhSfXdIqzEk8MPUq1XHEOfwRzLpTiCN\n" +
+ "FQDQIt1LXnzESCUurJS8r4mxgaVLAwHFytOTDrQn0Xfs93dm0tnRGAg7iBg+N33V\n" +
+ "zOR4aqojdDUWa1Rr4WFqZMkZIxzREQCYC8HXSYqLA1oPuoMMog8dId7XSalBmGJ4\n" +
+ "KQVsZ0/Hpi0y9k/Zw5obGcEYJWMbuU1iaEkvdtXOiXEQfJ1WS+Yy55J4GSjpIiop\n" +
+ "qDZD88xA9r7ttzM/khao7jfIpVWG2HuX0JlHWdh3y9aegiw=\n" +
+ "-----END CERTIFICATE-----";
+
+ // 1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=Delaware/businessCategory=Private
+ // Organization/serialNumber=5510922, C=US, ST=Arizona, L=Scottsdale, O=GoDaddy INC., CN=revoked.gdig2.catest.godaddy.com
+ private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
+ "MIIHdDCCBlygAwIBAgIIEBJV3vmogM8wDQYJKoZIhvcNAQELBQAwgbQxCzAJBgNV\n" +
+ "BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRow\n" +
+ "GAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UECxMkaHR0cDovL2NlcnRz\n" +
+ "LmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQDEypHbyBEYWRkeSBTZWN1\n" +
+ "cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwHhcNMTcwOTE1MjMyMzAzWhcN\n" +
+ "MTkwOTE1MjMyMzAzWjCB1zETMBEGCysGAQQBgjc8AgEDEwJVUzEZMBcGCysGAQQB\n" +
+ "gjc8AgECEwhEZWxhd2FyZTEdMBsGA1UEDxMUUHJpdmF0ZSBPcmdhbml6YXRpb24x\n" +
+ "EDAOBgNVBAUTBzU1MTA5MjIxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25h\n" +
+ "MRMwEQYDVQQHEwpTY290dHNkYWxlMRUwEwYDVQQKEwxHb0RhZGR5IElOQy4xKTAn\n" +
+ "BgNVBAMTIHJldm9rZWQuZ2RpZzIuY2F0ZXN0LmdvZGFkZHkuY29tMIIBIjANBgkq\n" +
+ "hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCuBsAR2XGf05mYOuag+0aS4lBuLO5/f\n" +
+ "kEO7KNo7BcdY7J78yXYRYW0jGnV29bjrQZJfu5yv5bU+OjTIDVbCWZAwtBXEKrJj\n" +
+ "riIOUXi3hXphtlyMMAaiXQoA84jwS634DsD0w6XUUP2Lem8jC3RudjvmkDQHoY3M\n" +
+ "uhhS7jLxKnYKnXbLwlqxpdwmEgbqIb5DN5snLAyinTkALLVWZ6RneIuSjhKWbuef\n" +
+ "cEKFScHm6SFsKraltV/T17SWi6zQd/AypKA8JeWXD9WZcsSR9z/41VMJbvTeuP+d\n" +
+ "ZBA4dqPsBTl4N4i54rNEyzMyxDwdvIGrJJ+FVRMKoYjuUi5wY9zO4QIDAQABo4ID\n" +
+ "YzCCA18wDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUH\n" +
+ "AwIwDgYDVR0PAQH/BAQDAgWgMDUGA1UdHwQuMCwwKqAooCaGJGh0dHA6Ly9jcmwu\n" +
+ "Z29kYWRkeS5jb20vZ2RpZzJzMy05LmNybDBcBgNVHSAEVTBTMEgGC2CGSAGG/W0B\n" +
+ "BxcDMDkwNwYIKwYBBQUHAgEWK2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j\n" +
+ "b20vcmVwb3NpdG9yeS8wBwYFZ4EMAQEwdgYIKwYBBQUHAQEEajBoMCQGCCsGAQUF\n" +
+ "BzABhhhodHRwOi8vb2NzcC5nb2RhZGR5LmNvbS8wQAYIKwYBBQUHMAKGNGh0dHA6\n" +
+ "Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeS9nZGlnMi5jcnQw\n" +
+ "HwYDVR0jBBgwFoAUQMK9J47MNIMwojPX+2yz8LQsgM4wUQYDVR0RBEowSIIgcmV2\n" +
+ "b2tlZC5nZGlnMi5jYXRlc3QuZ29kYWRkeS5jb22CJHd3dy5yZXZva2VkLmdkaWcy\n" +
+ "LmNhdGVzdC5nb2RhZGR5LmNvbTAdBgNVHQ4EFgQUCJELlWq8+ntmR5JTjmZMG+HI\n" +
+ "e5EwggF+BgorBgEEAdZ5AgQCBIIBbgSCAWoBaAB1AFYUBpov18Ls0/XhvUSyPsdG\n" +
+ "drm8mRFcwO+UmFXWidDdAAABXofbk3cAAAQDAEYwRAIgHo8UllsN8FcaF16xx7kT\n" +
+ "vQU1wM7qUKnhN38/z8dU4QUCIFrzGJyajoVPQ2fzOTb9ygzA7T3wqsnT3ML5/KJ6\n" +
+ "+6+CAHYA7ku9t3XOYLrhQmkfq+GeZqMPfl+wctiDAMR7iXqo/csAAAFeh9uXHQAA\n" +
+ "BAMARzBFAiEA5DENZZT7SBxNRvo9yFHNNeWqH2d4uqGUwc1rKILrMGsCIHZ3N4dZ\n" +
+ "zv/J+7fbLP1nrAmdUT92ow1bhtMPuq2PfXsAAHcApLkJkLQYWBSHuxOizGdwCjw1\n" +
+ "mAT5G9+443fNDsgN3BAAAAFeh9uYjAAABAMASDBGAiEAyY8ylnGHiH5L3yXE7BsH\n" +
+ "v75ja2RtuuYbMADAlDK/ZDoCIQDwuCq3x+egpB/GISxTnwkrDwhNhhIJNyk5F4j1\n" +
+ "/J8A0DANBgkqhkiG9w0BAQsFAAOCAQEAMGot6gBZ77HIDMb1n/HPrKdSHN0ngq7Z\n" +
+ "rhrkgbp+mH1Cs1lZA3qldMDxKXgNiodFqU/e4VewasQ9tJMmDXrTZIHualJGmIvq\n" +
+ "ISvV0ZUfSW/sJmo0ZDw8iBM993LDkA4wSc6SunhjOwu3LBfl9aKkeq6IhUEAG8X7\n" +
+ "54oO4iApt+APLMyeV9lZ/T7MGVbAjwdm+T1RMa/Ca99BahaRWN7hiM+zS3Ly+l6G\n" +
+ "7kqAkBFuJWbbZImADZ2RPldY6hBzTk6MT2hLCV40UD8JqwJo+qq7nGfJdTaFyZI6\n" +
+ "nJvrVATO7jL64YFP3xlVi8EQaCeKdZdn+BCCNA/ja0mWMj8EU9Islg==\n" +
+ "-----END CERTIFICATE-----";
+
+ public void runTest(ValidatePathWithParams pathValidator) throws Exception {
+ // Validate valid
+ pathValidator.validate(new String[]{VALID, INT},
+ ValidatePathWithParams.Status.GOOD, null, System.out);
+
+ // Validate Revoked
+ pathValidator.validate(new String[]{REVOKED, INT},
+ ValidatePathWithParams.Status.REVOKED, null, System.out);
+ }
+}
+
+class GoDaddySfig2 {
+
+ // Owner: CN=Starfield Secure Certificate Authority - G2,
+ // OU=http://certs.starfieldtech.com/repository/, O="Starfield Technologies, Inc.",
+ // L=Scottsdale, ST=Arizona, C=US
+ // Issuer: CN=Starfield Root Certificate Authority - G2,
+ // O="Starfield Technologies, Inc.", L=Scottsdale, ST=Arizona, C=US
+ private static final String INT = "-----BEGIN CERTIFICATE-----\n"
+ + "MIIFADCCA+igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx\n"
+ + "EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT\n"
+ + "HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs\n"
+ + "ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAw\n"
+ + "MFoXDTMxMDUwMzA3MDAwMFowgcYxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6\n"
+ + "b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj\n"
+ + "aG5vbG9naWVzLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydHMuc3RhcmZpZWxk\n"
+ + "dGVjaC5jb20vcmVwb3NpdG9yeS8xNDAyBgNVBAMTK1N0YXJmaWVsZCBTZWN1cmUg\n"
+ + "Q2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IB\n"
+ + "DwAwggEKAoIBAQDlkGZL7PlGcakgg77pbL9KyUhpgXVObST2yxcT+LBxWYR6ayuF\n"
+ + "pDS1FuXLzOlBcCykLtb6Mn3hqN6UEKwxwcDYav9ZJ6t21vwLdGu4p64/xFT0tDFE\n"
+ + "3ZNWjKRMXpuJyySDm+JXfbfYEh/JhW300YDxUJuHrtQLEAX7J7oobRfpDtZNuTlV\n"
+ + "Bv8KJAV+L8YdcmzUiymMV33a2etmGtNPp99/UsQwxaXJDgLFU793OGgGJMNmyDd+\n"
+ + "MB5FcSM1/5DYKp2N57CSTTx/KgqT3M0WRmX3YISLdkuRJ3MUkuDq7o8W6o0OPnYX\n"
+ + "v32JgIBEQ+ct4EMJddo26K3biTr1XRKOIwSDAgMBAAGjggEsMIIBKDAPBgNVHRMB\n"
+ + "Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUJUWBaFAmOD07LSy+\n"
+ + "zWrZtj2zZmMwHwYDVR0jBBgwFoAUfAwyH6fZMH/EfWijYqihzqsHWycwOgYIKwYB\n"
+ + "BQUHAQEELjAsMCoGCCsGAQUFBzABhh5odHRwOi8vb2NzcC5zdGFyZmllbGR0ZWNo\n"
+ + "LmNvbS8wOwYDVR0fBDQwMjAwoC6gLIYqaHR0cDovL2NybC5zdGFyZmllbGR0ZWNo\n"
+ + "LmNvbS9zZnJvb3QtZzIuY3JsMEwGA1UdIARFMEMwQQYEVR0gADA5MDcGCCsGAQUF\n"
+ + "BwIBFitodHRwczovL2NlcnRzLnN0YXJmaWVsZHRlY2guY29tL3JlcG9zaXRvcnkv\n"
+ + "MA0GCSqGSIb3DQEBCwUAA4IBAQBWZcr+8z8KqJOLGMfeQ2kTNCC+Tl94qGuc22pN\n"
+ + "QdvBE+zcMQAiXvcAngzgNGU0+bE6TkjIEoGIXFs+CFN69xpk37hQYcxTUUApS8L0\n"
+ + "rjpf5MqtJsxOYUPl/VemN3DOQyuwlMOS6eFfqhBJt2nk4NAfZKQrzR9voPiEJBjO\n"
+ + "eT2pkb9UGBOJmVQRDVXFJgt5T1ocbvlj2xSApAer+rKluYjdkf5lO6Sjeb6JTeHQ\n"
+ + "sPTIFwwKlhR8Cbds4cLYVdQYoKpBaXAko7nv6VrcPuuUSvC33l8Odvr7+2kDRUBQ\n"
+ + "7nIMpBKGgc0T0U7EPMpODdIm8QC3tKai4W56gf0wrHofx1l7\n"
+ + "-----END CERTIFICATE-----";
+
+ // 1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=Arizona/businessCategory=Private
+ // Organization/serialNumber=R17247416, C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, LLC,
+ // CN=valid.sfig2.catest.starfieldtech.com
+ private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+ "MIIHuzCCBqOgAwIBAgIIaZoUcUIjkGwwDQYJKoZIhvcNAQELBQAwgcYxCzAJBgNV\n" +
+ "BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUw\n" +
+ "IwYDVQQKExxTdGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTMwMQYDVQQLEypo\n" +
+ "dHRwOi8vY2VydHMuc3RhcmZpZWxkdGVjaC5jb20vcmVwb3NpdG9yeS8xNDAyBgNV\n" +
+ "BAMTK1N0YXJmaWVsZCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIw\n" +
+ "HhcNMTcwOTE3MDM0ODAxWhcNMTkwOTE3MDM0ODAxWjCB6zETMBEGCysGAQQBgjc8\n" +
+ "AgEDEwJVUzEYMBYGCysGAQQBgjc8AgECEwdBcml6b25hMR0wGwYDVQQPExRQcml2\n" +
+ "YXRlIE9yZ2FuaXphdGlvbjESMBAGA1UEBRMJUjE3MjQ3NDE2MQswCQYDVQQGEwJV\n" +
+ "UzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEkMCIGA1UE\n" +
+ "ChMbU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgTExDMS0wKwYDVQQDEyR2YWxpZC5z\n" +
+ "ZmlnMi5jYXRlc3Quc3RhcmZpZWxkdGVjaC5jb20wggEiMA0GCSqGSIb3DQEBAQUA\n" +
+ "A4IBDwAwggEKAoIBAQDVxhI45IQtNrJuun7HU8v2CKg/h/euysft2VrRsaGSMAln\n" +
+ "V6TtpWj2UGm7OmzE2NNzOhD9JJQSc1W6aHEsCTVJ148sgldFFmP39cboBFoLCFlJ\n" +
+ "DxsVGeyKu+KlDKq7Vp2+ty3TeFNOBXEVtEc8SsC8mVjsk2VWW7X/fCVFYEzzyPUI\n" +
+ "sJPWahNOW2wVxNWKeW5jwzeNMOFVQiT9+YpZVQnV06uK3rPd9tVYU5SfdfPVpScY\n" +
+ "/O/tyZyflTGuXZ+YXn1CYRsOq3VypVFfhXunV5prQ/vTnyjddVWce1wwoUT5DvFO\n" +
+ "/0vcWolHktiOAJkmAiGRfHvjhxW8mkjKqaMnstKRAgMBAAGjggOEMIIDgDAMBgNV\n" +
+ "HRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAOBgNVHQ8B\n" +
+ "Af8EBAMCBaAwOwYDVR0fBDQwMjAwoC6gLIYqaHR0cDovL2NybC5zdGFyZmllbGR0\n" +
+ "ZWNoLmNvbS9zZmlnMnMzLTEuY3JsMGIGA1UdIARbMFkwTgYLYIZIAYb9bgEHFwMw\n" +
+ "PzA9BggrBgEFBQcCARYxaHR0cDovL2NlcnRpZmljYXRlcy5zdGFyZmllbGR0ZWNo\n" +
+ "LmNvbS9yZXBvc2l0b3J5LzAHBgVngQwBATCBggYIKwYBBQUHAQEEdjB0MCoGCCsG\n" +
+ "AQUFBzABhh5odHRwOi8vb2NzcC5zdGFyZmllbGR0ZWNoLmNvbS8wRgYIKwYBBQUH\n" +
+ "MAKGOmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuc3RhcmZpZWxkdGVjaC5jb20vcmVwb3Np\n" +
+ "dG9yeS9zZmlnMi5jcnQwHwYDVR0jBBgwFoAUJUWBaFAmOD07LSy+zWrZtj2zZmMw\n" +
+ "WQYDVR0RBFIwUIIkdmFsaWQuc2ZpZzIuY2F0ZXN0LnN0YXJmaWVsZHRlY2guY29t\n" +
+ "gih3d3cudmFsaWQuc2ZpZzIuY2F0ZXN0LnN0YXJmaWVsZHRlY2guY29tMB0GA1Ud\n" +
+ "DgQWBBTxiYdHMn55sMWTFgp7xif7ludWTjCCAX4GCisGAQQB1nkCBAIEggFuBIIB\n" +
+ "agFoAHcAVhQGmi/XwuzT9eG9RLI+x0Z2ubyZEVzA75SYVdaJ0N0AAAFejfR7OAAA\n" +
+ "BAMASDBGAiEA/s7a5OGhtaCutT1l4KNE7dUbM3WGUExG/ZJ+Y6IH3nUCIQCvpVJf\n" +
+ "Y0XBInIUv391hNzSEhv6nvIBEjZtKdvGcP8/5QB2AO5Lvbd1zmC64UJpH6vhnmaj\n" +
+ "D35fsHLYgwDEe4l6qP3LAAABXo30fxEAAAQDAEcwRQIhANqG9yfi3ax0pTnwr4Ti\n" +
+ "wVfUrZclJDS06ePkTHppLkLTAiBTRKkVf1df4Irvmd7neT1wdS2fhDxmnVIYAN5J\n" +
+ "6tOGDQB1AKS5CZC0GFgUh7sTosxncAo8NZgE+RvfuON3zQ7IDdwQAAABXo30gFsA\n" +
+ "AAQDAEYwRAIgb8Xc54M+QD4wfSWLj5Ae/wrSEgRp7Kbf4Lf4vT4W0usCIGAShkJI\n" +
+ "CRxoudQDRxooNJhfXgsTB8QhwFC9PUPo3ZV+MA0GCSqGSIb3DQEBCwUAA4IBAQBt\n" +
+ "TqvwxqrkPYm/ssbN9cpVWlrQPw3DblsAEV6gnrrTJMd7HB042H3HLUiitddRjO40\n" +
+ "0EJM/tUOSGcWfqnJHWFDKoWzdrF5lHAzSRkMjdXgY9TTN5K5tUMEpfRjtink/zoY\n" +
+ "pNyc5ua4SXn94KfMZcOYGRvUM+0q6vLRBBMH541E3M6q6JbEBqZJFY8gBWwYqHH0\n" +
+ "xNGahm5++v4trFFCJzSfvfV1v+rnqy8tRivi7ZFLXWCcSyAqMH+T9Q36lKeFtaw4\n" +
+ "Sapf+dh2yrd2IBLW5eaAD13nCAjO/W0GuC7zw4+4mhW5+DTVJXrCkK5XddkVLhML\n" +
+ "k5pMoIv5EsFIm0Cs+DfF\n" +
+ "-----END CERTIFICATE-----";
+
+ // 1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=Arizona/businessCategory=Private
+ // Organization/serialNumber=R17247416, C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, LLC,
+ // CN=revoked.sfig2.catest.starfieldtech.com
+ private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
+ "MIIHwTCCBqmgAwIBAgIJAPc1qVz+WDxpMA0GCSqGSIb3DQEBCwUAMIHGMQswCQYD\n" +
+ "VQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEl\n" +
+ "MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEzMDEGA1UECxMq\n" +
+ "aHR0cDovL2NlcnRzLnN0YXJmaWVsZHRlY2guY29tL3JlcG9zaXRvcnkvMTQwMgYD\n" +
+ "VQQDEytTdGFyZmllbGQgU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcy\n" +
+ "MB4XDTE3MDkxOTEzMDkwMVoXDTE5MDkxOTEzMDkwMVowge0xEzARBgsrBgEEAYI3\n" +
+ "PAIBAxMCVVMxGDAWBgsrBgEEAYI3PAIBAhMHQXJpem9uYTEdMBsGA1UEDxMUUHJp\n" +
+ "dmF0ZSBPcmdhbml6YXRpb24xEjAQBgNVBAUTCVIxNzI0NzQxNjELMAkGA1UEBhMC\n" +
+ "VVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJDAiBgNV\n" +
+ "BAoTG1N0YXJmaWVsZCBUZWNobm9sb2dpZXMsIExMQzEvMC0GA1UEAxMmcmV2b2tl\n" +
+ "ZC5zZmlnMi5jYXRlc3Quc3RhcmZpZWxkdGVjaC5jb20wggEiMA0GCSqGSIb3DQEB\n" +
+ "AQUAA4IBDwAwggEKAoIBAQCWsAZC9goWW6yzg9HiLjCG4Gv2PCHlUIQGqyhc1y9a\n" +
+ "YZVXUI27/NhHjNNMTwP9TKmncrxnGaTZ9+ZCS1JlSgsNYQcLKKZW+SiEOzwpOfwV\n" +
+ "dOCSWrt/EDyJHktx3VIbfi+mD7dvzH3B/iGxMrmdCGIy3xiVAc7MkfsWzcLlPUP3\n" +
+ "oUpPBYyzWqZ2tVsBDigoirERFqZNfHZ7ZNMnn8FcmAt7udKjAAewNRlwzR7ZVp5s\n" +
+ "f5pbnRlRikF30msSHVJoPBICEYmzCxUI+zFlDBjf4vlJojwV0/Rfq85it2yhN/MV\n" +
+ "we2IBC+z9FAAogYo+JFw7Uxq8nsLCKX1tTPsqxGXWNonAgMBAAGjggOHMIIDgzAM\n" +
+ "BgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAOBgNV\n" +
+ "HQ8BAf8EBAMCBaAwOwYDVR0fBDQwMjAwoC6gLIYqaHR0cDovL2NybC5zdGFyZmll\n" +
+ "bGR0ZWNoLmNvbS9zZmlnMnMzLTEuY3JsMGIGA1UdIARbMFkwTgYLYIZIAYb9bgEH\n" +
+ "FwMwPzA9BggrBgEFBQcCARYxaHR0cDovL2NlcnRpZmljYXRlcy5zdGFyZmllbGR0\n" +
+ "ZWNoLmNvbS9yZXBvc2l0b3J5LzAHBgVngQwBATCBggYIKwYBBQUHAQEEdjB0MCoG\n" +
+ "CCsGAQUFBzABhh5odHRwOi8vb2NzcC5zdGFyZmllbGR0ZWNoLmNvbS8wRgYIKwYB\n" +
+ "BQUHMAKGOmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuc3RhcmZpZWxkdGVjaC5jb20vcmVw\n" +
+ "b3NpdG9yeS9zZmlnMi5jcnQwHwYDVR0jBBgwFoAUJUWBaFAmOD07LSy+zWrZtj2z\n" +
+ "ZmMwXQYDVR0RBFYwVIImcmV2b2tlZC5zZmlnMi5jYXRlc3Quc3RhcmZpZWxkdGVj\n" +
+ "aC5jb22CKnd3dy5yZXZva2VkLnNmaWcyLmNhdGVzdC5zdGFyZmllbGR0ZWNoLmNv\n" +
+ "bTAdBgNVHQ4EFgQU9hCSl7QoQ8KdsGgwMDwlvSurKNcwggF9BgorBgEEAdZ5AgQC\n" +
+ "BIIBbQSCAWkBZwB1AFYUBpov18Ls0/XhvUSyPsdGdrm8mRFcwO+UmFXWidDdAAAB\n" +
+ "XppC0cEAAAQDAEYwRAIgIO8sIG88JlA73P2myZ7EshemxaR8qBgf3wlYZpg5aZEC\n" +
+ "IGtlcUL7Il1uOLN0LTAzNTQ7pfb7oFYbr0R4LWe2ZvBIAHYA7ku9t3XOYLrhQmkf\n" +
+ "q+GeZqMPfl+wctiDAMR7iXqo/csAAAFemkLVbwAABAMARzBFAiEAmWkzcotxZSwb\n" +
+ "xPS3MG13TVXGu2+MiXXjOIf42DR8zJQCIBL4cSOJh+LX5kpPub6KOiEOn7TVE1Zv\n" +
+ "IQUxuf+vyAD4AHYApLkJkLQYWBSHuxOizGdwCjw1mAT5G9+443fNDsgN3BAAAAFe\n" +
+ "mkLXRQAABAMARzBFAiBX8foh/KrYr34O2c9cH6uyWW2XjBHNLsYX1mr+8VuNaAIh\n" +
+ "AObDQwpDYh/bNp6k547gDxnR73LeU3kvl1Y76GjgxLAhMA0GCSqGSIb3DQEBCwUA\n" +
+ "A4IBAQDJ5vlagzOH8/ORUMgT33muSDFXCe5el/sQzVg8dridw9qjnxOpkGibdCiT\n" +
+ "b9Il1bdi7UnG8MlA3XpDjGgp6J/mUTijD9WcFx4lp5JnPaIbShHWCyIlRVZJzrZc\n" +
+ "UYhR56xXOKDYKYOIvM6qTqegXyEynJrIVTArMk7jQf0oNQLLHzXE1fVS1zut0H5l\n" +
+ "GE+TBgjasMEa1o1e/H/heSytb2zFNsZr8oxojzGBmlKyfCoIIcCv3PxX2ur57zJE\n" +
+ "9ADWoYK/7gYVba0JmLV4nQltDPp06nOYT9imxBWTrFahgPx1jOQDLgIpitkjyCy4\n" +
+ "xpmxUk8L6yc3O3aSD9OU/fzk/t/d\n" +
+ "-----END CERTIFICATE-----";
+
+ public void runTest(ValidatePathWithParams pathValidator) throws Exception {
+ // Validate valid
+ pathValidator.validate(new String[]{VALID, INT},
+ ValidatePathWithParams.Status.GOOD, null, System.out);
+
+ // Validate Revoked
+ pathValidator.validate(new String[]{REVOKED, INT},
+ ValidatePathWithParams.Status.REVOKED, null, System.out);
+ }
+}
+
--- a/test/jdk/sun/applet/DeprecatedAppletViewer/DeprecatedAppletViewer.java Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 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.
- */
-
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-
-/**
- * @test
- * @bug 8074165
- * @modules java.desktop/sun.applet
- * @run main/othervm -Duser.language=en DeprecatedAppletViewer
- */
-public final class DeprecatedAppletViewer {
-
- private static final String TEXT
- = "Warning: Applet API and AppletViewer are deprecated.";
-
- public static void main(final String[] args) {
- final PrintStream old = System.err;
- final ByteArrayOutputStream baos = new ByteArrayOutputStream(1000);
- final PrintStream ps = new PrintStream(baos);
- try {
- System.setErr(ps);
- sun.applet.Main.main(new String[]{});
- } finally {
- System.setErr(old);
- }
-
- final String text = new String(baos.toByteArray());
- if (!text.contains(TEXT)) {
- System.err.println("The text should contain: \"" + TEXT + "\"");
- System.err.println("But the current text is: ");
- System.err.println(text);
- throw new RuntimeException("Error");
- }
- }
-}
--- a/test/jdk/sun/applet/TEST.properties Wed Jun 13 09:57:59 2018 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-modules=java.desktop
-
--- a/test/jdk/sun/security/tools/jarsigner/JarSigningNonAscii.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/sun/security/tools/jarsigner/JarSigningNonAscii.java Wed Jun 13 11:01:25 2018 -0700
@@ -29,9 +29,7 @@
* @run main/othervm JarSigningNonAscii
*/
-import sun.security.tools.*;
import java.io.*;
-import java.security.Security;
import java.util.*;
import java.util.jar.*;
import java.security.cert.Certificate;
--- a/test/jdk/tools/launcher/SourceMode.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/jdk/tools/launcher/SourceMode.java Wed Jun 13 11:01:25 2018 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8192920
+ * @bug 8192920 8204588
* @summary Test source mode
* @modules jdk.compiler
* @run main SourceMode
@@ -31,6 +31,7 @@
import java.io.IOException;
+import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -48,78 +49,115 @@
new SourceMode().run(args);
}
+ // to reduce the chance of creating shebang lines that are too long,
+ // we use a relative path to the java command if that is shorter
+ private final Path shortJavaCmd;
+
+ private final PrintStream log;
+
+ private final boolean skipShebangTest;
+
+ SourceMode() {
+ Path cwd = Paths.get(System.getProperty("user.dir"));
+ Path cmd = Paths.get(javaCmd);
+
+ if (isWindows) {
+ // Skip shebang tests on Windows, because that requires Cygwin.
+ shortJavaCmd = cmd;
+ skipShebangTest = true;
+ } else {
+ // Skip shebang tests if the path to the Java launcher is too long,
+ // because that will cause tests to overflow the mostly undocumented
+ // limit of 120 characters for a shebang line.
+ Path p = cwd.relativize(cmd);
+ shortJavaCmd = (p.toString().length() < cmd.toString().length()) ? p : cmd;
+ // skipShebangTest = shortJavaCmd.toString().length() > 100;
+ skipShebangTest = true;
+ }
+
+ log = System.err;
+ }
+
// java Simple.java 1 2 3
@Test
void testSimpleJava() throws IOException {
+ starting("testSimpleJava");
Path file = getSimpleFile("Simple.java", false);
TestResult tr = doExec(javaCmd, file.toString(), "1", "2", "3");
if (!tr.isOK())
error(tr, "Bad exit code: " + tr.exitValue);
if (!tr.contains("[1, 2, 3]"))
error(tr, "Expected output not found");
- System.out.println(tr.testOutput);
+ show(tr);
}
// java --source 10 simple 1 2 3
@Test
void testSimple() throws IOException {
+ starting("testSimple");
Path file = getSimpleFile("simple", false);
TestResult tr = doExec(javaCmd, "--source", "10", file.toString(), "1", "2", "3");
if (!tr.isOK())
error(tr, "Bad exit code: " + tr.exitValue);
if (!tr.contains("[1, 2, 3]"))
error(tr, "Expected output not found");
- System.out.println(tr.testOutput);
+ show(tr);
}
// execSimple 1 2 3
@Test
void testExecSimple() throws IOException {
- if (isWindows) // Will not work without cygwin, pass silently
+ starting("testExecSimple");
+ if (skipShebangTest) {
+ log.println("SKIPPED");
return;
+ }
Path file = setExecutable(getSimpleFile("execSimple", true));
TestResult tr = doExec(file.toAbsolutePath().toString(), "1", "2", "3");
if (!tr.isOK())
error(tr, "Bad exit code: " + tr.exitValue);
if (!tr.contains("[1, 2, 3]"))
error(tr, "Expected output not found");
- System.out.println(tr.testOutput);
+ show(tr);
}
// java @simpleJava.at (contains Simple.java 1 2 3)
@Test
void testSimpleJavaAtFile() throws IOException {
+ starting("testSimpleJavaAtFile");
Path file = getSimpleFile("Simple.java", false);
Path atFile = Paths.get("simpleJava.at");
- createFile(atFile.toFile(), List.of(file + " 1 2 3"));
+ createFile(atFile, List.of(file + " 1 2 3"));
TestResult tr = doExec(javaCmd, "@" + atFile);
if (!tr.isOK())
error(tr, "Bad exit code: " + tr.exitValue);
if (!tr.contains("[1, 2, 3]"))
error(tr, "Expected output not found");
- System.out.println(tr.testOutput);
+ show(tr);
}
// java @simple.at (contains --source 10 simple 1 2 3)
@Test
void testSimpleAtFile() throws IOException {
+ starting("testSimpleAtFile");
Path file = getSimpleFile("simple", false);
Path atFile = Paths.get("simple.at");
- createFile(atFile.toFile(), List.of("--source 10 " + file + " 1 2 3"));
+ createFile(atFile, List.of("--source 10 " + file + " 1 2 3"));
TestResult tr = doExec(javaCmd, "@" + atFile);
if (!tr.isOK())
error(tr, "Bad exit code: " + tr.exitValue);
if (!tr.contains("[1, 2, 3]"))
error(tr, "Expected output not found");
- System.out.println(tr.testOutput);
+ show(tr);
}
// java -cp classes Main.java 1 2 3
@Test
void testClasspath() throws IOException {
+ starting("testClasspath");
Path base = Files.createDirectories(Paths.get("testClasspath"));
Path otherJava = base.resolve("Other.java");
- createFile(otherJava.toFile(), List.of(
+ createFile(otherJava, List.of(
"public class Other {",
" public static String join(String[] args) {",
" return String.join(\"-\", args);",
@@ -128,7 +166,7 @@
));
Path classes = Files.createDirectories(base.resolve("classes"));
Path mainJava = base.resolve("Main.java");
- createFile(mainJava.toFile(), List.of(
+ createFile(mainJava, List.of(
"class Main {",
" public static void main(String[] args) {",
" System.out.println(Other.join(args));",
@@ -141,14 +179,15 @@
error(tr, "Bad exit code: " + tr.exitValue);
if (!tr.contains("1-2-3"))
error(tr, "Expected output not found");
- System.out.println(tr.testOutput);
+ show(tr);
}
// java --add-exports=... Export.java --help
@Test
void testAddExports() throws IOException {
+ starting("testAddExports");
Path exportJava = Paths.get("Export.java");
- createFile(exportJava.toFile(), List.of(
+ createFile(exportJava, List.of(
"public class Export {",
" public static void main(String[] args) {",
" new com.sun.tools.javac.main.Main(\"demo\").compile(args);",
@@ -159,6 +198,7 @@
TestResult tr1 = doExec(javaCmd, exportJava.toString(), "--help");
if (tr1.isOK())
error(tr1, "Compilation succeeded unexpectedly");
+ show(tr1);
// verify access succeeds with --add-exports
TestResult tr2 = doExec(javaCmd,
"--add-exports", "jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED",
@@ -167,15 +207,17 @@
error(tr2, "Bad exit code: " + tr2.exitValue);
if (!(tr2.contains("demo") && tr2.contains("Usage")))
error(tr2, "Expected output not found");
+ show(tr2);
}
// java -cp ... HelloWorld.java (for a class "java" in package "HelloWorld")
@Test
void testClassNamedJava() throws IOException {
+ starting("testClassNamedJava");
Path base = Files.createDirectories(Paths.get("testClassNamedJava"));
Path src = Files.createDirectories(base.resolve("src"));
Path srcfile = src.resolve("java.java");
- createFile(srcfile.toFile(), List.of(
+ createFile(srcfile, List.of(
"package HelloWorld;",
"class java {",
" public static void main(String... args) {",
@@ -191,22 +233,25 @@
error(tr, "Command failed");
if (!tr.contains("HelloWorld.java"))
error(tr, "Expected output not found");
+ show(tr);
}
// java --source
@Test
void testSourceNoArg() throws IOException {
+ starting("testSourceNoArg");
TestResult tr = doExec(javaCmd, "--source");
if (tr.isOK())
error(tr, "Command succeeded unexpectedly");
- System.err.println(tr);
if (!tr.contains("--source requires source version"))
error(tr, "Expected output not found");
+ show(tr);
}
// java --source 10 -jar simple.jar
@Test
void testSourceJarConflict() throws IOException {
+ starting("testSourceJarConflict");
Path base = Files.createDirectories(Paths.get("testSourceJarConflict"));
Path file = getSimpleFile("Simple.java", false);
Path classes = Files.createDirectories(base.resolve("classes"));
@@ -219,71 +264,101 @@
error(tr, "Command succeeded unexpectedly");
if (!tr.contains("Option -jar is not allowed with --source"))
error(tr, "Expected output not found");
+ show(tr);
}
// java --source 10 -m jdk.compiler
@Test
void testSourceModuleConflict() throws IOException {
+ starting("testSourceModuleConflict");
TestResult tr = doExec(javaCmd, "--source", "10", "-m", "jdk.compiler");
if (tr.isOK())
error(tr, "Command succeeded unexpectedly");
if (!tr.contains("Option -m is not allowed with --source"))
error(tr, "Expected output not found");
+ show(tr);
}
// #!.../java --source 10 -version
@Test
void testTerminalOptionInShebang() throws IOException {
- if (isWindows) // Will not work without cygwin, pass silently
+ starting("testTerminalOptionInShebang");
+ if (skipShebangTest) {
+ log.println("SKIPPED");
return;
+ }
Path base = Files.createDirectories(
Paths.get("testTerminalOptionInShebang"));
Path bad = base.resolve("bad");
- createFile(bad.toFile(), List.of(
- "#!" + javaCmd + " --source 10 -version"));
+ createFile(bad, List.of(
+ "#!" + shortJavaCmd + " --source 10 -version"));
setExecutable(bad);
TestResult tr = doExec(bad.toString());
if (!tr.contains("Option -version is not allowed in this context"))
error(tr, "Expected output not found");
+ show(tr);
}
// #!.../java --source 10 @bad.at (contains -version)
@Test
void testTerminalOptionInShebangAtFile() throws IOException {
- if (isWindows) // Will not work without cygwin, pass silently
+ starting("testTerminalOptionInShebangAtFile");
+ if (skipShebangTest) {
+ log.println("SKIPPED");
return;
+ }
// Use a short directory name, to avoid line length limitations
Path base = Files.createDirectories(Paths.get("testBadAtFile"));
Path bad_at = base.resolve("bad.at");
- createFile(bad_at.toFile(), List.of("-version"));
+ createFile(bad_at, List.of("-version"));
Path bad = base.resolve("bad");
- createFile(bad.toFile(), List.of(
- "#!" + javaCmd + " --source 10 @" + bad_at));
+ createFile(bad, List.of(
+ "#!" + shortJavaCmd + " --source 10 @" + bad_at));
setExecutable(bad);
TestResult tr = doExec(bad.toString());
- System.err.println("JJG JJG " + tr);
if (!tr.contains("Option -version in @testBadAtFile/bad.at is "
+ "not allowed in this context"))
error(tr, "Expected output not found");
+ show(tr);
}
// #!.../java --source 10 HelloWorld
@Test
void testMainClassInShebang() throws IOException {
- if (isWindows) // Will not work without cygwin, pass silently
+ starting("testMainClassInShebang");
+ if (skipShebangTest) {
+ log.println("SKIPPED");
return;
+ }
Path base = Files.createDirectories(Paths.get("testMainClassInShebang"));
Path bad = base.resolve("bad");
- createFile(bad.toFile(), List.of(
- "#!" + javaCmd + " --source 10 HelloWorld"));
+ createFile(bad, List.of(
+ "#!" + shortJavaCmd + " --source 10 HelloWorld"));
setExecutable(bad);
TestResult tr = doExec(bad.toString());
if (!tr.contains("Cannot specify main class in this context"))
error(tr, "Expected output not found");
+ show(tr);
}
//--------------------------------------------------------------------------
+ private void starting(String label) {
+ System.out.println();
+ System.out.println("*** Starting: " + label + " (stdout)");
+
+ System.err.println();
+ System.err.println("*** Starting: " + label + " (stderr)");
+ }
+
+ private void show(TestResult tr) {
+ log.println("*** Test Output:");
+ for (String line: tr.testOutput) {
+ log.println(line);
+ }
+ log.println("*** End Of Test Output:");
+ }
+
private Map<String,String> getLauncherDebugEnv() {
return Map.of("_JAVA_LAUNCHER_DEBUG", "1");
}
@@ -291,8 +366,8 @@
private Path getSimpleFile(String name, boolean shebang) throws IOException {
Path file = Paths.get(name);
if (!Files.exists(file)) {
- createFile(file.toFile(), List.of(
- (shebang ? "#!" + javaCmd + " --source 10" : ""),
+ createFile(file, List.of(
+ (shebang ? "#!" + shortJavaCmd + " --source 10" : ""),
"public class Simple {",
" public static void main(String[] args) {",
" System.out.println(java.util.Arrays.toString(args));",
@@ -301,6 +376,21 @@
return file;
}
+ private void createFile(Path file, List<String> lines) throws IOException {
+ lines.stream()
+ .filter(line -> line.length() > 128)
+ .forEach(line -> {
+ log.println("*** Warning: long line ("
+ + line.length()
+ + " chars) in file " + file);
+ log.println("*** " + line);
+ });
+ log.println("*** File: " + file);
+ lines.stream().forEach(log::println);
+ log.println("*** End Of File");
+ createFile(file.toFile(), lines);
+ }
+
private Path setExecutable(Path file) throws IOException {
Set<PosixFilePermission> perms = Files.getPosixFilePermissions(file);
perms.add(PosixFilePermission.OWNER_EXECUTE);
@@ -309,7 +399,7 @@
}
private void error(TestResult tr, String message) {
- System.err.println(tr);
+ show(tr);
throw new RuntimeException(message);
}
}
--- a/test/langtools/ProblemList.txt Wed Jun 13 09:57:59 2018 -0700
+++ b/test/langtools/ProblemList.txt Wed Jun 13 11:01:25 2018 -0700
@@ -57,7 +57,6 @@
tools/javac/modules/SourceInSymlinkTest.java 8180263 windows-all fails when run on a subst drive
tools/javac/options/release/ReleaseOptionUnsupported.java 8193784 generic-all temporary until support for --release 11 is worked out
tools/javac/importscope/T8193717.java 8203925 generic-all the test requires too much memory
-tools/javac/launcher/SourceLauncherTest.java 8204588 windows-all New test needs adjusting for Windows
###########################################################################
#
--- a/test/langtools/tools/javac/importChecks/ImportsObservable.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/langtools/tools/javac/importChecks/ImportsObservable.java Wed Jun 13 11:01:25 2018 -0700
@@ -23,9 +23,10 @@
/*
* @test
- * @bug 4869999
+ * @bug 4869999 8193302
* @summary Verify that the compiler does not prematurely decide a package is not observable.
- * @compile ImportsObservable.java
+ * @compile -source 8 -Xlint:-options ImportsObservable.java
+ * @compile/fail/ref=ImportsObservable.out -XDrawDiagnostics ImportsObservable.java
*/
import javax.*;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/importChecks/ImportsObservable.out Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,2 @@
+ImportsObservable.java:32:1: compiler.err.doesnt.exist: javax
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/lambda/methodReference/MethodRefStuckParenthesized.java Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2018, Google LLC. All rights reserved.
+ * 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 8203679
+ * @summary This is a negative regression test for an AssertionError in DeferredAttr.
+ * @compile/fail/ref=MethodRefStuckParenthesized.out -XDrawDiagnostics MethodRefStuckParenthesized.java
+ */
+
+public abstract class MethodRefStuckParenthesized {
+
+ interface I {
+ String v();
+ }
+
+ interface J {
+ String v();
+ }
+
+ abstract String v();
+
+ abstract void f(I v);
+
+ abstract <X extends J> J g(X x);
+
+ void test() {
+ f(g((this::v)));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/lambda/methodReference/MethodRefStuckParenthesized.out Wed Jun 13 11:01:25 2018 -0700
@@ -0,0 +1,2 @@
+MethodRefStuckParenthesized.java:48:5: compiler.err.cant.apply.symbol: kindname.method, f, MethodRefStuckParenthesized.I, MethodRefStuckParenthesized.J, kindname.class, MethodRefStuckParenthesized, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.infer.no.conforming.instance.exists: X, MethodRefStuckParenthesized.J, MethodRefStuckParenthesized.I))
+1 error
--- a/test/langtools/tools/javac/launcher/SourceLauncherTest.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/langtools/tools/javac/launcher/SourceLauncherTest.java Wed Jun 13 11:01:25 2018 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8192920
+ * @bug 8192920 8204588
* @summary Test source launcher
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
@@ -34,6 +34,7 @@
*/
import java.io.ByteArrayOutputStream;
+import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
@@ -281,8 +282,9 @@
List<String> javacArgs = List.of("-classpath", auxSrc.toString());
List<String> classArgs = List.of("1", "2", "3");
+ String FS = File.separator;
String expectStdErr =
- "testNoSourceOnClassPath/mainSrc/HelloWorld.java:4: error: cannot find symbol\n" +
+ "testNoSourceOnClassPath" + FS + "mainSrc" + FS + "HelloWorld.java:4: error: cannot find symbol\n" +
" System.out.println(Aux.MESSAGE + Arrays.toString(args));\n" +
" ^\n" +
" symbol: variable Aux\n" +
--- a/test/langtools/tools/javac/modules/ConvenientAccessErrorsTest.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/langtools/tools/javac/modules/ConvenientAccessErrorsTest.java Wed Jun 13 11:01:25 2018 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8169197 8172668 8173117 8175007 8189765
+ * @bug 8169197 8172668 8173117 8175007 8189765 8193302
* @summary Check convenient errors are produced for inaccessible classes.
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
@@ -433,29 +433,6 @@
}
@Test
- public void testUnusedImportOnDemand1(Path base) throws Exception {
- Path src = base.resolve("src");
- tb.writeJavaFiles(src,
- "package test; import javax.annotation.*; public class Test { }");
- Path classes = base.resolve("classes");
- tb.createDirectories(classes);
-
- List<String> log = new JavacTask(tb)
- .options("-XDrawDiagnostics",
- "--add-modules", "java.compiler")
- .outdir(classes)
- .files(findJavaFiles(src))
- .run()
- .writeAll()
- .getOutputLines(Task.OutputKind.DIRECT);
-
- List<String> expected = Arrays.asList("");
-
- if (!expected.equals(log))
- throw new Exception("expected output not found; actual: " + log);
- }
-
- @Test
public void testUnusedImportOnDemand2(Path base) throws Exception {
Path src = base.resolve("src");
Path src_m1 = src.resolve("m1x");
@@ -744,4 +721,155 @@
if (!expected.equals(log))
throw new Exception("expected output not found; actual: " + log);
}
+
+ @Test
+ public void testPackagesUniquelyVisibleInImportOnDemand(Path base) throws Exception {
+ Path src = base.resolve("src");
+ Path src_ma = src.resolve("ma");
+ tb.writeJavaFiles(src_ma,
+ "module ma { exports ma; }",
+ "package ma; public class Api { }");
+ Path src_mb = src.resolve("mb");
+ tb.writeJavaFiles(src_mb,
+ "module mb { exports ma.mb; }",
+ "package ma.mb; public class Api { }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ new JavacTask(tb)
+ .options("--module-source-path", src.toString())
+ .outdir(classes)
+ .files(findJavaFiles(src))
+ .run()
+ .writeAll();
+
+ Path test = src.resolve("test");
+ tb.writeJavaFiles(test,
+ "module test { requires mb; }",
+ "package test; import ma.*; public class Test { }");
+
+ List<String> log = new JavacTask(tb)
+ .options("-XDrawDiagnostics",
+ "--module-path", classes.toString())
+ .outdir(classes)
+ .files(findJavaFiles(test))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ List<String> expected = Arrays.asList(
+ "Test.java:1:22: compiler.err.package.not.visible: ma, (compiler.misc.not.def.access.does.not.read: test, ma, ma)",
+ "1 error");
+
+ if (!expected.equals(log))
+ throw new Exception("expected output not found; actual: " + log);
+ }
+
+ @Test
+ public void testPackagesUniquelyVisibleInImportOnDemandNoPrefixes(Path base) throws Exception {
+ Path src = base.resolve("src");
+ Path src_mb = src.resolve("mb");
+ tb.writeJavaFiles(src_mb,
+ "module mb { exports ma.mb; }",
+ "package ma.mb; public class Api { }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ new JavacTask(tb)
+ .options("--module-source-path", src.toString())
+ .outdir(classes)
+ .files(findJavaFiles(src))
+ .run()
+ .writeAll();
+
+ Path test = src.resolve("test");
+ tb.writeJavaFiles(test,
+ "module test { requires mb; }",
+ "package test; import ma.mb.*; import ma.*; public class Test { }");
+
+ List<String> log = new JavacTask(tb)
+ .options("-XDrawDiagnostics",
+ "--module-path", classes.toString())
+ .outdir(classes)
+ .files(findJavaFiles(test))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ List<String> expected = Arrays.asList(
+ "Test.java:1:31: compiler.err.doesnt.exist: ma",
+ "1 error");
+
+ if (!expected.equals(log))
+ throw new Exception("expected output not found; actual: " + log);
+ }
+
+ @Test
+ public void testPackagesUniquelyVisibleInImportOnDemandThisModule(Path base) throws Exception {
+ Path src = base.resolve("src");
+ Path test = src.resolve("test");
+ tb.writeJavaFiles(test,
+ "module test { }",
+ "package ma.mb; public class Impl { }",
+ "package test; import ma.*; public class Test { }");
+
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ List<String> log = new JavacTask(tb)
+ .options("-XDrawDiagnostics")
+ .outdir(classes)
+ .files(findJavaFiles(test))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ List<String> expected = Arrays.asList(
+ "Test.java:1:15: compiler.err.doesnt.exist: ma",
+ "1 error");
+
+ if (!expected.equals(log))
+ throw new Exception("expected output not found; actual: " + log);
+
+ new JavacTask(tb)
+ .options("-source", "8")
+ .outdir(classes)
+ .files(findJavaFiles(test.resolve("ma"), test.resolve("test")))
+ .run(Task.Expect.SUCCESS)
+ .writeAll();
+ }
+
+ @Test
+ public void testPackagesUniquelyVisibleInImportOnDemandThisModuleUnnamed(Path base) throws Exception {
+ Path src = base.resolve("src");
+ Path test = src.resolve("test");
+ tb.writeJavaFiles(test,
+ "package ma.mb; public class Impl { }",
+ "package test; import ma.*; public class Test { }");
+
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ List<String> log = new JavacTask(tb)
+ .options("-XDrawDiagnostics")
+ .outdir(classes)
+ .files(findJavaFiles(test))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ List<String> expected = Arrays.asList(
+ "Test.java:1:15: compiler.err.doesnt.exist: ma",
+ "1 error");
+
+ if (!expected.equals(log))
+ throw new Exception("expected output not found; actual: " + log);
+
+ new JavacTask(tb)
+ .options("-source", "8")
+ .outdir(classes)
+ .files(findJavaFiles(test))
+ .run(Task.Expect.SUCCESS)
+ .writeAll();
+ }
}
--- a/test/langtools/tools/javac/tree/VarTree.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/langtools/tools/javac/tree/VarTree.java Wed Jun 13 11:01:25 2018 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8188225
+ * @bug 8188225 8204674
* @summary Check that variables of type var have a consistent model
* @modules jdk.compiler/com.sun.tools.javac.api
*/
@@ -42,6 +42,7 @@
import javax.tools.ToolProvider;
import com.sun.source.tree.VariableTree;
+import com.sun.source.util.JavacTask;
import com.sun.source.util.TreeScanner;
import com.sun.source.util.Trees;
@@ -64,6 +65,10 @@
"java.lang.String testVar");
test.run("java.util.function.Consumer<String> c = (|testVar|) -> {};",
"java.lang.String testVar");
+ test.run("java.util.function.Consumer<String> c = (|var testVar|) -> {};",
+ "java.lang.String testVar");
+ test.run("java.util.function.IntBinaryOperator c = (var x, |testType|) -> 1;",
+ "testType ");
}
void run(String code, String expected) throws IOException {
@@ -81,9 +86,12 @@
null, Arrays.asList(new MyFileObject(src)));
Iterable<? extends CompilationUnitTree> units = ct.parse();
+
+ runSpanCheck(ct, units, src, prefix.length() + parts[0].length(), prefix.length() + parts[0].length() + parts[1].length());
+
ct.analyze();
- Trees trees = Trees.instance(ct);
+ runSpanCheck(ct, units, src, prefix.length() + parts[0].length(), prefix.length() + parts[0].length() + parts[1].length());
for (CompilationUnitTree cut : units) {
new TreeScanner<Void, Void>() {
@@ -93,13 +101,34 @@
if (!expected.equals(node.toString())) {
throw new AssertionError("Unexpected tree: " + node.toString());
}
+ }
+ if (String.valueOf(node.getType()).equals("testType")) {
+ if (!expected.equals(node.toString())) {
+ throw new AssertionError("Unexpected tree: " + node.toString());
+ }
+ }
+ return super.visitVariable(node, p);
+ }
+ }.scan(cut, null);
+ }
+ }
+
+ private void runSpanCheck(JavacTask ct, Iterable<? extends CompilationUnitTree> units, String src, int spanStart, int spanEnd) {
+ Trees trees = Trees.instance(ct);
+ boolean[] found = new boolean[1];
+
+ for (CompilationUnitTree cut : units) {
+ new TreeScanner<Void, Void>() {
+ @Override
+ public Void visitVariable(VariableTree node, Void p) {
+ if (node.getName().contentEquals("testVar")) {
int start = (int) trees.getSourcePositions().getStartPosition(cut, node);
int end = (int) trees.getSourcePositions().getEndPosition(cut, node);
String snip = src.substring(start, end);
- if (start != prefix.length() + parts[0].length() || end != prefix.length() + parts[0].length() + parts[1].length()) {
+ if (start != spanStart || end != spanEnd) {
throw new AssertionError("Unexpected span: " + snip);
}
@@ -109,13 +138,32 @@
if (typeStart != (-1) && typeEnd != (-1)) {
throw new AssertionError("Unexpected type position: " + typeStart + ", " + typeEnd);
}
+
+ found[0] = true;
+ }
+ if (String.valueOf(node.getType()).equals("testType")) {
+ int start = (int) trees.getSourcePositions().getStartPosition(cut, node);
+ int end = (int) trees.getSourcePositions().getEndPosition(cut, node);
+
+ String snip = src.substring(start, end);
+
+ if (start != spanStart || end != spanEnd) {
+ throw new AssertionError("Unexpected span: " + snip);
+ }
+
+ found[0] = true;
}
return super.visitVariable(node, p);
}
}.scan(cut, null);
}
+
+ if (!found[0]) {
+ throw new AssertionError("Didn't find the test variable.");
+ }
}
+
class MyFileObject extends SimpleJavaFileObject {
private String text;
--- a/test/lib/sun/hotspot/gc/GC.java Wed Jun 13 09:57:59 2018 -0700
+++ b/test/lib/sun/hotspot/gc/GC.java Wed Jun 13 11:01:25 2018 -0700
@@ -36,7 +36,9 @@
Serial(1),
Parallel(2),
ConcMarkSweep(3),
- G1(4);
+ G1(4),
+ Epsilon(5),
+ Z(6);
private static final WhiteBox WB = WhiteBox.getWhiteBox();