-| 907 |
+--- |
JTA (XA) |
-Original JSR |
-java.sql |
+UJSR for Java SE |
+java.transaction.xa |
plat |
No |
Formerly a Standalone Technology (unlisted) |
diff --git a/make/jdk/src/classes/build/tools/taglet/ExtLink.java b/make/jdk/src/classes/build/tools/taglet/ExtLink.java
index 94a93824fbf..15555f4e72e 100644
--- a/make/jdk/src/classes/build/tools/taglet/ExtLink.java
+++ b/make/jdk/src/classes/build/tools/taglet/ExtLink.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -49,14 +49,14 @@ import static jdk.javadoc.doclet.Taglet.Location.*;
* will produce the following html
*
* {@code
- * Please see a spectacular sight.
+ * Please see a spectacular sight.
* }
*/
public class ExtLink implements Taglet {
static final String TAG_NAME = "extLink";
- static final String URL = "https://www.oracle.com/pls/topic/lookup?ctx=javase9&id=";
+ static final String URL = "https://www.oracle.com/pls/topic/lookup?ctx=javase10&id=";
static final Pattern TAG_PATTERN = Pattern.compile("(?s)(\\s*)(?\\w+)(\\s+)(?.*)$");
diff --git a/make/jdk/src/classes/build/tools/x11wrappergen/WrapperGenerator.java b/make/jdk/src/classes/build/tools/x11wrappergen/WrapperGenerator.java
index 60888904b89..80a4bcfc390 100644
--- a/make/jdk/src/classes/build/tools/x11wrappergen/WrapperGenerator.java
+++ b/make/jdk/src/classes/build/tools/x11wrappergen/WrapperGenerator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, 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
@@ -1109,7 +1109,6 @@ public class WrapperGenerator {
}
public void writeJavaWrapperClass(String outputDir) {
-// (new File(outputDir, package_path)).mkdirs();
try {
for (Enumeration e = symbolTable.elements() ; e.hasMoreElements() ;) {
BaseType tp = (BaseType) e.nextElement();
@@ -1126,7 +1125,6 @@ public class WrapperGenerator {
}
}
-
public void writeNativeSizer(String file)
{
int type;
@@ -1136,7 +1134,6 @@ public class WrapperGenerator {
StructType stp;
Enumeration eo;
-
try {
FileOutputStream fs = new FileOutputStream(file);
@@ -1158,7 +1155,6 @@ public class WrapperGenerator {
pw.println(" unsigned long status;\n");
pw.println("} PropMwmHints;\n");
-
pw.println("\n\nint main(){");
j=0;
for ( eo = symbolTable.elements() ; eo.hasMoreElements() ;) {
@@ -1182,7 +1178,6 @@ public class WrapperGenerator {
pw.println("printf(\"Atom\t%d\\n\",(int)sizeof(Atom));");
pw.println("printf(\"Window\t%d\\n\",(int)sizeof(Window));");
-
for (eo = symbolTable.elements() ; eo.hasMoreElements() ;) {
@@ -1234,7 +1229,8 @@ public class WrapperGenerator {
symbolTable.put("Atom", new AtomicType(AtomicType.TYPE_ATOM, "", "Atom"));
symbolTable.put("ulong", new AtomicType(AtomicType.TYPE_ULONG, "", "ulong"));
}
- public WrapperGenerator(String outputDir, String xlibFilename) {
+
+ public WrapperGenerator(String xlibFilename) {
initTypes();
try {
BufferedReader in = new BufferedReader(new FileReader(xlibFilename));
@@ -1303,33 +1299,19 @@ public class WrapperGenerator {
catch (Exception e) {
e.printStackTrace();
}
-
}
- private void makeSizer(String outputDir) {
- if (wide) {
- sizerFileName = "sizer.64.c";
- } else {
- sizerFileName = "sizer.32.c";
- }
- File fp = new File(outputDir, sizerFileName);
+
+ private void makeSizer(String sizerFileName) {
+ File fp = new File(sizerFileName);
writeNativeSizer(fp.getAbsolutePath());
}
- private boolean readSizeInfo(String sizeInfo) {
+
+ private boolean readFileSizeInfo(String filename, boolean wide) {
try {
- File f = new File(sizeInfo+".32");
boolean res = true;
- FileInputStream fis = null;
- if (f.exists()) {
- fis = new FileInputStream(f);
- res = readSizeInfo(fis, false);
- fis.close();
- }
- f = new File(sizeInfo+".64");
- if (f.exists()) {
- fis = new FileInputStream(f);
- res &= readSizeInfo(fis, true);
- fis.close();
- }
+ FileInputStream fis = new FileInputStream(filename);
+ res = readSizeInfo(fis, wide);
+ fis.close();
return res;
} catch (Exception e) {
e.printStackTrace();
@@ -1337,8 +1319,8 @@ public class WrapperGenerator {
}
}
- private void startGeneration(String outputDir, String sizeInfo) {
- if (readSizeInfo(sizeInfo))
+ private void startGeneration(String outputDir, String filename, boolean wide) {
+ if (readFileSizeInfo(filename, wide))
{
writeJavaWrapperClass(outputDir);
}
@@ -1348,21 +1330,22 @@ public class WrapperGenerator {
}
public static void main(String[] args) {
-
if (args.length < 4) {
- System.out.println("Usage:\nWrapperGenerator [ | ]");
- System.out.println("Where : gen, sizer");
- System.out.println(" : 32, 64");
+ System.out.println("Usage:\nWrapperGenerator gen_java ");
+ System.out.println(" or");
+ System.out.println("WrapperGenerator gen_c_source ");
+ System.out.println("Where : 32, 64");
+
System.exit(1);
}
- WrapperGenerator xparser = new WrapperGenerator(args[0], args[1]);
- if (args[2].equals("sizer")) {
+ WrapperGenerator xparser = new WrapperGenerator(args[2]);
+ if (args[0].equals("gen_c_source")) {
xparser.wide = args[3].equals("64");
- xparser.makeSizer(args[0]);
- } else if (args[2].equals("gen")) {
- xparser.startGeneration(args[0], args[3]);
+ xparser.makeSizer(args[1]);
+ } else if (args[0].equals("gen_java")) {
+ boolean wide = args[4].equals("64");
+ xparser.startGeneration(args[1], args[3], wide);
}
}
-
}
diff --git a/make/langtools/tools/crules/AbstractCodingRulesAnalyzer.java b/make/langtools/tools/crules/AbstractCodingRulesAnalyzer.java
index e8781cf6b2f..de24ceb8c84 100644
--- a/make/langtools/tools/crules/AbstractCodingRulesAnalyzer.java
+++ b/make/langtools/tools/crules/AbstractCodingRulesAnalyzer.java
@@ -4,7 +4,9 @@
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
+ * 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
diff --git a/make/langtools/tools/crules/AssertCheckAnalyzer.java b/make/langtools/tools/crules/AssertCheckAnalyzer.java
index b665d74215e..4ef7fc22707 100644
--- a/make/langtools/tools/crules/AssertCheckAnalyzer.java
+++ b/make/langtools/tools/crules/AssertCheckAnalyzer.java
@@ -4,7 +4,9 @@
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
+ * 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
diff --git a/make/langtools/tools/crules/CodingRulesAnalyzerPlugin.java b/make/langtools/tools/crules/CodingRulesAnalyzerPlugin.java
index 4a4d959173b..322b2fa4eef 100644
--- a/make/langtools/tools/crules/CodingRulesAnalyzerPlugin.java
+++ b/make/langtools/tools/crules/CodingRulesAnalyzerPlugin.java
@@ -4,7 +4,9 @@
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
+ * 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
diff --git a/make/langtools/tools/crules/DefinedByAnalyzer.java b/make/langtools/tools/crules/DefinedByAnalyzer.java
index fe79c8eb745..40faa473ea0 100644
--- a/make/langtools/tools/crules/DefinedByAnalyzer.java
+++ b/make/langtools/tools/crules/DefinedByAnalyzer.java
@@ -4,7 +4,9 @@
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
+ * 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
diff --git a/make/langtools/tools/crules/LegacyLogMethodAnalyzer.java b/make/langtools/tools/crules/LegacyLogMethodAnalyzer.java
index 5153aa6f6ee..c96ba23f0c7 100644
--- a/make/langtools/tools/crules/LegacyLogMethodAnalyzer.java
+++ b/make/langtools/tools/crules/LegacyLogMethodAnalyzer.java
@@ -4,7 +4,9 @@
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
+ * 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
diff --git a/make/langtools/tools/crules/MutableFieldsAnalyzer.java b/make/langtools/tools/crules/MutableFieldsAnalyzer.java
index b5c0dd74469..73fbd5af647 100644
--- a/make/langtools/tools/crules/MutableFieldsAnalyzer.java
+++ b/make/langtools/tools/crules/MutableFieldsAnalyzer.java
@@ -4,7 +4,9 @@
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
+ * 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
diff --git a/make/langtools/tools/propertiesparser/gen/ClassGenerator.java b/make/langtools/tools/propertiesparser/gen/ClassGenerator.java
index 85a5472be95..999f67e55af 100644
--- a/make/langtools/tools/propertiesparser/gen/ClassGenerator.java
+++ b/make/langtools/tools/propertiesparser/gen/ClassGenerator.java
@@ -4,7 +4,9 @@
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
+ * 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
diff --git a/make/langtools/tools/propertiesparser/parser/Message.java b/make/langtools/tools/propertiesparser/parser/Message.java
index bc46f3aeb9e..02a2f5e4f5c 100644
--- a/make/langtools/tools/propertiesparser/parser/Message.java
+++ b/make/langtools/tools/propertiesparser/parser/Message.java
@@ -4,7 +4,9 @@
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
+ * 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
diff --git a/make/langtools/tools/propertiesparser/parser/MessageFile.java b/make/langtools/tools/propertiesparser/parser/MessageFile.java
index d9aea3e1d23..25ac27e49fc 100644
--- a/make/langtools/tools/propertiesparser/parser/MessageFile.java
+++ b/make/langtools/tools/propertiesparser/parser/MessageFile.java
@@ -4,7 +4,9 @@
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
+ * 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
diff --git a/make/langtools/tools/propertiesparser/parser/MessageInfo.java b/make/langtools/tools/propertiesparser/parser/MessageInfo.java
index c57ccf73bfb..7bc5daf2e49 100644
--- a/make/langtools/tools/propertiesparser/parser/MessageInfo.java
+++ b/make/langtools/tools/propertiesparser/parser/MessageInfo.java
@@ -4,7 +4,9 @@
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
+ * 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
diff --git a/make/langtools/tools/propertiesparser/parser/MessageLine.java b/make/langtools/tools/propertiesparser/parser/MessageLine.java
index 94c0f90a034..e370eefa38a 100644
--- a/make/langtools/tools/propertiesparser/parser/MessageLine.java
+++ b/make/langtools/tools/propertiesparser/parser/MessageLine.java
@@ -4,7 +4,9 @@
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
+ * 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
diff --git a/make/langtools/tools/propertiesparser/parser/MessageType.java b/make/langtools/tools/propertiesparser/parser/MessageType.java
index e5366b939af..a6ae325d541 100644
--- a/make/langtools/tools/propertiesparser/parser/MessageType.java
+++ b/make/langtools/tools/propertiesparser/parser/MessageType.java
@@ -4,7 +4,9 @@
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
+ * 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
diff --git a/make/launcher/Launcher-java.base.gmk b/make/launcher/Launcher-java.base.gmk
index 26b89d54b8b..e6dad18155c 100644
--- a/make/launcher/Launcher-java.base.gmk
+++ b/make/launcher/Launcher-java.base.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -27,8 +27,8 @@ include LauncherCommon.gmk
$(eval $(call IncludeCustomExtension, launcher/Launcher-java.base.gmk))
-JAVA_RC_FLAGS += -I $(TOPDIR)/src/java.base/windows/native/common
-JAVA_RC_FLAGS += -I $(TOPDIR)/src/java.base/windows/native/launcher/icons
+JAVA_RC_FLAGS += -I$(TOPDIR)/src/java.base/windows/native/common
+JAVA_RC_FLAGS += -I$(TOPDIR)/src/java.base/windows/native/launcher/icons
################################################################################
@@ -39,7 +39,7 @@ $(eval $(call SetupBuildLauncher, java, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS -DENABLE_ARG_FILES, \
LDFLAGS_solaris := -R$(OPENWIN_HOME)/lib$(OPENJDK_TARGET_CPU_ISADIR), \
LIBS_windows := user32.lib comctl32.lib, \
- RC_FLAGS := $(JAVA_RC_FLAGS), \
+ EXTRA_RC_FLAGS := $(JAVA_RC_FLAGS), \
VERSION_INFO_RESOURCE := $(JAVA_VERSION_INFO_RESOURCE), \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/java_objs, \
OPTIMIZATION := HIGH, \
@@ -58,7 +58,7 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
$(eval $(call SetupBuildLauncher, javaw, \
CFLAGS := -DJAVAW -DEXPAND_CLASSPATH_WILDCARDS -DENABLE_ARG_FILES, \
LIBS_windows := user32.lib comctl32.lib, \
- RC_FLAGS := $(JAVA_RC_FLAGS), \
+ EXTRA_RC_FLAGS := $(JAVA_RC_FLAGS), \
VERSION_INFO_RESOURCE := $(JAVA_VERSION_INFO_RESOURCE), \
WINDOWS_STATIC_LINK := true, \
NO_JAVA_MS := true, \
@@ -72,7 +72,8 @@ $(eval $(call SetupBuildLauncher, keytool, \
################################################################################
ifeq ($(OPENJDK_TARGET_OS), linux)
- $(eval $(call SetupNativeCompilation, BUILD_JEXEC, \
+ $(eval $(call SetupJdkExecutable, BUILD_JEXEC, \
+ NAME := jexec, \
SRC := $(TOPDIR)/src/$(MODULE)/unix/native/launcher, \
INCLUDE_FILES := jexec.c, \
OPTIMIZATION := LOW, \
@@ -81,9 +82,7 @@ ifeq ($(OPENJDK_TARGET_OS), linux)
CFLAGS_linux := -fPIC, \
CFLAGS_solaris := -KPIC, \
LDFLAGS := $(LDFLAGS_JDKEXE), \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/jexec_obj, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_libs/$(MODULE), \
- PROGRAM := jexec, \
))
TARGETS += $(BUILD_JEXEC)
@@ -92,15 +91,14 @@ endif
################################################################################
ifneq ($(findstring $(OPENJDK_TARGET_OS), macosx solaris aix), )
- $(eval $(call SetupNativeCompilation, BUILD_JSPAWNHELPER, \
+ $(eval $(call SetupJdkExecutable, BUILD_JSPAWNHELPER, \
+ NAME := jspawnhelper, \
SRC := $(TOPDIR)/src/$(MODULE)/unix/native/jspawnhelper, \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKEXE) -I$(TOPDIR)/src/$(MODULE)/unix/native/libjava, \
EXTRA_OBJECT_FILES := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjava/childproc.o, \
LDFLAGS := $(LDFLAGS_JDKEXE), \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/jspawnhelper, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_libs/$(MODULE), \
- PROGRAM := jspawnhelper, \
))
TARGETS += $(BUILD_JSPAWNHELPER)
diff --git a/make/launcher/Launcher-jdk.accessibility.gmk b/make/launcher/Launcher-jdk.accessibility.gmk
index 1163e7691fd..f31d039aab4 100644
--- a/make/launcher/Launcher-jdk.accessibility.gmk
+++ b/make/launcher/Launcher-jdk.accessibility.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,8 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
JABSWITCH_SRC := $(TOPDIR)/src/jdk.accessibility/windows/native/jabswitch
ACCESSBRIDGE_SRC := $(TOPDIR)/src/jdk.accessibility/windows/native/common
- $(eval $(call SetupNativeCompilation,BUILD_JABSWITCH, \
+ $(eval $(call SetupJdkExecutable, BUILD_JABSWITCH, \
+ NAME := jabswitch, \
SRC := $(JABSWITCH_SRC), \
INCLUDE_FILES := jabswitch.cpp, \
CFLAGS := $(filter-out -Zc:wchar_t-, $(CFLAGS_JDKEXE)) -Zc:wchar_t \
@@ -42,14 +43,7 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
DISABLED_WARNINGS_microsoft := 4267 4996, \
LDFLAGS := $(LDFLAGS_JDKEXE), \
LIBS := advapi32.lib version.lib user32.lib, \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/jdk.accessibility/jabswitch, \
- OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_cmds/jdk.accessibility, \
- PROGRAM := jabswitch, \
VERSIONINFO_RESOURCE := $(ACCESSBRIDGE_SRC)/AccessBridgeStatusWindow.RC, \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=jabswitch.exe" \
- -D "JDK_INTERNAL_NAME=jabswitch" \
- -D "JDK_FTYPE=0x01L", \
MANIFEST := $(JABSWITCH_SRC)/jabswitch.manifest, \
MANIFEST_VERSION := $(VERSION_NUMBER_FOUR_POSITIONS), \
))
@@ -69,20 +63,14 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
# Parameter 1 File name suffix
# Parameter 2 ACCESSBRIDGE_ARCH_ -D suffix
- $$(eval $$(call SetupNativeCompilation, BUILD_JACCESSINSPECTOR$1, \
+ $$(eval $$(call SetupJdkExecutable, BUILD_JACCESSINSPECTOR$1, \
+ NAME := jaccessinspector$1, \
SRC := $(TOPDIR)/jaccessinspector $(TOPDIR)/common \
$(TOPDIR)/toolscommon $(TOPDIR)/bridge, \
CFLAGS := $$(CFLAGS_JDKEXE) $(TOOLS_CFLAGS) -DACCESSBRIDGE_ARCH_$2 -EHsc, \
LDFLAGS := $$(LDFLAGS_JDKEXE) -stack:655360, \
LIBS := advapi32.lib user32.lib, \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/jdk.accessibility/jaccessinspector$1, \
- OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_cmds/jdk.accessibility, \
- PROGRAM := jaccessinspector$1, \
VERSIONINFO_RESOURCE := $(TOPDIR)/jaccessinspector/jaccessinspectorWindow.rc, \
- RC_FLAGS := $$(RC_FLAGS) \
- -D "JDK_FNAME=jaccessinspector$1.exe" \
- -D "JDK_INTERNAL_NAME=jaccessinspector$1" \
- -D "JDK_FTYPE=0x01L", \
))
TARGETS += $$(BUILD_JACCESSINSPECTOR$1)
@@ -96,20 +84,14 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
# Parameter 1 File name suffix
# Parameter 2 ACCESSBRIDGE_ARCH_ -D suffix
- $$(eval $$(call SetupNativeCompilation,BUILD_JACCESSWALKER$1, \
+ $$(eval $$(call SetupJdkExecutable, BUILD_JACCESSWALKER$1, \
+ NAME := jaccesswalker$1, \
SRC := $(TOPDIR)/jaccesswalker $(TOPDIR)/common \
$(TOPDIR)/toolscommon $(TOPDIR)/bridge, \
CFLAGS := $$(CFLAGS_JDKEXE) $(TOOLS_CFLAGS) -DACCESSBRIDGE_ARCH_$2 -EHsc, \
LDFLAGS := $$(LDFLAGS_JDKEXE) -stack:655360, \
LIBS := advapi32.lib comctl32.lib gdi32.lib user32.lib, \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/jdk.accessibility/jaccesswalker$1, \
- OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_cmds/jdk.accessibility, \
- PROGRAM := jaccesswalker$1, \
VERSIONINFO_RESOURCE := $(TOPDIR)/jaccesswalker/jaccesswalkerWindow.rc, \
- RC_FLAGS := $$(RC_FLAGS) \
- -D "JDK_FNAME=jaccesswalker$1.exe" \
- -D "JDK_INTERNAL_NAME=jaccesswalker$1" \
- -D "JDK_FTYPE=0x01L", \
))
TARGETS += $$(BUILD_JACCESSWALKER$1)
diff --git a/make/launcher/Launcher-jdk.pack.gmk b/make/launcher/Launcher-jdk.pack.gmk
index af1fe139c6b..51047c5fe6b 100644
--- a/make/launcher/Launcher-jdk.pack.gmk
+++ b/make/launcher/Launcher-jdk.pack.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -73,7 +73,8 @@ else
UNPACK_MAPFILE := $(UNPACK_MAPFILE_DIR)/mapfile-vers-unpack200
endif
-$(eval $(call SetupNativeCompilation,BUILD_UNPACKEXE, \
+$(eval $(call SetupJdkExecutable, BUILD_UNPACKEXE, \
+ NAME := unpack200, \
SRC := $(UNPACKEXE_SRC), \
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
OPTIMIZATION := LOW, \
@@ -88,15 +89,7 @@ $(eval $(call SetupNativeCompilation,BUILD_UNPACKEXE, \
$(LDFLAGS_JDKEXE) $(LDFLAGS_CXX_JDK) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LIBS := $(UNPACKEXE_LIBS) $(LIBCXX), \
- LIBS_solaris := -lc, \
OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/unpackexe, \
- OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_cmds/$(MODULE), \
- PROGRAM := unpack200, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=unpack200.exe" \
- -D "JDK_INTERNAL_NAME=unpack200" \
- -D "JDK_FTYPE=0x1L", \
MANIFEST := $(TOPDIR)/src/jdk.pack/windows/native/unpack200/unpack200_proto.exe.manifest, \
MANIFEST_VERSION := $(VERSION_NUMBER_FOUR_POSITIONS), \
))
diff --git a/make/launcher/LauncherCommon.gmk b/make/launcher/LauncherCommon.gmk
index aa07cac2467..05cf6bc4c89 100644
--- a/make/launcher/LauncherCommon.gmk
+++ b/make/launcher/LauncherCommon.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
# questions.
#
-include NativeCompilation.gmk
+include JdkNativeCompilation.gmk
ifeq ($(OPENJDK_TARGET_OS), macosx)
DISABLE_MAPFILES := true
@@ -85,14 +85,6 @@ JAVA_MANIFEST := $(TOPDIR)/src/java.base/windows/native/launcher/java.manifest
SetupBuildLauncher = $(NamedParamsMacroTemplate)
define SetupBuildLauncherBody
# Setup default values (unless overridden)
- ifeq ($$($1_VERSION_INFO_RESOURCE), )
- $1_VERSION_INFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE)
- endif
-
- ifeq ($$($1_OUTPUT_DIR), )
- $1_OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_cmds/$(MODULE)
- endif
-
ifeq ($$($1_OPTIMIZATION), )
$1_OPTIMIZATION := LOW
endif
@@ -182,7 +174,8 @@ define SetupBuildLauncherBody
endif
endif
- $$(eval $$(call SetupNativeCompilation, BUILD_LAUNCHER_$1, \
+ $$(eval $$(call SetupJdkExecutable, BUILD_LAUNCHER_$1, \
+ NAME := $1, \
EXTRA_FILES := $(LAUNCHER_SRC)/main.c, \
OPTIMIZATION := $$($1_OPTIMIZATION), \
CFLAGS := $$($1_CFLAGS) \
@@ -204,20 +197,14 @@ define SetupBuildLauncherBody
MAPFILE := $$($1_MAPFILE), \
LIBS := $(JDKEXE_LIBS) $$($1_LIBS), \
LIBS_unix := $$($1_LIBS_unix), \
- LIBS_linux := -lpthread -ljli $(LIBDL) -lc, \
- LIBS_solaris := -ljli -lthread $(LIBDL) -lc, \
+ LIBS_linux := -lpthread -ljli $(LIBDL), \
+ LIBS_solaris := -ljli -lthread $(LIBDL), \
LIBS_windows := $$($1_WINDOWS_JLI_LIB) \
$(SUPPORT_OUTPUTDIR)/native/java.base/libjava/java.lib advapi32.lib \
$$($1_LIBS_windows), \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/$1_objs, \
OUTPUT_DIR := $$($1_OUTPUT_DIR), \
- PROGRAM := $1, \
VERSIONINFO_RESOURCE := $$($1_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $$(RC_FLAGS) \
- -D "JDK_FNAME=$1$(EXE_SUFFIX)" \
- -D "JDK_INTERNAL_NAME=$1" \
- -D "JDK_FTYPE=0x1L" \
- $$($1_RC_FLAGS), \
+ EXTRA_RC_FLAGS := $$($1_EXTRA_RC_FLAGS), \
MANIFEST := $(JAVA_MANIFEST), \
MANIFEST_VERSION := $(VERSION_NUMBER_FOUR_POSITIONS), \
CODESIGN := $$($1_CODESIGN), \
diff --git a/make/lib/Awt2dLibraries.gmk b/make/lib/Awt2dLibraries.gmk
index 14c41b9d83a..5191e18f411 100644
--- a/make/lib/Awt2dLibraries.gmk
+++ b/make/lib/Awt2dLibraries.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -48,9 +48,8 @@ ifneq ($(OPENJDK_TARGET_OS), windows)
BUILD_LIBMLIB_LDLIBS += $(LIBM) $(LIBDL)
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBMLIB_IMAGE, \
- LIBRARY := mlib_image, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+$(eval $(call SetupJdkLibrary, BUILD_LIBMLIB_IMAGE, \
+ NAME := mlib_image, \
SRC := $(BUILD_LIBMLIB_SRC), \
EXCLUDE_FILES := mlib_c_ImageBlendTable.c, \
OPTIMIZATION := HIGHEST, \
@@ -61,13 +60,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBMLIB_IMAGE, \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LIBS := $(BUILD_LIBMLIB_LDLIBS) \
$(JDKLIB_LIBS), \
- LIBS_solaris := -lc, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=mlib_image.dll" \
- -D "JDK_INTERNAL_NAME=mlib_image" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libmlib_image, \
))
$(BUILD_LIBMLIB_IMAGE): $(call FindLib, java.base, java)
@@ -107,9 +99,8 @@ ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_ARCH), solaris-sparc)
LIBMLIB_IMAGE_V_CFLAGS += $(filter-out -DMLIB_NO_LIBSUNMATH, $(BUILD_LIBMLIB_CFLAGS))
- $(eval $(call SetupNativeCompilation,BUILD_LIBMLIB_IMAGE_V, \
- LIBRARY := mlib_image_v, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ $(eval $(call SetupJdkLibrary, BUILD_LIBMLIB_IMAGE_V, \
+ NAME := mlib_image_v, \
SRC := $(LIBMLIB_IMAGE_V_SRC), \
EXCLUDE_FILES := $(BUILD_LIBMLIB_IMAGE_V_EXFILES), \
OPTIMIZATION := HIGHEST, \
@@ -119,8 +110,7 @@ ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_ARCH), solaris-sparc)
MAPFILE := $(BUILD_LIBMLIB_IMAGE_MAPFILE), \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
- LIBS := -ljava -ljvm -lc $(BUILD_LIBMLIB_LDLIBS), \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libmlib_image_v, \
+ LIBS := -ljava -ljvm $(BUILD_LIBMLIB_LDLIBS), \
))
$(BUILD_LIBMLIB_IMAGE_V): $(call FindLib, java.base, java)
@@ -226,9 +216,8 @@ ifeq ($(TOOLCHAIN_TYPE), gcc)
LIBAWT_CFLAGS += -fgcse-after-reload
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBAWT, \
- LIBRARY := awt, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+$(eval $(call SetupJdkLibrary, BUILD_LIBAWT, \
+ NAME := awt, \
SRC := $(LIBAWT_DIRS), \
EXCLUDES := $(LIBAWT_EXCLUDES), \
EXCLUDE_FILES := $(LIBAWT_EXFILES), \
@@ -250,7 +239,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBAWT, \
-delayload:comctl32.dll -delayload:shlwapi.dll, \
LIBS_unix := -ljvm -ljava $(LIBM), \
LIBS_linux := $(LIBDL), \
- LIBS_solaris := $(LIBDL) -lc, \
+ LIBS_solaris := $(LIBDL), \
LIBS_aix := $(LIBDL),\
LIBS_macosx := -lmlib_image \
-framework Cocoa \
@@ -268,7 +257,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBAWT, \
-D "JDK_FNAME=awt.dll" \
-D "JDK_INTERNAL_NAME=awt" \
-D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libawt, \
))
$(BUILD_LIBAWT): $(call FindLib, java.base, java)
@@ -330,7 +318,7 @@ ifeq ($(findstring $(OPENJDK_TARGET_OS),windows macosx),)
endif
endif
- LIBAWT_XAWT_LIBS := $(LIBM) -lawt -lXext -lX11 -lXrender $(LIBDL) -lXtst -lXi -ljava -ljvm -lc
+ LIBAWT_XAWT_LIBS := $(LIBM) -lawt -lXext -lX11 -lXrender $(LIBDL) -lXtst -lXi -ljava -ljvm
ifeq ($(OPENJDK_TARGET_OS), linux)
LIBAWT_XAWT_LIBS += -lpthread
@@ -347,9 +335,8 @@ ifeq ($(findstring $(OPENJDK_TARGET_OS),windows macosx),)
BUILD_LIBAWT_XAWT_debug_mem.c_CFLAGS := -w
endif
- $(eval $(call SetupNativeCompilation,BUILD_LIBAWT_XAWT, \
- LIBRARY := awt_xawt, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ $(eval $(call SetupJdkLibrary, BUILD_LIBAWT_XAWT, \
+ NAME := awt_xawt, \
SRC := $(LIBAWT_XAWT_DIRS), \
EXCLUDES := $(LIBAWT_XAWT_EXCLUDES), \
OPTIMIZATION := LOW, \
@@ -367,12 +354,10 @@ ifeq ($(findstring $(OPENJDK_TARGET_OS),windows macosx),)
$(call SET_SHARED_LIBRARY_ORIGIN) \
-L$(INSTALL_LIBRARIES_HERE), \
LIBS := $(X_LIBS) $(LIBAWT_XAWT_LIBS), \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
RC_FLAGS := $(RC_FLAGS) \
-D "JDK_FNAME=xawt.dll" \
-D "JDK_INTERNAL_NAME=xawt" \
-D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libawt_xawt, \
))
$(BUILD_LIBAWT_XAWT): $(call FindLib, java.base, java)
@@ -406,9 +391,8 @@ else
LIBLCMS_CPPFLAGS += $(addprefix -I, $(LIBLCMS_SRC))
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBLCMS, \
- LIBRARY := lcms, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+$(eval $(call SetupJdkLibrary, BUILD_LIBLCMS, \
+ NAME := lcms, \
SRC := $(LIBLCMS_SRC), \
INCLUDE_FILES := $(BUILD_LIBLCMS_INCLUDE_FILES), \
OPTIMIZATION := HIGHEST, \
@@ -429,15 +413,8 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBLCMS, \
LIBS_unix := -lawt -ljvm -ljava $(LCMS_LIBS), \
LIBS_linux := $(LIBM), \
LIBS_macosx := $(LIBM), \
- LIBS_solaris := -lc, \
LIBS_aix := $(LIBM),\
LIBS_windows := $(WIN_AWT_LIB) $(WIN_JAVA_LIB), \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=lcms.dll" \
- -D "JDK_INTERNAL_NAME=lcms" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/liblcms, \
))
TARGETS += $(BUILD_LIBLCMS)
@@ -483,9 +460,8 @@ else
BUILD_LIBJAVAJPEG_HEADERS := $(addprefix -I, $(LIBJAVAJPEG_SRC))
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBJAVAJPEG, \
- LIBRARY := javajpeg, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+$(eval $(call SetupJdkLibrary, BUILD_LIBJAVAJPEG, \
+ NAME := javajpeg, \
SRC := $(LIBJAVAJPEG_SRC), \
INCLUDE_FILES := $(BUILD_LIBJAVAJPEG_INCLUDE_FILES), \
OPTIMIZATION := HIGHEST, \
@@ -498,13 +474,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJAVAJPEG, \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LIBS := $(LIBJPEG_LIBS) $(JDKLIB_LIBS), \
LIBS_windows := $(WIN_JAVA_LIB) jvm.lib, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=javajpeg.dll" \
- -D "JDK_INTERNAL_NAME=javajpeg" \
- -D "JDK_FTYPE=0x2L", \
REORDER := $(BUILD_LIBJAVAJPEG_REORDER), \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjavajpeg, \
))
$(BUILD_LIBJAVAJPEG): $(call FindLib, java.base, java)
@@ -547,9 +517,8 @@ ifeq ($(findstring $(OPENJDK_TARGET_OS), windows macosx),)
endif
endif
- $(eval $(call SetupNativeCompilation,BUILD_LIBAWT_HEADLESS, \
- LIBRARY := awt_headless, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ $(eval $(call SetupJdkLibrary, BUILD_LIBAWT_HEADLESS, \
+ NAME := awt_headless, \
SRC := $(LIBAWT_HEADLESS_DIRS), \
EXCLUDES := $(LIBAWT_HEADLESS_EXCLUDES), \
OPTIMIZATION := LOW, \
@@ -569,8 +538,7 @@ ifeq ($(findstring $(OPENJDK_TARGET_OS), windows macosx),)
REORDER := $(LIBAWT_HEADLESS_REORDER), \
LIBS_unix := -lawt -ljvm -ljava, \
LIBS_linux := $(LIBM) $(LIBDL), \
- LIBS_solaris := $(LIBM) $(LIBDL) $(LIBCXX) -lc, \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libawt_headless, \
+ LIBS_solaris := $(LIBM) $(LIBDL) $(LIBCXX), \
))
# AIX warning explanation:
@@ -585,6 +553,38 @@ endif
################################################################################
+ifeq ($(FREETYPE_TO_USE), system)
+ LIBFREETYPE_CFLAGS := $(FREETYPE_CFLAGS)
+ LIBFREETYPE_LIBS := $(FREETYPE_LIBS)
+else
+ LIBFREETYPE_SRC := $(TOPDIR)/src/java.desktop/share/native/libfreetype
+ BUILD_LIBFREETYPE_HEADERS := $(addprefix -I, $(LIBFREETYPE_SRC)/include)
+ LIBFREETYPE_CFLAGS := $(BUILD_LIBFREETYPE_HEADERS)
+ ifeq ($(OPENJDK_TARGET_OS), windows)
+ LIBFREETYPE_LIBS := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libfreetype/freetype.lib
+ else
+ LIBFREETYPE_LIBS := -lfreetype
+ endif
+
+ $(eval $(call SetupJdkLibrary, BUILD_LIBFREETYPE, \
+ NAME := freetype, \
+ SRC := $(LIBFREETYPE_SRC)/src, \
+ OPTIMIZATION := HIGHEST, \
+ CFLAGS := $(CFLAGS_JDKLIB) $(BUILD_LIBFREETYPE_HEADERS) \
+ -DFT2_BUILD_LIBRARY, \
+ DISABLED_WARNINGS_solstudio := \
+ E_STATEMENT_NOT_REACHED \
+ E_END_OF_LOOP_CODE_NOT_REACHED, \
+ DISABLED_WARNINGS_microsoft := 4267 2220 4244, \
+ LDFLAGS := $(LDFLAGS_JDKLIB) \
+ $(call SET_SHARED_LIBRARY_ORIGIN), \
+ ))
+
+ TARGETS += $(BUILD_LIBFREETYPE)
+endif
+
+###########################################################################
+
LIBFONTMANAGER_SRC := $(TOPDIR)/src/java.desktop/share/native/libfontmanager \
$(TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/libfontmanager
LIBFONTMANAGER_CFLAGS := \
@@ -625,10 +625,10 @@ LIBFONTMANAGER_CFLAGS += $(HARFBUZZ_CFLAGS)
#### End harfbuzz configuration
-LIBFONTMANAGER_CFLAGS += $(FREETYPE_CFLAGS)
+LIBFONTMANAGER_CFLAGS += $(LIBFREETYPE_CFLAGS)
# This may be overridden in a custom makefile
BUILD_LIBFONTMANAGER_MAPFILE ?= $(TOPDIR)/make/mapfiles/libfontmanager/mapfile-vers
-BUILD_LIBFONTMANAGER_FONTLIB += $(FREETYPE_LIBS)
+BUILD_LIBFONTMANAGER_FONTLIB += $(LIBFREETYPE_LIBS)
LIBFONTMANAGER_OPTIMIZATION := HIGH
@@ -657,9 +657,8 @@ ifeq ($(TOOLCHAIN_TYPE), gcc)
BUILD_LIBFONTMANAGER_ExtensionSubtables.cpp_CXXFLAGS := -fno-strict-aliasing
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBFONTMANAGER, \
- LIBRARY := fontmanager, \
- OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libfontmanager, \
+$(eval $(call SetupJdkLibrary, BUILD_LIBFONTMANAGER, \
+ NAME := fontmanager, \
SRC := $(LIBFONTMANAGER_SRC), \
EXCLUDE_FILES := $(LIBFONTMANAGER_EXCLUDE_FILES) \
AccelGlyphCache.c, \
@@ -690,40 +689,21 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBFONTMANAGER, \
LDFLAGS_macosx := -undefined dynamic_lookup, \
LIBS := $(BUILD_LIBFONTMANAGER_FONTLIB), \
LIBS_unix := -lawt -ljava -ljvm $(LIBM) $(LIBCXX), \
- LIBS_linux := -lc, \
- LIBS_solaris := -lawt_headless -lc, \
LIBS_aix := -lawt_headless,\
LIBS_windows := $(WIN_JAVA_LIB) advapi32.lib user32.lib gdi32.lib \
$(WIN_AWT_LIB), \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=fontmanager.dll" \
- -D "JDK_INTERNAL_NAME=fontmanager" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libfontmanager, \
))
-$(INSTALL_LIBRARIES_HERE)/$(call SHARED_LIBRARY,fontmanager): $(BUILD_LIBFONTMANAGER_TARGET)
- $(install-file)
- ifneq ($(FREETYPE_BUNDLE_LIB_PATH), )
- ifeq ($(OPENJDK_TARGET_OS), macosx)
- # If bundling freetype on macosx, we need to rewrite the rpath location
- # in the libfontmanager library to point to the bundled location
- $(INSTALL_NAME_TOOL) -change \
- `$(OTOOL) -D $(FREETYPE_BUNDLE_LIB_PATH)/$(call SHARED_LIBRARY,freetype) | $(TAIL) -n1` \
- '@rpath/$(call SHARED_LIBRARY,freetype)' \
- $@
- endif
- endif
-
-BUILD_LIBFONTMANAGER += $(INSTALL_LIBRARIES_HERE)/$(call SHARED_LIBRARY,fontmanager)
-
$(BUILD_LIBFONTMANAGER): $(BUILD_LIBAWT)
ifneq (, $(findstring $(OPENJDK_TARGET_OS), solaris aix))
$(BUILD_LIBFONTMANAGER): $(BUILD_LIBAWT_HEADLESS)
endif
+ifeq ($(FREETYPE_TO_USE), bundled)
+ $(BUILD_LIBFONTMANAGER): $(BUILD_LIBFREETYPE)
+endif
+
TARGETS += $(BUILD_LIBFONTMANAGER)
################################################################################
@@ -744,9 +724,8 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
ifeq ($(OPENJDK_TARGET_CPU), x86)
KERNEL32_LIB := kernel32.lib
endif
- $(eval $(call SetupNativeCompilation,BUILD_LIBJAWT, \
- LIBRARY := jawt, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ $(eval $(call SetupJdkLibrary, BUILD_LIBJAWT, \
+ NAME := jawt, \
SRC := $(LIBJAWT_SRC), \
INCLUDE_FILES := $(LIBJAWT_INCLUDE_FILES), \
OPTIMIZATION := LOW, \
@@ -755,12 +734,6 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
$(LIBJAWT_CFLAGS), \
LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK), \
LIBS := $(JDKLIB_LIBS) $(KERNEL32_LIB) advapi32.lib $(WIN_AWT_LIB), \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=jawt.dll" \
- -D "JDK_INTERNAL_NAME=jawt" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjawt, \
))
$(BUILD_LIBJAWT): $(BUILD_LIBAWT)
@@ -804,9 +777,8 @@ else # OPENJDK_TARGET_OS not windows
endif
endif
- $(eval $(call SetupNativeCompilation,BUILD_LIBJAWT, \
- LIBRARY := jawt, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ $(eval $(call SetupJdkLibrary, BUILD_LIBJAWT, \
+ NAME := jawt, \
SRC := $(LIBJAWT_SRC), \
INCLUDE_FILES := $(JAWT_FILES), \
OPTIMIZATION := LOW, \
@@ -822,7 +794,6 @@ else # OPENJDK_TARGET_OS not windows
LIBS_unix := $(JAWT_LIBS) $(JDKLIB_LIBS), \
LIBS_solaris := $(X_LIBS) -lXrender, \
LIBS_macosx := -framework Cocoa, \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjawt, \
))
ifeq ($(ENABLE_HEADLESS_ONLY), false)
@@ -921,7 +892,6 @@ ifeq ($(ENABLE_HEADLESS_ONLY), false)
endif
ifeq ($(OPENJDK_TARGET_OS), macosx)
- LIBSPLASHSCREEN_LDFLAGS := -L$(INSTALL_LIBRARIES_HERE)
LIBSPLASHSCREEN_LIBS += \
$(LIBM) -lpthread -liconv -losxapp \
-framework ApplicationServices \
@@ -929,15 +899,13 @@ ifeq ($(ENABLE_HEADLESS_ONLY), false)
-framework Cocoa \
-framework JavaNativeFoundation
else ifeq ($(OPENJDK_TARGET_OS), windows)
- LIBSPLASHSCREEN_LDFLAGS := -delayload:user32.dll
LIBSPLASHSCREEN_LIBS += kernel32.lib user32.lib gdi32.lib delayimp.lib $(WIN_JAVA_LIB) jvm.lib
else
LIBSPLASHSCREEN_LIBS += $(X_LIBS) -lX11 -lXext $(LIBM) -lpthread -ldl
endif
- $(eval $(call SetupNativeCompilation,BUILD_LIBSPLASHSCREEN, \
- LIBRARY := splashscreen, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ $(eval $(call SetupJdkLibrary, BUILD_LIBSPLASHSCREEN, \
+ NAME := splashscreen, \
SRC := $(LIBSPLASHSCREEN_DIRS), \
EXCLUDE_FILES := imageioJPEG.c jpegdecoder.c pngtest.c, \
EXCLUDES := $(LIBSPLASHSCREEN_EXCLUDES), \
@@ -951,17 +919,13 @@ ifeq ($(ENABLE_HEADLESS_ONLY), false)
E_STATEMENT_NOT_REACHED, \
DISABLED_WARNINGS_microsoft := 4018 4244 4267, \
MAPFILE := $(TOPDIR)/make/mapfiles/libsplashscreen/mapfile-vers, \
- LDFLAGS := $(LIBSPLASHSCREEN_LDFLAGS) $(LDFLAGS_JDKLIB) \
+ LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
+ LDFLAGS_macosx := -L$(INSTALL_LIBRARIES_HERE), \
+ LDFLAGS_windows := -delayload:user32.dll, \
LIBS := $(JDKLIB_LIBS) $(LIBSPLASHSCREEN_LIBS) $(LIBZ_LIBS) \
$(GIFLIB_LIBS) $(LIBJPEG_LIBS) $(PNG_LIBS), \
LIBS_aix := -liconv, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=splashscreen.dll" \
- -D "JDK_INTERNAL_NAME=splashscreen" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libsplashscreen, \
))
TARGETS += $(BUILD_LIBSPLASHSCREEN)
@@ -1008,9 +972,8 @@ ifeq ($(OPENJDK_TARGET_OS), macosx)
LIBAWT_LWAWT_EXFILES := fontpath.c awt_Font.c X11Color.c
LIBAWT_LWAWT_EXCLUDES := $(TOPDIR)/src/java.desktop/unix/native/common/awt/medialib
- $(eval $(call SetupNativeCompilation,BUILD_LIBAWT_LWAWT, \
- LIBRARY := awt_lwawt, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ $(eval $(call SetupJdkLibrary, BUILD_LIBAWT_LWAWT, \
+ NAME := awt_lwawt, \
SRC := $(LIBAWT_LWAWT_DIRS), \
INCLUDE_FILES := $(LIBAWT_LWAWT_FILES), \
EXCLUDE_FILES := $(LIBAWT_LWAWT_EXFILES), \
@@ -1038,7 +1001,6 @@ ifeq ($(OPENJDK_TARGET_OS), macosx)
-framework JavaRuntimeSupport \
-framework OpenGL \
-framework QuartzCore -ljava, \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libawt_lwawt, \
))
TARGETS += $(BUILD_LIBAWT_LWAWT)
@@ -1057,9 +1019,8 @@ endif
ifeq ($(OPENJDK_TARGET_OS), macosx)
- $(eval $(call SetupNativeCompilation,BUILD_LIBOSXUI, \
- LIBRARY := osxui, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ $(eval $(call SetupJdkLibrary, BUILD_LIBOSXUI, \
+ NAME := osxui, \
SRC := $(TOPDIR)/src/java.desktop/macosx/native/libosxui, \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) \
@@ -1080,7 +1041,6 @@ ifeq ($(OPENJDK_TARGET_OS), macosx)
-framework JavaNativeFoundation \
-framework JavaRuntimeSupport \
-ljava -ljvm, \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libosxui, \
))
TARGETS += $(BUILD_LIBOSXUI)
diff --git a/make/lib/CoreLibraries.gmk b/make/lib/CoreLibraries.gmk
index 72e5fe8a7e4..b54151d6d1e 100644
--- a/make/lib/CoreLibraries.gmk
+++ b/make/lib/CoreLibraries.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -55,8 +55,9 @@ LIBFDLIBM_SRC := $(TOPDIR)/src/java.base/share/native/libfdlibm
LIBFDLIBM_CFLAGS := -I$(LIBFDLIBM_SRC)
ifneq ($(OPENJDK_TARGET_OS), macosx)
- $(eval $(call SetupNativeCompilation,BUILD_LIBFDLIBM, \
- STATIC_LIBRARY := fdlibm, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBFDLIBM, \
+ NAME := fdlibm, \
+ TYPE := STATIC_LIBRARY, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE), \
SRC := $(LIBFDLIBM_SRC), \
OPTIMIZATION := $(BUILD_LIBFDLIBM_OPTIMIZATION), \
@@ -77,8 +78,8 @@ else
# On macosx the old build does partial (incremental) linking of fdlibm instead of
# a plain static library.
- $(eval $(call SetupNativeCompilation,BUILD_LIBFDLIBM_MAC, \
- LIBRARY := fdlibm, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBFDLIBM_MAC, \
+ NAME := fdlibm, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libfdlibm, \
SRC := $(LIBFDLIBM_SRC), \
CFLAGS := $(CFLAGS_JDKLIB) $(LIBFDLIBM_CFLAGS), \
@@ -107,9 +108,8 @@ ifneq ($(findstring $(OPENJDK_TARGET_OS), solaris linux), )
endif
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBVERIFY, \
- LIBRARY := verify, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+$(eval $(call SetupJdkLibrary, BUILD_LIBVERIFY, \
+ NAME := verify, \
SRC := $(TOPDIR)/src/java.base/share/native/libverify, \
OPTIMIZATION := $(LIBVERIFY_OPTIMIZATION), \
CFLAGS := $(CFLAGS_JDKLIB), \
@@ -118,15 +118,9 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBVERIFY, \
MAPFILE := $(TOPDIR)/make/mapfiles/libverify/mapfile-vers, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
- LIBS_unix := -ljvm -lc, \
+ LIBS_unix := -ljvm, \
LIBS_windows := jvm.lib, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=verify.dll" \
- -D "JDK_INTERNAL_NAME=verify" \
- -D "JDK_FTYPE=0x2L", \
REORDER := $(BUILD_LIBVERIFY_REORDER), \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libverify, \
))
TARGETS += $(BUILD_LIBVERIFY)
@@ -155,9 +149,8 @@ ifeq ($(OPENJDK_TARGET_OS), solaris)
endif
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBJAVA, \
- LIBRARY := java, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+$(eval $(call SetupJdkLibrary, BUILD_LIBJAVA, \
+ NAME := java, \
SRC := $(LIBJAVA_SRC_DIRS), \
OPTIMIZATION := HIGH, \
CFLAGS := $(CFLAGS_JDKLIB) \
@@ -176,7 +169,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJAVA, \
-export:getErrorString -delayload:shell32.dll, \
LIBS_unix := -ljvm -lverify, \
LIBS_linux := $(LIBDL) $(BUILD_LIBFDLIBM), \
- LIBS_solaris := -lsocket -lnsl -lscf $(LIBDL) $(BUILD_LIBFDLIBM) -lc, \
+ LIBS_solaris := -lsocket -lnsl -lscf $(LIBDL) $(BUILD_LIBFDLIBM), \
LIBS_aix := $(LIBDL) $(BUILD_LIBFDLIBM) $(LIBM),\
LIBS_macosx := -lfdlibm \
-framework CoreFoundation \
@@ -185,13 +178,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJAVA, \
LIBS_windows := jvm.lib $(BUILD_LIBFDLIBM) $(WIN_VERIFY_LIB) \
shell32.lib delayimp.lib \
advapi32.lib version.lib, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=java.dll" \
- -D "JDK_INTERNAL_NAME=java" \
- -D "JDK_FTYPE=0x2L", \
REORDER := $(LIBJAVA_REORDER), \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjava, \
))
TARGETS += $(BUILD_LIBJAVA)
@@ -218,9 +205,8 @@ ifeq ($(LIBZIP_CAN_USE_MMAP), true)
BUILD_LIBZIP_MMAP := -DUSE_MMAP
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBZIP, \
- LIBRARY := zip, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+$(eval $(call SetupJdkLibrary, BUILD_LIBZIP, \
+ NAME := zip, \
OPTIMIZATION := LOW, \
SRC := $(TOPDIR)/src/java.base/share/native/libzip, \
EXCLUDES := $(LIBZIP_EXCLUDES), \
@@ -239,14 +225,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBZIP, \
-export:ZIP_ReadEntry -export:ZIP_GetNextEntry \
-export:ZIP_InflateFully -export:ZIP_CRC32 -export:ZIP_FreeEntry, \
LIBS_unix := -ljvm -ljava $(LIBZ_LIBS), \
- LIBS_solaris := -lc, \
LIBS_windows := jvm.lib $(WIN_JAVA_LIB), \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=zip.dll" \
- -D "JDK_INTERNAL_NAME=zip" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libzip, \
))
$(BUILD_LIBZIP): $(BUILD_LIBJAVA)
@@ -262,10 +241,9 @@ JIMAGELIB_CPPFLAGS := \
-I$(SUPPORT_OUTPUTDIR)/headers/java.base \
#
-$(eval $(call SetupNativeCompilation,BUILD_LIBJIMAGE, \
- LIBRARY := jimage, \
+$(eval $(call SetupJdkLibrary, BUILD_LIBJIMAGE, \
+ NAME := jimage, \
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
OPTIMIZATION := LOW, \
SRC := $(TOPDIR)/src/java.base/share/native/libjimage \
$(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libjimage, \
@@ -282,15 +260,8 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJIMAGE, \
-export:JIMAGE_FindResource -export:JIMAGE_GetResource \
-export:JIMAGE_ResourceIterator -export:JIMAGE_ResourcePath, \
LIBS_unix := -ljvm -ldl $(LIBCXX), \
- LIBS_solaris := -lc, \
LIBS_macosx := -lc++, \
LIBS_windows := jvm.lib, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=jimage.dll" \
- -D "JDK_INTERNAL_NAME=jimage" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjimage, \
))
$(BUILD_LIBJIMAGE): $(BUILD_LIBJAVA)
@@ -358,8 +329,8 @@ ifneq ($(USE_EXTERNAL_LIBZ), true)
)
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBJLI, \
- LIBRARY := jli, \
+$(eval $(call SetupJdkLibrary, BUILD_LIBJLI, \
+ NAME := jli, \
OUTPUT_DIR := $(LIBJLI_OUTPUT_DIR), \
SRC := $(LIBJLI_SRC_DIRS), \
EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
@@ -396,17 +367,11 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJLI, \
-export:JLI_AddArgsFromEnvVar \
-export:JLI_GetAppArgIndex, \
LIBS_unix := $(LIBZ_LIBS), \
- LIBS_linux := $(LIBDL) -lc -lpthread, \
- LIBS_solaris := $(LIBDL) -lc, \
+ LIBS_linux := $(LIBDL) -lpthread, \
+ LIBS_solaris := $(LIBDL), \
LIBS_aix := $(LIBDL),\
LIBS_macosx := -framework Cocoa -framework Security -framework ApplicationServices, \
LIBS_windows := advapi32.lib comctl32.lib user32.lib, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=jli.dll" \
- -D "JDK_INTERNAL_NAME=jli" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjli, \
))
TARGETS += $(BUILD_LIBJLI)
@@ -415,8 +380,9 @@ TARGETS += $(BUILD_LIBJLI)
# with the shared library, so the static library is given a different name. No harm
# in doing it for all platform to reduce complexity.
ifeq ($(OPENJDK_TARGET_OS), windows)
- $(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC, \
- STATIC_LIBRARY := jli_static, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBJLI_STATIC, \
+ NAME := jli_static, \
+ TYPE := STATIC_LIBRARY, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE), \
SRC := $(LIBJLI_SRC_DIRS), \
EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
@@ -434,8 +400,8 @@ else ifeq ($(OPENJDK_TARGET_OS), macosx)
# On macosx they do partial (incremental) linking of libjli_static.a
# code it here...rather than add support to NativeCompilation
# as this is first time I see it
- $(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC, \
- LIBRARY := jli_static, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBJLI_STATIC, \
+ NAME := jli_static, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE), \
SRC := $(LIBJLI_SRC_DIRS), \
EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
@@ -457,8 +423,9 @@ else ifeq ($(OPENJDK_TARGET_OS), macosx)
else ifeq ($(OPENJDK_TARGET_OS), aix)
# AIX also requires a static libjli because the compiler doesn't support '-rpath'
- $(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC, \
- STATIC_LIBRARY := jli_static, \
+ $(eval $(call SetupNativeCompilation, BUILD_LIBJLI_STATIC, \
+ NAME := jli_static, \
+ TYPE := STATIC_LIBRARY, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE), \
SRC := $(LIBJLI_SRC_DIRS), \
EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
diff --git a/make/lib/Lib-java.base.gmk b/make/lib/Lib-java.base.gmk
index 37bb4d9da68..9e5f14b4886 100644
--- a/make/lib/Lib-java.base.gmk
+++ b/make/lib/Lib-java.base.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -33,10 +33,145 @@ LIB_java.base_SRC_DIRS += $(TOPDIR)/src/java.base/*/native
$(eval $(call FillCacheFind, $(wildcard $(LIB_java.base_SRC_DIRS))))
+################################################################################
+# Create all the core libraries
+
include CoreLibraries.gmk
-include NetworkingLibraries.gmk
-include NioLibraries.gmk
-include SecurityLibraries.gmk
+
+################################################################################
+# Create the network library
+
+LIBNET_SRC_DIRS := $(call FindSrcDirsForLib, java.base, net)
+
+$(eval $(call SetupJdkLibrary, BUILD_LIBNET, \
+ NAME := net, \
+ SRC := $(LIBNET_SRC_DIRS), \
+ OPTIMIZATION := LOW, \
+ CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/java.base \
+ $(LIBJAVA_HEADER_FLAGS) $(addprefix -I, $(LIBNET_SRC_DIRS)), \
+ DISABLED_WARNINGS_gcc := format-nonliteral, \
+ DISABLED_WARNINGS_clang := parentheses-equality constant-logical-operand, \
+ DISABLED_WARNINGS_microsoft := 4244 4047 4133 4996, \
+ DISABLED_WARNINGS_solstudio := E_ARG_INCOMPATIBLE_WITH_ARG_L, \
+ MAPFILE := $(TOPDIR)/make/mapfiles/libnet/mapfile-vers, \
+ LDFLAGS := $(LDFLAGS_JDKLIB) \
+ $(call SET_SHARED_LIBRARY_ORIGIN), \
+ LDFLAGS_windows := -delayload:secur32.dll -delayload:iphlpapi.dll, \
+ LIBS_unix := -ljvm -ljava, \
+ LIBS_linux := $(LIBDL) -lpthread, \
+ LIBS_solaris := -lnsl -lsocket $(LIBDL), \
+ LIBS_aix := $(LIBDL),\
+ LIBS_windows := ws2_32.lib jvm.lib secur32.lib iphlpapi.lib winhttp.lib \
+ delayimp.lib $(WIN_JAVA_LIB) advapi32.lib, \
+ LIBS_macosx := -framework CoreFoundation -framework CoreServices, \
+))
+
+$(BUILD_LIBNET): $(BUILD_LIBJAVA)
+
+TARGETS += $(BUILD_LIBNET)
+
+################################################################################
+# Create the nio library
+
+BUILD_LIBNIO_SRC := \
+ $(TOPDIR)/src/java.base/share/native/libnio \
+ $(TOPDIR)/src/java.base/share/native/libnio/ch \
+ $(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libnio \
+ $(sort $(wildcard \
+ $(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libnio/ch \
+ $(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libnio/fs \
+ $(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS)/native/libnio/ch \
+ $(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS)/native/libnio/fs)) \
+ #
+
+BUILD_LIBNIO_CFLAGS := \
+ $(addprefix -I, $(BUILD_LIBNIO_SRC)) \
+ -I$(SUPPORT_OUTPUTDIR)/headers/java.base \
+ $(LIBJAVA_HEADER_FLAGS) \
+ $(addprefix -I, $(BUILD_LIBNET_SRC))
+
+ifeq ($(OPENJDK_TARGET_OS), linux)
+ BUILD_LIBNIO_MAPFILE := $(TOPDIR)/make/mapfiles/libnio/mapfile-$(OPENJDK_TARGET_OS)
+endif
+
+ifeq ($(OPENJDK_TARGET_OS), macosx)
+ BUILD_LIBNIO_MAPFILE := $(TOPDIR)/make/mapfiles/libnio/mapfile-$(OPENJDK_TARGET_OS)
+endif
+
+ifeq ($(OPENJDK_TARGET_OS), solaris)
+ BUILD_LIBNIO_MAPFILE := $(TOPDIR)/make/mapfiles/libnio/mapfile-$(OPENJDK_TARGET_OS)
+endif
+
+ifeq ($(OPENJDK_TARGET_OS), aix)
+ BUILD_LIBNIO_MAPFILE := $(TOPDIR)/make/mapfiles/libnio/mapfile-$(OPENJDK_TARGET_OS)
+endif
+
+$(eval $(call SetupJdkLibrary, BUILD_LIBNIO, \
+ NAME := nio, \
+ SRC := $(BUILD_LIBNIO_SRC), \
+ EXCLUDE_FILES := $(BUILD_LIBNIO_EXFILES), \
+ OPTIMIZATION := HIGH, \
+ WARNINGS_AS_ERRORS_xlc := false, \
+ CFLAGS := $(CFLAGS_JDKLIB) \
+ $(BUILD_LIBNIO_CFLAGS), \
+ MAPFILE := $(BUILD_LIBNIO_MAPFILE), \
+ LDFLAGS := $(LDFLAGS_JDKLIB) \
+ $(call SET_SHARED_LIBRARY_ORIGIN), \
+ LIBS_unix := -ljava -lnet, \
+ LIBS_linux := -lpthread $(LIBDL), \
+ LIBS_solaris := -ljvm -lsocket -lposix4 $(LIBDL) \
+ -lsendfile, \
+ LIBS_aix := $(LIBDL), \
+ LIBS_macosx := \
+ -framework CoreFoundation -framework CoreServices, \
+ LIBS_windows := jvm.lib ws2_32.lib $(WIN_JAVA_LIB) \
+ $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libnet/net.lib \
+ advapi32.lib, \
+))
+
+TARGETS += $(BUILD_LIBNIO)
+
+$(BUILD_LIBNIO): $(BUILD_LIBNET)
+
+################################################################################
+# Create the macosx security library
+
+ifeq ($(OPENJDK_TARGET_OS), macosx)
+ # JavaNativeFoundation framework not supported in static builds
+ ifneq ($(STATIC_BUILD), true)
+
+ LIBOSXSECURITY_DIRS := $(TOPDIR)/src/java.base/macosx/native/libosxsecurity
+ LIBOSXSECURITY_CFLAGS := -I$(LIBOSXSECURITY_DIRS) \
+ $(LIBJAVA_HEADER_FLAGS) \
+ -I$(SUPPORT_OUTPUTDIR)/headers/java.base \
+
+ $(eval $(call SetupJdkLibrary, BUILD_LIBOSXSECURITY, \
+ NAME := osxsecurity, \
+ SRC := $(LIBOSXSECURITY_DIRS), \
+ OPTIMIZATION := LOW, \
+ CFLAGS := $(CFLAGS_JDKLIB) \
+ $(LIBOSXSECURITY_CFLAGS), \
+ DISABLED_WARNINGS_clang := deprecated-declarations, \
+ LDFLAGS := $(LDFLAGS_JDKLIB) \
+ -L$(SUPPORT_OUTPUTDIR)/modules_libs/java.base \
+ $(call SET_SHARED_LIBRARY_ORIGIN) \
+ -fobjc-link-runtime, \
+ LIBS := \
+ -framework JavaNativeFoundation \
+ -framework CoreServices \
+ -framework Security \
+ $(JDKLIB_LIBS), \
+ ))
+
+ $(BUILD_LIBOSXSECURITY): $(BUILD_LIBJAVA)
+
+ TARGETS += $(BUILD_LIBOSXSECURITY)
+
+ endif
+endif
+
+################################################################################
+# Create the symbols file for static builds.
ifeq ($(STATIC_BUILD), true)
JAVA_BASE_EXPORT_SYMBOLS_SRC := \
diff --git a/make/lib/Lib-java.desktop.gmk b/make/lib/Lib-java.desktop.gmk
index 2f193c1a48a..0c2dff4735a 100644
--- a/make/lib/Lib-java.desktop.gmk
+++ b/make/lib/Lib-java.desktop.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,79 @@ LIB_java.desktop_SRC_DIRS += $(TOPDIR)/src/java.desktop/*/native
$(eval $(call FillCacheFind, $(wildcard $(LIB_java.desktop_SRC_DIRS))))
-include LibosxLibraries.gmk
-include PlatformLibraries.gmk
+################################################################################
+# Create the AWT/2D and sound libraries
+
include Awt2dLibraries.gmk
include SoundLibraries.gmk
+
+################################################################################
+# Create the macosx specific osxapp and osx libraries
+
+ifeq ($(OPENJDK_TARGET_OS), macosx)
+ LIBOSXAPP_SRC := $(TOPDIR)/src/java.desktop/macosx/native/libosxapp
+
+ $(eval $(call SetupJdkLibrary, BUILD_LIBOSXAPP, \
+ NAME := osxapp, \
+ SRC := $(LIBOSXAPP_SRC), \
+ OPTIMIZATION := LOW, \
+ CFLAGS := $(CFLAGS_JDKLIB) \
+ $(addprefix -I, $(LIBOSXAPP_SRC)) \
+ -I$(SUPPORT_OUTPUTDIR)/headers/java.desktop, \
+ DISABLED_WARNINGS_clang := objc-method-access objc-root-class, \
+ LDFLAGS := $(LDFLAGS_JDKLIB) \
+ $(call SET_SHARED_LIBRARY_ORIGIN), \
+ LIBS := \
+ -framework Accelerate \
+ -framework ApplicationServices \
+ -framework AudioToolbox \
+ -framework Carbon \
+ -framework Cocoa \
+ -framework Security \
+ -framework ExceptionHandling \
+ -framework JavaNativeFoundation \
+ -framework JavaRuntimeSupport \
+ -framework OpenGL \
+ -framework IOSurface \
+ -framework QuartzCore, \
+ ))
+
+ TARGETS += $(BUILD_LIBOSXAPP)
+
+ ##############################################################################
+
+ LIBOSX_DIRS := $(TOPDIR)/src/java.desktop/macosx/native/libosx
+ LIBOSX_CFLAGS := -I$(LIBOSX_DIRS) \
+ -I$(TOPDIR)/src/java.desktop/macosx/native/libosxapp \
+ $(LIBJAVA_HEADER_FLAGS) \
+ -I$(SUPPORT_OUTPUTDIR)/headers/java.desktop \
+ #
+
+ $(eval $(call SetupJdkLibrary, BUILD_LIBOSX, \
+ NAME := osx, \
+ SRC := $(LIBOSX_DIRS), \
+ OPTIMIZATION := LOW, \
+ CFLAGS := $(CFLAGS_JDKLIB) \
+ $(LIBOSX_CFLAGS), \
+ DISABLED_WARNINGS_clang := deprecated-declarations, \
+ LDFLAGS := $(LDFLAGS_JDKLIB) \
+ -L$(SUPPORT_OUTPUTDIR)/modules_libs/java.desktop \
+ $(call SET_SHARED_LIBRARY_ORIGIN), \
+ LIBS := \
+ -losxapp \
+ -framework Cocoa \
+ -framework ApplicationServices \
+ -framework JavaNativeFoundation \
+ -framework JavaRuntimeSupport \
+ -framework SystemConfiguration \
+ $(JDKLIB_LIBS), \
+ ))
+
+ TARGETS += $(BUILD_LIBOSX)
+
+ $(BUILD_LIBOSX): $(call FindLib, java.desktop, osxapp)
+
+ $(BUILD_LIBOSX): $(call FindLib, java.base, java)
+
+endif
+
diff --git a/make/lib/Lib-java.instrument.gmk b/make/lib/Lib-java.instrument.gmk
index 51523c8855e..ed04de05e20 100644
--- a/make/lib/Lib-java.instrument.gmk
+++ b/make/lib/Lib-java.instrument.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -49,9 +49,8 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
LIBINSTRUMENT_CFLAGS += -Dstrcasecmp=stricmp
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBINSTRUMENT, \
- LIBRARY := instrument, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+$(eval $(call SetupJdkLibrary, BUILD_LIBINSTRUMENT, \
+ NAME := instrument, \
SRC := $(LIBINSTRUMENT_SRC), \
OPTIMIZATION := LOW, \
CFLAGS := $(LIBINSTRUMENT_CFLAGS), \
@@ -77,12 +76,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBINSTRUMENT, \
$(SUPPORT_OUTPUTDIR)/native/java.base/libjli_static.a, \
LIBS_windows := jvm.lib $(WIN_JAVA_LIB) advapi32.lib \
$(SUPPORT_OUTPUTDIR)/native/java.base/jli_static.lib, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=instrument.dll" \
- -D "JDK_INTERNAL_NAME=instrument" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libinstrument, \
))
ifneq (, $(findstring $(OPENJDK_TARGET_OS), macosx windows aix))
diff --git a/make/lib/Lib-java.management.gmk b/make/lib/Lib-java.management.gmk
index 84e37386ba3..fd9510e8c09 100644
--- a/make/lib/Lib-java.management.gmk
+++ b/make/lib/Lib-java.management.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -44,9 +44,8 @@ ifneq ($(findstring $(OPENJDK_TARGET_OS), solaris linux), )
endif
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBMANAGEMENT, \
- LIBRARY := management, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+$(eval $(call SetupJdkLibrary, BUILD_LIBMANAGEMENT, \
+ NAME := management, \
SRC := $(LIBMANAGEMENT_SRC), \
OPTIMIZATION := $(LIBMANAGEMENT_OPTIMIZATION), \
CFLAGS := $(CFLAGS_JDKLIB) $(LIBMANAGEMENT_CFLAGS), \
@@ -57,12 +56,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBMANAGEMENT, \
LIBS_solaris := -lkstat, \
LIBS_aix := -lperfstat,\
LIBS_windows := jvm.lib psapi.lib $(WIN_JAVA_LIB) advapi32.lib, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=management.dll" \
- -D "JDK_INTERNAL_NAME=management" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libmanagement, \
))
$(BUILD_LIBMANAGEMENT): $(call FindLib, java.base, java)
diff --git a/make/lib/Lib-java.prefs.gmk b/make/lib/Lib-java.prefs.gmk
index 358ccecd6ea..28872dba85e 100644
--- a/make/lib/Lib-java.prefs.gmk
+++ b/make/lib/Lib-java.prefs.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -33,9 +33,8 @@ else
LIBPREF_SRC_DIRS := $(TOPDIR)/src/java.prefs/$(OPENJDK_TARGET_OS_TYPE)/native/libprefs
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBPREFS, \
- LIBRARY := prefs, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+$(eval $(call SetupJdkLibrary, BUILD_LIBPREFS, \
+ NAME := prefs, \
SRC := $(LIBPREF_SRC_DIRS), \
OPTIMIZATION := HIGH, \
CFLAGS := $(CFLAGS_JDKLIB) $(addprefix -I, $(LIBPREF_SRC_DIRS)) \
@@ -45,16 +44,10 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBPREFS, \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LIBS_unix := -ljvm, \
LIBS_linux := -ljava, \
- LIBS_solaris := -ljava -lc, \
+ LIBS_solaris := -ljava, \
LIBS_aix := -ljava, \
LIBS_macosx := -framework CoreFoundation -framework Foundation, \
LIBS_windows := advapi32.lib jvm.lib $(WIN_JAVA_LIB), \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=prefs.dll" \
- -D "JDK_INTERNAL_NAME=prefs" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libprefs, \
))
$(BUILD_LIBPREFS): $(call FindLib, java.base, java)
diff --git a/make/lib/Lib-java.rmi.gmk b/make/lib/Lib-java.rmi.gmk
index 0e32650240c..1be2595819f 100644
--- a/make/lib/Lib-java.rmi.gmk
+++ b/make/lib/Lib-java.rmi.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -27,9 +27,8 @@ include LibCommon.gmk
################################################################################
-$(eval $(call SetupNativeCompilation,BUILD_LIBRMI, \
- LIBRARY := rmi, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+$(eval $(call SetupJdkLibrary, BUILD_LIBRMI, \
+ NAME := rmi, \
SRC := $(TOPDIR)/src/java.rmi/share/native/librmi, \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/java.rmi, \
@@ -38,12 +37,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBRMI, \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LIBS_unix := -ljvm, \
LIBS_windows := jvm.lib, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=rmi.dll" \
- -D "JDK_INTERNAL_NAME=rmi" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/librmi, \
))
$(BUILD_LIBRMI): $(call FindLib, java.base, java)
diff --git a/make/lib/Lib-java.security.jgss.gmk b/make/lib/Lib-java.security.jgss.gmk
index d56006df849..b0985a20040 100644
--- a/make/lib/Lib-java.security.jgss.gmk
+++ b/make/lib/Lib-java.security.jgss.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -32,9 +32,8 @@ ifneq ($(OPENJDK_TARGET_OS), windows)
$(TOPDIR)/src/java.security.jgss/$(OPENJDK_TARGET_OS_TYPE)/native/libj2gss \
#
- $(eval $(call SetupNativeCompilation,BUILD_LIBJ2GSS, \
- LIBRARY := j2gss, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ $(eval $(call SetupJdkLibrary, BUILD_LIBJ2GSS, \
+ NAME := j2gss, \
SRC := $(LIBJ2GSS_SRC), \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) $(addprefix -I, $(LIBJ2GSS_SRC)) \
@@ -44,8 +43,6 @@ ifneq ($(OPENJDK_TARGET_OS), windows)
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LIBS := $(LIBDL), \
- LIBS_solaris := -lc, \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libj2gss, \
))
TARGETS += $(BUILD_LIBJ2GSS)
@@ -54,47 +51,47 @@ endif
################################################################################
ifneq ($(BUILD_CRYPTO), false)
- BUILD_LIBKRB5_NAME :=
- ifeq ($(OPENJDK_TARGET_OS), windows)
- BUILD_LIBKRB5_NAME := w2k_lsa_auth
- BUILD_LIBKRB5_SRC := $(TOPDIR)/src/java.security.jgss/$(OPENJDK_TARGET_OS_TYPE)/native/libw2k_lsa_auth
- BUILD_LIBKRB5_LIBS := advapi32.lib Secur32.lib netapi32.lib kernel32.lib user32.lib \
- gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib \
- ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib
- else ifeq ($(OPENJDK_TARGET_OS), macosx)
- BUILD_LIBKRB5_NAME := osxkrb5
- BUILD_LIBKRB5_SRC := $(TOPDIR)/src/java.security.jgss/macosx/native/libosxkrb5
- BUILD_LIBKRB5_LIBS := \
- -framework JavaNativeFoundation \
- -framework Cocoa \
- -framework SystemConfiguration \
- -framework Kerberos
- endif
- ifneq ($(BUILD_LIBKRB5_NAME), )
- # libosxkrb5 needs to call deprecated krb5 APIs so that java
- # can use the native credentials cache.
- $(eval $(call SetupNativeCompilation,BUILD_LIBKRB5, \
- LIBRARY := $(BUILD_LIBKRB5_NAME), \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
- SRC := $(BUILD_LIBKRB5_SRC), \
+ ifeq ($(OPENJDK_TARGET_OS), windows)
+ BUILD_LIBW2K_LSA_AUTH_SRC := $(call FindSrcDirsForLib, $(MODULE), w2k_lsa_auth)
+
+ $(eval $(call SetupJdkLibrary, BUILD_LIBW2K_LSA_AUTH, \
+ NAME := w2k_lsa_auth, \
+ SRC := $(BUILD_LIBW2K_LSA_AUTH_SRC), \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) \
- $(addprefix -I, $(BUILD_LIBKRB5_SRC)) \
+ $(addprefix -I, $(BUILD_LIBW2K_LSA_AUTH_SRC)) \
+ -I$(SUPPORT_OUTPUTDIR)/headers/java.security.jgss, \
+ LDFLAGS := $(LDFLAGS_JDKLIB) \
+ $(call SET_SHARED_LIBRARY_ORIGIN), \
+ LIBS := advapi32.lib Secur32.lib netapi32.lib kernel32.lib user32.lib \
+ gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib \
+ ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib, \
+ ))
+
+ TARGETS += $(BUILD_LIBW2K_LSA_AUTH)
+ endif
+
+ ifeq ($(OPENJDK_TARGET_OS), macosx)
+ BUILD_LIBOSXKRB5_SRC := $(call FindSrcDirsForLib, $(MODULE), osxkrb5)
+
+ # libosxkrb5 needs to call deprecated krb5 APIs so that java
+ # can use the native credentials cache.
+ $(eval $(call SetupJdkLibrary, BUILD_LIBOSXKRB5, \
+ NAME := osxkrb5, \
+ SRC := $(BUILD_LIBOSXKRB5_SRC), \
+ OPTIMIZATION := LOW, \
+ CFLAGS := $(CFLAGS_JDKLIB) \
+ $(addprefix -I, $(BUILD_LIBOSXKRB5_SRC)) \
-I$(SUPPORT_OUTPUTDIR)/headers/java.security.jgss, \
DISABLED_WARNINGS_clang := deprecated-declarations, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
- LIBS := $(BUILD_LIBKRB5_LIBS), \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=$(BUILD_LIBKRB5_NAME).dll" \
- -D "JDK_INTERNAL_NAME=$(BUILD_LIBKRB5_NAME)" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libkrb5, \
+ LIBS := -framework JavaNativeFoundation -framework Cocoa \
+ -framework SystemConfiguration -framework Kerberos, \
))
- TARGETS += $(BUILD_LIBKRB5)
+ TARGETS += $(BUILD_LIBOSXKRB5)
endif
endif
diff --git a/make/lib/Lib-java.smartcardio.gmk b/make/lib/Lib-java.smartcardio.gmk
index a89046d2900..9bc419d7b5b 100644
--- a/make/lib/Lib-java.smartcardio.gmk
+++ b/make/lib/Lib-java.smartcardio.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -33,9 +33,8 @@ LIBJ2PCSC_CPPFLAGS := $(addprefix -I,$(LIBJ2PCSC_SRC)) \
-I$(TOPDIR)/src/java.smartcardio/$(OPENJDK_TARGET_OS_TYPE)/native/libj2pcsc/MUSCLE \
-I$(SUPPORT_OUTPUTDIR)/headers/java.smartcardio
-$(eval $(call SetupNativeCompilation,BUILD_LIBJ2PCSC, \
- LIBRARY := j2pcsc, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+$(eval $(call SetupJdkLibrary, BUILD_LIBJ2PCSC, \
+ NAME := j2pcsc, \
SRC := $(LIBJ2PCSC_SRC), \
CFLAGS_unix := -D__sun_jdk, \
OPTIMIZATION := LOW, \
@@ -44,14 +43,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJ2PCSC, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LIBS_unix := $(LIBDL), \
- LIBS_solaris := -lc, \
LIBS_windows := winscard.lib, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=j2pcsc.dll" \
- -D "JDK_INTERNAL_NAME=j2pcsc" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libj2pcsc, \
))
TARGETS += $(BUILD_LIBJ2PCSC)
diff --git a/make/lib/Lib-jdk.accessibility.gmk b/make/lib/Lib-jdk.accessibility.gmk
index 1ddcfdfa0a1..9e899e8a773 100644
--- a/make/lib/Lib-jdk.accessibility.gmk
+++ b/make/lib/Lib-jdk.accessibility.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -41,26 +41,20 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
# Parameter 1 Suffix
# Parameter 2 ACCESSBRIDGE_ARCH_ suffix
- $(call SetupNativeCompilation,BUILD_JAVAACCESSBRIDGE$1, \
- LIBRARY = javaaccessbridge$1, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ $(call SetupJdkLibrary, BUILD_JAVAACCESSBRIDGE$1, \
+ NAME := javaaccessbridge$1, \
SRC := $(JAVA_AB_SRCDIR), \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) $(ACCESSBRIDGE_CFLAGS) \
$(addprefix -I,$(JAVA_AB_SRCDIR)) \
-I$(ROOT_SRCDIR)/include/bridge \
-DACCESSBRIDGE_ARCH_$2, \
- LDFLAGS := $(LDFLAGS_JDKLIB) -subsystem:windows, \
+ LDFLAGS := $(LDFLAGS_JDKLIB), \
LIBS := kernel32.lib user32.lib gdi32.lib \
winspool.lib comdlg32.lib advapi32.lib shell32.lib \
$(SUPPORT_OUTPUTDIR)/native/java.desktop/libjawt/jawt.lib \
ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib, \
VERSIONINFO_RESOURCE := $(ROOT_SRCDIR)/common/AccessBridgeStatusWindow.rc, \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=javaaccessbridge$1.dll" \
- -D "JDK_INTERNAL_NAME=javaaccessbridge$1" \
- -D "JDK_FTYPE=0x02L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjavaaccessbridge$1, \
)
$$(BUILD_JAVAACCESSBRIDGE$1): $(SUPPORT_OUTPUTDIR)/native/java.desktop/libjawt/jawt.lib
@@ -71,26 +65,20 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
define SetupWinDLL
# Parameter 1 Suffix
# Parameter 2 ACCESSBRIDGE_ARCH_ suffix
- $(call SetupNativeCompilation,BUILD_WINDOWSACCESSBRIDGE$1, \
- LIBRARY = windowsaccessbridge$1, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ $(call SetupJdkLibrary, BUILD_WINDOWSACCESSBRIDGE$1, \
+ NAME := windowsaccessbridge$1, \
SRC := $(WIN_AB_SRCDIR), \
OPTIMIZATION := LOW, \
CFLAGS := $(filter-out -MD, $(CFLAGS_JDKLIB)) -MT $(ACCESSBRIDGE_CFLAGS) \
$(addprefix -I,$(WIN_AB_SRCDIR)) \
-I$(ROOT_SRCDIR)/include/bridge \
-DACCESSBRIDGE_ARCH_$2, \
- LDFLAGS := $(LDFLAGS_JDKLIB) -subsystem:windows \
+ LDFLAGS := $(LDFLAGS_JDKLIB) \
-def:$(ROOT_SRCDIR)/libwindowsaccessbridge/WinAccessBridge.DEF, \
LIBS := kernel32.lib user32.lib gdi32.lib \
winspool.lib comdlg32.lib advapi32.lib shell32.lib \
ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib, \
VERSIONINFO_RESOURCE := $(ROOT_SRCDIR)/common/AccessBridgeStatusWindow.rc, \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=windowsaccessbridge$1.dll" \
- -D "JDK_INTERNAL_NAME=windowsaccessbridge$1" \
- -D "JDK_FTYPE=0x02L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libwindowsaccessbridge$1, \
)
TARGETS += $$(BUILD_WINDOWSACCESSBRIDGE$1)
@@ -99,20 +87,13 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
define SetupAccessBridgeSysInfo
- $(call SetupNativeCompilation,BUILD_ACCESSBRIDGESYSINFO, \
- LIBRARY = jabsysinfo, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ $(call SetupJdkLibrary, BUILD_ACCESSBRIDGESYSINFO, \
+ NAME := jabsysinfo, \
SRC := $(SYSINFO_SRCDIR), \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) $(ACCESSBRIDGE_CFLAGS), \
- LDFLAGS := $(LDFLAGS_JDKLIB) \
- -subsystem:windows -machine:I386, \
+ LDFLAGS := $(LDFLAGS_JDKLIB), \
VERSIONINFO_RESOURCE := $(ROOT_SRCDIR)/common/AccessBridgeStatusWindow.rc, \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=jabsysinfo.dll" \
- -D "JDK_INTERNAL_NAME=jabsysinfo" \
- -D "JDK_FTYPE=0x02L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/lib/libjabsysinfo, \
)
TARGETS += $$(BUILD_ACCESSBRIDGESYSINFO)
diff --git a/make/lib/Lib-jdk.attach.gmk b/make/lib/Lib-jdk.attach.gmk
index b3fdb3b94c8..ccf1803656c 100644
--- a/make/lib/Lib-jdk.attach.gmk
+++ b/make/lib/Lib-jdk.attach.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -34,9 +34,8 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
LIBATTACH_CFLAGS := -DPSAPI_VERSION=1
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBATTACH, \
- LIBRARY := attach, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+$(eval $(call SetupJdkLibrary, BUILD_LIBATTACH, \
+ NAME := attach, \
SRC := $(call FindSrcDirsForLib, jdk.attach, attach), \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) \
@@ -44,18 +43,12 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBATTACH, \
$(LIBJAVA_HEADER_FLAGS) $(LIBATTACH_CFLAGS), \
CFLAGS_windows := /Gy, \
MAPFILE := $(TOPDIR)/make/mapfiles/libattach/mapfile-$(OPENJDK_TARGET_OS), \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=attach.dll" \
- -D "JDK_INTERNAL_NAME=attach" \
- -D "JDK_FTYPE=0x2L", \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LDFLAGS_windows := -order:@$(TOPDIR)/make/mapfiles/libattach/reorder-windows-$(OPENJDK_TARGET_CPU), \
LIBS := $(JDKLIB_LIBS), \
LIBS_solaris := -ldoor, \
LIBS_windows := $(WIN_JAVA_LIB) advapi32.lib psapi.lib, \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libattach, \
))
$(BUILD_LIBATTACH): $(call FindLib, java.base, java)
diff --git a/make/lib/Lib-jdk.crypto.cryptoki.gmk b/make/lib/Lib-jdk.crypto.cryptoki.gmk
index ff1467c18ee..5080a07ce21 100644
--- a/make/lib/Lib-jdk.crypto.cryptoki.gmk
+++ b/make/lib/Lib-jdk.crypto.cryptoki.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -30,9 +30,8 @@ include LibCommon.gmk
LIBJ2PKCS11_SRC := $(TOPDIR)/src/jdk.crypto.cryptoki/share/native/libj2pkcs11 \
$(TOPDIR)/src/jdk.crypto.cryptoki/$(OPENJDK_TARGET_OS_TYPE)/native/libj2pkcs11
-$(eval $(call SetupNativeCompilation,BUILD_LIBJ2PKCS11, \
- LIBRARY := j2pkcs11, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+$(eval $(call SetupJdkLibrary, BUILD_LIBJ2PKCS11, \
+ NAME := j2pkcs11, \
SRC := $(LIBJ2PKCS11_SRC), \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) $(addprefix -I, $(LIBJ2PKCS11_SRC)) \
@@ -42,13 +41,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJ2PKCS11, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LIBS_unix := $(LIBDL), \
- LIBS_solaris := -lc, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=j2pkcs11.dll" \
- -D "JDK_INTERNAL_NAME=j2pkcs11" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libj2pkcs11, \
))
TARGETS += $(BUILD_LIBJ2PKCS11)
diff --git a/make/lib/Lib-jdk.crypto.ec.gmk b/make/lib/Lib-jdk.crypto.ec.gmk
index 96323314f92..b220bd7b23f 100644
--- a/make/lib/Lib-jdk.crypto.ec.gmk
+++ b/make/lib/Lib-jdk.crypto.ec.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -43,9 +43,8 @@ ifeq ($(ENABLE_INTREE_EC), true)
ECC_JNI_SOLSPARC_FILTER := -xregs=no%appl
endif
- $(eval $(call SetupNativeCompilation,BUILD_LIBSUNEC, \
- LIBRARY := sunec, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ $(eval $(call SetupJdkLibrary, BUILD_LIBSUNEC, \
+ NAME := sunec, \
SRC := $(LIBSUNEC_SRC), \
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
OPTIMIZATION := LOW, \
@@ -60,14 +59,6 @@ ifeq ($(ENABLE_INTREE_EC), true)
LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK), \
LDFLAGS_macosx := $(call SET_SHARED_LIBRARY_ORIGIN), \
LIBS := $(LIBCXX), \
- LIBS_linux := -lc, \
- LIBS_solaris := -lc, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=sunec.dll" \
- -D "JDK_INTERNAL_NAME=sunec" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libsunec, \
))
TARGETS += $(BUILD_LIBSUNEC)
diff --git a/make/lib/Lib-jdk.crypto.mscapi.gmk b/make/lib/Lib-jdk.crypto.mscapi.gmk
index 76d105a1e3f..3bd4eb9e357 100644
--- a/make/lib/Lib-jdk.crypto.mscapi.gmk
+++ b/make/lib/Lib-jdk.crypto.mscapi.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -31,9 +31,8 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
LIBSUNMSCAPI_SRC := $(TOPDIR)/src/jdk.crypto.mscapi/$(OPENJDK_TARGET_OS_TYPE)/native/libsunmscapi
- $(eval $(call SetupNativeCompilation,BUILD_LIBSUNMSCAPI, \
- LIBRARY := sunmscapi, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ $(eval $(call SetupJdkLibrary, BUILD_LIBSUNMSCAPI, \
+ NAME := sunmscapi, \
SRC := $(LIBSUNMSCAPI_SRC), \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) \
@@ -41,12 +40,6 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LIBS := crypt32.lib advapi32.lib, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=sunmscapi.dll" \
- -D "JDK_INTERNAL_NAME=sunmscapi" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libsunmscapi, \
))
TARGETS += $(BUILD_LIBSUNMSCAPI)
diff --git a/make/lib/Lib-jdk.crypto.ucrypto.gmk b/make/lib/Lib-jdk.crypto.ucrypto.gmk
index 92c30759228..1b4be9d89e5 100644
--- a/make/lib/Lib-jdk.crypto.ucrypto.gmk
+++ b/make/lib/Lib-jdk.crypto.ucrypto.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -31,9 +31,8 @@ ifeq ($(OPENJDK_TARGET_OS), solaris)
LIBJ2UCRYPTO_SRC := $(TOPDIR)/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto
- $(eval $(call SetupNativeCompilation,BUILD_LIBJ2UCRYPTO, \
- LIBRARY := j2ucrypto, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ $(eval $(call SetupJdkLibrary, BUILD_LIBJ2UCRYPTO, \
+ NAME := j2ucrypto, \
SRC := $(LIBJ2UCRYPTO_SRC), \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) \
@@ -41,8 +40,6 @@ ifeq ($(OPENJDK_TARGET_OS), solaris)
MAPFILE := $(TOPDIR)/make/mapfiles/libj2ucrypto/mapfile-vers, \
LDFLAGS := $(LDFLAGS_JDKLIB), \
LIBS := $(LIBDL), \
- LIBS_solaris := -lc, \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libj2ucrypto, \
))
$(BUILD_LIBJ2UCRYPTO): $(BUILD_LIBJAVA)
diff --git a/make/lib/Lib-jdk.hotspot.agent.gmk b/make/lib/Lib-jdk.hotspot.agent.gmk
index 00dfda0c24e..cb662105915 100644
--- a/make/lib/Lib-jdk.hotspot.agent.gmk
+++ b/make/lib/Lib-jdk.hotspot.agent.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
# questions.
#
-include NativeCompilation.gmk
+include LibCommon.gmk
$(eval $(call IncludeCustomExtension, hotspot/lib/Lib-jdk.hotspot.agent.gmk))
@@ -46,73 +46,61 @@ SA_INCLUDES := \
-I$(TOPDIR)/src/hotspot/os/$(OPENJDK_TARGET_OS) \
#
-ifeq ($(OPENJDK_TARGET_CPU), x86_64)
- SA_MACHINE_FLAG_windows := -machine:AMD64
-else ifeq ($(OPENJDK_TARGET_CPU), x86)
- SA_MACHINE_FLAG_linux := -march=i586
- SA_MACHINE_FLAG_windows := -machine:I386
-endif
-
ifeq ($(OPENJDK_TARGET_OS), linux)
- SA_CFLAGS := $(CFLAGS_JDKLIB) -D_FILE_OFFSET_BITS=64 \
- $(SA_MACHINE_FLAG_linux)
- SA_LDFLAGS := $(LDFLAGS_JDKLIB) $(SA_MACHINE_FLAG_linux)
+ SA_CFLAGS := $(CFLAGS_JDKLIB) -D_FILE_OFFSET_BITS=64
+ ifeq ($(OPENJDK_TARGET_CPU), x86)
+ SA_LDFLAGS := -march=i586
+ endif
+
SA_LIBS := -lthread_db $(LIBDL)
else ifeq ($(OPENJDK_TARGET_OS), solaris)
SA_TOOLCHAIN := TOOLCHAIN_LINK_CXX
SA_CFLAGS := $(CFLAGS_JDKLIB)
SA_CXXFLAGS := $(CXXFLAGS_JDKLIB)
- SA_LDFLAGS := $(subst -Wl$(COMMA)-z$(COMMA)defs,, $(LDFLAGS_JDKLIB)) \
- -mt $(LDFLAGS_CXX_JDK)
- SA_LIBS := -ldl -ldemangle -lthread -lc
+ SA_LDFLAGS := -mt $(LDFLAGS_CXX_JDK)
+ SA_LIBS := -ldl -ldemangle -lthread -lproc
else ifeq ($(OPENJDK_TARGET_OS), macosx)
SA_EXCLUDE_FILES := BsdDebuggerLocal.c ps_proc.c salibelf.c StubDebuggerLocal.c
SA_CFLAGS := $(CFLAGS_JDKLIB) \
-Damd64 -D_GNU_SOURCE -mno-omit-leaf-frame-pointer \
-mstack-alignment=16 -fPIC
- SA_LDFLAGS := $(LDFLAGS_JDKLIB)
SA_LIBS := -framework Foundation -framework JavaNativeFoundation \
-framework JavaRuntimeSupport -framework Security -framework CoreFoundation
else ifeq ($(OPENJDK_TARGET_OS), windows)
SA_NAME := sawindbg
- COMMON_CFLAGS := -D_WINDOWS -D_DEBUG -D_CONSOLE -D_MBCS -EHsc -FD
+ COMMON_CFLAGS := -D_WINDOWS -D_DEBUG -D_CONSOLE -D_MBCS -EHsc
SA_CFLAGS := $(subst -DWIN32_LEAN_AND_MEAN,, $(CFLAGS_JDKLIB)) \
$(COMMON_CFLAGS)
SA_CXXFLAGS := $(subst -DWIN32_LEAN_AND_MEAN,, $(CXXFLAGS_JDKLIB)) \
$(COMMON_CFLAGS)
- SA_LDFLAGS := $(LDFLAGS_JDKLIB) \
- $(SA_MACHINE_FLAG_windows) -manifest \
- -subsystem:console -map
+ SA_LDFLAGS := -manifest
SA_LIBS := dbgeng.lib
ifeq ($(OPENJDK_TARGET_CPU), x86_64)
SA_CXXFLAGS += -DWIN64
else
SA_CXXFLAGS += -RTC1
- SA_LDFLAGS += -SAFESEH
endif
endif
################################################################################
-$(eval $(call SetupNativeCompilation, BUILD_LIBSA, \
+$(eval $(call SetupJdkLibrary, BUILD_LIBSA, \
+ NAME := $(SA_NAME), \
TOOLCHAIN := $(SA_TOOLCHAIN), \
OPTIMIZATION := NONE, \
DISABLED_WARNINGS_microsoft := 4267, \
DISABLED_WARNINGS_gcc := sign-compare, \
DISABLED_WARNINGS_CXX_solstudio := truncwarn unknownpragma, \
- LIBRARY := $(SA_NAME), \
- OUTPUT_DIR := $(call FindLibDirForModule, $(MODULE)), \
SRC := $(SA_SRC), \
EXCLUDE_FILES := test.c saproc_audit.cpp $(SA_EXCLUDE_FILES), \
CFLAGS := $(SA_INCLUDES) $(SA_CFLAGS) $(SA_CUSTOM_CFLAGS), \
CXXFLAGS := $(SA_INCLUDES) $(SA_CXXFLAGS) $(SA_CUSTOM_CXXFLAGS), \
- LDFLAGS := $(SA_LDFLAGS) $(SA_CUSTOM_LDFLAGS), \
+ LDFLAGS := $(LDFLAGS_JDKLIB) $(SA_LDFLAGS), \
LIBS := $(SA_LIBS), \
MAPFILE := $(SA_MAPFILE), \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libsa, \
))
TARGETS += $(BUILD_LIBSA)
diff --git a/make/lib/Lib-jdk.internal.le.gmk b/make/lib/Lib-jdk.internal.le.gmk
index 8b2d37127b5..62f69bcadd3 100644
--- a/make/lib/Lib-jdk.internal.le.gmk
+++ b/make/lib/Lib-jdk.internal.le.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -36,21 +36,14 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
-I$(SUPPORT_OUTPUTDIR)/headers/jdk.internal.le \
#
- $(eval $(call SetupNativeCompilation,BUILD_LIBLE, \
- LIBRARY := le, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ $(eval $(call SetupJdkLibrary, BUILD_LIBLE, \
+ NAME := le, \
SRC := $(LIBLE_SRC), \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) $(LIBJAVA_HEADER_FLAGS)\
$(LIBLE_CPPFLAGS), \
LDFLAGS := $(LDFLAGS_JDKLIB), \
LIBS := $(JDKLIB_LIBS) user32.lib, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=le.dll" \
- -D "JDK_INTERNAL_NAME=le" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/lible, \
))
TARGETS += $(BUILD_LIBLE)
diff --git a/make/lib/Lib-jdk.jdi.gmk b/make/lib/Lib-jdk.jdi.gmk
index 1b7b83fa7fc..21573ae8c05 100644
--- a/make/lib/Lib-jdk.jdi.gmk
+++ b/make/lib/Lib-jdk.jdi.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -39,9 +39,8 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
-I$(SUPPORT_OUTPUTDIR)/headers/jdk.jdi \
#
- $(eval $(call SetupNativeCompilation,BUILD_LIBDT_SHMEM, \
- LIBRARY := dt_shmem, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ $(eval $(call SetupJdkLibrary, BUILD_LIBDT_SHMEM, \
+ NAME := dt_shmem, \
SRC := $(LIBDT_SHMEM_SRC), \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) -DUSE_MMAP \
@@ -49,12 +48,6 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
LDFLAGS := $(LDFLAGS_JDKLIB), \
LDFLAGS_windows := -export:jdwpTransport_OnLoad, \
LIBS := $(JDKLIB_LIBS), \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=dt_shmem.dll" \
- -D "JDK_INTERNAL_NAME=dt_shmem" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libdt_shmem, \
))
TARGETS += $(BUILD_LIBDT_SHMEM)
diff --git a/make/lib/Lib-jdk.jdwp.agent.gmk b/make/lib/Lib-jdk.jdwp.agent.gmk
index f86000cd720..10e3c393ed9 100644
--- a/make/lib/Lib-jdk.jdwp.agent.gmk
+++ b/make/lib/Lib-jdk.jdwp.agent.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -36,27 +36,19 @@ LIBDT_SOCKET_CPPFLAGS := \
-I$(TOPDIR)/src/jdk.jdwp.agent/share/native/include \
#
-$(eval $(call SetupNativeCompilation,BUILD_LIBDT_SOCKET, \
- LIBRARY := dt_socket, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+$(eval $(call SetupJdkLibrary, BUILD_LIBDT_SOCKET, \
+ NAME := dt_socket, \
SRC := $(LIBDT_SOCKET_SRC), \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) -DUSE_MMAP \
$(LIBDT_SOCKET_CPPFLAGS), \
- DISABLED_WARNINGS_gcc := shift-negative-value, \
MAPFILE := $(TOPDIR)/make/mapfiles/libdt_socket/mapfile-vers, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LDFLAGS_windows := -export:jdwpTransport_OnLoad, \
LIBS_linux := -lpthread, \
- LIBS_solaris := -lnsl -lsocket -lc, \
+ LIBS_solaris := -lnsl -lsocket, \
LIBS_windows := $(JDKLIB_LIBS) ws2_32.lib, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=dt_socket.dll" \
- -D "JDK_INTERNAL_NAME=dt_socket" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libdt_socket, \
))
$(BUILD_LIBDT_SOCKET): $(call FindLib, java.base, java)
@@ -74,9 +66,8 @@ LIBJDWP_CPPFLAGS := \
$(addprefix -I, $(LIBJDWP_SRC))
# JDWP_LOGGING causes log messages to be compiled into the library.
-$(eval $(call SetupNativeCompilation,BUILD_LIBJDWP, \
- LIBRARY := jdwp, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+$(eval $(call SetupJdkLibrary, BUILD_LIBJDWP, \
+ NAME := jdwp, \
SRC := $(LIBJDWP_SRC), \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) -DJDWP_LOGGING \
@@ -90,12 +81,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJDWP, \
LIBS_solaris := $(LIBDL), \
LIBS_macosx := -liconv, \
LIBS_aix := -liconv, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=jdwp.dll" \
- -D "JDK_INTERNAL_NAME=jdwp" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjdwp, \
))
$(BUILD_LIBJDWP): $(call FindLib, java.base, java)
diff --git a/make/lib/Lib-jdk.management.agent.gmk b/make/lib/Lib-jdk.management.agent.gmk
index 630163c3471..4c3237c7041 100644
--- a/make/lib/Lib-jdk.management.agent.gmk
+++ b/make/lib/Lib-jdk.management.agent.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -33,9 +33,8 @@ LIBMANAGEMENT_AGENT_CFLAGS := $(addprefix -I,$(LIBMANAGEMENT_AGENT_SRC)) \
$(LIBJAVA_HEADER_FLAGS) \
#
-$(eval $(call SetupNativeCompilation,BUILD_LIBMANAGEMENT_AGENT, \
- LIBRARY := management_agent, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+$(eval $(call SetupJdkLibrary, BUILD_LIBMANAGEMENT_AGENT, \
+ NAME := management_agent, \
SRC := $(LIBMANAGEMENT_AGENT_SRC), \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) $(LIBMANAGEMENT_AGENT_CFLAGS), \
@@ -44,12 +43,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBMANAGEMENT_AGENT, \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LIBS := $(JDKLIB_LIBS), \
LIBS_windows := $(WIN_JAVA_LIB) advapi32.lib, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=management_agent.dll" \
- -D "JDK_INTERNAL_NAME=management_agent" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libmanagement_agent, \
))
$(BUILD_LIBMANAGEMENT_AGENT): $(call FindLib, java.base, java)
diff --git a/make/lib/Lib-jdk.management.gmk b/make/lib/Lib-jdk.management.gmk
index 6bb92b1c796..d5ce0ece009 100644
--- a/make/lib/Lib-jdk.management.gmk
+++ b/make/lib/Lib-jdk.management.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -53,9 +53,8 @@ ifneq ($(findstring $(OPENJDK_TARGET_OS), solaris linux), )
endif
endif
-$(eval $(call SetupNativeCompilation,BUILD_LIBMANAGEMENT_EXT, \
- LIBRARY := management_ext, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+$(eval $(call SetupJdkLibrary, BUILD_LIBMANAGEMENT_EXT, \
+ NAME := management_ext, \
SRC := $(LIBMANAGEMENT_EXT_SRC), \
LANG := C, \
OPTIMIZATION := $(LIBMANAGEMENT_EXT_OPTIMIZATION), \
@@ -67,12 +66,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBMANAGEMENT_EXT, \
LIBS_solaris := -lkstat, \
LIBS_aix := -lperfstat,\
LIBS_windows := jvm.lib psapi.lib $(WIN_JAVA_LIB) advapi32.lib, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=management_ext.dll" \
- -D "JDK_INTERNAL_NAME=management_ext" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libmanagement_ext, \
))
$(BUILD_LIBMANAGEMENT_EXT): $(call FindLib, java.base, java)
diff --git a/make/lib/Lib-jdk.net.gmk b/make/lib/Lib-jdk.net.gmk
index d1e35e82d4d..c146e5d2216 100644
--- a/make/lib/Lib-jdk.net.gmk
+++ b/make/lib/Lib-jdk.net.gmk
@@ -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
@@ -27,19 +27,19 @@ include LibCommon.gmk
################################################################################
-ifeq ($(OPENJDK_TARGET_OS), solaris)
+ifneq ($(filter $(OPENJDK_TARGET_OS), solaris linux), )
- $(eval $(call SetupNativeCompilation, BUILD_LIBEXTNET, \
- LIBRARY := extnet, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
- SRC := $(TOPDIR)/src/jdk.net/solaris/native/libextnet, \
+ $(eval $(call SetupJdkLibrary, BUILD_LIBEXTNET, \
+ NAME := extnet, \
+ SRC := $(TOPDIR)/src/jdk.net/$(OPENJDK_TARGET_OS)/native/libextnet, \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/jdk.net, \
- MAPFILE := $(TOPDIR)/make/mapfiles/libextnet/mapfile-solaris, \
+ MAPFILE := $(TOPDIR)/make/mapfiles/libextnet/mapfile-$(OPENJDK_TARGET_OS), \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
- LIBS := -lsocket -lc -ljava, \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libextnet, \
+ LIBS := -ljava, \
+ LIBS_solaris := -lsocket, \
+ LIBS_linux := -ljvm, \
))
$(BUILD_LIBEXTNET): $(call FindLib, java.base, java)
@@ -47,26 +47,4 @@ ifeq ($(OPENJDK_TARGET_OS), solaris)
TARGETS += $(BUILD_LIBEXTNET)
endif
-
-ifeq ($(OPENJDK_TARGET_OS), linux)
-
- $(eval $(call SetupNativeCompilation, BUILD_LIBEXTNET, \
- LIBRARY := extnet, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
- SRC := $(TOPDIR)/src/jdk.net/linux/native/libextnet, \
- OPTIMIZATION := LOW, \
- CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/jdk.net, \
- MAPFILE := $(TOPDIR)/make/mapfiles/libextnet/mapfile-linux, \
- LDFLAGS := $(LDFLAGS_JDKLIB) \
- $(call SET_SHARED_LIBRARY_ORIGIN), \
- LIBS := -ljvm -ljava -lc, \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libextnet, \
- ))
-
- $(BUILD_LIBEXTNET): $(call FindLib, java.base, java)
-
- TARGETS += $(BUILD_LIBEXTNET)
-endif
-
-
################################################################################
diff --git a/make/lib/Lib-jdk.pack.gmk b/make/lib/Lib-jdk.pack.gmk
index 3bbc3a4537a..036faac48ec 100644
--- a/make/lib/Lib-jdk.pack.gmk
+++ b/make/lib/Lib-jdk.pack.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -27,9 +27,8 @@ include LibCommon.gmk
################################################################################
-$(eval $(call SetupNativeCompilation,BUILD_LIBUNPACK, \
- LIBRARY := unpack, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+$(eval $(call SetupJdkLibrary, BUILD_LIBUNPACK, \
+ NAME := unpack, \
SRC := $(TOPDIR)/src/jdk.pack/share/native/libunpack \
$(TOPDIR)/src/jdk.pack/share/native/common-unpack, \
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
@@ -45,14 +44,8 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBUNPACK, \
LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LDFLAGS_windows := -map:$(SUPPORT_OUTPUTDIR)/native/$(MODULE)/unpack.map -debug, \
- LIBS_unix := -ljvm $(LIBCXX) -ljava -lc, \
+ LIBS_unix := -ljvm $(LIBCXX) -ljava, \
LIBS_windows := jvm.lib $(WIN_JAVA_LIB), \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libunpack, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=unpack.dll" \
- -D "JDK_INTERNAL_NAME=unpack" \
- -D "JDK_FTYPE=0x2L", \
))
$(BUILD_LIBUNPACK): $(call FindLib, java.base, java)
diff --git a/make/lib/Lib-jdk.sctp.gmk b/make/lib/Lib-jdk.sctp.gmk
index d40d70e2ccc..72c15bb7ae9 100644
--- a/make/lib/Lib-jdk.sctp.gmk
+++ b/make/lib/Lib-jdk.sctp.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -30,9 +30,8 @@ include LibCommon.gmk
ifeq ($(OPENJDK_TARGET_OS_TYPE), unix)
ifeq (, $(filter $(OPENJDK_TARGET_OS), macosx aix))
- $(eval $(call SetupNativeCompilation,BUILD_LIBSCTP, \
- LIBRARY := sctp, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ $(eval $(call SetupJdkLibrary, BUILD_LIBSCTP, \
+ NAME := sctp, \
SRC := $(TOPDIR)/src/jdk.sctp/$(OPENJDK_TARGET_OS_TYPE)/native/libsctp, \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) \
@@ -47,8 +46,7 @@ ifeq ($(OPENJDK_TARGET_OS_TYPE), unix)
$(call SET_SHARED_LIBRARY_ORIGIN), \
LIBS_unix := -lnio -lnet -ljava -ljvm, \
LIBS_linux := -lpthread $(LIBDL), \
- LIBS_solaris := -lsocket -lc, \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libsctp, \
+ LIBS_solaris := -lsocket, \
))
TARGETS += $(BUILD_LIBSCTP)
diff --git a/make/lib/Lib-jdk.security.auth.gmk b/make/lib/Lib-jdk.security.auth.gmk
index 996cf9a6f6d..130ae3d9410 100644
--- a/make/lib/Lib-jdk.security.auth.gmk
+++ b/make/lib/Lib-jdk.security.auth.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -33,28 +33,15 @@ ifeq ($(OPENJDK_TARGET_OS), solaris)
LIBJAAS_MAPFILE := $(TOPDIR)/make/mapfiles/libjaas/mapfile-vers
endif
-LIBJAAS_NAME := jaas_unix
-ifeq ($(OPENJDK_TARGET_OS), windows)
- LIBJAAS_NAME := jaas_nt
-endif
-
-$(eval $(call SetupNativeCompilation,BUILD_LIBJAAS, \
- LIBRARY := $(LIBJAAS_NAME), \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+$(eval $(call SetupJdkLibrary, BUILD_LIBJAAS, \
+ NAME := jaas, \
SRC := $(call FindSrcDirsForLib, jdk.security.auth, jaas), \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/jdk.security.auth, \
MAPFILE := $(LIBJAAS_MAPFILE), \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
- LIBS_solaris := -lc, \
LIBS_windows := netapi32.lib user32.lib mpr.lib advapi32.lib $(JDKLIB_LIBS), \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=$(LIBJAAS_NAME).dll" \
- -D "JDK_INTERNAL_NAME=$(LIBJAAS_NAME)" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjaas, \
))
$(BUILD_LIBJAAS): $(call FindLib, java.base, java)
diff --git a/make/lib/LibCommon.gmk b/make/lib/LibCommon.gmk
index 0c329d1b858..a40be6e5602 100644
--- a/make/lib/LibCommon.gmk
+++ b/make/lib/LibCommon.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
# questions.
#
-include NativeCompilation.gmk
+include JdkNativeCompilation.gmk
# Hook to include the corresponding custom file, if present.
$(eval $(call IncludeCustomExtension, lib/LibCommon.gmk))
@@ -32,7 +32,7 @@ $(eval $(call IncludeCustomExtension, lib/LibCommon.gmk))
GLOBAL_VERSION_INFO_RESOURCE := $(TOPDIR)/src/java.base/windows/native/common/version.rc
-# Absolute paths to lib files on windows for use in LDFLAGS. Should figure out a more
+# Absolute paths to lib files on windows for use in LIBS. Should figure out a more
# elegant solution to this.
WIN_JAVA_LIB := $(SUPPORT_OUTPUTDIR)/native/java.base/libjava/java.lib
diff --git a/make/lib/LibosxLibraries.gmk b/make/lib/LibosxLibraries.gmk
deleted file mode 100644
index d7a99ab9059..00000000000
--- a/make/lib/LibosxLibraries.gmk
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# Copyright (c) 2011, 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.
-#
-
-ifeq ($(OPENJDK_TARGET_OS), macosx)
-
- ################################################################################
-
- LIBOSX_DIRS := $(TOPDIR)/src/java.desktop/macosx/native/libosx
- LIBOSX_CFLAGS := -I$(LIBOSX_DIRS) \
- -I$(TOPDIR)/src/java.desktop/macosx/native/libosxapp \
- $(LIBJAVA_HEADER_FLAGS) \
- -I$(SUPPORT_OUTPUTDIR)/headers/java.desktop \
- #
-
- $(eval $(call SetupNativeCompilation,BUILD_LIBOSX, \
- LIBRARY := osx, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
- SRC := $(LIBOSX_DIRS), \
- OPTIMIZATION := LOW, \
- CFLAGS := $(CFLAGS_JDKLIB) \
- $(LIBOSX_CFLAGS), \
- DISABLED_WARNINGS_clang := deprecated-declarations, \
- LDFLAGS := $(LDFLAGS_JDKLIB) \
- -L$(SUPPORT_OUTPUTDIR)/modules_libs/java.desktop \
- $(call SET_SHARED_LIBRARY_ORIGIN), \
- LIBS := \
- -losxapp \
- -framework Cocoa \
- -framework ApplicationServices \
- -framework JavaNativeFoundation \
- -framework JavaRuntimeSupport \
- -framework SystemConfiguration \
- $(JDKLIB_LIBS), \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libosx, \
- ))
-
- TARGETS += $(BUILD_LIBOSX)
-
- $(BUILD_LIBOSX): $(call FindLib, java.desktop, osxapp)
-
- $(BUILD_LIBOSX): $(call FindLib, java.base, java)
-
- ################################################################################
-
-endif
diff --git a/make/lib/NetworkingLibraries.gmk b/make/lib/NetworkingLibraries.gmk
deleted file mode 100644
index fbfecde36ea..00000000000
--- a/make/lib/NetworkingLibraries.gmk
+++ /dev/null
@@ -1,60 +0,0 @@
-#
-# Copyright (c) 2011, 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.
-#
-
-LIBNET_SRC_DIRS := $(call FindSrcDirsForLib, java.base, net)
-
-$(eval $(call SetupNativeCompilation,BUILD_LIBNET, \
- LIBRARY := net, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
- SRC := $(LIBNET_SRC_DIRS), \
- OPTIMIZATION := LOW, \
- CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/java.base \
- $(LIBJAVA_HEADER_FLAGS) $(addprefix -I, $(LIBNET_SRC_DIRS)), \
- DISABLED_WARNINGS_gcc := format-nonliteral, \
- DISABLED_WARNINGS_clang := parentheses-equality constant-logical-operand, \
- DISABLED_WARNINGS_microsoft := 4244 4047 4133 4996, \
- DISABLED_WARNINGS_solstudio := E_ARG_INCOMPATIBLE_WITH_ARG_L, \
- MAPFILE := $(TOPDIR)/make/mapfiles/libnet/mapfile-vers, \
- LDFLAGS := $(LDFLAGS_JDKLIB) \
- $(call SET_SHARED_LIBRARY_ORIGIN), \
- LDFLAGS_windows := -delayload:secur32.dll -delayload:iphlpapi.dll, \
- LIBS_unix := -ljvm -ljava, \
- LIBS_linux := $(LIBDL) -lpthread, \
- LIBS_solaris := -lnsl -lsocket $(LIBDL) -lc, \
- LIBS_aix := $(LIBDL),\
- LIBS_windows := ws2_32.lib jvm.lib secur32.lib iphlpapi.lib winhttp.lib \
- delayimp.lib $(WIN_JAVA_LIB) advapi32.lib, \
- LIBS_macosx := -framework CoreFoundation -framework CoreServices, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=net.dll" \
- -D "JDK_INTERNAL_NAME=net" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libnet, \
-))
-
-$(BUILD_LIBNET): $(BUILD_LIBJAVA)
-
-TARGETS += $(BUILD_LIBNET)
diff --git a/make/lib/NioLibraries.gmk b/make/lib/NioLibraries.gmk
deleted file mode 100644
index 2d298dd13c6..00000000000
--- a/make/lib/NioLibraries.gmk
+++ /dev/null
@@ -1,91 +0,0 @@
-#
-# Copyright (c) 2011, 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.
-#
-
-BUILD_LIBNIO_SRC := \
- $(TOPDIR)/src/java.base/share/native/libnio \
- $(TOPDIR)/src/java.base/share/native/libnio/ch \
- $(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libnio \
- $(sort $(wildcard \
- $(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libnio/ch \
- $(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libnio/fs \
- $(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS)/native/libnio/ch \
- $(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS)/native/libnio/fs)) \
- #
-
-BUILD_LIBNIO_CFLAGS := \
- $(addprefix -I, $(BUILD_LIBNIO_SRC)) \
- -I$(SUPPORT_OUTPUTDIR)/headers/java.base \
- $(LIBJAVA_HEADER_FLAGS) \
- $(addprefix -I, $(BUILD_LIBNET_SRC))
-
-ifeq ($(OPENJDK_TARGET_OS), linux)
- BUILD_LIBNIO_MAPFILE := $(TOPDIR)/make/mapfiles/libnio/mapfile-$(OPENJDK_TARGET_OS)
-endif
-
-ifeq ($(OPENJDK_TARGET_OS), macosx)
- BUILD_LIBNIO_MAPFILE := $(TOPDIR)/make/mapfiles/libnio/mapfile-$(OPENJDK_TARGET_OS)
-endif
-
-ifeq ($(OPENJDK_TARGET_OS), solaris)
- BUILD_LIBNIO_MAPFILE := $(TOPDIR)/make/mapfiles/libnio/mapfile-$(OPENJDK_TARGET_OS)
-endif
-
-ifeq ($(OPENJDK_TARGET_OS), aix)
- BUILD_LIBNIO_MAPFILE := $(TOPDIR)/make/mapfiles/libnio/mapfile-$(OPENJDK_TARGET_OS)
-endif
-
-$(eval $(call SetupNativeCompilation,BUILD_LIBNIO, \
- LIBRARY := nio, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
- SRC := $(BUILD_LIBNIO_SRC), \
- EXCLUDE_FILES := $(BUILD_LIBNIO_EXFILES), \
- OPTIMIZATION := HIGH, \
- WARNINGS_AS_ERRORS_xlc := false, \
- CFLAGS := $(CFLAGS_JDKLIB) \
- $(BUILD_LIBNIO_CFLAGS), \
- MAPFILE := $(BUILD_LIBNIO_MAPFILE), \
- LDFLAGS := $(LDFLAGS_JDKLIB) \
- $(call SET_SHARED_LIBRARY_ORIGIN), \
- LIBS_unix := -ljava -lnet, \
- LIBS_linux := -lpthread $(LIBDL), \
- LIBS_solaris := -ljvm -lsocket -lposix4 $(LIBDL) \
- -lsendfile -lc, \
- LIBS_aix := $(LIBDL), \
- LIBS_macosx := \
- -framework CoreFoundation -framework CoreServices, \
- LIBS_windows := jvm.lib ws2_32.lib $(WIN_JAVA_LIB) \
- $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libnet/net.lib \
- advapi32.lib, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=nio.dll" \
- -D "JDK_INTERNAL_NAME=nio" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libnio, \
-))
-
-TARGETS += $(BUILD_LIBNIO)
-
-$(BUILD_LIBNIO): $(BUILD_LIBNET)
diff --git a/make/lib/PlatformLibraries.gmk b/make/lib/PlatformLibraries.gmk
deleted file mode 100644
index 0cba6a3a643..00000000000
--- a/make/lib/PlatformLibraries.gmk
+++ /dev/null
@@ -1,61 +0,0 @@
-#
-# Copyright (c) 2011, 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.
-#
-
-################################################################################
-
-ifeq ($(OPENJDK_TARGET_OS), macosx)
-
- LIBOSXAPP_SRC := $(TOPDIR)/src/java.desktop/macosx/native/libosxapp
-
- $(eval $(call SetupNativeCompilation,BUILD_LIBOSXAPP, \
- LIBRARY := osxapp, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
- SRC := $(LIBOSXAPP_SRC), \
- OPTIMIZATION := LOW, \
- CFLAGS := $(CFLAGS_JDKLIB) \
- $(addprefix -I, $(LIBOSXAPP_SRC)) \
- -I$(SUPPORT_OUTPUTDIR)/headers/java.desktop, \
- DISABLED_WARNINGS_clang := objc-method-access objc-root-class, \
- LDFLAGS := $(LDFLAGS_JDKLIB) \
- $(call SET_SHARED_LIBRARY_ORIGIN), \
- LIBS := \
- -framework Accelerate \
- -framework ApplicationServices \
- -framework AudioToolbox \
- -framework Carbon \
- -framework Cocoa \
- -framework Security \
- -framework ExceptionHandling \
- -framework JavaNativeFoundation \
- -framework JavaRuntimeSupport \
- -framework OpenGL \
- -framework IOSurface \
- -framework QuartzCore, \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libosxapp, \
- ))
-
- TARGETS += $(BUILD_LIBOSXAPP)
-
-endif
diff --git a/make/lib/SecurityLibraries.gmk b/make/lib/SecurityLibraries.gmk
deleted file mode 100644
index 4d96461d8b3..00000000000
--- a/make/lib/SecurityLibraries.gmk
+++ /dev/null
@@ -1,66 +0,0 @@
-#
-# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation. 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.
-#
-
-include LibCommon.gmk
-
-ifeq ($(OPENJDK_TARGET_OS), macosx)
- # JavaNativeFoundation framework not supported in static builds
- ifneq ($(STATIC_BUILD), true)
-
- ################################################################################
-
- LIBOSXSECURITY_DIRS := $(TOPDIR)/src/java.base/macosx/native/libosxsecurity
- LIBOSXSECURITY_CFLAGS := -I$(LIBOSXSECURITY_DIRS) \
- $(LIBJAVA_HEADER_FLAGS) \
- -I$(SUPPORT_OUTPUTDIR)/headers/java.base \
-
- $(eval $(call SetupNativeCompilation,BUILD_LIBOSXSECURITY, \
- LIBRARY := osxsecurity, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
- SRC := $(LIBOSXSECURITY_DIRS), \
- OPTIMIZATION := LOW, \
- CFLAGS := $(CFLAGS_JDKLIB) \
- $(LIBOSXSECURITY_CFLAGS), \
- DISABLED_WARNINGS_clang := deprecated-declarations, \
- LDFLAGS := $(LDFLAGS_JDKLIB) \
- -L$(SUPPORT_OUTPUTDIR)/modules_libs/java.base \
- $(call SET_SHARED_LIBRARY_ORIGIN) \
- -fobjc-link-runtime, \
- LIBS := \
- -framework JavaNativeFoundation \
- -framework CoreServices \
- -framework Security \
- $(JDKLIB_LIBS), \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libosxsecurity, \
- ))
-
- $(BUILD_LIBOSXSECURITY): $(BUILD_LIBJAVA)
-
- TARGETS += $(BUILD_LIBOSXSECURITY)
-
- ################################################################################
-
- endif
-endif
diff --git a/make/lib/SoundLibraries.gmk b/make/lib/SoundLibraries.gmk
index 2174476e92b..98f25f24edd 100644
--- a/make/lib/SoundLibraries.gmk
+++ b/make/lib/SoundLibraries.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -114,9 +114,8 @@ endif # OPENJDK_TARGET_OS solaris
LIBJSOUND_CFLAGS += -DEXTRA_SOUND_JNI_LIBS='"$(EXTRA_SOUND_JNI_LIBS)"'
-$(eval $(call SetupNativeCompilation,BUILD_LIBJSOUND, \
- LIBRARY := jsound, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+$(eval $(call SetupJdkLibrary, BUILD_LIBJSOUND, \
+ NAME := jsound, \
SRC := $(LIBJSOUND_SRC_DIRS), \
INCLUDE_FILES := $(LIBJSOUND_SRC_FILES), \
TOOLCHAIN := $(LIBJSOUND_TOOLCHAIN), \
@@ -128,17 +127,10 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJSOUND, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LIBS_unix := -ljava -ljvm, \
- LIBS_solaris := -lc, \
LIBS_macosx := -framework CoreAudio -framework CoreFoundation \
-framework CoreServices -framework AudioUnit $(LIBCXX) \
-framework CoreMIDI -framework AudioToolbox, \
LIBS_windows := $(WIN_JAVA_LIB) advapi32.lib winmm.lib, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=jsound.dll" \
- -D "JDK_INTERNAL_NAME=jsound" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjsound, \
))
$(BUILD_LIBJSOUND): $(BUILD_LIBJAVA)
@@ -149,9 +141,8 @@ TARGETS += $(BUILD_LIBJSOUND)
ifneq ($(filter jsoundalsa, $(EXTRA_SOUND_JNI_LIBS)), )
- $(eval $(call SetupNativeCompilation,BUILD_LIBJSOUNDALSA, \
- LIBRARY := jsoundalsa, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ $(eval $(call SetupJdkLibrary, BUILD_LIBJSOUNDALSA, \
+ NAME := jsoundalsa, \
SRC := $(LIBJSOUND_SRC_DIRS), \
INCLUDE_FILES := Utilities.c $(LIBJSOUND_MIDIFILES) $(LIBJSOUND_PORTFILES) \
$(LIBJSOUND_DAUDIOFILES) \
@@ -173,7 +164,6 @@ ifneq ($(filter jsoundalsa, $(EXTRA_SOUND_JNI_LIBS)), )
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LIBS := $(ALSA_LIBS) -ljava -ljvm, \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjsoundalsa, \
))
$(BUILD_LIBJSOUNDALSA): $(BUILD_LIBJAVA)
@@ -186,9 +176,8 @@ endif
ifneq ($(filter jsoundds, $(EXTRA_SOUND_JNI_LIBS)), )
- $(eval $(call SetupNativeCompilation,BUILD_LIBJSOUNDDS, \
- LIBRARY := jsoundds, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ $(eval $(call SetupJdkLibrary, BUILD_LIBJSOUNDDS, \
+ NAME := jsoundds, \
SRC := $(LIBJSOUND_SRC_DIRS), \
INCLUDE_FILES := Utilities.c $(LIBJSOUND_DAUDIOFILES) \
PLATFORM_API_WinOS_Charset_Util.cpp \
@@ -200,12 +189,6 @@ ifneq ($(filter jsoundds, $(EXTRA_SOUND_JNI_LIBS)), )
LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LIBS := $(JDKLIB_LIBS) dsound.lib winmm.lib user32.lib ole32.lib, \
- VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
- RC_FLAGS := $(RC_FLAGS) \
- -D "JDK_FNAME=jsoundds.dll" \
- -D "JDK_INTERNAL_NAME=jsoundds" \
- -D "JDK_FTYPE=0x2L", \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjsoundds, \
))
$(BUILD_LIBJSOUNDDS): $(BUILD_LIBJAVA)
diff --git a/make/mapfiles/libjava/mapfile-vers b/make/mapfiles/libjava/mapfile-vers
index fd4c3448bd0..4bde361b148 100644
--- a/make/mapfiles/libjava/mapfile-vers
+++ b/make/mapfiles/libjava/mapfile-vers
@@ -206,6 +206,7 @@ SUNWprivate_1.1 {
Java_java_lang_Runtime_totalMemory;
Java_java_lang_Runtime_availableProcessors;
Java_java_lang_SecurityManager_getClassContext;
+ Java_java_lang_Shutdown_beforeHalt;
Java_java_lang_Shutdown_halt0;
Java_java_lang_StackTraceElement_initStackTraceElement;
Java_java_lang_StackTraceElement_initStackTraceElements;
diff --git a/make/mapfiles/libjava/reorder-sparc b/make/mapfiles/libjava/reorder-sparc
index 43f1afda6b1..20f54e51631 100644
--- a/make/mapfiles/libjava/reorder-sparc
+++ b/make/mapfiles/libjava/reorder-sparc
@@ -26,7 +26,6 @@ text: .text%Java_java_io_FileInputStream_initIDs;
text: .text%Java_java_io_FileDescriptor_initIDs;
text: .text%Java_java_io_FileOutputStream_initIDs;
text: .text%Java_java_lang_System_setIn0;
-text: .text%Java_sun_reflect_Reflection_getCallerClass__;
text: .text%Java_java_lang_Class_forName0;
text: .text%Java_java_lang_Object_getClass;
text: .text%Java_sun_reflect_Reflection_getClassAccessFlags;
diff --git a/make/mapfiles/libjava/reorder-sparcv9 b/make/mapfiles/libjava/reorder-sparcv9
index 3e480bb7682..eb2de474255 100644
--- a/make/mapfiles/libjava/reorder-sparcv9
+++ b/make/mapfiles/libjava/reorder-sparcv9
@@ -25,7 +25,6 @@ text: .text%Java_java_io_FileInputStream_initIDs;
text: .text%Java_java_io_FileDescriptor_initIDs;
text: .text%Java_java_io_FileOutputStream_initIDs;
text: .text%Java_java_lang_System_setIn0;
-text: .text%Java_sun_reflect_Reflection_getCallerClass__;
text: .text%Java_java_lang_Class_forName0;
text: .text%Java_java_lang_String_intern;
text: .text%Java_java_lang_StringUTF16_isBigEndian;
diff --git a/make/mapfiles/libjava/reorder-x86 b/make/mapfiles/libjava/reorder-x86
index f294a93c4ba..7eeb16b95cf 100644
--- a/make/mapfiles/libjava/reorder-x86
+++ b/make/mapfiles/libjava/reorder-x86
@@ -26,7 +26,6 @@ text: .text%Java_java_io_FileInputStream_initIDs;
text: .text%Java_java_io_FileDescriptor_initIDs;
text: .text%Java_java_io_FileOutputStream_initIDs;
text: .text%Java_java_lang_System_setIn0;
-text: .text%Java_sun_reflect_Reflection_getCallerClass__;
text: .text%Java_java_lang_Class_forName0;
text: .text%Java_java_lang_String_intern;
text: .text%Java_java_lang_StringUTF16_isBigEndian;
diff --git a/make/nashorn/package-list b/make/nashorn/package-list
index 24c17a899bb..c23758a24e4 100644
--- a/make/nashorn/package-list
+++ b/make/nashorn/package-list
@@ -261,7 +261,6 @@ jdk.jshell
jdk.jshell.execution
jdk.jshell.spi
jdk.jshell.tool
-jdk.management.cmm
jdk.management.jfr
jdk.management.resource
jdk.nashorn.api.scripting
diff --git a/make/test/BuildFailureHandler.gmk b/make/test/BuildFailureHandler.gmk
index 52b828b69a2..0dca6f3663d 100644
--- a/make/test/BuildFailureHandler.gmk
+++ b/make/test/BuildFailureHandler.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -64,7 +64,7 @@ TARGETS += $(BUILD_FAILURE_HANDLER)
ifeq ($(OPENJDK_TARGET_OS), windows)
$(eval $(call SetupNativeCompilation, BUILD_LIBTIMEOUT_HANDLER, \
- LIBRARY := timeoutHandler, \
+ NAME := timeoutHandler, \
SRC := $(FH_BASEDIR)/src/windows/native/libtimeoutHandler, \
OBJECT_DIR := $(FH_SUPPORT)/libtimeoutHandler, \
OUTPUT_DIR := $(FH_SUPPORT), \
diff --git a/make/test/JtregNativeHotspot.gmk b/make/test/JtregNativeHotspot.gmk
index 70f9884eafb..17b7bcc6a24 100644
--- a/make/test/JtregNativeHotspot.gmk
+++ b/make/test/JtregNativeHotspot.gmk
@@ -41,113 +41,45 @@ $(eval $(call IncludeCustomExtension, test/JtregNativeHotspot.gmk))
# Targets for building the native tests themselves.
################################################################################
-# Add more directories here when needed.
-BUILD_HOTSPOT_JTREG_NATIVE_SRC += \
- $(TOPDIR)/test/hotspot/jtreg/gc/g1/TestJNIWeakG1 \
- $(TOPDIR)/test/hotspot/jtreg/gc/stress/TestJNIBlockFullGC \
- $(TOPDIR)/test/hotspot/jtreg/gc/stress/gclocker \
- $(TOPDIR)/test/hotspot/jtreg/gc/cslocker \
- $(TOPDIR)/test/hotspot/jtreg/native_sanity \
- $(TOPDIR)/test/hotspot/jtreg/runtime/jni/8025979 \
- $(TOPDIR)/test/hotspot/jtreg/runtime/jni/8033445 \
- $(TOPDIR)/test/hotspot/jtreg/runtime/jni/checked \
- $(TOPDIR)/test/hotspot/jtreg/runtime/jni/FindClass \
- $(TOPDIR)/test/hotspot/jtreg/runtime/jni/PrivateInterfaceMethods \
- $(TOPDIR)/test/hotspot/jtreg/runtime/jni/ToStringInInterfaceTest \
- $(TOPDIR)/test/hotspot/jtreg/runtime/jni/CalleeSavedRegisters \
- $(TOPDIR)/test/hotspot/jtreg/runtime/jni/CallWithJNIWeak \
- $(TOPDIR)/test/hotspot/jtreg/runtime/jni/ReturnJNIWeak \
- $(TOPDIR)/test/hotspot/jtreg/runtime/modules/getModuleJNI \
- $(TOPDIR)/test/hotspot/jtreg/runtime/SameObject \
- $(TOPDIR)/test/hotspot/jtreg/runtime/BoolReturn \
- $(TOPDIR)/test/hotspot/jtreg/runtime/noClassDefFoundMsg \
- $(TOPDIR)/test/hotspot/jtreg/runtime/handshake \
- $(TOPDIR)/test/hotspot/jtreg/runtime/RedefineTests \
- $(TOPDIR)/test/hotspot/jtreg/compiler/floatingpoint/ \
- $(TOPDIR)/test/hotspot/jtreg/compiler/calls \
- $(TOPDIR)/test/hotspot/jtreg/compiler/runtime/criticalnatives/lookup \
- $(TOPDIR)/test/hotspot/jtreg/compiler/runtime/criticalnatives/argumentcorruption \
- $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/CanGenerateAllClassHook \
- $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/GetOwnedMonitorInfo \
- $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/GetOwnedMonitorStackDepthInfo \
- $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/GetNamedModule \
- $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/IsModifiableModule \
- $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/AddModuleReads \
- $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/AddModuleExportsAndOpens \
- $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/AddModuleUsesAndProvides \
- $(TOPDIR)/test/hotspot/jtreg/testlibrary/jvmti \
- $(TOPDIR)/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test \
- $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/GetModulesInfo \
- $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/ModuleAwareAgents/ClassFileLoadHook \
- $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/ModuleAwareAgents/ClassLoadPrepare \
- $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/ModuleAwareAgents/ThreadStart \
- $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/StartPhase/AllowedFunctions \
- $(TOPDIR)/test/hotspot/jtreg/serviceability/dcmd/jvmti/AttachFailed \
- #
+# This might have been added to by a custom extension.
+BUILD_HOTSPOT_JTREG_NATIVE_SRC += $(TOPDIR)/test/hotspot/jtreg
-# Add conditional directories here when needed.
-ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_ARCH), solaris-sparc)
-BUILD_HOTSPOT_JTREG_NATIVE_SRC += \
- $(TOPDIR)/test/hotspot/jtreg/runtime/libadimalloc.solaris.sparc \
- $(TOPDIR)/test/hotspot/jtreg/runtime/ThreadSignalMask
-endif
+BUILD_HOTSPOT_JTREG_OUTPUT_DIR := $(OUTPUTDIR)/support/test/hotspot/jtreg/native
-ifeq ($(OPENJDK_TARGET_OS), linux)
-BUILD_HOTSPOT_JTREG_NATIVE_SRC += \
- $(TOPDIR)/test/hotspot/jtreg/runtime/execstack \
- $(TOPDIR)/test/hotspot/jtreg/runtime/jsig \
- $(TOPDIR)/test/hotspot/jtreg/runtime/StackGuardPages
-endif
+BUILD_HOTSPOT_JTREG_IMAGE_DIR := $(TEST_IMAGE_DIR)/hotspot/jtreg
-ifeq ($(TOOLCHAIN_TYPE), solstudio)
- BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_liboverflow := -lc
- BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libSimpleClassFileLoadHook := -lc
- BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libCanGenerateAllClassHook := -lc
- BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libGetOwnedMonitorInfoTest := -lc
- BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libGetOwnedMonitorStackDepthInfoTest := -lc
- BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libGetNamedModuleTest := -lc
- BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libIsModifiableModuleTest := -lc
- BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libAddModuleReadsTest := -lc
- BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libAddModuleExportsAndOpensTest := -lc
- BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libAddModuleUsesAndProvidesTest := -lc
- BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libMAAClassFileLoadHook := -lc
- BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libMAAClassLoadPrepare := -lc
- BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libMAAThreadStart := -lc
- BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libAllowedFunctions := -lc
- BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libRedefineDoubleDelete := -lc
- BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libHandshakeTransitionTest := -lc
- BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libHasNoEntryPoint := -lc
- BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libReturnError := -lc
- BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libCNLookUp := -lc
- BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libTestCheckedEnsureLocalCapacity := -lc
+# Platform specific setup
+ifneq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_ARCH), solaris-sparc)
+ BUILD_HOTSPOT_JTREG_EXCLUDE += liboverflow.c exeThreadSignalMask.c
endif
ifeq ($(OPENJDK_TARGET_OS), linux)
BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libtest-rw := -z noexecstack
BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libtest-rwx := -z execstack
BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exeinvoke := -ljvm -lpthread
- BUILD_TEST_invoke_exeinvoke.c_OPTIMIZATION := NONE
+ BUILD_TEST_exeinvoke_exeinvoke.c_OPTIMIZATION := NONE
BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exeFPRegs := -ldl
+else
+ BUILD_HOTSPOT_JTREG_EXCLUDE += libtest-rw.c libtest-rwx.c libTestJNI.c \
+ exeinvoke.c
endif
ifeq ($(OPENJDK_TARGET_OS), windows)
BUILD_HOTSPOT_JTREG_EXECUTABLES_CFLAGS_exeFPRegs := -MT
endif
-BUILD_HOTSPOT_JTREG_OUTPUT_DIR := $(OUTPUTDIR)/support/test/hotspot/jtreg/native
-
-BUILD_HOTSPOT_JTREG_IMAGE_DIR := $(TEST_IMAGE_DIR)/hotspot/jtreg
-
$(eval $(call SetupTestFilesCompilation, BUILD_HOTSPOT_JTREG_LIBRARIES, \
TYPE := LIBRARY, \
SOURCE_DIRS := $(BUILD_HOTSPOT_JTREG_NATIVE_SRC), \
OUTPUT_DIR := $(BUILD_HOTSPOT_JTREG_OUTPUT_DIR), \
+ EXCLUDE := $(BUILD_HOTSPOT_JTREG_EXCLUDE), \
))
$(eval $(call SetupTestFilesCompilation, BUILD_HOTSPOT_JTREG_EXECUTABLES, \
TYPE := PROGRAM, \
SOURCE_DIRS := $(BUILD_HOTSPOT_JTREG_NATIVE_SRC), \
OUTPUT_DIR := $(BUILD_HOTSPOT_JTREG_OUTPUT_DIR), \
+ EXCLUDE := $(BUILD_HOTSPOT_JTREG_EXCLUDE), \
))
build-test-hotspot-jtreg-native: $(BUILD_HOTSPOT_JTREG_LIBRARIES) $(BUILD_HOTSPOT_JTREG_EXECUTABLES)
diff --git a/make/test/JtregNativeJdk.gmk b/make/test/JtregNativeJdk.gmk
index 3e8d3af1d4e..1d2a6045b6b 100644
--- a/make/test/JtregNativeJdk.gmk
+++ b/make/test/JtregNativeJdk.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -41,47 +41,45 @@ $(eval $(call IncludeCustomExtension, test/JtregNativeJdk.gmk))
# Targets for building the native tests themselves.
################################################################################
-# Add more directories here when needed.
-BUILD_JDK_JTREG_NATIVE_SRC += \
- $(TOPDIR)/test/jdk/native_sanity \
- $(TOPDIR)/test/jdk/java/lang/ClassLoader/nativeLibrary \
- $(TOPDIR)/test/jdk/java/lang/String/nativeEncoding \
- #
-
-ifneq ($(OPENJDK_TARGET_OS), windows)
- BUILD_JDK_JTREG_NATIVE_SRC += $(TOPDIR)/test/jdk/java/nio/channels/FileChannel/directio
-endif
+# This might have been added to by a custom extension.
+BUILD_JDK_JTREG_NATIVE_SRC += $(TOPDIR)/test/jdk
BUILD_JDK_JTREG_OUTPUT_DIR := $(OUTPUTDIR)/support/test/jdk/jtreg/native
BUILD_JDK_JTREG_IMAGE_DIR := $(TEST_IMAGE_DIR)/jdk/jtreg
+# Platform specific setup
ifeq ($(OPENJDK_TARGET_OS), windows)
- WIN_LIB_JAVA := $(SUPPORT_OUTPUTDIR)/native/java.base/libjava/java.lib
- BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := $(WIN_LIB_JAVA)
-else ifeq ($(OPENJDK_TARGET_OS), solaris)
- BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := -ljava -lc
- BUILD_JDK_JTREG_LIBRARIES_LIBS_libDirectIO := -ljava -lc
+ BUILD_JDK_JTREG_EXCLUDE += libDirectIO.c libInheritedChannel.c
+
+ WIN_LIB_JAVA := $(SUPPORT_OUTPUTDIR)/native/java.base/libjava/java.lib
+ BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := $(WIN_LIB_JAVA)
else
- BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := -ljava
- BUILD_JDK_JTREG_LIBRARIES_LIBS_libDirectIO := -ljava
+ BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := -ljava
+ BUILD_JDK_JTREG_LIBRARIES_LIBS_libDirectIO := -ljava
+ ifeq ($(OPENJDK_TARGET_OS), linux)
+ BUILD_JDK_JTREG_LIBRARIES_LIBS_libInheritedChannel := -ljava
+ else ifeq ($(OPENJDK_TARGET_OS), solaris)
+ BUILD_JDK_JTREG_LIBRARIES_LIBS_libInheritedChannel := -ljava
+ endif
endif
$(eval $(call SetupTestFilesCompilation, BUILD_JDK_JTREG_LIBRARIES, \
TYPE := LIBRARY, \
SOURCE_DIRS := $(BUILD_JDK_JTREG_NATIVE_SRC), \
OUTPUT_DIR := $(BUILD_JDK_JTREG_OUTPUT_DIR), \
+ EXCLUDE := $(BUILD_JDK_JTREG_EXCLUDE), \
))
$(eval $(call SetupTestFilesCompilation, BUILD_JDK_JTREG_EXECUTABLES, \
TYPE := PROGRAM, \
SOURCE_DIRS := $(BUILD_JDK_JTREG_NATIVE_SRC), \
OUTPUT_DIR := $(BUILD_JDK_JTREG_OUTPUT_DIR), \
+ EXCLUDE := $(BUILD_JDK_JTREG_EXCLUDE), \
))
build-test-jdk-jtreg-native: $(BUILD_JDK_JTREG_LIBRARIES) $(BUILD_JDK_JTREG_EXECUTABLES)
-
################################################################################
# Targets for building test-image.
################################################################################
diff --git a/src/demo/share/java2d/J2DBench/src/j2dbench/ResultSet.java b/src/demo/share/java2d/J2DBench/src/j2dbench/ResultSet.java
index 018a9d579e5..233453a7e10 100644
--- a/src/demo/share/java2d/J2DBench/src/j2dbench/ResultSet.java
+++ b/src/demo/share/java2d/J2DBench/src/j2dbench/ResultSet.java
@@ -77,7 +77,6 @@ public class ResultSet {
"line.separator",
"file.separator",
"file.encoding",
- "file.encoding.pkg",
"java.class.path",
"java.library.path",
"java.io.tmpdir",
diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad
index e6b88fe4c44..4018f4243c7 100644
--- a/src/hotspot/cpu/aarch64/aarch64.ad
+++ b/src/hotspot/cpu/aarch64/aarch64.ad
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2014, Red Hat Inc. All rights reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
//
@@ -995,6 +995,7 @@ definitions %{
source_hpp %{
+#include "gc/shared/cardTable.hpp"
#include "gc/shared/cardTableModRefBS.hpp"
#include "opto/addnode.hpp"
@@ -4438,8 +4439,8 @@ encode %{
__ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
Assembler::byte, /*acquire*/ false, /*release*/ true,
/*weak*/ false, noreg);
- %}
-
+ %}
+
// The only difference between aarch64_enc_cmpxchg and
// aarch64_enc_cmpxchg_acq is that we use load-acquire in the
@@ -5845,7 +5846,7 @@ operand immByteMapBase()
%{
// Get base of card map
predicate(Universe::heap()->barrier_set()->is_a(BarrierSet::CardTableModRef) &&
- (jbyte*)n->get_ptr() == ((CardTableModRefBS*)(Universe::heap()->barrier_set()))->byte_map_base);
+ (jbyte*)n->get_ptr() == ((CardTableModRefBS*)(Universe::heap()->barrier_set()))->card_table()->byte_map_base());
match(ConP);
op_cost(0);
diff --git a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp
index 23d0c691ce1..22b97d8873f 100644
--- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp
+++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp
@@ -2048,21 +2048,21 @@ public:
starti;
f(0,31), f((int)T & 1, 30);
f(op1, 29, 21), f(0, 20, 16), f(op2, 15, 12);
- f((int)T >> 1, 11, 10), rf(Xn, 5), rf(Vt, 0);
+ f((int)T >> 1, 11, 10), srf(Xn, 5), rf(Vt, 0);
}
void ld_st(FloatRegister Vt, SIMD_Arrangement T, Register Xn,
int imm, int op1, int op2) {
starti;
f(0,31), f((int)T & 1, 30);
f(op1 | 0b100, 29, 21), f(0b11111, 20, 16), f(op2, 15, 12);
- f((int)T >> 1, 11, 10), rf(Xn, 5), rf(Vt, 0);
+ f((int)T >> 1, 11, 10), srf(Xn, 5), rf(Vt, 0);
}
void ld_st(FloatRegister Vt, SIMD_Arrangement T, Register Xn,
Register Xm, int op1, int op2) {
starti;
f(0,31), f((int)T & 1, 30);
f(op1 | 0b100, 29, 21), rf(Xm, 16), f(op2, 15, 12);
- f((int)T >> 1, 11, 10), rf(Xn, 5), rf(Vt, 0);
+ f((int)T >> 1, 11, 10), srf(Xn, 5), rf(Vt, 0);
}
void ld_st(FloatRegister Vt, SIMD_Arrangement T, Address a, int op1, int op2) {
diff --git a/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp
index 8c83dc4125c..e4f3ccb6c18 100644
--- a/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp
@@ -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.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -30,6 +30,8 @@
#include "c1/c1_MacroAssembler.hpp"
#include "c1/c1_Runtime1.hpp"
#include "compiler/disassembler.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "gc/shared/cardTableModRefBS.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_aarch64.hpp"
#include "oops/compiledICHolder.hpp"
@@ -42,6 +44,7 @@
#include "runtime/vframeArray.hpp"
#include "vmreg_aarch64.inline.hpp"
#if INCLUDE_ALL_GCS
+#include "gc/g1/g1CardTable.hpp"
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
#endif
@@ -684,14 +687,14 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
}
if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) &&
- UseTLAB && FastTLABRefill) {
+ UseTLAB && Universe::heap()->supports_inline_contig_alloc()) {
Label slow_path;
Register obj_size = r2;
Register t1 = r19;
Register t2 = r4;
assert_different_registers(klass, obj, obj_size, t1, t2);
- __ stp(r5, r19, Address(__ pre(sp, -2 * wordSize)));
+ __ stp(r19, zr, Address(__ pre(sp, -2 * wordSize)));
if (id == fast_new_instance_init_check_id) {
// make sure the klass is initialized
@@ -716,24 +719,6 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
}
#endif // ASSERT
- // if we got here then the TLAB allocation failed, so try
- // refilling the TLAB or allocating directly from eden.
- Label retry_tlab, try_eden;
- __ tlab_refill(retry_tlab, try_eden, slow_path); // does not destroy r3 (klass), returns r5
-
- __ bind(retry_tlab);
-
- // get the instance size (size is postive so movl is fine for 64bit)
- __ ldrw(obj_size, Address(klass, Klass::layout_helper_offset()));
-
- __ tlab_allocate(obj, obj_size, 0, t1, t2, slow_path);
-
- __ initialize_object(obj, klass, obj_size, 0, t1, t2, /* is_tlab_allocated */ true);
- __ verify_oop(obj);
- __ ldp(r5, r19, Address(__ post(sp, 2 * wordSize)));
- __ ret(lr);
-
- __ bind(try_eden);
// get the instance size (size is postive so movl is fine for 64bit)
__ ldrw(obj_size, Address(klass, Klass::layout_helper_offset()));
@@ -742,11 +727,11 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
__ initialize_object(obj, klass, obj_size, 0, t1, t2, /* is_tlab_allocated */ false);
__ verify_oop(obj);
- __ ldp(r5, r19, Address(__ post(sp, 2 * wordSize)));
+ __ ldp(r19, zr, Address(__ post(sp, 2 * wordSize)));
__ ret(lr);
__ bind(slow_path);
- __ ldp(r5, r19, Address(__ post(sp, 2 * wordSize)));
+ __ ldp(r19, zr, Address(__ post(sp, 2 * wordSize)));
}
__ enter();
@@ -814,7 +799,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
}
#endif // ASSERT
- if (UseTLAB && FastTLABRefill) {
+ if (UseTLAB && Universe::heap()->supports_inline_contig_alloc()) {
Register arr_size = r4;
Register t1 = r2;
Register t2 = r5;
@@ -826,45 +811,10 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
__ cmpw(length, rscratch1);
__ br(Assembler::HI, slow_path);
- // if we got here then the TLAB allocation failed, so try
- // refilling the TLAB or allocating directly from eden.
- Label retry_tlab, try_eden;
- const Register thread =
- __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves r19 & r3, returns rthread
-
- __ bind(retry_tlab);
-
// get the allocation size: round_up(hdr + length << (layout_helper & 0x1F))
// since size is positive ldrw does right thing on 64bit
__ ldrw(t1, Address(klass, Klass::layout_helper_offset()));
- __ lslvw(arr_size, length, t1);
- __ ubfx(t1, t1, Klass::_lh_header_size_shift,
- exact_log2(Klass::_lh_header_size_mask + 1));
- __ add(arr_size, arr_size, t1);
- __ add(arr_size, arr_size, MinObjAlignmentInBytesMask); // align up
- __ andr(arr_size, arr_size, ~MinObjAlignmentInBytesMask);
-
- __ tlab_allocate(obj, arr_size, 0, t1, t2, slow_path); // preserves arr_size
-
- __ initialize_header(obj, klass, length, t1, t2);
- __ ldrb(t1, Address(klass, in_bytes(Klass::layout_helper_offset()) + (Klass::_lh_header_size_shift / BitsPerByte)));
- assert(Klass::_lh_header_size_shift % BitsPerByte == 0, "bytewise");
- assert(Klass::_lh_header_size_mask <= 0xFF, "bytewise");
- __ andr(t1, t1, Klass::_lh_header_size_mask);
- __ sub(arr_size, arr_size, t1); // body length
- __ add(t1, t1, obj); // body start
- if (!ZeroTLAB) {
- __ initialize_body(t1, arr_size, 0, t2);
- }
- __ verify_oop(obj);
-
- __ ret(lr);
-
- __ bind(try_eden);
- // get the allocation size: round_up(hdr + length << (layout_helper & 0x1F))
- // since size is positive ldrw does right thing on 64bit
- __ ldrw(t1, Address(klass, Klass::layout_helper_offset()));
- // since size is postive movw does right thing on 64bit
+ // since size is positive movw does right thing on 64bit
__ movw(arr_size, length);
__ lslvw(arr_size, length, t1);
__ ubfx(t1, t1, Klass::_lh_header_size_shift,
@@ -874,7 +824,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
__ andr(arr_size, arr_size, ~MinObjAlignmentInBytesMask);
__ eden_allocate(obj, arr_size, 0, t1, slow_path); // preserves arr_size
- __ incr_allocated_bytes(thread, arr_size, 0, rscratch1);
+ __ incr_allocated_bytes(rthread, arr_size, 0, rscratch1);
__ initialize_header(obj, klass, length, t1, t2);
__ ldrb(t1, Address(klass, in_bytes(Klass::layout_helper_offset()) + (Klass::_lh_header_size_shift / BitsPerByte)));
@@ -1215,10 +1165,6 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
// arg0: store_address
Address store_addr(rfp, 2*BytesPerWord);
- BarrierSet* bs = Universe::heap()->barrier_set();
- CardTableModRefBS* ct = (CardTableModRefBS*)bs;
- assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
-
Label done;
Label runtime;
@@ -1239,13 +1185,13 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
assert_different_registers(card_offset, byte_map_base, rscratch1);
f.load_argument(0, card_offset);
- __ lsr(card_offset, card_offset, CardTableModRefBS::card_shift);
+ __ lsr(card_offset, card_offset, CardTable::card_shift);
__ load_byte_map_base(byte_map_base);
__ ldrb(rscratch1, Address(byte_map_base, card_offset));
- __ cmpw(rscratch1, (int)G1SATBCardTableModRefBS::g1_young_card_val());
+ __ cmpw(rscratch1, (int)G1CardTable::g1_young_card_val());
__ br(Assembler::EQ, done);
- assert((int)CardTableModRefBS::dirty_card_val() == 0, "must be 0");
+ assert((int)CardTable::dirty_card_val() == 0, "must be 0");
__ membar(Assembler::StoreLoad);
__ ldrb(rscratch1, Address(byte_map_base, card_offset));
diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
index dc871bc9f7a..2dd34d0a5d9 100644
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
@@ -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.
* Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -29,8 +29,9 @@
#include "jvm.h"
#include "asm/assembler.hpp"
#include "asm/assembler.inline.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "gc/shared/cardTableModRefBS.hpp"
#include "interpreter/interpreter.hpp"
-
#include "compiler/disassembler.hpp"
#include "memory/resourceArea.hpp"
#include "nativeInst_aarch64.hpp"
@@ -42,10 +43,12 @@
#include "runtime/biasedLocking.hpp"
#include "runtime/icache.hpp"
#include "runtime/interfaceSupport.hpp"
+#include "runtime/jniHandles.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/thread.hpp"
#if INCLUDE_ALL_GCS
+#include "gc/g1/g1CardTable.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
#include "gc/g1/heapRegion.hpp"
@@ -1794,18 +1797,63 @@ int MacroAssembler::corrected_idivq(Register result, Register ra, Register rb,
void MacroAssembler::membar(Membar_mask_bits order_constraint) {
address prev = pc() - NativeMembar::instruction_size;
- if (prev == code()->last_membar()) {
+ address last = code()->last_insn();
+ if (last != NULL && nativeInstruction_at(last)->is_Membar() && prev == last) {
NativeMembar *bar = NativeMembar_at(prev);
// We are merging two memory barrier instructions. On AArch64 we
// can do this simply by ORing them together.
bar->set_kind(bar->get_kind() | order_constraint);
BLOCK_COMMENT("merged membar");
} else {
- code()->set_last_membar(pc());
+ code()->set_last_insn(pc());
dmb(Assembler::barrier(order_constraint));
}
}
+bool MacroAssembler::try_merge_ldst(Register rt, const Address &adr, size_t size_in_bytes, bool is_store) {
+ if (ldst_can_merge(rt, adr, size_in_bytes, is_store)) {
+ merge_ldst(rt, adr, size_in_bytes, is_store);
+ code()->clear_last_insn();
+ return true;
+ } else {
+ assert(size_in_bytes == 8 || size_in_bytes == 4, "only 8 bytes or 4 bytes load/store is supported.");
+ const unsigned mask = size_in_bytes - 1;
+ if (adr.getMode() == Address::base_plus_offset &&
+ (adr.offset() & mask) == 0) { // only supports base_plus_offset.
+ code()->set_last_insn(pc());
+ }
+ return false;
+ }
+}
+
+void MacroAssembler::ldr(Register Rx, const Address &adr) {
+ // We always try to merge two adjacent loads into one ldp.
+ if (!try_merge_ldst(Rx, adr, 8, false)) {
+ Assembler::ldr(Rx, adr);
+ }
+}
+
+void MacroAssembler::ldrw(Register Rw, const Address &adr) {
+ // We always try to merge two adjacent loads into one ldp.
+ if (!try_merge_ldst(Rw, adr, 4, false)) {
+ Assembler::ldrw(Rw, adr);
+ }
+}
+
+void MacroAssembler::str(Register Rx, const Address &adr) {
+ // We always try to merge two adjacent stores into one stp.
+ if (!try_merge_ldst(Rx, adr, 8, true)) {
+ Assembler::str(Rx, adr);
+ }
+}
+
+void MacroAssembler::strw(Register Rw, const Address &adr) {
+ // We always try to merge two adjacent stores into one stp.
+ if (!try_merge_ldst(Rw, adr, 4, true)) {
+ Assembler::strw(Rw, adr);
+ }
+}
+
// MacroAssembler routines found actually to be needed
void MacroAssembler::push(Register src)
@@ -2576,6 +2624,143 @@ Address MacroAssembler::spill_address(int size, int offset, Register tmp)
return Address(base, offset);
}
+// Checks whether offset is aligned.
+// Returns true if it is, else false.
+bool MacroAssembler::merge_alignment_check(Register base,
+ size_t size,
+ long cur_offset,
+ long prev_offset) const {
+ if (AvoidUnalignedAccesses) {
+ if (base == sp) {
+ // Checks whether low offset if aligned to pair of registers.
+ long pair_mask = size * 2 - 1;
+ long offset = prev_offset > cur_offset ? cur_offset : prev_offset;
+ return (offset & pair_mask) == 0;
+ } else { // If base is not sp, we can't guarantee the access is aligned.
+ return false;
+ }
+ } else {
+ long mask = size - 1;
+ // Load/store pair instruction only supports element size aligned offset.
+ return (cur_offset & mask) == 0 && (prev_offset & mask) == 0;
+ }
+}
+
+// Checks whether current and previous loads/stores can be merged.
+// Returns true if it can be merged, else false.
+bool MacroAssembler::ldst_can_merge(Register rt,
+ const Address &adr,
+ size_t cur_size_in_bytes,
+ bool is_store) const {
+ address prev = pc() - NativeInstruction::instruction_size;
+ address last = code()->last_insn();
+
+ if (last == NULL || !nativeInstruction_at(last)->is_Imm_LdSt()) {
+ return false;
+ }
+
+ if (adr.getMode() != Address::base_plus_offset || prev != last) {
+ return false;
+ }
+
+ NativeLdSt* prev_ldst = NativeLdSt_at(prev);
+ size_t prev_size_in_bytes = prev_ldst->size_in_bytes();
+
+ assert(prev_size_in_bytes == 4 || prev_size_in_bytes == 8, "only supports 64/32bit merging.");
+ assert(cur_size_in_bytes == 4 || cur_size_in_bytes == 8, "only supports 64/32bit merging.");
+
+ if (cur_size_in_bytes != prev_size_in_bytes || is_store != prev_ldst->is_store()) {
+ return false;
+ }
+
+ long max_offset = 63 * prev_size_in_bytes;
+ long min_offset = -64 * prev_size_in_bytes;
+
+ assert(prev_ldst->is_not_pre_post_index(), "pre-index or post-index is not supported to be merged.");
+
+ // Only same base can be merged.
+ if (adr.base() != prev_ldst->base()) {
+ return false;
+ }
+
+ long cur_offset = adr.offset();
+ long prev_offset = prev_ldst->offset();
+ size_t diff = abs(cur_offset - prev_offset);
+ if (diff != prev_size_in_bytes) {
+ return false;
+ }
+
+ // Following cases can not be merged:
+ // ldr x2, [x2, #8]
+ // ldr x3, [x2, #16]
+ // or:
+ // ldr x2, [x3, #8]
+ // ldr x2, [x3, #16]
+ // If t1 and t2 is the same in "ldp t1, t2, [xn, #imm]", we'll get SIGILL.
+ if (!is_store && (adr.base() == prev_ldst->target() || rt == prev_ldst->target())) {
+ return false;
+ }
+
+ long low_offset = prev_offset > cur_offset ? cur_offset : prev_offset;
+ // Offset range must be in ldp/stp instruction's range.
+ if (low_offset > max_offset || low_offset < min_offset) {
+ return false;
+ }
+
+ if (merge_alignment_check(adr.base(), prev_size_in_bytes, cur_offset, prev_offset)) {
+ return true;
+ }
+
+ return false;
+}
+
+// Merge current load/store with previous load/store into ldp/stp.
+void MacroAssembler::merge_ldst(Register rt,
+ const Address &adr,
+ size_t cur_size_in_bytes,
+ bool is_store) {
+
+ assert(ldst_can_merge(rt, adr, cur_size_in_bytes, is_store) == true, "cur and prev must be able to be merged.");
+
+ Register rt_low, rt_high;
+ address prev = pc() - NativeInstruction::instruction_size;
+ NativeLdSt* prev_ldst = NativeLdSt_at(prev);
+
+ long offset;
+
+ if (adr.offset() < prev_ldst->offset()) {
+ offset = adr.offset();
+ rt_low = rt;
+ rt_high = prev_ldst->target();
+ } else {
+ offset = prev_ldst->offset();
+ rt_low = prev_ldst->target();
+ rt_high = rt;
+ }
+
+ Address adr_p = Address(prev_ldst->base(), offset);
+ // Overwrite previous generated binary.
+ code_section()->set_end(prev);
+
+ const int sz = prev_ldst->size_in_bytes();
+ assert(sz == 8 || sz == 4, "only supports 64/32bit merging.");
+ if (!is_store) {
+ BLOCK_COMMENT("merged ldr pair");
+ if (sz == 8) {
+ ldp(rt_low, rt_high, adr_p);
+ } else {
+ ldpw(rt_low, rt_high, adr_p);
+ }
+ } else {
+ BLOCK_COMMENT("merged str pair");
+ if (sz == 8) {
+ stp(rt_low, rt_high, adr_p);
+ } else {
+ stpw(rt_low, rt_high, adr_p);
+ }
+ }
+}
+
/**
* Multiply 64 bit by 64 bit first loop.
*/
@@ -3433,16 +3618,16 @@ void MacroAssembler::store_check(Register obj) {
// register obj is destroyed afterwards.
BarrierSet* bs = Universe::heap()->barrier_set();
- assert(bs->kind() == BarrierSet::CardTableForRS ||
- bs->kind() == BarrierSet::CardTableExtension,
+ assert(bs->kind() == BarrierSet::CardTableModRef,
"Wrong barrier set kind");
- CardTableModRefBS* ct = barrier_set_cast(bs);
- assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
+ CardTableModRefBS* ctbs = barrier_set_cast(bs);
+ CardTable* ct = ctbs->card_table();
+ assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
- lsr(obj, obj, CardTableModRefBS::card_shift);
+ lsr(obj, obj, CardTable::card_shift);
- assert(CardTableModRefBS::dirty_card_val() == 0, "must be");
+ assert(CardTable::dirty_card_val() == 0, "must be");
load_byte_map_base(rscratch1);
@@ -3944,8 +4129,9 @@ void MacroAssembler::g1_write_barrier_post(Register store_addr,
DirtyCardQueue::byte_offset_of_buf()));
BarrierSet* bs = Universe::heap()->barrier_set();
- CardTableModRefBS* ct = (CardTableModRefBS*)bs;
- assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
+ CardTableModRefBS* ctbs = barrier_set_cast(bs);
+ CardTable* ct = ctbs->card_table();
+ assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
Label done;
Label runtime;
@@ -3962,20 +4148,20 @@ void MacroAssembler::g1_write_barrier_post(Register store_addr,
// storing region crossing non-NULL, is card already dirty?
- ExternalAddress cardtable((address) ct->byte_map_base);
- assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
+ ExternalAddress cardtable((address) ct->byte_map_base());
+ assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
const Register card_addr = tmp;
- lsr(card_addr, store_addr, CardTableModRefBS::card_shift);
+ lsr(card_addr, store_addr, CardTable::card_shift);
// get the address of the card
load_byte_map_base(tmp2);
add(card_addr, card_addr, tmp2);
ldrb(tmp2, Address(card_addr));
- cmpw(tmp2, (int)G1SATBCardTableModRefBS::g1_young_card_val());
+ cmpw(tmp2, (int)G1CardTable::g1_young_card_val());
br(Assembler::EQ, done);
- assert((int)CardTableModRefBS::dirty_card_val() == 0, "must be 0");
+ assert((int)CardTable::dirty_card_val() == 0, "must be 0");
membar(Assembler::StoreLoad);
@@ -4096,131 +4282,6 @@ void MacroAssembler::tlab_allocate(Register obj,
// verify_tlab();
}
-// Preserves r19, and r3.
-Register MacroAssembler::tlab_refill(Label& retry,
- Label& try_eden,
- Label& slow_case) {
- Register top = r0;
- Register t1 = r2;
- Register t2 = r4;
- assert_different_registers(top, rthread, t1, t2, /* preserve: */ r19, r3);
- Label do_refill, discard_tlab;
-
- if (!Universe::heap()->supports_inline_contig_alloc()) {
- // No allocation in the shared eden.
- b(slow_case);
- }
-
- ldr(top, Address(rthread, in_bytes(JavaThread::tlab_top_offset())));
- ldr(t1, Address(rthread, in_bytes(JavaThread::tlab_end_offset())));
-
- // calculate amount of free space
- sub(t1, t1, top);
- lsr(t1, t1, LogHeapWordSize);
-
- // Retain tlab and allocate object in shared space if
- // the amount free in the tlab is too large to discard.
-
- ldr(rscratch1, Address(rthread, in_bytes(JavaThread::tlab_refill_waste_limit_offset())));
- cmp(t1, rscratch1);
- br(Assembler::LE, discard_tlab);
-
- // Retain
- // ldr(rscratch1, Address(rthread, in_bytes(JavaThread::tlab_refill_waste_limit_offset())));
- mov(t2, (int32_t) ThreadLocalAllocBuffer::refill_waste_limit_increment());
- add(rscratch1, rscratch1, t2);
- str(rscratch1, Address(rthread, in_bytes(JavaThread::tlab_refill_waste_limit_offset())));
-
- if (TLABStats) {
- // increment number of slow_allocations
- addmw(Address(rthread, in_bytes(JavaThread::tlab_slow_allocations_offset())),
- 1, rscratch1);
- }
- b(try_eden);
-
- bind(discard_tlab);
- if (TLABStats) {
- // increment number of refills
- addmw(Address(rthread, in_bytes(JavaThread::tlab_number_of_refills_offset())), 1,
- rscratch1);
- // accumulate wastage -- t1 is amount free in tlab
- addmw(Address(rthread, in_bytes(JavaThread::tlab_fast_refill_waste_offset())), t1,
- rscratch1);
- }
-
- // if tlab is currently allocated (top or end != null) then
- // fill [top, end + alignment_reserve) with array object
- cbz(top, do_refill);
-
- // set up the mark word
- mov(rscratch1, (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2));
- str(rscratch1, Address(top, oopDesc::mark_offset_in_bytes()));
- // set the length to the remaining space
- sub(t1, t1, typeArrayOopDesc::header_size(T_INT));
- add(t1, t1, (int32_t)ThreadLocalAllocBuffer::alignment_reserve());
- lsl(t1, t1, log2_intptr(HeapWordSize/sizeof(jint)));
- strw(t1, Address(top, arrayOopDesc::length_offset_in_bytes()));
- // set klass to intArrayKlass
- {
- unsigned long offset;
- // dubious reloc why not an oop reloc?
- adrp(rscratch1, ExternalAddress((address)Universe::intArrayKlassObj_addr()),
- offset);
- ldr(t1, Address(rscratch1, offset));
- }
- // store klass last. concurrent gcs assumes klass length is valid if
- // klass field is not null.
- store_klass(top, t1);
-
- mov(t1, top);
- ldr(rscratch1, Address(rthread, in_bytes(JavaThread::tlab_start_offset())));
- sub(t1, t1, rscratch1);
- incr_allocated_bytes(rthread, t1, 0, rscratch1);
-
- // refill the tlab with an eden allocation
- bind(do_refill);
- ldr(t1, Address(rthread, in_bytes(JavaThread::tlab_size_offset())));
- lsl(t1, t1, LogHeapWordSize);
- // allocate new tlab, address returned in top
- eden_allocate(top, t1, 0, t2, slow_case);
-
- // Check that t1 was preserved in eden_allocate.
-#ifdef ASSERT
- if (UseTLAB) {
- Label ok;
- Register tsize = r4;
- assert_different_registers(tsize, rthread, t1);
- str(tsize, Address(pre(sp, -16)));
- ldr(tsize, Address(rthread, in_bytes(JavaThread::tlab_size_offset())));
- lsl(tsize, tsize, LogHeapWordSize);
- cmp(t1, tsize);
- br(Assembler::EQ, ok);
- STOP("assert(t1 != tlab size)");
- should_not_reach_here();
-
- bind(ok);
- ldr(tsize, Address(post(sp, 16)));
- }
-#endif
- str(top, Address(rthread, in_bytes(JavaThread::tlab_start_offset())));
- str(top, Address(rthread, in_bytes(JavaThread::tlab_top_offset())));
- add(top, top, t1);
- sub(top, top, (int32_t)ThreadLocalAllocBuffer::alignment_reserve_in_bytes());
- str(top, Address(rthread, in_bytes(JavaThread::tlab_end_offset())));
-
- if (ZeroTLAB) {
- // This is a fast TLAB refill, therefore the GC is not notified of it.
- // So compiled code must fill the new TLAB with zeroes.
- ldr(top, Address(rthread, in_bytes(JavaThread::tlab_start_offset())));
- zero_memory(top,t1,t2);
- }
-
- verify_tlab();
- b(retry);
-
- return rthread; // for use by caller
-}
-
// Zero words; len is in bytes
// Destroys all registers except addr
// len must be a nonzero multiple of wordSize
@@ -4277,7 +4338,7 @@ void MacroAssembler::zero_memory(Register addr, Register len, Register t1) {
bind(loop);
sub(len, len, unroll);
for (int i = -unroll; i < 0; i++)
- str(zr, Address(t1, i * wordSize));
+ Assembler::str(zr, Address(t1, i * wordSize));
bind(entry);
add(t1, t1, unroll * wordSize);
cbnz(len, loop);
@@ -4454,7 +4515,7 @@ void MacroAssembler::adrp(Register reg1, const Address &dest, unsigned long &byt
void MacroAssembler::load_byte_map_base(Register reg) {
jbyte *byte_map_base =
- ((CardTableModRefBS*)(Universe::heap()->barrier_set()))->byte_map_base;
+ ((CardTableModRefBS*)(Universe::heap()->barrier_set()))->card_table()->byte_map_base();
if (is_valid_AArch64_address((address)byte_map_base)) {
// Strictly speaking the byte_map_base isn't an address at all,
diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp
index a0291d4a23f..59d1c8e2c67 100644
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp
@@ -150,11 +150,19 @@ class MacroAssembler: public Assembler {
void bind(Label& L) {
Assembler::bind(L);
- code()->clear_last_membar();
+ code()->clear_last_insn();
}
void membar(Membar_mask_bits order_constraint);
+ using Assembler::ldr;
+ using Assembler::str;
+
+ void ldr(Register Rx, const Address &adr);
+ void ldrw(Register Rw, const Address &adr);
+ void str(Register Rx, const Address &adr);
+ void strw(Register Rx, const Address &adr);
+
// Frame creation and destruction shared between JITs.
void build_frame(int framesize);
void remove_frame(int framesize);
@@ -861,7 +869,6 @@ public:
Register t2, // temp register
Label& slow_case // continuation point if fast allocation fails
);
- Register tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case); // returns TLS address
void zero_memory(Register addr, Register len, Register t1);
void verify_tlab();
@@ -1291,6 +1298,17 @@ private:
// Uses rscratch2 if the address is not directly reachable
Address spill_address(int size, int offset, Register tmp=rscratch2);
+ bool merge_alignment_check(Register base, size_t size, long cur_offset, long prev_offset) const;
+
+ // Check whether two loads/stores can be merged into ldp/stp.
+ bool ldst_can_merge(Register rx, const Address &adr, size_t cur_size_in_bytes, bool is_store) const;
+
+ // Merge current load/store with previous load/store into ldp/stp.
+ void merge_ldst(Register rx, const Address &adr, size_t cur_size_in_bytes, bool is_store);
+
+ // Try to merge two loads/stores into ldp/stp. If success, returns true else false.
+ bool try_merge_ldst(Register rt, const Address &adr, size_t cur_size_in_bytes, bool is_store);
+
public:
void spill(Register Rx, bool is64, int offset) {
if (is64) {
diff --git a/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp b/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp
index da61fcf75d1..f78d26e9025 100644
--- a/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp
+++ b/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp
@@ -131,6 +131,13 @@ class NativeInstruction VALUE_OBJ_CLASS_SPEC {
return Instruction_aarch64::extract(insn, 31, 12) == 0b11010101000000110011 &&
Instruction_aarch64::extract(insn, 7, 0) == 0b10111111;
}
+
+ bool is_Imm_LdSt() {
+ unsigned int insn = uint_at(0);
+ return Instruction_aarch64::extract(insn, 29, 27) == 0b111 &&
+ Instruction_aarch64::extract(insn, 23, 23) == 0b0 &&
+ Instruction_aarch64::extract(insn, 26, 25) == 0b00;
+ }
};
inline NativeInstruction* nativeInstruction_at(address address) {
@@ -532,4 +539,57 @@ inline NativeMembar *NativeMembar_at(address addr) {
return (NativeMembar*)addr;
}
+class NativeLdSt : public NativeInstruction {
+private:
+ int32_t size() { return Instruction_aarch64::extract(uint_at(0), 31, 30); }
+ // Check whether instruction is with unscaled offset.
+ bool is_ldst_ur() {
+ return (Instruction_aarch64::extract(uint_at(0), 29, 21) == 0b111000010 ||
+ Instruction_aarch64::extract(uint_at(0), 29, 21) == 0b111000000) &&
+ Instruction_aarch64::extract(uint_at(0), 11, 10) == 0b00;
+ }
+ bool is_ldst_unsigned_offset() {
+ return Instruction_aarch64::extract(uint_at(0), 29, 22) == 0b11100101 ||
+ Instruction_aarch64::extract(uint_at(0), 29, 22) == 0b11100100;
+ }
+public:
+ Register target() {
+ uint32_t r = Instruction_aarch64::extract(uint_at(0), 4, 0);
+ return r == 0x1f ? zr : as_Register(r);
+ }
+ Register base() {
+ uint32_t b = Instruction_aarch64::extract(uint_at(0), 9, 5);
+ return b == 0x1f ? sp : as_Register(b);
+ }
+ int64_t offset() {
+ if (is_ldst_ur()) {
+ return Instruction_aarch64::sextract(uint_at(0), 20, 12);
+ } else if (is_ldst_unsigned_offset()) {
+ return Instruction_aarch64::extract(uint_at(0), 21, 10) << size();
+ } else {
+ // others like: pre-index or post-index.
+ ShouldNotReachHere();
+ return 0;
+ }
+ }
+ size_t size_in_bytes() { return 1 << size(); }
+ bool is_not_pre_post_index() { return (is_ldst_ur() || is_ldst_unsigned_offset()); }
+ bool is_load() {
+ assert(Instruction_aarch64::extract(uint_at(0), 23, 22) == 0b01 ||
+ Instruction_aarch64::extract(uint_at(0), 23, 22) == 0b00, "must be ldr or str");
+
+ return Instruction_aarch64::extract(uint_at(0), 23, 22) == 0b01;
+ }
+ bool is_store() {
+ assert(Instruction_aarch64::extract(uint_at(0), 23, 22) == 0b01 ||
+ Instruction_aarch64::extract(uint_at(0), 23, 22) == 0b00, "must be ldr or str");
+
+ return Instruction_aarch64::extract(uint_at(0), 23, 22) == 0b00;
+ }
+};
+
+inline NativeLdSt *NativeLdSt_at(address addr) {
+ assert(nativeInstruction_at(addr)->is_Imm_LdSt(), "no immediate load/store found");
+ return (NativeLdSt*)addr;
+}
#endif // CPU_AARCH64_VM_NATIVEINST_AARCH64_HPP
diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
index a2515e5774f..c6d2faaad6c 100644
--- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -26,6 +26,8 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.hpp"
#include "asm/macroAssembler.inline.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "gc/shared/cardTableModRefBS.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_aarch64.hpp"
#include "oops/instanceOop.hpp"
@@ -652,9 +654,7 @@ class StubGenerator: public StubCodeGenerator {
__ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 2);
__ pop(saved_regs, sp);
break;
- case BarrierSet::CardTableForRS:
- case BarrierSet::CardTableExtension:
- case BarrierSet::ModRef:
+ case BarrierSet::CardTableModRef:
break;
default:
ShouldNotReachHere();
@@ -695,16 +695,16 @@ class StubGenerator: public StubCodeGenerator {
__ pop(saved_regs, sp);
}
break;
- case BarrierSet::CardTableForRS:
- case BarrierSet::CardTableExtension:
+ case BarrierSet::CardTableModRef:
{
- CardTableModRefBS* ct = (CardTableModRefBS*)bs;
- assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
+ CardTableModRefBS* ctbs = barrier_set_cast(bs);
+ CardTable* ct = ctbs->card_table();
+ assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
Label L_loop;
- __ lsr(start, start, CardTableModRefBS::card_shift);
- __ lsr(end, end, CardTableModRefBS::card_shift);
+ __ lsr(start, start, CardTable::card_shift);
+ __ lsr(end, end, CardTable::card_shift);
__ sub(end, end, start); // number of bytes to copy
const Register count = end; // 'end' register contains bytes count now
diff --git a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp
index 3cb57a7931e..6a8fa62d4f4 100644
--- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -184,8 +184,7 @@ static void do_oop_store(InterpreterMacroAssembler* _masm,
}
break;
#endif // INCLUDE_ALL_GCS
- case BarrierSet::CardTableForRS:
- case BarrierSet::CardTableExtension:
+ case BarrierSet::CardTableModRef:
{
if (val == noreg) {
__ store_heap_oop_null(obj);
diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp
index 33e78cd8914..b5911b559a8 100644
--- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp
@@ -193,7 +193,9 @@ void VM_Version::get_processor_features() {
}
// Enable vendor specific features
- if (_cpu == CPU_CAVIUM) {
+
+ // ThunderX
+ if (_cpu == CPU_CAVIUM && (_model == 0xA1)) {
if (_variant == 0) _features |= CPU_DMB_ATOMICS;
if (FLAG_IS_DEFAULT(AvoidUnalignedAccesses)) {
FLAG_SET_DEFAULT(AvoidUnalignedAccesses, true);
@@ -202,6 +204,20 @@ void VM_Version::get_processor_features() {
FLAG_SET_DEFAULT(UseSIMDForMemoryOps, (_variant > 0));
}
}
+ // ThunderX2
+ if ((_cpu == CPU_CAVIUM && (_model == 0xAF)) ||
+ (_cpu == CPU_BROADCOM && (_model == 0x516))) {
+ if (FLAG_IS_DEFAULT(AvoidUnalignedAccesses)) {
+ FLAG_SET_DEFAULT(AvoidUnalignedAccesses, true);
+ }
+ if (FLAG_IS_DEFAULT(UseSIMDForMemoryOps)) {
+ FLAG_SET_DEFAULT(UseSIMDForMemoryOps, true);
+ }
+ if (FLAG_IS_DEFAULT(UseFPUForSpilling)) {
+ FLAG_SET_DEFAULT(UseFPUForSpilling, true);
+ }
+ }
+
if (_cpu == CPU_ARM && (_model == 0xd03 || _model2 == 0xd03)) _features |= CPU_A53MAC;
if (_cpu == CPU_ARM && (_model == 0xd07 || _model2 == 0xd07)) _features |= CPU_STXR_PREFETCH;
// If an olde style /proc/cpuinfo (cpu_lines == 1) then if _model is an A57 (0xd07)
diff --git a/src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp b/src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp
index 742705f1681..c897e82d4ec 100644
--- a/src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp
+++ b/src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp
@@ -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
@@ -33,6 +33,8 @@
#include "ci/ciArray.hpp"
#include "ci/ciObjArrayKlass.hpp"
#include "ci/ciTypeArrayKlass.hpp"
+#include "ci/ciUtilities.hpp"
+#include "gc/shared/cardTable.hpp"
#include "gc/shared/cardTableModRefBS.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
@@ -475,22 +477,21 @@ void LIRGenerator::store_stack_parameter(LIR_Opr item, ByteSize offset_from_sp)
}
void LIRGenerator::set_card(LIR_Opr value, LIR_Address* card_addr) {
- assert(CardTableModRefBS::dirty_card_val() == 0,
+ assert(CardTable::dirty_card_val() == 0,
"Cannot use ZR register (aarch64) or the register containing the card table base address directly (aarch32) otherwise");
#ifdef AARCH64
// AARCH64 has a register that is constant zero. We can use that one to set the
// value in the card table to dirty.
__ move(FrameMap::ZR_opr, card_addr);
#else // AARCH64
- CardTableModRefBS* ct = (CardTableModRefBS*)_bs;
- if(((intx)ct->byte_map_base & 0xff) == 0) {
+ if((ci_card_table_address_as() & 0xff) == 0) {
// If the card table base address is aligned to 256 bytes, we can use the register
// that contains the card_table_base_address.
__ move(value, card_addr);
} else {
// Otherwise we need to create a register containing that value.
LIR_Opr tmp_zero = new_register(T_INT);
- __ move(LIR_OprFact::intConst(CardTableModRefBS::dirty_card_val()), tmp_zero);
+ __ move(LIR_OprFact::intConst(CardTable::dirty_card_val()), tmp_zero);
__ move(tmp_zero, card_addr);
}
#endif // AARCH64
@@ -510,14 +511,14 @@ void LIRGenerator::CardTableModRef_post_barrier_helper(LIR_OprDesc* addr, LIR_Co
}
#ifdef AARCH64
- LIR_Address* shifted_reg_operand = new LIR_Address(tmp, addr, (LIR_Address::Scale) -CardTableModRefBS::card_shift, 0, T_BYTE);
+ LIR_Address* shifted_reg_operand = new LIR_Address(tmp, addr, (LIR_Address::Scale) -CardTable::card_shift, 0, T_BYTE);
LIR_Opr tmp2 = tmp;
- __ add(tmp, LIR_OprFact::address(shifted_reg_operand), tmp2); // tmp2 = tmp + (addr >> CardTableModRefBS::card_shift)
+ __ add(tmp, LIR_OprFact::address(shifted_reg_operand), tmp2); // tmp2 = tmp + (addr >> CardTable::card_shift)
LIR_Address* card_addr = new LIR_Address(tmp2, T_BYTE);
#else
// Use unsigned type T_BOOLEAN here rather than (signed) T_BYTE since signed load
// byte instruction does not support the addressing mode we need.
- LIR_Address* card_addr = new LIR_Address(tmp, addr, (LIR_Address::Scale) -CardTableModRefBS::card_shift, 0, T_BOOLEAN);
+ LIR_Address* card_addr = new LIR_Address(tmp, addr, (LIR_Address::Scale) -CardTable::card_shift, 0, T_BOOLEAN);
#endif
if (UseCondCardMark) {
if (UseConcMarkSweepGC) {
@@ -527,7 +528,7 @@ void LIRGenerator::CardTableModRef_post_barrier_helper(LIR_OprDesc* addr, LIR_Co
__ move(card_addr, cur_value);
LabelObj* L_already_dirty = new LabelObj();
- __ cmp(lir_cond_equal, cur_value, LIR_OprFact::intConst(CardTableModRefBS::dirty_card_val()));
+ __ cmp(lir_cond_equal, cur_value, LIR_OprFact::intConst(CardTable::dirty_card_val()));
__ branch(lir_cond_equal, T_BYTE, L_already_dirty->label());
set_card(tmp, card_addr);
__ branch_destination(L_already_dirty->label());
diff --git a/src/hotspot/cpu/arm/c1_Runtime1_arm.cpp b/src/hotspot/cpu/arm/c1_Runtime1_arm.cpp
index a4a969c87fa..4b98dd8ca1f 100644
--- a/src/hotspot/cpu/arm/c1_Runtime1_arm.cpp
+++ b/src/hotspot/cpu/arm/c1_Runtime1_arm.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2017, 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
@@ -28,6 +28,9 @@
#include "c1/c1_LIRAssembler.hpp"
#include "c1/c1_MacroAssembler.hpp"
#include "c1/c1_Runtime1.hpp"
+#include "ci/ciUtilities.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "gc/shared/cardTableModRefBS.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_arm.hpp"
#include "oops/compiledICHolder.hpp"
@@ -40,6 +43,7 @@
#include "utilities/align.hpp"
#include "vmreg_arm.inline.hpp"
#if INCLUDE_ALL_GCS
+#include "gc/g1/g1CardTable.hpp"
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
#endif
@@ -608,8 +612,6 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
__ set_info("g1_post_barrier_slow_id", dont_gc_arguments);
- BarrierSet* bs = Universe::heap()->barrier_set();
- CardTableModRefBS* ct = barrier_set_cast(bs);
Label done;
Label recheck;
Label runtime;
@@ -619,8 +621,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
Address buffer(Rthread, in_bytes(JavaThread::dirty_card_queue_offset() +
DirtyCardQueue::byte_offset_of_buf()));
- AddressLiteral cardtable((address)ct->byte_map_base, relocInfo::none);
- assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
+ AddressLiteral cardtable(ci_card_table_address_as(), relocInfo::none);
// save at least the registers that need saving if the runtime is called
#ifdef AARCH64
@@ -649,12 +650,12 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
// explicitly specify that 'cardtable' has a relocInfo::none
// type.
__ lea(r_card_base_1, cardtable);
- __ add(r_card_addr_0, r_card_base_1, AsmOperand(r_obj_0, lsr, CardTableModRefBS::card_shift));
+ __ add(r_card_addr_0, r_card_base_1, AsmOperand(r_obj_0, lsr, CardTable::card_shift));
// first quick check without barrier
__ ldrb(r_tmp2, Address(r_card_addr_0));
- __ cmp(r_tmp2, (int)G1SATBCardTableModRefBS::g1_young_card_val());
+ __ cmp(r_tmp2, (int)G1CardTable::g1_young_card_val());
__ b(recheck, ne);
__ bind(done);
@@ -675,14 +676,14 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
// reload card state after the barrier that ensures the stored oop was visible
__ ldrb(r_tmp2, Address(r_card_addr_0));
- assert(CardTableModRefBS::dirty_card_val() == 0, "adjust this code");
+ assert(CardTable::dirty_card_val() == 0, "adjust this code");
__ cbz(r_tmp2, done);
// storing region crossing non-NULL, card is clean.
// dirty card and log.
- assert(0 == (int)CardTableModRefBS::dirty_card_val(), "adjust this code");
- if (((intptr_t)ct->byte_map_base & 0xff) == 0) {
+ assert(0 == (int)CardTable::dirty_card_val(), "adjust this code");
+ if ((ci_card_table_address_as() & 0xff) == 0) {
// Card table is aligned so the lowest byte of the table address base is zero.
__ strb(r_card_base_1, Address(r_card_addr_0));
} else {
@@ -722,10 +723,10 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
const Register result = R0;
const Register klass = R1;
- if (UseTLAB && FastTLABRefill && id != new_instance_id) {
+ if (UseTLAB && Universe::heap()->supports_inline_contig_alloc() && id != new_instance_id) {
// We come here when TLAB allocation failed.
- // In this case we either refill TLAB or allocate directly from eden.
- Label retry_tlab, try_eden, slow_case, slow_case_no_pop;
+ // In this case we try to allocate directly from eden.
+ Label slow_case, slow_case_no_pop;
// Make sure the class is fully initialized
if (id == fast_new_instance_init_check_id) {
@@ -742,17 +743,6 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
__ raw_push(R4, R5, LR);
- __ tlab_refill(result, obj_size, tmp1, tmp2, obj_end, try_eden, slow_case);
-
- __ bind(retry_tlab);
- __ ldr_u32(obj_size, Address(klass, Klass::layout_helper_offset()));
- __ tlab_allocate(result, obj_end, tmp1, obj_size, slow_case); // initializes result and obj_end
- __ initialize_object(result, obj_end, klass, noreg /* len */, tmp1, tmp2,
- instanceOopDesc::header_size() * HeapWordSize, -1,
- /* is_tlab_allocated */ true);
- __ raw_pop_and_ret(R4, R5);
-
- __ bind(try_eden);
__ ldr_u32(obj_size, Address(klass, Klass::layout_helper_offset()));
__ eden_allocate(result, obj_end, tmp1, tmp2, obj_size, slow_case); // initializes result and obj_end
__ incr_allocated_bytes(obj_size, tmp2);
@@ -803,10 +793,10 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
const Register klass = R1;
const Register length = R2;
- if (UseTLAB && FastTLABRefill) {
+ if (UseTLAB && Universe::heap()->supports_inline_contig_alloc()) {
// We come here when TLAB allocation failed.
- // In this case we either refill TLAB or allocate directly from eden.
- Label retry_tlab, try_eden, slow_case, slow_case_no_pop;
+ // In this case we try to allocate directly from eden.
+ Label slow_case, slow_case_no_pop;
#ifdef AARCH64
__ mov_slow(Rtemp, C1_MacroAssembler::max_array_allocation_length);
@@ -825,40 +815,6 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
__ raw_push(R4, R5, LR);
- __ tlab_refill(result, arr_size, tmp1, tmp2, tmp3, try_eden, slow_case);
-
- __ bind(retry_tlab);
- // Get the allocation size: round_up((length << (layout_helper & 0xff)) + header_size)
- __ ldr_u32(tmp1, Address(klass, Klass::layout_helper_offset()));
- __ mov(arr_size, MinObjAlignmentInBytesMask);
- __ and_32(tmp2, tmp1, (unsigned int)(Klass::_lh_header_size_mask << Klass::_lh_header_size_shift));
-
-#ifdef AARCH64
- __ lslv_w(tmp3, length, tmp1);
- __ add(arr_size, arr_size, tmp3);
-#else
- __ add(arr_size, arr_size, AsmOperand(length, lsl, tmp1));
-#endif // AARCH64
-
- __ add(arr_size, arr_size, AsmOperand(tmp2, lsr, Klass::_lh_header_size_shift));
- __ align_reg(arr_size, arr_size, MinObjAlignmentInBytes);
-
- // tlab_allocate initializes result and obj_end, and preserves tmp2 which contains header_size
- __ tlab_allocate(result, obj_end, tmp1, arr_size, slow_case);
-
- assert_different_registers(result, obj_end, klass, length, tmp1, tmp2);
- __ initialize_header(result, klass, length, tmp1);
-
- __ add(tmp2, result, AsmOperand(tmp2, lsr, Klass::_lh_header_size_shift));
- if (!ZeroTLAB) {
- __ initialize_body(tmp2, obj_end, tmp1);
- }
-
- __ membar(MacroAssembler::StoreStore, tmp1);
-
- __ raw_pop_and_ret(R4, R5);
-
- __ bind(try_eden);
// Get the allocation size: round_up((length << (layout_helper & 0xff)) + header_size)
__ ldr_u32(tmp1, Address(klass, Klass::layout_helper_offset()));
__ mov(arr_size, MinObjAlignmentInBytesMask);
diff --git a/src/hotspot/cpu/arm/interp_masm_arm.cpp b/src/hotspot/cpu/arm/interp_masm_arm.cpp
index d3b6feb11d7..09a5a583f1c 100644
--- a/src/hotspot/cpu/arm/interp_masm_arm.cpp
+++ b/src/hotspot/cpu/arm/interp_masm_arm.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "jvm.h"
#include "gc/shared/barrierSet.inline.hpp"
+#include "gc/shared/cardTable.hpp"
#include "gc/shared/cardTableModRefBS.inline.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "interp_masm_arm.hpp"
@@ -410,12 +411,12 @@ void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass,
void InterpreterMacroAssembler::store_check_part1(Register card_table_base) {
// Check barrier set type (should be card table) and element size
BarrierSet* bs = Universe::heap()->barrier_set();
- assert(bs->kind() == BarrierSet::CardTableForRS ||
- bs->kind() == BarrierSet::CardTableExtension,
+ assert(bs->kind() == BarrierSet::CardTableModRef,
"Wrong barrier set kind");
- CardTableModRefBS* ct = barrier_set_cast(bs);
- assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "Adjust store check code");
+ CardTableModRefBS* ctbs = barrier_set_cast(bs);
+ CardTable* ct = ctbs->card_table();
+ assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "Adjust store check code");
// Load card table base address.
@@ -433,19 +434,19 @@ void InterpreterMacroAssembler::store_check_part1(Register card_table_base) {
rarely accessed area of thread descriptor).
*/
// TODO-AARCH64 Investigate if mov_slow is faster than ldr from Rthread on AArch64
- mov_address(card_table_base, (address)ct->byte_map_base, symbolic_Relocation::card_table_reference);
+ mov_address(card_table_base, (address)ct->byte_map_base(), symbolic_Relocation::card_table_reference);
}
// The 2nd part of the store check.
void InterpreterMacroAssembler::store_check_part2(Register obj, Register card_table_base, Register tmp) {
assert_different_registers(obj, card_table_base, tmp);
- assert(CardTableModRefBS::dirty_card_val() == 0, "Dirty card value must be 0 due to optimizations.");
+ assert(CardTable::dirty_card_val() == 0, "Dirty card value must be 0 due to optimizations.");
#ifdef AARCH64
- add(card_table_base, card_table_base, AsmOperand(obj, lsr, CardTableModRefBS::card_shift));
+ add(card_table_base, card_table_base, AsmOperand(obj, lsr, CardTable::card_shift));
Address card_table_addr(card_table_base);
#else
- Address card_table_addr(card_table_base, obj, lsr, CardTableModRefBS::card_shift);
+ Address card_table_addr(card_table_base, obj, lsr, CardTable::card_shift);
#endif
if (UseCondCardMark) {
@@ -472,8 +473,9 @@ void InterpreterMacroAssembler::set_card(Register card_table_base, Address card_
#ifdef AARCH64
strb(ZR, card_table_addr);
#else
- CardTableModRefBS* ct = barrier_set_cast(Universe::heap()->barrier_set());
- if ((((uintptr_t)ct->byte_map_base & 0xff) == 0)) {
+ CardTableModRefBS* ctbs = barrier_set_cast(Universe::heap()->barrier_set());
+ CardTable* ct = ctbs->card_table();
+ if ((((uintptr_t)ct->byte_map_base() & 0xff) == 0)) {
// Card table is aligned so the lowest byte of the table address base is zero.
// This works only if the code is not saved for later use, possibly
// in a context where the base would no longer be aligned.
diff --git a/src/hotspot/cpu/arm/macroAssembler_arm.cpp b/src/hotspot/cpu/arm/macroAssembler_arm.cpp
index 7bdc89a67d8..880cd746528 100644
--- a/src/hotspot/cpu/arm/macroAssembler_arm.cpp
+++ b/src/hotspot/cpu/arm/macroAssembler_arm.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2017, 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
@@ -29,6 +29,7 @@
#include "ci/ciEnv.hpp"
#include "code/nativeInst.hpp"
#include "compiler/disassembler.hpp"
+#include "gc/shared/cardTable.hpp"
#include "gc/shared/cardTableModRefBS.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/interpreter.hpp"
@@ -43,6 +44,7 @@
#include "runtime/stubRoutines.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
+#include "gc/g1/g1CardTable.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
#include "gc/g1/heapRegion.hpp"
@@ -1316,98 +1318,6 @@ void MacroAssembler::tlab_allocate(Register obj, Register obj_end, Register tmp1
str(obj_end, Address(Rthread, JavaThread::tlab_top_offset()));
}
-void MacroAssembler::tlab_refill(Register top, Register tmp1, Register tmp2,
- Register tmp3, Register tmp4,
- Label& try_eden, Label& slow_case) {
- if (!Universe::heap()->supports_inline_contig_alloc()) {
- b(slow_case);
- return;
- }
-
- InlinedAddress intArrayKlass_addr((address)Universe::intArrayKlassObj_addr());
- Label discard_tlab, do_refill;
- ldr(top, Address(Rthread, JavaThread::tlab_top_offset()));
- ldr(tmp1, Address(Rthread, JavaThread::tlab_end_offset()));
- ldr(tmp2, Address(Rthread, JavaThread::tlab_refill_waste_limit_offset()));
-
- // Calculate amount of free space
- sub(tmp1, tmp1, top);
- // Retain tlab and allocate in shared space
- // if the amount of free space in tlab is too large to discard
- cmp(tmp2, AsmOperand(tmp1, lsr, LogHeapWordSize));
- b(discard_tlab, ge);
-
- // Increment waste limit to prevent getting stuck on this slow path
- mov_slow(tmp3, ThreadLocalAllocBuffer::refill_waste_limit_increment());
- add(tmp2, tmp2, tmp3);
- str(tmp2, Address(Rthread, JavaThread::tlab_refill_waste_limit_offset()));
- if (TLABStats) {
- ldr_u32(tmp2, Address(Rthread, JavaThread::tlab_slow_allocations_offset()));
- add_32(tmp2, tmp2, 1);
- str_32(tmp2, Address(Rthread, JavaThread::tlab_slow_allocations_offset()));
- }
- b(try_eden);
- bind_literal(intArrayKlass_addr);
-
- bind(discard_tlab);
- if (TLABStats) {
- ldr_u32(tmp2, Address(Rthread, JavaThread::tlab_number_of_refills_offset()));
- ldr_u32(tmp3, Address(Rthread, JavaThread::tlab_fast_refill_waste_offset()));
- add_32(tmp2, tmp2, 1);
- add_32(tmp3, tmp3, AsmOperand(tmp1, lsr, LogHeapWordSize));
- str_32(tmp2, Address(Rthread, JavaThread::tlab_number_of_refills_offset()));
- str_32(tmp3, Address(Rthread, JavaThread::tlab_fast_refill_waste_offset()));
- }
- // If tlab is currently allocated (top or end != null)
- // then fill [top, end + alignment_reserve) with array object
- cbz(top, do_refill);
-
- // Set up the mark word
- mov_slow(tmp2, (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2));
- str(tmp2, Address(top, oopDesc::mark_offset_in_bytes()));
- // Set klass to intArrayKlass and the length to the remaining space
- ldr_literal(tmp2, intArrayKlass_addr);
- add(tmp1, tmp1, ThreadLocalAllocBuffer::alignment_reserve_in_bytes() -
- typeArrayOopDesc::header_size(T_INT) * HeapWordSize);
- Register klass = tmp2;
- ldr(klass, Address(tmp2));
- logical_shift_right(tmp1, tmp1, LogBytesPerInt); // divide by sizeof(jint)
- str_32(tmp1, Address(top, arrayOopDesc::length_offset_in_bytes()));
- store_klass(klass, top); // blows klass:
- klass = noreg;
-
- ldr(tmp1, Address(Rthread, JavaThread::tlab_start_offset()));
- sub(tmp1, top, tmp1); // size of tlab's allocated portion
- incr_allocated_bytes(tmp1, tmp2);
-
- bind(do_refill);
- // Refill the tlab with an eden allocation
- ldr(tmp1, Address(Rthread, JavaThread::tlab_size_offset()));
- logical_shift_left(tmp4, tmp1, LogHeapWordSize);
- eden_allocate(top, tmp1, tmp2, tmp3, tmp4, slow_case);
- str(top, Address(Rthread, JavaThread::tlab_start_offset()));
- str(top, Address(Rthread, JavaThread::tlab_top_offset()));
-
-#ifdef ASSERT
- // Verify that tmp1 contains tlab_end
- ldr(tmp2, Address(Rthread, JavaThread::tlab_size_offset()));
- add(tmp2, top, AsmOperand(tmp2, lsl, LogHeapWordSize));
- cmp(tmp1, tmp2);
- breakpoint(ne);
-#endif
-
- sub(tmp1, tmp1, ThreadLocalAllocBuffer::alignment_reserve_in_bytes());
- str(tmp1, Address(Rthread, JavaThread::tlab_end_offset()));
-
- if (ZeroTLAB) {
- // clobbers start and tmp
- // top must be preserved!
- add(tmp1, tmp1, ThreadLocalAllocBuffer::alignment_reserve_in_bytes());
- ldr(tmp2, Address(Rthread, JavaThread::tlab_start_offset()));
- zero_memory(tmp2, tmp1, tmp3);
- }
-}
-
// Fills memory regions [start..end] with zeroes. Clobbers `start` and `tmp` registers.
void MacroAssembler::zero_memory(Register start, Register end, Register tmp) {
Label loop;
@@ -2357,7 +2267,8 @@ void MacroAssembler::g1_write_barrier_post(Register store_addr,
DirtyCardQueue::byte_offset_of_buf()));
BarrierSet* bs = Universe::heap()->barrier_set();
- CardTableModRefBS* ct = (CardTableModRefBS*)bs;
+ CardTableModRefBS* ctbs = barrier_set_cast(bs);
+ CardTable* ct = ctbs->card_table();
Label done;
Label runtime;
@@ -2378,18 +2289,18 @@ void MacroAssembler::g1_write_barrier_post(Register store_addr,
// storing region crossing non-NULL, is card already dirty?
const Register card_addr = tmp1;
- assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
+ assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
- mov_address(tmp2, (address)ct->byte_map_base, symbolic_Relocation::card_table_reference);
- add(card_addr, tmp2, AsmOperand(store_addr, lsr, CardTableModRefBS::card_shift));
+ mov_address(tmp2, (address)ct->byte_map_base(), symbolic_Relocation::card_table_reference);
+ add(card_addr, tmp2, AsmOperand(store_addr, lsr, CardTable::card_shift));
ldrb(tmp2, Address(card_addr));
- cmp(tmp2, (int)G1SATBCardTableModRefBS::g1_young_card_val());
+ cmp(tmp2, (int)G1CardTable::g1_young_card_val());
b(done, eq);
membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreLoad), tmp2);
- assert(CardTableModRefBS::dirty_card_val() == 0, "adjust this code");
+ assert(CardTable::dirty_card_val() == 0, "adjust this code");
ldrb(tmp2, Address(card_addr));
cbz(tmp2, done);
@@ -3115,7 +3026,6 @@ void MacroAssembler::set_narrow_oop(Register dst, jobject obj) {
}
#endif // COMPILER2
-
// Must preserve condition codes, or C2 encodeKlass_not_null rule
// must be changed.
void MacroAssembler::encode_klass_not_null(Register r) {
@@ -3353,4 +3263,3 @@ void MacroAssembler::fast_unlock(Register Roop, Register Rbox, Register Rscratch
}
#endif // COMPILER2
-
diff --git a/src/hotspot/cpu/arm/macroAssembler_arm.hpp b/src/hotspot/cpu/arm/macroAssembler_arm.hpp
index 4462a38cab5..63c262393df 100644
--- a/src/hotspot/cpu/arm/macroAssembler_arm.hpp
+++ b/src/hotspot/cpu/arm/macroAssembler_arm.hpp
@@ -359,8 +359,6 @@ public:
void tlab_allocate(Register obj, Register obj_end, Register tmp1,
RegisterOrConstant size_expression, Label& slow_case);
- void tlab_refill(Register top, Register tmp1, Register tmp2, Register tmp3, Register tmp4,
- Label& try_eden, Label& slow_case);
void zero_memory(Register start, Register end, Register tmp);
void incr_allocated_bytes(RegisterOrConstant size_in_bytes, Register tmp);
diff --git a/src/hotspot/cpu/arm/stubGenerator_arm.cpp b/src/hotspot/cpu/arm/stubGenerator_arm.cpp
index ec1a6d8279d..5e2e52e619d 100644
--- a/src/hotspot/cpu/arm/stubGenerator_arm.cpp
+++ b/src/hotspot/cpu/arm/stubGenerator_arm.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
#include "precompiled.hpp"
#include "asm/assembler.hpp"
#include "assembler_arm.inline.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "gc/shared/cardTableModRefBS.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_arm.hpp"
#include "oops/instanceOop.hpp"
@@ -2907,8 +2909,7 @@ class StubGenerator: public StubCodeGenerator {
__ pop(saved_regs | R9ifScratched);
#endif // AARCH64
}
- case BarrierSet::CardTableForRS:
- case BarrierSet::CardTableExtension:
+ case BarrierSet::CardTableModRef:
break;
default:
ShouldNotReachHere();
@@ -2961,12 +2962,12 @@ class StubGenerator: public StubCodeGenerator {
#endif // !AARCH64
}
break;
- case BarrierSet::CardTableForRS:
- case BarrierSet::CardTableExtension:
+ case BarrierSet::CardTableModRef:
{
BLOCK_COMMENT("CardTablePostBarrier");
- CardTableModRefBS* ct = barrier_set_cast(bs);
- assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
+ CardTableModRefBS* ctbs = barrier_set_cast(bs);
+ CardTable* ct = ctbs->card_table();
+ assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
Label L_cardtable_loop, L_done;
@@ -2975,12 +2976,12 @@ class StubGenerator: public StubCodeGenerator {
__ add_ptr_scaled_int32(count, addr, count, LogBytesPerHeapOop);
__ sub(count, count, BytesPerHeapOop); // last addr
- __ logical_shift_right(addr, addr, CardTableModRefBS::card_shift);
- __ logical_shift_right(count, count, CardTableModRefBS::card_shift);
+ __ logical_shift_right(addr, addr, CardTable::card_shift);
+ __ logical_shift_right(count, count, CardTable::card_shift);
__ sub(count, count, addr); // nb of cards
// warning: Rthread has not been preserved
- __ mov_address(tmp, (address) ct->byte_map_base, symbolic_Relocation::card_table_reference);
+ __ mov_address(tmp, (address) ct->byte_map_base(), symbolic_Relocation::card_table_reference);
__ add(addr,tmp, addr);
Register zero = __ zero_register(tmp);
@@ -2992,8 +2993,6 @@ class StubGenerator: public StubCodeGenerator {
__ BIND(L_done);
}
break;
- case BarrierSet::ModRef:
- break;
default:
ShouldNotReachHere();
}
diff --git a/src/hotspot/cpu/arm/templateTable_arm.cpp b/src/hotspot/cpu/arm/templateTable_arm.cpp
index 3b35418b01a..736f6cedb7d 100644
--- a/src/hotspot/cpu/arm/templateTable_arm.cpp
+++ b/src/hotspot/cpu/arm/templateTable_arm.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2017, 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
@@ -228,8 +228,7 @@ static void do_oop_store(InterpreterMacroAssembler* _masm,
}
break;
#endif // INCLUDE_ALL_GCS
- case BarrierSet::CardTableForRS:
- case BarrierSet::CardTableExtension:
+ case BarrierSet::CardTableModRef:
{
if (is_null) {
__ store_heap_oop_null(new_val, obj);
diff --git a/src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp b/src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp
index 0c68f5a4c8b..a1932b72872 100644
--- a/src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp
+++ b/src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp
@@ -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.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -27,6 +27,9 @@
#include "c1/c1_Defs.hpp"
#include "c1/c1_MacroAssembler.hpp"
#include "c1/c1_Runtime1.hpp"
+#include "ci/ciUtilities.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "gc/shared/cardTableModRefBS.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_ppc.hpp"
#include "oops/compiledICHolder.hpp"
@@ -40,6 +43,7 @@
#include "utilities/macros.hpp"
#include "vmreg_ppc.inline.hpp"
#if INCLUDE_ALL_GCS
+#include "gc/g1/g1CardTable.hpp"
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
#endif
@@ -413,34 +417,9 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
assert(id == fast_new_instance_init_check_id, "bad StubID");
__ set_info("fast new_instance init check", dont_gc_arguments);
}
+
// We don't support eden allocation.
-// if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) &&
-// UseTLAB && FastTLABRefill) {
-// if (id == fast_new_instance_init_check_id) {
-// // make sure the klass is initialized
-// __ lbz(R0, in_bytes(InstanceKlass::init_state_offset()), R3_ARG1);
-// __ cmpwi(CCR0, R0, InstanceKlass::fully_initialized);
-// __ bne(CCR0, slow_path);
-// }
-//#ifdef ASSERT
-// // assert object can be fast path allocated
-// {
-// Label ok, not_ok;
-// __ lwz(R0, in_bytes(Klass::layout_helper_offset()), R3_ARG1);
-// // make sure it's an instance (LH > 0)
-// __ cmpwi(CCR0, R0, 0);
-// __ ble(CCR0, not_ok);
-// __ testbitdi(CCR0, R0, R0, Klass::_lh_instance_slow_path_bit);
-// __ beq(CCR0, ok);
-//
-// __ bind(not_ok);
-// __ stop("assert(can be fast path allocated)");
-// __ bind(ok);
-// }
-//#endif // ASSERT
-// // We don't support eden allocation.
-// __ bind(slow_path);
-// }
+
oop_maps = generate_stub_call(sasm, R3_RET, CAST_FROM_FN_PTR(address, new_instance), R4_ARG2);
}
break;
@@ -820,7 +799,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
Register tmp = R0;
Register addr = R14;
Register tmp2 = R15;
- jbyte* byte_map_base = ((CardTableModRefBS*)bs)->byte_map_base;
+ jbyte* byte_map_base = ci_card_table_address();
Label restart, refill, ret;
@@ -828,26 +807,26 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
__ std(addr, -8, R1_SP);
__ std(tmp2, -16, R1_SP);
- __ srdi(addr, R0, CardTableModRefBS::card_shift); // Addr is passed in R0.
+ __ srdi(addr, R0, CardTable::card_shift); // Addr is passed in R0.
__ load_const_optimized(/*cardtable*/ tmp2, byte_map_base, tmp);
__ add(addr, tmp2, addr);
__ lbz(tmp, 0, addr); // tmp := [addr + cardtable]
// Return if young card.
- __ cmpwi(CCR0, tmp, G1SATBCardTableModRefBS::g1_young_card_val());
+ __ cmpwi(CCR0, tmp, G1CardTable::g1_young_card_val());
__ beq(CCR0, ret);
// Return if sequential consistent value is already dirty.
__ membar(Assembler::StoreLoad);
__ lbz(tmp, 0, addr); // tmp := [addr + cardtable]
- __ cmpwi(CCR0, tmp, G1SATBCardTableModRefBS::dirty_card_val());
+ __ cmpwi(CCR0, tmp, G1CardTable::dirty_card_val());
__ beq(CCR0, ret);
// Not dirty.
// First, dirty it.
- __ li(tmp, G1SATBCardTableModRefBS::dirty_card_val());
+ __ li(tmp, G1CardTable::dirty_card_val());
__ stb(tmp, 0, addr);
int dirty_card_q_index_byte_offset =
diff --git a/src/hotspot/cpu/ppc/frame_ppc.cpp b/src/hotspot/cpu/ppc/frame_ppc.cpp
index 7437d33fc5c..1369aaef7ec 100644
--- a/src/hotspot/cpu/ppc/frame_ppc.cpp
+++ b/src/hotspot/cpu/ppc/frame_ppc.cpp
@@ -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.
* Copyright (c) 2012, 2017 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -32,6 +32,7 @@
#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp"
+#include "runtime/jniHandles.inline.hpp"
#include "runtime/monitorChunk.hpp"
#include "runtime/signature.hpp"
#include "runtime/stubCodeGenerator.hpp"
diff --git a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp
index cecb696b079..46cd68b1fbb 100644
--- a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp
+++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp
@@ -26,6 +26,7 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.inline.hpp"
#include "compiler/disassembler.hpp"
+#include "gc/shared/cardTable.hpp"
#include "gc/shared/cardTableModRefBS.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/interpreter.hpp"
@@ -43,6 +44,7 @@
#include "runtime/stubRoutines.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
+#include "gc/g1/g1CardTable.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
#include "gc/g1/heapRegion.hpp"
@@ -2336,9 +2338,6 @@ void MacroAssembler::tlab_allocate(
std(new_top, in_bytes(JavaThread::tlab_top_offset()), R16_thread);
//verify_tlab(); not implemented
}
-void MacroAssembler::tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case) {
- unimplemented("tlab_refill");
-}
void MacroAssembler::incr_allocated_bytes(RegisterOrConstant size_in_bytes, Register t1, Register t2) {
unimplemented("incr_allocated_bytes");
}
@@ -3039,20 +3038,20 @@ void MacroAssembler::safepoint_poll(Label& slow_path, Register temp_reg) {
void MacroAssembler::card_write_barrier_post(Register Rstore_addr, Register Rnew_val, Register Rtmp) {
CardTableModRefBS* bs =
barrier_set_cast(Universe::heap()->barrier_set());
- assert(bs->kind() == BarrierSet::CardTableForRS ||
- bs->kind() == BarrierSet::CardTableExtension, "wrong barrier");
+ assert(bs->kind() == BarrierSet::CardTableModRef, "wrong barrier");
+ CardTable* ct = bs->card_table();
#ifdef ASSERT
cmpdi(CCR0, Rnew_val, 0);
asm_assert_ne("null oop not allowed", 0x321);
#endif
- card_table_write(bs->byte_map_base, Rtmp, Rstore_addr);
+ card_table_write(ct->byte_map_base(), Rtmp, Rstore_addr);
}
// Write the card table byte.
void MacroAssembler::card_table_write(jbyte* byte_map_base, Register Rtmp, Register Robj) {
assert_different_registers(Robj, Rtmp, R0);
load_const_optimized(Rtmp, (address)byte_map_base, R0);
- srdi(Robj, Robj, CardTableModRefBS::card_shift);
+ srdi(Robj, Robj, CardTable::card_shift);
li(R0, 0); // dirty
if (UseConcMarkSweepGC) membar(Assembler::StoreStore);
stbx(R0, Rtmp, Robj);
@@ -3174,6 +3173,7 @@ void MacroAssembler::g1_write_barrier_post(Register Rstore_addr, Register Rnew_v
G1SATBCardTableLoggingModRefBS* bs =
barrier_set_cast(Universe::heap()->barrier_set());
+ CardTable* ct = bs->card_table();
// Does store cross heap regions?
if (G1RSBarrierRegionFilter) {
@@ -3190,26 +3190,26 @@ void MacroAssembler::g1_write_barrier_post(Register Rstore_addr, Register Rnew_v
#endif
// Storing region crossing non-NULL, is card already dirty?
- assert(sizeof(*bs->byte_map_base) == sizeof(jbyte), "adjust this code");
+ assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
const Register Rcard_addr = Rtmp1;
Register Rbase = Rtmp2;
- load_const_optimized(Rbase, (address)bs->byte_map_base, /*temp*/ Rtmp3);
+ load_const_optimized(Rbase, (address)ct->byte_map_base(), /*temp*/ Rtmp3);
- srdi(Rcard_addr, Rstore_addr, CardTableModRefBS::card_shift);
+ srdi(Rcard_addr, Rstore_addr, CardTable::card_shift);
// Get the address of the card.
lbzx(/*card value*/ Rtmp3, Rbase, Rcard_addr);
- cmpwi(CCR0, Rtmp3, (int)G1SATBCardTableModRefBS::g1_young_card_val());
+ cmpwi(CCR0, Rtmp3, (int)G1CardTable::g1_young_card_val());
beq(CCR0, filtered);
membar(Assembler::StoreLoad);
lbzx(/*card value*/ Rtmp3, Rbase, Rcard_addr); // Reload after membar.
- cmpwi(CCR0, Rtmp3 /* card value */, CardTableModRefBS::dirty_card_val());
+ cmpwi(CCR0, Rtmp3 /* card value */, CardTable::dirty_card_val());
beq(CCR0, filtered);
// Storing a region crossing, non-NULL oop, card is clean.
// Dirty card and log.
- li(Rtmp3, CardTableModRefBS::dirty_card_val());
+ li(Rtmp3, CardTable::dirty_card_val());
//release(); // G1: oops are allowed to get visible after dirty marking.
stbx(Rtmp3, Rbase, Rcard_addr);
diff --git a/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp b/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp
index ee48fc2ff37..0d9b8c2cbf0 100644
--- a/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp
+++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp
@@ -602,7 +602,6 @@ class MacroAssembler: public Assembler {
Register t1, // temp register
Label& slow_case // continuation point if fast allocation fails
);
- void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case);
void incr_allocated_bytes(RegisterOrConstant size_in_bytes, Register t1, Register t2);
enum { trampoline_stub_size = 6 * 4 };
diff --git a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp
index 7c535a4e20f..8364c63b834 100644
--- a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp
+++ b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp
@@ -25,6 +25,8 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.inline.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "gc/shared/cardTableModRefBS.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_ppc.hpp"
#include "oops/instanceOop.hpp"
@@ -667,9 +669,7 @@ class StubGenerator: public StubCodeGenerator {
__ bind(filtered);
}
break;
- case BarrierSet::CardTableForRS:
- case BarrierSet::CardTableExtension:
- case BarrierSet::ModRef:
+ case BarrierSet::CardTableModRef:
break;
default:
ShouldNotReachHere();
@@ -703,8 +703,7 @@ class StubGenerator: public StubCodeGenerator {
__ restore_LR_CR(R0);
}
break;
- case BarrierSet::CardTableForRS:
- case BarrierSet::CardTableExtension:
+ case BarrierSet::CardTableModRef:
{
Label Lskip_loop, Lstore_loop;
if (UseConcMarkSweepGC) {
@@ -712,19 +711,20 @@ class StubGenerator: public StubCodeGenerator {
__ release();
}
- CardTableModRefBS* const ct = barrier_set_cast(bs);
- assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
+ CardTableModRefBS* const ctbs = barrier_set_cast(bs);
+ CardTable* const ct = ctbs->card_table();
+ assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
assert_different_registers(addr, count, tmp);
__ sldi(count, count, LogBytesPerHeapOop);
__ addi(count, count, -BytesPerHeapOop);
__ add(count, addr, count);
// Use two shifts to clear out those low order two bits! (Cannot opt. into 1.)
- __ srdi(addr, addr, CardTableModRefBS::card_shift);
- __ srdi(count, count, CardTableModRefBS::card_shift);
+ __ srdi(addr, addr, CardTable::card_shift);
+ __ srdi(count, count, CardTable::card_shift);
__ subf(count, addr, count);
assert_different_registers(R0, addr, count, tmp);
- __ load_const(tmp, (address)ct->byte_map_base);
+ __ load_const(tmp, (address)ct->byte_map_base());
__ addic_(count, count, 1);
__ beq(CCR0, Lskip_loop);
__ li(R0, 0);
diff --git a/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp b/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp
index 0ca24ff9475..58aa98683b3 100644
--- a/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp
+++ b/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp
@@ -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.
* Copyright (c) 2013, 2017 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -103,8 +103,7 @@ static void do_oop_store(InterpreterMacroAssembler* _masm,
}
break;
#endif // INCLUDE_ALL_GCS
- case BarrierSet::CardTableForRS:
- case BarrierSet::CardTableExtension:
+ case BarrierSet::CardTableModRef:
{
Label Lnull, Ldone;
if (Rval != noreg) {
diff --git a/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp b/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp
index 4f3c0950ad2..bf4cf4666b7 100644
--- a/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp
+++ b/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp
@@ -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.
* Copyright (c) 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -27,6 +27,9 @@
#include "c1/c1_Defs.hpp"
#include "c1/c1_MacroAssembler.hpp"
#include "c1/c1_Runtime1.hpp"
+#include "ci/ciUtilities.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "gc/shared/cardTableModRefBS.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_s390.hpp"
#include "oops/compiledICHolder.hpp"
@@ -40,6 +43,7 @@
#include "vmreg_s390.inline.hpp"
#include "registerSaver_s390.hpp"
#if INCLUDE_ALL_GCS
+#include "gc/g1/g1CardTable.hpp"
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
#endif
@@ -346,11 +350,6 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
__ set_info("fast new_instance init check", dont_gc_arguments);
}
- if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) &&
- UseTLAB && FastTLABRefill) {
- // Sapjvm: must call RT to generate allocation events.
- }
-
OopMap* map = save_live_registers_except_r2(sasm);
int call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_instance), klass);
oop_maps = new OopMapSet();
@@ -411,10 +410,6 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
}
#endif // ASSERT
- if (UseTLAB && FastTLABRefill) {
- // sapjvm: must call RT to generate allocation events.
- }
-
OopMap* map = save_live_registers_except_r2(sasm);
int call_offset;
if (id == new_type_array_id) {
@@ -854,7 +849,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
Register r1 = Z_R6; // Must be saved/restored.
Register r2 = Z_R7; // Must be saved/restored.
Register cardtable = r1; // Must be non-volatile, because it is used to save addr_card.
- jbyte* byte_map_base = ((CardTableModRefBS*)bs)->byte_map_base;
+ jbyte* byte_map_base = ci_card_table_address();
// Save registers used below (see assertion in G1PreBarrierStub::emit_code()).
__ z_stg(r1, 0*BytesPerWord + FrameMap::first_available_sp_in_frame, Z_SP);
@@ -863,17 +858,17 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
// Calculate address of card corresponding to the updated oop slot.
AddressLiteral rs(byte_map_base);
- __ z_srlg(addr_card, addr_oop, CardTableModRefBS::card_shift);
+ __ z_srlg(addr_card, addr_oop, CardTable::card_shift);
addr_oop = noreg; // dead now
__ load_const_optimized(cardtable, rs); // cardtable :=
__ z_agr(addr_card, cardtable); // addr_card := addr_oop>>card_shift + cardtable
- __ z_cli(0, addr_card, (int)G1SATBCardTableModRefBS::g1_young_card_val());
+ __ z_cli(0, addr_card, (int)G1CardTable::g1_young_card_val());
__ z_bre(young_card);
__ z_sync(); // Required to support concurrent cleaning.
- __ z_cli(0, addr_card, (int)CardTableModRefBS::dirty_card_val());
+ __ z_cli(0, addr_card, (int)CardTable::dirty_card_val());
__ z_brne(not_already_dirty);
__ bind(young_card);
@@ -886,7 +881,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
__ bind(not_already_dirty);
// First, dirty it: [addr_card] := 0
- __ z_mvi(0, addr_card, CardTableModRefBS::dirty_card_val());
+ __ z_mvi(0, addr_card, CardTable::dirty_card_val());
Register idx = cardtable; // Must be non-volatile, because it is used to save addr_card.
Register buf = r2;
diff --git a/src/hotspot/cpu/s390/macroAssembler_s390.cpp b/src/hotspot/cpu/s390/macroAssembler_s390.cpp
index 01358f5909d..3580ef6868a 100644
--- a/src/hotspot/cpu/s390/macroAssembler_s390.cpp
+++ b/src/hotspot/cpu/s390/macroAssembler_s390.cpp
@@ -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.
* Copyright (c) 2016, 2017, SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -27,6 +27,7 @@
#include "asm/codeBuffer.hpp"
#include "asm/macroAssembler.inline.hpp"
#include "compiler/disassembler.hpp"
+#include "gc/shared/cardTable.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/interpreter.hpp"
#include "gc/shared/cardTableModRefBS.hpp"
@@ -50,6 +51,7 @@
#include "utilities/events.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
+#include "gc/g1/g1CardTable.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
#include "gc/g1/heapRegion.hpp"
@@ -3502,12 +3504,13 @@ void MacroAssembler::compiler_fast_unlock_object(Register oop, Register box, Reg
// Write to card table for modification at store_addr - register is destroyed afterwards.
void MacroAssembler::card_write_barrier_post(Register store_addr, Register tmp) {
- CardTableModRefBS* bs = (CardTableModRefBS*) Universe::heap()->barrier_set();
- assert(bs->kind() == BarrierSet::CardTableForRS ||
- bs->kind() == BarrierSet::CardTableExtension, "wrong barrier");
+ BarrierSet* bs = Universe::heap()->barrier_set();
+ CardTableModRefBS* ctbs = barrier_set_cast(bs);
+ CardTable* ct = ctbs->card_table();
+ assert(bs->kind() == BarrierSet::CardTableModRef, "wrong barrier");
assert_different_registers(store_addr, tmp);
- z_srlg(store_addr, store_addr, CardTableModRefBS::card_shift);
- load_absolute_address(tmp, (address)bs->byte_map_base);
+ z_srlg(store_addr, store_addr, CardTable::card_shift);
+ load_absolute_address(tmp, (address)ct->byte_map_base());
z_agr(store_addr, tmp);
z_mvi(0, store_addr, 0); // Store byte 0.
}
@@ -3707,6 +3710,7 @@ void MacroAssembler::g1_write_barrier_post(Register Rstore_addr,
assert_different_registers(Rstore_addr, Rnew_val, Rtmp1, Rtmp2); // Most probably, Rnew_val == Rtmp3.
G1SATBCardTableModRefBS* bs = (G1SATBCardTableModRefBS*) Universe::heap()->barrier_set();
+ CardTable* ct = bs->card_table();
assert(bs->kind() == BarrierSet::G1SATBCTLogging, "wrong barrier");
BLOCK_COMMENT("g1_write_barrier_post {");
@@ -3733,33 +3737,33 @@ void MacroAssembler::g1_write_barrier_post(Register Rstore_addr,
Rnew_val = noreg; // end of lifetime
// Storing region crossing non-NULL, is card already dirty?
- assert(sizeof(*bs->byte_map_base) == sizeof(jbyte), "adjust this code");
+ assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
assert_different_registers(Rtmp1, Rtmp2, Rtmp3);
// Make sure not to use Z_R0 for any of these registers.
Register Rcard_addr = (Rtmp1 != Z_R0_scratch) ? Rtmp1 : Rtmp3;
Register Rbase = (Rtmp2 != Z_R0_scratch) ? Rtmp2 : Rtmp3;
// calculate address of card
- load_const_optimized(Rbase, (address)bs->byte_map_base); // Card table base.
- z_srlg(Rcard_addr, Rstore_addr, CardTableModRefBS::card_shift); // Index into card table.
+ load_const_optimized(Rbase, (address)ct->byte_map_base()); // Card table base.
+ z_srlg(Rcard_addr, Rstore_addr, CardTable::card_shift); // Index into card table.
z_algr(Rcard_addr, Rbase); // Explicit calculation needed for cli.
Rbase = noreg; // end of lifetime
// Filter young.
- assert((unsigned int)G1SATBCardTableModRefBS::g1_young_card_val() <= 255, "otherwise check this code");
- z_cli(0, Rcard_addr, (int)G1SATBCardTableModRefBS::g1_young_card_val());
+ assert((unsigned int)G1CardTable::g1_young_card_val() <= 255, "otherwise check this code");
+ z_cli(0, Rcard_addr, (int)G1CardTable::g1_young_card_val());
z_bre(filtered);
// Check the card value. If dirty, we're done.
// This also avoids false sharing of the (already dirty) card.
z_sync(); // Required to support concurrent cleaning.
- assert((unsigned int)CardTableModRefBS::dirty_card_val() <= 255, "otherwise check this code");
- z_cli(0, Rcard_addr, CardTableModRefBS::dirty_card_val()); // Reload after membar.
+ assert((unsigned int)CardTable::dirty_card_val() <= 255, "otherwise check this code");
+ z_cli(0, Rcard_addr, CardTable::dirty_card_val()); // Reload after membar.
z_bre(filtered);
// Storing a region crossing, non-NULL oop, card is clean.
// Dirty card and log.
- z_mvi(0, Rcard_addr, CardTableModRefBS::dirty_card_val());
+ z_mvi(0, Rcard_addr, CardTable::dirty_card_val());
Register Rcard_addr_x = Rcard_addr;
Register Rqueue_index = (Rtmp2 != Z_R0_scratch) ? Rtmp2 : Rtmp1;
diff --git a/src/hotspot/cpu/s390/stubGenerator_s390.cpp b/src/hotspot/cpu/s390/stubGenerator_s390.cpp
index d779e90c042..f58510c74b3 100644
--- a/src/hotspot/cpu/s390/stubGenerator_s390.cpp
+++ b/src/hotspot/cpu/s390/stubGenerator_s390.cpp
@@ -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.
* Copyright (c) 2016, 2017, SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -26,6 +26,8 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.inline.hpp"
#include "registerSaver_s390.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "gc/shared/cardTableModRefBS.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interp_masm.hpp"
#include "nativeInst_s390.hpp"
@@ -722,8 +724,7 @@ class StubGenerator: public StubCodeGenerator {
__ bind(filtered);
}
break;
- case BarrierSet::CardTableForRS:
- case BarrierSet::CardTableExtension:
+ case BarrierSet::CardTableModRef:
case BarrierSet::ModRef:
break;
default:
@@ -761,14 +762,14 @@ class StubGenerator: public StubCodeGenerator {
}
}
break;
- case BarrierSet::CardTableForRS:
- case BarrierSet::CardTableExtension:
+ case BarrierSet::CardTableModRef:
// These cases formerly known as
// void array_store_check(Register addr, Register count, bool branchToEnd).
{
NearLabel doXC, done;
- CardTableModRefBS* ct = (CardTableModRefBS*)bs;
- assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
+ CardTableModRefBS* ctbs = barrier_set_cast(bs);
+ CardTable* ct = ctbs->card_table();
+ assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
assert_different_registers(Z_R0, Z_R1, addr, count);
// Nothing to do if count <= 0.
@@ -787,11 +788,11 @@ class StubGenerator: public StubCodeGenerator {
__ add2reg_with_index(count, -BytesPerHeapOop, count, addr);
// Get base address of card table.
- __ load_const_optimized(Z_R1, (address)ct->byte_map_base);
+ __ load_const_optimized(Z_R1, (address)ct->byte_map_base());
// count = (count>>shift) - (addr>>shift)
- __ z_srlg(addr, addr, CardTableModRefBS::card_shift);
- __ z_srlg(count, count, CardTableModRefBS::card_shift);
+ __ z_srlg(addr, addr, CardTable::card_shift);
+ __ z_srlg(count, count, CardTable::card_shift);
// Prefetch first elements of card table for update.
if (VM_Version::has_Prefetch()) {
diff --git a/src/hotspot/cpu/s390/templateTable_s390.cpp b/src/hotspot/cpu/s390/templateTable_s390.cpp
index ce02eecd8b4..6b80d69386e 100644
--- a/src/hotspot/cpu/s390/templateTable_s390.cpp
+++ b/src/hotspot/cpu/s390/templateTable_s390.cpp
@@ -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.
* Copyright (c) 2016, 2017 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -260,8 +260,7 @@ static void do_oop_store(InterpreterMacroAssembler* _masm,
}
break;
#endif // INCLUDE_ALL_GCS
- case BarrierSet::CardTableForRS:
- case BarrierSet::CardTableExtension:
+ case BarrierSet::CardTableModRef:
{
if (val_is_null) {
__ store_heap_oop_null(val, offset, base);
diff --git a/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp b/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp
index b96a1945cc5..558f311708a 100644
--- a/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp
+++ b/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp
@@ -35,6 +35,7 @@
#include "gc/shared/collectedHeap.hpp"
#include "nativeInst_sparc.hpp"
#include "oops/objArrayKlass.hpp"
+#include "runtime/jniHandles.inline.hpp"
#include "runtime/safepointMechanism.inline.hpp"
#include "runtime/sharedRuntime.hpp"
diff --git a/src/hotspot/cpu/sparc/c1_Runtime1_sparc.cpp b/src/hotspot/cpu/sparc/c1_Runtime1_sparc.cpp
index baadab70bac..cd9a1d39ec5 100644
--- a/src/hotspot/cpu/sparc/c1_Runtime1_sparc.cpp
+++ b/src/hotspot/cpu/sparc/c1_Runtime1_sparc.cpp
@@ -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
@@ -26,6 +26,9 @@
#include "c1/c1_Defs.hpp"
#include "c1/c1_MacroAssembler.hpp"
#include "c1/c1_Runtime1.hpp"
+#include "ci/ciUtilities.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "gc/shared/cardTableModRefBS.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_sparc.hpp"
#include "oops/compiledICHolder.hpp"
@@ -38,6 +41,7 @@
#include "utilities/align.hpp"
#include "vmreg_sparc.inline.hpp"
#if INCLUDE_ALL_GCS
+#include "gc/g1/g1CardTable.hpp"
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
#endif
@@ -389,7 +393,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
}
if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) &&
- UseTLAB && FastTLABRefill) {
+ UseTLAB && Universe::heap()->supports_inline_contig_alloc()) {
Label slow_path;
Register G1_obj_size = G1;
Register G3_t1 = G3;
@@ -424,25 +428,8 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
__ bind(ok);
}
#endif // ASSERT
- // if we got here then the TLAB allocation failed, so try
- // refilling the TLAB or allocating directly from eden.
- Label retry_tlab, try_eden;
- __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves G5_klass
- __ bind(retry_tlab);
-
- // get the instance size
- __ ld(G5_klass, in_bytes(Klass::layout_helper_offset()), G1_obj_size);
-
- __ tlab_allocate(O0_obj, G1_obj_size, 0, G3_t1, slow_path);
-
- __ initialize_object(O0_obj, G5_klass, G1_obj_size, 0, G3_t1, G4_t2, /* is_tlab_allocated */ true);
- __ verify_oop(O0_obj);
- __ mov(O0, I0);
- __ ret();
- __ delayed()->restore();
-
- __ bind(try_eden);
+ // If we got here then the TLAB allocation failed, so try allocating directly from eden.
// get the instance size
__ ld(G5_klass, in_bytes(Klass::layout_helper_offset()), G1_obj_size);
__ eden_allocate(O0_obj, G1_obj_size, 0, G3_t1, G4_t2, slow_path);
@@ -508,73 +495,6 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
}
#endif // ASSERT
- if (UseTLAB && FastTLABRefill) {
- Label slow_path;
- Register G1_arr_size = G1;
- Register G3_t1 = G3;
- Register O1_t2 = O1;
- assert_different_registers(G5_klass, G4_length, G1_arr_size, G3_t1, O1_t2);
-
- // check that array length is small enough for fast path
- __ set(C1_MacroAssembler::max_array_allocation_length, G3_t1);
- __ cmp(G4_length, G3_t1);
- __ br(Assembler::greaterUnsigned, false, Assembler::pn, slow_path);
- __ delayed()->nop();
-
- // if we got here then the TLAB allocation failed, so try
- // refilling the TLAB or allocating directly from eden.
- Label retry_tlab, try_eden;
- __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves G4_length and G5_klass
-
- __ bind(retry_tlab);
-
- // get the allocation size: (length << (layout_helper & 0x1F)) + header_size
- __ ld(klass_lh, G3_t1);
- __ sll(G4_length, G3_t1, G1_arr_size);
- __ srl(G3_t1, Klass::_lh_header_size_shift, G3_t1);
- __ and3(G3_t1, Klass::_lh_header_size_mask, G3_t1);
- __ add(G1_arr_size, G3_t1, G1_arr_size);
- __ add(G1_arr_size, MinObjAlignmentInBytesMask, G1_arr_size); // align up
- __ and3(G1_arr_size, ~MinObjAlignmentInBytesMask, G1_arr_size);
-
- __ tlab_allocate(O0_obj, G1_arr_size, 0, G3_t1, slow_path); // preserves G1_arr_size
-
- __ initialize_header(O0_obj, G5_klass, G4_length, G3_t1, O1_t2);
- __ ldub(klass_lh, G3_t1, klass_lh_header_size_offset);
- __ sub(G1_arr_size, G3_t1, O1_t2); // body length
- __ add(O0_obj, G3_t1, G3_t1); // body start
- if (!ZeroTLAB) {
- __ initialize_body(G3_t1, O1_t2);
- }
- __ verify_oop(O0_obj);
- __ retl();
- __ delayed()->nop();
-
- __ bind(try_eden);
- // get the allocation size: (length << (layout_helper & 0x1F)) + header_size
- __ ld(klass_lh, G3_t1);
- __ sll(G4_length, G3_t1, G1_arr_size);
- __ srl(G3_t1, Klass::_lh_header_size_shift, G3_t1);
- __ and3(G3_t1, Klass::_lh_header_size_mask, G3_t1);
- __ add(G1_arr_size, G3_t1, G1_arr_size);
- __ add(G1_arr_size, MinObjAlignmentInBytesMask, G1_arr_size);
- __ and3(G1_arr_size, ~MinObjAlignmentInBytesMask, G1_arr_size);
-
- __ eden_allocate(O0_obj, G1_arr_size, 0, G3_t1, O1_t2, slow_path); // preserves G1_arr_size
- __ incr_allocated_bytes(G1_arr_size, G3_t1, O1_t2);
-
- __ initialize_header(O0_obj, G5_klass, G4_length, G3_t1, O1_t2);
- __ ldub(klass_lh, G3_t1, klass_lh_header_size_offset);
- __ sub(G1_arr_size, G3_t1, O1_t2); // body length
- __ add(O0_obj, G3_t1, G3_t1); // body start
- __ initialize_body(G3_t1, O1_t2);
- __ verify_oop(O0_obj);
- __ retl();
- __ delayed()->nop();
-
- __ bind(slow_path);
- }
-
if (id == new_type_array_id) {
oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_type_array), G5_klass, G4_length);
} else {
@@ -927,22 +847,22 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
Register cardtable = G5;
Register tmp = G1_scratch;
Register tmp2 = G3_scratch;
- jbyte* byte_map_base = barrier_set_cast(bs)->byte_map_base;
+ jbyte* byte_map_base = ci_card_table_address();
Label not_already_dirty, restart, refill, young_card;
- __ srlx(addr, CardTableModRefBS::card_shift, addr);
+ __ srlx(addr, CardTable::card_shift, addr);
AddressLiteral rs(byte_map_base);
__ set(rs, cardtable); // cardtable :=
__ ldub(addr, cardtable, tmp); // tmp := [addr + cardtable]
- __ cmp_and_br_short(tmp, G1SATBCardTableModRefBS::g1_young_card_val(), Assembler::equal, Assembler::pt, young_card);
+ __ cmp_and_br_short(tmp, G1CardTable::g1_young_card_val(), Assembler::equal, Assembler::pt, young_card);
__ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
__ ldub(addr, cardtable, tmp); // tmp := [addr + cardtable]
- assert(CardTableModRefBS::dirty_card_val() == 0, "otherwise check this code");
+ assert(CardTable::dirty_card_val() == 0, "otherwise check this code");
__ cmp_and_br_short(tmp, G0, Assembler::notEqual, Assembler::pt, not_already_dirty);
__ bind(young_card);
diff --git a/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp b/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp
index ded9e99ea8d..b86e4ef0fa2 100644
--- a/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp
+++ b/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
#include "jvm.h"
#include "asm/macroAssembler.inline.hpp"
#include "compiler/disassembler.hpp"
+#include "gc/shared/cardTable.hpp"
#include "gc/shared/cardTableModRefBS.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/interpreter.hpp"
@@ -35,6 +36,7 @@
#include "prims/methodHandles.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/interfaceSupport.hpp"
+#include "runtime/jniHandles.inline.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/os.inline.hpp"
#include "runtime/safepoint.hpp"
@@ -44,6 +46,7 @@
#include "utilities/align.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
+#include "gc/g1/g1CardTable.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
#include "gc/g1/heapRegion.hpp"
@@ -658,7 +661,7 @@ void MacroAssembler::ic_call(address entry, bool emit_delay, jint method_index)
void MacroAssembler::card_table_write(jbyte* byte_map_base,
Register tmp, Register obj) {
- srlx(obj, CardTableModRefBS::card_shift, obj);
+ srlx(obj, CardTable::card_shift, obj);
assert(tmp != obj, "need separate temp reg");
set((address) byte_map_base, tmp);
stb(G0, tmp, obj);
@@ -3242,127 +3245,6 @@ void MacroAssembler::tlab_allocate(
verify_tlab();
}
-
-void MacroAssembler::tlab_refill(Label& retry, Label& try_eden, Label& slow_case) {
- Register top = O0;
- Register t1 = G1;
- Register t2 = G3;
- Register t3 = O1;
- assert_different_registers(top, t1, t2, t3, G4, G5 /* preserve G4 and G5 */);
- Label do_refill, discard_tlab;
-
- if (!Universe::heap()->supports_inline_contig_alloc()) {
- // No allocation in the shared eden.
- ba(slow_case);
- delayed()->nop();
- }
-
- ld_ptr(G2_thread, in_bytes(JavaThread::tlab_top_offset()), top);
- ld_ptr(G2_thread, in_bytes(JavaThread::tlab_end_offset()), t1);
- ld_ptr(G2_thread, in_bytes(JavaThread::tlab_refill_waste_limit_offset()), t2);
-
- // calculate amount of free space
- sub(t1, top, t1);
- srl_ptr(t1, LogHeapWordSize, t1);
-
- // Retain tlab and allocate object in shared space if
- // the amount free in the tlab is too large to discard.
- cmp(t1, t2);
-
- brx(Assembler::lessEqual, false, Assembler::pt, discard_tlab);
- // increment waste limit to prevent getting stuck on this slow path
- if (Assembler::is_simm13(ThreadLocalAllocBuffer::refill_waste_limit_increment())) {
- delayed()->add(t2, ThreadLocalAllocBuffer::refill_waste_limit_increment(), t2);
- } else {
- delayed()->nop();
- // set64 does not use the temp register if the given constant is 32 bit. So
- // we can just use any register; using G0 results in ignoring of the upper 32 bit
- // of that value.
- set64(ThreadLocalAllocBuffer::refill_waste_limit_increment(), t3, G0);
- add(t2, t3, t2);
- }
-
- st_ptr(t2, G2_thread, in_bytes(JavaThread::tlab_refill_waste_limit_offset()));
- if (TLABStats) {
- // increment number of slow_allocations
- ld(G2_thread, in_bytes(JavaThread::tlab_slow_allocations_offset()), t2);
- add(t2, 1, t2);
- stw(t2, G2_thread, in_bytes(JavaThread::tlab_slow_allocations_offset()));
- }
- ba(try_eden);
- delayed()->nop();
-
- bind(discard_tlab);
- if (TLABStats) {
- // increment number of refills
- ld(G2_thread, in_bytes(JavaThread::tlab_number_of_refills_offset()), t2);
- add(t2, 1, t2);
- stw(t2, G2_thread, in_bytes(JavaThread::tlab_number_of_refills_offset()));
- // accumulate wastage
- ld(G2_thread, in_bytes(JavaThread::tlab_fast_refill_waste_offset()), t2);
- add(t2, t1, t2);
- stw(t2, G2_thread, in_bytes(JavaThread::tlab_fast_refill_waste_offset()));
- }
-
- // if tlab is currently allocated (top or end != null) then
- // fill [top, end + alignment_reserve) with array object
- br_null_short(top, Assembler::pn, do_refill);
-
- set((intptr_t)markOopDesc::prototype()->copy_set_hash(0x2), t2);
- st_ptr(t2, top, oopDesc::mark_offset_in_bytes()); // set up the mark word
- // set klass to intArrayKlass
- sub(t1, typeArrayOopDesc::header_size(T_INT), t1);
- add(t1, ThreadLocalAllocBuffer::alignment_reserve(), t1);
- sll_ptr(t1, log2_intptr(HeapWordSize/sizeof(jint)), t1);
- st(t1, top, arrayOopDesc::length_offset_in_bytes());
- set((intptr_t)Universe::intArrayKlassObj_addr(), t2);
- ld_ptr(t2, 0, t2);
- // store klass last. concurrent gcs assumes klass length is valid if
- // klass field is not null.
- store_klass(t2, top);
- verify_oop(top);
-
- ld_ptr(G2_thread, in_bytes(JavaThread::tlab_start_offset()), t1);
- sub(top, t1, t1); // size of tlab's allocated portion
- incr_allocated_bytes(t1, t2, t3);
-
- // refill the tlab with an eden allocation
- bind(do_refill);
- ld_ptr(G2_thread, in_bytes(JavaThread::tlab_size_offset()), t1);
- sll_ptr(t1, LogHeapWordSize, t1);
- // allocate new tlab, address returned in top
- eden_allocate(top, t1, 0, t2, t3, slow_case);
-
- st_ptr(top, G2_thread, in_bytes(JavaThread::tlab_start_offset()));
- st_ptr(top, G2_thread, in_bytes(JavaThread::tlab_top_offset()));
-#ifdef ASSERT
- // check that tlab_size (t1) is still valid
- {
- Label ok;
- ld_ptr(G2_thread, in_bytes(JavaThread::tlab_size_offset()), t2);
- sll_ptr(t2, LogHeapWordSize, t2);
- cmp_and_br_short(t1, t2, Assembler::equal, Assembler::pt, ok);
- STOP("assert(t1 == tlab_size)");
- should_not_reach_here();
-
- bind(ok);
- }
-#endif // ASSERT
- add(top, t1, top); // t1 is tlab_size
- sub(top, ThreadLocalAllocBuffer::alignment_reserve_in_bytes(), top);
- st_ptr(top, G2_thread, in_bytes(JavaThread::tlab_end_offset()));
-
- if (ZeroTLAB) {
- // This is a fast TLAB refill, therefore the GC is not notified of it.
- // So compiled code must fill the new TLAB with zeroes.
- ld_ptr(G2_thread, in_bytes(JavaThread::tlab_start_offset()), t2);
- zero_memory(t2, t1);
- }
- verify_tlab();
- ba(retry);
- delayed()->nop();
-}
-
void MacroAssembler::zero_memory(Register base, Register index) {
assert_different_registers(base, index);
Label loop;
@@ -3695,17 +3577,17 @@ static void generate_dirty_card_log_enqueue(jbyte* byte_map_base) {
Label not_already_dirty, restart, refill, young_card;
- __ srlx(O0, CardTableModRefBS::card_shift, O0);
+ __ srlx(O0, CardTable::card_shift, O0);
AddressLiteral addrlit(byte_map_base);
__ set(addrlit, O1); // O1 :=
__ ldub(O0, O1, O2); // O2 := [O0 + O1]
- __ cmp_and_br_short(O2, G1SATBCardTableModRefBS::g1_young_card_val(), Assembler::equal, Assembler::pt, young_card);
+ __ cmp_and_br_short(O2, G1CardTable::g1_young_card_val(), Assembler::equal, Assembler::pt, young_card);
__ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
__ ldub(O0, O1, O2); // O2 := [O0 + O1]
- assert(CardTableModRefBS::dirty_card_val() == 0, "otherwise check this code");
+ assert(CardTable::dirty_card_val() == 0, "otherwise check this code");
__ cmp_and_br_short(O2, G0, Assembler::notEqual, Assembler::pt, not_already_dirty);
__ bind(young_card);
@@ -3785,6 +3667,7 @@ void MacroAssembler::g1_write_barrier_post(Register store_addr, Register new_val
G1SATBCardTableLoggingModRefBS* bs =
barrier_set_cast(Universe::heap()->barrier_set());
+ CardTable* ct = bs->card_table();
if (G1RSBarrierRegionFilter) {
xor3(store_addr, new_val, tmp);
@@ -3825,7 +3708,8 @@ void g1_barrier_stubs_init() {
if (dirty_card_log_enqueue == 0) {
G1SATBCardTableLoggingModRefBS* bs =
barrier_set_cast(heap->barrier_set());
- generate_dirty_card_log_enqueue(bs->byte_map_base);
+ CardTable *ct = bs->card_table();
+ generate_dirty_card_log_enqueue(ct->byte_map_base());
assert(dirty_card_log_enqueue != 0, "postcondition.");
}
if (satb_log_enqueue_with_frame == 0) {
@@ -3847,9 +3731,10 @@ void MacroAssembler::card_write_barrier_post(Register store_addr, Register new_v
if (new_val == G0) return;
CardTableModRefBS* bs =
barrier_set_cast(Universe::heap()->barrier_set());
- assert(bs->kind() == BarrierSet::CardTableForRS ||
- bs->kind() == BarrierSet::CardTableExtension, "wrong barrier");
- card_table_write(bs->byte_map_base, tmp, store_addr);
+ CardTable* ct = bs->card_table();
+
+ assert(bs->kind() == BarrierSet::CardTableModRef, "wrong barrier");
+ card_table_write(ct->byte_map_base(), tmp, store_addr);
}
// ((OopHandle)result).resolve();
diff --git a/src/hotspot/cpu/sparc/macroAssembler_sparc.hpp b/src/hotspot/cpu/sparc/macroAssembler_sparc.hpp
index 62beb5c390a..67f74b47c3e 100644
--- a/src/hotspot/cpu/sparc/macroAssembler_sparc.hpp
+++ b/src/hotspot/cpu/sparc/macroAssembler_sparc.hpp
@@ -1266,7 +1266,6 @@ public:
Register t1, // temp register
Label& slow_case // continuation point if fast allocation fails
);
- void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case);
void zero_memory(Register base, Register index);
void incr_allocated_bytes(RegisterOrConstant size_in_bytes,
Register t1, Register t2);
diff --git a/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp b/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp
index 1966926c413..06ef48ed2dc 100644
--- a/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp
+++ b/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp
@@ -24,6 +24,8 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.inline.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "gc/shared/cardTableModRefBS.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_sparc.hpp"
#include "oops/instanceOop.hpp"
@@ -875,9 +877,7 @@ class StubGenerator: public StubCodeGenerator {
DEBUG_ONLY(__ set(0xDEADC0DE, tmp);) // we have killed tmp
}
break;
- case BarrierSet::CardTableForRS:
- case BarrierSet::CardTableExtension:
- case BarrierSet::ModRef:
+ case BarrierSet::CardTableModRef:
break;
default:
ShouldNotReachHere();
@@ -908,11 +908,11 @@ class StubGenerator: public StubCodeGenerator {
__ restore();
}
break;
- case BarrierSet::CardTableForRS:
- case BarrierSet::CardTableExtension:
+ case BarrierSet::CardTableModRef:
{
- CardTableModRefBS* ct = barrier_set_cast(bs);
- assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
+ CardTableModRefBS* ctbs = barrier_set_cast(bs);
+ CardTable* ct = ctbs->card_table();
+ assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
assert_different_registers(addr, count, tmp);
Label L_loop, L_done;
@@ -923,10 +923,10 @@ class StubGenerator: public StubCodeGenerator {
__ sub(count, BytesPerHeapOop, count);
__ add(count, addr, count);
// Use two shifts to clear out those low order two bits! (Cannot opt. into 1.)
- __ srl_ptr(addr, CardTableModRefBS::card_shift, addr);
- __ srl_ptr(count, CardTableModRefBS::card_shift, count);
+ __ srl_ptr(addr, CardTable::card_shift, addr);
+ __ srl_ptr(count, CardTable::card_shift, count);
__ sub(count, addr, count);
- AddressLiteral rs(ct->byte_map_base);
+ AddressLiteral rs(ct->byte_map_base());
__ set(rs, tmp);
__ BIND(L_loop);
__ stb(G0, tmp, addr);
diff --git a/src/hotspot/cpu/sparc/templateTable_sparc.cpp b/src/hotspot/cpu/sparc/templateTable_sparc.cpp
index c135a163633..b44d89645fd 100644
--- a/src/hotspot/cpu/sparc/templateTable_sparc.cpp
+++ b/src/hotspot/cpu/sparc/templateTable_sparc.cpp
@@ -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
@@ -90,8 +90,7 @@ static void do_oop_store(InterpreterMacroAssembler* _masm,
}
break;
#endif // INCLUDE_ALL_GCS
- case BarrierSet::CardTableForRS:
- case BarrierSet::CardTableExtension:
+ case BarrierSet::CardTableModRef:
{
if (index == noreg ) {
assert(Assembler::is_simm13(offset), "fix this code");
diff --git a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp
index 9b5601be6ee..d7e01a8f917 100644
--- a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp
+++ b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp
@@ -529,12 +529,16 @@ void LIR_Assembler::return_op(LIR_Opr result) {
if (SafepointMechanism::uses_thread_local_poll()) {
#ifdef _LP64
- __ movptr(rscratch1, Address(r15_thread, Thread::polling_page_offset()));
- __ relocate(relocInfo::poll_return_type);
- __ testl(rax, Address(rscratch1, 0));
+ const Register poll_addr = rscratch1;
+ __ movptr(poll_addr, Address(r15_thread, Thread::polling_page_offset()));
#else
- ShouldNotReachHere();
+ const Register poll_addr = rbx;
+ assert(FrameMap::is_caller_save_register(poll_addr), "will overwrite");
+ __ get_thread(poll_addr);
+ __ movptr(poll_addr, Address(poll_addr, Thread::polling_page_offset()));
#endif
+ __ relocate(relocInfo::poll_return_type);
+ __ testl(rax, Address(poll_addr, 0));
} else {
AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type);
@@ -555,16 +559,20 @@ int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) {
int offset = __ offset();
if (SafepointMechanism::uses_thread_local_poll()) {
#ifdef _LP64
- __ movptr(rscratch1, Address(r15_thread, Thread::polling_page_offset()));
+ const Register poll_addr = rscratch1;
+ __ movptr(poll_addr, Address(r15_thread, Thread::polling_page_offset()));
+#else
+ assert(tmp->is_cpu_register(), "needed");
+ const Register poll_addr = tmp->as_register();
+ __ get_thread(poll_addr);
+ __ movptr(poll_addr, Address(poll_addr, in_bytes(Thread::polling_page_offset())));
+#endif
add_debug_info_for_branch(info);
__ relocate(relocInfo::poll_type);
address pre_pc = __ pc();
- __ testl(rax, Address(rscratch1, 0));
+ __ testl(rax, Address(poll_addr, 0));
address post_pc = __ pc();
- guarantee(pointer_delta(post_pc, pre_pc, 1) == 3, "must be exact length");
-#else
- ShouldNotReachHere();
-#endif
+ guarantee(pointer_delta(post_pc, pre_pc, 1) == 2 LP64_ONLY(+1), "must be exact length");
} else {
AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_type);
if (Assembler::is_polling_page_far()) {
diff --git a/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp b/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp
index b7dc39f7cd4..770aaa13b31 100644
--- a/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp
+++ b/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp
@@ -143,6 +143,7 @@ bool LIRGenerator::can_inline_as_constant(LIR_Const* c) const {
LIR_Opr LIRGenerator::safepoint_poll_register() {
+ NOT_LP64( if (SafepointMechanism::uses_thread_local_poll()) { return new_register(T_ADDRESS); } )
return LIR_OprFact::illegalOpr;
}
@@ -1515,7 +1516,7 @@ void LIRGenerator::do_If(If* x) {
if (x->is_safepoint()) {
// increment backedge counter if needed
increment_backedge_counter(state_for(x, x->state_before()), x->profiled_bci());
- __ safepoint(LIR_OprFact::illegalOpr, state_for(x, x->state_before()));
+ __ safepoint(safepoint_poll_register(), state_for(x, x->state_before()));
}
set_no_result(x);
diff --git a/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp b/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp
index 58db92dcd32..0b62ee7aeb5 100644
--- a/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp
+++ b/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp
@@ -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
@@ -27,6 +27,9 @@
#include "c1/c1_Defs.hpp"
#include "c1/c1_MacroAssembler.hpp"
#include "c1/c1_Runtime1.hpp"
+#include "ci/ciUtilities.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "gc/shared/cardTableModRefBS.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_x86.hpp"
#include "oops/compiledICHolder.hpp"
@@ -39,6 +42,7 @@
#include "utilities/macros.hpp"
#include "vmreg_x86.inline.hpp"
#if INCLUDE_ALL_GCS
+#include "gc/g1/g1CardTable.hpp"
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
#endif
@@ -994,8 +998,8 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
__ set_info("fast new_instance init check", dont_gc_arguments);
}
- if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) &&
- UseTLAB && FastTLABRefill) {
+ if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) && UseTLAB
+ && Universe::heap()->supports_inline_contig_alloc()) {
Label slow_path;
Register obj_size = rcx;
Register t1 = rbx;
@@ -1030,21 +1034,8 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
// if we got here then the TLAB allocation failed, so try
// refilling the TLAB or allocating directly from eden.
Label retry_tlab, try_eden;
- const Register thread =
- __ tlab_refill(retry_tlab, try_eden, slow_path); // does not destroy rdx (klass), returns rdi
-
- __ bind(retry_tlab);
-
- // get the instance size (size is postive so movl is fine for 64bit)
- __ movl(obj_size, Address(klass, Klass::layout_helper_offset()));
-
- __ tlab_allocate(obj, obj_size, 0, t1, t2, slow_path);
-
- __ initialize_object(obj, klass, obj_size, 0, t1, t2, /* is_tlab_allocated */ true);
- __ verify_oop(obj);
- __ pop(rbx);
- __ pop(rdi);
- __ ret(0);
+ const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread);
+ NOT_LP64(__ get_thread(thread));
__ bind(try_eden);
// get the instance size (size is postive so movl is fine for 64bit)
@@ -1128,54 +1119,14 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
}
#endif // ASSERT
- if (UseTLAB && FastTLABRefill) {
+ // If we got here, the TLAB allocation failed, so try allocating from
+ // eden if inline contiguous allocations are supported.
+ if (UseTLAB && Universe::heap()->supports_inline_contig_alloc()) {
Register arr_size = rsi;
Register t1 = rcx; // must be rcx for use as shift count
Register t2 = rdi;
Label slow_path;
- assert_different_registers(length, klass, obj, arr_size, t1, t2);
- // check that array length is small enough for fast path.
- __ cmpl(length, C1_MacroAssembler::max_array_allocation_length);
- __ jcc(Assembler::above, slow_path);
-
- // if we got here then the TLAB allocation failed, so try
- // refilling the TLAB or allocating directly from eden.
- Label retry_tlab, try_eden;
- const Register thread =
- __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves rbx & rdx, returns rdi
-
- __ bind(retry_tlab);
-
- // get the allocation size: round_up(hdr + length << (layout_helper & 0x1F))
- // since size is positive movl does right thing on 64bit
- __ movl(t1, Address(klass, Klass::layout_helper_offset()));
- // since size is postive movl does right thing on 64bit
- __ movl(arr_size, length);
- assert(t1 == rcx, "fixed register usage");
- __ shlptr(arr_size /* by t1=rcx, mod 32 */);
- __ shrptr(t1, Klass::_lh_header_size_shift);
- __ andptr(t1, Klass::_lh_header_size_mask);
- __ addptr(arr_size, t1);
- __ addptr(arr_size, MinObjAlignmentInBytesMask); // align up
- __ andptr(arr_size, ~MinObjAlignmentInBytesMask);
-
- __ tlab_allocate(obj, arr_size, 0, t1, t2, slow_path); // preserves arr_size
-
- __ initialize_header(obj, klass, length, t1, t2);
- __ movb(t1, Address(klass, in_bytes(Klass::layout_helper_offset()) + (Klass::_lh_header_size_shift / BitsPerByte)));
- assert(Klass::_lh_header_size_shift % BitsPerByte == 0, "bytewise");
- assert(Klass::_lh_header_size_mask <= 0xFF, "bytewise");
- __ andptr(t1, Klass::_lh_header_size_mask);
- __ subptr(arr_size, t1); // body length
- __ addptr(t1, obj); // body start
- if (!ZeroTLAB) {
- __ initialize_body(t1, arr_size, 0, t2);
- }
- __ verify_oop(obj);
- __ ret(0);
-
- __ bind(try_eden);
// get the allocation size: round_up(hdr + length << (layout_helper & 0x1F))
// since size is positive movl does right thing on 64bit
__ movl(t1, Address(klass, Klass::layout_helper_offset()));
@@ -1190,6 +1141,10 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
__ andptr(arr_size, ~MinObjAlignmentInBytesMask);
__ eden_allocate(obj, arr_size, 0, t1, slow_path); // preserves arr_size
+
+ // Using t2 for non 64-bit.
+ const Register thread = NOT_LP64(t2) LP64_ONLY(r15_thread);
+ NOT_LP64(__ get_thread(thread));
__ incr_allocated_bytes(thread, arr_size, 0);
__ initialize_header(obj, klass, length, t1, t2);
@@ -1681,10 +1636,6 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
// arg0: store_address
Address store_addr(rbp, 2*BytesPerWord);
- CardTableModRefBS* ct =
- barrier_set_cast(Universe::heap()->barrier_set());
- assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
-
Label done;
Label enqueued;
Label runtime;
@@ -1706,25 +1657,25 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
const Register card_addr = rcx;
f.load_argument(0, card_addr);
- __ shrptr(card_addr, CardTableModRefBS::card_shift);
+ __ shrptr(card_addr, CardTable::card_shift);
// Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT
// a valid address and therefore is not properly handled by the relocation code.
- __ movptr(cardtable, (intptr_t)ct->byte_map_base);
+ __ movptr(cardtable, ci_card_table_address_as());
__ addptr(card_addr, cardtable);
NOT_LP64(__ get_thread(thread);)
- __ cmpb(Address(card_addr, 0), (int)G1SATBCardTableModRefBS::g1_young_card_val());
+ __ cmpb(Address(card_addr, 0), (int)G1CardTable::g1_young_card_val());
__ jcc(Assembler::equal, done);
__ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
- __ cmpb(Address(card_addr, 0), (int)CardTableModRefBS::dirty_card_val());
+ __ cmpb(Address(card_addr, 0), (int)CardTable::dirty_card_val());
__ jcc(Assembler::equal, done);
// storing region crossing non-NULL, card is clean.
// dirty card and log.
- __ movb(Address(card_addr, 0), (int)CardTableModRefBS::dirty_card_val());
+ __ movb(Address(card_addr, 0), (int)CardTable::dirty_card_val());
const Register tmp = rdx;
__ push(rdx);
diff --git a/src/hotspot/cpu/x86/globalDefinitions_x86.hpp b/src/hotspot/cpu/x86/globalDefinitions_x86.hpp
index 421923659ce..94d1ee20eca 100644
--- a/src/hotspot/cpu/x86/globalDefinitions_x86.hpp
+++ b/src/hotspot/cpu/x86/globalDefinitions_x86.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -65,9 +65,6 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
#define SUPPORT_RESERVED_STACK_AREA
#endif
-#ifdef _LP64
-// X64 have implemented the local polling
#define THREAD_LOCAL_POLL
-#endif
#endif // CPU_X86_VM_GLOBALDEFINITIONS_X86_HPP
diff --git a/src/hotspot/cpu/x86/globals_x86.hpp b/src/hotspot/cpu/x86/globals_x86.hpp
index 63a10f6adcd..ce58234f382 100644
--- a/src/hotspot/cpu/x86/globals_x86.hpp
+++ b/src/hotspot/cpu/x86/globals_x86.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -97,9 +97,10 @@ define_pd_global(bool, PreserveFramePointer, false);
define_pd_global(intx, InitArrayShortSize, 8*BytesPerLong);
-#ifdef _LP64
+#if defined(_LP64) || defined(_WINDOWS)
define_pd_global(bool, ThreadLocalHandshakes, true);
#else
+// get_thread() is slow on linux 32 bit, therefore off by default
define_pd_global(bool, ThreadLocalHandshakes, false);
#endif
diff --git a/src/hotspot/cpu/x86/interp_masm_x86.cpp b/src/hotspot/cpu/x86/interp_masm_x86.cpp
index d819b37122e..879373effb5 100644
--- a/src/hotspot/cpu/x86/interp_masm_x86.cpp
+++ b/src/hotspot/cpu/x86/interp_masm_x86.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -830,13 +830,12 @@ void InterpreterMacroAssembler::dispatch_base(TosState state,
if (verifyoop) {
verify_oop(rax, state);
}
-#ifdef _LP64
- Label no_safepoint, dispatch;
address* const safepoint_table = Interpreter::safept_table(state);
+#ifdef _LP64
+ Label no_safepoint, dispatch;
if (SafepointMechanism::uses_thread_local_poll() && table != safepoint_table && generate_poll) {
NOT_PRODUCT(block_comment("Thread-local Safepoint poll"));
-
testb(Address(r15_thread, Thread::polling_page_offset()), SafepointMechanism::poll_bit());
jccb(Assembler::zero, no_safepoint);
@@ -851,9 +850,23 @@ void InterpreterMacroAssembler::dispatch_base(TosState state,
#else
Address index(noreg, rbx, Address::times_ptr);
- ExternalAddress tbl((address)table);
- ArrayAddress dispatch(tbl, index);
- jump(dispatch);
+ if (SafepointMechanism::uses_thread_local_poll() && table != safepoint_table && generate_poll) {
+ NOT_PRODUCT(block_comment("Thread-local Safepoint poll"));
+ Label no_safepoint;
+ const Register thread = rcx;
+ get_thread(thread);
+ testb(Address(thread, Thread::polling_page_offset()), SafepointMechanism::poll_bit());
+
+ jccb(Assembler::zero, no_safepoint);
+ ArrayAddress dispatch_addr(ExternalAddress((address)safepoint_table), index);
+ jump(dispatch_addr);
+ bind(no_safepoint);
+ }
+
+ {
+ ArrayAddress dispatch_addr(ExternalAddress((address)table), index);
+ jump(dispatch_addr);
+ }
#endif // _LP64
}
diff --git a/src/hotspot/cpu/x86/interpreterRT_x86_64.cpp b/src/hotspot/cpu/x86/interpreterRT_x86_64.cpp
index 53f03a38b6c..257fd3785c3 100644
--- a/src/hotspot/cpu/x86/interpreterRT_x86_64.cpp
+++ b/src/hotspot/cpu/x86/interpreterRT_x86_64.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -346,8 +346,9 @@ class SlowSignatureHandler
_from -= Interpreter::stackElementSize;
if (_num_args < Argument::n_float_register_parameters_c-1) {
+ assert((_num_args*2) < BitsPerWord, "_num_args*2 is out of range");
*_reg_args++ = from_obj;
- *_fp_identifiers |= (intptr_t)(0x01 << (_num_args*2)); // mark as float
+ *_fp_identifiers |= ((intptr_t)0x01 << (_num_args*2)); // mark as float
_num_args++;
} else {
*_to++ = from_obj;
@@ -360,8 +361,9 @@ class SlowSignatureHandler
_from -= 2*Interpreter::stackElementSize;
if (_num_args < Argument::n_float_register_parameters_c-1) {
+ assert((_num_args*2) < BitsPerWord, "_num_args*2 is out of range");
*_reg_args++ = from_obj;
- *_fp_identifiers |= (intptr_t)(0x3 << (_num_args*2)); // mark as double
+ *_fp_identifiers |= ((intptr_t)0x3 << (_num_args*2)); // mark as double
_num_args++;
} else {
*_to++ = from_obj;
diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.cpp b/src/hotspot/cpu/x86/macroAssembler_x86.cpp
index bdee29beb76..98512c11dd6 100644
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp
@@ -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
@@ -27,6 +27,7 @@
#include "asm/assembler.hpp"
#include "asm/assembler.inline.hpp"
#include "compiler/disassembler.hpp"
+#include "gc/shared/cardTable.hpp"
#include "gc/shared/cardTableModRefBS.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/interpreter.hpp"
@@ -45,6 +46,7 @@
#include "runtime/thread.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
+#include "gc/g1/g1CardTable.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
#include "gc/g1/heapRegion.hpp"
@@ -3767,10 +3769,17 @@ void MacroAssembler::serialize_memory(Register thread, Register tmp) {
movl(as_Address(ArrayAddress(page, index)), tmp);
}
-#ifdef _LP64
void MacroAssembler::safepoint_poll(Label& slow_path, Register thread_reg, Register temp_reg) {
if (SafepointMechanism::uses_thread_local_poll()) {
- testb(Address(r15_thread, Thread::polling_page_offset()), SafepointMechanism::poll_bit());
+#ifdef _LP64
+ assert(thread_reg == r15_thread, "should be");
+#else
+ if (thread_reg == noreg) {
+ thread_reg = temp_reg;
+ get_thread(thread_reg);
+ }
+#endif
+ testb(Address(thread_reg, Thread::polling_page_offset()), SafepointMechanism::poll_bit());
jcc(Assembler::notZero, slow_path); // handshake bit set implies poll
} else {
cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
@@ -3778,13 +3787,6 @@ void MacroAssembler::safepoint_poll(Label& slow_path, Register thread_reg, Regis
jcc(Assembler::notEqual, slow_path);
}
}
-#else
-void MacroAssembler::safepoint_poll(Label& slow_path) {
- cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
- SafepointSynchronize::_not_synchronized);
- jcc(Assembler::notEqual, slow_path);
-}
-#endif
// Calls to C land
//
@@ -5407,9 +5409,10 @@ void MacroAssembler::g1_write_barrier_post(Register store_addr,
Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
DirtyCardQueue::byte_offset_of_buf()));
- CardTableModRefBS* ct =
+ CardTableModRefBS* ctbs =
barrier_set_cast(Universe::heap()->barrier_set());
- assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
+ CardTable* ct = ctbs->card_table();
+ assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
Label done;
Label runtime;
@@ -5432,24 +5435,24 @@ void MacroAssembler::g1_write_barrier_post(Register store_addr,
const Register cardtable = tmp2;
movptr(card_addr, store_addr);
- shrptr(card_addr, CardTableModRefBS::card_shift);
+ shrptr(card_addr, CardTable::card_shift);
// Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT
// a valid address and therefore is not properly handled by the relocation code.
- movptr(cardtable, (intptr_t)ct->byte_map_base);
+ movptr(cardtable, (intptr_t)ct->byte_map_base());
addptr(card_addr, cardtable);
- cmpb(Address(card_addr, 0), (int)G1SATBCardTableModRefBS::g1_young_card_val());
+ cmpb(Address(card_addr, 0), (int)G1CardTable::g1_young_card_val());
jcc(Assembler::equal, done);
membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
- cmpb(Address(card_addr, 0), (int)CardTableModRefBS::dirty_card_val());
+ cmpb(Address(card_addr, 0), (int)CardTable::dirty_card_val());
jcc(Assembler::equal, done);
// storing a region crossing, non-NULL oop, card is clean.
// dirty card and log.
- movb(Address(card_addr, 0), (int)CardTableModRefBS::dirty_card_val());
+ movb(Address(card_addr, 0), (int)CardTable::dirty_card_val());
cmpl(queue_index, 0);
jcc(Assembler::equal, runtime);
@@ -5494,14 +5497,14 @@ void MacroAssembler::store_check(Register obj) {
// Does a store check for the oop in register obj. The content of
// register obj is destroyed afterwards.
BarrierSet* bs = Universe::heap()->barrier_set();
- assert(bs->kind() == BarrierSet::CardTableForRS ||
- bs->kind() == BarrierSet::CardTableExtension,
+ assert(bs->kind() == BarrierSet::CardTableModRef,
"Wrong barrier set kind");
- CardTableModRefBS* ct = barrier_set_cast(bs);
- assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
+ CardTableModRefBS* ctbs = barrier_set_cast(bs);
+ CardTable* ct = ctbs->card_table();
+ assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
- shrptr(obj, CardTableModRefBS::card_shift);
+ shrptr(obj, CardTable::card_shift);
Address card_addr;
@@ -5510,7 +5513,7 @@ void MacroAssembler::store_check(Register obj) {
// So this essentially converts an address to a displacement and it will
// never need to be relocated. On 64bit however the value may be too
// large for a 32bit displacement.
- intptr_t disp = (intptr_t) ct->byte_map_base;
+ intptr_t disp = (intptr_t) ct->byte_map_base();
if (is_simm32(disp)) {
card_addr = Address(noreg, obj, Address::times_1, disp);
} else {
@@ -5518,12 +5521,12 @@ void MacroAssembler::store_check(Register obj) {
// displacement and done in a single instruction given favorable mapping and a
// smarter version of as_Address. However, 'ExternalAddress' generates a relocation
// entry and that entry is not properly handled by the relocation code.
- AddressLiteral cardtable((address)ct->byte_map_base, relocInfo::none);
+ AddressLiteral cardtable((address)ct->byte_map_base(), relocInfo::none);
Address index(noreg, obj, Address::times_1);
card_addr = as_Address(ArrayAddress(cardtable, index));
}
- int dirty = CardTableModRefBS::dirty_card_val();
+ int dirty = CardTable::dirty_card_val();
if (UseCondCardMark) {
Label L_already_dirty;
if (UseConcMarkSweepGC) {
@@ -5604,121 +5607,6 @@ void MacroAssembler::tlab_allocate(Register obj,
verify_tlab();
}
-// Preserves rbx, and rdx.
-Register MacroAssembler::tlab_refill(Label& retry,
- Label& try_eden,
- Label& slow_case) {
- Register top = rax;
- Register t1 = rcx; // object size
- Register t2 = rsi;
- Register thread_reg = NOT_LP64(rdi) LP64_ONLY(r15_thread);
- assert_different_registers(top, thread_reg, t1, t2, /* preserve: */ rbx, rdx);
- Label do_refill, discard_tlab;
-
- if (!Universe::heap()->supports_inline_contig_alloc()) {
- // No allocation in the shared eden.
- jmp(slow_case);
- }
-
- NOT_LP64(get_thread(thread_reg));
-
- movptr(top, Address(thread_reg, in_bytes(JavaThread::tlab_top_offset())));
- movptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_end_offset())));
-
- // calculate amount of free space
- subptr(t1, top);
- shrptr(t1, LogHeapWordSize);
-
- // Retain tlab and allocate object in shared space if
- // the amount free in the tlab is too large to discard.
- cmpptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_refill_waste_limit_offset())));
- jcc(Assembler::lessEqual, discard_tlab);
-
- // Retain
- // %%% yuck as movptr...
- movptr(t2, (int32_t) ThreadLocalAllocBuffer::refill_waste_limit_increment());
- addptr(Address(thread_reg, in_bytes(JavaThread::tlab_refill_waste_limit_offset())), t2);
- if (TLABStats) {
- // increment number of slow_allocations
- addl(Address(thread_reg, in_bytes(JavaThread::tlab_slow_allocations_offset())), 1);
- }
- jmp(try_eden);
-
- bind(discard_tlab);
- if (TLABStats) {
- // increment number of refills
- addl(Address(thread_reg, in_bytes(JavaThread::tlab_number_of_refills_offset())), 1);
- // accumulate wastage -- t1 is amount free in tlab
- addl(Address(thread_reg, in_bytes(JavaThread::tlab_fast_refill_waste_offset())), t1);
- }
-
- // if tlab is currently allocated (top or end != null) then
- // fill [top, end + alignment_reserve) with array object
- testptr(top, top);
- jcc(Assembler::zero, do_refill);
-
- // set up the mark word
- movptr(Address(top, oopDesc::mark_offset_in_bytes()), (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2));
- // set the length to the remaining space
- subptr(t1, typeArrayOopDesc::header_size(T_INT));
- addptr(t1, (int32_t)ThreadLocalAllocBuffer::alignment_reserve());
- shlptr(t1, log2_intptr(HeapWordSize/sizeof(jint)));
- movl(Address(top, arrayOopDesc::length_offset_in_bytes()), t1);
- // set klass to intArrayKlass
- // dubious reloc why not an oop reloc?
- movptr(t1, ExternalAddress((address)Universe::intArrayKlassObj_addr()));
- // store klass last. concurrent gcs assumes klass length is valid if
- // klass field is not null.
- store_klass(top, t1);
-
- movptr(t1, top);
- subptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_start_offset())));
- incr_allocated_bytes(thread_reg, t1, 0);
-
- // refill the tlab with an eden allocation
- bind(do_refill);
- movptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset())));
- shlptr(t1, LogHeapWordSize);
- // allocate new tlab, address returned in top
- eden_allocate(top, t1, 0, t2, slow_case);
-
- // Check that t1 was preserved in eden_allocate.
-#ifdef ASSERT
- if (UseTLAB) {
- Label ok;
- Register tsize = rsi;
- assert_different_registers(tsize, thread_reg, t1);
- push(tsize);
- movptr(tsize, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset())));
- shlptr(tsize, LogHeapWordSize);
- cmpptr(t1, tsize);
- jcc(Assembler::equal, ok);
- STOP("assert(t1 != tlab size)");
- should_not_reach_here();
-
- bind(ok);
- pop(tsize);
- }
-#endif
- movptr(Address(thread_reg, in_bytes(JavaThread::tlab_start_offset())), top);
- movptr(Address(thread_reg, in_bytes(JavaThread::tlab_top_offset())), top);
- addptr(top, t1);
- subptr(top, (int32_t)ThreadLocalAllocBuffer::alignment_reserve_in_bytes());
- movptr(Address(thread_reg, in_bytes(JavaThread::tlab_end_offset())), top);
-
- if (ZeroTLAB) {
- // This is a fast TLAB refill, therefore the GC is not notified of it.
- // So compiled code must fill the new TLAB with zeroes.
- movptr(top, Address(thread_reg, in_bytes(JavaThread::tlab_start_offset())));
- zero_memory(top, t1, 0, t2);
- }
-
- verify_tlab();
- jmp(retry);
-
- return thread_reg; // for use by caller
-}
-
// Preserves the contents of address, destroys the contents length_in_bytes and temp.
void MacroAssembler::zero_memory(Register address, Register length_in_bytes, int offset_in_bytes, Register temp) {
assert(address != length_in_bytes && address != temp && temp != length_in_bytes, "registers must be different");
diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.hpp b/src/hotspot/cpu/x86/macroAssembler_x86.hpp
index 61e29e9b092..ebd638c384e 100644
--- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -531,7 +531,6 @@ class MacroAssembler: public Assembler {
Register t2, // temp register
Label& slow_case // continuation point if fast allocation fails
);
- Register tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case); // returns TLS address
void zero_memory(Register address, Register length_in_bytes, int offset_in_bytes, Register temp);
void incr_allocated_bytes(Register thread,
@@ -657,11 +656,9 @@ class MacroAssembler: public Assembler {
// Support for serializing memory accesses between threads
void serialize_memory(Register thread, Register tmp);
-#ifdef _LP64
+ // If thread_reg is != noreg the code assumes the register passed contains
+ // the thread (required on 64 bit).
void safepoint_poll(Label& slow_path, Register thread_reg, Register temp_reg);
-#else
- void safepoint_poll(Label& slow_path);
-#endif
void verify_tlab();
diff --git a/src/hotspot/cpu/x86/nativeInst_x86.hpp b/src/hotspot/cpu/x86/nativeInst_x86.hpp
index de4b448396b..91bca3654fa 100644
--- a/src/hotspot/cpu/x86/nativeInst_x86.hpp
+++ b/src/hotspot/cpu/x86/nativeInst_x86.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -704,14 +704,18 @@ inline bool NativeInstruction::is_far_jump() { return is_mov_literal64(); }
inline bool NativeInstruction::is_cond_jump() { return (int_at(0) & 0xF0FF) == 0x800F /* long jump */ ||
(ubyte_at(0) & 0xF0) == 0x70; /* short jump */ }
inline bool NativeInstruction::is_safepoint_poll() {
-#ifdef AMD64
if (SafepointMechanism::uses_thread_local_poll()) {
+#ifdef AMD64
const bool has_rex_prefix = ubyte_at(0) == NativeTstRegMem::instruction_rex_b_prefix;
const int test_offset = has_rex_prefix ? 1 : 0;
+#else
+ const int test_offset = 0;
+#endif
const bool is_test_opcode = ubyte_at(test_offset) == NativeTstRegMem::instruction_code_memXregl;
const bool is_rax_target = (ubyte_at(test_offset + 1) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg;
return is_test_opcode && is_rax_target;
}
+#ifdef AMD64
// Try decoding a near safepoint first:
if (ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
ubyte_at(1) == 0x05) { // 00 rax 101
diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp
index 078e573f86c..d9c6c004873 100644
--- a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp
@@ -2111,16 +2111,13 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
Label after_transition;
// check for safepoint operation in progress and/or pending suspend requests
- { Label Continue;
+ { Label Continue, slow_path;
- __ cmp32(ExternalAddress((address)SafepointSynchronize::address_of_state()),
- SafepointSynchronize::_not_synchronized);
+ __ safepoint_poll(slow_path, thread, noreg);
- Label L;
- __ jcc(Assembler::notEqual, L);
__ cmpl(Address(thread, JavaThread::suspend_flags_offset()), 0);
__ jcc(Assembler::equal, Continue);
- __ bind(L);
+ __ bind(slow_path);
// Don't use call_VM as it will see a possible pending exception and forward it
// and never return here preventing us from clearing _last_native_pc down below.
@@ -2996,8 +2993,11 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t
// if this was not a poll_return then we need to correct the return address now.
if (!cause_return) {
- __ movptr(rax, Address(java_thread, JavaThread::saved_exception_pc_offset()));
- __ movptr(Address(rbp, wordSize), rax);
+ // Get the return pc saved by the signal handler and stash it in its appropriate place on the stack.
+ // Additionally, rbx is a callee saved register and we can look at it later to determine
+ // if someone changed the return address for us!
+ __ movptr(rbx, Address(java_thread, JavaThread::saved_exception_pc_offset()));
+ __ movptr(Address(rbp, wordSize), rbx);
}
// do the call
@@ -3029,11 +3029,63 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t
__ bind(noException);
+ Label no_adjust, bail, not_special;
+ if (SafepointMechanism::uses_thread_local_poll() && !cause_return) {
+ // If our stashed return pc was modified by the runtime we avoid touching it
+ __ cmpptr(rbx, Address(rbp, wordSize));
+ __ jccb(Assembler::notEqual, no_adjust);
+
+ // Skip over the poll instruction.
+ // See NativeInstruction::is_safepoint_poll()
+ // Possible encodings:
+ // 85 00 test %eax,(%rax)
+ // 85 01 test %eax,(%rcx)
+ // 85 02 test %eax,(%rdx)
+ // 85 03 test %eax,(%rbx)
+ // 85 06 test %eax,(%rsi)
+ // 85 07 test %eax,(%rdi)
+ //
+ // 85 04 24 test %eax,(%rsp)
+ // 85 45 00 test %eax,0x0(%rbp)
+
+#ifdef ASSERT
+ __ movptr(rax, rbx); // remember where 0x85 should be, for verification below
+#endif
+ // rsp/rbp base encoding takes 3 bytes with the following register values:
+ // rsp 0x04
+ // rbp 0x05
+ __ movzbl(rcx, Address(rbx, 1));
+ __ andptr(rcx, 0x07); // looking for 0x04 .. 0x05
+ __ subptr(rcx, 4); // looking for 0x00 .. 0x01
+ __ cmpptr(rcx, 1);
+ __ jcc(Assembler::above, not_special);
+ __ addptr(rbx, 1);
+ __ bind(not_special);
+#ifdef ASSERT
+ // Verify the correct encoding of the poll we're about to skip.
+ __ cmpb(Address(rax, 0), NativeTstRegMem::instruction_code_memXregl);
+ __ jcc(Assembler::notEqual, bail);
+ // Mask out the modrm bits
+ __ testb(Address(rax, 1), NativeTstRegMem::modrm_mask);
+ // rax encodes to 0, so if the bits are nonzero it's incorrect
+ __ jcc(Assembler::notZero, bail);
+#endif
+ // Adjust return pc forward to step over the safepoint poll instruction
+ __ addptr(rbx, 2);
+ __ movptr(Address(rbp, wordSize), rbx);
+ }
+
+ __ bind(no_adjust);
// Normal exit, register restoring and exit
RegisterSaver::restore_live_registers(masm, save_vectors);
__ ret(0);
+#ifdef ASSERT
+ __ bind(bail);
+ __ stop("Attempting to adjust pc to skip safepoint poll but the return point is not what we expected");
+#endif
+
// make sure all code is generated
masm->flush();
diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp
index 08309305dc7..1fc3bed8db4 100644
--- a/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp
@@ -25,6 +25,8 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.hpp"
#include "asm/macroAssembler.inline.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "gc/shared/cardTableModRefBS.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_x86.hpp"
#include "oops/instanceOop.hpp"
@@ -705,9 +707,7 @@ class StubGenerator: public StubCodeGenerator {
}
break;
#endif // INCLUDE_ALL_GCS
- case BarrierSet::CardTableForRS:
- case BarrierSet::CardTableExtension:
- case BarrierSet::ModRef:
+ case BarrierSet::CardTableModRef:
break;
default :
ShouldNotReachHere();
@@ -739,22 +739,22 @@ class StubGenerator: public StubCodeGenerator {
break;
#endif // INCLUDE_ALL_GCS
- case BarrierSet::CardTableForRS:
- case BarrierSet::CardTableExtension:
+ case BarrierSet::CardTableModRef:
{
- CardTableModRefBS* ct = barrier_set_cast(bs);
- assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
+ CardTableModRefBS* ctbs = barrier_set_cast(bs);
+ CardTable* ct = ctbs->card_table();
+ assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
Label L_loop;
const Register end = count; // elements count; end == start+count-1
assert_different_registers(start, end);
__ lea(end, Address(start, count, Address::times_ptr, -wordSize));
- __ shrptr(start, CardTableModRefBS::card_shift);
- __ shrptr(end, CardTableModRefBS::card_shift);
+ __ shrptr(start, CardTable::card_shift);
+ __ shrptr(end, CardTable::card_shift);
__ subptr(end, start); // end --> count
__ BIND(L_loop);
- intptr_t disp = (intptr_t) ct->byte_map_base;
+ intptr_t disp = (intptr_t) ct->byte_map_base();
Address cardtable(start, count, Address::times_1, disp);
__ movb(cardtable, 0);
__ decrement(count);
diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp
index 44e6b9d5f70..020d811321c 100644
--- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp
@@ -25,6 +25,9 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.hpp"
#include "asm/macroAssembler.inline.hpp"
+#include "ci/ciUtilities.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "gc/shared/cardTableModRefBS.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_x86.hpp"
#include "oops/instanceOop.hpp"
@@ -1232,9 +1235,7 @@ class StubGenerator: public StubCodeGenerator {
__ bind(filtered);
}
break;
- case BarrierSet::CardTableForRS:
- case BarrierSet::CardTableExtension:
- case BarrierSet::ModRef:
+ case BarrierSet::CardTableModRef:
break;
default:
ShouldNotReachHere();
@@ -1272,12 +1273,8 @@ class StubGenerator: public StubCodeGenerator {
__ popa();
}
break;
- case BarrierSet::CardTableForRS:
- case BarrierSet::CardTableExtension:
+ case BarrierSet::CardTableModRef:
{
- CardTableModRefBS* ct = barrier_set_cast(bs);
- assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
-
Label L_loop, L_done;
const Register end = count;
@@ -1286,11 +1283,11 @@ class StubGenerator: public StubCodeGenerator {
__ leaq(end, Address(start, count, TIMES_OOP, 0)); // end == start+count*oop_size
__ subptr(end, BytesPerHeapOop); // end - 1 to make inclusive
- __ shrptr(start, CardTableModRefBS::card_shift);
- __ shrptr(end, CardTableModRefBS::card_shift);
+ __ shrptr(start, CardTable::card_shift);
+ __ shrptr(end, CardTable::card_shift);
__ subptr(end, start); // end --> cards count
- int64_t disp = (int64_t) ct->byte_map_base;
+ int64_t disp = ci_card_table_address_as();
__ mov64(scratch, disp);
__ addptr(start, scratch);
__ BIND(L_loop);
diff --git a/src/hotspot/cpu/x86/stubRoutines_x86.cpp b/src/hotspot/cpu/x86/stubRoutines_x86.cpp
index 3922d45091c..ab4b528961f 100644
--- a/src/hotspot/cpu/x86/stubRoutines_x86.cpp
+++ b/src/hotspot/cpu/x86/stubRoutines_x86.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -303,45 +303,45 @@ ALIGNED_(64) juint StubRoutines::x86::_k256_W[2*sizeof(StubRoutines::x86::_k256)
// used in MacroAssembler::sha512_AVX2
ALIGNED_(64) julong StubRoutines::x86::_k512_W[] =
{
- 0x428a2f98d728ae22LL, 0x7137449123ef65cdLL,
- 0xb5c0fbcfec4d3b2fLL, 0xe9b5dba58189dbbcLL,
- 0x3956c25bf348b538LL, 0x59f111f1b605d019LL,
- 0x923f82a4af194f9bLL, 0xab1c5ed5da6d8118LL,
- 0xd807aa98a3030242LL, 0x12835b0145706fbeLL,
- 0x243185be4ee4b28cLL, 0x550c7dc3d5ffb4e2LL,
- 0x72be5d74f27b896fLL, 0x80deb1fe3b1696b1LL,
- 0x9bdc06a725c71235LL, 0xc19bf174cf692694LL,
- 0xe49b69c19ef14ad2LL, 0xefbe4786384f25e3LL,
- 0x0fc19dc68b8cd5b5LL, 0x240ca1cc77ac9c65LL,
- 0x2de92c6f592b0275LL, 0x4a7484aa6ea6e483LL,
- 0x5cb0a9dcbd41fbd4LL, 0x76f988da831153b5LL,
- 0x983e5152ee66dfabLL, 0xa831c66d2db43210LL,
- 0xb00327c898fb213fLL, 0xbf597fc7beef0ee4LL,
- 0xc6e00bf33da88fc2LL, 0xd5a79147930aa725LL,
- 0x06ca6351e003826fLL, 0x142929670a0e6e70LL,
- 0x27b70a8546d22ffcLL, 0x2e1b21385c26c926LL,
- 0x4d2c6dfc5ac42aedLL, 0x53380d139d95b3dfLL,
- 0x650a73548baf63deLL, 0x766a0abb3c77b2a8LL,
- 0x81c2c92e47edaee6LL, 0x92722c851482353bLL,
- 0xa2bfe8a14cf10364LL, 0xa81a664bbc423001LL,
- 0xc24b8b70d0f89791LL, 0xc76c51a30654be30LL,
- 0xd192e819d6ef5218LL, 0xd69906245565a910LL,
- 0xf40e35855771202aLL, 0x106aa07032bbd1b8LL,
- 0x19a4c116b8d2d0c8LL, 0x1e376c085141ab53LL,
- 0x2748774cdf8eeb99LL, 0x34b0bcb5e19b48a8LL,
- 0x391c0cb3c5c95a63LL, 0x4ed8aa4ae3418acbLL,
- 0x5b9cca4f7763e373LL, 0x682e6ff3d6b2b8a3LL,
- 0x748f82ee5defb2fcLL, 0x78a5636f43172f60LL,
- 0x84c87814a1f0ab72LL, 0x8cc702081a6439ecLL,
- 0x90befffa23631e28LL, 0xa4506cebde82bde9LL,
- 0xbef9a3f7b2c67915LL, 0xc67178f2e372532bLL,
- 0xca273eceea26619cLL, 0xd186b8c721c0c207LL,
- 0xeada7dd6cde0eb1eLL, 0xf57d4f7fee6ed178LL,
- 0x06f067aa72176fbaLL, 0x0a637dc5a2c898a6LL,
- 0x113f9804bef90daeLL, 0x1b710b35131c471bLL,
- 0x28db77f523047d84LL, 0x32caab7b40c72493LL,
- 0x3c9ebe0a15c9bebcLL, 0x431d67c49c100d4cLL,
- 0x4cc5d4becb3e42b6LL, 0x597f299cfc657e2aLL,
- 0x5fcb6fab3ad6faecLL, 0x6c44198c4a475817LL,
+ 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
+ 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
+ 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+ 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
+ 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
+ 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+ 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
+ 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
+ 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+ 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
+ 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
+ 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+ 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
+ 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
+ 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+ 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
+ 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
+ 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+ 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
+ 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
+ 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+ 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
+ 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
+ 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+ 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
+ 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
+ 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+ 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
+ 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
+ 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+ 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
+ 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
+ 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+ 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
+ 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
+ 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+ 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
+ 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
+ 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+ 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL,
};
#endif
diff --git a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp
index a5c813d7fb9..defe032ab7d 100644
--- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp
+++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1148,7 +1148,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
Label slow_path;
#ifndef _LP64
- __ safepoint_poll(slow_path);
+ __ safepoint_poll(slow_path, thread, noreg);
#else
__ safepoint_poll(slow_path, r15_thread, rscratch1);
#endif
diff --git a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_32.cpp b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_32.cpp
index 861403164ae..69870e0ce09 100644
--- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_32.cpp
+++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_32.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -61,10 +61,7 @@ address TemplateInterpreterGenerator::generate_CRC32_update_entry() {
Label slow_path;
// If we need a safepoint check, generate full interpreter entry.
- ExternalAddress state(SafepointSynchronize::address_of_state());
- __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
- SafepointSynchronize::_not_synchronized);
- __ jcc(Assembler::notEqual, slow_path);
+ __ safepoint_poll(slow_path, noreg, rdi);
// We don't generate local frame and don't align stack because
// we call stub code and there is no safepoint on this path.
@@ -113,10 +110,7 @@ address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractI
Label slow_path;
// If we need a safepoint check, generate full interpreter entry.
- ExternalAddress state(SafepointSynchronize::address_of_state());
- __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
- SafepointSynchronize::_not_synchronized);
- __ jcc(Assembler::notEqual, slow_path);
+ __ safepoint_poll(slow_path, noreg, rdi);
// We don't generate local frame and don't align stack because
// we call stub code and there is no safepoint on this path.
diff --git a/src/hotspot/cpu/x86/templateTable_x86.cpp b/src/hotspot/cpu/x86/templateTable_x86.cpp
index 7ccd860f8cf..fb9ce0ef5ae 100644
--- a/src/hotspot/cpu/x86/templateTable_x86.cpp
+++ b/src/hotspot/cpu/x86/templateTable_x86.cpp
@@ -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
@@ -198,8 +198,7 @@ static void do_oop_store(InterpreterMacroAssembler* _masm,
}
break;
#endif // INCLUDE_ALL_GCS
- case BarrierSet::CardTableForRS:
- case BarrierSet::CardTableExtension:
+ case BarrierSet::CardTableModRef:
{
if (val == noreg) {
__ store_heap_oop_null(obj);
@@ -2692,11 +2691,16 @@ void TemplateTable::_return(TosState state) {
__ bind(skip_register_finalizer);
}
-#ifdef _LP64
if (SafepointMechanism::uses_thread_local_poll() && _desc->bytecode() != Bytecodes::_return_register_finalizer) {
Label no_safepoint;
NOT_PRODUCT(__ block_comment("Thread-local Safepoint poll"));
+#ifdef _LP64
__ testb(Address(r15_thread, Thread::polling_page_offset()), SafepointMechanism::poll_bit());
+#else
+ const Register thread = rdi;
+ __ get_thread(thread);
+ __ testb(Address(thread, Thread::polling_page_offset()), SafepointMechanism::poll_bit());
+#endif
__ jcc(Assembler::zero, no_safepoint);
__ push(state);
__ call_VM(noreg, CAST_FROM_FN_PTR(address,
@@ -2704,7 +2708,6 @@ void TemplateTable::_return(TosState state) {
__ pop(state);
__ bind(no_safepoint);
}
-#endif
// Narrow result if state is itos but result type is smaller.
// Need to narrow in the return bytecode rather than in generate_return_entry
diff --git a/src/hotspot/cpu/x86/x86_32.ad b/src/hotspot/cpu/x86/x86_32.ad
index 60e3d212887..ef9bb5e49c4 100644
--- a/src/hotspot/cpu/x86/x86_32.ad
+++ b/src/hotspot/cpu/x86/x86_32.ad
@@ -317,7 +317,7 @@ int MachCallRuntimeNode::ret_addr_offset() {
// Indicate if the safepoint node needs the polling page as an input.
// Since x86 does have absolute addressing, it doesn't.
bool SafePointNode::needs_polling_address_input() {
- return false;
+ return SafepointMechanism::uses_thread_local_poll();
}
//
@@ -706,34 +706,25 @@ void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
}
if (do_polling() && C->is_method_compilation()) {
- cbuf.relocate(cbuf.insts_end(), relocInfo::poll_return_type, 0);
- emit_opcode(cbuf,0x85);
- emit_rm(cbuf, 0x0, EAX_enc, 0x5); // EAX
- emit_d32(cbuf, (intptr_t)os::get_polling_page());
+ if (SafepointMechanism::uses_thread_local_poll()) {
+ Register pollReg = as_Register(EBX_enc);
+ MacroAssembler masm(&cbuf);
+ masm.get_thread(pollReg);
+ masm.movl(pollReg, Address(pollReg, in_bytes(Thread::polling_page_offset())));
+ masm.relocate(relocInfo::poll_return_type);
+ masm.testl(rax, Address(pollReg, 0));
+ } else {
+ cbuf.relocate(cbuf.insts_end(), relocInfo::poll_return_type, 0);
+ emit_opcode(cbuf,0x85);
+ emit_rm(cbuf, 0x0, EAX_enc, 0x5); // EAX
+ emit_d32(cbuf, (intptr_t)os::get_polling_page());
+ }
}
}
uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
- Compile *C = ra_->C;
- // If method set FPU control word, restore to standard control word
- int size = C->in_24_bit_fp_mode() ? 6 : 0;
- if (C->max_vector_size() > 16) size += 3; // vzeroupper
- if (do_polling() && C->is_method_compilation()) size += 6;
-
- int framesize = C->frame_size_in_bytes();
- assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
- // Remove two words for return addr and rbp,
- framesize -= 2*wordSize;
-
- size++; // popl rbp,
-
- if (framesize >= 128) {
- size += 6;
- } else {
- size += framesize ? 3 : 0;
- }
- size += 64; // added to support ReservedStackAccess
- return size;
+ return MachNode::size(ra_); // too many variables; just compute it
+ // the hard way
}
int MachEpilogNode::reloc() const {
@@ -13336,6 +13327,7 @@ instruct cmpFastUnlock(eFlagsReg cr, eRegP object, eAXRegP box, eRegP tmp ) %{
// ============================================================================
// Safepoint Instruction
instruct safePoint_poll(eFlagsReg cr) %{
+ predicate(SafepointMechanism::uses_global_page_poll());
match(SafePoint);
effect(KILL cr);
@@ -13354,6 +13346,25 @@ instruct safePoint_poll(eFlagsReg cr) %{
ins_pipe( ialu_reg_mem );
%}
+instruct safePoint_poll_tls(eFlagsReg cr, eRegP_no_EBP poll) %{
+ predicate(SafepointMechanism::uses_thread_local_poll());
+ match(SafePoint poll);
+ effect(KILL cr, USE poll);
+
+ format %{ "TSTL #EAX,[$poll]\t! Safepoint: poll for GC" %}
+ ins_cost(125);
+ // EBP would need size(3)
+ size(2); /* setting an explicit size will cause debug builds to assert if size is incorrect */
+ ins_encode %{
+ __ relocate(relocInfo::poll_type);
+ address pre_pc = __ pc();
+ __ testl(rax, Address($poll$$Register, 0));
+ address post_pc = __ pc();
+ guarantee(pre_pc[0] == 0x85, "must emit test-ax [reg]");
+ %}
+ ins_pipe(ialu_reg_mem);
+%}
+
// ============================================================================
// This name is KNOWN by the ADLC and cannot be changed.
diff --git a/src/hotspot/cpu/zero/cppInterpreter_zero.cpp b/src/hotspot/cpu/zero/cppInterpreter_zero.cpp
index 55f7b510080..ec52c3060e6 100644
--- a/src/hotspot/cpu/zero/cppInterpreter_zero.cpp
+++ b/src/hotspot/cpu/zero/cppInterpreter_zero.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -41,6 +41,7 @@
#include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/interfaceSupport.hpp"
+#include "runtime/jniHandles.inline.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
diff --git a/src/hotspot/os/bsd/decoder_machO.cpp b/src/hotspot/os/bsd/decoder_machO.cpp
index a523e6fc9b4..f2c60755ca8 100644
--- a/src/hotspot/os/bsd/decoder_machO.cpp
+++ b/src/hotspot/os/bsd/decoder_machO.cpp
@@ -27,6 +27,7 @@
#ifdef __APPLE__
#include "jvm.h"
#include "decoder_machO.hpp"
+#include "memory/allocation.inline.hpp"
#include
#include
diff --git a/src/hotspot/os/linux/globals_linux.hpp b/src/hotspot/os/linux/globals_linux.hpp
index e09a828185d..022492118aa 100644
--- a/src/hotspot/os/linux/globals_linux.hpp
+++ b/src/hotspot/os/linux/globals_linux.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -62,6 +62,11 @@
product(bool, UseContainerSupport, true, \
"Enable detection and runtime container configuration support") \
\
+ product(bool, PreferContainerQuotaForCPUCount, true, \
+ "Calculate the container CPU availability based on the value" \
+ " of quotas (if set), when true. Otherwise, use the CPU" \
+ " shares value, provided it is less than quota.") \
+ \
diagnostic(bool, UseCpuAllocPath, false, \
"Use CPU_ALLOC code path in os::active_processor_count ")
diff --git a/src/hotspot/os/linux/osContainer_linux.cpp b/src/hotspot/os/linux/osContainer_linux.cpp
index 463f3ccb134..0b35bb32c5d 100644
--- a/src/hotspot/os/linux/osContainer_linux.cpp
+++ b/src/hotspot/os/linux/osContainer_linux.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -414,9 +414,9 @@ void OSContainer::init() {
}
-char * OSContainer::container_type() {
+const char * OSContainer::container_type() {
if (is_containerized()) {
- return (char *)"cgroupv1";
+ return "cgroupv1";
} else {
return NULL;
}
@@ -499,11 +499,11 @@ jlong OSContainer::memory_max_usage_in_bytes() {
/* active_processor_count
*
* Calculate an appropriate number of active processors for the
- * VM to use based on these three cgroup options.
+ * VM to use based on these three inputs.
*
* cpu affinity
- * cpu quota & cpu period
- * cpu shares
+ * cgroup cpu quota & cpu period
+ * cgroup cpu shares
*
* Algorithm:
*
@@ -513,42 +513,61 @@ jlong OSContainer::memory_max_usage_in_bytes() {
* required CPUs by dividing quota by period.
*
* If shares are in effect (shares != -1), calculate the number
- * of cpus required for the shares by dividing the share value
+ * of CPUs required for the shares by dividing the share value
* by PER_CPU_SHARES.
*
* All results of division are rounded up to the next whole number.
*
- * Return the smaller number from the three different settings.
+ * If neither shares or quotas have been specified, return the
+ * number of active processors in the system.
+ *
+ * If both shares and quotas have been specified, the results are
+ * based on the flag PreferContainerQuotaForCPUCount. If true,
+ * return the quota value. If false return the smallest value
+ * between shares or quotas.
+ *
+ * If shares and/or quotas have been specified, the resulting number
+ * returned will never exceed the number of active processors.
*
* return:
- * number of cpus
- * OSCONTAINER_ERROR if failure occured during extract of cpuset info
+ * number of CPUs
*/
int OSContainer::active_processor_count() {
- int cpu_count, share_count, quota_count;
- int share, quota, period;
+ int quota_count = 0, share_count = 0;
+ int cpu_count, limit_count;
int result;
- cpu_count = os::Linux::active_processor_count();
+ cpu_count = limit_count = os::Linux::active_processor_count();
+ int quota = cpu_quota();
+ int period = cpu_period();
+ int share = cpu_shares();
- share = cpu_shares();
- if (share > -1) {
- share_count = ceilf((float)share / (float)PER_CPU_SHARES);
- log_trace(os, container)("cpu_share count: %d", share_count);
- } else {
- share_count = cpu_count;
- }
-
- quota = cpu_quota();
- period = cpu_period();
if (quota > -1 && period > 0) {
quota_count = ceilf((float)quota / (float)period);
- log_trace(os, container)("quota_count: %d", quota_count);
- } else {
- quota_count = cpu_count;
+ log_trace(os, container)("CPU Quota count based on quota/period: %d", quota_count);
+ }
+ if (share > -1) {
+ share_count = ceilf((float)share / (float)PER_CPU_SHARES);
+ log_trace(os, container)("CPU Share count based on shares: %d", share_count);
}
- result = MIN2(cpu_count, MIN2(share_count, quota_count));
+ // If both shares and quotas are setup results depend
+ // on flag PreferContainerQuotaForCPUCount.
+ // If true, limit CPU count to quota
+ // If false, use minimum of shares and quotas
+ if (quota_count !=0 && share_count != 0) {
+ if (PreferContainerQuotaForCPUCount) {
+ limit_count = quota_count;
+ } else {
+ limit_count = MIN2(quota_count, share_count);
+ }
+ } else if (quota_count != 0) {
+ limit_count = quota_count;
+ } else if (share_count != 0) {
+ limit_count = share_count;
+ }
+
+ result = MIN2(cpu_count, limit_count);
log_trace(os, container)("OSContainer::active_processor_count: %d", result);
return result;
}
diff --git a/src/hotspot/os/linux/osContainer_linux.hpp b/src/hotspot/os/linux/osContainer_linux.hpp
index 5ace80165d9..0a81364fc8d 100644
--- a/src/hotspot/os/linux/osContainer_linux.hpp
+++ b/src/hotspot/os/linux/osContainer_linux.hpp
@@ -40,7 +40,7 @@ class OSContainer: AllStatic {
public:
static void init();
static inline bool is_containerized();
- static char * container_type();
+ static const char * container_type();
static jlong memory_limit_in_bytes();
static jlong memory_and_swap_limit_in_bytes();
diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp
index 4544baa8f76..580c7ebcae5 100644
--- a/src/hotspot/os/linux/os_linux.cpp
+++ b/src/hotspot/os/linux/os_linux.cpp
@@ -177,20 +177,17 @@ julong os::Linux::available_memory() {
if (OSContainer::is_containerized()) {
jlong mem_limit, mem_usage;
- if ((mem_limit = OSContainer::memory_limit_in_bytes()) > 0) {
- if ((mem_usage = OSContainer::memory_usage_in_bytes()) > 0) {
- if (mem_limit > mem_usage) {
- avail_mem = (julong)mem_limit - (julong)mem_usage;
- } else {
- avail_mem = 0;
- }
- log_trace(os)("available container memory: " JULONG_FORMAT, avail_mem);
- return avail_mem;
- } else {
- log_debug(os,container)("container memory usage call failed: " JLONG_FORMAT, mem_usage);
- }
- } else {
- log_debug(os,container)("container memory unlimited or failed: " JLONG_FORMAT, mem_limit);
+ if ((mem_limit = OSContainer::memory_limit_in_bytes()) < 1) {
+ log_debug(os, container)("container memory limit %s: " JLONG_FORMAT ", using host value",
+ mem_limit == OSCONTAINER_ERROR ? "failed" : "unlimited", mem_limit);
+ }
+ if (mem_limit > 0 && (mem_usage = OSContainer::memory_usage_in_bytes()) < 1) {
+ log_debug(os, container)("container memory usage failed: " JLONG_FORMAT ", using host value", mem_usage);
+ }
+ if (mem_limit > 0 && mem_usage > 0 ) {
+ avail_mem = mem_limit > mem_usage ? (julong)mem_limit - (julong)mem_usage : 0;
+ log_trace(os)("available container memory: " JULONG_FORMAT, avail_mem);
+ return avail_mem;
}
}
@@ -201,22 +198,18 @@ julong os::Linux::available_memory() {
}
julong os::physical_memory() {
+ jlong phys_mem = 0;
if (OSContainer::is_containerized()) {
jlong mem_limit;
if ((mem_limit = OSContainer::memory_limit_in_bytes()) > 0) {
log_trace(os)("total container memory: " JLONG_FORMAT, mem_limit);
- return (julong)mem_limit;
- } else {
- if (mem_limit == OSCONTAINER_ERROR) {
- log_debug(os,container)("container memory limit call failed");
- }
- if (mem_limit == -1) {
- log_debug(os,container)("container memory unlimited, using host value");
- }
+ return mem_limit;
}
+ log_debug(os, container)("container memory limit %s: " JLONG_FORMAT ", using host value",
+ mem_limit == OSCONTAINER_ERROR ? "failed" : "unlimited", mem_limit);
}
- jlong phys_mem = Linux::physical_memory();
+ phys_mem = Linux::physical_memory();
log_trace(os)("total system memory: " JLONG_FORMAT, phys_mem);
return phys_mem;
}
@@ -2135,63 +2128,54 @@ void os::Linux::print_full_memory_info(outputStream* st) {
}
void os::Linux::print_container_info(outputStream* st) {
- if (OSContainer::is_containerized()) {
- st->print("container (cgroup) information:\n");
-
- char *p = OSContainer::container_type();
- if (p == NULL)
- st->print("container_type() failed\n");
- else {
- st->print("container_type: %s\n", p);
- }
-
- p = OSContainer::cpu_cpuset_cpus();
- if (p == NULL)
- st->print("cpu_cpuset_cpus() failed\n");
- else {
- st->print("cpu_cpuset_cpus: %s\n", p);
- free(p);
- }
-
- p = OSContainer::cpu_cpuset_memory_nodes();
- if (p < 0)
- st->print("cpu_memory_nodes() failed\n");
- else {
- st->print("cpu_memory_nodes: %s\n", p);
- free(p);
- }
-
- int i = OSContainer::active_processor_count();
- if (i < 0)
- st->print("active_processor_count() failed\n");
- else
- st->print("active_processor_count: %d\n", i);
-
- i = OSContainer::cpu_quota();
- st->print("cpu_quota: %d\n", i);
-
- i = OSContainer::cpu_period();
- st->print("cpu_period: %d\n", i);
-
- i = OSContainer::cpu_shares();
- st->print("cpu_shares: %d\n", i);
-
- jlong j = OSContainer::memory_limit_in_bytes();
- st->print("memory_limit_in_bytes: " JLONG_FORMAT "\n", j);
-
- j = OSContainer::memory_and_swap_limit_in_bytes();
- st->print("memory_and_swap_limit_in_bytes: " JLONG_FORMAT "\n", j);
-
- j = OSContainer::memory_soft_limit_in_bytes();
- st->print("memory_soft_limit_in_bytes: " JLONG_FORMAT "\n", j);
-
- j = OSContainer::OSContainer::memory_usage_in_bytes();
- st->print("memory_usage_in_bytes: " JLONG_FORMAT "\n", j);
-
- j = OSContainer::OSContainer::memory_max_usage_in_bytes();
- st->print("memory_max_usage_in_bytes: " JLONG_FORMAT "\n", j);
- st->cr();
+ if (!OSContainer::is_containerized()) {
+ return;
}
+
+ st->print("container (cgroup) information:\n");
+
+ const char *p_ct = OSContainer::container_type();
+ st->print("container_type: %s\n", p_ct != NULL ? p_ct : "failed");
+
+ char *p = OSContainer::cpu_cpuset_cpus();
+ st->print("cpu_cpuset_cpus: %s\n", p != NULL ? p : "failed");
+ free(p);
+
+ p = OSContainer::cpu_cpuset_memory_nodes();
+ st->print("cpu_memory_nodes: %s\n", p != NULL ? p : "failed");
+ free(p);
+
+ int i = OSContainer::active_processor_count();
+ if (i > 0) {
+ st->print("active_processor_count: %d\n", i);
+ } else {
+ st->print("active_processor_count: failed\n");
+ }
+
+ i = OSContainer::cpu_quota();
+ st->print("cpu_quota: %d\n", i);
+
+ i = OSContainer::cpu_period();
+ st->print("cpu_period: %d\n", i);
+
+ i = OSContainer::cpu_shares();
+ st->print("cpu_shares: %d\n", i);
+
+ jlong j = OSContainer::memory_limit_in_bytes();
+ st->print("memory_limit_in_bytes: " JLONG_FORMAT "\n", j);
+
+ j = OSContainer::memory_and_swap_limit_in_bytes();
+ st->print("memory_and_swap_limit_in_bytes: " JLONG_FORMAT "\n", j);
+
+ j = OSContainer::memory_soft_limit_in_bytes();
+ st->print("memory_soft_limit_in_bytes: " JLONG_FORMAT "\n", j);
+
+ j = OSContainer::OSContainer::memory_usage_in_bytes();
+ st->print("memory_usage_in_bytes: " JLONG_FORMAT "\n", j);
+
+ j = OSContainer::OSContainer::memory_max_usage_in_bytes();
+ st->print("memory_max_usage_in_bytes: " JLONG_FORMAT "\n", j);
+ st->cr();
}
void os::print_memory_info(outputStream* st) {
@@ -3069,10 +3053,12 @@ bool os::pd_uncommit_memory(char* addr, size_t size) {
return res != (uintptr_t) MAP_FAILED;
}
-static address get_stack_commited_bottom(address bottom, size_t size) {
- address nbot = bottom;
- address ntop = bottom + size;
-
+// If there is no page mapped/committed, top (bottom + size) is returned
+static address get_stack_mapped_bottom(address bottom,
+ size_t size,
+ bool committed_only /* must have backing pages */) {
+ // address used to test if the page is mapped/committed
+ address test_addr = bottom + size;
size_t page_sz = os::vm_page_size();
unsigned pages = size / page_sz;
@@ -3084,39 +3070,40 @@ static address get_stack_commited_bottom(address bottom, size_t size) {
while (imin < imax) {
imid = (imax + imin) / 2;
- nbot = ntop - (imid * page_sz);
+ test_addr = bottom + (imid * page_sz);
// Use a trick with mincore to check whether the page is mapped or not.
// mincore sets vec to 1 if page resides in memory and to 0 if page
// is swapped output but if page we are asking for is unmapped
// it returns -1,ENOMEM
- mincore_return_value = mincore(nbot, page_sz, vec);
+ mincore_return_value = mincore(test_addr, page_sz, vec);
- if (mincore_return_value == -1) {
- // Page is not mapped go up
- // to find first mapped page
- if (errno != EAGAIN) {
- assert(errno == ENOMEM, "Unexpected mincore errno");
- imax = imid;
+ if (mincore_return_value == -1 || (committed_only && (vec[0] & 0x01) == 0)) {
+ // Page is not mapped/committed go up
+ // to find first mapped/committed page
+ if ((mincore_return_value == -1 && errno != EAGAIN)
+ || (committed_only && (vec[0] & 0x01) == 0)) {
+ assert(mincore_return_value != -1 || errno == ENOMEM, "Unexpected mincore errno");
+
+ imin = imid + 1;
}
} else {
- // Page is mapped go down
- // to find first not mapped page
- imin = imid + 1;
+ // mapped/committed, go down
+ imax= imid;
}
}
- nbot = nbot + page_sz;
+ // Adjust stack bottom one page up if last checked page is not mapped/committed
+ if (mincore_return_value == -1 || (committed_only && (vec[0] & 0x01) == 0)) {
+ assert(mincore_return_value != -1 || (errno != EAGAIN && errno != ENOMEM),
+ "Should not get to here");
- // Adjust stack bottom one page up if last checked page is not mapped
- if (mincore_return_value == -1) {
- nbot = nbot + page_sz;
+ test_addr = test_addr + page_sz;
}
- return nbot;
+ return test_addr;
}
-
// Linux uses a growable mapping for the stack, and if the mapping for
// the stack guard pages is not removed when we detach a thread the
// stack cannot grow beyond the pages where the stack guard was
@@ -3153,9 +3140,9 @@ bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
if (mincore((address)stack_extent, os::vm_page_size(), vec) == -1) {
// Fallback to slow path on all errors, including EAGAIN
- stack_extent = (uintptr_t) get_stack_commited_bottom(
- os::Linux::initial_thread_stack_bottom(),
- (size_t)addr - stack_extent);
+ stack_extent = (uintptr_t) get_stack_mapped_bottom(os::Linux::initial_thread_stack_bottom(),
+ (size_t)addr - stack_extent,
+ false /* committed_only */);
}
if (stack_extent < (uintptr_t)addr) {
@@ -3182,6 +3169,11 @@ bool os::remove_stack_guard_pages(char* addr, size_t size) {
return os::uncommit_memory(addr, size);
}
+size_t os::committed_stack_size(address bottom, size_t size) {
+ address bot = get_stack_mapped_bottom(bottom, size, true /* committed_only */);
+ return size_t(bottom + size - bot);
+}
+
// If 'fixed' is true, anon_mmap() will attempt to reserve anonymous memory
// at 'requested_addr'. If there are existing memory mappings at the same
// location, however, they will be overwritten. If 'fixed' is false,
diff --git a/src/hotspot/os/posix/os_posix.cpp b/src/hotspot/os/posix/os_posix.cpp
index 1019b6b1277..8f5741e69af 100644
--- a/src/hotspot/os/posix/os_posix.cpp
+++ b/src/hotspot/os/posix/os_posix.cpp
@@ -331,8 +331,15 @@ char* os::reserve_memory_aligned(size_t size, size_t alignment, int file_desc) {
return aligned_base;
}
-int os::log_vsnprintf(char* buf, size_t len, const char* fmt, va_list args) {
- return vsnprintf(buf, len, fmt, args);
+int os::vsnprintf(char* buf, size_t len, const char* fmt, va_list args) {
+ // All supported POSIX platforms provide C99 semantics.
+ int result = ::vsnprintf(buf, len, fmt, args);
+ // If an encoding error occurred (result < 0) then it's not clear
+ // whether the buffer is NUL terminated, so ensure it is.
+ if ((result < 0) && (len > 0)) {
+ buf[len - 1] = '\0';
+ }
+ return result;
}
int os::get_fileno(FILE* fp) {
diff --git a/src/hotspot/os/solaris/dtrace/jhelper.d b/src/hotspot/os/solaris/dtrace/jhelper.d
index c214481bec8..87bdf4b07fc 100644
--- a/src/hotspot/os/solaris/dtrace/jhelper.d
+++ b/src/hotspot/os/solaris/dtrace/jhelper.d
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, 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
@@ -19,7 +19,7 @@
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
- *
+ *
*/
/* This file is auto-generated */
@@ -30,7 +30,7 @@
#ifdef DEBUG
#define MARK_LINE this->line = __LINE__
#else
-#define MARK_LINE
+#define MARK_LINE
#endif
#ifdef _LP64
@@ -59,9 +59,8 @@ extern pointer __1cKBufferBlobG__vtbl_;
#define copyin_int32(ADDR) *(int32_t*) copyin((pointer) (ADDR), sizeof(int32_t))
#define copyin_uint8(ADDR) *(uint8_t*) copyin((pointer) (ADDR), sizeof(uint8_t))
-#define SAME(x) x
#define copyin_offset(JVM_CONST) JVM_CONST = \
- copyin_int32(JvmOffsetsPtr + SAME(IDX_)JVM_CONST * sizeof(int32_t))
+ copyin_int32(JvmOffsetsPtr + IDX_##JVM_CONST * sizeof(int32_t))
int init_done;
@@ -97,7 +96,7 @@ dtrace:helper:ustack:
/!init_done && !this->done/
{
MARK_LINE;
-
+
copyin_offset(POINTER_SIZE);
copyin_offset(COMPILER);
copyin_offset(OFFSET_CollectedHeap_reserved);
@@ -158,7 +157,9 @@ dtrace:helper:ustack:
#endif
/* Read address of GrowableArray */
- this->code_heaps_address = copyin_ptr(&``__1cJCodeCacheG_heaps_);
+ // this->code_heaps_address = copyin_ptr(&``__1cJCodeCacheG_heaps_);
+ this->code_heaps_address = * ( uint64_t * ) copyin ( ( uint64_t ) ( &``__1cJCodeCacheG_heaps_ ) , sizeof ( uint64_t ) );
+
/* Read address of _data array field in GrowableArray */
this->code_heaps_array_address = copyin_ptr(this->code_heaps_address + OFFSET_GrowableArray_CodeHeap_data);
this->number_of_heaps = copyin_uint32(this->code_heaps_address + OFFSET_GrowableArray_CodeHeap_len);
@@ -168,7 +169,9 @@ dtrace:helper:ustack:
/*
* Get Java heap bounds
*/
- this->Universe_collectedHeap = copyin_ptr(&``__1cIUniverseO_collectedHeap_);
+ // this->Universe_collectedHeap = copyin_ptr(&``__1cIUniverseO_collectedHeap_);
+ this->Universe_collectedHeap = * ( uint64_t * ) copyin ( ( uint64_t ) ( &``__1cIUniverseO_collectedHeap_ ) , sizeof ( uint64_t ) );
+
this->heap_start = copyin_ptr(this->Universe_collectedHeap +
OFFSET_CollectedHeap_reserved +
OFFSET_MemRegion_start);
@@ -181,8 +184,8 @@ dtrace:helper:ustack:
}
/*
- * IMPORTANT: At the moment the ustack helper supports up to 5 code heaps in
- * the code cache. If more code heaps are added the following probes have to
+ * IMPORTANT: At the moment the ustack helper supports up to 5 code heaps in
+ * the code cache. If more code heaps are added the following probes have to
* be extended. This is done by simply adding a probe to get the heap bounds
* and another probe to set the code heap address of the newly created heap.
*/
@@ -197,7 +200,7 @@ dtrace:helper:ustack:
/* CodeHeap 1 */
init_done = 1;
this->code_heap1_address = copyin_ptr(this->code_heaps_array_address);
- this->code_heap1_low = copyin_ptr(this->code_heap1_address +
+ this->code_heap1_low = copyin_ptr(this->code_heap1_address +
OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_low);
this->code_heap1_high = copyin_ptr(this->code_heap1_address +
OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_high);
@@ -211,7 +214,7 @@ dtrace:helper:ustack:
init_done = 2;
this->code_heaps_array_address = this->code_heaps_array_address + POINTER_SIZE;
this->code_heap2_address = copyin_ptr(this->code_heaps_array_address);
- this->code_heap2_low = copyin_ptr(this->code_heap2_address +
+ this->code_heap2_low = copyin_ptr(this->code_heap2_address +
OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_low);
this->code_heap2_high = copyin_ptr(this->code_heap2_address +
OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_high);
@@ -224,7 +227,7 @@ dtrace:helper:ustack:
init_done = 3;
this->code_heaps_array_address = this->code_heaps_array_address + POINTER_SIZE;
this->code_heap3_address = copyin_ptr(this->code_heaps_array_address);
- this->code_heap3_low = copyin_ptr(this->code_heap3_address +
+ this->code_heap3_low = copyin_ptr(this->code_heap3_address +
OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_low);
this->code_heap3_high = copyin_ptr(this->code_heap3_address +
OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_high);
@@ -237,7 +240,7 @@ dtrace:helper:ustack:
init_done = 4;
this->code_heaps_array_address = this->code_heaps_array_address + POINTER_SIZE;
this->code_heap4_address = copyin_ptr(this->code_heaps_array_address);
- this->code_heap4_low = copyin_ptr(this->code_heap4_address +
+ this->code_heap4_low = copyin_ptr(this->code_heap4_address +
OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_low);
this->code_heap4_high = copyin_ptr(this->code_heap4_address +
OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_high);
@@ -250,7 +253,7 @@ dtrace:helper:ustack:
init_done = 5;
this->code_heaps_array_address = this->code_heaps_array_address + POINTER_SIZE;
this->code_heap5_address = copyin_ptr(this->code_heaps_array_address);
- this->code_heap5_low = copyin_ptr(this->code_heap5_address +
+ this->code_heap5_low = copyin_ptr(this->code_heap5_address +
OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_low);
this->code_heap5_high = copyin_ptr(this->code_heap5_address +
OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_high);
@@ -309,10 +312,10 @@ dtrace:helper:ustack:
/!this->done && this->codecache/
{
MARK_LINE;
- /*
+ /*
* Get code heap configuration
*/
- this->code_heap_low = copyin_ptr(this->code_heap_address +
+ this->code_heap_low = copyin_ptr(this->code_heap_address +
OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_low);
this->code_heap_segmap_low = copyin_ptr(this->code_heap_address +
OFFSET_CodeHeap_segmap + OFFSET_VirtualSpace_low);
@@ -506,10 +509,10 @@ dtrace:helper:ustack:
/*
* Now we need to add a trailing '\0' and possibly a tag character.
*/
- this->result[this->klassSymbolLength + 1 +
+ this->result[this->klassSymbolLength + 1 +
this->nameSymbolLength +
this->signatureSymbolLength] = this->suffix;
- this->result[this->klassSymbolLength + 2 +
+ this->result[this->klassSymbolLength + 2 +
this->nameSymbolLength +
this->signatureSymbolLength] = '\0';
@@ -519,7 +522,7 @@ dtrace:helper:ustack:
dtrace:helper:ustack:
/this->done && this->error == (char *) NULL/
{
- this->result;
+ this->result;
}
dtrace:helper:ustack:
diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp
index 8e0e64f1d1a..1e667194116 100644
--- a/src/hotspot/os/windows/os_windows.cpp
+++ b/src/hotspot/os/windows/os_windows.cpp
@@ -363,6 +363,25 @@ size_t os::current_stack_size() {
return sz;
}
+size_t os::committed_stack_size(address bottom, size_t size) {
+ MEMORY_BASIC_INFORMATION minfo;
+ address top = bottom + size;
+ size_t committed_size = 0;
+
+ while (committed_size < size) {
+ // top is exclusive
+ VirtualQuery(top - 1, &minfo, sizeof(minfo));
+ if ((minfo.State & MEM_COMMIT) != 0) {
+ committed_size += minfo.RegionSize;
+ top -= minfo.RegionSize;
+ } else {
+ break;
+ }
+ }
+
+ return MIN2(committed_size, size);
+}
+
struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {
const struct tm* time_struct_ptr = localtime(clock);
if (time_struct_ptr != NULL) {
@@ -979,11 +998,6 @@ void os::shutdown() {
}
-static BOOL (WINAPI *_MiniDumpWriteDump)(HANDLE, DWORD, HANDLE, MINIDUMP_TYPE,
- PMINIDUMP_EXCEPTION_INFORMATION,
- PMINIDUMP_USER_STREAM_INFORMATION,
- PMINIDUMP_CALLBACK_INFORMATION);
-
static HANDLE dumpFile = NULL;
// Check if dump file can be created.
@@ -1499,13 +1513,39 @@ void os::get_summary_os_info(char* buf, size_t buflen) {
if (nl != NULL) *nl = '\0';
}
-int os::log_vsnprintf(char* buf, size_t len, const char* fmt, va_list args) {
- int ret = vsnprintf(buf, len, fmt, args);
- // Get the correct buffer size if buf is too small
- if (ret < 0) {
- return _vscprintf(fmt, args);
+int os::vsnprintf(char* buf, size_t len, const char* fmt, va_list args) {
+#if _MSC_VER >= 1900
+ // Starting with Visual Studio 2015, vsnprint is C99 compliant.
+ int result = ::vsnprintf(buf, len, fmt, args);
+ // If an encoding error occurred (result < 0) then it's not clear
+ // whether the buffer is NUL terminated, so ensure it is.
+ if ((result < 0) && (len > 0)) {
+ buf[len - 1] = '\0';
}
- return ret;
+ return result;
+#else
+ // Before Visual Studio 2015, vsnprintf is not C99 compliant, so use
+ // _vsnprintf, whose behavior seems to be *mostly* consistent across
+ // versions. However, when len == 0, avoid _vsnprintf too, and just
+ // go straight to _vscprintf. The output is going to be truncated in
+ // that case, except in the unusual case of empty output. More
+ // importantly, the documentation for various versions of Visual Studio
+ // are inconsistent about the behavior of _vsnprintf when len == 0,
+ // including it possibly being an error.
+ int result = -1;
+ if (len > 0) {
+ result = _vsnprintf(buf, len, fmt, args);
+ // If output (including NUL terminator) is truncated, the buffer
+ // won't be NUL terminated. Add the trailing NUL specified by C99.
+ if ((result < 0) || (result >= len)) {
+ buf[len - 1] = '\0';
+ }
+ }
+ if (result < 0) {
+ result = _vscprintf(fmt, args);
+ }
+ return result;
+#endif // _MSC_VER dispatch
}
static inline time_t get_mtime(const char* filename) {
diff --git a/src/hotspot/os/windows/semaphore_windows.hpp b/src/hotspot/os/windows/semaphore_windows.hpp
index fc9ed1ba7cd..cb62acda61f 100644
--- a/src/hotspot/os/windows/semaphore_windows.hpp
+++ b/src/hotspot/os/windows/semaphore_windows.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
#include "memory/allocation.hpp"
-#include
+#include
class WindowsSemaphore : public CHeapObj {
HANDLE _semaphore;
diff --git a/src/hotspot/os/windows/sharedRuntimeRem.cpp b/src/hotspot/os/windows/sharedRuntimeRem.cpp
index 23b2619882d..243f1eb75ce 100644
--- a/src/hotspot/os/windows/sharedRuntimeRem.cpp
+++ b/src/hotspot/os/windows/sharedRuntimeRem.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "runtime/sharedRuntime.hpp"
#ifdef _WIN64
// These are copied defines from fdlibm.h, this allows us to keep the code
diff --git a/src/hotspot/os/windows/symbolengine.cpp b/src/hotspot/os/windows/symbolengine.cpp
index 7f816dc365e..cf0af3c45b0 100644
--- a/src/hotspot/os/windows/symbolengine.cpp
+++ b/src/hotspot/os/windows/symbolengine.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
#include "utilities/globalDefinitions.hpp"
#include "symbolengine.hpp"
#include "utilities/debug.hpp"
+#include "utilities/ostream.hpp"
#include "windbghelp.hpp"
#include
diff --git a/src/hotspot/os/windows/windbghelp.hpp b/src/hotspot/os/windows/windbghelp.hpp
index 97dddbc9aa5..f55c55384ec 100644
--- a/src/hotspot/os/windows/windbghelp.hpp
+++ b/src/hotspot/os/windows/windbghelp.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,8 +22,8 @@
*
*/
-#ifndef OS_WINDOWS_VM_DBGHELPLOADER_HPP
-#define OS_WINDOWS_VM_DBGHELPLOADER_HPP
+#ifndef OS_WINDOWS_WINDBGHELP_HPP
+#define OS_WINDOWS_WINDBGHELP_HPP
#include
#include
@@ -71,6 +71,5 @@ namespace WindowsDbgHelp {
};
-
-#endif // OS_WINDOWS_VM_DBGHELPLOADER_HPP
+#endif // OS_WINDOWS_WINDBGHELP_HPP
diff --git a/src/hotspot/os_cpu/linux_arm/thread_linux_arm.cpp b/src/hotspot/os_cpu/linux_arm/thread_linux_arm.cpp
index 4225da2a17a..287fcea9b2a 100644
--- a/src/hotspot/os_cpu/linux_arm/thread_linux_arm.cpp
+++ b/src/hotspot/os_cpu/linux_arm/thread_linux_arm.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2017, 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
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "gc/shared/barrierSet.inline.hpp"
+#include "gc/shared/cardTable.hpp"
#include "gc/shared/cardTableModRefBS.inline.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "memory/metaspaceShared.hpp"
@@ -42,7 +43,7 @@ void JavaThread::cache_global_variables() {
}
if (bs->is_a(BarrierSet::CardTableModRef)) {
- _card_table_base = (address) (barrier_set_cast(bs)->byte_map_base);
+ _card_table_base = (address) (barrier_set_cast(bs)->card_table()->byte_map_base());
} else {
_card_table_base = NULL;
}
diff --git a/src/hotspot/share/adlc/arena.hpp b/src/hotspot/share/adlc/arena.hpp
index 7f09511d6ca..b98bf2a77e5 100644
--- a/src/hotspot/share/adlc/arena.hpp
+++ b/src/hotspot/share/adlc/arena.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -69,6 +69,11 @@ class AllStatic {
//------------------------------Chunk------------------------------------------
// Linked list of raw memory chunks
class Chunk: public CHeapObj {
+ private:
+ // This ordinary operator delete is needed even though not used, so the
+ // below two-argument operator delete will be treated as a placement
+ // delete rather than an ordinary sized delete; see C++14 3.7.4.2/p2.
+ void operator delete(void* p);
public:
void* operator new(size_t size, size_t length) throw();
void operator delete(void* p, size_t length);
diff --git a/src/hotspot/share/aot/aotCodeHeap.cpp b/src/hotspot/share/aot/aotCodeHeap.cpp
index e22e228acf1..387d311bdc8 100644
--- a/src/hotspot/share/aot/aotCodeHeap.cpp
+++ b/src/hotspot/share/aot/aotCodeHeap.cpp
@@ -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,7 +25,10 @@
#include "aot/aotCodeHeap.hpp"
#include "aot/aotLoader.hpp"
+#include "ci/ciUtilities.hpp"
#include "classfile/javaAssertions.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "gc/shared/cardTableModRefBS.hpp"
#include "gc/g1/heapRegion.hpp"
#include "gc/shared/gcLocker.hpp"
#include "interpreter/abstractInterpreter.hpp"
@@ -194,7 +197,7 @@ void AOTLib::verify_config() {
}
AOTLib::~AOTLib() {
- free((void*) _name);
+ os::free((void*) _name);
}
AOTCodeHeap::~AOTCodeHeap() {
@@ -207,7 +210,7 @@ AOTCodeHeap::~AOTCodeHeap() {
}
AOTLib::AOTLib(void* handle, const char* name, int dso_id) : _valid(true), _dl_handle(handle), _dso_id(dso_id) {
- _name = (const char*) strdup(name);
+ _name = (const char*) os::strdup(name);
// Verify that VM runs with the same parameters as AOT tool.
_config = (AOTConfiguration*) load_symbol("A.config");
@@ -539,8 +542,7 @@ void AOTCodeHeap::link_global_lib_symbols() {
_lib_symbols_initialized = true;
CollectedHeap* heap = Universe::heap();
- CardTableModRefBS* ct = (CardTableModRefBS*)(heap->barrier_set());
- SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_card_table_address", address, ct->byte_map_base);
+ SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_card_table_address", address, ci_card_table_address());
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_heap_top_address", address, (heap->supports_inline_contig_alloc() ? heap->top_addr() : NULL));
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_heap_end_address", address, (heap->supports_inline_contig_alloc() ? heap->end_addr() : NULL));
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_polling_page", address, os::get_polling_page());
diff --git a/src/hotspot/share/asm/codeBuffer.hpp b/src/hotspot/share/asm/codeBuffer.hpp
index d9bf86e4850..294af88c6f3 100644
--- a/src/hotspot/share/asm/codeBuffer.hpp
+++ b/src/hotspot/share/asm/codeBuffer.hpp
@@ -380,7 +380,7 @@ class CodeBuffer: public StackObj {
OopRecorder _default_oop_recorder; // override with initialize_oop_recorder
Arena* _overflow_arena;
- address _last_membar; // used to merge consecutive memory barriers
+ address _last_insn; // used to merge consecutive memory barriers, loads or stores.
address _decode_begin; // start address for decode
address decode_begin();
@@ -395,7 +395,7 @@ class CodeBuffer: public StackObj {
_decode_begin = NULL;
_overflow_arena = NULL;
_code_strings = CodeStrings();
- _last_membar = NULL;
+ _last_insn = NULL;
}
void initialize(address code_start, csize_t code_size) {
@@ -587,9 +587,9 @@ class CodeBuffer: public StackObj {
OopRecorder* oop_recorder() const { return _oop_recorder; }
CodeStrings& strings() { return _code_strings; }
- address last_membar() const { return _last_membar; }
- void set_last_membar(address a) { _last_membar = a; }
- void clear_last_membar() { set_last_membar(NULL); }
+ address last_insn() const { return _last_insn; }
+ void set_last_insn(address a) { _last_insn = a; }
+ void clear_last_insn() { set_last_insn(NULL); }
void free_strings() {
if (!_code_strings.is_null()) {
diff --git a/src/hotspot/share/c1/c1_LIRGenerator.cpp b/src/hotspot/share/c1/c1_LIRGenerator.cpp
index ed64f686a92..367fa30d9b4 100644
--- a/src/hotspot/share/c1/c1_LIRGenerator.cpp
+++ b/src/hotspot/share/c1/c1_LIRGenerator.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,8 @@
#include "ci/ciArrayKlass.hpp"
#include "ci/ciInstance.hpp"
#include "ci/ciObjArray.hpp"
+#include "ci/ciUtilities.hpp"
+#include "gc/shared/cardTable.hpp"
#include "gc/shared/cardTableModRefBS.hpp"
#include "runtime/arguments.hpp"
#include "runtime/sharedRuntime.hpp"
@@ -1461,11 +1463,7 @@ void LIRGenerator::pre_barrier(LIR_Opr addr_opr, LIR_Opr pre_val,
G1SATBCardTableModRef_pre_barrier(addr_opr, pre_val, do_load, patch, info);
break;
#endif // INCLUDE_ALL_GCS
- case BarrierSet::CardTableForRS:
- case BarrierSet::CardTableExtension:
- // No pre barriers
- break;
- case BarrierSet::ModRef:
+ case BarrierSet::CardTableModRef:
// No pre barriers
break;
default :
@@ -1481,13 +1479,9 @@ void LIRGenerator::post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) {
G1SATBCardTableModRef_post_barrier(addr, new_val);
break;
#endif // INCLUDE_ALL_GCS
- case BarrierSet::CardTableForRS:
- case BarrierSet::CardTableExtension:
+ case BarrierSet::CardTableModRef:
CardTableModRef_post_barrier(addr, new_val);
break;
- case BarrierSet::ModRef:
- // No post barriers
- break;
default :
ShouldNotReachHere();
}
@@ -1616,9 +1610,7 @@ void LIRGenerator::G1SATBCardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_Opr
////////////////////////////////////////////////////////////////////////
void LIRGenerator::CardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) {
- CardTableModRefBS* ct = barrier_set_cast(_bs);
- assert(sizeof(*(ct->byte_map_base)) == sizeof(jbyte), "adjust this code");
- LIR_Const* card_table_base = new LIR_Const(ct->byte_map_base);
+ LIR_Const* card_table_base = new LIR_Const(ci_card_table_address());
if (addr->is_address()) {
LIR_Address* address = addr->as_address_ptr();
// ptr cannot be an object because we use this barrier for array card marks
@@ -1640,9 +1632,9 @@ void LIRGenerator::CardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc*
LIR_Opr tmp = new_pointer_register();
if (TwoOperandLIRForm) {
__ move(addr, tmp);
- __ unsigned_shift_right(tmp, CardTableModRefBS::card_shift, tmp);
+ __ unsigned_shift_right(tmp, CardTable::card_shift, tmp);
} else {
- __ unsigned_shift_right(addr, CardTableModRefBS::card_shift, tmp);
+ __ unsigned_shift_right(addr, CardTable::card_shift, tmp);
}
LIR_Address* card_addr;
@@ -1652,7 +1644,7 @@ void LIRGenerator::CardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc*
card_addr = new LIR_Address(tmp, load_constant(card_table_base), T_BYTE);
}
- LIR_Opr dirty = LIR_OprFact::intConst(CardTableModRefBS::dirty_card_val());
+ LIR_Opr dirty = LIR_OprFact::intConst(CardTable::dirty_card_val());
if (UseCondCardMark) {
LIR_Opr cur_value = new_register(T_INT);
if (UseConcMarkSweepGC) {
diff --git a/src/hotspot/share/c1/c1_Runtime1.cpp b/src/hotspot/share/c1/c1_Runtime1.cpp
index 4d567b7dd07..3256106a5c9 100644
--- a/src/hotspot/share/c1/c1_Runtime1.cpp
+++ b/src/hotspot/share/c1/c1_Runtime1.cpp
@@ -47,6 +47,7 @@
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "oops/access.inline.hpp"
+#include "oops/objArrayOop.inline.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/atomic.hpp"
diff --git a/src/hotspot/share/ci/ciArray.cpp b/src/hotspot/share/ci/ciArray.cpp
index 2c9b44a2042..8cd5ddd6af7 100644
--- a/src/hotspot/share/ci/ciArray.cpp
+++ b/src/hotspot/share/ci/ciArray.cpp
@@ -30,7 +30,7 @@
#include "ci/ciUtilities.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
-#include "oops/typeArrayOop.hpp"
+#include "oops/typeArrayOop.inline.hpp"
// ciArray
//
diff --git a/src/hotspot/share/ci/ciEnv.cpp b/src/hotspot/share/ci/ciEnv.cpp
index d6129433c8d..ee8573bae1b 100644
--- a/src/hotspot/share/ci/ciEnv.cpp
+++ b/src/hotspot/share/ci/ciEnv.cpp
@@ -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
@@ -53,6 +53,7 @@
#include "prims/jvmtiExport.hpp"
#include "runtime/init.hpp"
#include "runtime/reflection.hpp"
+#include "runtime/jniHandles.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/thread.inline.hpp"
#include "trace/tracing.hpp"
diff --git a/src/hotspot/share/ci/ciInstanceKlass.cpp b/src/hotspot/share/ci/ciInstanceKlass.cpp
index 3368cc01048..c1aad9f2c43 100644
--- a/src/hotspot/share/ci/ciInstanceKlass.cpp
+++ b/src/hotspot/share/ci/ciInstanceKlass.cpp
@@ -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
@@ -34,6 +34,7 @@
#include "oops/oop.inline.hpp"
#include "oops/fieldStreams.hpp"
#include "runtime/fieldDescriptor.hpp"
+#include "runtime/jniHandles.inline.hpp"
// ciInstanceKlass
//
diff --git a/src/hotspot/share/ci/ciObject.cpp b/src/hotspot/share/ci/ciObject.cpp
index 23f4b0f2fdf..16794b02e87 100644
--- a/src/hotspot/share/ci/ciObject.cpp
+++ b/src/hotspot/share/ci/ciObject.cpp
@@ -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
@@ -27,6 +27,7 @@
#include "ci/ciUtilities.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "runtime/jniHandles.inline.hpp"
// ciObject
//
@@ -97,6 +98,14 @@ ciObject::ciObject() {
_klass = NULL;
}
+// ------------------------------------------------------------------
+// ciObject::get_oop
+//
+// Get the oop of this ciObject.
+oop ciObject::get_oop() const {
+ return JNIHandles::resolve_non_null(_handle);
+}
+
// ------------------------------------------------------------------
// ciObject::klass
//
diff --git a/src/hotspot/share/ci/ciObject.hpp b/src/hotspot/share/ci/ciObject.hpp
index c33b79ed5ed..5fbdfd1d7d3 100644
--- a/src/hotspot/share/ci/ciObject.hpp
+++ b/src/hotspot/share/ci/ciObject.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -67,10 +67,7 @@ protected:
jobject handle() const { return _handle; }
// Get the VM oop that this object holds.
- oop get_oop() const {
- assert(_handle != NULL, "null oop");
- return JNIHandles::resolve_non_null(_handle);
- }
+ oop get_oop() const;
void init_flags_from(oop x);
diff --git a/src/hotspot/share/ci/ciTypeArray.cpp b/src/hotspot/share/ci/ciTypeArray.cpp
index f85379fdb43..60814a261eb 100644
--- a/src/hotspot/share/ci/ciTypeArray.cpp
+++ b/src/hotspot/share/ci/ciTypeArray.cpp
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "ci/ciTypeArray.hpp"
#include "ci/ciUtilities.hpp"
+#include "oops/typeArrayOop.inline.hpp"
// ciTypeArray
//
diff --git a/src/hotspot/share/ci/ciUtilities.cpp b/src/hotspot/share/ci/ciUtilities.cpp
index f64f7efb376..2c8ed80acf3 100644
--- a/src/hotspot/share/ci/ciUtilities.cpp
+++ b/src/hotspot/share/ci/ciUtilities.cpp
@@ -24,6 +24,9 @@
#include "precompiled.hpp"
#include "ci/ciUtilities.hpp"
+#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "memory/universe.hpp"
// ciUtilities
//
@@ -43,3 +46,13 @@ const char basictype_to_char(BasicType t) {
char c = type2char(t);
return c ? c : 'X';
}
+
+// ------------------------------------------------------------------
+// card_table_base
+jbyte *ci_card_table_address() {
+ BarrierSet* bs = Universe::heap()->barrier_set();
+ CardTableModRefBS* ctbs = barrier_set_cast(bs);
+ CardTable* ct = ctbs->card_table();
+ assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust users of this code");
+ return ct->byte_map_base();
+}
diff --git a/src/hotspot/share/ci/ciUtilities.hpp b/src/hotspot/share/ci/ciUtilities.hpp
index bba611fc3b6..e0ec54fb74e 100644
--- a/src/hotspot/share/ci/ciUtilities.hpp
+++ b/src/hotspot/share/ci/ciUtilities.hpp
@@ -27,6 +27,7 @@
#include "ci/ciEnv.hpp"
#include "runtime/interfaceSupport.hpp"
+#include "utilities/globalDefinitions.hpp"
// The following routines and definitions are used internally in the
// compiler interface.
@@ -114,4 +115,9 @@ inline const char* bool_to_str(bool b) {
const char* basictype_to_str(BasicType t);
const char basictype_to_char(BasicType t);
+jbyte *ci_card_table_address();
+template T ci_card_table_address_as() {
+ return reinterpret_cast(ci_card_table_address());
+}
+
#endif // SHARE_VM_CI_CIUTILITIES_HPP
diff --git a/src/hotspot/share/classfile/classLoader.cpp b/src/hotspot/share/classfile/classLoader.cpp
index 2aa83548fe0..5f2e9d845a1 100644
--- a/src/hotspot/share/classfile/classLoader.cpp
+++ b/src/hotspot/share/classfile/classLoader.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -137,7 +137,6 @@ PerfCounter* ClassLoader::_sync_JVMFindLoadedClassLockFreeCounter = NULL;
PerfCounter* ClassLoader::_sync_JVMDefineClassLockFreeCounter = NULL;
PerfCounter* ClassLoader::_sync_JNIDefineClassLockFreeCounter = NULL;
PerfCounter* ClassLoader::_unsafe_defineClassCallCounter = NULL;
-PerfCounter* ClassLoader::_isUnsyncloadClass = NULL;
PerfCounter* ClassLoader::_load_instance_class_failCounter = NULL;
GrowableArray* ClassLoader::_patch_mod_entries = NULL;
@@ -1642,9 +1641,6 @@ void ClassLoader::initialize() {
// of the bug fix of 6365597. They are mainly focused on finding out
// the behavior of system & user-defined classloader lock, whether
// ClassLoader.loadClass/findClass is being called synchronized or not.
- // Also two additional counters are created to see whether 'UnsyncloadClass'
- // flag is being set or not and how many times load_instance_class call
- // fails with linkageError etc.
NEWPERFEVENTCOUNTER(_sync_systemLoaderLockContentionRate, SUN_CLS,
"systemLoaderLockContentionRate");
NEWPERFEVENTCOUNTER(_sync_nonSystemLoaderLockContentionRate, SUN_CLS,
@@ -1660,14 +1656,8 @@ void ClassLoader::initialize() {
NEWPERFEVENTCOUNTER(_unsafe_defineClassCallCounter, SUN_CLS,
"unsafeDefineClassCalls");
- NEWPERFEVENTCOUNTER(_isUnsyncloadClass, SUN_CLS, "isUnsyncloadClassSet");
NEWPERFEVENTCOUNTER(_load_instance_class_failCounter, SUN_CLS,
"loadInstanceClassFailRate");
-
- // increment the isUnsyncloadClass counter if UnsyncloadClass is set.
- if (UnsyncloadClass) {
- _isUnsyncloadClass->inc();
- }
}
// lookup zip library entry points
diff --git a/src/hotspot/share/classfile/classLoader.hpp b/src/hotspot/share/classfile/classLoader.hpp
index 202a170979f..15fe68793e9 100644
--- a/src/hotspot/share/classfile/classLoader.hpp
+++ b/src/hotspot/share/classfile/classLoader.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -207,7 +207,6 @@ class ClassLoader: AllStatic {
static PerfCounter* _sync_JNIDefineClassLockFreeCounter;
static PerfCounter* _unsafe_defineClassCallCounter;
- static PerfCounter* _isUnsyncloadClass;
static PerfCounter* _load_instance_class_failCounter;
// The boot class path consists of 3 ordered pieces:
diff --git a/src/hotspot/share/classfile/classLoaderData.cpp b/src/hotspot/share/classfile/classLoaderData.cpp
index 25e1f7c0482..fb7eb43c245 100644
--- a/src/hotspot/share/classfile/classLoaderData.cpp
+++ b/src/hotspot/share/classfile/classLoaderData.cpp
@@ -1001,9 +1001,8 @@ ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous, TRA
if (!is_anonymous) {
- ClassLoaderData** cld_addr = java_lang_ClassLoader::loader_data_addr(loader());
// First, Atomically set it
- ClassLoaderData* old = Atomic::cmpxchg(cld, cld_addr, (ClassLoaderData*)NULL);
+ ClassLoaderData* old = java_lang_ClassLoader::cmpxchg_loader_data(cld, loader(), NULL);
if (old != NULL) {
delete cld;
// Returns the data.
diff --git a/src/hotspot/share/classfile/javaAssertions.cpp b/src/hotspot/share/classfile/javaAssertions.cpp
index 790c420e2e0..1bc6e7c460a 100644
--- a/src/hotspot/share/classfile/javaAssertions.cpp
+++ b/src/hotspot/share/classfile/javaAssertions.cpp
@@ -31,6 +31,7 @@
#include "memory/oopFactory.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "runtime/handles.inline.hpp"
bool JavaAssertions::_userDefault = false;
diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp
index 5fdb0b10ea0..30c51117926 100644
--- a/src/hotspot/share/classfile/javaClasses.cpp
+++ b/src/hotspot/share/classfile/javaClasses.cpp
@@ -46,13 +46,14 @@
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
-#include "oops/typeArrayOop.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "prims/resolvedMethodTable.hpp"
#include "runtime/fieldDescriptor.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
+#include "runtime/jniHandles.inline.hpp"
#include "runtime/safepoint.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/vframe.hpp"
@@ -3403,7 +3404,7 @@ void java_lang_invoke_MethodHandleNatives_CallSiteContext::compute_offsets() {
DependencyContext java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(oop call_site) {
assert(java_lang_invoke_MethodHandleNatives_CallSiteContext::is_instance(call_site), "");
- intptr_t* vmdeps_addr = (intptr_t*)call_site->address_field_addr(_vmdependencies_offset);
+ intptr_t* vmdeps_addr = (intptr_t*)call_site->field_addr(_vmdependencies_offset);
DependencyContext dep_ctx(vmdeps_addr);
return dep_ctx;
}
@@ -3458,13 +3459,14 @@ int java_lang_ClassLoader::parallelCapable_offset = -1;
int java_lang_ClassLoader::name_offset = -1;
int java_lang_ClassLoader::unnamedModule_offset = -1;
-ClassLoaderData** java_lang_ClassLoader::loader_data_addr(oop loader) {
- assert(loader != NULL && oopDesc::is_oop(loader), "loader must be oop");
- return (ClassLoaderData**) loader->address_field_addr(_loader_data_offset);
+ClassLoaderData* java_lang_ClassLoader::loader_data(oop loader) {
+ assert(loader != NULL && oopDesc::is_oop(loader), "loader must be oop");
+ return HeapAccess<>::load_at(loader, _loader_data_offset);
}
-ClassLoaderData* java_lang_ClassLoader::loader_data(oop loader) {
- return *java_lang_ClassLoader::loader_data_addr(loader);
+ClassLoaderData* java_lang_ClassLoader::cmpxchg_loader_data(ClassLoaderData* new_data, oop loader, ClassLoaderData* expected_data) {
+ assert(loader != NULL && oopDesc::is_oop(loader), "loader must be oop");
+ return HeapAccess<>::atomic_cmpxchg_at(new_data, loader, _loader_data_offset, expected_data);
}
void java_lang_ClassLoader::compute_offsets() {
diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp
index 2aa1f886c23..741f225aea0 100644
--- a/src/hotspot/share/classfile/javaClasses.hpp
+++ b/src/hotspot/share/classfile/javaClasses.hpp
@@ -881,15 +881,15 @@ class java_lang_ref_Reference: AllStatic {
static inline oop referent(oop ref);
static inline void set_referent(oop ref, oop value);
static inline void set_referent_raw(oop ref, oop value);
- static inline HeapWord* referent_addr(oop ref);
+ static inline HeapWord* referent_addr_raw(oop ref);
static inline oop next(oop ref);
static inline void set_next(oop ref, oop value);
static inline void set_next_raw(oop ref, oop value);
- static inline HeapWord* next_addr(oop ref);
+ static inline HeapWord* next_addr_raw(oop ref);
static inline oop discovered(oop ref);
static inline void set_discovered(oop ref, oop value);
static inline void set_discovered_raw(oop ref, oop value);
- static inline HeapWord* discovered_addr(oop ref);
+ static inline HeapWord* discovered_addr_raw(oop ref);
static bool is_referent_field(oop obj, ptrdiff_t offset);
static inline bool is_phantom(oop ref);
};
@@ -1229,8 +1229,8 @@ class java_lang_ClassLoader : AllStatic {
public:
static void compute_offsets();
- static ClassLoaderData** loader_data_addr(oop loader);
static ClassLoaderData* loader_data(oop loader);
+ static ClassLoaderData* cmpxchg_loader_data(ClassLoaderData* new_data, oop loader, ClassLoaderData* expected_data);
static oop parent(oop loader);
static oop name(oop loader);
diff --git a/src/hotspot/share/classfile/javaClasses.inline.hpp b/src/hotspot/share/classfile/javaClasses.inline.hpp
index 1ca986a4c48..88dd152ef31 100644
--- a/src/hotspot/share/classfile/javaClasses.inline.hpp
+++ b/src/hotspot/share/classfile/javaClasses.inline.hpp
@@ -100,8 +100,8 @@ void java_lang_ref_Reference::set_referent(oop ref, oop value) {
void java_lang_ref_Reference::set_referent_raw(oop ref, oop value) {
ref->obj_field_put_raw(referent_offset, value);
}
-HeapWord* java_lang_ref_Reference::referent_addr(oop ref) {
- return ref->obj_field_addr(referent_offset);
+HeapWord* java_lang_ref_Reference::referent_addr_raw(oop ref) {
+ return ref->obj_field_addr_raw(referent_offset);
}
oop java_lang_ref_Reference::next(oop ref) {
return ref->obj_field(next_offset);
@@ -112,8 +112,8 @@ void java_lang_ref_Reference::set_next(oop ref, oop value) {
void java_lang_ref_Reference::set_next_raw(oop ref, oop value) {
ref->obj_field_put_raw(next_offset, value);
}
-HeapWord* java_lang_ref_Reference::next_addr(oop ref) {
- return ref->obj_field_addr(next_offset);
+HeapWord* java_lang_ref_Reference::next_addr_raw(oop ref) {
+ return ref->obj_field_addr_raw(next_offset);
}
oop java_lang_ref_Reference::discovered(oop ref) {
return ref->obj_field(discovered_offset);
@@ -124,8 +124,8 @@ void java_lang_ref_Reference::set_discovered(oop ref, oop value) {
void java_lang_ref_Reference::set_discovered_raw(oop ref, oop value) {
ref->obj_field_put_raw(discovered_offset, value);
}
-HeapWord* java_lang_ref_Reference::discovered_addr(oop ref) {
- return ref->obj_field_addr(discovered_offset);
+HeapWord* java_lang_ref_Reference::discovered_addr_raw(oop ref) {
+ return ref->obj_field_addr_raw(discovered_offset);
}
bool java_lang_ref_Reference::is_phantom(oop ref) {
return InstanceKlass::cast(ref->klass())->reference_type() == REF_PHANTOM;
diff --git a/src/hotspot/share/classfile/modules.cpp b/src/hotspot/share/classfile/modules.cpp
index efa770e4f33..30250770215 100644
--- a/src/hotspot/share/classfile/modules.cpp
+++ b/src/hotspot/share/classfile/modules.cpp
@@ -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
@@ -44,6 +44,7 @@
#include "runtime/arguments.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp"
+#include "runtime/jniHandles.inline.hpp"
#include "runtime/reflection.hpp"
#include "utilities/stringUtils.hpp"
#include "utilities/utf8.hpp"
diff --git a/src/hotspot/share/classfile/stringTable.cpp b/src/hotspot/share/classfile/stringTable.cpp
index a4ba7fd7a05..63b019fa2bb 100644
--- a/src/hotspot/share/classfile/stringTable.cpp
+++ b/src/hotspot/share/classfile/stringTable.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,7 @@
#include "memory/resourceArea.hpp"
#include "oops/access.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/mutexLocker.hpp"
#include "services/diagnosticCommand.hpp"
diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp
index 03d5b76c593..48e0c6ee1c5 100644
--- a/src/hotspot/share/classfile/systemDictionary.cpp
+++ b/src/hotspot/share/classfile/systemDictionary.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -106,7 +106,6 @@ InstanceKlass* SystemDictionary::_box_klasses[T_VOID+1] = { NULL /*,
oop SystemDictionary::_java_system_loader = NULL;
oop SystemDictionary::_java_platform_loader = NULL;
-bool SystemDictionary::_has_loadClassInternal = false;
bool SystemDictionary::_has_checkPackageAccess = false;
// lazily initialized klass variables
@@ -159,7 +158,7 @@ ClassLoaderData* SystemDictionary::register_loader(Handle class_loader, TRAPS) {
// Parallel class loading check
bool SystemDictionary::is_parallelCapable(Handle class_loader) {
- if (UnsyncloadClass || class_loader.is_null()) return true;
+ if (class_loader.is_null()) return true;
if (AlwaysLockClassLoader) return false;
return java_lang_ClassLoader::parallelCapable(class_loader());
}
@@ -503,8 +502,7 @@ void SystemDictionary::validate_protection_domain(InstanceKlass* klass,
//
// We only get here if
// 1) custom classLoader, i.e. not bootstrap classloader
-// 2) UnsyncloadClass not set
-// 3) custom classLoader has broken the class loader objectLock
+// 2) custom classLoader has broken the class loader objectLock
// so another thread got here in parallel
//
// lockObject must be held.
@@ -594,7 +592,6 @@ InstanceKlass* SystemDictionary::handle_parallel_super_load(
} else {
placeholder = placeholders()->get_entry(p_index, p_hash, name, loader_data);
if (placeholder && placeholder->super_load_in_progress() ){
- // Before UnsyncloadClass:
// We only get here if the application has released the
// classloader lock when another thread was in the middle of loading a
// superclass/superinterface for this class, and now
@@ -687,9 +684,9 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name,
// defining the class in parallel by accident.
// This lock must be acquired here so the waiter will find
// any successful result in the SystemDictionary and not attempt
- // the define
- // ParallelCapable Classloaders and the bootstrap classloader,
- // or all classloaders with UnsyncloadClass do not acquire lock here
+ // the define.
+ // ParallelCapable Classloaders and the bootstrap classloader
+ // do not acquire lock here.
bool DoObjectLock = true;
if (is_parallelCapable(class_loader)) {
DoObjectLock = false;
@@ -765,14 +762,11 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name,
// and that lock is still held when calling classloader's loadClass.
// For these classloaders, we ensure that the first requestor
// completes the load and other requestors wait for completion.
- // case 3. UnsyncloadClass - don't use objectLocker
- // With this flag, we allow parallel classloading of a
- // class/classloader pair
- // case4. Bootstrap classloader - don't own objectLocker
+ // case 3. Bootstrap classloader - don't own objectLocker
// This classloader supports parallelism at the classloader level,
// but only allows a single load of a class/classloader pair.
// No performance benefit and no deadlock issues.
- // case 5. parallelCapable user level classloaders - without objectLocker
+ // case 4. parallelCapable user level classloaders - without objectLocker
// Allow parallel classloading of a class/classloader pair
{
@@ -788,7 +782,7 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name,
// case 1: traditional: should never see load_in_progress.
while (!class_has_been_loaded && oldprobe && oldprobe->instance_load_in_progress()) {
- // case 4: bootstrap classloader: prevent futile classloading,
+ // case 3: bootstrap classloader: prevent futile classloading,
// wait on first requestor
if (class_loader.is_null()) {
SystemDictionary_lock->wait();
@@ -811,7 +805,7 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name,
}
}
// All cases: add LOAD_INSTANCE holding SystemDictionary_lock
- // case 3: UnsyncloadClass || case 5: parallelCapable: allow competing threads to try
+ // case 4: parallelCapable: allow competing threads to try
// LOAD_INSTANCE in parallel
if (!throw_circularity_error && !class_has_been_loaded) {
@@ -844,28 +838,6 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name,
// Do actual loading
k = load_instance_class(name, class_loader, THREAD);
- // For UnsyncloadClass only
- // If they got a linkageError, check if a parallel class load succeeded.
- // If it did, then for bytecode resolution the specification requires
- // that we return the same result we did for the other thread, i.e. the
- // successfully loaded InstanceKlass
- // Should not get here for classloaders that support parallelism
- // with the new cleaner mechanism, even with AllowParallelDefineClass
- // Bootstrap goes through here to allow for an extra guarantee check
- if (UnsyncloadClass || (class_loader.is_null())) {
- if (k == NULL && HAS_PENDING_EXCEPTION
- && PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) {
- MutexLocker mu(SystemDictionary_lock, THREAD);
- InstanceKlass* check = find_class(d_hash, name, dictionary);
- if (check != NULL) {
- // Klass is already loaded, so just use it
- k = check;
- CLEAR_PENDING_EXCEPTION;
- guarantee((!class_loader.is_null()), "dup definition for bootstrap loader?");
- }
- }
- }
-
// If everything was OK (no exceptions, no null return value), and
// class_loader is NOT the defining loader, do a little more bookkeeping.
if (!HAS_PENDING_EXCEPTION && k != NULL &&
@@ -1097,7 +1069,7 @@ InstanceKlass* SystemDictionary::resolve_from_stream(Symbol* class_name,
HandleMark hm(THREAD);
// Classloaders that support parallelism, e.g. bootstrap classloader,
- // or all classloaders with UnsyncloadClass do not acquire lock here
+ // do not acquire lock here
bool DoObjectLock = true;
if (is_parallelCapable(class_loader)) {
DoObjectLock = false;
@@ -1556,40 +1528,17 @@ InstanceKlass* SystemDictionary::load_instance_class(Symbol* class_name, Handle
InstanceKlass* spec_klass = SystemDictionary::ClassLoader_klass();
- // Call public unsynchronized loadClass(String) directly for all class loaders
- // for parallelCapable class loaders. JDK >=7, loadClass(String, boolean) will
+ // Call public unsynchronized loadClass(String) directly for all class loaders.
+ // For parallelCapable class loaders, JDK >=7, loadClass(String, boolean) will
// acquire a class-name based lock rather than the class loader object lock.
- // JDK < 7 already acquire the class loader lock in loadClass(String, boolean),
- // so the call to loadClassInternal() was not required.
- //
- // UnsyncloadClass flag means both call loadClass(String) and do
- // not acquire the class loader lock even for class loaders that are
- // not parallelCapable. This was a risky transitional
- // flag for diagnostic purposes only. It is risky to call
- // custom class loaders without synchronization.
- // WARNING If a custom class loader does NOT synchronizer findClass, or callers of
- // findClass, the UnsyncloadClass flag risks unexpected timing bugs in the field.
- // Do NOT assume this will be supported in future releases.
- //
- // Added MustCallLoadClassInternal in case we discover in the field
- // a customer that counts on this call
- if (MustCallLoadClassInternal && has_loadClassInternal()) {
- JavaCalls::call_special(&result,
- class_loader,
- spec_klass,
- vmSymbols::loadClassInternal_name(),
- vmSymbols::string_class_signature(),
- string,
- CHECK_NULL);
- } else {
- JavaCalls::call_virtual(&result,
- class_loader,
- spec_klass,
- vmSymbols::loadClass_name(),
- vmSymbols::string_class_signature(),
- string,
- CHECK_NULL);
- }
+ // JDK < 7 already acquire the class loader lock in loadClass(String, boolean).
+ JavaCalls::call_virtual(&result,
+ class_loader,
+ spec_klass,
+ vmSymbols::loadClass_name(),
+ vmSymbols::string_class_signature(),
+ string,
+ CHECK_NULL);
assert(result.get_type() == T_OBJECT, "just checking");
oop obj = (oop) result.get_jobject();
@@ -1718,7 +1667,7 @@ InstanceKlass* SystemDictionary::find_or_define_instance_class(Symbol* class_nam
{
MutexLocker mu(SystemDictionary_lock, THREAD);
// First check if class already defined
- if (UnsyncloadClass || (is_parallelDefine(class_loader))) {
+ if (is_parallelDefine(class_loader)) {
InstanceKlass* check = find_class(d_hash, name_h, dictionary);
if (check != NULL) {
return check;
@@ -1737,7 +1686,7 @@ InstanceKlass* SystemDictionary::find_or_define_instance_class(Symbol* class_nam
// Only special cases allow parallel defines and can use other thread's results
// Other cases fall through, and may run into duplicate defines
// caught by finding an entry in the SystemDictionary
- if ((UnsyncloadClass || is_parallelDefine(class_loader)) && (probe->instance_klass() != NULL)) {
+ if (is_parallelDefine(class_loader) && (probe->instance_klass() != NULL)) {
placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, THREAD);
SystemDictionary_lock->notify_all();
#ifdef ASSERT
@@ -2174,10 +2123,6 @@ void SystemDictionary::initialize_preloaded_classes(TRAPS) {
//_box_klasses[T_OBJECT] = WK_KLASS(object_klass);
//_box_klasses[T_ARRAY] = WK_KLASS(object_klass);
- { // Compute whether we should use loadClass or loadClassInternal when loading classes.
- Method* method = InstanceKlass::cast(ClassLoader_klass())->find_method(vmSymbols::loadClassInternal_name(), vmSymbols::string_class_signature());
- _has_loadClassInternal = (method != NULL);
- }
{ // Compute whether we should use checkPackageAccess or NOT
Method* method = InstanceKlass::cast(ClassLoader_klass())->find_method(vmSymbols::checkPackageAccess_name(), vmSymbols::class_protectiondomain_signature());
_has_checkPackageAccess = (method != NULL);
diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp
index 67ee987b204..a86bb27c3de 100644
--- a/src/hotspot/share/classfile/systemDictionary.hpp
+++ b/src/hotspot/share/classfile/systemDictionary.hpp
@@ -467,9 +467,6 @@ public:
static void load_abstract_ownable_synchronizer_klass(TRAPS);
protected:
- // Tells whether ClassLoader.loadClassInternal is present
- static bool has_loadClassInternal() { return _has_loadClassInternal; }
-
// Returns the class loader data to be used when looking up/updating the
// system dictionary.
static ClassLoaderData *class_loader_data(Handle class_loader) {
@@ -746,7 +743,6 @@ protected:
static oop _java_system_loader;
static oop _java_platform_loader;
- static bool _has_loadClassInternal;
static bool _has_checkPackageAccess;
};
diff --git a/src/hotspot/share/classfile/systemDictionaryShared.cpp b/src/hotspot/share/classfile/systemDictionaryShared.cpp
index 692ba891823..939e45fcb98 100644
--- a/src/hotspot/share/classfile/systemDictionaryShared.cpp
+++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -48,6 +48,7 @@
#include "oops/klass.inline.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
diff --git a/src/hotspot/share/classfile/verifier.cpp b/src/hotspot/share/classfile/verifier.cpp
index 14cb12d3d86..7c6ee408652 100644
--- a/src/hotspot/share/classfile/verifier.cpp
+++ b/src/hotspot/share/classfile/verifier.cpp
@@ -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
@@ -45,6 +45,7 @@
#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/javaCalls.hpp"
+#include "runtime/jniHandles.inline.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "runtime/os.hpp"
#include "runtime/thread.hpp"
diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp
index d451b56676e..d48f96283ea 100644
--- a/src/hotspot/share/classfile/vmSymbols.hpp
+++ b/src/hotspot/share/classfile/vmSymbols.hpp
@@ -360,7 +360,6 @@
template(run_finalization_name, "runFinalization") \
template(dispatchUncaughtException_name, "dispatchUncaughtException") \
template(loadClass_name, "loadClass") \
- template(loadClassInternal_name, "loadClassInternal") \
template(get_name, "get") \
template(put_name, "put") \
template(type_name, "type") \
diff --git a/src/hotspot/share/code/debugInfo.cpp b/src/hotspot/share/code/debugInfo.cpp
index c81ef90e9d0..2191effdd3c 100644
--- a/src/hotspot/share/code/debugInfo.cpp
+++ b/src/hotspot/share/code/debugInfo.cpp
@@ -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
@@ -29,6 +29,7 @@
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.hpp"
+#include "runtime/jniHandles.inline.hpp"
#include "runtime/thread.hpp"
// Constructors
diff --git a/src/hotspot/share/code/dependencies.cpp b/src/hotspot/share/code/dependencies.cpp
index 79d272e154e..cf877ee2f71 100644
--- a/src/hotspot/share/code/dependencies.cpp
+++ b/src/hotspot/share/code/dependencies.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,7 @@
#include "oops/objArrayKlass.hpp"
#include "runtime/handles.hpp"
#include "runtime/handles.inline.hpp"
+#include "runtime/jniHandles.inline.hpp"
#include "runtime/thread.inline.hpp"
#include "utilities/copy.hpp"
diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp
index b2429f17703..9c7dfa810ba 100644
--- a/src/hotspot/share/code/nmethod.cpp
+++ b/src/hotspot/share/code/nmethod.cpp
@@ -44,6 +44,7 @@
#include "oops/oop.inline.hpp"
#include "prims/jvmtiImpl.hpp"
#include "runtime/atomic.hpp"
+#include "runtime/jniHandles.inline.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
diff --git a/src/hotspot/share/code/oopRecorder.cpp b/src/hotspot/share/code/oopRecorder.cpp
index 22eeb4b2ac5..aa0a30a8f39 100644
--- a/src/hotspot/share/code/oopRecorder.cpp
+++ b/src/hotspot/share/code/oopRecorder.cpp
@@ -29,6 +29,7 @@
#include "code/oopRecorder.hpp"
#include "memory/allocation.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "runtime/jniHandles.inline.hpp"
#ifdef ASSERT
template int ValueRecorder::_find_index_calls = 0;
diff --git a/src/hotspot/share/code/relocInfo_ext.cpp b/src/hotspot/share/code/relocInfo_ext.cpp
index 7f910100fa4..7b97ccc5de0 100644
--- a/src/hotspot/share/code/relocInfo_ext.cpp
+++ b/src/hotspot/share/code/relocInfo_ext.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
#include "code/codeCache.hpp"
#include "code/relocInfo.hpp"
#include "code/relocInfo_ext.hpp"
+#include "gc/shared/cardTable.hpp"
#include "gc/shared/cardTableModRefBS.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "memory/universe.hpp"
@@ -59,8 +60,9 @@ address symbolic_Relocation::symbolic_value(symbolic_Relocation::symbolic_refere
}
case symbolic_Relocation::card_table_reference: {
BarrierSet* bs = Universe::heap()->barrier_set();
- CardTableModRefBS* ct = (CardTableModRefBS*)bs;
- return (address)ct->byte_map_base;
+ CardTableModRefBS* ctbs = barrier_set_cast(bs);
+ CardTable* ct = ctbs->card_table();
+ return (address)ct->byte_map_base();
}
case symbolic_Relocation::mark_bits_reference: {
return (address)Universe::verify_mark_bits();
diff --git a/src/hotspot/share/compiler/disassembler.cpp b/src/hotspot/share/compiler/disassembler.cpp
index bb36edbc58d..c751ee9f5e8 100644
--- a/src/hotspot/share/compiler/disassembler.cpp
+++ b/src/hotspot/share/compiler/disassembler.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2017, 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
@@ -23,9 +23,11 @@
*/
#include "precompiled.hpp"
+#include "ci/ciUtilities.hpp"
#include "classfile/javaClasses.hpp"
#include "code/codeCache.hpp"
#include "compiler/disassembler.hpp"
+#include "gc/shared/cardTable.hpp"
#include "gc/shared/cardTableModRefBS.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "memory/resourceArea.hpp"
@@ -318,7 +320,7 @@ void decode_env::print_address(address adr) {
BarrierSet* bs = Universe::heap()->barrier_set();
if (bs->is_a(BarrierSet::CardTableModRef) &&
- adr == (address)(barrier_set_cast(bs)->byte_map_base)) {
+ adr == ci_card_table_address_as()) {
st->print("word_map_base");
if (WizardMode) st->print(" " INTPTR_FORMAT, p2i(adr));
return;
diff --git a/src/hotspot/share/gc/cms/cmsCollectorPolicy.cpp b/src/hotspot/share/gc/cms/cmsCollectorPolicy.cpp
index e7160fb622a..f808be676da 100644
--- a/src/hotspot/share/gc/cms/cmsCollectorPolicy.cpp
+++ b/src/hotspot/share/gc/cms/cmsCollectorPolicy.cpp
@@ -51,26 +51,3 @@ void ConcurrentMarkSweepPolicy::initialize_alignments() {
_space_alignment = _gen_alignment = (uintx)Generation::GenGrain;
_heap_alignment = compute_heap_alignment();
}
-
-void ConcurrentMarkSweepPolicy::initialize_generations() {
- _young_gen_spec = new GenerationSpec(Generation::ParNew, _initial_young_size,
- _max_young_size, _gen_alignment);
- _old_gen_spec = new GenerationSpec(Generation::ConcurrentMarkSweep,
- _initial_old_size, _max_old_size, _gen_alignment);
-}
-
-void ConcurrentMarkSweepPolicy::initialize_size_policy(size_t init_eden_size,
- size_t init_promo_size,
- size_t init_survivor_size) {
- double max_gc_pause_sec = ((double) MaxGCPauseMillis)/1000.0;
- _size_policy = new AdaptiveSizePolicy(init_eden_size,
- init_promo_size,
- init_survivor_size,
- max_gc_pause_sec,
- GCTimeRatio);
-}
-
-void ConcurrentMarkSweepPolicy::initialize_gc_policy_counters() {
- // initialize the policy counters - 2 collectors, 2 generations
- _gc_policy_counters = new GCPolicyCounters("ParNew:CMS", 2, 2);
-}
diff --git a/src/hotspot/share/gc/cms/cmsCollectorPolicy.hpp b/src/hotspot/share/gc/cms/cmsCollectorPolicy.hpp
index 30d1fc68884..24211499901 100644
--- a/src/hotspot/share/gc/cms/cmsCollectorPolicy.hpp
+++ b/src/hotspot/share/gc/cms/cmsCollectorPolicy.hpp
@@ -30,18 +30,9 @@
class ConcurrentMarkSweepPolicy : public GenCollectorPolicy {
protected:
void initialize_alignments();
- void initialize_generations();
public:
ConcurrentMarkSweepPolicy() {}
-
- ConcurrentMarkSweepPolicy* as_concurrent_mark_sweep_policy() { return this; }
-
- void initialize_gc_policy_counters();
-
- virtual void initialize_size_policy(size_t init_eden_size,
- size_t init_promo_size,
- size_t init_survivor_size);
};
#endif // SHARE_VM_GC_CMS_CMSCOLLECTORPOLICY_HPP
diff --git a/src/hotspot/share/gc/cms/cmsHeap.cpp b/src/hotspot/share/gc/cms/cmsHeap.cpp
index 8b44d900312..57ab1172b98 100644
--- a/src/hotspot/share/gc/cms/cmsHeap.cpp
+++ b/src/hotspot/share/gc/cms/cmsHeap.cpp
@@ -64,7 +64,13 @@ public:
};
CMSHeap::CMSHeap(GenCollectorPolicy *policy) :
- GenCollectedHeap(policy), _eden_pool(NULL), _survivor_pool(NULL), _old_pool(NULL) {
+ GenCollectedHeap(policy,
+ Generation::ParNew,
+ Generation::ConcurrentMarkSweep,
+ "ParNew::CMS"),
+ _eden_pool(NULL),
+ _survivor_pool(NULL),
+ _old_pool(NULL) {
_workers = new WorkGang("GC Thread", ParallelGCThreads,
/* are_GC_task_threads */true,
/* are_ConcurrentGC_threads */false);
@@ -77,7 +83,6 @@ jint CMSHeap::initialize() {
// If we are running CMS, create the collector responsible
// for collecting the CMS generations.
- assert(collector_policy()->is_concurrent_mark_sweep_policy(), "must be CMS policy");
if (!create_cms_collector()) {
return JNI_ENOMEM;
}
@@ -152,11 +157,10 @@ void CMSHeap::print_on_error(outputStream* st) const {
bool CMSHeap::create_cms_collector() {
assert(old_gen()->kind() == Generation::ConcurrentMarkSweep,
"Unexpected generation kinds");
- assert(gen_policy()->is_concurrent_mark_sweep_policy(), "Unexpected policy type");
CMSCollector* collector =
new CMSCollector((ConcurrentMarkSweepGeneration*) old_gen(),
rem_set(),
- gen_policy()->as_concurrent_mark_sweep_policy());
+ (ConcurrentMarkSweepPolicy*) gen_policy());
if (collector == NULL || !collector->completed_initialization()) {
if (collector) {
diff --git a/src/hotspot/share/gc/cms/compactibleFreeListSpace.cpp b/src/hotspot/share/gc/cms/compactibleFreeListSpace.cpp
index ca5d056c789..51085b81ebc 100644
--- a/src/hotspot/share/gc/cms/compactibleFreeListSpace.cpp
+++ b/src/hotspot/share/gc/cms/compactibleFreeListSpace.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -88,9 +88,9 @@ CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs, M
_parDictionaryAllocLock(Mutex::leaf - 1, // == rank(ExpandHeap_lock) - 1
"CompactibleFreeListSpace._dict_par_lock", true,
Monitor::_safepoint_check_never),
- _rescan_task_size(CardTableModRefBS::card_size_in_words * BitsPerWord *
+ _rescan_task_size(CardTable::card_size_in_words * BitsPerWord *
CMSRescanMultiple),
- _marking_task_size(CardTableModRefBS::card_size_in_words * BitsPerWord *
+ _marking_task_size(CardTable::card_size_in_words * BitsPerWord *
CMSConcMarkMultiple),
_collector(NULL),
_preconsumptionDirtyCardClosure(NULL)
@@ -609,7 +609,7 @@ public:
FreeListSpaceDCTOC(CompactibleFreeListSpace* sp,
CMSCollector* collector,
ExtendedOopClosure* cl,
- CardTableModRefBS::PrecisionStyle precision,
+ CardTable::PrecisionStyle precision,
HeapWord* boundary,
bool parallel) :
FilteringDCTOC(sp, cl, precision, boundary),
@@ -693,7 +693,7 @@ FreeListSpaceDCTOC__walk_mem_region_with_cl_DEFN(FilteringClosure)
DirtyCardToOopClosure*
CompactibleFreeListSpace::new_dcto_cl(ExtendedOopClosure* cl,
- CardTableModRefBS::PrecisionStyle precision,
+ CardTable::PrecisionStyle precision,
HeapWord* boundary,
bool parallel) {
return new FreeListSpaceDCTOC(this, _collector, cl, precision, boundary, parallel);
@@ -2828,7 +2828,7 @@ void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n
}
const size_t CompactibleFreeListSpace::max_flag_size_for_task_size() const {
- const size_t ergo_max = _old_gen->reserved().word_size() / (CardTableModRefBS::card_size_in_words * BitsPerWord);
+ const size_t ergo_max = _old_gen->reserved().word_size() / (CardTable::card_size_in_words * BitsPerWord);
return ergo_max;
}
@@ -2865,15 +2865,15 @@ initialize_sequential_subtasks_for_marking(int n_threads,
// The "size" of each task is fixed according to rescan_task_size.
assert(n_threads > 0, "Unexpected n_threads argument");
const size_t task_size = marking_task_size();
- assert(task_size > CardTableModRefBS::card_size_in_words &&
- (task_size % CardTableModRefBS::card_size_in_words == 0),
+ assert(task_size > CardTable::card_size_in_words &&
+ (task_size % CardTable::card_size_in_words == 0),
"Otherwise arithmetic below would be incorrect");
MemRegion span = _old_gen->reserved();
if (low != NULL) {
if (span.contains(low)) {
// Align low down to a card boundary so that
// we can use block_offset_careful() on span boundaries.
- HeapWord* aligned_low = align_down(low, CardTableModRefBS::card_size);
+ HeapWord* aligned_low = align_down(low, CardTable::card_size);
// Clip span prefix at aligned_low
span = span.intersection(MemRegion(aligned_low, span.end()));
} else if (low > span.end()) {
@@ -2881,7 +2881,7 @@ initialize_sequential_subtasks_for_marking(int n_threads,
} // else use entire span
}
assert(span.is_empty() ||
- ((uintptr_t)span.start() % CardTableModRefBS::card_size == 0),
+ ((uintptr_t)span.start() % CardTable::card_size == 0),
"span should start at a card boundary");
size_t n_tasks = (span.word_size() + task_size - 1)/task_size;
assert((n_tasks == 0) == span.is_empty(), "Inconsistency");
diff --git a/src/hotspot/share/gc/cms/compactibleFreeListSpace.hpp b/src/hotspot/share/gc/cms/compactibleFreeListSpace.hpp
index 15fa9812dc5..c7a3fd8db4a 100644
--- a/src/hotspot/share/gc/cms/compactibleFreeListSpace.hpp
+++ b/src/hotspot/share/gc/cms/compactibleFreeListSpace.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
#include "gc/cms/adaptiveFreeList.hpp"
#include "gc/cms/promotionInfo.hpp"
#include "gc/shared/blockOffsetTable.hpp"
+#include "gc/shared/cardTable.hpp"
#include "gc/shared/space.hpp"
#include "logging/log.hpp"
#include "memory/binaryTreeDictionary.hpp"
@@ -432,7 +433,7 @@ class CompactibleFreeListSpace: public CompactibleSpace {
// Override: provides a DCTO_CL specific to this kind of space.
DirtyCardToOopClosure* new_dcto_cl(ExtendedOopClosure* cl,
- CardTableModRefBS::PrecisionStyle precision,
+ CardTable::PrecisionStyle precision,
HeapWord* boundary,
bool parallel);
diff --git a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp
index 4f8f7836550..528c0554001 100644
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -300,8 +300,7 @@ void CMSCollector::ref_processor_init() {
}
AdaptiveSizePolicy* CMSCollector::size_policy() {
- CMSHeap* heap = CMSHeap::heap();
- return heap->gen_policy()->size_policy();
+ return CMSHeap::heap()->size_policy();
}
void ConcurrentMarkSweepGeneration::initialize_performance_counters() {
@@ -449,7 +448,7 @@ CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen,
_start_sampling(false),
_between_prologue_and_epilogue(false),
_markBitMap(0, Mutex::leaf + 1, "CMS_markBitMap_lock"),
- _modUnionTable((CardTableModRefBS::card_shift - LogHeapWordSize),
+ _modUnionTable((CardTable::card_shift - LogHeapWordSize),
-1 /* lock-free */, "No_lock" /* dummy */),
_modUnionClosurePar(&_modUnionTable),
// Adjust my span to cover old (cms) gen
@@ -901,7 +900,7 @@ void CMSCollector::promoted(bool par, HeapWord* start,
// card size.
MemRegion mr(start,
align_up(start + obj_size,
- CardTableModRefBS::card_size /* bytes */));
+ CardTable::card_size /* bytes */));
if (par) {
_modUnionTable.par_mark_range(mr);
} else {
@@ -1182,8 +1181,6 @@ bool CMSCollector::shouldConcurrentCollect() {
// this is not likely to be productive in practice because it's probably too
// late anyway.
CMSHeap* heap = CMSHeap::heap();
- assert(heap->collector_policy()->is_generation_policy(),
- "You may want to check the correctness of the following");
if (heap->incremental_collection_will_fail(true /* consult_young */)) {
log.print("CMSCollector: collect because incremental collection will fail ");
return true;
@@ -1498,7 +1495,7 @@ void CMSCollector::acquire_control_and_collect(bool full,
max_eden_size,
full,
gc_cause,
- heap->collector_policy());
+ heap->soft_ref_policy());
// Reset the expansion cause, now that we just completed
// a collection cycle.
@@ -1890,7 +1887,7 @@ void CMSCollector::collect_in_background(GCCause::Cause cause) {
}
// Should this be in gc_epilogue?
- collector_policy()->counters()->update_counters();
+ heap->counters()->update_counters();
{
// Clear _foregroundGCShouldWait and, in the event that the
@@ -3226,7 +3223,7 @@ void CMSConcMarkingTask::do_scan_and_mark(int i, CompactibleFreeListSpace* sp) {
if (sp->used_region().contains(_restart_addr)) {
// Align down to a card boundary for the start of 0th task
// for this space.
- aligned_start = align_down(_restart_addr, CardTableModRefBS::card_size);
+ aligned_start = align_down(_restart_addr, CardTable::card_size);
}
size_t chunk_size = sp->marking_task_size();
@@ -4029,17 +4026,16 @@ size_t CMSCollector::preclean_card_table(ConcurrentMarkSweepGeneration* old_gen,
startTimer();
sample_eden();
// Get and clear dirty region from card table
- dirtyRegion = _ct->ct_bs()->dirty_card_range_after_reset(
- MemRegion(nextAddr, endAddr),
- true,
- CardTableModRefBS::precleaned_card_val());
+ dirtyRegion = _ct->dirty_card_range_after_reset(MemRegion(nextAddr, endAddr),
+ true,
+ CardTable::precleaned_card_val());
assert(dirtyRegion.start() >= nextAddr,
"returned region inconsistent?");
}
lastAddr = dirtyRegion.end();
numDirtyCards =
- dirtyRegion.word_size()/CardTableModRefBS::card_size_in_words;
+ dirtyRegion.word_size()/CardTable::card_size_in_words;
if (!dirtyRegion.is_empty()) {
stopTimer();
@@ -4053,7 +4049,7 @@ size_t CMSCollector::preclean_card_table(ConcurrentMarkSweepGeneration* old_gen,
if (stop_point != NULL) {
assert((_collectorState == AbortablePreclean && should_abort_preclean()),
"Should only be AbortablePreclean.");
- _ct->ct_bs()->invalidate(MemRegion(stop_point, dirtyRegion.end()));
+ _ct->invalidate(MemRegion(stop_point, dirtyRegion.end()));
if (should_abort_preclean()) {
break; // out of preclean loop
} else {
@@ -4580,7 +4576,7 @@ CMSParRemarkTask::do_dirty_card_rescan_tasks(
SequentialSubTasksDone* pst = sp->conc_par_seq_tasks();
assert(pst->valid(), "Uninitialized use?");
uint nth_task = 0;
- const int alignment = CardTableModRefBS::card_size * BitsPerWord;
+ const int alignment = CardTable::card_size * BitsPerWord;
MemRegion span = sp->used_region();
HeapWord* start_addr = span.start();
HeapWord* end_addr = align_up(span.end(), alignment);
@@ -4606,7 +4602,7 @@ CMSParRemarkTask::do_dirty_card_rescan_tasks(
// precleaned, and setting the corresponding bits in the mod union
// table. Since we have been careful to partition at Card and MUT-word
// boundaries no synchronization is needed between parallel threads.
- _collector->_ct->ct_bs()->dirty_card_iterate(this_span,
+ _collector->_ct->dirty_card_iterate(this_span,
&modUnionClosure);
// Having transferred these marks into the modUnionTable,
@@ -4917,16 +4913,14 @@ void CMSCollector::do_remark_non_parallel() {
// mod union table.
{
ModUnionClosure modUnionClosure(&_modUnionTable);
- _ct->ct_bs()->dirty_card_iterate(
- _cmsGen->used_region(),
- &modUnionClosure);
+ _ct->dirty_card_iterate(_cmsGen->used_region(),
+ &modUnionClosure);
}
// Having transferred these marks into the modUnionTable, we just need
// to rescan the marked objects on the dirty cards in the modUnionTable.
// The initial marking may have been done during an asynchronous
// collection so there may be dirty bits in the mod-union table.
- const int alignment =
- CardTableModRefBS::card_size * BitsPerWord;
+ const int alignment = CardTable::card_size * BitsPerWord;
{
// ... First handle dirty cards in CMS gen
markFromDirtyCardsClosure.set_space(_cmsGen->cmsSpace());
@@ -5551,7 +5545,7 @@ void CMSCollector::reset_stw() {
// already have the lock
assert(_collectorState == Resetting, "just checking");
assert_lock_strong(bitMapLock());
- GCIdMarkAndRestore gc_id_mark(_cmsThread->gc_id());
+ GCIdMark gc_id_mark(_cmsThread->gc_id());
_markBitMap.clear_all();
_collectorState = Idling;
register_gc_end();
@@ -5636,9 +5630,9 @@ HeapWord* CMSCollector::next_card_start_after_block(HeapWord* addr) const {
}
assert(sz > 0, "size must be nonzero");
HeapWord* next_block = addr + sz;
- HeapWord* next_card = align_up(next_block, CardTableModRefBS::card_size);
- assert(align_down((uintptr_t)addr, CardTableModRefBS::card_size) <
- align_down((uintptr_t)next_card, CardTableModRefBS::card_size),
+ HeapWord* next_card = align_up(next_block, CardTable::card_size);
+ assert(align_down((uintptr_t)addr, CardTable::card_size) <
+ align_down((uintptr_t)next_card, CardTable::card_size),
"must be different cards");
return next_card;
}
@@ -6297,7 +6291,7 @@ void MarkFromRootsClosure::reset(HeapWord* addr) {
assert(_markStack->isEmpty(), "would cause duplicates on stack");
assert(_span.contains(addr), "Out of bounds _finger?");
_finger = addr;
- _threshold = align_up(_finger, CardTableModRefBS::card_size);
+ _threshold = align_up(_finger, CardTable::card_size);
}
// Should revisit to see if this should be restructured for
@@ -6324,7 +6318,7 @@ bool MarkFromRootsClosure::do_bit(size_t offset) {
// during the preclean or remark phase. (CMSCleanOnEnter)
if (CMSCleanOnEnter) {
size_t sz = _collector->block_size_using_printezis_bits(addr);
- HeapWord* end_card_addr = align_up(addr + sz, CardTableModRefBS::card_size);
+ HeapWord* end_card_addr = align_up(addr + sz, CardTable::card_size);
MemRegion redirty_range = MemRegion(addr, end_card_addr);
assert(!redirty_range.is_empty(), "Arithmetical tautology");
// Bump _threshold to end_card_addr; note that
@@ -6411,9 +6405,9 @@ void MarkFromRootsClosure::scanOopsInOop(HeapWord* ptr) {
// _threshold is always kept card-aligned but _finger isn't
// always card-aligned.
HeapWord* old_threshold = _threshold;
- assert(is_aligned(old_threshold, CardTableModRefBS::card_size),
+ assert(is_aligned(old_threshold, CardTable::card_size),
"_threshold should always be card-aligned");
- _threshold = align_up(_finger, CardTableModRefBS::card_size);
+ _threshold = align_up(_finger, CardTable::card_size);
MemRegion mr(old_threshold, _threshold);
assert(!mr.is_empty(), "Control point invariant");
assert(_span.contains(mr), "Should clear within span");
@@ -6523,9 +6517,9 @@ void ParMarkFromRootsClosure::scan_oops_in_oop(HeapWord* ptr) {
// _threshold is always kept card-aligned but _finger isn't
// always card-aligned.
HeapWord* old_threshold = _threshold;
- assert(is_aligned(old_threshold, CardTableModRefBS::card_size),
+ assert(is_aligned(old_threshold, CardTable::card_size),
"_threshold should always be card-aligned");
- _threshold = align_up(_finger, CardTableModRefBS::card_size);
+ _threshold = align_up(_finger, CardTable::card_size);
MemRegion mr(old_threshold, _threshold);
assert(!mr.is_empty(), "Control point invariant");
assert(_span.contains(mr), "Should clear within span"); // _whole_span ??
@@ -6893,7 +6887,7 @@ void PushAndMarkClosure::do_oop(oop obj) {
// are required.
if (obj->is_objArray()) {
size_t sz = obj->size();
- HeapWord* end_card_addr = align_up(addr + sz, CardTableModRefBS::card_size);
+ HeapWord* end_card_addr = align_up(addr + sz, CardTable::card_size);
MemRegion redirty_range = MemRegion(addr, end_card_addr);
assert(!redirty_range.is_empty(), "Arithmetical tautology");
_mod_union_table->mark_range(redirty_range);
@@ -7006,15 +7000,15 @@ bool CMSPrecleanRefsYieldClosure::should_return() {
}
void MarkFromDirtyCardsClosure::do_MemRegion(MemRegion mr) {
- assert(((size_t)mr.start())%CardTableModRefBS::card_size_in_words == 0,
+ assert(((size_t)mr.start())%CardTable::card_size_in_words == 0,
"mr should be aligned to start at a card boundary");
// We'd like to assert:
- // assert(mr.word_size()%CardTableModRefBS::card_size_in_words == 0,
+ // assert(mr.word_size()%CardTable::card_size_in_words == 0,
// "mr should be a range of cards");
// However, that would be too strong in one case -- the last
// partition ends at _unallocated_block which, in general, can be
// an arbitrary boundary, not necessarily card aligned.
- _num_dirty_cards += mr.word_size()/CardTableModRefBS::card_size_in_words;
+ _num_dirty_cards += mr.word_size()/CardTable::card_size_in_words;
_space->object_iterate_mem(mr, &_scan_cl);
}
@@ -7623,7 +7617,7 @@ void CMSKeepAliveClosure::do_oop(oop obj) {
// table.
if (obj->is_objArray()) {
size_t sz = obj->size();
- HeapWord* end_card_addr = align_up(addr + sz, CardTableModRefBS::card_size);
+ HeapWord* end_card_addr = align_up(addr + sz, CardTable::card_size);
MemRegion redirty_range = MemRegion(addr, end_card_addr);
assert(!redirty_range.is_empty(), "Arithmetical tautology");
_collector->_modUnionTable.mark_range(redirty_range);
diff --git a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.hpp b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.hpp
index 70cd9716876..0ce89504491 100644
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.hpp
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.hpp
@@ -77,7 +77,7 @@ class SerialOldTracer;
// methods are used). This is essentially a wrapper around the BitMap class,
// with one bit per (1<<_shifter) HeapWords. (i.e. for the marking bit map,
// we have _shifter == 0. and for the mod union table we have
-// shifter == CardTableModRefBS::card_shift - LogHeapWordSize.)
+// shifter == CardTable::card_shift - LogHeapWordSize.)
// XXX 64-bit issues in BitMap?
class CMSBitMap VALUE_OBJ_CLASS_SPEC {
friend class VMStructs;
diff --git a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.inline.hpp b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.inline.hpp
index ca61c8fd45c..ff04458a439 100644
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.inline.hpp
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.inline.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -448,7 +448,7 @@ inline void ModUnionClosure::do_MemRegion(MemRegion mr) {
// This is superfluous except at the end of the space;
// we should do better than this XXX
MemRegion mr2(mr.start(), align_up(mr.end(),
- CardTableModRefBS::card_size /* bytes */));
+ CardTable::card_size /* bytes */));
_t->mark_range(mr2);
}
@@ -457,7 +457,7 @@ inline void ModUnionClosurePar::do_MemRegion(MemRegion mr) {
// This is superfluous except at the end of the space;
// we should do better than this XXX
MemRegion mr2(mr.start(), align_up(mr.end(),
- CardTableModRefBS::card_size /* bytes */));
+ CardTable::card_size /* bytes */));
_t->par_mark_range(mr2);
}
diff --git a/src/hotspot/share/gc/cms/parCardTableModRefBS.cpp b/src/hotspot/share/gc/cms/parCardTableModRefBS.cpp
index 085b94cb388..540abb33bdc 100644
--- a/src/hotspot/share/gc/cms/parCardTableModRefBS.cpp
+++ b/src/hotspot/share/gc/cms/parCardTableModRefBS.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,7 +36,7 @@
#include "runtime/orderAccess.inline.hpp"
#include "runtime/vmThread.hpp"
-void CardTableModRefBSForCTRS::
+void CardTableRS::
non_clean_card_iterate_parallel_work(Space* sp, MemRegion mr,
OopsInGenClosure* cl,
CardTableRS* ct,
@@ -82,7 +82,7 @@ non_clean_card_iterate_parallel_work(Space* sp, MemRegion mr,
}
void
-CardTableModRefBSForCTRS::
+CardTableRS::
process_stride(Space* sp,
MemRegion used,
jint stride, int n_strides,
@@ -162,7 +162,7 @@ process_stride(Space* sp,
}
void
-CardTableModRefBSForCTRS::
+CardTableRS::
process_chunk_boundaries(Space* sp,
DirtyCardToOopClosure* dcto_cl,
MemRegion chunk_mr,
@@ -371,7 +371,7 @@ process_chunk_boundaries(Space* sp,
}
void
-CardTableModRefBSForCTRS::
+CardTableRS::
get_LNC_array_for_space(Space* sp,
jbyte**& lowest_non_clean,
uintptr_t& lowest_non_clean_base_chunk_index,
diff --git a/src/hotspot/share/gc/cms/parNewGeneration.cpp b/src/hotspot/share/gc/cms/parNewGeneration.cpp
index 74bb6c96e3f..7481435e862 100644
--- a/src/hotspot/share/gc/cms/parNewGeneration.cpp
+++ b/src/hotspot/share/gc/cms/parNewGeneration.cpp
@@ -889,7 +889,7 @@ void ParNewGeneration::collect(bool full,
_gc_timer->register_gc_start();
- AdaptiveSizePolicy* size_policy = gch->gen_policy()->size_policy();
+ AdaptiveSizePolicy* size_policy = gch->size_policy();
WorkGang* workers = gch->workers();
assert(workers != NULL, "Need workgang for parallel work");
uint active_workers =
@@ -1490,4 +1490,3 @@ void ParNewGeneration::restore_preserved_marks() {
SharedRestorePreservedMarksTaskExecutor task_executor(CMSHeap::heap()->workers());
_preserved_marks_set.restore(&task_executor);
}
-
diff --git a/src/hotspot/share/gc/g1/concurrentMarkThread.cpp b/src/hotspot/share/gc/g1/concurrentMarkThread.cpp
index 84e3000520b..c78b7cbcc9e 100644
--- a/src/hotspot/share/gc/g1/concurrentMarkThread.cpp
+++ b/src/hotspot/share/gc/g1/concurrentMarkThread.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -268,8 +268,6 @@ void ConcurrentMarkThread::run_service() {
cm()->concurrent_cycle_start();
- assert(GCId::current() != GCId::undefined(), "GC id should have been set up by the initial mark GC.");
-
GCTraceConcTime(Info, gc) tt("Concurrent Cycle");
{
ResourceMark rm;
diff --git a/src/hotspot/share/gc/g1/g1AllocationContext.hpp b/src/hotspot/share/gc/g1/g1AllocationContext.hpp
index b740b375573..2f3dddd64b8 100644
--- a/src/hotspot/share/gc/g1/g1AllocationContext.hpp
+++ b/src/hotspot/share/gc/g1/g1AllocationContext.hpp
@@ -41,12 +41,4 @@ public:
}
};
-class AllocationContextStats: public StackObj {
-public:
- inline void clear() { }
- inline void update(bool full_gc) { }
- inline void update_after_mark() { }
- inline bool available() { return false; }
-};
-
#endif // SHARE_VM_GC_G1_G1ALLOCATIONCONTEXT_HPP
diff --git a/src/hotspot/share/gc/g1/g1Arguments.cpp b/src/hotspot/share/gc/g1/g1Arguments.cpp
index 57ef5dac158..28221263275 100644
--- a/src/hotspot/share/gc/g1/g1Arguments.cpp
+++ b/src/hotspot/share/gc/g1/g1Arguments.cpp
@@ -40,9 +40,6 @@ size_t G1Arguments::conservative_max_heap_alignment() {
void G1Arguments::initialize_flags() {
GCArguments::initialize_flags();
assert(UseG1GC, "Error");
-#if defined(COMPILER1) || INCLUDE_JVMCI
- FastTLABRefill = false;
-#endif
FLAG_SET_DEFAULT(ParallelGCThreads, Abstract_VM_Version::parallel_worker_threads());
if (ParallelGCThreads == 0) {
assert(!FLAG_IS_DEFAULT(ParallelGCThreads), "The default value for ParallelGCThreads should not be 0.");
diff --git a/src/hotspot/share/gc/g1/g1CardCounts.cpp b/src/hotspot/share/gc/g1/g1CardCounts.cpp
index 4ff32b42eef..b2f48ad14bf 100644
--- a/src/hotspot/share/gc/g1/g1CardCounts.cpp
+++ b/src/hotspot/share/gc/g1/g1CardCounts.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -40,12 +40,12 @@ void G1CardCountsMappingChangedListener::on_commit(uint start_idx, size_t num_re
size_t G1CardCounts::compute_size(size_t mem_region_size_in_words) {
// We keep card counts for every card, so the size of the card counts table must
// be the same as the card table.
- return G1SATBCardTableLoggingModRefBS::compute_size(mem_region_size_in_words);
+ return G1CardTable::compute_size(mem_region_size_in_words);
}
size_t G1CardCounts::heap_map_factor() {
// See G1CardCounts::compute_size() why we reuse the card table value.
- return G1SATBCardTableLoggingModRefBS::heap_map_factor();
+ return G1CardTable::heap_map_factor();
}
void G1CardCounts::clear_range(size_t from_card_num, size_t to_card_num) {
@@ -72,8 +72,8 @@ void G1CardCounts::initialize(G1RegionToSpaceMapper* mapper) {
// threshold limit is no more than this.
guarantee(G1ConcRSHotCardLimit <= max_jubyte, "sanity");
- _ct_bs = _g1h->g1_barrier_set();
- _ct_bot = _ct_bs->byte_for_const(_g1h->reserved_region().start());
+ _ct = _g1h->card_table();
+ _ct_bot = _ct->byte_for_const(_g1h->reserved_region().start());
_card_counts = (jubyte*) mapper->reserved().start();
_reserved_max_card_num = mapper->reserved().byte_size();
@@ -116,17 +116,17 @@ void G1CardCounts::clear_region(HeapRegion* hr) {
void G1CardCounts::clear_range(MemRegion mr) {
if (has_count_table()) {
- const jbyte* from_card_ptr = _ct_bs->byte_for_const(mr.start());
+ const jbyte* from_card_ptr = _ct->byte_for_const(mr.start());
// We use the last address in the range as the range could represent the
// last region in the heap. In which case trying to find the card will be an
// OOB access to the card table.
- const jbyte* last_card_ptr = _ct_bs->byte_for_const(mr.last());
+ const jbyte* last_card_ptr = _ct->byte_for_const(mr.last());
#ifdef ASSERT
- HeapWord* start_addr = _ct_bs->addr_for(from_card_ptr);
+ HeapWord* start_addr = _ct->addr_for(from_card_ptr);
assert(start_addr == mr.start(), "MemRegion start must be aligned to a card.");
- HeapWord* last_addr = _ct_bs->addr_for(last_card_ptr);
- assert((last_addr + CardTableModRefBS::card_size_in_words) == mr.end(), "MemRegion end must be aligned to a card.");
+ HeapWord* last_addr = _ct->addr_for(last_card_ptr);
+ assert((last_addr + G1CardTable::card_size_in_words) == mr.end(), "MemRegion end must be aligned to a card.");
#endif // ASSERT
// Clear the counts for the (exclusive) card range.
diff --git a/src/hotspot/share/gc/g1/g1CardCounts.hpp b/src/hotspot/share/gc/g1/g1CardCounts.hpp
index 60b6f3dd2f5..3d439f16f9e 100644
--- a/src/hotspot/share/gc/g1/g1CardCounts.hpp
+++ b/src/hotspot/share/gc/g1/g1CardCounts.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
#ifndef SHARE_VM_GC_G1_G1CARDCOUNTS_HPP
#define SHARE_VM_GC_G1_G1CARDCOUNTS_HPP
+#include "gc/g1/g1CardTable.hpp"
#include "gc/g1/g1RegionToSpaceMapper.hpp"
#include "memory/allocation.hpp"
#include "memory/virtualspace.hpp"
@@ -56,6 +57,7 @@ class G1CardCounts: public CHeapObj {
G1CardCountsMappingChangedListener _listener;
G1CollectedHeap* _g1h;
+ G1CardTable* _ct;
// The table of counts
jubyte* _card_counts;
@@ -66,9 +68,6 @@ class G1CardCounts: public CHeapObj {
// CardTable bottom.
const jbyte* _ct_bot;
- // Barrier set
- CardTableModRefBS* _ct_bs;
-
// Returns true if the card counts table has been reserved.
bool has_reserved_count_table() { return _card_counts != NULL; }
diff --git a/src/hotspot/share/gc/g1/g1CardLiveData.cpp b/src/hotspot/share/gc/g1/g1CardLiveData.cpp
index 1e071034b59..2a4f8e66802 100644
--- a/src/hotspot/share/gc/g1/g1CardLiveData.cpp
+++ b/src/hotspot/share/gc/g1/g1CardLiveData.cpp
@@ -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
@@ -68,10 +68,10 @@ void G1CardLiveData::initialize(size_t max_capacity, uint num_max_regions) {
assert(max_capacity % num_max_regions == 0,
"Given capacity must be evenly divisible by region size.");
size_t region_size = max_capacity / num_max_regions;
- assert(region_size % (G1SATBCardTableModRefBS::card_size * BitsPerWord) == 0,
+ assert(region_size % (G1CardTable::card_size * BitsPerWord) == 0,
"Region size must be evenly divisible by area covered by a single word.");
_max_capacity = max_capacity;
- _cards_per_region = region_size / G1SATBCardTableModRefBS::card_size;
+ _cards_per_region = region_size / G1CardTable::card_size;
_live_regions_size_in_bits = live_region_bitmap_size_in_bits();
_live_regions = allocate_large_bitmap(_live_regions_size_in_bits);
@@ -85,11 +85,11 @@ void G1CardLiveData::pretouch() {
}
size_t G1CardLiveData::live_region_bitmap_size_in_bits() const {
- return _max_capacity / (_cards_per_region << G1SATBCardTableModRefBS::card_shift);
+ return _max_capacity / (_cards_per_region << G1CardTable::card_shift);
}
size_t G1CardLiveData::live_card_bitmap_size_in_bits() const {
- return _max_capacity >> G1SATBCardTableModRefBS::card_shift;
+ return _max_capacity >> G1CardTable::card_shift;
}
// Helper class that provides functionality to generate the Live Data Count
@@ -132,7 +132,7 @@ private:
void clear_card_bitmap_range(HeapWord* start, HeapWord* end) {
BitMap::idx_t start_idx = card_live_bitmap_index_for(start);
- BitMap::idx_t end_idx = card_live_bitmap_index_for(align_up(end, CardTableModRefBS::card_size));
+ BitMap::idx_t end_idx = card_live_bitmap_index_for(align_up(end, CardTable::card_size));
_card_bm.clear_range(start_idx, end_idx);
}
@@ -140,7 +140,7 @@ private:
// Mark the card liveness bitmap for the object spanning from start to end.
void mark_card_bitmap_range(HeapWord* start, HeapWord* end) {
BitMap::idx_t start_idx = card_live_bitmap_index_for(start);
- BitMap::idx_t end_idx = card_live_bitmap_index_for(align_up(end, CardTableModRefBS::card_size));
+ BitMap::idx_t end_idx = card_live_bitmap_index_for(align_up(end, CardTable::card_size));
assert((end_idx - start_idx) > 0, "Trying to mark zero sized range.");
@@ -168,7 +168,7 @@ public:
// by the card shift -- address 0 corresponds to card number 0. One
// must subtract the card num of the bottom of the heap to obtain a
// card table index.
- BitMap::idx_t card_num = uintptr_t(addr) >> CardTableModRefBS::card_shift;
+ BitMap::idx_t card_num = uintptr_t(addr) >> G1CardTable::card_shift;
return card_num - _heap_card_bias;
}
@@ -262,7 +262,7 @@ public:
// Calculate the card number for the bottom of the heap. Used
// in biasing indexes into the accounting card bitmaps.
_heap_card_bias =
- uintptr_t(base_address) >> CardTableModRefBS::card_shift;
+ uintptr_t(base_address) >> G1CardTable::card_shift;
}
};
diff --git a/src/hotspot/share/gc/g1/g1CardTable.cpp b/src/hotspot/share/gc/g1/g1CardTable.cpp
new file mode 100644
index 00000000000..3a68f4a7c46
--- /dev/null
+++ b/src/hotspot/share/gc/g1/g1CardTable.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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/g1/g1CardTable.hpp"
+#include "gc/g1/g1CollectedHeap.inline.hpp"
+#include "gc/shared/memset_with_concurrent_readers.hpp"
+#include "logging/log.hpp"
+#include "runtime/atomic.hpp"
+#include "runtime/orderAccess.inline.hpp"
+
+bool G1CardTable::mark_card_deferred(size_t card_index) {
+ jbyte val = _byte_map[card_index];
+ // It's already processed
+ if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) {
+ return false;
+ }
+
+ // Cached bit can be installed either on a clean card or on a claimed card.
+ jbyte new_val = val;
+ if (val == clean_card_val()) {
+ new_val = (jbyte)deferred_card_val();
+ } else {
+ if (val & claimed_card_val()) {
+ new_val = val | (jbyte)deferred_card_val();
+ }
+ }
+ if (new_val != val) {
+ Atomic::cmpxchg(new_val, &_byte_map[card_index], val);
+ }
+ return true;
+}
+
+void G1CardTable::g1_mark_as_young(const MemRegion& mr) {
+ jbyte *const first = byte_for(mr.start());
+ jbyte *const last = byte_after(mr.last());
+
+ memset_with_concurrent_readers(first, g1_young_gen, last - first);
+}
+
+#ifndef PRODUCT
+void G1CardTable::verify_g1_young_region(MemRegion mr) {
+ verify_region(mr, g1_young_gen, true);
+}
+#endif
+
+void G1CardTableChangedListener::on_commit(uint start_idx, size_t num_regions, bool zero_filled) {
+ // Default value for a clean card on the card table is -1. So we cannot take advantage of the zero_filled parameter.
+ MemRegion mr(G1CollectedHeap::heap()->bottom_addr_for_region(start_idx), num_regions * HeapRegion::GrainWords);
+ _card_table->clear(mr);
+}
+
+void G1CardTable::initialize(G1RegionToSpaceMapper* mapper) {
+ mapper->set_mapping_changed_listener(&_listener);
+
+ _byte_map_size = mapper->reserved().byte_size();
+
+ _guard_index = cards_required(_whole_heap.word_size()) - 1;
+ _last_valid_index = _guard_index - 1;
+
+ HeapWord* low_bound = _whole_heap.start();
+ HeapWord* high_bound = _whole_heap.end();
+
+ _cur_covered_regions = 1;
+ _covered[0] = _whole_heap;
+
+ _byte_map = (jbyte*) mapper->reserved().start();
+ _byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift);
+ assert(byte_for(low_bound) == &_byte_map[0], "Checking start of map");
+ assert(byte_for(high_bound-1) <= &_byte_map[_last_valid_index], "Checking end of map");
+
+ log_trace(gc, barrier)("G1CardTable::G1CardTable: ");
+ log_trace(gc, barrier)(" &_byte_map[0]: " INTPTR_FORMAT " &_byte_map[_last_valid_index]: " INTPTR_FORMAT,
+ p2i(&_byte_map[0]), p2i(&_byte_map[_last_valid_index]));
+ log_trace(gc, barrier)(" _byte_map_base: " INTPTR_FORMAT, p2i(_byte_map_base));
+}
+
+bool G1CardTable::is_in_young(oop obj) const {
+ volatile jbyte* p = byte_for(obj);
+ return *p == G1CardTable::g1_young_card_val();
+}
diff --git a/src/hotspot/share/gc/g1/g1CardTable.hpp b/src/hotspot/share/gc/g1/g1CardTable.hpp
new file mode 100644
index 00000000000..bd6ac37da0c
--- /dev/null
+++ b/src/hotspot/share/gc/g1/g1CardTable.hpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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_G1_G1CARDTABLE_HPP
+#define SHARE_VM_GC_G1_G1CARDTABLE_HPP
+
+#include "gc/g1/g1RegionToSpaceMapper.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "oops/oopsHierarchy.hpp"
+#include "utilities/macros.hpp"
+
+class G1CardTable;
+class G1RegionToSpaceMapper;
+
+class G1CardTableChangedListener : public G1MappingChangedListener {
+ private:
+ G1CardTable* _card_table;
+ public:
+ G1CardTableChangedListener() : _card_table(NULL) { }
+
+ void set_card_table(G1CardTable* card_table) { _card_table = card_table; }
+
+ virtual void on_commit(uint start_idx, size_t num_regions, bool zero_filled);
+};
+
+class G1CardTable: public CardTable {
+ friend class VMStructs;
+ friend class G1CardTableChangedListener;
+
+ G1CardTableChangedListener _listener;
+
+ enum G1CardValues {
+ g1_young_gen = CT_MR_BS_last_reserved << 1
+ };
+
+public:
+ G1CardTable(MemRegion whole_heap): CardTable(whole_heap, /* scanned concurrently */ true), _listener() {
+ _listener.set_card_table(this);
+ }
+ bool is_card_dirty(size_t card_index) {
+ return _byte_map[card_index] == dirty_card_val();
+ }
+
+ static jbyte g1_young_card_val() { return g1_young_gen; }
+
+/*
+ Claimed and deferred bits are used together in G1 during the evacuation
+ pause. These bits can have the following state transitions:
+ 1. The claimed bit can be put over any other card state. Except that
+ the "dirty -> dirty and claimed" transition is checked for in
+ G1 code and is not used.
+ 2. Deferred bit can be set only if the previous state of the card
+ was either clean or claimed. mark_card_deferred() is wait-free.
+ We do not care if the operation is be successful because if
+ it does not it will only result in duplicate entry in the update
+ buffer because of the "cache-miss". So it's not worth spinning.
+ */
+
+ bool is_card_claimed(size_t card_index) {
+ jbyte val = _byte_map[card_index];
+ return (val & (clean_card_mask_val() | claimed_card_val())) == claimed_card_val();
+ }
+
+ inline void set_card_claimed(size_t card_index);
+
+ void verify_g1_young_region(MemRegion mr) PRODUCT_RETURN;
+ void g1_mark_as_young(const MemRegion& mr);
+
+ bool mark_card_deferred(size_t card_index);
+
+ bool is_card_deferred(size_t card_index) {
+ jbyte val = _byte_map[card_index];
+ return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val();
+ }
+
+ static size_t compute_size(size_t mem_region_size_in_words) {
+ size_t number_of_slots = (mem_region_size_in_words / card_size_in_words);
+ return ReservedSpace::allocation_align_size_up(number_of_slots);
+ }
+
+ // Returns how many bytes of the heap a single byte of the Card Table corresponds to.
+ static size_t heap_map_factor() { return card_size; }
+
+ void initialize() {}
+ void initialize(G1RegionToSpaceMapper* mapper);
+
+ virtual void resize_covered_region(MemRegion new_region) { ShouldNotReachHere(); }
+
+ virtual bool is_in_young(oop obj) const;
+};
+
+#endif // SHARE_VM_GC_G1_G1CARDTABLE_HPP
diff --git a/make/hotspot/src/native/dtrace/generateJvmOffsetsMain.c b/src/hotspot/share/gc/g1/g1CardTable.inline.hpp
similarity index 60%
rename from make/hotspot/src/native/dtrace/generateJvmOffsetsMain.c
rename to src/hotspot/share/gc/g1/g1CardTable.inline.hpp
index 4cd8ebfb49e..5ca09d42835 100644
--- a/make/hotspot/src/native/dtrace/generateJvmOffsetsMain.c
+++ b/src/hotspot/share/gc/g1/g1CardTable.inline.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,32 +22,19 @@
*
*/
+#ifndef SHARE_VM_GC_G1_G1CARDTABLE_INLINE_HPP
+#define SHARE_VM_GC_G1_G1CARDTABLE_INLINE_HPP
-#include "generateJvmOffsets.h"
+#include "gc/g1/g1CardTable.hpp"
-const char *HELP =
- "HELP: generateJvmOffsets {-header | -index | -table} \n";
-
-int main(int argc, const char *argv[]) {
- GEN_variant gen_var;
-
- if (argc != 2) {
- printf("%s", HELP);
- return 1;
- }
-
- if (0 == strcmp(argv[1], "-header")) {
- gen_var = GEN_OFFSET;
- }
- else if (0 == strcmp(argv[1], "-index")) {
- gen_var = GEN_INDEX;
- }
- else if (0 == strcmp(argv[1], "-table")) {
- gen_var = GEN_TABLE;
- }
- else {
- printf("%s", HELP);
- return 1;
- }
- return generateJvmOffsets(gen_var);
+void G1CardTable::set_card_claimed(size_t card_index) {
+ jbyte val = _byte_map[card_index];
+ if (val == clean_card_val()) {
+ val = (jbyte)claimed_card_val();
+ } else {
+ val |= (jbyte)claimed_card_val();
+ }
+ _byte_map[card_index] = val;
}
+
+#endif // SHARE_VM_GC_G1_G1CARDTABLE_INLINE_HPP
diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
index 8cb608a5340..6339cb21a1b 100644
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
@@ -52,6 +52,7 @@
#include "gc/g1/g1RemSet.hpp"
#include "gc/g1/g1RootClosures.hpp"
#include "gc/g1/g1RootProcessor.hpp"
+#include "gc/g1/g1SATBCardTableModRefBS.hpp"
#include "gc/g1/g1StringDedup.hpp"
#include "gc/g1/g1YCTypes.hpp"
#include "gc/g1/g1YoungRemSetSamplingThread.hpp"
@@ -59,6 +60,7 @@
#include "gc/g1/heapRegionRemSet.hpp"
#include "gc/g1/heapRegionSet.inline.hpp"
#include "gc/g1/vm_operations_g1.hpp"
+#include "gc/shared/adaptiveSizePolicy.hpp"
#include "gc/shared/gcHeapSummary.hpp"
#include "gc/shared/gcId.hpp"
#include "gc/shared/gcLocker.inline.hpp"
@@ -102,10 +104,10 @@ class RedirtyLoggedCardTableEntryClosure : public CardTableEntryClosure {
private:
size_t _num_dirtied;
G1CollectedHeap* _g1h;
- G1SATBCardTableLoggingModRefBS* _g1_bs;
+ G1CardTable* _g1_ct;
HeapRegion* region_for_card(jbyte* card_ptr) const {
- return _g1h->heap_region_containing(_g1_bs->addr_for(card_ptr));
+ return _g1h->heap_region_containing(_g1_ct->addr_for(card_ptr));
}
bool will_become_free(HeapRegion* hr) const {
@@ -116,14 +118,14 @@ class RedirtyLoggedCardTableEntryClosure : public CardTableEntryClosure {
public:
RedirtyLoggedCardTableEntryClosure(G1CollectedHeap* g1h) : CardTableEntryClosure(),
- _num_dirtied(0), _g1h(g1h), _g1_bs(g1h->g1_barrier_set()) { }
+ _num_dirtied(0), _g1h(g1h), _g1_ct(g1h->card_table()) { }
bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
HeapRegion* hr = region_for_card(card_ptr);
// Should only dirty cards in regions that won't be freed.
if (!will_become_free(hr)) {
- *card_ptr = CardTableModRefBS::dirty_card_val();
+ *card_ptr = G1CardTable::dirty_card_val();
_num_dirtied++;
}
@@ -1168,7 +1170,7 @@ bool G1CollectedHeap::do_full_collection(bool explicit_gc,
}
const bool do_clear_all_soft_refs = clear_all_soft_refs ||
- collector_policy()->should_clear_all_soft_refs();
+ soft_ref_policy()->should_clear_all_soft_refs();
G1FullCollector collector(this, &_full_gc_memory_manager, explicit_gc, do_clear_all_soft_refs);
GCTraceTime(Info, gc) tm("Pause Full", NULL, gc_cause(), true);
@@ -1343,7 +1345,7 @@ HeapWord* G1CollectedHeap::satisfy_failed_allocation(size_t word_size,
return result;
}
- assert(!collector_policy()->should_clear_all_soft_refs(),
+ assert(!soft_ref_policy()->should_clear_all_soft_refs(),
"Flag should have been handled and cleared prior to this point");
// What else? We might try synchronous finalization later. If the total
@@ -1463,6 +1465,8 @@ G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* collector_policy) :
CollectedHeap(),
_young_gen_sampling_thread(NULL),
_collector_policy(collector_policy),
+ _soft_ref_policy(),
+ _card_table(NULL),
_memory_manager("G1 Young Generation", "end of minor GC"),
_full_gc_memory_manager("G1 Old Generation", "end of major GC"),
_eden_pool(NULL),
@@ -1614,11 +1618,13 @@ jint G1CollectedHeap::initialize() {
initialize_reserved_region((HeapWord*)heap_rs.base(), (HeapWord*)(heap_rs.base() + heap_rs.size()));
// Create the barrier set for the entire reserved region.
- G1SATBCardTableLoggingModRefBS* bs
- = new G1SATBCardTableLoggingModRefBS(reserved_region());
+ G1CardTable* ct = new G1CardTable(reserved_region());
+ ct->initialize();
+ G1SATBCardTableLoggingModRefBS* bs = new G1SATBCardTableLoggingModRefBS(ct);
bs->initialize();
assert(bs->is_a(BarrierSet::G1SATBCTLogging), "sanity");
set_barrier_set(bs);
+ _card_table = ct;
// Create the hot card cache.
_hot_card_cache = new G1HotCardCache(this);
@@ -1649,8 +1655,8 @@ jint G1CollectedHeap::initialize() {
G1RegionToSpaceMapper* cardtable_storage =
create_aux_memory_mapper("Card Table",
- G1SATBCardTableLoggingModRefBS::compute_size(g1_rs.size() / HeapWordSize),
- G1SATBCardTableLoggingModRefBS::heap_map_factor());
+ G1CardTable::compute_size(g1_rs.size() / HeapWordSize),
+ G1CardTable::heap_map_factor());
G1RegionToSpaceMapper* card_counts_storage =
create_aux_memory_mapper("Card Counts Table",
@@ -1664,7 +1670,7 @@ jint G1CollectedHeap::initialize() {
create_aux_memory_mapper("Next Bitmap", bitmap_size, G1CMBitMap::heap_map_factor());
_hrm.initialize(heap_storage, prev_bitmap_storage, next_bitmap_storage, bot_storage, cardtable_storage, card_counts_storage);
- g1_barrier_set()->initialize(cardtable_storage);
+ _card_table->initialize(cardtable_storage);
// Do later initialization work for concurrent refinement.
_hot_card_cache->initialize(card_counts_storage);
@@ -1674,7 +1680,7 @@ jint G1CollectedHeap::initialize() {
guarantee((max_regions() - 1) <= max_region_idx, "too many regions");
// Also create a G1 rem set.
- _g1_rem_set = new G1RemSet(this, g1_barrier_set(), _hot_card_cache);
+ _g1_rem_set = new G1RemSet(this, _card_table, _hot_card_cache);
_g1_rem_set->initialize(max_capacity(), max_regions());
size_t max_cards_per_region = ((size_t)1 << (sizeof(CardIdx_t)*BitsPerByte-1)) - 1;
@@ -1893,6 +1899,10 @@ CollectorPolicy* G1CollectedHeap::collector_policy() const {
return _collector_policy;
}
+SoftRefPolicy* G1CollectedHeap::soft_ref_policy() {
+ return &_soft_ref_policy;
+}
+
size_t G1CollectedHeap::capacity() const {
return _hrm.length() * HeapRegion::GrainBytes;
}
@@ -1989,7 +1999,6 @@ bool G1CollectedHeap::is_user_requested_concurrent_full_gc(GCCause::Cause cause
switch (cause) {
case GCCause::_java_lang_system_gc: return ExplicitGCInvokesConcurrent;
case GCCause::_dcmd_gc_run: return ExplicitGCInvokesConcurrent;
- case GCCause::_update_allocation_context_stats_inc: return true;
case GCCause::_wb_conc_mark: return true;
default : return false;
}
@@ -2542,8 +2551,6 @@ void G1CollectedHeap::gc_epilogue(bool full) {
resize_all_tlabs();
g1_policy()->phase_times()->record_resize_tlab_time_ms((os::elapsedTime() - start) * 1000.0);
- allocation_context_stats().update(full);
-
MemoryService::track_memory_usage();
// We have just completed a GC. Update the soft reference
// policy with the new heap occupancy
@@ -2688,17 +2695,17 @@ class RegisterHumongousWithInCSetFastTestClosure : public HeapRegionClosure {
if (!r->rem_set()->is_empty()) {
guarantee(r->rem_set()->occupancy_less_or_equal_than(G1RSetSparseRegionEntries),
"Found a not-small remembered set here. This is inconsistent with previous assumptions.");
- G1SATBCardTableLoggingModRefBS* bs = g1h->g1_barrier_set();
+ G1CardTable* ct = g1h->card_table();
HeapRegionRemSetIterator hrrs(r->rem_set());
size_t card_index;
while (hrrs.has_next(card_index)) {
- jbyte* card_ptr = (jbyte*)bs->byte_for_index(card_index);
+ jbyte* card_ptr = (jbyte*)ct->byte_for_index(card_index);
// The remembered set might contain references to already freed
// regions. Filter out such entries to avoid failing card table
// verification.
- if (g1h->is_in_closed_subset(bs->addr_for(card_ptr))) {
- if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
- *card_ptr = CardTableModRefBS::dirty_card_val();
+ if (g1h->is_in_closed_subset(ct->addr_for(card_ptr))) {
+ if (*card_ptr != G1CardTable::dirty_card_val()) {
+ *card_ptr = G1CardTable::dirty_card_val();
_dcq.enqueue(card_ptr);
}
}
diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp
index 4eb2eccd565..1052649e8d6 100644
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp
@@ -28,6 +28,7 @@
#include "gc/g1/evacuationInfo.hpp"
#include "gc/g1/g1AllocationContext.hpp"
#include "gc/g1/g1BiasedArray.hpp"
+#include "gc/g1/g1CardTable.hpp"
#include "gc/g1/g1CollectionSet.hpp"
#include "gc/g1/g1CollectorState.hpp"
#include "gc/g1/g1ConcurrentMark.hpp"
@@ -49,6 +50,7 @@
#include "gc/shared/gcHeapSummary.hpp"
#include "gc/shared/plab.hpp"
#include "gc/shared/preservedMarks.hpp"
+#include "gc/shared/softRefPolicy.hpp"
#include "memory/memRegion.hpp"
#include "services/memoryManager.hpp"
#include "utilities/stack.hpp"
@@ -149,6 +151,9 @@ private:
WorkGang* _workers;
G1CollectorPolicy* _collector_policy;
+ G1CardTable* _card_table;
+
+ SoftRefPolicy _soft_ref_policy;
GCMemoryManager _memory_manager;
GCMemoryManager _full_gc_memory_manager;
@@ -222,9 +227,6 @@ private:
// Class that handles archive allocation ranges.
G1ArchiveAllocator* _archive_allocator;
- // Statistics for each allocation context
- AllocationContextStats _allocation_context_stats;
-
// GC allocation statistics policy for survivors.
G1EvacStats _survivor_evac_stats;
@@ -277,8 +279,7 @@ private:
// (b) cause == _g1_humongous_allocation
// (c) cause == _java_lang_system_gc and +ExplicitGCInvokesConcurrent.
// (d) cause == _dcmd_gc_run and +ExplicitGCInvokesConcurrent.
- // (e) cause == _update_allocation_context_stats_inc
- // (f) cause == _wb_conc_mark
+ // (e) cause == _wb_conc_mark
bool should_do_concurrent_full_gc(GCCause::Cause cause);
// indicates whether we are in young or mixed GC mode
@@ -580,8 +581,6 @@ public:
// Determines PLAB size for a given destination.
inline size_t desired_plab_sz(InCSetState dest);
- inline AllocationContextStats& allocation_context_stats();
-
// Do anything common to GC's.
void gc_prologue(bool full);
void gc_epilogue(bool full);
@@ -998,8 +997,7 @@ public:
virtual CollectorPolicy* collector_policy() const;
- // Adaptive size policy. No such thing for g1.
- virtual AdaptiveSizePolicy* size_policy() { return NULL; }
+ virtual SoftRefPolicy* soft_ref_policy();
virtual GrowableArray memory_managers();
virtual GrowableArray memory_pools();
@@ -1130,11 +1128,6 @@ public:
// "CollectedHeap" supports.
virtual void collect(GCCause::Cause cause);
- virtual bool copy_allocation_context_stats(const jint* contexts,
- jlong* totals,
- jbyte* accuracy,
- jint len);
-
// True iff an evacuation has failed in the most-recent collection.
bool evacuation_failed() { return _evacuation_failed; }
@@ -1187,6 +1180,10 @@ public:
G1HotCardCache* g1_hot_card_cache() const { return _hot_card_cache; }
+ G1CardTable* card_table() const {
+ return _card_table;
+ }
+
// Iteration functions.
// Iterate over all objects, calling "cl.do_object" on each.
diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp
index c2cf18698e2..4e579fb1573 100644
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp
@@ -57,10 +57,6 @@ size_t G1CollectedHeap::desired_plab_sz(InCSetState dest) {
// Inline functions for G1CollectedHeap
-inline AllocationContextStats& G1CollectedHeap::allocation_context_stats() {
- return _allocation_context_stats;
-}
-
// Return the region with the given index. It assumes the index is valid.
inline HeapRegion* G1CollectedHeap::region_at(uint index) const { return _hrm.at(index); }
@@ -127,7 +123,7 @@ G1CollectedHeap::dirty_young_block(HeapWord* start, size_t word_size) {
assert(containing_hr->is_in(end - 1), "it should also contain end - 1");
MemRegion mr(start, end);
- g1_barrier_set()->g1_mark_as_young(mr);
+ card_table()->g1_mark_as_young(mr);
}
inline RefToScanQueue* G1CollectedHeap::task_queue(uint i) const {
diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap_ext.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap_ext.cpp
index a30cf4b4484..b13c966497a 100644
--- a/src/hotspot/share/gc/g1/g1CollectedHeap_ext.cpp
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap_ext.cpp
@@ -30,13 +30,6 @@
class STWGCTimer;
-bool G1CollectedHeap::copy_allocation_context_stats(const jint* contexts,
- jlong* totals,
- jbyte* accuracy,
- jint len) {
- return false;
-}
-
G1Policy* G1CollectedHeap::create_g1_policy(STWGCTimer* gc_timer) {
return new G1DefaultPolicy(gc_timer);
}
diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp
index 410ad0b8c58..5d81f361e88 100644
--- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp
@@ -38,6 +38,7 @@
#include "gc/g1/heapRegion.inline.hpp"
#include "gc/g1/heapRegionRemSet.hpp"
#include "gc/g1/heapRegionSet.inline.hpp"
+#include "gc/shared/adaptiveSizePolicy.hpp"
#include "gc/shared/gcId.hpp"
#include "gc/shared/gcTimer.hpp"
#include "gc/shared/gcTrace.hpp"
@@ -1275,7 +1276,6 @@ void G1ConcurrentMark::cleanup() {
// We reclaimed old regions so we should calculate the sizes to make
// sure we update the old gen/space data.
g1h->g1mm()->update_sizes();
- g1h->allocation_context_stats().update_after_mark();
}
void G1ConcurrentMark::complete_cleanup() {
diff --git a/src/hotspot/share/gc/g1/g1EvacFailure.cpp b/src/hotspot/share/gc/g1/g1EvacFailure.cpp
index 23f95154bc3..8b34cebab39 100644
--- a/src/hotspot/share/gc/g1/g1EvacFailure.cpp
+++ b/src/hotspot/share/gc/g1/g1EvacFailure.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2016, 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
@@ -38,12 +38,12 @@
class UpdateRSetDeferred : public ExtendedOopClosure {
private:
G1CollectedHeap* _g1;
- DirtyCardQueue *_dcq;
- G1SATBCardTableModRefBS* _ct_bs;
+ DirtyCardQueue* _dcq;
+ G1CardTable* _ct;
public:
UpdateRSetDeferred(DirtyCardQueue* dcq) :
- _g1(G1CollectedHeap::heap()), _ct_bs(_g1->g1_barrier_set()), _dcq(dcq) {}
+ _g1(G1CollectedHeap::heap()), _ct(_g1->card_table()), _dcq(dcq) {}
virtual void do_oop(narrowOop* p) { do_oop_work(p); }
virtual void do_oop( oop* p) { do_oop_work(p); }
@@ -59,9 +59,9 @@ public:
if (HeapRegion::is_in_same_region(p, oopDesc::decode_heap_oop(o))) {
return;
}
- size_t card_index = _ct_bs->index_for(p);
- if (_ct_bs->mark_card_deferred(card_index)) {
- _dcq->enqueue((jbyte*)_ct_bs->byte_for_index(card_index));
+ size_t card_index = _ct->index_for(p);
+ if (_ct->mark_card_deferred(card_index)) {
+ _dcq->enqueue((jbyte*)_ct->byte_for_index(card_index));
}
}
};
diff --git a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp
index 8dc75250c6f..f769ddd3c2c 100644
--- a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp
+++ b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -112,7 +112,7 @@ void G1FullGCPrepareTask::G1CalculatePointersClosure::reset_region_metadata(Heap
hr->reset_gc_time_stamp();
hr->rem_set()->clear();
- _g1h->g1_barrier_set()->clear(MemRegion(hr->bottom(), hr->end()));
+ _g1h->card_table()->clear(MemRegion(hr->bottom(), hr->end()));
if (_g1h->g1_hot_card_cache()->use_cache()) {
_g1h->g1_hot_card_cache()->reset_card_counts(hr);
diff --git a/src/hotspot/share/gc/g1/g1FullGCScope.cpp b/src/hotspot/share/gc/g1/g1FullGCScope.cpp
index 2430451df1c..ce421041b19 100644
--- a/src/hotspot/share/gc/g1/g1FullGCScope.cpp
+++ b/src/hotspot/share/gc/g1/g1FullGCScope.cpp
@@ -35,7 +35,7 @@ G1FullGCScope::G1FullGCScope(GCMemoryManager* memory_manager, bool explicit_gc,
_tracer(),
_active(),
_cpu_time(),
- _soft_refs(clear_soft, _g1h->collector_policy()),
+ _soft_refs(clear_soft, _g1h->soft_ref_policy()),
_memory_stats(memory_manager, _g1h->gc_cause()),
_collector_stats(_g1h->g1mm()->full_collection_counters()),
_heap_transition(_g1h) {
diff --git a/src/hotspot/share/gc/g1/g1HeapVerifier.cpp b/src/hotspot/share/gc/g1/g1HeapVerifier.cpp
index 4427933e0a3..ce6d0a839dd 100644
--- a/src/hotspot/share/gc/g1/g1HeapVerifier.cpp
+++ b/src/hotspot/share/gc/g1/g1HeapVerifier.cpp
@@ -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
@@ -604,10 +604,9 @@ void G1HeapVerifier::verify_after_gc(G1VerifyType type) {
#ifndef PRODUCT
class G1VerifyCardTableCleanup: public HeapRegionClosure {
G1HeapVerifier* _verifier;
- G1SATBCardTableModRefBS* _ct_bs;
public:
- G1VerifyCardTableCleanup(G1HeapVerifier* verifier, G1SATBCardTableModRefBS* ct_bs)
- : _verifier(verifier), _ct_bs(ct_bs) { }
+ G1VerifyCardTableCleanup(G1HeapVerifier* verifier)
+ : _verifier(verifier) { }
virtual bool do_heap_region(HeapRegion* r) {
if (r->is_survivor()) {
_verifier->verify_dirty_region(r);
@@ -620,16 +619,16 @@ public:
void G1HeapVerifier::verify_card_table_cleanup() {
if (G1VerifyCTCleanup || VerifyAfterGC) {
- G1VerifyCardTableCleanup cleanup_verifier(this, _g1h->g1_barrier_set());
+ G1VerifyCardTableCleanup cleanup_verifier(this);
_g1h->heap_region_iterate(&cleanup_verifier);
}
}
void G1HeapVerifier::verify_not_dirty_region(HeapRegion* hr) {
// All of the region should be clean.
- G1SATBCardTableModRefBS* ct_bs = _g1h->g1_barrier_set();
+ G1CardTable* ct = _g1h->card_table();
MemRegion mr(hr->bottom(), hr->end());
- ct_bs->verify_not_dirty_region(mr);
+ ct->verify_not_dirty_region(mr);
}
void G1HeapVerifier::verify_dirty_region(HeapRegion* hr) {
@@ -640,12 +639,12 @@ void G1HeapVerifier::verify_dirty_region(HeapRegion* hr) {
// not dirty that area (one less thing to have to do while holding
// a lock). So we can only verify that [bottom(),pre_dummy_top()]
// is dirty.
- G1SATBCardTableModRefBS* ct_bs = _g1h->g1_barrier_set();
+ G1CardTable* ct = _g1h->card_table();
MemRegion mr(hr->bottom(), hr->pre_dummy_top());
if (hr->is_young()) {
- ct_bs->verify_g1_young_region(mr);
+ ct->verify_g1_young_region(mr);
} else {
- ct_bs->verify_dirty_region(mr);
+ ct->verify_dirty_region(mr);
}
}
diff --git a/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp b/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp
index bdf01d36940..10818065491 100644
--- a/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp
+++ b/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -235,13 +235,7 @@ private:
size_t const _page_size;
public:
G1PretouchTask(char* start_address, char* end_address, size_t page_size) :
- AbstractGangTask("G1 PreTouch",
- Universe::is_fully_initialized() &&
- Thread::current()->is_Named_thread() ? GCId::current_raw() :
- // During VM initialization there is
- // no GC cycle that this task can be
- // associated with.
- GCId::undefined()),
+ AbstractGangTask("G1 PreTouch"),
_cur_addr(start_address),
_start_addr(start_address),
_end_addr(end_address),
diff --git a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp
index dfdb980658b..69619e42591 100644
--- a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp
+++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp
@@ -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
@@ -40,7 +40,7 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint worker_id,
: _g1h(g1h),
_refs(g1h->task_queue(worker_id)),
_dcq(&g1h->dirty_card_queue_set()),
- _ct_bs(g1h->g1_barrier_set()),
+ _ct(g1h->card_table()),
_closures(NULL),
_hash_seed(17),
_worker_id(worker_id),
@@ -390,7 +390,6 @@ oop G1ParScanThreadState::handle_evacuation_failure_par(oop old, markOop m) {
return forward_ptr;
}
}
-
G1ParScanThreadStateSet::G1ParScanThreadStateSet(G1CollectedHeap* g1h, uint n_workers, size_t young_cset_length) :
_g1h(g1h),
_states(NEW_C_HEAP_ARRAY(G1ParScanThreadState*, n_workers, mtGC)),
diff --git a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp
index 310b4270b02..ee93afa26e1 100644
--- a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp
+++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp
@@ -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
@@ -45,7 +45,7 @@ class G1ParScanThreadState : public CHeapObj {
G1CollectedHeap* _g1h;
RefToScanQueue* _refs;
DirtyCardQueue _dcq;
- G1SATBCardTableModRefBS* _ct_bs;
+ G1CardTable* _ct;
G1EvacuationRootClosures* _closures;
G1PLABAllocator* _plab_allocator;
@@ -72,7 +72,7 @@ class G1ParScanThreadState : public CHeapObj {
#define PADDING_ELEM_NUM (DEFAULT_CACHE_LINE_SIZE / sizeof(size_t))
DirtyCardQueue& dirty_card_queue() { return _dcq; }
- G1SATBCardTableModRefBS* ctbs() { return _ct_bs; }
+ G1CardTable* ct() { return _ct; }
InCSetState dest(InCSetState original) const {
assert(original.is_valid(),
@@ -104,10 +104,10 @@ class G1ParScanThreadState : public CHeapObj {
// If the field originates from the to-space, we don't need to include it
// in the remembered set updates.
if (!from->is_young()) {
- size_t card_index = ctbs()->index_for(p);
+ size_t card_index = ct()->index_for(p);
// If the card hasn't been added to the buffer, do it.
- if (ctbs()->mark_card_deferred(card_index)) {
- dirty_card_queue().enqueue((jbyte*)ctbs()->byte_for_index(card_index));
+ if (ct()->mark_card_deferred(card_index)) {
+ dirty_card_queue().enqueue((jbyte*)ct()->byte_for_index(card_index));
}
}
}
diff --git a/src/hotspot/share/gc/g1/g1RemSet.cpp b/src/hotspot/share/gc/g1/g1RemSet.cpp
index 21562078d41..e752ca26a8c 100644
--- a/src/hotspot/share/gc/g1/g1RemSet.cpp
+++ b/src/hotspot/share/gc/g1/g1RemSet.cpp
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "gc/g1/dirtyCardQueue.hpp"
#include "gc/g1/g1BlockOffsetTable.inline.hpp"
+#include "gc/g1/g1CardTable.inline.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1ConcurrentRefine.hpp"
#include "gc/g1/g1FromCardCache.hpp"
@@ -74,7 +75,7 @@ private:
static size_t chunk_size() { return M; }
void work(uint worker_id) {
- G1SATBCardTableModRefBS* ct_bs = _g1h->g1_barrier_set();
+ G1CardTable* ct = _g1h->card_table();
while (_cur_dirty_regions < _num_dirty_regions) {
size_t next = Atomic::add(_chunk_length, &_cur_dirty_regions) - _chunk_length;
@@ -83,7 +84,7 @@ private:
for (size_t i = next; i < max; i++) {
HeapRegion* r = _g1h->region_at(_dirty_region_list[i]);
if (!r->is_survivor()) {
- ct_bs->clear(MemRegion(r->bottom(), r->end()));
+ ct->clear(MemRegion(r->bottom(), r->end()));
}
}
}
@@ -280,12 +281,12 @@ public:
};
G1RemSet::G1RemSet(G1CollectedHeap* g1,
- CardTableModRefBS* ct_bs,
+ G1CardTable* ct,
G1HotCardCache* hot_card_cache) :
_g1(g1),
_scan_state(new G1RemSetScanState()),
_num_conc_refined_cards(0),
- _ct_bs(ct_bs),
+ _ct(ct),
_g1p(_g1->g1_policy()),
_hot_card_cache(hot_card_cache),
_prev_period_summary() {
@@ -328,7 +329,7 @@ G1ScanRSForRegionClosure::G1ScanRSForRegionClosure(G1RemSetScanState* scan_state
_worker_i(worker_i) {
_g1h = G1CollectedHeap::heap();
_bot = _g1h->bot();
- _ct_bs = _g1h->g1_barrier_set();
+ _ct = _g1h->card_table();
}
void G1ScanRSForRegionClosure::scan_card(MemRegion mr, uint region_idx_for_card) {
@@ -345,7 +346,7 @@ void G1ScanRSForRegionClosure::scan_strong_code_roots(HeapRegion* r) {
}
void G1ScanRSForRegionClosure::claim_card(size_t card_index, const uint region_idx_for_card){
- _ct_bs->set_card_claimed(card_index);
+ _ct->set_card_claimed(card_index);
_scan_state->add_dirty_region(region_idx_for_card);
}
@@ -381,7 +382,7 @@ bool G1ScanRSForRegionClosure::do_heap_region(HeapRegion* r) {
_cards_claimed++;
// If the card is dirty, then G1 will scan it during Update RS.
- if (_ct_bs->is_card_claimed(card_index) || _ct_bs->is_card_dirty(card_index)) {
+ if (_ct->is_card_claimed(card_index) || _ct->is_card_dirty(card_index)) {
continue;
}
@@ -535,15 +536,15 @@ void G1RemSet::scrub(uint worker_num, HeapRegionClaimer *hrclaimer) {
_g1->heap_region_par_iterate_from_worker_offset(&scrub_cl, hrclaimer, worker_num);
}
-inline void check_card_ptr(jbyte* card_ptr, CardTableModRefBS* ct_bs) {
+inline void check_card_ptr(jbyte* card_ptr, G1CardTable* ct) {
#ifdef ASSERT
G1CollectedHeap* g1 = G1CollectedHeap::heap();
- assert(g1->is_in_exact(ct_bs->addr_for(card_ptr)),
+ assert(g1->is_in_exact(ct->addr_for(card_ptr)),
"Card at " PTR_FORMAT " index " SIZE_FORMAT " representing heap at " PTR_FORMAT " (%u) must be in committed heap",
p2i(card_ptr),
- ct_bs->index_for(ct_bs->addr_for(card_ptr)),
- p2i(ct_bs->addr_for(card_ptr)),
- g1->addr_to_region(ct_bs->addr_for(card_ptr)));
+ ct->index_for(ct->addr_for(card_ptr)),
+ p2i(ct->addr_for(card_ptr)),
+ g1->addr_to_region(ct->addr_for(card_ptr)));
#endif
}
@@ -551,15 +552,15 @@ void G1RemSet::refine_card_concurrently(jbyte* card_ptr,
uint worker_i) {
assert(!_g1->is_gc_active(), "Only call concurrently");
- check_card_ptr(card_ptr, _ct_bs);
+ check_card_ptr(card_ptr, _ct);
// If the card is no longer dirty, nothing to do.
- if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
+ if (*card_ptr != G1CardTable::dirty_card_val()) {
return;
}
// Construct the region representing the card.
- HeapWord* start = _ct_bs->addr_for(card_ptr);
+ HeapWord* start = _ct->addr_for(card_ptr);
// And find the region containing it.
HeapRegion* r = _g1->heap_region_containing(start);
@@ -586,6 +587,20 @@ void G1RemSet::refine_card_concurrently(jbyte* card_ptr,
return;
}
+ // While we are processing RSet buffers during the collection, we
+ // actually don't want to scan any cards on the collection set,
+ // since we don't want to update remembered sets with entries that
+ // point into the collection set, given that live objects from the
+ // collection set are about to move and such entries will be stale
+ // very soon. This change also deals with a reliability issue which
+ // involves scanning a card in the collection set and coming across
+ // an array that was being chunked and looking malformed. Note,
+ // however, that if evacuation fails, we have to scan any objects
+ // that were not moved and create any missing entries.
+ if (r->in_collection_set()) {
+ return;
+ }
+
// The result from the hot card cache insert call is either:
// * pointer to the current card
// (implying that the current card is not 'hot'),
@@ -605,12 +620,13 @@ void G1RemSet::refine_card_concurrently(jbyte* card_ptr,
return;
} else if (card_ptr != orig_card_ptr) {
// Original card was inserted and an old card was evicted.
- start = _ct_bs->addr_for(card_ptr);
+ start = _ct->addr_for(card_ptr);
r = _g1->heap_region_containing(start);
// Check whether the region formerly in the cache should be
// ignored, as discussed earlier for the original card. The
- // region could have been freed while in the cache.
+ // region could have been freed while in the cache. The cset is
+ // not relevant here, since we're in concurrent phase.
if (!r->is_old_or_humongous()) {
return;
}
@@ -639,7 +655,7 @@ void G1RemSet::refine_card_concurrently(jbyte* card_ptr,
// Okay to clean and process the card now. There are still some
// stale card cases that may be detected by iteration and dealt with
// as iteration failure.
- *const_cast(card_ptr) = CardTableModRefBS::clean_card_val();
+ *const_cast(card_ptr) = G1CardTable::clean_card_val();
// This fence serves two purposes. First, the card must be cleaned
// before processing the contents. Second, we can't proceed with
@@ -651,7 +667,7 @@ void G1RemSet::refine_card_concurrently(jbyte* card_ptr,
// Don't use addr_for(card_ptr + 1) which can ask for
// a card beyond the heap.
- HeapWord* end = start + CardTableModRefBS::card_size_in_words;
+ HeapWord* end = start + G1CardTable::card_size_in_words;
MemRegion dirty_region(start, MIN2(scan_limit, end));
assert(!dirty_region.is_empty(), "sanity");
@@ -668,8 +684,8 @@ void G1RemSet::refine_card_concurrently(jbyte* card_ptr,
if (!card_processed) {
// The card might have gotten re-dirtied and re-enqueued while we
// worked. (In fact, it's pretty likely.)
- if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
- *card_ptr = CardTableModRefBS::dirty_card_val();
+ if (*card_ptr != G1CardTable::dirty_card_val()) {
+ *card_ptr = G1CardTable::dirty_card_val();
MutexLockerEx x(Shared_DirtyCardQ_lock,
Mutex::_no_safepoint_check_flag);
DirtyCardQueue* sdcq =
@@ -685,20 +701,20 @@ bool G1RemSet::refine_card_during_gc(jbyte* card_ptr,
G1ScanObjsDuringUpdateRSClosure* update_rs_cl) {
assert(_g1->is_gc_active(), "Only call during GC");
- check_card_ptr(card_ptr, _ct_bs);
+ check_card_ptr(card_ptr, _ct);
// If the card is no longer dirty, nothing to do. This covers cards that were already
// scanned as parts of the remembered sets.
- if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
+ if (*card_ptr != G1CardTable::dirty_card_val()) {
return false;
}
// We claim lazily (so races are possible but they're benign), which reduces the
// number of potential duplicate scans (multiple threads may enqueue the same card twice).
- *card_ptr = CardTableModRefBS::clean_card_val() | CardTableModRefBS::claimed_card_val();
+ *card_ptr = G1CardTable::clean_card_val() | G1CardTable::claimed_card_val();
// Construct the region representing the card.
- HeapWord* card_start = _ct_bs->addr_for(card_ptr);
+ HeapWord* card_start = _ct->addr_for(card_ptr);
// And find the region containing it.
uint const card_region_idx = _g1->addr_to_region(card_start);
@@ -711,7 +727,7 @@ bool G1RemSet::refine_card_during_gc(jbyte* card_ptr,
// Don't use addr_for(card_ptr + 1) which can ask for
// a card beyond the heap.
- HeapWord* card_end = card_start + CardTableModRefBS::card_size_in_words;
+ HeapWord* card_end = card_start + G1CardTable::card_size_in_words;
MemRegion dirty_region(card_start, MIN2(scan_limit, card_end));
assert(!dirty_region.is_empty(), "sanity");
diff --git a/src/hotspot/share/gc/g1/g1RemSet.hpp b/src/hotspot/share/gc/g1/g1RemSet.hpp
index 8a6f6f48d42..28fd71bb6c4 100644
--- a/src/hotspot/share/gc/g1/g1RemSet.hpp
+++ b/src/hotspot/share/gc/g1/g1RemSet.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
#include "gc/g1/dirtyCardQueue.hpp"
#include "gc/g1/g1CardLiveData.hpp"
+#include "gc/g1/g1CardTable.hpp"
#include "gc/g1/g1RemSetSummary.hpp"
#include "gc/g1/heapRegion.hpp"
#include "memory/allocation.hpp"
@@ -72,7 +73,7 @@ private:
G1CollectedHeap* _g1;
size_t _num_conc_refined_cards; // Number of cards refined concurrently to the mutator.
- CardTableModRefBS* _ct_bs;
+ G1CardTable* _ct;
G1Policy* _g1p;
G1HotCardCache* _hot_card_cache;
@@ -93,7 +94,7 @@ public:
void cleanupHRRS();
G1RemSet(G1CollectedHeap* g1,
- CardTableModRefBS* ct_bs,
+ G1CardTable* ct,
G1HotCardCache* hot_card_cache);
~G1RemSet();
@@ -162,7 +163,7 @@ class G1ScanRSForRegionClosure : public HeapRegionClosure {
CodeBlobClosure* _code_root_cl;
G1BlockOffsetTable* _bot;
- G1SATBCardTableModRefBS *_ct_bs;
+ G1CardTable *_ct;
double _strong_code_root_scan_time_sec;
uint _worker_i;
diff --git a/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.cpp b/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.cpp
index a416e516bb7..6d1b5f75ea3 100644
--- a/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.cpp
+++ b/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.cpp
@@ -23,22 +23,20 @@
*/
#include "precompiled.hpp"
+#include "gc/g1/g1CardTable.inline.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1SATBCardTableModRefBS.inline.hpp"
#include "gc/g1/heapRegion.hpp"
#include "gc/g1/satbMarkQueue.hpp"
-#include "gc/shared/memset_with_concurrent_readers.hpp"
#include "logging/log.hpp"
#include "oops/oop.inline.hpp"
-#include "runtime/atomic.hpp"
#include "runtime/mutexLocker.hpp"
-#include "runtime/orderAccess.inline.hpp"
#include "runtime/thread.inline.hpp"
G1SATBCardTableModRefBS::G1SATBCardTableModRefBS(
- MemRegion whole_heap,
+ G1CardTable* card_table,
const BarrierSet::FakeRtti& fake_rtti) :
- CardTableModRefBS(whole_heap, fake_rtti.add_tag(BarrierSet::G1SATBCT))
+ CardTableModRefBS(card_table, fake_rtti.add_tag(BarrierSet::G1SATBCT))
{ }
void G1SATBCardTableModRefBS::enqueue(oop pre_val) {
@@ -80,88 +78,17 @@ void G1SATBCardTableModRefBS::write_ref_array_pre(narrowOop* dst, int count, boo
}
}
-bool G1SATBCardTableModRefBS::mark_card_deferred(size_t card_index) {
- jbyte val = _byte_map[card_index];
- // It's already processed
- if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) {
- return false;
- }
-
- // Cached bit can be installed either on a clean card or on a claimed card.
- jbyte new_val = val;
- if (val == clean_card_val()) {
- new_val = (jbyte)deferred_card_val();
- } else {
- if (val & claimed_card_val()) {
- new_val = val | (jbyte)deferred_card_val();
- }
- }
- if (new_val != val) {
- Atomic::cmpxchg(new_val, &_byte_map[card_index], val);
- }
- return true;
-}
-
-void G1SATBCardTableModRefBS::g1_mark_as_young(const MemRegion& mr) {
- jbyte *const first = byte_for(mr.start());
- jbyte *const last = byte_after(mr.last());
-
- memset_with_concurrent_readers(first, g1_young_gen, last - first);
-}
-
-#ifndef PRODUCT
-void G1SATBCardTableModRefBS::verify_g1_young_region(MemRegion mr) {
- verify_region(mr, g1_young_gen, true);
-}
-#endif
-
-void G1SATBCardTableLoggingModRefBSChangedListener::on_commit(uint start_idx, size_t num_regions, bool zero_filled) {
- // Default value for a clean card on the card table is -1. So we cannot take advantage of the zero_filled parameter.
- MemRegion mr(G1CollectedHeap::heap()->bottom_addr_for_region(start_idx), num_regions * HeapRegion::GrainWords);
- _card_table->clear(mr);
-}
-
G1SATBCardTableLoggingModRefBS::
-G1SATBCardTableLoggingModRefBS(MemRegion whole_heap) :
- G1SATBCardTableModRefBS(whole_heap, BarrierSet::FakeRtti(G1SATBCTLogging)),
- _dcqs(JavaThread::dirty_card_queue_set()),
- _listener()
-{
- _listener.set_card_table(this);
-}
-
-void G1SATBCardTableLoggingModRefBS::initialize(G1RegionToSpaceMapper* mapper) {
- initialize_deferred_card_mark_barriers();
- mapper->set_mapping_changed_listener(&_listener);
-
- _byte_map_size = mapper->reserved().byte_size();
-
- _guard_index = cards_required(_whole_heap.word_size()) - 1;
- _last_valid_index = _guard_index - 1;
-
- HeapWord* low_bound = _whole_heap.start();
- HeapWord* high_bound = _whole_heap.end();
-
- _cur_covered_regions = 1;
- _covered[0] = _whole_heap;
-
- _byte_map = (jbyte*) mapper->reserved().start();
- byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift);
- assert(byte_for(low_bound) == &_byte_map[0], "Checking start of map");
- assert(byte_for(high_bound-1) <= &_byte_map[_last_valid_index], "Checking end of map");
-
- log_trace(gc, barrier)("G1SATBCardTableModRefBS::G1SATBCardTableModRefBS: ");
- log_trace(gc, barrier)(" &_byte_map[0]: " INTPTR_FORMAT " &_byte_map[_last_valid_index]: " INTPTR_FORMAT,
- p2i(&_byte_map[0]), p2i(&_byte_map[_last_valid_index]));
- log_trace(gc, barrier)(" byte_map_base: " INTPTR_FORMAT, p2i(byte_map_base));
-}
+G1SATBCardTableLoggingModRefBS(G1CardTable* card_table) :
+ G1SATBCardTableModRefBS(card_table, BarrierSet::FakeRtti(G1SATBCTLogging)),
+ _dcqs(JavaThread::dirty_card_queue_set()) {}
void G1SATBCardTableLoggingModRefBS::write_ref_field_post_slow(volatile jbyte* byte) {
// In the slow path, we know a card is not young
- assert(*byte != g1_young_gen, "slow path invoked without filtering");
+ assert(*byte != G1CardTable::g1_young_card_val(), "slow path invoked without filtering");
OrderAccess::storeload();
- if (*byte != dirty_card) {
- *byte = dirty_card;
+ if (*byte != G1CardTable::dirty_card_val()) {
+ *byte = G1CardTable::dirty_card_val();
Thread* thr = Thread::current();
if (thr->is_Java_thread()) {
JavaThread* jt = (JavaThread*)thr;
@@ -174,16 +101,15 @@ void G1SATBCardTableLoggingModRefBS::write_ref_field_post_slow(volatile jbyte* b
}
}
-void
-G1SATBCardTableLoggingModRefBS::invalidate(MemRegion mr) {
+void G1SATBCardTableLoggingModRefBS::invalidate(MemRegion mr) {
if (mr.is_empty()) {
return;
}
- volatile jbyte* byte = byte_for(mr.start());
- jbyte* last_byte = byte_for(mr.last());
+ volatile jbyte* byte = _card_table->byte_for(mr.start());
+ jbyte* last_byte = _card_table->byte_for(mr.last());
Thread* thr = Thread::current();
// skip all consecutive young cards
- for (; byte <= last_byte && *byte == g1_young_gen; byte++);
+ for (; byte <= last_byte && *byte == G1CardTable::g1_young_card_val(); byte++);
if (byte <= last_byte) {
OrderAccess::storeload();
@@ -191,11 +117,11 @@ G1SATBCardTableLoggingModRefBS::invalidate(MemRegion mr) {
if (thr->is_Java_thread()) {
JavaThread* jt = (JavaThread*)thr;
for (; byte <= last_byte; byte++) {
- if (*byte == g1_young_gen) {
+ if (*byte == G1CardTable::g1_young_card_val()) {
continue;
}
- if (*byte != dirty_card) {
- *byte = dirty_card;
+ if (*byte != G1CardTable::dirty_card_val()) {
+ *byte = G1CardTable::dirty_card_val();
jt->dirty_card_queue().enqueue(byte);
}
}
@@ -203,11 +129,11 @@ G1SATBCardTableLoggingModRefBS::invalidate(MemRegion mr) {
MutexLockerEx x(Shared_DirtyCardQ_lock,
Mutex::_no_safepoint_check_flag);
for (; byte <= last_byte; byte++) {
- if (*byte == g1_young_gen) {
+ if (*byte == G1CardTable::g1_young_card_val()) {
continue;
}
- if (*byte != dirty_card) {
- *byte = dirty_card;
+ if (*byte != G1CardTable::dirty_card_val()) {
+ *byte = G1CardTable::dirty_card_val();
_dcqs.shared_dirty_card_queue()->enqueue(byte);
}
}
@@ -215,13 +141,39 @@ G1SATBCardTableLoggingModRefBS::invalidate(MemRegion mr) {
}
}
-bool G1SATBCardTableModRefBS::is_in_young(oop obj) const {
- volatile jbyte* p = byte_for((void*)obj);
- return *p == g1_young_card_val();
+void G1SATBCardTableLoggingModRefBS::on_thread_attach(JavaThread* thread) {
+ // This method initializes the SATB and dirty card queues before a
+ // JavaThread is added to the Java thread list. Right now, we don't
+ // have to do anything to the dirty card queue (it should have been
+ // activated when the thread was created), but we have to activate
+ // the SATB queue if the thread is created while a marking cycle is
+ // in progress. The activation / de-activation of the SATB queues at
+ // the beginning / end of a marking cycle is done during safepoints
+ // so we have to make sure this method is called outside one to be
+ // able to safely read the active field of the SATB queue set. Right
+ // now, it is called just before the thread is added to the Java
+ // thread list in the Threads::add() method. That method is holding
+ // the Threads_lock which ensures we are outside a safepoint. We
+ // cannot do the obvious and set the active field of the SATB queue
+ // when the thread is created given that, in some cases, safepoints
+ // might happen between the JavaThread constructor being called and the
+ // thread being added to the Java thread list (an example of this is
+ // when the structure for the DestroyJavaVM thread is created).
+ assert(!SafepointSynchronize::is_at_safepoint(), "We should not be at a safepoint");
+ assert(!thread->satb_mark_queue().is_active(), "SATB queue should not be active");
+ assert(thread->satb_mark_queue().is_empty(), "SATB queue should be empty");
+ assert(thread->dirty_card_queue().is_active(), "Dirty card queue should be active");
+
+ // If we are creating the thread during a marking cycle, we should
+ // set the active field of the SATB queue to true.
+ if (thread->satb_mark_queue_set().is_active()) {
+ thread->satb_mark_queue().set_active(true);
+ }
}
-void G1SATBCardTableLoggingModRefBS::flush_deferred_barriers(JavaThread* thread) {
- CardTableModRefBS::flush_deferred_barriers(thread);
+void G1SATBCardTableLoggingModRefBS::on_thread_detach(JavaThread* thread) {
+ // Flush any deferred card marks, SATB buffers and dirty card queue buffers
+ CardTableModRefBS::on_thread_detach(thread);
thread->satb_mark_queue().flush();
thread->dirty_card_queue().flush();
}
diff --git a/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.hpp b/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.hpp
index f9d84a6e817..52c2ee723fb 100644
--- a/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.hpp
+++ b/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.hpp
@@ -33,6 +33,8 @@
class DirtyCardQueueSet;
class G1SATBCardTableLoggingModRefBS;
+class CardTable;
+class G1CardTable;
// This barrier is specialized to use a logging barrier to support
// snapshot-at-the-beginning marking.
@@ -40,16 +42,10 @@ class G1SATBCardTableLoggingModRefBS;
class G1SATBCardTableModRefBS: public CardTableModRefBS {
friend class VMStructs;
protected:
- enum G1CardValues {
- g1_young_gen = CT_MR_BS_last_reserved << 1
- };
-
- G1SATBCardTableModRefBS(MemRegion whole_heap, const BarrierSet::FakeRtti& fake_rtti);
+ G1SATBCardTableModRefBS(G1CardTable* table, const BarrierSet::FakeRtti& fake_rtti);
~G1SATBCardTableModRefBS() { }
public:
- static int g1_young_card_val() { return g1_young_gen; }
-
// Add "pre_val" to a set of objects that may have been disconnected from the
// pre-marking object graph.
static void enqueue(oop pre_val);
@@ -62,38 +58,6 @@ public:
template
void write_ref_field_pre(T* field);
-
-/*
- Claimed and deferred bits are used together in G1 during the evacuation
- pause. These bits can have the following state transitions:
- 1. The claimed bit can be put over any other card state. Except that
- the "dirty -> dirty and claimed" transition is checked for in
- G1 code and is not used.
- 2. Deferred bit can be set only if the previous state of the card
- was either clean or claimed. mark_card_deferred() is wait-free.
- We do not care if the operation is be successful because if
- it does not it will only result in duplicate entry in the update
- buffer because of the "cache-miss". So it's not worth spinning.
- */
-
- bool is_card_claimed(size_t card_index) {
- jbyte val = _byte_map[card_index];
- return (val & (clean_card_mask_val() | claimed_card_val())) == claimed_card_val();
- }
-
- inline void set_card_claimed(size_t card_index);
-
- void verify_g1_young_region(MemRegion mr) PRODUCT_RETURN;
- void g1_mark_as_young(const MemRegion& mr);
-
- bool mark_card_deferred(size_t card_index);
-
- bool is_card_deferred(size_t card_index) {
- jbyte val = _byte_map[card_index];
- return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val();
- }
-
- virtual bool is_in_young(oop obj) const;
};
template<>
@@ -106,42 +70,14 @@ struct BarrierSet::GetType {
typedef G1SATBCardTableModRefBS type;
};
-class G1SATBCardTableLoggingModRefBSChangedListener : public G1MappingChangedListener {
- private:
- G1SATBCardTableLoggingModRefBS* _card_table;
- public:
- G1SATBCardTableLoggingModRefBSChangedListener() : _card_table(NULL) { }
-
- void set_card_table(G1SATBCardTableLoggingModRefBS* card_table) { _card_table = card_table; }
-
- virtual void on_commit(uint start_idx, size_t num_regions, bool zero_filled);
-};
-
// Adds card-table logging to the post-barrier.
// Usual invariant: all dirty cards are logged in the DirtyCardQueueSet.
class G1SATBCardTableLoggingModRefBS: public G1SATBCardTableModRefBS {
- friend class G1SATBCardTableLoggingModRefBSChangedListener;
private:
- G1SATBCardTableLoggingModRefBSChangedListener _listener;
DirtyCardQueueSet& _dcqs;
public:
- static size_t compute_size(size_t mem_region_size_in_words) {
- size_t number_of_slots = (mem_region_size_in_words / card_size_in_words);
- return ReservedSpace::allocation_align_size_up(number_of_slots);
- }
-
- // Returns how many bytes of the heap a single byte of the Card Table corresponds to.
- static size_t heap_map_factor() {
- return CardTableModRefBS::card_size;
- }
-
- G1SATBCardTableLoggingModRefBS(MemRegion whole_heap);
-
- virtual void initialize() { }
- virtual void initialize(G1RegionToSpaceMapper* mapper);
-
- virtual void resize_covered_region(MemRegion new_region) { ShouldNotReachHere(); }
+ G1SATBCardTableLoggingModRefBS(G1CardTable* card_table);
// NB: if you do a whole-heap invalidation, the "usual invariant" defined
// above no longer applies.
@@ -154,11 +90,8 @@ class G1SATBCardTableLoggingModRefBS: public G1SATBCardTableModRefBS {
void write_ref_field_post(T* field, oop new_val);
void write_ref_field_post_slow(volatile jbyte* byte);
- virtual void flush_deferred_barriers(JavaThread* thread);
-
- virtual bool card_mark_must_follow_store() const {
- return true;
- }
+ virtual void on_thread_attach(JavaThread* thread);
+ virtual void on_thread_detach(JavaThread* thread);
// Callbacks for runtime accesses.
template
diff --git a/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.inline.hpp b/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.inline.hpp
index 04b25a39fa8..05d4a263e70 100644
--- a/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.inline.hpp
+++ b/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.inline.hpp
@@ -25,8 +25,9 @@
#ifndef SHARE_VM_GC_G1_G1SATBCARDTABLEMODREFBS_INLINE_HPP
#define SHARE_VM_GC_G1_G1SATBCARDTABLEMODREFBS_INLINE_HPP
-#include "gc/shared/accessBarrierSupport.inline.hpp"
+#include "gc/g1/g1CardTable.hpp"
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
+#include "gc/shared/accessBarrierSupport.inline.hpp"
template
inline void G1SATBCardTableModRefBS::write_ref_field_pre(T* field) {
@@ -43,23 +44,13 @@ inline void G1SATBCardTableModRefBS::write_ref_field_pre(T* field) {
template
inline void G1SATBCardTableLoggingModRefBS::write_ref_field_post(T* field, oop new_val) {
- volatile jbyte* byte = byte_for(field);
- if (*byte != g1_young_gen) {
+ volatile jbyte* byte = _card_table->byte_for(field);
+ if (*byte != G1CardTable::g1_young_card_val()) {
// Take a slow path for cards in old
write_ref_field_post_slow(byte);
}
}
-void G1SATBCardTableModRefBS::set_card_claimed(size_t card_index) {
- jbyte val = _byte_map[card_index];
- if (val == clean_card_val()) {
- val = (jbyte)claimed_card_val();
- } else {
- val |= (jbyte)claimed_card_val();
- }
- _byte_map[card_index] = val;
-}
-
inline void G1SATBCardTableModRefBS::enqueue_if_weak_or_archive(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
diff --git a/src/hotspot/share/gc/g1/g1StringDedupTable.cpp b/src/hotspot/share/gc/g1/g1StringDedupTable.cpp
index 4b236f9cae0..1d4243f36bd 100644
--- a/src/hotspot/share/gc/g1/g1StringDedupTable.cpp
+++ b/src/hotspot/share/gc/g1/g1StringDedupTable.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,7 @@
#include "gc/shared/gcLocker.hpp"
#include "logging/log.hpp"
#include "memory/padded.inline.hpp"
+#include "oops/arrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/typeArrayOop.hpp"
#include "runtime/mutexLocker.hpp"
diff --git a/src/hotspot/share/gc/g1/heapRegion.cpp b/src/hotspot/share/gc/g1/heapRegion.cpp
index 1c69be223a3..42a31bbe49e 100644
--- a/src/hotspot/share/gc/g1/heapRegion.cpp
+++ b/src/hotspot/share/gc/g1/heapRegion.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -100,7 +100,7 @@ void HeapRegion::setup_heap_region_size(size_t initial_heap_size, size_t max_hea
guarantee((size_t) 1 << LogOfHRGrainWords == GrainWords, "sanity");
guarantee(CardsPerRegion == 0, "we should only set it once");
- CardsPerRegion = GrainBytes >> CardTableModRefBS::card_shift;
+ CardsPerRegion = GrainBytes >> G1CardTable::card_shift;
if (G1HeapRegionSize != GrainBytes) {
FLAG_SET_ERGO(size_t, G1HeapRegionSize, GrainBytes);
@@ -139,9 +139,8 @@ void HeapRegion::par_clear() {
assert(capacity() == HeapRegion::GrainBytes, "should be back to normal");
HeapRegionRemSet* hrrs = rem_set();
hrrs->clear();
- CardTableModRefBS* ct_bs =
- barrier_set_cast(G1CollectedHeap::heap()->barrier_set());
- ct_bs->clear(MemRegion(bottom(), end()));
+ G1CardTable* ct = G1CollectedHeap::heap()->card_table();
+ ct->clear(MemRegion(bottom(), end()));
}
void HeapRegion::calc_gc_efficiency() {
@@ -463,7 +462,7 @@ void HeapRegion::print_on(outputStream* st) const {
class G1VerificationClosure : public OopClosure {
protected:
G1CollectedHeap* _g1h;
- CardTableModRefBS* _bs;
+ G1CardTable *_ct;
oop _containing_obj;
bool _failures;
int _n_failures;
@@ -473,7 +472,7 @@ public:
// _vo == UseNextMarking -> use "next" marking information,
// _vo == UseFullMarking -> use "next" marking bitmap but no TAMS.
G1VerificationClosure(G1CollectedHeap* g1h, VerifyOption vo) :
- _g1h(g1h), _bs(barrier_set_cast(g1h->barrier_set())),
+ _g1h(g1h), _ct(g1h->card_table()),
_containing_obj(NULL), _failures(false), _n_failures(0), _vo(vo) {
}
@@ -576,9 +575,9 @@ public:
if (from != NULL && to != NULL &&
from != to &&
!to->is_pinned()) {
- jbyte cv_obj = *_bs->byte_for_const(_containing_obj);
- jbyte cv_field = *_bs->byte_for_const(p);
- const jbyte dirty = CardTableModRefBS::dirty_card_val();
+ jbyte cv_obj = *_ct->byte_for_const(_containing_obj);
+ jbyte cv_field = *_ct->byte_for_const(p);
+ const jbyte dirty = G1CardTable::dirty_card_val();
bool is_bad = !(from->is_young()
|| to->rem_set()->contains_reference(p)
@@ -834,7 +833,6 @@ void G1ContiguousSpace::clear(bool mangle_space) {
CompactibleSpace::clear(mangle_space);
reset_bot();
}
-
#ifndef PRODUCT
void G1ContiguousSpace::mangle_unused_area() {
mangle_unused_area_complete();
diff --git a/src/hotspot/share/gc/g1/heapRegion.hpp b/src/hotspot/share/gc/g1/heapRegion.hpp
index d93a8d51bdb..2869b4659a1 100644
--- a/src/hotspot/share/gc/g1/heapRegion.hpp
+++ b/src/hotspot/share/gc/g1/heapRegion.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,7 @@
#include "gc/g1/heapRegionType.hpp"
#include "gc/g1/survRateGroup.hpp"
#include "gc/shared/ageTable.hpp"
+#include "gc/shared/cardTable.hpp"
#include "gc/shared/spaceDecorator.hpp"
#include "utilities/macros.hpp"
diff --git a/src/hotspot/share/gc/g1/heapRegionRemSet.cpp b/src/hotspot/share/gc/g1/heapRegionRemSet.cpp
index 603be129590..4cdddb313ee 100644
--- a/src/hotspot/share/gc/g1/heapRegionRemSet.cpp
+++ b/src/hotspot/share/gc/g1/heapRegionRemSet.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -103,7 +103,7 @@ protected:
if (loc_hr->is_in_reserved(from)) {
size_t hw_offset = pointer_delta((HeapWord*)from, loc_hr->bottom());
CardIdx_t from_card = (CardIdx_t)
- hw_offset >> (CardTableModRefBS::card_shift - LogHeapWordSize);
+ hw_offset >> (G1CardTable::card_shift - LogHeapWordSize);
assert((size_t)from_card < HeapRegion::CardsPerRegion,
"Must be in range.");
@@ -170,7 +170,7 @@ public:
bool contains_reference(OopOrNarrowOopStar from) const {
assert(hr()->is_in_reserved(from), "Precondition.");
size_t card_ind = pointer_delta(from, hr()->bottom(),
- CardTableModRefBS::card_size);
+ G1CardTable::card_size);
return _bm.at(card_ind);
}
@@ -354,7 +354,7 @@ void OtherRegionsTable::unlink_from_all(PerRegionTable* prt) {
void OtherRegionsTable::add_reference(OopOrNarrowOopStar from, uint tid) {
uint cur_hrm_ind = _hr->hrm_index();
- int from_card = (int)(uintptr_t(from) >> CardTableModRefBS::card_shift);
+ int from_card = (int)(uintptr_t(from) >> G1CardTable::card_shift);
if (G1FromCardCache::contains_or_replace(tid, cur_hrm_ind, from_card)) {
assert(contains_reference(from), "We just found " PTR_FORMAT " in the FromCardCache", p2i(from));
@@ -382,7 +382,7 @@ void OtherRegionsTable::add_reference(OopOrNarrowOopStar from, uint tid) {
uintptr_t from_hr_bot_card_index =
uintptr_t(from_hr->bottom())
- >> CardTableModRefBS::card_shift;
+ >> G1CardTable::card_shift;
CardIdx_t card_index = from_card - from_hr_bot_card_index;
assert((size_t)card_index < HeapRegion::CardsPerRegion,
"Must be in range.");
@@ -671,9 +671,9 @@ bool OtherRegionsTable::contains_reference_locked(OopOrNarrowOopStar from) const
} else {
uintptr_t from_card =
- (uintptr_t(from) >> CardTableModRefBS::card_shift);
+ (uintptr_t(from) >> G1CardTable::card_shift);
uintptr_t hr_bot_card_index =
- uintptr_t(hr->bottom()) >> CardTableModRefBS::card_shift;
+ uintptr_t(hr->bottom()) >> G1CardTable::card_shift;
assert(from_card >= hr_bot_card_index, "Inv");
CardIdx_t card_index = from_card - hr_bot_card_index;
assert((size_t)card_index < HeapRegion::CardsPerRegion,
diff --git a/src/hotspot/share/gc/g1/satbMarkQueue.cpp b/src/hotspot/share/gc/g1/satbMarkQueue.cpp
index 178cb450c9b..ba6ddd43f5c 100644
--- a/src/hotspot/share/gc/g1/satbMarkQueue.cpp
+++ b/src/hotspot/share/gc/g1/satbMarkQueue.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -40,7 +40,8 @@ SATBMarkQueue::SATBMarkQueue(SATBMarkQueueSet* qset, bool permanent) :
// them with their active field set to false. If a thread is
// created during a cycle and its SATB queue needs to be activated
// before the thread starts running, we'll need to set its active
- // field to true. This is done in JavaThread::initialize_queues().
+ // field to true. This is done in G1SATBCardTableLoggingModRefBS::
+ // on_thread_attach().
PtrQueue(qset, permanent, false /* active */)
{ }
diff --git a/src/hotspot/share/gc/g1/sparsePRT.cpp b/src/hotspot/share/gc/g1/sparsePRT.cpp
index 6131f3cd692..45cbb676237 100644
--- a/src/hotspot/share/gc/g1/sparsePRT.cpp
+++ b/src/hotspot/share/gc/g1/sparsePRT.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,7 +41,7 @@ void SparsePRTEntry::init(RegionIdx_t region_ind) {
// Check that the card array element type can represent all cards in the region.
// Choose a large SparsePRTEntry::card_elem_t (e.g. CardIdx_t) if required.
assert(((size_t)1 << (sizeof(SparsePRTEntry::card_elem_t) * BitsPerByte)) *
- G1SATBCardTableModRefBS::card_size >= HeapRegionBounds::max_size(), "precondition");
+ G1CardTable::card_size >= HeapRegionBounds::max_size(), "precondition");
assert(G1RSetSparseRegionEntries > 0, "precondition");
_region_ind = region_ind;
_next_index = RSHashTable::NullEntry;
diff --git a/src/hotspot/share/gc/parallel/asPSYoungGen.cpp b/src/hotspot/share/gc/parallel/asPSYoungGen.cpp
index 74ff23ee09b..3b9e57d8e96 100644
--- a/src/hotspot/share/gc/parallel/asPSYoungGen.cpp
+++ b/src/hotspot/share/gc/parallel/asPSYoungGen.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2016, 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
@@ -509,7 +509,7 @@ void ASPSYoungGen::reset_after_change() {
}
MemRegion cmr((HeapWord*)virtual_space()->low(),
(HeapWord*)virtual_space()->high());
- ParallelScavengeHeap::heap()->barrier_set()->resize_covered_region(cmr);
+ ParallelScavengeHeap::heap()->barrier_set()->card_table()->resize_covered_region(cmr);
space_invariants();
}
diff --git a/src/hotspot/share/gc/parallel/generationSizer.hpp b/src/hotspot/share/gc/parallel/generationSizer.hpp
index 558476049b7..539629b1c96 100644
--- a/src/hotspot/share/gc/parallel/generationSizer.hpp
+++ b/src/hotspot/share/gc/parallel/generationSizer.hpp
@@ -41,11 +41,5 @@ class GenerationSizer : public GenCollectorPolicy {
void initialize_alignments();
void initialize_flags();
void initialize_size_info();
-
- public:
- // We don't have associated counters and complain if this is invoked.
- void initialize_gc_policy_counters() {
- ShouldNotReachHere();
- }
};
#endif // SHARE_VM_GC_PARALLEL_GENERATIONSIZER_HPP
diff --git a/src/hotspot/share/gc/parallel/objectStartArray.cpp b/src/hotspot/share/gc/parallel/objectStartArray.cpp
index bfeb81aaa56..e40f8624c0e 100644
--- a/src/hotspot/share/gc/parallel/objectStartArray.cpp
+++ b/src/hotspot/share/gc/parallel/objectStartArray.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,7 @@
void ObjectStartArray::initialize(MemRegion reserved_region) {
// We're based on the assumption that we use the same
// size blocks as the card table.
- assert((int)block_size == (int)CardTableModRefBS::card_size, "Sanity");
+ assert((int)block_size == (int)CardTable::card_size, "Sanity");
assert((int)block_size <= 512, "block_size must be less than or equal to 512");
// Calculate how much space must be reserved
diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp
index 67e81c621b1..73c2ff7438c 100644
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp
@@ -26,7 +26,6 @@
#include "code/codeCache.hpp"
#include "gc/parallel/adjoiningGenerations.hpp"
#include "gc/parallel/adjoiningVirtualSpaces.hpp"
-#include "gc/parallel/cardTableExtension.hpp"
#include "gc/parallel/gcTaskManager.hpp"
#include "gc/parallel/generationSizer.hpp"
#include "gc/parallel/objectStartArray.inline.hpp"
@@ -70,7 +69,9 @@ jint ParallelScavengeHeap::initialize() {
initialize_reserved_region((HeapWord*)heap_rs.base(), (HeapWord*)(heap_rs.base() + heap_rs.size()));
- CardTableExtension* const barrier_set = new CardTableExtension(reserved_region());
+ PSCardTable* card_table = new PSCardTable(reserved_region());
+ card_table->initialize();
+ CardTableModRefBS* const barrier_set = new CardTableModRefBS(card_table);
barrier_set->initialize();
set_barrier_set(barrier_set);
@@ -331,7 +332,7 @@ HeapWord* ParallelScavengeHeap::mem_allocate(
// excesses). Fill op.result() with a filler object so that the
// heap remains parsable.
const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
- const bool softrefs_clear = collector_policy()->all_soft_refs_clear();
+ const bool softrefs_clear = soft_ref_policy()->all_soft_refs_clear();
if (limit_exceeded && softrefs_clear) {
*gc_overhead_limit_was_exceeded = true;
@@ -625,6 +626,14 @@ ParallelScavengeHeap* ParallelScavengeHeap::heap() {
return (ParallelScavengeHeap*)heap;
}
+CardTableModRefBS* ParallelScavengeHeap::barrier_set() {
+ return barrier_set_cast(CollectedHeap::barrier_set());
+}
+
+PSCardTable* ParallelScavengeHeap::card_table() {
+ return static_cast(barrier_set()->card_table());
+}
+
// Before delegating the resize to the young generation,
// the reserved space for the young and old generations
// may be changed to accommodate the desired resize.
diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp
index c06468673f2..684b83f178f 100644
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp
@@ -30,10 +30,12 @@
#include "gc/parallel/psGCAdaptivePolicyCounters.hpp"
#include "gc/parallel/psOldGen.hpp"
#include "gc/parallel/psYoungGen.hpp"
+#include "gc/shared/cardTableModRefBS.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "gc/shared/collectorPolicy.hpp"
#include "gc/shared/gcPolicyCounters.hpp"
#include "gc/shared/gcWhen.hpp"
+#include "gc/shared/softRefPolicy.hpp"
#include "gc/shared/strongRootsScope.hpp"
#include "memory/metaspace.hpp"
#include "utilities/growableArray.hpp"
@@ -45,6 +47,7 @@ class GCTaskManager;
class MemoryManager;
class MemoryPool;
class PSAdaptiveSizePolicy;
+class PSCardTable;
class PSHeapSummary;
class ParallelScavengeHeap : public CollectedHeap {
@@ -59,6 +62,8 @@ class ParallelScavengeHeap : public CollectedHeap {
GenerationSizer* _collector_policy;
+ SoftRefPolicy _soft_ref_policy;
+
// Collection of generations that are adjacent in the
// space reserved for the heap.
AdjoiningGenerations* _gens;
@@ -106,6 +111,8 @@ class ParallelScavengeHeap : public CollectedHeap {
virtual CollectorPolicy* collector_policy() const { return _collector_policy; }
+ virtual SoftRefPolicy* soft_ref_policy() { return &_soft_ref_policy; }
+
virtual GrowableArray memory_managers();
virtual GrowableArray memory_pools();
@@ -120,6 +127,9 @@ class ParallelScavengeHeap : public CollectedHeap {
static GCTaskManager* const gc_task_manager() { return _gc_task_manager; }
+ CardTableModRefBS* barrier_set();
+ PSCardTable* card_table();
+
AdjoiningGenerations* gens() { return _gens; }
// Returns JNI_OK on success
diff --git a/src/hotspot/share/gc/parallel/cardTableExtension.cpp b/src/hotspot/share/gc/parallel/psCardTable.cpp
similarity index 88%
rename from src/hotspot/share/gc/parallel/cardTableExtension.cpp
rename to src/hotspot/share/gc/parallel/psCardTable.cpp
index 26eef1226fd..db2c00ffeb7 100644
--- a/src/hotspot/share/gc/parallel/cardTableExtension.cpp
+++ b/src/hotspot/share/gc/parallel/psCardTable.cpp
@@ -23,10 +23,10 @@
*/
#include "precompiled.hpp"
-#include "gc/parallel/cardTableExtension.hpp"
#include "gc/parallel/gcTaskManager.hpp"
#include "gc/parallel/objectStartArray.inline.hpp"
#include "gc/parallel/parallelScavengeHeap.inline.hpp"
+#include "gc/parallel/psCardTable.hpp"
#include "gc/parallel/psPromotionManager.inline.hpp"
#include "gc/parallel/psScavenge.hpp"
#include "gc/parallel/psTasks.hpp"
@@ -39,9 +39,9 @@
// may be either dirty or newgen.
class CheckForUnmarkedOops : public OopClosure {
private:
- PSYoungGen* _young_gen;
- CardTableExtension* _card_table;
- HeapWord* _unmarked_addr;
+ PSYoungGen* _young_gen;
+ PSCardTable* _card_table;
+ HeapWord* _unmarked_addr;
protected:
template void do_oop_work(T* p) {
@@ -56,7 +56,7 @@ class CheckForUnmarkedOops : public OopClosure {
}
public:
- CheckForUnmarkedOops(PSYoungGen* young_gen, CardTableExtension* card_table) :
+ CheckForUnmarkedOops(PSYoungGen* young_gen, PSCardTable* card_table) :
_young_gen(young_gen), _card_table(card_table), _unmarked_addr(NULL) { }
virtual void do_oop(oop* p) { CheckForUnmarkedOops::do_oop_work(p); }
@@ -71,16 +71,14 @@ class CheckForUnmarkedOops : public OopClosure {
// precise or imprecise, dirty or newgen.
class CheckForUnmarkedObjects : public ObjectClosure {
private:
- PSYoungGen* _young_gen;
- CardTableExtension* _card_table;
+ PSYoungGen* _young_gen;
+ PSCardTable* _card_table;
public:
CheckForUnmarkedObjects() {
ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
_young_gen = heap->young_gen();
- _card_table = barrier_set_cast(heap->barrier_set());
- // No point in asserting barrier set type here. Need to make CardTableExtension
- // a unique barrier set type.
+ _card_table = heap->card_table();
}
// Card marks are not precise. The current system can leave us with
@@ -99,8 +97,8 @@ class CheckForUnmarkedObjects : public ObjectClosure {
// Checks for precise marking of oops as newgen.
class CheckForPreciseMarks : public OopClosure {
private:
- PSYoungGen* _young_gen;
- CardTableExtension* _card_table;
+ PSYoungGen* _young_gen;
+ PSCardTable* _card_table;
protected:
template void do_oop_work(T* p) {
@@ -112,7 +110,7 @@ class CheckForPreciseMarks : public OopClosure {
}
public:
- CheckForPreciseMarks( PSYoungGen* young_gen, CardTableExtension* card_table ) :
+ CheckForPreciseMarks(PSYoungGen* young_gen, PSCardTable* card_table) :
_young_gen(young_gen), _card_table(card_table) { }
virtual void do_oop(oop* p) { CheckForPreciseMarks::do_oop_work(p); }
@@ -128,12 +126,12 @@ class CheckForPreciseMarks : public OopClosure {
// when the space is empty, fix the calculation of
// end_card to allow sp_top == sp->bottom().
-void CardTableExtension::scavenge_contents_parallel(ObjectStartArray* start_array,
- MutableSpace* sp,
- HeapWord* space_top,
- PSPromotionManager* pm,
- uint stripe_number,
- uint stripe_total) {
+void PSCardTable::scavenge_contents_parallel(ObjectStartArray* start_array,
+ MutableSpace* sp,
+ HeapWord* space_top,
+ PSPromotionManager* pm,
+ uint stripe_number,
+ uint stripe_total) {
int ssize = 128; // Naked constant! Work unit = 64k.
int dirty_card_count = 0;
@@ -320,7 +318,7 @@ void CardTableExtension::scavenge_contents_parallel(ObjectStartArray* start_arra
}
// This should be called before a scavenge.
-void CardTableExtension::verify_all_young_refs_imprecise() {
+void PSCardTable::verify_all_young_refs_imprecise() {
CheckForUnmarkedObjects check;
ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
@@ -330,26 +328,21 @@ void CardTableExtension::verify_all_young_refs_imprecise() {
}
// This should be called immediately after a scavenge, before mutators resume.
-void CardTableExtension::verify_all_young_refs_precise() {
+void PSCardTable::verify_all_young_refs_precise() {
ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
PSOldGen* old_gen = heap->old_gen();
- CheckForPreciseMarks check(
- heap->young_gen(),
- barrier_set_cast(heap->barrier_set()));
+ CheckForPreciseMarks check(heap->young_gen(), this);
old_gen->oop_iterate_no_header(&check);
verify_all_young_refs_precise_helper(old_gen->object_space()->used_region());
}
-void CardTableExtension::verify_all_young_refs_precise_helper(MemRegion mr) {
- CardTableExtension* card_table =
- barrier_set_cast(ParallelScavengeHeap::heap()->barrier_set());
-
- jbyte* bot = card_table->byte_for(mr.start());
- jbyte* top = card_table->byte_for(mr.end());
- while(bot <= top) {
+void PSCardTable::verify_all_young_refs_precise_helper(MemRegion mr) {
+ jbyte* bot = byte_for(mr.start());
+ jbyte* top = byte_for(mr.end());
+ while (bot <= top) {
assert(*bot == clean_card || *bot == verify_card, "Found unwanted or unknown card mark");
if (*bot == verify_card)
*bot = youngergen_card;
@@ -357,7 +350,7 @@ void CardTableExtension::verify_all_young_refs_precise_helper(MemRegion mr) {
}
}
-bool CardTableExtension::addr_is_marked_imprecise(void *addr) {
+bool PSCardTable::addr_is_marked_imprecise(void *addr) {
jbyte* p = byte_for(addr);
jbyte val = *p;
@@ -376,7 +369,7 @@ bool CardTableExtension::addr_is_marked_imprecise(void *addr) {
}
// Also includes verify_card
-bool CardTableExtension::addr_is_marked_precise(void *addr) {
+bool PSCardTable::addr_is_marked_precise(void *addr) {
jbyte* p = byte_for(addr);
jbyte val = *p;
@@ -404,8 +397,7 @@ bool CardTableExtension::addr_is_marked_precise(void *addr) {
// The method resize_covered_region_by_end() is analogous to
// CardTableModRefBS::resize_covered_region() but
// for regions that grow or shrink at the low end.
-void CardTableExtension::resize_covered_region(MemRegion new_region) {
-
+void PSCardTable::resize_covered_region(MemRegion new_region) {
for (int i = 0; i < _cur_covered_regions; i++) {
if (_covered[i].start() == new_region.start()) {
// Found a covered region with the same start as the
@@ -439,13 +431,13 @@ void CardTableExtension::resize_covered_region(MemRegion new_region) {
resize_covered_region_by_start(new_region);
}
-void CardTableExtension::resize_covered_region_by_start(MemRegion new_region) {
- CardTableModRefBS::resize_covered_region(new_region);
+void PSCardTable::resize_covered_region_by_start(MemRegion new_region) {
+ CardTable::resize_covered_region(new_region);
debug_only(verify_guard();)
}
-void CardTableExtension::resize_covered_region_by_end(int changed_region,
- MemRegion new_region) {
+void PSCardTable::resize_covered_region_by_end(int changed_region,
+ MemRegion new_region) {
assert(SafepointSynchronize::is_at_safepoint(),
"Only expect an expansion at the low end at a GC");
debug_only(verify_guard();)
@@ -484,8 +476,8 @@ void CardTableExtension::resize_covered_region_by_end(int changed_region,
debug_only(verify_guard();)
}
-bool CardTableExtension::resize_commit_uncommit(int changed_region,
- MemRegion new_region) {
+bool PSCardTable::resize_commit_uncommit(int changed_region,
+ MemRegion new_region) {
bool result = false;
// Commit new or uncommit old pages, if necessary.
MemRegion cur_committed = _committed[changed_region];
@@ -506,13 +498,12 @@ bool CardTableExtension::resize_commit_uncommit(int changed_region,
#ifdef ASSERT
ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
assert(cur_committed.start() == align_up(cur_committed.start(), os::vm_page_size()),
- "Starts should have proper alignment");
+ "Starts should have proper alignment");
#endif
jbyte* new_start = byte_for(new_region.start());
// Round down because this is for the start address
- HeapWord* new_start_aligned =
- (HeapWord*)align_down((uintptr_t)new_start, os::vm_page_size());
+ HeapWord* new_start_aligned = align_down((HeapWord*)new_start, os::vm_page_size());
// The guard page is always committed and should not be committed over.
// This method is used in cases where the generation is growing toward
// lower addresses but the guard region is still at the end of the
@@ -579,21 +570,20 @@ bool CardTableExtension::resize_commit_uncommit(int changed_region,
return result;
}
-void CardTableExtension::resize_update_committed_table(int changed_region,
- MemRegion new_region) {
+void PSCardTable::resize_update_committed_table(int changed_region,
+ MemRegion new_region) {
jbyte* new_start = byte_for(new_region.start());
// Set the new start of the committed region
- HeapWord* new_start_aligned =
- (HeapWord*)align_down(new_start, os::vm_page_size());
+ HeapWord* new_start_aligned = align_down((HeapWord*)new_start, os::vm_page_size());
MemRegion new_committed = MemRegion(new_start_aligned,
- _committed[changed_region].end());
+ _committed[changed_region].end());
_committed[changed_region] = new_committed;
_committed[changed_region].set_start(new_start_aligned);
}
-void CardTableExtension::resize_update_card_table_entries(int changed_region,
- MemRegion new_region) {
+void PSCardTable::resize_update_card_table_entries(int changed_region,
+ MemRegion new_region) {
debug_only(verify_guard();)
MemRegion original_covered = _covered[changed_region];
// Initialize the card entries. Only consider the
@@ -610,8 +600,8 @@ void CardTableExtension::resize_update_card_table_entries(int changed_region,
while (entry < end) { *entry++ = clean_card; }
}
-void CardTableExtension::resize_update_covered_table(int changed_region,
- MemRegion new_region) {
+void PSCardTable::resize_update_covered_table(int changed_region,
+ MemRegion new_region) {
// Update the covered region
_covered[changed_region].set_start(new_region.start());
_covered[changed_region].set_word_size(new_region.word_size());
@@ -665,7 +655,7 @@ void CardTableExtension::resize_update_covered_table(int changed_region,
// -------------
// ^ returns this
-HeapWord* CardTableExtension::lowest_prev_committed_start(int ind) const {
+HeapWord* PSCardTable::lowest_prev_committed_start(int ind) const {
assert(_cur_covered_regions >= 0, "Expecting at least on region");
HeapWord* min_start = _committed[ind].start();
for (int j = 0; j < ind; j++) {
@@ -678,6 +668,6 @@ HeapWord* CardTableExtension::lowest_prev_committed_start(int ind) const {
return min_start;
}
-bool CardTableExtension::is_in_young(oop obj) const {
+bool PSCardTable::is_in_young(oop obj) const {
return ParallelScavengeHeap::heap()->is_in_young(obj);
}
diff --git a/src/hotspot/share/gc/parallel/cardTableExtension.hpp b/src/hotspot/share/gc/parallel/psCardTable.hpp
similarity index 76%
rename from src/hotspot/share/gc/parallel/cardTableExtension.hpp
rename to src/hotspot/share/gc/parallel/psCardTable.hpp
index c37d19fec99..3c79f26a463 100644
--- a/src/hotspot/share/gc/parallel/cardTableExtension.hpp
+++ b/src/hotspot/share/gc/parallel/psCardTable.hpp
@@ -22,17 +22,18 @@
*
*/
-#ifndef SHARE_VM_GC_PARALLEL_CARDTABLEEXTENSION_HPP
-#define SHARE_VM_GC_PARALLEL_CARDTABLEEXTENSION_HPP
+#ifndef SHARE_VM_GC_PARALLEL_PSCARDTABLE_HPP
+#define SHARE_VM_GC_PARALLEL_PSCARDTABLE_HPP
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTable.hpp"
+#include "oops/oop.hpp"
class MutableSpace;
class ObjectStartArray;
class PSPromotionManager;
class GCTaskQueue;
-class CardTableExtension : public CardTableModRefBS {
+class PSCardTable: public CardTable {
private:
// Support methods for resizing the card table.
// resize_commit_uncommit() returns true if the pages were committed or
@@ -43,21 +44,18 @@ class CardTableExtension : public CardTableModRefBS {
void resize_update_committed_table(int changed_region, MemRegion new_region);
void resize_update_covered_table(int changed_region, MemRegion new_region);
- protected:
+ void verify_all_young_refs_precise_helper(MemRegion mr);
- static void verify_all_young_refs_precise_helper(MemRegion mr);
-
- public:
enum ExtendedCardValue {
- youngergen_card = CardTableModRefBS::CT_MR_BS_last_reserved + 1,
- verify_card = CardTableModRefBS::CT_MR_BS_last_reserved + 5
+ youngergen_card = CT_MR_BS_last_reserved + 1,
+ verify_card = CT_MR_BS_last_reserved + 5
};
- CardTableExtension(MemRegion whole_heap) :
- CardTableModRefBS(
- whole_heap,
- BarrierSet::FakeRtti(BarrierSet::CardTableExtension))
- { }
+ public:
+ PSCardTable(MemRegion whole_heap) : CardTable(whole_heap, /* scanned_concurrently */ false) {}
+
+ static jbyte youngergen_card_val() { return youngergen_card; }
+ static jbyte verify_card_val() { return verify_card; }
// Scavenge support
void scavenge_contents_parallel(ObjectStartArray* start_array,
@@ -67,10 +65,6 @@ class CardTableExtension : public CardTableModRefBS {
uint stripe_number,
uint stripe_total);
- // Verification
- static void verify_all_young_refs_imprecise();
- static void verify_all_young_refs_precise();
-
bool addr_is_marked_imprecise(void *addr);
bool addr_is_marked_precise(void *addr);
@@ -88,6 +82,9 @@ class CardTableExtension : public CardTableModRefBS {
*byte = youngergen_card;
}
+ // ReduceInitialCardMarks support
+ bool is_in_young(oop obj) const;
+
// Adaptive size policy support
// Allows adjustment of the base and size of the covered regions
void resize_covered_region(MemRegion new_region);
@@ -102,29 +99,14 @@ class CardTableExtension : public CardTableModRefBS {
HeapWord* lowest_prev_committed_start(int ind) const;
#ifdef ASSERT
-
bool is_valid_card_address(jbyte* addr) {
return (addr >= _byte_map) && (addr < _byte_map + _byte_map_size);
}
-
#endif // ASSERT
- // ReduceInitialCardMarks support
- virtual bool is_in_young(oop obj) const;
-
- virtual bool card_mark_must_follow_store() const {
- return false;
- }
+ // Verification
+ void verify_all_young_refs_imprecise();
+ void verify_all_young_refs_precise();
};
-template<>
-struct BarrierSet::GetName {
- static const BarrierSet::Name value = BarrierSet::CardTableExtension;
-};
-
-template<>
-struct BarrierSet::GetType {
- typedef ::CardTableExtension type;
-};
-
-#endif // SHARE_VM_GC_PARALLEL_CARDTABLEEXTENSION_HPP
+#endif // SHARE_VM_GC_PARALLEL_PSCARDTABLE
diff --git a/src/hotspot/share/gc/parallel/psCompactionManager.cpp b/src/hotspot/share/gc/parallel/psCompactionManager.cpp
index c79b52af589..b47ce3c572f 100644
--- a/src/hotspot/share/gc/parallel/psCompactionManager.cpp
+++ b/src/hotspot/share/gc/parallel/psCompactionManager.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -181,7 +181,7 @@ void InstanceClassLoaderKlass::oop_pc_follow_contents(oop obj, ParCompactionMana
template
static void oop_pc_follow_contents_specialized(InstanceRefKlass* klass, oop obj, ParCompactionManager* cm) {
- T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
+ T* referent_addr = (T*)java_lang_ref_Reference::referent_addr_raw(obj);
T heap_oop = oopDesc::load_heap_oop(referent_addr);
log_develop_trace(gc, ref)("InstanceRefKlass::oop_pc_follow_contents " PTR_FORMAT, p2i(obj));
if (!oopDesc::is_null(heap_oop)) {
@@ -198,12 +198,12 @@ static void oop_pc_follow_contents_specialized(InstanceRefKlass* klass, oop obj,
cm->mark_and_push(referent_addr);
}
}
- T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
+ T* next_addr = (T*)java_lang_ref_Reference::next_addr_raw(obj);
// Treat discovered as normal oop, if ref is not "active",
// i.e. if next is non-NULL.
T next_oop = oopDesc::load_heap_oop(next_addr);
if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
- T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
+ T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr_raw(obj);
log_develop_trace(gc, ref)(" Process discovered as normal " PTR_FORMAT, p2i(discovered_addr));
cm->mark_and_push(discovered_addr);
}
diff --git a/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp b/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp
index 1376fa65c8e..8ae61066a0f 100644
--- a/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp
+++ b/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp
@@ -29,7 +29,8 @@
#include "gc/parallel/psCompactionManager.hpp"
#include "gc/parallel/psParallelCompact.inline.hpp"
#include "gc/shared/taskqueue.inline.hpp"
-#include "oops/objArrayOop.hpp"
+#include "oops/arrayOop.inline.hpp"
+#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "utilities/debug.hpp"
#include "utilities/globalDefinitions.hpp"
@@ -117,7 +118,7 @@ inline void oop_pc_follow_contents_specialized(objArrayOop obj, int index, ParCo
const size_t stride = MIN2(len - beg_index, ObjArrayMarkingStride);
const size_t end_index = beg_index + stride;
- T* const base = (T*)obj->base();
+ T* const base = (T*)obj->base_raw();
T* const beg = base + beg_index;
T* const end = base + end_index;
diff --git a/src/hotspot/share/gc/parallel/psMarkSweep.cpp b/src/hotspot/share/gc/parallel/psMarkSweep.cpp
index 2ac25afc016..cf67ff8a596 100644
--- a/src/hotspot/share/gc/parallel/psMarkSweep.cpp
+++ b/src/hotspot/share/gc/parallel/psMarkSweep.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -98,7 +98,7 @@ void PSMarkSweep::invoke(bool maximum_heap_compaction) {
}
const bool clear_all_soft_refs =
- heap->collector_policy()->should_clear_all_soft_refs();
+ heap->soft_ref_policy()->should_clear_all_soft_refs();
uint count = maximum_heap_compaction ? 1 : MarkSweepAlwaysCompactCount;
UIntFlagSetting flag_setting(MarkSweepAlwaysCompactCount, count);
@@ -126,7 +126,7 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
// The scope of casr should end after code that can change
// CollectorPolicy::_should_clear_all_soft_refs.
- ClearedAllSoftRefs casr(clear_all_softrefs, heap->collector_policy());
+ ClearedAllSoftRefs casr(clear_all_softrefs, heap->soft_ref_policy());
PSYoungGen* young_gen = heap->young_gen();
PSOldGen* old_gen = heap->old_gen();
@@ -236,12 +236,12 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
young_gen->to_space()->is_empty();
young_gen_empty = eden_empty && survivors_empty;
- ModRefBarrierSet* modBS = barrier_set_cast(heap->barrier_set());
+ PSCardTable* card_table = heap->card_table();
MemRegion old_mr = heap->old_gen()->reserved();
if (young_gen_empty) {
- modBS->clear(MemRegion(old_mr.start(), old_mr.end()));
+ card_table->clear(MemRegion(old_mr.start(), old_mr.end()));
} else {
- modBS->invalidate(MemRegion(old_mr.start(), old_mr.end()));
+ card_table->invalidate(MemRegion(old_mr.start(), old_mr.end()));
}
// Delete metaspaces for unloaded class loaders and clean up loader_data graph
@@ -320,7 +320,7 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
max_eden_size,
true /* full gc*/,
gc_cause,
- heap->collector_policy());
+ heap->soft_ref_policy());
size_policy->decay_supplemental_growth(true /* full gc*/);
diff --git a/src/hotspot/share/gc/parallel/psOldGen.cpp b/src/hotspot/share/gc/parallel/psOldGen.cpp
index 323996d2f32..f2f89354cf2 100644
--- a/src/hotspot/share/gc/parallel/psOldGen.cpp
+++ b/src/hotspot/share/gc/parallel/psOldGen.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
#include "gc/parallel/objectStartArray.inline.hpp"
#include "gc/parallel/parallelScavengeHeap.hpp"
#include "gc/parallel/psAdaptiveSizePolicy.hpp"
+#include "gc/parallel/psCardTable.hpp"
#include "gc/parallel/psMarkSweepDecorator.hpp"
#include "gc/parallel/psOldGen.hpp"
#include "gc/shared/cardTableModRefBS.hpp"
@@ -111,11 +112,8 @@ void PSOldGen::initialize_work(const char* perf_data_name, int level) {
}
ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
- BarrierSet* bs = heap->barrier_set();
-
- bs->resize_covered_region(cmr);
-
- CardTableModRefBS* ct = barrier_set_cast(bs);
+ PSCardTable* ct = heap->card_table();
+ ct->resize_covered_region(cmr);
// Verify that the start and end of this generation is the start of a card.
// If this wasn't true, a single card could span more than one generation,
@@ -386,7 +384,7 @@ void PSOldGen::post_resize() {
size_t new_word_size = new_memregion.word_size();
start_array()->set_covered_region(new_memregion);
- ParallelScavengeHeap::heap()->barrier_set()->resize_covered_region(new_memregion);
+ ParallelScavengeHeap::heap()->card_table()->resize_covered_region(new_memregion);
// ALWAYS do this last!!
object_space()->initialize(new_memregion,
diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.cpp b/src/hotspot/share/gc/parallel/psParallelCompact.cpp
index be23ea77681..753e2830aa8 100644
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1017,12 +1017,12 @@ void PSParallelCompact::post_compact()
bool young_gen_empty = eden_empty && from_space->is_empty() &&
to_space->is_empty();
- ModRefBarrierSet* modBS = barrier_set_cast(heap->barrier_set());
+ PSCardTable* ct = heap->card_table();
MemRegion old_mr = heap->old_gen()->reserved();
if (young_gen_empty) {
- modBS->clear(MemRegion(old_mr.start(), old_mr.end()));
+ ct->clear(MemRegion(old_mr.start(), old_mr.end()));
} else {
- modBS->invalidate(MemRegion(old_mr.start(), old_mr.end()));
+ ct->invalidate(MemRegion(old_mr.start(), old_mr.end()));
}
// Delete metaspaces for unloaded class loaders and clean up loader_data graph
@@ -1707,7 +1707,7 @@ void PSParallelCompact::invoke(bool maximum_heap_compaction) {
}
const bool clear_all_soft_refs =
- heap->collector_policy()->should_clear_all_soft_refs();
+ heap->soft_ref_policy()->should_clear_all_soft_refs();
PSParallelCompact::invoke_no_policy(clear_all_soft_refs ||
maximum_heap_compaction);
@@ -1741,7 +1741,7 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
// The scope of casr should end after code that can change
// CollectorPolicy::_should_clear_all_soft_refs.
ClearedAllSoftRefs casr(maximum_heap_compaction,
- heap->collector_policy());
+ heap->soft_ref_policy());
if (ZapUnusedHeapArea) {
// Save information needed to minimize mangling
@@ -1869,7 +1869,7 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
max_eden_size,
true /* full gc*/,
gc_cause,
- heap->collector_policy());
+ heap->soft_ref_policy());
size_policy->decay_supplemental_growth(true /* full gc*/);
@@ -3087,11 +3087,11 @@ template static void trace_reference_gc(const char *s, oop obj,
template
static void oop_pc_update_pointers_specialized(oop obj, ParCompactionManager* cm) {
- T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
+ T* referent_addr = (T*)java_lang_ref_Reference::referent_addr_raw(obj);
PSParallelCompact::adjust_pointer(referent_addr, cm);
- T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
+ T* next_addr = (T*)java_lang_ref_Reference::next_addr_raw(obj);
PSParallelCompact::adjust_pointer(next_addr, cm);
- T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
+ T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr_raw(obj);
PSParallelCompact::adjust_pointer(discovered_addr, cm);
debug_only(trace_reference_gc("InstanceRefKlass::oop_update_ptrs", obj,
referent_addr, next_addr, discovered_addr);)
diff --git a/src/hotspot/share/gc/parallel/psPromotionManager.cpp b/src/hotspot/share/gc/parallel/psPromotionManager.cpp
index 4353527bd90..519028966a0 100644
--- a/src/hotspot/share/gc/parallel/psPromotionManager.cpp
+++ b/src/hotspot/share/gc/parallel/psPromotionManager.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -38,9 +38,11 @@
#include "memory/memRegion.hpp"
#include "memory/padded.inline.hpp"
#include "memory/resourceArea.hpp"
+#include "oops/arrayOop.inline.hpp"
#include "oops/instanceKlass.inline.hpp"
#include "oops/instanceMirrorKlass.inline.hpp"
#include "oops/objArrayKlass.inline.hpp"
+#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
PaddedEnd* PSPromotionManager::_manager_array = NULL;
@@ -434,7 +436,7 @@ void InstanceClassLoaderKlass::oop_ps_push_contents(oop obj, PSPromotionManager*
template
static void oop_ps_push_contents_specialized(oop obj, InstanceRefKlass *klass, PSPromotionManager* pm) {
- T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
+ T* referent_addr = (T*)java_lang_ref_Reference::referent_addr_raw(obj);
if (PSScavenge::should_scavenge(referent_addr)) {
ReferenceProcessor* rp = PSScavenge::reference_processor();
if (rp->discover_reference(obj, klass->reference_type())) {
@@ -448,10 +450,10 @@ static void oop_ps_push_contents_specialized(oop obj, InstanceRefKlass *klass, P
}
// Treat discovered as normal oop, if ref is not "active",
// i.e. if next is non-NULL.
- T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
+ T* next_addr = (T*)java_lang_ref_Reference::next_addr_raw(obj);
T next_oop = oopDesc::load_heap_oop(next_addr);
if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
- T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
+ T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr_raw(obj);
log_develop_trace(gc, ref)(" Process discovered as normal " PTR_FORMAT, p2i(discovered_addr));
if (PSScavenge::should_scavenge(discovered_addr)) {
pm->claim_or_forward_depth(discovered_addr);
diff --git a/src/hotspot/share/gc/parallel/psScavenge.cpp b/src/hotspot/share/gc/parallel/psScavenge.cpp
index 5bcb21bf9ff..e8ea85b0e22 100644
--- a/src/hotspot/share/gc/parallel/psScavenge.cpp
+++ b/src/hotspot/share/gc/parallel/psScavenge.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
#include "precompiled.hpp"
#include "classfile/stringTable.hpp"
#include "code/codeCache.hpp"
-#include "gc/parallel/cardTableExtension.hpp"
#include "gc/parallel/gcTaskManager.hpp"
#include "gc/parallel/parallelScavengeHeap.hpp"
#include "gc/parallel/psAdaptiveSizePolicy.hpp"
@@ -60,7 +59,7 @@
HeapWord* PSScavenge::_to_space_top_before_gc = NULL;
int PSScavenge::_consecutive_skipped_scavenges = 0;
ReferenceProcessor* PSScavenge::_ref_processor = NULL;
-CardTableExtension* PSScavenge::_card_table = NULL;
+PSCardTable* PSScavenge::_card_table = NULL;
bool PSScavenge::_survivor_overflow = false;
uint PSScavenge::_tenuring_threshold = 0;
HeapWord* PSScavenge::_young_generation_boundary = NULL;
@@ -228,8 +227,8 @@ bool PSScavenge::invoke() {
if (need_full_gc) {
GCCauseSetter gccs(heap, GCCause::_adaptive_size_policy);
- CollectorPolicy* cp = heap->collector_policy();
- const bool clear_all_softrefs = cp->should_clear_all_soft_refs();
+ SoftRefPolicy* srp = heap->soft_ref_policy();
+ const bool clear_all_softrefs = srp->should_clear_all_soft_refs();
if (UseParallelOldGC) {
full_gc_done = PSParallelCompact::invoke_no_policy(clear_all_softrefs);
@@ -322,7 +321,7 @@ bool PSScavenge::invoke_no_policy() {
// Verify no unmarked old->young roots
if (VerifyRememberedSets) {
- CardTableExtension::verify_all_young_refs_imprecise();
+ heap->card_table()->verify_all_young_refs_imprecise();
}
assert(young_gen->to_space()->is_empty(),
@@ -569,7 +568,7 @@ bool PSScavenge::invoke_no_policy() {
max_eden_size,
false /* not full gc*/,
gc_cause,
- heap->collector_policy());
+ heap->soft_ref_policy());
size_policy->decay_supplemental_growth(false /* not full gc*/);
}
@@ -617,8 +616,8 @@ bool PSScavenge::invoke_no_policy() {
if (VerifyRememberedSets) {
// Precise verification will give false positives. Until this is fixed,
// use imprecise verification.
- // CardTableExtension::verify_all_young_refs_precise();
- CardTableExtension::verify_all_young_refs_imprecise();
+ // heap->card_table()->verify_all_young_refs_precise();
+ heap->card_table()->verify_all_young_refs_imprecise();
}
if (log_is_enabled(Debug, gc, heap, exit)) {
@@ -778,7 +777,7 @@ void PSScavenge::initialize() {
NULL); // header provides liveness info
// Cache the cardtable
- _card_table = barrier_set_cast(heap->barrier_set());
+ _card_table = heap->card_table();
_counters = new CollectorCounters("PSScavenge", 0);
}
diff --git a/src/hotspot/share/gc/parallel/psScavenge.hpp b/src/hotspot/share/gc/parallel/psScavenge.hpp
index e3c870c4297..8797e29b0b6 100644
--- a/src/hotspot/share/gc/parallel/psScavenge.hpp
+++ b/src/hotspot/share/gc/parallel/psScavenge.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
#ifndef SHARE_VM_GC_PARALLEL_PSSCAVENGE_HPP
#define SHARE_VM_GC_PARALLEL_PSSCAVENGE_HPP
-#include "gc/parallel/cardTableExtension.hpp"
+#include "gc/parallel/psCardTable.hpp"
#include "gc/parallel/psVirtualspace.hpp"
#include "gc/shared/collectorCounters.hpp"
#include "gc/shared/gcTrace.hpp"
@@ -67,7 +67,7 @@ class PSScavenge: AllStatic {
// Flags/counters
static ReferenceProcessor* _ref_processor; // Reference processor for scavenging.
static PSIsAliveClosure _is_alive_closure; // Closure used for reference processing
- static CardTableExtension* _card_table; // We cache the card table for fast access.
+ static PSCardTable* _card_table; // We cache the card table for fast access.
static bool _survivor_overflow; // Overflow this collection
static uint _tenuring_threshold; // tenuring threshold for next scavenge
static elapsedTimer _accumulated_time; // total time spent on scavenge
@@ -89,7 +89,7 @@ class PSScavenge: AllStatic {
static inline void save_to_space_top_before_gc();
// Private accessors
- static CardTableExtension* const card_table() { assert(_card_table != NULL, "Sanity"); return _card_table; }
+ static PSCardTable* const card_table() { assert(_card_table != NULL, "Sanity"); return _card_table; }
static const ParallelScavengeTracer* gc_tracer() { return &_gc_tracer; }
public:
diff --git a/src/hotspot/share/gc/parallel/psScavenge.inline.hpp b/src/hotspot/share/gc/parallel/psScavenge.inline.hpp
index 70bb4ba4afc..3e72db1c22d 100644
--- a/src/hotspot/share/gc/parallel/psScavenge.inline.hpp
+++ b/src/hotspot/share/gc/parallel/psScavenge.inline.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
#ifndef SHARE_VM_GC_PARALLEL_PSSCAVENGE_INLINE_HPP
#define SHARE_VM_GC_PARALLEL_PSSCAVENGE_INLINE_HPP
-#include "gc/parallel/cardTableExtension.hpp"
#include "gc/parallel/parallelScavengeHeap.hpp"
#include "gc/parallel/psPromotionManager.inline.hpp"
#include "gc/parallel/psScavenge.hpp"
diff --git a/src/hotspot/share/gc/parallel/psTasks.cpp b/src/hotspot/share/gc/parallel/psTasks.cpp
index 3effcc6d1f6..2696e66a404 100644
--- a/src/hotspot/share/gc/parallel/psTasks.cpp
+++ b/src/hotspot/share/gc/parallel/psTasks.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,9 +26,9 @@
#include "aot/aotLoader.hpp"
#include "classfile/systemDictionary.hpp"
#include "code/codeCache.hpp"
-#include "gc/parallel/cardTableExtension.hpp"
#include "gc/parallel/gcTaskManager.hpp"
#include "gc/parallel/psMarkSweep.hpp"
+#include "gc/parallel/psCardTable.hpp"
#include "gc/parallel/psPromotionManager.hpp"
#include "gc/parallel/psPromotionManager.inline.hpp"
#include "gc/parallel/psScavenge.inline.hpp"
@@ -176,8 +176,7 @@ void OldToYoungRootsTask::do_it(GCTaskManager* manager, uint which) {
{
PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
- CardTableExtension* card_table =
- barrier_set_cast(ParallelScavengeHeap::heap()->barrier_set());
+ PSCardTable* card_table = ParallelScavengeHeap::heap()->card_table();
card_table->scavenge_contents_parallel(_old_gen->start_array(),
_old_gen->object_space(),
diff --git a/src/hotspot/share/gc/parallel/psTasks.hpp b/src/hotspot/share/gc/parallel/psTasks.hpp
index f527ead719c..02b5449bba9 100644
--- a/src/hotspot/share/gc/parallel/psTasks.hpp
+++ b/src/hotspot/share/gc/parallel/psTasks.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -148,7 +148,7 @@ class StealTask : public GCTask {
// will be covered. In this example if 4 tasks have been created to cover
// all the stripes and there are only 3 threads, one of the threads will
// get the tasks with the 4th stripe. However, there is a dependence in
-// CardTableExtension::scavenge_contents_parallel() on the number
+// PSCardTable::scavenge_contents_parallel() on the number
// of tasks created. In scavenge_contents_parallel the distance
// to the next stripe is calculated based on the number of tasks.
// If the stripe width is ssize, a task's next stripe is at
diff --git a/src/hotspot/share/gc/parallel/psYoungGen.cpp b/src/hotspot/share/gc/parallel/psYoungGen.cpp
index 02b328f9f0e..31ee1a290ec 100644
--- a/src/hotspot/share/gc/parallel/psYoungGen.cpp
+++ b/src/hotspot/share/gc/parallel/psYoungGen.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -64,7 +64,7 @@ void PSYoungGen::initialize_work() {
MemRegion cmr((HeapWord*)virtual_space()->low(),
(HeapWord*)virtual_space()->high());
- ParallelScavengeHeap::heap()->barrier_set()->resize_covered_region(cmr);
+ ParallelScavengeHeap::heap()->card_table()->resize_covered_region(cmr);
if (ZapUnusedHeapArea) {
// Mangle newly committed space immediately because it
@@ -870,7 +870,7 @@ void PSYoungGen::post_resize() {
MemRegion cmr((HeapWord*)virtual_space()->low(),
(HeapWord*)virtual_space()->high());
- ParallelScavengeHeap::heap()->barrier_set()->resize_covered_region(cmr);
+ ParallelScavengeHeap::heap()->card_table()->resize_covered_region(cmr);
space_invariants();
}
diff --git a/src/hotspot/share/gc/serial/defNewGeneration.cpp b/src/hotspot/share/gc/serial/defNewGeneration.cpp
index f6bf3437f3e..d16655a493b 100644
--- a/src/hotspot/share/gc/serial/defNewGeneration.cpp
+++ b/src/hotspot/share/gc/serial/defNewGeneration.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "gc/serial/defNewGeneration.inline.hpp"
+#include "gc/shared/adaptiveSizePolicy.hpp"
#include "gc/shared/ageTable.inline.hpp"
#include "gc/shared/cardTableRS.hpp"
#include "gc/shared/collectorCounters.hpp"
@@ -188,7 +189,7 @@ DefNewGeneration::DefNewGeneration(ReservedSpace rs,
(HeapWord*)_virtual_space.high());
GenCollectedHeap* gch = GenCollectedHeap::heap();
- gch->barrier_set()->resize_covered_region(cmr);
+ gch->rem_set()->resize_covered_region(cmr);
_eden_space = new ContiguousSpace();
_from_space = new ContiguousSpace();
@@ -453,7 +454,7 @@ void DefNewGeneration::compute_new_size() {
SpaceDecorator::DontMangle);
MemRegion cmr((HeapWord*)_virtual_space.low(),
(HeapWord*)_virtual_space.high());
- gch->barrier_set()->resize_covered_region(cmr);
+ gch->rem_set()->resize_covered_region(cmr);
log_debug(gc, ergo, heap)(
"New generation size " SIZE_FORMAT "K->" SIZE_FORMAT "K [eden=" SIZE_FORMAT "K,survivor=" SIZE_FORMAT "K]",
@@ -564,7 +565,7 @@ void DefNewGeneration::adjust_desired_tenuring_threshold() {
_tenuring_threshold = age_table()->compute_tenuring_threshold(desired_survivor_size);
if (UsePerfData) {
- GCPolicyCounters* gc_counters = GenCollectedHeap::heap()->gen_policy()->counters();
+ GCPolicyCounters* gc_counters = GenCollectedHeap::heap()->counters();
gc_counters->tenuring_threshold()->set_value(_tenuring_threshold);
gc_counters->desired_survivor_size()->set_value(desired_survivor_size * oopSize);
}
@@ -616,9 +617,6 @@ void DefNewGeneration::collect(bool full,
assert(gch->no_allocs_since_save_marks(),
"save marks have not been newly set.");
- // Not very pretty.
- CollectorPolicy* cp = gch->collector_policy();
-
FastScanClosure fsc_with_no_gc_barrier(this, false);
FastScanClosure fsc_with_gc_barrier(this, true);
@@ -636,7 +634,7 @@ void DefNewGeneration::collect(bool full,
{
// DefNew needs to run with n_threads == 0, to make sure the serial
// version of the card table scanning code is used.
- // See: CardTableModRefBSForCTRS::non_clean_card_iterate_possibly_parallel.
+ // See: CardTableRS::non_clean_card_iterate_possibly_parallel.
StrongRootsScope srs(0);
gch->young_process_roots(&srs,
@@ -688,7 +686,7 @@ void DefNewGeneration::collect(bool full,
// A successful scavenge should restart the GC time limit count which is
// for full GC's.
- AdaptiveSizePolicy* size_policy = gch->gen_policy()->size_policy();
+ AdaptiveSizePolicy* size_policy = gch->size_policy();
size_policy->reset_gc_overhead_limit_count();
assert(!gch->incremental_collection_failed(), "Should be clear");
} else {
@@ -953,7 +951,7 @@ void DefNewGeneration::gc_epilogue(bool full) {
// update the generation and space performance counters
update_counters();
- gch->gen_policy()->counters()->update_counters();
+ gch->counters()->update_counters();
}
void DefNewGeneration::record_spaces_top() {
diff --git a/src/hotspot/share/gc/serial/genMarkSweep.cpp b/src/hotspot/share/gc/serial/genMarkSweep.cpp
index 6f031f7bad4..2c006e9e481 100644
--- a/src/hotspot/share/gc/serial/genMarkSweep.cpp
+++ b/src/hotspot/share/gc/serial/genMarkSweep.cpp
@@ -60,7 +60,7 @@ void GenMarkSweep::invoke_at_safepoint(ReferenceProcessor* rp, bool clear_all_so
GenCollectedHeap* gch = GenCollectedHeap::heap();
#ifdef ASSERT
- if (gch->collector_policy()->should_clear_all_soft_refs()) {
+ if (gch->soft_ref_policy()->should_clear_all_soft_refs()) {
assert(clear_all_softrefs, "Policy should have been checked earlier");
}
#endif
diff --git a/src/hotspot/share/gc/serial/serialHeap.cpp b/src/hotspot/share/gc/serial/serialHeap.cpp
index c395e11fd27..9e413a063da 100644
--- a/src/hotspot/share/gc/serial/serialHeap.cpp
+++ b/src/hotspot/share/gc/serial/serialHeap.cpp
@@ -29,7 +29,13 @@
#include "services/memoryManager.hpp"
SerialHeap::SerialHeap(GenCollectorPolicy* policy) :
- GenCollectedHeap(policy), _eden_pool(NULL), _survivor_pool(NULL), _old_pool(NULL) {
+ GenCollectedHeap(policy,
+ Generation::DefNew,
+ Generation::MarkSweepCompact,
+ "Copy:MSC"),
+ _eden_pool(NULL),
+ _survivor_pool(NULL),
+ _old_pool(NULL) {
_young_manager = new GCMemoryManager("Copy", "end of minor GC");
_old_manager = new GCMemoryManager("MarkSweepCompact", "end of major GC");
}
diff --git a/src/hotspot/share/gc/shared/adaptiveSizePolicy.cpp b/src/hotspot/share/gc/shared/adaptiveSizePolicy.cpp
index 830835f19dc..00ac1e675cc 100644
--- a/src/hotspot/share/gc/shared/adaptiveSizePolicy.cpp
+++ b/src/hotspot/share/gc/shared/adaptiveSizePolicy.cpp
@@ -27,10 +27,12 @@
#include "gc/shared/collectorPolicy.hpp"
#include "gc/shared/gcCause.hpp"
#include "gc/shared/gcUtil.inline.hpp"
+#include "gc/shared/softRefPolicy.hpp"
#include "gc/shared/workgroup.hpp"
#include "logging/log.hpp"
#include "runtime/timer.hpp"
#include "utilities/ostream.hpp"
+
elapsedTimer AdaptiveSizePolicy::_minor_timer;
elapsedTimer AdaptiveSizePolicy::_major_timer;
bool AdaptiveSizePolicy::_debug_perturbation = false;
@@ -409,7 +411,7 @@ void AdaptiveSizePolicy::check_gc_overhead_limit(
size_t max_eden_size,
bool is_full_gc,
GCCause::Cause gc_cause,
- CollectorPolicy* collector_policy) {
+ SoftRefPolicy* soft_ref_policy) {
// Ignore explicit GC's. Exiting here does not set the flag and
// does not reset the count. Updating of the averages for system
@@ -506,7 +508,7 @@ void AdaptiveSizePolicy::check_gc_overhead_limit(
// The clearing will be done on the next GC.
bool near_limit = gc_overhead_limit_near();
if (near_limit) {
- collector_policy->set_should_clear_all_soft_refs(true);
+ soft_ref_policy->set_should_clear_all_soft_refs(true);
log_trace(gc, ergo)("Nearing GC overhead limit, will be clearing all SoftReference");
}
}
diff --git a/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp b/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp
index 2fd822ae8f9..f1680409475 100644
--- a/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp
+++ b/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp
@@ -37,7 +37,7 @@
// Forward decls
class elapsedTimer;
-class CollectorPolicy;
+class SoftRefPolicy;
class AdaptiveSizePolicy : public CHeapObj {
friend class GCAdaptivePolicyCounters;
@@ -486,7 +486,7 @@ class AdaptiveSizePolicy : public CHeapObj {
size_t max_eden_size,
bool is_full_gc,
GCCause::Cause gc_cause,
- CollectorPolicy* collector_policy);
+ SoftRefPolicy* soft_ref_policy);
static bool should_update_promo_stats(GCCause::Cause cause) {
return ((GCCause::is_user_requested_gc(cause) &&
diff --git a/src/hotspot/share/gc/shared/barrierSet.hpp b/src/hotspot/share/gc/shared/barrierSet.hpp
index 9c6c9dd7049..52cab8ab33f 100644
--- a/src/hotspot/share/gc/shared/barrierSet.hpp
+++ b/src/hotspot/share/gc/shared/barrierSet.hpp
@@ -115,22 +115,14 @@ public:
// is redone until it succeeds. This can e.g. prevent allocations from the slow path
// to be in old.
virtual void on_slowpath_allocation_exit(JavaThread* thread, oop new_obj) {}
- virtual void flush_deferred_barriers(JavaThread* thread) {}
+ virtual void on_thread_attach(JavaThread* thread) {}
+ virtual void on_thread_detach(JavaThread* thread) {}
virtual void make_parsable(JavaThread* thread) {}
protected:
virtual void write_ref_array_work(MemRegion mr) = 0;
public:
- // Inform the BarrierSet that the the covered heap region that starts
- // with "base" has been changed to have the given size (possibly from 0,
- // for initialization.)
- virtual void resize_covered_region(MemRegion new_region) = 0;
-
- // If the barrier set imposes any alignment restrictions on boundaries
- // within the heap, this function tells whether they are met.
- virtual bool is_aligned(HeapWord* addr) = 0;
-
// Print a description of the memory for the barrier set
virtual void print_on(outputStream* st) const = 0;
@@ -272,6 +264,10 @@ public:
static void clone_in_heap(oop src, oop dst, size_t size) {
Raw::clone(src, dst, size);
}
+
+ static oop resolve(oop obj) {
+ return Raw::resolve(obj);
+ }
};
};
diff --git a/src/hotspot/share/gc/shared/barrierSetConfig.hpp b/src/hotspot/share/gc/shared/barrierSetConfig.hpp
index 9acbcaac0e0..aa93f978e96 100644
--- a/src/hotspot/share/gc/shared/barrierSetConfig.hpp
+++ b/src/hotspot/share/gc/shared/barrierSetConfig.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,32 +29,46 @@
#if INCLUDE_ALL_GCS
#define FOR_EACH_CONCRETE_INCLUDE_ALL_GC_BARRIER_SET_DO(f) \
- f(CardTableExtension) \
f(G1SATBCTLogging)
#else
#define FOR_EACH_CONCRETE_INCLUDE_ALL_GC_BARRIER_SET_DO(f)
#endif
+#if INCLUDE_ALL_GCS
+#define FOR_EACH_ABSTRACT_INCLUDE_ALL_GC_BARRIER_SET_DO(f) \
+ f(G1SATBCT)
+#else
+#define FOR_EACH_ABSTRACT_INCLUDE_ALL_GC_BARRIER_SET_DO(f)
+#endif
+
// Do something for each concrete barrier set part of the build.
#define FOR_EACH_CONCRETE_BARRIER_SET_DO(f) \
- f(CardTableForRS) \
+ f(CardTableModRef) \
FOR_EACH_CONCRETE_INCLUDE_ALL_GC_BARRIER_SET_DO(f)
+#define FOR_EACH_ABSTRACT_BARRIER_SET_DO(f) \
+ f(ModRef) \
+ FOR_EACH_ABSTRACT_INCLUDE_ALL_GC_BARRIER_SET_DO(f)
+
// Do something for each known barrier set.
#define FOR_EACH_BARRIER_SET_DO(f) \
- f(ModRef) \
- f(CardTableModRef) \
- f(CardTableForRS) \
- f(CardTableExtension) \
- f(G1SATBCT) \
- f(G1SATBCTLogging)
+ FOR_EACH_ABSTRACT_BARRIER_SET_DO(f) \
+ FOR_EACH_CONCRETE_BARRIER_SET_DO(f)
// To enable runtime-resolution of GC barriers on primitives, please
// define SUPPORT_BARRIER_ON_PRIMITIVES.
#ifdef SUPPORT_BARRIER_ON_PRIMITIVES
-#define BT_BUILDTIME_DECORATORS INTERNAL_BT_BARRIER_ON_PRIMITIVES
+#define ACCESS_PRIMITIVE_SUPPORT INTERNAL_BT_BARRIER_ON_PRIMITIVES
#else
-#define BT_BUILDTIME_DECORATORS INTERNAL_EMPTY
+#define ACCESS_PRIMITIVE_SUPPORT INTERNAL_EMPTY
#endif
+#ifdef SUPPORT_NOT_TO_SPACE_INVARIANT
+#define ACCESS_TO_SPACE_INVARIANT_SUPPORT INTERNAL_EMPTY
+#else
+#define ACCESS_TO_SPACE_INVARIANT_SUPPORT INTERNAL_BT_TO_SPACE_INVARIANT
+#endif
+
+#define BT_BUILDTIME_DECORATORS (ACCESS_PRIMITIVE_SUPPORT | ACCESS_TO_SPACE_INVARIANT_SUPPORT)
+
#endif // SHARE_VM_GC_SHARED_BARRIERSETCONFIG_HPP
diff --git a/src/hotspot/share/gc/shared/barrierSetConfig.inline.hpp b/src/hotspot/share/gc/shared/barrierSetConfig.inline.hpp
index 369ce4f97f9..fd8ab09c8b1 100644
--- a/src/hotspot/share/gc/shared/barrierSetConfig.inline.hpp
+++ b/src/hotspot/share/gc/shared/barrierSetConfig.inline.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,10 +29,8 @@
#include "gc/shared/modRefBarrierSet.inline.hpp"
#include "gc/shared/cardTableModRefBS.inline.hpp"
-#include "gc/shared/cardTableModRefBSForCTRS.hpp"
#if INCLUDE_ALL_GCS
-#include "gc/parallel/cardTableExtension.hpp" // Parallel support
#include "gc/g1/g1SATBCardTableModRefBS.inline.hpp" // G1 support
#endif
diff --git a/src/hotspot/share/gc/shared/cardGeneration.cpp b/src/hotspot/share/gc/shared/cardGeneration.cpp
index 9acb3802d3c..026772adbb9 100644
--- a/src/hotspot/share/gc/shared/cardGeneration.cpp
+++ b/src/hotspot/share/gc/shared/cardGeneration.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -79,7 +79,7 @@ bool CardGeneration::grow_by(size_t bytes) {
heap_word_size(_virtual_space.committed_size());
MemRegion mr(space()->bottom(), new_word_size);
// Expand card table
- GenCollectedHeap::heap()->barrier_set()->resize_covered_region(mr);
+ GenCollectedHeap::heap()->rem_set()->resize_covered_region(mr);
// Expand shared block offset array
_bts->resize(new_word_size);
@@ -166,7 +166,7 @@ void CardGeneration::shrink(size_t bytes) {
_bts->resize(new_word_size);
MemRegion mr(space()->bottom(), new_word_size);
// Shrink the card table
- GenCollectedHeap::heap()->barrier_set()->resize_covered_region(mr);
+ GenCollectedHeap::heap()->rem_set()->resize_covered_region(mr);
size_t new_mem_size = _virtual_space.committed_size();
size_t old_mem_size = new_mem_size + size;
diff --git a/src/hotspot/share/gc/shared/cardTable.cpp b/src/hotspot/share/gc/shared/cardTable.cpp
new file mode 100644
index 00000000000..5a094e20738
--- /dev/null
+++ b/src/hotspot/share/gc/shared/cardTable.cpp
@@ -0,0 +1,512 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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/cardTable.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "gc/shared/space.inline.hpp"
+#include "logging/log.hpp"
+#include "memory/virtualspace.hpp"
+#include "runtime/java.hpp"
+#include "runtime/os.hpp"
+#include "services/memTracker.hpp"
+#include "utilities/align.hpp"
+
+size_t CardTable::compute_byte_map_size() {
+ assert(_guard_index == cards_required(_whole_heap.word_size()) - 1,
+ "uninitialized, check declaration order");
+ assert(_page_size != 0, "uninitialized, check declaration order");
+ const size_t granularity = os::vm_allocation_granularity();
+ return align_up(_guard_index + 1, MAX2(_page_size, granularity));
+}
+
+CardTable::CardTable(MemRegion whole_heap, bool conc_scan) :
+ _scanned_concurrently(conc_scan),
+ _whole_heap(whole_heap),
+ _guard_index(0),
+ _guard_region(),
+ _last_valid_index(0),
+ _page_size(os::vm_page_size()),
+ _byte_map_size(0),
+ _covered(NULL),
+ _committed(NULL),
+ _cur_covered_regions(0),
+ _byte_map(NULL),
+ _byte_map_base(NULL)
+{
+ assert((uintptr_t(_whole_heap.start()) & (card_size - 1)) == 0, "heap must start at card boundary");
+ assert((uintptr_t(_whole_heap.end()) & (card_size - 1)) == 0, "heap must end at card boundary");
+
+ assert(card_size <= 512, "card_size must be less than 512"); // why?
+
+ _covered = new MemRegion[_max_covered_regions];
+ if (_covered == NULL) {
+ vm_exit_during_initialization("Could not allocate card table covered region set.");
+ }
+}
+
+CardTable::~CardTable() {
+ if (_covered) {
+ delete[] _covered;
+ _covered = NULL;
+ }
+ if (_committed) {
+ delete[] _committed;
+ _committed = NULL;
+ }
+}
+
+void CardTable::initialize() {
+ _guard_index = cards_required(_whole_heap.word_size()) - 1;
+ _last_valid_index = _guard_index - 1;
+
+ _byte_map_size = compute_byte_map_size();
+
+ HeapWord* low_bound = _whole_heap.start();
+ HeapWord* high_bound = _whole_heap.end();
+
+ _cur_covered_regions = 0;
+ _committed = new MemRegion[_max_covered_regions];
+ if (_committed == NULL) {
+ vm_exit_during_initialization("Could not allocate card table committed region set.");
+ }
+
+ const size_t rs_align = _page_size == (size_t) os::vm_page_size() ? 0 :
+ MAX2(_page_size, (size_t) os::vm_allocation_granularity());
+ ReservedSpace heap_rs(_byte_map_size, rs_align, false);
+
+ MemTracker::record_virtual_memory_type((address)heap_rs.base(), mtGC);
+
+ os::trace_page_sizes("Card Table", _guard_index + 1, _guard_index + 1,
+ _page_size, heap_rs.base(), heap_rs.size());
+ if (!heap_rs.is_reserved()) {
+ vm_exit_during_initialization("Could not reserve enough space for the "
+ "card marking array");
+ }
+
+ // The assembler store_check code will do an unsigned shift of the oop,
+ // then add it to _byte_map_base, i.e.
+ //
+ // _byte_map = _byte_map_base + (uintptr_t(low_bound) >> card_shift)
+ _byte_map = (jbyte*) heap_rs.base();
+ _byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift);
+ assert(byte_for(low_bound) == &_byte_map[0], "Checking start of map");
+ assert(byte_for(high_bound-1) <= &_byte_map[_last_valid_index], "Checking end of map");
+
+ jbyte* guard_card = &_byte_map[_guard_index];
+ HeapWord* guard_page = align_down((HeapWord*)guard_card, _page_size);
+ _guard_region = MemRegion(guard_page, _page_size);
+ os::commit_memory_or_exit((char*)guard_page, _page_size, _page_size,
+ !ExecMem, "card table last card");
+ *guard_card = last_card;
+
+ log_trace(gc, barrier)("CardTable::CardTable: ");
+ log_trace(gc, barrier)(" &_byte_map[0]: " INTPTR_FORMAT " &_byte_map[_last_valid_index]: " INTPTR_FORMAT,
+ p2i(&_byte_map[0]), p2i(&_byte_map[_last_valid_index]));
+ log_trace(gc, barrier)(" _byte_map_base: " INTPTR_FORMAT, p2i(_byte_map_base));
+}
+
+int CardTable::find_covering_region_by_base(HeapWord* base) {
+ int i;
+ for (i = 0; i < _cur_covered_regions; i++) {
+ if (_covered[i].start() == base) return i;
+ if (_covered[i].start() > base) break;
+ }
+ // If we didn't find it, create a new one.
+ assert(_cur_covered_regions < _max_covered_regions,
+ "too many covered regions");
+ // Move the ones above up, to maintain sorted order.
+ for (int j = _cur_covered_regions; j > i; j--) {
+ _covered[j] = _covered[j-1];
+ _committed[j] = _committed[j-1];
+ }
+ int res = i;
+ _cur_covered_regions++;
+ _covered[res].set_start(base);
+ _covered[res].set_word_size(0);
+ jbyte* ct_start = byte_for(base);
+ HeapWord* ct_start_aligned = align_down((HeapWord*)ct_start, _page_size);
+ _committed[res].set_start(ct_start_aligned);
+ _committed[res].set_word_size(0);
+ return res;
+}
+
+int CardTable::find_covering_region_containing(HeapWord* addr) {
+ for (int i = 0; i < _cur_covered_regions; i++) {
+ if (_covered[i].contains(addr)) {
+ return i;
+ }
+ }
+ assert(0, "address outside of heap?");
+ return -1;
+}
+
+HeapWord* CardTable::largest_prev_committed_end(int ind) const {
+ HeapWord* max_end = NULL;
+ for (int j = 0; j < ind; j++) {
+ HeapWord* this_end = _committed[j].end();
+ if (this_end > max_end) max_end = this_end;
+ }
+ return max_end;
+}
+
+MemRegion CardTable::committed_unique_to_self(int self, MemRegion mr) const {
+ MemRegion result = mr;
+ for (int r = 0; r < _cur_covered_regions; r += 1) {
+ if (r != self) {
+ result = result.minus(_committed[r]);
+ }
+ }
+ // Never include the guard page.
+ result = result.minus(_guard_region);
+ return result;
+}
+
+void CardTable::resize_covered_region(MemRegion new_region) {
+ // We don't change the start of a region, only the end.
+ assert(_whole_heap.contains(new_region),
+ "attempt to cover area not in reserved area");
+ debug_only(verify_guard();)
+ // collided is true if the expansion would push into another committed region
+ debug_only(bool collided = false;)
+ int const ind = find_covering_region_by_base(new_region.start());
+ MemRegion const old_region = _covered[ind];
+ assert(old_region.start() == new_region.start(), "just checking");
+ if (new_region.word_size() != old_region.word_size()) {
+ // Commit new or uncommit old pages, if necessary.
+ MemRegion cur_committed = _committed[ind];
+ // Extend the end of this _committed region
+ // to cover the end of any lower _committed regions.
+ // This forms overlapping regions, but never interior regions.
+ HeapWord* const max_prev_end = largest_prev_committed_end(ind);
+ if (max_prev_end > cur_committed.end()) {
+ cur_committed.set_end(max_prev_end);
+ }
+ // Align the end up to a page size (starts are already aligned).
+ HeapWord* new_end = (HeapWord*) byte_after(new_region.last());
+ HeapWord* new_end_aligned = align_up(new_end, _page_size);
+ assert(new_end_aligned >= new_end, "align up, but less");
+ // Check the other regions (excludes "ind") to ensure that
+ // the new_end_aligned does not intrude onto the committed
+ // space of another region.
+ int ri = 0;
+ for (ri = ind + 1; ri < _cur_covered_regions; ri++) {
+ if (new_end_aligned > _committed[ri].start()) {
+ assert(new_end_aligned <= _committed[ri].end(),
+ "An earlier committed region can't cover a later committed region");
+ // Any region containing the new end
+ // should start at or beyond the region found (ind)
+ // for the new end (committed regions are not expected to
+ // be proper subsets of other committed regions).
+ assert(_committed[ri].start() >= _committed[ind].start(),
+ "New end of committed region is inconsistent");
+ new_end_aligned = _committed[ri].start();
+ // new_end_aligned can be equal to the start of its
+ // committed region (i.e., of "ind") if a second
+ // region following "ind" also start at the same location
+ // as "ind".
+ assert(new_end_aligned >= _committed[ind].start(),
+ "New end of committed region is before start");
+ debug_only(collided = true;)
+ // Should only collide with 1 region
+ break;
+ }
+ }
+#ifdef ASSERT
+ for (++ri; ri < _cur_covered_regions; ri++) {
+ assert(!_committed[ri].contains(new_end_aligned),
+ "New end of committed region is in a second committed region");
+ }
+#endif
+ // The guard page is always committed and should not be committed over.
+ // "guarded" is used for assertion checking below and recalls the fact
+ // that the would-be end of the new committed region would have
+ // penetrated the guard page.
+ HeapWord* new_end_for_commit = new_end_aligned;
+
+ DEBUG_ONLY(bool guarded = false;)
+ if (new_end_for_commit > _guard_region.start()) {
+ new_end_for_commit = _guard_region.start();
+ DEBUG_ONLY(guarded = true;)
+ }
+
+ if (new_end_for_commit > cur_committed.end()) {
+ // Must commit new pages.
+ MemRegion const new_committed =
+ MemRegion(cur_committed.end(), new_end_for_commit);
+
+ assert(!new_committed.is_empty(), "Region should not be empty here");
+ os::commit_memory_or_exit((char*)new_committed.start(),
+ new_committed.byte_size(), _page_size,
+ !ExecMem, "card table expansion");
+ // Use new_end_aligned (as opposed to new_end_for_commit) because
+ // the cur_committed region may include the guard region.
+ } else if (new_end_aligned < cur_committed.end()) {
+ // Must uncommit pages.
+ MemRegion const uncommit_region =
+ committed_unique_to_self(ind, MemRegion(new_end_aligned,
+ cur_committed.end()));
+ if (!uncommit_region.is_empty()) {
+ // It is not safe to uncommit cards if the boundary between
+ // the generations is moving. A shrink can uncommit cards
+ // owned by generation A but being used by generation B.
+ if (!UseAdaptiveGCBoundary) {
+ if (!os::uncommit_memory((char*)uncommit_region.start(),
+ uncommit_region.byte_size())) {
+ assert(false, "Card table contraction failed");
+ // The call failed so don't change the end of the
+ // committed region. This is better than taking the
+ // VM down.
+ new_end_aligned = _committed[ind].end();
+ }
+ } else {
+ new_end_aligned = _committed[ind].end();
+ }
+ }
+ }
+ // In any case, we can reset the end of the current committed entry.
+ _committed[ind].set_end(new_end_aligned);
+
+#ifdef ASSERT
+ // Check that the last card in the new region is committed according
+ // to the tables.
+ bool covered = false;
+ for (int cr = 0; cr < _cur_covered_regions; cr++) {
+ if (_committed[cr].contains(new_end - 1)) {
+ covered = true;
+ break;
+ }
+ }
+ assert(covered, "Card for end of new region not committed");
+#endif
+
+ // The default of 0 is not necessarily clean cards.
+ jbyte* entry;
+ if (old_region.last() < _whole_heap.start()) {
+ entry = byte_for(_whole_heap.start());
+ } else {
+ entry = byte_after(old_region.last());
+ }
+ assert(index_for(new_region.last()) < _guard_index,
+ "The guard card will be overwritten");
+ // This line commented out cleans the newly expanded region and
+ // not the aligned up expanded region.
+ // jbyte* const end = byte_after(new_region.last());
+ jbyte* const end = (jbyte*) new_end_for_commit;
+ assert((end >= byte_after(new_region.last())) || collided || guarded,
+ "Expect to be beyond new region unless impacting another region");
+ // do nothing if we resized downward.
+#ifdef ASSERT
+ for (int ri = 0; ri < _cur_covered_regions; ri++) {
+ if (ri != ind) {
+ // The end of the new committed region should not
+ // be in any existing region unless it matches
+ // the start of the next region.
+ assert(!_committed[ri].contains(end) ||
+ (_committed[ri].start() == (HeapWord*) end),
+ "Overlapping committed regions");
+ }
+ }
+#endif
+ if (entry < end) {
+ memset(entry, clean_card, pointer_delta(end, entry, sizeof(jbyte)));
+ }
+ }
+ // In any case, the covered size changes.
+ _covered[ind].set_word_size(new_region.word_size());
+
+ log_trace(gc, barrier)("CardTable::resize_covered_region: ");
+ log_trace(gc, barrier)(" _covered[%d].start(): " INTPTR_FORMAT " _covered[%d].last(): " INTPTR_FORMAT,
+ ind, p2i(_covered[ind].start()), ind, p2i(_covered[ind].last()));
+ log_trace(gc, barrier)(" _committed[%d].start(): " INTPTR_FORMAT " _committed[%d].last(): " INTPTR_FORMAT,
+ ind, p2i(_committed[ind].start()), ind, p2i(_committed[ind].last()));
+ log_trace(gc, barrier)(" byte_for(start): " INTPTR_FORMAT " byte_for(last): " INTPTR_FORMAT,
+ p2i(byte_for(_covered[ind].start())), p2i(byte_for(_covered[ind].last())));
+ log_trace(gc, barrier)(" addr_for(start): " INTPTR_FORMAT " addr_for(last): " INTPTR_FORMAT,
+ p2i(addr_for((jbyte*) _committed[ind].start())), p2i(addr_for((jbyte*) _committed[ind].last())));
+
+ // Touch the last card of the covered region to show that it
+ // is committed (or SEGV).
+ debug_only((void) (*byte_for(_covered[ind].last()));)
+ debug_only(verify_guard();)
+}
+
+// Note that these versions are precise! The scanning code has to handle the
+// fact that the write barrier may be either precise or imprecise.
+void CardTable::dirty_MemRegion(MemRegion mr) {
+ assert(align_down(mr.start(), HeapWordSize) == mr.start(), "Unaligned start");
+ assert(align_up (mr.end(), HeapWordSize) == mr.end(), "Unaligned end" );
+ jbyte* cur = byte_for(mr.start());
+ jbyte* last = byte_after(mr.last());
+ while (cur < last) {
+ *cur = dirty_card;
+ cur++;
+ }
+}
+
+void CardTable::clear_MemRegion(MemRegion mr) {
+ // Be conservative: only clean cards entirely contained within the
+ // region.
+ jbyte* cur;
+ if (mr.start() == _whole_heap.start()) {
+ cur = byte_for(mr.start());
+ } else {
+ assert(mr.start() > _whole_heap.start(), "mr is not covered.");
+ cur = byte_after(mr.start() - 1);
+ }
+ jbyte* last = byte_after(mr.last());
+ memset(cur, clean_card, pointer_delta(last, cur, sizeof(jbyte)));
+}
+
+void CardTable::clear(MemRegion mr) {
+ for (int i = 0; i < _cur_covered_regions; i++) {
+ MemRegion mri = mr.intersection(_covered[i]);
+ if (!mri.is_empty()) clear_MemRegion(mri);
+ }
+}
+
+void CardTable::dirty(MemRegion mr) {
+ jbyte* first = byte_for(mr.start());
+ jbyte* last = byte_after(mr.last());
+ memset(first, dirty_card, last-first);
+}
+
+// Unlike several other card table methods, dirty_card_iterate()
+// iterates over dirty cards ranges in increasing address order.
+void CardTable::dirty_card_iterate(MemRegion mr, MemRegionClosure* cl) {
+ for (int i = 0; i < _cur_covered_regions; i++) {
+ MemRegion mri = mr.intersection(_covered[i]);
+ if (!mri.is_empty()) {
+ jbyte *cur_entry, *next_entry, *limit;
+ for (cur_entry = byte_for(mri.start()), limit = byte_for(mri.last());
+ cur_entry <= limit;
+ cur_entry = next_entry) {
+ next_entry = cur_entry + 1;
+ if (*cur_entry == dirty_card) {
+ size_t dirty_cards;
+ // Accumulate maximal dirty card range, starting at cur_entry
+ for (dirty_cards = 1;
+ next_entry <= limit && *next_entry == dirty_card;
+ dirty_cards++, next_entry++);
+ MemRegion cur_cards(addr_for(cur_entry),
+ dirty_cards*card_size_in_words);
+ cl->do_MemRegion(cur_cards);
+ }
+ }
+ }
+ }
+}
+
+MemRegion CardTable::dirty_card_range_after_reset(MemRegion mr,
+ bool reset,
+ int reset_val) {
+ for (int i = 0; i < _cur_covered_regions; i++) {
+ MemRegion mri = mr.intersection(_covered[i]);
+ if (!mri.is_empty()) {
+ jbyte* cur_entry, *next_entry, *limit;
+ for (cur_entry = byte_for(mri.start()), limit = byte_for(mri.last());
+ cur_entry <= limit;
+ cur_entry = next_entry) {
+ next_entry = cur_entry + 1;
+ if (*cur_entry == dirty_card) {
+ size_t dirty_cards;
+ // Accumulate maximal dirty card range, starting at cur_entry
+ for (dirty_cards = 1;
+ next_entry <= limit && *next_entry == dirty_card;
+ dirty_cards++, next_entry++);
+ MemRegion cur_cards(addr_for(cur_entry),
+ dirty_cards*card_size_in_words);
+ if (reset) {
+ for (size_t i = 0; i < dirty_cards; i++) {
+ cur_entry[i] = reset_val;
+ }
+ }
+ return cur_cards;
+ }
+ }
+ }
+ }
+ return MemRegion(mr.end(), mr.end());
+}
+
+uintx CardTable::ct_max_alignment_constraint() {
+ return card_size * os::vm_page_size();
+}
+
+void CardTable::verify_guard() {
+ // For product build verification
+ guarantee(_byte_map[_guard_index] == last_card,
+ "card table guard has been modified");
+}
+
+void CardTable::invalidate(MemRegion mr) {
+ assert(align_down(mr.start(), HeapWordSize) == mr.start(), "Unaligned start");
+ assert(align_up (mr.end(), HeapWordSize) == mr.end(), "Unaligned end" );
+ for (int i = 0; i < _cur_covered_regions; i++) {
+ MemRegion mri = mr.intersection(_covered[i]);
+ if (!mri.is_empty()) dirty_MemRegion(mri);
+ }
+}
+
+void CardTable::verify() {
+ verify_guard();
+}
+
+#ifndef PRODUCT
+void CardTable::verify_region(MemRegion mr,
+ jbyte val, bool val_equals) {
+ jbyte* start = byte_for(mr.start());
+ jbyte* end = byte_for(mr.last());
+ bool failures = false;
+ for (jbyte* curr = start; curr <= end; ++curr) {
+ jbyte curr_val = *curr;
+ bool failed = (val_equals) ? (curr_val != val) : (curr_val == val);
+ if (failed) {
+ if (!failures) {
+ log_error(gc, verify)("== CT verification failed: [" INTPTR_FORMAT "," INTPTR_FORMAT "]", p2i(start), p2i(end));
+ log_error(gc, verify)("== %sexpecting value: %d", (val_equals) ? "" : "not ", val);
+ failures = true;
+ }
+ log_error(gc, verify)("== card " PTR_FORMAT " [" PTR_FORMAT "," PTR_FORMAT "], val: %d",
+ p2i(curr), p2i(addr_for(curr)),
+ p2i((HeapWord*) (((size_t) addr_for(curr)) + card_size)),
+ (int) curr_val);
+ }
+ }
+ guarantee(!failures, "there should not have been any failures");
+}
+
+void CardTable::verify_not_dirty_region(MemRegion mr) {
+ verify_region(mr, dirty_card, false /* val_equals */);
+}
+
+void CardTable::verify_dirty_region(MemRegion mr) {
+ verify_region(mr, dirty_card, true /* val_equals */);
+}
+#endif
+
+void CardTable::print_on(outputStream* st) const {
+ st->print_cr("Card table byte_map: [" INTPTR_FORMAT "," INTPTR_FORMAT "] _byte_map_base: " INTPTR_FORMAT,
+ p2i(_byte_map), p2i(_byte_map + _byte_map_size), p2i(_byte_map_base));
+}
diff --git a/src/hotspot/share/gc/shared/cardTable.hpp b/src/hotspot/share/gc/shared/cardTable.hpp
new file mode 100644
index 00000000000..2758213d1b5
--- /dev/null
+++ b/src/hotspot/share/gc/shared/cardTable.hpp
@@ -0,0 +1,266 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_SHARED_CARDTABLE_HPP
+#define SHARE_VM_GC_SHARED_CARDTABLE_HPP
+
+#include "memory/allocation.hpp"
+#include "memory/memRegion.hpp"
+#include "oops/oopsHierarchy.hpp"
+#include "utilities/align.hpp"
+
+class CardTable: public CHeapObj {
+ friend class VMStructs;
+protected:
+ // The declaration order of these const fields is important; see the
+ // constructor before changing.
+ const bool _scanned_concurrently;
+ const MemRegion _whole_heap; // the region covered by the card table
+ size_t _guard_index; // index of very last element in the card
+ // table; it is set to a guard value
+ // (last_card) and should never be modified
+ size_t _last_valid_index; // index of the last valid element
+ const size_t _page_size; // page size used when mapping _byte_map
+ size_t _byte_map_size; // in bytes
+ jbyte* _byte_map; // the card marking array
+ jbyte* _byte_map_base;
+
+ int _cur_covered_regions;
+
+ // The covered regions should be in address order.
+ MemRegion* _covered;
+ // The committed regions correspond one-to-one to the covered regions.
+ // They represent the card-table memory that has been committed to service
+ // the corresponding covered region. It may be that committed region for
+ // one covered region corresponds to a larger region because of page-size
+ // roundings. Thus, a committed region for one covered region may
+ // actually extend onto the card-table space for the next covered region.
+ MemRegion* _committed;
+
+ // The last card is a guard card, and we commit the page for it so
+ // we can use the card for verification purposes. We make sure we never
+ // uncommit the MemRegion for that page.
+ MemRegion _guard_region;
+
+ inline size_t compute_byte_map_size();
+
+ // Finds and return the index of the region, if any, to which the given
+ // region would be contiguous. If none exists, assign a new region and
+ // returns its index. Requires that no more than the maximum number of
+ // covered regions defined in the constructor are ever in use.
+ int find_covering_region_by_base(HeapWord* base);
+
+ // Same as above, but finds the region containing the given address
+ // instead of starting at a given base address.
+ int find_covering_region_containing(HeapWord* addr);
+
+ // Returns the leftmost end of a committed region corresponding to a
+ // covered region before covered region "ind", or else "NULL" if "ind" is
+ // the first covered region.
+ HeapWord* largest_prev_committed_end(int ind) const;
+
+ // Returns the part of the region mr that doesn't intersect with
+ // any committed region other than self. Used to prevent uncommitting
+ // regions that are also committed by other regions. Also protects
+ // against uncommitting the guard region.
+ MemRegion committed_unique_to_self(int self, MemRegion mr) const;
+
+ // Some barrier sets create tables whose elements correspond to parts of
+ // the heap; the CardTableModRefBS is an example. Such barrier sets will
+ // normally reserve space for such tables, and commit parts of the table
+ // "covering" parts of the heap that are committed. At most one covered
+ // region per generation is needed.
+ static const int _max_covered_regions = 2;
+
+ enum CardValues {
+ clean_card = -1,
+ // The mask contains zeros in places for all other values.
+ clean_card_mask = clean_card - 31,
+
+ dirty_card = 0,
+ precleaned_card = 1,
+ claimed_card = 2,
+ deferred_card = 4,
+ last_card = 8,
+ CT_MR_BS_last_reserved = 16
+ };
+
+ // a word's worth (row) of clean card values
+ static const intptr_t clean_card_row = (intptr_t)(-1);
+
+public:
+ CardTable(MemRegion whole_heap, bool conc_scan);
+ virtual ~CardTable();
+ virtual void initialize();
+
+ // The kinds of precision a CardTableModRefBS may offer.
+ enum PrecisionStyle {
+ Precise,
+ ObjHeadPreciseArray
+ };
+
+ // Tells what style of precision this card table offers.
+ PrecisionStyle precision() {
+ return ObjHeadPreciseArray; // Only one supported for now.
+ }
+
+ // *** Barrier set functions.
+
+ // Initialization utilities; covered_words is the size of the covered region
+ // in, um, words.
+ inline size_t cards_required(size_t covered_words) {
+ // Add one for a guard card, used to detect errors.
+ const size_t words = align_up(covered_words, card_size_in_words);
+ return words / card_size_in_words + 1;
+ }
+
+ // Dirty the bytes corresponding to "mr" (not all of which must be
+ // covered.)
+ void dirty_MemRegion(MemRegion mr);
+
+ // Clear (to clean_card) the bytes entirely contained within "mr" (not
+ // all of which must be covered.)
+ void clear_MemRegion(MemRegion mr);
+
+ // Return true if "p" is at the start of a card.
+ bool is_card_aligned(HeapWord* p) {
+ jbyte* pcard = byte_for(p);
+ return (addr_for(pcard) == p);
+ }
+
+ // Mapping from address to card marking array entry
+ jbyte* byte_for(const void* p) const {
+ assert(_whole_heap.contains(p),
+ "Attempt to access p = " PTR_FORMAT " out of bounds of "
+ " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")",
+ p2i(p), p2i(_whole_heap.start()), p2i(_whole_heap.end()));
+ jbyte* result = &_byte_map_base[uintptr_t(p) >> card_shift];
+ assert(result >= _byte_map && result < _byte_map + _byte_map_size,
+ "out of bounds accessor for card marking array");
+ return result;
+ }
+
+ // The card table byte one after the card marking array
+ // entry for argument address. Typically used for higher bounds
+ // for loops iterating through the card table.
+ jbyte* byte_after(const void* p) const {
+ return byte_for(p) + 1;
+ }
+
+ virtual void invalidate(MemRegion mr);
+ void clear(MemRegion mr);
+ void dirty(MemRegion mr);
+
+ // Provide read-only access to the card table array.
+ const jbyte* byte_for_const(const void* p) const {
+ return byte_for(p);
+ }
+ const jbyte* byte_after_const(const void* p) const {
+ return byte_after(p);
+ }
+
+ // Mapping from card marking array entry to address of first word
+ HeapWord* addr_for(const jbyte* p) const {
+ assert(p >= _byte_map && p < _byte_map + _byte_map_size,
+ "out of bounds access to card marking array. p: " PTR_FORMAT
+ " _byte_map: " PTR_FORMAT " _byte_map + _byte_map_size: " PTR_FORMAT,
+ p2i(p), p2i(_byte_map), p2i(_byte_map + _byte_map_size));
+ size_t delta = pointer_delta(p, _byte_map_base, sizeof(jbyte));
+ HeapWord* result = (HeapWord*) (delta << card_shift);
+ assert(_whole_heap.contains(result),
+ "Returning result = " PTR_FORMAT " out of bounds of "
+ " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")",
+ p2i(result), p2i(_whole_heap.start()), p2i(_whole_heap.end()));
+ return result;
+ }
+
+ // Mapping from address to card marking array index.
+ size_t index_for(void* p) {
+ assert(_whole_heap.contains(p),
+ "Attempt to access p = " PTR_FORMAT " out of bounds of "
+ " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")",
+ p2i(p), p2i(_whole_heap.start()), p2i(_whole_heap.end()));
+ return byte_for(p) - _byte_map;
+ }
+
+ const jbyte* byte_for_index(const size_t card_index) const {
+ return _byte_map + card_index;
+ }
+
+ // Resize one of the regions covered by the remembered set.
+ virtual void resize_covered_region(MemRegion new_region);
+
+ // *** Card-table-RemSet-specific things.
+
+ static uintx ct_max_alignment_constraint();
+
+ // Apply closure "cl" to the dirty cards containing some part of
+ // MemRegion "mr".
+ void dirty_card_iterate(MemRegion mr, MemRegionClosure* cl);
+
+ // Return the MemRegion corresponding to the first maximal run
+ // of dirty cards lying completely within MemRegion mr.
+ // If reset is "true", then sets those card table entries to the given
+ // value.
+ MemRegion dirty_card_range_after_reset(MemRegion mr, bool reset,
+ int reset_val);
+
+ // Constants
+ enum SomePublicConstants {
+ card_shift = 9,
+ card_size = 1 << card_shift,
+ card_size_in_words = card_size / sizeof(HeapWord)
+ };
+
+ static jbyte clean_card_val() { return clean_card; }
+ static jbyte clean_card_mask_val() { return clean_card_mask; }
+ static jbyte dirty_card_val() { return dirty_card; }
+ static jbyte claimed_card_val() { return claimed_card; }
+ static jbyte precleaned_card_val() { return precleaned_card; }
+ static jbyte deferred_card_val() { return deferred_card; }
+ static intptr_t clean_card_row_val() { return clean_card_row; }
+
+ // Card marking array base (adjusted for heap low boundary)
+ // This would be the 0th element of _byte_map, if the heap started at 0x0.
+ // But since the heap starts at some higher address, this points to somewhere
+ // before the beginning of the actual _byte_map.
+ jbyte* byte_map_base() const { return _byte_map_base; }
+ bool scanned_concurrently() const { return _scanned_concurrently; }
+
+ virtual bool is_in_young(oop obj) const = 0;
+
+ // Print a description of the memory for the card table
+ virtual void print_on(outputStream* st) const;
+
+ void verify();
+ void verify_guard();
+
+ // val_equals -> it will check that all cards covered by mr equal val
+ // !val_equals -> it will check that all cards covered by mr do not equal val
+ void verify_region(MemRegion mr, jbyte val, bool val_equals) PRODUCT_RETURN;
+ void verify_not_dirty_region(MemRegion mr) PRODUCT_RETURN;
+ void verify_dirty_region(MemRegion mr) PRODUCT_RETURN;
+};
+
+#endif // SHARE_VM_GC_SHARED_CARDTABLE_HPP
diff --git a/src/hotspot/share/gc/shared/cardTableModRefBS.cpp b/src/hotspot/share/gc/shared/cardTableModRefBS.cpp
index ddaceae30f8..80e681b0868 100644
--- a/src/hotspot/share/gc/shared/cardTableModRefBS.cpp
+++ b/src/hotspot/share/gc/shared/cardTableModRefBS.cpp
@@ -39,490 +39,38 @@
// enumerate ref fields that have been modified (since the last
// enumeration.)
-size_t CardTableModRefBS::compute_byte_map_size()
-{
- assert(_guard_index == cards_required(_whole_heap.word_size()) - 1,
- "uninitialized, check declaration order");
- assert(_page_size != 0, "uninitialized, check declaration order");
- const size_t granularity = os::vm_allocation_granularity();
- return align_up(_guard_index + 1, MAX2(_page_size, granularity));
-}
-
CardTableModRefBS::CardTableModRefBS(
- MemRegion whole_heap,
+ CardTable* card_table,
const BarrierSet::FakeRtti& fake_rtti) :
ModRefBarrierSet(fake_rtti.add_tag(BarrierSet::CardTableModRef)),
- _whole_heap(whole_heap),
- _guard_index(0),
- _guard_region(),
- _last_valid_index(0),
- _page_size(os::vm_page_size()),
- _byte_map_size(0),
- _covered(NULL),
- _committed(NULL),
- _cur_covered_regions(0),
- _byte_map(NULL),
- byte_map_base(NULL),
- _defer_initial_card_mark(false)
-{
- assert((uintptr_t(_whole_heap.start()) & (card_size - 1)) == 0, "heap must start at card boundary");
- assert((uintptr_t(_whole_heap.end()) & (card_size - 1)) == 0, "heap must end at card boundary");
+ _defer_initial_card_mark(false),
+ _card_table(card_table)
+{}
- assert(card_size <= 512, "card_size must be less than 512"); // why?
-
- _covered = new MemRegion[_max_covered_regions];
- if (_covered == NULL) {
- vm_exit_during_initialization("Could not allocate card table covered region set.");
- }
-}
+CardTableModRefBS::CardTableModRefBS(CardTable* card_table) :
+ ModRefBarrierSet(BarrierSet::FakeRtti(BarrierSet::CardTableModRef)),
+ _defer_initial_card_mark(false),
+ _card_table(card_table)
+{}
void CardTableModRefBS::initialize() {
initialize_deferred_card_mark_barriers();
- _guard_index = cards_required(_whole_heap.word_size()) - 1;
- _last_valid_index = _guard_index - 1;
-
- _byte_map_size = compute_byte_map_size();
-
- HeapWord* low_bound = _whole_heap.start();
- HeapWord* high_bound = _whole_heap.end();
-
- _cur_covered_regions = 0;
- _committed = new MemRegion[_max_covered_regions];
- if (_committed == NULL) {
- vm_exit_during_initialization("Could not allocate card table committed region set.");
- }
-
- const size_t rs_align = _page_size == (size_t) os::vm_page_size() ? 0 :
- MAX2(_page_size, (size_t) os::vm_allocation_granularity());
- ReservedSpace heap_rs(_byte_map_size, rs_align, false);
-
- MemTracker::record_virtual_memory_type((address)heap_rs.base(), mtGC);
-
- os::trace_page_sizes("Card Table", _guard_index + 1, _guard_index + 1,
- _page_size, heap_rs.base(), heap_rs.size());
- if (!heap_rs.is_reserved()) {
- vm_exit_during_initialization("Could not reserve enough space for the "
- "card marking array");
- }
-
- // The assembler store_check code will do an unsigned shift of the oop,
- // then add it to byte_map_base, i.e.
- //
- // _byte_map = byte_map_base + (uintptr_t(low_bound) >> card_shift)
- _byte_map = (jbyte*) heap_rs.base();
- byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift);
- assert(byte_for(low_bound) == &_byte_map[0], "Checking start of map");
- assert(byte_for(high_bound-1) <= &_byte_map[_last_valid_index], "Checking end of map");
-
- jbyte* guard_card = &_byte_map[_guard_index];
- uintptr_t guard_page = align_down((uintptr_t)guard_card, _page_size);
- _guard_region = MemRegion((HeapWord*)guard_page, _page_size);
- os::commit_memory_or_exit((char*)guard_page, _page_size, _page_size,
- !ExecMem, "card table last card");
- *guard_card = last_card;
-
- log_trace(gc, barrier)("CardTableModRefBS::CardTableModRefBS: ");
- log_trace(gc, barrier)(" &_byte_map[0]: " INTPTR_FORMAT " &_byte_map[_last_valid_index]: " INTPTR_FORMAT,
- p2i(&_byte_map[0]), p2i(&_byte_map[_last_valid_index]));
- log_trace(gc, barrier)(" byte_map_base: " INTPTR_FORMAT, p2i(byte_map_base));
}
CardTableModRefBS::~CardTableModRefBS() {
- if (_covered) {
- delete[] _covered;
- _covered = NULL;
- }
- if (_committed) {
- delete[] _committed;
- _committed = NULL;
- }
+ delete _card_table;
}
-int CardTableModRefBS::find_covering_region_by_base(HeapWord* base) {
- int i;
- for (i = 0; i < _cur_covered_regions; i++) {
- if (_covered[i].start() == base) return i;
- if (_covered[i].start() > base) break;
- }
- // If we didn't find it, create a new one.
- assert(_cur_covered_regions < _max_covered_regions,
- "too many covered regions");
- // Move the ones above up, to maintain sorted order.
- for (int j = _cur_covered_regions; j > i; j--) {
- _covered[j] = _covered[j-1];
- _committed[j] = _committed[j-1];
- }
- int res = i;
- _cur_covered_regions++;
- _covered[res].set_start(base);
- _covered[res].set_word_size(0);
- jbyte* ct_start = byte_for(base);
- uintptr_t ct_start_aligned = align_down((uintptr_t)ct_start, _page_size);
- _committed[res].set_start((HeapWord*)ct_start_aligned);
- _committed[res].set_word_size(0);
- return res;
-}
-
-int CardTableModRefBS::find_covering_region_containing(HeapWord* addr) {
- for (int i = 0; i < _cur_covered_regions; i++) {
- if (_covered[i].contains(addr)) {
- return i;
- }
- }
- assert(0, "address outside of heap?");
- return -1;
-}
-
-HeapWord* CardTableModRefBS::largest_prev_committed_end(int ind) const {
- HeapWord* max_end = NULL;
- for (int j = 0; j < ind; j++) {
- HeapWord* this_end = _committed[j].end();
- if (this_end > max_end) max_end = this_end;
- }
- return max_end;
-}
-
-MemRegion CardTableModRefBS::committed_unique_to_self(int self,
- MemRegion mr) const {
- MemRegion result = mr;
- for (int r = 0; r < _cur_covered_regions; r += 1) {
- if (r != self) {
- result = result.minus(_committed[r]);
- }
- }
- // Never include the guard page.
- result = result.minus(_guard_region);
- return result;
-}
-
-void CardTableModRefBS::resize_covered_region(MemRegion new_region) {
- // We don't change the start of a region, only the end.
- assert(_whole_heap.contains(new_region),
- "attempt to cover area not in reserved area");
- debug_only(verify_guard();)
- // collided is true if the expansion would push into another committed region
- debug_only(bool collided = false;)
- int const ind = find_covering_region_by_base(new_region.start());
- MemRegion const old_region = _covered[ind];
- assert(old_region.start() == new_region.start(), "just checking");
- if (new_region.word_size() != old_region.word_size()) {
- // Commit new or uncommit old pages, if necessary.
- MemRegion cur_committed = _committed[ind];
- // Extend the end of this _committed region
- // to cover the end of any lower _committed regions.
- // This forms overlapping regions, but never interior regions.
- HeapWord* const max_prev_end = largest_prev_committed_end(ind);
- if (max_prev_end > cur_committed.end()) {
- cur_committed.set_end(max_prev_end);
- }
- // Align the end up to a page size (starts are already aligned).
- jbyte* const new_end = byte_after(new_region.last());
- HeapWord* new_end_aligned = (HeapWord*) align_up(new_end, _page_size);
- assert((void*)new_end_aligned >= (void*) new_end, "align up, but less");
- // Check the other regions (excludes "ind") to ensure that
- // the new_end_aligned does not intrude onto the committed
- // space of another region.
- int ri = 0;
- for (ri = ind + 1; ri < _cur_covered_regions; ri++) {
- if (new_end_aligned > _committed[ri].start()) {
- assert(new_end_aligned <= _committed[ri].end(),
- "An earlier committed region can't cover a later committed region");
- // Any region containing the new end
- // should start at or beyond the region found (ind)
- // for the new end (committed regions are not expected to
- // be proper subsets of other committed regions).
- assert(_committed[ri].start() >= _committed[ind].start(),
- "New end of committed region is inconsistent");
- new_end_aligned = _committed[ri].start();
- // new_end_aligned can be equal to the start of its
- // committed region (i.e., of "ind") if a second
- // region following "ind" also start at the same location
- // as "ind".
- assert(new_end_aligned >= _committed[ind].start(),
- "New end of committed region is before start");
- debug_only(collided = true;)
- // Should only collide with 1 region
- break;
- }
- }
-#ifdef ASSERT
- for (++ri; ri < _cur_covered_regions; ri++) {
- assert(!_committed[ri].contains(new_end_aligned),
- "New end of committed region is in a second committed region");
- }
-#endif
- // The guard page is always committed and should not be committed over.
- // "guarded" is used for assertion checking below and recalls the fact
- // that the would-be end of the new committed region would have
- // penetrated the guard page.
- HeapWord* new_end_for_commit = new_end_aligned;
-
- DEBUG_ONLY(bool guarded = false;)
- if (new_end_for_commit > _guard_region.start()) {
- new_end_for_commit = _guard_region.start();
- DEBUG_ONLY(guarded = true;)
- }
-
- if (new_end_for_commit > cur_committed.end()) {
- // Must commit new pages.
- MemRegion const new_committed =
- MemRegion(cur_committed.end(), new_end_for_commit);
-
- assert(!new_committed.is_empty(), "Region should not be empty here");
- os::commit_memory_or_exit((char*)new_committed.start(),
- new_committed.byte_size(), _page_size,
- !ExecMem, "card table expansion");
- // Use new_end_aligned (as opposed to new_end_for_commit) because
- // the cur_committed region may include the guard region.
- } else if (new_end_aligned < cur_committed.end()) {
- // Must uncommit pages.
- MemRegion const uncommit_region =
- committed_unique_to_self(ind, MemRegion(new_end_aligned,
- cur_committed.end()));
- if (!uncommit_region.is_empty()) {
- // It is not safe to uncommit cards if the boundary between
- // the generations is moving. A shrink can uncommit cards
- // owned by generation A but being used by generation B.
- if (!UseAdaptiveGCBoundary) {
- if (!os::uncommit_memory((char*)uncommit_region.start(),
- uncommit_region.byte_size())) {
- assert(false, "Card table contraction failed");
- // The call failed so don't change the end of the
- // committed region. This is better than taking the
- // VM down.
- new_end_aligned = _committed[ind].end();
- }
- } else {
- new_end_aligned = _committed[ind].end();
- }
- }
- }
- // In any case, we can reset the end of the current committed entry.
- _committed[ind].set_end(new_end_aligned);
-
-#ifdef ASSERT
- // Check that the last card in the new region is committed according
- // to the tables.
- bool covered = false;
- for (int cr = 0; cr < _cur_covered_regions; cr++) {
- if (_committed[cr].contains(new_end - 1)) {
- covered = true;
- break;
- }
- }
- assert(covered, "Card for end of new region not committed");
-#endif
-
- // The default of 0 is not necessarily clean cards.
- jbyte* entry;
- if (old_region.last() < _whole_heap.start()) {
- entry = byte_for(_whole_heap.start());
- } else {
- entry = byte_after(old_region.last());
- }
- assert(index_for(new_region.last()) < _guard_index,
- "The guard card will be overwritten");
- // This line commented out cleans the newly expanded region and
- // not the aligned up expanded region.
- // jbyte* const end = byte_after(new_region.last());
- jbyte* const end = (jbyte*) new_end_for_commit;
- assert((end >= byte_after(new_region.last())) || collided || guarded,
- "Expect to be beyond new region unless impacting another region");
- // do nothing if we resized downward.
-#ifdef ASSERT
- for (int ri = 0; ri < _cur_covered_regions; ri++) {
- if (ri != ind) {
- // The end of the new committed region should not
- // be in any existing region unless it matches
- // the start of the next region.
- assert(!_committed[ri].contains(end) ||
- (_committed[ri].start() == (HeapWord*) end),
- "Overlapping committed regions");
- }
- }
-#endif
- if (entry < end) {
- memset(entry, clean_card, pointer_delta(end, entry, sizeof(jbyte)));
- }
- }
- // In any case, the covered size changes.
- _covered[ind].set_word_size(new_region.word_size());
-
- log_trace(gc, barrier)("CardTableModRefBS::resize_covered_region: ");
- log_trace(gc, barrier)(" _covered[%d].start(): " INTPTR_FORMAT " _covered[%d].last(): " INTPTR_FORMAT,
- ind, p2i(_covered[ind].start()), ind, p2i(_covered[ind].last()));
- log_trace(gc, barrier)(" _committed[%d].start(): " INTPTR_FORMAT " _committed[%d].last(): " INTPTR_FORMAT,
- ind, p2i(_committed[ind].start()), ind, p2i(_committed[ind].last()));
- log_trace(gc, barrier)(" byte_for(start): " INTPTR_FORMAT " byte_for(last): " INTPTR_FORMAT,
- p2i(byte_for(_covered[ind].start())), p2i(byte_for(_covered[ind].last())));
- log_trace(gc, barrier)(" addr_for(start): " INTPTR_FORMAT " addr_for(last): " INTPTR_FORMAT,
- p2i(addr_for((jbyte*) _committed[ind].start())), p2i(addr_for((jbyte*) _committed[ind].last())));
-
- // Touch the last card of the covered region to show that it
- // is committed (or SEGV).
- debug_only((void) (*byte_for(_covered[ind].last()));)
- debug_only(verify_guard();)
-}
-
-// Note that these versions are precise! The scanning code has to handle the
-// fact that the write barrier may be either precise or imprecise.
-
-void CardTableModRefBS::dirty_MemRegion(MemRegion mr) {
- assert(align_down(mr.start(), HeapWordSize) == mr.start(), "Unaligned start");
- assert(align_up (mr.end(), HeapWordSize) == mr.end(), "Unaligned end" );
- jbyte* cur = byte_for(mr.start());
- jbyte* last = byte_after(mr.last());
- while (cur < last) {
- *cur = dirty_card;
- cur++;
- }
+void CardTableModRefBS::write_ref_array_work(MemRegion mr) {
+ _card_table->dirty_MemRegion(mr);
}
void CardTableModRefBS::invalidate(MemRegion mr) {
- assert(align_down(mr.start(), HeapWordSize) == mr.start(), "Unaligned start");
- assert(align_up (mr.end(), HeapWordSize) == mr.end(), "Unaligned end" );
- for (int i = 0; i < _cur_covered_regions; i++) {
- MemRegion mri = mr.intersection(_covered[i]);
- if (!mri.is_empty()) dirty_MemRegion(mri);
- }
+ _card_table->invalidate(mr);
}
-void CardTableModRefBS::clear_MemRegion(MemRegion mr) {
- // Be conservative: only clean cards entirely contained within the
- // region.
- jbyte* cur;
- if (mr.start() == _whole_heap.start()) {
- cur = byte_for(mr.start());
- } else {
- assert(mr.start() > _whole_heap.start(), "mr is not covered.");
- cur = byte_after(mr.start() - 1);
- }
- jbyte* last = byte_after(mr.last());
- memset(cur, clean_card, pointer_delta(last, cur, sizeof(jbyte)));
-}
-
-void CardTableModRefBS::clear(MemRegion mr) {
- for (int i = 0; i < _cur_covered_regions; i++) {
- MemRegion mri = mr.intersection(_covered[i]);
- if (!mri.is_empty()) clear_MemRegion(mri);
- }
-}
-
-void CardTableModRefBS::dirty(MemRegion mr) {
- jbyte* first = byte_for(mr.start());
- jbyte* last = byte_after(mr.last());
- memset(first, dirty_card, last-first);
-}
-
-// Unlike several other card table methods, dirty_card_iterate()
-// iterates over dirty cards ranges in increasing address order.
-void CardTableModRefBS::dirty_card_iterate(MemRegion mr,
- MemRegionClosure* cl) {
- for (int i = 0; i < _cur_covered_regions; i++) {
- MemRegion mri = mr.intersection(_covered[i]);
- if (!mri.is_empty()) {
- jbyte *cur_entry, *next_entry, *limit;
- for (cur_entry = byte_for(mri.start()), limit = byte_for(mri.last());
- cur_entry <= limit;
- cur_entry = next_entry) {
- next_entry = cur_entry + 1;
- if (*cur_entry == dirty_card) {
- size_t dirty_cards;
- // Accumulate maximal dirty card range, starting at cur_entry
- for (dirty_cards = 1;
- next_entry <= limit && *next_entry == dirty_card;
- dirty_cards++, next_entry++);
- MemRegion cur_cards(addr_for(cur_entry),
- dirty_cards*card_size_in_words);
- cl->do_MemRegion(cur_cards);
- }
- }
- }
- }
-}
-
-MemRegion CardTableModRefBS::dirty_card_range_after_reset(MemRegion mr,
- bool reset,
- int reset_val) {
- for (int i = 0; i < _cur_covered_regions; i++) {
- MemRegion mri = mr.intersection(_covered[i]);
- if (!mri.is_empty()) {
- jbyte* cur_entry, *next_entry, *limit;
- for (cur_entry = byte_for(mri.start()), limit = byte_for(mri.last());
- cur_entry <= limit;
- cur_entry = next_entry) {
- next_entry = cur_entry + 1;
- if (*cur_entry == dirty_card) {
- size_t dirty_cards;
- // Accumulate maximal dirty card range, starting at cur_entry
- for (dirty_cards = 1;
- next_entry <= limit && *next_entry == dirty_card;
- dirty_cards++, next_entry++);
- MemRegion cur_cards(addr_for(cur_entry),
- dirty_cards*card_size_in_words);
- if (reset) {
- for (size_t i = 0; i < dirty_cards; i++) {
- cur_entry[i] = reset_val;
- }
- }
- return cur_cards;
- }
- }
- }
- }
- return MemRegion(mr.end(), mr.end());
-}
-
-uintx CardTableModRefBS::ct_max_alignment_constraint() {
- return card_size * os::vm_page_size();
-}
-
-void CardTableModRefBS::verify_guard() {
- // For product build verification
- guarantee(_byte_map[_guard_index] == last_card,
- "card table guard has been modified");
-}
-
-void CardTableModRefBS::verify() {
- verify_guard();
-}
-
-#ifndef PRODUCT
-void CardTableModRefBS::verify_region(MemRegion mr,
- jbyte val, bool val_equals) {
- jbyte* start = byte_for(mr.start());
- jbyte* end = byte_for(mr.last());
- bool failures = false;
- for (jbyte* curr = start; curr <= end; ++curr) {
- jbyte curr_val = *curr;
- bool failed = (val_equals) ? (curr_val != val) : (curr_val == val);
- if (failed) {
- if (!failures) {
- log_error(gc, verify)("== CT verification failed: [" INTPTR_FORMAT "," INTPTR_FORMAT "]", p2i(start), p2i(end));
- log_error(gc, verify)("== %sexpecting value: %d", (val_equals) ? "" : "not ", val);
- failures = true;
- }
- log_error(gc, verify)("== card " PTR_FORMAT " [" PTR_FORMAT "," PTR_FORMAT "], val: %d",
- p2i(curr), p2i(addr_for(curr)),
- p2i((HeapWord*) (((size_t) addr_for(curr)) + card_size)),
- (int) curr_val);
- }
- }
- guarantee(!failures, "there should not have been any failures");
-}
-
-void CardTableModRefBS::verify_not_dirty_region(MemRegion mr) {
- verify_region(mr, dirty_card, false /* val_equals */);
-}
-
-void CardTableModRefBS::verify_dirty_region(MemRegion mr) {
- verify_region(mr, dirty_card, true /* val_equals */);
-}
-#endif
-
void CardTableModRefBS::print_on(outputStream* st) const {
- st->print_cr("Card table byte_map: [" INTPTR_FORMAT "," INTPTR_FORMAT "] byte_map_base: " INTPTR_FORMAT,
- p2i(_byte_map), p2i(_byte_map + _byte_map_size), p2i(byte_map_base));
+ _card_table->print_on(st);
}
// Helper for ReduceInitialCardMarks. For performance,
@@ -573,7 +121,7 @@ void CardTableModRefBS::on_slowpath_allocation_exit(JavaThread* thread, oop new_
}
// If a previous card-mark was deferred, flush it now.
flush_deferred_card_mark_barrier(thread);
- if (new_obj->is_typeArray() || is_in_young(new_obj)) {
+ if (new_obj->is_typeArray() || _card_table->is_in_young(new_obj)) {
// Arrays of non-references don't need a post-barrier.
// The deferred_card_mark region should be empty
// following the flush above.
@@ -586,7 +134,7 @@ void CardTableModRefBS::on_slowpath_allocation_exit(JavaThread* thread, oop new_
thread->set_deferred_card_mark(mr);
} else {
// Do the card mark
- write_region(mr);
+ invalidate(mr);
}
}
}
@@ -610,7 +158,7 @@ void CardTableModRefBS::flush_deferred_card_mark_barrier(JavaThread* thread) {
{
// Verify that the storage points to a parsable object in heap
DEBUG_ONLY(oop old_obj = oop(deferred.start());)
- assert(!is_in_young(old_obj),
+ assert(!_card_table->is_in_young(old_obj),
"Else should have been filtered in on_slowpath_allocation_exit()");
assert(oopDesc::is_oop(old_obj, true), "Not an oop");
assert(deferred.word_size() == (size_t)(old_obj->size()),
@@ -627,9 +175,13 @@ void CardTableModRefBS::flush_deferred_card_mark_barrier(JavaThread* thread) {
#endif
}
-void CardTableModRefBS::flush_deferred_barriers(JavaThread* thread) {
+void CardTableModRefBS::on_thread_detach(JavaThread* thread) {
// The deferred store barriers must all have been flushed to the
// card-table (or other remembered set structure) before GC starts
// processing the card-table (or other remembered set).
flush_deferred_card_mark_barrier(thread);
}
+
+bool CardTableModRefBS::card_mark_must_follow_store() const {
+ return _card_table->scanned_concurrently();
+}
diff --git a/src/hotspot/share/gc/shared/cardTableModRefBS.hpp b/src/hotspot/share/gc/shared/cardTableModRefBS.hpp
index 2a5cb8033ae..0a59ddcdb7f 100644
--- a/src/hotspot/share/gc/shared/cardTableModRefBS.hpp
+++ b/src/hotspot/share/gc/shared/cardTableModRefBS.hpp
@@ -28,6 +28,8 @@
#include "gc/shared/modRefBarrierSet.hpp"
#include "utilities/align.hpp"
+class CardTable;
+
// This kind of "BarrierSet" allows a "CollectedHeap" to detect and
// enumerate ref fields that have been modified (since the last
// enumeration.)
@@ -45,162 +47,29 @@ class CardTableModRefBS: public ModRefBarrierSet {
friend class VMStructs;
protected:
- enum CardValues {
- clean_card = -1,
- // The mask contains zeros in places for all other values.
- clean_card_mask = clean_card - 31,
-
- dirty_card = 0,
- precleaned_card = 1,
- claimed_card = 2,
- deferred_card = 4,
- last_card = 8,
- CT_MR_BS_last_reserved = 16
- };
-
// Used in support of ReduceInitialCardMarks; only consulted if COMPILER2
// or INCLUDE_JVMCI is being used
- bool _defer_initial_card_mark;
+ bool _defer_initial_card_mark;
+ CardTable* _card_table;
- // a word's worth (row) of clean card values
- static const intptr_t clean_card_row = (intptr_t)(-1);
-
- // The declaration order of these const fields is important; see the
- // constructor before changing.
- const MemRegion _whole_heap; // the region covered by the card table
- size_t _guard_index; // index of very last element in the card
- // table; it is set to a guard value
- // (last_card) and should never be modified
- size_t _last_valid_index; // index of the last valid element
- const size_t _page_size; // page size used when mapping _byte_map
- size_t _byte_map_size; // in bytes
- jbyte* _byte_map; // the card marking array
-
- // Some barrier sets create tables whose elements correspond to parts of
- // the heap; the CardTableModRefBS is an example. Such barrier sets will
- // normally reserve space for such tables, and commit parts of the table
- // "covering" parts of the heap that are committed. At most one covered
- // region per generation is needed.
- static const int _max_covered_regions = 2;
-
- int _cur_covered_regions;
-
- // The covered regions should be in address order.
- MemRegion* _covered;
- // The committed regions correspond one-to-one to the covered regions.
- // They represent the card-table memory that has been committed to service
- // the corresponding covered region. It may be that committed region for
- // one covered region corresponds to a larger region because of page-size
- // roundings. Thus, a committed region for one covered region may
- // actually extend onto the card-table space for the next covered region.
- MemRegion* _committed;
-
- // The last card is a guard card, and we commit the page for it so
- // we can use the card for verification purposes. We make sure we never
- // uncommit the MemRegion for that page.
- MemRegion _guard_region;
-
- inline size_t compute_byte_map_size();
-
- // Finds and return the index of the region, if any, to which the given
- // region would be contiguous. If none exists, assign a new region and
- // returns its index. Requires that no more than the maximum number of
- // covered regions defined in the constructor are ever in use.
- int find_covering_region_by_base(HeapWord* base);
-
- // Same as above, but finds the region containing the given address
- // instead of starting at a given base address.
- int find_covering_region_containing(HeapWord* addr);
-
- // Resize one of the regions covered by the remembered set.
- virtual void resize_covered_region(MemRegion new_region);
-
- // Returns the leftmost end of a committed region corresponding to a
- // covered region before covered region "ind", or else "NULL" if "ind" is
- // the first covered region.
- HeapWord* largest_prev_committed_end(int ind) const;
-
- // Returns the part of the region mr that doesn't intersect with
- // any committed region other than self. Used to prevent uncommitting
- // regions that are also committed by other regions. Also protects
- // against uncommitting the guard region.
- MemRegion committed_unique_to_self(int self, MemRegion mr) const;
-
- // Mapping from address to card marking array entry
- jbyte* byte_for(const void* p) const {
- assert(_whole_heap.contains(p),
- "Attempt to access p = " PTR_FORMAT " out of bounds of "
- " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")",
- p2i(p), p2i(_whole_heap.start()), p2i(_whole_heap.end()));
- jbyte* result = &byte_map_base[uintptr_t(p) >> card_shift];
- assert(result >= _byte_map && result < _byte_map + _byte_map_size,
- "out of bounds accessor for card marking array");
- return result;
- }
-
- // The card table byte one after the card marking array
- // entry for argument address. Typically used for higher bounds
- // for loops iterating through the card table.
- jbyte* byte_after(const void* p) const {
- return byte_for(p) + 1;
- }
-
- // Dirty the bytes corresponding to "mr" (not all of which must be
- // covered.)
- void dirty_MemRegion(MemRegion mr);
-
- // Clear (to clean_card) the bytes entirely contained within "mr" (not
- // all of which must be covered.)
- void clear_MemRegion(MemRegion mr);
+ CardTableModRefBS(CardTable* card_table, const BarrierSet::FakeRtti& fake_rtti);
public:
- // Constants
- enum SomePublicConstants {
- card_shift = 9,
- card_size = 1 << card_shift,
- card_size_in_words = card_size / sizeof(HeapWord)
- };
+ CardTableModRefBS(CardTable* card_table);
+ ~CardTableModRefBS();
- static int clean_card_val() { return clean_card; }
- static int clean_card_mask_val() { return clean_card_mask; }
- static int dirty_card_val() { return dirty_card; }
- static int claimed_card_val() { return claimed_card; }
- static int precleaned_card_val() { return precleaned_card; }
- static int deferred_card_val() { return deferred_card; }
+ CardTable* card_table() const { return _card_table; }
virtual void initialize();
- // *** Barrier set functions.
-
- // Initialization utilities; covered_words is the size of the covered region
- // in, um, words.
- inline size_t cards_required(size_t covered_words) {
- // Add one for a guard card, used to detect errors.
- const size_t words = align_up(covered_words, card_size_in_words);
- return words / card_size_in_words + 1;
- }
-
- protected:
- CardTableModRefBS(MemRegion whole_heap, const BarrierSet::FakeRtti& fake_rtti);
- ~CardTableModRefBS();
-
- public:
void write_region(MemRegion mr) {
- dirty_MemRegion(mr);
+ invalidate(mr);
}
protected:
- void write_ref_array_work(MemRegion mr) {
- dirty_MemRegion(mr);
- }
+ void write_ref_array_work(MemRegion mr);
public:
- bool is_aligned(HeapWord* addr) {
- return is_card_aligned(addr);
- }
-
- // *** Card-table-barrier-specific things.
-
// Record a reference update. Note that these versions are precise!
// The scanning code has to handle the fact that the write barrier may be
// either precise or imprecise. We make non-virtual inline variants of
@@ -208,115 +77,7 @@ class CardTableModRefBS: public ModRefBarrierSet {
template
void write_ref_field_post(T* field, oop newVal);
- // These are used by G1, when it uses the card table as a temporary data
- // structure for card claiming.
- bool is_card_dirty(size_t card_index) {
- return _byte_map[card_index] == dirty_card_val();
- }
-
- void mark_card_dirty(size_t card_index) {
- _byte_map[card_index] = dirty_card_val();
- }
-
- bool is_card_clean(size_t card_index) {
- return _byte_map[card_index] == clean_card_val();
- }
-
- // Card marking array base (adjusted for heap low boundary)
- // This would be the 0th element of _byte_map, if the heap started at 0x0.
- // But since the heap starts at some higher address, this points to somewhere
- // before the beginning of the actual _byte_map.
- jbyte* byte_map_base;
-
- // Return true if "p" is at the start of a card.
- bool is_card_aligned(HeapWord* p) {
- jbyte* pcard = byte_for(p);
- return (addr_for(pcard) == p);
- }
-
- HeapWord* align_to_card_boundary(HeapWord* p) {
- jbyte* pcard = byte_for(p + card_size_in_words - 1);
- return addr_for(pcard);
- }
-
- // The kinds of precision a CardTableModRefBS may offer.
- enum PrecisionStyle {
- Precise,
- ObjHeadPreciseArray
- };
-
- // Tells what style of precision this card table offers.
- PrecisionStyle precision() {
- return ObjHeadPreciseArray; // Only one supported for now.
- }
-
- // ModRefBS functions.
virtual void invalidate(MemRegion mr);
- void clear(MemRegion mr);
- void dirty(MemRegion mr);
-
- // *** Card-table-RemSet-specific things.
-
- static uintx ct_max_alignment_constraint();
-
- // Apply closure "cl" to the dirty cards containing some part of
- // MemRegion "mr".
- void dirty_card_iterate(MemRegion mr, MemRegionClosure* cl);
-
- // Return the MemRegion corresponding to the first maximal run
- // of dirty cards lying completely within MemRegion mr.
- // If reset is "true", then sets those card table entries to the given
- // value.
- MemRegion dirty_card_range_after_reset(MemRegion mr, bool reset,
- int reset_val);
-
- // Provide read-only access to the card table array.
- const jbyte* byte_for_const(const void* p) const {
- return byte_for(p);
- }
- const jbyte* byte_after_const(const void* p) const {
- return byte_after(p);
- }
-
- // Mapping from card marking array entry to address of first word
- HeapWord* addr_for(const jbyte* p) const {
- assert(p >= _byte_map && p < _byte_map + _byte_map_size,
- "out of bounds access to card marking array. p: " PTR_FORMAT
- " _byte_map: " PTR_FORMAT " _byte_map + _byte_map_size: " PTR_FORMAT,
- p2i(p), p2i(_byte_map), p2i(_byte_map + _byte_map_size));
- size_t delta = pointer_delta(p, byte_map_base, sizeof(jbyte));
- HeapWord* result = (HeapWord*) (delta << card_shift);
- assert(_whole_heap.contains(result),
- "Returning result = " PTR_FORMAT " out of bounds of "
- " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")",
- p2i(result), p2i(_whole_heap.start()), p2i(_whole_heap.end()));
- return result;
- }
-
- // Mapping from address to card marking array index.
- size_t index_for(void* p) {
- assert(_whole_heap.contains(p),
- "Attempt to access p = " PTR_FORMAT " out of bounds of "
- " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")",
- p2i(p), p2i(_whole_heap.start()), p2i(_whole_heap.end()));
- return byte_for(p) - _byte_map;
- }
-
- const jbyte* byte_for_index(const size_t card_index) const {
- return _byte_map + card_index;
- }
-
- // Print a description of the memory for the barrier set
- virtual void print_on(outputStream* st) const;
-
- void verify();
- void verify_guard();
-
- // val_equals -> it will check that all cards covered by mr equal val
- // !val_equals -> it will check that all cards covered by mr do not equal val
- void verify_region(MemRegion mr, jbyte val, bool val_equals) PRODUCT_RETURN;
- void verify_not_dirty_region(MemRegion mr) PRODUCT_RETURN;
- void verify_dirty_region(MemRegion mr) PRODUCT_RETURN;
// ReduceInitialCardMarks
void initialize_deferred_card_mark_barriers();
@@ -352,15 +113,15 @@ class CardTableModRefBS: public ModRefBarrierSet {
// barrier until the next slow-path allocation or gc-related safepoint.)
// This interface answers whether a particular barrier type needs the card
// mark to be thus strictly sequenced after the stores.
- virtual bool card_mark_must_follow_store() const = 0;
-
- virtual bool is_in_young(oop obj) const = 0;
+ virtual bool card_mark_must_follow_store() const;
virtual void on_slowpath_allocation_exit(JavaThread* thread, oop new_obj);
- virtual void flush_deferred_barriers(JavaThread* thread);
+ virtual void on_thread_detach(JavaThread* thread);
virtual void make_parsable(JavaThread* thread) { flush_deferred_card_mark_barrier(thread); }
+ virtual void print_on(outputStream* st) const;
+
template
class AccessBarrier: public ModRefBarrierSet::AccessBarrier {};
};
diff --git a/src/hotspot/share/gc/shared/cardTableModRefBS.inline.hpp b/src/hotspot/share/gc/shared/cardTableModRefBS.inline.hpp
index e2636b18953..888f0a4ed1f 100644
--- a/src/hotspot/share/gc/shared/cardTableModRefBS.inline.hpp
+++ b/src/hotspot/share/gc/shared/cardTableModRefBS.inline.hpp
@@ -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
@@ -26,17 +26,18 @@
#define SHARE_VM_GC_SHARED_CARDTABLEMODREFBS_INLINE_HPP
#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTable.hpp"
#include "runtime/orderAccess.inline.hpp"
template
inline void CardTableModRefBS::write_ref_field_post(T* field, oop newVal) {
- volatile jbyte* byte = byte_for(field);
+ volatile jbyte* byte = _card_table->byte_for(field);
if (UseConcMarkSweepGC) {
// Perform a releasing store if using CMS so that it may
// scan and clear the cards concurrently during pre-cleaning.
- OrderAccess::release_store(byte, jbyte(dirty_card));
+ OrderAccess::release_store(byte, CardTable::dirty_card_val());
} else {
- *byte = dirty_card;
+ *byte = CardTable::dirty_card_val();
}
}
diff --git a/src/hotspot/share/gc/shared/cardTableModRefBSForCTRS.cpp b/src/hotspot/share/gc/shared/cardTableModRefBSForCTRS.cpp
deleted file mode 100644
index 2f68808dfd6..00000000000
--- a/src/hotspot/share/gc/shared/cardTableModRefBSForCTRS.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * 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/cardTableModRefBS.inline.hpp"
-#include "gc/shared/cardTableRS.hpp"
-#include "memory/allocation.inline.hpp"
-#include "gc/shared/space.inline.hpp"
-
-CardTableModRefBSForCTRS::CardTableModRefBSForCTRS(MemRegion whole_heap) :
- CardTableModRefBS(
- whole_heap,
- BarrierSet::FakeRtti(BarrierSet::CardTableForRS)),
- // LNC functionality
- _lowest_non_clean(NULL),
- _lowest_non_clean_chunk_size(NULL),
- _lowest_non_clean_base_chunk_index(NULL),
- _last_LNC_resizing_collection(NULL)
-{ }
-
-void CardTableModRefBSForCTRS::initialize() {
- CardTableModRefBS::initialize();
- _lowest_non_clean =
- NEW_C_HEAP_ARRAY(CardArr, _max_covered_regions, mtGC);
- _lowest_non_clean_chunk_size =
- NEW_C_HEAP_ARRAY(size_t, _max_covered_regions, mtGC);
- _lowest_non_clean_base_chunk_index =
- NEW_C_HEAP_ARRAY(uintptr_t, _max_covered_regions, mtGC);
- _last_LNC_resizing_collection =
- NEW_C_HEAP_ARRAY(int, _max_covered_regions, mtGC);
- if (_lowest_non_clean == NULL
- || _lowest_non_clean_chunk_size == NULL
- || _lowest_non_clean_base_chunk_index == NULL
- || _last_LNC_resizing_collection == NULL)
- vm_exit_during_initialization("couldn't allocate an LNC array.");
- for (int i = 0; i < _max_covered_regions; i++) {
- _lowest_non_clean[i] = NULL;
- _lowest_non_clean_chunk_size[i] = 0;
- _last_LNC_resizing_collection[i] = -1;
- }
-}
-
-CardTableModRefBSForCTRS::~CardTableModRefBSForCTRS() {
- if (_lowest_non_clean) {
- FREE_C_HEAP_ARRAY(CardArr, _lowest_non_clean);
- _lowest_non_clean = NULL;
- }
- if (_lowest_non_clean_chunk_size) {
- FREE_C_HEAP_ARRAY(size_t, _lowest_non_clean_chunk_size);
- _lowest_non_clean_chunk_size = NULL;
- }
- if (_lowest_non_clean_base_chunk_index) {
- FREE_C_HEAP_ARRAY(uintptr_t, _lowest_non_clean_base_chunk_index);
- _lowest_non_clean_base_chunk_index = NULL;
- }
- if (_last_LNC_resizing_collection) {
- FREE_C_HEAP_ARRAY(int, _last_LNC_resizing_collection);
- _last_LNC_resizing_collection = NULL;
- }
-}
-
-bool CardTableModRefBSForCTRS::card_will_be_scanned(jbyte cv) {
- return
- card_is_dirty_wrt_gen_iter(cv) ||
- _rs->is_prev_nonclean_card_val(cv);
-}
-
-bool CardTableModRefBSForCTRS::card_may_have_been_dirty(jbyte cv) {
- return
- cv != clean_card &&
- (card_is_dirty_wrt_gen_iter(cv) ||
- CardTableRS::youngergen_may_have_been_dirty(cv));
-}
-
-void CardTableModRefBSForCTRS::non_clean_card_iterate_possibly_parallel(
- Space* sp,
- MemRegion mr,
- OopsInGenClosure* cl,
- CardTableRS* ct,
- uint n_threads)
-{
- if (!mr.is_empty()) {
- if (n_threads > 0) {
-#if INCLUDE_ALL_GCS
- non_clean_card_iterate_parallel_work(sp, mr, cl, ct, n_threads);
-#else // INCLUDE_ALL_GCS
- fatal("Parallel gc not supported here.");
-#endif // INCLUDE_ALL_GCS
- } else {
- // clear_cl finds contiguous dirty ranges of cards to process and clear.
-
- // This is the single-threaded version used by DefNew.
- const bool parallel = false;
-
- DirtyCardToOopClosure* dcto_cl = sp->new_dcto_cl(cl, precision(), cl->gen_boundary(), parallel);
- ClearNoncleanCardWrapper clear_cl(dcto_cl, ct, parallel);
-
- clear_cl.do_MemRegion(mr);
- }
- }
-}
-
-bool CardTableModRefBSForCTRS::is_in_young(oop obj) const {
- return GenCollectedHeap::heap()->is_in_young(obj);
-}
diff --git a/src/hotspot/share/gc/shared/cardTableRS.cpp b/src/hotspot/share/gc/shared/cardTableRS.cpp
index 27d015110c4..4b01c815cf0 100644
--- a/src/hotspot/share/gc/shared/cardTableRS.cpp
+++ b/src/hotspot/share/gc/shared/cardTableRS.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -75,41 +75,6 @@ void CLDRemSet::clear_mod_union() {
}
-CardTableRS::CardTableRS(MemRegion whole_heap) :
- _bs(NULL),
- _cur_youngergen_card_val(youngergenP1_card)
-{
- _ct_bs = new CardTableModRefBSForCTRS(whole_heap);
- _ct_bs->initialize();
- set_bs(_ct_bs);
- // max_gens is really GenCollectedHeap::heap()->gen_policy()->number_of_generations()
- // (which is always 2, young & old), but GenCollectedHeap has not been initialized yet.
- uint max_gens = 2;
- _last_cur_val_in_gen = NEW_C_HEAP_ARRAY3(jbyte, max_gens + 1,
- mtGC, CURRENT_PC, AllocFailStrategy::RETURN_NULL);
- if (_last_cur_val_in_gen == NULL) {
- vm_exit_during_initialization("Could not create last_cur_val_in_gen array.");
- }
- for (uint i = 0; i < max_gens + 1; i++) {
- _last_cur_val_in_gen[i] = clean_card_val();
- }
- _ct_bs->set_CTRS(this);
-}
-
-CardTableRS::~CardTableRS() {
- if (_ct_bs) {
- delete _ct_bs;
- _ct_bs = NULL;
- }
- if (_last_cur_val_in_gen) {
- FREE_C_HEAP_ARRAY(jbyte, _last_cur_val_in_gen);
- }
-}
-
-void CardTableRS::resize_covered_region(MemRegion new_region) {
- _ct_bs->resize_covered_region(new_region);
-}
-
jbyte CardTableRS::find_unused_youngergenP_card_value() {
for (jbyte v = youngergenP1_card;
v < cur_youngergen_and_prev_nonclean_card;
@@ -247,7 +212,7 @@ void ClearNoncleanCardWrapper::do_MemRegion(MemRegion mr) {
// fast forward through potential continuous whole-word range of clean cards beginning at a word-boundary
if (is_word_aligned(cur_entry)) {
jbyte* cur_row = cur_entry - BytesPerWord;
- while (cur_row >= limit && *((intptr_t*)cur_row) == CardTableRS::clean_card_row()) {
+ while (cur_row >= limit && *((intptr_t*)cur_row) == CardTableRS::clean_card_row_val()) {
cur_row -= BytesPerWord;
}
cur_entry = cur_row + BytesPerWord;
@@ -283,7 +248,7 @@ void ClearNoncleanCardWrapper::do_MemRegion(MemRegion mr) {
// cur-younger-gen ==> cur_younger_gen
// cur_youngergen_and_prev_nonclean_card ==> no change.
void CardTableRS::write_ref_field_gc_par(void* field, oop new_val) {
- volatile jbyte* entry = _ct_bs->byte_for(field);
+ volatile jbyte* entry = byte_for(field);
do {
jbyte entry_val = *entry;
// We put this first because it's probably the most common case.
@@ -341,7 +306,7 @@ void CardTableRS::younger_refs_in_space_iterate(Space* sp,
ShouldNotReachHere();
}
#endif
- _ct_bs->non_clean_card_iterate_possibly_parallel(sp, urasm, cl, this, n_threads);
+ non_clean_card_iterate_possibly_parallel(sp, urasm, cl, this, n_threads);
}
void CardTableRS::clear_into_younger(Generation* old_gen) {
@@ -642,5 +607,115 @@ void CardTableRS::verify() {
// generational heaps.
VerifyCTGenClosure blk(this);
GenCollectedHeap::heap()->generation_iterate(&blk, false);
- _ct_bs->verify();
+ CardTable::verify();
+}
+
+CardTableRS::CardTableRS(MemRegion whole_heap) :
+ CardTable(whole_heap, /* scanned concurrently */ UseConcMarkSweepGC && CMSPrecleaningEnabled),
+ _cur_youngergen_card_val(youngergenP1_card),
+ // LNC functionality
+ _lowest_non_clean(NULL),
+ _lowest_non_clean_chunk_size(NULL),
+ _lowest_non_clean_base_chunk_index(NULL),
+ _last_LNC_resizing_collection(NULL)
+{
+ // max_gens is really GenCollectedHeap::heap()->gen_policy()->number_of_generations()
+ // (which is always 2, young & old), but GenCollectedHeap has not been initialized yet.
+ uint max_gens = 2;
+ _last_cur_val_in_gen = NEW_C_HEAP_ARRAY3(jbyte, max_gens + 1,
+ mtGC, CURRENT_PC, AllocFailStrategy::RETURN_NULL);
+ if (_last_cur_val_in_gen == NULL) {
+ vm_exit_during_initialization("Could not create last_cur_val_in_gen array.");
+ }
+ for (uint i = 0; i < max_gens + 1; i++) {
+ _last_cur_val_in_gen[i] = clean_card_val();
+ }
+}
+
+CardTableRS::~CardTableRS() {
+ if (_last_cur_val_in_gen) {
+ FREE_C_HEAP_ARRAY(jbyte, _last_cur_val_in_gen);
+ _last_cur_val_in_gen = NULL;
+ }
+ if (_lowest_non_clean) {
+ FREE_C_HEAP_ARRAY(CardArr, _lowest_non_clean);
+ _lowest_non_clean = NULL;
+ }
+ if (_lowest_non_clean_chunk_size) {
+ FREE_C_HEAP_ARRAY(size_t, _lowest_non_clean_chunk_size);
+ _lowest_non_clean_chunk_size = NULL;
+ }
+ if (_lowest_non_clean_base_chunk_index) {
+ FREE_C_HEAP_ARRAY(uintptr_t, _lowest_non_clean_base_chunk_index);
+ _lowest_non_clean_base_chunk_index = NULL;
+ }
+ if (_last_LNC_resizing_collection) {
+ FREE_C_HEAP_ARRAY(int, _last_LNC_resizing_collection);
+ _last_LNC_resizing_collection = NULL;
+ }
+}
+
+void CardTableRS::initialize() {
+ CardTable::initialize();
+ _lowest_non_clean =
+ NEW_C_HEAP_ARRAY(CardArr, _max_covered_regions, mtGC);
+ _lowest_non_clean_chunk_size =
+ NEW_C_HEAP_ARRAY(size_t, _max_covered_regions, mtGC);
+ _lowest_non_clean_base_chunk_index =
+ NEW_C_HEAP_ARRAY(uintptr_t, _max_covered_regions, mtGC);
+ _last_LNC_resizing_collection =
+ NEW_C_HEAP_ARRAY(int, _max_covered_regions, mtGC);
+ if (_lowest_non_clean == NULL
+ || _lowest_non_clean_chunk_size == NULL
+ || _lowest_non_clean_base_chunk_index == NULL
+ || _last_LNC_resizing_collection == NULL)
+ vm_exit_during_initialization("couldn't allocate an LNC array.");
+ for (int i = 0; i < _max_covered_regions; i++) {
+ _lowest_non_clean[i] = NULL;
+ _lowest_non_clean_chunk_size[i] = 0;
+ _last_LNC_resizing_collection[i] = -1;
+ }
+}
+
+bool CardTableRS::card_will_be_scanned(jbyte cv) {
+ return card_is_dirty_wrt_gen_iter(cv) || is_prev_nonclean_card_val(cv);
+}
+
+bool CardTableRS::card_may_have_been_dirty(jbyte cv) {
+ return
+ cv != clean_card &&
+ (card_is_dirty_wrt_gen_iter(cv) ||
+ CardTableRS::youngergen_may_have_been_dirty(cv));
+}
+
+void CardTableRS::non_clean_card_iterate_possibly_parallel(
+ Space* sp,
+ MemRegion mr,
+ OopsInGenClosure* cl,
+ CardTableRS* ct,
+ uint n_threads)
+{
+ if (!mr.is_empty()) {
+ if (n_threads > 0) {
+#if INCLUDE_ALL_GCS
+ non_clean_card_iterate_parallel_work(sp, mr, cl, ct, n_threads);
+#else // INCLUDE_ALL_GCS
+ fatal("Parallel gc not supported here.");
+#endif // INCLUDE_ALL_GCS
+ } else {
+ // clear_cl finds contiguous dirty ranges of cards to process and clear.
+
+ // This is the single-threaded version used by DefNew.
+ const bool parallel = false;
+
+ DirtyCardToOopClosure* dcto_cl = sp->new_dcto_cl(cl, precision(), cl->gen_boundary(), parallel);
+ ClearNoncleanCardWrapper clear_cl(dcto_cl, ct, parallel);
+
+ clear_cl.do_MemRegion(mr);
+ }
+ }
+}
+
+bool CardTableRS::is_in_young(oop obj) const {
+ return GenCollectedHeap::heap()->is_in_young(obj);
}
diff --git a/src/hotspot/share/gc/shared/cardTableRS.hpp b/src/hotspot/share/gc/shared/cardTableRS.hpp
index 051c78aa569..d939f257e4f 100644
--- a/src/hotspot/share/gc/shared/cardTableRS.hpp
+++ b/src/hotspot/share/gc/shared/cardTableRS.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,9 +25,11 @@
#ifndef SHARE_VM_GC_SHARED_CARDTABLERS_HPP
#define SHARE_VM_GC_SHARED_CARDTABLERS_HPP
-#include "gc/shared/cardTableModRefBSForCTRS.hpp"
+#include "gc/shared/cardTable.hpp"
#include "memory/memRegion.hpp"
+#include "oops/oop.hpp"
+class DirtyCardToOopClosure;
class Generation;
class Space;
class OopsInGenClosure;
@@ -46,44 +48,28 @@ class CLDRemSet {
// This RemSet uses a card table both as shared data structure
// for a mod ref barrier set and for the rem set information.
-class CardTableRS: public CHeapObj {
+class CardTableRS: public CardTable {
friend class VMStructs;
// Below are private classes used in impl.
friend class VerifyCTSpaceClosure;
friend class ClearNoncleanCardWrapper;
- static jbyte clean_card_val() {
- return CardTableModRefBSForCTRS::clean_card;
- }
-
- static intptr_t clean_card_row() {
- return CardTableModRefBSForCTRS::clean_card_row;
- }
-
- static bool
- card_is_dirty_wrt_gen_iter(jbyte cv) {
- return CardTableModRefBSForCTRS::card_is_dirty_wrt_gen_iter(cv);
- }
-
CLDRemSet _cld_rem_set;
- BarrierSet* _bs;
-
- CardTableModRefBSForCTRS* _ct_bs;
void verify_space(Space* s, HeapWord* gen_start);
enum ExtendedCardValue {
- youngergen_card = CardTableModRefBSForCTRS::CT_MR_BS_last_reserved + 1,
+ youngergen_card = CT_MR_BS_last_reserved + 1,
// These are for parallel collection.
// There are three P (parallel) youngergen card values. In general, this
// needs to be more than the number of generations (including the perm
// gen) that might have younger_refs_do invoked on them separately. So
// if we add more gens, we have to add more values.
- youngergenP1_card = CardTableModRefBSForCTRS::CT_MR_BS_last_reserved + 2,
- youngergenP2_card = CardTableModRefBSForCTRS::CT_MR_BS_last_reserved + 3,
- youngergenP3_card = CardTableModRefBSForCTRS::CT_MR_BS_last_reserved + 4,
+ youngergenP1_card = CT_MR_BS_last_reserved + 2,
+ youngergenP2_card = CT_MR_BS_last_reserved + 3,
+ youngergenP3_card = CT_MR_BS_last_reserved + 4,
cur_youngergen_and_prev_nonclean_card =
- CardTableModRefBSForCTRS::CT_MR_BS_last_reserved + 5
+ CT_MR_BS_last_reserved + 5
};
// An array that contains, for each generation, the card table value last
@@ -116,16 +102,8 @@ public:
CardTableRS(MemRegion whole_heap);
~CardTableRS();
- // Return the barrier set associated with "this."
- BarrierSet* bs() { return _bs; }
-
- // Set the barrier set.
- void set_bs(BarrierSet* bs) { _bs = bs; }
-
CLDRemSet* cld_rem_set() { return &_cld_rem_set; }
- CardTableModRefBSForCTRS* ct_bs() { return _ct_bs; }
-
void younger_refs_in_space_iterate(Space* sp, OopsInGenClosure* cl, uint n_threads);
// Override.
@@ -137,7 +115,7 @@ public:
void younger_refs_iterate(Generation* g, OopsInGenClosure* blk, uint n_threads);
void inline_write_ref_field_gc(void* field, oop new_val) {
- jbyte* byte = _ct_bs->byte_for(field);
+ jbyte* byte = byte_for(field);
*byte = youngergen_card;
}
void write_ref_field_gc_work(void* field, oop new_val) {
@@ -149,30 +127,17 @@ public:
// a younger card in the current collection.
virtual void write_ref_field_gc_par(void* field, oop new_val);
- void resize_covered_region(MemRegion new_region);
-
bool is_aligned(HeapWord* addr) {
- return _ct_bs->is_card_aligned(addr);
+ return is_card_aligned(addr);
}
void verify();
+ void initialize();
- void clear(MemRegion mr) { _ct_bs->clear(mr); }
void clear_into_younger(Generation* old_gen);
- void invalidate(MemRegion mr) {
- _ct_bs->invalidate(mr);
- }
void invalidate_or_clear(Generation* old_gen);
- static uintx ct_max_alignment_constraint() {
- return CardTableModRefBSForCTRS::ct_max_alignment_constraint();
- }
-
- jbyte* byte_for(void* p) { return _ct_bs->byte_for(p); }
- jbyte* byte_after(void* p) { return _ct_bs->byte_after(p); }
- HeapWord* addr_for(jbyte* p) { return _ct_bs->addr_for(p); }
-
bool is_prev_nonclean_card_val(jbyte v) {
return
youngergen_card <= v &&
@@ -184,6 +149,94 @@ public:
return cv == CardTableRS::cur_youngergen_and_prev_nonclean_card;
}
+ // *** Support for parallel card scanning.
+
+ // dirty and precleaned are equivalent wrt younger_refs_iter.
+ static bool card_is_dirty_wrt_gen_iter(jbyte cv) {
+ return cv == dirty_card || cv == precleaned_card;
+ }
+
+ // Returns "true" iff the value "cv" will cause the card containing it
+ // to be scanned in the current traversal. May be overridden by
+ // subtypes.
+ bool card_will_be_scanned(jbyte cv);
+
+ // Returns "true" iff the value "cv" may have represented a dirty card at
+ // some point.
+ bool card_may_have_been_dirty(jbyte cv);
+
+ // Iterate over the portion of the card-table which covers the given
+ // region mr in the given space and apply cl to any dirty sub-regions
+ // of mr. Clears the dirty cards as they are processed.
+ void non_clean_card_iterate_possibly_parallel(Space* sp, MemRegion mr,
+ OopsInGenClosure* cl, CardTableRS* ct,
+ uint n_threads);
+
+ // Work method used to implement non_clean_card_iterate_possibly_parallel()
+ // above in the parallel case.
+ void non_clean_card_iterate_parallel_work(Space* sp, MemRegion mr,
+ OopsInGenClosure* cl, CardTableRS* ct,
+ uint n_threads);
+
+ // This is an array, one element per covered region of the card table.
+ // Each entry is itself an array, with one element per chunk in the
+ // covered region. Each entry of these arrays is the lowest non-clean
+ // card of the corresponding chunk containing part of an object from the
+ // previous chunk, or else NULL.
+ typedef jbyte* CardPtr;
+ typedef CardPtr* CardArr;
+ CardArr* _lowest_non_clean;
+ size_t* _lowest_non_clean_chunk_size;
+ uintptr_t* _lowest_non_clean_base_chunk_index;
+ volatile int* _last_LNC_resizing_collection;
+
+ // Initializes "lowest_non_clean" to point to the array for the region
+ // covering "sp", and "lowest_non_clean_base_chunk_index" to the chunk
+ // index of the corresponding to the first element of that array.
+ // Ensures that these arrays are of sufficient size, allocating if necessary.
+ // May be called by several threads concurrently.
+ void get_LNC_array_for_space(Space* sp,
+ jbyte**& lowest_non_clean,
+ uintptr_t& lowest_non_clean_base_chunk_index,
+ size_t& lowest_non_clean_chunk_size);
+
+ // Returns the number of chunks necessary to cover "mr".
+ size_t chunks_to_cover(MemRegion mr) {
+ return (size_t)(addr_to_chunk_index(mr.last()) -
+ addr_to_chunk_index(mr.start()) + 1);
+ }
+
+ // Returns the index of the chunk in a stride which
+ // covers the given address.
+ uintptr_t addr_to_chunk_index(const void* addr) {
+ uintptr_t card = (uintptr_t) byte_for(addr);
+ return card / ParGCCardsPerStrideChunk;
+ }
+
+ // Apply cl, which must either itself apply dcto_cl or be dcto_cl,
+ // to the cards in the stride (of n_strides) within the given space.
+ void process_stride(Space* sp,
+ MemRegion used,
+ jint stride, int n_strides,
+ OopsInGenClosure* cl,
+ CardTableRS* ct,
+ jbyte** lowest_non_clean,
+ uintptr_t lowest_non_clean_base_chunk_index,
+ size_t lowest_non_clean_chunk_size);
+
+ // Makes sure that chunk boundaries are handled appropriately, by
+ // adjusting the min_done of dcto_cl, and by using a special card-table
+ // value to indicate how min_done should be set.
+ void process_chunk_boundaries(Space* sp,
+ DirtyCardToOopClosure* dcto_cl,
+ MemRegion chunk_mr,
+ MemRegion used,
+ jbyte** lowest_non_clean,
+ uintptr_t lowest_non_clean_base_chunk_index,
+ size_t lowest_non_clean_chunk_size);
+
+ virtual bool is_in_young(oop obj) const;
+
};
class ClearNoncleanCardWrapper: public MemRegionClosure {
diff --git a/src/hotspot/share/gc/shared/collectedHeap.cpp b/src/hotspot/share/gc/shared/collectedHeap.cpp
index 49af5ce155e..5ebb70d4a42 100644
--- a/src/hotspot/share/gc/shared/collectedHeap.cpp
+++ b/src/hotspot/share/gc/shared/collectedHeap.cpp
@@ -28,6 +28,7 @@
#include "gc/shared/barrierSet.inline.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
+#include "gc/shared/gcLocker.inline.hpp"
#include "gc/shared/gcHeapSummary.hpp"
#include "gc/shared/gcTrace.hpp"
#include "gc/shared/gcTraceTime.inline.hpp"
@@ -41,9 +42,11 @@
#include "runtime/init.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/threadSMR.hpp"
+#include "runtime/vmThread.hpp"
#include "services/heapDumper.hpp"
#include "utilities/align.hpp"
+class ClassLoaderData;
#ifdef ASSERT
int CollectedHeap::_fire_out_of_memory_count = 0;
@@ -233,6 +236,80 @@ void CollectedHeap::collect_as_vm_thread(GCCause::Cause cause) {
}
}
+MetaWord* CollectedHeap::satisfy_failed_metadata_allocation(ClassLoaderData* loader_data,
+ size_t word_size,
+ Metaspace::MetadataType mdtype) {
+ uint loop_count = 0;
+ uint gc_count = 0;
+ uint full_gc_count = 0;
+
+ assert(!Heap_lock->owned_by_self(), "Should not be holding the Heap_lock");
+
+ do {
+ MetaWord* result = loader_data->metaspace_non_null()->allocate(word_size, mdtype);
+ if (result != NULL) {
+ return result;
+ }
+
+ if (GCLocker::is_active_and_needs_gc()) {
+ // If the GCLocker is active, just expand and allocate.
+ // If that does not succeed, wait if this thread is not
+ // in a critical section itself.
+ result = loader_data->metaspace_non_null()->expand_and_allocate(word_size, mdtype);
+ if (result != NULL) {
+ return result;
+ }
+ JavaThread* jthr = JavaThread::current();
+ if (!jthr->in_critical()) {
+ // Wait for JNI critical section to be exited
+ GCLocker::stall_until_clear();
+ // The GC invoked by the last thread leaving the critical
+ // section will be a young collection and a full collection
+ // is (currently) needed for unloading classes so continue
+ // to the next iteration to get a full GC.
+ continue;
+ } else {
+ if (CheckJNICalls) {
+ fatal("Possible deadlock due to allocating while"
+ " in jni critical section");
+ }
+ return NULL;
+ }
+ }
+
+ { // Need lock to get self consistent gc_count's
+ MutexLocker ml(Heap_lock);
+ gc_count = Universe::heap()->total_collections();
+ full_gc_count = Universe::heap()->total_full_collections();
+ }
+
+ // Generate a VM operation
+ VM_CollectForMetadataAllocation op(loader_data,
+ word_size,
+ mdtype,
+ gc_count,
+ full_gc_count,
+ GCCause::_metadata_GC_threshold);
+ VMThread::execute(&op);
+
+ // If GC was locked out, try again. Check before checking success because the
+ // prologue could have succeeded and the GC still have been locked out.
+ if (op.gc_locked()) {
+ continue;
+ }
+
+ if (op.prologue_succeeded()) {
+ return op.result();
+ }
+ loop_count++;
+ if ((QueuedAllocationWarningCount > 0) &&
+ (loop_count % QueuedAllocationWarningCount == 0)) {
+ log_warning(gc, ergo)("satisfy_failed_metadata_allocation() retries %d times,"
+ " size=" SIZE_FORMAT, loop_count, word_size);
+ }
+ } while (true); // Until a GC is done
+}
+
void CollectedHeap::set_barrier_set(BarrierSet* barrier_set) {
_barrier_set = barrier_set;
BarrierSet::set_bs(barrier_set);
diff --git a/src/hotspot/share/gc/shared/collectedHeap.hpp b/src/hotspot/share/gc/shared/collectedHeap.hpp
index b71a514d0a4..a115369d71c 100644
--- a/src/hotspot/share/gc/shared/collectedHeap.hpp
+++ b/src/hotspot/share/gc/shared/collectedHeap.hpp
@@ -50,6 +50,7 @@ class GCTracer;
class GCMemoryManager;
class MemoryPool;
class MetaspaceSummary;
+class SoftRefPolicy;
class Thread;
class ThreadClosure;
class VirtualSpaceSummary;
@@ -411,6 +412,10 @@ class CollectedHeap : public CHeapObj {
// the context of the vm thread.
virtual void collect_as_vm_thread(GCCause::Cause cause);
+ virtual MetaWord* satisfy_failed_metadata_allocation(ClassLoaderData* loader_data,
+ size_t size,
+ Metaspace::MetadataType mdtype);
+
// Returns the barrier set for this heap
BarrierSet* barrier_set() { return _barrier_set; }
void set_barrier_set(BarrierSet* barrier_set);
@@ -438,6 +443,9 @@ class CollectedHeap : public CHeapObj {
// Return the CollectorPolicy for the heap
virtual CollectorPolicy* collector_policy() const = 0;
+ // Return the SoftRefPolicy for the heap;
+ virtual SoftRefPolicy* soft_ref_policy() = 0;
+
virtual GrowableArray memory_managers() = 0;
virtual GrowableArray memory_pools() = 0;
@@ -492,7 +500,7 @@ class CollectedHeap : public CHeapObj {
void pre_full_gc_dump(GCTimer* timer);
void post_full_gc_dump(GCTimer* timer);
- VirtualSpaceSummary create_heap_space_summary();
+ virtual VirtualSpaceSummary create_heap_space_summary();
GCHeapSummary create_heap_summary();
MetaspaceSummary create_metaspace_summary();
@@ -599,20 +607,6 @@ class CollectedHeap : public CHeapObj {
return (CIFireOOMAt > 1 && _fire_out_of_memory_count >= CIFireOOMAt);
}
#endif
-
- public:
- // Copy the current allocation context statistics for the specified contexts.
- // For each context in contexts, set the corresponding entries in the totals
- // and accuracy arrays to the current values held by the statistics. Each
- // array should be of length len.
- // Returns true if there are more stats available.
- virtual bool copy_allocation_context_stats(const jint* contexts,
- jlong* totals,
- jbyte* accuracy,
- jint len) {
- return false;
- }
-
};
// Class to set and reset the GC cause for a CollectedHeap.
@@ -622,16 +616,12 @@ class GCCauseSetter : StackObj {
GCCause::Cause _previous_cause;
public:
GCCauseSetter(CollectedHeap* heap, GCCause::Cause cause) {
- assert(SafepointSynchronize::is_at_safepoint(),
- "This method manipulates heap state without locking");
_heap = heap;
_previous_cause = _heap->gc_cause();
_heap->set_gc_cause(cause);
}
~GCCauseSetter() {
- assert(SafepointSynchronize::is_at_safepoint(),
- "This method manipulates heap state without locking");
_heap->set_gc_cause(_previous_cause);
}
};
diff --git a/src/hotspot/share/gc/shared/collectorPolicy.cpp b/src/hotspot/share/gc/shared/collectorPolicy.cpp
index 7542662ee76..cbc43fe86e5 100644
--- a/src/hotspot/share/gc/shared/collectorPolicy.cpp
+++ b/src/hotspot/share/gc/shared/collectorPolicy.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -50,9 +50,7 @@ CollectorPolicy::CollectorPolicy() :
_heap_alignment(0),
_initial_heap_byte_size(InitialHeapSize),
_max_heap_byte_size(MaxHeapSize),
- _min_heap_byte_size(Arguments::min_heap_size()),
- _should_clear_all_soft_refs(false),
- _all_soft_refs_clear(false)
+ _min_heap_byte_size(Arguments::min_heap_size())
{}
#ifdef ASSERT
@@ -145,20 +143,6 @@ void CollectorPolicy::initialize_size_info() {
DEBUG_ONLY(CollectorPolicy::assert_size_info();)
}
-bool CollectorPolicy::use_should_clear_all_soft_refs(bool v) {
- bool result = _should_clear_all_soft_refs;
- set_should_clear_all_soft_refs(false);
- return result;
-}
-
-CardTableRS* CollectorPolicy::create_rem_set(MemRegion whole_heap) {
- return new CardTableRS(whole_heap);
-}
-
-void CollectorPolicy::cleared_all_soft_refs() {
- _all_soft_refs_clear = true;
-}
-
size_t CollectorPolicy::compute_heap_alignment() {
// The card marking array and the offset arrays for old generations are
// committed in os pages as well. Make sure they are entirely full (to
@@ -186,10 +170,7 @@ GenCollectorPolicy::GenCollectorPolicy() :
_min_old_size(0),
_initial_old_size(0),
_max_old_size(0),
- _gen_alignment(0),
- _young_gen_spec(NULL),
- _old_gen_spec(NULL),
- _size_policy(NULL)
+ _gen_alignment(0)
{}
size_t GenCollectorPolicy::scale_by_NewRatio_aligned(size_t base_size) {
@@ -202,29 +183,6 @@ size_t GenCollectorPolicy::bound_minus_alignment(size_t desired_size,
return desired_size < max_minus ? desired_size : max_minus;
}
-
-void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size,
- size_t init_promo_size,
- size_t init_survivor_size) {
- const double max_gc_pause_sec = ((double) MaxGCPauseMillis) / 1000.0;
- _size_policy = new AdaptiveSizePolicy(init_eden_size,
- init_promo_size,
- init_survivor_size,
- max_gc_pause_sec,
- GCTimeRatio);
-}
-
-void GenCollectorPolicy::cleared_all_soft_refs() {
- // If near gc overhear limit, continue to clear SoftRefs. SoftRefs may
- // have been cleared in the last collection but if the gc overhear
- // limit continues to be near, SoftRefs should still be cleared.
- if (size_policy() != NULL) {
- _should_clear_all_soft_refs = size_policy()->gc_overhead_limit_near();
- }
-
- CollectorPolicy::cleared_all_soft_refs();
-}
-
size_t GenCollectorPolicy::young_gen_size_lower_bound() {
// The young generation must be aligned and have room for eden + two survivors
return align_up(3 * _space_alignment, _gen_alignment);
@@ -580,322 +538,6 @@ void GenCollectorPolicy::initialize_size_info() {
DEBUG_ONLY(GenCollectorPolicy::assert_size_info();)
}
-HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size,
- bool is_tlab,
- bool* gc_overhead_limit_was_exceeded) {
- GenCollectedHeap *gch = GenCollectedHeap::heap();
-
- debug_only(gch->check_for_valid_allocation_state());
- assert(gch->no_gc_in_progress(), "Allocation during gc not allowed");
-
- // In general gc_overhead_limit_was_exceeded should be false so
- // set it so here and reset it to true only if the gc time
- // limit is being exceeded as checked below.
- *gc_overhead_limit_was_exceeded = false;
-
- HeapWord* result = NULL;
-
- // Loop until the allocation is satisfied, or unsatisfied after GC.
- for (uint try_count = 1, gclocker_stalled_count = 0; /* return or throw */; try_count += 1) {
- HandleMark hm; // Discard any handles allocated in each iteration.
-
- // First allocation attempt is lock-free.
- Generation *young = gch->young_gen();
- assert(young->supports_inline_contig_alloc(),
- "Otherwise, must do alloc within heap lock");
- if (young->should_allocate(size, is_tlab)) {
- result = young->par_allocate(size, is_tlab);
- if (result != NULL) {
- assert(gch->is_in_reserved(result), "result not in heap");
- return result;
- }
- }
- uint gc_count_before; // Read inside the Heap_lock locked region.
- {
- MutexLocker ml(Heap_lock);
- log_trace(gc, alloc)("GenCollectorPolicy::mem_allocate_work: attempting locked slow path allocation");
- // Note that only large objects get a shot at being
- // allocated in later generations.
- bool first_only = ! should_try_older_generation_allocation(size);
-
- result = gch->attempt_allocation(size, is_tlab, first_only);
- if (result != NULL) {
- assert(gch->is_in_reserved(result), "result not in heap");
- return result;
- }
-
- if (GCLocker::is_active_and_needs_gc()) {
- if (is_tlab) {
- return NULL; // Caller will retry allocating individual object.
- }
- if (!gch->is_maximal_no_gc()) {
- // Try and expand heap to satisfy request.
- result = expand_heap_and_allocate(size, is_tlab);
- // Result could be null if we are out of space.
- if (result != NULL) {
- return result;
- }
- }
-
- if (gclocker_stalled_count > GCLockerRetryAllocationCount) {
- return NULL; // We didn't get to do a GC and we didn't get any memory.
- }
-
- // If this thread is not in a jni critical section, we stall
- // the requestor until the critical section has cleared and
- // GC allowed. When the critical section clears, a GC is
- // initiated by the last thread exiting the critical section; so
- // we retry the allocation sequence from the beginning of the loop,
- // rather than causing more, now probably unnecessary, GC attempts.
- JavaThread* jthr = JavaThread::current();
- if (!jthr->in_critical()) {
- MutexUnlocker mul(Heap_lock);
- // Wait for JNI critical section to be exited
- GCLocker::stall_until_clear();
- gclocker_stalled_count += 1;
- continue;
- } else {
- if (CheckJNICalls) {
- fatal("Possible deadlock due to allocating while"
- " in jni critical section");
- }
- return NULL;
- }
- }
-
- // Read the gc count while the heap lock is held.
- gc_count_before = gch->total_collections();
- }
-
- VM_GenCollectForAllocation op(size, is_tlab, gc_count_before);
- VMThread::execute(&op);
- if (op.prologue_succeeded()) {
- result = op.result();
- if (op.gc_locked()) {
- assert(result == NULL, "must be NULL if gc_locked() is true");
- continue; // Retry and/or stall as necessary.
- }
-
- // Allocation has failed and a collection
- // has been done. If the gc time limit was exceeded the
- // this time, return NULL so that an out-of-memory
- // will be thrown. Clear gc_overhead_limit_exceeded
- // so that the overhead exceeded does not persist.
-
- const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
- const bool softrefs_clear = all_soft_refs_clear();
-
- if (limit_exceeded && softrefs_clear) {
- *gc_overhead_limit_was_exceeded = true;
- size_policy()->set_gc_overhead_limit_exceeded(false);
- if (op.result() != NULL) {
- CollectedHeap::fill_with_object(op.result(), size);
- }
- return NULL;
- }
- assert(result == NULL || gch->is_in_reserved(result),
- "result not in heap");
- return result;
- }
-
- // Give a warning if we seem to be looping forever.
- if ((QueuedAllocationWarningCount > 0) &&
- (try_count % QueuedAllocationWarningCount == 0)) {
- log_warning(gc, ergo)("GenCollectorPolicy::mem_allocate_work retries %d times,"
- " size=" SIZE_FORMAT " %s", try_count, size, is_tlab ? "(TLAB)" : "");
- }
- }
-}
-
-HeapWord* GenCollectorPolicy::expand_heap_and_allocate(size_t size,
- bool is_tlab) {
- GenCollectedHeap *gch = GenCollectedHeap::heap();
- HeapWord* result = NULL;
- Generation *old = gch->old_gen();
- if (old->should_allocate(size, is_tlab)) {
- result = old->expand_and_allocate(size, is_tlab);
- }
- if (result == NULL) {
- Generation *young = gch->young_gen();
- if (young->should_allocate(size, is_tlab)) {
- result = young->expand_and_allocate(size, is_tlab);
- }
- }
- assert(result == NULL || gch->is_in_reserved(result), "result not in heap");
- return result;
-}
-
-HeapWord* GenCollectorPolicy::satisfy_failed_allocation(size_t size,
- bool is_tlab) {
- GenCollectedHeap *gch = GenCollectedHeap::heap();
- GCCauseSetter x(gch, GCCause::_allocation_failure);
- HeapWord* result = NULL;
-
- assert(size != 0, "Precondition violated");
- if (GCLocker::is_active_and_needs_gc()) {
- // GC locker is active; instead of a collection we will attempt
- // to expand the heap, if there's room for expansion.
- if (!gch->is_maximal_no_gc()) {
- result = expand_heap_and_allocate(size, is_tlab);
- }
- return result; // Could be null if we are out of space.
- } else if (!gch->incremental_collection_will_fail(false /* don't consult_young */)) {
- // Do an incremental collection.
- gch->do_collection(false, // full
- false, // clear_all_soft_refs
- size, // size
- is_tlab, // is_tlab
- GenCollectedHeap::OldGen); // max_generation
- } else {
- log_trace(gc)(" :: Trying full because partial may fail :: ");
- // Try a full collection; see delta for bug id 6266275
- // for the original code and why this has been simplified
- // with from-space allocation criteria modified and
- // such allocation moved out of the safepoint path.
- gch->do_collection(true, // full
- false, // clear_all_soft_refs
- size, // size
- is_tlab, // is_tlab
- GenCollectedHeap::OldGen); // max_generation
- }
-
- result = gch->attempt_allocation(size, is_tlab, false /*first_only*/);
-
- if (result != NULL) {
- assert(gch->is_in_reserved(result), "result not in heap");
- return result;
- }
-
- // OK, collection failed, try expansion.
- result = expand_heap_and_allocate(size, is_tlab);
- if (result != NULL) {
- return result;
- }
-
- // If we reach this point, we're really out of memory. Try every trick
- // we can to reclaim memory. Force collection of soft references. Force
- // a complete compaction of the heap. Any additional methods for finding
- // free memory should be here, especially if they are expensive. If this
- // attempt fails, an OOM exception will be thrown.
- {
- UIntFlagSetting flag_change(MarkSweepAlwaysCompactCount, 1); // Make sure the heap is fully compacted
-
- gch->do_collection(true, // full
- true, // clear_all_soft_refs
- size, // size
- is_tlab, // is_tlab
- GenCollectedHeap::OldGen); // max_generation
- }
-
- result = gch->attempt_allocation(size, is_tlab, false /* first_only */);
- if (result != NULL) {
- assert(gch->is_in_reserved(result), "result not in heap");
- return result;
- }
-
- assert(!should_clear_all_soft_refs(),
- "Flag should have been handled and cleared prior to this point");
-
- // What else? We might try synchronous finalization later. If the total
- // space available is large enough for the allocation, then a more
- // complete compaction phase than we've tried so far might be
- // appropriate.
- return NULL;
-}
-
-MetaWord* CollectorPolicy::satisfy_failed_metadata_allocation(
- ClassLoaderData* loader_data,
- size_t word_size,
- Metaspace::MetadataType mdtype) {
- uint loop_count = 0;
- uint gc_count = 0;
- uint full_gc_count = 0;
-
- assert(!Heap_lock->owned_by_self(), "Should not be holding the Heap_lock");
-
- do {
- MetaWord* result = loader_data->metaspace_non_null()->allocate(word_size, mdtype);
- if (result != NULL) {
- return result;
- }
-
- if (GCLocker::is_active_and_needs_gc()) {
- // If the GCLocker is active, just expand and allocate.
- // If that does not succeed, wait if this thread is not
- // in a critical section itself.
- result =
- loader_data->metaspace_non_null()->expand_and_allocate(word_size,
- mdtype);
- if (result != NULL) {
- return result;
- }
- JavaThread* jthr = JavaThread::current();
- if (!jthr->in_critical()) {
- // Wait for JNI critical section to be exited
- GCLocker::stall_until_clear();
- // The GC invoked by the last thread leaving the critical
- // section will be a young collection and a full collection
- // is (currently) needed for unloading classes so continue
- // to the next iteration to get a full GC.
- continue;
- } else {
- if (CheckJNICalls) {
- fatal("Possible deadlock due to allocating while"
- " in jni critical section");
- }
- return NULL;
- }
- }
-
- { // Need lock to get self consistent gc_count's
- MutexLocker ml(Heap_lock);
- gc_count = Universe::heap()->total_collections();
- full_gc_count = Universe::heap()->total_full_collections();
- }
-
- // Generate a VM operation
- VM_CollectForMetadataAllocation op(loader_data,
- word_size,
- mdtype,
- gc_count,
- full_gc_count,
- GCCause::_metadata_GC_threshold);
- VMThread::execute(&op);
-
- // If GC was locked out, try again. Check before checking success because the
- // prologue could have succeeded and the GC still have been locked out.
- if (op.gc_locked()) {
- continue;
- }
-
- if (op.prologue_succeeded()) {
- return op.result();
- }
- loop_count++;
- if ((QueuedAllocationWarningCount > 0) &&
- (loop_count % QueuedAllocationWarningCount == 0)) {
- log_warning(gc, ergo)("satisfy_failed_metadata_allocation() retries %d times,"
- " size=" SIZE_FORMAT, loop_count, word_size);
- }
- } while (true); // Until a GC is done
-}
-
-// Return true if any of the following is true:
-// . the allocation won't fit into the current young gen heap
-// . gc locker is occupied (jni critical section)
-// . heap memory is tight -- the most recent previous collection
-// was a full collection because a partial collection (would
-// have) failed and is likely to fail again
-bool GenCollectorPolicy::should_try_older_generation_allocation(
- size_t word_size) const {
- GenCollectedHeap* gch = GenCollectedHeap::heap();
- size_t young_capacity = gch->young_gen()->capacity_before_gc();
- return (word_size > heap_word_size(young_capacity))
- || GCLocker::is_active_and_needs_gc()
- || gch->incremental_collection_failed();
-}
-
-
//
// MarkSweepPolicy methods
//
@@ -904,14 +546,3 @@ void MarkSweepPolicy::initialize_alignments() {
_space_alignment = _gen_alignment = (size_t)Generation::GenGrain;
_heap_alignment = compute_heap_alignment();
}
-
-void MarkSweepPolicy::initialize_generations() {
- _young_gen_spec = new GenerationSpec(Generation::DefNew, _initial_young_size, _max_young_size, _gen_alignment);
- _old_gen_spec = new GenerationSpec(Generation::MarkSweepCompact, _initial_old_size, _max_old_size, _gen_alignment);
-}
-
-void MarkSweepPolicy::initialize_gc_policy_counters() {
- // Initialize the policy counters - 2 collectors, 2 generations.
- _gc_policy_counters = new GCPolicyCounters("Copy:MSC", 2, 2);
-}
-
diff --git a/src/hotspot/share/gc/shared/collectorPolicy.hpp b/src/hotspot/share/gc/shared/collectorPolicy.hpp
index 00e6ad144dc..7fec4c463ce 100644
--- a/src/hotspot/share/gc/shared/collectorPolicy.hpp
+++ b/src/hotspot/share/gc/shared/collectorPolicy.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -53,7 +53,6 @@ class ConcurrentMarkSweepPolicy;
class G1CollectorPolicy;
#endif // INCLUDE_ALL_GCS
-class GCPolicyCounters;
class MarkSweepPolicy;
class CollectorPolicy : public CHeapObj {
@@ -72,21 +71,10 @@ class CollectorPolicy : public CHeapObj {
size_t _space_alignment;
size_t _heap_alignment;
- // Set to true when policy wants soft refs cleared.
- // Reset to false by gc after it clears all soft refs.
- bool _should_clear_all_soft_refs;
-
- // Set to true by the GC if the just-completed gc cleared all
- // softrefs. This is set to true whenever a gc clears all softrefs, and
- // set to false each time gc returns to the mutator. For example, in the
- // ParallelScavengeHeap case the latter would be done toward the end of
- // mem_allocate() where it returns op.result()
- bool _all_soft_refs_clear;
-
CollectorPolicy();
public:
- virtual void initialize_all() {
+ void initialize_all() {
initialize_alignments();
initialize_flags();
initialize_size_info();
@@ -101,58 +89,6 @@ class CollectorPolicy : public CHeapObj {
size_t initial_heap_byte_size() { return _initial_heap_byte_size; }
size_t max_heap_byte_size() { return _max_heap_byte_size; }
size_t min_heap_byte_size() { return _min_heap_byte_size; }
-
- bool should_clear_all_soft_refs() { return _should_clear_all_soft_refs; }
- void set_should_clear_all_soft_refs(bool v) { _should_clear_all_soft_refs = v; }
- // Returns the current value of _should_clear_all_soft_refs.
- // _should_clear_all_soft_refs is set to false as a side effect.
- bool use_should_clear_all_soft_refs(bool v);
- bool all_soft_refs_clear() { return _all_soft_refs_clear; }
- void set_all_soft_refs_clear(bool v) { _all_soft_refs_clear = v; }
-
- // Called by the GC after Soft Refs have been cleared to indicate
- // that the request in _should_clear_all_soft_refs has been fulfilled.
- virtual void cleared_all_soft_refs();
-
- // Identification methods.
- virtual GenCollectorPolicy* as_generation_policy() { return NULL; }
- virtual MarkSweepPolicy* as_mark_sweep_policy() { return NULL; }
-#if INCLUDE_ALL_GCS
- virtual ConcurrentMarkSweepPolicy* as_concurrent_mark_sweep_policy() { return NULL; }
-#endif // INCLUDE_ALL_GCS
- // Note that these are not virtual.
- bool is_generation_policy() { return as_generation_policy() != NULL; }
- bool is_mark_sweep_policy() { return as_mark_sweep_policy() != NULL; }
-#if INCLUDE_ALL_GCS
- bool is_concurrent_mark_sweep_policy() { return as_concurrent_mark_sweep_policy() != NULL; }
-#else // INCLUDE_ALL_GCS
- bool is_concurrent_mark_sweep_policy() { return false; }
-#endif // INCLUDE_ALL_GCS
-
-
- virtual CardTableRS* create_rem_set(MemRegion reserved);
-
- MetaWord* satisfy_failed_metadata_allocation(ClassLoaderData* loader_data,
- size_t size,
- Metaspace::MetadataType mdtype);
-};
-
-class ClearedAllSoftRefs : public StackObj {
- bool _clear_all_soft_refs;
- CollectorPolicy* _collector_policy;
- public:
- ClearedAllSoftRefs(bool clear_all_soft_refs,
- CollectorPolicy* collector_policy) :
- _clear_all_soft_refs(clear_all_soft_refs),
- _collector_policy(collector_policy) {}
-
- ~ClearedAllSoftRefs() {
- if (_clear_all_soft_refs) {
- _collector_policy->cleared_all_soft_refs();
- }
- }
-
- bool should_clear() { return _clear_all_soft_refs; }
};
class GenCollectorPolicy : public CollectorPolicy {
@@ -171,27 +107,12 @@ protected:
// time. When using large pages they can differ.
size_t _gen_alignment;
- GenerationSpec* _young_gen_spec;
- GenerationSpec* _old_gen_spec;
-
- GCPolicyCounters* _gc_policy_counters;
-
- // The sizing of the heap is controlled by a sizing policy.
- AdaptiveSizePolicy* _size_policy;
-
- // Return true if an allocation should be attempted in the older generation
- // if it fails in the younger generation. Return false, otherwise.
- virtual bool should_try_older_generation_allocation(size_t word_size) const;
-
void initialize_flags();
void initialize_size_info();
DEBUG_ONLY(void assert_flags();)
DEBUG_ONLY(void assert_size_info();)
- // Try to allocate space by expanding the heap.
- virtual HeapWord* expand_heap_and_allocate(size_t size, bool is_tlab);
-
// Compute max heap alignment.
size_t compute_max_alignment();
@@ -215,63 +136,17 @@ protected:
size_t initial_old_size() { return _initial_old_size; }
size_t max_old_size() { return _max_old_size; }
- GenerationSpec* young_gen_spec() const {
- assert(_young_gen_spec != NULL, "_young_gen_spec should have been initialized");
- return _young_gen_spec;
- }
-
- GenerationSpec* old_gen_spec() const {
- assert(_old_gen_spec != NULL, "_old_gen_spec should have been initialized");
- return _old_gen_spec;
- }
-
- // Performance Counter support
- GCPolicyCounters* counters() { return _gc_policy_counters; }
-
- // Create the jstat counters for the GC policy.
- virtual void initialize_gc_policy_counters() = 0;
-
- virtual GenCollectorPolicy* as_generation_policy() { return this; }
-
- virtual void initialize_generations() { };
-
- virtual void initialize_all() {
- CollectorPolicy::initialize_all();
- initialize_generations();
- }
-
size_t young_gen_size_lower_bound();
size_t old_gen_size_lower_bound();
-
- HeapWord* mem_allocate_work(size_t size,
- bool is_tlab,
- bool* gc_overhead_limit_was_exceeded);
-
- HeapWord *satisfy_failed_allocation(size_t size, bool is_tlab);
-
- // Adaptive size policy
- AdaptiveSizePolicy* size_policy() { return _size_policy; }
-
- virtual void initialize_size_policy(size_t init_eden_size,
- size_t init_promo_size,
- size_t init_survivor_size);
-
- virtual void cleared_all_soft_refs();
-
};
class MarkSweepPolicy : public GenCollectorPolicy {
protected:
void initialize_alignments();
- void initialize_generations();
public:
MarkSweepPolicy() {}
-
- MarkSweepPolicy* as_mark_sweep_policy() { return this; }
-
- void initialize_gc_policy_counters();
};
#endif // SHARE_VM_GC_SHARED_COLLECTORPOLICY_HPP
diff --git a/src/hotspot/share/gc/shared/gcCause.cpp b/src/hotspot/share/gc/shared/gcCause.cpp
index 91bb436c547..cc8b216ff7c 100644
--- a/src/hotspot/share/gc/shared/gcCause.cpp
+++ b/src/hotspot/share/gc/shared/gcCause.cpp
@@ -60,10 +60,6 @@ const char* GCCause::to_string(GCCause::Cause cause) {
case _wb_full_gc:
return "WhiteBox Initiated Full GC";
- case _update_allocation_context_stats_inc:
- case _update_allocation_context_stats_full:
- return "Update Allocation Context Stats";
-
case _no_gc:
return "No GC";
diff --git a/src/hotspot/share/gc/shared/gcCause.hpp b/src/hotspot/share/gc/shared/gcCause.hpp
index 3ff7b53e92a..7bedce85a49 100644
--- a/src/hotspot/share/gc/shared/gcCause.hpp
+++ b/src/hotspot/share/gc/shared/gcCause.hpp
@@ -52,8 +52,6 @@ class GCCause : public AllStatic {
_wb_young_gc,
_wb_conc_mark,
_wb_full_gc,
- _update_allocation_context_stats_inc,
- _update_allocation_context_stats_full,
/* implementation independent, but reserved for GC use */
_no_gc,
diff --git a/src/hotspot/share/gc/shared/gcId.cpp b/src/hotspot/share/gc/shared/gcId.cpp
index cc1d83bf587..f48812c6770 100644
--- a/src/hotspot/share/gc/shared/gcId.cpp
+++ b/src/hotspot/share/gc/shared/gcId.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,27 +35,28 @@ NamedThread* currentNamedthread() {
return (NamedThread*)Thread::current();
}
-const uint GCId::create() {
+uint GCId::create() {
return _next_id++;
}
-const uint GCId::peek() {
+uint GCId::peek() {
return _next_id;
}
-const uint GCId::current() {
- assert(currentNamedthread()->gc_id() != undefined(), "Using undefined GC id.");
- return current_raw();
+uint GCId::current() {
+ const uint gc_id = currentNamedthread()->gc_id();
+ assert(gc_id != undefined(), "Using undefined GC id.");
+ return gc_id;
}
-const uint GCId::current_raw() {
- return currentNamedthread()->gc_id();
+uint GCId::current_or_undefined() {
+ return Thread::current()->is_Named_thread() ? currentNamedthread()->gc_id() : undefined();
}
size_t GCId::print_prefix(char* buf, size_t len) {
Thread* thread = Thread::current_or_null();
- if (thread != NULL && thread->is_Named_thread()) {
- uint gc_id = current_raw();
+ if (thread != NULL) {
+ uint gc_id = current_or_undefined();
if (gc_id != undefined()) {
int ret = jio_snprintf(buf, len, "GC(%u) ", gc_id);
assert(ret > 0, "Failed to print prefix. Log buffer too small?");
@@ -65,28 +66,14 @@ size_t GCId::print_prefix(char* buf, size_t len) {
return 0;
}
-GCIdMark::GCIdMark() : _gc_id(GCId::create()) {
- currentNamedthread()->set_gc_id(_gc_id);
+GCIdMark::GCIdMark() : _previous_gc_id(currentNamedthread()->gc_id()) {
+ currentNamedthread()->set_gc_id(GCId::create());
}
-GCIdMark::GCIdMark(uint gc_id) : _gc_id(gc_id) {
- currentNamedthread()->set_gc_id(_gc_id);
+GCIdMark::GCIdMark(uint gc_id) : _previous_gc_id(currentNamedthread()->gc_id()) {
+ currentNamedthread()->set_gc_id(gc_id);
}
GCIdMark::~GCIdMark() {
- currentNamedthread()->set_gc_id(GCId::undefined());
-}
-
-GCIdMarkAndRestore::GCIdMarkAndRestore() : _gc_id(GCId::create()) {
- _previous_gc_id = GCId::current_raw();
- currentNamedthread()->set_gc_id(_gc_id);
-}
-
-GCIdMarkAndRestore::GCIdMarkAndRestore(uint gc_id) : _gc_id(gc_id) {
- _previous_gc_id = GCId::current_raw();
- currentNamedthread()->set_gc_id(_gc_id);
-}
-
-GCIdMarkAndRestore::~GCIdMarkAndRestore() {
currentNamedthread()->set_gc_id(_previous_gc_id);
}
diff --git a/src/hotspot/share/gc/shared/gcId.hpp b/src/hotspot/share/gc/shared/gcId.hpp
index f8ac5b3db89..648fae834e7 100644
--- a/src/hotspot/share/gc/shared/gcId.hpp
+++ b/src/hotspot/share/gc/shared/gcId.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,38 +28,32 @@
#include "memory/allocation.hpp"
class GCId : public AllStatic {
+private:
friend class GCIdMark;
- friend class GCIdMarkAndRestore;
+
static uint _next_id;
static const uint UNDEFINED = (uint)-1;
- static const uint create();
+ static uint create();
- public:
+public:
// Returns the currently active GC id. Asserts that there is an active GC id.
- static const uint current();
+ static uint current();
// Same as current() but can return undefined() if no GC id is currently active
- static const uint current_raw();
+ static uint current_or_undefined();
// Returns the next expected GCId.
- static const uint peek();
- static const uint undefined() { return UNDEFINED; }
+ static uint peek();
+ static uint undefined() { return UNDEFINED; }
static size_t print_prefix(char* buf, size_t len);
};
class GCIdMark : public StackObj {
- uint _gc_id;
- public:
+private:
+ const uint _previous_gc_id;
+
+public:
GCIdMark();
GCIdMark(uint gc_id);
~GCIdMark();
};
-class GCIdMarkAndRestore : public StackObj {
- uint _gc_id;
- uint _previous_gc_id;
- public:
- GCIdMarkAndRestore();
- GCIdMarkAndRestore(uint gc_id);
- ~GCIdMarkAndRestore();
-};
-
#endif // SHARE_VM_GC_SHARED_GCID_HPP
diff --git a/src/hotspot/share/gc/shared/gcTimer.cpp b/src/hotspot/share/gc/shared/gcTimer.cpp
index a13e7a8c5dd..c17cd184586 100644
--- a/src/hotspot/share/gc/shared/gcTimer.cpp
+++ b/src/hotspot/share/gc/shared/gcTimer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -68,14 +68,14 @@ void STWGCTimer::register_gc_end(const Ticks& time) {
GCTimer::register_gc_end(time);
}
-void ConcurrentGCTimer::register_gc_pause_start(const char* name) {
+void ConcurrentGCTimer::register_gc_pause_start(const char* name, const Ticks& time) {
assert(!_is_concurrent_phase_active, "A pause phase can't be started while a concurrent phase is active.");
- GCTimer::register_gc_pause_start(name);
+ GCTimer::register_gc_pause_start(name, time);
}
-void ConcurrentGCTimer::register_gc_pause_end() {
+void ConcurrentGCTimer::register_gc_pause_end(const Ticks& time) {
assert(!_is_concurrent_phase_active, "A pause phase can't be ended while a concurrent phase is active.");
- GCTimer::register_gc_pause_end();
+ GCTimer::register_gc_pause_end(time);
}
void ConcurrentGCTimer::register_gc_concurrent_start(const char* name, const Ticks& time) {
diff --git a/src/hotspot/share/gc/shared/gcTimer.hpp b/src/hotspot/share/gc/shared/gcTimer.hpp
index 14f397dd408..d8834cfee63 100644
--- a/src/hotspot/share/gc/shared/gcTimer.hpp
+++ b/src/hotspot/share/gc/shared/gcTimer.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -166,8 +166,8 @@ class ConcurrentGCTimer : public GCTimer {
public:
ConcurrentGCTimer(): GCTimer(), _is_concurrent_phase_active(false) {};
- void register_gc_pause_start(const char* name);
- void register_gc_pause_end();
+ void register_gc_pause_start(const char* name, const Ticks& time = Ticks::now());
+ void register_gc_pause_end(const Ticks& time = Ticks::now());
void register_gc_concurrent_start(const char* name, const Ticks& time = Ticks::now());
void register_gc_concurrent_end(const Ticks& time = Ticks::now());
diff --git a/src/hotspot/share/gc/shared/genCollectedHeap.cpp b/src/hotspot/share/gc/shared/genCollectedHeap.cpp
index 67356b78660..6f884cc6fe7 100644
--- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp
@@ -30,10 +30,14 @@
#include "classfile/vmSymbols.hpp"
#include "code/codeCache.hpp"
#include "code/icBuffer.hpp"
+#include "gc/shared/adaptiveSizePolicy.hpp"
+#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTableRS.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "gc/shared/collectorCounters.hpp"
#include "gc/shared/gcId.hpp"
#include "gc/shared/gcLocker.inline.hpp"
+#include "gc/shared/gcPolicyCounters.hpp"
#include "gc/shared/gcTrace.hpp"
#include "gc/shared/gcTraceTime.inline.hpp"
#include "gc/shared/genCollectedHeap.hpp"
@@ -60,14 +64,25 @@
#include "utilities/stack.inline.hpp"
#include "utilities/vmError.hpp"
-GenCollectedHeap::GenCollectedHeap(GenCollectorPolicy *policy) :
+GenCollectedHeap::GenCollectedHeap(GenCollectorPolicy *policy,
+ Generation::Name young,
+ Generation::Name old,
+ const char* policy_counters_name) :
CollectedHeap(),
_rem_set(NULL),
+ _young_gen_spec(new GenerationSpec(young,
+ policy->initial_young_size(),
+ policy->max_young_size(),
+ policy->gen_alignment())),
+ _old_gen_spec(new GenerationSpec(old,
+ policy->initial_old_size(),
+ policy->max_old_size(),
+ policy->gen_alignment())),
_gen_policy(policy),
+ _soft_ref_gen_policy(),
+ _gc_policy_counters(new GCPolicyCounters(policy_counters_name, 2, 2)),
_process_strong_tasks(new SubTasksDone(GCH_PS_NumElements)),
- _full_collections_completed(0)
-{
- assert(policy != NULL, "Sanity check");
+ _full_collections_completed(0) {
}
jint GenCollectedHeap::initialize() {
@@ -95,32 +110,43 @@ jint GenCollectedHeap::initialize() {
initialize_reserved_region((HeapWord*)heap_rs.base(), (HeapWord*)(heap_rs.base() + heap_rs.size()));
- _rem_set = collector_policy()->create_rem_set(reserved_region());
- set_barrier_set(rem_set()->bs());
+ _rem_set = new CardTableRS(reserved_region());
+ _rem_set->initialize();
+ CardTableModRefBS *bs = new CardTableModRefBS(_rem_set);
+ bs->initialize();
+ set_barrier_set(bs);
- ReservedSpace young_rs = heap_rs.first_part(gen_policy()->young_gen_spec()->max_size(), false, false);
- _young_gen = gen_policy()->young_gen_spec()->init(young_rs, rem_set());
- heap_rs = heap_rs.last_part(gen_policy()->young_gen_spec()->max_size());
+ ReservedSpace young_rs = heap_rs.first_part(_young_gen_spec->max_size(), false, false);
+ _young_gen = _young_gen_spec->init(young_rs, rem_set());
+ heap_rs = heap_rs.last_part(_young_gen_spec->max_size());
- ReservedSpace old_rs = heap_rs.first_part(gen_policy()->old_gen_spec()->max_size(), false, false);
- _old_gen = gen_policy()->old_gen_spec()->init(old_rs, rem_set());
+ ReservedSpace old_rs = heap_rs.first_part(_old_gen_spec->max_size(), false, false);
+ _old_gen = _old_gen_spec->init(old_rs, rem_set());
clear_incremental_collection_failed();
return JNI_OK;
}
+void GenCollectedHeap::initialize_size_policy(size_t init_eden_size,
+ size_t init_promo_size,
+ size_t init_survivor_size) {
+ const double max_gc_pause_sec = ((double) MaxGCPauseMillis) / 1000.0;
+ _size_policy = new AdaptiveSizePolicy(init_eden_size,
+ init_promo_size,
+ init_survivor_size,
+ max_gc_pause_sec,
+ GCTimeRatio);
+}
+
char* GenCollectedHeap::allocate(size_t alignment,
ReservedSpace* heap_rs){
// Now figure out the total size.
const size_t pageSize = UseLargePages ? os::large_page_size() : os::vm_page_size();
assert(alignment % pageSize == 0, "Must be");
- GenerationSpec* young_spec = gen_policy()->young_gen_spec();
- GenerationSpec* old_spec = gen_policy()->old_gen_spec();
-
// Check for overflow.
- size_t total_reserved = young_spec->max_size() + old_spec->max_size();
- if (total_reserved < young_spec->max_size()) {
+ size_t total_reserved = _young_gen_spec->max_size() + _old_gen_spec->max_size();
+ if (total_reserved < _young_gen_spec->max_size()) {
vm_exit_during_initialization("The size of the object heap + VM data exceeds "
"the maximum representable size");
}
@@ -146,10 +172,9 @@ void GenCollectedHeap::post_initialize() {
check_gen_kinds();
DefNewGeneration* def_new_gen = (DefNewGeneration*)_young_gen;
- _gen_policy->initialize_size_policy(def_new_gen->eden()->capacity(),
- _old_gen->capacity(),
- def_new_gen->from()->capacity());
- _gen_policy->initialize_gc_policy_counters();
+ initialize_size_policy(def_new_gen->eden()->capacity(),
+ _old_gen->capacity(),
+ def_new_gen->from()->capacity());
}
void GenCollectedHeap::ref_processing_init() {
@@ -157,6 +182,14 @@ void GenCollectedHeap::ref_processing_init() {
_old_gen->ref_processor_init();
}
+GenerationSpec* GenCollectedHeap::young_gen_spec() const {
+ return _young_gen_spec;
+}
+
+GenerationSpec* GenCollectedHeap::old_gen_spec() const {
+ return _old_gen_spec;
+}
+
size_t GenCollectedHeap::capacity() const {
return _young_gen->capacity() + _old_gen->capacity();
}
@@ -202,6 +235,157 @@ unsigned int GenCollectedHeap::update_full_collections_completed(unsigned int co
return _full_collections_completed;
}
+// Return true if any of the following is true:
+// . the allocation won't fit into the current young gen heap
+// . gc locker is occupied (jni critical section)
+// . heap memory is tight -- the most recent previous collection
+// was a full collection because a partial collection (would
+// have) failed and is likely to fail again
+bool GenCollectedHeap::should_try_older_generation_allocation(size_t word_size) const {
+ size_t young_capacity = young_gen()->capacity_before_gc();
+ return (word_size > heap_word_size(young_capacity))
+ || GCLocker::is_active_and_needs_gc()
+ || incremental_collection_failed();
+}
+
+HeapWord* GenCollectedHeap::expand_heap_and_allocate(size_t size, bool is_tlab) {
+ HeapWord* result = NULL;
+ if (old_gen()->should_allocate(size, is_tlab)) {
+ result = old_gen()->expand_and_allocate(size, is_tlab);
+ }
+ if (result == NULL) {
+ if (young_gen()->should_allocate(size, is_tlab)) {
+ result = young_gen()->expand_and_allocate(size, is_tlab);
+ }
+ }
+ assert(result == NULL || is_in_reserved(result), "result not in heap");
+ return result;
+}
+
+HeapWord* GenCollectedHeap::mem_allocate_work(size_t size,
+ bool is_tlab,
+ bool* gc_overhead_limit_was_exceeded) {
+ debug_only(check_for_valid_allocation_state());
+ assert(no_gc_in_progress(), "Allocation during gc not allowed");
+
+ // In general gc_overhead_limit_was_exceeded should be false so
+ // set it so here and reset it to true only if the gc time
+ // limit is being exceeded as checked below.
+ *gc_overhead_limit_was_exceeded = false;
+
+ HeapWord* result = NULL;
+
+ // Loop until the allocation is satisfied, or unsatisfied after GC.
+ for (uint try_count = 1, gclocker_stalled_count = 0; /* return or throw */; try_count += 1) {
+ HandleMark hm; // Discard any handles allocated in each iteration.
+
+ // First allocation attempt is lock-free.
+ Generation *young = young_gen();
+ assert(young->supports_inline_contig_alloc(),
+ "Otherwise, must do alloc within heap lock");
+ if (young->should_allocate(size, is_tlab)) {
+ result = young->par_allocate(size, is_tlab);
+ if (result != NULL) {
+ assert(is_in_reserved(result), "result not in heap");
+ return result;
+ }
+ }
+ uint gc_count_before; // Read inside the Heap_lock locked region.
+ {
+ MutexLocker ml(Heap_lock);
+ log_trace(gc, alloc)("GenCollectedHeap::mem_allocate_work: attempting locked slow path allocation");
+ // Note that only large objects get a shot at being
+ // allocated in later generations.
+ bool first_only = !should_try_older_generation_allocation(size);
+
+ result = attempt_allocation(size, is_tlab, first_only);
+ if (result != NULL) {
+ assert(is_in_reserved(result), "result not in heap");
+ return result;
+ }
+
+ if (GCLocker::is_active_and_needs_gc()) {
+ if (is_tlab) {
+ return NULL; // Caller will retry allocating individual object.
+ }
+ if (!is_maximal_no_gc()) {
+ // Try and expand heap to satisfy request.
+ result = expand_heap_and_allocate(size, is_tlab);
+ // Result could be null if we are out of space.
+ if (result != NULL) {
+ return result;
+ }
+ }
+
+ if (gclocker_stalled_count > GCLockerRetryAllocationCount) {
+ return NULL; // We didn't get to do a GC and we didn't get any memory.
+ }
+
+ // If this thread is not in a jni critical section, we stall
+ // the requestor until the critical section has cleared and
+ // GC allowed. When the critical section clears, a GC is
+ // initiated by the last thread exiting the critical section; so
+ // we retry the allocation sequence from the beginning of the loop,
+ // rather than causing more, now probably unnecessary, GC attempts.
+ JavaThread* jthr = JavaThread::current();
+ if (!jthr->in_critical()) {
+ MutexUnlocker mul(Heap_lock);
+ // Wait for JNI critical section to be exited
+ GCLocker::stall_until_clear();
+ gclocker_stalled_count += 1;
+ continue;
+ } else {
+ if (CheckJNICalls) {
+ fatal("Possible deadlock due to allocating while"
+ " in jni critical section");
+ }
+ return NULL;
+ }
+ }
+
+ // Read the gc count while the heap lock is held.
+ gc_count_before = total_collections();
+ }
+
+ VM_GenCollectForAllocation op(size, is_tlab, gc_count_before);
+ VMThread::execute(&op);
+ if (op.prologue_succeeded()) {
+ result = op.result();
+ if (op.gc_locked()) {
+ assert(result == NULL, "must be NULL if gc_locked() is true");
+ continue; // Retry and/or stall as necessary.
+ }
+
+ // Allocation has failed and a collection
+ // has been done. If the gc time limit was exceeded the
+ // this time, return NULL so that an out-of-memory
+ // will be thrown. Clear gc_overhead_limit_exceeded
+ // so that the overhead exceeded does not persist.
+
+ const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
+ const bool softrefs_clear = soft_ref_policy()->all_soft_refs_clear();
+
+ if (limit_exceeded && softrefs_clear) {
+ *gc_overhead_limit_was_exceeded = true;
+ size_policy()->set_gc_overhead_limit_exceeded(false);
+ if (op.result() != NULL) {
+ CollectedHeap::fill_with_object(op.result(), size);
+ }
+ return NULL;
+ }
+ assert(result == NULL || is_in_reserved(result),
+ "result not in heap");
+ return result;
+ }
+
+ // Give a warning if we seem to be looping forever.
+ if ((QueuedAllocationWarningCount > 0) &&
+ (try_count % QueuedAllocationWarningCount == 0)) {
+ log_warning(gc, ergo)("GenCollectedHeap::mem_allocate_work retries %d times,"
+ " size=" SIZE_FORMAT " %s", try_count, size, is_tlab ? "(TLAB)" : "");
+ }
+ }
+}
#ifndef PRODUCT
// Override of memory state checking method in CollectedHeap:
@@ -253,9 +437,9 @@ HeapWord* GenCollectedHeap::attempt_allocation(size_t size,
HeapWord* GenCollectedHeap::mem_allocate(size_t size,
bool* gc_overhead_limit_was_exceeded) {
- return gen_policy()->mem_allocate_work(size,
- false /* is_tlab */,
- gc_overhead_limit_was_exceeded);
+ return mem_allocate_work(size,
+ false /* is_tlab */,
+ gc_overhead_limit_was_exceeded);
}
bool GenCollectedHeap::must_clear_all_soft_refs() {
@@ -367,12 +551,12 @@ void GenCollectedHeap::do_collection(bool full,
return; // GC is disabled (e.g. JNI GetXXXCritical operation)
}
- GCIdMarkAndRestore gc_id_mark;
+ GCIdMark gc_id_mark;
const bool do_clear_all_soft_refs = clear_all_soft_refs ||
- collector_policy()->should_clear_all_soft_refs();
+ soft_ref_policy()->should_clear_all_soft_refs();
- ClearedAllSoftRefs casr(do_clear_all_soft_refs, collector_policy());
+ ClearedAllSoftRefs casr(do_clear_all_soft_refs, soft_ref_policy());
const size_t metadata_prev_used = MetaspaceAux::used_bytes();
@@ -442,7 +626,7 @@ void GenCollectedHeap::do_collection(bool full,
if (do_young_collection) {
// We did a young GC. Need a new GC id for the old GC.
- GCIdMarkAndRestore gc_id_mark;
+ GCIdMark gc_id_mark;
GCTraceTime(Info, gc) t("Pause Full", NULL, gc_cause(), true);
collect_generation(_old_gen, full, size, is_tlab, run_verification && VerifyGCLevel <= 1, do_clear_all_soft_refs, true);
} else {
@@ -503,7 +687,79 @@ void GenCollectedHeap::verify_nmethod(nmethod* nm) {
}
HeapWord* GenCollectedHeap::satisfy_failed_allocation(size_t size, bool is_tlab) {
- return gen_policy()->satisfy_failed_allocation(size, is_tlab);
+ GCCauseSetter x(this, GCCause::_allocation_failure);
+ HeapWord* result = NULL;
+
+ assert(size != 0, "Precondition violated");
+ if (GCLocker::is_active_and_needs_gc()) {
+ // GC locker is active; instead of a collection we will attempt
+ // to expand the heap, if there's room for expansion.
+ if (!is_maximal_no_gc()) {
+ result = expand_heap_and_allocate(size, is_tlab);
+ }
+ return result; // Could be null if we are out of space.
+ } else if (!incremental_collection_will_fail(false /* don't consult_young */)) {
+ // Do an incremental collection.
+ do_collection(false, // full
+ false, // clear_all_soft_refs
+ size, // size
+ is_tlab, // is_tlab
+ GenCollectedHeap::OldGen); // max_generation
+ } else {
+ log_trace(gc)(" :: Trying full because partial may fail :: ");
+ // Try a full collection; see delta for bug id 6266275
+ // for the original code and why this has been simplified
+ // with from-space allocation criteria modified and
+ // such allocation moved out of the safepoint path.
+ do_collection(true, // full
+ false, // clear_all_soft_refs
+ size, // size
+ is_tlab, // is_tlab
+ GenCollectedHeap::OldGen); // max_generation
+ }
+
+ result = attempt_allocation(size, is_tlab, false /*first_only*/);
+
+ if (result != NULL) {
+ assert(is_in_reserved(result), "result not in heap");
+ return result;
+ }
+
+ // OK, collection failed, try expansion.
+ result = expand_heap_and_allocate(size, is_tlab);
+ if (result != NULL) {
+ return result;
+ }
+
+ // If we reach this point, we're really out of memory. Try every trick
+ // we can to reclaim memory. Force collection of soft references. Force
+ // a complete compaction of the heap. Any additional methods for finding
+ // free memory should be here, especially if they are expensive. If this
+ // attempt fails, an OOM exception will be thrown.
+ {
+ UIntFlagSetting flag_change(MarkSweepAlwaysCompactCount, 1); // Make sure the heap is fully compacted
+
+ do_collection(true, // full
+ true, // clear_all_soft_refs
+ size, // size
+ is_tlab, // is_tlab
+ GenCollectedHeap::OldGen); // max_generation
+ }
+
+ result = attempt_allocation(size, is_tlab, false /* first_only */);
+ if (result != NULL) {
+ assert(is_in_reserved(result), "result not in heap");
+ return result;
+ }
+
+ assert(!soft_ref_policy()->should_clear_all_soft_refs(),
+ "Flag should have been handled and cleared prior to this point");
+
+ // What else? We might try synchronous finalization later. If the total
+ // space available is large enough for the allocation, then a more
+ // complete compaction phase than we've tried so far might be
+ // appropriate.
+ return NULL;
}
#ifdef ASSERT
@@ -886,9 +1142,9 @@ size_t GenCollectedHeap::unsafe_max_tlab_alloc(Thread* thr) const {
HeapWord* GenCollectedHeap::allocate_new_tlab(size_t size) {
bool gc_overhead_limit_was_exceeded;
- return gen_policy()->mem_allocate_work(size /* size */,
- true /* is_tlab */,
- &gc_overhead_limit_was_exceeded);
+ return mem_allocate_work(size /* size */,
+ true /* is_tlab */,
+ &gc_overhead_limit_was_exceeded);
}
// Requires "*prev_ptr" to be non-NULL. Deletes and a block of minimal size
diff --git a/src/hotspot/share/gc/shared/genCollectedHeap.hpp b/src/hotspot/share/gc/shared/genCollectedHeap.hpp
index bcdd36a5e89..b571c777a2c 100644
--- a/src/hotspot/share/gc/shared/genCollectedHeap.hpp
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.hpp
@@ -25,11 +25,14 @@
#ifndef SHARE_VM_GC_SHARED_GENCOLLECTEDHEAP_HPP
#define SHARE_VM_GC_SHARED_GENCOLLECTEDHEAP_HPP
-#include "gc/shared/adaptiveSizePolicy.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "gc/shared/collectorPolicy.hpp"
#include "gc/shared/generation.hpp"
+#include "gc/shared/softRefGenPolicy.hpp"
+class AdaptiveSizePolicy;
+class GCPolicyCounters;
+class GenerationSpec;
class StrongRootsScope;
class SubTasksDone;
class WorkGang;
@@ -64,12 +67,22 @@ private:
Generation* _young_gen;
Generation* _old_gen;
+ GenerationSpec* _young_gen_spec;
+ GenerationSpec* _old_gen_spec;
+
// The singleton CardTable Remembered Set.
CardTableRS* _rem_set;
// The generational collector policy.
GenCollectorPolicy* _gen_policy;
+ SoftRefGenPolicy _soft_ref_gen_policy;
+
+ // The sizing of the heap is controlled by a sizing policy.
+ AdaptiveSizePolicy* _size_policy;
+
+ GCPolicyCounters* _gc_policy_counters;
+
// Indicates that the most recent previous incremental collection failed.
// The flag is cleared when an action is taken that might clear the
// condition that caused that incremental collection to fail.
@@ -143,7 +156,10 @@ protected:
// we absolutely __must__ clear soft refs?
bool must_clear_all_soft_refs();
- GenCollectedHeap(GenCollectorPolicy *policy);
+ GenCollectedHeap(GenCollectorPolicy *policy,
+ Generation::Name young,
+ Generation::Name old,
+ const char* policy_counters_name);
virtual void check_gen_kinds() = 0;
@@ -152,6 +168,10 @@ public:
// Returns JNI_OK on success
virtual jint initialize();
+ void initialize_size_policy(size_t init_eden_size,
+ size_t init_promo_size,
+ size_t init_survivor_size);
+
// Does operations required after initialization has been done.
void post_initialize();
@@ -161,16 +181,24 @@ public:
bool is_young_gen(const Generation* gen) const { return gen == _young_gen; }
bool is_old_gen(const Generation* gen) const { return gen == _old_gen; }
+ GenerationSpec* young_gen_spec() const;
+ GenerationSpec* old_gen_spec() const;
+
// The generational collector policy.
GenCollectorPolicy* gen_policy() const { return _gen_policy; }
virtual CollectorPolicy* collector_policy() const { return gen_policy(); }
+ virtual SoftRefPolicy* soft_ref_policy() { return &_soft_ref_gen_policy; }
+
// Adaptive size policy
virtual AdaptiveSizePolicy* size_policy() {
- return gen_policy()->size_policy();
+ return _size_policy;
}
+ // Performance Counter support
+ GCPolicyCounters* counters() { return _gc_policy_counters; }
+
// Return the (conservative) maximum heap alignment
static size_t conservative_max_heap_alignment() {
return Generation::GenGrain;
@@ -456,6 +484,17 @@ public:
private:
+ // Return true if an allocation should be attempted in the older generation
+ // if it fails in the younger generation. Return false, otherwise.
+ bool should_try_older_generation_allocation(size_t word_size) const;
+
+ // Try to allocate space by expanding the heap.
+ HeapWord* expand_heap_and_allocate(size_t size, bool is_tlab);
+
+ HeapWord* mem_allocate_work(size_t size,
+ bool is_tlab,
+ bool* gc_overhead_limit_was_exceeded);
+
// Override
void check_for_non_bad_heap_word_value(HeapWord* addr,
size_t size) PRODUCT_RETURN;
diff --git a/src/hotspot/share/gc/shared/generation.cpp b/src/hotspot/share/gc/shared/generation.cpp
index fbdb2f45b3f..3f3b68ac1f2 100644
--- a/src/hotspot/share/gc/shared/generation.cpp
+++ b/src/hotspot/share/gc/shared/generation.cpp
@@ -63,9 +63,9 @@ Generation::Generation(ReservedSpace rs, size_t initial_size) :
size_t Generation::initial_size() {
GenCollectedHeap* gch = GenCollectedHeap::heap();
if (gch->is_young_gen(this)) {
- return gch->gen_policy()->young_gen_spec()->init_size();
+ return gch->young_gen_spec()->init_size();
}
- return gch->gen_policy()->old_gen_spec()->init_size();
+ return gch->old_gen_spec()->init_size();
}
size_t Generation::max_capacity() const {
diff --git a/src/hotspot/share/gc/shared/modRefBarrierSet.hpp b/src/hotspot/share/gc/shared/modRefBarrierSet.hpp
index 26ce93f716c..7e4e7a5138c 100644
--- a/src/hotspot/share/gc/shared/modRefBarrierSet.hpp
+++ b/src/hotspot/share/gc/shared/modRefBarrierSet.hpp
@@ -47,10 +47,6 @@ public:
virtual void invalidate(MemRegion mr) = 0;
virtual void write_region(MemRegion mr) = 0;
- // The caller guarantees that "mr" contains no references. (Perhaps it's
- // objects have been moved elsewhere.)
- virtual void clear(MemRegion mr) = 0;
-
// The ModRef abstraction introduces pre and post barriers
template
class AccessBarrier: public BarrierSet::AccessBarrier {
diff --git a/src/hotspot/share/gc/shared/oopStorageParState.hpp b/src/hotspot/share/gc/shared/oopStorageParState.hpp
new file mode 100644
index 00000000000..d418334db63
--- /dev/null
+++ b/src/hotspot/share/gc/shared/oopStorageParState.hpp
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_SHARED_OOPSTORAGEPARSTATE_HPP
+#define SHARE_GC_SHARED_OOPSTORAGEPARSTATE_HPP
+
+#include "gc/shared/oopStorage.hpp"
+#include "memory/allocation.hpp"
+#include "utilities/macros.hpp"
+
+#if INCLUDE_ALL_GCS
+
+//////////////////////////////////////////////////////////////////////////////
+// Support for parallel and optionally concurrent state iteration.
+//
+// Parallel iteration is for the exclusive use of the GC. Other iteration
+// clients must use serial iteration.
+//
+// Concurrent Iteration
+//
+// Iteration involves the _active_list, which contains all of the blocks owned
+// by a storage object. This is a doubly-linked list, linked through
+// dedicated fields in the blocks.
+//
+// At most one concurrent ParState can exist at a time for a given storage
+// object.
+//
+// A concurrent ParState sets the associated storage's
+// _concurrent_iteration_active flag true when the state is constructed, and
+// sets it false when the state is destroyed. These assignments are made with
+// _active_mutex locked. Meanwhile, empty block deletion is not done while
+// _concurrent_iteration_active is true. The flag check and the dependent
+// removal of a block from the _active_list is performed with _active_mutex
+// locked. This prevents concurrent iteration and empty block deletion from
+// interfering with with each other.
+//
+// Both allocate() and delete_empty_blocks_concurrent() lock the
+// _allocate_mutex while performing their respective list manipulations,
+// preventing them from interfering with each other.
+//
+// When allocate() creates a new block, it is added to the front of the
+// _active_list. Then _active_head is set to the new block. When concurrent
+// iteration is started (by a parallel worker thread calling the state's
+// iterate() function), the current _active_head is used as the initial block
+// for the iteration, with iteration proceeding down the list headed by that
+// block.
+//
+// As a result, the list over which concurrent iteration operates is stable.
+// However, once the iteration is started, later allocations may add blocks to
+// the front of the list that won't be examined by the iteration. And while
+// the list is stable, concurrent allocate() and release() operations may
+// change the set of allocated entries in a block at any time during the
+// iteration.
+//
+// As a result, a concurrent iteration handler must accept that some
+// allocations and releases that occur after the iteration started will not be
+// seen by the iteration. Further, some may overlap examination by the
+// iteration. To help with this, allocate() and release() have an invariant
+// that an entry's value must be NULL when it is not in use.
+//
+// An in-progress delete_empty_blocks_concurrent() operation can contend with
+// the start of a concurrent iteration over the _active_mutex. Since both are
+// under GC control, that potential contention can be eliminated by never
+// scheduling both operations to run at the same time.
+//
+// ParState
+// concurrent must be true if iteration is concurrent with the
+// mutator, false if iteration is at a safepoint.
+//
+// is_const must be true if the iteration is over a constant storage
+// object, false if the iteration may modify the storage object.
+//
+// ParState([const] OopStorage* storage)
+// Construct an object for managing an iteration over storage. For a
+// concurrent ParState, empty block deletion for the associated storage
+// is inhibited for the life of the ParState. There can be no more
+// than one live concurrent ParState at a time for a given storage object.
+//
+// template void iterate(F f)
+// Repeatedly claims a block from the associated storage that has
+// not been processed by this iteration (possibly by other threads),
+// and applies f to each entry in the claimed block. Assume p is of
+// type const oop* or oop*, according to is_const. Then f(p) must be
+// a valid expression whose value is ignored. Concurrent uses must
+// be prepared for an entry's value to change at any time, due to
+// mutator activity.
+//
+// template void oops_do(Closure* cl)
+// Wrapper around iterate, providing an adaptation layer allowing
+// the use of OopClosures and similar objects for iteration. Assume
+// p is of type const oop* or oop*, according to is_const. Then
+// cl->do_oop(p) must be a valid expression whose value is ignored.
+// Concurrent uses must be prepared for the entry's value to change
+// at any time, due to mutator activity.
+//
+// Optional operations, provided only if !concurrent && !is_const.
+// These are not provided when is_const, because the storage object
+// may be modified by the iteration infrastructure, even if the
+// provided closure doesn't modify the storage object. These are not
+// provided when concurrent because any pre-filtering behavior by the
+// iteration infrastructure is inappropriate for concurrent iteration;
+// modifications of the storage by the mutator could result in the
+// pre-filtering being applied (successfully or not) to objects that
+// are unrelated to what the closure finds in the entry.
+//
+// template void weak_oops_do(Closure* cl)
+// template
+// void weak_oops_do(IsAliveClosure* is_alive, Closure* cl)
+// Wrappers around iterate, providing an adaptation layer allowing
+// the use of is-alive closures and OopClosures for iteration.
+// Assume p is of type oop*. Then
+//
+// - cl->do_oop(p) must be a valid expression whose value is ignored.
+//
+// - is_alive->do_object_b(*p) must be a valid expression whose value
+// is convertible to bool.
+//
+// If *p == NULL then neither is_alive nor cl will be invoked for p.
+// If is_alive->do_object_b(*p) is false, then cl will not be
+// invoked on p.
+
+class OopStorage::BasicParState VALUE_OBJ_CLASS_SPEC {
+ OopStorage* _storage;
+ void* volatile _next_block;
+ bool _concurrent;
+
+ // Noncopyable.
+ BasicParState(const BasicParState&);
+ BasicParState& operator=(const BasicParState&);
+
+ void update_iteration_state(bool value);
+ void ensure_iteration_started();
+ Block* claim_next_block();
+
+ // Wrapper for iteration handler; ignore handler result and return true.
+ template class AlwaysTrueFn;
+
+public:
+ BasicParState(OopStorage* storage, bool concurrent);
+ ~BasicParState();
+
+ template void iterate(F f);
+};
+
+template
+class OopStorage::ParState VALUE_OBJ_CLASS_SPEC {
+ BasicParState _basic_state;
+
+public:
+ ParState(const OopStorage* storage) :
+ // For simplicity, always recorded as non-const.
+ _basic_state(const_cast(storage), concurrent)
+ {}
+
+ template void iterate(F f);
+ template void oops_do(Closure* cl);
+};
+
+template<>
+class OopStorage::ParState VALUE_OBJ_CLASS_SPEC {
+ BasicParState _basic_state;
+
+public:
+ ParState(OopStorage* storage) :
+ _basic_state(storage, false)
+ {}
+
+ template void iterate(F f);
+ template void oops_do(Closure* cl);
+ template void weak_oops_do(Closure* cl);
+ template
+ void weak_oops_do(IsAliveClosure* is_alive, Closure* cl);
+};
+
+#endif // INCLUDE_ALL_GCS
+
+#endif // SHARE_GC_SHARED_OOPSTORAGEPARSTATE_HPP
diff --git a/src/hotspot/share/gc/shared/oopStorageParState.inline.hpp b/src/hotspot/share/gc/shared/oopStorageParState.inline.hpp
index 4779d6605b4..c4107726591 100644
--- a/src/hotspot/share/gc/shared/oopStorageParState.inline.hpp
+++ b/src/hotspot/share/gc/shared/oopStorageParState.inline.hpp
@@ -26,152 +26,13 @@
#define SHARE_GC_SHARED_OOPSTORAGEPARSTATE_INLINE_HPP
#include "gc/shared/oopStorage.inline.hpp"
+#include "gc/shared/oopStorageParState.hpp"
#include "memory/allocation.hpp"
#include "metaprogramming/conditional.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
-//////////////////////////////////////////////////////////////////////////////
-// Support for parallel and optionally concurrent state iteration.
-//
-// Parallel iteration is for the exclusive use of the GC. Other iteration
-// clients must use serial iteration.
-//
-// Concurrent Iteration
-//
-// Iteration involves the _active_list, which contains all of the blocks owned
-// by a storage object. This is a doubly-linked list, linked through
-// dedicated fields in the blocks.
-//
-// At most one concurrent ParState can exist at a time for a given storage
-// object.
-//
-// A concurrent ParState sets the associated storage's
-// _concurrent_iteration_active flag true when the state is constructed, and
-// sets it false when the state is destroyed. These assignments are made with
-// _active_mutex locked. Meanwhile, empty block deletion is not done while
-// _concurrent_iteration_active is true. The flag check and the dependent
-// removal of a block from the _active_list is performed with _active_mutex
-// locked. This prevents concurrent iteration and empty block deletion from
-// interfering with with each other.
-//
-// Both allocate() and delete_empty_blocks_concurrent() lock the
-// _allocate_mutex while performing their respective list manipulations,
-// preventing them from interfering with each other.
-//
-// When allocate() creates a new block, it is added to the front of the
-// _active_list. Then _active_head is set to the new block. When concurrent
-// iteration is started (by a parallel worker thread calling the state's
-// iterate() function), the current _active_head is used as the initial block
-// for the iteration, with iteration proceeding down the list headed by that
-// block.
-//
-// As a result, the list over which concurrent iteration operates is stable.
-// However, once the iteration is started, later allocations may add blocks to
-// the front of the list that won't be examined by the iteration. And while
-// the list is stable, concurrent allocate() and release() operations may
-// change the set of allocated entries in a block at any time during the
-// iteration.
-//
-// As a result, a concurrent iteration handler must accept that some
-// allocations and releases that occur after the iteration started will not be
-// seen by the iteration. Further, some may overlap examination by the
-// iteration. To help with this, allocate() and release() have an invariant
-// that an entry's value must be NULL when it is not in use.
-//
-// An in-progress delete_empty_blocks_concurrent() operation can contend with
-// the start of a concurrent iteration over the _active_mutex. Since both are
-// under GC control, that potential contention can be eliminated by never
-// scheduling both operations to run at the same time.
-//
-// ParState
-// concurrent must be true if iteration is concurrent with the
-// mutator, false if iteration is at a safepoint.
-//
-// is_const must be true if the iteration is over a constant storage
-// object, false if the iteration may modify the storage object.
-//
-// ParState([const] OopStorage* storage)
-// Construct an object for managing an iteration over storage. For a
-// concurrent ParState, empty block deletion for the associated storage
-// is inhibited for the life of the ParState. There can be no more
-// than one live concurrent ParState at a time for a given storage object.
-//
-// template void iterate(F f)
-// Repeatedly claims a block from the associated storage that has
-// not been processed by this iteration (possibly by other threads),
-// and applies f to each entry in the claimed block. Assume p is of
-// type const oop* or oop*, according to is_const. Then f(p) must be
-// a valid expression whose value is ignored. Concurrent uses must
-// be prepared for an entry's value to change at any time, due to
-// mutator activity.
-//
-// template void oops_do(Closure* cl)
-// Wrapper around iterate, providing an adaptation layer allowing
-// the use of OopClosures and similar objects for iteration. Assume
-// p is of type const oop* or oop*, according to is_const. Then
-// cl->do_oop(p) must be a valid expression whose value is ignored.
-// Concurrent uses must be prepared for the entry's value to change
-// at any time, due to mutator activity.
-//
-// Optional operations, provided only if !concurrent && !is_const.
-// These are not provided when is_const, because the storage object
-// may be modified by the iteration infrastructure, even if the
-// provided closure doesn't modify the storage object. These are not
-// provided when concurrent because any pre-filtering behavior by the
-// iteration infrastructure is inappropriate for concurrent iteration;
-// modifications of the storage by the mutator could result in the
-// pre-filtering being applied (successfully or not) to objects that
-// are unrelated to what the closure finds in the entry.
-//
-// template void weak_oops_do(Closure* cl)
-// template
-// void weak_oops_do(IsAliveClosure* is_alive, Closure* cl)
-// Wrappers around iterate, providing an adaptation layer allowing
-// the use of is-alive closures and OopClosures for iteration.
-// Assume p is of type oop*. Then
-//
-// - cl->do_oop(p) must be a valid expression whose value is ignored.
-//
-// - is_alive->do_object_b(*p) must be a valid expression whose value
-// is convertible to bool.
-//
-// If *p == NULL then neither is_alive nor cl will be invoked for p.
-// If is_alive->do_object_b(*p) is false, then cl will not be
-// invoked on p.
-
-class OopStorage::BasicParState VALUE_OBJ_CLASS_SPEC {
- OopStorage* _storage;
- void* volatile _next_block;
- bool _concurrent;
-
- // Noncopyable.
- BasicParState(const BasicParState&);
- BasicParState& operator=(const BasicParState&);
-
- void update_iteration_state(bool value);
- void ensure_iteration_started();
- Block* claim_next_block();
-
- // Wrapper for iteration handler; ignore handler result and return true.
- template class AlwaysTrueFn;
-
-public:
- BasicParState(OopStorage* storage, bool concurrent);
- ~BasicParState();
-
- template void iterate(F f) {
- // Wrap f in ATF so we can use Block::iterate.
- AlwaysTrueFn atf_f(f);
- ensure_iteration_started();
- typename Conditional::type block;
- while ((block = claim_next_block()) != NULL) {
- block->iterate(atf_f);
- }
- }
-};
-
template
class OopStorage::BasicParState::AlwaysTrueFn VALUE_OBJ_CLASS_SPEC {
F _f;
@@ -183,57 +44,49 @@ public:
bool operator()(OopPtr ptr) const { _f(ptr); return true; }
};
+template
+inline void OopStorage::BasicParState::iterate(F f) {
+ // Wrap f in ATF so we can use Block::iterate.
+ AlwaysTrueFn atf_f(f);
+ ensure_iteration_started();
+ typename Conditional::type block;
+ while ((block = claim_next_block()) != NULL) {
+ block->iterate(atf_f);
+ }
+}
+
template
-class OopStorage::ParState VALUE_OBJ_CLASS_SPEC {
- BasicParState _basic_state;
+template
+inline void OopStorage::ParState::iterate(F f) {
+ _basic_state.template iterate(f);
+}
-public:
- ParState(const OopStorage* storage) :
- // For simplicity, always recorded as non-const.
- _basic_state(const_cast(storage), concurrent)
- {}
+template
+template
+inline void OopStorage::ParState::oops_do(Closure* cl) {
+ this->iterate(oop_fn(cl));
+}
- template
- void iterate(F f) {
- _basic_state.template iterate(f);
- }
+template
+inline void OopStorage::ParState::iterate(F f) {
+ _basic_state.template iterate(f);
+}
- template
- void oops_do(Closure* cl) {
- this->iterate(oop_fn(cl));
- }
-};
+template
+inline void OopStorage::ParState::oops_do(Closure* cl) {
+ this->iterate(oop_fn(cl));
+}
-template<>
-class OopStorage::ParState VALUE_OBJ_CLASS_SPEC {
- BasicParState _basic_state;
+template
+inline void OopStorage::ParState::weak_oops_do(Closure* cl) {
+ this->iterate(skip_null_fn(oop_fn(cl)));
+}
-public:
- ParState(OopStorage* storage) :
- _basic_state(storage, false)
- {}
-
- template
- void iterate(F f) {
- _basic_state.template iterate(f);
- }
-
- template
- void oops_do(Closure* cl) {
- this->iterate(oop_fn(cl));
- }
-
- template
- void weak_oops_do(Closure* cl) {
- this->iterate(skip_null_fn(oop_fn(cl)));
- }
-
- template
- void weak_oops_do(IsAliveClosure* is_alive, Closure* cl) {
- this->iterate(if_alive_fn(is_alive, oop_fn(cl)));
- }
-};
+template
+inline void OopStorage::ParState::weak_oops_do(IsAliveClosure* is_alive, Closure* cl) {
+ this->iterate(if_alive_fn(is_alive, oop_fn(cl)));
+}
#endif // INCLUDE_ALL_GCS
-#endif // include guard
+#endif // SHARE_GC_SHARED_OOPSTORAGEPARSTATE_INLINE_HPP
diff --git a/src/hotspot/share/gc/shared/referenceProcessor.cpp b/src/hotspot/share/gc/shared/referenceProcessor.cpp
index b5e29581719..4d6933cf4c3 100644
--- a/src/hotspot/share/gc/shared/referenceProcessor.cpp
+++ b/src/hotspot/share/gc/shared/referenceProcessor.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -363,12 +363,12 @@ void ReferenceProcessor::enqueue_discovered_reflists(AbstractRefProcTaskExecutor
}
void DiscoveredListIterator::load_ptrs(DEBUG_ONLY(bool allow_null_referent)) {
- _discovered_addr = java_lang_ref_Reference::discovered_addr(_ref);
+ _discovered_addr = java_lang_ref_Reference::discovered_addr_raw(_ref);
oop discovered = java_lang_ref_Reference::discovered(_ref);
assert(_discovered_addr && oopDesc::is_oop_or_null(discovered),
"Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered));
_next = discovered;
- _referent_addr = java_lang_ref_Reference::referent_addr(_ref);
+ _referent_addr = java_lang_ref_Reference::referent_addr_raw(_ref);
_referent = java_lang_ref_Reference::referent(_ref);
assert(Universe::heap()->is_in_reserved_or_null(_referent),
"Wrong oop found in java.lang.Reference object");
@@ -494,7 +494,7 @@ ReferenceProcessor::pp2_work_concurrent_discovery(DiscoveredList& refs_list,
DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
while (iter.has_next()) {
iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
- HeapWord* next_addr = java_lang_ref_Reference::next_addr(iter.obj());
+ HeapWord* next_addr = java_lang_ref_Reference::next_addr_raw(iter.obj());
oop next = java_lang_ref_Reference::next(iter.obj());
if ((iter.referent() == NULL || iter.is_referent_alive() ||
next != NULL)) {
@@ -1019,7 +1019,7 @@ bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) {
ResourceMark rm; // Needed for tracing.
- HeapWord* const discovered_addr = java_lang_ref_Reference::discovered_addr(obj);
+ HeapWord* const discovered_addr = java_lang_ref_Reference::discovered_addr_raw(obj);
const oop discovered = java_lang_ref_Reference::discovered(obj);
assert(oopDesc::is_oop_or_null(discovered), "Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered));
if (discovered != NULL) {
@@ -1186,10 +1186,10 @@ ReferenceProcessor::preclean_discovered_reflist(DiscoveredList& refs_list,
// Keep alive its cohort.
iter.make_referent_alive();
if (UseCompressedOops) {
- narrowOop* next_addr = (narrowOop*)java_lang_ref_Reference::next_addr(obj);
+ narrowOop* next_addr = (narrowOop*)java_lang_ref_Reference::next_addr_raw(obj);
keep_alive->do_oop(next_addr);
} else {
- oop* next_addr = (oop*)java_lang_ref_Reference::next_addr(obj);
+ oop* next_addr = (oop*)java_lang_ref_Reference::next_addr_raw(obj);
keep_alive->do_oop(next_addr);
}
iter.move_to_next();
diff --git a/src/hotspot/share/gc/shared/softRefGenPolicy.cpp b/src/hotspot/share/gc/shared/softRefGenPolicy.cpp
new file mode 100644
index 00000000000..8d512fc200c
--- /dev/null
+++ b/src/hotspot/share/gc/shared/softRefGenPolicy.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/shared/adaptiveSizePolicy.hpp"
+#include "gc/shared/genCollectedHeap.hpp"
+#include "gc/shared/softRefGenPolicy.hpp"
+
+void SoftRefGenPolicy::cleared_all_soft_refs() {
+ // If near gc overhear limit, continue to clear SoftRefs. SoftRefs may
+ // have been cleared in the last collection but if the gc overhear
+ // limit continues to be near, SoftRefs should still be cleared.
+ AdaptiveSizePolicy* size_policy = GenCollectedHeap::heap()->size_policy();
+ if (size_policy != NULL) {
+ set_should_clear_all_soft_refs(size_policy->gc_overhead_limit_near());
+ }
+
+ SoftRefPolicy::cleared_all_soft_refs();
+}
diff --git a/src/hotspot/share/services/allocationContextService.hpp b/src/hotspot/share/gc/shared/softRefGenPolicy.hpp
similarity index 65%
rename from src/hotspot/share/services/allocationContextService.hpp
rename to src/hotspot/share/gc/shared/softRefGenPolicy.hpp
index fa634c5ecc8..02492dde2bd 100644
--- a/src/hotspot/share/services/allocationContextService.hpp
+++ b/src/hotspot/share/gc/shared/softRefGenPolicy.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,18 +22,17 @@
*
*/
-#ifndef SHARE_VM_SERVICES_ALLOCATION_CONTEXT_SERVICE_HPP
-#define SHARE_VM_SERVICES_ALLOCATION_CONTEXT_SERVICE_HPP
+#ifndef SHARE_VM_GC_SHARED_SOFTREFGENPOLICY_HPP
+#define SHARE_VM_GC_SHARED_SOFTREFGENPOLICY_HPP
-#include "utilities/exceptions.hpp"
+#include "gc/shared/softRefPolicy.hpp"
+#include "utilities/globalDefinitions.hpp"
-class AllocationContextService: public AllStatic {
+class AdaptiveSizePolicy;
+
+class SoftRefGenPolicy : public SoftRefPolicy {
public:
- static inline bool should_notify();
- static inline void notify(TRAPS);
+ virtual void cleared_all_soft_refs();
};
-bool AllocationContextService::should_notify() { return false; }
-void AllocationContextService::notify(TRAPS) { }
-
-#endif // SHARE_VM_SERVICES_ALLOCATION_CONTEXT_SERVICE_HPP
+#endif // SHARE_VM_GC_SHARED_SOFTREFGENPOLICY_HPP
diff --git a/src/hotspot/share/gc/shared/softRefPolicy.cpp b/src/hotspot/share/gc/shared/softRefPolicy.cpp
new file mode 100644
index 00000000000..9668b83d59e
--- /dev/null
+++ b/src/hotspot/share/gc/shared/softRefPolicy.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/shared/softRefPolicy.hpp"
+
+SoftRefPolicy::SoftRefPolicy() :
+ _should_clear_all_soft_refs(false),
+ _all_soft_refs_clear(false) {
+}
+
+bool SoftRefPolicy::use_should_clear_all_soft_refs(bool v) {
+ bool result = _should_clear_all_soft_refs;
+ set_should_clear_all_soft_refs(false);
+ return result;
+}
+
+void SoftRefPolicy::cleared_all_soft_refs() {
+ _all_soft_refs_clear = true;
+}
diff --git a/src/hotspot/share/gc/shared/softRefPolicy.hpp b/src/hotspot/share/gc/shared/softRefPolicy.hpp
new file mode 100644
index 00000000000..33fd73aff7b
--- /dev/null
+++ b/src/hotspot/share/gc/shared/softRefPolicy.hpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_SHARED_SOFTREFPOLICY_HPP
+#define SHARE_VM_GC_SHARED_SOFTREFPOLICY_HPP
+
+#include "memory/allocation.hpp"
+
+class SoftRefPolicy {
+ private:
+ // Set to true when policy wants soft refs cleared.
+ // Reset to false by gc after it clears all soft refs.
+ bool _should_clear_all_soft_refs;
+
+ // Set to true by the GC if the just-completed gc cleared all
+ // softrefs. This is set to true whenever a gc clears all softrefs, and
+ // set to false each time gc returns to the mutator. For example, in the
+ // ParallelScavengeHeap case the latter would be done toward the end of
+ // mem_allocate() where it returns op.result()
+ bool _all_soft_refs_clear;
+
+ public:
+ SoftRefPolicy();
+
+ bool should_clear_all_soft_refs() { return _should_clear_all_soft_refs; }
+ void set_should_clear_all_soft_refs(bool v) { _should_clear_all_soft_refs = v; }
+ // Returns the current value of _should_clear_all_soft_refs.
+ // _should_clear_all_soft_refs is set to false as a side effect.
+ bool use_should_clear_all_soft_refs(bool v);
+ bool all_soft_refs_clear() { return _all_soft_refs_clear; }
+ void set_all_soft_refs_clear(bool v) { _all_soft_refs_clear = v; }
+
+ // Called by the GC after Soft Refs have been cleared to indicate
+ // that the request in _should_clear_all_soft_refs has been fulfilled.
+ virtual void cleared_all_soft_refs();
+};
+
+class ClearedAllSoftRefs : public StackObj {
+ bool _clear_all_soft_refs;
+ SoftRefPolicy* _soft_ref_policy;
+ public:
+ ClearedAllSoftRefs(bool clear_all_soft_refs, SoftRefPolicy* soft_ref_policy) :
+ _clear_all_soft_refs(clear_all_soft_refs),
+ _soft_ref_policy(soft_ref_policy) {}
+
+ ~ClearedAllSoftRefs() {
+ if (_clear_all_soft_refs) {
+ _soft_ref_policy->cleared_all_soft_refs();
+ }
+ }
+
+ bool should_clear() { return _clear_all_soft_refs; }
+};
+
+#endif // SHARE_VM_GC_SHARED_SOFTREFPOLICY_HPP
diff --git a/src/hotspot/share/gc/shared/space.cpp b/src/hotspot/share/gc/shared/space.cpp
index 0a39aae230b..15502b2f01b 100644
--- a/src/hotspot/share/gc/shared/space.cpp
+++ b/src/hotspot/share/gc/shared/space.cpp
@@ -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
@@ -49,7 +49,7 @@ HeapWord* DirtyCardToOopClosure::get_actual_top(HeapWord* top,
HeapWord* top_obj) {
if (top_obj != NULL) {
if (_sp->block_is_obj(top_obj)) {
- if (_precision == CardTableModRefBS::ObjHeadPreciseArray) {
+ if (_precision == CardTable::ObjHeadPreciseArray) {
if (oop(top_obj)->is_objArray() || oop(top_obj)->is_typeArray()) {
// An arrayOop is starting on the dirty card - since we do exact
// store checks for objArrays we are done.
@@ -125,11 +125,11 @@ void DirtyCardToOopClosure::do_MemRegion(MemRegion mr) {
HeapWord* bottom_obj;
HeapWord* top_obj;
- assert(_precision == CardTableModRefBS::ObjHeadPreciseArray ||
- _precision == CardTableModRefBS::Precise,
+ assert(_precision == CardTable::ObjHeadPreciseArray ||
+ _precision == CardTable::Precise,
"Only ones we deal with for now.");
- assert(_precision != CardTableModRefBS::ObjHeadPreciseArray ||
+ assert(_precision != CardTable::ObjHeadPreciseArray ||
_cl->idempotent() || _last_bottom == NULL ||
top <= _last_bottom,
"Not decreasing");
@@ -147,7 +147,7 @@ void DirtyCardToOopClosure::do_MemRegion(MemRegion mr) {
top = get_actual_top(top, top_obj);
// If the previous call did some part of this region, don't redo.
- if (_precision == CardTableModRefBS::ObjHeadPreciseArray &&
+ if (_precision == CardTable::ObjHeadPreciseArray &&
_min_done != NULL &&
_min_done < top) {
top = _min_done;
@@ -159,7 +159,7 @@ void DirtyCardToOopClosure::do_MemRegion(MemRegion mr) {
bottom = MIN2(bottom, top);
MemRegion extended_mr = MemRegion(bottom, top);
assert(bottom <= top &&
- (_precision != CardTableModRefBS::ObjHeadPreciseArray ||
+ (_precision != CardTable::ObjHeadPreciseArray ||
_min_done == NULL ||
top <= _min_done),
"overlap!");
@@ -180,7 +180,7 @@ void DirtyCardToOopClosure::do_MemRegion(MemRegion mr) {
}
DirtyCardToOopClosure* Space::new_dcto_cl(ExtendedOopClosure* cl,
- CardTableModRefBS::PrecisionStyle precision,
+ CardTable::PrecisionStyle precision,
HeapWord* boundary,
bool parallel) {
return new DirtyCardToOopClosure(this, cl, precision, boundary);
@@ -189,7 +189,7 @@ DirtyCardToOopClosure* Space::new_dcto_cl(ExtendedOopClosure* cl,
HeapWord* ContiguousSpaceDCTOC::get_actual_top(HeapWord* top,
HeapWord* top_obj) {
if (top_obj != NULL && top_obj < (_sp->toContiguousSpace())->top()) {
- if (_precision == CardTableModRefBS::ObjHeadPreciseArray) {
+ if (_precision == CardTable::ObjHeadPreciseArray) {
if (oop(top_obj)->is_objArray() || oop(top_obj)->is_typeArray()) {
// An arrayOop is starting on the dirty card - since we do exact
// store checks for objArrays we are done.
@@ -260,7 +260,7 @@ ContiguousSpaceDCTOC__walk_mem_region_with_cl_DEFN(FilteringClosure)
DirtyCardToOopClosure*
ContiguousSpace::new_dcto_cl(ExtendedOopClosure* cl,
- CardTableModRefBS::PrecisionStyle precision,
+ CardTable::PrecisionStyle precision,
HeapWord* boundary,
bool parallel) {
return new ContiguousSpaceDCTOC(this, cl, precision, boundary);
diff --git a/src/hotspot/share/gc/shared/space.hpp b/src/hotspot/share/gc/shared/space.hpp
index a4d10541e56..a8381117388 100644
--- a/src/hotspot/share/gc/shared/space.hpp
+++ b/src/hotspot/share/gc/shared/space.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
#define SHARE_VM_GC_SHARED_SPACE_HPP
#include "gc/shared/blockOffsetTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/cardTable.hpp"
#include "gc/shared/workgroup.hpp"
#include "memory/allocation.hpp"
#include "memory/iterator.hpp"
@@ -181,7 +181,7 @@ class Space: public CHeapObj {
// depending on the type of space in which the closure will
// operate. ResourceArea allocated.
virtual DirtyCardToOopClosure* new_dcto_cl(ExtendedOopClosure* cl,
- CardTableModRefBS::PrecisionStyle precision,
+ CardTable::PrecisionStyle precision,
HeapWord* boundary,
bool parallel);
@@ -253,7 +253,7 @@ class DirtyCardToOopClosure: public MemRegionClosureRO {
protected:
ExtendedOopClosure* _cl;
Space* _sp;
- CardTableModRefBS::PrecisionStyle _precision;
+ CardTable::PrecisionStyle _precision;
HeapWord* _boundary; // If non-NULL, process only non-NULL oops
// pointing below boundary.
HeapWord* _min_done; // ObjHeadPreciseArray precision requires
@@ -282,7 +282,7 @@ protected:
public:
DirtyCardToOopClosure(Space* sp, ExtendedOopClosure* cl,
- CardTableModRefBS::PrecisionStyle precision,
+ CardTable::PrecisionStyle precision,
HeapWord* boundary) :
_sp(sp), _cl(cl), _precision(precision), _boundary(boundary),
_min_done(NULL) {
@@ -619,7 +619,7 @@ class ContiguousSpace: public CompactibleSpace {
// Override.
DirtyCardToOopClosure* new_dcto_cl(ExtendedOopClosure* cl,
- CardTableModRefBS::PrecisionStyle precision,
+ CardTable::PrecisionStyle precision,
HeapWord* boundary,
bool parallel);
@@ -694,7 +694,7 @@ protected:
public:
FilteringDCTOC(Space* sp, ExtendedOopClosure* cl,
- CardTableModRefBS::PrecisionStyle precision,
+ CardTable::PrecisionStyle precision,
HeapWord* boundary) :
DirtyCardToOopClosure(sp, cl, precision, boundary) {}
};
@@ -723,7 +723,7 @@ protected:
public:
ContiguousSpaceDCTOC(ContiguousSpace* sp, ExtendedOopClosure* cl,
- CardTableModRefBS::PrecisionStyle precision,
+ CardTable::PrecisionStyle precision,
HeapWord* boundary) :
FilteringDCTOC(sp, cl, precision, boundary)
{}
diff --git a/src/hotspot/share/gc/shared/vmGCOperations.cpp b/src/hotspot/share/gc/shared/vmGCOperations.cpp
index 371a4da09cb..3f1901279bf 100644
--- a/src/hotspot/share/gc/shared/vmGCOperations.cpp
+++ b/src/hotspot/share/gc/shared/vmGCOperations.cpp
@@ -46,7 +46,7 @@
VM_GC_Operation::~VM_GC_Operation() {
CollectedHeap* ch = Universe::heap();
- ch->collector_policy()->set_all_soft_refs_clear(false);
+ ch->soft_ref_policy()->set_all_soft_refs_clear(false);
}
// The same dtrace probe can't be inserted in two different files, so we
diff --git a/src/hotspot/share/gc/shared/workgroup.hpp b/src/hotspot/share/gc/shared/workgroup.hpp
index c1b50f3885d..deaf4d28a3d 100644
--- a/src/hotspot/share/gc/shared/workgroup.hpp
+++ b/src/hotspot/share/gc/shared/workgroup.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -59,14 +59,9 @@ class AbstractGangTask VALUE_OBJ_CLASS_SPEC {
const uint _gc_id;
public:
- AbstractGangTask(const char* name) :
+ explicit AbstractGangTask(const char* name) :
_name(name),
- _gc_id(GCId::current_raw())
- {}
-
- AbstractGangTask(const char* name, const uint gc_id) :
- _name(name),
- _gc_id(gc_id)
+ _gc_id(GCId::current_or_undefined())
{}
// The abstract work method.
diff --git a/src/hotspot/share/include/jvm.h b/src/hotspot/share/include/jvm.h
index c08dcc882f9..d36c07ae245 100644
--- a/src/hotspot/share/include/jvm.h
+++ b/src/hotspot/share/include/jvm.h
@@ -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
@@ -118,6 +118,9 @@ JVM_InitProperties(JNIEnv *env, jobject p);
/*
* java.lang.Runtime
*/
+JNIEXPORT void JNICALL
+JVM_BeforeHalt();
+
JNIEXPORT void JNICALL
JVM_Halt(jint code);
diff --git a/src/hotspot/share/interpreter/bytecode.cpp b/src/hotspot/share/interpreter/bytecode.cpp
index 153ffeb3ea5..7df782bbf9b 100644
--- a/src/hotspot/share/interpreter/bytecode.cpp
+++ b/src/hotspot/share/interpreter/bytecode.cpp
@@ -123,6 +123,11 @@ void Bytecode_invoke::verify() const {
assert(cpcache() != NULL, "do not call this from verifier or rewriter");
}
+int Bytecode_invoke::size_of_parameters() const {
+ ArgumentSizeComputer asc(signature());
+ return asc.size() + (has_receiver() ? 1 : 0);
+}
+
Symbol* Bytecode_member_ref::klass() const {
return constants()->klass_ref_at_noresolve(index());
diff --git a/src/hotspot/share/interpreter/bytecode.hpp b/src/hotspot/share/interpreter/bytecode.hpp
index 0609a290434..450856ed925 100644
--- a/src/hotspot/share/interpreter/bytecode.hpp
+++ b/src/hotspot/share/interpreter/bytecode.hpp
@@ -197,7 +197,7 @@ class Bytecode_member_ref: public Bytecode {
BasicType result_type() const; // returns the result type of the getfield or invoke
};
-// Abstraction for invoke_{virtual, static, interface, special}
+// Abstraction for invoke_{virtual, static, interface, special, dynamic, handle}
class Bytecode_invoke: public Bytecode_member_ref {
protected:
@@ -231,6 +231,8 @@ class Bytecode_invoke: public Bytecode_member_ref {
bool has_appendix() { return cpcache_entry()->has_appendix(); }
+ int size_of_parameters() const;
+
private:
// Helper to skip verification. Used is_valid() to check if the result is really an invoke
inline friend Bytecode_invoke Bytecode_invoke_check(const methodHandle& method, int bci);
diff --git a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp
index fa7f375ad98..2628411c774 100644
--- a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp
+++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,9 +34,12 @@
#include "jvmci/jvmciJavaClasses.hpp"
#include "jvmci/jvmciCompilerToVM.hpp"
#include "jvmci/jvmciRuntime.hpp"
+#include "oops/arrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/objArrayOop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "runtime/javaCalls.hpp"
+#include "runtime/jniHandles.inline.hpp"
#include "runtime/safepointMechanism.inline.hpp"
#include "utilities/align.hpp"
@@ -95,6 +98,32 @@ VMReg getVMRegFromLocation(Handle location, int total_frame_size, TRAPS) {
}
}
+objArrayOop CodeInstaller::sites() {
+ return (objArrayOop) JNIHandles::resolve(_sites_handle);
+}
+
+arrayOop CodeInstaller::code() {
+ return (arrayOop) JNIHandles::resolve(_code_handle);
+}
+
+arrayOop CodeInstaller::data_section() {
+ return (arrayOop) JNIHandles::resolve(_data_section_handle);
+}
+
+objArrayOop CodeInstaller::data_section_patches() {
+ return (objArrayOop) JNIHandles::resolve(_data_section_patches_handle);
+}
+
+#ifndef PRODUCT
+objArrayOop CodeInstaller::comments() {
+ return (objArrayOop) JNIHandles::resolve(_comments_handle);
+}
+#endif
+
+oop CodeInstaller::word_kind() {
+ return JNIHandles::resolve(_word_kind_handle);
+}
+
// creates a HotSpot oop map out of the byte arrays provided by DebugInfo
OopMap* CodeInstaller::create_oop_map(Handle debug_info, TRAPS) {
Handle reference_map(THREAD, DebugInfo::referenceMap(debug_info));
diff --git a/src/hotspot/share/jvmci/jvmciCodeInstaller.hpp b/src/hotspot/share/jvmci/jvmciCodeInstaller.hpp
index 315ea500f9f..93a8f3df51f 100644
--- a/src/hotspot/share/jvmci/jvmciCodeInstaller.hpp
+++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -188,15 +188,15 @@ private:
void pd_relocate_JavaMethod(CodeBuffer &cbuf, Handle method, jint pc_offset, TRAPS);
void pd_relocate_poll(address pc, jint mark, TRAPS);
- objArrayOop sites() { return (objArrayOop) JNIHandles::resolve(_sites_handle); }
- arrayOop code() { return (arrayOop) JNIHandles::resolve(_code_handle); }
- arrayOop data_section() { return (arrayOop) JNIHandles::resolve(_data_section_handle); }
- objArrayOop data_section_patches() { return (objArrayOop) JNIHandles::resolve(_data_section_patches_handle); }
+ objArrayOop sites();
+ arrayOop code();
+ arrayOop data_section();
+ objArrayOop data_section_patches();
#ifndef PRODUCT
- objArrayOop comments() { return (objArrayOop) JNIHandles::resolve(_comments_handle); }
+ objArrayOop comments();
#endif
- oop word_kind() { return (oop) JNIHandles::resolve(_word_kind_handle); }
+ oop word_kind();
public:
diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
index 996049476ce..47a46cad062 100644
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
@@ -22,6 +22,7 @@
*/
#include "precompiled.hpp"
+#include "ci/ciUtilities.hpp"
#include "classfile/javaClasses.inline.hpp"
#include "code/codeCache.hpp"
#include "code/scopeDesc.hpp"
@@ -32,8 +33,10 @@
#include "oops/fieldStreams.hpp"
#include "oops/oop.inline.hpp"
#include "oops/objArrayOop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
#include "runtime/fieldDescriptor.hpp"
#include "runtime/javaCalls.hpp"
+#include "runtime/jniHandles.inline.hpp"
#include "jvmci/jvmciRuntime.hpp"
#include "compiler/abstractCompiler.hpp"
#include "compiler/compileBroker.hpp"
@@ -47,6 +50,7 @@
#include "jvmci/jvmciCodeInstaller.hpp"
#include "jvmci/vmStructs_jvmci.hpp"
#include "gc/g1/heapRegion.hpp"
+#include "gc/shared/cardTable.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/timerTrace.hpp"
@@ -204,10 +208,10 @@ void CompilerToVM::Data::initialize(TRAPS) {
BarrierSet* bs = Universe::heap()->barrier_set();
if (bs->is_a(BarrierSet::CardTableModRef)) {
- jbyte* base = barrier_set_cast(bs)->byte_map_base;
- assert(base != 0, "unexpected byte_map_base");
+ jbyte* base = ci_card_table_address();
+ assert(base != NULL, "unexpected byte_map_base");
cardtable_start_address = base;
- cardtable_shift = CardTableModRefBS::card_shift;
+ cardtable_shift = CardTable::card_shift;
} else {
// No card mark barriers
cardtable_start_address = 0;
diff --git a/src/hotspot/share/jvmci/jvmciJavaClasses.hpp b/src/hotspot/share/jvmci/jvmciJavaClasses.hpp
index eca9635ec87..87b2279b74a 100644
--- a/src/hotspot/share/jvmci/jvmciJavaClasses.hpp
+++ b/src/hotspot/share/jvmci/jvmciJavaClasses.hpp
@@ -28,6 +28,7 @@
#include "oops/access.inline.hpp"
#include "oops/instanceMirrorKlass.hpp"
#include "oops/oop.inline.hpp"
+#include "runtime/jniHandles.inline.hpp"
class JVMCIJavaClasses : AllStatic {
public:
diff --git a/src/hotspot/share/jvmci/jvmciRuntime.cpp b/src/hotspot/share/jvmci/jvmciRuntime.cpp
index 7ed94a09ea2..45df8d824a0 100644
--- a/src/hotspot/share/jvmci/jvmciRuntime.cpp
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -40,6 +40,7 @@
#include "oops/objArrayOop.inline.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/interfaceSupport.hpp"
+#include "runtime/jniHandles.inline.hpp"
#include "runtime/reflection.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/threadSMR.hpp"
@@ -630,6 +631,11 @@ Handle JVMCIRuntime::callStatic(const char* className, const char* methodName, c
return Handle(THREAD, (oop)result.get_jobject());
}
+Handle JVMCIRuntime::get_HotSpotJVMCIRuntime(TRAPS) {
+ initialize_JVMCI(CHECK_(Handle()));
+ return Handle(THREAD, JNIHandles::resolve_non_null(_HotSpotJVMCIRuntime_instance));
+}
+
void JVMCIRuntime::initialize_HotSpotJVMCIRuntime(TRAPS) {
guarantee(!_HotSpotJVMCIRuntime_initialized, "cannot reinitialize HotSpotJVMCIRuntime");
JVMCIRuntime::initialize_well_known_classes(CHECK);
diff --git a/src/hotspot/share/jvmci/jvmciRuntime.hpp b/src/hotspot/share/jvmci/jvmciRuntime.hpp
index 75588a70c60..2ee6b9d482d 100644
--- a/src/hotspot/share/jvmci/jvmciRuntime.hpp
+++ b/src/hotspot/share/jvmci/jvmciRuntime.hpp
@@ -73,10 +73,7 @@ class JVMCIRuntime: public AllStatic {
/**
* Gets the singleton HotSpotJVMCIRuntime instance, initializing it if necessary
*/
- static Handle get_HotSpotJVMCIRuntime(TRAPS) {
- initialize_JVMCI(CHECK_(Handle()));
- return Handle(THREAD, JNIHandles::resolve_non_null(_HotSpotJVMCIRuntime_instance));
- }
+ static Handle get_HotSpotJVMCIRuntime(TRAPS);
static jobject get_HotSpotJVMCIRuntime_jobject(TRAPS) {
initialize_JVMCI(CHECK_NULL);
diff --git a/src/hotspot/share/jvmci/jvmci_globals.cpp b/src/hotspot/share/jvmci/jvmci_globals.cpp
index f9dba2af188..76bcc2758dd 100644
--- a/src/hotspot/share/jvmci/jvmci_globals.cpp
+++ b/src/hotspot/share/jvmci/jvmci_globals.cpp
@@ -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
@@ -80,6 +80,15 @@ bool JVMCIGlobals::check_jvmci_flags_are_consistent() {
FLAG_SET_DEFAULT(EnableJVMCI, true);
}
+ if (!EnableJVMCI) {
+ // Switch off eager JVMCI initialization if JVMCI is disabled.
+ // Don't throw error if EagerJVMCI is set to allow testing.
+ if (EagerJVMCI) {
+ FLAG_SET_DEFAULT(EagerJVMCI, false);
+ }
+ }
+ JVMCI_FLAG_CHECKED(EagerJVMCI)
+
CHECK_NOT_SET(JVMCITraceLevel, EnableJVMCI)
CHECK_NOT_SET(JVMCICounterSize, EnableJVMCI)
CHECK_NOT_SET(JVMCICountersExcludeCompiler, EnableJVMCI)
diff --git a/src/hotspot/share/jvmci/jvmci_globals.hpp b/src/hotspot/share/jvmci/jvmci_globals.hpp
index abec3e9816b..0944494eb69 100644
--- a/src/hotspot/share/jvmci/jvmci_globals.hpp
+++ b/src/hotspot/share/jvmci/jvmci_globals.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -55,6 +55,9 @@
experimental(bool, BootstrapJVMCI, false, \
"Bootstrap JVMCI before running Java main method") \
\
+ experimental(bool, EagerJVMCI, false, \
+ "Force eager JVMCI initialization") \
+ \
experimental(bool, PrintBootstrap, true, \
"Print JVMCI bootstrap progress and summary") \
\
diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp
index e20d1b98896..c26da43c26a 100644
--- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp
+++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -426,7 +426,7 @@
declare_constant(BitData::null_seen_flag) \
declare_constant(BranchData::not_taken_off_set) \
\
- declare_constant_with_value("CardTableModRefBS::dirty_card", CardTableModRefBS::dirty_card_val()) \
+ declare_constant_with_value("CardTable::dirty_card", CardTable::dirty_card_val()) \
\
declare_constant(CodeInstaller::VERIFIED_ENTRY) \
declare_constant(CodeInstaller::UNVERIFIED_ENTRY) \
@@ -653,7 +653,7 @@
static_field(HeapRegion, LogOfHRGrainBytes, int)
#define VM_INT_CONSTANTS_G1(declare_constant, declare_constant_with_value, declare_preprocessor_constant) \
- declare_constant_with_value("G1SATBCardTableModRefBS::g1_young_gen", G1SATBCardTableModRefBS::g1_young_card_val())
+ declare_constant_with_value("G1CardTable::g1_young_gen", G1CardTable::g1_young_card_val())
#endif // INCLUDE_ALL_GCS
diff --git a/src/hotspot/share/logging/logConfiguration.cpp b/src/hotspot/share/logging/logConfiguration.cpp
index c96a5aba4fa..ed5e61aec4d 100644
--- a/src/hotspot/share/logging/logConfiguration.cpp
+++ b/src/hotspot/share/logging/logConfiguration.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,8 +30,8 @@
#include "logging/logDiagnosticCommand.hpp"
#include "logging/logFileOutput.hpp"
#include "logging/logOutput.hpp"
+#include "logging/logSelectionList.hpp"
#include "logging/logStream.hpp"
-#include "logging/logTagLevelExpression.hpp"
#include "logging/logTagSet.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
@@ -78,19 +78,25 @@ bool ConfigurationLock::current_thread_has_lock() {
#endif
void LogConfiguration::post_initialize() {
+ // Reset the reconfigured status of all outputs
+ for (size_t i = 0; i < _n_outputs; i++) {
+ _outputs[i]->_reconfigured = false;
+ }
+
LogDiagnosticCommand::registerCommand();
Log(logging) log;
if (log.is_info()) {
log.info("Log configuration fully initialized.");
log_develop_info(logging)("Develop logging is available.");
- if (log.is_debug()) {
- LogStream debug_stream(log.debug());
- describe(&debug_stream);
- if (log.is_trace()) {
- LogStream trace_stream(log.trace());
- LogTagSet::list_all_tagsets(&trace_stream);
- }
- }
+
+ LogStream info_stream(log.info());
+ describe_available(&info_stream);
+
+ LogStream debug_stream(log.debug());
+ LogTagSet::list_all_tagsets(&debug_stream);
+
+ ConfigurationLock cl;
+ describe_current_configuration(&info_stream);
}
}
@@ -207,20 +213,22 @@ void LogConfiguration::delete_output(size_t idx) {
delete output;
}
-void LogConfiguration::configure_output(size_t idx, const LogTagLevelExpression& tag_level_expression, const LogDecorators& decorators) {
+void LogConfiguration::configure_output(size_t idx, const LogSelectionList& selections, const LogDecorators& decorators) {
assert(ConfigurationLock::current_thread_has_lock(), "Must hold configuration lock to call this function.");
assert(idx < _n_outputs, "Invalid index, idx = " SIZE_FORMAT " and _n_outputs = " SIZE_FORMAT, idx, _n_outputs);
LogOutput* output = _outputs[idx];
- // Clear the previous config description
- output->clear_config_string();
+ output->_reconfigured = true;
+
+ size_t on_level[LogLevel::Count] = {0};
bool enabled = false;
for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
- LogLevelType level = tag_level_expression.level_for(*ts);
+ LogLevelType level = selections.level_for(*ts);
// Ignore tagsets that do not, and will not log on the output
if (!ts->has_output(output) && (level == LogLevel::NotMentioned || level == LogLevel::Off)) {
+ on_level[LogLevel::Off]++;
continue;
}
@@ -233,20 +241,18 @@ void LogConfiguration::configure_output(size_t idx, const LogTagLevelExpression&
// Set the new level, if it changed
if (level != LogLevel::NotMentioned) {
ts->set_output_level(output, level);
+ } else {
+ // Look up the previously set level for this output on this tagset
+ level = ts->level_for(output);
}
if (level != LogLevel::Off) {
// Keep track of whether or not the output is ever used by some tagset
enabled = true;
-
- if (level == LogLevel::NotMentioned) {
- // Look up the previously set level for this output on this tagset
- level = ts->level_for(output);
- }
-
- // Update the config description with this tagset and level
- output->add_to_config_string(ts, level);
}
+
+ // Track of the number of tag sets on each level
+ on_level[level]++;
}
// It is now safe to set the new decorators for the actual output
@@ -257,17 +263,14 @@ void LogConfiguration::configure_output(size_t idx, const LogTagLevelExpression&
ts->update_decorators();
}
- if (enabled) {
- assert(strlen(output->config_string()) > 0,
- "Should always have a config description if the output is enabled.");
- } else if (idx > 1) {
- // Output is unused and should be removed.
+ if (!enabled && idx > 1) {
+ // Output is unused and should be removed, unless it is stdout/stderr (idx < 2)
delete_output(idx);
- } else {
- // Output is either stdout or stderr, which means we can't remove it.
- // Update the config description to reflect that the output is disabled.
- output->set_config_string("all=off");
+ return;
}
+
+ output->update_config_string(on_level);
+ assert(strlen(output->config_string()) > 0, "should always have a config description");
}
void LogConfiguration::disable_output(size_t idx) {
@@ -299,11 +302,11 @@ void LogConfiguration::disable_logging() {
void LogConfiguration::configure_stdout(LogLevelType level, int exact_match, ...) {
size_t i;
va_list ap;
- LogTagLevelExpression expr;
+ LogTagType tags[LogTag::MaxTags];
va_start(ap, exact_match);
for (i = 0; i < LogTag::MaxTags; i++) {
LogTagType tag = static_cast(va_arg(ap, int));
- expr.add_tag(tag);
+ tags[i] = tag;
if (tag == LogTag::__NO_TAG) {
assert(i > 0, "Must specify at least one tag!");
break;
@@ -313,17 +316,14 @@ void LogConfiguration::configure_stdout(LogLevelType level, int exact_match, ...
"Too many tags specified! Can only have up to " SIZE_FORMAT " tags in a tag set.", LogTag::MaxTags);
va_end(ap);
- if (!exact_match) {
- expr.set_allow_other_tags();
- }
- expr.set_level(level);
- expr.new_combination();
- assert(expr.verify_tagsets(),
- "configure_stdout() called with invalid/non-existing tag set");
+ LogSelection selection(tags, !exact_match, level);
+ assert(selection.tag_sets_selected() > 0,
+ "configure_stdout() called with invalid/non-existing log selection");
+ LogSelectionList list(selection);
// Apply configuration to stdout (output #0), with the same decorators as before.
ConfigurationLock cl;
- configure_output(0, expr, _outputs[0]->decorators());
+ configure_output(0, list, _outputs[0]->decorators());
notify_update_listeners();
}
@@ -367,14 +367,24 @@ bool LogConfiguration::parse_command_line_arguments(const char* opts) {
bool success = parse_log_arguments(output, what, decorators, output_options, &ss);
if (ss.size() > 0) {
- errbuf[strlen(errbuf) - 1] = '\0'; // Strip trailing newline
// If it failed, log the error. If it didn't fail, but something was written
// to the stream, log it as a warning.
- if (!success) {
- log_error(logging)("%s", ss.base());
- } else {
- log_warning(logging)("%s", ss.base());
- }
+ LogLevelType level = success ? LogLevel::Warning : LogLevel::Error;
+
+ Log(logging) log;
+ char* start = errbuf;
+ char* end = strchr(start, '\n');
+ assert(end != NULL, "line must end with newline '%s'", start);
+ do {
+ assert(start < errbuf + sizeof(errbuf) &&
+ end < errbuf + sizeof(errbuf),
+ "buffer overflow");
+ *end = '\0';
+ log.write(level, "%s", start);
+ start = end + 1;
+ end = strchr(start, '\n');
+ assert(end != NULL || *start == '\0', "line must end with newline '%s'", start);
+ } while (end != NULL);
}
os::free(copy);
@@ -382,7 +392,7 @@ bool LogConfiguration::parse_command_line_arguments(const char* opts) {
}
bool LogConfiguration::parse_log_arguments(const char* outputstr,
- const char* what,
+ const char* selectionstr,
const char* decoratorstr,
const char* output_options,
outputStream* errstream) {
@@ -391,8 +401,8 @@ bool LogConfiguration::parse_log_arguments(const char* outputstr,
outputstr = "stdout";
}
- LogTagLevelExpression expr;
- if (!expr.parse(what, errstream)) {
+ LogSelectionList selections;
+ if (!selections.parse(selectionstr, errstream)) {
return false;
}
@@ -433,13 +443,13 @@ bool LogConfiguration::parse_log_arguments(const char* outputstr,
return false;
}
}
- configure_output(idx, expr, decorators);
+ configure_output(idx, selections, decorators);
notify_update_listeners();
- expr.verify_tagsets(errstream);
+ selections.verify_selections(errstream);
return true;
}
-void LogConfiguration::describe_available(outputStream* out){
+void LogConfiguration::describe_available(outputStream* out) {
out->print("Available log levels:");
for (size_t i = 0; i < LogLevel::Count; i++) {
out->print("%s %s", (i == 0 ? "" : ","), LogLevel::name(static_cast(i)));
@@ -454,19 +464,19 @@ void LogConfiguration::describe_available(outputStream* out){
out->cr();
out->print("Available log tags:");
- for (size_t i = 1; i < LogTag::Count; i++) {
- out->print("%s %s", (i == 1 ? "" : ","), LogTag::name(static_cast(i)));
- }
- out->cr();
+ LogTag::list_tags(out);
LogTagSet::describe_tagsets(out);
}
-void LogConfiguration::describe_current_configuration(outputStream* out){
+void LogConfiguration::describe_current_configuration(outputStream* out) {
out->print_cr("Log output configuration:");
for (size_t i = 0; i < _n_outputs; i++) {
- out->print("#" SIZE_FORMAT ": ", i);
+ out->print(" #" SIZE_FORMAT ": ", i);
_outputs[i]->describe(out);
+ if (_outputs[i]->is_reconfigured()) {
+ out->print(" (reconfigured)");
+ }
out->cr();
}
}
@@ -477,69 +487,89 @@ void LogConfiguration::describe(outputStream* out) {
describe_current_configuration(out);
}
-void LogConfiguration::print_command_line_help(FILE* out) {
- jio_fprintf(out, "-Xlog Usage: -Xlog[:[what][:[output][:[decorators][:output-options]]]]\n"
- "\t where 'what' is a combination of tags and levels of the form tag1[+tag2...][*][=level][,...]\n"
- "\t Unless wildcard (*) is specified, only log messages tagged with exactly the tags specified will be matched.\n\n");
+void LogConfiguration::print_command_line_help(outputStream* out) {
+ out->print_cr("-Xlog Usage: -Xlog[:[selections][:[output][:[decorators][:output-options]]]]");
+ out->print_cr("\t where 'selections' are combinations of tags and levels of the form tag1[+tag2...][*][=level][,...]");
+ out->print_cr("\t NOTE: Unless wildcard (*) is specified, only log messages tagged with exactly the tags specified will be matched.");
+ out->cr();
- jio_fprintf(out, "Available log levels:\n");
+ out->print_cr("Available log levels:");
for (size_t i = 0; i < LogLevel::Count; i++) {
- jio_fprintf(out, "%s %s", (i == 0 ? "" : ","), LogLevel::name(static_cast(i)));
+ out->print("%s %s", (i == 0 ? "" : ","), LogLevel::name(static_cast(i)));
}
+ out->cr();
+ out->cr();
- jio_fprintf(out, "\n\nAvailable log decorators: \n");
+ out->print_cr("Available log decorators: ");
for (size_t i = 0; i < LogDecorators::Count; i++) {
LogDecorators::Decorator d = static_cast(i);
- jio_fprintf(out, "%s %s (%s)", (i == 0 ? "" : ","), LogDecorators::name(d), LogDecorators::abbreviation(d));
+ out->print("%s %s (%s)", (i == 0 ? "" : ","), LogDecorators::name(d), LogDecorators::abbreviation(d));
}
- jio_fprintf(out, "\n Decorators can also be specified as 'none' for no decoration.\n\n");
+ out->cr();
+ out->print_cr(" Decorators can also be specified as 'none' for no decoration.");
+ out->cr();
- jio_fprintf(out, "Available log tags:\n");
- for (size_t i = 1; i < LogTag::Count; i++) {
- jio_fprintf(out, "%s %s", (i == 1 ? "" : ","), LogTag::name(static_cast(i)));
- }
- jio_fprintf(out, "\n Specifying 'all' instead of a tag combination matches all tag combinations.\n\n");
+ out->print_cr("Available log tags:");
+ LogTag::list_tags(out);
+ out->print_cr(" Specifying 'all' instead of a tag combination matches all tag combinations.");
+ out->cr();
- fileStream stream(out, false);
- LogTagSet::describe_tagsets(&stream);
+ LogTagSet::describe_tagsets(out);
- jio_fprintf(out, "\nAvailable log outputs:\n"
- " stdout, stderr, file=\n"
- " Specifying %%p and/or %%t in the filename will expand to the JVM's PID and startup timestamp, respectively.\n\n"
+ out->print_cr("\nAvailable log outputs:");
+ out->print_cr(" stdout/stderr");
+ out->print_cr(" file=");
+ out->print_cr(" If the filename contains %%p and/or %%t, they will expand to the JVM's PID and startup timestamp, respectively.");
+ out->print_cr(" Additional output-options for file outputs:");
+ out->print_cr(" filesize=.. - Target byte size for log rotation (supports K/M/G suffix)."
+ " If set to 0, log rotation will not trigger automatically,"
+ " but can be performed manually (see the VM.log DCMD).");
+ out->print_cr(" filecount=.. - Number of files to keep in rotation (not counting the active file)."
+ " If set to 0, log rotation is disabled."
+ " This will cause existing log files to be overwritten.");
+ out->cr();
- "Some examples:\n"
- " -Xlog\n"
- "\t Log all messages using 'info' level to stdout with 'uptime', 'levels' and 'tags' decorations.\n"
- "\t (Equivalent to -Xlog:all=info:stdout:uptime,levels,tags).\n\n"
+ out->print_cr("Some examples:");
+ out->print_cr(" -Xlog");
+ out->print_cr("\t Log all messages up to 'info' level to stdout with 'uptime', 'levels' and 'tags' decorations.");
+ out->print_cr("\t (Equivalent to -Xlog:all=info:stdout:uptime,levels,tags).");
+ out->cr();
- " -Xlog:gc\n"
- "\t Log messages tagged with 'gc' tag using 'info' level to stdout, with default decorations.\n\n"
+ out->print_cr(" -Xlog:gc");
+ out->print_cr("\t Log messages tagged with 'gc' tag up to 'info' level to stdout, with default decorations.");
+ out->cr();
- " -Xlog:gc,safepoint\n"
- "\t Log messages tagged either with 'gc' or 'safepoint' tags, both using 'info' level, to stdout, with default decorations.\n"
- "\t (Messages tagged with both 'gc' and 'safepoint' will not be logged.)\n\n"
+ out->print_cr(" -Xlog:gc,safepoint");
+ out->print_cr("\t Log messages tagged either with 'gc' or 'safepoint' tags, both up to 'info' level, to stdout, with default decorations.");
+ out->print_cr("\t (Messages tagged with both 'gc' and 'safepoint' will not be logged.)");
+ out->cr();
- " -Xlog:gc+ref=debug\n"
- "\t Log messages tagged with both 'gc' and 'ref' tags, using 'debug' level, to stdout, with default decorations.\n"
- "\t (Messages tagged only with one of the two tags will not be logged.)\n\n"
+ out->print_cr(" -Xlog:gc+ref=debug");
+ out->print_cr("\t Log messages tagged with both 'gc' and 'ref' tags, up to 'debug' level, to stdout, with default decorations.");
+ out->print_cr("\t (Messages tagged only with one of the two tags will not be logged.)");
+ out->cr();
- " -Xlog:gc=debug:file=gc.txt:none\n"
- "\t Log messages tagged with 'gc' tag using 'debug' level to file 'gc.txt' with no decorations.\n\n"
+ out->print_cr(" -Xlog:gc=debug:file=gc.txt:none");
+ out->print_cr("\t Log messages tagged with 'gc' tag up to 'debug' level to file 'gc.txt' with no decorations.");
+ out->cr();
- " -Xlog:gc=trace:file=gctrace.txt:uptimemillis,pids:filecount=5,filesize=1m\n"
- "\t Log messages tagged with 'gc' tag using 'trace' level to a rotating fileset of 5 files of size 1MB,\n"
- "\t using the base name 'gctrace.txt', with 'uptimemillis' and 'pid' decorations.\n\n"
+ out->print_cr(" -Xlog:gc=trace:file=gctrace.txt:uptimemillis,pids:filecount=5,filesize=1m");
+ out->print_cr("\t Log messages tagged with 'gc' tag up to 'trace' level to a rotating fileset of 5 files of size 1MB,");
+ out->print_cr("\t using the base name 'gctrace.txt', with 'uptimemillis' and 'pid' decorations.");
+ out->cr();
- " -Xlog:gc::uptime,tid\n"
- "\t Log messages tagged with 'gc' tag using 'info' level to output 'stdout', using 'uptime' and 'tid' decorations.\n\n"
+ out->print_cr(" -Xlog:gc::uptime,tid");
+ out->print_cr("\t Log messages tagged with 'gc' tag up to 'info' level to output 'stdout', using 'uptime' and 'tid' decorations.");
+ out->cr();
- " -Xlog:gc*=info,safepoint*=off\n"
- "\t Log messages tagged with at least 'gc' using 'info' level, but turn off logging of messages tagged with 'safepoint'.\n"
- "\t (Messages tagged with both 'gc' and 'safepoint' will not be logged.)\n\n"
+ out->print_cr(" -Xlog:gc*=info,safepoint*=off");
+ out->print_cr("\t Log messages tagged with at least 'gc' up to 'info' level, but turn off logging of messages tagged with 'safepoint'.");
+ out->print_cr("\t (Messages tagged with both 'gc' and 'safepoint' will not be logged.)");
+ out->cr();
- " -Xlog:disable -Xlog:safepoint=trace:safepointtrace.txt\n"
- "\t Turn off all logging, including warnings and errors,\n"
- "\t and then enable messages tagged with 'safepoint' using 'trace' level to file 'safepointtrace.txt'.\n");
+ out->print_cr(" -Xlog:disable -Xlog:safepoint=trace:safepointtrace.txt");
+ out->print_cr("\t Turn off all logging, including warnings and errors,");
+ out->print_cr("\t and then enable messages tagged with 'safepoint' up to 'trace' level to file 'safepointtrace.txt'.");
}
void LogConfiguration::rotate_all_outputs() {
diff --git a/src/hotspot/share/logging/logConfiguration.hpp b/src/hotspot/share/logging/logConfiguration.hpp
index e5d99e25fc3..d66ad2e6fab 100644
--- a/src/hotspot/share/logging/logConfiguration.hpp
+++ b/src/hotspot/share/logging/logConfiguration.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@
class LogOutput;
class LogDecorators;
-class LogTagLevelExpression;
+class LogSelectionList;
// Global configuration of logging. Handles parsing and configuration of the logging framework,
// and manages the list of configured log outputs. The actual tag and level configuration is
@@ -38,6 +38,7 @@ class LogTagLevelExpression;
// are iterated over and updated accordingly.
class LogConfiguration : public AllStatic {
friend class VMError;
+ friend class LogTestFixture;
public:
// Function for listeners
typedef void (*UpdateListenerFunction)(void);
@@ -75,7 +76,7 @@ class LogConfiguration : public AllStatic {
static size_t find_output(const char* name);
// Configure output (add or update existing configuration) to log on tag-level combination using specified decorators.
- static void configure_output(size_t idx, const LogTagLevelExpression& tag_level_expression, const LogDecorators& decorators);
+ static void configure_output(size_t idx, const LogSelectionList& tag_level_expression, const LogDecorators& decorators);
// This should be called after any configuration change while still holding ConfigurationLock
static void notify_update_listeners();
@@ -118,7 +119,7 @@ class LogConfiguration : public AllStatic {
static void describe(outputStream* out);
// Prints usage help for command line log configuration.
- static void print_command_line_help(FILE* out);
+ static void print_command_line_help(outputStream* out);
// Rotates all LogOutput
static void rotate_all_outputs();
diff --git a/src/hotspot/share/logging/logFileOutput.cpp b/src/hotspot/share/logging/logFileOutput.cpp
index 7b782d7a10c..c4764006d96 100644
--- a/src/hotspot/share/logging/logFileOutput.cpp
+++ b/src/hotspot/share/logging/logFileOutput.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -169,6 +169,7 @@ bool LogFileOutput::parse_options(const char* options, outputStream* errstream)
char* equals_pos = strchr(pos, '=');
if (equals_pos == NULL) {
+ errstream->print_cr("Invalid option '%s' for log file output.", pos);
success = false;
break;
}
diff --git a/src/hotspot/share/logging/logFileOutput.hpp b/src/hotspot/share/logging/logFileOutput.hpp
index 8ce9deb67c8..aca7026475e 100644
--- a/src/hotspot/share/logging/logFileOutput.hpp
+++ b/src/hotspot/share/logging/logFileOutput.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -85,7 +85,7 @@ class LogFileOutput : public LogFileStreamOutput {
virtual int write(const LogDecorations& decorations, const char* msg);
virtual int write(LogMessageBuffer::Iterator msg_iterator);
virtual void force_rotate();
- virtual void describe(outputStream *out);
+ virtual void describe(outputStream* out);
virtual const char* name() const {
return _name;
diff --git a/src/hotspot/share/logging/logLevel.cpp b/src/hotspot/share/logging/logLevel.cpp
index f33653e6dda..2b9ef795163 100644
--- a/src/hotspot/share/logging/logLevel.cpp
+++ b/src/hotspot/share/logging/logLevel.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "logging/logLevel.hpp"
#include "utilities/globalDefinitions.hpp"
+#include "utilities/stringUtils.hpp"
const char* LogLevel::_name[] = {
"off",
@@ -40,3 +41,19 @@ LogLevelType LogLevel::from_string(const char* str) {
}
return Invalid;
}
+
+LogLevelType LogLevel::fuzzy_match(const char *level) {
+ size_t len = strlen(level);
+ LogLevelType match = LogLevel::Invalid;
+ double best = 0.4; // required similarity to be considered a match
+ for (uint i = 1; i < Count; i++) {
+ LogLevelType cur = static_cast(i);
+ const char* levelname = LogLevel::name(cur);
+ double score = StringUtils::similarity(level, len, levelname, strlen(levelname));
+ if (score >= best) {
+ match = cur;
+ best= score;
+ }
+ }
+ return match;
+}
diff --git a/src/hotspot/share/logging/logLevel.hpp b/src/hotspot/share/logging/logLevel.hpp
index 4ea016b6f1e..2db0c34cfcd 100644
--- a/src/hotspot/share/logging/logLevel.hpp
+++ b/src/hotspot/share/logging/logLevel.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -71,6 +71,7 @@ class LogLevel : public AllStatic {
}
static LogLevel::type from_string(const char* str);
+ static LogLevel::type fuzzy_match(const char *level);
private:
static const char* _name[];
diff --git a/src/hotspot/share/logging/logMessageBuffer.cpp b/src/hotspot/share/logging/logMessageBuffer.cpp
index f652dc5bd98..6a890630ac8 100644
--- a/src/hotspot/share/logging/logMessageBuffer.cpp
+++ b/src/hotspot/share/logging/logMessageBuffer.cpp
@@ -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
@@ -110,7 +110,7 @@ void LogMessageBuffer::vwrite(LogLevelType level, const char* fmt, va_list args)
va_list copy;
va_copy(copy, args);
- written += (size_t)os::log_vsnprintf(current_buffer_position, remaining_buffer_length, fmt, copy) + 1;
+ written += (size_t)os::vsnprintf(current_buffer_position, remaining_buffer_length, fmt, copy) + 1;
va_end(copy);
if (written > _message_buffer_capacity - _message_buffer_size) {
assert(attempts == 0, "Second attempt should always have a sufficiently large buffer (resized to fit).");
diff --git a/src/hotspot/share/logging/logOutput.cpp b/src/hotspot/share/logging/logOutput.cpp
index a9039ff8c7f..d3e9670ea7d 100644
--- a/src/hotspot/share/logging/logOutput.cpp
+++ b/src/hotspot/share/logging/logOutput.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,8 +23,10 @@
*/
#include "precompiled.hpp"
#include "jvm.h"
+#include "logging/log.hpp"
#include "logging/logFileStreamOutput.hpp"
#include "logging/logOutput.hpp"
+#include "logging/logSelection.hpp"
#include "logging/logTagSet.hpp"
#include "memory/allocation.inline.hpp"
#include "runtime/mutexLocker.hpp"
@@ -34,11 +36,23 @@ LogOutput::~LogOutput() {
os::free(_config_string);
}
-void LogOutput::clear_config_string() {
- os::free(_config_string);
- _config_string_buffer_size = InitialConfigBufferSize;
- _config_string = NEW_C_HEAP_ARRAY(char, _config_string_buffer_size, mtLogging);
- _config_string[0] = '\0';
+void LogOutput::describe(outputStream *out) {
+ out->print("%s ", name());
+ out->print_raw(config_string()); // raw printed because length might exceed O_BUFLEN
+
+ bool has_decorator = false;
+ char delimiter = ' ';
+ for (size_t d = 0; d < LogDecorators::Count; d++) {
+ LogDecorators::Decorator decorator = static_cast(d);
+ if (decorators().is_decorator(decorator)) {
+ has_decorator = true;
+ out->print("%c%s", delimiter, LogDecorators::name(decorator));
+ delimiter = ',';
+ }
+ }
+ if (!has_decorator) {
+ out->print(" none");
+ }
}
void LogOutput::set_config_string(const char* string) {
@@ -47,7 +61,7 @@ void LogOutput::set_config_string(const char* string) {
_config_string_buffer_size = strlen(_config_string) + 1;
}
-void LogOutput::add_to_config_string(const LogTagSet* ts, LogLevelType level) {
+void LogOutput::add_to_config_string(const LogSelection& selection) {
if (_config_string_buffer_size < InitialConfigBufferSize) {
_config_string_buffer_size = InitialConfigBufferSize;
_config_string = REALLOC_C_HEAP_ARRAY(char, _config_string, _config_string_buffer_size, mtLogging);
@@ -60,7 +74,8 @@ void LogOutput::add_to_config_string(const LogTagSet* ts, LogLevelType level) {
}
for (;;) {
- int ret = ts->label(_config_string + offset, _config_string_buffer_size - offset, "+");
+ int ret = selection.describe(_config_string + offset,
+ _config_string_buffer_size - offset);
if (ret == -1) {
// Double the buffer size and retry
_config_string_buffer_size *= 2;
@@ -69,30 +84,257 @@ void LogOutput::add_to_config_string(const LogTagSet* ts, LogLevelType level) {
}
break;
};
+}
- offset = strlen(_config_string);
- for (;;) {
- int ret = jio_snprintf(_config_string + offset, _config_string_buffer_size - offset, "=%s", LogLevel::name(level));
- if (ret == -1) {
- _config_string_buffer_size *= 2;
- _config_string = REALLOC_C_HEAP_ARRAY(char, _config_string, _config_string_buffer_size, mtLogging);
+
+static int tag_cmp(const void *a, const void *b) {
+ return static_cast(a) - static_cast(b);
+}
+
+static void sort_tags(LogTagType tags[LogTag::MaxTags]) {
+ size_t ntags = 0;
+ while (tags[ntags] != LogTag::__NO_TAG) {
+ ntags++;
+ }
+ qsort(tags, ntags, sizeof(*tags), tag_cmp);
+}
+
+static const size_t MaxSubsets = 1 << LogTag::MaxTags;
+
+// Fill result with all possible subsets of the given tag set. Empty set not included.
+// For example, if tags is {gc, heap} then the result is {{gc}, {heap}, {gc, heap}}.
+// (Arguments with default values are intended exclusively for recursive calls.)
+static void generate_all_subsets_of(LogTagType result[MaxSubsets][LogTag::MaxTags],
+ size_t* result_size,
+ const LogTagType tags[LogTag::MaxTags],
+ LogTagType subset[LogTag::MaxTags] = NULL,
+ const size_t subset_size = 0,
+ const size_t depth = 0) {
+ assert(subset_size <= LogTag::MaxTags, "subset must never have more than MaxTags tags");
+ assert(depth <= LogTag::MaxTags, "recursion depth overflow");
+
+ if (subset == NULL) {
+ assert(*result_size == 0, "outer (non-recursive) call expects result_size to be 0");
+ // Make subset the first element in the result array initially
+ subset = result[0];
+ }
+ assert((void*) subset >= &result[0] && (void*) subset <= &result[MaxSubsets - 1],
+ "subset should always point to element in result");
+
+ if (depth == LogTag::MaxTags || tags[depth] == LogTag::__NO_TAG) {
+ if (subset_size == 0) {
+ // Ignore empty subset
+ return;
+ }
+ if (subset_size != LogTag::MaxTags) {
+ subset[subset_size] = LogTag::__NO_TAG;
+ }
+ assert(*result_size < MaxSubsets, "subsets overflow");
+ *result_size += 1;
+
+ // Bump subset and copy over current state
+ memcpy(result[*result_size], subset, sizeof(*subset) * LogTag::MaxTags);
+ subset = result[*result_size];
+ return;
+ }
+
+ // Recurse, excluding the tag of the current depth
+ generate_all_subsets_of(result, result_size, tags, subset, subset_size, depth + 1);
+ // ... and with it included
+ subset[subset_size] = tags[depth];
+ generate_all_subsets_of(result, result_size, tags, subset, subset_size + 1, depth + 1);
+}
+
+// Generate all possible selections (for the given level) based on the given tag set,
+// and add them to the selections array (growing it as necessary).
+static void add_selections(LogSelection** selections,
+ size_t* n_selections,
+ size_t* selections_cap,
+ const LogTagSet& tagset,
+ LogLevelType level) {
+ LogTagType tags[LogTag::MaxTags] = { LogTag::__NO_TAG };
+ for (size_t i = 0; i < tagset.ntags(); i++) {
+ tags[i] = tagset.tag(i);
+ }
+
+ size_t n_subsets = 0;
+ LogTagType subsets[MaxSubsets][LogTag::MaxTags];
+ generate_all_subsets_of(subsets, &n_subsets, tags);
+
+ for (size_t i = 0; i < n_subsets; i++) {
+ // Always keep tags sorted
+ sort_tags(subsets[i]);
+
+ // Ignore subsets already represented in selections
+ bool unique = true;
+ for (size_t sel = 0; sel < *n_selections; sel++) {
+ if (level == (*selections)[sel].level() && (*selections)[sel].consists_of(subsets[i])) {
+ unique = false;
+ break;
+ }
+ }
+ if (!unique) {
continue;
}
- break;
- }
-}
-void LogOutput::describe(outputStream *out) {
- out->print("%s ", name());
- out->print_raw(config_string());
- out->print(" ");
- char delimiter[2] = {0};
- for (size_t d = 0; d < LogDecorators::Count; d++) {
- LogDecorators::Decorator decorator = static_cast(d);
- if (decorators().is_decorator(decorator)) {
- out->print("%s%s", delimiter, LogDecorators::name(decorator));
- *delimiter = ',';
+ LogSelection exact_selection(subsets[i], false, level);
+ LogSelection wildcard_selection(subsets[i], true, level);
+
+ // Check if the two selections match any tag sets
+ bool wildcard_match = false;
+ bool exact_match = false;
+ for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
+ if (!wildcard_selection.selects(*ts)) {
+ continue;
+ }
+
+ wildcard_match = true;
+ if (exact_selection.selects(*ts)) {
+ exact_match = true;
+ }
+ if (exact_match) {
+ break;
+ }
+ }
+
+ if (!wildcard_match && !exact_match) {
+ continue;
+ }
+
+ // Ensure there's enough room for both wildcard_match and exact_match
+ if (*n_selections + 2 > *selections_cap) {
+ *selections_cap *= 2;
+ *selections = REALLOC_C_HEAP_ARRAY(LogSelection, *selections, *selections_cap, mtLogging);
+ }
+
+ // Add found matching selections to the result array
+ if (exact_match) {
+ (*selections)[(*n_selections)++] = exact_selection;
+ }
+ if (wildcard_match) {
+ (*selections)[(*n_selections)++] = wildcard_selection;
}
}
}
+void LogOutput::update_config_string(const size_t on_level[LogLevel::Count]) {
+ // Find the most common level (MCL)
+ LogLevelType mcl = LogLevel::Off;
+ size_t max = on_level[LogLevel::Off];
+ for (LogLevelType l = LogLevel::First; l <= LogLevel::Last; l = static_cast(l + 1)) {
+ if (on_level[l] > max) {
+ mcl = l;
+ max = on_level[l];
+ }
+ }
+
+ // Always let the first part of each output's config string be "all="
+ {
+ char buf[64];
+ jio_snprintf(buf, sizeof(buf), "all=%s", LogLevel::name(mcl));
+ set_config_string(buf);
+ }
+
+ // If there are no deviating tag sets, we're done
+ size_t deviating_tagsets = LogTagSet::ntagsets() - max;
+ if (deviating_tagsets == 0) {
+ return;
+ }
+
+ size_t n_selections = 0;
+ size_t selections_cap = 4 * MaxSubsets; // Start with some reasonably large initial capacity
+ LogSelection* selections = NEW_C_HEAP_ARRAY(LogSelection, selections_cap, mtLogging);
+
+ size_t n_deviates = 0;
+ const LogTagSet** deviates = NEW_C_HEAP_ARRAY(const LogTagSet*, deviating_tagsets, mtLogging);
+
+ // Generate all possible selections involving the deviating tag sets
+ for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
+ LogLevelType level = ts->level_for(this);
+ if (level == mcl) {
+ continue;
+ }
+ deviates[n_deviates++] = ts;
+ add_selections(&selections, &n_selections, &selections_cap, *ts, level);
+ }
+
+ // Reduce deviates greedily, using the "best" selection at each step to reduce the number of deviating tag sets
+ while (n_deviates > 0) {
+ size_t prev_deviates = n_deviates;
+ int max_score = 0;
+ const LogSelection* best_selection = NULL;
+ for (size_t i = 0; i < n_selections; i++) {
+
+ // Give the selection a score based on how many deviating tag sets it selects (with correct level)
+ int score = 0;
+ for (size_t d = 0; d < n_deviates; d++) {
+ if (selections[i].selects(*deviates[d]) && deviates[d]->level_for(this) == selections[i].level()) {
+ score++;
+ }
+ }
+
+ // Ignore selections with lower score than the current best even before subtracting mismatched selections
+ if (score < max_score) {
+ continue;
+ }
+
+ // Subtract from the score the number of tag sets it selects with an incorrect level
+ for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
+ if (selections[i].selects(*ts) && ts->level_for(this) != selections[i].level()) {
+ score--;
+ }
+ }
+
+ // Pick the selection with the best score, or in the case of a tie, the one with fewest tags
+ if (score > max_score ||
+ (score == max_score && best_selection != NULL && selections[i].ntags() < best_selection->ntags())) {
+ max_score = score;
+ best_selection = &selections[i];
+ }
+ }
+
+ assert(best_selection != NULL, "must always find a maximal selection");
+ add_to_config_string(*best_selection);
+
+ // Remove all deviates that this selection covered
+ for (size_t d = 0; d < n_deviates;) {
+ if (deviates[d]->level_for(this) == best_selection->level() && best_selection->selects(*deviates[d])) {
+ deviates[d] = deviates[--n_deviates];
+ continue;
+ }
+ d++;
+ }
+
+ // Add back any new deviates that this selection added (no array growth since removed > added)
+ for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
+ if (ts->level_for(this) == best_selection->level() || !best_selection->selects(*ts)) {
+ continue;
+ }
+
+ bool already_added = false;
+ for (size_t dev = 0; dev < n_deviates; dev++) {
+ if (deviates[dev] == ts) {
+ already_added = true;
+ break;
+ }
+ }
+ if (already_added) {
+ continue;
+ }
+
+ deviates[n_deviates++] = ts;
+ }
+
+ // Reset the selections and generate a new ones based on the updated deviating tag sets
+ n_selections = 0;
+ for (size_t d = 0; d < n_deviates; d++) {
+ add_selections(&selections, &n_selections, &selections_cap, *deviates[d], deviates[d]->level_for(this));
+ }
+
+ assert(n_deviates < deviating_tagsets, "deviating tag set array overflow");
+ assert(prev_deviates > n_deviates, "number of deviating tag sets must never grow");
+ }
+ FREE_C_HEAP_ARRAY(LogTagSet*, deviates);
+ FREE_C_HEAP_ARRAY(Selection, selections);
+}
+
diff --git a/src/hotspot/share/logging/logOutput.hpp b/src/hotspot/share/logging/logOutput.hpp
index bdfb77b0f5b..d857b8cc43b 100644
--- a/src/hotspot/share/logging/logOutput.hpp
+++ b/src/hotspot/share/logging/logOutput.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,7 @@
class LogDecorations;
class LogMessageBuffer;
+class LogSelection;
class LogTagSet;
// The base class/interface for log outputs.
@@ -43,19 +44,27 @@ class LogOutput : public CHeapObj {
private:
static const size_t InitialConfigBufferSize = 256;
+
+ // Track if the output has been reconfigured dynamically during runtime.
+ // The status is set each time the configuration of the output is modified,
+ // and is reset once after logging initialization is complete.
+ bool _reconfigured;
+
char* _config_string;
size_t _config_string_buffer_size;
+ // Adds the log selection to the config description (e.g. "tag1+tag2*=level").
+ void add_to_config_string(const LogSelection& selection);
+
protected:
LogDecorators _decorators;
- // Clears any previous config description in preparation of reconfiguration.
- void clear_config_string();
- // Adds the tagset on the given level to the config description (e.g. "tag1+tag2=level").
- void add_to_config_string(const LogTagSet* ts, LogLevelType level);
// Replaces the current config description with the given string.
void set_config_string(const char* string);
+ // Update the config string for this output to reflect its current configuration
+ void update_config_string(const size_t on_level[LogLevel::Count]);
+
public:
void set_decorators(const LogDecorators &decorators) {
_decorators = decorators;
@@ -65,11 +74,15 @@ class LogOutput : public CHeapObj {
return _decorators;
}
+ bool is_reconfigured() const {
+ return _reconfigured;
+ }
+
const char* config_string() const {
return _config_string;
}
- LogOutput() : _config_string(NULL), _config_string_buffer_size(0) {
+ LogOutput() : _reconfigured(false), _config_string(NULL), _config_string_buffer_size(0) {
}
virtual ~LogOutput();
diff --git a/src/hotspot/share/logging/logSelection.cpp b/src/hotspot/share/logging/logSelection.cpp
new file mode 100644
index 00000000000..5fcc63228f7
--- /dev/null
+++ b/src/hotspot/share/logging/logSelection.cpp
@@ -0,0 +1,351 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#include "precompiled.hpp"
+#include "utilities/ostream.hpp"
+#include "logging/log.hpp"
+#include "logging/logSelection.hpp"
+#include "logging/logTagSet.hpp"
+#include "runtime/os.inline.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/ostream.hpp"
+#include "utilities/quickSort.hpp"
+
+const LogSelection LogSelection::Invalid;
+
+LogSelection::LogSelection() : _ntags(0), _wildcard(false), _level(LogLevel::Invalid), _tag_sets_selected(0) {
+}
+
+LogSelection::LogSelection(const LogTagType tags[LogTag::MaxTags], bool wildcard, LogLevelType level)
+ : _ntags(0), _wildcard(wildcard), _level(level), _tag_sets_selected(0) {
+ while (_ntags < LogTag::MaxTags && tags[_ntags] != LogTag::__NO_TAG) {
+ _tags[_ntags] = tags[_ntags];
+ _ntags++;
+ }
+
+ for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
+ if (selects(*ts)) {
+ _tag_sets_selected++;
+ }
+ }
+}
+
+bool LogSelection::operator==(const LogSelection& ref) const {
+ if (_ntags != ref._ntags ||
+ _wildcard != ref._wildcard ||
+ _level != ref._level ||
+ _tag_sets_selected != ref._tag_sets_selected) {
+ return false;
+ }
+ for (size_t i = 0; i < _ntags; i++) {
+ if (_tags[i] != ref._tags[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool LogSelection::operator!=(const LogSelection& ref) const {
+ return !operator==(ref);
+}
+
+static LogSelection parse_internal(char *str, outputStream* errstream) {
+ // Parse the level, if specified
+ LogLevelType level = LogLevel::Unspecified;
+ char* equals = strchr(str, '=');
+ if (equals != NULL) {
+ const char* levelstr = equals + 1;
+ level = LogLevel::from_string(levelstr);
+ if (level == LogLevel::Invalid) {
+ if (errstream != NULL) {
+ errstream->print("Invalid level '%s' in log selection.", levelstr);
+ LogLevelType match = LogLevel::fuzzy_match(levelstr);
+ if (match != LogLevel::Invalid) {
+ errstream->print(" Did you mean '%s'?", LogLevel::name(match));
+ }
+ errstream->cr();
+ }
+ return LogSelection::Invalid;
+ }
+ *equals = '\0';
+ }
+
+ size_t ntags = 0;
+ LogTagType tags[LogTag::MaxTags] = { LogTag::__NO_TAG };
+
+ // Parse special tags such as 'all'
+ if (strcmp(str, "all") == 0) {
+ return LogSelection(tags, true, level);
+ }
+
+ // Check for '*' suffix
+ bool wildcard = false;
+ char* asterisk_pos = strchr(str, '*');
+ if (asterisk_pos != NULL && asterisk_pos[1] == '\0') {
+ wildcard = true;
+ *asterisk_pos = '\0';
+ }
+
+ // Parse the tag expression (t1+t2+...+tn)
+ char* plus_pos;
+ char* cur_tag = str;
+ do {
+ plus_pos = strchr(cur_tag, '+');
+ if (plus_pos != NULL) {
+ *plus_pos = '\0';
+ }
+ LogTagType tag = LogTag::from_string(cur_tag);
+ if (tag == LogTag::__NO_TAG) {
+ if (errstream != NULL) {
+ errstream->print("Invalid tag '%s' in log selection.", cur_tag);
+ LogTagType match = LogTag::fuzzy_match(cur_tag);
+ if (match != LogTag::__NO_TAG) {
+ errstream->print(" Did you mean '%s'?", LogTag::name(match));
+ }
+ errstream->cr();
+ }
+ return LogSelection::Invalid;
+ }
+ if (ntags == LogTag::MaxTags) {
+ if (errstream != NULL) {
+ errstream->print_cr("Too many tags in log selection '%s' (can only have up to " SIZE_FORMAT " tags).",
+ str, LogTag::MaxTags);
+ }
+ return LogSelection::Invalid;
+ }
+ tags[ntags++] = tag;
+ cur_tag = plus_pos + 1;
+ } while (plus_pos != NULL);
+
+ for (size_t i = 0; i < ntags; i++) {
+ for (size_t j = 0; j < ntags; j++) {
+ if (i != j && tags[i] == tags[j]) {
+ if (errstream != NULL) {
+ errstream->print_cr("Log selection contains duplicates of tag %s.", LogTag::name(tags[i]));
+ }
+ return LogSelection::Invalid;
+ }
+ }
+ }
+
+ return LogSelection(tags, wildcard, level);
+}
+
+LogSelection LogSelection::parse(const char* str, outputStream* error_stream) {
+ char* copy = os::strdup_check_oom(str, mtLogging);
+ LogSelection s = parse_internal(copy, error_stream);
+ os::free(copy);
+ return s;
+}
+
+bool LogSelection::selects(const LogTagSet& ts) const {
+ if (!_wildcard && _ntags != ts.ntags()) {
+ return false;
+ }
+ for (size_t i = 0; i < _ntags; i++) {
+ if (!ts.contains(_tags[i])) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static bool contains(LogTagType tag, const LogTagType tags[LogTag::MaxTags], size_t ntags) {
+ for (size_t i = 0; i < ntags; i++) {
+ if (tags[i] == tag) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool LogSelection::consists_of(const LogTagType tags[LogTag::MaxTags]) const {
+ size_t i;
+ for (i = 0; tags[i] != LogTag::__NO_TAG; i++) {
+ if (!contains(tags[i], _tags, _ntags)) {
+ return false;
+ }
+ }
+ return i == _ntags;
+}
+
+size_t LogSelection::ntags() const {
+ return _ntags;
+}
+
+LogLevelType LogSelection::level() const {
+ return _level;
+}
+
+size_t LogSelection::tag_sets_selected() const {
+ return _tag_sets_selected;
+}
+
+int LogSelection::describe_tags(char* buf, size_t bufsize) const {
+ int tot_written = 0;
+ for (size_t i = 0; i < _ntags; i++) {
+ int written = jio_snprintf(buf + tot_written, bufsize - tot_written,
+ "%s%s", (i == 0 ? "" : "+"), LogTag::name(_tags[i]));
+ if (written == -1) {
+ return written;
+ }
+ tot_written += written;
+ }
+
+ if (_wildcard) {
+ int written = jio_snprintf(buf + tot_written, bufsize - tot_written, "*");
+ if (written == -1) {
+ return written;
+ }
+ tot_written += written;
+ }
+ return tot_written;
+}
+
+int LogSelection::describe(char* buf, size_t bufsize) const {
+ int tot_written = describe_tags(buf, bufsize);
+
+ int written = jio_snprintf(buf + tot_written, bufsize - tot_written, "=%s", LogLevel::name(_level));
+ if (written == -1) {
+ return -1;
+ }
+ tot_written += written;
+ return tot_written;
+}
+
+double LogSelection::similarity(const LogSelection& other) const {
+ // Compute Soerensen-Dice coefficient as the similarity measure
+ size_t intersecting = 0;
+ for (size_t i = 0; i < _ntags; i++) {
+ for (size_t j = 0; j < other._ntags; j++) {
+ if (_tags[i] == other._tags[j]) {
+ intersecting++;
+ break;
+ }
+ }
+ }
+ return 2.0 * intersecting / (_ntags + other._ntags);
+}
+
+// Comparator used for sorting LogSelections based on their similarity to a specific LogSelection.
+// A negative return value means that 'a' is more similar to 'ref' than 'b' is, while a positive
+// return value means that 'b' is more similar.
+// For the sake of giving short and effective suggestions, when two selections have an equal
+// similarity score, the selection with the fewer tags (selecting the most tag sets) is considered
+// more similar.
+class SimilarityComparator {
+ const LogSelection& _ref;
+ public:
+ SimilarityComparator(const LogSelection& ref) : _ref(ref) {
+ }
+ int operator()(const LogSelection& a, const LogSelection& b) const {
+ const double epsilon = 1.0e-6;
+
+ // Sort by similarity (descending)
+ double s = _ref.similarity(b) - _ref.similarity(a);
+ if (fabs(s) > epsilon) {
+ return s < 0 ? -1 : 1;
+ }
+
+ // Then by number of tags (ascending)
+ int t = static_cast(a.ntags() - (int)b.ntags());
+ if (t != 0) {
+ return t;
+ }
+
+ // Lastly by tag sets selected (descending)
+ return static_cast(b.tag_sets_selected() - a.tag_sets_selected());
+ }
+};
+
+static const size_t suggestion_cap = 5;
+static const double similarity_requirement = 0.3;
+void LogSelection::suggest_similar_matching(outputStream* out) const {
+ LogSelection suggestions[suggestion_cap];
+ uint nsuggestions = 0;
+
+ // See if simply adding a wildcard would make the selection match
+ if (!_wildcard) {
+ LogSelection sel(_tags, true, _level);
+ if (sel.tag_sets_selected() > 0) {
+ suggestions[nsuggestions++] = sel;
+ }
+ }
+
+ // Check for matching tag sets with a single tag mismatching (a tag too many or short a tag)
+ for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
+ LogTagType tags[LogTag::MaxTags] = { LogTag::__NO_TAG };
+ for (size_t i = 0; i < ts->ntags(); i++) {
+ tags[i] = ts->tag(i);
+ }
+
+ // Suggest wildcard selection unless the wildcard doesn't match anything extra
+ LogSelection sel(tags, true, _level);
+ if (sel.tag_sets_selected() == 1) {
+ sel = LogSelection(tags, false, _level);
+ }
+
+ double score = similarity(sel);
+
+ // Ignore suggestions with too low similarity
+ if (score < similarity_requirement) {
+ continue;
+ }
+
+ // Cap not reached, simply add the new suggestion and continue searching
+ if (nsuggestions < suggestion_cap) {
+ suggestions[nsuggestions++] = sel;
+ continue;
+ }
+
+ // Find the least matching suggestion already found, and if the new suggestion is a better match, replace it
+ double min = 1.0;
+ size_t pos = -1;
+ for (size_t i = 0; i < nsuggestions; i++) {
+ double score = similarity(suggestions[i]);
+ if (score < min) {
+ min = score;
+ pos = i;
+ }
+ }
+ if (score > min) {
+ suggestions[pos] = sel;
+ }
+ }
+
+ if (nsuggestions == 0) {
+ // Found no similar enough selections to suggest.
+ return;
+ }
+
+ // Sort found suggestions to suggest the best one first
+ SimilarityComparator sc(*this);
+ QuickSort::sort(suggestions, nsuggestions, sc, false);
+
+ out->print("Did you mean any of the following?");
+ for (size_t i = 0; i < nsuggestions; i++) {
+ char buf[128];
+ suggestions[i].describe_tags(buf, sizeof(buf));
+ out->print(" %s", buf);
+ }
+}
diff --git a/src/hotspot/share/logging/logSelection.hpp b/src/hotspot/share/logging/logSelection.hpp
new file mode 100644
index 00000000000..d70a019770f
--- /dev/null
+++ b/src/hotspot/share/logging/logSelection.hpp
@@ -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.
+ *
+ */
+#ifndef SHARE_VM_LOGGING_LOGSELECTION_HPP
+#define SHARE_VM_LOGGING_LOGSELECTION_HPP
+
+#include "logging/logLevel.hpp"
+#include "logging/logTag.hpp"
+#include "memory/allocation.hpp"
+
+class LogTagSet;
+
+// Class representing a selection of tags with for a given level.
+// Consists of a set of tags, an optional wildcard flag, and a level, e.g. "tag1+tag2*=level".
+class LogSelection : public StackObj {
+ friend class LogSelectionList;
+
+ private:
+ size_t _ntags;
+ LogTagType _tags[LogTag::MaxTags];
+ bool _wildcard;
+ LogLevelType _level;
+ size_t _tag_sets_selected;
+
+ LogSelection();
+
+ public:
+ static const LogSelection Invalid;
+
+ static LogSelection parse(const char* str, outputStream* error_stream = NULL);
+
+ LogSelection(const LogTagType tags[LogTag::MaxTags], bool wildcard, LogLevelType level);
+
+ bool operator==(const LogSelection& ref) const;
+ bool operator!=(const LogSelection& ref) const;
+
+ size_t ntags() const;
+ LogLevelType level() const;
+ size_t tag_sets_selected() const;
+
+ bool selects(const LogTagSet& ts) const;
+ bool consists_of(const LogTagType tags[LogTag::MaxTags]) const;
+
+ int describe_tags(char* buf, size_t bufsize) const;
+ int describe(char* buf, size_t bufsize) const;
+
+ // List similar selections that matches existing tag sets on the given outputstream
+ void suggest_similar_matching(outputStream* out) const;
+
+ // Compute a similarity measure in the range [0, 1], where higher means more similar
+ double similarity(const LogSelection& other) const;
+};
+
+#endif // SHARE_VM_LOGGING_LOGSELECTION_HPP
diff --git a/src/hotspot/share/logging/logSelectionList.cpp b/src/hotspot/share/logging/logSelectionList.cpp
new file mode 100644
index 00000000000..977e4489f04
--- /dev/null
+++ b/src/hotspot/share/logging/logSelectionList.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "logging/logSelectionList.hpp"
+#include "logging/logTagSet.hpp"
+#include "runtime/arguments.hpp"
+#include "runtime/os.inline.hpp"
+
+static const char* DefaultExpressionString = "all";
+
+bool LogSelectionList::verify_selections(outputStream* out) const {
+ bool valid = true;
+
+ for (size_t i = 0; i < _nselections; i++) {
+ if (_selections[i].tag_sets_selected() == 0) {
+ // Return immediately unless all invalid selections should be listed
+ if (out == NULL) {
+ return false;
+ }
+
+ out->print("No tag set matches selection:");
+ valid = false;
+
+ char buf[256];
+ _selections[i].describe_tags(buf, sizeof(buf));
+ out->print(" %s. ", buf);
+
+ _selections[i].suggest_similar_matching(out);
+ out->cr();
+ }
+ }
+ return valid;
+}
+
+
+bool LogSelectionList::parse(const char* str, outputStream* errstream) {
+ bool success = true;
+ if (str == NULL || strcmp(str, "") == 0) {
+ str = DefaultExpressionString;
+ }
+ char* copy = os::strdup_check_oom(str, mtLogging);
+ // Split string on commas
+ for (char *comma_pos = copy, *cur = copy; success && comma_pos != NULL; cur = comma_pos + 1) {
+ if (_nselections == MaxSelections) {
+ if (errstream != NULL) {
+ errstream->print_cr("Can not have more than " SIZE_FORMAT " log selections in a single configuration.",
+ MaxSelections);
+ }
+ success = false;
+ break;
+ }
+
+ comma_pos = strchr(cur, ',');
+ if (comma_pos != NULL) {
+ *comma_pos = '\0';
+ }
+
+ LogSelection selection = LogSelection::parse(cur, errstream);
+ if (selection == LogSelection::Invalid) {
+ success = false;
+ break;
+ }
+ _selections[_nselections++] = selection;
+ }
+
+ os::free(copy);
+ return success;
+}
+
+LogLevelType LogSelectionList::level_for(const LogTagSet& ts) const {
+ // Return NotMentioned if the given tagset isn't covered by this expression.
+ LogLevelType level = LogLevel::NotMentioned;
+ for (size_t i= 0; i < _nselections; i++) {
+ if (_selections[i].selects(ts)) {
+ level = _selections[i].level();
+ }
+ }
+ return level;
+}
diff --git a/src/hotspot/share/logging/logSelectionList.hpp b/src/hotspot/share/logging/logSelectionList.hpp
new file mode 100644
index 00000000000..22414fb4478
--- /dev/null
+++ b/src/hotspot/share/logging/logSelectionList.hpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015, 2018 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef SHARE_VM_LOGGING_LOGSELECTIONLIST_HPP
+#define SHARE_VM_LOGGING_LOGSELECTIONLIST_HPP
+
+#include "logging/logConfiguration.hpp"
+#include "logging/logSelection.hpp"
+#include "logging/logTag.hpp"
+#include "memory/allocation.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class LogTagSet;
+
+// Class used to temporary encode a series of log selections during log configuration.
+// Consists of ordered LogSelections, i.e. "tag1+tag2=level1,tag3*=level2".
+class LogSelectionList : public StackObj {
+ public:
+ static const size_t MaxSelections = 256;
+
+ private:
+ friend void LogConfiguration::configure_stdout(LogLevelType, int, ...);
+
+ size_t _nselections;
+ LogSelection _selections[MaxSelections];
+
+ public:
+ LogSelectionList() : _nselections(0) {
+ }
+
+ LogSelectionList(const LogSelection& selection) : _nselections(1) {
+ _selections[0] = selection;
+ }
+
+ bool parse(const char* str, outputStream* errstream = NULL);
+ LogLevelType level_for(const LogTagSet& ts) const;
+
+ // Verify that each selection actually selects something.
+ // Returns false if some invalid selection was found. If given an outputstream,
+ // this function will list all the invalid selections on the stream.
+ bool verify_selections(outputStream* out = NULL) const;
+};
+
+#endif // SHARE_VM_LOGGING_LOGSELECTIONLIST_HPP
diff --git a/src/hotspot/share/logging/logTag.cpp b/src/hotspot/share/logging/logTag.cpp
index 9694ede5270..1ab13173854 100644
--- a/src/hotspot/share/logging/logTag.cpp
+++ b/src/hotspot/share/logging/logTag.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,10 @@
*/
#include "precompiled.hpp"
#include "logging/logTag.hpp"
+#include "utilities/stringUtils.hpp"
#include "utilities/globalDefinitions.hpp"
+#include "utilities/ostream.hpp"
+#include "utilities/quickSort.hpp"
const char* LogTag::_name[] = {
"", // __NO_TAG
@@ -40,3 +43,45 @@ LogTagType LogTag::from_string(const char* str) {
}
return __NO_TAG;
}
+
+LogTagType LogTag::fuzzy_match(const char *str) {
+ size_t len = strlen(str);
+ LogTagType match = LogTag::__NO_TAG;
+ double best = 0.5; // required similarity to be considered a match
+ for (size_t i = 1; i < LogTag::Count; i++) {
+ LogTagType tag = static_cast(i);
+ const char* tagname = LogTag::name(tag);
+ double score = StringUtils::similarity(tagname, strlen(tagname), str, len);
+ if (score >= best) {
+ match = tag;
+ best = score;
+ }
+ }
+ return match;
+}
+
+static int cmp_logtag(LogTagType a, LogTagType b) {
+ return strcmp(LogTag::name(a), LogTag::name(b));
+}
+
+static const size_t sorted_tagcount = LogTag::Count - 1; // Not counting _NO_TAG
+static LogTagType sorted_tags[sorted_tagcount];
+
+class TagSorter {
+ public:
+ TagSorter() {
+ for (size_t i = 1; i < LogTag::Count; i++) {
+ sorted_tags[i - 1] = static_cast(i);
+ }
+ QuickSort::sort(sorted_tags, sorted_tagcount, cmp_logtag, true);
+ }
+};
+
+static TagSorter tagsorter; // Sorts tags during static initialization
+
+void LogTag::list_tags(outputStream* out) {
+ for (size_t i = 0; i < sorted_tagcount; i++) {
+ out->print("%s %s", (i == 0 ? "" : ","), _name[sorted_tags[i]]);
+ }
+ out->cr();
+}
diff --git a/src/hotspot/share/logging/logTag.hpp b/src/hotspot/share/logging/logTag.hpp
index cd13d7aba12..5ca0767ba88 100644
--- a/src/hotspot/share/logging/logTag.hpp
+++ b/src/hotspot/share/logging/logTag.hpp
@@ -192,6 +192,8 @@ class LogTag : public AllStatic {
}
static LogTag::type from_string(const char *str);
+ static LogTag::type fuzzy_match(const char *tag);
+ static void list_tags(outputStream* out);
private:
static const char* _name[];
diff --git a/src/hotspot/share/logging/logTagLevelExpression.cpp b/src/hotspot/share/logging/logTagLevelExpression.cpp
deleted file mode 100644
index 6b53ab563a9..00000000000
--- a/src/hotspot/share/logging/logTagLevelExpression.cpp
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-#include "precompiled.hpp"
-#include "logging/logTagLevelExpression.hpp"
-#include "logging/logTagSet.hpp"
-#include "runtime/arguments.hpp"
-#include "runtime/os.inline.hpp"
-
-const char* LogTagLevelExpression::DefaultExpressionString = "all";
-
-static bool matches_tagset(const LogTagType tags[],
- bool allow_other_tags,
- const LogTagSet& ts) {
- bool contains_all = true;
- size_t tag_idx;
- for (tag_idx = 0; tag_idx < LogTag::MaxTags && tags[tag_idx] != LogTag::__NO_TAG; tag_idx++) {
- if (!ts.contains(tags[tag_idx])) {
- contains_all = false;
- break;
- }
- }
- // All tags in the expression must be part of the tagset,
- // and either the expression allows other tags (has a wildcard),
- // or the number of tags in the expression and tagset must match.
- return contains_all && (allow_other_tags || tag_idx == ts.ntags());
-}
-
-bool LogTagLevelExpression::verify_tagsets(outputStream* out) const {
- bool valid = true;
-
- for (size_t i = 0; i < _ncombinations; i++) {
- bool matched = false;
- for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
- if (matches_tagset(_tags[i], _allow_other_tags[i], *ts)) {
- matched = true;
- break;
- }
- }
-
- if (!matched) {
- // If this was the first invalid combination, write the message header
- if (valid && out != NULL) {
- out->print("No tag set matches selection(s): ");
- }
- valid = false;
-
- // Break as soon as possible unless listing all invalid combinations
- if (out == NULL) {
- break;
- }
-
- // List the combination on the outputStream
- for (size_t t = 0; t < LogTag::MaxTags && _tags[i][t] != LogTag::__NO_TAG; t++) {
- out->print("%s%s", (t == 0 ? "" : "+"), LogTag::name(_tags[i][t]));
- }
- if (_allow_other_tags[i]) {
- out->print("*");
- }
- out->print(" ");
- }
- }
-
- if (!valid && out != NULL) {
- out->cr();
- }
-
- return valid;
-}
-
-bool LogTagLevelExpression::parse(const char* str, outputStream* errstream) {
- bool success = true;
- if (str == NULL || strcmp(str, "") == 0) {
- str = DefaultExpressionString;
- }
- char* copy = os::strdup_check_oom(str, mtLogging);
- // Split string on commas
- for (char *comma_pos = copy, *cur = copy; success && comma_pos != NULL; cur = comma_pos + 1) {
- if (_ncombinations == MaxCombinations) {
- if (errstream != NULL) {
- errstream->print_cr("Can not have more than " SIZE_FORMAT " tag combinations in a what-expression.",
- MaxCombinations);
- }
- success = false;
- break;
- }
-
- comma_pos = strchr(cur, ',');
- if (comma_pos != NULL) {
- *comma_pos = '\0';
- }
-
- // Parse the level, if specified
- LogLevelType level = LogLevel::Unspecified;
- char* equals = strchr(cur, '=');
- if (equals != NULL) {
- level = LogLevel::from_string(equals + 1);
- if (level == LogLevel::Invalid) {
- if (errstream != NULL) {
- errstream->print_cr("Invalid level '%s' in what-expression.", equals + 1);
- }
- success = false;
- break;
- }
- *equals = '\0'; // now ignore "=level" part of substr
- }
- set_level(level);
-
- // Parse special tags such as 'all'
- if (strcmp(cur, "all") == 0) {
- set_allow_other_tags();
- new_combination();
- continue;
- }
-
- // Check for '*' suffix
- char* asterisk_pos = strchr(cur, '*');
- if (asterisk_pos != NULL && asterisk_pos[1] == '\0') {
- set_allow_other_tags();
- *asterisk_pos = '\0';
- }
-
- // Parse the tag expression (t1+t2+...+tn)
- char* plus_pos;
- char* cur_tag = cur;
- do {
- plus_pos = strchr(cur_tag, '+');
- if (plus_pos != NULL) {
- *plus_pos = '\0';
- }
- LogTagType tag = LogTag::from_string(cur_tag);
- if (tag == LogTag::__NO_TAG) {
- if (errstream != NULL) {
- errstream->print_cr("Invalid tag '%s' in what-expression.", cur_tag);
- }
- success = false;
- break;
- }
- if (_ntags == LogTag::MaxTags) {
- if (errstream != NULL) {
- errstream->print_cr("Tag combination exceeds the maximum of " SIZE_FORMAT " tags.",
- LogTag::MaxTags);
- }
- success = false;
- break;
- }
- if (!add_tag(tag)) {
- if (errstream != NULL) {
- errstream->print_cr("Tag combination have duplicate tag '%s' in what-expression.",
- cur_tag);
- }
- success = false;
- break;
- }
- cur_tag = plus_pos + 1;
- } while (plus_pos != NULL);
-
- new_combination();
- }
-
- os::free(copy);
- return success;
-}
-
-LogLevelType LogTagLevelExpression::level_for(const LogTagSet& ts) const {
- // Return NotMentioned if the given tagset isn't covered by this expression.
- LogLevelType level = LogLevel::NotMentioned;
- for (size_t combination = 0; combination < _ncombinations; combination++) {
- if (matches_tagset(_tags[combination], _allow_other_tags[combination], ts)) {
- level = _level[combination];
- }
- }
- return level;
-}
-
diff --git a/src/hotspot/share/logging/logTagLevelExpression.hpp b/src/hotspot/share/logging/logTagLevelExpression.hpp
deleted file mode 100644
index 98179889114..00000000000
--- a/src/hotspot/share/logging/logTagLevelExpression.hpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-#ifndef SHARE_VM_LOGGING_LOGTAGLEVELEXPRESSION_HPP
-#define SHARE_VM_LOGGING_LOGTAGLEVELEXPRESSION_HPP
-
-#include "logging/logConfiguration.hpp"
-#include "logging/logLevel.hpp"
-#include "logging/logTag.hpp"
-#include "memory/allocation.hpp"
-#include "utilities/debug.hpp"
-#include "utilities/globalDefinitions.hpp"
-
-class LogTagSet;
-
-// Class used to temporary encode a 'what'-expression during log configuration.
-// Consists of a combination of tags and levels, e.g. "tag1+tag2=level1,tag3*=level2".
-class LogTagLevelExpression : public StackObj {
- public:
- static const size_t MaxCombinations = 256;
-
- private:
- friend void LogConfiguration::configure_stdout(LogLevelType, int, ...);
-
- static const char* DefaultExpressionString;
-
- size_t _ntags, _ncombinations;
- LogTagType _tags[MaxCombinations][LogTag::MaxTags];
- LogLevelType _level[MaxCombinations];
- bool _allow_other_tags[MaxCombinations];
-
- void new_combination() {
- // Make sure either all tags are set or the last tag is __NO_TAG
- if (_ntags < LogTag::MaxTags) {
- _tags[_ncombinations][_ntags] = LogTag::__NO_TAG;
- }
-
- _ncombinations++;
- _ntags = 0;
- }
-
- bool add_tag(LogTagType tag) {
- assert(_ntags < LogTag::MaxTags, "Can't have more tags than MaxTags!");
- for (size_t i = 0; i < _ntags; i++) {
- if (_tags[_ncombinations][i] == tag) {
- return false;
- }
- }
- _tags[_ncombinations][_ntags++] = tag;
- return true;
- }
-
- void set_level(LogLevelType level) {
- _level[_ncombinations] = level;
- }
-
- void set_allow_other_tags() {
- _allow_other_tags[_ncombinations] = true;
- }
-
- public:
- LogTagLevelExpression() : _ntags(0), _ncombinations(0) {
- for (size_t combination = 0; combination < MaxCombinations; combination++) {
- _level[combination] = LogLevel::Invalid;
- _allow_other_tags[combination] = false;
- _tags[combination][0] = LogTag::__NO_TAG;
- }
- }
-
- bool parse(const char* str, outputStream* errstream = NULL);
- LogLevelType level_for(const LogTagSet& ts) const;
-
- // Verify the tagsets/selections mentioned in this expression.
- // Returns false if some invalid tagset was found. If given an outputstream,
- // this function will list all the invalid selections on the stream.
- bool verify_tagsets(outputStream* out = NULL) const;
-};
-
-#endif // SHARE_VM_LOGGING_LOGTAGLEVELEXPRESSION_HPP
diff --git a/src/hotspot/share/logging/logTagSet.cpp b/src/hotspot/share/logging/logTagSet.cpp
index 1be30d36e4a..2a2f640e0c6 100644
--- a/src/hotspot/share/logging/logTagSet.cpp
+++ b/src/hotspot/share/logging/logTagSet.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -118,17 +118,17 @@ void LogTagSet::vwrite(LogLevelType level, const char* fmt, va_list args) {
// Check that string fits in buffer; resize buffer if necessary
int ret;
if (prefix_len < vwrite_buffer_size) {
- ret = os::log_vsnprintf(buf + prefix_len, sizeof(buf) - prefix_len, fmt, args);
+ ret = os::vsnprintf(buf + prefix_len, sizeof(buf) - prefix_len, fmt, args);
} else {
// Buffer too small. Just call printf to find out the length for realloc below.
- ret = os::log_vsnprintf(buf, sizeof(buf), fmt, args);
+ ret = os::vsnprintf(buf, sizeof(buf), fmt, args);
}
assert(ret >= 0, "Log message buffer issue");
if ((size_t)ret >= sizeof(buf)) {
size_t newbuf_len = prefix_len + ret + 1;
char* newbuf = NEW_C_HEAP_ARRAY(char, newbuf_len, mtLogging);
prefix_len = _write_prefix(newbuf, newbuf_len);
- ret = os::log_vsnprintf(newbuf + prefix_len, newbuf_len - prefix_len, fmt, saved_args);
+ ret = os::vsnprintf(newbuf + prefix_len, newbuf_len - prefix_len, fmt, saved_args);
assert(ret >= 0, "Log message buffer issue");
log(level, newbuf);
FREE_C_HEAP_ARRAY(char, newbuf);
@@ -141,7 +141,7 @@ void LogTagSet::vwrite(LogLevelType level, const char* fmt, va_list args) {
static const size_t TagSetBufferSize = 128;
void LogTagSet::describe_tagsets(outputStream* out) {
- out->print_cr("Described tag combinations:");
+ out->print_cr("Described tag sets:");
for (const LogTagSetDescription* d = tagset_descriptions; d->tagset != NULL; d++) {
char buf[TagSetBufferSize];
d->tagset->label(buf, sizeof(buf), "+");
@@ -169,7 +169,7 @@ void LogTagSet::list_all_tagsets(outputStream* out) {
qsort(tagset_labels, _ntagsets, sizeof(*tagset_labels), qsort_strcmp);
// Print and then free the labels
- out->print("All available tag sets: ");
+ out->print("Available tag sets: ");
for (idx = 0; idx < _ntagsets; idx++) {
out->print("%s%s", (idx == 0 ? "" : ", "), tagset_labels[idx]);
os::free(tagset_labels[idx]);
diff --git a/src/hotspot/share/memory/metaspace.cpp b/src/hotspot/share/memory/metaspace.cpp
index b2027415452..3f12399084f 100644
--- a/src/hotspot/share/memory/metaspace.cpp
+++ b/src/hotspot/share/memory/metaspace.cpp
@@ -3952,8 +3952,7 @@ MetaWord* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
// Only start a GC if the bootstrapping has completed.
// Try to clean out some memory and retry.
- result = Universe::heap()->collector_policy()->satisfy_failed_metadata_allocation(
- loader_data, word_size, mdtype);
+ result = Universe::heap()->satisfy_failed_metadata_allocation(loader_data, word_size, mdtype);
}
}
diff --git a/src/hotspot/share/memory/metaspace.hpp b/src/hotspot/share/memory/metaspace.hpp
index b9e86bd15b0..41d0850cbcf 100644
--- a/src/hotspot/share/memory/metaspace.hpp
+++ b/src/hotspot/share/memory/metaspace.hpp
@@ -87,7 +87,7 @@ class Metaspace : public CHeapObj {
friend class MetaspaceGC;
friend class MetaspaceAux;
friend class MetaspaceShared;
- friend class CollectorPolicy;
+ friend class CollectedHeap;
friend class PrintCLDMetaspaceInfoClosure;
public:
diff --git a/src/hotspot/share/memory/oopFactory.cpp b/src/hotspot/share/memory/oopFactory.cpp
index 2df89bccb1c..b735420c45a 100644
--- a/src/hotspot/share/memory/oopFactory.cpp
+++ b/src/hotspot/share/memory/oopFactory.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,7 @@
#include "oops/instanceOop.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
typeArrayOop oopFactory::new_charArray(const char* utf8_str, TRAPS) {
diff --git a/src/hotspot/share/memory/universe.cpp b/src/hotspot/share/memory/universe.cpp
index ac5840fbab6..6ac5f1f7519 100644
--- a/src/hotspot/share/memory/universe.cpp
+++ b/src/hotspot/share/memory/universe.cpp
@@ -134,7 +134,6 @@ oop Universe::_null_ptr_exception_instance = NULL;
oop Universe::_arithmetic_exception_instance = NULL;
oop Universe::_virtual_machine_error_instance = NULL;
oop Universe::_vm_exception = NULL;
-oop Universe::_allocation_context_notification_obj = NULL;
oop Universe::_reference_pending_list = NULL;
Array* Universe::_the_empty_int_array = NULL;
@@ -213,7 +212,6 @@ void Universe::oops_do(OopClosure* f, bool do_all) {
f->do_oop((oop*)&_main_thread_group);
f->do_oop((oop*)&_system_thread_group);
f->do_oop((oop*)&_vm_exception);
- f->do_oop((oop*)&_allocation_context_notification_obj);
f->do_oop((oop*)&_reference_pending_list);
debug_only(f->do_oop((oop*)&_fullgc_alot_dummy_array);)
}
@@ -736,14 +734,8 @@ CollectedHeap* Universe::create_heap() {
// HeapBased - Use compressed oops with heap base + encoding.
jint Universe::initialize_heap() {
- jint status = JNI_ERR;
-
- _collectedHeap = create_heap_ext();
- if (_collectedHeap == NULL) {
- _collectedHeap = create_heap();
- }
-
- status = _collectedHeap->initialize();
+ _collectedHeap = create_heap();
+ jint status = _collectedHeap->initialize();
if (status != JNI_OK) {
return status;
}
diff --git a/src/hotspot/share/memory/universe.hpp b/src/hotspot/share/memory/universe.hpp
index c93c0269a1c..f6b7829ec78 100644
--- a/src/hotspot/share/memory/universe.hpp
+++ b/src/hotspot/share/memory/universe.hpp
@@ -181,8 +181,6 @@ class Universe: AllStatic {
// the vm thread.
static oop _vm_exception;
- static oop _allocation_context_notification_obj;
-
// References waiting to be transferred to the ReferenceHandler
static oop _reference_pending_list;
@@ -222,7 +220,6 @@ class Universe: AllStatic {
static size_t _heap_used_at_last_gc;
static CollectedHeap* create_heap();
- static CollectedHeap* create_heap_ext();
static jint initialize_heap();
static void initialize_basic_type_mirrors(TRAPS);
static void fixup_mirrors(TRAPS);
@@ -334,9 +331,6 @@ class Universe: AllStatic {
static oop virtual_machine_error_instance() { return _virtual_machine_error_instance; }
static oop vm_exception() { return _vm_exception; }
- static inline oop allocation_context_notification_obj();
- static inline void set_allocation_context_notification_obj(oop obj);
-
// Reference pending list manipulation. Access is protected by
// Heap_lock. The getter, setter and predicate require the caller
// owns the lock. Swap is used by parallel non-concurrent reference
diff --git a/src/hotspot/share/memory/universe.inline.hpp b/src/hotspot/share/memory/universe.inline.hpp
index 3d0047c12ac..8bb6de330ad 100644
--- a/src/hotspot/share/memory/universe.inline.hpp
+++ b/src/hotspot/share/memory/universe.inline.hpp
@@ -41,12 +41,4 @@ inline bool Universe::field_type_should_be_aligned(BasicType type) {
return type == T_DOUBLE || type == T_LONG;
}
-inline oop Universe::allocation_context_notification_obj() {
- return _allocation_context_notification_obj;
-}
-
-inline void Universe::set_allocation_context_notification_obj(oop obj) {
- _allocation_context_notification_obj = obj;
-}
-
#endif // SHARE_VM_MEMORY_UNIVERSE_INLINE_HPP
diff --git a/src/hotspot/share/oops/access.hpp b/src/hotspot/share/oops/access.hpp
index e1c901d961a..4343751f814 100644
--- a/src/hotspot/share/oops/access.hpp
+++ b/src/hotspot/share/oops/access.hpp
@@ -55,6 +55,7 @@
// * atomic_xchg_at: Atomically swap a new value at an internal pointer address if previous value matched the compared value.
// * arraycopy: Copy data from one heap array to another heap array.
// * clone: Clone the contents of an object to a newly allocated object.
+// * resolve: Resolve a stable to-space invariant oop that is guaranteed not to relocate its payload until a subsequent thread transition.
typedef uint64_t DecoratorSet;
@@ -69,12 +70,15 @@ const DecoratorSet INTERNAL_VALUE_IS_OOP = UCONST64(1) << 2;
// == Internal build-time Decorators ==
// * INTERNAL_BT_BARRIER_ON_PRIMITIVES: This is set in the barrierSetConfig.hpp file.
+// * INTERNAL_BT_TO_SPACE_INVARIANT: This is set in the barrierSetConfig.hpp file iff
+// no GC is bundled in the build that is to-space invariant.
const DecoratorSet INTERNAL_BT_BARRIER_ON_PRIMITIVES = UCONST64(1) << 3;
+const DecoratorSet INTERNAL_BT_TO_SPACE_INVARIANT = UCONST64(1) << 4;
// == Internal run-time Decorators ==
// * INTERNAL_RT_USE_COMPRESSED_OOPS: This decorator will be set in runtime resolved
// access backends iff UseCompressedOops is true.
-const DecoratorSet INTERNAL_RT_USE_COMPRESSED_OOPS = UCONST64(1) << 4;
+const DecoratorSet INTERNAL_RT_USE_COMPRESSED_OOPS = UCONST64(1) << 5;
const DecoratorSet INTERNAL_DECORATOR_MASK = INTERNAL_CONVERT_COMPRESSED_OOP | INTERNAL_VALUE_IS_OOP |
INTERNAL_BT_BARRIER_ON_PRIMITIVES | INTERNAL_RT_USE_COMPRESSED_OOPS;
@@ -138,12 +142,12 @@ const DecoratorSet INTERNAL_DECORATOR_MASK = INTERNAL_CONVERT_COMPRESS
// - Guarantees from MO_RELAXED loads and MO_RELAXED stores hold.
// * MO_SEQ_CST: Sequentially consistent xchg.
// - Guarantees from MO_SEQ_CST loads and MO_SEQ_CST stores hold.
-const DecoratorSet MO_UNORDERED = UCONST64(1) << 5;
-const DecoratorSet MO_VOLATILE = UCONST64(1) << 6;
-const DecoratorSet MO_RELAXED = UCONST64(1) << 7;
-const DecoratorSet MO_ACQUIRE = UCONST64(1) << 8;
-const DecoratorSet MO_RELEASE = UCONST64(1) << 9;
-const DecoratorSet MO_SEQ_CST = UCONST64(1) << 10;
+const DecoratorSet MO_UNORDERED = UCONST64(1) << 6;
+const DecoratorSet MO_VOLATILE = UCONST64(1) << 7;
+const DecoratorSet MO_RELAXED = UCONST64(1) << 8;
+const DecoratorSet MO_ACQUIRE = UCONST64(1) << 9;
+const DecoratorSet MO_RELEASE = UCONST64(1) << 10;
+const DecoratorSet MO_SEQ_CST = UCONST64(1) << 11;
const DecoratorSet MO_DECORATOR_MASK = MO_UNORDERED | MO_VOLATILE | MO_RELAXED |
MO_ACQUIRE | MO_RELEASE | MO_SEQ_CST;
@@ -166,10 +170,10 @@ const DecoratorSet MO_DECORATOR_MASK = MO_UNORDERED | MO_VOLATILE | MO_RELAXED |
// responsibility of performing the access and what barriers to be performed to the GC. This is the default.
// Note that primitive accesses will only be resolved on the barrier set if the appropriate build-time
// decorator for enabling primitive barriers is enabled for the build.
-const DecoratorSet AS_RAW = UCONST64(1) << 11;
-const DecoratorSet AS_DEST_NOT_INITIALIZED = UCONST64(1) << 12;
-const DecoratorSet AS_NO_KEEPALIVE = UCONST64(1) << 13;
-const DecoratorSet AS_NORMAL = UCONST64(1) << 14;
+const DecoratorSet AS_RAW = UCONST64(1) << 12;
+const DecoratorSet AS_DEST_NOT_INITIALIZED = UCONST64(1) << 13;
+const DecoratorSet AS_NO_KEEPALIVE = UCONST64(1) << 14;
+const DecoratorSet AS_NORMAL = UCONST64(1) << 15;
const DecoratorSet AS_DECORATOR_MASK = AS_RAW | AS_DEST_NOT_INITIALIZED |
AS_NO_KEEPALIVE | AS_NORMAL;
@@ -182,10 +186,10 @@ const DecoratorSet AS_DECORATOR_MASK = AS_RAW | AS_DEST_NOT_INITIALIZED |
// * ON_UNKNOWN_OOP_REF: The memory access is performed on a reference of unknown strength.
// This could for example come from the unsafe API.
// * Default (no explicit reference strength specified): ON_STRONG_OOP_REF
-const DecoratorSet ON_STRONG_OOP_REF = UCONST64(1) << 15;
-const DecoratorSet ON_WEAK_OOP_REF = UCONST64(1) << 16;
-const DecoratorSet ON_PHANTOM_OOP_REF = UCONST64(1) << 17;
-const DecoratorSet ON_UNKNOWN_OOP_REF = UCONST64(1) << 18;
+const DecoratorSet ON_STRONG_OOP_REF = UCONST64(1) << 16;
+const DecoratorSet ON_WEAK_OOP_REF = UCONST64(1) << 17;
+const DecoratorSet ON_PHANTOM_OOP_REF = UCONST64(1) << 18;
+const DecoratorSet ON_UNKNOWN_OOP_REF = UCONST64(1) << 19;
const DecoratorSet ON_DECORATOR_MASK = ON_STRONG_OOP_REF | ON_WEAK_OOP_REF |
ON_PHANTOM_OOP_REF | ON_UNKNOWN_OOP_REF;
@@ -200,18 +204,18 @@ const DecoratorSet ON_DECORATOR_MASK = ON_STRONG_OOP_REF | ON_WEAK_OOP_REF |
// * IN_CONCURRENT_ROOT: The access is performed in an off-heap data structure pointing into the Java heap,
// but is notably not scanned during safepoints. This is sometimes a special case for some GCs and
// implies that it is also an IN_ROOT.
-const DecoratorSet IN_HEAP = UCONST64(1) << 19;
-const DecoratorSet IN_HEAP_ARRAY = UCONST64(1) << 20;
-const DecoratorSet IN_ROOT = UCONST64(1) << 21;
-const DecoratorSet IN_CONCURRENT_ROOT = UCONST64(1) << 22;
-const DecoratorSet IN_ARCHIVE_ROOT = UCONST64(1) << 23;
+const DecoratorSet IN_HEAP = UCONST64(1) << 20;
+const DecoratorSet IN_HEAP_ARRAY = UCONST64(1) << 21;
+const DecoratorSet IN_ROOT = UCONST64(1) << 22;
+const DecoratorSet IN_CONCURRENT_ROOT = UCONST64(1) << 23;
+const DecoratorSet IN_ARCHIVE_ROOT = UCONST64(1) << 24;
const DecoratorSet IN_DECORATOR_MASK = IN_HEAP | IN_HEAP_ARRAY |
IN_ROOT | IN_CONCURRENT_ROOT |
IN_ARCHIVE_ROOT;
// == Value Decorators ==
// * OOP_NOT_NULL: This property can make certain barriers faster such as compressing oops.
-const DecoratorSet OOP_NOT_NULL = UCONST64(1) << 24;
+const DecoratorSet OOP_NOT_NULL = UCONST64(1) << 25;
const DecoratorSet OOP_DECORATOR_MASK = OOP_NOT_NULL;
// == Arraycopy Decorators ==
@@ -224,11 +228,11 @@ const DecoratorSet OOP_DECORATOR_MASK = OOP_NOT_NULL;
// * ARRAYCOPY_ARRAYOF: The copy is in the arrayof form.
// * ARRAYCOPY_ATOMIC: The accesses have to be atomic over the size of its elements.
// * ARRAYCOPY_ALIGNED: The accesses have to be aligned on a HeapWord.
-const DecoratorSet ARRAYCOPY_CHECKCAST = UCONST64(1) << 25;
-const DecoratorSet ARRAYCOPY_DISJOINT = UCONST64(1) << 26;
-const DecoratorSet ARRAYCOPY_ARRAYOF = UCONST64(1) << 27;
-const DecoratorSet ARRAYCOPY_ATOMIC = UCONST64(1) << 28;
-const DecoratorSet ARRAYCOPY_ALIGNED = UCONST64(1) << 29;
+const DecoratorSet ARRAYCOPY_CHECKCAST = UCONST64(1) << 26;
+const DecoratorSet ARRAYCOPY_DISJOINT = UCONST64(1) << 27;
+const DecoratorSet ARRAYCOPY_ARRAYOF = UCONST64(1) << 28;
+const DecoratorSet ARRAYCOPY_ATOMIC = UCONST64(1) << 29;
+const DecoratorSet ARRAYCOPY_ALIGNED = UCONST64(1) << 30;
const DecoratorSet ARRAYCOPY_DECORATOR_MASK = ARRAYCOPY_CHECKCAST | ARRAYCOPY_DISJOINT |
ARRAYCOPY_DISJOINT | ARRAYCOPY_ARRAYOF |
ARRAYCOPY_ATOMIC | ARRAYCOPY_ALIGNED;
@@ -297,6 +301,9 @@ namespace AccessInternal {
template
void clone(oop src, oop dst, size_t size);
+ template
+ oop resolve(oop src);
+
// Infer the type that should be returned from a load.
template
class LoadProxy: public StackObj {
@@ -500,6 +507,11 @@ public:
OopType new_oop_value = new_value;
return AccessInternal::atomic_xchg