--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/make/lib/CompileGtest.gmk Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,116 @@
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. 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.
+#
+
+GTEST_TEST_SRC := $(HOTSPOT_TOPDIR)/test/native
+GTEST_FRAMEWORK_SRC := $(SRC_ROOT)/test/fmw/gtest
+
+# On Windows, there are no internal debug symbols so must set copying to true
+# to get any at all.
+ifeq ($(OPENJDK_TARGET_OS), windows)
+ GTEST_COPY_DEBUG_SYMBOLS := true
+else
+ GTEST_COPY_DEBUG_SYMBOLS := false
+endif
+
+################################################################################
+
+GTEST_TEST_SRC_FILES := $(shell $(FIND) $(HOTSPOT_TOPDIR)/test/native -name \
+ "test*.cpp" -type f)
+
+ifeq ($(OPENJDK_TARGET_OS), windows)
+ GTEST_JVM_MAPFILE := $(JVM_MAPFILE)
+else
+ GTEST_JVM_MAPFILE := $(JVM_OUTPUTDIR)/gtest/mapfile
+
+ $(JVM_OUTPUTDIR)/gtest/symbols: $(JVM_OUTPUTDIR)/symbols
+ $(call MakeDir, $(@D))
+ ( $(CAT) $< ; echo "runUnitTests" ) > $@
+
+ $(GTEST_JVM_MAPFILE): $(JVM_OUTPUTDIR)/gtest/symbols
+ $(call create-mapfile)
+endif
+
+# Disabling switch warning for clang because of test source.
+
+$(eval $(call SetupNativeCompilation, BUILD_GTEST_LIBJVM, \
+ TOOLCHAIN := $(JVM_TOOLCHAIN), \
+ LIBRARY := jvm, \
+ OUTPUT_DIR := $(JVM_OUTPUTDIR)/gtest, \
+ EXTRA_FILES := $(GTEST_TEST_SRC_FILES) \
+ $(GTEST_FRAMEWORK_SRC)/src/gtest-all.cc \
+ $(GTEST_TEST_SRC)/gtestMain.cpp, \
+ OBJECT_DIR := $(JVM_OUTPUTDIR)/gtest/objs, \
+ EXTRA_OBJECT_FILES := $(filter-out %/operator_new$(OBJ_SUFFIX), \
+ $(BUILD_LIBJVM_ALL_OBJS)), \
+ CFLAGS := $(JVM_CFLAGS) -I$(GTEST_FRAMEWORK_SRC) \
+ -I$(GTEST_FRAMEWORK_SRC)/include \
+ -I$(GTEST_TEST_SRC), \
+ CFLAGS_windows := /EHsc, \
+ CFLAGS_solaris := -DGTEST_HAS_EXCEPTIONS=0 -library=stlport4, \
+ CFLAGS_macosx := -DGTEST_OS_MAC=1, \
+ CFLAGS_DEBUG_SYMBOLS := $(JVM_CFLAGS_SYMBOLS), \
+ CXXFLAGS_DEBUG_SYMBOLS := $(JVM_CFLAGS_SYMBOLS), \
+ DISABLED_WARNINGS_gcc := undef, \
+ DISABLED_WARNINGS_clang := undef switch format-nonliteral \
+ tautological-undefined-compare, \
+ DISABLED_WARNINGS_solstudio := identexpected, \
+ LDFLAGS := $(JVM_LDFLAGS), \
+ LDFLAGS_solaris := -library=stlport4 $(call SET_SHARED_LIBRARY_ORIGIN), \
+ LIBS := $(JVM_LIBS), \
+ OPTIMIZATION := $(JVM_OPTIMIZATION), \
+ MAPFILE := $(GTEST_JVM_MAPFILE), \
+ USE_MAPFILE_FOR_SYMBOLS := true, \
+ COPY_DEBUG_SYMBOLS := $(GTEST_COPY_DEBUG_SYMBOLS), \
+ ZIP_EXTERNAL_DEBUG_SYMBOLS := false, \
+))
+
+TARGETS += $(BUILD_GTEST_LIBJVM)
+
+################################################################################
+
+$(eval $(call SetupNativeCompilation, BUILD_GTEST_LAUNCHER, \
+ TOOLCHAIN := $(JVM_TOOLCHAIN), \
+ PROGRAM := gtestLauncher, \
+ OUTPUT_DIR := $(JVM_OUTPUTDIR)/gtest, \
+ EXTRA_FILES := $(GTEST_TEST_SRC)/gtestLauncher.cpp, \
+ OBJECT_DIR := $(JVM_OUTPUTDIR)/gtest/launcher-objs, \
+ CFLAGS := $(JVM_CFLAGS) -I$(GTEST_FRAMEWORK_SRC) \
+ -I$(GTEST_FRAMEWORK_SRC)/include, \
+ CFLAGS_DEBUG_SYMBOLS := $(JVM_CFLAGS_SYMBOLS), \
+ CXXFLAGS_DEBUG_SYMBOLS := $(JVM_CFLAGS_SYMBOLS), \
+ LDFLAGS := $(LDFLAGS_TESTEXE), \
+ LDFLAGS_unix := -L$(JVM_OUTPUTDIR)/gtest $(call SET_SHARED_LIBRARY_ORIGIN), \
+ LDFLAGS_solaris := -library=stlport4, \
+ LIBS_unix := -ljvm, \
+ LIBS_windows := $(JVM_OUTPUTDIR)/gtest/objs/jvm.lib, \
+ COPY_DEBUG_SYMBOLS := $(GTEST_COPY_DEBUG_SYMBOLS), \
+ ZIP_EXTERNAL_DEBUG_SYMBOLS := false, \
+))
+
+$(BUILD_GTEST_LAUNCHER): $(BUILD_GTEST_LIBJVM)
+
+TARGETS += $(BUILD_GTEST_LAUNCHER)
+
+################################################################################
--- a/hotspot/make/lib/CompileLibraries.gmk Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/make/lib/CompileLibraries.gmk Wed May 11 00:38:58 2016 +0300
@@ -37,6 +37,10 @@
include lib/CompileJvm.gmk
include lib/CompileDtracePostJvm.gmk
+ifeq ($(BUILD_GTEST), true)
+ include lib/CompileGtest.gmk
+endif
+
all: $(TARGETS)
.PHONY: all
--- a/hotspot/make/lib/JvmMapfile.gmk Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/make/lib/JvmMapfile.gmk Wed May 11 00:38:58 2016 +0300
@@ -153,20 +153,33 @@
################################################################################
# Finally convert the symbol list into a platform-specific mapfile
-$(JVM_MAPFILE): $(JVM_OUTPUTDIR)/symbols
- $(call LogInfo, Creating mapfile)
- $(RM) $@
- ifeq ($(OPENJDK_TARGET_OS), macosx)
- # On macosx, we need to add a leading underscore
+ifeq ($(OPENJDK_TARGET_OS), macosx)
+ # On macosx, we need to add a leading underscore
+ define create-mapfile-work
$(AWK) '{ if ($$0 ~ ".") { print " _" $$0 } }' < $^ > $@.tmp
- else ifeq ($(OPENJDK_TARGET_OS), windows)
- # On windows, add an 'EXPORTS' header
+ endef
+else ifeq ($(OPENJDK_TARGET_OS), windows)
+ # On windows, add an 'EXPORTS' header
+ define create-mapfile-work
$(ECHO) "EXPORTS" > $@.tmp
$(AWK) '{ if ($$0 ~ ".") { print " " $$0 } }' < $^ >> $@.tmp
- else
- # Assume standard linker script
+ endef
+else
+ # Assume standard linker script
+ define create-mapfile-work
$(PRINTF) "SUNWprivate_1.1 { \n global: \n" > $@.tmp
$(AWK) '{ if ($$0 ~ ".") { print " " $$0 ";" } }' < $^ >> $@.tmp
$(PRINTF) " local: \n *; \n }; \n" >> $@.tmp
- endif
+ endef
+endif
+
+define create-mapfile
+ $(call LogInfo, Creating mapfile)
+ $(call MakeDir, $(@D))
+ $(call create-mapfile-work)
+ $(RM) $@
$(MV) $@.tmp $@
+endef
+
+$(JVM_MAPFILE): $(JVM_OUTPUTDIR)/symbols
+ $(call create-mapfile)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/make/src/classes/build/tools/projectcreator/ArgsParser.java Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2005, 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.
+ *
+ */
+
+package build.tools.projectcreator;
+
+class ArgIterator {
+ String[] args;
+ int i;
+ ArgIterator(String[] args) {
+ this.args = args;
+ this.i = 0;
+ }
+ String get() { return args[i]; }
+ boolean hasMore() { return args != null && i < args.length; }
+ boolean next() { return ++i < args.length; }
+}
+
+abstract class ArgHandler {
+ public abstract void handle(ArgIterator it);
+
+}
+
+class ArgRule {
+ String arg;
+ ArgHandler handler;
+ ArgRule(String arg, ArgHandler handler) {
+ this.arg = arg;
+ this.handler = handler;
+ }
+
+ boolean process(ArgIterator it) {
+ if (match(it.get(), arg)) {
+ handler.handle(it);
+ return true;
+ }
+ return false;
+ }
+ boolean match(String rule_pattern, String arg) {
+ return arg.equals(rule_pattern);
+ }
+}
+
+class ArgsParser {
+ ArgsParser(String[] args,
+ ArgRule[] rules,
+ ArgHandler defaulter) {
+ ArgIterator ai = new ArgIterator(args);
+ while (ai.hasMore()) {
+ boolean processed = false;
+ for (int i=0; i<rules.length; i++) {
+ processed |= rules[i].process(ai);
+ if (processed) {
+ break;
+ }
+ }
+ if (!processed) {
+ if (defaulter != null) {
+ defaulter.handle(ai);
+ } else {
+ System.err.println("ERROR: unparsed \""+ai.get()+"\"");
+ ai.next();
+ }
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/make/src/classes/build/tools/projectcreator/BuildConfig.java Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,624 @@
+/*
+ * Copyright (c) 2005, 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.
+ *
+ */
+
+package build.tools.projectcreator;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+class BuildConfig {
+ @SuppressWarnings("rawtypes")
+ Hashtable vars;
+ Vector<String> basicNames, basicPaths;
+ String[] context;
+
+ static CompilerInterface ci;
+ static CompilerInterface getCI() {
+ if (ci == null) {
+ String comp = (String)getField(null, "CompilerVersion");
+ try {
+ ci = (CompilerInterface)Class.forName("build.tools.projectcreator.CompilerInterface" + comp).newInstance();
+ } catch (Exception cnfe) {
+ System.err.println("Cannot find support for compiler " + comp);
+ throw new RuntimeException(cnfe.toString());
+ }
+ }
+ return ci;
+ }
+
+ @SuppressWarnings("rawtypes")
+ protected void initNames(String flavour, String build, String outDll) {
+ if (vars == null) vars = new Hashtable();
+
+ String flavourBuild = flavour + "_" + build;
+ String platformName = getFieldString(null, "PlatformName");
+ System.out.println();
+ System.out.println(flavourBuild);
+
+ put("Name", getCI().makeCfgName(flavourBuild, platformName));
+ put("Flavour", flavour);
+ put("Build", build);
+ put("PlatformName", platformName);
+
+ // ones mentioned above were needed to expand format
+ String buildBase = expandFormat(getFieldString(null, "BuildBase"));
+ String sourceBase = getFieldString(null, "SourceBase");
+ String buildSpace = getFieldString(null, "BuildSpace");
+ String outDir = buildBase;
+ String jdkTargetRoot = getFieldString(null, "JdkTargetRoot");
+ String makeBinary = getFieldString(null, "MakeBinary");
+ String makeOutput = expandFormat(getFieldString(null, "MakeOutput"));
+
+ put("Id", flavourBuild);
+ put("OutputDir", outDir);
+ put("SourceBase", sourceBase);
+ put("BuildBase", buildBase);
+ put("BuildSpace", buildSpace);
+ put("OutputDll", outDir + Util.sep + outDll);
+ put("JdkTargetRoot", jdkTargetRoot);
+ put("MakeBinary", makeBinary);
+ put("MakeOutput", makeOutput);
+
+ context = new String [] {flavourBuild, flavour, build, null};
+ }
+
+ protected void init(Vector<String> includes, Vector<String> defines) {
+ initDefaultDefines(defines);
+ initDefaultCompilerFlags(includes);
+ initDefaultLinkerFlags();
+ //handleDB();
+ }
+
+
+ protected void initDefaultCompilerFlags(Vector<String> includes) {
+ Vector compilerFlags = new Vector();
+
+ compilerFlags.addAll(getCI().getBaseCompilerFlags(getV("Define"),
+ includes,
+ get("OutputDir")));
+
+ put("CompilerFlags", compilerFlags);
+ }
+
+ protected void initDefaultLinkerFlags() {
+ Vector linkerFlags = new Vector();
+
+ linkerFlags.addAll(getCI().getBaseLinkerFlags( get("OutputDir"), get("OutputDll"), get("PlatformName")));
+
+ put("LinkerFlags", linkerFlags);
+ }
+
+ public boolean matchesIgnoredPath(String path) {
+ Vector<String> rv = new Vector<String>();
+ collectRelevantVectors(rv, "IgnorePath");
+ for (String pathPart : rv) {
+ if (path.contains(pathPart)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean matchesHidePath(String path) {
+ Vector<String> rv = new Vector<String>();
+ collectRelevantVectors(rv, "HidePath");
+ for (String pathPart : rv) {
+ if (path.contains(Util.normalize(pathPart))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public Vector<String> matchesAdditionalGeneratedPath(String fullPath) {
+ Vector<String> rv = new Vector<String>();
+ Hashtable<String, String> v = (Hashtable<String, String>)BuildConfig.getField(this.toString(), "AdditionalGeneratedFile");
+ if (v != null) {
+ for (Enumeration<String> e=v.keys(); e.hasMoreElements(); ) {
+ String key = e.nextElement();
+ String val = v.get(key);
+
+ if (fullPath.endsWith(expandFormat(key))) {
+ rv.add(expandFormat(val));
+ }
+ }
+ }
+ return rv;
+ }
+
+ // Returns true if the specified path refers to a relative alternate
+ // source file. RelativeAltSrcInclude is usually "src\closed".
+ public static boolean matchesRelativeAltSrcInclude(String path) {
+ String relativeAltSrcInclude =
+ getFieldString(null, "RelativeAltSrcInclude");
+ Vector<String> v = getFieldVector(null, "AltRelativeInclude");
+ if (v != null) {
+ for (String pathPart : v) {
+ if (path.contains(relativeAltSrcInclude + Util.sep + pathPart)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ // Returns the relative alternate source file for the specified path.
+ // Null is returned if the specified path does not have a matching
+ // alternate source file.
+ public static String getMatchingRelativeAltSrcFile(String path) {
+ Vector<String> v = getFieldVector(null, "RelativeAltSrcFileList");
+ if (v == null) {
+ return null;
+ }
+ for (String pathPart : v) {
+ if (path.endsWith(pathPart)) {
+ String relativeAltSrcInclude =
+ getFieldString(null, "RelativeAltSrcInclude");
+ return relativeAltSrcInclude + Util.sep + pathPart;
+ }
+ }
+ return null;
+ }
+
+ // Returns true if the specified path has a matching alternate
+ // source file.
+ public static boolean matchesRelativeAltSrcFile(String path) {
+ return getMatchingRelativeAltSrcFile(path) != null;
+ }
+
+ // Track the specified alternate source file. The source file is
+ // tracked without the leading .*<sep><RelativeAltSrcFileList><sep>
+ // part to make matching regular source files easier.
+ public static void trackRelativeAltSrcFile(String path) {
+ String pattern = getFieldString(null, "RelativeAltSrcInclude") +
+ Util.sep;
+ int altSrcInd = path.indexOf(pattern);
+ if (altSrcInd == -1) {
+ // not an AltSrc path
+ return;
+ }
+
+ altSrcInd += pattern.length();
+ if (altSrcInd >= path.length()) {
+ // not a valid AltSrc path
+ return;
+ }
+
+ String altSrcFile = path.substring(altSrcInd);
+ Vector v = getFieldVector(null, "RelativeAltSrcFileList");
+ if (v == null || !v.contains(altSrcFile)) {
+ addFieldVector(null, "RelativeAltSrcFileList", altSrcFile);
+ }
+ }
+
+ void addTo(Hashtable ht, String key, String value) {
+ ht.put(expandFormat(key), expandFormat(value));
+ }
+
+ void initDefaultDefines(Vector defines) {
+ Vector sysDefines = new Vector();
+ sysDefines.add("WIN32");
+ sysDefines.add("_WINDOWS");
+ sysDefines.add("HOTSPOT_BUILD_USER=\\\""+System.getProperty("user.name")+"\\\"");
+ sysDefines.add("HOTSPOT_BUILD_TARGET=\\\""+get("Build")+"\\\"");
+ sysDefines.add("INCLUDE_TRACE=1");
+ sysDefines.add("_JNI_IMPLEMENTATION_");
+ if (vars.get("PlatformName").equals("Win32")) {
+ sysDefines.add("HOTSPOT_LIB_ARCH=\\\"i386\\\"");
+ } else {
+ sysDefines.add("HOTSPOT_LIB_ARCH=\\\"amd64\\\"");
+ }
+ sysDefines.add("DEBUG_LEVEL=\\\"" + get("Build")+"\\\"");
+ sysDefines.addAll(defines);
+
+ put("Define", sysDefines);
+ }
+
+ String get(String key) {
+ return (String)vars.get(key);
+ }
+
+ Vector getV(String key) {
+ return (Vector)vars.get(key);
+ }
+
+ Object getO(String key) {
+ return vars.get(key);
+ }
+
+ Hashtable getH(String key) {
+ return (Hashtable)vars.get(key);
+ }
+
+ Object getFieldInContext(String field) {
+ for (int i=0; i<context.length; i++) {
+ Object rv = getField(context[i], field);
+ if (rv != null) {
+ return rv;
+ }
+ }
+ return null;
+ }
+
+ Object lookupHashFieldInContext(String field, String key) {
+ for (int i=0; i<context.length; i++) {
+ Hashtable ht = (Hashtable)getField(context[i], field);
+ if (ht != null) {
+ Object rv = ht.get(key);
+ if (rv != null) {
+ return rv;
+ }
+ }
+ }
+ return null;
+ }
+
+ void put(String key, String value) {
+ vars.put(key, value);
+ }
+
+ void put(String key, Vector vvalue) {
+ vars.put(key, vvalue);
+ }
+
+ void add(String key, Vector vvalue) {
+ getV(key).addAll(vvalue);
+ }
+
+ String flavour() {
+ return get("Flavour");
+ }
+
+ String build() {
+ return get("Build");
+ }
+
+ Object getSpecificField(String field) {
+ return getField(get("Id"), field);
+ }
+
+ void putSpecificField(String field, Object value) {
+ putField(get("Id"), field, value);
+ }
+
+ void collectRelevantVectors(Vector rv, String field) {
+ for (String ctx : context) {
+ Vector<String> v = getFieldVector(ctx, field);
+ if (v != null) {
+ for (String val : v) {
+ rv.add(expandFormat(val).replace('/', '\\'));
+ }
+ }
+ }
+ }
+
+ void collectRelevantHashes(Hashtable rv, String field) {
+ for (String ctx : context) {
+ Hashtable v = (Hashtable)getField(ctx, field);
+ if (v != null) {
+ for (Enumeration e=v.keys(); e.hasMoreElements(); ) {
+ String key = (String)e.nextElement();
+ String val = (String)v.get(key);
+ addTo(rv, key, val);
+ }
+ }
+ }
+ }
+
+
+ Vector getDefines() {
+ Vector rv = new Vector();
+ collectRelevantVectors(rv, "Define");
+ return rv;
+ }
+
+ Vector getIncludes() {
+ Vector rv = new Vector();
+ collectRelevantVectors(rv, "AbsoluteInclude");
+ rv.addAll(getSourceIncludes());
+ return rv;
+ }
+
+ private Vector getSourceIncludes() {
+ Vector<String> rv = new Vector<String>();
+ String sourceBase = getFieldString(null, "SourceBase");
+
+ // add relative alternate source include values:
+ String relativeAltSrcInclude =
+ getFieldString(null, "RelativeAltSrcInclude");
+ Vector<String> asri = new Vector<String>();
+ collectRelevantVectors(asri, "AltRelativeInclude");
+ for (String f : asri) {
+ rv.add(sourceBase + Util.sep + relativeAltSrcInclude +
+ Util.sep + f);
+ }
+
+ Vector<String> ri = new Vector<String>();
+ collectRelevantVectors(ri, "RelativeInclude");
+ for (String f : ri) {
+ rv.add(sourceBase + Util.sep + f);
+ }
+ return rv;
+ }
+
+ static Hashtable cfgData = new Hashtable();
+ static Hashtable globalData = new Hashtable();
+
+ static boolean appliesToTieredBuild(String cfg) {
+ return (cfg != null &&
+ cfg.startsWith("server"));
+ }
+
+ // Filters out the IgnoreFile and IgnorePaths since they are
+ // handled specially for tiered builds.
+ static boolean appliesToTieredBuild(String cfg, String key) {
+ return (appliesToTieredBuild(cfg))&& (key != null && !key.startsWith("Ignore"));
+ }
+
+ static String getTieredBuildCfg(String cfg) {
+ assert appliesToTieredBuild(cfg) : "illegal configuration " + cfg;
+ return "server";
+ }
+
+ static Object getField(String cfg, String field) {
+ if (cfg == null) {
+ return globalData.get(field);
+ }
+
+ Hashtable ht = (Hashtable)cfgData.get(cfg);
+ return ht == null ? null : ht.get(field);
+ }
+
+ static String getFieldString(String cfg, String field) {
+ return (String)getField(cfg, field);
+ }
+
+ static Vector getFieldVector(String cfg, String field) {
+ return (Vector)getField(cfg, field);
+ }
+
+ static void putField(String cfg, String field, Object value) {
+ putFieldImpl(cfg, field, value);
+ if (appliesToTieredBuild(cfg, field)) {
+ putFieldImpl(getTieredBuildCfg(cfg), field, value);
+ }
+ }
+
+ private static void putFieldImpl(String cfg, String field, Object value) {
+ if (cfg == null) {
+ globalData.put(field, value);
+ return;
+ }
+
+ Hashtable ht = (Hashtable)cfgData.get(cfg);
+ if (ht == null) {
+ ht = new Hashtable();
+ cfgData.put(cfg, ht);
+ }
+
+ ht.put(field, value);
+ }
+
+ static Object getFieldHash(String cfg, String field, String name) {
+ Hashtable ht = (Hashtable)getField(cfg, field);
+
+ return ht == null ? null : ht.get(name);
+ }
+
+ static void putFieldHash(String cfg, String field, String name, Object val) {
+ putFieldHashImpl(cfg, field, name, val);
+ if (appliesToTieredBuild(cfg, field)) {
+ putFieldHashImpl(getTieredBuildCfg(cfg), field, name, val);
+ }
+ }
+
+ private static void putFieldHashImpl(String cfg, String field, String name, Object val) {
+ Hashtable ht = (Hashtable)getField(cfg, field);
+
+ if (ht == null) {
+ ht = new Hashtable();
+ putFieldImpl(cfg, field, ht);
+ }
+
+ ht.put(name, val);
+ }
+
+ static void addFieldVector(String cfg, String field, String element) {
+ addFieldVectorImpl(cfg, field, element);
+ if (appliesToTieredBuild(cfg, field)) {
+ addFieldVectorImpl(getTieredBuildCfg(cfg), field, element);
+ }
+ }
+
+ private static void addFieldVectorImpl(String cfg, String field, String element) {
+ Vector v = (Vector)getField(cfg, field);
+
+ if (v == null) {
+ v = new Vector();
+ putFieldImpl(cfg, field, v);
+ }
+
+ v.add(element);
+ }
+
+ String expandFormat(String format) {
+ if (format == null) {
+ return null;
+ }
+
+ if (format.indexOf('%') == -1) {
+ return format;
+ }
+
+ StringBuffer sb = new StringBuffer();
+ int len = format.length();
+ for (int i=0; i<len; i++) {
+ char ch = format.charAt(i);
+ if (ch == '%') {
+ char ch1 = format.charAt(i+1);
+ switch (ch1) {
+ case '%':
+ sb.append(ch1);
+ break;
+ case 'b':
+ sb.append(build());
+ break;
+ case 'f':
+ sb.append(flavour());
+ break;
+ default:
+ sb.append(ch);
+ sb.append(ch1);
+ }
+ i++;
+ } else {
+ sb.append(ch);
+ }
+ }
+
+ return sb.toString();
+ }
+}
+
+abstract class GenericDebugConfig extends BuildConfig {
+ abstract String getOptFlag();
+
+ protected void init(Vector includes, Vector defines) {
+ defines.add("_DEBUG");
+ defines.add("ASSERT");
+
+ super.init(includes, defines);
+
+ getV("CompilerFlags").addAll(getCI().getDebugCompilerFlags(getOptFlag(), get("PlatformName")));
+ getV("LinkerFlags").addAll(getCI().getDebugLinkerFlags());
+ }
+}
+
+abstract class GenericDebugNonKernelConfig extends GenericDebugConfig {
+ protected void init(Vector includes, Vector defines) {
+ super.init(includes, defines);
+ if (get("PlatformName").equals("Win32")) {
+ getCI().getAdditionalNonKernelLinkerFlags(getV("LinkerFlags"));
+ }
+ }
+}
+
+class C1DebugConfig extends GenericDebugNonKernelConfig {
+ String getOptFlag() {
+ return getCI().getNoOptFlag();
+ }
+
+ C1DebugConfig() {
+ initNames("client", "debug", "jvm.dll");
+ init(getIncludes(), getDefines());
+ }
+}
+
+class C1FastDebugConfig extends GenericDebugNonKernelConfig {
+ String getOptFlag() {
+ return getCI().getOptFlag();
+ }
+
+ C1FastDebugConfig() {
+ initNames("client", "fastdebug", "jvm.dll");
+ init(getIncludes(), getDefines());
+ }
+}
+
+class TieredDebugConfig extends GenericDebugNonKernelConfig {
+ String getOptFlag() {
+ return getCI().getNoOptFlag();
+ }
+
+ TieredDebugConfig() {
+ initNames("server", "debug", "jvm.dll");
+ init(getIncludes(), getDefines());
+ }
+}
+
+class TieredFastDebugConfig extends GenericDebugNonKernelConfig {
+ String getOptFlag() {
+ return getCI().getOptFlag();
+ }
+
+ TieredFastDebugConfig() {
+ initNames("server", "fastdebug", "jvm.dll");
+ init(getIncludes(), getDefines());
+ }
+}
+
+abstract class ProductConfig extends BuildConfig {
+ protected void init(Vector includes, Vector defines) {
+ defines.add("NDEBUG");
+ defines.add("PRODUCT");
+
+ super.init(includes, defines);
+
+ getV("CompilerFlags").addAll(getCI().getProductCompilerFlags());
+ getV("LinkerFlags").addAll(getCI().getProductLinkerFlags());
+ }
+}
+
+class C1ProductConfig extends ProductConfig {
+ C1ProductConfig() {
+ initNames("client", "product", "jvm.dll");
+ init(getIncludes(), getDefines());
+ }
+}
+
+class TieredProductConfig extends ProductConfig {
+ TieredProductConfig() {
+ initNames("server", "product", "jvm.dll");
+ init(getIncludes(), getDefines());
+ }
+}
+
+
+abstract class CompilerInterface {
+ abstract Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir);
+ abstract Vector getBaseLinkerFlags(String outDir, String outDll, String platformName);
+ abstract Vector getDebugCompilerFlags(String opt, String platformName);
+ abstract Vector getDebugLinkerFlags();
+ abstract void getAdditionalNonKernelLinkerFlags(Vector rv);
+ abstract Vector getProductCompilerFlags();
+ abstract Vector getProductLinkerFlags();
+ abstract String getOptFlag();
+ abstract String getNoOptFlag();
+ abstract String makeCfgName(String flavourBuild, String platformName);
+
+ void addAttr(Vector receiver, String attr, String value) {
+ receiver.add(attr); receiver.add(value);
+ }
+ void extAttr(Vector receiver, String attr, String value) {
+ int attr_pos=receiver.indexOf(attr) ;
+ if ( attr_pos == -1) {
+ // If attr IS NOT present in the Vector - add it
+ receiver.add(attr); receiver.add(value);
+ } else {
+ // If attr IS present in the Vector - append value to it
+ receiver.set(attr_pos+1,receiver.get(attr_pos+1)+value);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/make/src/classes/build/tools/projectcreator/FileTreeCreator.java Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+package build.tools.projectcreator;
+
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.util.HashSet;
+import java.util.Stack;
+import java.util.Vector;
+
+public class FileTreeCreator extends SimpleFileVisitor<Path>
+{
+ Path vcProjLocation;
+ Path startDir;
+ final int startDirLength;
+ Stack<DirAttributes> attributes = new Stack<DirAttributes>();
+ Vector<BuildConfig> allConfigs;
+ WinGammaPlatform wg;
+ WinGammaPlatformVC10 wg10;
+
+ public FileTreeCreator(Path startDir, Vector<BuildConfig> allConfigs, WinGammaPlatform wg) {
+ super();
+ this.wg = wg;
+ if (wg instanceof WinGammaPlatformVC10) {
+ wg10 = (WinGammaPlatformVC10)wg;
+ }
+ this.allConfigs = allConfigs;
+ this.startDir = startDir;
+ startDirLength = startDir.toAbsolutePath().toString().length();
+ vcProjLocation = FileSystems.getDefault().getPath(allConfigs.firstElement().get("BuildSpace"));
+ attributes.push(new DirAttributes());
+ }
+
+ public class DirAttributes {
+
+ private HashSet<BuildConfig> ignores;
+ private HashSet<BuildConfig> disablePch;
+
+ public DirAttributes() {
+ ignores = new HashSet<BuildConfig>();
+ disablePch = new HashSet<BuildConfig>();
+ }
+
+ public DirAttributes(HashSet<BuildConfig> excludes2, HashSet<BuildConfig> disablePch2) {
+ ignores = excludes2;
+ disablePch = disablePch2;
+ }
+
+ @SuppressWarnings("unchecked")
+ public DirAttributes clone() {
+ return new DirAttributes((HashSet<BuildConfig>)this.ignores.clone(), (HashSet<BuildConfig>)this.disablePch.clone());
+ }
+
+ public void setIgnore(BuildConfig conf) {
+ ignores.add(conf);
+ }
+
+ public boolean hasIgnore(BuildConfig cfg) {
+ return ignores.contains(cfg);
+ }
+
+ public void removeFromIgnored(BuildConfig cfg) {
+ ignores.remove(cfg);
+ }
+
+ public void setDisablePch(BuildConfig conf) {
+ disablePch.add(conf);
+ }
+
+ public boolean hasDisablePch(BuildConfig cfg) {
+ return disablePch.contains(cfg);
+ }
+
+ public void removeFromDisablePch(BuildConfig cfg) {
+ disablePch.remove(cfg);
+ }
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/make/src/classes/build/tools/projectcreator/FileTreeCreatorVC10.java Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+package build.tools.projectcreator;
+
+import static java.nio.file.FileVisitResult.CONTINUE;
+
+import java.io.IOException;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Stack;
+import java.util.Vector;
+
+public class FileTreeCreatorVC10 extends FileTreeCreator {
+
+ public FileTreeCreatorVC10(Path startDir, Vector<BuildConfig> allConfigs, WinGammaPlatformVC10 wg) {
+ super(startDir, allConfigs, wg);
+ }
+
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attr) {
+ DirAttributes currentFileAttr = attributes.peek().clone();
+ boolean usePch = false;
+ boolean disablePch = false;
+ boolean useIgnore = false;
+ boolean isAltSrc = false; // only needed as a debugging crumb
+ boolean isReplacedByAltSrc = false;
+ String fileName = file.getFileName().toString();
+
+ // TODO hideFile
+
+ // usePch applies to all configs for a file.
+ if (fileName.equals(BuildConfig.getFieldString(null, "UseToGeneratePch"))) {
+ usePch = true;
+ }
+
+ String fileLoc = vcProjLocation.relativize(file).toString();
+
+ // isAltSrc and isReplacedByAltSrc applies to all configs for a file
+ if (BuildConfig.matchesRelativeAltSrcInclude(
+ file.toAbsolutePath().toString())) {
+ // current file is an alternate source file so track it
+ isAltSrc = true;
+ BuildConfig.trackRelativeAltSrcFile(
+ file.toAbsolutePath().toString());
+ } else if (BuildConfig.matchesRelativeAltSrcFile(
+ file.toAbsolutePath().toString())) {
+ // current file is a regular file that matches an alternate
+ // source file so yack about replacing the regular file
+ isReplacedByAltSrc = true;
+ System.out.println("INFO: alternate source file '" +
+ BuildConfig.getMatchingRelativeAltSrcFile(
+ file.toAbsolutePath().toString()) +
+ "' replaces '" + fileLoc + "'");
+ }
+
+ for (BuildConfig cfg : allConfigs) {
+ if (cfg.lookupHashFieldInContext("IgnoreFile", fileName) != null) {
+ useIgnore = true;
+ currentFileAttr.setIgnore(cfg);
+ } else if (cfg.matchesIgnoredPath(file.toAbsolutePath().toString())) {
+ useIgnore = true;
+ currentFileAttr.setIgnore(cfg);
+ }
+
+ if (cfg.lookupHashFieldInContext("DisablePch", fileName) != null) {
+ disablePch = true;
+ currentFileAttr.setDisablePch(cfg);
+ }
+
+ Vector<String> rv = new Vector<String>();
+ cfg.collectRelevantVectors(rv, "AdditionalFile");
+ for(String addFile : rv) {
+ if (addFile.equals(fileName)) {
+ // supress any ignore
+ // TODO - may need some adjustments
+ if (file.toAbsolutePath().toString().contains(cfg.get("Flavour"))) {
+ currentFileAttr.removeFromIgnored(cfg);
+ }
+ }
+ }
+ }
+
+ String tagName = wg10.getFileTagFromSuffix(fileName);
+
+ if (!useIgnore && !disablePch && !usePch && !isReplacedByAltSrc) {
+ wg.tag(tagName, new String[] { "Include", fileLoc});
+ } else {
+ wg.startTag(
+ tagName,
+ new String[] { "Include", fileLoc});
+
+ for (BuildConfig cfg : allConfigs) {
+ boolean ignore = currentFileAttr.hasIgnore(cfg);
+ if (ignore) {
+ wg.tagData("ExcludedFromBuild", "true", "Condition", "'$(Configuration)|$(Platform)'=='" + cfg.get("Name") + "'");
+ }
+ if (usePch) {
+ wg.tagData("PrecompiledHeader", "Create", "Condition", "'$(Configuration)|$(Platform)'=='" + cfg.get("Name") + "'");
+ }
+ if (disablePch) {
+ wg.tag("PrecompiledHeader", "Condition", "'$(Configuration)|$(Platform)'=='" + cfg.get("Name") + "'");
+ }
+ if (isReplacedByAltSrc) {
+ wg.tagData("ExcludedFromBuild", "true", "Condition",
+ "'$(Configuration)|$(Platform)'=='" +
+ cfg.get("Name") + "'");
+ }
+ }
+ wg.endTag();
+ }
+
+ String filter = startDir.relativize(file.getParent().toAbsolutePath()).toString();
+ wg10.addFilterDependency(fileLoc, filter);
+
+ return CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes attrs)
+ throws IOException {
+ Boolean hide = false;
+ // TODO remove attrs, if path is matched in this dir, then it is too in every subdir.
+ // And we will check anyway
+ DirAttributes newAttr = attributes.peek().clone();
+
+ // check per config ignorePaths!
+ for (BuildConfig cfg : allConfigs) {
+ if (cfg.matchesIgnoredPath(path.toAbsolutePath().toString())) {
+ newAttr.setIgnore(cfg);
+ }
+
+ // Hide is always on all configs. And additional files are never hiddden
+ if (cfg.matchesHidePath(path.toAbsolutePath().toString())) {
+ hide = true;
+ break;
+ }
+ }
+
+ if (!hide) {
+ String name = startDir.relativize(path.toAbsolutePath()).toString();
+ if (!"".equals(name)) {
+ wg10.addFilter(name);
+ }
+
+ attributes.push(newAttr);
+ return super.preVisitDirectory(path, attrs);
+ } else {
+ return FileVisitResult.SKIP_SUBTREE;
+ }
+ }
+
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
+ //end matching attributes set by ignorepath
+ attributes.pop();
+ return CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFileFailed(Path file, IOException exc) {
+ return CONTINUE;
+ }
+
+ public void writeFileTree() throws IOException {
+ Files.walkFileTree(this.startDir, this);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/make/src/classes/build/tools/projectcreator/ProjectCreator.java Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package build.tools.projectcreator;
+
+public class ProjectCreator {
+
+ public static void usage() {
+ System.out.println("ProjectCreator options:");
+ System.err.println("WinGammaPlatform platform-specific options:");
+ System.err.println(" -sourceBase <path to directory (workspace) "
+ + "containing source files; no trailing slash>");
+ System.err.println(" -dspFileName <full pathname to which .dsp file "
+ + "will be written; all parent directories must "
+ + "already exist>");
+ System.err.println(" -envVar <environment variable to be inserted "
+ + "into .dsp file, substituting for path given in "
+ + "-sourceBase. Example: HotSpotWorkSpace>");
+ System.err.println(" -dllLoc <path to directory in which to put "
+ + "jvm.dll; no trailing slash>");
+ System.err.println(" If any of the above are specified, "
+ + "they must all be.");
+ System.err.println(" Note: if '-altRelativeInclude' option below is "
+ + "used, then the '-relativeAltSrcInclude' option must be used "
+ + "to specify the alternate source dir, e.g., 'src\\closed'");
+ System.err.println(" Additional, optional arguments, which can be "
+ + "specified multiple times:");
+ System.err.println(" -absoluteInclude <string containing absolute "
+ + "path to include directory>");
+ System.err.println(" -altRelativeInclude <string containing "
+ + "alternate include directory relative to -envVar>");
+ System.err.println(" -relativeInclude <string containing include "
+ + "directory relative to -envVar>");
+ System.err.println(" -define <preprocessor flag to be #defined "
+ + "(note: doesn't yet support " + "#define (flag) (value))>");
+ System.err.println(" -perFileLine <file> <line>");
+ System.err.println(" -conditionalPerFileLine <file> <line for "
+ + "release build> <line for debug build>");
+ System.err.println(" (NOTE: To work around a bug in nmake, where "
+ + "you can't have a '#' character in a quoted "
+ + "string, all of the lines outputted have \"#\"" + "prepended)");
+ System.err.println(" -startAt <subdir of sourceBase>");
+ System.err.println(" -ignoreFile <file which won't be able to be "
+ + "found in the sourceBase because it's generated " + "later>");
+ System.err.println(" -additionalFile <file not in database but "
+ + "which should show up in .dsp file>");
+ System.err
+ .println(" -additionalGeneratedFile <environment variable of "
+ + "generated file's location> <relative path to "
+ + "directory containing file; no trailing slash> "
+ + "<name of file generated later in the build process>");
+ System.err.println(" -prelink <build> <desc> <cmds>:");
+ System.err
+ .println(" Generate a set of prelink commands for the given BUILD");
+ System.err
+ .println(" (\"Debug\" or \"Release\"). The prelink description and commands");
+ System.err.println(" are both quoted strings.");
+ System.err.println(" Default includes: \".\"");
+ System.err
+ .println(" Default defines: WIN32, _WINDOWS, \"HOTSPOT_BUILD_USER=$(USERNAME)\"");
+ }
+
+ public static void main(String[] args) {
+ try {
+ if (args.length < 3) {
+ usage();
+ System.exit(1);
+ }
+
+ String platformName = args[0];
+ Class platformClass = Class.forName(platformName);
+ WinGammaPlatform platform = (WinGammaPlatform) platformClass
+ .newInstance();
+
+ String[] platformArgs = new String[args.length - 1];
+ System.arraycopy(args, 1, platformArgs, 0, platformArgs.length);
+
+ // Allow the platform to write platform-specific files
+ platform.createVcproj(platformArgs);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/make/src/classes/build/tools/projectcreator/Util.java Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2005, 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.
+ *
+ */
+
+package build.tools.projectcreator;
+
+import java.util.*;
+import java.io.File;
+
+public class Util {
+
+ static String join(String padder, Vector<String> v) {
+ return join(padder, v, false);
+ }
+
+ static String join(String padder, Vector<String> v, boolean quoted) {
+ StringBuffer sb = new StringBuffer();
+
+ for (Iterator<String> iter = v.iterator(); iter.hasNext(); ) {
+ if (quoted) {
+ sb.append('"');
+ }
+ sb.append(iter.next());
+ if (quoted) {
+ sb.append('"');
+ }
+ if (iter.hasNext()) sb.append(padder);
+ }
+
+ return sb.toString();
+ }
+
+
+ static String prefixed_join(String padder, Vector<String> v, boolean quoted) {
+ StringBuffer sb = new StringBuffer();
+
+ for (Iterator<String> iter = v.iterator(); iter.hasNext(); ) {
+ sb.append(padder);
+
+ if (quoted) {
+ sb.append('"');
+ }
+ sb.append((String)iter.next());
+ if (quoted) {
+ sb.append('"');
+ }
+ }
+
+ return sb.toString();
+ }
+
+
+ static String normalize(String file) {
+ file = file.replace('\\', '/');
+ if (file.length() > 2) {
+ if (file.charAt(1) == ':' && file.charAt(2) == '/') {
+ // convert drive letter to uppercase
+ String drive = file.substring(0, 1).toUpperCase();
+ return drive + file.substring(1);
+ }
+ }
+ return file;
+ }
+
+ static String sep = File.separator;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/make/src/classes/build/tools/projectcreator/WinGammaPlatform.java Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,685 @@
+/*
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package build.tools.projectcreator;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Stack;
+import java.util.Vector;
+
+abstract class HsArgHandler extends ArgHandler {
+ static final int STRING = 1;
+ static final int VECTOR = 2;
+ static final int HASH = 3;
+
+ boolean nextNotKey(ArgIterator it) {
+ if (it.next()) {
+ String s = it.get();
+ return (s.length() == 0) || (s.charAt(0) != '-');
+ } else {
+ return false;
+ }
+ }
+
+ void empty(String key, String message) {
+ if (key != null) {
+ System.err.println("** Error: empty " + key);
+ }
+ if (message != null) {
+ System.err.println(message);
+ }
+ WinGammaPlatform.usage();
+ }
+
+ static String getCfg(String val) {
+ int under = val.indexOf('_');
+ int len = val.length();
+ if (under != -1 && under < len - 1) {
+ return val.substring(under+1, len);
+ } else {
+ return null;
+ }
+ }
+}
+
+class ArgRuleSpecific extends ArgRule {
+ ArgRuleSpecific(String arg, ArgHandler handler) {
+ super(arg, handler);
+ }
+
+ boolean match(String rulePattern, String arg) {
+ return rulePattern.startsWith(arg);
+ }
+}
+
+
+class SpecificHsArgHandler extends HsArgHandler {
+
+ String message, argKey, valKey;
+ int type;
+
+ public void handle(ArgIterator it) {
+ String cfg = getCfg(it.get());
+ if (nextNotKey(it)) {
+ String val = it.get();
+ switch (type) {
+ case VECTOR:
+ BuildConfig.addFieldVector(cfg, valKey, val);
+ break;
+ case HASH:
+ BuildConfig.putFieldHash(cfg, valKey, val, "1");
+ break;
+ case STRING:
+ BuildConfig.putField(cfg, valKey, val);
+ break;
+ default:
+ empty(valKey, "Unknown type: "+type);
+ }
+ it.next();
+
+ } else {
+ empty(argKey, message);
+ }
+ }
+
+ SpecificHsArgHandler(String argKey, String valKey, String message, int type) {
+ this.argKey = argKey;
+ this.valKey = valKey;
+ this.message = message;
+ this.type = type;
+ }
+}
+
+
+class HsArgRule extends ArgRuleSpecific {
+
+ HsArgRule(String argKey, String valKey, String message, int type) {
+ super(argKey, new SpecificHsArgHandler(argKey, valKey, message, type));
+ }
+
+}
+
+public abstract class WinGammaPlatform {
+
+ public boolean fileNameStringEquality(String s1, String s2) {
+ return s1.equalsIgnoreCase(s2);
+ }
+
+ static void usage() throws IllegalArgumentException {
+ System.err.println("WinGammaPlatform platform-specific options:");
+ System.err.println(" -sourceBase <path to directory (workspace) " +
+ "containing source files; no trailing slash>");
+ System.err.println(" -projectFileName <full pathname to which project file " +
+ "will be written; all parent directories must " +
+ "already exist>");
+ System.err.println(" If any of the above are specified, "+
+ "they must all be.");
+ System.err.println(" Note: if '-altRelativeInclude' option below " +
+ "is used, then the '-relativeAltSrcInclude' " +
+ "option must be used to specify the alternate " +
+ "source dir, e.g., 'src\\closed'");
+ System.err.println(" Additional, optional arguments, which can be " +
+ "specified multiple times:");
+ System.err.println(" -absoluteInclude <string containing absolute " +
+ "path to include directory>");
+ System.err.println(" -altRelativeInclude <string containing " +
+ "alternate include directory relative to " +
+ "-sourceBase>");
+ System.err.println(" -relativeInclude <string containing include " +
+ "directory relative to -sourceBase>");
+ System.err.println(" -define <preprocessor flag to be #defined " +
+ "(note: doesn't yet support " +
+ "#define (flag) (value))>");
+ System.err.println(" -startAt <subdir of sourceBase>");
+ System.err.println(" -additionalFile <file not in database but " +
+ "which should show up in project file>");
+ System.err.println(" -additionalGeneratedFile <absolute path to " +
+ "directory containing file; no trailing slash> " +
+ "<name of file generated later in the build process>");
+ throw new IllegalArgumentException();
+ }
+
+
+ public void addPerFileLine(Hashtable table,
+ String fileName,
+ String line) {
+ Vector v = (Vector) table.get(fileName);
+ if (v != null) {
+ v.add(line);
+ } else {
+ v = new Vector();
+ v.add(line);
+ table.put(fileName, v);
+ }
+ }
+
+ protected static class PerFileCondData {
+ public String releaseString;
+ public String debugString;
+ }
+
+ protected void addConditionalPerFileLine(Hashtable table,
+ String fileName,
+ String releaseLine,
+ String debugLine) {
+ PerFileCondData data = new PerFileCondData();
+ data.releaseString = releaseLine;
+ data.debugString = debugLine;
+ Vector v = (Vector) table.get(fileName);
+ if (v != null) {
+ v.add(data);
+ } else {
+ v = new Vector();
+ v.add(data);
+ table.put(fileName, v);
+ }
+ }
+
+ protected static class PrelinkCommandData {
+ String description;
+ String commands;
+ }
+
+ protected void addPrelinkCommand(Hashtable table,
+ String build,
+ String description,
+ String commands) {
+ PrelinkCommandData data = new PrelinkCommandData();
+ data.description = description;
+ data.commands = commands;
+ table.put(build, data);
+ }
+
+ public boolean findString(Vector v, String s) {
+ for (Iterator iter = v.iterator(); iter.hasNext(); ) {
+ if (((String) iter.next()).equals(s)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ String getProjectName(String fullPath, String extension)
+ throws IllegalArgumentException, IOException {
+ File file = new File(fullPath).getCanonicalFile();
+ fullPath = file.getCanonicalPath();
+ String parent = file.getParent();
+
+ if (!fullPath.endsWith(extension)) {
+ throw new IllegalArgumentException("project file name \"" +
+ fullPath +
+ "\" does not end in "+extension);
+ }
+
+ if ((parent != null) &&
+ (!fullPath.startsWith(parent))) {
+ throw new RuntimeException(
+ "Internal error: parent of file name \"" + parent +
+ "\" does not match file name \"" + fullPath + "\""
+ );
+ }
+
+ int len = parent.length();
+ if (!parent.endsWith(Util.sep)) {
+ len += Util.sep.length();
+ }
+
+ int end = fullPath.length() - extension.length();
+
+ if (len == end) {
+ throw new RuntimeException(
+ "Internal error: file name was empty"
+ );
+ }
+
+ return fullPath.substring(len, end);
+ }
+
+ protected abstract String getProjectExt();
+
+ public void createVcproj(String[] args)
+ throws IllegalArgumentException, IOException {
+
+ parseArguments(args);
+
+ String projectFileName = BuildConfig.getFieldString(null, "ProjectFileName");
+ String ext = getProjectExt();
+
+ String projectName = getProjectName(projectFileName, ext);
+
+ writeProjectFile(projectFileName, projectName, createAllConfigs(BuildConfig.getFieldString(null, "PlatformName")));
+ }
+
+ protected void writePrologue(String[] args) {
+ System.err.println("WinGammaPlatform platform-specific arguments:");
+ for (int i = 0; i < args.length; i++) {
+ System.err.print(args[i] + " ");
+ }
+ System.err.println();
+ }
+
+
+ void parseArguments(String[] args) {
+ new ArgsParser(args,
+ new ArgRule[]
+ {
+ new ArgRule("-sourceBase",
+ new HsArgHandler() {
+ public void handle(ArgIterator it) {
+ String cfg = getCfg(it.get());
+ if (nextNotKey(it)) {
+ String sb = (String) it.get();
+ if (sb.endsWith(Util.sep)) {
+ sb = sb.substring(0, sb.length() - 1);
+ }
+ BuildConfig.putField(cfg, "SourceBase", sb);
+ it.next();
+ } else {
+ empty("-sourceBase", null);
+ }
+ }
+ }
+ ),
+
+ new HsArgRule("-buildBase",
+ "BuildBase",
+ " (Did you set the HotSpotBuildSpace environment variable?)",
+ HsArgHandler.STRING
+ ),
+
+ new HsArgRule("-buildSpace",
+ "BuildSpace",
+ null,
+ HsArgHandler.STRING
+ ),
+
+ new HsArgRule("-makeBinary",
+ "MakeBinary",
+ null,
+ HsArgHandler.STRING
+ ),
+
+ new HsArgRule("-makeOutput",
+ "MakeOutput",
+ null,
+ HsArgHandler.STRING
+ ),
+
+ new HsArgRule("-platformName",
+ "PlatformName",
+ null,
+ HsArgHandler.STRING
+ ),
+
+ new HsArgRule("-projectFileName",
+ "ProjectFileName",
+ null,
+ HsArgHandler.STRING
+ ),
+
+ new HsArgRule("-jdkTargetRoot",
+ "JdkTargetRoot",
+ " (Did you set the HotSpotJDKDist environment variable?)",
+ HsArgHandler.STRING
+ ),
+
+ new HsArgRule("-compiler",
+ "CompilerVersion",
+ " (Did you set the VcVersion correctly?)",
+ HsArgHandler.STRING
+ ),
+
+ new HsArgRule("-absoluteInclude",
+ "AbsoluteInclude",
+ null,
+ HsArgHandler.VECTOR
+ ),
+
+ new HsArgRule("-altRelativeInclude",
+ "AltRelativeInclude",
+ null,
+ HsArgHandler.VECTOR
+ ),
+
+ new HsArgRule("-relativeInclude",
+ "RelativeInclude",
+ null,
+ HsArgHandler.VECTOR
+ ),
+
+ new HsArgRule("-absoluteSrcInclude",
+ "AbsoluteSrcInclude",
+ null,
+ HsArgHandler.VECTOR
+ ),
+
+ new HsArgRule("-relativeAltSrcInclude",
+ "RelativeAltSrcInclude",
+ null,
+ HsArgHandler.STRING
+ ),
+
+ new HsArgRule("-relativeSrcInclude",
+ "RelativeSrcInclude",
+ null,
+ HsArgHandler.VECTOR
+ ),
+
+ new HsArgRule("-define",
+ "Define",
+ null,
+ HsArgHandler.VECTOR
+ ),
+
+ new HsArgRule("-useToGeneratePch",
+ "UseToGeneratePch",
+ null,
+ HsArgHandler.STRING
+ ),
+
+ new ArgRuleSpecific("-perFileLine",
+ new HsArgHandler() {
+ public void handle(ArgIterator it) {
+ String cfg = getCfg(it.get());
+ if (nextNotKey(it)) {
+ String fileName = it.get();
+ if (nextNotKey(it)) {
+ String line = it.get();
+ BuildConfig.putFieldHash(cfg, "PerFileLine", fileName, line);
+ it.next();
+ return;
+ }
+ }
+ empty(null, "** Error: wrong number of args to -perFileLine");
+ }
+ }
+ ),
+
+ new ArgRuleSpecific("-conditionalPerFileLine",
+ new HsArgHandler() {
+ public void handle(ArgIterator it) {
+ String cfg = getCfg(it.get());
+ if (nextNotKey(it)) {
+ String fileName = it.get();
+ if (nextNotKey(it)) {
+ String productLine = it.get();
+ if (nextNotKey(it)) {
+ String debugLine = it.get();
+ BuildConfig.putFieldHash(cfg+"_debug", "CondPerFileLine",
+ fileName, debugLine);
+ BuildConfig.putFieldHash(cfg+"_product", "CondPerFileLine",
+ fileName, productLine);
+ it.next();
+ return;
+ }
+ }
+ }
+
+ empty(null, "** Error: wrong number of args to -conditionalPerFileLine");
+ }
+ }
+ ),
+
+ new HsArgRule("-disablePch",
+ "DisablePch",
+ null,
+ HsArgHandler.HASH
+ ),
+
+ new ArgRule("-startAt",
+ new HsArgHandler() {
+ public void handle(ArgIterator it) {
+ if (BuildConfig.getField(null, "StartAt") != null) {
+ empty(null, "** Error: multiple -startAt");
+ }
+ if (nextNotKey(it)) {
+ BuildConfig.putField(null, "StartAt", it.get());
+ it.next();
+ } else {
+ empty("-startAt", null);
+ }
+ }
+ }
+ ),
+
+ new HsArgRule("-ignoreFile",
+ "IgnoreFile",
+ null,
+ HsArgHandler.HASH
+ ),
+
+ new HsArgRule("-ignorePath",
+ "IgnorePath",
+ null,
+ HsArgHandler.VECTOR
+ ),
+
+ new HsArgRule("-hidePath",
+ "HidePath",
+ null,
+ HsArgHandler.VECTOR
+ ),
+
+ new HsArgRule("-additionalFile",
+ "AdditionalFile",
+ null,
+ HsArgHandler.VECTOR
+ ),
+
+ new ArgRuleSpecific("-additionalGeneratedFile",
+ new HsArgHandler() {
+ public void handle(ArgIterator it) {
+ String cfg = getCfg(it.get());
+ if (nextNotKey(it)) {
+ String dir = it.get();
+ if (nextNotKey(it)) {
+ String fileName = it.get();
+ BuildConfig.putFieldHash(cfg, "AdditionalGeneratedFile",
+ Util.normalize(dir + Util.sep + fileName),
+ fileName);
+ it.next();
+ return;
+ }
+ }
+ empty(null, "** Error: wrong number of args to -additionalGeneratedFile");
+ }
+ }
+ ),
+
+ new ArgRule("-prelink",
+ new HsArgHandler() {
+ public void handle(ArgIterator it) {
+ if (nextNotKey(it)) {
+ if (nextNotKey(it)) {
+ String description = it.get();
+ if (nextNotKey(it)) {
+ String command = it.get();
+ BuildConfig.putField(null, "PrelinkDescription", description);
+ BuildConfig.putField(null, "PrelinkCommand", command);
+ it.next();
+ return;
+ }
+ }
+ }
+
+ empty(null, "** Error: wrong number of args to -prelink");
+ }
+ }
+ ),
+
+ new ArgRule("-postbuild",
+ new HsArgHandler() {
+ public void handle(ArgIterator it) {
+ if (nextNotKey(it)) {
+ if (nextNotKey(it)) {
+ String description = it.get();
+ if (nextNotKey(it)) {
+ String command = it.get();
+ BuildConfig.putField(null, "PostbuildDescription", description);
+ BuildConfig.putField(null, "PostbuildCommand", command);
+ it.next();
+ return;
+ }
+ }
+ }
+
+ empty(null, "** Error: wrong number of args to -postbuild");
+ }
+ }
+ ),
+ },
+ new ArgHandler() {
+ public void handle(ArgIterator it) {
+
+ throw new RuntimeException("Arg Parser: unrecognized option "+it.get());
+ }
+ }
+ );
+ if (BuildConfig.getField(null, "SourceBase") == null ||
+ BuildConfig.getField(null, "BuildBase") == null ||
+ BuildConfig.getField(null, "ProjectFileName") == null ||
+ BuildConfig.getField(null, "CompilerVersion") == null) {
+ usage();
+ }
+
+ BuildConfig.putField(null, "PlatformObject", this);
+ }
+
+ Vector createAllConfigs(String platform) {
+ Vector allConfigs = new Vector();
+
+ allConfigs.add(new C1DebugConfig());
+ allConfigs.add(new C1FastDebugConfig());
+ allConfigs.add(new C1ProductConfig());
+
+ allConfigs.add(new TieredDebugConfig());
+ allConfigs.add(new TieredFastDebugConfig());
+ allConfigs.add(new TieredProductConfig());
+
+ return allConfigs;
+ }
+
+ PrintWriter printWriter;
+
+ public void writeProjectFile(String projectFileName, String projectName,
+ Vector<BuildConfig> allConfigs) throws IOException {
+ throw new RuntimeException("use compiler version specific version");
+ }
+
+ int indent;
+ private Stack<String> tagStack = new Stack<String>();
+
+ private void startTagPrim(String name, String[] attrs, boolean close) {
+ startTagPrim(name, attrs, close, true);
+ }
+
+ private void startTagPrim(String name, String[] attrs, boolean close,
+ boolean newline) {
+ doIndent();
+ printWriter.print("<" + name);
+ indent++;
+
+ if (attrs != null && attrs.length > 0) {
+ for (int i = 0; i < attrs.length; i += 2) {
+ printWriter.print(" " + attrs[i] + "=\"" + attrs[i + 1] + "\"");
+ if (i < attrs.length - 2) {
+ }
+ }
+ }
+
+ if (close) {
+ indent--;
+ printWriter.print(" />");
+ } else {
+ // TODO push tag name, and change endTag to pop and print.
+ tagStack.push(name);
+ printWriter.print(">");
+ }
+ if (newline) {
+ printWriter.println();
+ }
+ }
+
+ void startTag(String name, String... attrs) {
+ startTagPrim(name, attrs, false);
+ }
+
+ void startTagV(String name, Vector attrs) {
+ String s[] = new String[attrs.size()];
+ for (int i = 0; i < attrs.size(); i++) {
+ s[i] = (String) attrs.elementAt(i);
+ }
+ startTagPrim(name, s, false);
+ }
+
+ void endTag() {
+ String name = tagStack.pop();
+ indent--;
+ doIndent();
+ printWriter.println("</" + name + ">");
+ }
+
+ private void endTagNoIndent() {
+ String name = tagStack.pop();
+ indent--;
+ printWriter.println("</" + name + ">");
+ }
+
+ void tag(String name, String... attrs) {
+ startTagPrim(name, attrs, true);
+ }
+
+ void tagData(String name, String data) {
+ startTagPrim(name, null, false, false);
+ printWriter.print(data);
+ endTagNoIndent();
+ }
+
+ void tagData(String name, String data, String... attrs) {
+ startTagPrim(name, attrs, false, false);
+ printWriter.print(data);
+ endTagNoIndent();
+ }
+
+ void tagV(String name, Vector attrs) {
+ String s[] = new String[attrs.size()];
+ for (int i = 0; i < attrs.size(); i++) {
+ s[i] = (String) attrs.elementAt(i);
+ }
+ startTagPrim(name, s, true);
+ }
+
+ void doIndent() {
+ for (int i = 0; i < indent; i++) {
+ printWriter.print(" ");
+ }
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/make/src/classes/build/tools/projectcreator/WinGammaPlatformVC10.java Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,471 @@
+/*
+ * 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package build.tools.projectcreator;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.nio.file.FileSystems;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.UUID;
+import java.util.Vector;
+
+public class WinGammaPlatformVC10 extends WinGammaPlatform {
+
+
+ LinkedList <String>filters = new LinkedList<String>();
+ LinkedList <String[]>filterDeps = new LinkedList<String[]>();
+
+ @Override
+ protected String getProjectExt() {
+ return ".vcxproj";
+ }
+
+ @Override
+ public void writeProjectFile(String projectFileName, String projectName,
+ Vector<BuildConfig> allConfigs) throws IOException {
+ System.out.println();
+ System.out.println(" Writing .vcxproj file: " + projectFileName);
+
+ String projDir = Util.normalize(new File(projectFileName).getParent());
+
+ printWriter = new PrintWriter(projectFileName, "UTF-8");
+ printWriter.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
+ startTag("Project",
+ "DefaultTargets", "Build",
+ "ToolsVersion", "4.0",
+ "xmlns", "http://schemas.microsoft.com/developer/msbuild/2003");
+ startTag("ItemGroup",
+ "Label", "ProjectConfigurations");
+ for (BuildConfig cfg : allConfigs) {
+ startTag("ProjectConfiguration",
+ "Include", cfg.get("Name"));
+ tagData("Configuration", cfg.get("Id"));
+ tagData("Platform", cfg.get("PlatformName"));
+ endTag();
+ }
+ endTag();
+
+ startTag("PropertyGroup", "Label", "Globals");
+ tagData("ProjectGuid", "{8822CB5C-1C41-41C2-8493-9F6E1994338B}");
+ tagData("Keyword", "MakeFileProj");
+ tag("SccProjectName");
+ tag("SccLocalPath");
+ endTag();
+
+ tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.Default.props");
+
+ for (BuildConfig cfg : allConfigs) {
+ startTag(cfg, "PropertyGroup", "Label", "Configuration");
+ tagData("ConfigurationType", "Makefile");
+ tagData("UseDebugLibraries", "true");
+ endTag();
+ }
+
+ tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.props");
+ startTag("ImportGroup", "Label", "ExtensionSettings");
+ endTag();
+ for (BuildConfig cfg : allConfigs) {
+ startTag(cfg, "ImportGroup", "Label", "PropertySheets");
+ tag("Import",
+ "Project", "$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props",
+ "Condition", "exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')",
+ "Label", "LocalAppDataPlatform");
+ endTag();
+ }
+
+ tag("PropertyGroup", "Label", "UserMacros");
+
+ startTag("PropertyGroup");
+ tagData("_ProjectFileVersion", "10.0.30319.1");
+ for (BuildConfig cfg : allConfigs) {
+ tagData(cfg, "OutDir", cfg.get("OutputDir") + Util.sep);
+ tagData(cfg, "IntDir", cfg.get("OutputDir") + Util.sep);
+ tagData(cfg, "LinkIncremental", "false");
+ }
+ for (BuildConfig cfg : allConfigs) {
+ tagData(cfg, "CodeAnalysisRuleSet", "AllRules.ruleset");
+ tag(cfg, "CodeAnalysisRules");
+ tag(cfg, "CodeAnalysisRuleAssemblies");
+ }
+ for (BuildConfig cfg : allConfigs) {
+ tagData(cfg, "NMakeBuildCommandLine", cfg.get("MakeBinary") + " -f ../../Makefile import-hotspot LOG=info");
+ tagData(cfg, "NMakeReBuildCommandLine", cfg.get("MakeBinary") + " -f ../../Makefile clean-hotspot import-hotspot LOG=info");
+ tagData(cfg, "NMakeCleanCommandLine", cfg.get("MakeBinary") + " -f ../../Makefile clean-hotspot LOG=info");
+ tagData(cfg, "NMakeOutput", cfg.get("MakeOutput") + Util.sep + "jvm.dll");
+ tagData(cfg, "NMakePreprocessorDefinitions", Util.join(";", cfg.getDefines()));
+ tagData(cfg, "NMakeIncludeSearchPath", Util.join(";", cfg.getIncludes()));
+ }
+ endTag();
+
+ for (BuildConfig cfg : allConfigs) {
+ startTag(cfg, "ItemDefinitionGroup");
+ startTag("ClCompile");
+ tagV(cfg.getV("CompilerFlags"));
+ endTag();
+
+ startTag("Link");
+ tagV(cfg.getV("LinkerFlags"));
+ endTag();
+
+ endTag();
+ }
+
+ writeFiles(allConfigs, projDir);
+
+ tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.targets");
+ startTag("ImportGroup", "Label", "ExtensionTargets");
+ endTag();
+
+ endTag();
+ printWriter.close();
+ System.out.println(" Done writing .vcxproj file.");
+
+ writeFilterFile(projectFileName, projectName, allConfigs, projDir);
+ writeUserFile(projectFileName, allConfigs);
+ }
+
+
+ private void writeUserFile(String projectFileName, Vector<BuildConfig> allConfigs) throws FileNotFoundException, UnsupportedEncodingException {
+ String userFileName = projectFileName + ".user";
+ if (new File(userFileName).exists()) {
+ return;
+ }
+ System.out.print(" Writing .vcxproj.user file: " + userFileName);
+ printWriter = new PrintWriter(userFileName, "UTF-8");
+
+ printWriter.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
+ startTag("Project",
+ "ToolsVersion", "4.0",
+ "xmlns", "http://schemas.microsoft.com/developer/msbuild/2003");
+
+ for (BuildConfig cfg : allConfigs) {
+ startTag(cfg, "PropertyGroup");
+ tagData("LocalDebuggerCommand", cfg.get("JdkTargetRoot") + "\\bin\\java.exe");
+ // Since we run "make hotspot-import", we get the correct jvm.dll by java.exe.
+ // The '-XX:+PauseAtExit' option
+ // causes the VM to wait for key press before exiting; this
+ // allows any stdout or stderr messages to be seen before
+ // the cmdtool exits.
+ tagData("LocalDebuggerCommandArguments",
+ "-XX:+UnlockDiagnosticVMOptions -XX:+PauseAtExit");
+ tagData("LocalDebuggerEnvironment", "JAVA_HOME=" + cfg.get("JdkTargetRoot"));
+ endTag();
+ }
+
+ endTag();
+ printWriter.close();
+ System.out.println(" Done.");
+ }
+
+ public void addFilter(String rPath) {
+ filters.add(rPath);
+ }
+
+ public void addFilterDependency(String fileLoc, String filter) {
+ filterDeps.add(new String[] {fileLoc, filter});
+ }
+
+ private void writeFilterFile(String projectFileName, String projectName,
+ Vector<BuildConfig> allConfigs, String base) throws FileNotFoundException, UnsupportedEncodingException {
+ String filterFileName = projectFileName + ".filters";
+ System.out.print(" Writing .vcxproj.filters file: " + filterFileName);
+ printWriter = new PrintWriter(filterFileName, "UTF-8");
+
+ printWriter.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
+ startTag("Project",
+ "ToolsVersion", "4.0",
+ "xmlns", "http://schemas.microsoft.com/developer/msbuild/2003");
+
+ startTag("ItemGroup");
+ for (String filter : filters) {
+ startTag("Filter", "Include",filter);
+ UUID uuid = UUID.randomUUID();
+ tagData("UniqueIdentifier", "{" + uuid.toString() + "}");
+ endTag();
+ }
+ endTag();
+
+ //TODO - do I need to split cpp and hpp files?
+
+ // then all files
+ startTag("ItemGroup");
+ for (String[] dep : filterDeps) {
+ String tagName = getFileTagFromSuffix(dep[0]);
+
+ startTag(tagName, "Include", dep[0]);
+ tagData("Filter", dep[1]);
+ endTag();
+ }
+ endTag();
+
+ endTag();
+ printWriter.close();
+ System.out.println(" Done.");
+ }
+
+ public String getFileTagFromSuffix(String fileName) {
+ if (fileName.endsWith(".cpp")) {
+ return"ClCompile";
+ } else if (fileName.endsWith(".c")) {
+ return "ClCompile";
+ } else if (fileName.endsWith(".hpp")) {
+ return"ClInclude";
+ } else if (fileName.endsWith(".h")) {
+ return "ClInclude";
+ } else {
+ return"None";
+ }
+ }
+
+ void writeFiles(Vector<BuildConfig> allConfigs, String projDir) {
+ // This code assummes there are no config specific includes.
+ startTag("ItemGroup");
+
+ String sourceBase = BuildConfig.getFieldString(null, "SourceBase");
+
+ // Use first config for all global absolute includes.
+ BuildConfig baseConfig = allConfigs.firstElement();
+ Vector<String> rv = new Vector<String>();
+
+ // Then use first config for all relative includes
+ Vector<String> ri = new Vector<String>();
+ baseConfig.collectRelevantVectors(ri, "RelativeSrcInclude");
+ for (String f : ri) {
+ rv.add(sourceBase + Util.sep + f);
+ }
+
+ baseConfig.collectRelevantVectors(rv, "AbsoluteSrcInclude");
+
+ handleIncludes(rv, allConfigs);
+
+ endTag();
+ }
+
+ // Will visit file tree for each include
+ private void handleIncludes(Vector<String> includes, Vector<BuildConfig> allConfigs) {
+ for (String path : includes) {
+ FileTreeCreatorVC10 ftc = new FileTreeCreatorVC10(FileSystems.getDefault().getPath(path) , allConfigs, this);
+ try {
+ ftc.writeFileTree();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ String buildCond(BuildConfig cfg) {
+ return "'$(Configuration)|$(Platform)'=='"+cfg.get("Name")+"'";
+ }
+
+ void tagV(Vector<String> v) {
+ Iterator<String> i = v.iterator();
+ while(i.hasNext()) {
+ String name = i.next();
+ String data = i.next();
+ tagData(name, data);
+ }
+ }
+
+ void tagData(BuildConfig cfg, String name, String data) {
+ tagData(name, data, "Condition", buildCond(cfg));
+ }
+
+ void tag(BuildConfig cfg, String name, String... attrs) {
+ String[] ss = new String[attrs.length + 2];
+ ss[0] = "Condition";
+ ss[1] = buildCond(cfg);
+ System.arraycopy(attrs, 0, ss, 2, attrs.length);
+
+ tag(name, ss);
+ }
+
+ void startTag(BuildConfig cfg, String name, String... attrs) {
+ String[] ss = new String[attrs.length + 2];
+ ss[0] = "Condition";
+ ss[1] = buildCond(cfg);
+ System.arraycopy(attrs, 0, ss, 2, attrs.length);
+
+ startTag(name, ss);
+ }
+
+}
+
+class CompilerInterfaceVC10 extends CompilerInterface {
+
+ @Override
+ Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir) {
+ Vector rv = new Vector();
+
+ addAttr(rv, "AdditionalIncludeDirectories", Util.join(";", includes));
+ addAttr(rv, "PreprocessorDefinitions",
+ Util.join(";", defines).replace("\\\"", "\""));
+ addAttr(rv, "PrecompiledHeaderFile", "precompiled.hpp");
+ addAttr(rv, "PrecompiledHeaderOutputFile", outDir+Util.sep+"vm.pch");
+ addAttr(rv, "AssemblerListingLocation", outDir);
+ addAttr(rv, "ObjectFileName", outDir+Util.sep);
+ addAttr(rv, "ProgramDataBaseFileName", outDir+Util.sep+"jvm.pdb");
+ // Set /nologo option
+ addAttr(rv, "SuppressStartupBanner", "true");
+ // Surpass the default /Tc or /Tp.
+ addAttr(rv, "CompileAs", "Default");
+ // Set /W3 option.
+ addAttr(rv, "WarningLevel", "Level3");
+ // Set /WX option,
+ addAttr(rv, "TreatWarningAsError", "true");
+ // Set /GS option
+ addAttr(rv, "BufferSecurityCheck", "false");
+ // Set /Zi option.
+ addAttr(rv, "DebugInformationFormat", "ProgramDatabase");
+ // Set /Yu option.
+ addAttr(rv, "PrecompiledHeader", "Use");
+ // Set /EHsc- option
+ addAttr(rv, "ExceptionHandling", "");
+
+ addAttr(rv, "MultiProcessorCompilation", "true");
+
+ return rv;
+ }
+
+ @Override
+ Vector getDebugCompilerFlags(String opt, String platformName) {
+ Vector rv = new Vector();
+
+ // Set /On option
+ addAttr(rv, "Optimization", opt);
+ // Set /MD option.
+ addAttr(rv, "RuntimeLibrary", "MultiThreadedDLL");
+ // Set /Oy- option
+ addAttr(rv, "OmitFramePointers", "false");
+ // Set /homeparams for x64 debug builds
+ if(platformName.equals("x64")) {
+ addAttr(rv, "AdditionalOptions", "/homeparams");
+ }
+
+ return rv;
+ }
+
+ @Override
+ Vector getProductCompilerFlags() {
+ Vector rv = new Vector();
+
+ // Set /O2 option.
+ addAttr(rv, "Optimization", "MaxSpeed");
+ // Set /Oy- option
+ addAttr(rv, "OmitFramePointers", "false");
+ // Set /Ob option. 1 is expandOnlyInline
+ addAttr(rv, "InlineFunctionExpansion", "OnlyExplicitInline");
+ // Set /GF option.
+ addAttr(rv, "StringPooling", "true");
+ // Set /MD option. 2 is rtMultiThreadedDLL
+ addAttr(rv, "RuntimeLibrary", "MultiThreadedDLL");
+ // Set /Gy option
+ addAttr(rv, "FunctionLevelLinking", "true");
+
+ return rv;
+ }
+
+ @Override
+ Vector getBaseLinkerFlags(String outDir, String outDll, String platformName) {
+ Vector rv = new Vector();
+
+ if(platformName.equals("Win32")) {
+ addAttr(rv, "AdditionalOptions",
+ "/export:JNI_GetDefaultJavaVMInitArgs " +
+ "/export:JNI_CreateJavaVM " +
+ "/export:JVM_FindClassFromBootLoader "+
+ "/export:JNI_GetCreatedJavaVMs "+
+ "/export:jio_snprintf /export:jio_printf "+
+ "/export:jio_fprintf /export:jio_vfprintf "+
+ "/export:jio_vsnprintf "+
+ "/export:JVM_GetVersionInfo "+
+ "/export:JVM_InitAgentProperties");
+ }
+ addAttr(rv, "AdditionalDependencies", "kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;Wsock32.lib;winmm.lib;psapi.lib;version.lib");
+ addAttr(rv, "OutputFile", outDll);
+ addAttr(rv, "SuppressStartupBanner", "true");
+ addAttr(rv, "ModuleDefinitionFile", outDir+Util.sep+"vm.def");
+ addAttr(rv, "ProgramDatabaseFile", outDir+Util.sep+"jvm.pdb");
+ addAttr(rv, "SubSystem", "Windows");
+ addAttr(rv, "BaseAddress", "0x8000000");
+ addAttr(rv, "ImportLibrary", outDir+Util.sep+"jvm.lib");
+
+ if(platformName.equals("Win32")) {
+ addAttr(rv, "TargetMachine", "MachineX86");
+ } else {
+ addAttr(rv, "TargetMachine", "MachineX64");
+ }
+
+ // We always want the /DEBUG option to get full symbol information in the pdb files
+ addAttr(rv, "GenerateDebugInformation", "true");
+
+ return rv;
+ }
+
+ @Override
+ Vector getDebugLinkerFlags() {
+ Vector rv = new Vector();
+
+ // Empty now that /DEBUG option is used by all configs
+
+ return rv;
+ }
+
+ @Override
+ Vector getProductLinkerFlags() {
+ Vector rv = new Vector();
+
+ // Set /OPT:REF option.
+ addAttr(rv, "OptimizeReferences", "true");
+ // Set /OPT:ICF option.
+ addAttr(rv, "EnableCOMDATFolding", "true");
+
+ return rv;
+ }
+
+ @Override
+ void getAdditionalNonKernelLinkerFlags(Vector rv) {
+ extAttr(rv, "AdditionalOptions", " /export:AsyncGetCallTrace");
+ }
+
+ @Override
+ String getOptFlag() {
+ return "MaxSpeed";
+ }
+
+ @Override
+ String getNoOptFlag() {
+ return "Disabled";
+ }
+
+ @Override
+ String makeCfgName(String flavourBuild, String platform) {
+ return flavourBuild + "|" + platform;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/make/test/GtestImage.gmk Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,67 @@
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. 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.
+#
+
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+
+$(foreach v, $(JVM_VARIANTS), \
+ $(eval $(call SetupCopyFiles, COPY_GTEST_$v, \
+ SRC := $(HOTSPOT_OUTPUTDIR)/variant-$v/libjvm/gtest, \
+ DEST := $(TEST_IMAGE_DIR)/hotspot/gtest/$v, \
+ FILES := $(call SHARED_LIBRARY,jvm) gtestLauncher$(EXE_SUFFIX), \
+ )) \
+ $(eval TARGETS += $$(COPY_GTEST_$v)) \
+)
+
+ifeq ($(OPENJDK_TARGET_OS), windows)
+ $(foreach v, $(JVM_VARIANTS), \
+ $(eval $(call SetupCopyFiles, COPY_GTEST_MSVCR_$v, \
+ DEST := $(TEST_IMAGE_DIR)/hotspot/gtest/$v, \
+ FILES := $(MSVCR_DLL) $(MSVCP_DLL), \
+ FLATTEN := true, \
+ )) \
+ $(eval TARGETS += $$(COPY_GTEST_MSVCR_$v)) \
+ $(eval $(call SetupCopyFiles, COPY_GTEST_PDB_$v, \
+ SRC := $(HOTSPOT_OUTPUTDIR)/variant-$v/libjvm/gtest, \
+ DEST := $(TEST_IMAGE_DIR)/hotspot/gtest/$v, \
+ FILES := jvm.pdb gtestLauncher.pdb, \
+ )) \
+ $(eval TARGETS += $$(COPY_GTEST_PDB_$v)) \
+ )
+endif
+
+ifeq ($(OPENJDK_TARGET_OS), solaris)
+ $(foreach v, $(JVM_VARIANTS), \
+ $(eval $(call SetupCopyFiles, COPY_GTEST_STLPORT_$v, \
+ DEST := $(TEST_IMAGE_DIR)/hotspot/gtest/$v, \
+ FILES := $(STLPORT_LIB), \
+ )) \
+ $(eval TARGETS += $$(COPY_GTEST_STLPORT_$v)) \
+ )
+endif
+
+all: $(TARGETS)
--- a/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp Wed May 11 00:38:58 2016 +0300
@@ -27,12 +27,12 @@
#include "interp_masm_aarch64.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
+#include "logging/log.hpp"
#include "oops/arrayOop.hpp"
#include "oops/markOop.hpp"
#include "oops/methodData.hpp"
#include "oops/method.hpp"
#include "prims/jvmtiExport.hpp"
-#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "prims/jvmtiThreadState.hpp"
#include "runtime/basicLock.hpp"
#include "runtime/biasedLocking.hpp"
@@ -1450,7 +1450,7 @@
}
// RedefineClasses() tracing support for obsolete method entry
- if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
+ if (log_is_enabled(Trace, redefine, class, obsolete)) {
get_method(c_rarg1);
call_VM_leaf(
CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry),
--- a/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp Wed May 11 00:38:58 2016 +0300
@@ -31,9 +31,9 @@
#include "code/vtableStubs.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interp_masm.hpp"
+#include "logging/log.hpp"
#include "memory/resourceArea.hpp"
#include "oops/compiledICHolder.hpp"
-#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vframeArray.hpp"
#include "vmreg_aarch64.inline.hpp"
@@ -1781,7 +1781,7 @@
}
// RedefineClasses() tracing support for obsolete method entry
- if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
+ if (log_is_enabled(Trace, redefine, class, obsolete)) {
// protect the args we've loaded
save_args(masm, total_c_args, c_arg, out_regs);
__ mov_metadata(c_rarg1, method());
--- a/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp Wed May 11 00:38:58 2016 +0300
@@ -33,7 +33,6 @@
#include "interpreter/interp_masm.hpp"
#include "memory/resourceArea.hpp"
#include "oops/compiledICHolder.hpp"
-#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vframeArray.hpp"
#include "vmreg_ppc.inline.hpp"
--- a/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp Wed May 11 00:38:58 2016 +0300
@@ -825,17 +825,6 @@
return start;
}
- // The following routine generates a subroutine to throw an asynchronous
- // UnknownError when an unsafe access gets a fault that could not be
- // reasonably prevented by the programmer. (Example: SIGBUS/OBJERR.)
- //
- address generate_handler_for_unsafe_access() {
- StubCodeMark mark(this, "StubRoutines", "handler_for_unsafe_access");
- address start = __ function_entry();
- __ unimplemented("StubRoutines::handler_for_unsafe_access", 93);
- return start;
- }
-
#if !defined(PRODUCT)
// Wrapper which calls oopDesc::is_oop_or_null()
// Only called by MacroAssembler::verify_oop
@@ -3111,8 +3100,6 @@
StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError), false);
StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call), false);
- StubRoutines::_handler_for_unsafe_access_entry = generate_handler_for_unsafe_access();
-
// support for verify_oop (must happen after universe_init)
StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop();
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp Wed May 11 00:38:58 2016 +0300
@@ -26,13 +26,13 @@
#include "interp_masm_sparc.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
+#include "logging/log.hpp"
#include "oops/arrayOop.hpp"
#include "oops/markOop.hpp"
#include "oops/methodData.hpp"
#include "oops/method.hpp"
#include "oops/methodCounters.hpp"
#include "prims/jvmtiExport.hpp"
-#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "prims/jvmtiThreadState.hpp"
#include "runtime/basicLock.hpp"
#include "runtime/biasedLocking.hpp"
@@ -2645,7 +2645,7 @@
}
// RedefineClasses() tracing support for obsolete method entry
- if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
+ if (log_is_enabled(Trace, redefine, class, obsolete)) {
call_VM_leaf(noreg,
CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry),
G2_thread, Lmethod);
--- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Wed May 11 00:38:58 2016 +0300
@@ -28,9 +28,9 @@
#include "code/icBuffer.hpp"
#include "code/vtableStubs.hpp"
#include "interpreter/interpreter.hpp"
+#include "logging/log.hpp"
#include "memory/resourceArea.hpp"
#include "oops/compiledICHolder.hpp"
-#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vframeArray.hpp"
#include "vmreg_sparc.inline.hpp"
@@ -2450,7 +2450,7 @@
}
// RedefineClasses() tracing support for obsolete method entry
- if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
+ if (log_is_enabled(Trace, redefine, class, obsolete)) {
// create inner frame
__ save_frame(0);
__ mov(G2_thread, L7_thread_cache);
--- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp Wed May 11 00:38:58 2016 +0300
@@ -64,20 +64,6 @@
// -------------------------------------------------------------------------------------------------------------------------
// Stub Code definitions
-static address handle_unsafe_access() {
- JavaThread* thread = JavaThread::current();
- address pc = thread->saved_exception_pc();
- address npc = thread->saved_exception_npc();
- // pc is the instruction which we must emulate
- // doing a no-op is fine: return garbage from the load
-
- // request an async exception
- thread->set_pending_unsafe_access_error();
-
- // return address of next instruction to execute
- return npc;
-}
-
class StubGenerator: public StubCodeGenerator {
private:
@@ -746,62 +732,6 @@
Label _atomic_add_stub; // called from other stubs
- //------------------------------------------------------------------------------------------------------------------------
- // The following routine generates a subroutine to throw an asynchronous
- // UnknownError when an unsafe access gets a fault that could not be
- // reasonably prevented by the programmer. (Example: SIGBUS/OBJERR.)
- //
- // Arguments :
- //
- // trapping PC: O7
- //
- // Results:
- // posts an asynchronous exception, skips the trapping instruction
- //
-
- address generate_handler_for_unsafe_access() {
- StubCodeMark mark(this, "StubRoutines", "handler_for_unsafe_access");
- address start = __ pc();
-
- const int preserve_register_words = (64 * 2);
- Address preserve_addr(FP, (-preserve_register_words * wordSize) + STACK_BIAS);
-
- Register Lthread = L7_thread_cache;
- int i;
-
- __ save_frame(0);
- __ mov(G1, L1);
- __ mov(G2, L2);
- __ mov(G3, L3);
- __ mov(G4, L4);
- __ mov(G5, L5);
- for (i = 0; i < 64; i += 2) {
- __ stf(FloatRegisterImpl::D, as_FloatRegister(i), preserve_addr, i * wordSize);
- }
-
- address entry_point = CAST_FROM_FN_PTR(address, handle_unsafe_access);
- BLOCK_COMMENT("call handle_unsafe_access");
- __ call(entry_point, relocInfo::runtime_call_type);
- __ delayed()->nop();
-
- __ mov(L1, G1);
- __ mov(L2, G2);
- __ mov(L3, G3);
- __ mov(L4, G4);
- __ mov(L5, G5);
- for (i = 0; i < 64; i += 2) {
- __ ldf(FloatRegisterImpl::D, preserve_addr, as_FloatRegister(i), i * wordSize);
- }
-
- __ verify_thread();
-
- __ jmp(O0, 0);
- __ delayed()->restore();
-
- return start;
- }
-
-
// Support for uint StubRoutine::Sparc::partial_subtype_check( Klass sub, Klass super );
// Arguments :
//
@@ -5218,9 +5148,6 @@
StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError));
StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call));
- StubRoutines::_handler_for_unsafe_access_entry =
- generate_handler_for_unsafe_access();
-
// support for verify_oop (must happen after universe_init)
StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop_subroutine();
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp Wed May 11 00:38:58 2016 +0300
@@ -26,12 +26,12 @@
#include "interp_masm_x86.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
+#include "logging/log.hpp"
#include "oops/arrayOop.hpp"
#include "oops/markOop.hpp"
#include "oops/methodData.hpp"
#include "oops/method.hpp"
#include "prims/jvmtiExport.hpp"
-#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "prims/jvmtiThreadState.hpp"
#include "runtime/basicLock.hpp"
#include "runtime/biasedLocking.hpp"
@@ -1953,7 +1953,7 @@
}
// RedefineClasses() tracing support for obsolete method entry
- if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
+ if (log_is_enabled(Trace, redefine, class, obsolete)) {
NOT_LP64(get_thread(rthread);)
get_method(rarg);
call_VM_leaf(
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Wed May 11 00:38:58 2016 +0300
@@ -29,9 +29,9 @@
#include "code/icBuffer.hpp"
#include "code/vtableStubs.hpp"
#include "interpreter/interpreter.hpp"
+#include "logging/log.hpp"
#include "memory/resourceArea.hpp"
#include "oops/compiledICHolder.hpp"
-#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vframeArray.hpp"
#include "vmreg_x86.inline.hpp"
@@ -1953,7 +1953,7 @@
}
// RedefineClasses() tracing support for obsolete method entry
- if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
+ if (log_is_enabled(Trace, redefine, class, obsolete)) {
__ mov_metadata(rax, method());
__ call_VM_leaf(
CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry),
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Wed May 11 00:38:58 2016 +0300
@@ -32,9 +32,9 @@
#include "code/icBuffer.hpp"
#include "code/vtableStubs.hpp"
#include "interpreter/interpreter.hpp"
+#include "logging/log.hpp"
#include "memory/resourceArea.hpp"
#include "oops/compiledICHolder.hpp"
-#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vframeArray.hpp"
#include "vmreg_x86.inline.hpp"
@@ -2322,7 +2322,7 @@
}
// RedefineClasses() tracing support for obsolete method entry
- if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
+ if (log_is_enabled(Trace, redefine, class, obsolete)) {
// protect the args we've loaded
save_args(masm, total_c_args, c_arg, out_regs);
__ mov_metadata(c_rarg1, method());
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -63,21 +63,6 @@
// -------------------------------------------------------------------------------------------------------------------------
// Stub Code definitions
-static address handle_unsafe_access() {
- JavaThread* thread = JavaThread::current();
- address pc = thread->saved_exception_pc();
- // pc is the instruction which we must emulate
- // doing a no-op is fine: return garbage from the load
- // therefore, compute npc
- address npc = Assembler::locate_next_instruction(pc);
-
- // request an async exception
- thread->set_pending_unsafe_access_error();
-
- // return address of next instruction to execute
- return npc;
-}
-
class StubGenerator: public StubCodeGenerator {
private:
@@ -623,27 +608,6 @@
}
- //---------------------------------------------------------------------------
- // The following routine generates a subroutine to throw an asynchronous
- // UnknownError when an unsafe access gets a fault that could not be
- // reasonably prevented by the programmer. (Example: SIGBUS/OBJERR.)
- address generate_handler_for_unsafe_access() {
- StubCodeMark mark(this, "StubRoutines", "handler_for_unsafe_access");
- address start = __ pc();
-
- __ push(0); // hole for return address-to-be
- __ pusha(); // push registers
- Address next_pc(rsp, RegisterImpl::number_of_registers * BytesPerWord);
- BLOCK_COMMENT("call handle_unsafe_access");
- __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, handle_unsafe_access)));
- __ movptr(next_pc, rax); // stuff next address
- __ popa();
- __ ret(0); // jump to next address
-
- return start;
- }
-
-
//----------------------------------------------------------------------------------------------------
// Non-destructive plausibility checks for oops
@@ -3865,9 +3829,6 @@
// These are currently used by Solaris/Intel
StubRoutines::_atomic_xchg_entry = generate_atomic_xchg();
- StubRoutines::_handler_for_unsafe_access_entry =
- generate_handler_for_unsafe_access();
-
// platform dependent
create_control_words();
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -61,21 +61,6 @@
// Stub Code definitions
-static address handle_unsafe_access() {
- JavaThread* thread = JavaThread::current();
- address pc = thread->saved_exception_pc();
- // pc is the instruction which we must emulate
- // doing a no-op is fine: return garbage from the load
- // therefore, compute npc
- address npc = Assembler::locate_next_instruction(pc);
-
- // request an async exception
- thread->set_pending_unsafe_access_error();
-
- // return address of next instruction to execute
- return npc;
-}
-
class StubGenerator: public StubCodeGenerator {
private:
@@ -989,32 +974,6 @@
return start;
}
- // The following routine generates a subroutine to throw an
- // asynchronous UnknownError when an unsafe access gets a fault that
- // could not be reasonably prevented by the programmer. (Example:
- // SIGBUS/OBJERR.)
- address generate_handler_for_unsafe_access() {
- StubCodeMark mark(this, "StubRoutines", "handler_for_unsafe_access");
- address start = __ pc();
-
- __ push(0); // hole for return address-to-be
- __ pusha(); // push registers
- Address next_pc(rsp, RegisterImpl::number_of_registers * BytesPerWord);
-
- // FIXME: this probably needs alignment logic
-
- __ subptr(rsp, frame::arg_reg_save_area_bytes);
- BLOCK_COMMENT("call handle_unsafe_access");
- __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, handle_unsafe_access)));
- __ addptr(rsp, frame::arg_reg_save_area_bytes);
-
- __ movptr(next_pc, rax); // stuff next address
- __ popa();
- __ ret(0); // jump to next address
-
- return start;
- }
-
// Non-destructive plausibility checks for oops
//
// Arguments:
@@ -5139,9 +5098,6 @@
StubRoutines::_atomic_add_ptr_entry = generate_atomic_add_ptr();
StubRoutines::_fence_entry = generate_orderaccess_fence();
- StubRoutines::_handler_for_unsafe_access_entry =
- generate_handler_for_unsafe_access();
-
// platform dependent
StubRoutines::x86::_get_previous_fp_entry = generate_get_previous_fp();
StubRoutines::x86::_get_previous_sp_entry = generate_get_previous_sp();
--- a/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp Wed May 11 00:38:58 2016 +0300
@@ -31,7 +31,6 @@
#include "code/vtableStubs.hpp"
#include "interpreter/interpreter.hpp"
#include "oops/compiledICHolder.hpp"
-#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vframeArray.hpp"
#include "vmreg_zero.inline.hpp"
--- a/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007, 2008, 2010, 2015 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -261,10 +261,6 @@
StubRoutines::_atomic_add_entry = ShouldNotCallThisStub();
StubRoutines::_atomic_add_ptr_entry = ShouldNotCallThisStub();
StubRoutines::_fence_entry = ShouldNotCallThisStub();
-
- // amd64 does this here, sparc does it in generate_all()
- StubRoutines::_handler_for_unsafe_access_entry =
- ShouldNotCallThisStub();
}
void generate_all() {
--- a/hotspot/src/os/posix/vm/os_posix.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/os/posix/vm/os_posix.cpp Wed May 11 00:38:58 2016 +0300
@@ -47,6 +47,12 @@
// Check core dump limit and report possible place where core can be found
void os::check_dump_limit(char* buffer, size_t bufferSize) {
+ if (!FLAG_IS_DEFAULT(CreateCoredumpOnCrash) && !CreateCoredumpOnCrash) {
+ jio_snprintf(buffer, bufferSize, "CreateCoredumpOnCrash is disabled from command line");
+ VMError::record_coredump_status(buffer, false);
+ return;
+ }
+
int n;
struct rlimit rlim;
bool success;
--- a/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp Wed May 11 00:38:58 2016 +0300
@@ -392,11 +392,9 @@
CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
CompiledMethod* nm = cb->as_compiled_method_or_null();
if (nm != NULL && nm->has_unsafe_access()) {
- // We don't really need a stub here! Just set the pending exeption and
- // continue at the next instruction after the faulting read. Returning
- // garbage from this read is ok.
- thread->set_pending_unsafe_access_error();
- os::Aix::ucontext_set_pc(uc, pc + 4);
+ address next_pc = pc + 4;
+ next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc);
+ os::Aix::ucontext_set_pc(uc, next_pc);
return 1;
}
}
@@ -415,11 +413,9 @@
}
else if (thread->thread_state() == _thread_in_vm &&
sig == SIGBUS && thread->doing_unsafe_access()) {
- // We don't really need a stub here! Just set the pending exeption and
- // continue at the next instruction after the faulting read. Returning
- // garbage from this read is ok.
- thread->set_pending_unsafe_access_error();
- os::Aix::ucontext_set_pc(uc, pc + 4);
+ address next_pc = pc + 4;
+ next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc);
+ os::Aix::ucontext_set_pc(uc, next_pc);
return 1;
}
}
--- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Wed May 11 00:38:58 2016 +0300
@@ -584,7 +584,8 @@
CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
if (nm != NULL && nm->has_unsafe_access()) {
- stub = StubRoutines::handler_for_unsafe_access();
+ address next_pc = Assembler::locate_next_instruction(pc);
+ stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
}
}
else
@@ -655,7 +656,8 @@
} else if (thread->thread_state() == _thread_in_vm &&
sig == SIGBUS && /* info->si_code == BUS_OBJERR && */
thread->doing_unsafe_access()) {
- stub = StubRoutines::handler_for_unsafe_access();
+ address next_pc = Assembler::locate_next_instruction(pc);
+ stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
}
// jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in
--- a/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp Wed May 11 00:38:58 2016 +0300
@@ -226,23 +226,6 @@
extern "C" void FetchNResume () ;
#endif
-// An operation in Unsafe has faulted. We're going to return to the
-// instruction after the faulting load or store. We also set
-// pending_unsafe_access_error so that at some point in the future our
-// user will get a helpful message.
-static address handle_unsafe_access(JavaThread* thread, address pc) {
- // pc is the instruction which we must emulate
- // doing a no-op is fine: return garbage from the load
- // therefore, compute npc
- address npc = pc + NativeCall::instruction_size;
-
- // request an async exception
- thread->set_pending_unsafe_access_error();
-
- // return address of next instruction to execute
- return npc;
-}
-
extern "C" JNIEXPORT int
JVM_handle_linux_signal(int sig,
siginfo_t* info,
@@ -387,7 +370,8 @@
CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
if (nm != NULL && nm->has_unsafe_access()) {
- stub = handle_unsafe_access(thread, pc);
+ address next_pc = pc + NativeCall::instruction_size;
+ stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
}
}
else
@@ -408,7 +392,8 @@
} else if (thread->thread_state() == _thread_in_vm &&
sig == SIGBUS && /* info->si_code == BUS_OBJERR && */
thread->doing_unsafe_access()) {
- stub = handle_unsafe_access(thread, pc);
+ address next_pc = pc + NativeCall::instruction_size;
+ stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
}
// jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in
--- a/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp Wed May 11 00:38:58 2016 +0300
@@ -366,11 +366,9 @@
CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
if (nm != NULL && nm->has_unsafe_access()) {
- // We don't really need a stub here! Just set the pending exeption and
- // continue at the next instruction after the faulting read. Returning
- // garbage from this read is ok.
- thread->set_pending_unsafe_access_error();
- os::Linux::ucontext_set_pc(uc, pc + 4);
+ address next_pc = pc + 4;
+ next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc);
+ os::Linux::ucontext_set_pc(uc, next_pc);
return true;
}
}
@@ -385,10 +383,8 @@
}
else if (thread->thread_state() == _thread_in_vm &&
sig == SIGBUS && thread->doing_unsafe_access()) {
- // We don't really need a stub here! Just set the pending exeption and
- // continue at the next instruction after the faulting read. Returning
- // garbage from this read is ok.
- thread->set_pending_unsafe_access_error();
+ address next_pc = pc + 4;
+ next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc);
os::Linux::ucontext_set_pc(uc, pc + 4);
return true;
}
--- a/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Wed May 11 00:38:58 2016 +0300
@@ -433,14 +433,14 @@
return false;
}
-inline static bool checkByteBuffer(address pc, address* stub) {
+inline static bool checkByteBuffer(address pc, address npc, address* stub) {
// BugId 4454115: A read from a MappedByteBuffer can fault
// here if the underlying file has been truncated.
// Do not crash the VM in such a case.
CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
CompiledMethod* nm = cb->as_compiled_method_or_null();
if (nm != NULL && nm->has_unsafe_access()) {
- *stub = StubRoutines::handler_for_unsafe_access();
+ *stub = SharedRuntime::handle_unsafe_access(thread, npc);
return true;
}
return false;
@@ -613,7 +613,7 @@
if (sig == SIGBUS &&
thread->thread_state() == _thread_in_vm &&
thread->doing_unsafe_access()) {
- stub = StubRoutines::handler_for_unsafe_access();
+ stub = SharedRuntime::handle_unsafe_access(thread, npc);
}
if (thread->thread_state() == _thread_in_Java) {
@@ -625,7 +625,7 @@
break;
}
- if ((sig == SIGBUS) && checkByteBuffer(pc, &stub)) {
+ if ((sig == SIGBUS) && checkByteBuffer(pc, npc, &stub)) {
break;
}
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Wed May 11 00:38:58 2016 +0300
@@ -420,7 +420,8 @@
CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
if (nm != NULL && nm->has_unsafe_access()) {
- stub = StubRoutines::handler_for_unsafe_access();
+ address next_pc = Assembler::locate_next_instruction(pc);
+ stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
}
}
else
@@ -469,7 +470,8 @@
} else if (thread->thread_state() == _thread_in_vm &&
sig == SIGBUS && /* info->si_code == BUS_OBJERR && */
thread->doing_unsafe_access()) {
- stub = StubRoutines::handler_for_unsafe_access();
+ address next_pc = Assembler::locate_next_instruction(pc);
+ stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
}
// jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in
--- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Wed May 11 00:38:58 2016 +0300
@@ -441,7 +441,7 @@
if (thread->thread_state() == _thread_in_vm) {
if (sig == SIGBUS && info->si_code == BUS_OBJERR && thread->doing_unsafe_access()) {
- stub = StubRoutines::handler_for_unsafe_access();
+ stub = SharedRuntime::handle_unsafe_access(thread, npc);
}
}
@@ -480,7 +480,7 @@
CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
CompiledMethod* nm = cb->as_compiled_method_or_null();
if (nm != NULL && nm->has_unsafe_access()) {
- stub = StubRoutines::handler_for_unsafe_access();
+ stub = SharedRuntime::handle_unsafe_access(thread, npc);
}
}
--- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Wed May 11 00:38:58 2016 +0300
@@ -503,7 +503,8 @@
if (thread->thread_state() == _thread_in_vm) {
if (sig == SIGBUS && info->si_code == BUS_OBJERR && thread->doing_unsafe_access()) {
- stub = StubRoutines::handler_for_unsafe_access();
+ address next_pc = Assembler::locate_next_instruction(pc);
+ stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
}
}
@@ -520,7 +521,8 @@
if (cb != NULL) {
CompiledMethod* nm = cb->as_compiled_method_or_null();
if (nm != NULL && nm->has_unsafe_access()) {
- stub = StubRoutines::handler_for_unsafe_access();
+ address next_pc = Assembler::locate_next_instruction(pc);
+ stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
}
}
}
--- a/hotspot/src/share/tools/ProjectCreator/ArgsParser.java Tue May 10 12:18:22 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-class ArgIterator {
- String[] args;
- int i;
- ArgIterator(String[] args) {
- this.args = args;
- this.i = 0;
- }
- String get() { return args[i]; }
- boolean hasMore() { return args != null && i < args.length; }
- boolean next() { return ++i < args.length; }
-}
-
-abstract class ArgHandler {
- public abstract void handle(ArgIterator it);
-
-}
-
-class ArgRule {
- String arg;
- ArgHandler handler;
- ArgRule(String arg, ArgHandler handler) {
- this.arg = arg;
- this.handler = handler;
- }
-
- boolean process(ArgIterator it) {
- if (match(it.get(), arg)) {
- handler.handle(it);
- return true;
- }
- return false;
- }
- boolean match(String rule_pattern, String arg) {
- return arg.equals(rule_pattern);
- }
-}
-
-class ArgsParser {
- ArgsParser(String[] args,
- ArgRule[] rules,
- ArgHandler defaulter) {
- ArgIterator ai = new ArgIterator(args);
- while (ai.hasMore()) {
- boolean processed = false;
- for (int i=0; i<rules.length; i++) {
- processed |= rules[i].process(ai);
- if (processed) {
- break;
- }
- }
- if (!processed) {
- if (defaulter != null) {
- defaulter.handle(ai);
- } else {
- System.err.println("ERROR: unparsed \""+ai.get()+"\"");
- ai.next();
- }
- }
- }
- }
-}
--- a/hotspot/src/share/tools/ProjectCreator/BuildConfig.java Tue May 10 12:18:22 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,617 +0,0 @@
-/*
- * Copyright (c) 2005, 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.
- *
- */
-
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Vector;
-
-class BuildConfig {
- @SuppressWarnings("rawtypes")
- Hashtable vars;
- Vector<String> basicNames, basicPaths;
- String[] context;
-
- static CompilerInterface ci;
- static CompilerInterface getCI() {
- if (ci == null) {
- String comp = (String)getField(null, "CompilerVersion");
- try {
- ci = (CompilerInterface)Class.forName("CompilerInterface" + comp).newInstance();
- } catch (Exception cnfe) {
- System.err.println("Cannot find support for compiler " + comp);
- throw new RuntimeException(cnfe.toString());
- }
- }
- return ci;
- }
-
- @SuppressWarnings("rawtypes")
- protected void initNames(String flavour, String build, String outDll) {
- if (vars == null) vars = new Hashtable();
-
- String flavourBuild = flavour + "_" + build;
- String platformName = getFieldString(null, "PlatformName");
- System.out.println();
- System.out.println(flavourBuild);
-
- put("Name", getCI().makeCfgName(flavourBuild, platformName));
- put("Flavour", flavour);
- put("Build", build);
- put("PlatformName", platformName);
-
- // ones mentioned above were needed to expand format
- String buildBase = expandFormat(getFieldString(null, "BuildBase"));
- String sourceBase = getFieldString(null, "SourceBase");
- String buildSpace = getFieldString(null, "BuildSpace");
- String outDir = buildBase;
- String jdkTargetRoot = getFieldString(null, "JdkTargetRoot");
-
- put("Id", flavourBuild);
- put("OutputDir", outDir);
- put("SourceBase", sourceBase);
- put("BuildBase", buildBase);
- put("BuildSpace", buildSpace);
- put("OutputDll", outDir + Util.sep + outDll);
- put("JdkTargetRoot", jdkTargetRoot);
-
- context = new String [] {flavourBuild, flavour, build, null};
- }
-
- protected void init(Vector<String> includes, Vector<String> defines) {
- initDefaultDefines(defines);
- initDefaultCompilerFlags(includes);
- initDefaultLinkerFlags();
- //handleDB();
- }
-
-
- protected void initDefaultCompilerFlags(Vector<String> includes) {
- Vector compilerFlags = new Vector();
-
- compilerFlags.addAll(getCI().getBaseCompilerFlags(getV("Define"),
- includes,
- get("OutputDir")));
-
- put("CompilerFlags", compilerFlags);
- }
-
- protected void initDefaultLinkerFlags() {
- Vector linkerFlags = new Vector();
-
- linkerFlags.addAll(getCI().getBaseLinkerFlags( get("OutputDir"), get("OutputDll"), get("PlatformName")));
-
- put("LinkerFlags", linkerFlags);
- }
-
- public boolean matchesIgnoredPath(String path) {
- Vector<String> rv = new Vector<String>();
- collectRelevantVectors(rv, "IgnorePath");
- for (String pathPart : rv) {
- if (path.contains(pathPart)) {
- return true;
- }
- }
- return false;
- }
-
- public boolean matchesHidePath(String path) {
- Vector<String> rv = new Vector<String>();
- collectRelevantVectors(rv, "HidePath");
- for (String pathPart : rv) {
- if (path.contains(Util.normalize(pathPart))) {
- return true;
- }
- }
- return false;
- }
-
- public Vector<String> matchesAdditionalGeneratedPath(String fullPath) {
- Vector<String> rv = new Vector<String>();
- Hashtable<String, String> v = (Hashtable<String, String>)BuildConfig.getField(this.toString(), "AdditionalGeneratedFile");
- if (v != null) {
- for (Enumeration<String> e=v.keys(); e.hasMoreElements(); ) {
- String key = e.nextElement();
- String val = v.get(key);
-
- if (fullPath.endsWith(expandFormat(key))) {
- rv.add(expandFormat(val));
- }
- }
- }
- return rv;
- }
-
- // Returns true if the specified path refers to a relative alternate
- // source file. RelativeAltSrcInclude is usually "src\closed".
- public static boolean matchesRelativeAltSrcInclude(String path) {
- String relativeAltSrcInclude =
- getFieldString(null, "RelativeAltSrcInclude");
- Vector<String> v = getFieldVector(null, "AltRelativeInclude");
- for (String pathPart : v) {
- if (path.contains(relativeAltSrcInclude + Util.sep + pathPart)) {
- return true;
- }
- }
- return false;
- }
-
- // Returns the relative alternate source file for the specified path.
- // Null is returned if the specified path does not have a matching
- // alternate source file.
- public static String getMatchingRelativeAltSrcFile(String path) {
- Vector<String> v = getFieldVector(null, "RelativeAltSrcFileList");
- if (v == null) {
- return null;
- }
- for (String pathPart : v) {
- if (path.endsWith(pathPart)) {
- String relativeAltSrcInclude =
- getFieldString(null, "RelativeAltSrcInclude");
- return relativeAltSrcInclude + Util.sep + pathPart;
- }
- }
- return null;
- }
-
- // Returns true if the specified path has a matching alternate
- // source file.
- public static boolean matchesRelativeAltSrcFile(String path) {
- return getMatchingRelativeAltSrcFile(path) != null;
- }
-
- // Track the specified alternate source file. The source file is
- // tracked without the leading .*<sep><RelativeAltSrcFileList><sep>
- // part to make matching regular source files easier.
- public static void trackRelativeAltSrcFile(String path) {
- String pattern = getFieldString(null, "RelativeAltSrcInclude") +
- Util.sep;
- int altSrcInd = path.indexOf(pattern);
- if (altSrcInd == -1) {
- // not an AltSrc path
- return;
- }
-
- altSrcInd += pattern.length();
- if (altSrcInd >= path.length()) {
- // not a valid AltSrc path
- return;
- }
-
- String altSrcFile = path.substring(altSrcInd);
- Vector v = getFieldVector(null, "RelativeAltSrcFileList");
- if (v == null || !v.contains(altSrcFile)) {
- addFieldVector(null, "RelativeAltSrcFileList", altSrcFile);
- }
- }
-
- void addTo(Hashtable ht, String key, String value) {
- ht.put(expandFormat(key), expandFormat(value));
- }
-
- void initDefaultDefines(Vector defines) {
- Vector sysDefines = new Vector();
- sysDefines.add("WIN32");
- sysDefines.add("_WINDOWS");
- sysDefines.add("HOTSPOT_BUILD_USER=\\\""+System.getProperty("user.name")+"\\\"");
- sysDefines.add("HOTSPOT_BUILD_TARGET=\\\""+get("Build")+"\\\"");
- sysDefines.add("INCLUDE_TRACE=1");
- sysDefines.add("_JNI_IMPLEMENTATION_");
- if (vars.get("PlatformName").equals("Win32")) {
- sysDefines.add("HOTSPOT_LIB_ARCH=\\\"i386\\\"");
- } else {
- sysDefines.add("HOTSPOT_LIB_ARCH=\\\"amd64\\\"");
- }
- sysDefines.add("DEBUG_LEVEL=\\\"" + get("Build")+"\\\"");
- sysDefines.addAll(defines);
-
- put("Define", sysDefines);
- }
-
- String get(String key) {
- return (String)vars.get(key);
- }
-
- Vector getV(String key) {
- return (Vector)vars.get(key);
- }
-
- Object getO(String key) {
- return vars.get(key);
- }
-
- Hashtable getH(String key) {
- return (Hashtable)vars.get(key);
- }
-
- Object getFieldInContext(String field) {
- for (int i=0; i<context.length; i++) {
- Object rv = getField(context[i], field);
- if (rv != null) {
- return rv;
- }
- }
- return null;
- }
-
- Object lookupHashFieldInContext(String field, String key) {
- for (int i=0; i<context.length; i++) {
- Hashtable ht = (Hashtable)getField(context[i], field);
- if (ht != null) {
- Object rv = ht.get(key);
- if (rv != null) {
- return rv;
- }
- }
- }
- return null;
- }
-
- void put(String key, String value) {
- vars.put(key, value);
- }
-
- void put(String key, Vector vvalue) {
- vars.put(key, vvalue);
- }
-
- void add(String key, Vector vvalue) {
- getV(key).addAll(vvalue);
- }
-
- String flavour() {
- return get("Flavour");
- }
-
- String build() {
- return get("Build");
- }
-
- Object getSpecificField(String field) {
- return getField(get("Id"), field);
- }
-
- void putSpecificField(String field, Object value) {
- putField(get("Id"), field, value);
- }
-
- void collectRelevantVectors(Vector rv, String field) {
- for (String ctx : context) {
- Vector<String> v = getFieldVector(ctx, field);
- if (v != null) {
- for (String val : v) {
- rv.add(expandFormat(val).replace('/', '\\'));
- }
- }
- }
- }
-
- void collectRelevantHashes(Hashtable rv, String field) {
- for (String ctx : context) {
- Hashtable v = (Hashtable)getField(ctx, field);
- if (v != null) {
- for (Enumeration e=v.keys(); e.hasMoreElements(); ) {
- String key = (String)e.nextElement();
- String val = (String)v.get(key);
- addTo(rv, key, val);
- }
- }
- }
- }
-
-
- Vector getDefines() {
- Vector rv = new Vector();
- collectRelevantVectors(rv, "Define");
- return rv;
- }
-
- Vector getIncludes() {
- Vector rv = new Vector();
- collectRelevantVectors(rv, "AbsoluteInclude");
- rv.addAll(getSourceIncludes());
- return rv;
- }
-
- private Vector getSourceIncludes() {
- Vector<String> rv = new Vector<String>();
- String sourceBase = getFieldString(null, "SourceBase");
-
- // add relative alternate source include values:
- String relativeAltSrcInclude =
- getFieldString(null, "RelativeAltSrcInclude");
- Vector<String> asri = new Vector<String>();
- collectRelevantVectors(asri, "AltRelativeInclude");
- for (String f : asri) {
- rv.add(sourceBase + Util.sep + relativeAltSrcInclude +
- Util.sep + f);
- }
-
- Vector<String> ri = new Vector<String>();
- collectRelevantVectors(ri, "RelativeInclude");
- for (String f : ri) {
- rv.add(sourceBase + Util.sep + f);
- }
- return rv;
- }
-
- static Hashtable cfgData = new Hashtable();
- static Hashtable globalData = new Hashtable();
-
- static boolean appliesToTieredBuild(String cfg) {
- return (cfg != null &&
- (cfg.startsWith("compiler1") ||
- cfg.startsWith("compiler2")));
- }
-
- // Filters out the IgnoreFile and IgnorePaths since they are
- // handled specially for tiered builds.
- static boolean appliesToTieredBuild(String cfg, String key) {
- return (appliesToTieredBuild(cfg))&& (key != null && !key.startsWith("Ignore"));
- }
-
- static String getTieredBuildCfg(String cfg) {
- assert appliesToTieredBuild(cfg) : "illegal configuration " + cfg;
- return "tiered" + cfg.substring(9);
- }
-
- static Object getField(String cfg, String field) {
- if (cfg == null) {
- return globalData.get(field);
- }
-
- Hashtable ht = (Hashtable)cfgData.get(cfg);
- return ht == null ? null : ht.get(field);
- }
-
- static String getFieldString(String cfg, String field) {
- return (String)getField(cfg, field);
- }
-
- static Vector getFieldVector(String cfg, String field) {
- return (Vector)getField(cfg, field);
- }
-
- static void putField(String cfg, String field, Object value) {
- putFieldImpl(cfg, field, value);
- if (appliesToTieredBuild(cfg, field)) {
- putFieldImpl(getTieredBuildCfg(cfg), field, value);
- }
- }
-
- private static void putFieldImpl(String cfg, String field, Object value) {
- if (cfg == null) {
- globalData.put(field, value);
- return;
- }
-
- Hashtable ht = (Hashtable)cfgData.get(cfg);
- if (ht == null) {
- ht = new Hashtable();
- cfgData.put(cfg, ht);
- }
-
- ht.put(field, value);
- }
-
- static Object getFieldHash(String cfg, String field, String name) {
- Hashtable ht = (Hashtable)getField(cfg, field);
-
- return ht == null ? null : ht.get(name);
- }
-
- static void putFieldHash(String cfg, String field, String name, Object val) {
- putFieldHashImpl(cfg, field, name, val);
- if (appliesToTieredBuild(cfg, field)) {
- putFieldHashImpl(getTieredBuildCfg(cfg), field, name, val);
- }
- }
-
- private static void putFieldHashImpl(String cfg, String field, String name, Object val) {
- Hashtable ht = (Hashtable)getField(cfg, field);
-
- if (ht == null) {
- ht = new Hashtable();
- putFieldImpl(cfg, field, ht);
- }
-
- ht.put(name, val);
- }
-
- static void addFieldVector(String cfg, String field, String element) {
- addFieldVectorImpl(cfg, field, element);
- if (appliesToTieredBuild(cfg, field)) {
- addFieldVectorImpl(getTieredBuildCfg(cfg), field, element);
- }
- }
-
- private static void addFieldVectorImpl(String cfg, String field, String element) {
- Vector v = (Vector)getField(cfg, field);
-
- if (v == null) {
- v = new Vector();
- putFieldImpl(cfg, field, v);
- }
-
- v.add(element);
- }
-
- String expandFormat(String format) {
- if (format == null) {
- return null;
- }
-
- if (format.indexOf('%') == -1) {
- return format;
- }
-
- StringBuffer sb = new StringBuffer();
- int len = format.length();
- for (int i=0; i<len; i++) {
- char ch = format.charAt(i);
- if (ch == '%') {
- char ch1 = format.charAt(i+1);
- switch (ch1) {
- case '%':
- sb.append(ch1);
- break;
- case 'b':
- sb.append(build());
- break;
- case 'f':
- sb.append(flavour());
- break;
- default:
- sb.append(ch);
- sb.append(ch1);
- }
- i++;
- } else {
- sb.append(ch);
- }
- }
-
- return sb.toString();
- }
-}
-
-abstract class GenericDebugConfig extends BuildConfig {
- abstract String getOptFlag();
-
- protected void init(Vector includes, Vector defines) {
- defines.add("_DEBUG");
- defines.add("ASSERT");
-
- super.init(includes, defines);
-
- getV("CompilerFlags").addAll(getCI().getDebugCompilerFlags(getOptFlag(), get("PlatformName")));
- getV("LinkerFlags").addAll(getCI().getDebugLinkerFlags());
- }
-}
-
-abstract class GenericDebugNonKernelConfig extends GenericDebugConfig {
- protected void init(Vector includes, Vector defines) {
- super.init(includes, defines);
- if (get("PlatformName").equals("Win32")) {
- getCI().getAdditionalNonKernelLinkerFlags(getV("LinkerFlags"));
- }
- }
-}
-
-class C1DebugConfig extends GenericDebugNonKernelConfig {
- String getOptFlag() {
- return getCI().getNoOptFlag();
- }
-
- C1DebugConfig() {
- initNames("compiler1", "debug", "jvm.dll");
- init(getIncludes(), getDefines());
- }
-}
-
-class C1FastDebugConfig extends GenericDebugNonKernelConfig {
- String getOptFlag() {
- return getCI().getOptFlag();
- }
-
- C1FastDebugConfig() {
- initNames("compiler1", "fastdebug", "jvm.dll");
- init(getIncludes(), getDefines());
- }
-}
-
-class TieredDebugConfig extends GenericDebugNonKernelConfig {
- String getOptFlag() {
- return getCI().getNoOptFlag();
- }
-
- TieredDebugConfig() {
- initNames("tiered", "debug", "jvm.dll");
- init(getIncludes(), getDefines());
- }
-}
-
-class TieredFastDebugConfig extends GenericDebugNonKernelConfig {
- String getOptFlag() {
- return getCI().getOptFlag();
- }
-
- TieredFastDebugConfig() {
- initNames("tiered", "fastdebug", "jvm.dll");
- init(getIncludes(), getDefines());
- }
-}
-
-abstract class ProductConfig extends BuildConfig {
- protected void init(Vector includes, Vector defines) {
- defines.add("NDEBUG");
- defines.add("PRODUCT");
-
- super.init(includes, defines);
-
- getV("CompilerFlags").addAll(getCI().getProductCompilerFlags());
- getV("LinkerFlags").addAll(getCI().getProductLinkerFlags());
- }
-}
-
-class C1ProductConfig extends ProductConfig {
- C1ProductConfig() {
- initNames("compiler1", "product", "jvm.dll");
- init(getIncludes(), getDefines());
- }
-}
-
-class TieredProductConfig extends ProductConfig {
- TieredProductConfig() {
- initNames("tiered", "product", "jvm.dll");
- init(getIncludes(), getDefines());
- }
-}
-
-
-abstract class CompilerInterface {
- abstract Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir);
- abstract Vector getBaseLinkerFlags(String outDir, String outDll, String platformName);
- abstract Vector getDebugCompilerFlags(String opt, String platformName);
- abstract Vector getDebugLinkerFlags();
- abstract void getAdditionalNonKernelLinkerFlags(Vector rv);
- abstract Vector getProductCompilerFlags();
- abstract Vector getProductLinkerFlags();
- abstract String getOptFlag();
- abstract String getNoOptFlag();
- abstract String makeCfgName(String flavourBuild, String platformName);
-
- void addAttr(Vector receiver, String attr, String value) {
- receiver.add(attr); receiver.add(value);
- }
- void extAttr(Vector receiver, String attr, String value) {
- int attr_pos=receiver.indexOf(attr) ;
- if ( attr_pos == -1) {
- // If attr IS NOT present in the Vector - add it
- receiver.add(attr); receiver.add(value);
- } else {
- // If attr IS present in the Vector - append value to it
- receiver.set(attr_pos+1,receiver.get(attr_pos+1)+value);
- }
- }
-}
--- a/hotspot/src/share/tools/ProjectCreator/FileTreeCreator.java Tue May 10 12:18:22 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-import java.nio.file.FileSystems;
-import java.nio.file.Path;
-import java.nio.file.SimpleFileVisitor;
-import java.util.HashSet;
-import java.util.Stack;
-import java.util.Vector;
-
-public class FileTreeCreator extends SimpleFileVisitor<Path>
-{
- Path vcProjLocation;
- Path startDir;
- final int startDirLength;
- Stack<DirAttributes> attributes = new Stack<DirAttributes>();
- Vector<BuildConfig> allConfigs;
- WinGammaPlatform wg;
- WinGammaPlatformVC10 wg10;
-
- public FileTreeCreator(Path startDir, Vector<BuildConfig> allConfigs, WinGammaPlatform wg) {
- super();
- this.wg = wg;
- if (wg instanceof WinGammaPlatformVC10) {
- wg10 = (WinGammaPlatformVC10)wg;
- }
- this.allConfigs = allConfigs;
- this.startDir = startDir;
- startDirLength = startDir.toAbsolutePath().toString().length();
- vcProjLocation = FileSystems.getDefault().getPath(allConfigs.firstElement().get("BuildSpace"));
- attributes.push(new DirAttributes());
- }
-
- public class DirAttributes {
-
- private HashSet<BuildConfig> ignores;
- private HashSet<BuildConfig> disablePch;
-
- public DirAttributes() {
- ignores = new HashSet<BuildConfig>();
- disablePch = new HashSet<BuildConfig>();
- }
-
- public DirAttributes(HashSet<BuildConfig> excludes2, HashSet<BuildConfig> disablePch2) {
- ignores = excludes2;
- disablePch = disablePch2;
- }
-
- @SuppressWarnings("unchecked")
- public DirAttributes clone() {
- return new DirAttributes((HashSet<BuildConfig>)this.ignores.clone(), (HashSet<BuildConfig>)this.disablePch.clone());
- }
-
- public void setIgnore(BuildConfig conf) {
- ignores.add(conf);
- }
-
- public boolean hasIgnore(BuildConfig cfg) {
- return ignores.contains(cfg);
- }
-
- public void removeFromIgnored(BuildConfig cfg) {
- ignores.remove(cfg);
- }
-
- public void setDisablePch(BuildConfig conf) {
- disablePch.add(conf);
- }
-
- public boolean hasDisablePch(BuildConfig cfg) {
- return disablePch.contains(cfg);
- }
-
- public void removeFromDisablePch(BuildConfig cfg) {
- disablePch.remove(cfg);
- }
-
- }
-}
--- a/hotspot/src/share/tools/ProjectCreator/FileTreeCreatorVC10.java Tue May 10 12:18:22 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,190 +0,0 @@
-/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-import static java.nio.file.FileVisitResult.CONTINUE;
-
-import java.io.IOException;
-import java.nio.file.FileSystems;
-import java.nio.file.FileVisitResult;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.util.Stack;
-import java.util.Vector;
-
-public class FileTreeCreatorVC10 extends FileTreeCreator {
-
- public FileTreeCreatorVC10(Path startDir, Vector<BuildConfig> allConfigs, WinGammaPlatformVC10 wg) {
- super(startDir, allConfigs, wg);
- }
-
- @Override
- public FileVisitResult visitFile(Path file, BasicFileAttributes attr) {
- DirAttributes currentFileAttr = attributes.peek().clone();
- boolean usePch = false;
- boolean disablePch = false;
- boolean useIgnore = false;
- boolean isAltSrc = false; // only needed as a debugging crumb
- boolean isReplacedByAltSrc = false;
- String fileName = file.getFileName().toString();
-
- // TODO hideFile
-
- // usePch applies to all configs for a file.
- if (fileName.equals(BuildConfig.getFieldString(null, "UseToGeneratePch"))) {
- usePch = true;
- }
-
- String fileLoc = vcProjLocation.relativize(file).toString();
-
- // isAltSrc and isReplacedByAltSrc applies to all configs for a file
- if (BuildConfig.matchesRelativeAltSrcInclude(
- file.toAbsolutePath().toString())) {
- // current file is an alternate source file so track it
- isAltSrc = true;
- BuildConfig.trackRelativeAltSrcFile(
- file.toAbsolutePath().toString());
- } else if (BuildConfig.matchesRelativeAltSrcFile(
- file.toAbsolutePath().toString())) {
- // current file is a regular file that matches an alternate
- // source file so yack about replacing the regular file
- isReplacedByAltSrc = true;
- System.out.println("INFO: alternate source file '" +
- BuildConfig.getMatchingRelativeAltSrcFile(
- file.toAbsolutePath().toString()) +
- "' replaces '" + fileLoc + "'");
- }
-
- for (BuildConfig cfg : allConfigs) {
- if (cfg.lookupHashFieldInContext("IgnoreFile", fileName) != null) {
- useIgnore = true;
- currentFileAttr.setIgnore(cfg);
- } else if (cfg.matchesIgnoredPath(file.toAbsolutePath().toString())) {
- useIgnore = true;
- currentFileAttr.setIgnore(cfg);
- }
-
- if (cfg.lookupHashFieldInContext("DisablePch", fileName) != null) {
- disablePch = true;
- currentFileAttr.setDisablePch(cfg);
- }
-
- Vector<String> rv = new Vector<String>();
- cfg.collectRelevantVectors(rv, "AdditionalFile");
- for(String addFile : rv) {
- if (addFile.equals(fileName)) {
- // supress any ignore
- // TODO - may need some adjustments
- if (file.toAbsolutePath().toString().contains(cfg.get("Flavour"))) {
- currentFileAttr.removeFromIgnored(cfg);
- }
- }
- }
- }
-
- String tagName = wg10.getFileTagFromSuffix(fileName);
-
- if (!useIgnore && !disablePch && !usePch && !isReplacedByAltSrc) {
- wg.tag(tagName, new String[] { "Include", fileLoc});
- } else {
- wg.startTag(
- tagName,
- new String[] { "Include", fileLoc});
-
- for (BuildConfig cfg : allConfigs) {
- boolean ignore = currentFileAttr.hasIgnore(cfg);
- if (ignore) {
- wg.tagData("ExcludedFromBuild", "true", "Condition", "'$(Configuration)|$(Platform)'=='" + cfg.get("Name") + "'");
- }
- if (usePch) {
- wg.tagData("PrecompiledHeader", "Create", "Condition", "'$(Configuration)|$(Platform)'=='" + cfg.get("Name") + "'");
- }
- if (disablePch) {
- wg.tag("PrecompiledHeader", "Condition", "'$(Configuration)|$(Platform)'=='" + cfg.get("Name") + "'");
- }
- if (isReplacedByAltSrc) {
- wg.tagData("ExcludedFromBuild", "true", "Condition",
- "'$(Configuration)|$(Platform)'=='" +
- cfg.get("Name") + "'");
- }
- }
- wg.endTag();
- }
-
- String filter = startDir.relativize(file.getParent().toAbsolutePath()).toString();
- wg10.addFilterDependency(fileLoc, filter);
-
- return CONTINUE;
- }
-
- @Override
- public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes attrs)
- throws IOException {
- Boolean hide = false;
- // TODO remove attrs, if path is matched in this dir, then it is too in every subdir.
- // And we will check anyway
- DirAttributes newAttr = attributes.peek().clone();
-
- // check per config ignorePaths!
- for (BuildConfig cfg : allConfigs) {
- if (cfg.matchesIgnoredPath(path.toAbsolutePath().toString())) {
- newAttr.setIgnore(cfg);
- }
-
- // Hide is always on all configs. And additional files are never hiddden
- if (cfg.matchesHidePath(path.toAbsolutePath().toString())) {
- hide = true;
- break;
- }
- }
-
- if (!hide) {
- String name = startDir.relativize(path.toAbsolutePath()).toString();
- if (!"".equals(name)) {
- wg10.addFilter(name);
- }
-
- attributes.push(newAttr);
- return super.preVisitDirectory(path, attrs);
- } else {
- return FileVisitResult.SKIP_SUBTREE;
- }
- }
-
- @Override
- public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
- //end matching attributes set by ignorepath
- attributes.pop();
- return CONTINUE;
- }
-
- @Override
- public FileVisitResult visitFileFailed(Path file, IOException exc) {
- return CONTINUE;
- }
-
- public void writeFileTree() throws IOException {
- Files.walkFileTree(this.startDir, this);
- }
-}
--- a/hotspot/src/share/tools/ProjectCreator/ProjectCreator.java Tue May 10 12:18:22 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-public class ProjectCreator {
-
- public static void usage() {
- System.out.println("ProjectCreator options:");
- System.err.println("WinGammaPlatform platform-specific options:");
- System.err.println(" -sourceBase <path to directory (workspace) "
- + "containing source files; no trailing slash>");
- System.err.println(" -dspFileName <full pathname to which .dsp file "
- + "will be written; all parent directories must "
- + "already exist>");
- System.err.println(" -envVar <environment variable to be inserted "
- + "into .dsp file, substituting for path given in "
- + "-sourceBase. Example: HotSpotWorkSpace>");
- System.err.println(" -dllLoc <path to directory in which to put "
- + "jvm.dll; no trailing slash>");
- System.err.println(" If any of the above are specified, "
- + "they must all be.");
- System.err.println(" Note: if '-altRelativeInclude' option below is "
- + "used, then the '-relativeAltSrcInclude' option must be used "
- + "to specify the alternate source dir, e.g., 'src\\closed'");
- System.err.println(" Additional, optional arguments, which can be "
- + "specified multiple times:");
- System.err.println(" -absoluteInclude <string containing absolute "
- + "path to include directory>");
- System.err.println(" -altRelativeInclude <string containing "
- + "alternate include directory relative to -envVar>");
- System.err.println(" -relativeInclude <string containing include "
- + "directory relative to -envVar>");
- System.err.println(" -define <preprocessor flag to be #defined "
- + "(note: doesn't yet support " + "#define (flag) (value))>");
- System.err.println(" -perFileLine <file> <line>");
- System.err.println(" -conditionalPerFileLine <file> <line for "
- + "release build> <line for debug build>");
- System.err.println(" (NOTE: To work around a bug in nmake, where "
- + "you can't have a '#' character in a quoted "
- + "string, all of the lines outputted have \"#\"" + "prepended)");
- System.err.println(" -startAt <subdir of sourceBase>");
- System.err.println(" -ignoreFile <file which won't be able to be "
- + "found in the sourceBase because it's generated " + "later>");
- System.err.println(" -additionalFile <file not in database but "
- + "which should show up in .dsp file>");
- System.err
- .println(" -additionalGeneratedFile <environment variable of "
- + "generated file's location> <relative path to "
- + "directory containing file; no trailing slash> "
- + "<name of file generated later in the build process>");
- System.err.println(" -prelink <build> <desc> <cmds>:");
- System.err
- .println(" Generate a set of prelink commands for the given BUILD");
- System.err
- .println(" (\"Debug\" or \"Release\"). The prelink description and commands");
- System.err.println(" are both quoted strings.");
- System.err.println(" Default includes: \".\"");
- System.err
- .println(" Default defines: WIN32, _WINDOWS, \"HOTSPOT_BUILD_USER=$(USERNAME)\"");
- }
-
- public static void main(String[] args) {
- try {
- if (args.length < 3) {
- usage();
- System.exit(1);
- }
-
- String platformName = args[0];
- Class platformClass = Class.forName(platformName);
- WinGammaPlatform platform = (WinGammaPlatform) platformClass
- .newInstance();
-
- String[] platformArgs = new String[args.length - 1];
- System.arraycopy(args, 1, platformArgs, 0, platformArgs.length);
-
- // Allow the platform to write platform-specific files
- platform.createVcproj(platformArgs);
- } catch (Exception e) {
- e.printStackTrace();
- System.exit(1);
- }
- }
-}
--- a/hotspot/src/share/tools/ProjectCreator/Util.java Tue May 10 12:18:22 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-import java.util.*;
-import java.io.File;
-
-public class Util {
-
- static String join(String padder, Vector<String> v) {
- return join(padder, v, false);
- }
-
- static String join(String padder, Vector<String> v, boolean quoted) {
- StringBuffer sb = new StringBuffer();
-
- for (Iterator<String> iter = v.iterator(); iter.hasNext(); ) {
- if (quoted) {
- sb.append('"');
- }
- sb.append(iter.next());
- if (quoted) {
- sb.append('"');
- }
- if (iter.hasNext()) sb.append(padder);
- }
-
- return sb.toString();
- }
-
-
- static String prefixed_join(String padder, Vector<String> v, boolean quoted) {
- StringBuffer sb = new StringBuffer();
-
- for (Iterator<String> iter = v.iterator(); iter.hasNext(); ) {
- sb.append(padder);
-
- if (quoted) {
- sb.append('"');
- }
- sb.append((String)iter.next());
- if (quoted) {
- sb.append('"');
- }
- }
-
- return sb.toString();
- }
-
-
- static String normalize(String file) {
- file = file.replace('\\', '/');
- if (file.length() > 2) {
- if (file.charAt(1) == ':' && file.charAt(2) == '/') {
- // convert drive letter to uppercase
- String drive = file.substring(0, 1).toUpperCase();
- return drive + file.substring(1);
- }
- }
- return file;
- }
-
- static String sep = File.separator;
-}
--- a/hotspot/src/share/tools/ProjectCreator/WinGammaPlatform.java Tue May 10 12:18:22 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,675 +0,0 @@
-/*
- * Copyright (c) 1999, 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.
- *
- */
-
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.Stack;
-import java.util.Vector;
-
-abstract class HsArgHandler extends ArgHandler {
- static final int STRING = 1;
- static final int VECTOR = 2;
- static final int HASH = 3;
-
- boolean nextNotKey(ArgIterator it) {
- if (it.next()) {
- String s = it.get();
- return (s.length() == 0) || (s.charAt(0) != '-');
- } else {
- return false;
- }
- }
-
- void empty(String key, String message) {
- if (key != null) {
- System.err.println("** Error: empty " + key);
- }
- if (message != null) {
- System.err.println(message);
- }
- WinGammaPlatform.usage();
- }
-
- static String getCfg(String val) {
- int under = val.indexOf('_');
- int len = val.length();
- if (under != -1 && under < len - 1) {
- return val.substring(under+1, len);
- } else {
- return null;
- }
- }
-}
-
-class ArgRuleSpecific extends ArgRule {
- ArgRuleSpecific(String arg, ArgHandler handler) {
- super(arg, handler);
- }
-
- boolean match(String rulePattern, String arg) {
- return rulePattern.startsWith(arg);
- }
-}
-
-
-class SpecificHsArgHandler extends HsArgHandler {
-
- String message, argKey, valKey;
- int type;
-
- public void handle(ArgIterator it) {
- String cfg = getCfg(it.get());
- if (nextNotKey(it)) {
- String val = it.get();
- switch (type) {
- case VECTOR:
- BuildConfig.addFieldVector(cfg, valKey, val);
- break;
- case HASH:
- BuildConfig.putFieldHash(cfg, valKey, val, "1");
- break;
- case STRING:
- BuildConfig.putField(cfg, valKey, val);
- break;
- default:
- empty(valKey, "Unknown type: "+type);
- }
- it.next();
-
- } else {
- empty(argKey, message);
- }
- }
-
- SpecificHsArgHandler(String argKey, String valKey, String message, int type) {
- this.argKey = argKey;
- this.valKey = valKey;
- this.message = message;
- this.type = type;
- }
-}
-
-
-class HsArgRule extends ArgRuleSpecific {
-
- HsArgRule(String argKey, String valKey, String message, int type) {
- super(argKey, new SpecificHsArgHandler(argKey, valKey, message, type));
- }
-
-}
-
-public abstract class WinGammaPlatform {
-
- public boolean fileNameStringEquality(String s1, String s2) {
- return s1.equalsIgnoreCase(s2);
- }
-
- static void usage() throws IllegalArgumentException {
- System.err.println("WinGammaPlatform platform-specific options:");
- System.err.println(" -sourceBase <path to directory (workspace) " +
- "containing source files; no trailing slash>");
- System.err.println(" -projectFileName <full pathname to which project file " +
- "will be written; all parent directories must " +
- "already exist>");
- System.err.println(" If any of the above are specified, "+
- "they must all be.");
- System.err.println(" Note: if '-altRelativeInclude' option below " +
- "is used, then the '-relativeAltSrcInclude' " +
- "option must be used to specify the alternate " +
- "source dir, e.g., 'src\\closed'");
- System.err.println(" Additional, optional arguments, which can be " +
- "specified multiple times:");
- System.err.println(" -absoluteInclude <string containing absolute " +
- "path to include directory>");
- System.err.println(" -altRelativeInclude <string containing " +
- "alternate include directory relative to " +
- "-sourceBase>");
- System.err.println(" -relativeInclude <string containing include " +
- "directory relative to -sourceBase>");
- System.err.println(" -define <preprocessor flag to be #defined " +
- "(note: doesn't yet support " +
- "#define (flag) (value))>");
- System.err.println(" -startAt <subdir of sourceBase>");
- System.err.println(" -additionalFile <file not in database but " +
- "which should show up in project file>");
- System.err.println(" -additionalGeneratedFile <absolute path to " +
- "directory containing file; no trailing slash> " +
- "<name of file generated later in the build process>");
- throw new IllegalArgumentException();
- }
-
-
- public void addPerFileLine(Hashtable table,
- String fileName,
- String line) {
- Vector v = (Vector) table.get(fileName);
- if (v != null) {
- v.add(line);
- } else {
- v = new Vector();
- v.add(line);
- table.put(fileName, v);
- }
- }
-
- protected static class PerFileCondData {
- public String releaseString;
- public String debugString;
- }
-
- protected void addConditionalPerFileLine(Hashtable table,
- String fileName,
- String releaseLine,
- String debugLine) {
- PerFileCondData data = new PerFileCondData();
- data.releaseString = releaseLine;
- data.debugString = debugLine;
- Vector v = (Vector) table.get(fileName);
- if (v != null) {
- v.add(data);
- } else {
- v = new Vector();
- v.add(data);
- table.put(fileName, v);
- }
- }
-
- protected static class PrelinkCommandData {
- String description;
- String commands;
- }
-
- protected void addPrelinkCommand(Hashtable table,
- String build,
- String description,
- String commands) {
- PrelinkCommandData data = new PrelinkCommandData();
- data.description = description;
- data.commands = commands;
- table.put(build, data);
- }
-
- public boolean findString(Vector v, String s) {
- for (Iterator iter = v.iterator(); iter.hasNext(); ) {
- if (((String) iter.next()).equals(s)) {
- return true;
- }
- }
-
- return false;
- }
-
- String getProjectName(String fullPath, String extension)
- throws IllegalArgumentException, IOException {
- File file = new File(fullPath).getCanonicalFile();
- fullPath = file.getCanonicalPath();
- String parent = file.getParent();
-
- if (!fullPath.endsWith(extension)) {
- throw new IllegalArgumentException("project file name \"" +
- fullPath +
- "\" does not end in "+extension);
- }
-
- if ((parent != null) &&
- (!fullPath.startsWith(parent))) {
- throw new RuntimeException(
- "Internal error: parent of file name \"" + parent +
- "\" does not match file name \"" + fullPath + "\""
- );
- }
-
- int len = parent.length();
- if (!parent.endsWith(Util.sep)) {
- len += Util.sep.length();
- }
-
- int end = fullPath.length() - extension.length();
-
- if (len == end) {
- throw new RuntimeException(
- "Internal error: file name was empty"
- );
- }
-
- return fullPath.substring(len, end);
- }
-
- protected abstract String getProjectExt();
-
- public void createVcproj(String[] args)
- throws IllegalArgumentException, IOException {
-
- parseArguments(args);
-
- String projectFileName = BuildConfig.getFieldString(null, "ProjectFileName");
- String ext = getProjectExt();
-
- String projectName = getProjectName(projectFileName, ext);
-
- writeProjectFile(projectFileName, projectName, createAllConfigs(BuildConfig.getFieldString(null, "PlatformName")));
- }
-
- protected void writePrologue(String[] args) {
- System.err.println("WinGammaPlatform platform-specific arguments:");
- for (int i = 0; i < args.length; i++) {
- System.err.print(args[i] + " ");
- }
- System.err.println();
- }
-
-
- void parseArguments(String[] args) {
- new ArgsParser(args,
- new ArgRule[]
- {
- new ArgRule("-sourceBase",
- new HsArgHandler() {
- public void handle(ArgIterator it) {
- String cfg = getCfg(it.get());
- if (nextNotKey(it)) {
- String sb = (String) it.get();
- if (sb.endsWith(Util.sep)) {
- sb = sb.substring(0, sb.length() - 1);
- }
- BuildConfig.putField(cfg, "SourceBase", sb);
- it.next();
- } else {
- empty("-sourceBase", null);
- }
- }
- }
- ),
-
- new HsArgRule("-buildBase",
- "BuildBase",
- " (Did you set the HotSpotBuildSpace environment variable?)",
- HsArgHandler.STRING
- ),
-
- new HsArgRule("-buildSpace",
- "BuildSpace",
- null,
- HsArgHandler.STRING
- ),
-
- new HsArgRule("-platformName",
- "PlatformName",
- null,
- HsArgHandler.STRING
- ),
-
- new HsArgRule("-projectFileName",
- "ProjectFileName",
- null,
- HsArgHandler.STRING
- ),
-
- new HsArgRule("-jdkTargetRoot",
- "JdkTargetRoot",
- " (Did you set the HotSpotJDKDist environment variable?)",
- HsArgHandler.STRING
- ),
-
- new HsArgRule("-compiler",
- "CompilerVersion",
- " (Did you set the VcVersion correctly?)",
- HsArgHandler.STRING
- ),
-
- new HsArgRule("-absoluteInclude",
- "AbsoluteInclude",
- null,
- HsArgHandler.VECTOR
- ),
-
- new HsArgRule("-altRelativeInclude",
- "AltRelativeInclude",
- null,
- HsArgHandler.VECTOR
- ),
-
- new HsArgRule("-relativeInclude",
- "RelativeInclude",
- null,
- HsArgHandler.VECTOR
- ),
-
- new HsArgRule("-absoluteSrcInclude",
- "AbsoluteSrcInclude",
- null,
- HsArgHandler.VECTOR
- ),
-
- new HsArgRule("-relativeAltSrcInclude",
- "RelativeAltSrcInclude",
- null,
- HsArgHandler.STRING
- ),
-
- new HsArgRule("-relativeSrcInclude",
- "RelativeSrcInclude",
- null,
- HsArgHandler.VECTOR
- ),
-
- new HsArgRule("-define",
- "Define",
- null,
- HsArgHandler.VECTOR
- ),
-
- new HsArgRule("-useToGeneratePch",
- "UseToGeneratePch",
- null,
- HsArgHandler.STRING
- ),
-
- new ArgRuleSpecific("-perFileLine",
- new HsArgHandler() {
- public void handle(ArgIterator it) {
- String cfg = getCfg(it.get());
- if (nextNotKey(it)) {
- String fileName = it.get();
- if (nextNotKey(it)) {
- String line = it.get();
- BuildConfig.putFieldHash(cfg, "PerFileLine", fileName, line);
- it.next();
- return;
- }
- }
- empty(null, "** Error: wrong number of args to -perFileLine");
- }
- }
- ),
-
- new ArgRuleSpecific("-conditionalPerFileLine",
- new HsArgHandler() {
- public void handle(ArgIterator it) {
- String cfg = getCfg(it.get());
- if (nextNotKey(it)) {
- String fileName = it.get();
- if (nextNotKey(it)) {
- String productLine = it.get();
- if (nextNotKey(it)) {
- String debugLine = it.get();
- BuildConfig.putFieldHash(cfg+"_debug", "CondPerFileLine",
- fileName, debugLine);
- BuildConfig.putFieldHash(cfg+"_product", "CondPerFileLine",
- fileName, productLine);
- it.next();
- return;
- }
- }
- }
-
- empty(null, "** Error: wrong number of args to -conditionalPerFileLine");
- }
- }
- ),
-
- new HsArgRule("-disablePch",
- "DisablePch",
- null,
- HsArgHandler.HASH
- ),
-
- new ArgRule("-startAt",
- new HsArgHandler() {
- public void handle(ArgIterator it) {
- if (BuildConfig.getField(null, "StartAt") != null) {
- empty(null, "** Error: multiple -startAt");
- }
- if (nextNotKey(it)) {
- BuildConfig.putField(null, "StartAt", it.get());
- it.next();
- } else {
- empty("-startAt", null);
- }
- }
- }
- ),
-
- new HsArgRule("-ignoreFile",
- "IgnoreFile",
- null,
- HsArgHandler.HASH
- ),
-
- new HsArgRule("-ignorePath",
- "IgnorePath",
- null,
- HsArgHandler.VECTOR
- ),
-
- new HsArgRule("-hidePath",
- "HidePath",
- null,
- HsArgHandler.VECTOR
- ),
-
- new HsArgRule("-additionalFile",
- "AdditionalFile",
- null,
- HsArgHandler.VECTOR
- ),
-
- new ArgRuleSpecific("-additionalGeneratedFile",
- new HsArgHandler() {
- public void handle(ArgIterator it) {
- String cfg = getCfg(it.get());
- if (nextNotKey(it)) {
- String dir = it.get();
- if (nextNotKey(it)) {
- String fileName = it.get();
- BuildConfig.putFieldHash(cfg, "AdditionalGeneratedFile",
- Util.normalize(dir + Util.sep + fileName),
- fileName);
- it.next();
- return;
- }
- }
- empty(null, "** Error: wrong number of args to -additionalGeneratedFile");
- }
- }
- ),
-
- new ArgRule("-prelink",
- new HsArgHandler() {
- public void handle(ArgIterator it) {
- if (nextNotKey(it)) {
- if (nextNotKey(it)) {
- String description = it.get();
- if (nextNotKey(it)) {
- String command = it.get();
- BuildConfig.putField(null, "PrelinkDescription", description);
- BuildConfig.putField(null, "PrelinkCommand", command);
- it.next();
- return;
- }
- }
- }
-
- empty(null, "** Error: wrong number of args to -prelink");
- }
- }
- ),
-
- new ArgRule("-postbuild",
- new HsArgHandler() {
- public void handle(ArgIterator it) {
- if (nextNotKey(it)) {
- if (nextNotKey(it)) {
- String description = it.get();
- if (nextNotKey(it)) {
- String command = it.get();
- BuildConfig.putField(null, "PostbuildDescription", description);
- BuildConfig.putField(null, "PostbuildCommand", command);
- it.next();
- return;
- }
- }
- }
-
- empty(null, "** Error: wrong number of args to -postbuild");
- }
- }
- ),
- },
- new ArgHandler() {
- public void handle(ArgIterator it) {
-
- throw new RuntimeException("Arg Parser: unrecognized option "+it.get());
- }
- }
- );
- if (BuildConfig.getField(null, "SourceBase") == null ||
- BuildConfig.getField(null, "BuildBase") == null ||
- BuildConfig.getField(null, "ProjectFileName") == null ||
- BuildConfig.getField(null, "CompilerVersion") == null) {
- usage();
- }
-
- if (BuildConfig.getField(null, "UseToGeneratePch") == null) {
- throw new RuntimeException("ERROR: need to specify one file to compute PCH, with -useToGeneratePch flag");
- }
-
- BuildConfig.putField(null, "PlatformObject", this);
- }
-
- Vector createAllConfigs(String platform) {
- Vector allConfigs = new Vector();
-
- allConfigs.add(new C1DebugConfig());
- allConfigs.add(new C1FastDebugConfig());
- allConfigs.add(new C1ProductConfig());
-
- allConfigs.add(new TieredDebugConfig());
- allConfigs.add(new TieredFastDebugConfig());
- allConfigs.add(new TieredProductConfig());
-
- return allConfigs;
- }
-
- PrintWriter printWriter;
-
- public void writeProjectFile(String projectFileName, String projectName,
- Vector<BuildConfig> allConfigs) throws IOException {
- throw new RuntimeException("use compiler version specific version");
- }
-
- int indent;
- private Stack<String> tagStack = new Stack<String>();
-
- private void startTagPrim(String name, String[] attrs, boolean close) {
- startTagPrim(name, attrs, close, true);
- }
-
- private void startTagPrim(String name, String[] attrs, boolean close,
- boolean newline) {
- doIndent();
- printWriter.print("<" + name);
- indent++;
-
- if (attrs != null && attrs.length > 0) {
- for (int i = 0; i < attrs.length; i += 2) {
- printWriter.print(" " + attrs[i] + "=\"" + attrs[i + 1] + "\"");
- if (i < attrs.length - 2) {
- }
- }
- }
-
- if (close) {
- indent--;
- printWriter.print(" />");
- } else {
- // TODO push tag name, and change endTag to pop and print.
- tagStack.push(name);
- printWriter.print(">");
- }
- if (newline) {
- printWriter.println();
- }
- }
-
- void startTag(String name, String... attrs) {
- startTagPrim(name, attrs, false);
- }
-
- void startTagV(String name, Vector attrs) {
- String s[] = new String[attrs.size()];
- for (int i = 0; i < attrs.size(); i++) {
- s[i] = (String) attrs.elementAt(i);
- }
- startTagPrim(name, s, false);
- }
-
- void endTag() {
- String name = tagStack.pop();
- indent--;
- doIndent();
- printWriter.println("</" + name + ">");
- }
-
- private void endTagNoIndent() {
- String name = tagStack.pop();
- indent--;
- printWriter.println("</" + name + ">");
- }
-
- void tag(String name, String... attrs) {
- startTagPrim(name, attrs, true);
- }
-
- void tagData(String name, String data) {
- startTagPrim(name, null, false, false);
- printWriter.print(data);
- endTagNoIndent();
- }
-
- void tagData(String name, String data, String... attrs) {
- startTagPrim(name, attrs, false, false);
- printWriter.print(data);
- endTagNoIndent();
- }
-
- void tagV(String name, Vector attrs) {
- String s[] = new String[attrs.size()];
- for (int i = 0; i < attrs.size(); i++) {
- s[i] = (String) attrs.elementAt(i);
- }
- startTagPrim(name, s, true);
- }
-
- void doIndent() {
- for (int i = 0; i < indent; i++) {
- printWriter.print(" ");
- }
- }
-
-
-}
--- a/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java Tue May 10 12:18:22 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,476 +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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.UnsupportedEncodingException;
-import java.nio.file.FileSystems;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.UUID;
-import java.util.Vector;
-
-public class WinGammaPlatformVC10 extends WinGammaPlatform {
-
-
- LinkedList <String>filters = new LinkedList<String>();
- LinkedList <String[]>filterDeps = new LinkedList<String[]>();
-
- @Override
- protected String getProjectExt() {
- return ".vcxproj";
- }
-
- @Override
- public void writeProjectFile(String projectFileName, String projectName,
- Vector<BuildConfig> allConfigs) throws IOException {
- System.out.println();
- System.out.println(" Writing .vcxproj file: " + projectFileName);
-
- String projDir = Util.normalize(new File(projectFileName).getParent());
-
- printWriter = new PrintWriter(projectFileName, "UTF-8");
- printWriter.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
- startTag("Project",
- "DefaultTargets", "Build",
- "ToolsVersion", "4.0",
- "xmlns", "http://schemas.microsoft.com/developer/msbuild/2003");
- startTag("ItemGroup",
- "Label", "ProjectConfigurations");
- for (BuildConfig cfg : allConfigs) {
- startTag("ProjectConfiguration",
- "Include", cfg.get("Name"));
- tagData("Configuration", cfg.get("Id"));
- tagData("Platform", cfg.get("PlatformName"));
- endTag();
- }
- endTag();
-
- startTag("PropertyGroup", "Label", "Globals");
- tagData("ProjectGuid", "{8822CB5C-1C41-41C2-8493-9F6E1994338B}");
- tag("SccProjectName");
- tag("SccLocalPath");
- endTag();
-
- tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.Default.props");
-
- for (BuildConfig cfg : allConfigs) {
- startTag(cfg, "PropertyGroup", "Label", "Configuration");
- tagData("ConfigurationType", "DynamicLibrary");
- tagData("UseOfMfc", "false");
- tagData("PlatformToolset", "v120");
- endTag();
- }
-
- tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.props");
- startTag("ImportGroup", "Label", "ExtensionSettings");
- endTag();
- for (BuildConfig cfg : allConfigs) {
- startTag(cfg, "ImportGroup", "Label", "PropertySheets");
- tag("Import",
- "Project", "$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props",
- "Condition", "exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')",
- "Label", "LocalAppDataPlatform");
- endTag();
- }
-
- tag("PropertyGroup", "Label", "UserMacros");
-
- startTag("PropertyGroup");
- tagData("_ProjectFileVersion", "10.0.30319.1");
- for (BuildConfig cfg : allConfigs) {
- tagData(cfg, "OutDir", cfg.get("OutputDir") + Util.sep);
- tagData(cfg, "IntDir", cfg.get("OutputDir") + Util.sep);
- tagData(cfg, "LinkIncremental", "false");
- }
- for (BuildConfig cfg : allConfigs) {
- tagData(cfg, "CodeAnalysisRuleSet", "AllRules.ruleset");
- tag(cfg, "CodeAnalysisRules");
- tag(cfg, "CodeAnalysisRuleAssemblies");
- }
- endTag();
-
- for (BuildConfig cfg : allConfigs) {
- startTag(cfg, "ItemDefinitionGroup");
- startTag("ClCompile");
- tagV(cfg.getV("CompilerFlags"));
- endTag();
-
- startTag("Link");
- tagV(cfg.getV("LinkerFlags"));
- endTag();
-
- startTag("PreLinkEvent");
- tagData("Message", BuildConfig.getFieldString(null, "PrelinkDescription"));
- tagData("Command", cfg.expandFormat(BuildConfig.getFieldString(null, "PrelinkCommand").replace("\t", "\r\n")));
- endTag();
-
- endTag();
- }
-
- writeFiles(allConfigs, projDir);
-
- tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.targets");
- startTag("ImportGroup", "Label", "ExtensionTargets");
- endTag();
-
- endTag();
- printWriter.close();
- System.out.println(" Done writing .vcxproj file.");
-
- writeFilterFile(projectFileName, projectName, allConfigs, projDir);
- writeUserFile(projectFileName, allConfigs);
- }
-
-
- private void writeUserFile(String projectFileName, Vector<BuildConfig> allConfigs) throws FileNotFoundException, UnsupportedEncodingException {
- String userFileName = projectFileName + ".user";
- if (new File(userFileName).exists()) {
- return;
- }
- System.out.print(" Writing .vcxproj.user file: " + userFileName);
- printWriter = new PrintWriter(userFileName, "UTF-8");
-
- printWriter.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
- startTag("Project",
- "ToolsVersion", "4.0",
- "xmlns", "http://schemas.microsoft.com/developer/msbuild/2003");
-
- for (BuildConfig cfg : allConfigs) {
- startTag(cfg, "PropertyGroup");
- tagData("LocalDebuggerCommand", cfg.get("JdkTargetRoot") + "\\bin\\java.exe");
- // The JVM loads some libraries using a path relative to
- // itself because it expects to be in a JRE or a JDK. The java
- // launcher's '-XXaltjvm=' option allows the JVM to be outside
- // the JRE or JDK so '-Dsun.java.launcher.is_altjvm=true'
- // forces a fake JAVA_HOME relative path to be used to
- // find the other libraries. The '-XX:+PauseAtExit' option
- // causes the VM to wait for key press before exiting; this
- // allows any stdout or stderr messages to be seen before
- // the cmdtool exits.
- tagData("LocalDebuggerCommandArguments", "-XXaltjvm=$(TargetDir) "
- + "-Dsun.java.launcher.is_altjvm=true "
- + "-XX:+UnlockDiagnosticVMOptions -XX:+PauseAtExit");
- tagData("LocalDebuggerEnvironment", "JAVA_HOME=" + cfg.get("JdkTargetRoot"));
- endTag();
- }
-
- endTag();
- printWriter.close();
- System.out.println(" Done.");
- }
-
- public void addFilter(String rPath) {
- filters.add(rPath);
- }
-
- public void addFilterDependency(String fileLoc, String filter) {
- filterDeps.add(new String[] {fileLoc, filter});
- }
-
- private void writeFilterFile(String projectFileName, String projectName,
- Vector<BuildConfig> allConfigs, String base) throws FileNotFoundException, UnsupportedEncodingException {
- String filterFileName = projectFileName + ".filters";
- System.out.print(" Writing .vcxproj.filters file: " + filterFileName);
- printWriter = new PrintWriter(filterFileName, "UTF-8");
-
- printWriter.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
- startTag("Project",
- "ToolsVersion", "4.0",
- "xmlns", "http://schemas.microsoft.com/developer/msbuild/2003");
-
- startTag("ItemGroup");
- for (String filter : filters) {
- startTag("Filter", "Include",filter);
- UUID uuid = UUID.randomUUID();
- tagData("UniqueIdentifier", "{" + uuid.toString() + "}");
- endTag();
- }
- startTag("Filter", "Include", "Resource Files");
- UUID uuid = UUID.randomUUID();
- tagData("UniqueIdentifier", "{" + uuid.toString() + "}");
- tagData("Extensions", "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe");
- endTag();
- endTag();
-
- //TODO - do I need to split cpp and hpp files?
-
- // then all files
- startTag("ItemGroup");
- for (String[] dep : filterDeps) {
- String tagName = getFileTagFromSuffix(dep[0]);
-
- startTag(tagName, "Include", dep[0]);
- tagData("Filter", dep[1]);
- endTag();
- }
- endTag();
-
- endTag();
- printWriter.close();
- System.out.println(" Done.");
- }
-
- public String getFileTagFromSuffix(String fileName) {
- if (fileName.endsWith(".cpp")) {
- return"ClCompile";
- } else if (fileName.endsWith(".c")) {
- return "ClCompile";
- } else if (fileName.endsWith(".hpp")) {
- return"ClInclude";
- } else if (fileName.endsWith(".h")) {
- return "ClInclude";
- } else {
- return"None";
- }
- }
-
- void writeFiles(Vector<BuildConfig> allConfigs, String projDir) {
- // This code assummes there are no config specific includes.
- startTag("ItemGroup");
-
- String sourceBase = BuildConfig.getFieldString(null, "SourceBase");
-
- // Use first config for all global absolute includes.
- BuildConfig baseConfig = allConfigs.firstElement();
- Vector<String> rv = new Vector<String>();
-
- // Then use first config for all relative includes
- Vector<String> ri = new Vector<String>();
- baseConfig.collectRelevantVectors(ri, "RelativeSrcInclude");
- for (String f : ri) {
- rv.add(sourceBase + Util.sep + f);
- }
-
- baseConfig.collectRelevantVectors(rv, "AbsoluteSrcInclude");
-
- handleIncludes(rv, allConfigs);
-
- endTag();
- }
-
- // Will visit file tree for each include
- private void handleIncludes(Vector<String> includes, Vector<BuildConfig> allConfigs) {
- for (String path : includes) {
- FileTreeCreatorVC10 ftc = new FileTreeCreatorVC10(FileSystems.getDefault().getPath(path) , allConfigs, this);
- try {
- ftc.writeFileTree();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-
- String buildCond(BuildConfig cfg) {
- return "'$(Configuration)|$(Platform)'=='"+cfg.get("Name")+"'";
- }
-
- void tagV(Vector<String> v) {
- Iterator<String> i = v.iterator();
- while(i.hasNext()) {
- String name = i.next();
- String data = i.next();
- tagData(name, data);
- }
- }
-
- void tagData(BuildConfig cfg, String name, String data) {
- tagData(name, data, "Condition", buildCond(cfg));
- }
-
- void tag(BuildConfig cfg, String name, String... attrs) {
- String[] ss = new String[attrs.length + 2];
- ss[0] = "Condition";
- ss[1] = buildCond(cfg);
- System.arraycopy(attrs, 0, ss, 2, attrs.length);
-
- tag(name, ss);
- }
-
- void startTag(BuildConfig cfg, String name, String... attrs) {
- String[] ss = new String[attrs.length + 2];
- ss[0] = "Condition";
- ss[1] = buildCond(cfg);
- System.arraycopy(attrs, 0, ss, 2, attrs.length);
-
- startTag(name, ss);
- }
-
-}
-
-class CompilerInterfaceVC10 extends CompilerInterface {
-
- @Override
- Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir) {
- Vector rv = new Vector();
-
- addAttr(rv, "AdditionalIncludeDirectories", Util.join(";", includes));
- addAttr(rv, "PreprocessorDefinitions",
- Util.join(";", defines).replace("\\\"", "\""));
- addAttr(rv, "PrecompiledHeaderFile", "precompiled.hpp");
- addAttr(rv, "PrecompiledHeaderOutputFile", outDir+Util.sep+"vm.pch");
- addAttr(rv, "AssemblerListingLocation", outDir);
- addAttr(rv, "ObjectFileName", outDir+Util.sep);
- addAttr(rv, "ProgramDataBaseFileName", outDir+Util.sep+"jvm.pdb");
- // Set /nologo option
- addAttr(rv, "SuppressStartupBanner", "true");
- // Surpass the default /Tc or /Tp.
- addAttr(rv, "CompileAs", "Default");
- // Set /W3 option.
- addAttr(rv, "WarningLevel", "Level3");
- // Set /WX option,
- addAttr(rv, "TreatWarningAsError", "true");
- // Set /GS option
- addAttr(rv, "BufferSecurityCheck", "false");
- // Set /Zi option.
- addAttr(rv, "DebugInformationFormat", "ProgramDatabase");
- // Set /Yu option.
- addAttr(rv, "PrecompiledHeader", "Use");
- // Set /EHsc- option
- addAttr(rv, "ExceptionHandling", "");
-
- addAttr(rv, "MultiProcessorCompilation", "true");
-
- return rv;
- }
-
- @Override
- Vector getDebugCompilerFlags(String opt, String platformName) {
- Vector rv = new Vector();
-
- // Set /On option
- addAttr(rv, "Optimization", opt);
- // Set /MD option.
- addAttr(rv, "RuntimeLibrary", "MultiThreadedDLL");
- // Set /Oy- option
- addAttr(rv, "OmitFramePointers", "false");
- // Set /homeparams for x64 debug builds
- if(platformName.equals("x64")) {
- addAttr(rv, "AdditionalOptions", "/homeparams");
- }
-
- return rv;
- }
-
- @Override
- Vector getProductCompilerFlags() {
- Vector rv = new Vector();
-
- // Set /O2 option.
- addAttr(rv, "Optimization", "MaxSpeed");
- // Set /Oy- option
- addAttr(rv, "OmitFramePointers", "false");
- // Set /Ob option. 1 is expandOnlyInline
- addAttr(rv, "InlineFunctionExpansion", "OnlyExplicitInline");
- // Set /GF option.
- addAttr(rv, "StringPooling", "true");
- // Set /MD option. 2 is rtMultiThreadedDLL
- addAttr(rv, "RuntimeLibrary", "MultiThreadedDLL");
- // Set /Gy option
- addAttr(rv, "FunctionLevelLinking", "true");
-
- return rv;
- }
-
- @Override
- Vector getBaseLinkerFlags(String outDir, String outDll, String platformName) {
- Vector rv = new Vector();
-
- if(platformName.equals("Win32")) {
- addAttr(rv, "AdditionalOptions",
- "/export:JNI_GetDefaultJavaVMInitArgs " +
- "/export:JNI_CreateJavaVM " +
- "/export:JVM_FindClassFromBootLoader "+
- "/export:JNI_GetCreatedJavaVMs "+
- "/export:jio_snprintf /export:jio_printf "+
- "/export:jio_fprintf /export:jio_vfprintf "+
- "/export:jio_vsnprintf "+
- "/export:JVM_GetVersionInfo "+
- "/export:JVM_InitAgentProperties");
- }
- addAttr(rv, "AdditionalDependencies", "kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;Wsock32.lib;winmm.lib;psapi.lib;version.lib");
- addAttr(rv, "OutputFile", outDll);
- addAttr(rv, "SuppressStartupBanner", "true");
- addAttr(rv, "ModuleDefinitionFile", outDir+Util.sep+"vm.def");
- addAttr(rv, "ProgramDatabaseFile", outDir+Util.sep+"jvm.pdb");
- addAttr(rv, "SubSystem", "Windows");
- addAttr(rv, "BaseAddress", "0x8000000");
- addAttr(rv, "ImportLibrary", outDir+Util.sep+"jvm.lib");
-
- if(platformName.equals("Win32")) {
- addAttr(rv, "TargetMachine", "MachineX86");
- } else {
- addAttr(rv, "TargetMachine", "MachineX64");
- }
-
- // We always want the /DEBUG option to get full symbol information in the pdb files
- addAttr(rv, "GenerateDebugInformation", "true");
-
- return rv;
- }
-
- @Override
- Vector getDebugLinkerFlags() {
- Vector rv = new Vector();
-
- // Empty now that /DEBUG option is used by all configs
-
- return rv;
- }
-
- @Override
- Vector getProductLinkerFlags() {
- Vector rv = new Vector();
-
- // Set /OPT:REF option.
- addAttr(rv, "OptimizeReferences", "true");
- // Set /OPT:ICF option.
- addAttr(rv, "EnableCOMDATFolding", "true");
-
- return rv;
- }
-
- @Override
- void getAdditionalNonKernelLinkerFlags(Vector rv) {
- extAttr(rv, "AdditionalOptions", " /export:AsyncGetCallTrace");
- }
-
- @Override
- String getOptFlag() {
- return "MaxSpeed";
- }
-
- @Override
- String getNoOptFlag() {
- return "Disabled";
- }
-
- @Override
- String makeCfgName(String flavourBuild, String platform) {
- return flavourBuild + "|" + platform;
- }
-
-}
--- a/hotspot/src/share/vm/c1/c1_Compiler.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/c1/c1_Compiler.cpp Wed May 11 00:38:58 2016 +0300
@@ -198,20 +198,6 @@
case vmIntrinsics::_putLongVolatile:
case vmIntrinsics::_putFloatVolatile:
case vmIntrinsics::_putDoubleVolatile:
- case vmIntrinsics::_getByte_raw:
- case vmIntrinsics::_getShort_raw:
- case vmIntrinsics::_getChar_raw:
- case vmIntrinsics::_getInt_raw:
- case vmIntrinsics::_getLong_raw:
- case vmIntrinsics::_getFloat_raw:
- case vmIntrinsics::_getDouble_raw:
- case vmIntrinsics::_putByte_raw:
- case vmIntrinsics::_putShort_raw:
- case vmIntrinsics::_putChar_raw:
- case vmIntrinsics::_putInt_raw:
- case vmIntrinsics::_putLong_raw:
- case vmIntrinsics::_putFloat_raw:
- case vmIntrinsics::_putDouble_raw:
case vmIntrinsics::_getShortUnaligned:
case vmIntrinsics::_getCharUnaligned:
case vmIntrinsics::_getIntUnaligned:
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Wed May 11 00:38:58 2016 +0300
@@ -3465,20 +3465,6 @@
case vmIntrinsics::_putLongVolatile : append_unsafe_put_obj(callee, T_LONG, true); return;
case vmIntrinsics::_putFloatVolatile : append_unsafe_put_obj(callee, T_FLOAT, true); return;
case vmIntrinsics::_putDoubleVolatile : append_unsafe_put_obj(callee, T_DOUBLE, true); return;
- case vmIntrinsics::_getByte_raw : append_unsafe_get_raw(callee, T_BYTE ); return;
- case vmIntrinsics::_getShort_raw : append_unsafe_get_raw(callee, T_SHORT ); return;
- case vmIntrinsics::_getChar_raw : append_unsafe_get_raw(callee, T_CHAR ); return;
- case vmIntrinsics::_getInt_raw : append_unsafe_get_raw(callee, T_INT ); return;
- case vmIntrinsics::_getLong_raw : append_unsafe_get_raw(callee, T_LONG ); return;
- case vmIntrinsics::_getFloat_raw : append_unsafe_get_raw(callee, T_FLOAT ); return;
- case vmIntrinsics::_getDouble_raw : append_unsafe_get_raw(callee, T_DOUBLE); return;
- case vmIntrinsics::_putByte_raw : append_unsafe_put_raw(callee, T_BYTE ); return;
- case vmIntrinsics::_putShort_raw : append_unsafe_put_raw(callee, T_SHORT ); return;
- case vmIntrinsics::_putChar_raw : append_unsafe_put_raw(callee, T_CHAR ); return;
- case vmIntrinsics::_putInt_raw : append_unsafe_put_raw(callee, T_INT ); return;
- case vmIntrinsics::_putLong_raw : append_unsafe_put_raw(callee, T_LONG ); return;
- case vmIntrinsics::_putFloat_raw : append_unsafe_put_raw(callee, T_FLOAT ); return;
- case vmIntrinsics::_putDouble_raw : append_unsafe_put_raw(callee, T_DOUBLE); return;
case vmIntrinsics::_compareAndSwapLong:
case vmIntrinsics::_compareAndSwapInt:
case vmIntrinsics::_compareAndSwapObject: append_unsafe_CAS(callee); return;
--- a/hotspot/src/share/vm/classfile/classLoader.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp Wed May 11 00:38:58 2016 +0300
@@ -140,9 +140,10 @@
PerfCounter* ClassLoader::_isUnsyncloadClass = NULL;
PerfCounter* ClassLoader::_load_instance_class_failCounter = NULL;
-ClassPathEntry* ClassLoader::_first_entry = NULL;
-ClassPathEntry* ClassLoader::_last_entry = NULL;
-int ClassLoader::_num_entries = 0;
+GrowableArray<ModuleClassPathList*>* ClassLoader::_xpatch_entries = NULL;
+ClassPathEntry* ClassLoader::_first_entry = NULL;
+ClassPathEntry* ClassLoader::_last_entry = NULL;
+int ClassLoader::_num_entries = 0;
ClassPathEntry* ClassLoader::_first_append_entry = NULL;
bool ClassLoader::_has_jimage = false;
#if INCLUDE_CDS
@@ -179,6 +180,44 @@
return (strncmp(str + (str_len - str_to_find_len), str_to_find, str_to_find_len) == 0);
}
+// Used to obtain the package name from a fully qualified class name.
+// It is the responsibility of the caller to establish ResourceMark.
+const char* ClassLoader::package_from_name(const char* class_name) {
+ const char* last_slash = strrchr(class_name, '/');
+ if (last_slash == NULL) {
+ // No package name
+ return NULL;
+ }
+ int length = last_slash - class_name;
+
+ // A class name could have just the slash character in the name,
+ // resulting in a negative length.
+ if (length <= 0) {
+ // No package name
+ return NULL;
+ }
+
+ // drop name after last slash (including slash)
+ // Ex., "java/lang/String.class" => "java/lang"
+ char* pkg_name = NEW_RESOURCE_ARRAY(char, length + 1);
+ strncpy(pkg_name, class_name, length);
+ *(pkg_name+length) = '\0';
+
+ return (const char *)pkg_name;
+}
+
+// Given a fully qualified class name, find its defining package in the class loader's
+// package entry table.
+static PackageEntry* get_package_entry(const char* class_name, ClassLoaderData* loader_data, TRAPS) {
+ ResourceMark rm(THREAD);
+ const char *pkg_name = ClassLoader::package_from_name(class_name);
+ if (pkg_name == NULL) {
+ return NULL;
+ }
+ PackageEntryTable* pkgEntryTable = loader_data->packages();
+ TempNewSymbol pkg_symbol = SymbolTable::new_symbol(pkg_name, CHECK_NULL);
+ return pkgEntryTable->lookup_only(pkg_symbol);
+}
ClassPathDirEntry::ClassPathDirEntry(const char* dir) : ClassPathEntry() {
char* copy = NEW_C_HEAP_ARRAY(char, strlen(dir)+1, mtClass);
@@ -281,8 +320,7 @@
#if INCLUDE_CDS
u1* ClassPathZipEntry::open_versioned_entry(const char* name, jint* filesize, TRAPS) {
u1* buffer = NULL;
- if (!_is_boot_append) {
- assert(DumpSharedSpaces, "Should be called only for non-boot entries during dump time");
+ if (DumpSharedSpaces) {
// We presume default is multi-release enabled
const char* multi_ver = Arguments::get_property("jdk.util.jar.enableMultiRelease");
const char* verstr = Arguments::get_property("jdk.util.jar.version");
@@ -399,31 +437,6 @@
}
}
-void ClassPathImageEntry::name_to_package(const char* name, char* buffer, int length) {
- const char *pslash = strrchr(name, '/');
- if (pslash == NULL) {
- buffer[0] = '\0';
- return;
- }
- int len = pslash - name;
-#if INCLUDE_CDS
- if (len <= 0 && DumpSharedSpaces) {
- buffer[0] = '\0';
- return;
- }
-#endif
- assert(len > 0, "Bad length for package name");
- if (len >= length) {
- buffer[0] = '\0';
- return;
- }
- // drop name after last slash (including slash)
- // Ex., "java/lang/String.class" => "java/lang"
- strncpy(buffer, name, len);
- // ensure string termination (strncpy does not guarantee)
- buffer[len] = '\0';
-}
-
// For a class in a named module, look it up in the jimage file using this syntax:
// /<module-name>/<package-name>/<base-class>
//
@@ -436,15 +449,10 @@
JImageLocationRef location = (*JImageFindResource)(_jimage, "", get_jimage_version_string(), name, &size);
if (location == 0) {
- char package[JIMAGE_MAX_PATH];
- name_to_package(name, package, JIMAGE_MAX_PATH);
+ ResourceMark rm;
+ const char* pkg_name = ClassLoader::package_from_name(name);
-#if INCLUDE_CDS
- if (package[0] == '\0' && DumpSharedSpaces) {
- return NULL;
- }
-#endif
- if (package[0] != '\0') {
+ if (pkg_name != NULL) {
if (!Universe::is_module_initialized()) {
location = (*JImageFindResource)(_jimage, "java.base", get_jimage_version_string(), name, &size);
#if INCLUDE_CDS
@@ -452,7 +460,7 @@
// modules defined for other class loaders. So, for now, get their module
// names from the "modules" jimage file.
if (DumpSharedSpaces && location == 0) {
- const char* module_name = (*JImagePackageToModule)(_jimage, package);
+ const char* module_name = (*JImagePackageToModule)(_jimage, pkg_name);
if (module_name != NULL) {
location = (*JImageFindResource)(_jimage, module_name, get_jimage_version_string(), name, &size);
}
@@ -460,13 +468,7 @@
#endif
} else {
- // Get boot class loader's package entry table
- PackageEntryTable* pkgEntryTable =
- ClassLoaderData::the_null_class_loader_data()->packages();
- // Get package's package entry
- TempNewSymbol pkg_symbol = SymbolTable::new_symbol(package, CHECK_NULL);
- PackageEntry* package_entry = pkgEntryTable->lookup_only(pkg_symbol);
-
+ PackageEntry* package_entry = get_package_entry(name, ClassLoaderData::the_null_class_loader_data(), THREAD);
if (package_entry != NULL) {
ResourceMark rm;
// Get the module name
@@ -539,6 +541,33 @@
}
#endif
+ModuleClassPathList::ModuleClassPathList(Symbol* module_name) {
+ _module_name = module_name;
+ _module_first_entry = NULL;
+ _module_last_entry = NULL;
+}
+
+ModuleClassPathList::~ModuleClassPathList() {
+ // Clean out each ClassPathEntry on list
+ ClassPathEntry* e = _module_first_entry;
+ while (e != NULL) {
+ ClassPathEntry* next_entry = e->next();
+ delete e;
+ e = next_entry;
+ }
+}
+
+void ModuleClassPathList::add_to_list(ClassPathEntry* new_entry) {
+ if (new_entry != NULL) {
+ if (_module_last_entry == NULL) {
+ _module_first_entry = _module_last_entry = new_entry;
+ } else {
+ _module_last_entry->set_next(new_entry);
+ _module_last_entry = new_entry;
+ }
+ }
+}
+
void ClassLoader::trace_class_path(const char* msg, const char* name) {
if (log_is_enabled(Info, class, path)) {
ResourceMark rm;
@@ -616,6 +645,61 @@
}
#endif
+// Construct the array of module/path pairs as specified to -Xpatch
+// for the boot loader to search ahead of the jimage, if the class being
+// loaded is defined to a module that has been specified to -Xpatch.
+void ClassLoader::setup_xpatch_entries() {
+ Thread* THREAD = Thread::current();
+ GrowableArray<ModuleXPatchPath*>* xpatch_args = Arguments::get_xpatchprefix();
+ int num_of_entries = xpatch_args->length();
+
+ // Set up the boot loader's xpatch_entries list
+ _xpatch_entries = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<ModuleClassPathList*>(num_of_entries, true);
+
+ for (int i = 0; i < num_of_entries; i++) {
+ const char* module_name = (xpatch_args->at(i))->module_name();
+ Symbol* const module_sym = SymbolTable::lookup(module_name, (int)strlen(module_name), CHECK);
+ assert(module_sym != NULL, "Failed to obtain Symbol for module name");
+ ModuleClassPathList* module_cpl = new ModuleClassPathList(module_sym);
+
+ char* class_path = (xpatch_args->at(i))->path_string();
+ int len = (int)strlen(class_path);
+ int end = 0;
+ // Iterate over the module's class path entries
+ for (int start = 0; start < len; start = end) {
+ while (class_path[end] && class_path[end] != os::path_separator()[0]) {
+ end++;
+ }
+ EXCEPTION_MARK;
+ ResourceMark rm(THREAD);
+ char* path = NEW_RESOURCE_ARRAY(char, end - start + 1);
+ strncpy(path, &class_path[start], end - start);
+ path[end - start] = '\0';
+
+ struct stat st;
+ if (os::stat(path, &st) == 0) {
+ // File or directory found
+ Thread* THREAD = Thread::current();
+ ClassPathEntry* new_entry = create_class_path_entry(path, &st, false, false, CHECK);
+ // If the path specification is valid, enter it into this module's list
+ if (new_entry != NULL) {
+ module_cpl->add_to_list(new_entry);
+ }
+ }
+
+ while (class_path[end] == os::path_separator()[0]) {
+ end++;
+ }
+ }
+
+ // Record the module into the list of -Xpatch entries only if
+ // valid ClassPathEntrys have been created
+ if (module_cpl->module_first_entry() != NULL) {
+ _xpatch_entries->push(module_cpl);
+ }
+ }
+}
+
void ClassLoader::setup_search_path(const char *class_path, bool bootstrap_search) {
int offset = 0;
int len = (int)strlen(class_path);
@@ -847,8 +931,29 @@
}
void ClassLoader::print_bootclasspath() {
- ClassPathEntry* e = _first_entry;
+ ClassPathEntry* e;
tty->print("[bootclasspath= ");
+
+ // Print -Xpatch module/path specifications first
+ if (_xpatch_entries != NULL) {
+ ResourceMark rm;
+ int num_of_entries = _xpatch_entries->length();
+ for (int i = 0; i < num_of_entries; i++) {
+ ModuleClassPathList* mpl = _xpatch_entries->at(i);
+ tty->print("%s=", mpl->module_name()->as_C_string());
+ e = mpl->module_first_entry();
+ while (e != NULL) {
+ tty->print("%s", e->name());
+ e = e->next();
+ if (e != NULL) {
+ tty->print("%s", os::path_separator());
+ }
+ }
+ tty->print(" ;");
+ }
+ }
+
+ e = _first_entry;
while (e != NULL) {
tty->print("%s ;", e->name());
e = e->next();
@@ -942,13 +1047,15 @@
return; // only needed for CDS dump time
}
+ ResourceMark rm;
jlong size;
JImageLocationRef location = (*JImageFindResource)(jimage, "java.base", get_jimage_version_string(), MODULE_LOADER_MAP, &size);
if (location == 0) {
vm_exit_during_initialization(
"Cannot find ModuleLoaderMap location from modules jimage.", NULL);
}
- char* buffer = NEW_RESOURCE_ARRAY(char, size);
+ char* buffer = NEW_RESOURCE_ARRAY(char, size + 1);
+ buffer[size] = '\0';
jlong read = (*JImageGetResource)(jimage, location, buffer, size);
if (read != size) {
vm_exit_during_initialization(
@@ -986,7 +1093,6 @@
begin_ptr = ++end_ptr;
end_ptr = strchr(begin_ptr, '\n');
}
- FREE_RESOURCE_ARRAY(u1, buffer, size);
}
#endif
@@ -1107,8 +1213,7 @@
return APP_LOADER;
}
-s2 ClassLoader::classloader_type(Symbol* class_name, ClassPathEntry* e,
- int classpath_index, TRAPS) {
+s2 ClassLoader::classloader_type(Symbol* class_name, ClassPathEntry* e, int classpath_index, TRAPS) {
assert(DumpSharedSpaces, "Only used for CDS dump time");
// obtain the classloader type based on the class name.
@@ -1157,12 +1262,11 @@
}
instanceKlassHandle ClassLoader::load_class(Symbol* name, bool search_append_only, TRAPS) {
-
assert(name != NULL, "invariant");
assert(THREAD->is_Java_thread(), "must be a JavaThread");
- ResourceMark rm;
- HandleMark hm;
+ ResourceMark rm(THREAD);
+ HandleMark hm(THREAD);
const char* const class_name = name->as_C_string();
@@ -1178,30 +1282,101 @@
// Lookup stream for parsing .class file
ClassFileStream* stream = NULL;
s2 classpath_index = 0;
+ ClassPathEntry* e = NULL;
// If DumpSharedSpaces is true, boot loader visibility boundaries are set
- // to be _first_entry to the end (all path entries).
+ // to be _first_entry to the end (all path entries). No -Xpatch entries are
+ // included since CDS and AppCDS are not supported if -Xpatch is specified.
//
// If search_append_only is true, boot loader visibility boundaries are
- // set to be _fist_append_entry to the end. This includes:
+ // set to be _first_append_entry to the end. This includes:
// [-Xbootclasspath/a]; [jvmti appended entries]
//
// If both DumpSharedSpaces and search_append_only are false, boot loader
// visibility boundaries are set to be _first_entry to the entry before
// the _first_append_entry. This would include:
- // [-Xpatch:<dirs>]; [exploded build | modules]
+ // [-Xpatch:<module>=<file>(<pathsep><file>)*]; [exploded build | jimage]
//
// DumpSharedSpaces and search_append_only are mutually exclusive and cannot
// be true at the same time.
- ClassPathEntry* e = (search_append_only ? _first_append_entry : _first_entry);
- ClassPathEntry* last_e =
- (search_append_only || DumpSharedSpaces ? NULL : _first_append_entry);
+ assert(!(DumpSharedSpaces && search_append_only), "DumpSharedSpaces and search_append_only are both true");
+
+ // Load Attempt #1: -Xpatch
+ // Determine the class' defining module. If it appears in the _xpatch_entries,
+ // attempt to load the class from those locations specific to the module.
+ // Note: The -Xpatch entries are never searched if the boot loader's
+ // visibility boundary is limited to only searching the append entries.
+ if (_xpatch_entries != NULL && !search_append_only && !DumpSharedSpaces) {
+ // Find the module in the boot loader's module entry table
+ PackageEntry* pkg_entry = get_package_entry(class_name, ClassLoaderData::the_null_class_loader_data(), THREAD);
+ ModuleEntry* mod_entry = (pkg_entry != NULL) ? pkg_entry->module() : NULL;
+
+ // If the module system has not defined java.base yet, then
+ // classes loaded are assumed to be defined to java.base.
+ // When java.base is eventually defined by the module system,
+ // all packages of classes that have been previously loaded
+ // are verified in ModuleEntryTable::verify_javabase_packages().
+ if (!Universe::is_module_initialized() &&
+ !ModuleEntryTable::javabase_defined() &&
+ mod_entry == NULL) {
+ mod_entry = ModuleEntryTable::javabase_module();
+ }
+
+ // The module must be a named module
+ if (mod_entry != NULL && mod_entry->is_named()) {
+ int num_of_entries = _xpatch_entries->length();
+ const Symbol* class_module_name = mod_entry->name();
+
+ // Loop through all the xpatch entries looking for module
+ for (int i = 0; i < num_of_entries; i++) {
+ ModuleClassPathList* module_cpl = _xpatch_entries->at(i);
+ Symbol* module_cpl_name = module_cpl->module_name();
- {
+ if (module_cpl_name->fast_compare(class_module_name) == 0) {
+ // Class' module has been located, attempt to load
+ // the class from the module's ClassPathEntry list.
+ e = module_cpl->module_first_entry();
+ while (e != NULL) {
+ stream = e->open_stream(file_name, CHECK_NULL);
+ // No context.check is required since both CDS
+ // and AppCDS are turned off if -Xpatch is specified.
+ if (NULL != stream) {
+ break;
+ }
+ e = e->next();
+ }
+ // If the module was located in the xpatch entries, break out
+ // even if the class was not located successfully from that module's
+ // ClassPathEntry list. There will not be another valid entry for
+ // that module in the _xpatch_entries array.
+ break;
+ }
+ }
+ }
+ }
+
+ // Load Attempt #2: [exploded build | jimage]
+ if (!search_append_only && (NULL == stream)) {
+ e = _first_entry;
+ while ((e != NULL) && (e != _first_append_entry)) {
+ stream = e->open_stream(file_name, CHECK_NULL);
+ if (!context.check(stream, classpath_index)) {
+ return NULL;
+ }
+ if (NULL != stream) {
+ break;
+ }
+ e = e->next();
+ ++classpath_index;
+ }
+ }
+
+ // Load Attempt #3: [-Xbootclasspath/a]; [jvmti appended entries]
+ if ((search_append_only || DumpSharedSpaces) && (NULL == stream)) {
+ // For the boot loader append path search, must calculate
+ // the starting classpath_index prior to attempting to
+ // load the classfile.
if (search_append_only) {
- // For the boot loader append path search, must calculate
- // the starting classpath_index prior to attempting to
- // load the classfile.
ClassPathEntry *tmp_e = _first_entry;
while ((tmp_e != NULL) && (tmp_e != _first_append_entry)) {
tmp_e = tmp_e->next();
@@ -1209,11 +1384,8 @@
}
}
- // Attempt to load the classfile from either:
- // - [-Xpatch:dir]; exploded build | modules
- // or
- // - [-Xbootclasspath/a]; [jvmti appended entries]
- while ((e != NULL) && (e != last_e)) {
+ e = _first_append_entry;
+ while (e != NULL) {
stream = e->open_stream(file_name, CHECK_NULL);
if (!context.check(stream, classpath_index)) {
return NULL;
@@ -1383,10 +1555,23 @@
}
-void classLoader_init() {
+void classLoader_init1() {
ClassLoader::initialize();
}
+// Complete the ClassPathEntry setup for the boot loader
+void classLoader_init2() {
+ // Setup the list of module/path pairs for -Xpatch processing
+ // This must be done after the SymbolTable is created in order
+ // to use fast_compare on module names instead of a string compare.
+ if (Arguments::get_xpatchprefix() != NULL) {
+ ClassLoader::setup_xpatch_entries();
+ }
+
+ // Determine if this is an exploded build
+ ClassLoader::set_has_jimage();
+}
+
bool ClassLoader::get_canonical_path(const char* orig, char* out, int len) {
assert(orig != NULL && out != NULL && len > 0, "bad arguments");
@@ -1430,17 +1615,19 @@
}
ModuleEntryTable::set_javabase_module(jb_module);
}
+}
- // When looking for the jimage file, only
- // search the boot loader's module path which
- // can consist of [-Xpatch]; exploded build | modules
- // Do not search the boot loader's append path.
+void ClassLoader::set_has_jimage() {
+ // Determine if this is an exploded build. When looking for
+ // the jimage file, only search the piece of the boot
+ // loader's boot class path which contains [exploded build | jimage].
+ // Do not search the boot loader's xpatch entries or append path.
ClassPathEntry* e = _first_entry;
ClassPathEntry* last_e = _first_append_entry;
while ((e != NULL) && (e != last_e)) {
JImageFile *jimage = e->jimage();
if (jimage != NULL && e->is_jrt()) {
- set_has_jimage(true);
+ _has_jimage = true;
#if INCLUDE_CDS
ClassLoader::initialize_module_loader_map(jimage);
#endif
--- a/hotspot/src/share/vm/classfile/classLoader.hpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/classfile/classLoader.hpp Wed May 11 00:38:58 2016 +0300
@@ -142,13 +142,30 @@
JImageFile* jimage() const { return _jimage; }
ClassPathImageEntry(JImageFile* jimage, const char* name);
~ClassPathImageEntry();
- void name_to_package(const char* name, char* package, int length);
ClassFileStream* open_stream(const char* name, TRAPS);
// Debugging
NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);)
};
+// ModuleClassPathList contains a linked list of ClassPathEntry's
+// that have been specified for a specific module. Currently,
+// the only way to specify a module/path pair is via the -Xpatch
+// command line option.
+class ModuleClassPathList : public CHeapObj<mtClass> {
+private:
+ Symbol* _module_name;
+ // First and last entries of class path entries for a specific module
+ ClassPathEntry* _module_first_entry;
+ ClassPathEntry* _module_last_entry;
+public:
+ Symbol* module_name() const { return _module_name; }
+ ClassPathEntry* module_first_entry() const { return _module_first_entry; }
+ ModuleClassPathList(Symbol* module_name);
+ ~ModuleClassPathList();
+ void add_to_list(ClassPathEntry* new_entry);
+};
+
class SharedPathsMiscInfo;
class ClassLoader: AllStatic {
@@ -195,21 +212,31 @@
static PerfCounter* _isUnsyncloadClass;
static PerfCounter* _load_instance_class_failCounter;
- // First entry in linked list of ClassPathEntry instances.
- // This consists of entries made up by:
- // - boot loader modules
- // [-Xpatch]; exploded build | modules;
- // - boot loader append path
- // [-Xbootclasspath/a]; [jvmti appended entries]
+ // The boot class path consists of 3 ordered pieces:
+ // 1. the module/path pairs specified to -Xpatch
+ // -Xpatch:<module>=<file>(<pathsep><file>)*
+ // 2. the base piece
+ // [exploded build | jimage]
+ // 3. boot loader append path
+ // [-Xbootclasspath/a]; [jvmti appended entries]
+ //
+ // The boot loader must obey this order when attempting
+ // to load a class.
+
+ // Contains the module/path pairs specified to -Xpatch
+ static GrowableArray<ModuleClassPathList*>* _xpatch_entries;
+
+ // Contains the ClassPathEntry instances that include
+ // both the base piece and the boot loader append path.
static ClassPathEntry* _first_entry;
// Last entry in linked list of ClassPathEntry instances
static ClassPathEntry* _last_entry;
static int _num_entries;
- // Pointer into the linked list of ClassPathEntry instances.
// Marks the start of:
// - the boot loader's append path
// [-Xbootclasspath/a]; [jvmti appended entries]
+ // within the linked list of ClassPathEntry instances.
static ClassPathEntry* _first_append_entry;
static const char* _shared_archive;
@@ -325,11 +352,11 @@
return _load_instance_class_failCounter;
}
+ // Set up the module/path pairs as specified to -Xpatch
+ static void setup_xpatch_entries();
+
// Sets _has_jimage to TRUE if "modules" jimage file exists
- static void set_has_jimage(bool val) {
- _has_jimage = val;
- }
-
+ static void set_has_jimage();
static bool has_jimage() { return _has_jimage; }
// Create the ModuleEntry for java.base
@@ -416,6 +443,9 @@
static bool string_ends_with(const char* str, const char* str_to_find);
+ // obtain package name from a fully qualified class name
+ static const char* package_from_name(const char* class_name);
+
static bool is_jrt(const char* name) { return string_ends_with(name, MODULES_IMAGE_NAME); }
// Debugging
--- a/hotspot/src/share/vm/classfile/dictionary.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/classfile/dictionary.cpp Wed May 11 00:38:58 2016 +0300
@@ -31,7 +31,6 @@
#include "memory/iterator.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
-#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "utilities/hashtable.inline.hpp"
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Wed May 11 00:38:58 2016 +0300
@@ -45,7 +45,6 @@
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
#include "oops/typeArrayOop.hpp"
-#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "runtime/fieldDescriptor.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.hpp"
--- a/hotspot/src/share/vm/classfile/modules.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/classfile/modules.cpp Wed May 11 00:38:58 2016 +0300
@@ -133,68 +133,31 @@
return NULL;
}
-// Check if -Xpatch:<dirs> was specified. If so, prepend each <dir>/module_name,
-// if it exists, to bootpath so boot loader can find the class files. Also, if
-// using exploded modules, append <java.home>/modules/module_name, if it exists,
-// to bootpath so that its class files can be found by the boot loader.
-static void add_to_boot_loader_list(char *module_name, TRAPS) {
- // java.base should be handled by argument parsing.
+// If using exploded build, append <java.home>/modules/module_name, if it exists,
+// to the system boot class path in order for the boot loader to locate class files.
+static void add_to_exploded_build_list(char *module_name, TRAPS) {
+ assert(!ClassLoader::has_jimage(), "Exploded build not applicable");
+ // java.base is handled by os::set_boot_path
assert(strcmp(module_name, "java.base") != 0, "Unexpected java.base module name");
+
char file_sep = os::file_separator()[0];
size_t module_len = strlen(module_name);
- // If -Xpatch is set then add <patch-dir>/module_name paths.
- char** patch_dirs = Arguments::patch_dirs();
- if (patch_dirs != NULL) {
- int dir_count = Arguments::patch_dirs_count();
- for (int x = 0; x < dir_count; x++) {
- // Really shouldn't be NULL, but check can't hurt
- if (patch_dirs[x] != NULL) {
- size_t len = strlen(patch_dirs[x]);
- if (len != 0) { // Ignore empty strings.
- len = len + module_len + 2;
- char* prefix_path = NEW_C_HEAP_ARRAY(char, len, mtInternal);
- jio_snprintf(prefix_path, len, "%s%c%s", patch_dirs[x], file_sep, module_name);
-
- // See if Xpatch module path exists.
- struct stat st;
- if ((os::stat(prefix_path, &st) != 0)) {
- FREE_C_HEAP_ARRAY(char, prefix_path);
- } else {
- {
- HandleMark hm;
- Handle loader_lock = Handle(THREAD, SystemDictionary::system_loader_lock());
- ObjectLocker ol(loader_lock, THREAD);
- ClassLoader::prepend_to_list(prefix_path);
- }
- log_info(class, load)("opened: -Xpatch %s", prefix_path);
- }
- }
- }
- }
- }
-
- // If "modules" jimage does not exist then assume exploded form
- // ${java.home}/modules/<module-name>
- char* path = NULL;
- if (!ClassLoader::has_jimage()) {
- const char* home = Arguments::get_java_home();
- size_t len = strlen(home) + module_len + 32;
- path = NEW_C_HEAP_ARRAY(char, len, mtInternal);
- jio_snprintf(path, len, "%s%cmodules%c%s", home, file_sep, file_sep, module_name);
- struct stat st;
- // See if exploded module path exists.
- if ((os::stat(path, &st) != 0)) {
- FREE_C_HEAP_ARRAY(char, path);
- path = NULL;
- }
+ const char* home = Arguments::get_java_home();
+ size_t len = strlen(home) + module_len + 32;
+ char* path = NEW_C_HEAP_ARRAY(char, len, mtInternal);
+ jio_snprintf(path, len, "%s%cmodules%c%s", home, file_sep, file_sep, module_name);
+ struct stat st;
+ // See if exploded module path exists
+ if ((os::stat(path, &st) != 0)) {
+ FREE_C_HEAP_ARRAY(char, path);
+ path = NULL;
}
if (path != NULL) {
HandleMark hm;
Handle loader_lock = Handle(THREAD, SystemDictionary::system_loader_lock());
ObjectLocker ol(loader_lock, THREAD);
-
log_info(class, load)("opened: %s", path);
ClassLoader::add_to_list(path);
}
@@ -498,13 +461,12 @@
}
}
- if (loader == NULL && !Universe::is_module_initialized()) {
- // Now that the module is defined, if it is in the bootloader, make sure that
- // its classes can be found. Check if -Xpatch:<path> was specified. If
- // so prepend <path>/module_name, if it exists, to bootpath. Also, if using
- // exploded modules, prepend <java.home>/modules/module_name, if it exists,
- // to bootpath.
- add_to_boot_loader_list(module_name, CHECK);
+ // If the module is defined to the boot loader and an exploded build is being
+ // used, prepend <java.home>/modules/modules_name, if it exists, to the system boot class path.
+ if (loader == NULL &&
+ !Universe::is_module_initialized() &&
+ !ClassLoader::has_jimage()) {
+ add_to_exploded_build_list(module_name, CHECK);
}
}
--- a/hotspot/src/share/vm/classfile/vmSymbols.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/classfile/vmSymbols.cpp Wed May 11 00:38:58 2016 +0300
@@ -580,20 +580,6 @@
case vmIntrinsics::_putLongOpaque:
case vmIntrinsics::_putFloatOpaque:
case vmIntrinsics::_putDoubleOpaque:
- case vmIntrinsics::_getByte_raw:
- case vmIntrinsics::_getShort_raw:
- case vmIntrinsics::_getChar_raw:
- case vmIntrinsics::_getInt_raw:
- case vmIntrinsics::_getLong_raw:
- case vmIntrinsics::_getFloat_raw:
- case vmIntrinsics::_getDouble_raw:
- case vmIntrinsics::_putByte_raw:
- case vmIntrinsics::_putShort_raw:
- case vmIntrinsics::_putChar_raw:
- case vmIntrinsics::_putInt_raw:
- case vmIntrinsics::_putLong_raw:
- case vmIntrinsics::_putFloat_raw:
- case vmIntrinsics::_putDouble_raw:
case vmIntrinsics::_getAndAddInt:
case vmIntrinsics::_getAndAddLong:
case vmIntrinsics::_getAndSetInt:
@@ -634,8 +620,6 @@
case vmIntrinsics::_putIntUnaligned:
case vmIntrinsics::_putLongUnaligned:
case vmIntrinsics::_allocateInstance:
- case vmIntrinsics::_getAddress_raw:
- case vmIntrinsics::_putAddress_raw:
if (!InlineUnsafeOps || !UseUnalignedAccesses) return true;
break;
case vmIntrinsics::_hashCode:
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Wed May 11 00:38:58 2016 +0300
@@ -1232,43 +1232,6 @@
do_intrinsic(_putIntUnaligned, jdk_internal_misc_Unsafe, putIntUnaligned_name, putInt_signature, F_R) \
do_intrinsic(_putLongUnaligned, jdk_internal_misc_Unsafe, putLongUnaligned_name, putLong_signature, F_R) \
\
- /* %%% these are redundant except perhaps for getAddress, but Unsafe has native methods for them */ \
- do_signature(getByte_raw_signature, "(J)B") \
- do_signature(putByte_raw_signature, "(JB)V") \
- do_signature(getShort_raw_signature, "(J)S") \
- do_signature(putShort_raw_signature, "(JS)V") \
- do_signature(getChar_raw_signature, "(J)C") \
- do_signature(putChar_raw_signature, "(JC)V") \
- do_signature(putInt_raw_signature, "(JI)V") \
- do_alias(getLong_raw_signature, /*(J)J*/ long_long_signature) \
- do_alias(putLong_raw_signature, /*(JJ)V*/ long_long_void_signature) \
- do_signature(getFloat_raw_signature, "(J)F") \
- do_signature(putFloat_raw_signature, "(JF)V") \
- do_alias(getDouble_raw_signature, /*(J)D*/ long_double_signature) \
- do_signature(putDouble_raw_signature, "(JD)V") \
- do_alias(getAddress_raw_signature, /*(J)J*/ long_long_signature) \
- do_alias(putAddress_raw_signature, /*(JJ)V*/ long_long_void_signature) \
- \
- do_name( getAddress_name, "getAddress") \
- do_name( putAddress_name, "putAddress") \
- \
- do_intrinsic(_getByte_raw, jdk_internal_misc_Unsafe, getByte_name, getByte_raw_signature, F_R) \
- do_intrinsic(_getShort_raw, jdk_internal_misc_Unsafe, getShort_name, getShort_raw_signature, F_R) \
- do_intrinsic(_getChar_raw, jdk_internal_misc_Unsafe, getChar_name, getChar_raw_signature, F_R) \
- do_intrinsic(_getInt_raw, jdk_internal_misc_Unsafe, getInt_name, long_int_signature, F_R) \
- do_intrinsic(_getLong_raw, jdk_internal_misc_Unsafe, getLong_name, getLong_raw_signature, F_R) \
- do_intrinsic(_getFloat_raw, jdk_internal_misc_Unsafe, getFloat_name, getFloat_raw_signature, F_R) \
- do_intrinsic(_getDouble_raw, jdk_internal_misc_Unsafe, getDouble_name, getDouble_raw_signature, F_R) \
- do_intrinsic(_getAddress_raw, jdk_internal_misc_Unsafe, getAddress_name, getAddress_raw_signature, F_R) \
- do_intrinsic(_putByte_raw, jdk_internal_misc_Unsafe, putByte_name, putByte_raw_signature, F_R) \
- do_intrinsic(_putShort_raw, jdk_internal_misc_Unsafe, putShort_name, putShort_raw_signature, F_R) \
- do_intrinsic(_putChar_raw, jdk_internal_misc_Unsafe, putChar_name, putChar_raw_signature, F_R) \
- do_intrinsic(_putInt_raw, jdk_internal_misc_Unsafe, putInt_name, putInt_raw_signature, F_R) \
- do_intrinsic(_putLong_raw, jdk_internal_misc_Unsafe, putLong_name, putLong_raw_signature, F_R) \
- do_intrinsic(_putFloat_raw, jdk_internal_misc_Unsafe, putFloat_name, putFloat_raw_signature, F_R) \
- do_intrinsic(_putDouble_raw, jdk_internal_misc_Unsafe, putDouble_name, putDouble_raw_signature, F_R) \
- do_intrinsic(_putAddress_raw, jdk_internal_misc_Unsafe, putAddress_name, putAddress_raw_signature, F_R) \
- \
do_signature(compareAndSwapObject_signature, "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z") \
do_signature(compareAndExchangeObject_signature, "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;") \
do_signature(compareAndSwapLong_signature, "(Ljava/lang/Object;JJJ)Z") \
--- a/hotspot/src/share/vm/code/nmethod.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/code/nmethod.cpp Wed May 11 00:38:58 2016 +0300
@@ -36,10 +36,10 @@
#include "compiler/directivesParser.hpp"
#include "compiler/disassembler.hpp"
#include "interpreter/bytecode.hpp"
+#include "logging/log.hpp"
#include "memory/resourceArea.hpp"
#include "oops/methodData.hpp"
#include "oops/oop.inline.hpp"
-#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "prims/jvmtiImpl.hpp"
#include "runtime/atomic.inline.hpp"
#include "runtime/orderAccess.inline.hpp"
@@ -2001,15 +2001,18 @@
Method* method = deps.method_argument(0);
for (int j = 0; j < dependee_methods->length(); j++) {
if (dependee_methods->at(j) == method) {
- // RC_TRACE macro has an embedded ResourceMark
- RC_TRACE(0x01000000,
- ("Found evol dependency of nmethod %s.%s(%s) compile_id=%d on method %s.%s(%s)",
- _method->method_holder()->external_name(),
- _method->name()->as_C_string(),
- _method->signature()->as_C_string(), compile_id(),
- method->method_holder()->external_name(),
- method->name()->as_C_string(),
- method->signature()->as_C_string()));
+ if (log_is_enabled(Debug, redefine, class, nmethod)) {
+ ResourceMark rm;
+ log_debug(redefine, class, nmethod)
+ ("Found evol dependency of nmethod %s.%s(%s) compile_id=%d on method %s.%s(%s)",
+ _method->method_holder()->external_name(),
+ _method->name()->as_C_string(),
+ _method->signature()->as_C_string(),
+ compile_id(),
+ method->method_holder()->external_name(),
+ method->name()->as_C_string(),
+ method->signature()->as_C_string());
+ }
if (TraceDependencies || LogCompilation)
deps.log_dependency(dependee);
return true;
--- a/hotspot/src/share/vm/gc/g1/g1Analytics.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1Analytics.cpp Wed May 11 00:38:58 2016 +0300
@@ -284,6 +284,10 @@
}
}
+double G1Analytics::predict_cost_per_byte_ms() const {
+ return get_new_prediction(_cost_per_byte_ms_seq);
+}
+
double G1Analytics::predict_constant_other_time_ms() const {
return get_new_prediction(_constant_other_time_ms_seq);
}
@@ -326,4 +330,3 @@
void G1Analytics::report_concurrent_mark_cleanup_times_ms(double ms) {
_concurrent_mark_cleanup_times_ms->add(ms);
}
-
--- a/hotspot/src/share/vm/gc/g1/g1Analytics.hpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1Analytics.hpp Wed May 11 00:38:58 2016 +0300
@@ -149,6 +149,8 @@
size_t predict_rs_lengths() const;
size_t predict_pending_cards() const;
+ double predict_cost_per_byte_ms() const;
+
// Add a new GC of the given duration and end time to the record.
void update_recent_gc_times(double end_time_sec, double elapsed_ms);
void compute_pause_time_ratio(double interval_ms, double pause_time_ms);
--- a/hotspot/src/share/vm/gc/parallel/gcTaskManager.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/gc/parallel/gcTaskManager.cpp Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -25,8 +25,8 @@
#include "precompiled.hpp"
#include "gc/parallel/gcTaskManager.hpp"
#include "gc/parallel/gcTaskThread.hpp"
-#include "gc/shared/adaptiveSizePolicy.hpp"
#include "gc/shared/gcId.hpp"
+#include "gc/shared/workerManager.hpp"
#include "logging/log.hpp"
#include "memory/allocation.hpp"
#include "memory/allocation.inline.hpp"
@@ -34,6 +34,7 @@
#include "runtime/mutex.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/orderAccess.inline.hpp"
+#include "runtime/os.hpp"
//
// GCTask
@@ -372,10 +373,28 @@
GCTaskManager::GCTaskManager(uint workers) :
_workers(workers),
_active_workers(0),
- _idle_workers(0) {
+ _idle_workers(0),
+ _created_workers(0) {
initialize();
}
+GCTaskThread* GCTaskManager::install_worker(uint t) {
+ GCTaskThread* new_worker = GCTaskThread::create(this, t, _processor_assignment[t]);
+ set_thread(t, new_worker);
+ return new_worker;
+}
+
+void GCTaskManager::add_workers(bool initializing) {
+ os::ThreadType worker_type = os::pgc_thread;
+ _created_workers = WorkerManager::add_workers(this,
+ _active_workers,
+ (uint) _workers,
+ _created_workers,
+ worker_type,
+ initializing);
+ _active_workers = MIN2(_created_workers, _active_workers);
+}
+
void GCTaskManager::initialize() {
if (TraceGCTaskManager) {
tty->print_cr("GCTaskManager::initialize: workers: %u", workers());
@@ -394,28 +413,30 @@
// Set up worker threads.
// Distribute the workers among the available processors,
// unless we were told not to, or if the os doesn't want to.
- uint* processor_assignment = NEW_C_HEAP_ARRAY(uint, workers(), mtGC);
+ _processor_assignment = NEW_C_HEAP_ARRAY(uint, workers(), mtGC);
if (!BindGCTaskThreadsToCPUs ||
- !os::distribute_processes(workers(), processor_assignment)) {
+ !os::distribute_processes(workers(), _processor_assignment)) {
for (uint a = 0; a < workers(); a += 1) {
- processor_assignment[a] = sentinel_worker();
+ _processor_assignment[a] = sentinel_worker();
}
}
+
_thread = NEW_C_HEAP_ARRAY(GCTaskThread*, workers(), mtGC);
- for (uint t = 0; t < workers(); t += 1) {
- set_thread(t, GCTaskThread::create(this, t, processor_assignment[t]));
+ _active_workers = ParallelGCThreads;
+ if (UseDynamicNumberOfGCThreads && !FLAG_IS_CMDLINE(ParallelGCThreads)) {
+ _active_workers = 1U;
}
+
Log(gc, task, thread) log;
if (log.is_trace()) {
ResourceMark rm;
outputStream* out = log.trace_stream();
out->print("GCTaskManager::initialize: distribution:");
for (uint t = 0; t < workers(); t += 1) {
- out->print(" %u", processor_assignment[t]);
+ out->print(" %u", _processor_assignment[t]);
}
out->cr();
}
- FREE_C_HEAP_ARRAY(uint, processor_assignment);
}
reset_busy_workers();
set_unblocked();
@@ -426,9 +447,8 @@
reset_completed_tasks();
reset_barriers();
reset_emptied_queue();
- for (uint s = 0; s < workers(); s += 1) {
- thread(s)->start();
- }
+
+ add_workers(true);
}
GCTaskManager::~GCTaskManager() {
@@ -437,13 +457,17 @@
NoopGCTask::destroy(_noop_task);
_noop_task = NULL;
if (_thread != NULL) {
- for (uint i = 0; i < workers(); i += 1) {
+ for (uint i = 0; i < created_workers(); i += 1) {
GCTaskThread::destroy(thread(i));
set_thread(i, NULL);
}
FREE_C_HEAP_ARRAY(GCTaskThread*, _thread);
_thread = NULL;
}
+ if (_processor_assignment != NULL) {
+ FREE_C_HEAP_ARRAY(uint, _processor_assignment);
+ _processor_assignment = NULL;
+ }
if (_resource_flag != NULL) {
FREE_C_HEAP_ARRAY(bool, _resource_flag);
_resource_flag = NULL;
@@ -470,6 +494,9 @@
"all_workers_active() is incorrect: "
"active %d ParallelGCThreads %u", active_workers(),
ParallelGCThreads);
+ _active_workers = MIN2(_active_workers, _workers);
+ // "add_workers" does not guarantee any additional workers
+ add_workers(false);
log_trace(gc, task)("GCTaskManager::set_active_gang(): "
"all_workers_active() %d workers %d "
"active %d ParallelGCThreads %u",
@@ -499,7 +526,7 @@
// is starting). Try later to release enough idle_workers
// to allow the desired number of active_workers.
more_inactive_workers =
- workers() - active_workers() - idle_workers();
+ created_workers() - active_workers() - idle_workers();
if (more_inactive_workers < 0) {
int reduced_active_workers = active_workers() + more_inactive_workers;
set_active_workers(reduced_active_workers);
@@ -507,7 +534,7 @@
}
log_trace(gc, task)("JT: %d workers %d active %d idle %d more %d",
Threads::number_of_non_daemon_threads(),
- workers(),
+ created_workers(),
active_workers(),
idle_workers(),
more_inactive_workers);
@@ -517,7 +544,7 @@
q->enqueue(IdleGCTask::create_on_c_heap());
increment_idle_workers();
}
- assert(workers() == active_workers() + idle_workers(),
+ assert(created_workers() == active_workers() + idle_workers(),
"total workers should equal active + inactive");
add_list(q);
// GCTaskQueue* q was created in a ResourceArea so a
@@ -539,14 +566,15 @@
if (!log_is_enabled(Debug, gc, task, time)) {
return;
}
- for(uint i=0; i<ParallelGCThreads; i++) {
+ uint num_thr = created_workers();
+ for(uint i=0; i < num_thr; i++) {
GCTaskThread* t = thread(i);
t->print_task_time_stamps();
}
}
void GCTaskManager::print_threads_on(outputStream* st) {
- uint num_thr = workers();
+ uint num_thr = created_workers();
for (uint i = 0; i < num_thr; i++) {
thread(i)->print_on(st);
st->cr();
@@ -555,19 +583,20 @@
void GCTaskManager::threads_do(ThreadClosure* tc) {
assert(tc != NULL, "Null ThreadClosure");
- uint num_thr = workers();
+ uint num_thr = created_workers();
for (uint i = 0; i < num_thr; i++) {
tc->do_thread(thread(i));
}
}
GCTaskThread* GCTaskManager::thread(uint which) {
- assert(which < workers(), "index out of bounds");
+ assert(which < created_workers(), "index out of bounds");
assert(_thread[which] != NULL, "shouldn't have null thread");
return _thread[which];
}
void GCTaskManager::set_thread(uint which, GCTaskThread* value) {
+ // "_created_workers" may not have been updated yet so use workers()
assert(which < workers(), "index out of bounds");
assert(value != NULL, "shouldn't have null thread");
_thread[which] = value;
@@ -728,7 +757,7 @@
void GCTaskManager::release_all_resources() {
// If you want this to be done atomically, do it in a WaitForBarrierGCTask.
- for (uint i = 0; i < workers(); i += 1) {
+ for (uint i = 0; i < created_workers(); i += 1) {
set_resource_flag(i, true);
}
}
--- a/hotspot/src/share/vm/gc/parallel/gcTaskManager.hpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/gc/parallel/gcTaskManager.hpp Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -370,6 +370,7 @@
Monitor* _monitor; // Notification of changes.
SynchronizedGCTaskQueue* _queue; // Queue of tasks.
GCTaskThread** _thread; // Array of worker threads.
+ uint _created_workers; // Number of workers created.
uint _active_workers; // Number of active workers.
uint _busy_workers; // Number of busy workers.
uint _blocking_worker; // The worker that's blocking.
@@ -381,6 +382,8 @@
NoopGCTask* _noop_task; // The NoopGCTask instance.
WaitHelper _wait_helper; // Used by inactive worker
volatile uint _idle_workers; // Number of idled workers
+ uint* _processor_assignment; // Worker to cpu mappings. May
+ // be used lazily
public:
// Factory create and destroy methods.
static GCTaskManager* create(uint workers) {
@@ -546,6 +549,13 @@
uint active_workers() const {
return _active_workers;
}
+ uint created_workers() const {
+ return _created_workers;
+ }
+ // Create a GC worker and install into GCTaskManager
+ GCTaskThread* install_worker(uint worker_id);
+ // Add GC workers as needed.
+ void add_workers(bool initializing);
};
//
--- a/hotspot/src/share/vm/gc/parallel/gcTaskThread.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/gc/parallel/gcTaskThread.cpp Wed May 11 00:38:58 2016 +0300
@@ -44,9 +44,6 @@
_time_stamps(NULL),
_time_stamp_index(0)
{
- if (!os::create_thread(this, os::pgc_thread))
- vm_exit_out_of_memory(0, OOM_MALLOC_ERROR, "Cannot create GC thread. Out of system resources.");
-
set_id(which);
set_name("ParGC Thread#%d", which);
}
@@ -57,10 +54,6 @@
}
}
-void GCTaskThread::start() {
- os::start_thread(this);
-}
-
GCTaskTimeStamp* GCTaskThread::time_stamp_at(uint index) {
guarantee(index < GCTaskTimeStampEntries, "increase GCTaskTimeStampEntries");
if (_time_stamps == NULL) {
--- a/hotspot/src/share/vm/gc/parallel/gcTaskThread.hpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/gc/parallel/gcTaskThread.hpp Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -48,13 +48,13 @@
bool _is_working; // True if participating in GC tasks
- public:
// Factory create and destroy methods.
static GCTaskThread* create(GCTaskManager* manager,
uint which,
uint processor_id) {
return new GCTaskThread(manager, which, processor_id);
}
+ public:
static void destroy(GCTaskThread* manager) {
if (manager != NULL) {
delete manager;
@@ -65,8 +65,6 @@
return true;
}
virtual void run();
- // Methods.
- void start();
void print_task_time_stamps();
--- a/hotspot/src/share/vm/gc/parallel/pcTasks.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/gc/parallel/pcTasks.cpp Wed May 11 00:38:58 2016 +0300
@@ -220,13 +220,13 @@
}
//
-// StealRegionCompactionTask
+// CompactionWithStealingTask
//
-StealRegionCompactionTask::StealRegionCompactionTask(ParallelTaskTerminator* t):
+CompactionWithStealingTask::CompactionWithStealingTask(ParallelTaskTerminator* t):
_terminator(t) {}
-void StealRegionCompactionTask::do_it(GCTaskManager* manager, uint which) {
+void CompactionWithStealingTask::do_it(GCTaskManager* manager, uint which) {
assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
ParCompactionManager* cm =
--- a/hotspot/src/share/vm/gc/parallel/pcTasks.hpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/gc/parallel/pcTasks.hpp Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -195,16 +195,16 @@
};
//
-// StealRegionCompactionTask
+// CompactionWithStealingTask
//
// This task is used to distribute work to idle threads.
//
-class StealRegionCompactionTask : public GCTask {
+class CompactionWithStealingTask : public GCTask {
private:
ParallelTaskTerminator* const _terminator;
public:
- StealRegionCompactionTask(ParallelTaskTerminator* t);
+ CompactionWithStealingTask(ParallelTaskTerminator* t);
char* name() { return (char *)"steal-region-task"; }
ParallelTaskTerminator* terminator() { return _terminator; }
--- a/hotspot/src/share/vm/gc/parallel/psCompactionManager.hpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psCompactionManager.hpp Wed May 11 00:38:58 2016 +0300
@@ -40,7 +40,7 @@
friend class ParallelTaskTerminator;
friend class ParMarkBitMap;
friend class PSParallelCompact;
- friend class StealRegionCompactionTask;
+ friend class CompactionWithStealingTask;
friend class UpdateAndFillClosure;
friend class RefProcTaskExecutor;
friend class IdleGCTask;
--- a/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp Wed May 11 00:38:58 2016 +0300
@@ -2371,7 +2371,7 @@
// Once a thread has drained it's stack, it should try to steal regions from
// other threads.
for (uint j = 0; j < parallel_gc_threads; j++) {
- q->enqueue(new StealRegionCompactionTask(terminator_ptr));
+ q->enqueue(new CompactionWithStealingTask(terminator_ptr));
}
}
--- a/hotspot/src/share/vm/gc/shared/adaptiveSizePolicy.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/gc/shared/adaptiveSizePolicy.cpp Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -130,10 +130,7 @@
uintx max_active_workers =
MAX2(active_workers_by_JT, active_workers_by_heap_size);
- // Limit the number of workers to the the number created,
- // (workers()).
- new_active_workers = MIN2(max_active_workers,
- (uintx) total_workers);
+ new_active_workers = MIN2(max_active_workers, (uintx) total_workers);
// Increase GC workers instantly but decrease them more
// slowly.
@@ -167,7 +164,7 @@
"Jiggled active workers too much");
}
- log_trace(gc, task)("GCTaskManager::calc_default_active_workers() : "
+ log_trace(gc, task)("GCTaskManager::calc_default_active_workers() : "
"active_workers(): " UINTX_FORMAT " new_active_workers: " UINTX_FORMAT " "
"prev_active_workers: " UINTX_FORMAT "\n"
" active_workers_by_JT: " UINTX_FORMAT " active_workers_by_heap_size: " UINTX_FORMAT,
--- a/hotspot/src/share/vm/gc/shared/adaptiveSizePolicy.hpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/gc/shared/adaptiveSizePolicy.hpp Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/shared/workerManager.hpp Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_SHARED_WORKERMANAGER_HPP
+#define SHARE_VM_GC_SHARED_WORKERMANAGER_HPP
+
+#include "gc/shared/adaptiveSizePolicy.hpp"
+
+class WorkerManager : public AllStatic {
+ public:
+ // Create additional workers as needed.
+ // active_workers - number of workers being requested for an upcoming
+ // parallel task.
+ // total_workers - total number of workers. This is the maximum
+ // number possible.
+ // created_workers - number of workers already created. This maybe
+ // less than, equal to, or greater than active workers. If greater than
+ // or equal to active_workers, nothing is done.
+ // worker_type - type of thread.
+ // initializing - true if this is called to get the initial number of
+ // GC workers.
+ // If initializing is true, do a vm exit if the workers cannot be created.
+ // The initializing = true case is for JVM start up and failing to
+ // create all the worker at start should considered a problem so exit.
+ // If initializing = false, there are already some number of worker
+ // threads and a failure would not be optimal but should not be fatal.
+ template <class WorkerType>
+ static uint add_workers (WorkerType* holder,
+ uint active_workers,
+ uint total_workers,
+ uint created_workers,
+ os::ThreadType worker_type,
+ bool initializing) {
+ uint start = created_workers;
+ uint end = MIN2(active_workers, total_workers);
+ for (uint worker_id = start; worker_id < end; worker_id += 1) {
+ WorkerThread* new_worker = holder->install_worker(worker_id);
+ assert(new_worker != NULL, "Failed to allocate GangWorker");
+ if (new_worker == NULL || !os::create_thread(new_worker, worker_type)) {
+ if(initializing) {
+ vm_exit_out_of_memory(0, OOM_MALLOC_ERROR,
+ "Cannot create worker GC thread. Out of system resources.");
+ }
+ }
+ created_workers++;
+ os::start_thread(new_worker);
+ }
+
+ log_trace(gc, task)("AdaptiveSizePolicy::add_workers() : "
+ "active_workers: %u created_workers: %u",
+ active_workers, created_workers);
+
+ return created_workers;
+ }
+};
+#endif // SHARE_VM_GC_SHARED_WORKERMANAGER_HPP
--- a/hotspot/src/share/vm/gc/shared/workgroup.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/gc/shared/workgroup.cpp Wed May 11 00:38:58 2016 +0300
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "gc/shared/gcId.hpp"
#include "gc/shared/workgroup.hpp"
+#include "gc/shared/workerManager.hpp"
#include "memory/allocation.hpp"
#include "memory/allocation.inline.hpp"
#include "runtime/atomic.inline.hpp"
@@ -35,37 +36,45 @@
// Definitions of WorkGang methods.
// The current implementation will exit if the allocation
-// of any worker fails. Still, return a boolean so that
-// a future implementation can possibly do a partial
-// initialization of the workers and report such to the
-// caller.
-bool AbstractWorkGang::initialize_workers() {
+// of any worker fails.
+void AbstractWorkGang::initialize_workers() {
log_develop_trace(gc, workgang)("Constructing work gang %s with %u threads", name(), total_workers());
_workers = NEW_C_HEAP_ARRAY(AbstractGangWorker*, total_workers(), mtInternal);
if (_workers == NULL) {
vm_exit_out_of_memory(0, OOM_MALLOC_ERROR, "Cannot create GangWorker array.");
- return false;
+ }
+
+ _active_workers = ParallelGCThreads;
+ if (UseDynamicNumberOfGCThreads && !FLAG_IS_CMDLINE(ParallelGCThreads)) {
+ _active_workers = 1U;
}
+
+ add_workers(true);
+}
+
+
+AbstractGangWorker* AbstractWorkGang::install_worker(uint worker_id) {
+ AbstractGangWorker* new_worker = allocate_worker(worker_id);
+ set_thread(worker_id, new_worker);
+ return new_worker;
+}
+
+void AbstractWorkGang::add_workers(bool initializing) {
+
os::ThreadType worker_type;
if (are_ConcurrentGC_threads()) {
worker_type = os::cgc_thread;
} else {
worker_type = os::pgc_thread;
}
- for (uint worker = 0; worker < total_workers(); worker += 1) {
- AbstractGangWorker* new_worker = allocate_worker(worker);
- assert(new_worker != NULL, "Failed to allocate GangWorker");
- _workers[worker] = new_worker;
- if (new_worker == NULL || !os::create_thread(new_worker, worker_type)) {
- vm_exit_out_of_memory(0, OOM_MALLOC_ERROR,
- "Cannot create worker GC thread. Out of system resources.");
- return false;
- }
- if (!DisableStartThread) {
- os::start_thread(new_worker);
- }
- }
- return true;
+
+ _created_workers = WorkerManager::add_workers(this,
+ _active_workers,
+ _total_workers,
+ _created_workers,
+ worker_type,
+ initializing);
+ _active_workers = MIN2(_created_workers, _active_workers);
}
AbstractGangWorker* AbstractWorkGang::worker(uint i) const {
@@ -79,7 +88,7 @@
}
void AbstractWorkGang::print_worker_threads_on(outputStream* st) const {
- uint workers = total_workers();
+ uint workers = created_workers();
for (uint i = 0; i < workers; i++) {
worker(i)->print_on(st);
st->cr();
@@ -88,7 +97,7 @@
void AbstractWorkGang::threads_do(ThreadClosure* tc) const {
assert(tc != NULL, "Null ThreadClosure");
- uint workers = total_workers();
+ uint workers = created_workers();
for (uint i = 0; i < workers; i++) {
tc->do_thread(worker(i));
}
--- a/hotspot/src/share/vm/gc/shared/workgroup.hpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/gc/shared/workgroup.hpp Wed May 11 00:38:58 2016 +0300
@@ -112,6 +112,8 @@
uint _total_workers;
// The currently active workers in this gang.
uint _active_workers;
+ // The count of created workers in the gang.
+ uint _created_workers;
// Printing support.
const char* _name;
@@ -120,23 +122,32 @@
const bool _are_GC_task_threads;
const bool _are_ConcurrentGC_threads;
+ void set_thread(uint worker_id, AbstractGangWorker* worker) {
+ _workers[worker_id] = worker;
+ }
+
public:
AbstractWorkGang(const char* name, uint workers, bool are_GC_task_threads, bool are_ConcurrentGC_threads) :
_name(name),
_total_workers(workers),
_active_workers(UseDynamicNumberOfGCThreads ? 1U : workers),
+ _created_workers(0),
_are_GC_task_threads(are_GC_task_threads),
_are_ConcurrentGC_threads(are_ConcurrentGC_threads)
{ }
// Initialize workers in the gang. Return true if initialization succeeded.
- bool initialize_workers();
+ void initialize_workers();
bool are_GC_task_threads() const { return _are_GC_task_threads; }
bool are_ConcurrentGC_threads() const { return _are_ConcurrentGC_threads; }
uint total_workers() const { return _total_workers; }
+ uint created_workers() const {
+ return _created_workers;
+ }
+
virtual uint active_workers() const {
assert(_active_workers <= _total_workers,
"_active_workers: %u > _total_workers: %u", _active_workers, _total_workers);
@@ -144,22 +155,29 @@
"Unless dynamic should use total workers");
return _active_workers;
}
+
void set_active_workers(uint v) {
assert(v <= _total_workers,
"Trying to set more workers active than there are");
_active_workers = MIN2(v, _total_workers);
+ add_workers(false /* exit_on_failure */);
assert(v != 0, "Trying to set active workers to 0");
- _active_workers = MAX2(1U, _active_workers);
assert(UseDynamicNumberOfGCThreads || _active_workers == _total_workers,
"Unless dynamic should use total workers");
log_info(gc, task)("GC Workers: using %d out of %d", _active_workers, _total_workers);
}
+ // Add GC workers as needed.
+ void add_workers(bool initializing);
+
// Return the Ith worker.
AbstractGangWorker* worker(uint i) const;
void threads_do(ThreadClosure* tc) const;
+ // Create a GC worker and install it into the work gang.
+ virtual AbstractGangWorker* install_worker(uint which);
+
// Debugging.
const char* name() const { return _name; }
--- a/hotspot/src/share/vm/interpreter/oopMapCache.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/interpreter/oopMapCache.cpp Wed May 11 00:38:58 2016 +0300
@@ -24,10 +24,10 @@
#include "precompiled.hpp"
#include "interpreter/oopMapCache.hpp"
+#include "logging/log.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
-#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/signature.hpp"
@@ -469,10 +469,12 @@
if (!_array[i].is_empty() && _array[i].method()->is_old()) {
// Cache entry is occupied by an old redefined method and we don't want
// to pin it down so flush the entry.
- RC_TRACE(0x08000000, ("flush: %s(%s): cached entry @%d",
- _array[i].method()->name()->as_C_string(),
- _array[i].method()->signature()->as_C_string(), i));
-
+ if (log_is_enabled(Debug, redefine, class, oopmap)) {
+ ResourceMark rm;
+ log_debug(redefine, class, oopmap)
+ ("flush: %s(%s): cached entry @%d",
+ _array[i].method()->name()->as_C_string(), _array[i].method()->signature()->as_C_string(), i);
+ }
_array[i].flush();
}
}
--- a/hotspot/src/share/vm/logging/logTag.hpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/logging/logTag.hpp Wed May 11 00:38:58 2016 +0300
@@ -32,23 +32,28 @@
// (The tags 'all', 'disable' and 'help' are special tags that can
// not be used in log calls, and should not be listed below.)
#define LOG_TAG_LIST \
- LOG_TAG(alloc) \
+ LOG_TAG(add) \
LOG_TAG(age) \
+ LOG_TAG(alloc) \
LOG_TAG(arguments) \
+ LOG_TAG(annotation) \
LOG_TAG(barrier) \
LOG_TAG(biasedlocking) \
LOG_TAG(bot) \
+ LOG_TAG(breakpoint) \
LOG_TAG(census) \
LOG_TAG(class) \
LOG_TAG(classhisto) \
LOG_TAG(cleanup) \
LOG_TAG(compaction) \
LOG_TAG(constraints) \
+ LOG_TAG(constantpool) \
LOG_TAG(coops) \
LOG_TAG(cpu) \
LOG_TAG(cset) \
LOG_TAG(data) \
LOG_TAG(defaultmethods) \
+ LOG_TAG(dump) \
LOG_TAG(ergo) \
LOG_TAG(exceptions) \
LOG_TAG(exit) \
@@ -57,6 +62,7 @@
LOG_TAG(heap) \
LOG_TAG(humongous) \
LOG_TAG(ihop) \
+ LOG_TAG(iklass) \
LOG_TAG(init) \
LOG_TAG(itables) \
LOG_TAG(jni) \
@@ -65,13 +71,20 @@
LOG_TAG(load) /* Trace all classes loaded */ \
LOG_TAG(loader) \
LOG_TAG(logging) \
+ LOG_TAG(mark) \
LOG_TAG(marking) \
+ LOG_TAG(methodcomparator) \
+ LOG_TAG(metadata) \
LOG_TAG(metaspace) \
LOG_TAG(mmu) \
LOG_TAG(modules) \
LOG_TAG(monitorinflation) \
LOG_TAG(monitormismatch) \
+ LOG_TAG(nmethod) \
+ LOG_TAG(normalize) \
LOG_TAG(objecttagging) \
+ LOG_TAG(obsolete) \
+ LOG_TAG(oopmap) \
LOG_TAG(os) \
LOG_TAG(pagesize) \
LOG_TAG(path) \
@@ -81,9 +94,11 @@
LOG_TAG(preorder) /* Trace all classes loaded in order referenced (not loaded) */ \
LOG_TAG(protectiondomain) /* "Trace protection domain verification" */ \
LOG_TAG(ref) \
+ LOG_TAG(redefine) \
LOG_TAG(refine) \
LOG_TAG(region) \
LOG_TAG(remset) \
+ LOG_TAG(purge) \
LOG_TAG(resolve) \
LOG_TAG(safepoint) \
LOG_TAG(scavenge) \
@@ -95,6 +110,8 @@
LOG_TAG(stats) \
LOG_TAG(stringdedup) \
LOG_TAG(stringtable) \
+ LOG_TAG(stackmap) \
+ LOG_TAG(subclass) \
LOG_TAG(survivor) \
LOG_TAG(sweep) \
LOG_TAG(task) \
@@ -102,6 +119,8 @@
LOG_TAG(thread) \
LOG_TAG(tlab) \
LOG_TAG(time) \
+ LOG_TAG(timer) \
+ LOG_TAG(update) \
LOG_TAG(unload) /* Trace unloading of classes */ \
LOG_TAG(verification) \
LOG_TAG(verify) \
--- a/hotspot/src/share/vm/memory/allocation.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/memory/allocation.cpp Wed May 11 00:38:58 2016 +0300
@@ -664,64 +664,6 @@
// Non-product code
#ifndef PRODUCT
-// The global operator new should never be called since it will usually indicate
-// a memory leak. Use CHeapObj as the base class of such objects to make it explicit
-// that they're allocated on the C heap.
-// Commented out in product version to avoid conflicts with third-party C++ native code.
-//
-// In C++98/03 the throwing new operators are defined with the following signature:
-//
-// void* operator new(std::size_tsize) throw(std::bad_alloc);
-// void* operator new[](std::size_tsize) throw(std::bad_alloc);
-//
-// while all the other (non-throwing) new and delete operators are defined with an empty
-// throw clause (i.e. "operator delete(void* p) throw()") which means that they do not
-// throw any exceptions (see section 18.4 of the C++ standard).
-//
-// In the new C++11/14 standard, the signature of the throwing new operators was changed
-// by completely omitting the throw clause (which effectively means they could throw any
-// exception) while all the other new/delete operators where changed to have a 'nothrow'
-// clause instead of an empty throw clause.
-//
-// Unfortunately, the support for exception specifications among C++ compilers is still
-// very fragile. While some more strict compilers like AIX xlC or HP aCC reject to
-// override the default throwing new operator with a user operator with an empty throw()
-// clause, the MS Visual C++ compiler warns for every non-empty throw clause like
-// throw(std::bad_alloc) that it will ignore the exception specification. The following
-// operator definitions have been checked to correctly work with all currently supported
-// compilers and they should be upwards compatible with C++11/14. Therefore
-// PLEASE BE CAREFUL if you change the signature of the following operators!
-
-static void * zero = (void *) 0;
-
-void* operator new(size_t size) /* throw(std::bad_alloc) */ {
- fatal("Should not call global operator new");
- return zero;
-}
-
-void* operator new [](size_t size) /* throw(std::bad_alloc) */ {
- fatal("Should not call global operator new[]");
- return zero;
-}
-
-void* operator new(size_t size, const std::nothrow_t& nothrow_constant) throw() {
- fatal("Should not call global operator new");
- return 0;
-}
-
-void* operator new [](size_t size, std::nothrow_t& nothrow_constant) throw() {
- fatal("Should not call global operator new[]");
- return 0;
-}
-
-void operator delete(void* p) throw() {
- fatal("Should not call global delete");
-}
-
-void operator delete [](void* p) throw() {
- fatal("Should not call global delete []");
-}
-
void AllocatedObj::print() const { print_on(tty); }
void AllocatedObj::print_value() const { print_value_on(tty); }
--- a/hotspot/src/share/vm/memory/filemap.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/memory/filemap.cpp Wed May 11 00:38:58 2016 +0300
@@ -881,7 +881,7 @@
return false;
}
- if (Arguments::patch_dirs() != NULL) {
+ if (Arguments::get_xpatchprefix() != NULL) {
FileMapInfo::fail_continue("The shared archive file cannot be used with -Xpatch.");
return false;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/memory/operator_new.cpp Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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/debug.hpp"
+
+#include <new>
+
+//--------------------------------------------------------------------------------------
+// Non-product code
+
+#ifndef PRODUCT
+// The global operator new should never be called since it will usually indicate
+// a memory leak. Use CHeapObj as the base class of such objects to make it explicit
+// that they're allocated on the C heap.
+// Commented out in product version to avoid conflicts with third-party C++ native code.
+//
+// In C++98/03 the throwing new operators are defined with the following signature:
+//
+// void* operator new(std::size_tsize) throw(std::bad_alloc);
+// void* operator new[](std::size_tsize) throw(std::bad_alloc);
+//
+// while all the other (non-throwing) new and delete operators are defined with an empty
+// throw clause (i.e. "operator delete(void* p) throw()") which means that they do not
+// throw any exceptions (see section 18.4 of the C++ standard).
+//
+// In the new C++11/14 standard, the signature of the throwing new operators was changed
+// by completely omitting the throw clause (which effectively means they could throw any
+// exception) while all the other new/delete operators where changed to have a 'nothrow'
+// clause instead of an empty throw clause.
+//
+// Unfortunately, the support for exception specifications among C++ compilers is still
+// very fragile. While some more strict compilers like AIX xlC or HP aCC reject to
+// override the default throwing new operator with a user operator with an empty throw()
+// clause, the MS Visual C++ compiler warns for every non-empty throw clause like
+// throw(std::bad_alloc) that it will ignore the exception specification. The following
+// operator definitions have been checked to correctly work with all currently supported
+// compilers and they should be upwards compatible with C++11/14. Therefore
+// PLEASE BE CAREFUL if you change the signature of the following operators!
+
+static void * zero = (void *) 0;
+
+void* operator new(size_t size) /* throw(std::bad_alloc) */ {
+ fatal("Should not call global operator new");
+ return zero;
+}
+
+void* operator new [](size_t size) /* throw(std::bad_alloc) */ {
+ fatal("Should not call global operator new[]");
+ return zero;
+}
+
+void* operator new(size_t size, const std::nothrow_t& nothrow_constant) throw() {
+ fatal("Should not call global operator new");
+ return 0;
+}
+
+void* operator new [](size_t size, std::nothrow_t& nothrow_constant) throw() {
+ fatal("Should not call global operator new[]");
+ return 0;
+}
+
+void operator delete(void* p) throw() {
+ fatal("Should not call global delete");
+}
+
+void operator delete [](void* p) throw() {
+ fatal("Should not call global delete []");
+}
+
+#endif // Non-product
--- a/hotspot/src/share/vm/memory/universe.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/memory/universe.cpp Wed May 11 00:38:58 2016 +0300
@@ -55,7 +55,6 @@
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/typeArrayKlass.hpp"
-#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "runtime/arguments.hpp"
#include "runtime/atomic.inline.hpp"
#include "runtime/commandLineFlagConstraintList.hpp"
--- a/hotspot/src/share/vm/oops/cpCache.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/oops/cpCache.cpp Wed May 11 00:38:58 2016 +0300
@@ -25,12 +25,12 @@
#include "precompiled.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/rewriter.hpp"
+#include "logging/log.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.inline.hpp"
#include "oops/cpCache.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
-#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/atomic.inline.hpp"
#include "runtime/handles.inline.hpp"
@@ -438,17 +438,14 @@
// match old_method so need an update
// NOTE: can't use set_f2_as_vfinal_method as it asserts on different values
_f2 = (intptr_t)new_method;
- if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
+ if (log_is_enabled(Info, redefine, class, update)) {
+ ResourceMark rm;
if (!(*trace_name_printed)) {
- // RC_TRACE_MESG macro has an embedded ResourceMark
- RC_TRACE_MESG(("adjust: name=%s",
- old_method->method_holder()->external_name()));
+ log_info(redefine, class, update)("adjust: name=%s", old_method->method_holder()->external_name());
*trace_name_printed = true;
}
- // RC_TRACE macro has an embedded ResourceMark
- RC_TRACE(0x00400000, ("cpc vf-entry update: %s(%s)",
- new_method->name()->as_C_string(),
- new_method->signature()->as_C_string()));
+ log_debug(redefine, class, update, constantpool)
+ ("cpc vf-entry update: %s(%s)", new_method->name()->as_C_string(), new_method->signature()->as_C_string());
}
return true;
}
@@ -465,17 +462,14 @@
if (_f1 == old_method) {
_f1 = new_method;
- if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
+ if (log_is_enabled(Info, redefine, class, update)) {
+ ResourceMark rm;
if (!(*trace_name_printed)) {
- // RC_TRACE_MESG macro has an embedded ResourceMark
- RC_TRACE_MESG(("adjust: name=%s",
- old_method->method_holder()->external_name()));
+ log_info(redefine, class, update)("adjust: name=%s", old_method->method_holder()->external_name());
*trace_name_printed = true;
}
- // RC_TRACE macro has an embedded ResourceMark
- RC_TRACE(0x00400000, ("cpc entry update: %s(%s)",
- new_method->name()->as_C_string(),
- new_method->signature()->as_C_string()));
+ log_debug(redefine, class, update, constantpool)
+ ("cpc entry update: %s(%s)", new_method->name()->as_C_string(), new_method->signature()->as_C_string());
}
return true;
}
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Wed May 11 00:38:58 2016 +0300
@@ -53,7 +53,6 @@
#include "oops/symbol.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/jvmtiRedefineClasses.hpp"
-#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "prims/jvmtiThreadState.hpp"
#include "prims/methodComparator.hpp"
#include "runtime/atomic.inline.hpp"
@@ -2574,17 +2573,17 @@
assert(old_method != new_method, "sanity check");
default_methods()->at_put(index, new_method);
- if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
+ if (log_is_enabled(Info, redefine, class, update)) {
+ ResourceMark rm;
if (!(*trace_name_printed)) {
- // RC_TRACE_MESG macro has an embedded ResourceMark
- RC_TRACE_MESG(("adjust: klassname=%s default methods from name=%s",
- external_name(),
- old_method->method_holder()->external_name()));
+ log_info(redefine, class, update)
+ ("adjust: klassname=%s default methods from name=%s",
+ external_name(), old_method->method_holder()->external_name());
*trace_name_printed = true;
}
- RC_TRACE(0x00100000, ("default method update: %s(%s) ",
- new_method->name()->as_C_string(),
- new_method->signature()->as_C_string()));
+ log_debug(redefine, class, update, vtables)
+ ("default method update: %s(%s) ",
+ new_method->name()->as_C_string(), new_method->signature()->as_C_string());
}
}
}
@@ -3353,8 +3352,8 @@
ClassLoaderData* loader_data = ik->class_loader_data();
assert(loader_data != NULL, "should never be null");
- // RC_TRACE macro has an embedded ResourceMark
- RC_TRACE(0x00000200, ("purge: %s: previous versions", ik->external_name()));
+ ResourceMark rm;
+ log_trace(redefine, class, iklass, purge)("%s: previous versions", ik->external_name());
// previous versions are linked together through the InstanceKlass
InstanceKlass* pv_node = ik->previous_versions();
@@ -3372,8 +3371,7 @@
// are executing. Unlink this previous_version.
// The previous version InstanceKlass is on the ClassLoaderData deallocate list
// so will be deallocated during the next phase of class unloading.
- RC_TRACE(0x00000200, ("purge: previous version " INTPTR_FORMAT " is dead",
- p2i(pv_node)));
+ log_trace(redefine, class, iklass, purge)("previous version " INTPTR_FORMAT " is dead", p2i(pv_node));
// For debugging purposes.
pv_node->set_is_scratch_class();
pv_node->class_loader_data()->add_to_deallocate_list(pv_node);
@@ -3383,8 +3381,7 @@
version++;
continue;
} else {
- RC_TRACE(0x00000200, ("purge: previous version " INTPTR_FORMAT " is alive",
- p2i(pv_node)));
+ log_trace(redefine, class, iklass, purge)("previous version " INTPTR_FORMAT " is alive", p2i(pv_node));
assert(pvcp->pool_holder() != NULL, "Constant pool with no holder");
guarantee (!loader_data->is_unloading(), "unloaded classes can't be on the stack");
live_count++;
@@ -3396,8 +3393,7 @@
// longer running.
Array<Method*>* method_refs = pv_node->methods();
if (method_refs != NULL) {
- RC_TRACE(0x00000200, ("purge: previous methods length=%d",
- method_refs->length()));
+ log_trace(redefine, class, iklass, purge)("previous methods length=%d", method_refs->length());
for (int j = 0; j < method_refs->length(); j++) {
Method* method = method_refs->at(j);
@@ -3409,11 +3405,9 @@
} else {
assert (method->is_obsolete() || method->is_running_emcp(),
"emcp method cannot run after emcp bit is cleared");
- // RC_TRACE macro has an embedded ResourceMark
- RC_TRACE(0x00000200,
+ log_trace(redefine, class, iklass, purge)
("purge: %s(%s): prev method @%d in version @%d is alive",
- method->name()->as_C_string(),
- method->signature()->as_C_string(), j, version));
+ method->name()->as_C_string(), method->signature()->as_C_string(), j, version);
}
}
}
@@ -3422,9 +3416,9 @@
pv_node = pv_node->previous_versions();
version++;
}
- RC_TRACE(0x00000200,
- ("purge: previous version stats: live=%d, deleted=%d", live_count,
- deleted_count));
+ log_trace(redefine, class, iklass, purge)
+ ("previous version stats: live=%d, deleted=%d",
+ live_count, deleted_count);
}
}
@@ -3459,9 +3453,9 @@
method->signature() == m_signature) {
// The current RedefineClasses() call has made all EMCP
// versions of this method obsolete so mark it as obsolete
- RC_TRACE(0x00000400,
- ("add: %s(%s): flush obsolete method @%d in version @%d",
- m_name->as_C_string(), m_signature->as_C_string(), k, j));
+ log_trace(redefine, class, iklass, add)
+ ("%s(%s): flush obsolete method @%d in version @%d",
+ m_name->as_C_string(), m_signature->as_C_string(), k, j);
method->set_is_obsolete();
break;
@@ -3493,9 +3487,9 @@
assert(Thread::current()->is_VM_thread(),
"only VMThread can add previous versions");
- // RC_TRACE macro has an embedded ResourceMark
- RC_TRACE(0x00000400, ("adding previous version ref for %s, EMCP_cnt=%d",
- scratch_class->external_name(), emcp_method_count));
+ ResourceMark rm;
+ log_trace(redefine, class, iklass, add)
+ ("adding previous version ref for %s, EMCP_cnt=%d", scratch_class->external_name(), emcp_method_count);
// Clean out old previous versions
purge_previous_versions(this);
@@ -3511,7 +3505,7 @@
// we don't need to add this as a previous version.
ConstantPool* cp_ref = scratch_class->constants();
if (!cp_ref->on_stack()) {
- RC_TRACE(0x00000400, ("add: scratch class not added; no methods are running"));
+ log_trace(redefine, class, iklass, add)("scratch class not added; no methods are running");
// For debugging purposes.
scratch_class->set_is_scratch_class();
scratch_class->class_loader_data()->add_to_deallocate_list(scratch_class());
@@ -3534,17 +3528,17 @@
// method may exit. If so, we would set a breakpoint in a method that
// is never reached, but this won't be noticeable to the programmer.
old_method->set_running_emcp(true);
- RC_TRACE(0x00000400, ("add: EMCP method %s is on_stack " INTPTR_FORMAT,
- old_method->name_and_sig_as_C_string(), p2i(old_method)));
+ log_trace(redefine, class, iklass, add)
+ ("EMCP method %s is on_stack " INTPTR_FORMAT, old_method->name_and_sig_as_C_string(), p2i(old_method));
} else if (!old_method->is_obsolete()) {
- RC_TRACE(0x00000400, ("add: EMCP method %s is NOT on_stack " INTPTR_FORMAT,
- old_method->name_and_sig_as_C_string(), p2i(old_method)));
+ log_trace(redefine, class, iklass, add)
+ ("EMCP method %s is NOT on_stack " INTPTR_FORMAT, old_method->name_and_sig_as_C_string(), p2i(old_method));
}
}
}
// Add previous version if any methods are still running.
- RC_TRACE(0x00000400, ("add: scratch class added; one of its methods is on_stack"));
+ log_trace(redefine, class, iklass, add)("scratch class added; one of its methods is on_stack");
assert(scratch_class->previous_versions() == NULL, "shouldn't have a previous version");
scratch_class->link_previous_versions(previous_versions());
link_previous_versions(scratch_class());
--- a/hotspot/src/share/vm/oops/klassVtable.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/oops/klassVtable.cpp Wed May 11 00:38:58 2016 +0300
@@ -34,7 +34,6 @@
#include "oops/method.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp"
-#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "runtime/arguments.hpp"
#include "runtime/handles.inline.hpp"
#include "utilities/copy.hpp"
@@ -887,19 +886,17 @@
updated_default = adjust_default_method(index, old_method, new_method);
}
- if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
+ if (log_is_enabled(Info, redefine, class, update)) {
+ ResourceMark rm;
if (!(*trace_name_printed)) {
- // RC_TRACE_MESG macro has an embedded ResourceMark
- RC_TRACE_MESG(("adjust: klassname=%s for methods from name=%s",
- klass()->external_name(),
- old_method->method_holder()->external_name()));
+ log_info(redefine, class, update)
+ ("adjust: klassname=%s for methods from name=%s",
+ klass()->external_name(), old_method->method_holder()->external_name());
*trace_name_printed = true;
}
- // RC_TRACE macro has an embedded ResourceMark
- RC_TRACE(0x00100000, ("vtable method update: %s(%s), updated default = %s",
- new_method->name()->as_C_string(),
- new_method->signature()->as_C_string(),
- updated_default ? "true" : "false"));
+ log_debug(redefine, class, update, vtables)
+ ("vtable method update: %s(%s), updated default = %s",
+ new_method->name()->as_C_string(), new_method->signature()->as_C_string(), updated_default ? "true" : "false");
}
}
}
@@ -1205,17 +1202,14 @@
ime->initialize(new_method);
- if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
+ if (log_is_enabled(Info, redefine, class, update)) {
+ ResourceMark rm;
if (!(*trace_name_printed)) {
- // RC_TRACE_MESG macro has an embedded ResourceMark
- RC_TRACE_MESG(("adjust: name=%s",
- old_method->method_holder()->external_name()));
+ log_info(redefine, class, update)("adjust: name=%s", old_method->method_holder()->external_name());
*trace_name_printed = true;
}
- // RC_TRACE macro has an embedded ResourceMark
- RC_TRACE(0x00200000, ("itable method update: %s(%s)",
- new_method->name()->as_C_string(),
- new_method->signature()->as_C_string()));
+ log_trace(redefine, class, update, itables)
+ ("itable method update: %s(%s)", new_method->name()->as_C_string(), new_method->signature()->as_C_string());
}
}
}
--- a/hotspot/src/share/vm/opto/c2compiler.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/opto/c2compiler.cpp Wed May 11 00:38:58 2016 +0300
@@ -409,22 +409,6 @@
case vmIntrinsics::_putLong:
case vmIntrinsics::_putFloat:
case vmIntrinsics::_putDouble:
- case vmIntrinsics::_getByte_raw:
- case vmIntrinsics::_getShort_raw:
- case vmIntrinsics::_getChar_raw:
- case vmIntrinsics::_getInt_raw:
- case vmIntrinsics::_getLong_raw:
- case vmIntrinsics::_getFloat_raw:
- case vmIntrinsics::_getDouble_raw:
- case vmIntrinsics::_getAddress_raw:
- case vmIntrinsics::_putByte_raw:
- case vmIntrinsics::_putShort_raw:
- case vmIntrinsics::_putChar_raw:
- case vmIntrinsics::_putInt_raw:
- case vmIntrinsics::_putLong_raw:
- case vmIntrinsics::_putFloat_raw:
- case vmIntrinsics::_putDouble_raw:
- case vmIntrinsics::_putAddress_raw:
case vmIntrinsics::_getObjectVolatile:
case vmIntrinsics::_getBooleanVolatile:
case vmIntrinsics::_getByteVolatile:
--- a/hotspot/src/share/vm/opto/library_call.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/opto/library_call.cpp Wed May 11 00:38:58 2016 +0300
@@ -93,7 +93,7 @@
Node* _result; // the result node, if any
int _reexecute_sp; // the stack pointer when bytecode needs to be reexecuted
- const TypeOopPtr* sharpen_unsafe_type(Compile::AliasType* alias_type, const TypePtr *adr_type, bool is_native_ptr = false);
+ const TypeOopPtr* sharpen_unsafe_type(Compile::AliasType* alias_type, const TypePtr *adr_type);
public:
LibraryCallKit(JVMState* jvms, LibraryIntrinsic* intrinsic)
@@ -247,7 +247,7 @@
void insert_pre_barrier(Node* base_oop, Node* offset, Node* pre_val, bool need_mem_bar);
typedef enum { Relaxed, Opaque, Volatile, Acquire, Release } AccessKind;
- bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, AccessKind kind, bool is_unaligned);
+ bool inline_unsafe_access(bool is_store, BasicType type, AccessKind kind, bool is_unaligned);
static bool klass_needs_init_guard(Node* kls);
bool inline_unsafe_allocate();
bool inline_unsafe_newArray(bool uninitialized);
@@ -475,7 +475,6 @@
// Handle symbolic names for otherwise undistinguished boolean switches:
const bool is_store = true;
const bool is_compress = true;
- const bool is_native_ptr = true;
const bool is_static = true;
const bool is_volatile = true;
@@ -555,113 +554,95 @@
case vmIntrinsics::_inflateStringC:
case vmIntrinsics::_inflateStringB: return inline_string_copy(!is_compress);
- case vmIntrinsics::_getObject: return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT, Relaxed, false);
- case vmIntrinsics::_getBoolean: return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN, Relaxed, false);
- case vmIntrinsics::_getByte: return inline_unsafe_access(!is_native_ptr, !is_store, T_BYTE, Relaxed, false);
- case vmIntrinsics::_getShort: return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT, Relaxed, false);
- case vmIntrinsics::_getChar: return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR, Relaxed, false);
- case vmIntrinsics::_getInt: return inline_unsafe_access(!is_native_ptr, !is_store, T_INT, Relaxed, false);
- case vmIntrinsics::_getLong: return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG, Relaxed, false);
- case vmIntrinsics::_getFloat: return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT, Relaxed, false);
- case vmIntrinsics::_getDouble: return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE, Relaxed, false);
-
- case vmIntrinsics::_putObject: return inline_unsafe_access(!is_native_ptr, is_store, T_OBJECT, Relaxed, false);
- case vmIntrinsics::_putBoolean: return inline_unsafe_access(!is_native_ptr, is_store, T_BOOLEAN, Relaxed, false);
- case vmIntrinsics::_putByte: return inline_unsafe_access(!is_native_ptr, is_store, T_BYTE, Relaxed, false);
- case vmIntrinsics::_putShort: return inline_unsafe_access(!is_native_ptr, is_store, T_SHORT, Relaxed, false);
- case vmIntrinsics::_putChar: return inline_unsafe_access(!is_native_ptr, is_store, T_CHAR, Relaxed, false);
- case vmIntrinsics::_putInt: return inline_unsafe_access(!is_native_ptr, is_store, T_INT, Relaxed, false);
- case vmIntrinsics::_putLong: return inline_unsafe_access(!is_native_ptr, is_store, T_LONG, Relaxed, false);
- case vmIntrinsics::_putFloat: return inline_unsafe_access(!is_native_ptr, is_store, T_FLOAT, Relaxed, false);
- case vmIntrinsics::_putDouble: return inline_unsafe_access(!is_native_ptr, is_store, T_DOUBLE, Relaxed, false);
-
- case vmIntrinsics::_getByte_raw: return inline_unsafe_access( is_native_ptr, !is_store, T_BYTE, Relaxed, false);
- case vmIntrinsics::_getShort_raw: return inline_unsafe_access( is_native_ptr, !is_store, T_SHORT, Relaxed, false);
- case vmIntrinsics::_getChar_raw: return inline_unsafe_access( is_native_ptr, !is_store, T_CHAR, Relaxed, false);
- case vmIntrinsics::_getInt_raw: return inline_unsafe_access( is_native_ptr, !is_store, T_INT, Relaxed, false);
- case vmIntrinsics::_getLong_raw: return inline_unsafe_access( is_native_ptr, !is_store, T_LONG, Relaxed, false);
- case vmIntrinsics::_getFloat_raw: return inline_unsafe_access( is_native_ptr, !is_store, T_FLOAT, Relaxed, false);
- case vmIntrinsics::_getDouble_raw: return inline_unsafe_access( is_native_ptr, !is_store, T_DOUBLE, Relaxed, false);
- case vmIntrinsics::_getAddress_raw: return inline_unsafe_access( is_native_ptr, !is_store, T_ADDRESS, Relaxed, false);
-
- case vmIntrinsics::_putByte_raw: return inline_unsafe_access( is_native_ptr, is_store, T_BYTE, Relaxed, false);
- case vmIntrinsics::_putShort_raw: return inline_unsafe_access( is_native_ptr, is_store, T_SHORT, Relaxed, false);
- case vmIntrinsics::_putChar_raw: return inline_unsafe_access( is_native_ptr, is_store, T_CHAR, Relaxed, false);
- case vmIntrinsics::_putInt_raw: return inline_unsafe_access( is_native_ptr, is_store, T_INT, Relaxed, false);
- case vmIntrinsics::_putLong_raw: return inline_unsafe_access( is_native_ptr, is_store, T_LONG, Relaxed, false);
- case vmIntrinsics::_putFloat_raw: return inline_unsafe_access( is_native_ptr, is_store, T_FLOAT, Relaxed, false);
- case vmIntrinsics::_putDouble_raw: return inline_unsafe_access( is_native_ptr, is_store, T_DOUBLE, Relaxed, false);
- case vmIntrinsics::_putAddress_raw: return inline_unsafe_access( is_native_ptr, is_store, T_ADDRESS, Relaxed, false);
-
- case vmIntrinsics::_getObjectVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT, Volatile, false);
- case vmIntrinsics::_getBooleanVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN, Volatile, false);
- case vmIntrinsics::_getByteVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_BYTE, Volatile, false);
- case vmIntrinsics::_getShortVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT, Volatile, false);
- case vmIntrinsics::_getCharVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR, Volatile, false);
- case vmIntrinsics::_getIntVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_INT, Volatile, false);
- case vmIntrinsics::_getLongVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG, Volatile, false);
- case vmIntrinsics::_getFloatVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT, Volatile, false);
- case vmIntrinsics::_getDoubleVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE, Volatile, false);
-
- case vmIntrinsics::_putObjectVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_OBJECT, Volatile, false);
- case vmIntrinsics::_putBooleanVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_BOOLEAN, Volatile, false);
- case vmIntrinsics::_putByteVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_BYTE, Volatile, false);
- case vmIntrinsics::_putShortVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_SHORT, Volatile, false);
- case vmIntrinsics::_putCharVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_CHAR, Volatile, false);
- case vmIntrinsics::_putIntVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_INT, Volatile, false);
- case vmIntrinsics::_putLongVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_LONG, Volatile, false);
- case vmIntrinsics::_putFloatVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_FLOAT, Volatile, false);
- case vmIntrinsics::_putDoubleVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_DOUBLE, Volatile, false);
-
- case vmIntrinsics::_getShortUnaligned: return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT, Relaxed, true);
- case vmIntrinsics::_getCharUnaligned: return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR, Relaxed, true);
- case vmIntrinsics::_getIntUnaligned: return inline_unsafe_access(!is_native_ptr, !is_store, T_INT, Relaxed, true);
- case vmIntrinsics::_getLongUnaligned: return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG, Relaxed, true);
-
- case vmIntrinsics::_putShortUnaligned: return inline_unsafe_access(!is_native_ptr, is_store, T_SHORT, Relaxed, true);
- case vmIntrinsics::_putCharUnaligned: return inline_unsafe_access(!is_native_ptr, is_store, T_CHAR, Relaxed, true);
- case vmIntrinsics::_putIntUnaligned: return inline_unsafe_access(!is_native_ptr, is_store, T_INT, Relaxed, true);
- case vmIntrinsics::_putLongUnaligned: return inline_unsafe_access(!is_native_ptr, is_store, T_LONG, Relaxed, true);
-
- case vmIntrinsics::_getObjectAcquire: return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT, Acquire, false);
- case vmIntrinsics::_getBooleanAcquire: return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN, Acquire, false);
- case vmIntrinsics::_getByteAcquire: return inline_unsafe_access(!is_native_ptr, !is_store, T_BYTE, Acquire, false);
- case vmIntrinsics::_getShortAcquire: return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT, Acquire, false);
- case vmIntrinsics::_getCharAcquire: return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR, Acquire, false);
- case vmIntrinsics::_getIntAcquire: return inline_unsafe_access(!is_native_ptr, !is_store, T_INT, Acquire, false);
- case vmIntrinsics::_getLongAcquire: return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG, Acquire, false);
- case vmIntrinsics::_getFloatAcquire: return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT, Acquire, false);
- case vmIntrinsics::_getDoubleAcquire: return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE, Acquire, false);
-
- case vmIntrinsics::_putObjectRelease: return inline_unsafe_access(!is_native_ptr, is_store, T_OBJECT, Release, false);
- case vmIntrinsics::_putBooleanRelease: return inline_unsafe_access(!is_native_ptr, is_store, T_BOOLEAN, Release, false);
- case vmIntrinsics::_putByteRelease: return inline_unsafe_access(!is_native_ptr, is_store, T_BYTE, Release, false);
- case vmIntrinsics::_putShortRelease: return inline_unsafe_access(!is_native_ptr, is_store, T_SHORT, Release, false);
- case vmIntrinsics::_putCharRelease: return inline_unsafe_access(!is_native_ptr, is_store, T_CHAR, Release, false);
- case vmIntrinsics::_putIntRelease: return inline_unsafe_access(!is_native_ptr, is_store, T_INT, Release, false);
- case vmIntrinsics::_putLongRelease: return inline_unsafe_access(!is_native_ptr, is_store, T_LONG, Release, false);
- case vmIntrinsics::_putFloatRelease: return inline_unsafe_access(!is_native_ptr, is_store, T_FLOAT, Release, false);
- case vmIntrinsics::_putDoubleRelease: return inline_unsafe_access(!is_native_ptr, is_store, T_DOUBLE, Release, false);
-
- case vmIntrinsics::_getObjectOpaque: return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT, Opaque, false);
- case vmIntrinsics::_getBooleanOpaque: return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN, Opaque, false);
- case vmIntrinsics::_getByteOpaque: return inline_unsafe_access(!is_native_ptr, !is_store, T_BYTE, Opaque, false);
- case vmIntrinsics::_getShortOpaque: return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT, Opaque, false);
- case vmIntrinsics::_getCharOpaque: return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR, Opaque, false);
- case vmIntrinsics::_getIntOpaque: return inline_unsafe_access(!is_native_ptr, !is_store, T_INT, Opaque, false);
- case vmIntrinsics::_getLongOpaque: return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG, Opaque, false);
- case vmIntrinsics::_getFloatOpaque: return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT, Opaque, false);
- case vmIntrinsics::_getDoubleOpaque: return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE, Opaque, false);
-
- case vmIntrinsics::_putObjectOpaque: return inline_unsafe_access(!is_native_ptr, is_store, T_OBJECT, Opaque, false);
- case vmIntrinsics::_putBooleanOpaque: return inline_unsafe_access(!is_native_ptr, is_store, T_BOOLEAN, Opaque, false);
- case vmIntrinsics::_putByteOpaque: return inline_unsafe_access(!is_native_ptr, is_store, T_BYTE, Opaque, false);
- case vmIntrinsics::_putShortOpaque: return inline_unsafe_access(!is_native_ptr, is_store, T_SHORT, Opaque, false);
- case vmIntrinsics::_putCharOpaque: return inline_unsafe_access(!is_native_ptr, is_store, T_CHAR, Opaque, false);
- case vmIntrinsics::_putIntOpaque: return inline_unsafe_access(!is_native_ptr, is_store, T_INT, Opaque, false);
- case vmIntrinsics::_putLongOpaque: return inline_unsafe_access(!is_native_ptr, is_store, T_LONG, Opaque, false);
- case vmIntrinsics::_putFloatOpaque: return inline_unsafe_access(!is_native_ptr, is_store, T_FLOAT, Opaque, false);
- case vmIntrinsics::_putDoubleOpaque: return inline_unsafe_access(!is_native_ptr, is_store, T_DOUBLE, Opaque, false);
+ case vmIntrinsics::_getObject: return inline_unsafe_access(!is_store, T_OBJECT, Relaxed, false);
+ case vmIntrinsics::_getBoolean: return inline_unsafe_access(!is_store, T_BOOLEAN, Relaxed, false);
+ case vmIntrinsics::_getByte: return inline_unsafe_access(!is_store, T_BYTE, Relaxed, false);
+ case vmIntrinsics::_getShort: return inline_unsafe_access(!is_store, T_SHORT, Relaxed, false);
+ case vmIntrinsics::_getChar: return inline_unsafe_access(!is_store, T_CHAR, Relaxed, false);
+ case vmIntrinsics::_getInt: return inline_unsafe_access(!is_store, T_INT, Relaxed, false);
+ case vmIntrinsics::_getLong: return inline_unsafe_access(!is_store, T_LONG, Relaxed, false);
+ case vmIntrinsics::_getFloat: return inline_unsafe_access(!is_store, T_FLOAT, Relaxed, false);
+ case vmIntrinsics::_getDouble: return inline_unsafe_access(!is_store, T_DOUBLE, Relaxed, false);
+
+ case vmIntrinsics::_putObject: return inline_unsafe_access( is_store, T_OBJECT, Relaxed, false);
+ case vmIntrinsics::_putBoolean: return inline_unsafe_access( is_store, T_BOOLEAN, Relaxed, false);
+ case vmIntrinsics::_putByte: return inline_unsafe_access( is_store, T_BYTE, Relaxed, false);
+ case vmIntrinsics::_putShort: return inline_unsafe_access( is_store, T_SHORT, Relaxed, false);
+ case vmIntrinsics::_putChar: return inline_unsafe_access( is_store, T_CHAR, Relaxed, false);
+ case vmIntrinsics::_putInt: return inline_unsafe_access( is_store, T_INT, Relaxed, false);
+ case vmIntrinsics::_putLong: return inline_unsafe_access( is_store, T_LONG, Relaxed, false);
+ case vmIntrinsics::_putFloat: return inline_unsafe_access( is_store, T_FLOAT, Relaxed, false);
+ case vmIntrinsics::_putDouble: return inline_unsafe_access( is_store, T_DOUBLE, Relaxed, false);
+
+ case vmIntrinsics::_getObjectVolatile: return inline_unsafe_access(!is_store, T_OBJECT, Volatile, false);
+ case vmIntrinsics::_getBooleanVolatile: return inline_unsafe_access(!is_store, T_BOOLEAN, Volatile, false);
+ case vmIntrinsics::_getByteVolatile: return inline_unsafe_access(!is_store, T_BYTE, Volatile, false);
+ case vmIntrinsics::_getShortVolatile: return inline_unsafe_access(!is_store, T_SHORT, Volatile, false);
+ case vmIntrinsics::_getCharVolatile: return inline_unsafe_access(!is_store, T_CHAR, Volatile, false);
+ case vmIntrinsics::_getIntVolatile: return inline_unsafe_access(!is_store, T_INT, Volatile, false);
+ case vmIntrinsics::_getLongVolatile: return inline_unsafe_access(!is_store, T_LONG, Volatile, false);
+ case vmIntrinsics::_getFloatVolatile: return inline_unsafe_access(!is_store, T_FLOAT, Volatile, false);
+ case vmIntrinsics::_getDoubleVolatile: return inline_unsafe_access(!is_store, T_DOUBLE, Volatile, false);
+
+ case vmIntrinsics::_putObjectVolatile: return inline_unsafe_access( is_store, T_OBJECT, Volatile, false);
+ case vmIntrinsics::_putBooleanVolatile: return inline_unsafe_access( is_store, T_BOOLEAN, Volatile, false);
+ case vmIntrinsics::_putByteVolatile: return inline_unsafe_access( is_store, T_BYTE, Volatile, false);
+ case vmIntrinsics::_putShortVolatile: return inline_unsafe_access( is_store, T_SHORT, Volatile, false);
+ case vmIntrinsics::_putCharVolatile: return inline_unsafe_access( is_store, T_CHAR, Volatile, false);
+ case vmIntrinsics::_putIntVolatile: return inline_unsafe_access( is_store, T_INT, Volatile, false);
+ case vmIntrinsics::_putLongVolatile: return inline_unsafe_access( is_store, T_LONG, Volatile, false);
+ case vmIntrinsics::_putFloatVolatile: return inline_unsafe_access( is_store, T_FLOAT, Volatile, false);
+ case vmIntrinsics::_putDoubleVolatile: return inline_unsafe_access( is_store, T_DOUBLE, Volatile, false);
+
+ case vmIntrinsics::_getShortUnaligned: return inline_unsafe_access(!is_store, T_SHORT, Relaxed, true);
+ case vmIntrinsics::_getCharUnaligned: return inline_unsafe_access(!is_store, T_CHAR, Relaxed, true);
+ case vmIntrinsics::_getIntUnaligned: return inline_unsafe_access(!is_store, T_INT, Relaxed, true);
+ case vmIntrinsics::_getLongUnaligned: return inline_unsafe_access(!is_store, T_LONG, Relaxed, true);
+
+ case vmIntrinsics::_putShortUnaligned: return inline_unsafe_access( is_store, T_SHORT, Relaxed, true);
+ case vmIntrinsics::_putCharUnaligned: return inline_unsafe_access( is_store, T_CHAR, Relaxed, true);
+ case vmIntrinsics::_putIntUnaligned: return inline_unsafe_access( is_store, T_INT, Relaxed, true);
+ case vmIntrinsics::_putLongUnaligned: return inline_unsafe_access( is_store, T_LONG, Relaxed, true);
+
+ case vmIntrinsics::_getObjectAcquire: return inline_unsafe_access(!is_store, T_OBJECT, Acquire, false);
+ case vmIntrinsics::_getBooleanAcquire: return inline_unsafe_access(!is_store, T_BOOLEAN, Acquire, false);
+ case vmIntrinsics::_getByteAcquire: return inline_unsafe_access(!is_store, T_BYTE, Acquire, false);
+ case vmIntrinsics::_getShortAcquire: return inline_unsafe_access(!is_store, T_SHORT, Acquire, false);
+ case vmIntrinsics::_getCharAcquire: return inline_unsafe_access(!is_store, T_CHAR, Acquire, false);
+ case vmIntrinsics::_getIntAcquire: return inline_unsafe_access(!is_store, T_INT, Acquire, false);
+ case vmIntrinsics::_getLongAcquire: return inline_unsafe_access(!is_store, T_LONG, Acquire, false);
+ case vmIntrinsics::_getFloatAcquire: return inline_unsafe_access(!is_store, T_FLOAT, Acquire, false);
+ case vmIntrinsics::_getDoubleAcquire: return inline_unsafe_access(!is_store, T_DOUBLE, Acquire, false);
+
+ case vmIntrinsics::_putObjectRelease: return inline_unsafe_access( is_store, T_OBJECT, Release, false);
+ case vmIntrinsics::_putBooleanRelease: return inline_unsafe_access( is_store, T_BOOLEAN, Release, false);
+ case vmIntrinsics::_putByteRelease: return inline_unsafe_access( is_store, T_BYTE, Release, false);
+ case vmIntrinsics::_putShortRelease: return inline_unsafe_access( is_store, T_SHORT, Release, false);
+ case vmIntrinsics::_putCharRelease: return inline_unsafe_access( is_store, T_CHAR, Release, false);
+ case vmIntrinsics::_putIntRelease: return inline_unsafe_access( is_store, T_INT, Release, false);
+ case vmIntrinsics::_putLongRelease: return inline_unsafe_access( is_store, T_LONG, Release, false);
+ case vmIntrinsics::_putFloatRelease: return inline_unsafe_access( is_store, T_FLOAT, Release, false);
+ case vmIntrinsics::_putDoubleRelease: return inline_unsafe_access( is_store, T_DOUBLE, Release, false);
+
+ case vmIntrinsics::_getObjectOpaque: return inline_unsafe_access(!is_store, T_OBJECT, Opaque, false);
+ case vmIntrinsics::_getBooleanOpaque: return inline_unsafe_access(!is_store, T_BOOLEAN, Opaque, false);
+ case vmIntrinsics::_getByteOpaque: return inline_unsafe_access(!is_store, T_BYTE, Opaque, false);
+ case vmIntrinsics::_getShortOpaque: return inline_unsafe_access(!is_store, T_SHORT, Opaque, false);
+ case vmIntrinsics::_getCharOpaque: return inline_unsafe_access(!is_store, T_CHAR, Opaque, false);
+ case vmIntrinsics::_getIntOpaque: return inline_unsafe_access(!is_store, T_INT, Opaque, false);
+ case vmIntrinsics::_getLongOpaque: return inline_unsafe_access(!is_store, T_LONG, Opaque, false);
+ case vmIntrinsics::_getFloatOpaque: return inline_unsafe_access(!is_store, T_FLOAT, Opaque, false);
+ case vmIntrinsics::_getDoubleOpaque: return inline_unsafe_access(!is_store, T_DOUBLE, Opaque, false);
+
+ case vmIntrinsics::_putObjectOpaque: return inline_unsafe_access( is_store, T_OBJECT, Opaque, false);
+ case vmIntrinsics::_putBooleanOpaque: return inline_unsafe_access( is_store, T_BOOLEAN, Opaque, false);
+ case vmIntrinsics::_putByteOpaque: return inline_unsafe_access( is_store, T_BYTE, Opaque, false);
+ case vmIntrinsics::_putShortOpaque: return inline_unsafe_access( is_store, T_SHORT, Opaque, false);
+ case vmIntrinsics::_putCharOpaque: return inline_unsafe_access( is_store, T_CHAR, Opaque, false);
+ case vmIntrinsics::_putIntOpaque: return inline_unsafe_access( is_store, T_INT, Opaque, false);
+ case vmIntrinsics::_putLongOpaque: return inline_unsafe_access( is_store, T_LONG, Opaque, false);
+ case vmIntrinsics::_putFloatOpaque: return inline_unsafe_access( is_store, T_FLOAT, Opaque, false);
+ case vmIntrinsics::_putDoubleOpaque: return inline_unsafe_access( is_store, T_DOUBLE, Opaque, false);
case vmIntrinsics::_compareAndSwapObject: return inline_unsafe_load_store(T_OBJECT, LS_cmp_swap, Volatile);
case vmIntrinsics::_compareAndSwapInt: return inline_unsafe_load_store(T_INT, LS_cmp_swap, Volatile);
@@ -2199,8 +2180,6 @@
//----------------------------inline_unsafe_access----------------------------
-const static BasicType T_ADDRESS_HOLDER = T_LONG;
-
// Helper that guards and inserts a pre-barrier.
void LibraryCallKit::insert_pre_barrier(Node* base_oop, Node* offset,
Node* pre_val, bool need_mem_bar) {
@@ -2301,13 +2280,12 @@
}
-const TypeOopPtr* LibraryCallKit::sharpen_unsafe_type(Compile::AliasType* alias_type, const TypePtr *adr_type, bool is_native_ptr) {
+const TypeOopPtr* LibraryCallKit::sharpen_unsafe_type(Compile::AliasType* alias_type, const TypePtr *adr_type) {
// Attempt to infer a sharper value type from the offset and base type.
ciKlass* sharpened_klass = NULL;
// See if it is an instance field, with an object type.
if (alias_type->field() != NULL) {
- assert(!is_native_ptr, "native pointer op cannot use a java address");
if (alias_type->field()->type()->is_klass()) {
sharpened_klass = alias_type->field()->type()->as_klass();
}
@@ -2340,7 +2318,7 @@
return NULL;
}
-bool LibraryCallKit::inline_unsafe_access(const bool is_native_ptr, bool is_store, const BasicType type, const AccessKind kind, const bool unaligned) {
+bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, const AccessKind kind, const bool unaligned) {
if (callee()->is_static()) return false; // caller must have the capability!
guarantee(!is_store || kind != Acquire, "Acquire accesses can be produced only for loads");
guarantee( is_store || kind != Release, "Release accesses can be produced only for stores");
@@ -2355,31 +2333,17 @@
if (!is_store) {
// Object getObject(Object base, int/long offset), etc.
BasicType rtype = sig->return_type()->basic_type();
- if (rtype == T_ADDRESS_HOLDER && callee()->name() == ciSymbol::getAddress_name())
- rtype = T_ADDRESS; // it is really a C void*
assert(rtype == type, "getter must return the expected value");
- if (!is_native_ptr) {
- assert(sig->count() == 2, "oop getter has 2 arguments");
- assert(sig->type_at(0)->basic_type() == T_OBJECT, "getter base is object");
- assert(sig->type_at(1)->basic_type() == T_LONG, "getter offset is correct");
- } else {
- assert(sig->count() == 1, "native getter has 1 argument");
- assert(sig->type_at(0)->basic_type() == T_LONG, "getter base is long");
- }
+ assert(sig->count() == 2, "oop getter has 2 arguments");
+ assert(sig->type_at(0)->basic_type() == T_OBJECT, "getter base is object");
+ assert(sig->type_at(1)->basic_type() == T_LONG, "getter offset is correct");
} else {
// void putObject(Object base, int/long offset, Object x), etc.
assert(sig->return_type()->basic_type() == T_VOID, "putter must not return a value");
- if (!is_native_ptr) {
- assert(sig->count() == 3, "oop putter has 3 arguments");
- assert(sig->type_at(0)->basic_type() == T_OBJECT, "putter base is object");
- assert(sig->type_at(1)->basic_type() == T_LONG, "putter offset is correct");
- } else {
- assert(sig->count() == 2, "native putter has 2 arguments");
- assert(sig->type_at(0)->basic_type() == T_LONG, "putter base is long");
- }
+ assert(sig->count() == 3, "oop putter has 3 arguments");
+ assert(sig->type_at(0)->basic_type() == T_OBJECT, "putter base is object");
+ assert(sig->type_at(1)->basic_type() == T_LONG, "putter offset is correct");
BasicType vtype = sig->type_at(sig->count()-1)->basic_type();
- if (vtype == T_ADDRESS_HOLDER && callee()->name() == ciSymbol::putAddress_name())
- vtype = T_ADDRESS; // it is really a C void*
assert(vtype == type, "putter must accept the expected value");
}
#endif // ASSERT
@@ -2396,27 +2360,22 @@
Node* offset = top();
Node* val;
- if (!is_native_ptr) {
- // The base is either a Java object or a value produced by Unsafe.staticFieldBase
- Node* base = argument(1); // type: oop
- // The offset is a value produced by Unsafe.staticFieldOffset or Unsafe.objectFieldOffset
- offset = argument(2); // type: long
- // We currently rely on the cookies produced by Unsafe.xxxFieldOffset
- // to be plain byte offsets, which are also the same as those accepted
- // by oopDesc::field_base.
- assert(Unsafe_field_offset_to_byte_offset(11) == 11,
- "fieldOffset must be byte-scaled");
- // 32-bit machines ignore the high half!
- offset = ConvL2X(offset);
- adr = make_unsafe_address(base, offset);
+ // The base is either a Java object or a value produced by Unsafe.staticFieldBase
+ Node* base = argument(1); // type: oop
+ // The offset is a value produced by Unsafe.staticFieldOffset or Unsafe.objectFieldOffset
+ offset = argument(2); // type: long
+ // We currently rely on the cookies produced by Unsafe.xxxFieldOffset
+ // to be plain byte offsets, which are also the same as those accepted
+ // by oopDesc::field_base.
+ assert(Unsafe_field_offset_to_byte_offset(11) == 11,
+ "fieldOffset must be byte-scaled");
+ // 32-bit machines ignore the high half!
+ offset = ConvL2X(offset);
+ adr = make_unsafe_address(base, offset);
+ if (_gvn.type(base)->isa_ptr() != TypePtr::NULL_PTR) {
heap_base_oop = base;
- val = is_store ? argument(4) : NULL;
- } else {
- Node* ptr = argument(1); // type: long
- ptr = ConvL2X(ptr); // adjust Java long to machine word
- adr = make_unsafe_address(NULL, ptr);
- val = is_store ? argument(3) : NULL;
- }
+ }
+ val = is_store ? argument(4) : NULL;
const TypePtr *adr_type = _gvn.type(adr)->isa_ptr();
@@ -2498,11 +2457,11 @@
// SATB log buffer using the pre-barrier mechanism.
// Also we need to add memory barrier to prevent commoning reads
// from this field across safepoint since GC can change its value.
- bool need_read_barrier = !is_native_ptr && !is_store &&
+ bool need_read_barrier = !is_store &&
offset != top() && heap_base_oop != top();
if (!is_store && type == T_OBJECT) {
- const TypeOopPtr* tjp = sharpen_unsafe_type(alias_type, adr_type, is_native_ptr);
+ const TypeOopPtr* tjp = sharpen_unsafe_type(alias_type, adr_type);
if (tjp != NULL) {
value_type = tjp;
}
--- a/hotspot/src/share/vm/prims/jvmtiImpl.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/prims/jvmtiImpl.cpp Wed May 11 00:38:58 2016 +0300
@@ -303,11 +303,10 @@
if (method->is_running_emcp() &&
method->name() == m_name &&
method->signature() == m_signature) {
- RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)",
- meth_act == &Method::set_breakpoint ? "sett" : "clear",
- method->name()->as_C_string(),
- method->signature()->as_C_string()));
-
+ ResourceMark rm;
+ log_debug(redefine, class, breakpoint)
+ ("%sing breakpoint in %s(%s)", meth_act == &Method::set_breakpoint ? "sett" : "clear",
+ method->name()->as_C_string(), method->signature()->as_C_string());
(method->*meth_act)(_bci);
break;
}
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed May 11 00:38:58 2016 +0300
@@ -32,6 +32,7 @@
#include "gc/shared/gcLocker.hpp"
#include "interpreter/oopMapCache.hpp"
#include "interpreter/rewriter.hpp"
+#include "logging/logStream.hpp"
#include "memory/metadataFactory.hpp"
#include "memory/metaspaceShared.hpp"
#include "memory/resourceArea.hpp"
@@ -94,7 +95,9 @@
// Start timer after all the sanity checks; not quite accurate, but
// better than adding a bunch of stop() calls.
- RC_TIMER_START(_timer_vm_op_prologue);
+ if (log_is_enabled(Info, redefine, class, timer)) {
+ _timer_vm_op_prologue.start();
+ }
// We first load new class versions in the prologue, because somewhere down the
// call chain it is required that the current thread is a Java thread.
@@ -111,11 +114,11 @@
}
// Free os::malloc allocated memory in load_new_class_version.
os::free(_scratch_classes);
- RC_TIMER_STOP(_timer_vm_op_prologue);
+ _timer_vm_op_prologue.stop();
return false;
}
- RC_TIMER_STOP(_timer_vm_op_prologue);
+ _timer_vm_op_prologue.stop();
return true;
}
@@ -128,8 +131,7 @@
// a shared class. We do the remap during the doit() phase of
// the safepoint to be safer.
if (!MetaspaceShared::remap_shared_readonly_as_readwrite()) {
- RC_TRACE_WITH_THREAD(0x00000001, thread,
- ("failed to remap shared readonly space to readwrite, private"));
+ log_info(redefine, class, load)("failed to remap shared readonly space to readwrite, private");
_res = JVMTI_ERROR_INTERNAL;
return;
}
@@ -161,9 +163,9 @@
// check_class() is optionally called for product bits, but is
// always called for non-product bits.
#ifdef PRODUCT
- if (RC_TRACE_ENABLED(0x00004000)) {
+ if (log_is_enabled(Trace, redefine, class, obsolete, metadata)) {
#endif
- RC_TRACE_WITH_THREAD(0x00004000, thread, ("calling check_class"));
+ log_trace(redefine, class, obsolete, metadata)("calling check_class");
CheckClass check_class(thread);
ClassLoaderDataGraph::classes_do(&check_class);
#ifdef PRODUCT
@@ -178,19 +180,19 @@
// Reset the_class_oop to null for error printing.
_the_class_oop = NULL;
- if (RC_TRACE_ENABLED(0x00000004)) {
+ if (log_is_enabled(Info, redefine, class, timer)) {
// Used to have separate timers for "doit" and "all", but the timer
// overhead skewed the measurements.
jlong doit_time = _timer_rsc_phase1.milliseconds() +
_timer_rsc_phase2.milliseconds();
jlong all_time = _timer_vm_op_prologue.milliseconds() + doit_time;
- RC_TRACE(0x00000004, ("vm_op: all=" UINT64_FORMAT
- " prologue=" UINT64_FORMAT " doit=" UINT64_FORMAT, all_time,
- _timer_vm_op_prologue.milliseconds(), doit_time));
- RC_TRACE(0x00000004,
+ log_info(redefine, class, timer)
+ ("vm_op: all=" UINT64_FORMAT " prologue=" UINT64_FORMAT " doit=" UINT64_FORMAT,
+ all_time, _timer_vm_op_prologue.milliseconds(), doit_time);
+ log_info(redefine, class, timer)
("redefine_single_class: phase1=" UINT64_FORMAT " phase2=" UINT64_FORMAT,
- _timer_rsc_phase1.milliseconds(), _timer_rsc_phase2.milliseconds()));
+ _timer_rsc_phase1.milliseconds(), _timer_rsc_phase2.milliseconds());
}
}
@@ -305,14 +307,14 @@
// both new_name_ref_i and new_signature_ref_i will both be 0.
// In that case, all we are appending is the current entry.
if (new_name_ref_i != name_ref_i) {
- RC_TRACE(0x00080000,
+ log_trace(redefine, class, constantpool)
("NameAndType entry@%d name_ref_index change: %d to %d",
- *merge_cp_length_p, name_ref_i, new_name_ref_i));
+ *merge_cp_length_p, name_ref_i, new_name_ref_i);
}
if (new_signature_ref_i != signature_ref_i) {
- RC_TRACE(0x00080000,
+ log_trace(redefine, class, constantpool)
("NameAndType entry@%d signature_ref_index change: %d to %d",
- *merge_cp_length_p, signature_ref_i, new_signature_ref_i));
+ *merge_cp_length_p, signature_ref_i, new_signature_ref_i);
}
(*merge_cp_p)->name_and_type_at_put(*merge_cp_length_p,
@@ -361,14 +363,13 @@
}
if (klass_ref_i != new_klass_ref_i) {
- RC_TRACE(0x00080000, ("%s entry@%d class_index changed: %d to %d",
- entry_name, *merge_cp_length_p, klass_ref_i, new_klass_ref_i));
+ log_trace(redefine, class, constantpool)
+ ("%s entry@%d class_index changed: %d to %d", entry_name, *merge_cp_length_p, klass_ref_i, new_klass_ref_i);
}
if (name_and_type_ref_i != new_name_and_type_ref_i) {
- RC_TRACE(0x00080000,
+ log_trace(redefine, class, constantpool)
("%s entry@%d name_and_type_index changed: %d to %d",
- entry_name, *merge_cp_length_p, name_and_type_ref_i,
- new_name_and_type_ref_i));
+ entry_name, *merge_cp_length_p, name_and_type_ref_i, new_name_and_type_ref_i);
}
if (scratch_i != *merge_cp_length_p) {
@@ -386,9 +387,8 @@
int new_ref_i = find_or_append_indirect_entry(scratch_cp, ref_i, merge_cp_p,
merge_cp_length_p, THREAD);
if (new_ref_i != ref_i) {
- RC_TRACE(0x00080000,
- ("MethodType entry@%d ref_index change: %d to %d",
- *merge_cp_length_p, ref_i, new_ref_i));
+ log_trace(redefine, class, constantpool)
+ ("MethodType entry@%d ref_index change: %d to %d", *merge_cp_length_p, ref_i, new_ref_i);
}
(*merge_cp_p)->method_type_index_at_put(*merge_cp_length_p, new_ref_i);
if (scratch_i != *merge_cp_length_p) {
@@ -407,9 +407,8 @@
int new_ref_i = find_or_append_indirect_entry(scratch_cp, ref_i, merge_cp_p,
merge_cp_length_p, THREAD);
if (new_ref_i != ref_i) {
- RC_TRACE(0x00080000,
- ("MethodHandle entry@%d ref_index change: %d to %d",
- *merge_cp_length_p, ref_i, new_ref_i));
+ log_trace(redefine, class, constantpool)
+ ("MethodHandle entry@%d ref_index change: %d to %d", *merge_cp_length_p, ref_i, new_ref_i);
}
(*merge_cp_p)->method_handle_index_at_put(*merge_cp_length_p, ref_kind, new_ref_i);
if (scratch_i != *merge_cp_length_p) {
@@ -432,14 +431,13 @@
int new_ref_i = find_or_append_indirect_entry(scratch_cp, old_ref_i, merge_cp_p,
merge_cp_length_p, THREAD);
if (new_bs_i != old_bs_i) {
- RC_TRACE(0x00080000,
- ("InvokeDynamic entry@%d bootstrap_method_attr_index change: %d to %d",
- *merge_cp_length_p, old_bs_i, new_bs_i));
+ log_trace(redefine, class, constantpool)
+ ("InvokeDynamic entry@%d bootstrap_method_attr_index change: %d to %d",
+ *merge_cp_length_p, old_bs_i, new_bs_i);
}
if (new_ref_i != old_ref_i) {
- RC_TRACE(0x00080000,
- ("InvokeDynamic entry@%d name_and_type_index change: %d to %d",
- *merge_cp_length_p, old_ref_i, new_ref_i));
+ log_trace(redefine, class, constantpool)
+ ("InvokeDynamic entry@%d name_and_type_index change: %d to %d", *merge_cp_length_p, old_ref_i, new_ref_i);
}
(*merge_cp_p)->invoke_dynamic_at_put(*merge_cp_length_p, new_bs_i, new_ref_i);
@@ -516,9 +514,8 @@
int new_ref_i = find_or_append_indirect_entry(scratch_cp, old_ref_i, merge_cp_p,
merge_cp_length_p, THREAD);
if (new_ref_i != old_ref_i) {
- RC_TRACE(0x00080000,
- ("operands entry@%d bootstrap method ref_index change: %d to %d",
- _operands_cur_length, old_ref_i, new_ref_i));
+ log_trace(redefine, class, constantpool)
+ ("operands entry@%d bootstrap method ref_index change: %d to %d", _operands_cur_length, old_ref_i, new_ref_i);
}
Array<u2>* merge_ops = (*merge_cp_p)->operands();
@@ -539,9 +536,9 @@
merge_cp_length_p, THREAD);
merge_ops->at_put(new_base++, new_arg_ref_i);
if (new_arg_ref_i != old_arg_ref_i) {
- RC_TRACE(0x00080000,
- ("operands entry@%d bootstrap method argument ref_index change: %d to %d",
- _operands_cur_length, old_arg_ref_i, new_arg_ref_i));
+ log_trace(redefine, class, constantpool)
+ ("operands entry@%d bootstrap method argument ref_index change: %d to %d",
+ _operands_cur_length, old_arg_ref_i, new_arg_ref_i);
}
}
if (old_bs_i != _operands_cur_length) {
@@ -586,14 +583,13 @@
// Shrink the merge_cp operands
merge_cp->shrink_operands(_operands_cur_length, CHECK);
- if (RC_TRACE_ENABLED(0x00040000)) {
+ if (log_is_enabled(Trace, redefine, class, constantpool)) {
// don't want to loop unless we are tracing
int count = 0;
for (int i = 1; i < _operands_index_map_p->length(); i++) {
int value = _operands_index_map_p->at(i);
if (value != -1) {
- RC_TRACE_WITH_THREAD(0x00040000, THREAD,
- ("operands_index_map[%d]: old=%d new=%d", count, i, value));
+ log_trace(redefine, class, constantpool)("operands_index_map[%d]: old=%d new=%d", count, i, value);
count++;
}
}
@@ -795,9 +791,9 @@
}
}
}
- RC_TRACE(0x00008000, ("Method matched: new: %s [%d] == old: %s [%d]",
- k_new_method->name_and_sig_as_C_string(), ni,
- k_old_method->name_and_sig_as_C_string(), oi));
+ log_trace(redefine, class, normalize)
+ ("Method matched: new: %s [%d] == old: %s [%d]",
+ k_new_method->name_and_sig_as_C_string(), ni, k_old_method->name_and_sig_as_C_string(), oi);
// advance to next pair of methods
++oi;
++ni;
@@ -832,8 +828,8 @@
return JVMTI_ERROR_OUT_OF_MEMORY;
}
}
- RC_TRACE(0x00008000, ("Method added: new: %s [%d]",
- k_new_method->name_and_sig_as_C_string(), ni));
+ log_trace(redefine, class, normalize)
+ ("Method added: new: %s [%d]", k_new_method->name_and_sig_as_C_string(), ni);
++ni; // advance to next new method
break;
case deleted:
@@ -846,8 +842,8 @@
// deleted methods must be private
return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED;
}
- RC_TRACE(0x00008000, ("Method deleted: old: %s [%d]",
- k_old_method->name_and_sig_as_C_string(), oi));
+ log_trace(redefine, class, normalize)
+ ("Method deleted: old: %s [%d]", k_old_method->name_and_sig_as_C_string(), oi);
++oi; // advance to next old method
break;
default:
@@ -973,11 +969,9 @@
instanceKlassHandle the_class = instanceKlassHandle(THREAD, the_class_oop);
Symbol* the_class_sym = the_class->name();
- // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
- RC_TRACE_WITH_THREAD(0x00000001, THREAD,
+ log_debug(redefine, class, load)
("loading name=%s kind=%d (avail_mem=" UINT64_FORMAT "K)",
- the_class->external_name(), _class_load_kind,
- os::available_memory() >> 10));
+ the_class->external_name(), _class_load_kind, os::available_memory() >> 10);
ClassFileStream st((u1*)_class_defs[i].class_bytes,
_class_defs[i].class_byte_count,
@@ -1011,9 +1005,7 @@
if (HAS_PENDING_EXCEPTION) {
Symbol* ex_name = PENDING_EXCEPTION->klass()->name();
- // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
- RC_TRACE_WITH_THREAD(0x00000002, THREAD, ("parse_stream exception: '%s'",
- ex_name->as_C_string()));
+ log_info(redefine, class, load, exceptions)("parse_stream exception: '%s'", ex_name->as_C_string());
CLEAR_PENDING_EXCEPTION;
if (ex_name == vmSymbols::java_lang_UnsupportedClassVersionError()) {
@@ -1037,9 +1029,7 @@
the_class->link_class(THREAD);
if (HAS_PENDING_EXCEPTION) {
Symbol* ex_name = PENDING_EXCEPTION->klass()->name();
- // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
- RC_TRACE_WITH_THREAD(0x00000002, THREAD, ("link_class exception: '%s'",
- ex_name->as_C_string()));
+ log_info(redefine, class, load, exceptions)("link_class exception: '%s'", ex_name->as_C_string());
CLEAR_PENDING_EXCEPTION;
if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) {
return JVMTI_ERROR_OUT_OF_MEMORY;
@@ -1075,9 +1065,7 @@
if (HAS_PENDING_EXCEPTION) {
Symbol* ex_name = PENDING_EXCEPTION->klass()->name();
- // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
- RC_TRACE_WITH_THREAD(0x00000002, THREAD,
- ("verify_byte_codes exception: '%s'", ex_name->as_C_string()));
+ log_info(redefine, class, load, exceptions)("verify_byte_codes exception: '%s'", ex_name->as_C_string());
CLEAR_PENDING_EXCEPTION;
if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) {
return JVMTI_ERROR_OUT_OF_MEMORY;
@@ -1090,9 +1078,7 @@
res = merge_cp_and_rewrite(the_class, scratch_class, THREAD);
if (HAS_PENDING_EXCEPTION) {
Symbol* ex_name = PENDING_EXCEPTION->klass()->name();
- // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
- RC_TRACE_WITH_THREAD(0x00000002, THREAD,
- ("merge_cp_and_rewrite exception: '%s'", ex_name->as_C_string()));
+ log_info(redefine, class, load, exceptions)("merge_cp_and_rewrite exception: '%s'", ex_name->as_C_string());
CLEAR_PENDING_EXCEPTION;
if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) {
return JVMTI_ERROR_OUT_OF_MEMORY;
@@ -1110,10 +1096,8 @@
if (HAS_PENDING_EXCEPTION) {
Symbol* ex_name = PENDING_EXCEPTION->klass()->name();
- // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
- RC_TRACE_WITH_THREAD(0x00000002, THREAD,
- ("verify_byte_codes post merge-CP exception: '%s'",
- ex_name->as_C_string()));
+ log_info(redefine, class, load, exceptions)
+ ("verify_byte_codes post merge-CP exception: '%s'", ex_name->as_C_string());
CLEAR_PENDING_EXCEPTION;
if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) {
return JVMTI_ERROR_OUT_OF_MEMORY;
@@ -1130,9 +1114,8 @@
}
if (HAS_PENDING_EXCEPTION) {
Symbol* ex_name = PENDING_EXCEPTION->klass()->name();
- // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
- RC_TRACE_WITH_THREAD(0x00000002, THREAD,
- ("Rewriter::rewrite or link_methods exception: '%s'", ex_name->as_C_string()));
+ log_info(redefine, class, load, exceptions)
+ ("Rewriter::rewrite or link_methods exception: '%s'", ex_name->as_C_string());
CLEAR_PENDING_EXCEPTION;
if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) {
return JVMTI_ERROR_OUT_OF_MEMORY;
@@ -1141,10 +1124,8 @@
}
}
- // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
- RC_TRACE_WITH_THREAD(0x00000001, THREAD,
- ("loaded name=%s (avail_mem=" UINT64_FORMAT "K)",
- the_class->external_name(), os::available_memory() >> 10));
+ log_debug(redefine, class, load)
+ ("loaded name=%s (avail_mem=" UINT64_FORMAT "K)", the_class->external_name(), os::available_memory() >> 10);
}
return JVMTI_ERROR_NONE;
@@ -1152,7 +1133,7 @@
// Map old_index to new_index as needed. scratch_cp is only needed
-// for RC_TRACE() calls.
+// for log calls.
void VM_RedefineClasses::map_index(const constantPoolHandle& scratch_cp,
int old_index, int new_index) {
if (find_new_index(old_index) != 0) {
@@ -1168,8 +1149,8 @@
_index_map_p->at_put(old_index, new_index);
_index_map_count++;
- RC_TRACE(0x00040000, ("mapped tag %d at index %d to %d",
- scratch_cp->tag_at(old_index).value(), old_index, new_index));
+ log_trace(redefine, class, constantpool)
+ ("mapped tag %d at index %d to %d", scratch_cp->tag_at(old_index).value(), old_index, new_index);
} // end map_index()
@@ -1188,7 +1169,7 @@
_operands_index_map_p->at_put(old_index, new_index);
_operands_index_map_count++;
- RC_TRACE(0x00040000, ("mapped bootstrap specifier at index %d to %d", old_index, new_index));
+ log_trace(redefine, class, constantpool)("mapped bootstrap specifier at index %d to %d", old_index, new_index);
} // end map_index()
@@ -1219,9 +1200,7 @@
return false; // robustness
}
- RC_TRACE_WITH_THREAD(0x00010000, THREAD,
- ("old_cp_len=%d, scratch_cp_len=%d", old_cp->length(),
- scratch_cp->length()));
+ log_info(redefine, class, constantpool)("old_cp_len=%d, scratch_cp_len=%d", old_cp->length(), scratch_cp->length());
{
// Pass 0:
@@ -1273,8 +1252,7 @@
// merge_cp_len should be the same as old_cp->length() at this point
// so this trace message is really a "warm-and-breathing" message.
- RC_TRACE_WITH_THREAD(0x00020000, THREAD,
- ("after pass 0: merge_cp_len=%d", *merge_cp_length_p));
+ log_debug(redefine, class, constantpool)("after pass 0: merge_cp_len=%d", *merge_cp_length_p);
int scratch_i; // index into scratch_cp
{
@@ -1339,9 +1317,9 @@
}
}
- RC_TRACE_WITH_THREAD(0x00020000, THREAD,
+ log_debug(redefine, class, constantpool)
("after pass 1a: merge_cp_len=%d, scratch_i=%d, index_map_len=%d",
- *merge_cp_length_p, scratch_i, _index_map_count));
+ *merge_cp_length_p, scratch_i, _index_map_count);
if (scratch_i < scratch_cp->length()) {
// Pass 1b:
@@ -1377,9 +1355,9 @@
CHECK_0);
}
- RC_TRACE_WITH_THREAD(0x00020000, THREAD,
+ log_debug(redefine, class, constantpool)
("after pass 1b: merge_cp_len=%d, scratch_i=%d, index_map_len=%d",
- *merge_cp_length_p, scratch_i, _index_map_count));
+ *merge_cp_length_p, scratch_i, _index_map_count);
}
finalize_operands_merge(*merge_cp_p, THREAD);
@@ -1468,8 +1446,7 @@
return JVMTI_ERROR_INTERNAL;
}
- RC_TRACE_WITH_THREAD(0x00010000, THREAD,
- ("merge_cp_len=%d, index_map_len=%d", merge_cp_length, _index_map_count));
+ log_info(redefine, class, constantpool)("merge_cp_len=%d, index_map_len=%d", merge_cp_length, _index_map_count);
if (_index_map_count == 0) {
// there is nothing to map between the new and merged constant pools
@@ -1508,15 +1485,14 @@
cp_cleaner.add_scratch_cp(scratch_cp());
}
} else {
- if (RC_TRACE_ENABLED(0x00040000)) {
+ if (log_is_enabled(Trace, redefine, class, constantpool)) {
// don't want to loop unless we are tracing
int count = 0;
for (int i = 1; i < _index_map_p->length(); i++) {
int value = _index_map_p->at(i);
if (value != -1) {
- RC_TRACE_WITH_THREAD(0x00040000, THREAD,
- ("index_map[%d]: old=%d new=%d", count, i, value));
+ log_trace(redefine, class, constantpool)("index_map[%d]: old=%d new=%d", count, i, value);
count++;
}
}
@@ -1653,9 +1629,7 @@
}
if (HAS_PENDING_EXCEPTION) {
Symbol* ex_name = PENDING_EXCEPTION->klass()->name();
- // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
- RC_TRACE_WITH_THREAD(0x00000002, THREAD,
- ("rewrite_cp_refs_in_method exception: '%s'", ex_name->as_C_string()));
+ log_info(redefine, class, load, exceptions)("rewrite_cp_refs_in_method exception: '%s'", ex_name->as_C_string());
// Need to clear pending exception here as the super caller sets
// the JVMTI_ERROR_INTERNAL if the returned value is false.
CLEAR_PENDING_EXCEPTION;
@@ -1715,14 +1689,12 @@
if (!StressLdcRewrite && new_index <= max_jubyte) {
// The new value can still use ldc instead of ldc_w
// unless we are trying to stress ldc -> ldc_w rewriting
- RC_TRACE_WITH_THREAD(0x00080000, THREAD,
- ("%s@" INTPTR_FORMAT " old=%d, new=%d", Bytecodes::name(c),
- p2i(bcp), cp_index, new_index));
+ log_trace(redefine, class, constantpool)
+ ("%s@" INTPTR_FORMAT " old=%d, new=%d", Bytecodes::name(c), p2i(bcp), cp_index, new_index);
*(bcp + 1) = new_index;
} else {
- RC_TRACE_WITH_THREAD(0x00080000, THREAD,
- ("%s->ldc_w@" INTPTR_FORMAT " old=%d, new=%d",
- Bytecodes::name(c), p2i(bcp), cp_index, new_index));
+ log_trace(redefine, class, constantpool)
+ ("%s->ldc_w@" INTPTR_FORMAT " old=%d, new=%d", Bytecodes::name(c), p2i(bcp), cp_index, new_index);
// the new value needs ldc_w instead of ldc
u_char inst_buffer[4]; // max instruction size is 4 bytes
bcp = (address)inst_buffer;
@@ -1781,9 +1753,8 @@
int new_index = find_new_index(cp_index);
if (new_index != 0) {
// the original index is mapped so update w/ new value
- RC_TRACE_WITH_THREAD(0x00080000, THREAD,
- ("%s@" INTPTR_FORMAT " old=%d, new=%d", Bytecodes::name(c),
- p2i(bcp), cp_index, new_index));
+ log_trace(redefine, class, constantpool)
+ ("%s@" INTPTR_FORMAT " old=%d, new=%d", Bytecodes::name(c),p2i(bcp), cp_index, new_index);
// Rewriter::rewrite_method() uses put_native_u2() in this
// situation because it is reusing the constant pool index
// location for a native index into the ConstantPoolCache.
@@ -1823,8 +1794,7 @@
return true;
}
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("class_annotations length=%d", class_annotations->length()));
+ log_debug(redefine, class, annotation)("class_annotations length=%d", class_annotations->length());
int byte_i = 0; // byte index into class_annotations
return rewrite_cp_refs_in_annotations_typeArray(class_annotations, byte_i,
@@ -1846,8 +1816,7 @@
if ((byte_i_ref + 2) > annotations_typeArray->length()) {
// not enough room for num_annotations field
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("length() is too small for num_annotations field"));
+ log_debug(redefine, class, annotation)("length() is too small for num_annotations field");
return false;
}
@@ -1855,15 +1824,13 @@
annotations_typeArray->adr_at(byte_i_ref));
byte_i_ref += 2;
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("num_annotations=%d", num_annotations));
+ log_debug(redefine, class, annotation)("num_annotations=%d", num_annotations);
int calc_num_annotations = 0;
for (; calc_num_annotations < num_annotations; calc_num_annotations++) {
if (!rewrite_cp_refs_in_annotation_struct(annotations_typeArray,
byte_i_ref, THREAD)) {
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("bad annotation_struct at %d", calc_num_annotations));
+ log_debug(redefine, class, annotation)("bad annotation_struct at %d", calc_num_annotations);
// propagate failure back to caller
return false;
}
@@ -1891,8 +1858,7 @@
AnnotationArray* annotations_typeArray, int &byte_i_ref, TRAPS) {
if ((byte_i_ref + 2 + 2) > annotations_typeArray->length()) {
// not enough room for smallest annotation_struct
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("length() is too small for annotation_struct"));
+ log_debug(redefine, class, annotation)("length() is too small for annotation_struct");
return false;
}
@@ -1903,9 +1869,8 @@
annotations_typeArray->adr_at(byte_i_ref));
byte_i_ref += 2;
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("type_index=%d num_element_value_pairs=%d", type_index,
- num_element_value_pairs));
+ log_debug(redefine, class, annotation)
+ ("type_index=%d num_element_value_pairs=%d", type_index, num_element_value_pairs);
int calc_num_element_value_pairs = 0;
for (; calc_num_element_value_pairs < num_element_value_pairs;
@@ -1913,8 +1878,7 @@
if ((byte_i_ref + 2) > annotations_typeArray->length()) {
// not enough room for another element_name_index, let alone
// the rest of another component
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("length() is too small for element_name_index"));
+ log_debug(redefine, class, annotation)("length() is too small for element_name_index");
return false;
}
@@ -1922,13 +1886,11 @@
annotations_typeArray, byte_i_ref,
"element_name_index", THREAD);
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("element_name_index=%d", element_name_index));
+ log_debug(redefine, class, annotation)("element_name_index=%d", element_name_index);
if (!rewrite_cp_refs_in_element_value(annotations_typeArray,
byte_i_ref, THREAD)) {
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("bad element_value at %d", calc_num_element_value_pairs));
+ log_debug(redefine, class, annotation)("bad element_value at %d", calc_num_element_value_pairs);
// propagate failure back to caller
return false;
}
@@ -1953,7 +1915,7 @@
u2 old_cp_index = Bytes::get_Java_u2(cp_index_addr);
u2 new_cp_index = find_new_index(old_cp_index);
if (new_cp_index != 0) {
- RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("mapped old %s=%d", trace_mesg, old_cp_index));
+ log_debug(redefine, class, annotation)("mapped old %s=%d", trace_mesg, old_cp_index);
Bytes::put_Java_u2(cp_index_addr, new_cp_index);
old_cp_index = new_cp_index;
}
@@ -1988,14 +1950,13 @@
if ((byte_i_ref + 1) > annotations_typeArray->length()) {
// not enough room for a tag let alone the rest of an element_value
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("length() is too small for a tag"));
+ log_debug(redefine, class, annotation)("length() is too small for a tag");
return false;
}
u1 tag = annotations_typeArray->at(byte_i_ref);
byte_i_ref++;
- RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("tag='%c'", tag));
+ log_debug(redefine, class, annotation)("tag='%c'", tag);
switch (tag) {
// These BaseType tag values are from Table 4.2 in VM spec:
@@ -2017,8 +1978,7 @@
if ((byte_i_ref + 2) > annotations_typeArray->length()) {
// not enough room for a const_value_index
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("length() is too small for a const_value_index"));
+ log_debug(redefine, class, annotation)("length() is too small for a const_value_index");
return false;
}
@@ -2026,8 +1986,7 @@
annotations_typeArray, byte_i_ref,
"const_value_index", THREAD);
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("const_value_index=%d", const_value_index));
+ log_debug(redefine, class, annotation)("const_value_index=%d", const_value_index);
} break;
case 'e':
@@ -2036,8 +1995,7 @@
if ((byte_i_ref + 4) > annotations_typeArray->length()) {
// not enough room for a enum_const_value
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("length() is too small for a enum_const_value"));
+ log_debug(redefine, class, annotation)("length() is too small for a enum_const_value");
return false;
}
@@ -2049,9 +2007,8 @@
annotations_typeArray, byte_i_ref,
"const_name_index", THREAD);
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("type_name_index=%d const_name_index=%d", type_name_index,
- const_name_index));
+ log_debug(redefine, class, annotation)
+ ("type_name_index=%d const_name_index=%d", type_name_index, const_name_index);
} break;
case 'c':
@@ -2060,8 +2017,7 @@
if ((byte_i_ref + 2) > annotations_typeArray->length()) {
// not enough room for a class_info_index
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("length() is too small for a class_info_index"));
+ log_debug(redefine, class, annotation)("length() is too small for a class_info_index");
return false;
}
@@ -2069,8 +2025,7 @@
annotations_typeArray, byte_i_ref,
"class_info_index", THREAD);
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("class_info_index=%d", class_info_index));
+ log_debug(redefine, class, annotation)("class_info_index=%d", class_info_index);
} break;
case '@':
@@ -2087,8 +2042,7 @@
{
if ((byte_i_ref + 2) > annotations_typeArray->length()) {
// not enough room for a num_values field
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("length() is too small for a num_values field"));
+ log_debug(redefine, class, annotation)("length() is too small for a num_values field");
return false;
}
@@ -2097,14 +2051,13 @@
u2 num_values = Bytes::get_Java_u2((address)
annotations_typeArray->adr_at(byte_i_ref));
byte_i_ref += 2;
- RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("num_values=%d", num_values));
+ log_debug(redefine, class, annotation)("num_values=%d", num_values);
int calc_num_values = 0;
for (; calc_num_values < num_values; calc_num_values++) {
if (!rewrite_cp_refs_in_element_value(
annotations_typeArray, byte_i_ref, THREAD)) {
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("bad nested element_value at %d", calc_num_values));
+ log_debug(redefine, class, annotation)("bad nested element_value at %d", calc_num_values);
// propagate failure back to caller
return false;
}
@@ -2113,7 +2066,7 @@
} break;
default:
- RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("bad tag=0x%x", tag));
+ log_debug(redefine, class, annotation)("bad tag=0x%x", tag);
return false;
} // end decode tag field
@@ -2132,8 +2085,7 @@
return true;
}
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("fields_annotations length=%d", fields_annotations->length()));
+ log_debug(redefine, class, annotation)("fields_annotations length=%d", fields_annotations->length());
for (int i = 0; i < fields_annotations->length(); i++) {
AnnotationArray* field_annotations = fields_annotations->at(i);
@@ -2145,8 +2097,7 @@
int byte_i = 0; // byte index into field_annotations
if (!rewrite_cp_refs_in_annotations_typeArray(field_annotations, byte_i,
THREAD)) {
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("bad field_annotations at %d", i));
+ log_debug(redefine, class, annotation)("bad field_annotations at %d", i);
// propagate failure back to caller
return false;
}
@@ -2172,8 +2123,7 @@
int byte_i = 0; // byte index into method_annotations
if (!rewrite_cp_refs_in_annotations_typeArray(method_annotations, byte_i,
THREAD)) {
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("bad method_annotations at %d", i));
+ log_debug(redefine, class, annotation)("bad method_annotations at %d", i);
// propagate failure back to caller
return false;
}
@@ -2210,8 +2160,7 @@
if (method_parameter_annotations->length() < 1) {
// not enough room for a num_parameters field
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("length() is too small for a num_parameters field at %d", i));
+ log_debug(redefine, class, annotation)("length() is too small for a num_parameters field at %d", i);
return false;
}
@@ -2220,15 +2169,13 @@
u1 num_parameters = method_parameter_annotations->at(byte_i);
byte_i++;
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("num_parameters=%d", num_parameters));
+ log_debug(redefine, class, annotation)("num_parameters=%d", num_parameters);
int calc_num_parameters = 0;
for (; calc_num_parameters < num_parameters; calc_num_parameters++) {
if (!rewrite_cp_refs_in_annotations_typeArray(
method_parameter_annotations, byte_i, THREAD)) {
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("bad method_parameter_annotations at %d", calc_num_parameters));
+ log_debug(redefine, class, annotation)("bad method_parameter_annotations at %d", calc_num_parameters);
// propagate failure back to caller
return false;
}
@@ -2264,8 +2211,7 @@
if (!rewrite_cp_refs_in_element_value(
method_default_annotations, byte_i, THREAD)) {
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("bad default element_value at %d", i));
+ log_debug(redefine, class, annotation)("bad default element_value at %d", i);
// propagate failure back to caller
return false;
}
@@ -2285,8 +2231,7 @@
return true;
}
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("class_type_annotations length=%d", class_type_annotations->length()));
+ log_debug(redefine, class, annotation)("class_type_annotations length=%d", class_type_annotations->length());
int byte_i = 0; // byte index into class_type_annotations
return rewrite_cp_refs_in_type_annotations_typeArray(class_type_annotations,
@@ -2304,8 +2249,7 @@
return true;
}
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("fields_type_annotations length=%d", fields_type_annotations->length()));
+ log_debug(redefine, class, annotation)("fields_type_annotations length=%d", fields_type_annotations->length());
for (int i = 0; i < fields_type_annotations->length(); i++) {
AnnotationArray* field_type_annotations = fields_type_annotations->at(i);
@@ -2317,8 +2261,7 @@
int byte_i = 0; // byte index into field_type_annotations
if (!rewrite_cp_refs_in_type_annotations_typeArray(field_type_annotations,
byte_i, "field_info", THREAD)) {
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("bad field_type_annotations at %d", i));
+ log_debug(redefine, class, annotation)("bad field_type_annotations at %d", i);
// propagate failure back to caller
return false;
}
@@ -2341,14 +2284,12 @@
continue;
}
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("methods type_annotations length=%d", method_type_annotations->length()));
+ log_debug(redefine, class, annotation)("methods type_annotations length=%d", method_type_annotations->length());
int byte_i = 0; // byte index into method_type_annotations
if (!rewrite_cp_refs_in_type_annotations_typeArray(method_type_annotations,
byte_i, "method_info", THREAD)) {
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("bad method_type_annotations at %d", i));
+ log_debug(redefine, class, annotation)("bad method_type_annotations at %d", i);
// propagate failure back to caller
return false;
}
@@ -2374,8 +2315,7 @@
if ((byte_i_ref + 2) > type_annotations_typeArray->length()) {
// not enough room for num_annotations field
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("length() is too small for num_annotations field"));
+ log_debug(redefine, class, annotation)("length() is too small for num_annotations field");
return false;
}
@@ -2383,15 +2323,13 @@
type_annotations_typeArray->adr_at(byte_i_ref));
byte_i_ref += 2;
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("num_type_annotations=%d", num_annotations));
+ log_debug(redefine, class, annotation)("num_type_annotations=%d", num_annotations);
int calc_num_annotations = 0;
for (; calc_num_annotations < num_annotations; calc_num_annotations++) {
if (!rewrite_cp_refs_in_type_annotation_struct(type_annotations_typeArray,
byte_i_ref, location_mesg, THREAD)) {
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("bad type_annotation_struct at %d", calc_num_annotations));
+ log_debug(redefine, class, annotation)("bad type_annotation_struct at %d", calc_num_annotations);
// propagate failure back to caller
return false;
}
@@ -2399,10 +2337,9 @@
assert(num_annotations == calc_num_annotations, "sanity check");
if (byte_i_ref != type_annotations_typeArray->length()) {
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("read wrong amount of bytes at end of processing "
- "type_annotations_typeArray (%d of %d bytes were read)",
- byte_i_ref, type_annotations_typeArray->length()));
+ log_debug(redefine, class, annotation)
+ ("read wrong amount of bytes at end of processing type_annotations_typeArray (%d of %d bytes were read)",
+ byte_i_ref, type_annotations_typeArray->length());
return false;
}
@@ -2479,15 +2416,14 @@
if ((byte_i_ref + 1) > type_annotations_typeArray->length()) {
// not enough room for a target_type let alone the rest of a type_annotation
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("length() is too small for a target_type"));
+ log_debug(redefine, class, annotation)("length() is too small for a target_type");
return false;
}
u1 target_type = type_annotations_typeArray->at(byte_i_ref);
byte_i_ref += 1;
- RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("target_type=0x%.2x", target_type));
- RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("location=%s", location_mesg));
+ log_debug(redefine, class, annotation)("target_type=0x%.2x", target_type);
+ log_debug(redefine, class, annotation)("location=%s", location_mesg);
// Skip over target_info
switch (target_type) {
@@ -2505,17 +2441,14 @@
// }
//
if ((byte_i_ref + 1) > type_annotations_typeArray->length()) {
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("length() is too small for a type_parameter_target"));
+ log_debug(redefine, class, annotation)("length() is too small for a type_parameter_target");
return false;
}
u1 type_parameter_index = type_annotations_typeArray->at(byte_i_ref);
byte_i_ref += 1;
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("type_parameter_target: type_parameter_index=%d",
- type_parameter_index));
+ log_debug(redefine, class, annotation)("type_parameter_target: type_parameter_index=%d", type_parameter_index);
} break;
case 0x10:
@@ -2531,8 +2464,7 @@
// }
//
if ((byte_i_ref + 2) > type_annotations_typeArray->length()) {
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("length() is too small for a supertype_target"));
+ log_debug(redefine, class, annotation)("length() is too small for a supertype_target");
return false;
}
@@ -2540,8 +2472,7 @@
type_annotations_typeArray->adr_at(byte_i_ref));
byte_i_ref += 2;
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("supertype_target: supertype_index=%d", supertype_index));
+ log_debug(redefine, class, annotation)("supertype_target: supertype_index=%d", supertype_index);
} break;
case 0x11:
@@ -2559,8 +2490,7 @@
// }
//
if ((byte_i_ref + 2) > type_annotations_typeArray->length()) {
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("length() is too small for a type_parameter_bound_target"));
+ log_debug(redefine, class, annotation)("length() is too small for a type_parameter_bound_target");
return false;
}
@@ -2569,9 +2499,8 @@
u1 bound_index = type_annotations_typeArray->at(byte_i_ref);
byte_i_ref += 1;
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("type_parameter_bound_target: type_parameter_index=%d, bound_index=%d",
- type_parameter_index, bound_index));
+ log_debug(redefine, class, annotation)
+ ("type_parameter_bound_target: type_parameter_index=%d, bound_index=%d", type_parameter_index, bound_index);
} break;
case 0x13:
@@ -2589,8 +2518,7 @@
// empty_target {
// }
//
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("empty_target"));
+ log_debug(redefine, class, annotation)("empty_target");
} break;
case 0x16:
@@ -2604,17 +2532,15 @@
// }
//
if ((byte_i_ref + 1) > type_annotations_typeArray->length()) {
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("length() is too small for a formal_parameter_target"));
+ log_debug(redefine, class, annotation)("length() is too small for a formal_parameter_target");
return false;
}
u1 formal_parameter_index = type_annotations_typeArray->at(byte_i_ref);
byte_i_ref += 1;
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("formal_parameter_target: formal_parameter_index=%d",
- formal_parameter_index));
+ log_debug(redefine, class, annotation)
+ ("formal_parameter_target: formal_parameter_index=%d", formal_parameter_index);
} break;
case 0x17:
@@ -2628,8 +2554,7 @@
// }
//
if ((byte_i_ref + 2) > type_annotations_typeArray->length()) {
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("length() is too small for a throws_target"));
+ log_debug(redefine, class, annotation)("length() is too small for a throws_target");
return false;
}
@@ -2637,8 +2562,7 @@
type_annotations_typeArray->adr_at(byte_i_ref));
byte_i_ref += 2;
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("throws_target: throws_type_index=%d", throws_type_index));
+ log_debug(redefine, class, annotation)("throws_target: throws_type_index=%d", throws_type_index);
} break;
case 0x40:
@@ -2661,8 +2585,7 @@
//
if ((byte_i_ref + 2) > type_annotations_typeArray->length()) {
// not enough room for a table_length let alone the rest of a localvar_target
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("length() is too small for a localvar_target table_length"));
+ log_debug(redefine, class, annotation)("length() is too small for a localvar_target table_length");
return false;
}
@@ -2670,16 +2593,14 @@
type_annotations_typeArray->adr_at(byte_i_ref));
byte_i_ref += 2;
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("localvar_target: table_length=%d", table_length));
+ log_debug(redefine, class, annotation)("localvar_target: table_length=%d", table_length);
int table_struct_size = 2 + 2 + 2; // 3 u2 variables per table entry
int table_size = table_length * table_struct_size;
if ((byte_i_ref + table_size) > type_annotations_typeArray->length()) {
// not enough room for a table
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("length() is too small for a table array of length %d", table_length));
+ log_debug(redefine, class, annotation)("length() is too small for a table array of length %d", table_length);
return false;
}
@@ -2698,8 +2619,7 @@
// }
//
if ((byte_i_ref + 2) > type_annotations_typeArray->length()) {
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("length() is too small for a catch_target"));
+ log_debug(redefine, class, annotation)("length() is too small for a catch_target");
return false;
}
@@ -2707,8 +2627,7 @@
type_annotations_typeArray->adr_at(byte_i_ref));
byte_i_ref += 2;
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("catch_target: exception_table_index=%d", exception_table_index));
+ log_debug(redefine, class, annotation)("catch_target: exception_table_index=%d", exception_table_index);
} break;
case 0x43:
@@ -2731,8 +2650,7 @@
// }
//
if ((byte_i_ref + 2) > type_annotations_typeArray->length()) {
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("length() is too small for a offset_target"));
+ log_debug(redefine, class, annotation)("length() is too small for a offset_target");
return false;
}
@@ -2740,8 +2658,7 @@
type_annotations_typeArray->adr_at(byte_i_ref));
byte_i_ref += 2;
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("offset_target: offset=%d", offset));
+ log_debug(redefine, class, annotation)("offset_target: offset=%d", offset);
} break;
case 0x47:
@@ -2769,8 +2686,7 @@
// }
//
if ((byte_i_ref + 3) > type_annotations_typeArray->length()) {
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("length() is too small for a type_argument_target"));
+ log_debug(redefine, class, annotation)("length() is too small for a type_argument_target");
return false;
}
@@ -2780,14 +2696,12 @@
u1 type_argument_index = type_annotations_typeArray->at(byte_i_ref);
byte_i_ref += 1;
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("type_argument_target: offset=%d, type_argument_index=%d",
- offset, type_argument_index));
+ log_debug(redefine, class, annotation)
+ ("type_argument_target: offset=%d, type_argument_index=%d", offset, type_argument_index);
} break;
default:
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("unknown target_type"));
+ log_debug(redefine, class, annotation)("unknown target_type");
#ifdef ASSERT
ShouldNotReachHere();
#endif
@@ -2814,24 +2728,21 @@
if ((byte_i_ref + 1) > type_annotations_typeArray->length()) {
// not enough room for a path_length let alone the rest of the type_path
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("length() is too small for a type_path"));
+ log_debug(redefine, class, annotation)("length() is too small for a type_path");
return false;
}
u1 path_length = type_annotations_typeArray->at(byte_i_ref);
byte_i_ref += 1;
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("type_path: path_length=%d", path_length));
+ log_debug(redefine, class, annotation)("type_path: path_length=%d", path_length);
int calc_path_length = 0;
for (; calc_path_length < path_length; calc_path_length++) {
if ((byte_i_ref + 1 + 1) > type_annotations_typeArray->length()) {
// not enough room for a path
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("length() is too small for path entry %d of %d",
- calc_path_length, path_length));
+ log_debug(redefine, class, annotation)
+ ("length() is too small for path entry %d of %d", calc_path_length, path_length);
return false;
}
@@ -2840,14 +2751,13 @@
u1 type_argument_index = type_annotations_typeArray->at(byte_i_ref);
byte_i_ref += 1;
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ log_debug(redefine, class, annotation)
("type_path: path[%d]: type_path_kind=%d, type_argument_index=%d",
- calc_path_length, type_path_kind, type_argument_index));
+ calc_path_length, type_path_kind, type_argument_index);
if (type_path_kind > 3 || (type_path_kind != 3 && type_argument_index != 0)) {
// not enough room for a path
- RC_TRACE_WITH_THREAD(0x02000000, THREAD,
- ("inconsistent type_path values"));
+ log_debug(redefine, class, annotation)("inconsistent type_path values");
return false;
}
}
@@ -2883,8 +2793,7 @@
u2 number_of_entries = Bytes::get_Java_u2(stackmap_p);
stackmap_p += 2;
- RC_TRACE_WITH_THREAD(0x04000000, THREAD,
- ("number_of_entries=%u", number_of_entries));
+ log_debug(redefine, class, stackmap)("number_of_entries=%u", number_of_entries);
// walk through each stack_map_frame
u2 calc_number_of_entries = 0;
@@ -3084,16 +2993,14 @@
u2 cpool_index = Bytes::get_Java_u2(stackmap_p_ref);
u2 new_cp_index = find_new_index(cpool_index);
if (new_cp_index != 0) {
- RC_TRACE_WITH_THREAD(0x04000000, THREAD,
- ("mapped old cpool_index=%d", cpool_index));
+ log_debug(redefine, class, stackmap)("mapped old cpool_index=%d", cpool_index);
Bytes::put_Java_u2(stackmap_p_ref, new_cp_index);
cpool_index = new_cp_index;
}
stackmap_p_ref += 2;
- RC_TRACE_WITH_THREAD(0x04000000, THREAD,
- ("frame_i=%u, frame_type=%u, cpool_index=%d", frame_i,
- frame_type, cpool_index));
+ log_debug(redefine, class, stackmap)
+ ("frame_i=%u, frame_type=%u, cpool_index=%d", frame_i, frame_type, cpool_index);
} break;
// Uninitialized_variable_info {
@@ -3106,8 +3013,7 @@
break;
default:
- RC_TRACE_WITH_THREAD(0x04000000, THREAD,
- ("frame_i=%u, frame_type=%u, bad tag=0x%x", frame_i, frame_type, tag));
+ log_debug(redefine, class, stackmap)("frame_i=%u, frame_type=%u, bad tag=0x%x", frame_i, frame_type, tag);
ShouldNotReachHere();
break;
} // end switch (tag)
@@ -3157,29 +3063,25 @@
jshort cur_index = fs.name_index();
jshort new_index = find_new_index(cur_index);
if (new_index != 0) {
- RC_TRACE_WITH_THREAD(0x00080000, THREAD,
- ("field-name_index change: %d to %d", cur_index, new_index));
+ log_trace(redefine, class, constantpool)("field-name_index change: %d to %d", cur_index, new_index);
fs.set_name_index(new_index);
}
cur_index = fs.signature_index();
new_index = find_new_index(cur_index);
if (new_index != 0) {
- RC_TRACE_WITH_THREAD(0x00080000, THREAD,
- ("field-signature_index change: %d to %d", cur_index, new_index));
+ log_trace(redefine, class, constantpool)("field-signature_index change: %d to %d", cur_index, new_index);
fs.set_signature_index(new_index);
}
cur_index = fs.initval_index();
new_index = find_new_index(cur_index);
if (new_index != 0) {
- RC_TRACE_WITH_THREAD(0x00080000, THREAD,
- ("field-initval_index change: %d to %d", cur_index, new_index));
+ log_trace(redefine, class, constantpool)("field-initval_index change: %d to %d", cur_index, new_index);
fs.set_initval_index(new_index);
}
cur_index = fs.generic_signature_index();
new_index = find_new_index(cur_index);
if (new_index != 0) {
- RC_TRACE_WITH_THREAD(0x00080000, THREAD,
- ("field-generic_signature change: %d to %d", cur_index, new_index));
+ log_trace(redefine, class, constantpool)("field-generic_signature change: %d to %d", cur_index, new_index);
fs.set_generic_signature_index(new_index);
}
} // end for each field
@@ -3196,22 +3098,19 @@
}
int new_index = find_new_index(cur_index);
if (new_index != 0) {
- RC_TRACE_WITH_THREAD(0x00080000, THREAD,
- ("inner_class_info change: %d to %d", cur_index, new_index));
+ log_trace(redefine, class, constantpool)("inner_class_info change: %d to %d", cur_index, new_index);
iter.set_inner_class_info_index(new_index);
}
cur_index = iter.outer_class_info_index();
new_index = find_new_index(cur_index);
if (new_index != 0) {
- RC_TRACE_WITH_THREAD(0x00080000, THREAD,
- ("outer_class_info change: %d to %d", cur_index, new_index));
+ log_trace(redefine, class, constantpool)("outer_class_info change: %d to %d", cur_index, new_index);
iter.set_outer_class_info_index(new_index);
}
cur_index = iter.inner_name_index();
new_index = find_new_index(cur_index);
if (new_index != 0) {
- RC_TRACE_WITH_THREAD(0x00080000, THREAD,
- ("inner_name change: %d to %d", cur_index, new_index));
+ log_trace(redefine, class, constantpool)("inner_name change: %d to %d", cur_index, new_index);
iter.set_inner_name_index(new_index);
}
} // end for each inner class
@@ -3225,23 +3124,20 @@
int new_index = find_new_index(method->name_index());
if (new_index != 0) {
- RC_TRACE_WITH_THREAD(0x00080000, THREAD,
- ("method-name_index change: %d to %d", method->name_index(),
- new_index));
+ log_trace(redefine, class, constantpool)
+ ("method-name_index change: %d to %d", method->name_index(), new_index);
method->set_name_index(new_index);
}
new_index = find_new_index(method->signature_index());
if (new_index != 0) {
- RC_TRACE_WITH_THREAD(0x00080000, THREAD,
- ("method-signature_index change: %d to %d",
- method->signature_index(), new_index));
+ log_trace(redefine, class, constantpool)
+ ("method-signature_index change: %d to %d", method->signature_index(), new_index);
method->set_signature_index(new_index);
}
new_index = find_new_index(method->generic_signature_index());
if (new_index != 0) {
- RC_TRACE_WITH_THREAD(0x00080000, THREAD,
- ("method-generic_signature_index change: %d to %d",
- method->generic_signature_index(), new_index));
+ log_trace(redefine, class, constantpool)
+ ("method-generic_signature_index change: %d to %d", method->generic_signature_index(), new_index);
method->set_generic_signature_index(new_index);
}
@@ -3255,8 +3151,7 @@
int cur_index = cext_table[j].class_cp_index;
int new_index = find_new_index(cur_index);
if (new_index != 0) {
- RC_TRACE_WITH_THREAD(0x00080000, THREAD,
- ("cext-class_cp_index change: %d to %d", cur_index, new_index));
+ log_trace(redefine, class, constantpool)("cext-class_cp_index change: %d to %d", cur_index, new_index);
cext_table[j].class_cp_index = (u2)new_index;
}
} // end for each checked exception table entry
@@ -3274,8 +3169,7 @@
int cur_index = ex_table.catch_type_index(j);
int new_index = find_new_index(cur_index);
if (new_index != 0) {
- RC_TRACE_WITH_THREAD(0x00080000, THREAD,
- ("ext-klass_index change: %d to %d", cur_index, new_index));
+ log_trace(redefine, class, constantpool)("ext-klass_index change: %d to %d", cur_index, new_index);
ex_table.set_catch_type_index(j, new_index);
}
} // end for each exception table entry
@@ -3292,23 +3186,19 @@
int cur_index = lv_table[j].name_cp_index;
int new_index = find_new_index(cur_index);
if (new_index != 0) {
- RC_TRACE_WITH_THREAD(0x00080000, THREAD,
- ("lvt-name_cp_index change: %d to %d", cur_index, new_index));
+ log_trace(redefine, class, constantpool)("lvt-name_cp_index change: %d to %d", cur_index, new_index);
lv_table[j].name_cp_index = (u2)new_index;
}
cur_index = lv_table[j].descriptor_cp_index;
new_index = find_new_index(cur_index);
if (new_index != 0) {
- RC_TRACE_WITH_THREAD(0x00080000, THREAD,
- ("lvt-descriptor_cp_index change: %d to %d", cur_index,
- new_index));
+ log_trace(redefine, class, constantpool)("lvt-descriptor_cp_index change: %d to %d", cur_index, new_index);
lv_table[j].descriptor_cp_index = (u2)new_index;
}
cur_index = lv_table[j].signature_cp_index;
new_index = find_new_index(cur_index);
if (new_index != 0) {
- RC_TRACE_WITH_THREAD(0x00080000, THREAD,
- ("lvt-signature_cp_index change: %d to %d", cur_index, new_index));
+ log_trace(redefine, class, constantpool)("lvt-signature_cp_index change: %d to %d", cur_index, new_index);
lv_table[j].signature_cp_index = (u2)new_index;
}
} // end for each local variable table entry
@@ -3332,13 +3222,6 @@
bool trace_name_printed = false;
InstanceKlass *the_class = InstanceKlass::cast(_the_class_oop);
- // Very noisy: only enable this call if you are trying to determine
- // that a specific class gets found by this routine.
- // RC_TRACE macro has an embedded ResourceMark
- // RC_TRACE_WITH_THREAD(0x00100000, THREAD,
- // ("adjust check: name=%s", k->external_name()));
- // trace_name_printed = true;
-
// If the class being redefined is java.lang.Object, we need to fix all
// array class vtables also
if (k->is_array_klass() && _the_class_oop == SystemDictionary::Object_klass()) {
@@ -3576,9 +3459,11 @@
// With tracing we try not to "yack" too much. The position of
// this trace assumes there are fewer obsolete methods than
// EMCP methods.
- RC_TRACE(0x00000100, ("mark %s(%s) as obsolete",
- old_method->name()->as_C_string(),
- old_method->signature()->as_C_string()));
+ if (log_is_enabled(Trace, redefine, class, obsolete, mark)) {
+ ResourceMark rm;
+ log_trace(redefine, class, obsolete, mark)
+ ("mark %s(%s) as obsolete", old_method->name()->as_C_string(), old_method->signature()->as_C_string());
+ }
}
old_method->set_is_old();
}
@@ -3596,14 +3481,15 @@
// With tracing we try not to "yack" too much. The position of
// this trace assumes there are fewer obsolete methods than
// EMCP methods.
- RC_TRACE(0x00000100, ("mark deleted %s(%s) as obsolete",
- old_method->name()->as_C_string(),
- old_method->signature()->as_C_string()));
+ if (log_is_enabled(Trace, redefine, class, obsolete, mark)) {
+ ResourceMark rm;
+ log_trace(redefine, class, obsolete, mark)
+ ("mark deleted %s(%s) as obsolete", old_method->name()->as_C_string(), old_method->signature()->as_C_string());
+ }
}
assert((emcp_method_count + obsolete_count) == _old_methods->length(),
"sanity check");
- RC_TRACE(0x00000100, ("EMCP_cnt=%d, obsolete_cnt=%d", emcp_method_count,
- obsolete_count));
+ log_trace(redefine, class, obsolete, mark)("EMCP_cnt=%d, obsolete_cnt=%d", emcp_method_count, obsolete_count);
return emcp_method_count;
}
@@ -3866,7 +3752,10 @@
Klass* scratch_class_oop, TRAPS) {
HandleMark hm(THREAD); // make sure handles from this call are freed
- RC_TIMER_START(_timer_rsc_phase1);
+
+ if (log_is_enabled(Info, redefine, class, timer)) {
+ _timer_rsc_phase1.start();
+ }
instanceKlassHandle scratch_class(scratch_class_oop);
@@ -4083,8 +3972,10 @@
// keep track of previous versions of this class
the_class->add_previous_version(scratch_class, emcp_method_count);
- RC_TIMER_STOP(_timer_rsc_phase1);
- RC_TIMER_START(_timer_rsc_phase2);
+ _timer_rsc_phase1.stop();
+ if (log_is_enabled(Info, redefine, class, timer)) {
+ _timer_rsc_phase2.start();
+ }
// Adjust constantpool caches and vtables for all classes
// that reference methods of the evolved class.
@@ -4104,25 +3995,20 @@
the_class->oop_map_cache()->flush_obsolete_entries();
}
- // increment the classRedefinedCount field in the_class and in any
- // direct and indirect subclasses of the_class
- increment_class_counter((InstanceKlass *)the_class(), THREAD);
-
- // RC_TRACE macro has an embedded ResourceMark
- RC_TRACE_WITH_THREAD(0x00000001, THREAD,
- ("redefined name=%s, count=%d (avail_mem=" UINT64_FORMAT "K)",
- the_class->external_name(),
- java_lang_Class::classRedefinedCount(the_class_mirror),
- os::available_memory() >> 10));
-
{
ResourceMark rm(THREAD);
+ // increment the classRedefinedCount field in the_class and in any
+ // direct and indirect subclasses of the_class
+ increment_class_counter((InstanceKlass *)the_class(), THREAD);
+ log_info(redefine, class, load)
+ ("redefined name=%s, count=%d (avail_mem=" UINT64_FORMAT "K)",
+ the_class->external_name(), java_lang_Class::classRedefinedCount(the_class_mirror), os::available_memory() >> 10);
Events::log_redefinition(THREAD, "redefined class name=%s, count=%d",
the_class->external_name(),
java_lang_Class::classRedefinedCount(the_class_mirror));
}
- RC_TIMER_STOP(_timer_rsc_phase2);
+ _timer_rsc_phase2.stop();
} // end redefine_single_class()
@@ -4136,8 +4022,7 @@
if (class_oop != _the_class_oop) {
// _the_class_oop count is printed at end of redefine_single_class()
- RC_TRACE_WITH_THREAD(0x00000008, THREAD,
- ("updated count in subclass=%s to %d", ik->external_name(), new_count));
+ log_debug(redefine, class, subclass)("updated count in subclass=%s to %d", ik->external_name(), new_count);
}
for (Klass *subk = ik->subklass(); subk != NULL;
@@ -4159,11 +4044,10 @@
ResourceMark rm(_thread);
if (k->vtable_length() > 0 &&
!k->vtable()->check_no_old_or_obsolete_entries()) {
- if (RC_TRACE_ENABLED(0x00004000)) {
- RC_TRACE_WITH_THREAD(0x00004000, _thread,
- ("klassVtable::check_no_old_or_obsolete_entries failure"
- " -- OLD or OBSOLETE method found -- class: %s",
- k->signature_name()));
+ if (log_is_enabled(Trace, redefine, class, obsolete, metadata)) {
+ log_trace(redefine, class, obsolete, metadata)
+ ("klassVtable::check_no_old_or_obsolete_entries failure -- OLD or OBSOLETE method found -- class: %s",
+ k->signature_name());
k->vtable()->dump_vtable();
}
no_old_methods = false;
@@ -4176,11 +4060,10 @@
// an itable should never contain old or obsolete methods
if (ik->itable_length() > 0 &&
!ik->itable()->check_no_old_or_obsolete_entries()) {
- if (RC_TRACE_ENABLED(0x00004000)) {
- RC_TRACE_WITH_THREAD(0x00004000, _thread,
- ("klassItable::check_no_old_or_obsolete_entries failure"
- " -- OLD or OBSOLETE method found -- class: %s",
- ik->signature_name()));
+ if (log_is_enabled(Trace, redefine, class, obsolete, metadata)) {
+ log_trace(redefine, class, obsolete, metadata)
+ ("klassItable::check_no_old_or_obsolete_entries failure -- OLD or OBSOLETE method found -- class: %s",
+ ik->signature_name());
ik->itable()->dump_itable();
}
no_old_methods = false;
@@ -4190,11 +4073,10 @@
if (ik->constants() != NULL &&
ik->constants()->cache() != NULL &&
!ik->constants()->cache()->check_no_old_or_obsolete_entries()) {
- if (RC_TRACE_ENABLED(0x00004000)) {
- RC_TRACE_WITH_THREAD(0x00004000, _thread,
- ("cp-cache::check_no_old_or_obsolete_entries failure"
- " -- OLD or OBSOLETE method found -- class: %s",
- ik->signature_name()));
+ if (log_is_enabled(Trace, redefine, class, obsolete, metadata)) {
+ log_trace(redefine, class, obsolete, metadata)
+ ("cp-cache::check_no_old_or_obsolete_entries failure -- OLD or OBSOLETE method found -- class: %s",
+ ik->signature_name());
ik->constants()->cache()->dump_cache();
}
no_old_methods = false;
@@ -4203,10 +4085,10 @@
// print and fail guarantee if old methods are found.
if (!no_old_methods) {
- if (RC_TRACE_ENABLED(0x00004000)) {
+ if (log_is_enabled(Trace, redefine, class, obsolete, metadata)) {
dump_methods();
} else {
- tty->print_cr("INFO: use the '-XX:TraceRedefineClasses=16384' option "
+ log_trace(redefine, class)("Use the '-Xlog:redefine+class*:' option "
"to see more info about the following guarantee() failure.");
}
guarantee(false, "OLD and/or OBSOLETE method(s) found");
@@ -4216,54 +4098,60 @@
void VM_RedefineClasses::dump_methods() {
int j;
- RC_TRACE(0x00004000, ("_old_methods --"));
+ log_trace(redefine, class, dump)("_old_methods --");
for (j = 0; j < _old_methods->length(); ++j) {
+ LogStreamHandle(Trace, redefine, class, dump) log_stream;
Method* m = _old_methods->at(j);
- RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index()));
- m->access_flags().print_on(tty);
- tty->print(" -- ");
- m->print_name(tty);
- tty->cr();
+ log_stream.print("%4d (%5d) ", j, m->vtable_index());
+ m->access_flags().print_on(&log_stream);
+ log_stream.print(" -- ");
+ m->print_name(&log_stream);
+ log_stream.cr();
}
- RC_TRACE(0x00004000, ("_new_methods --"));
+ log_trace(redefine, class, dump)("_new_methods --");
for (j = 0; j < _new_methods->length(); ++j) {
+ LogStreamHandle(Trace, redefine, class, dump) log_stream;
Method* m = _new_methods->at(j);
- RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index()));
- m->access_flags().print_on(tty);
- tty->print(" -- ");
- m->print_name(tty);
- tty->cr();
+ log_stream.print("%4d (%5d) ", j, m->vtable_index());
+ m->access_flags().print_on(&log_stream);
+ log_stream.print(" -- ");
+ m->print_name(&log_stream);
+ log_stream.cr();
}
- RC_TRACE(0x00004000, ("_matching_(old/new)_methods --"));
+ log_trace(redefine, class, dump)("_matching_methods --");
for (j = 0; j < _matching_methods_length; ++j) {
+ LogStreamHandle(Trace, redefine, class, dump) log_stream;
Method* m = _matching_old_methods[j];
- RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index()));
- m->access_flags().print_on(tty);
- tty->print(" -- ");
- m->print_name(tty);
- tty->cr();
+ log_stream.print("%4d (%5d) ", j, m->vtable_index());
+ m->access_flags().print_on(&log_stream);
+ log_stream.print(" -- ");
+ m->print_name();
+ log_stream.cr();
+
m = _matching_new_methods[j];
- RC_TRACE_NO_CR(0x00004000, (" (%5d) ", m->vtable_index()));
- m->access_flags().print_on(tty);
- tty->cr();
+ log_stream.print(" (%5d) ", m->vtable_index());
+ m->access_flags().print_on(&log_stream);
+ log_stream.cr();
}
- RC_TRACE(0x00004000, ("_deleted_methods --"));
+ log_trace(redefine, class, dump)("_deleted_methods --");
for (j = 0; j < _deleted_methods_length; ++j) {
+ LogStreamHandle(Trace, redefine, class, dump) log_stream;
Method* m = _deleted_methods[j];
- RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index()));
- m->access_flags().print_on(tty);
- tty->print(" -- ");
- m->print_name(tty);
- tty->cr();
+ log_stream.print("%4d (%5d) ", j, m->vtable_index());
+ m->access_flags().print_on(&log_stream);
+ log_stream.print(" -- ");
+ m->print_name(&log_stream);
+ log_stream.cr();
}
- RC_TRACE(0x00004000, ("_added_methods --"));
+ log_trace(redefine, class, dump)("_added_methods --");
for (j = 0; j < _added_methods_length; ++j) {
+ LogStreamHandle(Trace, redefine, class, dump) log_stream;
Method* m = _added_methods[j];
- RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index()));
- m->access_flags().print_on(tty);
- tty->print(" -- ");
- m->print_name(tty);
- tty->cr();
+ log_stream.print("%4d (%5d) ", j, m->vtable_index());
+ m->access_flags().print_on(&log_stream);
+ log_stream.print(" -- ");
+ m->print_name(&log_stream);
+ log_stream.cr();
}
}
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp Wed May 11 00:38:58 2016 +0300
@@ -30,7 +30,6 @@
#include "memory/resourceArea.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.hpp"
-#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "runtime/vm_operations.hpp"
// Introduction:
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp Tue May 10 12:18:22 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,138 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_PRIMS_JVMTIREDEFINECLASSESTRACE_HPP
-#define SHARE_VM_PRIMS_JVMTIREDEFINECLASSESTRACE_HPP
-
-// RedefineClasses tracing support via the TraceRedefineClasses
-// option. A bit is assigned to each group of trace messages.
-// Groups of messages are individually selectable. We have to use
-// decimal values on the command line since the command option
-// parsing logic doesn't like non-decimal numerics. The HEX values
-// are used in the actual RC_TRACE() calls for sanity. To achieve
-// the old cumulative behavior, pick the level after the one in
-// which you are interested and subtract one, e.g., 33554431 will
-// print every tracing message.
-//
-// 0x00000000 | 0 - default; no tracing messages
-// 0x00000001 | 1 - name each target class before loading, after
-// loading and after redefinition is completed
-// 0x00000002 | 2 - print info if parsing, linking or
-// verification throws an exception
-// 0x00000004 | 4 - print timer info for the VM operation
-// 0x00000008 | 8 - print subclass counter updates
-// 0x00000010 | 16 - unused
-// 0x00000020 | 32 - unused
-// 0x00000040 | 64 - unused
-// 0x00000080 | 128 - unused
-// 0x00000100 | 256 - previous class weak reference addition
-// 0x00000200 | 512 - previous class weak reference mgmt during
-// class unloading checks (GC)
-// 0x00000400 | 1024 - previous class weak reference mgmt during
-// add previous ops (GC)
-// 0x00000800 | 2048 - previous class breakpoint mgmt
-// 0x00001000 | 4096 - detect calls to obsolete methods
-// 0x00002000 | 8192 - fail a guarantee() in addition to detection
-// 0x00004000 | 16384 - detect old/obsolete methods in metadata
-// 0x00008000 | 32768 - old/new method matching/add/delete
-// 0x00010000 | 65536 - impl details: CP size info
-// 0x00020000 | 131072 - impl details: CP merge pass info
-// 0x00040000 | 262144 - impl details: CP index maps
-// 0x00080000 | 524288 - impl details: modified CP index values
-// 0x00100000 | 1048576 - impl details: vtable updates
-// 0x00200000 | 2097152 - impl details: itable updates
-// 0x00400000 | 4194304 - impl details: constant pool cache updates
-// 0x00800000 | 8388608 - impl details: methodComparator info
-// 0x01000000 | 16777216 - impl details: nmethod evolution info
-// 0x02000000 | 33554432 - impl details: annotation updates
-// 0x04000000 | 67108864 - impl details: StackMapTable updates
-// 0x08000000 | 134217728 - impl details: OopMapCache updates
-// 0x10000000 | 268435456 - unused
-// 0x20000000 | 536870912 - unused
-// 0x40000000 | 1073741824 - unused
-// 0x80000000 | 2147483648 - unused
-
-// Macro for checking if TraceRedefineClasses has a specific bit
-// enabled. Returns true if the bit specified by level is set.
-#define RC_TRACE_ENABLED(level) ((TraceRedefineClasses & level) != 0)
-
-// Macro for checking if TraceRedefineClasses has one or more bits
-// set in a range of bit values. Returns true if one or more bits
-// is set in the range from low..high inclusive. Assumes that low
-// and high are single bit values.
-//
-// ((high << 1) - 1)
-// Yields a mask that removes bits greater than the high bit value.
-// This algorithm doesn't work with highest bit.
-// ~(low - 1)
-// Yields a mask that removes bits lower than the low bit value.
-#define RC_TRACE_IN_RANGE(low, high) \
-(((TraceRedefineClasses & ((high << 1) - 1)) & ~(low - 1)) != 0)
-
-// Note: The ResourceMark is to cleanup resource allocated args.
-// The "do {...} while (0)" is so we can use semi-colon at end of RC_TRACE().
-#define RC_TRACE(level, args) do { \
- if (RC_TRACE_ENABLED(level)) { \
- ResourceMark rm; \
- tty->print("RedefineClasses-0x%x: ", level); \
- tty->print_cr args; \
- } \
-} while (0)
-
-#define RC_TRACE_NO_CR(level, args) do { \
- if (RC_TRACE_ENABLED(level)) { \
- ResourceMark rm; \
- tty->print("RedefineClasses-0x%x: ", level); \
- tty->print args; \
- } \
-} while (0)
-
-#define RC_TRACE_WITH_THREAD(level, thread, args) do { \
- if (RC_TRACE_ENABLED(level)) { \
- ResourceMark rm(thread); \
- tty->print("RedefineClasses-0x%x: ", level); \
- tty->print_cr args; \
- } \
-} while (0)
-
-#define RC_TRACE_MESG(args) do { \
- ResourceMark rm; \
- tty->print("RedefineClasses: "); \
- tty->print_cr args; \
-} while (0)
-
-// Timer support macros. Only do timer operations if timer tracing is enabled.
-// The "do {...} while (0)" is so we can use semi-colon at end of the macro.
-#define RC_TIMER_START(t) do { \
- if (RC_TRACE_ENABLED(0x00000004)) { \
- t.start(); \
- } \
-} while (0)
-#define RC_TIMER_STOP(t) do { \
- if (RC_TRACE_ENABLED(0x00000004)) { \
- t.stop(); \
- } \
-} while (0)
-
-#endif // SHARE_VM_PRIMS_JVMTIREDEFINECLASSESTRACE_HPP
--- a/hotspot/src/share/vm/prims/methodComparator.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/prims/methodComparator.cpp Wed May 11 00:38:58 2016 +0300
@@ -25,7 +25,6 @@
#include "precompiled.hpp"
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
-#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "prims/methodComparator.hpp"
#include "runtime/handles.inline.hpp"
#include "utilities/globalDefinitions.hpp"
@@ -39,10 +38,12 @@
if (old_method->code_size() != new_method->code_size())
return false;
if (check_stack_and_locals_size(old_method, new_method) != 0) {
- // RC_TRACE macro has an embedded ResourceMark
- RC_TRACE(0x00800000, ("Methods %s non-comparable with diagnosis %d",
- old_method->name()->as_C_string(),
- check_stack_and_locals_size(old_method, new_method)));
+ if (log_is_enabled(Debug, redefine, class, methodcomparator)) {
+ ResourceMark rm;
+ log_debug(redefine, class, methodcomparator)
+ ("Methods %s non-comparable with diagnosis %d",
+ old_method->name()->as_C_string(), check_stack_and_locals_size(old_method, new_method));
+ }
return false;
}
--- a/hotspot/src/share/vm/prims/methodHandles.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp Wed May 11 00:38:58 2016 +0300
@@ -38,7 +38,6 @@
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "prims/methodHandles.hpp"
-#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "runtime/compilationPolicy.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/timerTrace.hpp"
@@ -1084,17 +1083,15 @@
java_lang_invoke_MemberName::set_vmtarget(mem_name, new_method);
- if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
+ if (log_is_enabled(Info, redefine, class, update)) {
+ ResourceMark rm;
if (!(*trace_name_printed)) {
- // RC_TRACE_MESG macro has an embedded ResourceMark
- RC_TRACE_MESG(("adjust: name=%s",
- old_method->method_holder()->external_name()));
+ log_info(redefine, class, update)("adjust: name=%s", old_method->method_holder()->external_name());
*trace_name_printed = true;
}
- // RC_TRACE macro has an embedded ResourceMark
- RC_TRACE(0x00400000, ("MemberName method update: %s(%s)",
- new_method->name()->as_C_string(),
- new_method->signature()->as_C_string()));
+ log_debug(redefine, class, update, constantpool)
+ ("MemberName method update: %s(%s)",
+ new_method->name()->as_C_string(), new_method->signature()->as_C_string());
}
}
}
--- a/hotspot/src/share/vm/prims/stackwalk.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/prims/stackwalk.cpp Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -37,44 +37,44 @@
#include "utilities/globalDefinitions.hpp"
// setup and cleanup actions
-void StackWalkAnchor::setup_magic_on_entry(objArrayHandle frames_array) {
+void JavaFrameStream::setup_magic_on_entry(objArrayHandle frames_array) {
frames_array->obj_at_put(magic_pos, _thread->threadObj());
_anchor = address_value();
assert(check_magic(frames_array), "invalid magic");
}
-bool StackWalkAnchor::check_magic(objArrayHandle frames_array) {
+bool JavaFrameStream::check_magic(objArrayHandle frames_array) {
oop m1 = frames_array->obj_at(magic_pos);
jlong m2 = _anchor;
if (m1 == _thread->threadObj() && m2 == address_value()) return true;
return false;
}
-bool StackWalkAnchor::cleanup_magic_on_exit(objArrayHandle frames_array) {
+bool JavaFrameStream::cleanup_magic_on_exit(objArrayHandle frames_array) {
bool ok = check_magic(frames_array);
frames_array->obj_at_put(magic_pos, NULL);
_anchor = 0L;
return ok;
}
-// Returns StackWalkAnchor for the current stack being traversed.
+// Returns JavaFrameStream for the current stack being traversed.
//
// Parameters:
// thread Current Java thread.
// magic Magic value used for each stack walking
// frames_array User-supplied buffers. The 0th element is reserved
-// to this StackWalkAnchor to use
+// to this JavaFrameStream to use
//
-StackWalkAnchor* StackWalkAnchor::from_current(JavaThread* thread, jlong magic,
+JavaFrameStream* JavaFrameStream::from_current(JavaThread* thread, jlong magic,
objArrayHandle frames_array)
{
assert(thread != NULL && thread->is_Java_thread(), "");
oop m1 = frames_array->obj_at(magic_pos);
if (m1 != thread->threadObj()) return NULL;
if (magic == 0L) return NULL;
- StackWalkAnchor* anchor = (StackWalkAnchor*) (intptr_t) magic;
- if (!anchor->is_valid_in(thread, frames_array)) return NULL;
- return anchor;
+ JavaFrameStream* stream = (JavaFrameStream*) (intptr_t) magic;
+ if (!stream->is_valid_in(thread, frames_array)) return NULL;
+ return stream;
}
// Unpacks one or more frames into user-supplied buffers.
@@ -84,19 +84,19 @@
// In other words, do not leave any stale data in the vfst.
//
// Parameters:
-// mode Restrict which frames to be decoded.
-// vfst vFrameStream.
-// max_nframes Maximum number of frames to be filled.
-// start_index Start index to the user-supplied buffers.
-// frames_array Buffer to store Class or StackFrame in, starting at start_index.
-// frames array is a Class<?>[] array when only getting caller
-// reference, and a StackFrameInfo[] array (or derivative)
-// otherwise. It should never be null.
-// end_index End index to the user-supplied buffers with unpacked frames.
+// mode Restrict which frames to be decoded.
+// JavaFrameStream stream of javaVFrames
+// max_nframes Maximum number of frames to be filled.
+// start_index Start index to the user-supplied buffers.
+// frames_array Buffer to store Class or StackFrame in, starting at start_index.
+// frames array is a Class<?>[] array when only getting caller
+// reference, and a StackFrameInfo[] array (or derivative)
+// otherwise. It should never be null.
+// end_index End index to the user-supplied buffers with unpacked frames.
//
// Returns the number of frames whose information was transferred into the buffers.
//
-int StackWalk::fill_in_frames(jlong mode, vframeStream& vfst,
+int StackWalk::fill_in_frames(jlong mode, JavaFrameStream& stream,
int max_nframes, int start_index,
objArrayHandle frames_array,
int& end_index, TRAPS) {
@@ -108,9 +108,9 @@
assert(start_index + max_nframes <= frames_array->length(), "oob");
int frames_decoded = 0;
- for (; !vfst.at_end(); vfst.next()) {
- Method* method = vfst.method();
- int bci = vfst.bci();
+ for (; !stream.at_end(); stream.next()) {
+ Method* method = stream.method();
+ int bci = stream.bci();
if (method == NULL) continue;
if (!ShowHiddenFrames && StackWalk::skip_hidden_frames(mode)) {
@@ -133,7 +133,7 @@
if (live_frame_info(mode)) {
assert (use_frames_array(mode), "Bad mode for get live frame");
Handle stackFrame(frames_array->obj_at(index));
- fill_live_stackframe(stackFrame, method, bci, vfst.java_frame(), CHECK_0);
+ fill_live_stackframe(stackFrame, method, bci, stream.java_frame(), CHECK_0);
} else if (need_method_info(mode)) {
assert (use_frames_array(mode), "Bad mode for get stack frame");
Handle stackFrame(frames_array->obj_at(index));
@@ -294,6 +294,7 @@
int skip_frames, int frame_count, int start_index,
objArrayHandle frames_array,
TRAPS) {
+ ResourceMark rm(THREAD);
JavaThread* jt = (JavaThread*)THREAD;
if (TraceStackWalk) {
tty->print_cr("Start walking: mode " JLONG_FORMAT " skip %d frames batch size %d",
@@ -309,41 +310,39 @@
methodHandle m_doStackWalk(THREAD, Universe::do_stack_walk_method());
- // Open up a traversable stream onto my stack.
- // This stream will be made available by *reference* to the inner Java call.
- StackWalkAnchor anchor(jt);
- vframeStream& vfst = anchor.vframe_stream();
-
+ // Setup traversal onto my stack.
+ RegisterMap regMap(jt, true);
+ JavaFrameStream stream(jt, ®Map);
{
- while (!vfst.at_end()) {
- InstanceKlass* ik = vfst.method()->method_holder();
+ while (!stream.at_end()) {
+ InstanceKlass* ik = stream.method()->method_holder();
if (ik != stackWalker_klass &&
ik != abstractStackWalker_klass && ik->super() != abstractStackWalker_klass) {
break;
}
if (TraceStackWalk) {
- tty->print(" skip "); vfst.method()->print_short_name(); tty->print("\n");
+ tty->print(" skip "); stream.method()->print_short_name(); tty->print("\n");
}
- vfst.next();
+ stream.next();
}
// stack frame has been traversed individually and resume stack walk
// from the stack frame at depth == skip_frames.
- for (int n=0; n < skip_frames && !vfst.at_end(); vfst.next(), n++) {
+ for (int n=0; n < skip_frames && !stream.at_end(); stream.next(), n++) {
if (TraceStackWalk) {
- tty->print(" skip "); vfst.method()->print_short_name();
+ tty->print(" skip "); stream.method()->print_short_name();
tty->print_cr(" frame id: " PTR_FORMAT " pc: " PTR_FORMAT,
- p2i(vfst.frame_id()), p2i(vfst.frame_pc()));
+ p2i(stream.java_frame()->fr().id()),
+ p2i(stream.java_frame()->fr().pc()));
}
}
}
- // The Method* pointer in the vfst has a very short shelf life. Grab it now.
int end_index = start_index;
int numFrames = 0;
- if (!vfst.at_end()) {
- numFrames = fill_in_frames(mode, vfst, frame_count, start_index,
+ if (!stream.at_end()) {
+ numFrames = fill_in_frames(mode, stream, frame_count, start_index,
frames_array, end_index, CHECK_NULL);
if (numFrames < 1) {
THROW_MSG_(vmSymbols::java_lang_InternalError(), "stack walk: decode failed", NULL);
@@ -356,19 +355,19 @@
// When JVM_CallStackWalk returns, it invalidates the stack stream.
JavaValue result(T_OBJECT);
JavaCallArguments args(stackStream);
- args.push_long(anchor.address_value());
+ args.push_long(stream.address_value());
args.push_int(skip_frames);
args.push_int(frame_count);
args.push_int(start_index);
args.push_int(end_index);
// Link the thread and vframe stream into the callee-visible object
- anchor.setup_magic_on_entry(frames_array);
+ stream.setup_magic_on_entry(frames_array);
JavaCalls::call(&result, m_doStackWalk, &args, THREAD);
// Do this before anything else happens, to disable any lingering stream objects
- bool ok = anchor.cleanup_magic_on_exit(frames_array);
+ bool ok = stream.cleanup_magic_on_exit(frames_array);
// Throw pending exception if we must
(void) (CHECK_NULL);
@@ -379,7 +378,6 @@
// Return normally
return (oop)result.get_jobject();
-
}
// Walk the next batch of stack frames
@@ -400,8 +398,8 @@
TRAPS)
{
JavaThread* jt = (JavaThread*)THREAD;
- StackWalkAnchor* existing_anchor = StackWalkAnchor::from_current(jt, magic, frames_array);
- if (existing_anchor == NULL) {
+ JavaFrameStream* existing_stream = JavaFrameStream::from_current(jt, magic, frames_array);
+ if (existing_stream == NULL) {
THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: corrupted buffers", 0L);
}
@@ -410,8 +408,8 @@
}
if (TraceStackWalk) {
- tty->print_cr("StackWalk::moreFrames frame_count %d existing_anchor " PTR_FORMAT " start %d frames %d",
- frame_count, p2i(existing_anchor), start_index, frames_array->length());
+ tty->print_cr("StackWalk::moreFrames frame_count %d existing_stream " PTR_FORMAT " start %d frames %d",
+ frame_count, p2i(existing_stream), start_index, frames_array->length());
}
int end_index = start_index;
if (frame_count <= 0) {
@@ -421,12 +419,11 @@
int count = frame_count + start_index;
assert (frames_array->length() >= count, "not enough space in buffers");
- StackWalkAnchor& anchor = (*existing_anchor);
- vframeStream& vfst = anchor.vframe_stream();
- if (!vfst.at_end()) {
- vfst.next(); // this was the last frame decoded in the previous batch
- if (!vfst.at_end()) {
- int n = fill_in_frames(mode, vfst, frame_count, start_index,
+ JavaFrameStream& stream = (*existing_stream);
+ if (!stream.at_end()) {
+ stream.next(); // advance past the last frame decoded in previous batch
+ if (!stream.at_end()) {
+ int n = fill_in_frames(mode, stream, frame_count, start_index,
frames_array, end_index, CHECK_0);
if (n < 1) {
THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: later decode failed", 0L);
--- a/hotspot/src/share/vm/prims/stackwalk.hpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/prims/stackwalk.hpp Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -29,21 +29,31 @@
#include "oops/oop.hpp"
#include "runtime/vframe.hpp"
-class StackWalkAnchor : public StackObj {
+//
+// JavaFrameStream is used by StackWalker to iterate through Java stack frames
+// on the given JavaThread.
+//
+class JavaFrameStream : public StackObj {
private:
enum {
magic_pos = 0
};
JavaThread* _thread;
- vframeStream _vfst;
+ javaVFrame* _jvf;
jlong _anchor;
public:
- StackWalkAnchor(JavaThread* thread)
- : _thread(thread), _vfst(thread), _anchor(0L) {}
+ JavaFrameStream(JavaThread* thread, RegisterMap* rm)
+ : _thread(thread), _anchor(0L) {
+ _jvf = _thread->last_java_vframe(rm);
+ }
- vframeStream& vframe_stream() { return _vfst; }
- JavaThread* thread() { return _thread; }
+ javaVFrame* java_frame() { return _jvf; }
+ void next() { _jvf = _jvf->java_sender(); }
+ bool at_end() { return _jvf == NULL; }
+
+ Method* method() { return _jvf->method(); }
+ int bci() { return _jvf->bci(); }
void setup_magic_on_entry(objArrayHandle frames_array);
bool check_magic(objArrayHandle frames_array);
@@ -57,12 +67,12 @@
return (jlong) castable_address(this);
}
- static StackWalkAnchor* from_current(JavaThread* thread, jlong anchor, objArrayHandle frames_array);
+ static JavaFrameStream* from_current(JavaThread* thread, jlong magic, objArrayHandle frames_array);
};
class StackWalk : public AllStatic {
private:
- static int fill_in_frames(jlong mode, vframeStream& vfst,
+ static int fill_in_frames(jlong mode, JavaFrameStream& stream,
int max_nframes, int start_index,
objArrayHandle frames_array,
int& end_index, TRAPS);
--- a/hotspot/src/share/vm/prims/unsafe.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/prims/unsafe.cpp Wed May 11 00:38:58 2016 +0300
@@ -131,38 +131,137 @@
}
-///// Data in the Java heap.
+///// Data read/writes on the Java heap and in native (off-heap) memory
+
+/**
+ * Helper class for accessing memory.
+ *
+ * Normalizes values and wraps accesses in
+ * JavaThread::doing_unsafe_access() if needed.
+ */
+class MemoryAccess : StackObj {
+ JavaThread* _thread;
+ jobject _obj;
+ jlong _offset;
-#define truncate_jboolean(x) ((x) & 1)
-#define truncate_jbyte(x) (x)
-#define truncate_jshort(x) (x)
-#define truncate_jchar(x) (x)
-#define truncate_jint(x) (x)
-#define truncate_jlong(x) (x)
-#define truncate_jfloat(x) (x)
-#define truncate_jdouble(x) (x)
+ // Resolves and returns the address of the memory access
+ void* addr() {
+ return index_oop_from_field_offset_long(JNIHandles::resolve(_obj), _offset);
+ }
+
+ template <typename T>
+ T normalize(T x) {
+ return x;
+ }
-#define GET_FIELD(obj, offset, type_name, v) \
- oop p = JNIHandles::resolve(obj); \
- type_name v = *(type_name*)index_oop_from_field_offset_long(p, offset)
+ jboolean normalize(jboolean x) {
+ return x & 1;
+ }
+
+ /**
+ * Helper class to wrap memory accesses in JavaThread::doing_unsafe_access()
+ */
+ class GuardUnsafeAccess {
+ JavaThread* _thread;
+ bool _active;
-#define SET_FIELD(obj, offset, type_name, x) \
- oop p = JNIHandles::resolve(obj); \
- *(type_name*)index_oop_from_field_offset_long(p, offset) = truncate_##type_name(x)
+ public:
+ GuardUnsafeAccess(JavaThread* thread, jobject _obj) : _thread(thread) {
+ if (JNIHandles::resolve(_obj) == NULL) {
+ // native/off-heap access which may raise SIGBUS if accessing
+ // memory mapped file data in a region of the file which has
+ // been truncated and is now invalid
+ _thread->set_doing_unsafe_access(true);
+ _active = true;
+ } else {
+ _active = false;
+ }
+ }
+
+ ~GuardUnsafeAccess() {
+ if (_active) {
+ _thread->set_doing_unsafe_access(false);
+ }
+ }
+ };
-#define GET_FIELD_VOLATILE(obj, offset, type_name, v) \
- oop p = JNIHandles::resolve(obj); \
- if (support_IRIW_for_not_multiple_copy_atomic_cpu) { \
- OrderAccess::fence(); \
- } \
- volatile type_name v = OrderAccess::load_acquire((volatile type_name*)index_oop_from_field_offset_long(p, offset));
+public:
+ MemoryAccess(JavaThread* thread, jobject obj, jlong offset)
+ : _thread(thread), _obj(obj), _offset(offset) {
+ }
+
+ template <typename T>
+ T get() {
+ GuardUnsafeAccess guard(_thread, _obj);
+
+ T* p = (T*)addr();
-#define SET_FIELD_VOLATILE(obj, offset, type_name, x) \
- oop p = JNIHandles::resolve(obj); \
- OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), truncate_##type_name(x));
+ T x = *p;
+
+ return x;
+ }
+
+ template <typename T>
+ void put(T x) {
+ GuardUnsafeAccess guard(_thread, _obj);
+
+ T* p = (T*)addr();
+
+ *p = normalize(x);
+ }
-// Get/SetObject must be special-cased, since it works with handles.
+ template <typename T>
+ T get_volatile() {
+ GuardUnsafeAccess guard(_thread, _obj);
+
+ T* p = (T*)addr();
+
+ if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+ OrderAccess::fence();
+ }
+
+ T x = OrderAccess::load_acquire((volatile T*)p);
+
+ return x;
+ }
+
+ template <typename T>
+ void put_volatile(T x) {
+ GuardUnsafeAccess guard(_thread, _obj);
+
+ T* p = (T*)addr();
+
+ OrderAccess::release_store_fence((volatile T*)p, normalize(x));
+ }
+
+
+#ifndef SUPPORTS_NATIVE_CX8
+ jlong get_jlong_locked() {
+ GuardUnsafeAccess guard(_thread, _obj);
+
+ MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
+
+ jlong* p = (jlong*)addr();
+
+ jlong x = Atomic::load(p);
+
+ return x;
+ }
+
+ void put_jlong_locked(jlong x) {
+ GuardUnsafeAccess guard(_thread, _obj);
+
+ MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
+
+ jlong* p = (jlong*)addr();
+
+ Atomic::store(normalize(x), p);
+ }
+#endif
+};
+
+// Get/PutObject must be special-cased, since it works with handles.
// These functions allow a null base pointer with an arbitrary address.
// But if the base pointer is non-null, the offset should make some sense.
@@ -208,7 +307,7 @@
return ret;
} UNSAFE_END
-UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
+UNSAFE_ENTRY(void, Unsafe_PutObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
oop x = JNIHandles::resolve(x_h);
oop p = JNIHandles::resolve(obj);
@@ -236,7 +335,7 @@
return JNIHandles::make_local(env, v);
} UNSAFE_END
-UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
+UNSAFE_ENTRY(void, Unsafe_PutObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
oop x = JNIHandles::resolve(x_h);
oop p = JNIHandles::resolve(obj);
void* addr = index_oop_from_field_offset_long(p, offset);
@@ -301,25 +400,17 @@
UNSAFE_ENTRY(jlong, Unsafe_GetLongVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) {
if (VM_Version::supports_cx8()) {
- GET_FIELD_VOLATILE(obj, offset, jlong, v);
- return v;
+ return MemoryAccess(thread, obj, offset).get_volatile<jlong>();
} else {
- Handle p (THREAD, JNIHandles::resolve(obj));
- jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
- MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
- jlong value = Atomic::load(addr);
- return value;
+ return MemoryAccess(thread, obj, offset).get_jlong_locked();
}
} UNSAFE_END
-UNSAFE_ENTRY(void, Unsafe_SetLongVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong x)) {
+UNSAFE_ENTRY(void, Unsafe_PutLongVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong x)) {
if (VM_Version::supports_cx8()) {
- SET_FIELD_VOLATILE(obj, offset, jlong, x);
+ MemoryAccess(thread, obj, offset).put_volatile<jlong>(x);
} else {
- Handle p (THREAD, JNIHandles::resolve(obj));
- jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
- MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
- Atomic::store(x, addr);
+ MemoryAccess(thread, obj, offset).put_jlong_locked(x);
}
} UNSAFE_END
@@ -337,15 +428,14 @@
return UseUnalignedAccesses;
} UNSAFE_END
-#define DEFINE_GETSETOOP(java_type, Type) \
+#define DEFINE_GETSETOOP(java_type, Type) \
\
UNSAFE_ENTRY(java_type, Unsafe_Get##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { \
- GET_FIELD(obj, offset, java_type, v); \
- return v; \
+ return MemoryAccess(thread, obj, offset).get<java_type>(); \
} UNSAFE_END \
\
-UNSAFE_ENTRY(void, Unsafe_Set##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \
- SET_FIELD(obj, offset, java_type, x); \
+UNSAFE_ENTRY(void, Unsafe_Put##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \
+ MemoryAccess(thread, obj, offset).put<java_type>(x); \
} UNSAFE_END \
\
// END DEFINE_GETSETOOP.
@@ -364,12 +454,11 @@
#define DEFINE_GETSETOOP_VOLATILE(java_type, Type) \
\
UNSAFE_ENTRY(java_type, Unsafe_Get##Type##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { \
- GET_FIELD_VOLATILE(obj, offset, java_type, v); \
- return v; \
+ return MemoryAccess(thread, obj, offset).get_volatile<java_type>(); \
} UNSAFE_END \
\
-UNSAFE_ENTRY(void, Unsafe_Set##Type##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \
- SET_FIELD_VOLATILE(obj, offset, java_type, x); \
+UNSAFE_ENTRY(void, Unsafe_Put##Type##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \
+ MemoryAccess(thread, obj, offset).put_volatile<java_type>(x); \
} UNSAFE_END \
\
// END DEFINE_GETSETOOP_VOLATILE.
@@ -400,98 +489,6 @@
OrderAccess::fence();
} UNSAFE_END
-////// Data in the C heap.
-
-// Note: These do not throw NullPointerException for bad pointers.
-// They just crash. Only a oop base pointer can generate a NullPointerException.
-//
-#define DEFINE_GETSETNATIVE(java_type, Type, native_type) \
- \
-UNSAFE_ENTRY(java_type, Unsafe_GetNative##Type(JNIEnv *env, jobject unsafe, jlong addr)) { \
- void* p = addr_from_java(addr); \
- JavaThread* t = JavaThread::current(); \
- t->set_doing_unsafe_access(true); \
- java_type x = *(volatile native_type*)p; \
- t->set_doing_unsafe_access(false); \
- return x; \
-} UNSAFE_END \
- \
-UNSAFE_ENTRY(void, Unsafe_SetNative##Type(JNIEnv *env, jobject unsafe, jlong addr, java_type x)) { \
- JavaThread* t = JavaThread::current(); \
- t->set_doing_unsafe_access(true); \
- void* p = addr_from_java(addr); \
- *(volatile native_type*)p = x; \
- t->set_doing_unsafe_access(false); \
-} UNSAFE_END \
- \
-// END DEFINE_GETSETNATIVE.
-
-DEFINE_GETSETNATIVE(jbyte, Byte, signed char)
-DEFINE_GETSETNATIVE(jshort, Short, signed short);
-DEFINE_GETSETNATIVE(jchar, Char, unsigned short);
-DEFINE_GETSETNATIVE(jint, Int, jint);
-// no long -- handled specially
-DEFINE_GETSETNATIVE(jfloat, Float, float);
-DEFINE_GETSETNATIVE(jdouble, Double, double);
-
-#undef DEFINE_GETSETNATIVE
-
-UNSAFE_ENTRY(jlong, Unsafe_GetNativeLong(JNIEnv *env, jobject unsafe, jlong addr)) {
- JavaThread* t = JavaThread::current();
- // We do it this way to avoid problems with access to heap using 64
- // bit loads, as jlong in heap could be not 64-bit aligned, and on
- // some CPUs (SPARC) it leads to SIGBUS.
- t->set_doing_unsafe_access(true);
- void* p = addr_from_java(addr);
- jlong x;
-
- if (is_ptr_aligned(p, sizeof(jlong)) == 0) {
- // jlong is aligned, do a volatile access
- x = *(volatile jlong*)p;
- } else {
- jlong_accessor acc;
- acc.words[0] = ((volatile jint*)p)[0];
- acc.words[1] = ((volatile jint*)p)[1];
- x = acc.long_value;
- }
-
- t->set_doing_unsafe_access(false);
-
- return x;
-} UNSAFE_END
-
-UNSAFE_ENTRY(void, Unsafe_SetNativeLong(JNIEnv *env, jobject unsafe, jlong addr, jlong x)) {
- JavaThread* t = JavaThread::current();
- // see comment for Unsafe_GetNativeLong
- t->set_doing_unsafe_access(true);
- void* p = addr_from_java(addr);
-
- if (is_ptr_aligned(p, sizeof(jlong))) {
- // jlong is aligned, do a volatile access
- *(volatile jlong*)p = x;
- } else {
- jlong_accessor acc;
- acc.long_value = x;
- ((volatile jint*)p)[0] = acc.words[0];
- ((volatile jint*)p)[1] = acc.words[1];
- }
-
- t->set_doing_unsafe_access(false);
-} UNSAFE_END
-
-
-UNSAFE_LEAF(jlong, Unsafe_GetNativeAddress(JNIEnv *env, jobject unsafe, jlong addr)) {
- void* p = addr_from_java(addr);
-
- return addr_to_java(*(void**)p);
-} UNSAFE_END
-
-UNSAFE_LEAF(void, Unsafe_SetNativeAddress(JNIEnv *env, jobject unsafe, jlong addr, jlong x)) {
- void* p = addr_from_java(addr);
- *(void**)p = addr_from_java(x);
-} UNSAFE_END
-
-
////// Allocation requests
UNSAFE_ENTRY(jobject, Unsafe_AllocateInstance(JNIEnv *env, jobject unsafe, jclass cls)) {
@@ -980,8 +977,8 @@
} UNSAFE_END
UNSAFE_ENTRY(jlong, Unsafe_CompareAndExchangeLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x)) {
- Handle p (THREAD, JNIHandles::resolve(obj));
- jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
+ Handle p(THREAD, JNIHandles::resolve(obj));
+ jlong* addr = (jlong*)index_oop_from_field_offset_long(p(), offset);
#ifdef SUPPORTS_NATIVE_CX8
return (jlong)(Atomic::cmpxchg(x, addr, e));
@@ -1017,7 +1014,7 @@
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) {
oop p = JNIHandles::resolve(obj);
- jint* addr = (jint *) index_oop_from_field_offset_long(p, offset);
+ jint* addr = (jint *)index_oop_from_field_offset_long(p, offset);
return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
} UNSAFE_END
@@ -1143,20 +1140,16 @@
#define DECLARE_GETPUTOOP(Type, Desc) \
{CC "get" #Type, CC "(" OBJ "J)" #Desc, FN_PTR(Unsafe_Get##Type)}, \
- {CC "put" #Type, CC "(" OBJ "J" #Desc ")V", FN_PTR(Unsafe_Set##Type)}, \
+ {CC "put" #Type, CC "(" OBJ "J" #Desc ")V", FN_PTR(Unsafe_Put##Type)}, \
{CC "get" #Type "Volatile", CC "(" OBJ "J)" #Desc, FN_PTR(Unsafe_Get##Type##Volatile)}, \
- {CC "put" #Type "Volatile", CC "(" OBJ "J" #Desc ")V", FN_PTR(Unsafe_Set##Type##Volatile)}
+ {CC "put" #Type "Volatile", CC "(" OBJ "J" #Desc ")V", FN_PTR(Unsafe_Put##Type##Volatile)}
-#define DECLARE_GETPUTNATIVE(Byte, B) \
- {CC "get" #Byte, CC "(" ADR ")" #B, FN_PTR(Unsafe_GetNative##Byte)}, \
- {CC "put" #Byte, CC "(" ADR#B ")V", FN_PTR(Unsafe_SetNative##Byte)}
-
static JNINativeMethod jdk_internal_misc_Unsafe_methods[] = {
{CC "getObject", CC "(" OBJ "J)" OBJ "", FN_PTR(Unsafe_GetObject)},
- {CC "putObject", CC "(" OBJ "J" OBJ ")V", FN_PTR(Unsafe_SetObject)},
+ {CC "putObject", CC "(" OBJ "J" OBJ ")V", FN_PTR(Unsafe_PutObject)},
{CC "getObjectVolatile",CC "(" OBJ "J)" OBJ "", FN_PTR(Unsafe_GetObjectVolatile)},
- {CC "putObjectVolatile",CC "(" OBJ "J" OBJ ")V", FN_PTR(Unsafe_SetObjectVolatile)},
+ {CC "putObjectVolatile",CC "(" OBJ "J" OBJ ")V", FN_PTR(Unsafe_PutObjectVolatile)},
{CC "getUncompressedObject", CC "(" ADR ")" OBJ, FN_PTR(Unsafe_GetUncompressedObject)},
{CC "getJavaMirror", CC "(" ADR ")" CLS, FN_PTR(Unsafe_GetJavaMirror)},
@@ -1171,17 +1164,6 @@
DECLARE_GETPUTOOP(Float, F),
DECLARE_GETPUTOOP(Double, D),
- DECLARE_GETPUTNATIVE(Byte, B),
- DECLARE_GETPUTNATIVE(Short, S),
- DECLARE_GETPUTNATIVE(Char, C),
- DECLARE_GETPUTNATIVE(Int, I),
- DECLARE_GETPUTNATIVE(Long, J),
- DECLARE_GETPUTNATIVE(Float, F),
- DECLARE_GETPUTNATIVE(Double, D),
-
- {CC "getAddress", CC "(" ADR ")" ADR, FN_PTR(Unsafe_GetNativeAddress)},
- {CC "putAddress", CC "(" ADR "" ADR ")V", FN_PTR(Unsafe_SetNativeAddress)},
-
{CC "allocateMemory0", CC "(J)" ADR, FN_PTR(Unsafe_AllocateMemory0)},
{CC "reallocateMemory0", CC "(" ADR "J)" ADR, FN_PTR(Unsafe_ReallocateMemory0)},
{CC "freeMemory0", CC "(" ADR ")V", FN_PTR(Unsafe_FreeMemory0)},
@@ -1239,7 +1221,6 @@
#undef DAC_Args
#undef DECLARE_GETPUTOOP
-#undef DECLARE_GETPUTNATIVE
// This function is exported, used by NativeLookup.
--- a/hotspot/src/share/vm/runtime/arguments.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed May 11 00:38:58 2016 +0300
@@ -84,8 +84,6 @@
const char* Arguments::_sun_java_launcher = DEFAULT_JAVA_LAUNCHER;
int Arguments::_sun_java_launcher_pid = -1;
bool Arguments::_sun_java_launcher_is_altjvm = false;
-int Arguments::_patch_dirs_count = 0;
-char** Arguments::_patch_dirs = NULL;
int Arguments::_bootclassloader_append_index = -1;
// These parameters are reset in method parse_vm_init_args()
@@ -112,6 +110,7 @@
SystemProperty *Arguments::_java_class_path = NULL;
SystemProperty *Arguments::_jdk_boot_class_path_append = NULL;
+GrowableArray<ModuleXPatchPath*> *Arguments::_xpatchprefix = NULL;
PathString *Arguments::_system_boot_class_path = NULL;
char* Arguments::_ext_dirs = NULL;
@@ -421,6 +420,7 @@
{ "TraceMonitorInflation", LogLevel::Debug, true, LOG_TAGS(monitorinflation) },
{ "TraceSafepointCleanupTime", LogLevel::Info, true, LOG_TAGS(safepoint, cleanup) },
{ "TraceJVMTIObjectTagging", LogLevel::Debug, true, LOG_TAGS(jvmti, objecttagging) },
+ { "TraceRedefineClasses", LogLevel::Info, false, LOG_TAGS(redefine, class) },
{ NULL, LogLevel::Off, false, LOG_TAGS(_NO_TAG) }
};
@@ -580,204 +580,6 @@
}
#endif
-// Constructs the system boot class path from the following components, in order:
-//
-// prefix // from -Xpatch:...
-// base // from os::get_system_properties()
-// suffix // from -Xbootclasspath/a:...
-//
-// This could be AllStatic, but it isn't needed after argument processing is
-// complete. After argument processing, the combined components are copied
-// to Arguments::_system_boot_class_path via a call to Arguments::set_sysclasspath.
-class ArgumentBootClassPath: public StackObj {
-public:
- ArgumentBootClassPath(const char* base);
- ~ArgumentBootClassPath();
-
- inline void set_base(const char* base);
- inline void add_prefix(const char* prefix);
- inline void add_suffix_to_prefix(const char* suffix);
- inline void add_suffix(const char* suffix);
- inline void reset_path(const char* base);
-
- inline const char* get_base() const { return _items[_bcp_base]; }
- inline const char* get_prefix() const { return _items[_bcp_prefix]; }
- inline const char* get_suffix() const { return _items[_bcp_suffix]; }
-
- // Combine all the components into a single c-heap-allocated string; caller
- // must free the string if/when no longer needed.
- char* combined_path();
-
-private:
- // Utility routines.
- static char* add_to_path(const char* path, const char* str, bool prepend);
- static char* add_jars_to_path(char* path, const char* directory);
-
- inline void reset_item_at(int index);
-
- // Array indices for the items that make up the sysclasspath. All except the
- // base are allocated in the C heap and freed by this class.
- enum {
- _bcp_prefix, // was -Xpatch:...
- _bcp_base, // the default system boot class path
- _bcp_suffix, // from -Xbootclasspath/a:...
- _bcp_nitems // the number of items, must be last.
- };
-
- const char* _items[_bcp_nitems];
-};
-
-ArgumentBootClassPath::ArgumentBootClassPath(const char* base) {
- memset(_items, 0, sizeof(_items));
- _items[_bcp_base] = base;
-}
-
-ArgumentBootClassPath::~ArgumentBootClassPath() {
- // Free everything except the base.
- for (int i = 0; i < _bcp_nitems; ++i) {
- if (i != _bcp_base) reset_item_at(i);
- }
-}
-
-inline void ArgumentBootClassPath::set_base(const char* base) {
- _items[_bcp_base] = base;
-}
-
-inline void ArgumentBootClassPath::add_prefix(const char* prefix) {
- _items[_bcp_prefix] = add_to_path(_items[_bcp_prefix], prefix, true);
-}
-
-inline void ArgumentBootClassPath::add_suffix_to_prefix(const char* suffix) {
- _items[_bcp_prefix] = add_to_path(_items[_bcp_prefix], suffix, false);
-}
-
-inline void ArgumentBootClassPath::add_suffix(const char* suffix) {
- _items[_bcp_suffix] = add_to_path(_items[_bcp_suffix], suffix, false);
-}
-
-inline void ArgumentBootClassPath::reset_item_at(int index) {
- assert(index < _bcp_nitems && index != _bcp_base, "just checking");
- if (_items[index] != NULL) {
- FREE_C_HEAP_ARRAY(char, _items[index]);
- _items[index] = NULL;
- }
-}
-
-inline void ArgumentBootClassPath::reset_path(const char* base) {
- // Clear the prefix and suffix.
- reset_item_at(_bcp_prefix);
- reset_item_at(_bcp_suffix);
- set_base(base);
-}
-
-//------------------------------------------------------------------------------
-
-
-// Combine the bootclasspath elements, some of which may be null, into a single
-// c-heap-allocated string.
-char* ArgumentBootClassPath::combined_path() {
- assert(_items[_bcp_base] != NULL, "empty default sysclasspath");
-
- size_t lengths[_bcp_nitems];
- size_t total_len = 0;
-
- const char separator = *os::path_separator();
-
- // Get the lengths.
- int i;
- for (i = 0; i < _bcp_nitems; ++i) {
- if (i == _bcp_suffix) {
- // Record index of boot loader's append path.
- Arguments::set_bootclassloader_append_index((int)total_len);
- }
- if (_items[i] != NULL) {
- lengths[i] = strlen(_items[i]);
- // Include space for the separator char (or a NULL for the last item).
- total_len += lengths[i] + 1;
- }
- }
- assert(total_len > 0, "empty sysclasspath not allowed");
-
- // Copy the _items to a single string.
- char* cp = NEW_C_HEAP_ARRAY(char, total_len, mtArguments);
- char* cp_tmp = cp;
- for (i = 0; i < _bcp_nitems; ++i) {
- if (_items[i] != NULL) {
- memcpy(cp_tmp, _items[i], lengths[i]);
- cp_tmp += lengths[i];
- *cp_tmp++ = separator;
- }
- }
- *--cp_tmp = '\0'; // Replace the extra separator.
- return cp;
-}
-
-// Note: path must be c-heap-allocated (or NULL); it is freed if non-null.
-char*
-ArgumentBootClassPath::add_to_path(const char* path, const char* str, bool prepend) {
- char *cp;
-
- assert(str != NULL, "just checking");
- if (path == NULL) {
- size_t len = strlen(str) + 1;
- cp = NEW_C_HEAP_ARRAY(char, len, mtArguments);
- memcpy(cp, str, len); // copy the trailing null
- } else {
- const char separator = *os::path_separator();
- size_t old_len = strlen(path);
- size_t str_len = strlen(str);
- size_t len = old_len + str_len + 2;
-
- if (prepend) {
- cp = NEW_C_HEAP_ARRAY(char, len, mtArguments);
- char* cp_tmp = cp;
- memcpy(cp_tmp, str, str_len);
- cp_tmp += str_len;
- *cp_tmp = separator;
- memcpy(++cp_tmp, path, old_len + 1); // copy the trailing null
- FREE_C_HEAP_ARRAY(char, path);
- } else {
- cp = REALLOC_C_HEAP_ARRAY(char, path, len, mtArguments);
- char* cp_tmp = cp + old_len;
- *cp_tmp = separator;
- memcpy(++cp_tmp, str, str_len + 1); // copy the trailing null
- }
- }
- return cp;
-}
-
-// Scan the directory and append any jar or zip files found to path.
-// Note: path must be c-heap-allocated (or NULL); it is freed if non-null.
-char* ArgumentBootClassPath::add_jars_to_path(char* path, const char* directory) {
- DIR* dir = os::opendir(directory);
- if (dir == NULL) return path;
-
- char dir_sep[2] = { '\0', '\0' };
- size_t directory_len = strlen(directory);
- const char fileSep = *os::file_separator();
- if (directory[directory_len - 1] != fileSep) dir_sep[0] = fileSep;
-
- /* Scan the directory for jars/zips, appending them to path. */
- struct dirent *entry;
- char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(directory), mtArguments);
- while ((entry = os::readdir(dir, (dirent *) dbuf)) != NULL) {
- const char* name = entry->d_name;
- const char* ext = name + strlen(name) - 4;
- bool isJarOrZip = ext > name &&
- (os::file_name_strcmp(ext, ".jar") == 0 ||
- os::file_name_strcmp(ext, ".zip") == 0);
- if (isJarOrZip) {
- char* jarpath = NEW_C_HEAP_ARRAY(char, directory_len + 2 + strlen(name), mtArguments);
- sprintf(jarpath, "%s%s%s", directory, dir_sep, name);
- path = add_to_path(path, jarpath, false);
- FREE_C_HEAP_ARRAY(char, jarpath);
- }
- }
- FREE_C_HEAP_ARRAY(char, dbuf);
- os::closedir(dir);
- return path;
-}
-
// Parses a size specification string.
bool Arguments::atojulong(const char *s, julong* result) {
julong n = 0;
@@ -1003,7 +805,9 @@
}
strncat(tagset_buffer, LogTag::name(tagSet[i]), max_tagset_len - strlen(tagset_buffer));
}
-
+ if (!alf.exactMatch) {
+ strncat(tagset_buffer, "*", max_tagset_len - strlen(tagset_buffer));
+ }
log_warning(arguments)("-XX:%s%s is deprecated. Will use -Xlog:%s=%s instead.",
(on) ? "+" : "-",
name,
@@ -1064,6 +868,11 @@
Flag* flag;
// this scanf pattern matches both strings (handled here) and numbers (handled later))
+ AliasedLoggingFlag alf = catch_logging_aliases(name, true);
+ if (alf.alias_name != NULL) {
+ LogConfiguration::configure_stdout(alf.level, alf.exactMatch, alf.tag0, alf.tag1, alf.tag2, alf.tag3, alf.tag4, alf.tag5);
+ return true;
+ }
real_name = handle_aliases_and_deprecation(name, warn_if_deprecated);
if (real_name == NULL) {
return false;
@@ -2724,9 +2533,7 @@
jint Arguments::parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
const JavaVMInitArgs *java_options_args,
const JavaVMInitArgs *cmd_line_args) {
- // For components of the system classpath.
- ArgumentBootClassPath bcp(Arguments::get_sysclasspath());
- bool bcp_assembly_required = false;
+ bool xpatch_javabase = false;
// Save default settings for some mode flags
Arguments::_AlwaysCompileLoopMethods = AlwaysCompileLoopMethods;
@@ -2743,29 +2550,26 @@
// Parse args structure generated from JAVA_TOOL_OPTIONS environment
// variable (if present).
- jint result = parse_each_vm_init_arg(
- java_tool_options_args, &bcp, &bcp_assembly_required, Flag::ENVIRON_VAR);
+ jint result = parse_each_vm_init_arg(java_tool_options_args, &xpatch_javabase, Flag::ENVIRON_VAR);
if (result != JNI_OK) {
return result;
}
// Parse args structure generated from the command line flags.
- result = parse_each_vm_init_arg(cmd_line_args, &bcp, &bcp_assembly_required,
- Flag::COMMAND_LINE);
+ result = parse_each_vm_init_arg(cmd_line_args, &xpatch_javabase, Flag::COMMAND_LINE);
if (result != JNI_OK) {
return result;
}
// Parse args structure generated from the _JAVA_OPTIONS environment
// variable (if present) (mimics classic VM)
- result = parse_each_vm_init_arg(
- java_options_args, &bcp, &bcp_assembly_required, Flag::ENVIRON_VAR);
+ result = parse_each_vm_init_arg(java_options_args, &xpatch_javabase, Flag::ENVIRON_VAR);
if (result != JNI_OK) {
return result;
}
// Do final processing now that all arguments have been parsed
- result = finalize_vm_init_args(&bcp, bcp_assembly_required);
+ result = finalize_vm_init_args();
if (result != JNI_OK) {
return result;
}
@@ -2818,10 +2622,7 @@
return false;
}
-jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
- ArgumentBootClassPath* bcp_p,
- bool* bcp_assembly_required_p,
- Flag::Flags origin) {
+jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* xpatch_javabase, Flag::Flags origin) {
// For match_option to return remaining or value part of option string
const char* tail;
@@ -2877,8 +2678,8 @@
return JNI_EINVAL;
// -bootclasspath/a:
} else if (match_option(option, "-Xbootclasspath/a:", &tail)) {
- bcp_p->add_suffix(tail);
- *bcp_assembly_required_p = true;
+ Arguments::set_bootclassloader_append_index((int)strlen(Arguments::get_sysclasspath())+1);
+ Arguments::append_sysclasspath(tail);
// -bootclasspath/p:
} else if (match_option(option, "-Xbootclasspath/p:", &tail)) {
jio_fprintf(defaultStream::output_stream(),
@@ -2938,9 +2739,8 @@
if (tail != NULL) {
char *options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(tail) + 1, mtArguments), tail);
add_init_agent("instrument", options, false);
- // java agents need module java.instrument. Also -addmods ALL-SYSTEM because
- // the java agent is in the unmamed module of the application class loader
- if (!Arguments::append_to_addmods_property("java.instrument,ALL-SYSTEM")) {
+ // java agents need module java.instrument
+ if (!Arguments::append_to_addmods_property("java.instrument")) {
return JNI_ENOMEM;
}
}
@@ -3218,37 +3018,30 @@
return JNI_ERR;
#endif
}
- if (match_option(option, "-Djdk.launcher.patch.0=", &tail)) {
- // -Xpatch
- int dir_count;
- char** patch_dirs = os::split_path(tail, &dir_count);
- if (patch_dirs == NULL) {
- jio_fprintf(defaultStream::output_stream(),
- "Bad value for -Xpatch.\n");
+ if (match_option(option, "-Djdk.launcher.patch.", &tail)) {
+ // -Djdk.launcher.patch.#=<module>=<file>(<pathsep><file>)*
+ // The number, #, specified will be increasing with each -Xpatch
+ // specified on the command line.
+ // Pick up module name, following the -D property's equal sign.
+ const char* property_equal = strchr(tail, '=');
+ if (property_equal == NULL) {
+ jio_fprintf(defaultStream::output_stream(), "Missing '=' in -Xpatch specification\n");
return JNI_ERR;
- }
- set_patch_dirs(patch_dirs);
- set_patch_dirs_count(dir_count);
-
- // Create a path for each patch dir consisting of dir/java.base.
- char file_sep = os::file_separator()[0];
- for (int x = 0; x < dir_count; x++) {
- // Really shouldn't be NULL, but check can't hurt
- if (patch_dirs[x] != NULL) {
- size_t len = strlen(patch_dirs[x]);
- if (len != 0) { // Ignore empty strings.
- len += 11; // file_sep + "java.base" + null terminator.
- char* dir = NEW_C_HEAP_ARRAY(char, len, mtArguments);
- jio_snprintf(dir, len, "%s%cjava.base", patch_dirs[x], file_sep);
-
- // See if Xpatch module path exists.
- struct stat st;
- if ((os::stat(dir, &st) == 0)) {
- bcp_p->add_prefix(dir);
- *bcp_assembly_required_p = true;
- }
- FREE_C_HEAP_ARRAY(char, dir);
- }
+ } else {
+ // Find the equal sign between the module name and the path specification
+ const char* module_equal = strchr(property_equal + 1, '=');
+ if (module_equal == NULL) {
+ jio_fprintf(defaultStream::output_stream(), "Bad value for -Xpatch, no module name specified\n");
+ return JNI_ERR;
+ } else {
+ // Pick out the module name, in between the two equal signs
+ size_t module_len = module_equal - property_equal - 1;
+ char* module_name = NEW_C_HEAP_ARRAY(char, module_len+1, mtArguments);
+ memcpy(module_name, property_equal + 1, module_len);
+ *(module_name + module_len) = '\0';
+ // The path piece begins one past the module_equal sign
+ Arguments::add_xpatchprefix(module_name, module_equal + 1, xpatch_javabase);
+ FREE_C_HEAP_ARRAY(char, module_name);
}
}
}
@@ -3511,6 +3304,27 @@
return JNI_OK;
}
+void Arguments::add_xpatchprefix(const char* module_name, const char* path, bool* xpatch_javabase) {
+ // For java.base check for duplicate -Xpatch options being specified on the command line.
+ // This check is only required for java.base, all other duplicate module specifications
+ // will be checked during module system initialization. The module system initialization
+ // will throw an ExceptionInInitializerError if this situation occurs.
+ if (strcmp(module_name, "java.base") == 0) {
+ if (*xpatch_javabase) {
+ vm_exit_during_initialization("Cannot specify java.base more than once to -Xpatch");
+ } else {
+ *xpatch_javabase = true;
+ }
+ }
+
+ // Create GrowableArray lazily, only if -Xpatch has been specified
+ if (_xpatchprefix == NULL) {
+ _xpatchprefix = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<ModuleXPatchPath*>(10, true);
+ }
+
+ _xpatchprefix->push(new ModuleXPatchPath(module_name, path));
+}
+
// Set property jdk.boot.class.path.append to the contents of the bootclasspath
// that follows either the jimage file or exploded module directories. The
// property will contain -Xbootclasspath/a and/or jvmti appended additions.
@@ -3609,7 +3423,7 @@
return nonEmptyDirs;
}
-jint Arguments::finalize_vm_init_args(ArgumentBootClassPath* bcp_p, bool bcp_assembly_required) {
+jint Arguments::finalize_vm_init_args() {
// check if the default lib/endorsed directory exists; if so, error
char path[JVM_MAXPATHLEN];
const char* fileSep = os::file_separator();
@@ -3645,17 +3459,7 @@
return JNI_ERR;
}
- if (bcp_assembly_required) {
- // Assemble the bootclasspath elements into the final path.
- char *combined_path = bcp_p->combined_path();
- Arguments::set_sysclasspath(combined_path);
- FREE_C_HEAP_ARRAY(char, combined_path);
- } else {
- // At this point in sysclasspath processing anything
- // added would be considered in the boot loader's append path.
- // Record this index, including +1 for the file separator character.
- Arguments::set_bootclassloader_append_index(((int)strlen(Arguments::get_sysclasspath()))+1);
- }
+ Arguments::set_bootclassloader_append_index(((int)strlen(Arguments::get_sysclasspath()))+1);
// This must be done after all arguments have been processed.
// java_compiler() true means set to "NONE" or empty.
@@ -3704,6 +3508,12 @@
UNSUPPORTED_OPTION(TieredCompilation);
#endif
+#if INCLUDE_JVMCI
+ if (EnableJVMCI && !append_to_addmods_property("jdk.vm.ci")) {
+ return JNI_ENOMEM;
+ }
+#endif
+
// If we are running in a headless jre, force java.awt.headless property
// to be true unless the property has already been set.
// Also allow the OS environment variable JAVA_AWT_HEADLESS to set headless state.
@@ -4005,7 +3815,7 @@
void Arguments::set_shared_spaces_flags() {
if (DumpSharedSpaces) {
- if (Arguments::patch_dirs() != NULL) {
+ if (Arguments::get_xpatchprefix() != NULL) {
vm_exit_during_initialization(
"Cannot use the following option when dumping the shared archive", "-Xpatch");
}
--- a/hotspot/src/share/vm/runtime/arguments.hpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/runtime/arguments.hpp Wed May 11 00:38:58 2016 +0300
@@ -41,17 +41,15 @@
typedef jint (JNICALL *vfprintf_hook_t)(FILE *fp, const char *format, va_list args) ATTRIBUTE_PRINTF(2, 0);
}
-// Forward declarations
-class ArgumentBootClassPath;
-
-// PathString is used as the underlying value container for a
-// SystemProperty and for the string that represents the system
-// boot class path, Arguments::_system_boot_class_path.
+// PathString is used as:
+// - the underlying value for a SystemProperty
+// - the path portion of an -Xpatch module/path pair
+// - the string that represents the system boot class path, Arguments::_system_boot_class_path.
class PathString : public CHeapObj<mtArguments> {
protected:
- char* _value;
+ char* _value;
public:
- char* value() const { return _value; }
+ char* value() const { return _value; }
bool set_value(const char *value) {
if (_value != NULL) {
@@ -92,7 +90,6 @@
}
}
- // Constructor
PathString(const char* value) {
if (value == NULL) {
_value = NULL;
@@ -101,6 +98,43 @@
strcpy(_value, value);
}
}
+
+ ~PathString() {
+ if (_value != NULL) {
+ FreeHeap(_value);
+ _value = NULL;
+ }
+ }
+};
+
+// ModuleXPatchPath records the module/path pair as specified to -Xpatch.
+class ModuleXPatchPath : public CHeapObj<mtInternal> {
+private:
+ char* _module_name;
+ PathString* _path;
+public:
+ ModuleXPatchPath(const char* module_name, const char* path) {
+ assert(module_name != NULL && path != NULL, "Invalid module name or path value");
+ size_t len = strlen(module_name) + 1;
+ _module_name = AllocateHeap(len, mtInternal);
+ strncpy(_module_name, module_name, len); // copy the trailing null
+ _path = new PathString(path);
+ }
+
+ ~ModuleXPatchPath() {
+ if (_module_name != NULL) {
+ FreeHeap(_module_name);
+ _module_name = NULL;
+ }
+ if (_path != NULL) {
+ delete _path;
+ _path = NULL;
+ }
+ }
+
+ inline void set_path(const char* path) { _path->set_value(path); }
+ inline const char* module_name() const { return _module_name; }
+ inline char* path_string() const { return _path->value(); }
};
// Element describing System and User (-Dkey=value flags) defined property.
@@ -114,7 +148,7 @@
SystemProperty* _next;
bool _internal;
bool _writeable;
- bool writeable() { return _writeable; }
+ bool writeable() { return _writeable; }
public:
// Accessors
@@ -314,10 +348,19 @@
static SystemProperty *_java_class_path;
static SystemProperty *_jdk_boot_class_path_append;
+ // -Xpatch:module=<file>(<pathsep><file>)*
+ // Each element contains the associated module name, path
+ // string pair as specified to -Xpatch.
+ static GrowableArray<ModuleXPatchPath*>* _xpatchprefix;
+
// The constructed value of the system class path after
// argument processing and JVMTI OnLoad additions via
// calls to AddToBootstrapClassLoaderSearch. This is the
// final form before ClassLoader::setup_bootstrap_search().
+ // Note: since -Xpatch is a module name/path pair, the system
+ // boot class path string no longer contains the "prefix" to
+ // the boot class path base piece as it did when
+ // -Xbootclasspath/p was supported.
static PathString *_system_boot_class_path;
// temporary: to emit warning if the default ext dirs are not empty.
@@ -373,12 +416,6 @@
// mark the boot loader's append path observability boundary.
static int _bootclassloader_append_index;
- // -Xpatch flag
- static char** _patch_dirs;
- static int _patch_dirs_count;
- static void set_patch_dirs(char** dirs) { _patch_dirs = dirs; }
- static void set_patch_dirs_count(int count) { _patch_dirs_count = count; }
-
// -Xdebug flag
static bool _xdebug_mode;
static void set_xdebug_mode(bool arg) { _xdebug_mode = arg; }
@@ -465,8 +502,8 @@
static jint parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
const JavaVMInitArgs *java_options_args,
const JavaVMInitArgs *cmd_line_args);
- static jint parse_each_vm_init_arg(const JavaVMInitArgs* args, ArgumentBootClassPath* bcp_p, bool* bcp_assembly_required_p, Flag::Flags origin);
- static jint finalize_vm_init_args(ArgumentBootClassPath* bcp_p, bool bcp_assembly_required);
+ static jint parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* xpatch_javabase, Flag::Flags origin);
+ static jint finalize_vm_init_args();
static bool is_bad_option(const JavaVMOption* option, jboolean ignore, const char* option_type);
static bool is_bad_option(const JavaVMOption* option, jboolean ignore) {
@@ -637,13 +674,12 @@
return _bootclassloader_append_index;
}
static void set_bootclassloader_append_index(int value) {
- _bootclassloader_append_index = value;
+ // Set only if the index has not been set yet
+ if (_bootclassloader_append_index == -1) {
+ _bootclassloader_append_index = value;
+ }
}
- // -Xpatch
- static char** patch_dirs() { return _patch_dirs; }
- static int patch_dirs_count() { return _patch_dirs_count; }
-
// -Xrun
static AgentLibrary* libraries() { return _libraryList.first(); }
static bool init_libraries_at_startup() { return !_libraryList.is_empty(); }
@@ -701,8 +737,8 @@
static void set_library_path(const char *value) { _java_library_path->set_value(value); }
static void set_ext_dirs(char *value) { _ext_dirs = os::strdup_check_oom(value); }
- // Set up of the underlying system boot class path
- static void set_jdkbootclasspath_append();
+ // Set up the underlying pieces of the system boot class path
+ static void add_xpatchprefix(const char *module_name, const char *path, bool* xpatch_javabase);
static void set_sysclasspath(const char *value) {
_system_boot_class_path->set_value(value);
set_jdkbootclasspath_append();
@@ -711,11 +747,15 @@
_system_boot_class_path->append_value(value);
set_jdkbootclasspath_append();
}
+ static void set_jdkbootclasspath_append();
- static char* get_java_home() { return _java_home->value(); }
- static char* get_dll_dir() { return _sun_boot_library_path->value(); }
+ static GrowableArray<ModuleXPatchPath*>* get_xpatchprefix() { return _xpatchprefix; }
static char* get_sysclasspath() { return _system_boot_class_path->value(); }
- static char* get_ext_dirs() { return _ext_dirs; }
+ static char* get_jdk_boot_class_path_append() { return _jdk_boot_class_path_append->value(); }
+
+ static char* get_java_home() { return _java_home->value(); }
+ static char* get_dll_dir() { return _sun_boot_library_path->value(); }
+ static char* get_ext_dirs() { return _ext_dirs; }
static char* get_appclasspath() { return _java_class_path->value(); }
static void fix_appclasspath();
--- a/hotspot/src/share/vm/runtime/globals.hpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/runtime/globals.hpp Wed May 11 00:38:58 2016 +0300
@@ -1418,10 +1418,6 @@
product(bool, StressLdcRewrite, false, \
"Force ldc -> ldc_w rewrite during RedefineClasses") \
\
- product(uintx, TraceRedefineClasses, 0, \
- "Trace level for JVMTI RedefineClasses") \
- range(0, 0xFFFFFFFF) \
- \
/* change to false by default sometime after Mustang */ \
product(bool, VerifyMergedCPBytecodes, true, \
"Verify bytecodes after RedefineClasses constant pool merging") \
@@ -2070,6 +2066,9 @@
notproduct(bool, VerboseInternalVMTests, false, \
"Turn on logging for internal VM tests.") \
\
+ product(bool, ExecutingUnitTests, false, \
+ "Whether the JVM is running unit tests or not") \
+ \
product_pd(bool, UseTLAB, "Use thread-local object allocation") \
\
product_pd(bool, ResizeTLAB, \
--- a/hotspot/src/share/vm/runtime/init.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/runtime/init.cpp Wed May 11 00:38:58 2016 +0300
@@ -52,7 +52,8 @@
// Initialization done by Java thread in init_globals()
void management_init();
void bytecodes_init();
-void classLoader_init();
+void classLoader_init1();
+void classLoader_init2(); // note: ClassLoader need 2-phase init
void compilationPolicy_init();
void codeCache_init();
void VM_Version_init();
@@ -102,7 +103,7 @@
HandleMark hm;
management_init();
bytecodes_init();
- classLoader_init();
+ classLoader_init1();
compilationPolicy_init();
codeCache_init();
CodeCacheExtensions::initialize();
@@ -116,6 +117,7 @@
if (status != JNI_OK)
return status;
+ classLoader_init2(); // after SymbolTable creation, set up -Xpatch entries
CodeCacheExtensions::complete_step(CodeCacheExtensionsSteps::Universe);
interpreter_init(); // before any methods loaded
CodeCacheExtensions::complete_step(CodeCacheExtensionsSteps::Interpreter);
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Wed May 11 00:38:58 2016 +0300
@@ -46,7 +46,6 @@
#include "oops/oop.inline.hpp"
#include "prims/forte.hpp"
#include "prims/jvmtiExport.hpp"
-#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "prims/methodHandles.hpp"
#include "prims/nativeLookup.hpp"
#include "runtime/arguments.hpp"
@@ -603,27 +602,18 @@
}
// The interpreter code to call this tracing function is only
-// called/generated when TraceRedefineClasses has the right bits
-// set. Since obsolete methods are never compiled, we don't have
+// called/generated when UL is on for redefine, class and has the right level
+// and tags. Since obsolete methods are never compiled, we don't have
// to modify the compilers to generate calls to this function.
//
JRT_LEAF(int, SharedRuntime::rc_trace_method_entry(
JavaThread* thread, Method* method))
- assert(RC_TRACE_IN_RANGE(0x00001000, 0x00002000), "wrong call");
-
if (method->is_obsolete()) {
// We are calling an obsolete method, but this is not necessarily
// an error. Our method could have been redefined just after we
// fetched the Method* from the constant pool.
-
- // RC_TRACE macro has an embedded ResourceMark
- RC_TRACE_WITH_THREAD(0x00001000, thread,
- ("calling obsolete method '%s'",
- method->name_and_sig_as_C_string()));
- if (RC_TRACE_ENABLED(0x00002000)) {
- // this option is provided to debug calls to obsolete methods
- guarantee(false, "faulting at call to an obsolete method.");
- }
+ ResourceMark rm;
+ log_trace(redefine, class, obsolete)("calling obsolete method '%s'", method->name_and_sig_as_C_string());
}
return 0;
JRT_END
@@ -1762,6 +1752,21 @@
return callee_method;
}
+address SharedRuntime::handle_unsafe_access(JavaThread* thread, address next_pc) {
+ // The faulting unsafe accesses should be changed to throw the error
+ // synchronously instead. Meanwhile the faulting instruction will be
+ // skipped over (effectively turning it into a no-op) and an
+ // asynchronous exception will be raised which the thread will
+ // handle at a later point. If the instruction is a load it will
+ // return garbage.
+
+ // Request an async exception.
+ thread->set_pending_unsafe_access_error();
+
+ // Return address of next instruction to execute.
+ return next_pc;
+}
+
#ifdef ASSERT
void SharedRuntime::check_member_name_argument_is_last_argument(const methodHandle& method,
const BasicType* sig_bt,
--- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp Wed May 11 00:38:58 2016 +0300
@@ -522,6 +522,8 @@
static address handle_wrong_method_abstract(JavaThread* thread);
static address handle_wrong_method_ic_miss(JavaThread* thread);
+ static address handle_unsafe_access(JavaThread* thread, address next_pc);
+
#ifndef PRODUCT
// Collect and print inline cache miss statistics
--- a/hotspot/src/share/vm/runtime/stubRoutines.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/runtime/stubRoutines.cpp Wed May 11 00:38:58 2016 +0300
@@ -55,7 +55,6 @@
address StubRoutines::_throw_NullPointerException_at_call_entry = NULL;
address StubRoutines::_throw_StackOverflowError_entry = NULL;
address StubRoutines::_throw_delayed_StackOverflowError_entry = NULL;
-address StubRoutines::_handler_for_unsafe_access_entry = NULL;
jint StubRoutines::_verify_oop_count = 0;
address StubRoutines::_verify_oop_subroutine_entry = NULL;
address StubRoutines::_atomic_xchg_entry = NULL;
--- a/hotspot/src/share/vm/runtime/stubRoutines.hpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/runtime/stubRoutines.hpp Wed May 11 00:38:58 2016 +0300
@@ -111,7 +111,6 @@
static address _throw_NullPointerException_at_call_entry;
static address _throw_StackOverflowError_entry;
static address _throw_delayed_StackOverflowError_entry;
- static address _handler_for_unsafe_access_entry;
static address _atomic_xchg_entry;
static address _atomic_xchg_ptr_entry;
@@ -288,10 +287,6 @@
static address throw_StackOverflowError_entry() { return _throw_StackOverflowError_entry; }
static address throw_delayed_StackOverflowError_entry() { return _throw_delayed_StackOverflowError_entry; }
- // Exceptions during unsafe access - should throw Java exception rather
- // than crash.
- static address handler_for_unsafe_access() { return _handler_for_unsafe_access_entry; }
-
static address atomic_xchg_entry() { return _atomic_xchg_entry; }
static address atomic_xchg_ptr_entry() { return _atomic_xchg_ptr_entry; }
static address atomic_store_entry() { return _atomic_store_entry; }
--- a/hotspot/src/share/vm/runtime/vframe.hpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/runtime/vframe.hpp Wed May 11 00:38:58 2016 +0300
@@ -317,14 +317,6 @@
intptr_t* frame_id() const { return _frame.id(); }
address frame_pc() const { return _frame.pc(); }
- javaVFrame* java_frame() {
- vframe* vf = vframe::new_vframe(&_frame, &_reg_map, _thread);
- if (vf->is_java_frame()) {
- return (javaVFrame*)vf;
- }
- return NULL;
- }
-
CodeBlob* cb() const { return _frame.cb(); }
CompiledMethod* nm() const {
assert( cb() != NULL && cb()->is_compiled(), "usage");
--- a/hotspot/src/share/vm/services/management.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/services/management.cpp Wed May 11 00:38:58 2016 +0300
@@ -1609,8 +1609,8 @@
}
char* name = java_lang_String::as_utf8_string(fn);
- FormatBuffer<80> err_msg("%s", "");
- int succeed = WriteableFlags::set_flag(name, new_value, Flag::MANAGEMENT, err_msg);
+ FormatBuffer<80> error_msg("%s", "");
+ int succeed = WriteableFlags::set_flag(name, new_value, Flag::MANAGEMENT, error_msg);
if (succeed != Flag::SUCCESS) {
if (succeed == Flag::MISSING_VALUE) {
@@ -1619,7 +1619,7 @@
} else {
// all the other errors are reported as IAE with the appropriate error message
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
- err_msg.buffer());
+ error_msg.buffer());
}
}
assert(succeed == Flag::SUCCESS, "Setting flag should succeed");
--- a/hotspot/src/share/vm/utilities/debug.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/utilities/debug.cpp Wed May 11 00:38:58 2016 +0300
@@ -58,6 +58,8 @@
#include "trace/tracing.hpp"
#endif
+#include <stdio.h>
+
#ifndef ASSERT
# ifdef _DEBUG
// NOTE: don't turn the lines below into a comment -- if you're getting
@@ -187,7 +189,7 @@
return true;
}
- if (!is_error_reported()) {
+ if (!is_error_reported() && !SuppressFatalErrorMessage) {
// print a friendly hint:
fdStream out(defaultStream::output_fd());
out.print_raw_cr("# To suppress the following error report, specify this argument");
@@ -262,6 +264,21 @@
report_vm_error(file, line, "Unimplemented()");
}
+#ifdef ASSERT
+bool is_executing_unit_tests() {
+ return ExecutingUnitTests;
+}
+
+void report_assert_msg(const char* msg, ...) {
+ va_list ap;
+ va_start(ap, msg);
+
+ fprintf(stderr, "assert failed: %s\n", err_msg(FormatBufferDummy(), msg, ap).buffer());
+
+ va_end(ap);
+}
+#endif // ASSERT
+
void report_untested(const char* file, int line, const char* message) {
#ifndef PRODUCT
warning("Untested: %s in %s: %d\n", message, file, line);
--- a/hotspot/src/share/vm/utilities/debug.hpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/utilities/debug.hpp Wed May 11 00:38:58 2016 +0300
@@ -46,11 +46,15 @@
FormatBufferResource(const char * format, ...) ATTRIBUTE_PRINTF(2, 3);
};
+class FormatBufferDummy {};
+
// Use stack for buffer
template <size_t bufsz = FormatBufferBase::BufferSize>
class FormatBuffer : public FormatBufferBase {
public:
inline FormatBuffer(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
+ // since va_list is unspecified type (can be char*), we use FormatBufferDummy to disambiguate these constructors
+ inline FormatBuffer(FormatBufferDummy dummy, const char* format, va_list ap) ATTRIBUTE_PRINTF(3, 0);
inline void append(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
inline void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
inline void printv(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0);
@@ -75,6 +79,11 @@
}
template <size_t bufsz>
+FormatBuffer<bufsz>::FormatBuffer(FormatBufferDummy dummy, const char * format, va_list ap) : FormatBufferBase(_buffer) {
+ jio_vsnprintf(_buf, bufsz, format, ap);
+}
+
+template <size_t bufsz>
FormatBuffer<bufsz>::FormatBuffer() : FormatBufferBase(_buffer) {
_buf[0] = '\0';
}
@@ -119,11 +128,13 @@
#define vmassert(p, ...) \
do { \
if (!(p)) { \
+ if (is_executing_unit_tests()) { \
+ report_assert_msg(__VA_ARGS__); \
+ } \
report_vm_error(__FILE__, __LINE__, "assert(" #p ") failed", __VA_ARGS__); \
BREAKPOINT; \
} \
} while (0)
-
#endif
// For backward compatibility.
@@ -210,10 +221,16 @@
// ATTRIBUTE_PRINTF works with gcc >= 4.8 and any other compiler.
void report_vm_error(const char* file, int line, const char* error_msg,
const char* detail_fmt, ...) ATTRIBUTE_PRINTF(4, 5);
+#ifdef ASSERT
+void report_assert_msg(const char* msg, ...) ATTRIBUTE_PRINTF(1, 2);
+#endif // ASSERT
#else
// GCC < 4.8 warns because of empty format string. Warning can not be switched off selectively.
void report_vm_error(const char* file, int line, const char* error_msg,
const char* detail_fmt, ...);
+#ifdef ASSERT
+void report_assert_msg(const char* msg, ...);
+#endif // ASSERT
#endif
void report_vm_status_error(const char* file, int line, const char* error_msg,
int status, const char* detail);
@@ -225,6 +242,11 @@
void report_unimplemented(const char* file, int line);
void report_untested(const char* file, int line, const char* message);
+#ifdef ASSERT
+// unit test support
+bool is_executing_unit_tests();
+#endif // ASSERT
+
void warning(const char* format, ...) ATTRIBUTE_PRINTF(1, 2);
// Compile-time asserts. Cond must be a compile-time constant expression that
--- a/hotspot/src/share/vm/utilities/vmError.cpp Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/src/share/vm/utilities/vmError.cpp Wed May 11 00:38:58 2016 +0300
@@ -290,8 +290,8 @@
void VMError::report(outputStream* st, bool _verbose) {
-# define BEGIN if (_current_step == 0) { _current_step = 1;
-# define STEP(n, s) } if (_current_step < n) { _current_step = n; _current_step_info = s;
+# define BEGIN if (_current_step == 0) { _current_step = __LINE__;
+# define STEP(s) } if (_current_step < __LINE__) { _current_step = __LINE__; _current_step_info = s;
# define END }
// don't allocate large buffer on stack
@@ -299,7 +299,7 @@
BEGIN
- STEP(10, "(printing fatal error message)")
+ STEP("printing fatal error message")
st->print_cr("#");
if (should_report_bug(_id)) {
@@ -314,21 +314,21 @@
// test secondary error handling. Test it twice, to test that resetting
// error handler after a secondary crash works.
- STEP(20, "(test secondary crash 1)")
+ STEP("test secondary crash 1")
if (_verbose && TestCrashInErrorHandler != 0) {
st->print_cr("Will crash now (TestCrashInErrorHandler=" UINTX_FORMAT ")...",
TestCrashInErrorHandler);
controlled_crash(TestCrashInErrorHandler);
}
- STEP(30, "(test secondary crash 2)")
+ STEP("test secondary crash 2")
if (_verbose && TestCrashInErrorHandler != 0) {
st->print_cr("Will crash now (TestCrashInErrorHandler=" UINTX_FORMAT ")...",
TestCrashInErrorHandler);
controlled_crash(TestCrashInErrorHandler);
}
- STEP(40, "(test safefetch in error handler)")
+ STEP("test safefetch in error handler")
// test whether it is safe to use SafeFetch32 in Crash Handler. Test twice
// to test that resetting the signal handler works correctly.
if (_verbose && TestSafeFetchInErrorHandler) {
@@ -349,7 +349,7 @@
}
#endif // PRODUCT
- STEP(50, "(printing type of error)")
+ STEP("printing type of error")
switch(_id) {
case OOM_MALLOC_ERROR:
@@ -384,7 +384,7 @@
break;
}
- STEP(60, "(printing exception/signal name)")
+ STEP("printing exception/signal name")
st->print_cr("#");
st->print("# ");
@@ -414,14 +414,14 @@
}
}
- STEP(70, "(printing current thread and pid)")
+ STEP("printing current thread and pid")
// process id, thread id
st->print(", pid=%d", os::current_process_id());
st->print(", tid=" UINTX_FORMAT, os::current_thread_id());
st->cr();
- STEP(80, "(printing error message)")
+ STEP("printing error message")
if (should_report_bug(_id)) { // already printed the message.
// error message
@@ -432,11 +432,11 @@
}
}
- STEP(90, "(printing Java version string)")
+ STEP("printing Java version string")
report_vm_version(st, buf, sizeof(buf));
- STEP(100, "(printing problematic frame)")
+ STEP("printing problematic frame")
// Print current frame if we have a context (i.e. it's a crash)
if (_context) {
@@ -448,7 +448,7 @@
st->print_cr("#");
}
- STEP(110, "(printing core file information)")
+ STEP("printing core file information")
st->print("# ");
if (CreateCoredumpOnCrash) {
if (coredump_status) {
@@ -462,13 +462,13 @@
st->cr();
st->print_cr("#");
- STEP(120, "(printing bug submit message)")
+ STEP("printing bug submit message")
if (should_report_bug(_id) && _verbose) {
print_bug_submit_message(st, _thread);
}
- STEP(130, "(printing summary)" )
+ STEP("printing summary")
if (_verbose) {
st->cr();
@@ -476,7 +476,7 @@
st->cr();
}
- STEP(140, "(printing VM option summary)" )
+ STEP("printing VM option summary")
if (_verbose) {
// VM options
@@ -484,20 +484,20 @@
st->cr();
}
- STEP(150, "(printing summary machine and OS info)")
+ STEP("printing summary machine and OS info")
if (_verbose) {
os::print_summary_info(st, buf, sizeof(buf));
}
- STEP(160, "(printing date and time)" )
+ STEP("printing date and time")
if (_verbose) {
os::print_date_and_time(st, buf, sizeof(buf));
}
- STEP(170, "(printing thread)" )
+ STEP("printing thread")
if (_verbose) {
st->cr();
@@ -505,7 +505,7 @@
st->cr();
}
- STEP(180, "(printing current thread)" )
+ STEP("printing current thread")
// current thread
if (_verbose) {
@@ -519,7 +519,7 @@
st->cr();
}
- STEP(190, "(printing current compile task)" )
+ STEP("printing current compile task")
if (_verbose && _thread && _thread->is_Compiler_thread()) {
CompilerThread* t = (CompilerThread*)_thread;
@@ -532,7 +532,7 @@
}
- STEP(200, "(printing stack bounds)" )
+ STEP("printing stack bounds")
if (_verbose) {
st->print("Stack: ");
@@ -563,7 +563,7 @@
st->cr();
}
- STEP(210, "(printing native stack)" )
+ STEP("printing native stack")
if (_verbose) {
if (os::platform_print_native_stack(st, _context, buf, sizeof(buf))) {
@@ -577,13 +577,13 @@
}
}
- STEP(220, "(printing Java stack)" )
+ STEP("printing Java stack")
if (_verbose && _thread && _thread->is_Java_thread()) {
print_stack_trace(st, (JavaThread*)_thread, buf, sizeof(buf));
}
- STEP(230, "(printing target Java thread stack)" )
+ STEP("printing target Java thread stack")
// printing Java thread stack trace if it is involved in GC crash
if (_verbose && _thread && (_thread->is_Named_thread())) {
@@ -594,7 +594,7 @@
}
}
- STEP(240, "(printing siginfo)" )
+ STEP("printing siginfo")
// signal no, signal code, address that caused the fault
if (_verbose && _siginfo) {
@@ -603,7 +603,7 @@
st->cr();
}
- STEP(245, "(CDS archive access warning)" )
+ STEP("CDS archive access warning")
// Print an explicit hint if we crashed on access to the CDS archive.
if (_verbose && _siginfo) {
@@ -611,7 +611,7 @@
st->cr();
}
- STEP(250, "(printing register info)")
+ STEP("printing register info")
// decode register contents if possible
if (_verbose && _context && Universe::is_fully_initialized()) {
@@ -619,7 +619,7 @@
st->cr();
}
- STEP(260, "(printing registers, top of stack, instructions near pc)")
+ STEP("printing registers, top of stack, instructions near pc")
// registers, top of stack, instructions near pc
if (_verbose && _context) {
@@ -627,7 +627,7 @@
st->cr();
}
- STEP(265, "(printing code blob if possible)")
+ STEP("printing code blob if possible")
if (_verbose && _context) {
CodeBlob* cb = CodeCache::find_blob(_pc);
@@ -652,7 +652,7 @@
}
}
- STEP(270, "(printing VM operation)" )
+ STEP("printing VM operation")
if (_verbose && _thread && _thread->is_VM_thread()) {
VMThread* t = (VMThread*)_thread;
@@ -664,7 +664,7 @@
}
}
- STEP(280, "(printing process)" )
+ STEP("printing process")
if (_verbose) {
st->cr();
@@ -672,7 +672,7 @@
st->cr();
}
- STEP(290, "(printing all threads)" )
+ STEP("printing all threads")
// all threads
if (_verbose && _thread) {
@@ -680,7 +680,7 @@
st->cr();
}
- STEP(300, "(printing VM state)" )
+ STEP("printing VM state")
if (_verbose) {
// Safepoint state
@@ -702,7 +702,7 @@
st->cr();
}
- STEP(310, "(printing owned locks on error)" )
+ STEP("printing owned locks on error")
// mutexes/monitors that currently have an owner
if (_verbose) {
@@ -710,7 +710,7 @@
st->cr();
}
- STEP(320, "(printing number of OutOfMemoryError and StackOverflow exceptions)")
+ STEP("printing number of OutOfMemoryError and StackOverflow exceptions")
if (_verbose && Exceptions::has_exception_counts()) {
st->print_cr("OutOfMemory and StackOverflow Exception counts:");
@@ -718,7 +718,7 @@
st->cr();
}
- STEP(330, "(printing compressed oops mode")
+ STEP("printing compressed oops mode")
if (_verbose && UseCompressedOops) {
Universe::print_compressed_oops_mode(st);
@@ -728,7 +728,7 @@
st->cr();
}
- STEP(340, "(printing heap information)" )
+ STEP("printing heap information")
if (_verbose && Universe::is_fully_initialized()) {
Universe::heap()->print_on_error(st);
@@ -737,7 +737,7 @@
st->cr();
}
- STEP(350, "(printing code cache information)" )
+ STEP("printing code cache information")
if (_verbose && Universe::is_fully_initialized()) {
// print code cache information before vm abort
@@ -745,14 +745,14 @@
st->cr();
}
- STEP(360, "(printing ring buffers)" )
+ STEP("printing ring buffers")
if (_verbose) {
Events::print_all(st);
st->cr();
}
- STEP(370, "(printing dynamic libraries)" )
+ STEP("printing dynamic libraries")
if (_verbose) {
// dynamic libraries, or memory map
@@ -760,7 +760,7 @@
st->cr();
}
- STEP(380, "(printing VM options)" )
+ STEP("printing VM options")
if (_verbose) {
// VM options
@@ -768,40 +768,40 @@
st->cr();
}
- STEP(390, "(printing warning if internal testing API used)" )
+ STEP("printing warning if internal testing API used")
if (WhiteBox::used()) {
st->print_cr("Unsupported internal testing APIs have been used.");
st->cr();
}
- STEP(395, "(printing log configuration)")
+ STEP("printing log configuration")
if (_verbose){
st->print_cr("Logging:");
LogConfiguration::describe_current_configuration(st);
st->cr();
}
- STEP(400, "(printing all environment variables)" )
+ STEP("printing all environment variables")
if (_verbose) {
os::print_environment_variables(st, env_list);
st->cr();
}
- STEP(410, "(printing signal handlers)" )
+ STEP("printing signal handlers")
if (_verbose) {
os::print_signal_handlers(st, buf, sizeof(buf));
st->cr();
}
- STEP(420, "(Native Memory Tracking)" )
+ STEP("Native Memory Tracking")
if (_verbose) {
MemTracker::error_report(st);
}
- STEP(430, "(printing system)" )
+ STEP("printing system")
if (_verbose) {
st->cr();
@@ -809,27 +809,27 @@
st->cr();
}
- STEP(440, "(printing OS information)" )
+ STEP("printing OS information")
if (_verbose) {
os::print_os_info(st);
st->cr();
}
- STEP(450, "(printing CPU info)" )
+ STEP("printing CPU info")
if (_verbose) {
os::print_cpu_info(st, buf, sizeof(buf));
st->cr();
}
- STEP(460, "(printing memory info)" )
+ STEP("printing memory info")
if (_verbose) {
os::print_memory_info(st);
st->cr();
}
- STEP(470, "(printing internal vm info)" )
+ STEP("printing internal vm info")
if (_verbose) {
st->print_cr("vm_info: %s", Abstract_VM_Version::internal_vm_info_string());
@@ -837,7 +837,7 @@
}
// print a defined marker to show that error handling finished correctly.
- STEP(480, "(printing end marker)" )
+ STEP("printing end marker")
if (_verbose) {
st->print_cr("END.");
@@ -858,35 +858,35 @@
char buf[O_BUFLEN];
report_vm_version(st, buf, sizeof(buf));
- // STEP("(printing summary)")
+ // STEP("printing summary")
st->cr();
st->print_cr("--------------- S U M M A R Y ------------");
st->cr();
- // STEP("(printing VM option summary)")
+ // STEP("printing VM option summary")
// VM options
Arguments::print_summary_on(st);
st->cr();
- // STEP("(printing summary machine and OS info)")
+ // STEP("printing summary machine and OS info")
os::print_summary_info(st, buf, sizeof(buf));
- // STEP("(printing date and time)")
+ // STEP("printing date and time")
os::print_date_and_time(st, buf, sizeof(buf));
- // Skip: STEP("(printing thread)")
+ // Skip: STEP("printing thread")
- // STEP("(printing process)")
+ // STEP("printing process")
st->cr();
st->print_cr("--------------- P R O C E S S ---------------");
st->cr();
- // STEP("(printing number of OutOfMemoryError and StackOverflow exceptions)")
+ // STEP("printing number of OutOfMemoryError and StackOverflow exceptions")
if (Exceptions::has_exception_counts()) {
st->print_cr("OutOfMemory and StackOverflow Exception counts:");
@@ -894,7 +894,7 @@
st->cr();
}
- // STEP("(printing compressed oops mode")
+ // STEP("printing compressed oops mode")
if (UseCompressedOops) {
Universe::print_compressed_oops_mode(st);
@@ -904,7 +904,7 @@
st->cr();
}
- // STEP("(printing heap information)")
+ // STEP("printing heap information")
if (Universe::is_fully_initialized()) {
Universe::heap()->print_on_error(st);
@@ -913,7 +913,7 @@
st->cr();
}
- // STEP("(printing code cache information)")
+ // STEP("printing code cache information")
if (Universe::is_fully_initialized()) {
// print code cache information before vm abort
@@ -921,77 +921,77 @@
st->cr();
}
- // STEP("(printing ring buffers)")
+ // STEP("printing ring buffers")
Events::print_all(st);
st->cr();
- // STEP("(printing dynamic libraries)")
+ // STEP("printing dynamic libraries")
// dynamic libraries, or memory map
os::print_dll_info(st);
st->cr();
- // STEP("(printing VM options)")
+ // STEP("printing VM options")
// VM options
Arguments::print_on(st);
st->cr();
- // STEP("(printing warning if internal testing API used)")
+ // STEP("printing warning if internal testing API used")
if (WhiteBox::used()) {
st->print_cr("Unsupported internal testing APIs have been used.");
st->cr();
}
- // STEP("(printing log configuration)")
+ // STEP("printing log configuration")
st->print_cr("Logging:");
LogConfiguration::describe(st);
st->cr();
- // STEP("(printing all environment variables)")
+ // STEP("printing all environment variables")
os::print_environment_variables(st, env_list);
st->cr();
- // STEP("(printing signal handlers)")
+ // STEP("printing signal handlers")
os::print_signal_handlers(st, buf, sizeof(buf));
st->cr();
- // STEP("(Native Memory Tracking)")
+ // STEP("Native Memory Tracking")
MemTracker::error_report(st);
- // STEP("(printing system)")
+ // STEP("printing system")
st->cr();
st->print_cr("--------------- S Y S T E M ---------------");
st->cr();
- // STEP("(printing OS information)")
+ // STEP("printing OS information")
os::print_os_info(st);
st->cr();
- // STEP("(printing CPU info)")
+ // STEP("printing CPU info")
os::print_cpu_info(st, buf, sizeof(buf));
st->cr();
- // STEP("(printing memory info)")
+ // STEP("printing memory info")
os::print_memory_info(st);
st->cr();
- // STEP("(printing internal vm info)")
+ // STEP("printing internal vm info")
st->print_cr("vm_info: %s", Abstract_VM_Version::internal_vm_info_string());
st->cr();
// print a defined marker to show that error handling finished correctly.
- // STEP("(printing end marker)")
+ // STEP("printing end marker")
st->print_cr("END.");
}
@@ -1190,7 +1190,7 @@
}
jio_snprintf(buffer, sizeof(buffer),
- "[error occurred during error reporting %s, id 0x%x]",
+ "[error occurred during error reporting (%s), id 0x%x]",
_current_step_info, _id);
if (log.is_open()) {
log.cr();
--- a/hotspot/test/Makefile Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/Makefile Wed May 11 00:38:58 2016 +0300
@@ -52,6 +52,11 @@
WC = wc
ZIP = zip
+define NEWLINE
+
+
+endef
+
# Get OS name from uname (Cygwin inexplicably adds _NT-5.1)
UNAME_S := $(shell $(UNAME) -s | $(CUT) -f1 -d_)
ifeq ($(UNAME_S), SunOS)
@@ -427,6 +432,20 @@
################################################################
+# Run the native gtest tests from the test image
+
+hotspot_gtest:
+ $(foreach v, $(JVM_VARIANTS), \
+ $(MAKE) hotspot_gtest$v $(NEWLINE) )
+
+hotspot_gtestserver hotspot_gtestclient hotspot_gtestminimal: hotspot_gtest%:
+ $(TESTNATIVE_DIR)/hotspot/gtest/$*/gtestLauncher \
+ -jdk $(shell $(GETMIXEDPATH) "$(PRODUCT_HOME)")
+
+PHONY_LIST += hotspot_gtest hotspot_gtestserver hotspot_gtestclient \
+ hotspot_gtestminimal
+
+################################################################
# Phony targets (e.g. these are not filenames)
.PHONY: all clean prep $(PHONY_LIST)
--- a/hotspot/test/TEST.ROOT Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/TEST.ROOT Wed May 11 00:38:58 2016 +0300
@@ -36,9 +36,12 @@
requires.extraPropDefns = ../../test/jtreg-ext/requires/VMProps.java
requires.properties=sun.arch.data.model
-# Tests using jtreg 4.2 b01 features
-requiredVersion=4.2 b01
+# Tests using jtreg 4.2 b02 features
+requiredVersion=4.2 b02
# Path to libraries in the topmost test directory. This is needed so @library
# does not need ../../ notation to reach them
external.lib.roots = ../../
+
+# Use new form of -Xpatch
+useNewXpatch=true
--- a/hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestI.java Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestI.java Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
--- a/hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestL.java Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestL.java Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
--- a/hotspot/test/compiler/jvmci/compilerToVM/ReadUncompressedOopTest.java Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/compiler/jvmci/compilerToVM/ReadUncompressedOopTest.java Wed May 11 00:38:58 2016 +0300
@@ -24,6 +24,7 @@
/*
* @test
* @bug 8136421
+ * @ignore 8155216
* @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9" | os.simpleArch == "aarch64")
* @library / /testlibrary /test/lib/
* @library ../common/patches
--- a/hotspot/test/compiler/stable/TestStableBoolean.java Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/compiler/stable/TestStableBoolean.java Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
--- a/hotspot/test/compiler/stable/TestStableByte.java Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/compiler/stable/TestStableByte.java Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
--- a/hotspot/test/compiler/stable/TestStableChar.java Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/compiler/stable/TestStableChar.java Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
--- a/hotspot/test/compiler/stable/TestStableDouble.java Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/compiler/stable/TestStableDouble.java Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
--- a/hotspot/test/compiler/stable/TestStableFloat.java Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/compiler/stable/TestStableFloat.java Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
--- a/hotspot/test/compiler/stable/TestStableInt.java Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/compiler/stable/TestStableInt.java Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
--- a/hotspot/test/compiler/stable/TestStableLong.java Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/compiler/stable/TestStableLong.java Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
--- a/hotspot/test/compiler/stable/TestStableMemoryBarrier.java Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/compiler/stable/TestStableMemoryBarrier.java Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
--- a/hotspot/test/compiler/stable/TestStableObject.java Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/compiler/stable/TestStableObject.java Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
--- a/hotspot/test/compiler/stable/TestStableShort.java Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/compiler/stable/TestStableShort.java Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
--- a/hotspot/test/compiler/unsafe/UnsafeGetConstantField.java Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/compiler/unsafe/UnsafeGetConstantField.java Wed May 11 00:38:58 2016 +0300
@@ -40,6 +40,7 @@
* -XX:CompileCommand=dontinline,UnsafeGetConstantField.checkGetAddress()
* -XX:CompileCommand=dontinline,*.test*
* -XX:+UseUnalignedAccesses
+ * -XaddReads:java.base=ALL-UNNAMED
* compiler.unsafe.UnsafeGetConstantField
*
* @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions
@@ -49,6 +50,7 @@
* -XX:CompileCommand=dontinline,*.test*
* -XX:CompileCommand=inline,*Unsafe.get*
* -XX:-UseUnalignedAccesses
+ * -XaddReads:java.base=ALL-UNNAMED
* compiler.unsafe.UnsafeGetConstantField
*/
package compiler.unsafe;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/g1/humongousObjects/objectGraphTest/GC.java Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package gc.g1.humongousObjects.objectGraphTest;
+
+import gc.testlibrary.Helpers;
+import jdk.test.lib.Asserts;
+import sun.hotspot.WhiteBox;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Consumer;
+
+/**
+ * Provides methods to initiate GC of requested type and
+ * checks for states of humongous and non-humongous soft/weak externally
+ * referenced objects after GCs
+ */
+public enum GC {
+
+ YOUNG_GC {
+ @Override
+ public Runnable get() {
+ return WHITE_BOX::youngGC;
+ }
+
+ public Consumer<ReferenceInfo<Object[]>> getChecker() {
+ return getCheckerImpl(false, false, true, false);
+ }
+
+ @Override
+ public List<String> shouldContain() {
+ return Arrays.asList(GCTokens.WB_INITIATED_YOUNG_GC);
+ }
+
+ @Override
+ public List<String> shouldNotContain() {
+ return Arrays.asList(GCTokens.WB_INITIATED_MIXED_GC, GCTokens.FULL_GC, GCTokens.WB_INITIATED_CMC,
+ GCTokens.CMC, GCTokens.YOUNG_GC);
+ }
+ },
+ FULL_GC {
+ @Override
+ public Runnable get() {
+ return System::gc;
+ }
+
+ public Consumer<ReferenceInfo<Object[]>> getChecker() {
+ return getCheckerImpl(true, false, true, false);
+ }
+
+ @Override
+ public List<String> shouldContain() {
+ return Arrays.asList(GCTokens.FULL_GC);
+ }
+
+ @Override
+ public List<String> shouldNotContain() {
+ return Arrays.asList(GCTokens.WB_INITIATED_YOUNG_GC, GCTokens.WB_INITIATED_MIXED_GC,
+ GCTokens.WB_INITIATED_CMC, GCTokens.CMC, GCTokens.YOUNG_GC);
+ }
+ },
+
+ FULL_GC_MEMORY_PRESSURE {
+ @Override
+ public Runnable get() {
+ return WHITE_BOX::fullGC;
+ }
+
+ public Consumer<ReferenceInfo<Object[]>> getChecker() {
+ return getCheckerImpl(true, true, true, true);
+ }
+
+ @Override
+ public List<String> shouldContain() {
+ return Arrays.asList(GCTokens.FULL_GC_MEMORY_PRESSURE);
+ }
+
+ @Override
+ public List<String> shouldNotContain() {
+ return Arrays.asList(GCTokens.WB_INITIATED_YOUNG_GC, GCTokens.WB_INITIATED_MIXED_GC,
+ GCTokens.WB_INITIATED_CMC, GCTokens.CMC, GCTokens.YOUNG_GC, GCTokens.FULL_GC);
+ }
+ };
+
+ protected String getErrorMessage(ReferenceInfo<Object[]> ref, boolean expectedNull, String gcType) {
+ return String.format("Externally effectively %s referenced %shumongous object was%s deleted after %s",
+ (ref.softlyReachable ? "soft" : "weak"), (ref.effectiveHumongous ? "" : "non-"),
+ (expectedNull ? " not" : ""), gcType);
+ }
+
+ protected Consumer<ReferenceInfo<Object[]>> getCaseCheck(boolean expectedNull) {
+ return expectedNull
+ ? r -> Asserts.assertNull(r.reference.get(), getErrorMessage(r, true, name()))
+ : r -> Asserts.assertNotNull(r.reference.get(), getErrorMessage(r, false, name()));
+ }
+
+ protected Consumer<ReferenceInfo<Object[]>> getCheckerImpl(boolean weakH, boolean softH,
+ boolean weakS, boolean softS) {
+ return new Checker(getCaseCheck(weakH), getCaseCheck(softH), getCaseCheck(weakS), getCaseCheck(softS));
+ }
+
+ protected String getGcLogName(String prefix) {
+ return prefix + "_" + name() + ".gc.log";
+ }
+
+ private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
+
+ /**
+ * @return method to initiate GC
+ */
+ public abstract Runnable get();
+
+ /**
+ * @return checker for objects' states after GC
+ */
+ public abstract Consumer<ReferenceInfo<Object[]>> getChecker();
+
+ /**
+ * @return list of tokens that should be contained in gc log after gc of specified type
+ */
+ public abstract List<String> shouldContain();
+
+ /**
+ * @return list of tokens that should not be contained in gc log after gc of specified type
+ */
+ public abstract List<String> shouldNotContain();
+
+
+ /**
+ * Checks object' state after gc
+ * Contains 4 Consumers which are called depending on humongous/non-humongous and
+ * external weak/soft referenced objects
+ */
+ private static class Checker implements Consumer<ReferenceInfo<Object[]>> {
+ // 4 consumers with checks for (humongous /simple objects)*(weak/soft referenced)
+ final Consumer<ReferenceInfo<Object[]>> weakHumongousCheck;
+ final Consumer<ReferenceInfo<Object[]>> softHumongousCheck;
+ final Consumer<ReferenceInfo<Object[]>> weakSimpleCheck;
+ final Consumer<ReferenceInfo<Object[]>> softSimpleCheck;
+
+ public Checker(Consumer<ReferenceInfo<Object[]>> weakHumongousCheck,
+ Consumer<ReferenceInfo<Object[]>> softHumongousCheck,
+ Consumer<ReferenceInfo<Object[]>> weakSimpleCheck,
+ Consumer<ReferenceInfo<Object[]>> softSimpleCheck) {
+ this.weakHumongousCheck = weakHumongousCheck;
+ this.softHumongousCheck = softHumongousCheck;
+ this.weakSimpleCheck = weakSimpleCheck;
+ this.softSimpleCheck = softSimpleCheck;
+ }
+
+ public void accept(ReferenceInfo<Object[]> ref) {
+
+ System.out.println("reference.get() returned " + ref.reference.get());
+ if (ref.effectiveHumongous && ref.softlyReachable) {
+ System.out.println("soft and humongous");
+ softHumongousCheck.accept(ref);
+ }
+
+ if (ref.effectiveHumongous && !ref.softlyReachable) {
+ System.out.println("weak and humongous");
+ weakHumongousCheck.accept(ref);
+
+ }
+
+ if (!ref.effectiveHumongous && ref.softlyReachable) {
+ System.out.println("soft and non-humongous");
+ softSimpleCheck.accept(ref);
+ }
+
+ if (!ref.effectiveHumongous && !ref.softlyReachable) {
+ System.out.println("weak and non-humongous");
+ weakSimpleCheck.accept(ref);
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/g1/humongousObjects/objectGraphTest/GCTokens.java Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package gc.g1.humongousObjects.objectGraphTest;
+
+/**
+ * Contains tokens that could appear in gc log
+ */
+public final class GCTokens {
+ // Private c-tor to prevent instantiating
+ private GCTokens() {
+ }
+
+ public static final String WB_INITIATED_YOUNG_GC = "Young (WhiteBox Initiated Young GC)";
+ public static final String WB_INITIATED_MIXED_GC = "Pause Mixed (WhiteBox Initiated Young GC)";
+ public static final String WB_INITIATED_CMC = "WhiteBox Initiated Concurrent Mark";
+ public static final String FULL_GC = "Full (System.gc())";
+ public static final String FULL_GC_MEMORY_PRESSURE = "WhiteBox Initiated Full GC";
+ public static final String CMC = "Concurrent Mark)";
+ public static final String YOUNG_GC = "GC pause (young)";
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/g1/humongousObjects/objectGraphTest/ObjectGraph.java Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package gc.g1.humongousObjects.objectGraphTest;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+
+public class ObjectGraph {
+
+ private ObjectGraph() {
+ }
+
+ public enum ReferenceType {
+ NONE,
+ WEAK,
+ SOFT,
+ STRONG;
+ }
+
+ /**
+ * Performs operation on all nodes that are reachable from initial ones
+ *
+ * @param nodes initial nodes
+ * @param operation operation
+ */
+ public static void propagateTransitiveProperty(Set<Object[]> nodes, Consumer<Object[]> operation) {
+ Deque<Object[]> roots = new ArrayDeque<>();
+ nodes.stream().forEach(roots::push);
+ ObjectGraph.enumerateAndMark(roots, operation);
+ }
+
+ /**
+ * Connects graph's vertexes with single-directed (vertex -> neighbour) link
+ *
+ * @param vertex who is connected
+ * @param neighbour connected to whom
+ */
+ private static void connectVertexes(Object[] vertex, Object[] neighbour) {
+
+ // check if vertex array is full
+ if (vertex[vertex.length - 1] != null) {
+ throw new Error("Array is full and no connections could be added");
+ }
+ int i = 0;
+ while (vertex[i] != null) {
+ ++i;
+ }
+ vertex[i] = neighbour;
+ }
+
+
+ /**
+ * Builds object graph using description from list of parsed nodes. Graph uses Object[] as nodes, first n elements
+ * of array are links to connected nodes, others are null. Then runs visitors on generated graph
+ *
+ * @param parsedNodes list of nodes' description
+ * @param visitors visitors that will visit each node of generated graph
+ * @param humongousAllocationSize size of humongous node
+ * @param simpleAllocationSize size of simple (non-humongous) node
+ * @return root reference to generated graph
+ */
+ public static Object[] generateObjectNodes(List<TestcaseData.FinalParsedNode> parsedNodes,
+ Map<Predicate<TestcaseData.FinalParsedNode>,
+ BiConsumer<TestcaseData.FinalParsedNode, Object[][]>> visitors,
+ int humongousAllocationSize, int simpleAllocationSize) {
+
+ Object[][] objectNodes = new Object[parsedNodes.size()][];
+
+ // Allocating nodes on Object[]
+ for (int i = 0; i < parsedNodes.size(); ++i) {
+ objectNodes[i] = new Object[(parsedNodes.get(i).isHumongous ?
+ humongousAllocationSize : simpleAllocationSize)];
+ }
+
+ // Connecting nodes on allocated on Object[]
+ for (int i = 0; i < parsedNodes.size(); ++i) {
+ for (int j = 0; j < parsedNodes.get(i).getConnectedTo().size(); ++j) {
+ connectVertexes(objectNodes[i], objectNodes[parsedNodes.get(i).getConnectedTo().get(j)]);
+ }
+ }
+
+ // Calling visitors
+ visitors.entrySet()
+ .stream()
+ .forEach(
+ entry -> parsedNodes.stream()
+ .filter(parsedNode -> entry.getKey().test(parsedNode))
+ .forEach(node -> entry.getValue().accept(node, objectNodes))
+ );
+
+ return objectNodes[0];
+ }
+
+ /**
+ * Enumerates graph starting with provided vertexes. All vertexes that are reachable from the provided ones are
+ * marked
+ *
+ * @param markedParents provided vertexes
+ * @param markVertex lambda which marks vertexes
+ */
+ public static void enumerateAndMark(Deque<Object[]> markedParents,
+ Consumer<Object[]> markVertex) {
+ Map<Object[], Boolean> isVisited = new HashMap<>();
+ while (!markedParents.isEmpty()) {
+ Object[] vertex = markedParents.pop();
+ if (vertex == null || isVisited.containsKey(vertex)) {
+ continue;
+ }
+ isVisited.put(vertex, true);
+ markVertex.accept(vertex);
+
+ for (int i = 0; i < vertex.length; ++i) {
+ if (vertex[i] == null) {
+ break;
+ }
+ markedParents.add((Object[]) vertex[i]);
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/g1/humongousObjects/objectGraphTest/README Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+The test checks that after different type of GC unreachable objects behave as expected:
+
+1. Young GC - weakly referenced non-humongous objects are collected, other objects are not collected.
+
+2. Full GC - weakly referenced non-humongous and humongous objects are collected, softly referenced non-humongous and
+ humongous objects are not collected.
+
+3. Full GC with memory pressure - weakly and softly referenced non-humongous and humongous objects are collected.
+
+The test gets gc type as a command line argument.
+Then the test allocates object graph in heap (currently testing scenarios are pre-generated and stored in
+TestcaseData.getPregeneratedTestcases()) with TestObjectGraphAfterGC::allocateObjectGraph.
+
+Since we are testing humongous objects we need pretty unusual nodes - arrays of Object.
+We need this since only large enough array could be Humongous object (in fact class with huge amount of fields is
+humongous too but it's for other tests).
+ObjectGraph class generates object graph with Object[] nodes. It also provides a way to collect
+information about each node using "visitor" pattern.
+
+Using visitors we build Set of ReferenceInfo instances which contains the following information:
+reference - external weak/soft reference to graph's node
+graphId and nodeId - graph's and node's ids - we need this for error handling
+softlyReachable - is node effectively referenced by external soft reference. It could be when external
+soft reference or when this node is reachable from node that exteranally referenced by soft reference
+effectiveHumongous - if node behaves effectively humongous. It could be when node is humongous
+or when this node is reachable from humongous node.
+
+When we leave TestObjectGraphAfterGC::allocateObjectGraph we make graph reachable only with references from Set of
+ReferenceInfo instances.
+
+We run specified gc and check that each instance of ReferenceInfo set behaves as expected.
+Then we check that gc log file contains expected tokens and doesn't contain tokens that it should not contain.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/g1/humongousObjects/objectGraphTest/ReferenceInfo.java Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package gc.g1.humongousObjects.objectGraphTest;
+
+import java.lang.ref.Reference;
+
+/**
+ * Immutable structure that holds the following information about graph's node
+ * reference - weak/soft reference to graph's node
+ * graphId and nodeId - graph's and node's ids - we need this for error handling
+ * softlyReachable - is node effectively referenced by external soft reference. It could be when external
+ * soft reference or when this node is reachable from node that externally referenced by soft reference
+ * effectiveHumongous - if node behaves effectively humongous. It could be when node is humongous
+ * or when this node is reachable from humongous node.
+ *
+ * @param <T> - actual type of node
+ */
+public class ReferenceInfo<T> {
+ public final Reference<T> reference;
+ public final String graphId;
+ public final String nodeId;
+ public final boolean softlyReachable;
+ public final boolean effectiveHumongous;
+
+ public ReferenceInfo(Reference<T> reference, String graphId, String nodeId, boolean softlyReachable,
+ boolean effectiveHumongous) {
+ this.reference = reference;
+ this.graphId = graphId;
+ this.nodeId = nodeId;
+ this.softlyReachable = softlyReachable;
+ this.effectiveHumongous = effectiveHumongous;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("Node %s is effectively %shumongous and effectively %ssoft referenced\n"
+ + "\tReference type is %s and it points to %s", nodeId,
+ (effectiveHumongous ? "" : "non-"), (softlyReachable ? "" : "non-"),
+ reference.getClass().getSimpleName(), reference.get());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/g1/humongousObjects/objectGraphTest/TestObjectGraphAfterGC.java Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package gc.g1.humongousObjects.objectGraphTest;
+
+import jdk.test.lib.OutputAnalyzer;
+import sun.hotspot.WhiteBox;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
+import java.lang.ref.WeakReference;
+import java.nio.file.Files;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.List;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+
+/**
+ * @test TestObjectGraphAfterGC
+ * @summary Checks that objects' graph behave as expected after gc
+ * @requires vm.gc=="G1" | vm.gc=="null"
+ * @requires vm.opt.ExplicitGCInvokesConcurrent != true
+ * @library /testlibrary /test/lib /
+ * @modules java.management java.base/jdk.internal.misc
+ * @build sun.hotspot.WhiteBox
+ * gc.testlibrary.Helpers
+ * gc.g1.humongousObjects.objectGraphTest.GCTokens
+ * gc.g1.humongousObjects.objectGraphTest.ReferenceInfo
+ * gc.g1.humongousObjects.objectGraphTest.GC
+ * gc.g1.humongousObjects.objectGraphTest.ObjectGraph
+ * gc.g1.humongousObjects.objectGraphTest.TestObjectGraphAfterGC
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ *
+ * @run main/othervm -Xms200M -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
+ * -XX:G1HeapRegionSize=1M -Xlog:gc*=debug:file=TestObjectGraphAfterGC_YOUNG_GC.gc.log
+ * gc.g1.humongousObjects.objectGraphTest.TestObjectGraphAfterGC YOUNG_GC
+ *
+ * @run main/othervm -Xms200M -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
+ * -XX:G1HeapRegionSize=1M -Xlog:gc=info:file=TestObjectGraphAfterGC_FULL_GC.gc.log
+ * gc.g1.humongousObjects.objectGraphTest.TestObjectGraphAfterGC FULL_GC
+ *
+ * @run main/othervm -Xms200M -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
+ * -XX:G1HeapRegionSize=1M -Xlog:gc=info:file=TestObjectGraphAfterGC_FULL_GC_MEMORY_PRESSURE.gc.log
+ * gc.g1.humongousObjects.objectGraphTest.TestObjectGraphAfterGC FULL_GC_MEMORY_PRESSURE
+ *
+ */
+
+/**
+ * Checks that objects' graph behave as expected after gc
+ * See README file for detailed info on test's logic
+ */
+public class TestObjectGraphAfterGC {
+
+ private static final int simpleAllocationSize = 1024;
+
+ /**
+ * Entry point
+ *
+ * @param args - first argument - gc name
+ */
+ public static void main(String[] args) {
+
+ if (args.length < 1) {
+ throw new Error("Expected gc name wasn't provided as command line argument");
+ }
+
+ GC gcType = GC.valueOf(args[0].toUpperCase());
+
+ System.out.println("Testing " + gcType.name());
+
+ TestcaseData.getPregeneratedTestcases().stream().forEach(testcase -> {
+ System.out.println("Testcase: " + testcase);
+
+ try {
+ TestObjectGraphAfterGC.doTesting(testcase, gcType.get(), gcType.getChecker(),
+ gcType.getGcLogName(TestObjectGraphAfterGC.class.getSimpleName()), gcType.shouldContain(),
+ gcType.shouldNotContain());
+ } catch (IOException e) {
+ throw new Error("Problems trying to find or open " + TestObjectGraphAfterGC.class.getSimpleName()
+ + ".gc.log", e);
+ }
+ System.out.println(" Passed");
+ });
+ }
+
+ /**
+ * Implements testing with 3 methods - allocateObjectGraph, checkResults and checkGCLog
+ *
+ * @param testcaseData testcase in the following notation:
+ * H - humongous node
+ * S - non-humongous node
+ * s - external soft reference
+ * w - external weak reference
+ * Hs->Sw - 1st node is humongous, externally soft referenced and strong references to
+ * non-humongous node 2 which is externally weak referenced
+ * H->1 - humongous node connects to the first node of chain
+ * @param doGC method that initiates gc
+ * @param checker consumer that checks node's state after gc and throws Error if it's wrong
+ * @param gcLogName name of gc log
+ * @param shouldContain list of tokens that should be contained in gc log
+ * @param shouldNotContain list of tokens that should not be contained in gc log
+ * @throws IOException if there are some issues with gc log
+ */
+ private static void doTesting(String testcaseData, Runnable doGC, Consumer<ReferenceInfo<Object[]>> checker,
+ String gcLogName, List<String> shouldContain, List<String> shouldNotContain)
+ throws IOException {
+ Set<ReferenceInfo<Object[]>> nodeData = allocateObjectGraph(testcaseData);
+ doGC.run();
+ checkResults(nodeData, checker);
+ checkGCLog(gcLogName, shouldContain, shouldNotContain);
+ }
+
+ /**
+ * Allocates a number of objects of humongous and regular size and links then with strong references.
+ * How many objects to create, their size and links between them is encoded in the given parameters.
+ * As the result an object graph will be created.
+ * For the testing purpose for each created object (a graph node) an extra ReferenceInfo object will be created.
+ * The ReferenceInfo instances will contain either weak or soft reference to the graph node.
+ *
+ * @param testcaseData testcase in the
+ * <p>
+ * H - humongous node
+ * S - non-humongous node
+ * s - external soft reference
+ * w - external weak reference
+ * Hs->Sw - 1st node is humongous, externally soft referenced and strong references to
+ * non-humongous node 2 which is externally weak referenced
+ * H->1 - humongous node connects to the first node of chain
+ * @return set of ReferenceInfo objects containing weak/soft reference to the graph node and other data on how
+ * objects should behave after gc
+ */
+ private static Set<ReferenceInfo<Object[]>> allocateObjectGraph(String testcaseData) {
+ Map<Object[], String> nodeIds = new HashMap<>();
+ Set<Object[]> humongousNodes = new HashSet<>();
+ Set<Object[]> externalSoftReferenced = new HashSet<>();
+ Set<Object[]> externalWeakReferenced = new HashSet<>();
+
+ Map<Predicate<TestcaseData.FinalParsedNode>, BiConsumer<TestcaseData.FinalParsedNode, Object[][]>> visitors
+ = new HashMap<>();
+
+ visitors.put((parsedNode -> true),
+ (parsedNode, objects) -> nodeIds.put(objects[Integer.valueOf(parsedNode.id)], parsedNode.id)
+ );
+
+ visitors.put((parsedNode -> parsedNode.isHumongous),
+ (parsedNode, objects) -> humongousNodes.add(objects[Integer.valueOf(parsedNode.id)])
+ );
+
+ visitors.put(parsedNode -> parsedNode.getReferencesTypes().stream().
+ anyMatch(referenceType -> referenceType == ObjectGraph.ReferenceType.SOFT),
+ (parsedNode, objects) -> externalSoftReferenced.add(objects[Integer.valueOf(parsedNode.id)])
+ );
+
+ visitors.put(parsedNode -> parsedNode.getReferencesTypes().stream().
+ anyMatch(referenceType -> referenceType == ObjectGraph.ReferenceType.WEAK),
+ (parsedNode, objects) -> externalWeakReferenced.add(objects[Integer.valueOf(parsedNode.id)])
+ );
+
+ List<TestcaseData.FinalParsedNode> internalParsedNodes = TestcaseData.parse(testcaseData);
+
+ Object[] root = ObjectGraph.generateObjectNodes(internalParsedNodes, visitors,
+ WhiteBox.getWhiteBox().g1RegionSize(), simpleAllocationSize);
+
+ ObjectGraph.propagateTransitiveProperty(humongousNodes, humongousNodes::add);
+ Set<Object[]> effectiveSoftReferenced = new HashSet<>();
+ ObjectGraph.propagateTransitiveProperty(externalSoftReferenced, effectiveSoftReferenced::add);
+
+ // Create external references
+ ReferenceQueue<Object[]> referenceQueue = new ReferenceQueue<>();
+ Set<Reference<Object[]>> externalRefs = new HashSet<>();
+
+ externalWeakReferenced.stream()
+ .forEach(objects -> externalRefs.add(new WeakReference<>(objects, referenceQueue)));
+ externalSoftReferenced.stream()
+ .forEach(objects -> externalRefs.add(new SoftReference<>(objects, referenceQueue)));
+
+ return externalRefs.stream()
+ .map(ref -> new ReferenceInfo<>(ref, testcaseData, nodeIds.get(ref.get()),
+ effectiveSoftReferenced.contains(ref.get()), humongousNodes.contains(ref.get())))
+ .collect(Collectors.toSet());
+
+ }
+
+ /**
+ * Checks that object' state after gc is as expected
+ *
+ * @param nodeData array with information about nodes
+ * @param checker consumer that checks node's state after gc and throws Error if it's wrong
+ */
+ private static void checkResults(Set<ReferenceInfo<Object[]>> nodeData, Consumer<ReferenceInfo<Object[]>> checker) {
+ nodeData.stream().forEach(checker::accept);
+ }
+
+ /**
+ * Checks that gc log contains what we expected and does not contain what we didn't expect
+ *
+ * @param gcLogName gc log name
+ * @param shouldContain list of tokens that should be contained in gc log
+ * @param shouldNotContain list of tokens that should not be contained in gc log
+ * @throws IOException if there are some issues with gc log
+ */
+ private static void checkGCLog(String gcLogName, List<String> shouldContain, List<String> shouldNotContain)
+ throws IOException {
+
+ if (gcLogName == null) {
+ return;
+ }
+ String gcLog = new String(Files.readAllBytes(new File(gcLogName).toPath()));
+
+ OutputAnalyzer outputAnalyzer = new OutputAnalyzer(gcLog, "");
+
+ shouldContain.stream().forEach(outputAnalyzer::shouldContain);
+ shouldNotContain.stream().forEach(outputAnalyzer::shouldNotContain);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/g1/humongousObjects/objectGraphTest/TestcaseData.java Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package gc.g1.humongousObjects.objectGraphTest;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public final class TestcaseData {
+ /**
+ * Temporary node description used during parsing
+ */
+ private static class InternalParsedNode {
+ public String id;
+ public final ArrayList<Integer> connectedTo = new ArrayList<>();
+ public final ArrayList<Integer> connectedFrom = new ArrayList<>();
+ public final List<ObjectGraph.ReferenceType> referencesTypes = new ArrayList<>();
+ public boolean isHumongous;
+ }
+
+ /**
+ * Immutable node description.
+ * Contains:
+ * Node id
+ * Humongous flag
+ * List of external references' types
+ * List of nodes connected to
+ */
+ public static class FinalParsedNode {
+ public final String id;
+ public final boolean isHumongous;
+ private final List<ObjectGraph.ReferenceType> referencesTypes;
+ private final ArrayList<Integer> connectedTo;
+
+
+ public FinalParsedNode(InternalParsedNode internalParsedNode) {
+ referencesTypes = internalParsedNode.referencesTypes;
+ connectedTo = internalParsedNode.connectedTo;
+ id = internalParsedNode.id;
+ isHumongous = internalParsedNode.isHumongous;
+ }
+
+ public List<ObjectGraph.ReferenceType> getReferencesTypes() {
+ return Collections.unmodifiableList(referencesTypes);
+ }
+
+ public List<Integer> getConnectedTo() {
+ return Collections.unmodifiableList(connectedTo);
+ }
+ }
+
+ /**
+ * @param testcaseDesc testcase in the following notation:
+ * H - humongous node
+ * S - non-humongous node
+ * s - external soft reference
+ * w - external weak reference
+ * Hs->Sw - 1st node is humongous, externally soft referenced and strong references to non-humongous node 2 which is
+ * externally weak referenced
+ * H->1 - humongous node connects to the first node of chain
+ * @return list of nodes description in FinalParsedNode structure
+ */
+ public static List<FinalParsedNode> parse(String testcaseDesc) {
+ String[] nodes = testcaseDesc.split("-");
+ List<InternalParsedNode> internalParsedNodeList = new ArrayList<>();
+
+ for (int i = 0; i < nodes.length; ++i) {
+ String node = nodes[i];
+ InternalParsedNode nd;
+ if (node.contains("1")) {
+ nd = internalParsedNodeList.get(0);
+
+ } else {
+ nd = new InternalParsedNode();
+ internalParsedNodeList.add(nd);
+ nd.id = String.valueOf(i);
+ }
+
+ if (node.startsWith(">")) {
+ nd.connectedFrom.add(i - 1);
+ }
+ if (node.endsWith("<")) {
+ nd.connectedFrom.add(i + 1);
+ }
+ if (node.contains("w")) {
+ nd.referencesTypes.add(ObjectGraph.ReferenceType.WEAK);
+ }
+
+ if (node.contains("s")) {
+ nd.referencesTypes.add(ObjectGraph.ReferenceType.SOFT);
+ }
+ if (node.contains("H")) {
+ nd.isHumongous = true;
+ }
+
+ if (node.contains("S")) {
+ nd.isHumongous = false;
+ }
+ }
+
+ // we have connectedFrom but we need to get connectedTo
+ for (int i = 0; i < internalParsedNodeList.size(); ++i) {
+ for (Integer reference : internalParsedNodeList.get(i).connectedFrom) {
+ internalParsedNodeList.get(reference).connectedTo.add(i);
+ }
+ }
+
+ List<FinalParsedNode> finalParsedNodes = internalParsedNodeList.stream().map(FinalParsedNode::new)
+ .collect(Collectors.toList());
+
+ return finalParsedNodes;
+ }
+
+ /**
+ * @return List of pregenerated testing cases
+ */
+ public static List<String> getPregeneratedTestcases() {
+ return Arrays.asList(
+ "Hw",
+ "Sw",
+ "Sw->Hw",
+ "Hw->Sw",
+ "Sw<->Hw",
+ "Sw<->Sw",
+ "Hw->Sw->Sw",
+ "Hw->Sw->Sw",
+ "Sw->Hw->Sw",
+ "Hw->Sw->Sw->1",
+ "Sw->Hw->Sw->1",
+ "Sw->Hw->Hw->1",
+ "Sw<->Hw<->Hw->1",
+ "Sw<->Hw<->Sw->1",
+ "Sw->Hw<->Sw",
+ "Hs",
+ "Ss",
+ "Ss->Hs",
+ "Hs->Ss",
+ "Ss<->Hs",
+ "Ss<->Ss",
+ "Hs->Ss->Ss",
+ "Hs->Ss->Ss",
+ "Ss->Hs->Ss",
+ "Hs->Ss->Ss->1",
+ "Ss->Hs->Ss->1",
+ "Ss->Hs->Hs->1",
+ "Ss<->Hs<->Hs->1",
+ "Ss<->Hs<->Ss->1",
+ "Ss->Hs<->Ss",
+ "Ss->Hw",
+ "Sw->Hs",
+ "Hs->Sw",
+ "Hw->Ss",
+ "Ss<->Hw",
+ "Sw<->Hs",
+ "Ss<->Sw",
+ "Sw<->Ss",
+ "Hs->Sw->Sw",
+ "Hw->Ss->Sw",
+ "Hw->Sw->Ss",
+ "Ss->Hw->Sw",
+ "Sw->Hs->Sw",
+ "Sw->Hw->Ss",
+ "Hs->Sw->Sw->1",
+ "Hw->Ss->Sw->1",
+ "Hw->Sw->Ss->1",
+ "Ss->Hw->Sw->1",
+ "Ss->Hs->Sw->1",
+ "Sw->Hw->Ss->1",
+ "Ss->Hw->Hw->1",
+ "Sw->Hs->Hw->1",
+ "Sw->Hw->Hs->1",
+ "Ss<->Hw<->Hw->1",
+ "Sw<->Hs<->Hw->1",
+ "Sw<->Hw<->Hs->1",
+ "Ss<->Hw<->Sw->1",
+ "Sw<->Hs<->Sw->1",
+ "Sw<->Hw<->Ss->1",
+ "Ss->Hw<->Sw",
+ "Sw->Hs<->Sw",
+ "Sw->Hw<->Ss"
+ );
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/native/gtestLauncher.cpp Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "prims/jni.h"
+
+extern "C" {
+ JNIIMPORT void JNICALL runUnitTests(int argv, char** argc);
+}
+
+int main(int argc, char** argv) {
+ runUnitTests(argc, argv);
+ return 0;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/native/gtestMain.cpp Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#ifdef __APPLE__
+# include <dlfcn.h>
+#endif
+
+#include "prims/jni.h"
+#include "unittest.hpp"
+
+extern "C" {
+
+static int init_jvm(int argc, char **argv, bool is_executing_death_test) {
+ // don't care about the program name
+ argc--;
+ argv++;
+
+ int extra_jvm_args = is_executing_death_test ? 4 : 2;
+ int num_jvm_options = argc + extra_jvm_args;
+
+ JavaVMOption* options = new JavaVMOption[num_jvm_options];
+ options[0].optionString = (char*) "-Dsun.java.launcher.is_altjvm=true";
+ options[1].optionString = (char*) "-XX:+ExecutingUnitTests";
+
+ if (is_executing_death_test) {
+ // don't create core files or hs_err files when executing death tests
+ options[2].optionString = (char*) "-XX:+SuppressFatalErrorMessage";
+ options[3].optionString = (char*) "-XX:-CreateCoredumpOnCrash";
+ }
+
+ for (int i = 0; i < argc; i++) {
+ options[extra_jvm_args + i].optionString = argv[i];
+ }
+
+ JavaVMInitArgs args;
+ args.version = JNI_VERSION_1_8;
+ args.nOptions = num_jvm_options;
+ args.options = options;
+
+ JavaVM* jvm;
+ JNIEnv* env;
+
+ return JNI_CreateJavaVM(&jvm, (void**)&env, &args);
+}
+
+class JVMInitializerListener : public ::testing::EmptyTestEventListener {
+ private:
+ int _argc;
+ char** _argv;
+ bool _is_initialized;
+
+ void initialize_jvm() {
+ }
+
+ public:
+ JVMInitializerListener(int argc, char** argv) :
+ _argc(argc), _argv(argv), _is_initialized(false) {
+ }
+
+ virtual void OnTestStart(const ::testing::TestInfo& test_info) {
+ const char* name = test_info.name();
+ if (strstr(name, "_test_vm") != NULL && !_is_initialized) {
+ ASSERT_EQ(init_jvm(_argc, _argv, false), 0) << "Could not initialize the JVM";
+ _is_initialized = true;
+ }
+ }
+};
+
+static bool is_prefix(const char* prefix, const char* str) {
+ return strncmp(str, prefix, strlen(prefix)) == 0;
+}
+
+static char* get_java_home_arg(int argc, char** argv) {
+ for (int i = 0; i < argc; i++) {
+ if (strncmp(argv[i], "-jdk", strlen(argv[i])) == 0) {
+ return argv[i+1];
+ }
+ if (is_prefix("--jdk=", argv[i])) {
+ return argv[i] + strlen("--jdk=");
+ }
+ if (is_prefix("-jdk:", argv[i])) {
+ return argv[i] + strlen("-jdk:");
+ }
+ }
+ return NULL;
+}
+
+static int num_args_to_skip(char* arg) {
+ if (strcmp(arg, "-jdk") == 0) {
+ return 2; // skip the argument after -jdk as well
+ }
+ if (is_prefix("--jdk=", arg)) {
+ return 1;
+ }
+ if (is_prefix("-jdk:", arg)) {
+ return 1;
+ }
+ return 0;
+}
+
+static char** remove_test_runner_arguments(int* argcp, char **argv) {
+ int argc = *argcp;
+ char** new_argv = (char**) malloc(sizeof(char*) * argc);
+ int new_argc = 0;
+
+ int i = 0;
+ while (i < argc) {
+ int args_to_skip = num_args_to_skip(argv[i]);
+ if (args_to_skip == 0) {
+ new_argv[new_argc] = argv[i];
+ i++;
+ new_argc++;
+ } else {
+ i += num_args_to_skip(argv[i]);
+ }
+ }
+
+ *argcp = new_argc;
+ return new_argv;
+}
+
+JNIEXPORT void JNICALL runUnitTests(int argc, char** argv) {
+ // Must look at googletest options before initializing googletest, since
+ // InitGoogleTest removes googletest options from argv.
+ bool is_executing_death_test = true;
+ for (int i = 0; i < argc; i++) {
+ const char* death_test_flag = "--gtest_internal_run_death_test";
+ if (is_prefix(death_test_flag, argv[i])) {
+ is_executing_death_test = true;
+ }
+ }
+
+ ::testing::InitGoogleTest(&argc, argv);
+ ::testing::GTEST_FLAG(death_test_style) = "threadsafe";
+// ::testing::GTEST_FLAG(death_test_output_prefix) = "Other VM";
+
+ char* java_home = get_java_home_arg(argc, argv);
+ if (java_home == NULL) {
+ fprintf(stderr, "ERROR: You must specify a JDK to use for running the unit tests.\n");
+ exit(1);
+ }
+#ifndef _WIN32
+ int overwrite = 1; // overwrite an eventual existing value for JAVA_HOME
+ setenv("JAVA_HOME", java_home, overwrite);
+
+// workaround for JDK-7131356
+#ifdef __APPLE__
+ size_t len = strlen(java_home) + strlen("/lib/jli/libjli.dylib") + 1;
+ char* path = new char[len];
+ snprintf(path, len, "%s/lib/jli/libjli.dylib", java_home);
+ dlopen(path, RTLD_NOW | RTLD_GLOBAL);
+#endif // __APPLE__
+
+#else // _WIN32
+ char* java_home_var = "_ALT_JAVA_HOME_DIR";
+ size_t len = strlen(java_home) + strlen(java_home_var) + 2;
+ char * envString = new char[len];
+ sprintf_s(envString, len, "%s=%s", java_home_var, java_home);
+ _putenv(envString);
+#endif // _WIN32
+ argv = remove_test_runner_arguments(&argc, argv);
+
+ if (is_executing_death_test) {
+ if (init_jvm(argc, argv, true) != 0) {
+ abort();
+ }
+ } else {
+ ::testing::TestEventListeners& listeners = ::testing::UnitTest::GetInstance()->listeners();
+ listeners.Append(new JVMInitializerListener(argc, argv));
+ }
+
+ int result = RUN_ALL_TESTS();
+ if (result != 0) {
+ fprintf(stderr, "ERROR: RUN_ALL_TESTS() failed. Error %d\n", result);
+ exit(2);
+ }
+}
+
+} // extern "C"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/native/runtime/test_os.cpp Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "runtime/os.hpp"
+#include "unittest.hpp"
+
+TEST_VM(os, page_size_for_region) {
+ size_t large_page_example = 4 * M;
+ size_t large_page = os::page_size_for_region_aligned(large_page_example, 1);
+
+ size_t small_page = os::vm_page_size();
+ if (large_page > small_page) {
+ size_t num_small_in_large = large_page / small_page;
+ size_t page = os::page_size_for_region_aligned(large_page, num_small_in_large);
+ ASSERT_EQ(page, small_page) << "Did not get a small page";
+ }
+}
+
+#ifdef ASSERT
+TEST_VM_ASSERT_MSG(os, page_size_for_region_with_zero_min_pages, "sanity") {
+ size_t region_size = 16 * os::vm_page_size();
+ os::page_size_for_region_aligned(region_size, 0); // should assert
+}
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/native/unittest.hpp Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#define GTEST_DONT_DEFINE_TEST 1
+#include "gtest/gtest.h"
+#ifdef assert
+ #undef assert
+#endif
+
+#define CONCAT(a, b) a ## b
+
+#define TEST(category, name) GTEST_TEST(category, CONCAT(name, _test))
+
+#define TEST_VM(category, name) GTEST_TEST(category, CONCAT(name, _test_vm))
+
+#define TEST_VM_F(test_fixture, name) \
+ GTEST_TEST_(test_fixture, name ## _test_vm, test_fixture, \
+ ::testing::internal::GetTypeId<test_fixture>())
+
+#define TEST_OTHER_VM(category, name) \
+ static void test_ ## category ## _ ## name ## _(); \
+ \
+ static void child_ ## category ## _ ## name ## _() { \
+ ::testing::GTEST_FLAG(throw_on_failure) = true; \
+ test_ ## category ## _ ## name ## _(); \
+ fprintf(stderr, "OKIDOKI"); \
+ exit(0); \
+ } \
+ \
+ TEST(category, CONCAT(name, _other_vm)) { \
+ ASSERT_EXIT(child_ ## category ## _ ## name ## _(), \
+ ::testing::ExitedWithCode(0), \
+ ".*OKIDOKI.*"); \
+ } \
+ \
+ void test_ ## category ## _ ## name ## _()
+
+#ifdef ASSERT
+#define TEST_VM_ASSERT(category, name) \
+ static void test_ ## category ## _ ## name ## _(); \
+ \
+ static void child_ ## category ## _ ## name ## _() { \
+ ::testing::GTEST_FLAG(throw_on_failure) = true; \
+ test_ ## category ## _ ## name ## _(); \
+ exit(0); \
+ } \
+ \
+ TEST(category, CONCAT(name, _vm_assert)) { \
+ ASSERT_EXIT(child_ ## category ## _ ## name ## _(), \
+ ::testing::ExitedWithCode(1), \
+ "assert failed"); \
+ } \
+ \
+ void test_ ## category ## _ ## name ## _()
+#else
+#define TEST_VM_ASSERT(...) \
+ TEST_VM_ASSERT is only available in debug builds
+#endif
+
+#ifdef ASSERT
+#define TEST_VM_ASSERT_MSG(category, name, msg) \
+ static void test_ ## category ## _ ## name ## _(); \
+ \
+ static void child_ ## category ## _ ## name ## _() { \
+ ::testing::GTEST_FLAG(throw_on_failure) = true; \
+ test_ ## category ## _ ## name ## _(); \
+ exit(0); \
+ } \
+ \
+ TEST(category, CONCAT(name, _vm_assert)) { \
+ ASSERT_EXIT(child_ ## category ## _ ## name ## _(), \
+ ::testing::ExitedWithCode(1), \
+ "assert failed: " msg); \
+ } \
+ \
+ void test_ ## category ## _ ## name ## _()
+#else
+#define TEST_VM_ASSERT_MSG(...) \
+ TEST_VM_ASSERT_MSG is only available in debug builds
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/native/utilities/test_quicksort.cpp Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "prims/jvm.h"
+#include "utilities/quickSort.hpp"
+#include "unittest.hpp"
+
+static int int_comparator(int a, int b) {
+ if (a == b) {
+ return 0;
+ } else if (a < b) {
+ return -1;
+ }
+
+ // a > b
+ return 1;
+}
+
+TEST(utilities, quicksort) {
+ int test_array[] = {3,2,1};
+ QuickSort::sort(test_array, 3, int_comparator, false);
+
+ ASSERT_EQ(1, test_array[0]);
+ ASSERT_EQ(2, test_array[1]);
+ ASSERT_EQ(3, test_array[2]);
+}
--- a/hotspot/test/runtime/BadObjectClass/BootstrapRedefine.java Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/runtime/BadObjectClass/BootstrapRedefine.java Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -48,7 +48,7 @@
"-Xmodule:java.base"),
"mods/java.base");
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:mods", "-version");
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.base=mods/java.base", "-version");
new OutputAnalyzer(pb.start())
.shouldContain("Incompatible definition of java.lang.Object")
.shouldHaveExitValue(1);
--- a/hotspot/test/runtime/getSysPackage/GetSysPkgTest.java Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/runtime/getSysPackage/GetSysPkgTest.java Wed May 11 00:38:58 2016 +0300
@@ -120,9 +120,9 @@
getPkg("java/nio/charset", "jrt:/java.base");
// Test a package in a module not owned by boot loader.
- Class clss = Class.forName("javax.activation.DataHandler");
+ Class clss = Class.forName("jdk.nio.zipfs.ZipPath");
if (clss == null)
- throw new RuntimeException("Could not find class javax.activation.DataHandler");
+ throw new RuntimeException("Could not find class jdk.nio.zipfs.ZipPath");
getPkg("javax/activation", null); // Not owned by boot loader
// Test a package not in jimage file.
--- a/hotspot/test/runtime/modules/AccessCheck/DiffCL_Umod.java Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/runtime/modules/AccessCheck/DiffCL_Umod.java Wed May 11 00:38:58 2016 +0300
@@ -210,9 +210,9 @@
// now use the same loader to load class p1.c1Loose
Class p1_c1_class = MyDiffClassLoader.loader1.loadClass("p1.c1Loose");
- // change m1 to be a loose module
+ // change m1 to read all unnamed modules
Module m1 = layer.findModule("m1").get();
- jdk.internal.module.Modules.addReads(m1, null);
+ jdk.internal.module.Modules.addReadsAllUnnamed(m1);
try {
p1_c1_class.newInstance();
--- a/hotspot/test/runtime/modules/AccessCheck/Umod.java Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/runtime/modules/AccessCheck/Umod.java Wed May 11 00:38:58 2016 +0300
@@ -201,9 +201,9 @@
// now use the same loader to load class p1.c1Loose
Class p1_c1_class = loader.loadClass("p1.c1Loose");
- // change m1 to be a loose module
+ // change m1 to read all unnamed modules
Module m1 = layer.findModule("m1").get();
- jdk.internal.module.Modules.addReads(m1, null);
+ jdk.internal.module.Modules.addReadsAllUnnamed(m1);
try {
p1_c1_class.newInstance();
--- a/hotspot/test/runtime/modules/JVMAddReadsModule.java Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/runtime/modules/JVMAddReadsModule.java Wed May 11 00:38:58 2016 +0300
@@ -49,26 +49,27 @@
assertNotNull(to_module, "Module should not be null");
ModuleHelper.DefineModule(to_module, "9.0", "to_module/here", new String[] { "yourpackage" });
- // Null from_module argument, expect an NPE
+ // Null from_module argument, expect NPE
try {
ModuleHelper.AddReadsModule(null, to_module);
throw new RuntimeException("Failed to get the expected NPE");
- } catch(NullPointerException e) {
+ } catch (NullPointerException e) {
// Expected
}
- // Null to_module argument, do not expect an NPE
+ // Null to_module argument, expect NPE
try {
ModuleHelper.AddReadsModule(from_module, null);
- } catch(NullPointerException e) {
throw new RuntimeException("Unexpected NPE was thrown");
+ } catch (NullPointerException e) {
+ // Expected
}
- // Null from_module and to_module arguments, expect an NPE
+ // Null from_module and to_module arguments, expect NPE
try {
ModuleHelper.AddReadsModule(null, null);
throw new RuntimeException("Failed to get the expected NPE");
- } catch(NullPointerException e) {
+ } catch (NullPointerException e) {
// Expected
}
--- a/hotspot/test/runtime/modules/Visibility/XpatchVisibility.java Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/runtime/modules/Visibility/XpatchVisibility.java Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -83,7 +83,7 @@
"p2" + File.separator + "Vis2_B.class"));
new OutputAnalyzer(ProcessTools.createJavaProcessBuilder(
- "-Xpatch:mods2",
+ "-Xpatch:java.base=mods2/java.base",
"-XaddExports:java.base/p2=ALL-UNNAMED",
"Vis2_A")
.start()).shouldHaveExitValue(0);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/Xpatch/BasicJarBuilder.java Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+/*
+ * @summary Simple jar builder
+ * Input: jarName className1 className2 ...
+ * do not specify extensions, just the names
+ * E.g. prot_domain ProtDomainA ProtDomainB
+ * Output: A jar containing compiled classes, placed in a test classes folder
+ */
+
+import jdk.test.lib.*;
+
+import java.io.File;
+import java.util.ArrayList;
+import sun.tools.jar.Main;
+
+// Using JarBuilder requires that all to-be-jarred classes should be placed
+// in the current working directory, aka "."
+public class BasicJarBuilder {
+ private static final String classDir = System.getProperty("test.classes");
+
+ public static void build(boolean classesInWorkDir, String jarName,
+ String ...classNames) throws Exception {
+
+ if (classesInWorkDir) {
+ createSimpleJar(".", classDir + File.separator + jarName + ".jar", classNames);
+ } else {
+ build(jarName, classNames);
+ }
+ }
+
+ public static void build(String jarName, String ...classNames) throws Exception {
+ createSimpleJar(classDir, classDir + File.separator + jarName + ".jar",
+ classNames);
+ }
+
+ private static void createSimpleJar(String jarclassDir, String jarName,
+ String[] classNames) throws Exception {
+ ArrayList<String> args = new ArrayList<String>();
+ args.add("cf");
+ args.add(jarName);
+ addClassArgs(args, jarclassDir, classNames);
+ createJar(args);
+ }
+
+ private static void addClassArgs(ArrayList<String> args, String jarclassDir,
+ String[] classNames) {
+
+ for (String name : classNames) {
+ args.add("-C");
+ args.add(jarclassDir);
+ args.add(name + ".class");
+ }
+ }
+
+ private static void createJar(ArrayList<String> args) {
+ Main jarTool = new Main(System.out, System.err, "jar");
+ if (!jarTool.run(args.toArray(new String[1]))) {
+ throw new RuntimeException("jar operation failed");
+ }
+ }
+
+ // Get full path to the test jar
+ public static String getTestJar(String jar) {
+ File dir = new File(System.getProperty("test.classes", "."));
+ File jarFile = new File(dir, jar);
+ if (!jarFile.exists()) {
+ throw new RuntimeException("Cannot find " + jarFile.getPath());
+ }
+ if (!jarFile.isFile()) {
+ throw new RuntimeException("Not a regular file: " + jarFile.getPath());
+ }
+ return jarFile.getPath();
+ }
+}
--- a/hotspot/test/runtime/modules/Xpatch/Xpatch2Dirs.java Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/runtime/modules/Xpatch/Xpatch2Dirs.java Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -58,7 +58,8 @@
"mods2/java.desktop");
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
- "-Xpatch:mods" + File.pathSeparator + "mods2",
+ "-Xpatch:java.naming=mods/java.naming",
+ "-Xpatch:java.desktop=mods2/java.desktop",
"Xpatch2DirsMain", "javax.naming.spi.NamingManager", "java.beans.Encoder");
OutputAnalyzer oa = new OutputAnalyzer(pb.start());
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/Xpatch/XpatchDupJavaBase.java Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary VM exit initialization results if java.base is specificed more than once to Xpatch.
+ * @library /testlibrary
+ */
+
+import jdk.test.lib.*;
+
+public class XpatchDupJavaBase {
+ // The VM should exit initialization if java.base is specified
+ // more than once to -Xpatch.
+ public static void main(String args[]) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-Xpatch:java.base=javabase_dir",
+ "-Xpatch:java.base=javabase_dir",
+ "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Cannot specify java.base more than once to -Xpatch");
+ output.shouldHaveExitValue(1);
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/Xpatch/XpatchDupModule.java Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Module system initialization exception results if a module is specificed twice to Xpatch.
+ * @library /testlibrary
+ */
+
+import jdk.test.lib.*;
+
+public class XpatchDupModule {
+
+ // The module system initialization should generate an ExceptionInInitializerError
+ // if -Xpatch is specified with the same module more than once.
+
+ public static void main(String args[]) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-Xpatch:module1=module1_dir",
+ "-Xpatch:module1=module1_dir",
+ "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("java.lang.ExceptionInInitializerError");
+ output.shouldHaveExitValue(1);
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/Xpatch/XpatchJavaBase.java Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8130399
+ * @summary Make sure -Xpatch works for java.base.
+ * @library /testlibrary
+ * @compile XpatchMain.java
+ * @run main XpatchJavaBase
+ */
+
+import jdk.test.lib.*;
+
+public class XpatchJavaBase {
+
+ public static void main(String[] args) throws Exception {
+ String source = "package java.lang; " +
+ "public class NewClass { " +
+ " static { " +
+ " System.out.println(\"I pass!\"); " +
+ " } " +
+ "}";
+
+ ClassFileInstaller.writeClassToDisk("java/lang/NewClass",
+ InMemoryJavaCompiler.compile("java.lang.NewClass", source, "-Xmodule:java.base"),
+ "mods/java.base");
+
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.base=mods/java.base",
+ "XpatchMain", "java.lang.NewClass");
+
+ new OutputAnalyzer(pb.start())
+ .shouldContain("I pass!")
+ .shouldHaveExitValue(0);
+ }
+}
--- a/hotspot/test/runtime/modules/Xpatch/XpatchTest.java Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/runtime/modules/Xpatch/XpatchTest.java Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -47,7 +47,7 @@
InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"),
"mods/java.naming");
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:mods",
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.naming=mods/java.naming",
"XpatchMain", "javax.naming.spi.NamingManager");
new OutputAnalyzer(pb.start())
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/Xpatch/XpatchTestJar.java Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Make sure -Xpatch works when a jar file is specified for a module
+ * @library /testlibrary
+ * @modules java.base/jdk.internal.misc
+ * jdk.jartool/sun.tools.jar
+ * @build BasicJarBuilder
+ * @compile XpatchMain.java
+ * @run main XpatchTestJar
+ */
+
+import jdk.test.lib.*;
+
+public class XpatchTestJar {
+ private static String moduleJar;
+
+ public static void main(String[] args) throws Exception {
+
+ // Create a class file in the module java.naming. This class file
+ // will be put in the javanaming.jar file.
+ String source = "package javax.naming.spi; " +
+ "public class NamingManager { " +
+ " static { " +
+ " System.out.println(\"I pass!\"); " +
+ " } " +
+ "}";
+
+ ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
+ InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"),
+ System.getProperty("test.classes"));
+
+ // Build the jar file that will be used for the module "java.naming".
+ BasicJarBuilder.build("javanaming", "javax/naming/spi/NamingManager");
+ moduleJar = BasicJarBuilder.getTestJar("javanaming.jar");
+
+ // Just to make sure we are not fooled by the class file being on the
+ // class path where all the test classes are stored, write the NamingManager.class
+ // file out again with output that does not contain what OutputAnalyzer
+ // expects. This will provide confidence that the contents of the class
+ // is truly coming from the jar file and not the class file.
+ source = "package javax.naming.spi; " +
+ "public class NamingManager { " +
+ " static { " +
+ " System.out.println(\"Fail!\"); " +
+ " } " +
+ "}";
+
+ ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
+ InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"),
+ System.getProperty("test.classes"));
+
+ // Supply -Xpatch with the name of the jar file for the module java.naming.
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.naming=" + moduleJar,
+ "XpatchMain", "javax.naming.spi.NamingManager");
+
+ new OutputAnalyzer(pb.start())
+ .shouldContain("I pass!")
+ .shouldHaveExitValue(0);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/Xpatch/XpatchTestJarDir.java Wed May 11 00:38:58 2016 +0300
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Make sure -Xpatch works when a jar file and a directory is specified for a module
+ * @library /testlibrary
+ * @modules java.base/jdk.internal.misc
+ * jdk.jartool/sun.tools.jar
+ * @build BasicJarBuilder
+ * @compile Xpatch2DirsMain.java
+ * @run main XpatchTestJarDir
+ */
+
+import java.io.File;
+import java.nio.file.Files;
+import jdk.test.lib.*;
+
+public class XpatchTestJarDir {
+ private static String moduleJar;
+
+ public static void main(String[] args) throws Exception {
+
+ // Create a class file in the module java.naming. This class file
+ // will be put in the javanaming.jar file.
+ String source = "package javax.naming.spi; " +
+ "public class NamingManager1 { " +
+ " static { " +
+ " System.out.println(\"I pass one!\"); " +
+ " } " +
+ "}";
+
+ ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager1",
+ InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager1", source, "-Xmodule:java.naming"),
+ System.getProperty("test.classes"));
+
+ // Build the jar file that will be used for the module "java.naming".
+ BasicJarBuilder.build("javanaming", "javax/naming/spi/NamingManager1");
+ moduleJar = BasicJarBuilder.getTestJar("javanaming.jar");
+
+ // Just to make sure we are not fooled by the class file being on the
+ // class path where all the test classes are stored, write the NamingManager.class
+ // file out again with output that does not contain what OutputAnalyzer
+ // expects. This will provide confidence that the contents of the class
+ // is truly coming from the jar file and not the class file.
+ source = "package javax.naming.spi; " +
+ "public class NamingManager1 { " +
+ " static { " +
+ " System.out.println(\"Fail!\"); " +
+ " } " +
+ "}";
+
+ ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager1",
+ InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager1", source, "-Xmodule:java.naming"),
+ System.getProperty("test.classes"));
+
+ // Create a second class file in the module java.naming. This class file
+ // will be put in the mods/java.naming directory.
+ source = "package javax.naming.spi; " +
+ "public class NamingManager2 { " +
+ " static { " +
+ " System.out.println(\"I pass two!\"); " +
+ " } " +
+ "}";
+
+ ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager2",
+ InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager2", source, "-Xmodule:java.naming"),
+ (System.getProperty("test.classes") + "/mods/java.naming"));
+
+
+ // Supply -Xpatch with the name of the jar file for the module java.naming.
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.naming=" +
+ moduleJar +
+ File.pathSeparator +
+ System.getProperty("test.classes") + "/mods/java.naming",
+ "Xpatch2DirsMain",
+ "javax.naming.spi.NamingManager1",
+ "javax.naming.spi.NamingManager2");
+
+ new OutputAnalyzer(pb.start())
+ .shouldContain("I pass one!")
+ .shouldContain("I pass two!")
+ .shouldHaveExitValue(0);
+ }
+}
--- a/hotspot/test/runtime/modules/Xpatch/XpatchTraceCL.java Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/runtime/modules/Xpatch/XpatchTraceCL.java Wed May 11 00:38:58 2016 +0300
@@ -24,7 +24,7 @@
/*
* @test
* @bug 8069469
- * @summary Make sure -XX:+TraceClassLoading works properly with "modules" jimage,
+ * @summary Make sure -Xlog:classload=info works properly with "modules" jimage,
-Xpatch, and with -Xbootclasspath/a
* @modules java.base/jdk.internal.misc
* @library /testlibrary
@@ -45,24 +45,23 @@
" } " +
"}";
- // Test -XX:+TraceClassLoading output for -Xpatch
+ // Test -Xlog:classload=info output for -Xpatch
ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"),
"mods/java.naming");
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:mods",
- "-XX:+TraceClassLoading", "XpatchMain", "javax.naming.spi.NamingManager");
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.naming=mods/java.naming",
+ "-Xlog:class+load=info", "XpatchMain", "javax.naming.spi.NamingManager");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
// "modules" jimage case.
output.shouldContain("[class,load] java.lang.Thread source: jrt:/java.base");
// -Xpatch case.
- output.shouldContain("[class,load] javax.naming.spi.NamingManager source: mods" +
- File.separator + "java.naming");
+ output.shouldContain("[class,load] javax.naming.spi.NamingManager source: mods/java.naming");
// -cp case.
output.shouldContain("[class,load] XpatchMain source: file");
- // Test -XX:+TraceClassLoading output for -Xbootclasspath/a
+ // Test -Xlog:classload=info output for -Xbootclasspath/a
source = "package XpatchTraceCL_pkg; " +
"public class ItIsI { " +
" static { " +
@@ -75,7 +74,7 @@
"xbcp");
pb = ProcessTools.createJavaProcessBuilder("-Xbootclasspath/a:xbcp",
- "-XX:+TraceClassLoading", "XpatchMain", "XpatchTraceCL_pkg.ItIsI");
+ "-Xlog:class+load=info", "XpatchMain", "XpatchTraceCL_pkg.ItIsI");
output = new OutputAnalyzer(pb.start());
// -Xbootclasspath/a case.
output.shouldContain("[class,load] XpatchTraceCL_pkg.ItIsI source: xbcp");
--- a/hotspot/test/runtime/modules/XpatchCDS.java Tue May 10 12:18:22 2016 +0200
+++ b/hotspot/test/runtime/modules/XpatchCDS.java Wed May 11 00:38:58 2016 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -35,7 +35,7 @@
public static void main(String args[]) throws Throwable {
System.out.println("Test that -Xpatch and -Xshare:dump are incompatibable");
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:.", "-Xshare:dump");
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.naming=mods/java.naming", "-Xshare:dump");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("Cannot use the following option when dumping the shared archive: -Xpatch");
@@ -52,7 +52,7 @@
"-XX:+UnlockDiagnosticVMOptions",
"-XX:SharedArchiveFile=" + filename,
"-Xshare:on",
- "-Xpatch:.",
+ "-Xpatch:java.naming=mods/java.naming",
"-version");
output = new OutputAnalyzer(pb.start());
output.shouldContain("The shared archive file cannot be used with -Xpatch");