--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -49,19 +49,13 @@
Type type = db.lookupType("Method");
constMethod = type.getAddressField("_constMethod");
methodData = type.getAddressField("_method_data");
+ methodCounters = type.getAddressField("_method_counters");
methodSize = new CIntField(type.getCIntegerField("_method_size"), 0);
accessFlags = new CIntField(type.getCIntegerField("_access_flags"), 0);
code = type.getAddressField("_code");
vtableIndex = new CIntField(type.getCIntegerField("_vtable_index"), 0);
- if (!VM.getVM().isCore()) {
- invocationCounter = new CIntField(type.getCIntegerField("_invocation_counter"), 0);
- backedgeCounter = new CIntField(type.getCIntegerField("_backedge_counter"), 0);
- }
bytecodeOffset = type.getSize();
- interpreterThrowoutCountField = new CIntField(type.getCIntegerField("_interpreter_throwout_count"), 0);
- interpreterInvocationCountField = new CIntField(type.getCIntegerField("_interpreter_invocation_count"), 0);
-
/*
interpreterEntry = type.getAddressField("_interpreter_entry");
fromCompiledCodeEntryPoint = type.getAddressField("_from_compiled_code_entry_point");
@@ -80,18 +74,14 @@
// Fields
private static AddressField constMethod;
private static AddressField methodData;
+ private static AddressField methodCounters;
private static CIntField methodSize;
private static CIntField accessFlags;
private static CIntField vtableIndex;
- private static CIntField invocationCounter;
- private static CIntField backedgeCounter;
private static long bytecodeOffset;
private static AddressField code;
- private static CIntField interpreterThrowoutCountField;
- private static CIntField interpreterInvocationCountField;
-
// constant method names - <init>, <clinit>
// Initialized lazily to avoid initialization ordering dependencies between Method and SymbolTable
private static Symbol objectInitializerName;
@@ -127,6 +117,10 @@
Address addr = methodData.getValue(getAddress());
return (MethodData) VMObjectFactory.newObject(MethodData.class, addr);
}
+ public MethodCounters getMethodCounters() {
+ Address addr = methodCounters.getValue(getAddress());
+ return (MethodCounters) VMObjectFactory.newObject(MethodCounters.class, addr);
+ }
/** WARNING: this is in words, not useful in this system; use getObjectSize() instead */
public long getMethodSize() { return methodSize.getValue(this); }
public long getMaxStack() { return getConstMethod().getMaxStack(); }
@@ -139,16 +133,10 @@
public long getCodeSize() { return getConstMethod().getCodeSize(); }
public long getVtableIndex() { return vtableIndex.getValue(this); }
public long getInvocationCounter() {
- if (Assert.ASSERTS_ENABLED) {
- Assert.that(!VM.getVM().isCore(), "must not be used in core build");
- }
- return invocationCounter.getValue(this);
+ return getMethodCounters().getInvocationCounter();
}
public long getBackedgeCounter() {
- if (Assert.ASSERTS_ENABLED) {
- Assert.that(!VM.getVM().isCore(), "must not be used in core build");
- }
- return backedgeCounter.getValue(this);
+ return getMethodCounters().getBackedgeCounter();
}
// get associated compiled native method, if available, else return null.
@@ -369,10 +357,10 @@
}
public int interpreterThrowoutCount() {
- return (int) interpreterThrowoutCountField.getValue(this);
+ return getMethodCounters().interpreterThrowoutCount();
}
public int interpreterInvocationCount() {
- return (int) interpreterInvocationCountField.getValue(this);
+ return getMethodCounters().interpreterInvocationCount();
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodCounters.java Fri Apr 19 09:58:05 2013 -0700
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ */
+
+package sun.jvm.hotspot.oops;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+public class MethodCounters extends Metadata {
+ public MethodCounters(Address addr) {
+ super(addr);
+ }
+
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("MethodCounters");
+
+ interpreterInvocationCountField = new CIntField(type.getCIntegerField("_interpreter_invocation_count"), 0);
+ interpreterThrowoutCountField = new CIntField(type.getCIntegerField("_interpreter_throwout_count"), 0);
+ if (!VM.getVM().isCore()) {
+ invocationCounter = new CIntField(type.getCIntegerField("_invocation_counter"), 0);
+ backedgeCounter = new CIntField(type.getCIntegerField("_backedge_counter"), 0);
+ }
+ }
+
+ private static CIntField interpreterInvocationCountField;
+ private static CIntField interpreterThrowoutCountField;
+ private static CIntField invocationCounter;
+ private static CIntField backedgeCounter;
+
+ public int interpreterInvocationCount() {
+ return (int) interpreterInvocationCountField.getValue(this);
+ }
+
+ public int interpreterThrowoutCount() {
+ return (int) interpreterThrowoutCountField.getValue(this);
+ }
+ public long getInvocationCounter() {
+ if (Assert.ASSERTS_ENABLED) {
+ Assert.that(!VM.getVM().isCore(), "must not be used in core build");
+ }
+ return invocationCounter.getValue(this);
+ }
+ public long getBackedgeCounter() {
+ if (Assert.ASSERTS_ENABLED) {
+ Assert.that(!VM.getVM().isCore(), "must not be used in core build");
+ }
+ return backedgeCounter.getValue(this);
+ }
+
+ public void printValueOn(PrintStream tty) {
+ }
+}
+
--- a/hotspot/make/Makefile Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/Makefile Fri Apr 19 09:58:05 2013 -0700
@@ -19,7 +19,7 @@
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
-#
+#
#
# Top level gnumake file for hotspot builds
@@ -85,15 +85,15 @@
endif
# Typical C1/C2 targets made available with this Makefile
-C1_VM_TARGETS=product1 fastdebug1 optimized1 jvmg1
-C2_VM_TARGETS=product fastdebug optimized jvmg
-ZERO_VM_TARGETS=productzero fastdebugzero optimizedzero jvmgzero
-SHARK_VM_TARGETS=productshark fastdebugshark optimizedshark jvmgshark
-MINIMAL1_VM_TARGETS=productminimal1 fastdebugminimal1 jvmgminimal1
+C1_VM_TARGETS=product1 fastdebug1 optimized1 debug1
+C2_VM_TARGETS=product fastdebug optimized debug
+ZERO_VM_TARGETS=productzero fastdebugzero optimizedzero debugzero
+SHARK_VM_TARGETS=productshark fastdebugshark optimizedshark debugshark
+MINIMAL1_VM_TARGETS=productminimal1 fastdebugminimal1 debugminimal1
COMMON_VM_PRODUCT_TARGETS=product product1 docs export_product
COMMON_VM_FASTDEBUG_TARGETS=fastdebug fastdebug1 docs export_fastdebug
-COMMON_VM_DEBUG_TARGETS=jvmg jvmg1 docs export_debug
+COMMON_VM_DEBUG_TARGETS=debug debug1 docs export_debug
# JDK directory list
JDK_DIRS=bin include jre lib demo
@@ -103,13 +103,13 @@
ifeq ($(JVM_VARIANT_MINIMAL1),true)
all_product: productminimal1
all_fastdebug: fastdebugminimal1
-all_debug: jvmgminimal1
+all_debug: debugminimal1
endif
ifdef BUILD_CLIENT_ONLY
all_product: product1 docs export_product
all_fastdebug: fastdebug1 docs export_fastdebug
-all_debug: jvmg1 docs export_debug
+all_debug: debug1 docs export_debug
else
ifeq ($(MACOSX_UNIVERSAL),true)
all_product: universal_product
@@ -127,13 +127,13 @@
allzero: all_productzero all_fastdebugzero
all_productzero: productzero docs export_product
all_fastdebugzero: fastdebugzero docs export_fastdebug
-all_debugzero: jvmgzero docs export_debug
+all_debugzero: debugzero docs export_debug
all_optimizedzero: optimizedzero docs export_optimized
allshark: all_productshark all_fastdebugshark
all_productshark: productshark docs export_product
all_fastdebugshark: fastdebugshark docs export_fastdebug
-all_debugshark: jvmgshark docs export_debug
+all_debugshark: debugshark docs export_debug
all_optimizedshark: optimizedshark docs export_optimized
# Do everything
@@ -227,7 +227,7 @@
$(MKDIR) -p $(OUTPUTDIR)
$(CD) $(OUTPUTDIR); \
$(MAKE) -f $(ABS_OS_MAKEFILE) \
- $(MAKE_ARGS) $(VM_TARGET)
+ $(MAKE_ARGS) $(VM_TARGET)
generic_buildminimal1:
ifeq ($(JVM_VARIANT_MINIMAL1),true)
@@ -260,7 +260,7 @@
EXPORT_SUBDIR=/$(@:export_%=%) \
generic_export
export_debug:
- $(MAKE) BUILD_FLAVOR=$(@:export_%=%) VM_SUBDIR=${VM_DEBUG} \
+ $(MAKE) BUILD_FLAVOR=$(@:export_%=%) VM_SUBDIR=$(@:export_%=%) \
EXPORT_SUBDIR=/$(@:export_%=%) \
generic_export
export_optimized:
@@ -281,192 +281,197 @@
ALT_EXPORT_PATH=$(JDK_IMAGE_DIR)/$(@:export_%_jdk=%) \
generic_export
export_debug_jdk::
- $(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) VM_SUBDIR=${VM_DEBUG} \
+ $(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) VM_SUBDIR=$(@:export_%_jdk=%) \
ALT_EXPORT_PATH=$(JDK_IMAGE_DIR)/$(@:export_%_jdk=%) \
generic_export
# Export file copy rules
XUSAGE=$(HS_SRC_DIR)/share/vm/Xusage.txt
-DOCS_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_docs
-C1_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_compiler1
-C2_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_compiler2
-ZERO_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_zero
-SHARK_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_shark
-C1_DIR=$(C1_BASE_DIR)/$(VM_SUBDIR)
-C2_DIR=$(C2_BASE_DIR)/$(VM_SUBDIR)
-ZERO_DIR=$(ZERO_BASE_DIR)/$(VM_SUBDIR)
-SHARK_DIR=$(SHARK_BASE_DIR)/$(VM_SUBDIR)
-MINIMAL1_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_minimal1
-MINIMAL1_DIR=$(MINIMAL1_BASE_DIR)/$(VM_SUBDIR)
-
-ifeq ($(JVM_VARIANT_SERVER), true)
- MISC_DIR=$(C2_DIR)
- GEN_DIR=$(C2_BASE_DIR)/generated
-endif
-ifeq ($(JVM_VARIANT_CLIENT), true)
- MISC_DIR=$(C1_DIR)
- GEN_DIR=$(C1_BASE_DIR)/generated
-endif
-ifeq ($(JVM_VARIANT_ZEROSHARK), true)
- MISC_DIR=$(SHARK_DIR)
- GEN_DIR=$(SHARK_BASE_DIR)/generated
-endif
-ifeq ($(JVM_VARIANT_ZERO), true)
- MISC_DIR=$(ZERO_DIR)
- GEN_DIR=$(ZERO_BASE_DIR)/generated
-endif
-ifeq ($(JVM_VARIANT_MINIMAL1), true)
- MISC_DIR=$(MINIMAL1_DIR)
- GEN_DIR=$(MINIMAL1_BASE_DIR)/generated
-endif
+DOCS_DIR =$(OUTPUTDIR)/$(VM_PLATFORM)_docs
+C1_DIR =$(OUTPUTDIR)/$(VM_PLATFORM)_compiler1/$(VM_SUBDIR)
+C2_DIR =$(OUTPUTDIR)/$(VM_PLATFORM)_compiler2/$(VM_SUBDIR)
+MINIMAL1_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_minimal1/$(VM_SUBDIR)
+ZERO_DIR =$(OUTPUTDIR)/$(VM_PLATFORM)_zero/$(VM_SUBDIR)
+SHARK_DIR =$(OUTPUTDIR)/$(VM_PLATFORM)_shark/$(VM_SUBDIR)
-# Bin files (windows)
-ifeq ($(OSNAME),windows)
-
-# Get jvm.lib
-$(EXPORT_LIB_DIR)/%.lib: $(MISC_DIR)/%.lib
+# Server (C2)
+ifeq ($(JVM_VARIANT_SERVER), true)
+# Common
+$(EXPORT_SERVER_DIR)/%.diz: $(C2_DIR)/%.diz
+ $(install-file)
+$(EXPORT_LIB_DIR)/%.jar: $(C2_DIR)/../generated/%.jar
+ $(install-file)
+$(EXPORT_INCLUDE_DIR)/%: $(C2_DIR)/../generated/jvmtifiles/%
$(install-file)
-
-# Other libraries (like SA)
-$(EXPORT_JRE_BIN_DIR)/%.diz: $(MISC_DIR)/%.diz
+# Windows
+$(EXPORT_SERVER_DIR)/%.dll: $(C2_DIR)/%.dll
+ $(install-file)
+$(EXPORT_SERVER_DIR)/%.pdb: $(C2_DIR)/%.pdb
$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.dll: $(MISC_DIR)/%.dll
+$(EXPORT_SERVER_DIR)/%.map: $(C2_DIR)/%.map
$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.pdb: $(MISC_DIR)/%.pdb
+$(EXPORT_LIB_DIR)/%.lib: $(C2_DIR)/%.lib
$(install-file)
-$(EXPORT_JRE_BIN_DIR)/%.map: $(MISC_DIR)/%.map
+$(EXPORT_JRE_BIN_DIR)/%.diz: $(C2_DIR)/%.diz
$(install-file)
-
-# Client files always come from C1 area
-$(EXPORT_CLIENT_DIR)/%.diz: $(C1_DIR)/%.diz
+$(EXPORT_JRE_BIN_DIR)/%.dll: $(C2_DIR)/%.dll
+ $(install-file)
+$(EXPORT_JRE_BIN_DIR)/%.pdb: $(C2_DIR)/%.pdb
$(install-file)
-$(EXPORT_CLIENT_DIR)/%.dll: $(C1_DIR)/%.dll
+$(EXPORT_JRE_BIN_DIR)/%.map: $(C2_DIR)/%.map
$(install-file)
-$(EXPORT_CLIENT_DIR)/%.pdb: $(C1_DIR)/%.pdb
+# Unix
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C2_DIR)/%.$(LIBRARY_SUFFIX)
$(install-file)
-$(EXPORT_CLIENT_DIR)/%.map: $(C1_DIR)/%.map
+$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(C2_DIR)/%.$(LIBRARY_SUFFIX)
$(install-file)
-
-# Server files always come from C2 area
-$(EXPORT_SERVER_DIR)/%.diz: $(C2_DIR)/%.diz
+$(EXPORT_SERVER_DIR)/64/%.$(LIBRARY_SUFFIX): $(C2_DIR)/%.$(LIBRARY_SUFFIX)
+ $(install-file)
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(C2_DIR)/%.debuginfo
+ $(install-file)
+$(EXPORT_SERVER_DIR)/%.debuginfo: $(C2_DIR)/%.debuginfo
$(install-file)
-$(EXPORT_SERVER_DIR)/%.dll: $(C2_DIR)/%.dll
+$(EXPORT_SERVER_DIR)/64/%.debuginfo: $(C2_DIR)/%.debuginfo
$(install-file)
-$(EXPORT_SERVER_DIR)/%.pdb: $(C2_DIR)/%.pdb
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(C2_DIR)/%.diz
$(install-file)
-$(EXPORT_SERVER_DIR)/%.map: $(C2_DIR)/%.map
+$(EXPORT_SERVER_DIR)/64/%.diz: $(C2_DIR)/%.diz
$(install-file)
endif
-# Minimal JVM files always come from minimal area
-$(EXPORT_MINIMAL_DIR)/%.diz: $(MINIMAL1_DIR)/%.diz
+# Client (C1)
+ifeq ($(JVM_VARIANT_CLIENT), true)
+# Common
+$(EXPORT_CLIENT_DIR)/%.diz: $(C1_DIR)/%.diz
+ $(install-file)
+$(EXPORT_LIB_DIR)/%.jar: $(C1_DIR)/../generated/%.jar
+ $(install-file)
+$(EXPORT_INCLUDE_DIR)/%: $(C1_DIR)/../generated/jvmtifiles/%
$(install-file)
-$(EXPORT_MINIMAL_DIR)/%.dll: $(MINIMAL1_DIR)/%.dll
+# Windows
+$(EXPORT_CLIENT_DIR)/%.dll: $(C1_DIR)/%.dll
+ $(install-file)
+$(EXPORT_CLIENT_DIR)/%.pdb: $(C1_DIR)/%.pdb
$(install-file)
-$(EXPORT_MINIMAL_DIR)/%.pdb: $(MINIMAL1_DIR)/%.pdb
+$(EXPORT_CLIENT_DIR)/%.map: $(C1_DIR)/%.map
+ $(install-file)
+$(EXPORT_LIB_DIR)/%.lib: $(C1_DIR)/%.lib
$(install-file)
-$(EXPORT_MINIMAL_DIR)/%.map: $(MINIMAL1_DIR)/%.map
+$(EXPORT_JRE_BIN_DIR)/%.diz: $(C1_DIR)/%.diz
+ $(install-file)
+$(EXPORT_JRE_BIN_DIR)/%.dll: $(C1_DIR)/%.dll
$(install-file)
-
-# Shared Library
-ifneq ($(OSNAME),windows)
- ifeq ($(JVM_VARIANT_SERVER), true)
- $(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C2_DIR)/%.$(LIBRARY_SUFFIX)
- $(install-file)
- $(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(C2_DIR)/%.$(LIBRARY_SUFFIX)
- $(install-file)
- $(EXPORT_SERVER_DIR)/64/%.$(LIBRARY_SUFFIX): $(C2_DIR)/%.$(LIBRARY_SUFFIX)
- $(install-file)
- $(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(C2_DIR)/%.debuginfo
- $(install-file)
- $(EXPORT_SERVER_DIR)/%.debuginfo: $(C2_DIR)/%.debuginfo
- $(install-file)
- $(EXPORT_SERVER_DIR)/64/%.debuginfo: $(C2_DIR)/%.debuginfo
- $(install-file)
- $(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(C2_DIR)/%.diz
- $(install-file)
- $(EXPORT_SERVER_DIR)/%.diz: $(C2_DIR)/%.diz
- $(install-file)
- $(EXPORT_SERVER_DIR)/64/%.diz: $(C2_DIR)/%.diz
- $(install-file)
- endif
- ifeq ($(JVM_VARIANT_CLIENT), true)
- $(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C1_DIR)/%.$(LIBRARY_SUFFIX)
- $(install-file)
- $(EXPORT_CLIENT_DIR)/%.$(LIBRARY_SUFFIX): $(C1_DIR)/%.$(LIBRARY_SUFFIX)
- $(install-file)
- $(EXPORT_CLIENT_DIR)/64/%.$(LIBRARY_SUFFIX): $(C1_DIR)/%.$(LIBRARY_SUFFIX)
- $(install-file)
- $(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(C1_DIR)/%.debuginfo
- $(install-file)
- $(EXPORT_CLIENT_DIR)/%.debuginfo: $(C1_DIR)/%.debuginfo
- $(install-file)
- $(EXPORT_CLIENT_DIR)/64/%.debuginfo: $(C1_DIR)/%.debuginfo
- $(install-file)
- $(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(C1_DIR)/%.diz
- $(install-file)
- $(EXPORT_CLIENT_DIR)/%.diz: $(C1_DIR)/%.diz
- $(install-file)
- $(EXPORT_CLIENT_DIR)/64/%.diz: $(C1_DIR)/%.diz
- $(install-file)
- endif
- ifeq ($(JVM_VARIANT_ZEROSHARK), true)
- $(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
- $(install-file)
- $(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo): $(SHARK_DIR)/%.debuginfo
- $(install-file)
- $(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(SHARK_DIR)/%.diz
- $(install-file)
- $(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
- $(install-file)
- $(EXPORT_SERVER_DIR)/%.debuginfo: $(SHARK_DIR)/%.debuginfo
- $(install-file)
- $(EXPORT_SERVER_DIR)/%.diz: $(SHARK_DIR)/%.diz
- $(install-file)
- endif
- ifeq ($(JVM_VARIANT_ZERO), true)
- $(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
- $(install-file)
- $(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(ZERO_DIR)/%.debuginfo
- $(install-file)
- $(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(ZERO_DIR)/%.diz
- $(install-file)
- $(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
- $(install-file)
- $(EXPORT_SERVER_DIR)/%.debuginfo: $(ZERO_DIR)/%.debuginfo
- $(install-file)
- $(EXPORT_SERVER_DIR)/%.diz: $(ZERO_DIR)/%.diz
- $(install-file)
- endif
- ifeq ($(JVM_VARIANT_MINIMAL1), true)
- $(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(MINIMAL1_DIR)/%.$(LIBRARY_SUFFIX)
- $(install-file)
- $(EXPORT_MINIMAL_DIR)/%.$(LIBRARY_SUFFIX): $(MINIMAL1_DIR)/%.$(LIBRARY_SUFFIX)
- $(install-file)
- $(EXPORT_MINIMAL_DIR)/64/%.$(LIBRARY_SUFFIX): $(MINIMAL1_DIR)/%.$(LIBRARY_SUFFIX)
- $(install-file)
- $(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(MINIMAL1_DIR)/%.debuginfo
- $(install-file)
- $(EXPORT_MINIMAL_DIR)/%.debuginfo: $(MINIMAL1_DIR)/%.debuginfo
- $(install-file)
- $(EXPORT_MINIMAL_DIR)/64/%.debuginfo: $(MINIMAL1_DIR)/%.debuginfo
- $(install-file)
- $(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(MINIMAL1_DIR)/%.diz
- $(install-file)
- $(EXPORT_MINIMAL_DIR)/%.diz: $(MINIMAL1_DIR)/%.diz
- $(install-file)
- $(EXPORT_MINIMAL_DIR)/64/%.diz: $(MINIMAL1_DIR)/%.diz
- $(install-file)
- endif
+$(EXPORT_JRE_BIN_DIR)/%.pdb: $(C1_DIR)/%.pdb
+ $(install-file)
+$(EXPORT_JRE_BIN_DIR)/%.map: $(C1_DIR)/%.map
+ $(install-file)
+# Unix
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C1_DIR)/%.$(LIBRARY_SUFFIX)
+ $(install-file)
+$(EXPORT_CLIENT_DIR)/%.$(LIBRARY_SUFFIX): $(C1_DIR)/%.$(LIBRARY_SUFFIX)
+ $(install-file)
+$(EXPORT_CLIENT_DIR)/64/%.$(LIBRARY_SUFFIX): $(C1_DIR)/%.$(LIBRARY_SUFFIX)
+ $(install-file)
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(C1_DIR)/%.debuginfo
+ $(install-file)
+$(EXPORT_CLIENT_DIR)/%.debuginfo: $(C1_DIR)/%.debuginfo
+ $(install-file)
+$(EXPORT_CLIENT_DIR)/64/%.debuginfo: $(C1_DIR)/%.debuginfo
+ $(install-file)
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(C1_DIR)/%.diz
+ $(install-file)
+$(EXPORT_CLIENT_DIR)/64/%.diz: $(C1_DIR)/%.diz
+ $(install-file)
endif
-# Jar file (sa-jdi.jar)
-$(EXPORT_LIB_DIR)/%.jar: $(GEN_DIR)/%.jar
+# Minimal1
+ifeq ($(JVM_VARIANT_MINIMAL1), true)
+# Common
+$(EXPORT_MINIMAL_DIR)/%.diz: $(MINIMAL1_DIR)/%.diz
+ $(install-file)
+$(EXPORT_LIB_DIR)/%.jar: $(MINIMAL1_DIR)/../generated/%.jar
+ $(install-file)
+$(EXPORT_INCLUDE_DIR)/%: $(MINIMAL1_DIR)/../generated/jvmtifiles/%
+ $(install-file)
+# Windows
+$(EXPORT_MINIMAL_DIR)/%.dll: $(MINIMAL1_DIR)/%.dll
+ $(install-file)
+$(EXPORT_MINIMAL_DIR)/%.pdb: $(MINIMAL1_DIR)/%.pdb
+ $(install-file)
+$(EXPORT_MINIMAL_DIR)/%.map: $(MINIMAL1_DIR)/%.map
+ $(install-file)
+$(EXPORT_LIB_DIR)/%.lib: $(MINIMAL1_DIR)/%.lib
+ $(install-file)
+$(EXPORT_JRE_BIN_DIR)/%.diz: $(MINIMAL1_DIR)/%.diz
+ $(install-file)
+$(EXPORT_JRE_BIN_DIR)/%.dll: $(MINIMAL1_DIR)/%.dll
$(install-file)
+$(EXPORT_JRE_BIN_DIR)/%.pdb: $(MINIMAL1_DIR)/%.pdb
+ $(install-file)
+$(EXPORT_JRE_BIN_DIR)/%.map: $(MINIMAL1_DIR)/%.map
+ $(install-file)
+# Unix
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(MINIMAL1_DIR)/%.$(LIBRARY_SUFFIX)
+ $(install-file)
+$(EXPORT_MINIMAL_DIR)/%.$(LIBRARY_SUFFIX): $(MINIMAL1_DIR)/%.$(LIBRARY_SUFFIX)
+ $(install-file)
+$(EXPORT_MINIMAL_DIR)/64/%.$(LIBRARY_SUFFIX): $(MINIMAL1_DIR)/%.$(LIBRARY_SUFFIX)
+ $(install-file)
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(MINIMAL1_DIR)/%.debuginfo
+ $(install-file)
+$(EXPORT_MINIMAL_DIR)/%.debuginfo: $(MINIMAL1_DIR)/%.debuginfo
+ $(install-file)
+$(EXPORT_MINIMAL_DIR)/64/%.debuginfo: $(MINIMAL1_DIR)/%.debuginfo
+ $(install-file)
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(MINIMAL1_DIR)/%.diz
+ $(install-file)
+$(EXPORT_MINIMAL_DIR)/64/%.diz: $(MINIMAL1_DIR)/%.diz
+ $(install-file)
+endif
-# Include files (jvmti.h, jvmticmlr.h, jni.h, $(JDK_INCLUDE_SUBDIR)/jni_md.h, jmm.h, jfr.h)
-$(EXPORT_INCLUDE_DIR)/%: $(GEN_DIR)/jvmtifiles/%
+# Zero
+ifeq ($(JVM_VARIANT_ZERO), true)
+# Common
+$(EXPORT_LIB_DIR)/%.jar: $(ZERO_DIR)/../generated/%.jar
+ $(install-file)
+$(EXPORT_INCLUDE_DIR)/%: $(ZERO_DIR)/../generated/jvmtifiles/%
+ $(install-file)
+# Unix
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
+ $(install-file)
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(ZERO_DIR)/%.debuginfo
+ $(install-file)
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(ZERO_DIR)/%.diz
+ $(install-file)
+$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
+ $(install-file)
+$(EXPORT_SERVER_DIR)/%.debuginfo: $(ZERO_DIR)/%.debuginfo
+ $(install-file)
+$(EXPORT_SERVER_DIR)/%.diz: $(ZERO_DIR)/%.diz
$(install-file)
+endif
+
+# Shark
+ifeq ($(JVM_VARIANT_ZEROSHARK), true)
+# Common
+$(EXPORT_LIB_DIR)/%.jar: $(SHARK_DIR)/../generated/%.jar
+ $(install-file)
+$(EXPORT_INCLUDE_DIR)/%: $(SHARK_DIR)/../generated/jvmtifiles/%
+ $(install-file)
+# Unix
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
+ $(install-file)
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo): $(SHARK_DIR)/%.debuginfo
+ $(install-file)
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(SHARK_DIR)/%.diz
+ $(install-file)
+$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
+ $(install-file)
+$(EXPORT_SERVER_DIR)/%.debuginfo: $(SHARK_DIR)/%.debuginfo
+ $(install-file)
+$(EXPORT_SERVER_DIR)/%.diz: $(SHARK_DIR)/%.diz
+ $(install-file)
+endif
$(EXPORT_INCLUDE_DIR)/%: $(HS_SRC_DIR)/share/vm/code/%
$(install-file)
@@ -541,11 +546,11 @@
@$(RUN_JVM) -XXaltjvm=$(ALTJVM_DIR) -showversion -help
# C2 test targets
-test_product test_optimized test_fastdebug test_jvmg:
+test_product test_optimized test_fastdebug test_debug:
@$(MAKE) generic_test ALTJVM_DIR="$(C2_DIR)/$(@:test_%=%)"
# C1 test targets
-test_product1 test_optimized1 test_fastdebug1 test_jvmg1:
+test_product1 test_optimized1 test_fastdebug1 test_debug1:
ifeq ($(ARCH_DATA_MODEL), 32)
@$(MAKE) generic_test ALTJVM_DIR="$(C1_DIR)/$(@:test_%1=%)"
else
@@ -553,15 +558,15 @@
endif
# Zero test targets
-test_productzero test_optimizedzero test_fastdebugzero test_jvmgzero:
+test_productzero test_optimizedzero test_fastdebugzero test_debugzero:
@$(MAKE) generic_test ALTJVM_DIR="$(ZERO_DIR)/$(@:test_%zero=%)"
# Shark test targets
-test_productshark test_optimizedshark test_fastdebugshark test_jvmgshark:
+test_productshark test_optimizedshark test_fastdebugshark test_debugshark:
@$(MAKE) generic_test ALTJVM_DIR="$(SHARK_DIR)/$(@:test_%shark=%)"
# Minimal1 test targets
-test_productminimal1 test_optimizedminimal1 test_fastdebugminimal1 test_jvmgminimal1:
+test_productminimal1 test_optimizedminimal1 test_fastdebugminimal1 test_debugminimal1:
@$(MAKE) generic_test ALTJVM_DIR="$(MINIMAL1_DIR)/$(@:test_%minimal1=%)"
@@ -626,7 +631,7 @@
# Intro help message
intro_help:
@$(ECHO) \
-"Makefile for the Hotspot workspace."
+"Makefile for the Hotspot workspace."
@$(ECHO) \
"Default behavior is to build and create an export area for the j2se builds."
@@ -637,7 +642,7 @@
@$(ECHO) "world: Same as: all create_jdk"
@$(ECHO) "all_product: Same as: product product1 export_product"
@$(ECHO) "all_fastdebug: Same as: fastdebug fastdebug1 export_fastdebug"
- @$(ECHO) "all_debug: Same as: jvmg jvmg1 export_debug"
+ @$(ECHO) "all_debug: Same as: debug debug1 export_debug"
@$(ECHO) "all_optimized: Same as: optimized optimized1 export_optimized"
@$(ECHO) "clean: Clean all areas"
@$(ECHO) "export_product: Export product files to EXPORT_PATH"
@@ -730,7 +735,7 @@
@$(ECHO) \
" $(MAKE) world"
@$(ECHO) \
-" $(MAKE) ALT_BOOTDIR=/opt/java/jdk$(PREVIOUS_JDK_VERSION)"
+" $(MAKE) ALT_BOOTDIR=/opt/java/jdk$(PREVIOUS_JDK_VERSION)"
@$(ECHO) \
" $(MAKE) ALT_JDK_IMPORT_PATH=/opt/java/jdk$(JDK_VERSION)"
@@ -741,6 +746,23 @@
endif
endif
+# Compatibility for transition to new naming
+warn_jvmg_deprecated:
+ echo "Warning: The jvmg target has been replaced with debug"
+ echo "Warning: Please update your usage"
+
+jvmg: warn_jvmg_deprecated debug
+
+jvmg1: warn_jvmg_deprecated debug1
+
+jvmgminimal1: warn_jvmg_deprecated debugminimal1
+
+jvmgcore: warn_jvmg_deprecated debugcore
+
+jvmgzero: warn_jvmg_deprecated debugzero
+
+jvmgshark: warn_jvmg_deprecated debugshark
+
# JPRT rule to build this workspace
include $(GAMMADIR)/make/jprt.gmk
--- a/hotspot/make/bsd/Makefile Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/bsd/Makefile Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+# 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
@@ -142,55 +142,43 @@
#
# debug compiler2 <os>_<arch>_compiler2/debug
# fastdebug compiler2 <os>_<arch>_compiler2/fastdebug
-# jvmg compiler2 <os>_<arch>_compiler2/jvmg
# optimized compiler2 <os>_<arch>_compiler2/optimized
-# profiled compiler2 <os>_<arch>_compiler2/profiled
# product compiler2 <os>_<arch>_compiler2/product
#
# debug1 compiler1 <os>_<arch>_compiler1/debug
# fastdebug1 compiler1 <os>_<arch>_compiler1/fastdebug
-# jvmg1 compiler1 <os>_<arch>_compiler1/jvmg
# optimized1 compiler1 <os>_<arch>_compiler1/optimized
-# profiled1 compiler1 <os>_<arch>_compiler1/profiled
# product1 compiler1 <os>_<arch>_compiler1/product
#
# debugcore core <os>_<arch>_core/debug
# fastdebugcore core <os>_<arch>_core/fastdebug
-# jvmgcore core <os>_<arch>_core/jvmg
# optimizedcore core <os>_<arch>_core/optimized
-# profiledcore core <os>_<arch>_core/profiled
# productcore core <os>_<arch>_core/product
#
# debugzero zero <os>_<arch>_zero/debug
# fastdebugzero zero <os>_<arch>_zero/fastdebug
-# jvmgzero zero <os>_<arch>_zero/jvmg
# optimizedzero zero <os>_<arch>_zero/optimized
-# profiledzero zero <os>_<arch>_zero/profiled
# productzero zero <os>_<arch>_zero/product
#
# debugshark shark <os>_<arch>_shark/debug
# fastdebugshark shark <os>_<arch>_shark/fastdebug
-# jvmgshark shark <os>_<arch>_shark/jvmg
# optimizedshark shark <os>_<arch>_shark/optimized
-# profiledshark shark <os>_<arch>_shark/profiled
# productshark shark <os>_<arch>_shark/product
#
# fastdebugminimal1 minimal1 <os>_<arch>_minimal1/fastdebug
-# jvmgminimal1 minimal1 <os>_<arch>_minimal1/jvmg
+# debugminimal1 minimal1 <os>_<arch>_minimal1/debug
# productminimal1 minimal1 <os>_<arch>_minimal1/product
#
# What you get with each target:
#
-# debug* - "thin" libjvm - debug info linked into the gamma launcher
+# debug* - debug compile with asserts enabled
# fastdebug* - optimized compile, but with asserts enabled
-# jvmg* - "fat" libjvm - debug info linked into libjvm.so
# optimized* - optimized compile, no asserts
-# profiled* - gprof
# product* - the shippable thing: optimized compile, no asserts, -DPRODUCT
# This target list needs to be coordinated with the usage message
# in the build.sh script:
-TARGETS = debug jvmg fastdebug optimized profiled product
+TARGETS = debug fastdebug optimized product
ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
SUBDIR_DOCS = $(OSNAME)_$(VARIANTARCH)_docs
@@ -354,15 +342,29 @@
$(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/makefiles/jvmti.make $(MFLAGS) $(BUILDTREE_VARS) JvmtiOutDir=$(SUBDIR_DOCS) jvmtidocs
# Synonyms for win32-like targets.
-compiler2: jvmg product
+compiler2: debug product
+
+compiler1: debug1 product1
-compiler1: jvmg1 product1
+core: debugcore productcore
+
+zero: debugzero productzero
+
+shark: debugshark productshark
-core: jvmgcore productcore
+warn_jvmg_deprecated:
+ echo "Warning: The jvmg target has been replaced with debug"
+ echo "Warning: Please update your usage"
+
+jvmg: warn_jvmg_deprecated debug
-zero: jvmgzero productzero
+jvmg1: warn_jvmg_deprecated debug1
+
+jvmgcore: warn_jvmg_deprecated debugcore
-shark: jvmgshark productshark
+jvmgzero: warn_jvmg_deprecated debugzero
+
+jvmgshark: warn_jvmg_deprecated debugshark
clean_docs:
rm -rf $(SUBDIR_DOCS)
--- a/hotspot/make/bsd/makefiles/buildtree.make Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/bsd/makefiles/buildtree.make Fri Apr 19 09:58:05 2013 -0700
@@ -19,7 +19,7 @@
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
-#
+#
#
# Usage:
@@ -46,11 +46,11 @@
# Makefile - for "make foo"
# flags.make - with macro settings
# vm.make - to support making "$(MAKE) -v vm.make" in makefiles
-# adlc.make -
+# adlc.make -
# jvmti.make - generate JVMTI bindings from the spec (JSR-163)
# sa.make - generate SA jar file and natives
# env.[ck]sh - environment settings
-#
+#
# The makefiles are split this way so that "make foo" will run faster by not
# having to read the dependency files for the vm.
@@ -122,7 +122,7 @@
$(PLATFORM_DIR)/generated/jvmtifiles \
$(PLATFORM_DIR)/generated/dtracefiles
-TARGETS = debug fastdebug jvmg optimized product profiled
+TARGETS = debug fastdebug optimized product
SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS))
# For dependencies and recursive makes.
@@ -186,8 +186,8 @@
$(QUIETLY) mkdir -p $@
# Convenience macro which takes a source relative path, applies $(1) to the
-# absolute path, and then replaces $(GAMMADIR) in the result with a
-# literal "$(GAMMADIR)/" suitable for inclusion in a Makefile.
+# absolute path, and then replaces $(GAMMADIR) in the result with a
+# literal "$(GAMMADIR)/" suitable for inclusion in a Makefile.
gamma-path=$(subst $(GAMMADIR),\$$(GAMMADIR),$(call $(1),$(HS_COMMON_SRC)/$(2)))
# This bit is needed to enable local rebuilds.
@@ -279,8 +279,6 @@
$(QUIETLY) ( \
$(BUILDTREE_COMMENT); \
echo; \
- [ "$(TARGET)" = profiled ] && \
- echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/optimized.make"; \
echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(TARGET).make"; \
) > $@
@@ -381,7 +379,7 @@
$(QUIETLY) ( \
$(BUILDTREE_COMMENT); \
echo "JDK=${JAVA_HOME}"; \
- ) > $@
+ ) > $@
FORCE:
--- a/hotspot/make/bsd/makefiles/debug.make Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/bsd/makefiles/debug.make Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+# 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
@@ -19,7 +19,7 @@
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
-#
+#
#
# Sets make macros for making debug version of VM
@@ -27,17 +27,16 @@
# Compiler specific DEBUG_CFLAGS are passed in from gcc.make, sparcWorks.make
DEBUG_CFLAGS/DEFAULT= $(DEBUG_CFLAGS)
DEBUG_CFLAGS/BYFILE = $(DEBUG_CFLAGS/$@)$(DEBUG_CFLAGS/DEFAULT$(DEBUG_CFLAGS/$@))
-CFLAGS += $(DEBUG_CFLAGS/BYFILE)
+
+# _NMT_NOINLINE_ informs NMT that no inlining by Compiler
+CFLAGS += $(DEBUG_CFLAGS/BYFILE) -D_NMT_NOINLINE_
+
+# Set the environment variable HOTSPARC_GENERIC to "true"
+# to inhibit the effect of the previous line on CFLAGS.
# Linker mapfile
MAPFILE = $(GAMMADIR)/make/bsd/makefiles/mapfile-vers-debug
-_JUNK_ := $(shell echo -e >&2 ""\
- "----------------------------------------------------------------------\n" \
- "WARNING: 'make debug' is deprecated. It will be removed in the future.\n" \
- "Please use 'make jvmg' to build debug JVM. \n" \
- "----------------------------------------------------------------------\n")
-
VERSION = debug
-SYSDEFS += -DASSERT -DDEBUG
+SYSDEFS += -DASSERT
PICFLAGS = DEFAULT
--- a/hotspot/make/bsd/makefiles/defs.make Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/bsd/makefiles/defs.make Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 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
@@ -19,7 +19,7 @@
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
-#
+#
#
# The common definitions for hotspot bsd builds.
@@ -86,7 +86,7 @@
VM_PLATFORM = bsd_i486
HS_ARCH = x86
# We have to reset ARCH to i386 since SRCARCH relies on it
- ARCH = i386
+ ARCH = i386
endif
endif
@@ -146,9 +146,6 @@
LIBRARY_SUFFIX=so
endif
-# FIXUP: The subdirectory for a debug build is NOT the same on all platforms
-VM_DEBUG=jvmg
-
EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html
# client and server subdirectories have symbolic links to ../libjsig.so
@@ -177,7 +174,7 @@
else
EXPORT_LIST += $(EXPORT_MINIMAL_DIR)/libjvm.debuginfo
endif
- endif
+ endif
endif
# Serviceability Binaries
--- a/hotspot/make/bsd/makefiles/fastdebug.make Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/bsd/makefiles/fastdebug.make Fri Apr 19 09:58:05 2013 -0700
@@ -19,7 +19,7 @@
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
-#
+#
#
# Sets make macros for making debug version of VM
@@ -59,5 +59,5 @@
MAPFILE = $(GAMMADIR)/make/bsd/makefiles/mapfile-vers-debug
VERSION = optimized
-SYSDEFS += -DASSERT -DFASTDEBUG
+SYSDEFS += -DASSERT
PICFLAGS = DEFAULT
--- a/hotspot/make/bsd/makefiles/jvmg.make Thu Apr 18 10:30:11 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-#
-# Copyright (c) 1999, 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.
-#
-#
-
-# Sets make macros for making debug version of VM
-
-# Compiler specific DEBUG_CFLAGS are passed in from gcc.make, sparcWorks.make
-DEBUG_CFLAGS/DEFAULT= $(DEBUG_CFLAGS)
-DEBUG_CFLAGS/BYFILE = $(DEBUG_CFLAGS/$@)$(DEBUG_CFLAGS/DEFAULT$(DEBUG_CFLAGS/$@))
-
-# _NMT_NOINLINE_ informs NMT that no inlining by Compiler
-CFLAGS += $(DEBUG_CFLAGS/BYFILE) -D_NMT_NOINLINE_
-
-# Set the environment variable HOTSPARC_GENERIC to "true"
-# to inhibit the effect of the previous line on CFLAGS.
-
-# Linker mapfile
-MAPFILE = $(GAMMADIR)/make/bsd/makefiles/mapfile-vers-debug
-
-VERSION = debug
-SYSDEFS += -DASSERT -DDEBUG
-PICFLAGS = DEFAULT
--- a/hotspot/make/bsd/makefiles/profiled.make Thu Apr 18 10:30:11 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-#
-# Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-#
-
-# Sets make macros for making profiled version of Gamma VM
-# (It is also optimized.)
-
-CFLAGS += -pg
-AOUT_FLAGS += -pg
-LDNOMAP = true
--- a/hotspot/make/bsd/makefiles/vm.make Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/bsd/makefiles/vm.make Fri Apr 19 09:58:05 2013 -0700
@@ -187,7 +187,7 @@
Src_Dirs/SHARK := $(CORE_PATHS) $(SHARK_PATHS)
Src_Dirs := $(Src_Dirs/$(TYPE))
-COMPILER2_SPECIFIC_FILES := opto libadt bcEscapeAnalyzer.cpp chaitin\* c2_\* runtime_\*
+COMPILER2_SPECIFIC_FILES := opto libadt bcEscapeAnalyzer.cpp c2_\* runtime_\*
COMPILER1_SPECIFIC_FILES := c1_\*
SHARK_SPECIFIC_FILES := shark
ZERO_SPECIFIC_FILES := zero
--- a/hotspot/make/hotspot_version Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/hotspot_version Fri Apr 19 09:58:05 2013 -0700
@@ -35,7 +35,7 @@
HS_MAJOR_VER=25
HS_MINOR_VER=0
-HS_BUILD_NUMBER=28
+HS_BUILD_NUMBER=29
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
--- a/hotspot/make/jprt.properties Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/jprt.properties Fri Apr 19 09:58:05 2013 -0700
@@ -133,15 +133,15 @@
# Standard list of jprt build targets for this source tree
jprt.build.targets.standard= \
- ${jprt.my.solaris.sparc}-{product|fastdebug|debug}, \
- ${jprt.my.solaris.sparcv9}-{product|fastdebug|debug}, \
- ${jprt.my.solaris.i586}-{product|fastdebug|debug}, \
- ${jprt.my.solaris.x64}-{product|fastdebug|debug}, \
- ${jprt.my.linux.i586}-{product|fastdebug|debug}, \
+ ${jprt.my.solaris.sparc}-{product|fastdebug}, \
+ ${jprt.my.solaris.sparcv9}-{product|fastdebug}, \
+ ${jprt.my.solaris.i586}-{product|fastdebug}, \
+ ${jprt.my.solaris.x64}-{product|fastdebug}, \
+ ${jprt.my.linux.i586}-{product|fastdebug}, \
${jprt.my.linux.x64}-{product|fastdebug}, \
- ${jprt.my.macosx.x64}-{product|fastdebug|debug}, \
- ${jprt.my.windows.i586}-{product|fastdebug|debug}, \
- ${jprt.my.windows.x64}-{product|fastdebug|debug}, \
+ ${jprt.my.macosx.x64}-{product|fastdebug}, \
+ ${jprt.my.windows.i586}-{product|fastdebug}, \
+ ${jprt.my.windows.x64}-{product|fastdebug}, \
${jprt.my.linux.armvh}-{product|fastdebug}
jprt.build.targets.open= \
@@ -150,7 +150,7 @@
${jprt.my.linux.x64}-{productOpen}
jprt.build.targets.embedded= \
- ${jprt.my.linux.i586}-{productEmb|fastdebugEmb|debugEmb}, \
+ ${jprt.my.linux.i586}-{productEmb|fastdebugEmb}, \
${jprt.my.linux.ppc}-{productEmb|fastdebugEmb}, \
${jprt.my.linux.ppcv2}-{productEmb|fastdebugEmb}, \
${jprt.my.linux.ppcsflt}-{productEmb|fastdebugEmb}, \
@@ -174,21 +174,18 @@
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-scimark, \
${jprt.my.solaris.sparc}-product-{c1|c2}-runThese, \
${jprt.my.solaris.sparc}-fastdebug-c1-runThese_Xshare, \
- ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_default, \
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC, \
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_G1, \
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_ParOldGC, \
- ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_default, \
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_SerialGC, \
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_ParallelGC, \
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_ParNewGC, \
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_CMS, \
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_G1, \
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_ParOldGC, \
- ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_default, \
${jprt.my.solaris.sparc}-{product|fastdebug}-c2-jbb_default_nontiered, \
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_SerialGC, \
${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_ParallelGC, \
@@ -201,21 +198,18 @@
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jvm98_nontiered, \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-scimark, \
${jprt.my.solaris.sparcv9}-product-c2-runThese, \
- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_default, \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_SerialGC, \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_ParallelGC, \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_ParNewGC, \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_CMS, \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_G1, \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_ParOldGC, \
- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_default, \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_SerialGC, \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_ParallelGC, \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_ParNewGC, \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_CMS, \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_G1, \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_ParOldGC, \
- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_default, \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_default_nontiered, \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_SerialGC, \
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_ParallelGC, \
@@ -229,21 +223,18 @@
${jprt.my.solaris.x64}-{product|fastdebug}-c2-scimark, \
${jprt.my.solaris.x64}-product-c2-runThese, \
${jprt.my.solaris.x64}-product-c2-runThese_Xcomp, \
- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_default, \
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_SerialGC, \
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC, \
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC, \
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_CMS, \
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_G1, \
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_ParOldGC, \
- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_default, \
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_SerialGC, \
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_ParallelGC, \
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_ParNewGC, \
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_CMS, \
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_G1, \
${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_ParOldGC, \
- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_default, \
${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_default_nontiered, \
${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_SerialGC, \
${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_ParallelGC, \
@@ -258,28 +249,24 @@
${jprt.my.solaris.i586}-product-{c1|c2}-runThese_Xcomp, \
${jprt.my.solaris.i586}-fastdebug-c1-runThese_Xcomp, \
${jprt.my.solaris.i586}-fastdebug-c1-runThese_Xshare, \
- ${jprt.my.solaris.i586}-product-c1-GCBasher_default, \
${jprt.my.solaris.i586}-product-c1-GCBasher_SerialGC, \
${jprt.my.solaris.i586}-product-c1-GCBasher_ParallelGC, \
${jprt.my.solaris.i586}-product-c1-GCBasher_ParNewGC, \
${jprt.my.solaris.i586}-product-c1-GCBasher_CMS, \
${jprt.my.solaris.i586}-product-c1-GCBasher_G1, \
${jprt.my.solaris.i586}-product-c1-GCBasher_ParOldGC, \
- ${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_default, \
${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_SerialGC, \
${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_ParallelGC, \
${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_ParNewGC, \
${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_CMS, \
${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_G1, \
${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_ParOldGC, \
- ${jprt.my.solaris.i586}-product-c1-GCOld_default, \
${jprt.my.solaris.i586}-product-c1-GCOld_SerialGC, \
${jprt.my.solaris.i586}-product-c1-GCOld_ParallelGC, \
${jprt.my.solaris.i586}-product-c1-GCOld_ParNewGC, \
${jprt.my.solaris.i586}-product-c1-GCOld_CMS, \
${jprt.my.solaris.i586}-product-c1-GCOld_G1, \
${jprt.my.solaris.i586}-product-c1-GCOld_ParOldGC, \
- ${jprt.my.solaris.i586}-fastdebug-c2-jbb_default, \
${jprt.my.solaris.i586}-fastdebug-c2-jbb_default_nontiered, \
${jprt.my.solaris.i586}-fastdebug-c2-jbb_ParallelGC, \
${jprt.my.solaris.i586}-fastdebug-c2-jbb_CMS, \
@@ -293,21 +280,19 @@
${jprt.my.linux.i586}-product-c1-runThese_Xcomp, \
${jprt.my.linux.i586}-fastdebug-c1-runThese_Xshare, \
${jprt.my.linux.i586}-fastdebug-c2-runThese_Xcomp, \
- ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_default, \
${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC, \
${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \
${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \
${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \
${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_G1, \
${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParOldGC, \
- ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_default, \
${jprt.my.linux.i586}-product-{c1|c2}-GCOld_SerialGC, \
${jprt.my.linux.i586}-product-{c1|c2}-GCOld_ParallelGC, \
${jprt.my.linux.i586}-product-{c1|c2}-GCOld_ParNewGC, \
${jprt.my.linux.i586}-product-{c1|c2}-GCOld_CMS, \
${jprt.my.linux.i586}-product-{c1|c2}-GCOld_G1, \
${jprt.my.linux.i586}-product-{c1|c2}-GCOld_ParOldGC, \
- ${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_default, \
+ ${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_SerialGC, \
${jprt.my.linux.i586}-{product|fastdebug}-c2-jbb_default_nontiered, \
${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_ParallelGC, \
${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_CMS, \
@@ -318,21 +303,18 @@
${jprt.my.linux.x64}-{product|fastdebug}-c2-jvm98, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-jvm98_nontiered, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-scimark, \
- ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_default, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_SerialGC, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_CMS, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_G1, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_ParOldGC, \
- ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_default, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_SerialGC, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_ParallelGC, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_ParNewGC, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_CMS, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_G1, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_ParOldGC, \
- ${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_default, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_default_nontiered, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_ParallelGC, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_G1, \
@@ -342,21 +324,18 @@
${jprt.my.macosx.x64}-{product|fastdebug}-c2-jvm98, \
${jprt.my.macosx.x64}-{product|fastdebug}-c2-jvm98_nontiered, \
${jprt.my.macosx.x64}-{product|fastdebug}-c2-scimark, \
- ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCBasher_default, \
${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCBasher_SerialGC, \
${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC, \
${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC, \
${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCBasher_CMS, \
${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCBasher_G1, \
${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCBasher_ParOldGC, \
- ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCOld_default, \
${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCOld_SerialGC, \
${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCOld_ParallelGC, \
${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCOld_ParNewGC, \
${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCOld_CMS, \
${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCOld_G1, \
${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCOld_ParOldGC, \
- ${jprt.my.macosx.x64}-{product|fastdebug}-c2-jbb_default, \
${jprt.my.macosx.x64}-{product|fastdebug}-c2-jbb_default_nontiered, \
${jprt.my.macosx.x64}-{product|fastdebug}-c2-jbb_ParallelGC, \
${jprt.my.macosx.x64}-{product|fastdebug}-c2-jbb_G1, \
@@ -369,14 +348,12 @@
${jprt.my.windows.i586}-product-{c1|c2}-runThese, \
${jprt.my.windows.i586}-product-{c1|c2}-runThese_Xcomp, \
${jprt.my.windows.i586}-fastdebug-c1-runThese_Xshare, \
- ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_default, \
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC, \
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_G1, \
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParOldGC, \
- ${jprt.my.windows.i586}-product-{c1|c2}-GCOld_default, \
${jprt.my.windows.i586}-product-{c1|c2}-GCOld_SerialGC, \
${jprt.my.windows.i586}-product-{c1|c2}-GCOld_ParallelGC, \
${jprt.my.windows.i586}-product-{c1|c2}-GCOld_ParNewGC, \
@@ -396,14 +373,12 @@
${jprt.my.windows.x64}-{product|fastdebug}-c2-scimark, \
${jprt.my.windows.x64}-product-c2-runThese, \
${jprt.my.windows.x64}-product-c2-runThese_Xcomp, \
- ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_default, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_SerialGC, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_CMS, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_G1, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_ParOldGC, \
- ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_default, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_SerialGC, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_ParallelGC, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_ParNewGC, \
@@ -419,7 +394,7 @@
# Some basic "smoke" tests for OpenJDK builds
jprt.test.targets.open = \
- ${jprt.my.solaris.x64}-{productOpen|debugOpen|fastdebugOpen}-c2-jvm98, \
+ ${jprt.my.solaris.x64}-{productOpen|fastdebugOpen}-c2-jvm98, \
${jprt.my.solaris.i586}-{productOpen|fastdebugOpen}-c2-jvm98, \
${jprt.my.linux.x64}-{productOpen|fastdebugOpen}-c2-jvm98
@@ -520,5 +495,5 @@
jprt.make.rule.test.targets=${jprt.make.rule.test.targets.${jprt.tools.default.release}}
# 7155453: Work-around to prevent popups on OSX from blocking test completion
-# but the work-around is added to all platforms to be consistent
+# but the work-around is added to all platforms to be consistent
jprt.jbb.options=-Djava.awt.headless=true
--- a/hotspot/make/linux/Makefile Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/linux/Makefile Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+# 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
@@ -142,55 +142,42 @@
#
# debug compiler2 <os>_<arch>_compiler2/debug
# fastdebug compiler2 <os>_<arch>_compiler2/fastdebug
-# jvmg compiler2 <os>_<arch>_compiler2/jvmg
# optimized compiler2 <os>_<arch>_compiler2/optimized
-# profiled compiler2 <os>_<arch>_compiler2/profiled
# product compiler2 <os>_<arch>_compiler2/product
#
# debug1 compiler1 <os>_<arch>_compiler1/debug
# fastdebug1 compiler1 <os>_<arch>_compiler1/fastdebug
-# jvmg1 compiler1 <os>_<arch>_compiler1/jvmg
# optimized1 compiler1 <os>_<arch>_compiler1/optimized
-# profiled1 compiler1 <os>_<arch>_compiler1/profiled
# product1 compiler1 <os>_<arch>_compiler1/product
#
# debugcore core <os>_<arch>_core/debug
# fastdebugcore core <os>_<arch>_core/fastdebug
-# jvmgcore core <os>_<arch>_core/jvmg
# optimizedcore core <os>_<arch>_core/optimized
-# profiledcore core <os>_<arch>_core/profiled
# productcore core <os>_<arch>_core/product
#
# debugzero zero <os>_<arch>_zero/debug
# fastdebugzero zero <os>_<arch>_zero/fastdebug
-# jvmgzero zero <os>_<arch>_zero/jvmg
# optimizedzero zero <os>_<arch>_zero/optimized
-# profiledzero zero <os>_<arch>_zero/profiled
# productzero zero <os>_<arch>_zero/product
#
# debugshark shark <os>_<arch>_shark/debug
# fastdebugshark shark <os>_<arch>_shark/fastdebug
-# jvmgshark shark <os>_<arch>_shark/jvmg
# optimizedshark shark <os>_<arch>_shark/optimized
-# profiledshark shark <os>_<arch>_shark/profiled
# productshark shark <os>_<arch>_shark/product
#
# fastdebugminimal1 minimal1 <os>_<arch>_minimal1/fastdebug
-# jvmgminimal1 minimal1 <os>_<arch>_minimal1/jvmg
# productminimal1 minimal1 <os>_<arch>_minimal1/product
#
# What you get with each target:
#
-# debug* - "thin" libjvm - debug info linked into the gamma launcher
+# debug* - debug compile with asserts enabled
# fastdebug* - optimized compile, but with asserts enabled
-# jvmg* - "fat" libjvm - debug info linked into libjvm.so
# optimized* - optimized compile, no asserts
-# profiled* - gprof
# product* - the shippable thing: optimized compile, no asserts, -DPRODUCT
# This target list needs to be coordinated with the usage message
# in the build.sh script:
-TARGETS = debug jvmg fastdebug optimized profiled product
+TARGETS = debug fastdebug optimized product
ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
SUBDIR_DOCS = $(OSNAME)_$(VARIANTARCH)_docs
@@ -357,15 +344,29 @@
$(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/makefiles/jvmti.make $(MFLAGS) $(BUILDTREE_VARS) JvmtiOutDir=$(SUBDIR_DOCS) BUILD_FLAVOR=product jvmtidocs
# Synonyms for win32-like targets.
-compiler2: jvmg product
+compiler2: debug product
+
+compiler1: debug1 product1
-compiler1: jvmg1 product1
+core: debugcore productcore
+
+zero: debugzero productzero
+
+shark: debugshark productshark
-core: jvmgcore productcore
+warn_jvmg_deprecated:
+ echo "Warning: The jvmg target has been replaced with debug"
+ echo "Warning: Please update your usage"
+
+jvmg: warn_jvmg_deprecated debug
-zero: jvmgzero productzero
+jvmg1: warn_jvmg_deprecated debug1
+
+jvmgcore: warn_jvmg_deprecated debugcore
-shark: jvmgshark productshark
+jvmgzero: warn_jvmg_deprecated debugzero
+
+jvmgshark: warn_jvmg_deprecated debugshark
clean_docs:
rm -rf $(SUBDIR_DOCS)
--- a/hotspot/make/linux/makefiles/buildtree.make Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/linux/makefiles/buildtree.make Fri Apr 19 09:58:05 2013 -0700
@@ -19,7 +19,7 @@
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
-#
+#
#
# Usage:
@@ -46,11 +46,11 @@
# Makefile - for "make foo"
# flags.make - with macro settings
# vm.make - to support making "$(MAKE) -v vm.make" in makefiles
-# adlc.make -
+# adlc.make -
# jvmti.make - generate JVMTI bindings from the spec (JSR-163)
# sa.make - generate SA jar file and natives
# env.[ck]sh - environment settings
-#
+#
# The makefiles are split this way so that "make foo" will run faster by not
# having to read the dependency files for the vm.
@@ -117,7 +117,7 @@
$(PLATFORM_DIR)/generated/adfiles \
$(PLATFORM_DIR)/generated/jvmtifiles
-TARGETS = debug fastdebug jvmg optimized product profiled
+TARGETS = debug fastdebug optimized product
SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS))
# For dependencies and recursive makes.
@@ -179,8 +179,8 @@
$(QUIETLY) mkdir -p $@
# Convenience macro which takes a source relative path, applies $(1) to the
-# absolute path, and then replaces $(GAMMADIR) in the result with a
-# literal "$(GAMMADIR)/" suitable for inclusion in a Makefile.
+# absolute path, and then replaces $(GAMMADIR) in the result with a
+# literal "$(GAMMADIR)/" suitable for inclusion in a Makefile.
gamma-path=$(subst $(GAMMADIR),\$$(GAMMADIR),$(call $(1),$(HS_COMMON_SRC)/$(2)))
# This bit is needed to enable local rebuilds.
@@ -284,8 +284,6 @@
$(QUIETLY) ( \
$(BUILDTREE_COMMENT); \
echo; \
- [ "$(TARGET)" = profiled ] && \
- echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/optimized.make"; \
echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(TARGET).make"; \
) > $@
@@ -376,7 +374,7 @@
$(QUIETLY) ( \
$(BUILDTREE_COMMENT); \
echo "JDK=${JAVA_HOME}"; \
- ) > $@
+ ) > $@
FORCE:
--- a/hotspot/make/linux/makefiles/debug.make Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/linux/makefiles/debug.make Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+# 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
@@ -19,7 +19,7 @@
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
-#
+#
#
# Sets make macros for making debug version of VM
@@ -27,17 +27,16 @@
# Compiler specific DEBUG_CFLAGS are passed in from gcc.make, sparcWorks.make
DEBUG_CFLAGS/DEFAULT= $(DEBUG_CFLAGS)
DEBUG_CFLAGS/BYFILE = $(DEBUG_CFLAGS/$@)$(DEBUG_CFLAGS/DEFAULT$(DEBUG_CFLAGS/$@))
-CFLAGS += $(DEBUG_CFLAGS/BYFILE)
+
+# _NMT_NOINLINE_ informs NMT that no inlining by Compiler
+CFLAGS += $(DEBUG_CFLAGS/BYFILE) -D_NMT_NOINLINE_
+
+# Set the environment variable HOTSPARC_GENERIC to "true"
+# to inhibit the effect of the previous line on CFLAGS.
# Linker mapfile
MAPFILE = $(GAMMADIR)/make/linux/makefiles/mapfile-vers-debug
-_JUNK_ := $(shell echo -e >&2 ""\
- "----------------------------------------------------------------------\n" \
- "WARNING: 'make debug' is deprecated. It will be removed in the future.\n" \
- "Please use 'make jvmg' to build debug JVM. \n" \
- "----------------------------------------------------------------------\n")
-
VERSION = debug
-SYSDEFS += -DASSERT -DDEBUG
+SYSDEFS += -DASSERT
PICFLAGS = DEFAULT
--- a/hotspot/make/linux/makefiles/defs.make Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/linux/makefiles/defs.make Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 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
@@ -19,7 +19,7 @@
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
-#
+#
#
# The common definitions for hotspot linux builds.
@@ -92,7 +92,7 @@
VM_PLATFORM = linux_i486
HS_ARCH = x86
# We have to reset ARCH to i686 since SRCARCH relies on it
- ARCH = i686
+ ARCH = i686
endif
endif
@@ -240,9 +240,6 @@
# Library suffix
LIBRARY_SUFFIX=so
-# FIXUP: The subdirectory for a debug build is NOT the same on all platforms
-VM_DEBUG=jvmg
-
EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html
# client and server subdirectories have symbolic links to ../libjsig.so
@@ -279,7 +276,7 @@
else
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.debuginfo
endif
- endif
+ endif
endif
ifeq ($(JVM_VARIANT_MINIMAL1),true)
@@ -292,15 +289,15 @@
else
EXPORT_LIST += $(EXPORT_MINIMAL_DIR)/libjvm.debuginfo
endif
- endif
+ endif
endif
# Serviceability Binaries
# No SA Support for PPC, IA64, ARM or zero
ADD_SA_BINARIES/x86 = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \
- $(EXPORT_LIB_DIR)/sa-jdi.jar
+ $(EXPORT_LIB_DIR)/sa-jdi.jar
ADD_SA_BINARIES/sparc = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \
- $(EXPORT_LIB_DIR)/sa-jdi.jar
+ $(EXPORT_LIB_DIR)/sa-jdi.jar
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
ifeq ($(ZIP_DEBUGINFO_FILES),1)
ADD_SA_BINARIES/x86 += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.diz
@@ -310,10 +307,10 @@
ADD_SA_BINARIES/sparc += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.debuginfo
endif
endif
-ADD_SA_BINARIES/ppc =
-ADD_SA_BINARIES/ia64 =
-ADD_SA_BINARIES/arm =
-ADD_SA_BINARIES/zero =
+ADD_SA_BINARIES/ppc =
+ADD_SA_BINARIES/ia64 =
+ADD_SA_BINARIES/arm =
+ADD_SA_BINARIES/zero =
-include $(HS_ALT_MAKE)/linux/makefiles/defs.make
--- a/hotspot/make/linux/makefiles/fastdebug.make Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/linux/makefiles/fastdebug.make Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+# 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
@@ -19,7 +19,7 @@
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
-#
+#
#
# Sets make macros for making debug version of VM
@@ -59,5 +59,5 @@
MAPFILE = $(GAMMADIR)/make/linux/makefiles/mapfile-vers-debug
VERSION = optimized
-SYSDEFS += -DASSERT -DFASTDEBUG
+SYSDEFS += -DASSERT
PICFLAGS = DEFAULT
--- a/hotspot/make/linux/makefiles/jvmg.make Thu Apr 18 10:30:11 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-#
-# Copyright (c) 1999, 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.
-#
-#
-
-# Sets make macros for making debug version of VM
-
-# Compiler specific DEBUG_CFLAGS are passed in from gcc.make, sparcWorks.make
-DEBUG_CFLAGS/DEFAULT= $(DEBUG_CFLAGS)
-DEBUG_CFLAGS/BYFILE = $(DEBUG_CFLAGS/$@)$(DEBUG_CFLAGS/DEFAULT$(DEBUG_CFLAGS/$@))
-
-# _NMT_NOINLINE_ informs NMT that no inlining by Compiler
-CFLAGS += $(DEBUG_CFLAGS/BYFILE) -D_NMT_NOINLINE_
-
-# Set the environment variable HOTSPARC_GENERIC to "true"
-# to inhibit the effect of the previous line on CFLAGS.
-
-# Linker mapfile
-MAPFILE = $(GAMMADIR)/make/linux/makefiles/mapfile-vers-debug
-
-VERSION = debug
-SYSDEFS += -DASSERT -DDEBUG
-PICFLAGS = DEFAULT
--- a/hotspot/make/linux/makefiles/profiled.make Thu Apr 18 10:30:11 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-#
-# Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-#
-
-# Sets make macros for making profiled version of Gamma VM
-# (It is also optimized.)
-
-CFLAGS += -pg
-AOUT_FLAGS += -pg
-LDNOMAP = true
--- a/hotspot/make/linux/makefiles/vm.make Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/linux/makefiles/vm.make Fri Apr 19 09:58:05 2013 -0700
@@ -189,7 +189,7 @@
Src_Dirs/SHARK := $(CORE_PATHS) $(SHARK_PATHS)
Src_Dirs := $(Src_Dirs/$(TYPE))
-COMPILER2_SPECIFIC_FILES := opto libadt bcEscapeAnalyzer.cpp chaitin\* c2_\* runtime_\*
+COMPILER2_SPECIFIC_FILES := opto libadt bcEscapeAnalyzer.cpp c2_\* runtime_\*
COMPILER1_SPECIFIC_FILES := c1_\*
SHARK_SPECIFIC_FILES := shark
ZERO_SPECIFIC_FILES := zero
--- a/hotspot/make/solaris/Makefile Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/solaris/Makefile Fri Apr 19 09:58:05 2013 -0700
@@ -120,37 +120,29 @@
#
# debug compiler2 <os>_<arch>_compiler2/debug
# fastdebug compiler2 <os>_<arch>_compiler2/fastdebug
-# jvmg compiler2 <os>_<arch>_compiler2/jvmg
# optimized compiler2 <os>_<arch>_compiler2/optimized
-# profiled compiler2 <os>_<arch>_compiler2/profiled
# product compiler2 <os>_<arch>_compiler2/product
#
# debug1 compiler1 <os>_<arch>_compiler1/debug
# fastdebug1 compiler1 <os>_<arch>_compiler1/fastdebug
-# jvmg1 compiler1 <os>_<arch>_compiler1/jvmg
# optimized1 compiler1 <os>_<arch>_compiler1/optimized
-# profiled1 compiler1 <os>_<arch>_compiler1/profiled
# product1 compiler1 <os>_<arch>_compiler1/product
#
# debugcore core <os>_<arch>_core/debug
# fastdebugcore core <os>_<arch>_core/fastdebug
-# jvmgcore core <os>_<arch>_core/jvmg
# optimizedcore core <os>_<arch>_core/optimized
-# profiledcore core <os>_<arch>_core/profiled
# productcore core <os>_<arch>_core/product
#
# What you get with each target:
#
-# debug* - "thin" libjvm - debug info linked into the gamma launcher
+# debug* - debug compile with asserts enabled
# fastdebug* - optimized compile, but with asserts enabled
-# jvmg* - "fat" libjvm - debug info linked into libjvm.so
# optimized* - optimized compile, no asserts
-# profiled* - gprof
# product* - the shippable thing: optimized compile, no asserts, -DPRODUCT
# This target list needs to be coordinated with the usage message
# in the build.sh script:
-TARGETS = debug jvmg fastdebug optimized profiled product
+TARGETS = debug fastdebug optimized product
SUBDIR_DOCS = $(OSNAME)_$(BUILDARCH)_docs
SUBDIRS_C1 = $(addprefix $(OSNAME)_$(BUILDARCH)_compiler1/,$(TARGETS))
@@ -267,11 +259,21 @@
$(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/makefiles/jvmti.make $(MFLAGS) $(BUILDTREE_VARS) JvmtiOutDir=$(SUBDIR_DOCS) BUILD_FLAVOR=product jvmtidocs
# Synonyms for win32-like targets.
-compiler2: jvmg product
+compiler2: debug product
+
+compiler1: debug1 product1
+
+core: debugcore productcore
-compiler1: jvmg1 product1
+warn_jvmg_deprecated:
+ echo "Warning: The jvmg target has been replaced with debug"
+ echo "Warning: Please update your usage"
-core: jvmgcore productcore
+jvmg: warn_jvmg_deprecated debug
+
+jvmg1: warn_jvmg_deprecated debug1
+
+jvmgcore: warn_jvmg_deprecated debugcore
clean_docs:
rm -rf $(SUBDIR_DOCS)
--- a/hotspot/make/solaris/makefiles/buildtree.make Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/solaris/makefiles/buildtree.make Fri Apr 19 09:58:05 2013 -0700
@@ -19,7 +19,7 @@
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
-#
+#
#
# Usage:
@@ -46,11 +46,11 @@
# Makefile - for "make foo"
# flags.make - with macro settings
# vm.make - to support making "$(MAKE) -v vm.make" in makefiles
-# adlc.make -
+# adlc.make -
# jvmti.make - generate JVMTI bindings from the spec (JSR-163)
# sa.make - generate SA jar file and natives
# env.[ck]sh - environment settings
-#
+#
# The makefiles are split this way so that "make foo" will run faster by not
# having to read the dependency files for the vm.
@@ -69,7 +69,7 @@
GCC_LIB = /usr/local/lib
else
PLATFORM_FILE = $(GAMMADIR)/make/$(OS_FAMILY)/platform_$(BUILDARCH)
-GCC_LIB =
+GCC_LIB =
endif
ifdef FORCE_TIERED
@@ -110,7 +110,7 @@
$(PLATFORM_DIR)/generated/adfiles \
$(PLATFORM_DIR)/generated/jvmtifiles
-TARGETS = debug fastdebug jvmg optimized product profiled
+TARGETS = debug fastdebug optimized product
SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS))
# For dependencies and recursive makes.
@@ -153,7 +153,7 @@
endif
endif
-BUILDTREE_VARS += HOTSPOT_RELEASE_VERSION=$(HS_BUILD_VER) HOTSPOT_BUILD_VERSION= JRE_RELEASE_VERSION=$(JRE_RELEASE_VERSION)
+BUILDTREE_VARS += HOTSPOT_RELEASE_VERSION=$(HS_BUILD_VER) HOTSPOT_BUILD_VERSION= JRE_RELEASE_VERSION=$(JRE_RELEASE_VERSION)
BUILDTREE = \
$(MAKE) -f $(BUILDTREE_MAKE) $(BUILDTREE_TARGETS) $(BUILDTREE_VARS)
@@ -172,8 +172,8 @@
$(QUIETLY) mkdir -p $@
# Convenience macro which takes a source relative path, applies $(1) to the
-# absolute path, and then replaces $(GAMMADIR) in the result with a
-# literal "$(GAMMADIR)/" suitable for inclusion in a Makefile.
+# absolute path, and then replaces $(GAMMADIR) in the result with a
+# literal "$(GAMMADIR)/" suitable for inclusion in a Makefile.
gamma-path=$(subst $(GAMMADIR),\$$(GAMMADIR),$(call $(1),$(HS_COMMON_SRC)/$(2)))
# This bit is needed to enable local rebuilds.
@@ -274,8 +274,6 @@
$(QUIETLY) ( \
$(BUILDTREE_COMMENT); \
echo; \
- [ "$(TARGET)" = profiled ] && \
- echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/optimized.make"; \
echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(TARGET).make"; \
) > $@
@@ -366,7 +364,7 @@
$(QUIETLY) ( \
$(BUILDTREE_COMMENT); \
echo "JDK=${JAVA_HOME}"; \
- ) > $@
+ ) > $@
FORCE:
--- a/hotspot/make/solaris/makefiles/debug.make Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/solaris/makefiles/debug.make Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+# 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
@@ -19,7 +19,7 @@
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
-#
+#
#
# Sets make macros for making debug version of VM
@@ -37,22 +37,20 @@
endif
endif
-CFLAGS += $(DEBUG_CFLAGS/BYFILE)
+# _NMT_NOINLINE_ informs NMT that no inlining by Compiler
+CFLAGS += $(DEBUG_CFLAGS/BYFILE) -D_NMT_NOINLINE_
+
+# Set the environment variable HOTSPARC_GENERIC to "true"
+# to inhibit the effect of the previous line on CFLAGS.
# Linker mapfiles
MAPFILE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers \
$(GAMMADIR)/make/solaris/makefiles/mapfile-vers-debug
-# This mapfile is only needed when compiling with dtrace support,
+# This mapfile is only needed when compiling with dtrace support,
# and mustn't be otherwise.
MAPFILE_DTRACE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-$(TYPE)
-_JUNK_ := $(shell echo >&2 ""\
- "-------------------------------------------------------------------------\n" \
- "WARNING: 'gnumake debug' is deprecated. It will be removed in the future.\n" \
- "Please use 'gnumake jvmg' to build debug JVM. \n" \
- "-------------------------------------------------------------------------\n")
-
VERSION = debug
-SYSDEFS += -DASSERT -DDEBUG
+SYSDEFS += -DASSERT
PICFLAGS = DEFAULT
--- a/hotspot/make/solaris/makefiles/defs.make Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/solaris/makefiles/defs.make Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 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
@@ -19,7 +19,7 @@
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
-#
+#
#
# The common definitions for hotspot solaris builds.
@@ -172,9 +172,6 @@
# Library suffix
LIBRARY_SUFFIX=so
-# FIXUP: The subdirectory for a debug build is NOT the same on all platforms
-VM_DEBUG=jvmg
-
EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html
# client and server subdirectories have symbolic links to ../libjsig.$(LIBRARY_SUFFIX)
@@ -221,8 +218,8 @@
endif
ifeq ($(JVM_VARIANT_CLIENT),true)
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
- EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX)
- EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_db.$(LIBRARY_SUFFIX)
+ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX)
+ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_db.$(LIBRARY_SUFFIX)
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_dtrace.$(LIBRARY_SUFFIX)
ifeq ($(ARCH_DATA_MODEL),32)
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_db.$(LIBRARY_SUFFIX)
@@ -257,4 +254,4 @@
EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.debuginfo
endif
endif
-EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar
+EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar
--- a/hotspot/make/solaris/makefiles/fastdebug.make Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/solaris/makefiles/fastdebug.make Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1998, 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
@@ -19,7 +19,7 @@
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
-#
+#
#
# Sets make macros for making debug version of VM
@@ -118,10 +118,10 @@
MAPFILE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers \
$(GAMMADIR)/make/solaris/makefiles/mapfile-vers-debug
-# This mapfile is only needed when compiling with dtrace support,
+# This mapfile is only needed when compiling with dtrace support,
# and mustn't be otherwise.
MAPFILE_DTRACE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-$(TYPE)
VERSION = optimized
-SYSDEFS += -DASSERT -DFASTDEBUG -DCHECK_UNHANDLED_OOPS
+SYSDEFS += -DASSERT -DCHECK_UNHANDLED_OOPS
PICFLAGS = DEFAULT
--- a/hotspot/make/solaris/makefiles/jvmg.make Thu Apr 18 10:30:11 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-#
-# Copyright (c) 1999, 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.
-#
-#
-
-# Sets make macros for making debug version of VM
-
-# Compiler specific DEBUG_CFLAGS are passed in from gcc.make, sparcWorks.make
-DEBUG_CFLAGS/DEFAULT= $(DEBUG_CFLAGS)
-DEBUG_CFLAGS/BYFILE = $(DEBUG_CFLAGS/$@)$(DEBUG_CFLAGS/DEFAULT$(DEBUG_CFLAGS/$@))
-
-ifeq ("${Platform_compiler}", "sparcWorks")
-
-ifeq ($(COMPILER_REV_NUMERIC),508)
- # SS11 SEGV when compiling with -g and -xarch=v8, using different backend
- DEBUG_CFLAGS/compileBroker.o = $(DEBUG_CFLAGS) -xO0
- DEBUG_CFLAGS/jvmtiTagMap.o = $(DEBUG_CFLAGS) -xO0
-endif
-endif
-
-# _NMT_NOINLINE_ informs NMT that no inlining by Compiler
-CFLAGS += $(DEBUG_CFLAGS/BYFILE) -D_NMT_NOINLINE_
-
-# Set the environment variable HOTSPARC_GENERIC to "true"
-# to inhibit the effect of the previous line on CFLAGS.
-
-# Linker mapfiles
-MAPFILE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers \
- $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-debug
-
-# This mapfile is only needed when compiling with dtrace support,
-# and mustn't be otherwise.
-MAPFILE_DTRACE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-$(TYPE)
-
-VERSION = debug
-SYSDEFS += -DASSERT -DDEBUG
-PICFLAGS = DEFAULT
--- a/hotspot/make/solaris/makefiles/profiled.make Thu Apr 18 10:30:11 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-#
-# Copyright (c) 1998, 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.
-#
-#
-
-# Sets make macros for making profiled version of Gamma VM
-# (It is also optimized.)
-
-CFLAGS += -pg
-
-# On x86 Solaris 2.6, 7, and 8 if LD_LIBRARY_PATH has /usr/lib in it then
-# adlc linked with -pg puts out empty header files. To avoid linking adlc
-# with -pg the profile flag is split out separately and used in rules.make
-
-PROF_AOUT_FLAGS += -pg
-
-# To do a profiled build of the product, such as for generating the
-# reordering file, set PROFILE_PRODUCT. Otherwise the reordering file will
-# contain references to functions which are not defined in the PRODUCT build.
-
-ifdef PROFILE_PRODUCT
- SYSDEFS += -DPRODUCT
-endif
-
-LDNOMAP = true
--- a/hotspot/make/solaris/makefiles/vm.make Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/solaris/makefiles/vm.make Fri Apr 19 09:58:05 2013 -0700
@@ -202,7 +202,7 @@
Src_Dirs/SHARK := $(CORE_PATHS)
Src_Dirs := $(Src_Dirs/$(TYPE))
-COMPILER2_SPECIFIC_FILES := opto libadt bcEscapeAnalyzer.cpp chaitin\* c2_\* runtime_\*
+COMPILER2_SPECIFIC_FILES := opto libadt bcEscapeAnalyzer.cpp c2_\* runtime_\*
COMPILER1_SPECIFIC_FILES := c1_\*
SHARK_SPECIFIC_FILES := shark
ZERO_SPECIFIC_FILES := zero
--- a/hotspot/make/windows/build.make Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/windows/build.make Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1998, 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
@@ -235,18 +235,14 @@
cd $(variantDir)
nmake -nologo -f $(WorkSpace)\make\windows\makefiles\top.make BUILD_FLAVOR=product ARCH=$(ARCH)
-# The debug or jvmg (all the same thing) is an optional build
-debug jvmg: checks $(variantDir) $(variantDir)\local.make sanity
+# The debug build is an optional build
+debug: checks $(variantDir) $(variantDir)\local.make sanity
cd $(variantDir)
nmake -nologo -f $(WorkSpace)\make\windows\makefiles\top.make BUILD_FLAVOR=debug ARCH=$(ARCH)
fastdebug: checks $(variantDir) $(variantDir)\local.make sanity
cd $(variantDir)
nmake -nologo -f $(WorkSpace)\make\windows\makefiles\top.make BUILD_FLAVOR=fastdebug ARCH=$(ARCH)
-develop: checks $(variantDir) $(variantDir)\local.make sanity
- cd $(variantDir)
- nmake -nologo -f $(WorkSpace)\make\windows\makefiles\top.make BUILD_FLAVOR=product DEVELOP=1 ARCH=$(ARCH)
-
# target to create just the directory structure
tree: checks $(variantDir) $(variantDir)\local.make sanity
mkdir $(variantDir)\product
--- a/hotspot/make/windows/create_obj_files.sh Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/windows/create_obj_files.sh Fri Apr 19 09:58:05 2013 -0700
@@ -114,7 +114,7 @@
"shark") Src_Dirs="${CORE_PATHS}" ;;
esac
-COMPILER2_SPECIFIC_FILES="opto libadt bcEscapeAnalyzer.cpp chaitin* c2_* runtime_*"
+COMPILER2_SPECIFIC_FILES="opto libadt bcEscapeAnalyzer.cpp c2_* runtime_*"
COMPILER1_SPECIFIC_FILES="c1_*"
SHARK_SPECIFIC_FILES="shark"
ZERO_SPECIFIC_FILES="zero"
--- a/hotspot/make/windows/makefiles/defs.make Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/windows/makefiles/defs.make Fri Apr 19 09:58:05 2013 -0700
@@ -19,7 +19,7 @@
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
-#
+#
#
# The common definitions for hotspot windows builds.
@@ -209,8 +209,6 @@
ifneq (,$(findstring MINGW,$(SYSTEM_UNAME)))
USING_MINGW=true
endif
-# FIXUP: The subdirectory for a debug build is NOT the same on all platforms
-VM_DEBUG=debug
# Windows wants particular paths due to nmake (must be after macros defined)
# It is important that gnumake invokes nmake with C:\\...\\ formated
@@ -292,7 +290,7 @@
MAKE_ARGS += BUILD_WIN_SA=1
endif
-# Propagate compiler and tools paths from configure to nmake.
+# Propagate compiler and tools paths from configure to nmake.
# Need to make sure they contain \\ and not /.
ifneq ($(SPEC),)
ifeq ($(USING_CYGWIN), true)
--- a/hotspot/make/windows/makefiles/vm.make Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/windows/makefiles/vm.make Fri Apr 19 09:58:05 2013 -0700
@@ -31,11 +31,7 @@
ALTSRC=$(WorkSpace)\src\closed
!ifdef RELEASE
-!ifdef DEVELOP
-CXX_FLAGS=$(CXX_FLAGS) /D "DEBUG"
-!else
CXX_FLAGS=$(CXX_FLAGS) /D "PRODUCT"
-!endif
!else
CXX_FLAGS=$(CXX_FLAGS) /D "ASSERT"
!endif
@@ -186,7 +182,7 @@
# Special case files not using precompiled header files.
-c1_RInfo_$(Platform_arch).obj: $(WorkSpace)\src\cpu\$(Platform_arch)\vm\c1_RInfo_$(Platform_arch).cpp
+c1_RInfo_$(Platform_arch).obj: $(WorkSpace)\src\cpu\$(Platform_arch)\vm\c1_RInfo_$(Platform_arch).cpp
$(CXX) $(CXX_FLAGS) $(CXX_DONT_USE_PCH) /c $(WorkSpace)\src\cpu\$(Platform_arch)\vm\c1_RInfo_$(Platform_arch).cpp
os_windows.obj: $(WorkSpace)\src\os\windows\vm\os_windows.cpp
--- a/hotspot/make/windows/projectfiles/compiler2/ADLCompiler.dsp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/windows/projectfiles/compiler2/ADLCompiler.dsp Fri Apr 19 09:58:05 2013 -0700
@@ -67,7 +67,7 @@
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /ML /W3 /WX /Gm /GX /Zi /Od /I "." /I "$(HotSpotWorkSpace)\src\share\vm\opto" /I "$(HotSpotWorkSpace)\src\share\vm\prims" /I "$(HotSpotWorkSpace)\src\share\vm\lookup" /I "$(HotSpotWorkSpace)\src\share\vm\interpreter" /I "$(HotSpotWorkSpace)\src\share\vm\asm" /I "$(HotSpotWorkSpace)\src\share\vm\compiler" /I "$(HotSpotWorkSpace)\src\share\vm\utilities" /I "$(HotSpotWorkSpace)\src\share\vm\code" /I "$(HotSpotWorkSpace)\src\share\vm\oops" /I "$(HotSpotWorkSpace)\src\share\vm\runtime" /I "$(HotSpotWorkSpace)\src\share\vm\memory" /I "$(HotSpotWorkSpace)\src\share\vm\libadt" /I "$(HotSpotWorkSpace)\src\cpu\i486\vm" /I "$(HotSpotWorkSpace)\src\os\win32\vm" /D "WIN32" /D "DEBUG" /D "_WINDOWS" /D "ASSERT" /Fr /FD /c
+# ADD CPP /nologo /ML /W3 /WX /Gm /GX /Zi /Od /I "." /I "$(HotSpotWorkSpace)\src\share\vm\opto" /I "$(HotSpotWorkSpace)\src\share\vm\prims" /I "$(HotSpotWorkSpace)\src\share\vm\lookup" /I "$(HotSpotWorkSpace)\src\share\vm\interpreter" /I "$(HotSpotWorkSpace)\src\share\vm\asm" /I "$(HotSpotWorkSpace)\src\share\vm\compiler" /I "$(HotSpotWorkSpace)\src\share\vm\utilities" /I "$(HotSpotWorkSpace)\src\share\vm\code" /I "$(HotSpotWorkSpace)\src\share\vm\oops" /I "$(HotSpotWorkSpace)\src\share\vm\runtime" /I "$(HotSpotWorkSpace)\src\share\vm\memory" /I "$(HotSpotWorkSpace)\src\share\vm\libadt" /I "$(HotSpotWorkSpace)\src\cpu\i486\vm" /I "$(HotSpotWorkSpace)\src\os\win32\vm" /D "WIN32" /D "_WINDOWS" /D "ASSERT" /Fr /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
--- a/hotspot/make/windows/projectfiles/tiered/ADLCompiler.dsp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/make/windows/projectfiles/tiered/ADLCompiler.dsp Fri Apr 19 09:58:05 2013 -0700
@@ -67,7 +67,7 @@
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /ML /W3 /WX /Gm /GX /Zi /Od /I "." /I "$(HotSpotWorkSpace)\src\share\vm\opto" /I "$(HotSpotWorkSpace)\src\share\vm\prims" /I "$(HotSpotWorkSpace)\src\share\vm\lookup" /I "$(HotSpotWorkSpace)\src\share\vm\interpreter" /I "$(HotSpotWorkSpace)\src\share\vm\asm" /I "$(HotSpotWorkSpace)\src\share\vm\compiler" /I "$(HotSpotWorkSpace)\src\share\vm\utilities" /I "$(HotSpotWorkSpace)\src\share\vm\code" /I "$(HotSpotWorkSpace)\src\share\vm\oops" /I "$(HotSpotWorkSpace)\src\share\vm\runtime" /I "$(HotSpotWorkSpace)\src\share\vm\memory" /I "$(HotSpotWorkSpace)\src\share\vm\libadt" /I "$(HotSpotWorkSpace)\src\cpu\i486\vm" /I "$(HotSpotWorkSpace)\src\os\win32\vm" /D "WIN32" /D "DEBUG" /D "_WINDOWS" /D "ASSERT" /Fr /FD /c
+# ADD CPP /nologo /ML /W3 /WX /Gm /GX /Zi /Od /I "." /I "$(HotSpotWorkSpace)\src\share\vm\opto" /I "$(HotSpotWorkSpace)\src\share\vm\prims" /I "$(HotSpotWorkSpace)\src\share\vm\lookup" /I "$(HotSpotWorkSpace)\src\share\vm\interpreter" /I "$(HotSpotWorkSpace)\src\share\vm\asm" /I "$(HotSpotWorkSpace)\src\share\vm\compiler" /I "$(HotSpotWorkSpace)\src\share\vm\utilities" /I "$(HotSpotWorkSpace)\src\share\vm\code" /I "$(HotSpotWorkSpace)\src\share\vm\oops" /I "$(HotSpotWorkSpace)\src\share\vm\runtime" /I "$(HotSpotWorkSpace)\src\share\vm\memory" /I "$(HotSpotWorkSpace)\src\share\vm\libadt" /I "$(HotSpotWorkSpace)\src\cpu\i486\vm" /I "$(HotSpotWorkSpace)\src\os\win32\vm" /D "WIN32" /D "_WINDOWS" /D "ASSERT" /Fr /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
--- a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1000,9 +1000,10 @@
DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
assert(deopt_blob != NULL, "deoptimization blob must have been created");
restore_live_registers(sasm);
- __ restore();
- __ br(Assembler::always, false, Assembler::pt, deopt_blob->unpack_with_reexecution(), relocInfo::runtime_call_type);
- __ delayed()->nop();
+
+ AddressLiteral dest(deopt_blob->unpack_with_reexecution());
+ __ jump_to(dest, O0);
+ __ delayed()->restore();
}
break;
--- a/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -404,14 +404,20 @@
// ??: invocation counter
//
void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) {
+ Label done;
+ const Register Rcounters = G3_scratch;
+
+ __ ld_ptr(STATE(_method), G5_method);
+ __ get_method_counters(G5_method, Rcounters, done);
+
// Update standard invocation counters
- __ increment_invocation_counter(O0, G3_scratch);
- if (ProfileInterpreter) { // %%% Merge this into MethodData*
- __ ld_ptr(STATE(_method), G3_scratch);
- Address interpreter_invocation_counter(G3_scratch, 0, in_bytes(Method::interpreter_invocation_counter_offset()));
- __ ld(interpreter_invocation_counter, G3_scratch);
- __ inc(G3_scratch);
- __ st(G3_scratch, interpreter_invocation_counter);
+ __ increment_invocation_counter(Rcounters, O0, G4_scratch);
+ if (ProfileInterpreter) {
+ Address interpreter_invocation_counter(Rcounters, 0,
+ in_bytes(MethodCounters::interpreter_invocation_counter_offset()));
+ __ ld(interpreter_invocation_counter, G4_scratch);
+ __ inc(G4_scratch);
+ __ st(G4_scratch, interpreter_invocation_counter);
}
Address invocation_limit(G3_scratch, (address)&InvocationCounter::InterpreterInvocationLimit);
@@ -420,7 +426,7 @@
__ cmp(O0, G3_scratch);
__ br(Assembler::greaterEqualUnsigned, false, Assembler::pn, *overflow);
__ delayed()->nop();
-
+ __ bind(done);
}
address InterpreterGenerator::generate_empty_entry(void) {
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -304,7 +304,7 @@
// The sender should positively be an nmethod or call_stub. On sparc we might in fact see something else.
// The cause of this is because at a save instruction the O7 we get is a leftover from an earlier
- // window use. So if a runtime stub creates two frames (common in fastdebug/jvmg) then we see the
+ // window use. So if a runtime stub creates two frames (common in fastdebug/debug) then we see the
// stale pc. So if the sender blob is not something we'd expect we have little choice but to declare
// the stack unwalkable. pd_get_top_frame_for_signal_handler tries to recover from this by unwinding
// that initial frame and retrying.
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -30,6 +30,7 @@
#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"
@@ -2086,19 +2087,28 @@
#endif /* CC_INTERP */
-void InterpreterMacroAssembler::increment_invocation_counter( Register Rtmp, Register Rtmp2 ) {
+void InterpreterMacroAssembler::get_method_counters(Register method,
+ Register Rcounters,
+ Label& skip) {
+ Label has_counters;
+ Address method_counters(method, in_bytes(Method::method_counters_offset()));
+ ld_ptr(method_counters, Rcounters);
+ br_notnull_short(Rcounters, Assembler::pt, has_counters);
+ call_VM(noreg, CAST_FROM_FN_PTR(address,
+ InterpreterRuntime::build_method_counters), method);
+ ld_ptr(method_counters, Rcounters);
+ br_null_short(Rcounters, Assembler::pn, skip); // No MethodCounters, OutOfMemory
+ bind(has_counters);
+}
+
+void InterpreterMacroAssembler::increment_invocation_counter( Register Rcounters, Register Rtmp, Register Rtmp2 ) {
assert(UseCompiler, "incrementing must be useful");
-#ifdef CC_INTERP
- Address inv_counter(G5_method, Method::invocation_counter_offset() +
- InvocationCounter::counter_offset());
- Address be_counter (G5_method, Method::backedge_counter_offset() +
+ assert_different_registers(Rcounters, Rtmp, Rtmp2);
+
+ Address inv_counter(Rcounters, MethodCounters::invocation_counter_offset() +
InvocationCounter::counter_offset());
-#else
- Address inv_counter(Lmethod, Method::invocation_counter_offset() +
- InvocationCounter::counter_offset());
- Address be_counter (Lmethod, Method::backedge_counter_offset() +
- InvocationCounter::counter_offset());
-#endif /* CC_INTERP */
+ Address be_counter (Rcounters, MethodCounters::backedge_counter_offset() +
+ InvocationCounter::counter_offset());
int delta = InvocationCounter::count_increment;
// Load each counter in a register
@@ -2122,19 +2132,15 @@
// Note that this macro must leave the backedge_count + invocation_count in Rtmp!
}
-void InterpreterMacroAssembler::increment_backedge_counter( Register Rtmp, Register Rtmp2 ) {
+void InterpreterMacroAssembler::increment_backedge_counter( Register Rcounters, Register Rtmp, Register Rtmp2 ) {
assert(UseCompiler, "incrementing must be useful");
-#ifdef CC_INTERP
- Address be_counter (G5_method, Method::backedge_counter_offset() +
- InvocationCounter::counter_offset());
- Address inv_counter(G5_method, Method::invocation_counter_offset() +
+ assert_different_registers(Rcounters, Rtmp, Rtmp2);
+
+ Address be_counter (Rcounters, MethodCounters::backedge_counter_offset() +
InvocationCounter::counter_offset());
-#else
- Address be_counter (Lmethod, Method::backedge_counter_offset() +
- InvocationCounter::counter_offset());
- Address inv_counter(Lmethod, Method::invocation_counter_offset() +
- InvocationCounter::counter_offset());
-#endif /* CC_INTERP */
+ Address inv_counter(Rcounters, MethodCounters::invocation_counter_offset() +
+ InvocationCounter::counter_offset());
+
int delta = InvocationCounter::count_increment;
// Load each counter in a register
ld( be_counter, Rtmp );
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -263,8 +263,9 @@
void compute_stack_base( Register Rdest );
#endif /* CC_INTERP */
- void increment_invocation_counter( Register Rtmp, Register Rtmp2 );
- void increment_backedge_counter( Register Rtmp, Register Rtmp2 );
+ void get_method_counters(Register method, Register Rcounters, Label& skip);
+ void increment_invocation_counter( Register Rcounters, Register Rtmp, Register Rtmp2 );
+ void increment_backedge_counter( Register Rcounters, Register Rtmp, Register Rtmp2 );
#ifndef CC_INTERP
void test_backedge_count_for_osr( Register backedge_count, Register branch_bcp, Register Rtmp );
--- a/hotspot/src/cpu/sparc/vm/sparc.ad Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
//
-// Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 1998, 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
@@ -8223,10 +8223,25 @@
format %{ "SUBcc $p,$q,$p\t! p' = p-q\n\t"
"ADD $p,$y,$tmp\t! g3=p-q+y\n\t"
"MOVlt $tmp,$p\t! p' < 0 ? p'+y : p'" %}
- ins_encode( enc_cadd_cmpLTMask(p, q, y, tmp) );
- ins_pipe( cadd_cmpltmask );
-%}
-
+ ins_encode(enc_cadd_cmpLTMask(p, q, y, tmp));
+ ins_pipe(cadd_cmpltmask);
+%}
+
+instruct and_cmpLTMask(iRegI p, iRegI q, iRegI y, flagsReg ccr) %{
+ match(Set p (AndI (CmpLTMask p q) y));
+ effect(KILL ccr);
+ ins_cost(DEFAULT_COST*3);
+
+ format %{ "CMP $p,$q\n\t"
+ "MOV $y,$p\n\t"
+ "MOVge G0,$p" %}
+ ins_encode %{
+ __ cmp($p$$Register, $q$$Register);
+ __ mov($y$$Register, $p$$Register);
+ __ movcc(Assembler::greaterEqual, false, Assembler::icc, G0, $p$$Register);
+ %}
+ ins_pipe(ialu_reg_reg_ialu);
+%}
//-----------------------------------------------------------------
// Direct raw moves between float and general registers using VIS3.
--- a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -292,11 +292,15 @@
// ??: invocation counter
//
void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) {
- // Note: In tiered we increment either counters in Method* or in MDO depending if we're profiling or not.
+ // Note: In tiered we increment either counters in MethodCounters* or in
+ // MDO depending if we're profiling or not.
+ const Register Rcounters = G3_scratch;
+ Label done;
+
if (TieredCompilation) {
const int increment = InvocationCounter::count_increment;
const int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift;
- Label no_mdo, done;
+ Label no_mdo;
if (ProfileInterpreter) {
// If no method data exists, go to profile_continue.
__ ld_ptr(Lmethod, Method::method_data_offset(), G4_scratch);
@@ -311,23 +315,26 @@
__ ba_short(done);
}
- // Increment counter in Method*
+ // Increment counter in MethodCounters*
__ bind(no_mdo);
- Address invocation_counter(Lmethod,
- in_bytes(Method::invocation_counter_offset()) +
- in_bytes(InvocationCounter::counter_offset()));
+ Address invocation_counter(Rcounters,
+ in_bytes(MethodCounters::invocation_counter_offset()) +
+ in_bytes(InvocationCounter::counter_offset()));
+ __ get_method_counters(Lmethod, Rcounters, done);
__ increment_mask_and_jump(invocation_counter, increment, mask,
- G3_scratch, Lscratch,
+ G4_scratch, Lscratch,
Assembler::zero, overflow);
__ bind(done);
} else {
// Update standard invocation counters
- __ increment_invocation_counter(O0, G3_scratch);
- if (ProfileInterpreter) { // %%% Merge this into MethodData*
- Address interpreter_invocation_counter(Lmethod,in_bytes(Method::interpreter_invocation_counter_offset()));
- __ ld(interpreter_invocation_counter, G3_scratch);
- __ inc(G3_scratch);
- __ st(G3_scratch, interpreter_invocation_counter);
+ __ get_method_counters(Lmethod, Rcounters, done);
+ __ increment_invocation_counter(Rcounters, O0, G4_scratch);
+ if (ProfileInterpreter) {
+ Address interpreter_invocation_counter(Rcounters,
+ in_bytes(MethodCounters::interpreter_invocation_counter_offset()));
+ __ ld(interpreter_invocation_counter, G4_scratch);
+ __ inc(G4_scratch);
+ __ st(G4_scratch, interpreter_invocation_counter);
}
if (ProfileInterpreter && profile_method != NULL) {
@@ -345,6 +352,7 @@
__ cmp(O0, G3_scratch);
__ br(Assembler::greaterEqualUnsigned, false, Assembler::pn, *overflow); // Far distance
__ delayed()->nop();
+ __ bind(done);
}
}
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -63,6 +63,13 @@
noreg /* pre_val */,
tmp, true /*preserve_o_regs*/);
+ // G1 barrier needs uncompressed oop for region cross check.
+ Register new_val = val;
+ if (UseCompressedOops && val != G0) {
+ new_val = tmp;
+ __ mov(val, new_val);
+ }
+
if (index == noreg ) {
assert(Assembler::is_simm13(offset), "fix this code");
__ store_heap_oop(val, base, offset);
@@ -79,7 +86,7 @@
__ add(base, index, base);
}
}
- __ g1_write_barrier_post(base, val, tmp);
+ __ g1_write_barrier_post(base, new_val, tmp);
}
}
break;
@@ -1604,9 +1611,8 @@
// Normal (non-jsr) branch handling
// Save the current Lbcp
- const Register O0_cur_bcp = O0;
- __ mov( Lbcp, O0_cur_bcp );
-
+ const Register l_cur_bcp = Lscratch;
+ __ mov( Lbcp, l_cur_bcp );
bool increment_invocation_counter_for_backward_branches = UseCompiler && UseLoopCounter;
if ( increment_invocation_counter_for_backward_branches ) {
@@ -1616,6 +1622,9 @@
// Bump bytecode pointer by displacement (take the branch)
__ delayed()->add( O1_disp, Lbcp, Lbcp ); // add to bc addr
+ const Register Rcounters = G3_scratch;
+ __ get_method_counters(Lmethod, Rcounters, Lforward);
+
if (TieredCompilation) {
Label Lno_mdo, Loverflow;
int increment = InvocationCounter::count_increment;
@@ -1628,21 +1637,22 @@
// Increment backedge counter in the MDO
Address mdo_backedge_counter(G4_scratch, in_bytes(MethodData::backedge_counter_offset()) +
in_bytes(InvocationCounter::counter_offset()));
- __ increment_mask_and_jump(mdo_backedge_counter, increment, mask, G3_scratch, Lscratch,
+ __ increment_mask_and_jump(mdo_backedge_counter, increment, mask, G3_scratch, O0,
Assembler::notZero, &Lforward);
__ ba_short(Loverflow);
}
- // If there's no MDO, increment counter in Method*
+ // If there's no MDO, increment counter in MethodCounters*
__ bind(Lno_mdo);
- Address backedge_counter(Lmethod, in_bytes(Method::backedge_counter_offset()) +
- in_bytes(InvocationCounter::counter_offset()));
- __ increment_mask_and_jump(backedge_counter, increment, mask, G3_scratch, Lscratch,
+ Address backedge_counter(Rcounters,
+ in_bytes(MethodCounters::backedge_counter_offset()) +
+ in_bytes(InvocationCounter::counter_offset()));
+ __ increment_mask_and_jump(backedge_counter, increment, mask, G4_scratch, O0,
Assembler::notZero, &Lforward);
__ bind(Loverflow);
// notify point for loop, pass branch bytecode
- __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), O0_cur_bcp);
+ __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), l_cur_bcp);
// Was an OSR adapter generated?
// O0 = osr nmethod
@@ -1679,15 +1689,15 @@
} else {
// Update Backedge branch separately from invocations
const Register G4_invoke_ctr = G4;
- __ increment_backedge_counter(G4_invoke_ctr, G1_scratch);
+ __ increment_backedge_counter(Rcounters, G4_invoke_ctr, G1_scratch);
if (ProfileInterpreter) {
__ test_invocation_counter_for_mdp(G4_invoke_ctr, G3_scratch, Lforward);
if (UseOnStackReplacement) {
- __ test_backedge_count_for_osr(O2_bumped_count, O0_cur_bcp, G3_scratch);
+ __ test_backedge_count_for_osr(O2_bumped_count, l_cur_bcp, G3_scratch);
}
} else {
if (UseOnStackReplacement) {
- __ test_backedge_count_for_osr(G4_invoke_ctr, O0_cur_bcp, G3_scratch);
+ __ test_backedge_count_for_osr(G4_invoke_ctr, l_cur_bcp, G3_scratch);
}
}
}
--- a/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -570,20 +570,28 @@
// rcx: invocation counter
//
void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) {
-
- const Address invocation_counter(rbx, Method::invocation_counter_offset() + InvocationCounter::counter_offset());
- const Address backedge_counter (rbx, Method::backedge_counter_offset() + InvocationCounter::counter_offset());
-
- if (ProfileInterpreter) { // %%% Merge this into MethodData*
- __ incrementl(Address(rbx,Method::interpreter_invocation_counter_offset()));
+ Label done;
+ const Address invocation_counter(rax,
+ MethodCounters::invocation_counter_offset() +
+ InvocationCounter::counter_offset());
+ const Address backedge_counter (rax,
+ MethodCounter::backedge_counter_offset() +
+ InvocationCounter::counter_offset());
+
+ __ get_method_counters(rbx, rax, done);
+
+ if (ProfileInterpreter) {
+ __ incrementl(Address(rax,
+ MethodCounters::interpreter_invocation_counter_offset()));
}
// Update standard invocation counters
- __ movl(rax, backedge_counter); // load backedge counter
-
+ __ movl(rcx, invocation_counter);
__ increment(rcx, InvocationCounter::count_increment);
+ __ movl(invocation_counter, rcx); // save invocation count
+
+ __ movl(rax, backedge_counter); // load backedge counter
__ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits
- __ movl(invocation_counter, rcx); // save invocation count
__ addl(rcx, rax); // add both counters
// profile_method is non-null only for interpreted method so
@@ -593,7 +601,7 @@
__ cmp32(rcx,
ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit));
__ jcc(Assembler::aboveEqual, *overflow);
-
+ __ bind(done);
}
void InterpreterGenerator::generate_counter_overflow(Label* do_continue) {
@@ -977,7 +985,6 @@
address entry_point = __ pc();
const Address constMethod (rbx, Method::const_offset());
- const Address invocation_counter(rbx, Method::invocation_counter_offset() + InvocationCounter::counter_offset());
const Address access_flags (rbx, Method::access_flags_offset());
const Address size_of_parameters(rcx, ConstMethod::size_of_parameters_offset());
@@ -1029,8 +1036,6 @@
}
#endif
- if (inc_counter) __ movl(rcx, invocation_counter); // (pre-)fetch invocation count
-
const Register unlock_thread = LP64_ONLY(r15_thread) NOT_LP64(rax);
NOT_LP64(__ movptr(unlock_thread, STATE(_thread));) // get thread
// Since at this point in the method invocation the exception handler
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -266,6 +266,20 @@
addptr(cache, tmp); // construct pointer to cache entry
}
+void InterpreterMacroAssembler::get_method_counters(Register method,
+ Register mcs, Label& skip) {
+ Label has_counters;
+ movptr(mcs, Address(method, Method::method_counters_offset()));
+ testptr(mcs, mcs);
+ jcc(Assembler::notZero, has_counters);
+ call_VM(noreg, CAST_FROM_FN_PTR(address,
+ InterpreterRuntime::build_method_counters), method);
+ movptr(mcs, Address(method,Method::method_counters_offset()));
+ testptr(mcs, mcs);
+ jcc(Assembler::zero, skip); // No MethodCounters allocated, OutOfMemory
+ bind(has_counters);
+}
+
// Load object from cpool->resolved_references(index)
void InterpreterMacroAssembler::load_resolved_reference_at_index(
Register result, Register index) {
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -89,6 +89,7 @@
void get_cache_and_index_and_bytecode_at_bcp(Register cache, Register index, Register bytecode, int byte_no, int bcp_offset, size_t index_size = sizeof(u2));
void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2));
void get_cache_index_at_bcp(Register index, int bcp_offset, size_t index_size = sizeof(u2));
+ void get_method_counters(Register method, Register mcs, Label& skip);
// load cpool->resolved_references(index);
void load_resolved_reference_at_index(Register result, Register index);
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -271,6 +271,20 @@
addptr(cache, tmp); // construct pointer to cache entry
}
+void InterpreterMacroAssembler::get_method_counters(Register method,
+ Register mcs, Label& skip) {
+ Label has_counters;
+ movptr(mcs, Address(method, Method::method_counters_offset()));
+ testptr(mcs, mcs);
+ jcc(Assembler::notZero, has_counters);
+ call_VM(noreg, CAST_FROM_FN_PTR(address,
+ InterpreterRuntime::build_method_counters), method);
+ movptr(mcs, Address(method,Method::method_counters_offset()));
+ testptr(mcs, mcs);
+ jcc(Assembler::zero, skip); // No MethodCounters allocated, OutOfMemory
+ bind(has_counters);
+}
+
// Load object from cpool->resolved_references(index)
void InterpreterMacroAssembler::load_resolved_reference_at_index(
Register result, Register index) {
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -111,6 +111,7 @@
void get_cache_and_index_and_bytecode_at_bcp(Register cache, Register index, Register bytecode, int byte_no, int bcp_offset, size_t index_size = sizeof(u2));
void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2));
void get_cache_index_at_bcp(Register index, int bcp_offset, size_t index_size = sizeof(u2));
+ void get_method_counters(Register method, Register mcs, Label& skip);
// load cpool->resolved_references(index);
void load_resolved_reference_at_index(Register result, Register index);
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -344,13 +344,13 @@
// rcx: invocation counter
//
void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) {
- const Address invocation_counter(rbx, in_bytes(Method::invocation_counter_offset()) +
- in_bytes(InvocationCounter::counter_offset()));
- // Note: In tiered we increment either counters in Method* or in MDO depending if we're profiling or not.
+ Label done;
+ // Note: In tiered we increment either counters in MethodCounters* or in MDO
+ // depending if we're profiling or not.
if (TieredCompilation) {
int increment = InvocationCounter::count_increment;
int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift;
- Label no_mdo, done;
+ Label no_mdo;
if (ProfileInterpreter) {
// Are we profiling?
__ movptr(rax, Address(rbx, Method::method_data_offset()));
@@ -363,23 +363,38 @@
__ jmpb(done);
}
__ bind(no_mdo);
- // Increment counter in Method* (we don't need to load it, it's in rcx).
- __ increment_mask_and_jump(invocation_counter, increment, mask, rcx, true, Assembler::zero, overflow);
+ // Increment counter in MethodCounters
+ const Address invocation_counter(rax,
+ MethodCounters::invocation_counter_offset() +
+ InvocationCounter::counter_offset());
+
+ __ get_method_counters(rbx, rax, done);
+ __ increment_mask_and_jump(invocation_counter, increment, mask,
+ rcx, false, Assembler::zero, overflow);
__ bind(done);
} else {
- const Address backedge_counter (rbx, Method::backedge_counter_offset() +
- InvocationCounter::counter_offset());
+ const Address backedge_counter (rax,
+ MethodCounters::backedge_counter_offset() +
+ InvocationCounter::counter_offset());
+ const Address invocation_counter(rax,
+ MethodCounters::invocation_counter_offset() +
+ InvocationCounter::counter_offset());
+
+ __ get_method_counters(rbx, rax, done);
- if (ProfileInterpreter) { // %%% Merge this into MethodData*
- __ incrementl(Address(rbx,Method::interpreter_invocation_counter_offset()));
+ if (ProfileInterpreter) {
+ __ incrementl(Address(rax,
+ MethodCounters::interpreter_invocation_counter_offset()));
}
+
// Update standard invocation counters
- __ movl(rax, backedge_counter); // load backedge counter
+ __ movl(rcx, invocation_counter);
+ __ incrementl(rcx, InvocationCounter::count_increment);
+ __ movl(invocation_counter, rcx); // save invocation count
- __ incrementl(rcx, InvocationCounter::count_increment);
+ __ movl(rax, backedge_counter); // load backedge counter
__ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits
- __ movl(invocation_counter, rcx); // save invocation count
__ addl(rcx, rax); // add both counters
// profile_method is non-null only for interpreted method so
@@ -399,6 +414,7 @@
__ cmp32(rcx,
ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit));
__ jcc(Assembler::aboveEqual, *overflow);
+ __ bind(done);
}
}
@@ -868,7 +884,6 @@
address entry_point = __ pc();
const Address constMethod (rbx, Method::const_offset());
- const Address invocation_counter(rbx, Method::invocation_counter_offset() + InvocationCounter::counter_offset());
const Address access_flags (rbx, Method::access_flags_offset());
const Address size_of_parameters(rcx, ConstMethod::size_of_parameters_offset());
@@ -897,9 +912,7 @@
// NULL oop temp (mirror or jni oop result)
__ push((int32_t)NULL_WORD);
- if (inc_counter) __ movl(rcx, invocation_counter); // (pre-)fetch invocation count
// initialize fixed part of activation frame
-
generate_fixed_frame(true);
// make sure method is native & not abstract
@@ -1286,7 +1299,6 @@
address entry_point = __ pc();
const Address constMethod (rbx, Method::const_offset());
- const Address invocation_counter(rbx, Method::invocation_counter_offset() + InvocationCounter::counter_offset());
const Address access_flags (rbx, Method::access_flags_offset());
const Address size_of_parameters(rdx, ConstMethod::size_of_parameters_offset());
const Address size_of_locals (rdx, ConstMethod::size_of_locals_offset());
@@ -1326,7 +1338,6 @@
__ bind(exit);
}
- if (inc_counter) __ movl(rcx, invocation_counter); // (pre-)fetch invocation count
// initialize fixed part of activation frame
generate_fixed_frame(false);
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -300,13 +300,12 @@
Label* overflow,
Label* profile_method,
Label* profile_method_continue) {
- const Address invocation_counter(rbx, in_bytes(Method::invocation_counter_offset()) +
- in_bytes(InvocationCounter::counter_offset()));
+ Label done;
// Note: In tiered we increment either counters in Method* or in MDO depending if we're profiling or not.
if (TieredCompilation) {
int increment = InvocationCounter::count_increment;
int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift;
- Label no_mdo, done;
+ Label no_mdo;
if (ProfileInterpreter) {
// Are we profiling?
__ movptr(rax, Address(rbx, Method::method_data_offset()));
@@ -319,25 +318,36 @@
__ jmpb(done);
}
__ bind(no_mdo);
- // Increment counter in Method* (we don't need to load it, it's in ecx).
- __ increment_mask_and_jump(invocation_counter, increment, mask, rcx, true, Assembler::zero, overflow);
+ // Increment counter in MethodCounters
+ const Address invocation_counter(rax,
+ MethodCounters::invocation_counter_offset() +
+ InvocationCounter::counter_offset());
+ __ get_method_counters(rbx, rax, done);
+ __ increment_mask_and_jump(invocation_counter, increment, mask, rcx,
+ false, Assembler::zero, overflow);
__ bind(done);
} else {
- const Address backedge_counter(rbx,
- Method::backedge_counter_offset() +
- InvocationCounter::counter_offset());
+ const Address backedge_counter(rax,
+ MethodCounters::backedge_counter_offset() +
+ InvocationCounter::counter_offset());
+ const Address invocation_counter(rax,
+ MethodCounters::invocation_counter_offset() +
+ InvocationCounter::counter_offset());
- if (ProfileInterpreter) { // %%% Merge this into MethodData*
- __ incrementl(Address(rbx,
- Method::interpreter_invocation_counter_offset()));
+ __ get_method_counters(rbx, rax, done);
+
+ if (ProfileInterpreter) {
+ __ incrementl(Address(rax,
+ MethodCounters::interpreter_invocation_counter_offset()));
}
// Update standard invocation counters
- __ movl(rax, backedge_counter); // load backedge counter
+ __ movl(rcx, invocation_counter);
+ __ incrementl(rcx, InvocationCounter::count_increment);
+ __ movl(invocation_counter, rcx); // save invocation count
- __ incrementl(rcx, InvocationCounter::count_increment);
+ __ movl(rax, backedge_counter); // load backedge counter
__ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits
- __ movl(invocation_counter, rcx); // save invocation count
__ addl(rcx, rax); // add both counters
// profile_method is non-null only for interpreted method so
@@ -354,6 +364,7 @@
__ cmp32(rcx, ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit));
__ jcc(Assembler::aboveEqual, *overflow);
+ __ bind(done);
}
}
@@ -843,9 +854,6 @@
address entry_point = __ pc();
const Address constMethod (rbx, Method::const_offset());
- const Address invocation_counter(rbx, Method::
- invocation_counter_offset() +
- InvocationCounter::counter_offset());
const Address access_flags (rbx, Method::access_flags_offset());
const Address size_of_parameters(rcx, ConstMethod::
size_of_parameters_offset());
@@ -876,10 +884,6 @@
// (static native method holder mirror/jni oop result)
__ push((int) NULL_WORD);
- if (inc_counter) {
- __ movl(rcx, invocation_counter); // (pre-)fetch invocation count
- }
-
// initialize fixed part of activation frame
generate_fixed_frame(true);
@@ -1296,9 +1300,6 @@
address entry_point = __ pc();
const Address constMethod(rbx, Method::const_offset());
- const Address invocation_counter(rbx,
- Method::invocation_counter_offset() +
- InvocationCounter::counter_offset());
const Address access_flags(rbx, Method::access_flags_offset());
const Address size_of_parameters(rdx,
ConstMethod::size_of_parameters_offset());
@@ -1343,10 +1344,6 @@
__ bind(exit);
}
- // (pre-)fetch invocation count
- if (inc_counter) {
- __ movl(rcx, invocation_counter);
- }
// initialize fixed part of activation frame
generate_fixed_frame(false);
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -1546,9 +1546,10 @@
__ get_method(rcx); // ECX holds method
__ profile_taken_branch(rax,rbx); // EAX holds updated MDP, EBX holds bumped taken count
- const ByteSize be_offset = Method::backedge_counter_offset() + InvocationCounter::counter_offset();
- const ByteSize inv_offset = Method::invocation_counter_offset() + InvocationCounter::counter_offset();
- const int method_offset = frame::interpreter_frame_method_offset * wordSize;
+ const ByteSize be_offset = MethodCounters::backedge_counter_offset() +
+ InvocationCounter::counter_offset();
+ const ByteSize inv_offset = MethodCounters::invocation_counter_offset() +
+ InvocationCounter::counter_offset();
// Load up EDX with the branch displacement
__ movl(rdx, at_bcp(1));
@@ -1596,6 +1597,22 @@
__ testl(rdx, rdx); // check if forward or backward branch
__ jcc(Assembler::positive, dispatch); // count only if backward branch
+ // check if MethodCounters exists
+ Label has_counters;
+ __ movptr(rax, Address(rcx, Method::method_counters_offset()));
+ __ testptr(rax, rax);
+ __ jcc(Assembler::notZero, has_counters);
+ __ push(rdx);
+ __ push(rcx);
+ __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::build_method_counters),
+ rcx);
+ __ pop(rcx);
+ __ pop(rdx);
+ __ movptr(rax, Address(rcx, Method::method_counters_offset()));
+ __ testptr(rax, rax);
+ __ jcc(Assembler::zero, dispatch);
+ __ bind(has_counters);
+
if (TieredCompilation) {
Label no_mdo;
int increment = InvocationCounter::count_increment;
@@ -1613,16 +1630,19 @@
__ jmp(dispatch);
}
__ bind(no_mdo);
- // Increment backedge counter in Method*
+ // Increment backedge counter in MethodCounters*
+ __ movptr(rcx, Address(rcx, Method::method_counters_offset()));
__ increment_mask_and_jump(Address(rcx, be_offset), increment, mask,
rax, false, Assembler::zero, &backedge_counter_overflow);
} else {
// increment counter
+ __ movptr(rcx, Address(rcx, Method::method_counters_offset()));
__ movl(rax, Address(rcx, be_offset)); // load backedge counter
__ incrementl(rax, InvocationCounter::count_increment); // increment counter
__ movl(Address(rcx, be_offset), rax); // store counter
__ movl(rax, Address(rcx, inv_offset)); // load invocation counter
+
__ andl(rax, InvocationCounter::count_mask_value); // and the status bits
__ addl(rax, Address(rcx, be_offset)); // add both counters
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -158,14 +158,19 @@
if (val == noreg) {
__ store_heap_oop_null(Address(rdx, 0));
} else {
+ // G1 barrier needs uncompressed oop for region cross check.
+ Register new_val = val;
+ if (UseCompressedOops) {
+ new_val = rbx;
+ __ movptr(new_val, val);
+ }
__ store_heap_oop(Address(rdx, 0), val);
__ g1_write_barrier_post(rdx /* store_adr */,
- val /* new_val */,
+ new_val /* new_val */,
r15_thread /* thread */,
r8 /* tmp */,
rbx /* tmp2 */);
}
-
}
break;
#endif // INCLUDE_ALL_GCS
@@ -1564,11 +1569,10 @@
__ profile_taken_branch(rax, rbx); // rax holds updated MDP, rbx
// holds bumped taken count
- const ByteSize be_offset = Method::backedge_counter_offset() +
+ const ByteSize be_offset = MethodCounters::backedge_counter_offset() +
InvocationCounter::counter_offset();
- const ByteSize inv_offset = Method::invocation_counter_offset() +
+ const ByteSize inv_offset = MethodCounters::invocation_counter_offset() +
InvocationCounter::counter_offset();
- const int method_offset = frame::interpreter_frame_method_offset * wordSize;
// Load up edx with the branch displacement
__ movl(rdx, at_bcp(1));
@@ -1618,6 +1622,22 @@
// r14: locals pointer
__ testl(rdx, rdx); // check if forward or backward branch
__ jcc(Assembler::positive, dispatch); // count only if backward branch
+
+ // check if MethodCounters exists
+ Label has_counters;
+ __ movptr(rax, Address(rcx, Method::method_counters_offset()));
+ __ testptr(rax, rax);
+ __ jcc(Assembler::notZero, has_counters);
+ __ push(rdx);
+ __ push(rcx);
+ __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::build_method_counters),
+ rcx);
+ __ pop(rcx);
+ __ pop(rdx);
+ __ movptr(rax, Address(rcx, Method::method_counters_offset()));
+ __ jcc(Assembler::zero, dispatch);
+ __ bind(has_counters);
+
if (TieredCompilation) {
Label no_mdo;
int increment = InvocationCounter::count_increment;
@@ -1635,16 +1655,19 @@
__ jmp(dispatch);
}
__ bind(no_mdo);
- // Increment backedge counter in Method*
+ // Increment backedge counter in MethodCounters*
+ __ movptr(rcx, Address(rcx, Method::method_counters_offset()));
__ increment_mask_and_jump(Address(rcx, be_offset), increment, mask,
rax, false, Assembler::zero, &backedge_counter_overflow);
} else {
// increment counter
+ __ movptr(rcx, Address(rcx, Method::method_counters_offset()));
__ movl(rax, Address(rcx, be_offset)); // load backedge counter
__ incrementl(rax, InvocationCounter::count_increment); // increment counter
__ movl(Address(rcx, be_offset), rax); // store counter
__ movl(rax, Address(rcx, inv_offset)); // load invocation counter
+
__ andl(rax, InvocationCounter::count_mask_value); // and the status bits
__ addl(rax, Address(rcx, be_offset)); // add both counters
--- a/hotspot/src/cpu/x86/vm/x86_32.ad Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
//
-// Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 1997, 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
@@ -2317,30 +2317,6 @@
emit_rm(cbuf, 0x3, $p$$reg, tmpReg);
%}
- enc_class enc_cmpLTP_mem(rRegI p, rRegI q, memory mem, eCXRegI tmp) %{ // cadd_cmpLT
- int tmpReg = $tmp$$reg;
-
- // SUB $p,$q
- emit_opcode(cbuf,0x2B);
- emit_rm(cbuf, 0x3, $p$$reg, $q$$reg);
- // SBB $tmp,$tmp
- emit_opcode(cbuf,0x1B);
- emit_rm(cbuf, 0x3, tmpReg, tmpReg);
- // AND $tmp,$y
- cbuf.set_insts_mark(); // Mark start of opcode for reloc info in mem operand
- emit_opcode(cbuf,0x23);
- int reg_encoding = tmpReg;
- int base = $mem$$base;
- int index = $mem$$index;
- int scale = $mem$$scale;
- int displace = $mem$$disp;
- relocInfo::relocType disp_reloc = $mem->disp_reloc();
- encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_reloc);
- // ADD $p,$tmp
- emit_opcode(cbuf,0x03);
- emit_rm(cbuf, 0x3, $p$$reg, tmpReg);
- %}
-
enc_class shift_left_long( eRegL dst, eCXRegI shift ) %{
// TEST shift,32
emit_opcode(cbuf,0xF7);
@@ -8922,9 +8898,9 @@
%}
%}
-instruct cmpLTMask( eCXRegI dst, ncxRegI p, ncxRegI q, eFlagsReg cr ) %{
+instruct cmpLTMask(eCXRegI dst, ncxRegI p, ncxRegI q, eFlagsReg cr) %{
match(Set dst (CmpLTMask p q));
- effect( KILL cr );
+ effect(KILL cr);
ins_cost(400);
// SETlt can only use low byte of EAX,EBX, ECX, or EDX as destination
@@ -8932,50 +8908,83 @@
"CMP $p,$q\n\t"
"SETlt $dst\n\t"
"NEG $dst" %}
- ins_encode( OpcRegReg(0x33,dst,dst),
- OpcRegReg(0x3B,p,q),
- setLT_reg(dst), neg_reg(dst) );
- ins_pipe( pipe_slow );
-%}
-
-instruct cmpLTMask0( rRegI dst, immI0 zero, eFlagsReg cr ) %{
+ ins_encode %{
+ Register Rp = $p$$Register;
+ Register Rq = $q$$Register;
+ Register Rd = $dst$$Register;
+ Label done;
+ __ xorl(Rd, Rd);
+ __ cmpl(Rp, Rq);
+ __ setb(Assembler::less, Rd);
+ __ negl(Rd);
+ %}
+
+ ins_pipe(pipe_slow);
+%}
+
+instruct cmpLTMask0(rRegI dst, immI0 zero, eFlagsReg cr) %{
match(Set dst (CmpLTMask dst zero));
- effect( DEF dst, KILL cr );
+ effect(DEF dst, KILL cr);
ins_cost(100);
- format %{ "SAR $dst,31" %}
- opcode(0xC1, 0x7); /* C1 /7 ib */
- ins_encode( RegOpcImm( dst, 0x1F ) );
- ins_pipe( ialu_reg );
-%}
-
-
-instruct cadd_cmpLTMask( ncxRegI p, ncxRegI q, ncxRegI y, eCXRegI tmp, eFlagsReg cr ) %{
+ format %{ "SAR $dst,31\t# cmpLTMask0" %}
+ ins_encode %{
+ __ sarl($dst$$Register, 31);
+ %}
+ ins_pipe(ialu_reg);
+%}
+
+/* better to save a register than avoid a branch */
+instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, eFlagsReg cr) %{
match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
- effect( KILL tmp, KILL cr );
+ effect(KILL cr);
ins_cost(400);
- // annoyingly, $tmp has no edges so you cant ask for it in
- // any format or encoding
- format %{ "SUB $p,$q\n\t"
- "SBB ECX,ECX\n\t"
- "AND ECX,$y\n\t"
- "ADD $p,ECX" %}
- ins_encode( enc_cmpLTP(p,q,y,tmp) );
- ins_pipe( pipe_cmplt );
+ format %{ "SUB $p,$q\t# cadd_cmpLTMask\n\t"
+ "JGE done\n\t"
+ "ADD $p,$y\n"
+ "done: " %}
+ ins_encode %{
+ Register Rp = $p$$Register;
+ Register Rq = $q$$Register;
+ Register Ry = $y$$Register;
+ Label done;
+ __ subl(Rp, Rq);
+ __ jccb(Assembler::greaterEqual, done);
+ __ addl(Rp, Ry);
+ __ bind(done);
+ %}
+
+ ins_pipe(pipe_cmplt);
+%}
+
+/* better to save a register than avoid a branch */
+instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, eFlagsReg cr) %{
+ match(Set y (AndI (CmpLTMask p q) y));
+ effect(KILL cr);
+
+ ins_cost(300);
+
+ format %{ "CMPL $p, $q\t# and_cmpLTMask\n\t"
+ "JLT done\n\t"
+ "XORL $y, $y\n"
+ "done: " %}
+ ins_encode %{
+ Register Rp = $p$$Register;
+ Register Rq = $q$$Register;
+ Register Ry = $y$$Register;
+ Label done;
+ __ cmpl(Rp, Rq);
+ __ jccb(Assembler::less, done);
+ __ xorl(Ry, Ry);
+ __ bind(done);
+ %}
+
+ ins_pipe(pipe_cmplt);
%}
/* If I enable this, I encourage spilling in the inner loop of compress.
-instruct cadd_cmpLTMask_mem( ncxRegI p, ncxRegI q, memory y, eCXRegI tmp, eFlagsReg cr ) %{
+instruct cadd_cmpLTMask_mem(ncxRegI p, ncxRegI q, memory y, eCXRegI tmp, eFlagsReg cr) %{
match(Set p (AddI (AndI (CmpLTMask p q) (LoadI y)) (SubI p q)));
- effect( USE_KILL tmp, KILL cr );
- ins_cost(400);
-
- format %{ "SUB $p,$q\n\t"
- "SBB ECX,ECX\n\t"
- "AND ECX,$y\n\t"
- "ADD $p,ECX" %}
- ins_encode( enc_cmpLTP_mem(p,q,y,tmp) );
-%}
*/
//----------Long Instructions------------------------------------------------
--- a/hotspot/src/cpu/x86/vm/x86_64.ad Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+// 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
@@ -9434,7 +9434,7 @@
match(Set dst (CmpLTMask p q));
effect(KILL cr);
- ins_cost(400); // XXX
+ ins_cost(400);
format %{ "cmpl $p, $q\t# cmpLTMask\n\t"
"setlt $dst\n\t"
"movzbl $dst, $dst\n\t"
@@ -9452,37 +9452,63 @@
match(Set dst (CmpLTMask dst zero));
effect(KILL cr);
- ins_cost(100); // XXX
+ ins_cost(100);
format %{ "sarl $dst, #31\t# cmpLTMask0" %}
- opcode(0xC1, 0x7); /* C1 /7 ib */
- ins_encode(reg_opc_imm(dst, 0x1F));
+ ins_encode %{
+ __ sarl($dst$$Register, 31);
+ %}
ins_pipe(ialu_reg);
%}
-
-instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rRegI tmp, rFlagsReg cr)
+/* Better to save a register than avoid a branch */
+instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr)
%{
match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
- effect(TEMP tmp, KILL cr);
-
- ins_cost(400); // XXX
- format %{ "subl $p, $q\t# cadd_cmpLTMask1\n\t"
- "sbbl $tmp, $tmp\n\t"
- "andl $tmp, $y\n\t"
- "addl $p, $tmp" %}
+ effect(KILL cr);
+ ins_cost(300);
+ format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t"
+ "jge done\n\t"
+ "addl $p,$y\n"
+ "done: " %}
ins_encode %{
Register Rp = $p$$Register;
Register Rq = $q$$Register;
Register Ry = $y$$Register;
- Register Rt = $tmp$$Register;
+ Label done;
__ subl(Rp, Rq);
- __ sbbl(Rt, Rt);
- __ andl(Rt, Ry);
- __ addl(Rp, Rt);
+ __ jccb(Assembler::greaterEqual, done);
+ __ addl(Rp, Ry);
+ __ bind(done);
%}
ins_pipe(pipe_cmplt);
%}
+/* Better to save a register than avoid a branch */
+instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr)
+%{
+ match(Set y (AndI (CmpLTMask p q) y));
+ effect(KILL cr);
+
+ ins_cost(300);
+
+ format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t"
+ "jlt done\n\t"
+ "xorl $y, $y\n"
+ "done: " %}
+ ins_encode %{
+ Register Rp = $p$$Register;
+ Register Rq = $q$$Register;
+ Register Ry = $y$$Register;
+ Label done;
+ __ cmpl(Rp, Rq);
+ __ jccb(Assembler::less, done);
+ __ xorl(Ry, Ry);
+ __ bind(done);
+ %}
+ ins_pipe(pipe_cmplt);
+%}
+
+
//---------- FP Instructions------------------------------------------------
instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2)
--- a/hotspot/src/os/bsd/dtrace/generateJvmOffsets.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/os/bsd/dtrace/generateJvmOffsets.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -60,7 +60,7 @@
#define PR_MODEL_LP64 2
#ifdef COMPILER1
-#if defined(DEBUG) || defined(FASTDEBUG)
+#ifdef ASSERT
/*
* To avoid the most part of potential link errors
@@ -84,7 +84,7 @@
StubQueue* AbstractInterpreter::_code = NULL;
-#endif /* defined(DEBUG) || defined(FASTDEBUG) */
+#endif /* ASSERT */
#endif /* COMPILER1 */
#define GEN_OFFS(Type,Name) \
--- a/hotspot/src/os/bsd/vm/chaitin_bsd.cpp Thu Apr 18 10:30:11 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 1999, 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.
- *
- */
-
-#include "precompiled.hpp"
-#include "opto/chaitin.hpp"
-#include "opto/machnode.hpp"
-
-void PhaseRegAlloc::pd_preallocate_hook() {
- // no action
-}
-
-#ifdef ASSERT
-void PhaseRegAlloc::pd_postallocate_verify_hook() {
- // no action
-}
-#endif
-
-
-// Reconciliation History
-// chaitin_solaris.cpp 1.7 99/07/12 23:54:22
-// End
--- a/hotspot/src/os/linux/vm/chaitin_linux.cpp Thu Apr 18 10:30:11 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 1999, 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.
- *
- */
-
-#include "precompiled.hpp"
-#include "opto/chaitin.hpp"
-#include "opto/machnode.hpp"
-
-void PhaseRegAlloc::pd_preallocate_hook() {
- // no action
-}
-
-#ifdef ASSERT
-void PhaseRegAlloc::pd_postallocate_verify_hook() {
- // no action
-}
-#endif
-
-
-// Reconciliation History
-// chaitin_solaris.cpp 1.7 99/07/12 23:54:22
-// End
--- a/hotspot/src/os/solaris/dtrace/generateJvmOffsets.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/os/solaris/dtrace/generateJvmOffsets.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -55,14 +55,14 @@
#include "utilities/accessFlags.hpp"
#include "utilities/globalDefinitions.hpp"
#ifdef COMPILER1
-#if defined(DEBUG) || defined(FASTDEBUG)
+#ifdef ASSERT
/*
* To avoid the most part of potential link errors
* we link this program with -z nodefs .
*
* But for 'debug1' and 'fastdebug1' we still have to provide
- * a particular workaround for the following symbols bellow.
+ * a particular workaround for the following symbols below.
* It will be good to find out a generic way in the future.
*/
@@ -79,7 +79,7 @@
StubQueue* AbstractInterpreter::_code = NULL;
-#endif /* defined(DEBUG) || defined(FASTDEBUG) */
+#endif /* ASSERT */
#endif /* COMPILER1 */
#define GEN_OFFS(Type,Name) \
--- a/hotspot/src/os/solaris/vm/chaitin_solaris.cpp Thu Apr 18 10:30:11 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 1999, 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.
- *
- */
-
-#include "precompiled.hpp"
-#include "opto/chaitin.hpp"
-#include "opto/machnode.hpp"
-
-void PhaseRegAlloc::pd_preallocate_hook() {
- // no action
-}
-
-#ifdef ASSERT
-void PhaseRegAlloc::pd_postallocate_verify_hook() {
- // no action
-}
-#endif
-
-
-//Reconciliation History
-// 1.1 99/02/12 15:35:26 chaitin_win32.cpp
-// 1.2 99/02/18 15:38:56 chaitin_win32.cpp
-// 1.4 99/03/09 10:37:48 chaitin_win32.cpp
-// 1.6 99/03/25 11:07:44 chaitin_win32.cpp
-// 1.8 99/06/22 16:38:58 chaitin_win32.cpp
-//End
--- a/hotspot/src/os/windows/vm/chaitin_windows.cpp Thu Apr 18 10:30:11 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 1999, 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.
- *
- */
-
-#include "precompiled.hpp"
-#include "opto/chaitin.hpp"
-#include "opto/machnode.hpp"
-
-// Disallow the use of the frame pointer (EBP) for implicit null exceptions
-// on win95/98. If we do not do this, the OS gets confused and gives a stack
-// error.
-void PhaseRegAlloc::pd_preallocate_hook() {
-#ifndef _WIN64
- if (ImplicitNullChecks && !os::win32::is_nt()) {
- for (uint block_num=1; block_num<_cfg._num_blocks; block_num++) {
- Block *block = _cfg._blocks[block_num];
-
- Node *block_end = block->end();
- if (block_end->is_MachNullCheck() &&
- block_end->as_Mach()->ideal_Opcode() != Op_Con) {
- // The last instruction in the block is an implicit null check.
- // Fix its input so that it does not load into the frame pointer.
- _matcher.pd_implicit_null_fixup(block_end->in(1)->as_Mach(),
- block_end->as_MachNullCheck()->_vidx);
- }
- }
- }
-#else
- // WIN64==itanium on XP
-#endif
-}
-
-#ifdef ASSERT
-// Verify that no implicit null check uses the frame pointer (EBP) as
-// its register on win95/98. Use of the frame pointer in an implicit
-// null check confuses the OS, yielding a stack error.
-void PhaseRegAlloc::pd_postallocate_verify_hook() {
-#ifndef _WIN64
- if (ImplicitNullChecks && !os::win32::is_nt()) {
- for (uint block_num=1; block_num<_cfg._num_blocks; block_num++) {
- Block *block = _cfg._blocks[block_num];
-
- Node *block_end = block->_nodes[block->_nodes.size()-1];
- if (block_end->is_MachNullCheck() && block_end->as_Mach()->ideal_Opcode() != Op_Con) {
- // The last instruction in the block is an implicit
- // null check. Verify that this instruction does not
- // use the frame pointer.
- int reg = get_reg_first(block_end->in(1)->in(block_end->as_MachNullCheck()->_vidx));
- assert(reg != EBP_num,
- "implicit null check using frame pointer on win95/98");
- }
- }
- }
-#else
- // WIN64==itanium on XP
-#endif
-}
-#endif
--- a/hotspot/src/os/windows/vm/os_windows.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -4238,9 +4238,6 @@
path[3] = '\0';
}
- #ifdef DEBUG
- jio_fprintf(stderr, "sysNativePath: %s\n", path);
- #endif DEBUG
return path;
}
--- a/hotspot/src/share/tools/hsdis/Makefile Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/tools/hsdis/Makefile Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2008, 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
@@ -19,7 +19,7 @@
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
-#
+#
#
# Single gnu makefile for solaris, linux and windows (windows requires cygwin and mingw)
@@ -66,7 +66,7 @@
endif
CC = $(MINGW)-gcc
CONFIGURE_ARGS= --host=$(MINGW) --target=$(MINGW)
-else #linux
+else #linux
CPU = $(shell uname -m)
ARCH1=$(CPU:x86_64=amd64)
ARCH=$(ARCH1:i686=i386)
@@ -116,7 +116,6 @@
else #Windows
OS = windows
CC = gcc
-#CPPFLAGS += /D"WIN32" /D"_WINDOWS" /D"DEBUG" /D"NDEBUG"
CFLAGS += /nologo /MD /W3 /WX /O2 /Fo$(@:.dll=.obj) /Gi-
CFLAGS += LIBARCH=\"$(LIBARCH)\"
DLDFLAGS += /dll /subsystem:windows /incremental:no \
--- a/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -938,5 +938,7 @@
void Canonicalizer::do_ProfileInvoke(ProfileInvoke* x) {}
void Canonicalizer::do_RuntimeCall(RuntimeCall* x) {}
void Canonicalizer::do_RangeCheckPredicate(RangeCheckPredicate* x) {}
+#ifdef ASSERT
void Canonicalizer::do_Assert(Assert* x) {}
+#endif
void Canonicalizer::do_MemBar(MemBar* x) {}
--- a/hotspot/src/share/vm/c1/c1_Canonicalizer.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_Canonicalizer.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -108,7 +108,9 @@
virtual void do_RuntimeCall (RuntimeCall* x);
virtual void do_MemBar (MemBar* x);
virtual void do_RangeCheckPredicate(RangeCheckPredicate* x);
+#ifdef ASSERT
virtual void do_Assert (Assert* x);
+#endif
};
#endif // SHARE_VM_C1_C1_CANONICALIZER_HPP
--- a/hotspot/src/share/vm/c1/c1_Instruction.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_Instruction.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -111,7 +111,9 @@
class RuntimeCall;
class MemBar;
class RangeCheckPredicate;
+#ifdef ASSERT
class Assert;
+#endif
// A Value is a reference to the instruction creating the value
typedef Instruction* Value;
--- a/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -871,12 +871,14 @@
}
}
+#ifdef ASSERT
void InstructionPrinter::do_Assert(Assert* x) {
output()->print("assert ");
print_value(x->x());
output()->print(" %s ", cond_name(x->cond()));
print_value(x->y());
}
+#endif
void InstructionPrinter::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {
print_unsafe_object_op(x, "UnsafePrefetchWrite");
--- a/hotspot/src/share/vm/c1/c1_InstructionPrinter.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_InstructionPrinter.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -136,7 +136,9 @@
virtual void do_RuntimeCall (RuntimeCall* x);
virtual void do_MemBar (MemBar* x);
virtual void do_RangeCheckPredicate(RangeCheckPredicate* x);
+#ifdef ASSERT
virtual void do_Assert (Assert* x);
+#endif
};
#endif // PRODUCT
--- a/hotspot/src/share/vm/c1/c1_LIR.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIR.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1778,7 +1778,9 @@
// LIR_OpProfileCall
case lir_profile_call: s = "profile_call"; break;
// LIR_OpAssert
+#ifdef ASSERT
case lir_assert: s = "assert"; break;
+#endif
case lir_none: ShouldNotReachHere();break;
default: s = "illegal_op"; break;
}
@@ -2025,12 +2027,14 @@
out->print("[lbl:0x%x]", stub()->entry());
}
+#ifdef ASSERT
void LIR_OpAssert::print_instr(outputStream* out) const {
print_condition(out, condition()); out->print(" ");
in_opr1()->print(out); out->print(" ");
in_opr2()->print(out); out->print(", \"");
out->print(msg()); out->print("\"");
}
+#endif
void LIR_OpDelay::print_instr(outputStream* out) const {
--- a/hotspot/src/share/vm/c1/c1_LIR.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIR.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -881,8 +881,9 @@
class LIR_OpTypeCheck;
class LIR_OpCompareAndSwap;
class LIR_OpProfileCall;
+#ifdef ASSERT
class LIR_OpAssert;
-
+#endif
// LIR operation codes
enum LIR_Code {
@@ -1139,7 +1140,9 @@
virtual LIR_OpTypeCheck* as_OpTypeCheck() { return NULL; }
virtual LIR_OpCompareAndSwap* as_OpCompareAndSwap() { return NULL; }
virtual LIR_OpProfileCall* as_OpProfileCall() { return NULL; }
+#ifdef ASSERT
virtual LIR_OpAssert* as_OpAssert() { return NULL; }
+#endif
virtual void verify() const {}
};
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -3044,21 +3044,20 @@
assert(level > CompLevel_simple, "Shouldn't be here");
int offset = -1;
- LIR_Opr counter_holder = new_register(T_METADATA);
- LIR_Opr meth;
+ LIR_Opr counter_holder;
if (level == CompLevel_limited_profile) {
- offset = in_bytes(backedge ? Method::backedge_counter_offset() :
- Method::invocation_counter_offset());
- __ metadata2reg(method->constant_encoding(), counter_holder);
- meth = counter_holder;
+ address counters_adr = method->ensure_method_counters();
+ counter_holder = new_pointer_register();
+ __ move(LIR_OprFact::intptrConst(counters_adr), counter_holder);
+ offset = in_bytes(backedge ? MethodCounters::backedge_counter_offset() :
+ MethodCounters::invocation_counter_offset());
} else if (level == CompLevel_full_profile) {
+ counter_holder = new_register(T_METADATA);
offset = in_bytes(backedge ? MethodData::backedge_counter_offset() :
MethodData::invocation_counter_offset());
ciMethodData* md = method->method_data_or_null();
assert(md != NULL, "Sanity");
__ metadata2reg(md->constant_encoding(), counter_holder);
- meth = new_register(T_METADATA);
- __ metadata2reg(method->constant_encoding(), meth);
} else {
ShouldNotReachHere();
}
@@ -3069,6 +3068,8 @@
__ store(result, counter);
if (notify) {
LIR_Opr mask = load_immediate(frequency << InvocationCounter::count_shift, T_INT);
+ LIR_Opr meth = new_register(T_METADATA);
+ __ metadata2reg(method->constant_encoding(), meth);
__ logical_and(result, mask, result);
__ cmp(lir_cond_equal, result, LIR_OprFact::intConst(0));
// The bci for info can point to cmp for if's we want the if bci
@@ -3103,8 +3104,8 @@
}
}
+#ifdef ASSERT
void LIRGenerator::do_Assert(Assert *x) {
-#ifdef ASSERT
ValueTag tag = x->x()->type()->tag();
If::Condition cond = x->cond();
@@ -3124,9 +3125,8 @@
LIR_Opr right = yin->result();
__ lir_assert(lir_cond(x->cond()), left, right, x->message(), true);
+}
#endif
-}
-
void LIRGenerator::do_RangeCheckPredicate(RangeCheckPredicate *x) {
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -537,7 +537,9 @@
virtual void do_RuntimeCall (RuntimeCall* x);
virtual void do_MemBar (MemBar* x);
virtual void do_RangeCheckPredicate(RangeCheckPredicate* x);
+#ifdef ASSERT
virtual void do_Assert (Assert* x);
+#endif
};
--- a/hotspot/src/share/vm/c1/c1_Optimizer.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_Optimizer.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -535,7 +535,9 @@
void do_RuntimeCall (RuntimeCall* x);
void do_MemBar (MemBar* x);
void do_RangeCheckPredicate(RangeCheckPredicate* x);
+#ifdef ASSERT
void do_Assert (Assert* x);
+#endif
};
@@ -718,8 +720,9 @@
void NullCheckVisitor::do_RuntimeCall (RuntimeCall* x) {}
void NullCheckVisitor::do_MemBar (MemBar* x) {}
void NullCheckVisitor::do_RangeCheckPredicate(RangeCheckPredicate* x) {}
+#ifdef ASSERT
void NullCheckVisitor::do_Assert (Assert* x) {}
-
+#endif
void NullCheckEliminator::visit(Value* p) {
assert(*p != NULL, "should not find NULL instructions");
--- a/hotspot/src/share/vm/c1/c1_RangeCheckElimination.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_RangeCheckElimination.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -166,7 +166,9 @@
void do_RuntimeCall (RuntimeCall* x) { /* nothing to do */ };
void do_MemBar (MemBar* x) { /* nothing to do */ };
void do_RangeCheckPredicate(RangeCheckPredicate* x) { /* nothing to do */ };
+#ifdef ASSERT
void do_Assert (Assert* x) { /* nothing to do */ };
+#endif
};
#ifdef ASSERT
--- a/hotspot/src/share/vm/c1/c1_ValueMap.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_ValueMap.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -207,7 +207,9 @@
void do_RuntimeCall (RuntimeCall* x) { /* nothing to do */ };
void do_MemBar (MemBar* x) { /* nothing to do */ };
void do_RangeCheckPredicate(RangeCheckPredicate* x) { /* nothing to do */ };
+#ifdef ASSERT
void do_Assert (Assert* x) { /* nothing to do */ };
+#endif
};
--- a/hotspot/src/share/vm/ci/ciMethod.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -905,6 +905,20 @@
}
// ------------------------------------------------------------------
+// ciMethod::ensure_method_counters
+//
+address ciMethod::ensure_method_counters() {
+ check_is_loaded();
+ VM_ENTRY_MARK;
+ methodHandle mh(THREAD, get_Method());
+ MethodCounters *counter = mh->method_counters();
+ if (counter == NULL) {
+ counter = Method::build_method_counters(mh(), CHECK_AND_CLEAR_NULL);
+ }
+ return (address)counter;
+}
+
+// ------------------------------------------------------------------
// ciMethod::should_exclude
//
// Should this method be excluded from compilation?
@@ -1191,13 +1205,14 @@
ASSERT_IN_VM;
ResourceMark rm;
Method* method = get_Method();
+ MethodCounters* mcs = method->method_counters();
Klass* holder = method->method_holder();
st->print_cr("ciMethod %s %s %s %d %d %d %d %d",
holder->name()->as_quoted_ascii(),
method->name()->as_quoted_ascii(),
method->signature()->as_quoted_ascii(),
- method->invocation_counter()->raw_counter(),
- method->backedge_counter()->raw_counter(),
+ mcs == NULL ? 0 : mcs->invocation_counter()->raw_counter(),
+ mcs == NULL ? 0 : mcs->backedge_counter()->raw_counter(),
interpreter_invocation_count(),
interpreter_throwout_count(),
_instructions_size);
--- a/hotspot/src/share/vm/ci/ciMethod.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciMethod.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -262,6 +262,7 @@
bool is_klass_loaded(int refinfo_index, bool must_be_resolved) const;
bool check_call(int refinfo_index, bool is_static) const;
bool ensure_method_data(); // make sure it exists in the VM also
+ address ensure_method_counters();
int instructions_size();
int scale_count(int count, float prof_factor = 1.); // make MDO count commensurate with IIC
--- a/hotspot/src/share/vm/ci/ciReplay.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciReplay.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -920,12 +920,17 @@
method->print_name(tty);
tty->cr();
} else {
+ EXCEPTION_CONTEXT;
+ MethodCounters* mcs = method->method_counters();
// m->_instructions_size = rec->instructions_size;
m->_instructions_size = -1;
m->_interpreter_invocation_count = rec->interpreter_invocation_count;
m->_interpreter_throwout_count = rec->interpreter_throwout_count;
- method->invocation_counter()->_counter = rec->invocation_counter;
- method->backedge_counter()->_counter = rec->backedge_counter;
+ if (mcs == NULL) {
+ mcs = Method::build_method_counters(method, CHECK_AND_CLEAR);
+ }
+ mcs->invocation_counter()->_counter = rec->invocation_counter;
+ mcs->backedge_counter()->_counter = rec->backedge_counter;
}
}
--- a/hotspot/src/share/vm/classfile/classLoader.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1274,13 +1274,16 @@
Handle system_class_loader (THREAD, SystemDictionary::java_system_loader());
// Iterate over all bootstrap class path entries
ClassPathEntry* e = _first_entry;
+ jlong start = os::javaTimeMillis();
while (e != NULL) {
// We stop at rt.jar, unless it is the first bootstrap path entry
if (e->is_rt_jar() && e != _first_entry) break;
e->compile_the_world(system_class_loader, CATCH);
e = e->next();
}
- tty->print_cr("CompileTheWorld : Done");
+ jlong end = os::javaTimeMillis();
+ tty->print_cr("CompileTheWorld : Done (%d classes, %d methods, %d ms)",
+ _compile_the_world_class_counter, _compile_the_world_method_counter, (end - start));
{
// Print statistics as if before normal exit:
extern void print_statistics();
@@ -1289,7 +1292,8 @@
vm_exit(0);
}
-int ClassLoader::_compile_the_world_counter = 0;
+int ClassLoader::_compile_the_world_class_counter = 0;
+int ClassLoader::_compile_the_world_method_counter = 0;
static int _codecache_sweep_counter = 0;
// Filter out all exceptions except OOMs
@@ -1311,8 +1315,8 @@
// If the file has a period after removing .class, it's not really a
// valid class file. The class loader will check everything else.
if (strchr(buffer, '.') == NULL) {
- _compile_the_world_counter++;
- if (_compile_the_world_counter > CompileTheWorldStopAt) return;
+ _compile_the_world_class_counter++;
+ if (_compile_the_world_class_counter > CompileTheWorldStopAt) return;
// Construct name without extension
TempNewSymbol sym = SymbolTable::new_symbol(buffer, CHECK);
@@ -1329,16 +1333,16 @@
if (HAS_PENDING_EXCEPTION) {
// If something went wrong in preloading we just ignore it
clear_pending_exception_if_not_oom(CHECK);
- tty->print_cr("Preloading failed for (%d) %s", _compile_the_world_counter, buffer);
+ tty->print_cr("Preloading failed for (%d) %s", _compile_the_world_class_counter, buffer);
}
}
- if (_compile_the_world_counter >= CompileTheWorldStartAt) {
+ if (_compile_the_world_class_counter >= CompileTheWorldStartAt) {
if (k.is_null() || exception_occurred) {
// If something went wrong (e.g. ExceptionInInitializerError) we skip this class
- tty->print_cr("CompileTheWorld (%d) : Skipping %s", _compile_the_world_counter, buffer);
+ tty->print_cr("CompileTheWorld (%d) : Skipping %s", _compile_the_world_class_counter, buffer);
} else {
- tty->print_cr("CompileTheWorld (%d) : %s", _compile_the_world_counter, buffer);
+ tty->print_cr("CompileTheWorld (%d) : %s", _compile_the_world_class_counter, buffer);
// Preload all classes to get around uncommon traps
// Iterate over all methods in class
for (int n = 0; n < k->methods()->length(); n++) {
@@ -1356,7 +1360,9 @@
methodHandle(), 0, "CTW", THREAD);
if (HAS_PENDING_EXCEPTION) {
clear_pending_exception_if_not_oom(CHECK);
- tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_counter, m->name()->as_C_string());
+ tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name()->as_C_string());
+ } else {
+ _compile_the_world_method_counter++;
}
if (TieredCompilation && TieredStopAtLevel >= CompLevel_full_optimization) {
// Clobber the first compile and force second tier compilation
@@ -1370,7 +1376,9 @@
methodHandle(), 0, "CTW", THREAD);
if (HAS_PENDING_EXCEPTION) {
clear_pending_exception_if_not_oom(CHECK);
- tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_counter, m->name()->as_C_string());
+ tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name()->as_C_string());
+ } else {
+ _compile_the_world_method_counter++;
}
}
}
--- a/hotspot/src/share/vm/classfile/classLoader.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/classfile/classLoader.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -340,11 +340,12 @@
// Force compilation of all methods in all classes in bootstrap class path (stress test)
#ifndef PRODUCT
private:
- static int _compile_the_world_counter;
+ static int _compile_the_world_class_counter;
+ static int _compile_the_world_method_counter;
public:
static void compile_the_world();
static void compile_the_world_in(char* name, Handle loader, TRAPS);
- static int compile_the_world_counter() { return _compile_the_world_counter; }
+ static int compile_the_world_counter() { return _compile_the_world_class_counter; }
#endif //PRODUCT
};
--- a/hotspot/src/share/vm/classfile/stackMapFrame.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/classfile/stackMapFrame.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -175,14 +175,14 @@
ErrorContext* ctx, TRAPS) const;
inline void set_mark() {
-#ifdef DEBUG
+#ifdef ASSERT
// Put bogus type to indicate it's no longer valid.
if (_stack_mark != -1) {
for (int i = _stack_mark - 1; i >= _stack_size; --i) {
_stack[i] = VerificationType::bogus_type();
}
}
-#endif // def DEBUG
+#endif // def ASSERT
_stack_mark = _stack_size;
}
--- a/hotspot/src/share/vm/code/codeBlob.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/code/codeBlob.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -348,14 +348,14 @@
void* RuntimeStub::operator new(size_t s, unsigned size) {
- void* p = CodeCache::allocate(size);
+ void* p = CodeCache::allocate(size, true);
if (!p) fatal("Initial size of CodeCache is too small");
return p;
}
// operator new shared by all singletons:
void* SingletonBlob::operator new(size_t s, unsigned size) {
- void* p = CodeCache::allocate(size);
+ void* p = CodeCache::allocate(size, true);
if (!p) fatal("Initial size of CodeCache is too small");
return p;
}
--- a/hotspot/src/share/vm/code/codeCache.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/code/codeCache.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -172,7 +172,7 @@
static size_t maxCodeCacheUsed = 0;
-CodeBlob* CodeCache::allocate(int size) {
+CodeBlob* CodeCache::allocate(int size, bool is_critical) {
// Do not seize the CodeCache lock here--if the caller has not
// already done so, we are going to lose bigtime, since the code
// cache will contain a garbage CodeBlob until the caller can
@@ -183,7 +183,7 @@
CodeBlob* cb = NULL;
_number_of_blobs++;
while (true) {
- cb = (CodeBlob*)_heap->allocate(size);
+ cb = (CodeBlob*)_heap->allocate(size, is_critical);
if (cb != NULL) break;
if (!_heap->expand_by(CodeCacheExpansionSize)) {
// Expansion failed
@@ -192,8 +192,8 @@
if (PrintCodeCacheExtension) {
ResourceMark rm;
tty->print_cr("code cache extended to [" INTPTR_FORMAT ", " INTPTR_FORMAT "] (%d bytes)",
- (intptr_t)_heap->begin(), (intptr_t)_heap->end(),
- (address)_heap->end() - (address)_heap->begin());
+ (intptr_t)_heap->low_boundary(), (intptr_t)_heap->high(),
+ (address)_heap->high() - (address)_heap->low_boundary());
}
}
maxCodeCacheUsed = MAX2(maxCodeCacheUsed, ((address)_heap->high_boundary() -
@@ -608,13 +608,13 @@
address CodeCache::first_address() {
assert_locked_or_safepoint(CodeCache_lock);
- return (address)_heap->begin();
+ return (address)_heap->low_boundary();
}
address CodeCache::last_address() {
assert_locked_or_safepoint(CodeCache_lock);
- return (address)_heap->end();
+ return (address)_heap->high();
}
@@ -996,10 +996,9 @@
void CodeCache::print_summary(outputStream* st, bool detailed) {
size_t total = (_heap->high_boundary() - _heap->low_boundary());
st->print_cr("CodeCache: size=" SIZE_FORMAT "Kb used=" SIZE_FORMAT
- "Kb max_used=" SIZE_FORMAT "Kb free=" SIZE_FORMAT
- "Kb max_free_chunk=" SIZE_FORMAT "Kb",
+ "Kb max_used=" SIZE_FORMAT "Kb free=" SIZE_FORMAT "Kb",
total/K, (total - unallocated_capacity())/K,
- maxCodeCacheUsed/K, unallocated_capacity()/K, largest_free_block()/K);
+ maxCodeCacheUsed/K, unallocated_capacity()/K);
if (detailed) {
st->print_cr(" bounds [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT "]",
@@ -1018,19 +1017,8 @@
void CodeCache::log_state(outputStream* st) {
st->print(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'"
- " adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'"
- " largest_free_block='" SIZE_FORMAT "'",
+ " adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
nof_blobs(), nof_nmethods(), nof_adapters(),
- unallocated_capacity(), largest_free_block());
+ unallocated_capacity());
}
-size_t CodeCache::largest_free_block() {
- // This is called both with and without CodeCache_lock held so
- // handle both cases.
- if (CodeCache_lock->owned_by_self()) {
- return _heap->largest_free_block();
- } else {
- MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
- return _heap->largest_free_block();
- }
-}
--- a/hotspot/src/share/vm/code/codeCache.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/code/codeCache.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -70,7 +70,7 @@
static void initialize();
// Allocation/administration
- static CodeBlob* allocate(int size); // allocates a new CodeBlob
+ static CodeBlob* allocate(int size, bool is_critical = false); // allocates a new CodeBlob
static void commit(CodeBlob* cb); // called when the allocated CodeBlob has been filled
static int alignment_unit(); // guaranteed alignment of all CodeBlobs
static int alignment_offset(); // guaranteed offset of first CodeBlob byte within alignment unit (i.e., allocation header)
@@ -156,19 +156,13 @@
static address low_bound() { return (address) _heap->low_boundary(); }
static address high_bound() { return (address) _heap->high_boundary(); }
- static bool has_space(int size) {
- // Always leave some room in the CodeCache for I2C/C2I adapters
- return largest_free_block() > (CodeCacheMinimumFreeSpace + size);
- }
-
// Profiling
static address first_address(); // first address used for CodeBlobs
static address last_address(); // last address used for CodeBlobs
static size_t capacity() { return _heap->capacity(); }
static size_t max_capacity() { return _heap->max_capacity(); }
static size_t unallocated_capacity() { return _heap->unallocated_capacity(); }
- static size_t largest_free_block();
- static bool needs_flushing() { return largest_free_block() < CodeCacheFlushingMinimumFreeSpace; }
+ static bool needs_flushing() { return unallocated_capacity() < CodeCacheFlushingMinimumFreeSpace; }
static bool needs_cache_clean() { return _needs_cache_clean; }
static void set_needs_cache_clean(bool v) { _needs_cache_clean = v; }
--- a/hotspot/src/share/vm/code/nmethod.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/code/nmethod.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -501,18 +501,17 @@
{
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
int native_nmethod_size = allocation_size(code_buffer, sizeof(nmethod));
- if (CodeCache::has_space(native_nmethod_size)) {
- CodeOffsets offsets;
- offsets.set_value(CodeOffsets::Verified_Entry, vep_offset);
- offsets.set_value(CodeOffsets::Frame_Complete, frame_complete);
- nm = new (native_nmethod_size) nmethod(method(), native_nmethod_size,
- compile_id, &offsets,
- code_buffer, frame_size,
- basic_lock_owner_sp_offset,
- basic_lock_sp_offset, oop_maps);
- NOT_PRODUCT(if (nm != NULL) nmethod_stats.note_native_nmethod(nm));
- if (PrintAssembly && nm != NULL)
- Disassembler::decode(nm);
+ CodeOffsets offsets;
+ offsets.set_value(CodeOffsets::Verified_Entry, vep_offset);
+ offsets.set_value(CodeOffsets::Frame_Complete, frame_complete);
+ nm = new (native_nmethod_size) nmethod(method(), native_nmethod_size,
+ compile_id, &offsets,
+ code_buffer, frame_size,
+ basic_lock_owner_sp_offset,
+ basic_lock_sp_offset, oop_maps);
+ NOT_PRODUCT(if (nm != NULL) nmethod_stats.note_native_nmethod(nm));
+ if (PrintAssembly && nm != NULL) {
+ Disassembler::decode(nm);
}
}
// verify nmethod
@@ -538,18 +537,17 @@
{
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
int nmethod_size = allocation_size(code_buffer, sizeof(nmethod));
- if (CodeCache::has_space(nmethod_size)) {
- CodeOffsets offsets;
- offsets.set_value(CodeOffsets::Verified_Entry, vep_offset);
- offsets.set_value(CodeOffsets::Dtrace_trap, trap_offset);
- offsets.set_value(CodeOffsets::Frame_Complete, frame_complete);
+ CodeOffsets offsets;
+ offsets.set_value(CodeOffsets::Verified_Entry, vep_offset);
+ offsets.set_value(CodeOffsets::Dtrace_trap, trap_offset);
+ offsets.set_value(CodeOffsets::Frame_Complete, frame_complete);
- nm = new (nmethod_size) nmethod(method(), nmethod_size,
- &offsets, code_buffer, frame_size);
+ nm = new (nmethod_size) nmethod(method(), nmethod_size,
+ &offsets, code_buffer, frame_size);
- NOT_PRODUCT(if (nm != NULL) nmethod_stats.note_nmethod(nm));
- if (PrintAssembly && nm != NULL)
- Disassembler::decode(nm);
+ NOT_PRODUCT(if (nm != NULL) nmethod_stats.note_nmethod(nm));
+ if (PrintAssembly && nm != NULL) {
+ Disassembler::decode(nm);
}
}
// verify nmethod
@@ -591,16 +589,16 @@
+ round_to(handler_table->size_in_bytes(), oopSize)
+ round_to(nul_chk_table->size_in_bytes(), oopSize)
+ round_to(debug_info->data_size() , oopSize);
- if (CodeCache::has_space(nmethod_size)) {
- nm = new (nmethod_size)
- nmethod(method(), nmethod_size, compile_id, entry_bci, offsets,
- orig_pc_offset, debug_info, dependencies, code_buffer, frame_size,
- oop_maps,
- handler_table,
- nul_chk_table,
- compiler,
- comp_level);
- }
+
+ nm = new (nmethod_size)
+ nmethod(method(), nmethod_size, compile_id, entry_bci, offsets,
+ orig_pc_offset, debug_info, dependencies, code_buffer, frame_size,
+ oop_maps,
+ handler_table,
+ nul_chk_table,
+ compiler,
+ comp_level);
+
if (nm != NULL) {
// To make dependency checking during class loading fast, record
// the nmethod dependencies in the classes it is dependent on.
@@ -612,15 +610,18 @@
// classes the slow way is too slow.
for (Dependencies::DepStream deps(nm); deps.next(); ) {
Klass* klass = deps.context_type();
- if (klass == NULL) continue; // ignore things like evol_method
+ if (klass == NULL) {
+ continue; // ignore things like evol_method
+ }
// record this nmethod as dependent on this klass
InstanceKlass::cast(klass)->add_dependent_nmethod(nm);
}
}
NOT_PRODUCT(if (nm != NULL) nmethod_stats.note_nmethod(nm));
- if (PrintAssembly && nm != NULL)
+ if (PrintAssembly && nm != NULL) {
Disassembler::decode(nm);
+ }
}
// verify nmethod
@@ -798,13 +799,11 @@
}
#endif // def HAVE_DTRACE_H
-void* nmethod::operator new(size_t size, int nmethod_size) {
- void* alloc = CodeCache::allocate(nmethod_size);
- guarantee(alloc != NULL, "CodeCache should have enough space");
- return alloc;
+void* nmethod::operator new(size_t size, int nmethod_size) throw () {
+ // Not critical, may return null if there is too little continuous memory
+ return CodeCache::allocate(nmethod_size);
}
-
nmethod::nmethod(
Method* method,
int nmethod_size,
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1581,7 +1581,7 @@
// We need this HandleMark to avoid leaking VM handles.
HandleMark hm(thread);
- if (CodeCache::largest_free_block() < CodeCacheMinimumFreeSpace) {
+ if (CodeCache::unallocated_capacity() < CodeCacheMinimumFreeSpace) {
// the code cache is really full
handle_full_code_cache();
} else if (UseCodeCacheFlushing && CodeCache::needs_flushing()) {
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -6921,7 +6921,7 @@
size = CompactibleFreeListSpace::adjustObjectSize(
p->oop_iterate(_scanningClosure));
}
- #ifdef DEBUG
+ #ifdef ASSERT
size_t direct_size =
CompactibleFreeListSpace::adjustObjectSize(p->size());
assert(size == direct_size, "Inconsistency in size");
@@ -6933,7 +6933,7 @@
assert(_bitMap->isMarked(addr+size-1),
"inconsistent Printezis mark");
}
- #endif // DEBUG
+ #endif // ASSERT
} else {
// an unitialized object
assert(_bitMap->isMarked(addr+1), "missing Printezis mark?");
@@ -7075,14 +7075,14 @@
HeapWord* addr = (HeapWord*)p;
assert(_span.contains(addr), "we are scanning the CMS generation");
bool is_obj_array = false;
- #ifdef DEBUG
+ #ifdef ASSERT
if (!_parallel) {
assert(_mark_stack->isEmpty(), "pre-condition (eager drainage)");
assert(_collector->overflow_list_is_empty(),
"overflow list should be empty");
}
- #endif // DEBUG
+ #endif // ASSERT
if (_bit_map->isMarked(addr)) {
// Obj arrays are precisely marked, non-arrays are not;
// so we scan objArrays precisely and non-arrays in their
@@ -7102,14 +7102,14 @@
}
}
}
- #ifdef DEBUG
+ #ifdef ASSERT
if (!_parallel) {
assert(_mark_stack->isEmpty(), "post-condition (eager drainage)");
assert(_collector->overflow_list_is_empty(),
"overflow list should be empty");
}
- #endif // DEBUG
+ #endif // ASSERT
return is_obj_array;
}
@@ -8320,7 +8320,7 @@
assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
"alignment problem");
-#ifdef DEBUG
+#ifdef ASSERT
if (oop(addr)->klass_or_null() != NULL) {
// Ignore mark word because we are running concurrent with mutators
assert(oop(addr)->is_oop(true), "live block should be an oop");
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -1322,233 +1322,239 @@
gclog_or_tty->date_stamp(G1Log::fine() && PrintGCDateStamps);
TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
- TraceTime t(GCCauseString("Full GC", gc_cause()), G1Log::fine(), true, gclog_or_tty);
- TraceCollectorStats tcs(g1mm()->full_collection_counters());
- TraceMemoryManagerStats tms(true /* fullGC */, gc_cause());
-
- double start = os::elapsedTime();
- g1_policy()->record_full_collection_start();
-
- // Note: When we have a more flexible GC logging framework that
- // allows us to add optional attributes to a GC log record we
- // could consider timing and reporting how long we wait in the
- // following two methods.
- wait_while_free_regions_coming();
- // If we start the compaction before the CM threads finish
- // scanning the root regions we might trip them over as we'll
- // be moving objects / updating references. So let's wait until
- // they are done. By telling them to abort, they should complete
- // early.
- _cm->root_regions()->abort();
- _cm->root_regions()->wait_until_scan_finished();
- append_secondary_free_list_if_not_empty_with_lock();
-
- gc_prologue(true);
- increment_total_collections(true /* full gc */);
- increment_old_marking_cycles_started();
-
- size_t g1h_prev_used = used();
- assert(used() == recalculate_used(), "Should be equal");
-
- verify_before_gc();
-
- pre_full_gc_dump();
-
- COMPILER2_PRESENT(DerivedPointerTable::clear());
-
- // Disable discovery and empty the discovered lists
- // for the CM ref processor.
- ref_processor_cm()->disable_discovery();
- ref_processor_cm()->abandon_partial_discovery();
- ref_processor_cm()->verify_no_references_recorded();
-
- // Abandon current iterations of concurrent marking and concurrent
- // refinement, if any are in progress. We have to do this before
- // wait_until_scan_finished() below.
- concurrent_mark()->abort();
-
- // Make sure we'll choose a new allocation region afterwards.
- release_mutator_alloc_region();
- abandon_gc_alloc_regions();
- g1_rem_set()->cleanupHRRS();
-
- // We should call this after we retire any currently active alloc
- // regions so that all the ALLOC / RETIRE events are generated
- // before the start GC event.
- _hr_printer.start_gc(true /* full */, (size_t) total_collections());
-
- // We may have added regions to the current incremental collection
- // set between the last GC or pause and now. We need to clear the
- // incremental collection set and then start rebuilding it afresh
- // after this full GC.
- abandon_collection_set(g1_policy()->inc_cset_head());
- g1_policy()->clear_incremental_cset();
- g1_policy()->stop_incremental_cset_building();
-
- tear_down_region_sets(false /* free_list_only */);
- g1_policy()->set_gcs_are_young(true);
-
- // See the comments in g1CollectedHeap.hpp and
- // G1CollectedHeap::ref_processing_init() about
- // how reference processing currently works in G1.
-
- // Temporarily make discovery by the STW ref processor single threaded (non-MT).
- ReferenceProcessorMTDiscoveryMutator stw_rp_disc_ser(ref_processor_stw(), false);
-
- // Temporarily clear the STW ref processor's _is_alive_non_header field.
- ReferenceProcessorIsAliveMutator stw_rp_is_alive_null(ref_processor_stw(), NULL);
-
- ref_processor_stw()->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/);
- ref_processor_stw()->setup_policy(do_clear_all_soft_refs);
-
- // Do collection work
{
- HandleMark hm; // Discard invalid handles created during gc
- G1MarkSweep::invoke_at_safepoint(ref_processor_stw(), do_clear_all_soft_refs);
- }
-
- assert(free_regions() == 0, "we should not have added any free regions");
- rebuild_region_sets(false /* free_list_only */);
-
- // Enqueue any discovered reference objects that have
- // not been removed from the discovered lists.
- ref_processor_stw()->enqueue_discovered_references();
-
- COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
-
- MemoryService::track_memory_usage();
-
- verify_after_gc();
-
- assert(!ref_processor_stw()->discovery_enabled(), "Postcondition");
- ref_processor_stw()->verify_no_references_recorded();
-
- // Delete metaspaces for unloaded class loaders and clean up loader_data graph
- ClassLoaderDataGraph::purge();
-
- // Note: since we've just done a full GC, concurrent
- // marking is no longer active. Therefore we need not
- // re-enable reference discovery for the CM ref processor.
- // That will be done at the start of the next marking cycle.
- assert(!ref_processor_cm()->discovery_enabled(), "Postcondition");
- ref_processor_cm()->verify_no_references_recorded();
-
- reset_gc_time_stamp();
- // Since everything potentially moved, we will clear all remembered
- // sets, and clear all cards. Later we will rebuild remebered
- // sets. We will also reset the GC time stamps of the regions.
- clear_rsets_post_compaction();
- check_gc_time_stamps();
-
- // Resize the heap if necessary.
- resize_if_necessary_after_full_collection(explicit_gc ? 0 : word_size);
-
- if (_hr_printer.is_active()) {
- // We should do this after we potentially resize the heap so
- // that all the COMMIT / UNCOMMIT events are generated before
- // the end GC event.
-
- print_hrs_post_compaction();
- _hr_printer.end_gc(true /* full */, (size_t) total_collections());
- }
-
- if (_cg1r->use_cache()) {
- _cg1r->clear_and_record_card_counts();
- _cg1r->clear_hot_cache();
- }
-
- // Rebuild remembered sets of all regions.
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- uint n_workers =
- AdaptiveSizePolicy::calc_active_workers(workers()->total_workers(),
- workers()->active_workers(),
- Threads::number_of_non_daemon_threads());
- assert(UseDynamicNumberOfGCThreads ||
- n_workers == workers()->total_workers(),
- "If not dynamic should be using all the workers");
- workers()->set_active_workers(n_workers);
- // Set parallel threads in the heap (_n_par_threads) only
- // before a parallel phase and always reset it to 0 after
- // the phase so that the number of parallel threads does
- // no get carried forward to a serial phase where there
- // may be code that is "possibly_parallel".
- set_par_threads(n_workers);
-
- ParRebuildRSTask rebuild_rs_task(this);
- assert(check_heap_region_claim_values(
- HeapRegion::InitialClaimValue), "sanity check");
- assert(UseDynamicNumberOfGCThreads ||
- workers()->active_workers() == workers()->total_workers(),
- "Unless dynamic should use total workers");
- // Use the most recent number of active workers
- assert(workers()->active_workers() > 0,
- "Active workers not properly set");
- set_par_threads(workers()->active_workers());
- workers()->run_task(&rebuild_rs_task);
- set_par_threads(0);
- assert(check_heap_region_claim_values(
- HeapRegion::RebuildRSClaimValue), "sanity check");
- reset_heap_region_claim_values();
- } else {
- RebuildRSOutOfRegionClosure rebuild_rs(this);
- heap_region_iterate(&rebuild_rs);
- }
-
- if (G1Log::fine()) {
- print_size_transition(gclog_or_tty, g1h_prev_used, used(), capacity());
- }
-
- if (true) { // FIXME
- MetaspaceGC::compute_new_size();
- }
-
- // Start a new incremental collection set for the next pause
- assert(g1_policy()->collection_set() == NULL, "must be");
- g1_policy()->start_incremental_cset_building();
-
- // Clear the _cset_fast_test bitmap in anticipation of adding
- // regions to the incremental collection set for the next
- // evacuation pause.
- clear_cset_fast_test();
-
- init_mutator_alloc_region();
-
- double end = os::elapsedTime();
- g1_policy()->record_full_collection_end();
+ TraceTime t(GCCauseString("Full GC", gc_cause()), G1Log::fine(), true, gclog_or_tty);
+ TraceCollectorStats tcs(g1mm()->full_collection_counters());
+ TraceMemoryManagerStats tms(true /* fullGC */, gc_cause());
+
+ double start = os::elapsedTime();
+ g1_policy()->record_full_collection_start();
+
+ // Note: When we have a more flexible GC logging framework that
+ // allows us to add optional attributes to a GC log record we
+ // could consider timing and reporting how long we wait in the
+ // following two methods.
+ wait_while_free_regions_coming();
+ // If we start the compaction before the CM threads finish
+ // scanning the root regions we might trip them over as we'll
+ // be moving objects / updating references. So let's wait until
+ // they are done. By telling them to abort, they should complete
+ // early.
+ _cm->root_regions()->abort();
+ _cm->root_regions()->wait_until_scan_finished();
+ append_secondary_free_list_if_not_empty_with_lock();
+
+ gc_prologue(true);
+ increment_total_collections(true /* full gc */);
+ increment_old_marking_cycles_started();
+
+ assert(used() == recalculate_used(), "Should be equal");
+
+ verify_before_gc();
+
+ pre_full_gc_dump();
+
+ COMPILER2_PRESENT(DerivedPointerTable::clear());
+
+ // Disable discovery and empty the discovered lists
+ // for the CM ref processor.
+ ref_processor_cm()->disable_discovery();
+ ref_processor_cm()->abandon_partial_discovery();
+ ref_processor_cm()->verify_no_references_recorded();
+
+ // Abandon current iterations of concurrent marking and concurrent
+ // refinement, if any are in progress. We have to do this before
+ // wait_until_scan_finished() below.
+ concurrent_mark()->abort();
+
+ // Make sure we'll choose a new allocation region afterwards.
+ release_mutator_alloc_region();
+ abandon_gc_alloc_regions();
+ g1_rem_set()->cleanupHRRS();
+
+ // We should call this after we retire any currently active alloc
+ // regions so that all the ALLOC / RETIRE events are generated
+ // before the start GC event.
+ _hr_printer.start_gc(true /* full */, (size_t) total_collections());
+
+ // We may have added regions to the current incremental collection
+ // set between the last GC or pause and now. We need to clear the
+ // incremental collection set and then start rebuilding it afresh
+ // after this full GC.
+ abandon_collection_set(g1_policy()->inc_cset_head());
+ g1_policy()->clear_incremental_cset();
+ g1_policy()->stop_incremental_cset_building();
+
+ tear_down_region_sets(false /* free_list_only */);
+ g1_policy()->set_gcs_are_young(true);
+
+ // See the comments in g1CollectedHeap.hpp and
+ // G1CollectedHeap::ref_processing_init() about
+ // how reference processing currently works in G1.
+
+ // Temporarily make discovery by the STW ref processor single threaded (non-MT).
+ ReferenceProcessorMTDiscoveryMutator stw_rp_disc_ser(ref_processor_stw(), false);
+
+ // Temporarily clear the STW ref processor's _is_alive_non_header field.
+ ReferenceProcessorIsAliveMutator stw_rp_is_alive_null(ref_processor_stw(), NULL);
+
+ ref_processor_stw()->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/);
+ ref_processor_stw()->setup_policy(do_clear_all_soft_refs);
+
+ // Do collection work
+ {
+ HandleMark hm; // Discard invalid handles created during gc
+ G1MarkSweep::invoke_at_safepoint(ref_processor_stw(), do_clear_all_soft_refs);
+ }
+
+ assert(free_regions() == 0, "we should not have added any free regions");
+ rebuild_region_sets(false /* free_list_only */);
+
+ // Enqueue any discovered reference objects that have
+ // not been removed from the discovered lists.
+ ref_processor_stw()->enqueue_discovered_references();
+
+ COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
+
+ MemoryService::track_memory_usage();
+
+ verify_after_gc();
+
+ assert(!ref_processor_stw()->discovery_enabled(), "Postcondition");
+ ref_processor_stw()->verify_no_references_recorded();
+
+ // Delete metaspaces for unloaded class loaders and clean up loader_data graph
+ ClassLoaderDataGraph::purge();
+
+ // Note: since we've just done a full GC, concurrent
+ // marking is no longer active. Therefore we need not
+ // re-enable reference discovery for the CM ref processor.
+ // That will be done at the start of the next marking cycle.
+ assert(!ref_processor_cm()->discovery_enabled(), "Postcondition");
+ ref_processor_cm()->verify_no_references_recorded();
+
+ reset_gc_time_stamp();
+ // Since everything potentially moved, we will clear all remembered
+ // sets, and clear all cards. Later we will rebuild remebered
+ // sets. We will also reset the GC time stamps of the regions.
+ clear_rsets_post_compaction();
+ check_gc_time_stamps();
+
+ // Resize the heap if necessary.
+ resize_if_necessary_after_full_collection(explicit_gc ? 0 : word_size);
+
+ if (_hr_printer.is_active()) {
+ // We should do this after we potentially resize the heap so
+ // that all the COMMIT / UNCOMMIT events are generated before
+ // the end GC event.
+
+ print_hrs_post_compaction();
+ _hr_printer.end_gc(true /* full */, (size_t) total_collections());
+ }
+
+ if (_cg1r->use_cache()) {
+ _cg1r->clear_and_record_card_counts();
+ _cg1r->clear_hot_cache();
+ }
+
+ // Rebuild remembered sets of all regions.
+ if (G1CollectedHeap::use_parallel_gc_threads()) {
+ uint n_workers =
+ AdaptiveSizePolicy::calc_active_workers(workers()->total_workers(),
+ workers()->active_workers(),
+ Threads::number_of_non_daemon_threads());
+ assert(UseDynamicNumberOfGCThreads ||
+ n_workers == workers()->total_workers(),
+ "If not dynamic should be using all the workers");
+ workers()->set_active_workers(n_workers);
+ // Set parallel threads in the heap (_n_par_threads) only
+ // before a parallel phase and always reset it to 0 after
+ // the phase so that the number of parallel threads does
+ // no get carried forward to a serial phase where there
+ // may be code that is "possibly_parallel".
+ set_par_threads(n_workers);
+
+ ParRebuildRSTask rebuild_rs_task(this);
+ assert(check_heap_region_claim_values(
+ HeapRegion::InitialClaimValue), "sanity check");
+ assert(UseDynamicNumberOfGCThreads ||
+ workers()->active_workers() == workers()->total_workers(),
+ "Unless dynamic should use total workers");
+ // Use the most recent number of active workers
+ assert(workers()->active_workers() > 0,
+ "Active workers not properly set");
+ set_par_threads(workers()->active_workers());
+ workers()->run_task(&rebuild_rs_task);
+ set_par_threads(0);
+ assert(check_heap_region_claim_values(
+ HeapRegion::RebuildRSClaimValue), "sanity check");
+ reset_heap_region_claim_values();
+ } else {
+ RebuildRSOutOfRegionClosure rebuild_rs(this);
+ heap_region_iterate(&rebuild_rs);
+ }
+
+ if (true) { // FIXME
+ MetaspaceGC::compute_new_size();
+ }
#ifdef TRACESPINNING
- ParallelTaskTerminator::print_termination_counts();
+ ParallelTaskTerminator::print_termination_counts();
#endif
- gc_epilogue(true);
-
- // Discard all rset updates
- JavaThread::dirty_card_queue_set().abandon_logs();
- assert(!G1DeferredRSUpdate
- || (G1DeferredRSUpdate && (dirty_card_queue_set().completed_buffers_num() == 0)), "Should not be any");
-
- _young_list->reset_sampled_info();
- // At this point there should be no regions in the
- // entire heap tagged as young.
- assert( check_young_list_empty(true /* check_heap */),
- "young list should be empty at this point");
-
- // Update the number of full collections that have been completed.
- increment_old_marking_cycles_completed(false /* concurrent */);
-
- _hrs.verify_optional();
- verify_region_sets_optional();
+ // Discard all rset updates
+ JavaThread::dirty_card_queue_set().abandon_logs();
+ assert(!G1DeferredRSUpdate
+ || (G1DeferredRSUpdate &&
+ (dirty_card_queue_set().completed_buffers_num() == 0)), "Should not be any");
+
+ _young_list->reset_sampled_info();
+ // At this point there should be no regions in the
+ // entire heap tagged as young.
+ assert(check_young_list_empty(true /* check_heap */),
+ "young list should be empty at this point");
+
+ // Update the number of full collections that have been completed.
+ increment_old_marking_cycles_completed(false /* concurrent */);
+
+ _hrs.verify_optional();
+ verify_region_sets_optional();
+
+ // Start a new incremental collection set for the next pause
+ assert(g1_policy()->collection_set() == NULL, "must be");
+ g1_policy()->start_incremental_cset_building();
+
+ // Clear the _cset_fast_test bitmap in anticipation of adding
+ // regions to the incremental collection set for the next
+ // evacuation pause.
+ clear_cset_fast_test();
+
+ init_mutator_alloc_region();
+
+ double end = os::elapsedTime();
+ g1_policy()->record_full_collection_end();
+
+ if (G1Log::fine()) {
+ g1_policy()->print_heap_transition();
+ }
+
+ // We must call G1MonitoringSupport::update_sizes() in the same scoping level
+ // as an active TraceMemoryManagerStats object (i.e. before the destructor for the
+ // TraceMemoryManagerStats is called) so that the G1 memory pools are updated
+ // before any GC notifications are raised.
+ g1mm()->update_sizes();
+
+ gc_epilogue(true);
+ }
+
+ if (G1Log::finer()) {
+ g1_policy()->print_detailed_heap_transition();
+ }
print_heap_after_gc();
- // We must call G1MonitoringSupport::update_sizes() in the same scoping level
- // as an active TraceMemoryManagerStats object (i.e. before the destructor for the
- // TraceMemoryManagerStats is called) so that the G1 memory pools are updated
- // before any GC notifications are raised.
- g1mm()->update_sizes();
- }
-
- post_full_gc_dump();
+ post_full_gc_dump();
+ }
return true;
}
@@ -3838,7 +3844,6 @@
// The elapsed time induced by the start time below deliberately elides
// the possible verification above.
double sample_start_time_sec = os::elapsedTime();
- size_t start_used_bytes = used();
#if YOUNG_LIST_VERBOSE
gclog_or_tty->print_cr("\nBefore recording pause start.\nYoung_list:");
@@ -3846,8 +3851,7 @@
g1_policy()->print_collection_set(g1_policy()->inc_cset_head(), gclog_or_tty);
#endif // YOUNG_LIST_VERBOSE
- g1_policy()->record_collection_pause_start(sample_start_time_sec,
- start_used_bytes);
+ g1_policy()->record_collection_pause_start(sample_start_time_sec);
double scan_wait_start = os::elapsedTime();
// We have to wait until the CM threads finish scanning the
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -406,7 +406,6 @@
}
_free_regions_at_end_of_collection = _g1->free_regions();
update_young_list_target_length();
- _prev_eden_capacity = _young_list_target_length * HeapRegion::GrainBytes;
// We may immediately start allocating regions and placing them on the
// collection set list. Initialize the per-collection set info
@@ -746,6 +745,7 @@
void G1CollectorPolicy::record_full_collection_start() {
_full_collection_start_sec = os::elapsedTime();
+ record_heap_size_info_at_start();
// Release the future to-space so that it is available for compaction into.
_g1->set_full_collection();
}
@@ -788,8 +788,7 @@
_stop_world_start = os::elapsedTime();
}
-void G1CollectorPolicy::record_collection_pause_start(double start_time_sec,
- size_t start_used) {
+void G1CollectorPolicy::record_collection_pause_start(double start_time_sec) {
// We only need to do this here as the policy will only be applied
// to the GC we're about to start. so, no point is calculating this
// every time we calculate / recalculate the target young length.
@@ -803,19 +802,14 @@
_trace_gen0_time_data.record_start_collection(s_w_t_ms);
_stop_world_start = 0.0;
+ record_heap_size_info_at_start();
+
phase_times()->record_cur_collection_start_sec(start_time_sec);
- _cur_collection_pause_used_at_start_bytes = start_used;
- _cur_collection_pause_used_regions_at_start = _g1->used_regions();
_pending_cards = _g1->pending_card_num();
_collection_set_bytes_used_before = 0;
_bytes_copied_during_gc = 0;
- YoungList* young_list = _g1->young_list();
- _eden_bytes_before_gc = young_list->eden_used_bytes();
- _survivor_bytes_before_gc = young_list->survivor_used_bytes();
- _capacity_before_gc = _g1->capacity();
-
_last_gc_was_young = false;
// do that for any other surv rate groups
@@ -1153,6 +1147,21 @@
byte_size_in_proper_unit((double)(bytes)), \
proper_unit_for_byte_size((bytes))
+void G1CollectorPolicy::record_heap_size_info_at_start() {
+ YoungList* young_list = _g1->young_list();
+ _eden_bytes_before_gc = young_list->eden_used_bytes();
+ _survivor_bytes_before_gc = young_list->survivor_used_bytes();
+ _capacity_before_gc = _g1->capacity();
+
+ _cur_collection_pause_used_at_start_bytes = _g1->used();
+ _cur_collection_pause_used_regions_at_start = _g1->used_regions();
+
+ size_t eden_capacity_before_gc =
+ (_young_list_target_length * HeapRegion::GrainBytes) - _survivor_bytes_before_gc;
+
+ _prev_eden_capacity = eden_capacity_before_gc;
+}
+
void G1CollectorPolicy::print_heap_transition() {
_g1->print_size_transition(gclog_or_tty,
_cur_collection_pause_used_at_start_bytes, _g1->used(), _g1->capacity());
@@ -1183,8 +1192,6 @@
EXT_SIZE_PARAMS(_capacity_before_gc),
EXT_SIZE_PARAMS(used),
EXT_SIZE_PARAMS(capacity));
-
- _prev_eden_capacity = eden_capacity;
}
void G1CollectorPolicy::adjust_concurrent_refinement(double update_rs_time,
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -671,34 +671,36 @@
bool need_to_start_conc_mark(const char* source, size_t alloc_word_size = 0);
- // Update the heuristic info to record a collection pause of the given
- // start time, where the given number of bytes were used at the start.
- // This may involve changing the desired size of a collection set.
+ // Record the start and end of an evacuation pause.
+ void record_collection_pause_start(double start_time_sec);
+ void record_collection_pause_end(double pause_time_ms);
- void record_stop_world_start();
-
- void record_collection_pause_start(double start_time_sec, size_t start_used);
+ // Record the start and end of a full collection.
+ void record_full_collection_start();
+ void record_full_collection_end();
// Must currently be called while the world is stopped.
- void record_concurrent_mark_init_end(double
- mark_init_elapsed_time_ms);
+ void record_concurrent_mark_init_end(double mark_init_elapsed_time_ms);
+ // Record start and end of remark.
void record_concurrent_mark_remark_start();
void record_concurrent_mark_remark_end();
+ // Record start, end, and completion of cleanup.
void record_concurrent_mark_cleanup_start();
void record_concurrent_mark_cleanup_end(int no_of_gc_threads);
void record_concurrent_mark_cleanup_completed();
- void record_concurrent_pause();
+ // Records the information about the heap size for reporting in
+ // print_detailed_heap_transition
+ void record_heap_size_info_at_start();
- void record_collection_pause_end(double pause_time);
+ // Print heap sizing transition (with less and more detail).
void print_heap_transition();
void print_detailed_heap_transition();
- // Record the fact that a full collection occurred.
- void record_full_collection_start();
- void record_full_collection_end();
+ void record_stop_world_start();
+ void record_concurrent_pause();
// Record how much space we copied during a GC. This is typically
// called when a GC alloc region is being retired.
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -454,7 +454,7 @@
continuation = Interpreter::remove_activation_entry();
#endif
// Count this for compilation purposes
- h_method->interpreter_throwout_increment();
+ h_method->interpreter_throwout_increment(THREAD);
} else {
// handler in this method => change bci/bcp to handler bci/bcp and continue there
handler_pc = h_method->code_base() + handler_bci;
@@ -903,6 +903,15 @@
fr.interpreter_frame_set_mdp(new_mdp);
IRT_END
+IRT_ENTRY(MethodCounters*, InterpreterRuntime::build_method_counters(JavaThread* thread, Method* m))
+ MethodCounters* mcs = Method::build_method_counters(m, thread);
+ if (HAS_PENDING_EXCEPTION) {
+ assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here");
+ CLEAR_PENDING_EXCEPTION;
+ }
+ return mcs;
+IRT_END
+
IRT_ENTRY(void, InterpreterRuntime::at_safepoint(JavaThread* thread))
// We used to need an explict preserve_arguments here for invoke bytecodes. However,
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -169,6 +169,7 @@
#ifdef ASSERT
static void verify_mdp(Method* method, address bcp, address mdp);
#endif // ASSERT
+ static MethodCounters* build_method_counters(JavaThread* thread, Method* m);
};
--- a/hotspot/src/share/vm/interpreter/invocationCounter.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/interpreter/invocationCounter.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -104,15 +104,19 @@
static address do_nothing(methodHandle method, TRAPS) {
// dummy action for inactive invocation counters
- method->invocation_counter()->set_carry();
- method->invocation_counter()->set_state(InvocationCounter::wait_for_nothing);
+ MethodCounters* mcs = method->method_counters();
+ assert(mcs != NULL, "");
+ mcs->invocation_counter()->set_carry();
+ mcs->invocation_counter()->set_state(InvocationCounter::wait_for_nothing);
return NULL;
}
static address do_decay(methodHandle method, TRAPS) {
// decay invocation counters so compilation gets delayed
- method->invocation_counter()->decay();
+ MethodCounters* mcs = method->method_counters();
+ assert(mcs != NULL, "");
+ mcs->invocation_counter()->decay();
return NULL;
}
--- a/hotspot/src/share/vm/memory/allocation.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/memory/allocation.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -178,7 +178,7 @@
#endif // INCLUDE_NMT
// debug build does not inline
-#if defined(_DEBUG_)
+#if defined(_NMT_NOINLINE_)
#define CURRENT_PC (NMT_track_callsite ? os::get_caller_pc(1) : 0)
#define CALLER_PC (NMT_track_callsite ? os::get_caller_pc(2) : 0)
#define CALLER_CALLER_PC (NMT_track_callsite ? os::get_caller_pc(3) : 0)
--- a/hotspot/src/share/vm/memory/heap.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/memory/heap.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -42,7 +42,7 @@
_log2_segment_size = 0;
_next_segment = 0;
_freelist = NULL;
- _free_segments = 0;
+ _freelist_segments = 0;
}
@@ -115,8 +115,8 @@
}
on_code_mapping(_memory.low(), _memory.committed_size());
- _number_of_committed_segments = number_of_segments(_memory.committed_size());
- _number_of_reserved_segments = number_of_segments(_memory.reserved_size());
+ _number_of_committed_segments = size_to_segments(_memory.committed_size());
+ _number_of_reserved_segments = size_to_segments(_memory.reserved_size());
assert(_number_of_reserved_segments >= _number_of_committed_segments, "just checking");
// reserve space for _segmap
@@ -149,8 +149,8 @@
if (!_memory.expand_by(dm)) return false;
on_code_mapping(base, dm);
size_t i = _number_of_committed_segments;
- _number_of_committed_segments = number_of_segments(_memory.committed_size());
- assert(_number_of_reserved_segments == number_of_segments(_memory.reserved_size()), "number of reserved segments should not change");
+ _number_of_committed_segments = size_to_segments(_memory.committed_size());
+ assert(_number_of_reserved_segments == size_to_segments(_memory.reserved_size()), "number of reserved segments should not change");
assert(_number_of_reserved_segments >= _number_of_committed_segments, "just checking");
// expand _segmap space
size_t ds = align_to_page_size(_number_of_committed_segments) - _segmap.committed_size();
@@ -176,33 +176,44 @@
}
-void* CodeHeap::allocate(size_t size) {
- size_t length = number_of_segments(size + sizeof(HeapBlock));
- assert(length *_segment_size >= sizeof(FreeBlock), "not enough room for FreeList");
+void* CodeHeap::allocate(size_t instance_size, bool is_critical) {
+ size_t number_of_segments = size_to_segments(instance_size + sizeof(HeapBlock));
+ assert(segments_to_size(number_of_segments) >= sizeof(FreeBlock), "not enough room for FreeList");
// First check if we can satify request from freelist
debug_only(verify());
- HeapBlock* block = search_freelist(length);
+ HeapBlock* block = search_freelist(number_of_segments, is_critical);
debug_only(if (VerifyCodeCacheOften) verify());
if (block != NULL) {
- assert(block->length() >= length && block->length() < length + CodeCacheMinBlockLength, "sanity check");
+ assert(block->length() >= number_of_segments && block->length() < number_of_segments + CodeCacheMinBlockLength, "sanity check");
assert(!block->free(), "must be marked free");
#ifdef ASSERT
- memset((void *)block->allocated_space(), badCodeHeapNewVal, size);
+ memset((void *)block->allocated_space(), badCodeHeapNewVal, instance_size);
#endif
return block->allocated_space();
}
- if (length < CodeCacheMinBlockLength) {
- length = CodeCacheMinBlockLength;
+ // Ensure minimum size for allocation to the heap.
+ if (number_of_segments < CodeCacheMinBlockLength) {
+ number_of_segments = CodeCacheMinBlockLength;
}
- if (_next_segment + length <= _number_of_committed_segments) {
- mark_segmap_as_used(_next_segment, _next_segment + length);
+
+ if (!is_critical) {
+ // Make sure the allocation fits in the unallocated heap without using
+ // the CodeCacheMimimumFreeSpace that is reserved for critical allocations.
+ if (segments_to_size(number_of_segments) > (heap_unallocated_capacity() - CodeCacheMinimumFreeSpace)) {
+ // Fail allocation
+ return NULL;
+ }
+ }
+
+ if (_next_segment + number_of_segments <= _number_of_committed_segments) {
+ mark_segmap_as_used(_next_segment, _next_segment + number_of_segments);
HeapBlock* b = block_at(_next_segment);
- b->initialize(length);
- _next_segment += length;
+ b->initialize(number_of_segments);
+ _next_segment += number_of_segments;
#ifdef ASSERT
- memset((void *)b->allocated_space(), badCodeHeapNewVal, size);
+ memset((void *)b->allocated_space(), badCodeHeapNewVal, instance_size);
#endif
return b->allocated_space();
} else {
@@ -219,7 +230,7 @@
#ifdef ASSERT
memset((void *)b->allocated_space(),
badCodeHeapFreeVal,
- size(b->length()) - sizeof(HeapBlock));
+ segments_to_size(b->length()) - sizeof(HeapBlock));
#endif
add_to_freelist(b);
@@ -299,32 +310,14 @@
}
size_t CodeHeap::allocated_capacity() const {
- // Start with the committed size in _memory;
- size_t l = _memory.committed_size();
-
- // Subtract the committed, but unused, segments
- l -= size(_number_of_committed_segments - _next_segment);
-
- // Subtract the size of the freelist
- l -= size(_free_segments);
-
- return l;
+ // size of used heap - size on freelist
+ return segments_to_size(_next_segment - _freelist_segments);
}
-size_t CodeHeap::largest_free_block() const {
- // First check unused space excluding free blocks.
- size_t free_sz = size(_free_segments);
- size_t unused = max_capacity() - allocated_capacity() - free_sz;
- if (unused >= free_sz)
- return unused;
-
- // Now check largest free block.
- size_t len = 0;
- for (FreeBlock* b = _freelist; b != NULL; b = b->link()) {
- if (b->length() > len)
- len = b->length();
- }
- return MAX2(unused, size(len));
+// Returns size of the unallocated heap block
+size_t CodeHeap::heap_unallocated_capacity() const {
+ // Total number of segments - number currently used
+ return segments_to_size(_number_of_reserved_segments - _next_segment);
}
// Free list management
@@ -365,7 +358,7 @@
assert(b != _freelist, "cannot be removed twice");
// Mark as free and update free space count
- _free_segments += b->length();
+ _freelist_segments += b->length();
b->set_free();
// First element in list?
@@ -400,7 +393,7 @@
// Search freelist for an entry on the list with the best fit
// Return NULL if no one was found
-FreeBlock* CodeHeap::search_freelist(size_t length) {
+FreeBlock* CodeHeap::search_freelist(size_t length, bool is_critical) {
FreeBlock *best_block = NULL;
FreeBlock *best_prev = NULL;
size_t best_length = 0;
@@ -411,6 +404,16 @@
while(cur != NULL) {
size_t l = cur->length();
if (l >= length && (best_block == NULL || best_length > l)) {
+
+ // Non critical allocations are not allowed to use the last part of the code heap.
+ if (!is_critical) {
+ // Make sure the end of the allocation doesn't cross into the last part of the code heap
+ if (((size_t)cur + length) > ((size_t)high_boundary() - CodeCacheMinimumFreeSpace)) {
+ // the freelist is sorted by address - if one fails, all consecutive will also fail.
+ break;
+ }
+ }
+
// Remember best block, its previous element, and its length
best_block = cur;
best_prev = prev;
@@ -452,7 +455,7 @@
}
best_block->set_used();
- _free_segments -= length;
+ _freelist_segments -= length;
return best_block;
}
@@ -478,7 +481,7 @@
}
// Verify that freelist contains the right amount of free space
- // guarantee(len == _free_segments, "wrong freelist");
+ // guarantee(len == _freelist_segments, "wrong freelist");
// Verify that the number of free blocks is not out of hand.
static int free_block_threshold = 10000;
--- a/hotspot/src/share/vm/memory/heap.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/memory/heap.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -91,11 +91,11 @@
size_t _next_segment;
FreeBlock* _freelist;
- size_t _free_segments; // No. of segments in freelist
+ size_t _freelist_segments; // No. of segments in freelist
// Helper functions
- size_t number_of_segments(size_t size) const { return (size + _segment_size - 1) >> _log2_segment_size; }
- size_t size(size_t number_of_segments) const { return number_of_segments << _log2_segment_size; }
+ size_t size_to_segments(size_t size) const { return (size + _segment_size - 1) >> _log2_segment_size; }
+ size_t segments_to_size(size_t number_of_segments) const { return number_of_segments << _log2_segment_size; }
size_t segment_for(void* p) const { return ((char*)p - _memory.low()) >> _log2_segment_size; }
HeapBlock* block_at(size_t i) const { return (HeapBlock*)(_memory.low() + (i << _log2_segment_size)); }
@@ -110,7 +110,7 @@
// Toplevel freelist management
void add_to_freelist(HeapBlock *b);
- FreeBlock* search_freelist(size_t length);
+ FreeBlock* search_freelist(size_t length, bool is_critical);
// Iteration helpers
void* next_free(HeapBlock* b) const;
@@ -132,22 +132,19 @@
void clear(); // clears all heap contents
// Memory allocation
- void* allocate (size_t size); // allocates a block of size or returns NULL
+ void* allocate (size_t size, bool is_critical); // allocates a block of size or returns NULL
void deallocate(void* p); // deallocates a block
// Attributes
- void* begin() const { return _memory.low (); }
- void* end() const { return _memory.high(); }
- bool contains(void* p) const { return begin() <= p && p < end(); }
- void* find_start(void* p) const; // returns the block containing p or NULL
- size_t alignment_unit() const; // alignment of any block
- size_t alignment_offset() const; // offset of first byte of any block, within the enclosing alignment unit
- static size_t header_size(); // returns the header size for each heap block
+ char* low_boundary() const { return _memory.low_boundary (); }
+ char* high() const { return _memory.high(); }
+ char* high_boundary() const { return _memory.high_boundary(); }
- // Returns reserved area high and low addresses
- char *low_boundary() const { return _memory.low_boundary (); }
- char *high() const { return _memory.high(); }
- char *high_boundary() const { return _memory.high_boundary(); }
+ bool contains(const void* p) const { return low_boundary() <= p && p < high(); }
+ void* find_start(void* p) const; // returns the block containing p or NULL
+ size_t alignment_unit() const; // alignment of any block
+ size_t alignment_offset() const; // offset of first byte of any block, within the enclosing alignment unit
+ static size_t header_size(); // returns the header size for each heap block
// Iteration
@@ -161,8 +158,11 @@
size_t max_capacity() const;
size_t allocated_capacity() const;
size_t unallocated_capacity() const { return max_capacity() - allocated_capacity(); }
- size_t largest_free_block() const;
+private:
+ size_t heap_unallocated_capacity() const;
+
+public:
// Debugging
void verify();
void print() PRODUCT_RETURN;
--- a/hotspot/src/share/vm/memory/metaspace.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/memory/metaspace.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -103,27 +103,7 @@
// a chunk is placed on the free list of blocks (BlockFreelist) and
// reused from there.
-// Pointer to list of Metachunks.
-class ChunkList VALUE_OBJ_CLASS_SPEC {
- // List of free chunks
- Metachunk* _head;
-
- public:
- // Constructor
- ChunkList() : _head(NULL) {}
-
- // Accessors
- Metachunk* head() { return _head; }
- void set_head(Metachunk* v) { _head = v; }
-
- // Link at head of the list
- void add_at_head(Metachunk* head, Metachunk* tail);
- void add_at_head(Metachunk* head);
-
- size_t sum_list_size();
- size_t sum_list_count();
- size_t sum_list_capacity();
-};
+typedef class FreeList<Metachunk> ChunkList;
// Manages the global free lists of chunks.
// Has three lists of free chunks, and a total size and
@@ -185,6 +165,10 @@
// for special, small, medium, and humongous chunks.
static ChunkIndex list_index(size_t size);
+ // Add the simple linked list of chunks to the freelist of chunks
+ // of type index.
+ void return_chunks(ChunkIndex index, Metachunk* chunks);
+
// Total of the space in the free chunks list
size_t free_chunks_total();
size_t free_chunks_total_in_bytes();
@@ -899,6 +883,9 @@
Mutex::_no_safepoint_check_flag);
bool initialization_succeeded = grow_vs(word_size);
+ _chunk_manager.free_chunks(SpecializedIndex)->set_size(SpecializedChunk);
+ _chunk_manager.free_chunks(SmallIndex)->set_size(SmallChunk);
+ _chunk_manager.free_chunks(MediumIndex)->set_size(MediumChunk);
assert(initialization_succeeded,
" VirtualSpaceList initialization should not fail");
}
@@ -913,6 +900,9 @@
Mutex::_no_safepoint_check_flag);
VirtualSpaceNode* class_entry = new VirtualSpaceNode(rs);
bool succeeded = class_entry->initialize();
+ _chunk_manager.free_chunks(SpecializedIndex)->set_size(SpecializedChunk);
+ _chunk_manager.free_chunks(SmallIndex)->set_size(ClassSmallChunk);
+ _chunk_manager.free_chunks(MediumIndex)->set_size(ClassMediumChunk);
assert(succeeded, " VirtualSpaceList initialization should not fail");
link_vs(class_entry, rs.size()/BytesPerWord);
}
@@ -1380,76 +1370,6 @@
}
#endif
-// ChunkList methods
-
-size_t ChunkList::sum_list_size() {
- size_t result = 0;
- Metachunk* cur = head();
- while (cur != NULL) {
- result += cur->word_size();
- cur = cur->next();
- }
- return result;
-}
-
-size_t ChunkList::sum_list_count() {
- size_t result = 0;
- Metachunk* cur = head();
- while (cur != NULL) {
- result++;
- cur = cur->next();
- }
- return result;
-}
-
-size_t ChunkList::sum_list_capacity() {
- size_t result = 0;
- Metachunk* cur = head();
- while (cur != NULL) {
- result += cur->capacity_word_size();
- cur = cur->next();
- }
- return result;
-}
-
-void ChunkList::add_at_head(Metachunk* head, Metachunk* tail) {
- assert_lock_strong(SpaceManager::expand_lock());
- assert(head == tail || tail->next() == NULL,
- "Not the tail or the head has already been added to a list");
-
- if (TraceMetadataChunkAllocation && Verbose) {
- gclog_or_tty->print("ChunkList::add_at_head(head, tail): ");
- Metachunk* cur = head;
- while (cur != NULL) {
- gclog_or_tty->print(PTR_FORMAT " (" SIZE_FORMAT ") ", cur, cur->word_size());
- cur = cur->next();
- }
- gclog_or_tty->print_cr("");
- }
-
- if (tail != NULL) {
- tail->set_next(_head);
- }
- set_head(head);
-}
-
-void ChunkList::add_at_head(Metachunk* list) {
- if (list == NULL) {
- // Nothing to add
- return;
- }
- assert_lock_strong(SpaceManager::expand_lock());
- Metachunk* head = list;
- Metachunk* tail = list;
- Metachunk* cur = head->next();
- // Search for the tail since it is not passed.
- while (cur != NULL) {
- tail = cur;
- cur = cur->next();
- }
- add_at_head(head, tail);
-}
-
// ChunkManager methods
// Verification of _free_chunks_total and _free_chunks_count does not
@@ -1553,7 +1473,7 @@
continue;
}
- result = result + list->sum_list_capacity();
+ result = result + list->count() * list->size();
}
result = result + humongous_dictionary()->total_size();
return result;
@@ -1567,7 +1487,7 @@
if (list == NULL) {
continue;
}
- count = count + list->sum_list_count();
+ count = count + list->count();
}
count = count + humongous_dictionary()->total_free_blocks();
return count;
@@ -1622,7 +1542,7 @@
}
// Remove the chunk as the head of the list.
- free_list->set_head(chunk->next());
+ free_list->remove_chunk(chunk);
// Chunk is being removed from the chunks free list.
dec_free_chunks_total(chunk->capacity_word_size());
@@ -1679,7 +1599,7 @@
size_t list_count;
if (list_index(word_size) < HumongousIndex) {
ChunkList* list = find_free_chunks_list(word_size);
- list_count = list->sum_list_count();
+ list_count = list->count();
} else {
list_count = humongous_dictionary()->total_count();
}
@@ -1958,6 +1878,29 @@
}
}
+void ChunkManager::return_chunks(ChunkIndex index, Metachunk* chunks) {
+ if (chunks == NULL) {
+ return;
+ }
+ ChunkList* list = free_chunks(index);
+ assert(list->size() == chunks->word_size(), "Mismatch in chunk sizes");
+ assert_lock_strong(SpaceManager::expand_lock());
+ Metachunk* cur = chunks;
+
+ // This return chunks one at a time. If a new
+ // class List can be created that is a base class
+ // of FreeList then something like FreeList::prepend()
+ // can be used in place of this loop
+ while (cur != NULL) {
+ // Capture the next link before it is changed
+ // by the call to return_chunk_at_head();
+ Metachunk* next = cur->next();
+ cur->set_is_free(true);
+ list->return_chunk_at_head(cur);
+ cur = next;
+ }
+}
+
SpaceManager::~SpaceManager() {
// This call this->_lock which can't be done while holding expand_lock()
const size_t in_use_before = sum_capacity_in_chunks_in_use();
@@ -1995,11 +1938,11 @@
chunk_size_name(i));
}
Metachunk* chunks = chunks_in_use(i);
- chunk_manager->free_chunks(i)->add_at_head(chunks);
+ chunk_manager->return_chunks(i, chunks);
set_chunks_in_use(i, NULL);
if (TraceMetadataChunkAllocation && Verbose) {
gclog_or_tty->print_cr("updated freelist count %d %s",
- chunk_manager->free_chunks(i)->sum_list_count(),
+ chunk_manager->free_chunks(i)->count(),
chunk_size_name(i));
}
assert(i != HumongousIndex, "Humongous chunks are handled explicitly later");
--- a/hotspot/src/share/vm/oops/method.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/oops/method.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -91,7 +91,7 @@
set_hidden(false);
set_dont_inline(false);
set_method_data(NULL);
- set_interpreter_throwout_count(0);
+ set_method_counters(NULL);
set_vtable_index(Method::garbage_vtable_index);
// Fix and bury in Method*
@@ -105,16 +105,6 @@
}
NOT_PRODUCT(set_compiled_invocation_count(0);)
- set_interpreter_invocation_count(0);
- invocation_counter()->init();
- backedge_counter()->init();
- clear_number_of_breakpoints();
-
-#ifdef TIERED
- set_rate(0);
- set_prev_event_count(0);
- set_prev_time(0);
-#endif
}
// Release Method*. The nmethod will be gone when we get here because
@@ -124,6 +114,8 @@
set_constMethod(NULL);
MetadataFactory::free_metadata(loader_data, method_data());
set_method_data(NULL);
+ MetadataFactory::free_metadata(loader_data, method_counters());
+ set_method_counters(NULL);
// The nmethod will be gone when we get here.
if (code() != NULL) _code = NULL;
}
@@ -323,7 +315,10 @@
// compiler does not bump invocation counter of compiled methods
return true;
}
- else if (_invocation_counter.carry() || (method_data() != NULL && method_data()->invocation_counter()->carry())) {
+ else if ((method_counters() != NULL &&
+ method_counters()->invocation_counter()->carry()) ||
+ (method_data() != NULL &&
+ method_data()->invocation_counter()->carry())) {
// The carry bit is set when the counter overflows and causes
// a compilation to occur. We don't know how many times
// the counter has been reset, so we simply assume it has
@@ -387,6 +382,18 @@
}
}
+MethodCounters* Method::build_method_counters(Method* m, TRAPS) {
+ methodHandle mh(m);
+ ClassLoaderData* loader_data = mh->method_holder()->class_loader_data();
+ MethodCounters* counters = MethodCounters::allocate(loader_data, CHECK_NULL);
+ if (mh->method_counters() == NULL) {
+ mh->set_method_counters(counters);
+ } else {
+ MetadataFactory::free_metadata(loader_data, counters);
+ }
+ return mh->method_counters();
+}
+
void Method::cleanup_inline_caches() {
// The current system doesn't use inline caches in the interpreter
// => nothing to do (keep this method around for future use)
@@ -794,8 +801,6 @@
set_signature_handler(NULL);
}
NOT_PRODUCT(set_compiled_invocation_count(0);)
- invocation_counter()->reset();
- backedge_counter()->reset();
_adapter = NULL;
_from_compiled_entry = NULL;
@@ -808,8 +813,7 @@
assert(!DumpSharedSpaces || _method_data == NULL, "unexpected method data?");
set_method_data(NULL);
- set_interpreter_throwout_count(0);
- set_interpreter_invocation_count(0);
+ set_method_counters(NULL);
}
// Called when the method_holder is getting linked. Setup entrypoints so the method
@@ -1545,28 +1549,34 @@
int Method::invocation_count() {
+ MethodCounters *mcs = method_counters();
if (TieredCompilation) {
MethodData* const mdo = method_data();
- if (invocation_counter()->carry() || ((mdo != NULL) ? mdo->invocation_counter()->carry() : false)) {
+ if (((mcs != NULL) ? mcs->invocation_counter()->carry() : false) ||
+ ((mdo != NULL) ? mdo->invocation_counter()->carry() : false)) {
return InvocationCounter::count_limit;
} else {
- return invocation_counter()->count() + ((mdo != NULL) ? mdo->invocation_counter()->count() : 0);
+ return ((mcs != NULL) ? mcs->invocation_counter()->count() : 0) +
+ ((mdo != NULL) ? mdo->invocation_counter()->count() : 0);
}
} else {
- return invocation_counter()->count();
+ return (mcs == NULL) ? 0 : mcs->invocation_counter()->count();
}
}
int Method::backedge_count() {
+ MethodCounters *mcs = method_counters();
if (TieredCompilation) {
MethodData* const mdo = method_data();
- if (backedge_counter()->carry() || ((mdo != NULL) ? mdo->backedge_counter()->carry() : false)) {
+ if (((mcs != NULL) ? mcs->backedge_counter()->carry() : false) ||
+ ((mdo != NULL) ? mdo->backedge_counter()->carry() : false)) {
return InvocationCounter::count_limit;
} else {
- return backedge_counter()->count() + ((mdo != NULL) ? mdo->backedge_counter()->count() : 0);
+ return ((mcs != NULL) ? mcs->backedge_counter()->count() : 0) +
+ ((mdo != NULL) ? mdo->backedge_counter()->count() : 0);
}
} else {
- return backedge_counter()->count();
+ return (mcs == NULL) ? 0 : mcs->backedge_counter()->count();
}
}
@@ -1621,12 +1631,12 @@
assert(orig_bytecode() == code, "original bytecode must be the same");
}
#endif
+ Thread *thread = Thread::current();
*method->bcp_from(_bci) = Bytecodes::_breakpoint;
- method->incr_number_of_breakpoints();
+ method->incr_number_of_breakpoints(thread);
SystemDictionary::notice_modification();
{
// Deoptimize all dependents on this method
- Thread *thread = Thread::current();
HandleMark hm(thread);
methodHandle mh(thread, method);
Universe::flush_dependents_on_method(mh);
@@ -1636,7 +1646,7 @@
void BreakpointInfo::clear(Method* method) {
*method->bcp_from(_bci) = orig_bytecode();
assert(method->number_of_breakpoints() > 0, "must not go negative");
- method->decr_number_of_breakpoints();
+ method->decr_number_of_breakpoints(Thread::current());
}
// jmethodID handling
--- a/hotspot/src/share/vm/oops/method.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/oops/method.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -31,6 +31,7 @@
#include "interpreter/invocationCounter.hpp"
#include "oops/annotations.hpp"
#include "oops/constantPool.hpp"
+#include "oops/methodCounters.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/oop.hpp"
#include "oops/typeArrayOop.hpp"
@@ -100,6 +101,7 @@
class LocalVariableTableElement;
class AdapterHandlerEntry;
class MethodData;
+class MethodCounters;
class ConstMethod;
class InlineTableSizes;
class KlassSizeStats;
@@ -109,7 +111,7 @@
private:
ConstMethod* _constMethod; // Method read-only data.
MethodData* _method_data;
- int _interpreter_invocation_count; // Count of times invoked (reused as prev_event_count in tiered)
+ MethodCounters* _method_counters;
AccessFlags _access_flags; // Access flags
int _vtable_index; // vtable index of this method (see VtableIndexFlag)
// note: can have vtables with >2**16 elements (because of inheritance)
@@ -124,15 +126,6 @@
_hidden : 1,
_dont_inline : 1,
: 3;
- u2 _interpreter_throwout_count; // Count of times method was exited via exception while interpreting
- u2 _number_of_breakpoints; // fullspeed debugging support
- InvocationCounter _invocation_counter; // Incremented before each activation of the method - used to trigger frequency-based optimizations
- InvocationCounter _backedge_counter; // Incremented before each backedge taken - used to trigger frequencey-based optimizations
-
-#ifdef TIERED
- float _rate; // Events (invocation and backedge counter increments) per millisecond
- jlong _prev_time; // Previous time the rate was acquired
-#endif
#ifndef PRODUCT
int _compiled_invocation_count; // Number of nmethod invocations so far (for perf. debugging)
@@ -247,11 +240,31 @@
void clear_all_breakpoints();
// Tracking number of breakpoints, for fullspeed debugging.
// Only mutated by VM thread.
- u2 number_of_breakpoints() const { return _number_of_breakpoints; }
- void incr_number_of_breakpoints() { ++_number_of_breakpoints; }
- void decr_number_of_breakpoints() { --_number_of_breakpoints; }
+ u2 number_of_breakpoints() const {
+ if (method_counters() == NULL) {
+ return 0;
+ } else {
+ return method_counters()->number_of_breakpoints();
+ }
+ }
+ void incr_number_of_breakpoints(TRAPS) {
+ MethodCounters* mcs = get_method_counters(CHECK);
+ if (mcs != NULL) {
+ mcs->incr_number_of_breakpoints();
+ }
+ }
+ void decr_number_of_breakpoints(TRAPS) {
+ MethodCounters* mcs = get_method_counters(CHECK);
+ if (mcs != NULL) {
+ mcs->decr_number_of_breakpoints();
+ }
+ }
// Initialization only
- void clear_number_of_breakpoints() { _number_of_breakpoints = 0; }
+ void clear_number_of_breakpoints() {
+ if (method_counters() != NULL) {
+ method_counters()->clear_number_of_breakpoints();
+ }
+ }
// index into InstanceKlass methods() array
// note: also used by jfr
@@ -288,14 +301,20 @@
void set_highest_osr_comp_level(int level);
// Count of times method was exited via exception while interpreting
- void interpreter_throwout_increment() {
- if (_interpreter_throwout_count < 65534) {
- _interpreter_throwout_count++;
+ void interpreter_throwout_increment(TRAPS) {
+ MethodCounters* mcs = get_method_counters(CHECK);
+ if (mcs != NULL) {
+ mcs->interpreter_throwout_increment();
}
}
- int interpreter_throwout_count() const { return _interpreter_throwout_count; }
- void set_interpreter_throwout_count(int count) { _interpreter_throwout_count = count; }
+ int interpreter_throwout_count() const {
+ if (method_counters() == NULL) {
+ return 0;
+ } else {
+ return method_counters()->interpreter_throwout_count();
+ }
+ }
// size of parameters
int size_of_parameters() const { return constMethod()->size_of_parameters(); }
@@ -339,23 +358,54 @@
MethodData* method_data() const {
return _method_data;
}
+
void set_method_data(MethodData* data) {
_method_data = data;
}
- // invocation counter
- InvocationCounter* invocation_counter() { return &_invocation_counter; }
- InvocationCounter* backedge_counter() { return &_backedge_counter; }
+ MethodCounters* method_counters() const {
+ return _method_counters;
+ }
+
+
+ void set_method_counters(MethodCounters* counters) {
+ _method_counters = counters;
+ }
#ifdef TIERED
// We are reusing interpreter_invocation_count as a holder for the previous event count!
// We can do that since interpreter_invocation_count is not used in tiered.
- int prev_event_count() const { return _interpreter_invocation_count; }
- void set_prev_event_count(int count) { _interpreter_invocation_count = count; }
- jlong prev_time() const { return _prev_time; }
- void set_prev_time(jlong time) { _prev_time = time; }
- float rate() const { return _rate; }
- void set_rate(float rate) { _rate = rate; }
+ int prev_event_count() const {
+ if (method_counters() == NULL) {
+ return 0;
+ } else {
+ return method_counters()->interpreter_invocation_count();
+ }
+ }
+ void set_prev_event_count(int count, TRAPS) {
+ MethodCounters* mcs = get_method_counters(CHECK);
+ if (mcs != NULL) {
+ mcs->set_interpreter_invocation_count(count);
+ }
+ }
+ jlong prev_time() const {
+ return method_counters() == NULL ? 0 : method_counters()->prev_time();
+ }
+ void set_prev_time(jlong time, TRAPS) {
+ MethodCounters* mcs = get_method_counters(CHECK);
+ if (mcs != NULL) {
+ mcs->set_prev_time(time);
+ }
+ }
+ float rate() const {
+ return method_counters() == NULL ? 0 : method_counters()->rate();
+ }
+ void set_rate(float rate, TRAPS) {
+ MethodCounters* mcs = get_method_counters(CHECK);
+ if (mcs != NULL) {
+ mcs->set_rate(rate);
+ }
+ }
#endif
int invocation_count();
@@ -366,14 +416,17 @@
static void build_interpreter_method_data(methodHandle method, TRAPS);
+ static MethodCounters* build_method_counters(Method* m, TRAPS);
+
int interpreter_invocation_count() {
if (TieredCompilation) return invocation_count();
- else return _interpreter_invocation_count;
+ else return (method_counters() == NULL) ? 0 :
+ method_counters()->interpreter_invocation_count();
}
- void set_interpreter_invocation_count(int count) { _interpreter_invocation_count = count; }
- int increment_interpreter_invocation_count() {
+ int increment_interpreter_invocation_count(TRAPS) {
if (TieredCompilation) ShouldNotReachHere();
- return ++_interpreter_invocation_count;
+ MethodCounters* mcs = get_method_counters(CHECK_0);
+ return (mcs == NULL) ? 0 : mcs->increment_interpreter_invocation_count();
}
#ifndef PRODUCT
@@ -582,12 +635,12 @@
#endif /* CC_INTERP */
static ByteSize from_compiled_offset() { return byte_offset_of(Method, _from_compiled_entry); }
static ByteSize code_offset() { return byte_offset_of(Method, _code); }
- static ByteSize invocation_counter_offset() { return byte_offset_of(Method, _invocation_counter); }
- static ByteSize backedge_counter_offset() { return byte_offset_of(Method, _backedge_counter); }
static ByteSize method_data_offset() {
return byte_offset_of(Method, _method_data);
}
- static ByteSize interpreter_invocation_counter_offset() { return byte_offset_of(Method, _interpreter_invocation_count); }
+ static ByteSize method_counters_offset() {
+ return byte_offset_of(Method, _method_counters);
+ }
#ifndef PRODUCT
static ByteSize compiled_invocation_counter_offset() { return byte_offset_of(Method, _compiled_invocation_count); }
#endif // not PRODUCT
@@ -598,8 +651,6 @@
// for code generation
static int method_data_offset_in_bytes() { return offset_of(Method, _method_data); }
- static int interpreter_invocation_counter_offset_in_bytes()
- { return offset_of(Method, _interpreter_invocation_count); }
static int intrinsic_id_offset_in_bytes() { return offset_of(Method, _intrinsic_id); }
static int intrinsic_id_size_in_bytes() { return sizeof(u1); }
@@ -757,6 +808,13 @@
private:
void print_made_not_compilable(int comp_level, bool is_osr, bool report, const char* reason);
+ MethodCounters* get_method_counters(TRAPS) {
+ if (_method_counters == NULL) {
+ build_method_counters(this, CHECK_AND_CLEAR_NULL);
+ }
+ return _method_counters;
+ }
+
public:
bool is_not_c1_compilable() const { return access_flags().is_not_c1_compilable(); }
void set_not_c1_compilable() { _access_flags.set_not_c1_compilable(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/oops/methodCounters.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#include "precompiled.hpp"
+#include "oops/methodCounters.hpp"
+#include "runtime/thread.inline.hpp"
+
+MethodCounters* MethodCounters::allocate(ClassLoaderData* loader_data, TRAPS) {
+ return new(loader_data, size(), false, THREAD) MethodCounters();
+}
+
+void MethodCounters::clear_counters() {
+ invocation_counter()->reset();
+ backedge_counter()->reset();
+ set_interpreter_throwout_count(0);
+ set_interpreter_invocation_count(0);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/oops/methodCounters.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_OOPS_METHODCOUNTERS_HPP
+#define SHARE_VM_OOPS_METHODCOUNTERS_HPP
+
+#include "oops/metadata.hpp"
+#include "interpreter/invocationCounter.hpp"
+
+class MethodCounters: public MetaspaceObj {
+ friend class VMStructs;
+ private:
+ int _interpreter_invocation_count; // Count of times invoked (reused as prev_event_count in tiered)
+ u2 _interpreter_throwout_count; // Count of times method was exited via exception while interpreting
+ u2 _number_of_breakpoints; // fullspeed debugging support
+ InvocationCounter _invocation_counter; // Incremented before each activation of the method - used to trigger frequency-based optimizations
+ InvocationCounter _backedge_counter; // Incremented before each backedge taken - used to trigger frequencey-based optimizations
+
+#ifdef TIERED
+ float _rate; // Events (invocation and backedge counter increments) per millisecond
+ jlong _prev_time; // Previous time the rate was acquired
+#endif
+
+ MethodCounters() : _interpreter_invocation_count(0),
+ _interpreter_throwout_count(0),
+ _number_of_breakpoints(0)
+#ifdef TIERED
+ , _rate(0),
+ _prev_time(0)
+#endif
+ {
+ invocation_counter()->init();
+ backedge_counter()->init();
+ }
+
+ public:
+ static MethodCounters* allocate(ClassLoaderData* loader_data, TRAPS);
+
+ void deallocate_contents(ClassLoaderData* loader_data) {}
+ DEBUG_ONLY(bool on_stack() { return false; }) // for template
+
+ static int size() { return sizeof(MethodCounters) / wordSize; }
+
+ bool is_klass() const { return false; }
+
+ void clear_counters();
+
+ int interpreter_invocation_count() {
+ return _interpreter_invocation_count;
+ }
+ void set_interpreter_invocation_count(int count) {
+ _interpreter_invocation_count = count;
+ }
+ int increment_interpreter_invocation_count() {
+ return ++_interpreter_invocation_count;
+ }
+
+ void interpreter_throwout_increment() {
+ if (_interpreter_throwout_count < 65534) {
+ _interpreter_throwout_count++;
+ }
+ }
+ int interpreter_throwout_count() const {
+ return _interpreter_throwout_count;
+ }
+ void set_interpreter_throwout_count(int count) {
+ _interpreter_throwout_count = count;
+ }
+
+ u2 number_of_breakpoints() const { return _number_of_breakpoints; }
+ void incr_number_of_breakpoints() { ++_number_of_breakpoints; }
+ void decr_number_of_breakpoints() { --_number_of_breakpoints; }
+ void clear_number_of_breakpoints() { _number_of_breakpoints = 0; }
+
+#ifdef TIERED
+ jlong prev_time() const { return _prev_time; }
+ void set_prev_time(jlong time) { _prev_time = time; }
+ float rate() const { return _rate; }
+ void set_rate(float rate) { _rate = rate; }
+#endif
+
+ // invocation counter
+ InvocationCounter* invocation_counter() { return &_invocation_counter; }
+ InvocationCounter* backedge_counter() { return &_backedge_counter; }
+
+ static ByteSize interpreter_invocation_counter_offset() {
+ return byte_offset_of(MethodCounters, _interpreter_invocation_count);
+ }
+
+ static ByteSize invocation_counter_offset() {
+ return byte_offset_of(MethodCounters, _invocation_counter);
+ }
+
+ static ByteSize backedge_counter_offset() {
+ return byte_offset_of(MethodCounters, _backedge_counter);
+ }
+
+ static int interpreter_invocation_counter_offset_in_bytes() {
+ return offset_of(MethodCounters, _interpreter_invocation_count);
+ }
+
+};
+#endif //SHARE_VM_OOPS_METHODCOUNTERS_HPP
--- a/hotspot/src/share/vm/oops/methodData.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/oops/methodData.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -732,14 +732,17 @@
} else {
int iic = method->interpreter_invocation_count();
if (mileage < iic) mileage = iic;
- InvocationCounter* ic = method->invocation_counter();
- InvocationCounter* bc = method->backedge_counter();
- int icval = ic->count();
- if (ic->carry()) icval += CompileThreshold;
- if (mileage < icval) mileage = icval;
- int bcval = bc->count();
- if (bc->carry()) bcval += CompileThreshold;
- if (mileage < bcval) mileage = bcval;
+ MethodCounters* mcs = method->method_counters();
+ if (mcs != NULL) {
+ InvocationCounter* ic = mcs->invocation_counter();
+ InvocationCounter* bc = mcs->backedge_counter();
+ int icval = ic->count();
+ if (ic->carry()) icval += CompileThreshold;
+ if (mileage < icval) mileage = icval;
+ int bcval = bc->count();
+ if (bc->carry()) bcval += CompileThreshold;
+ if (mileage < bcval) mileage = bcval;
+ }
}
return mileage;
}
--- a/hotspot/src/share/vm/opto/cfgnode.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/opto/cfgnode.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -1306,10 +1306,11 @@
return NULL;
Node *x = n2;
- Node *y = n1->in(1);
- if( n2 == n1->in(1) ) {
+ Node *y = NULL;
+ if( x == n1->in(1) ) {
y = n1->in(2);
- } else if( n2 == n1->in(1) ) {
+ } else if( x == n1->in(2) ) {
+ y = n1->in(1);
} else return NULL;
// Not so profitable if compare and add are constants
--- a/hotspot/src/share/vm/opto/chaitin.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/opto/chaitin.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -145,6 +145,72 @@
#define NUMBUCKS 3
+// Straight out of Tarjan's union-find algorithm
+uint LiveRangeMap::find_compress(uint lrg) {
+ uint cur = lrg;
+ uint next = _uf_map[cur];
+ while (next != cur) { // Scan chain of equivalences
+ assert( next < cur, "always union smaller");
+ cur = next; // until find a fixed-point
+ next = _uf_map[cur];
+ }
+
+ // Core of union-find algorithm: update chain of
+ // equivalences to be equal to the root.
+ while (lrg != next) {
+ uint tmp = _uf_map[lrg];
+ _uf_map.map(lrg, next);
+ lrg = tmp;
+ }
+ return lrg;
+}
+
+// Reset the Union-Find map to identity
+void LiveRangeMap::reset_uf_map(uint max_lrg_id) {
+ _max_lrg_id= max_lrg_id;
+ // Force the Union-Find mapping to be at least this large
+ _uf_map.extend(_max_lrg_id, 0);
+ // Initialize it to be the ID mapping.
+ for (uint i = 0; i < _max_lrg_id; ++i) {
+ _uf_map.map(i, i);
+ }
+}
+
+// Make all Nodes map directly to their final live range; no need for
+// the Union-Find mapping after this call.
+void LiveRangeMap::compress_uf_map_for_nodes() {
+ // For all Nodes, compress mapping
+ uint unique = _names.Size();
+ for (uint i = 0; i < unique; ++i) {
+ uint lrg = _names[i];
+ uint compressed_lrg = find(lrg);
+ if (lrg != compressed_lrg) {
+ _names.map(i, compressed_lrg);
+ }
+ }
+}
+
+// Like Find above, but no path compress, so bad asymptotic behavior
+uint LiveRangeMap::find_const(uint lrg) const {
+ if (!lrg) {
+ return lrg; // Ignore the zero LRG
+ }
+
+ // Off the end? This happens during debugging dumps when you got
+ // brand new live ranges but have not told the allocator yet.
+ if (lrg >= _max_lrg_id) {
+ return lrg;
+ }
+
+ uint next = _uf_map[lrg];
+ while (next != lrg) { // Scan chain of equivalences
+ assert(next < lrg, "always union smaller");
+ lrg = next; // until find a fixed-point
+ next = _uf_map[lrg];
+ }
+ return next;
+}
+
//------------------------------Chaitin----------------------------------------
PhaseChaitin::PhaseChaitin(uint unique, PhaseCFG &cfg, Matcher &matcher)
: PhaseRegAlloc(unique, cfg, matcher,
@@ -153,13 +219,13 @@
#else
NULL
#endif
- ),
- _names(unique), _uf_map(unique),
- _maxlrg(0), _live(0),
- _spilled_once(Thread::current()->resource_area()),
- _spilled_twice(Thread::current()->resource_area()),
- _lo_degree(0), _lo_stk_degree(0), _hi_degree(0), _simplified(0),
- _oldphi(unique)
+ )
+ , _lrg_map(unique)
+ , _live(0)
+ , _spilled_once(Thread::current()->resource_area())
+ , _spilled_twice(Thread::current()->resource_area())
+ , _lo_degree(0), _lo_stk_degree(0), _hi_degree(0), _simplified(0)
+ , _oldphi(unique)
#ifndef PRODUCT
, _trace_spilling(TraceSpilling || C->method_has_option("TraceSpilling"))
#endif
@@ -168,7 +234,6 @@
_high_frequency_lrg = MIN2(float(OPTO_LRG_HIGH_FREQ), _cfg._outer_loop_freq);
- uint i,j;
// Build a list of basic blocks, sorted by frequency
_blks = NEW_RESOURCE_ARRAY( Block *, _cfg._num_blocks );
// Experiment with sorting strategies to speed compilation
@@ -176,30 +241,30 @@
Block **buckets[NUMBUCKS]; // Array of buckets
uint buckcnt[NUMBUCKS]; // Array of bucket counters
double buckval[NUMBUCKS]; // Array of bucket value cutoffs
- for( i = 0; i < NUMBUCKS; i++ ) {
- buckets[i] = NEW_RESOURCE_ARRAY( Block *, _cfg._num_blocks );
+ for (uint i = 0; i < NUMBUCKS; i++) {
+ buckets[i] = NEW_RESOURCE_ARRAY(Block *, _cfg._num_blocks);
buckcnt[i] = 0;
// Bump by three orders of magnitude each time
cutoff *= 0.001;
buckval[i] = cutoff;
- for( j = 0; j < _cfg._num_blocks; j++ ) {
+ for (uint j = 0; j < _cfg._num_blocks; j++) {
buckets[i][j] = NULL;
}
}
// Sort blocks into buckets
- for( i = 0; i < _cfg._num_blocks; i++ ) {
- for( j = 0; j < NUMBUCKS; j++ ) {
- if( (j == NUMBUCKS-1) || (_cfg._blocks[i]->_freq > buckval[j]) ) {
+ for (uint i = 0; i < _cfg._num_blocks; i++) {
+ for (uint j = 0; j < NUMBUCKS; j++) {
+ if ((j == NUMBUCKS - 1) || (_cfg._blocks[i]->_freq > buckval[j])) {
// Assign block to end of list for appropriate bucket
buckets[j][buckcnt[j]++] = _cfg._blocks[i];
- break; // kick out of inner loop
+ break; // kick out of inner loop
}
}
}
// Dump buckets into final block array
uint blkcnt = 0;
- for( i = 0; i < NUMBUCKS; i++ ) {
- for( j = 0; j < buckcnt[i]; j++ ) {
+ for (uint i = 0; i < NUMBUCKS; i++) {
+ for (uint j = 0; j < buckcnt[i]; j++) {
_blks[blkcnt++] = buckets[i][j];
}
}
@@ -207,6 +272,77 @@
assert(blkcnt == _cfg._num_blocks, "Block array not totally filled");
}
+//------------------------------Union------------------------------------------
+// union 2 sets together.
+void PhaseChaitin::Union( const Node *src_n, const Node *dst_n ) {
+ uint src = _lrg_map.find(src_n);
+ uint dst = _lrg_map.find(dst_n);
+ assert(src, "");
+ assert(dst, "");
+ assert(src < _lrg_map.max_lrg_id(), "oob");
+ assert(dst < _lrg_map.max_lrg_id(), "oob");
+ assert(src < dst, "always union smaller");
+ _lrg_map.uf_map(dst, src);
+}
+
+//------------------------------new_lrg----------------------------------------
+void PhaseChaitin::new_lrg(const Node *x, uint lrg) {
+ // Make the Node->LRG mapping
+ _lrg_map.extend(x->_idx,lrg);
+ // Make the Union-Find mapping an identity function
+ _lrg_map.uf_extend(lrg, lrg);
+}
+
+
+bool PhaseChaitin::clone_projs_shared(Block *b, uint idx, Node *con, Node *copy, uint max_lrg_id) {
+ Block *bcon = _cfg._bbs[con->_idx];
+ uint cindex = bcon->find_node(con);
+ Node *con_next = bcon->_nodes[cindex+1];
+ if (con_next->in(0) != con || !con_next->is_MachProj()) {
+ return false; // No MachProj's follow
+ }
+
+ // Copy kills after the cloned constant
+ Node *kills = con_next->clone();
+ kills->set_req(0, copy);
+ b->_nodes.insert(idx, kills);
+ _cfg._bbs.map(kills->_idx, b);
+ new_lrg(kills, max_lrg_id);
+ return true;
+}
+
+//------------------------------compact----------------------------------------
+// Renumber the live ranges to compact them. Makes the IFG smaller.
+void PhaseChaitin::compact() {
+ // Current the _uf_map contains a series of short chains which are headed
+ // by a self-cycle. All the chains run from big numbers to little numbers.
+ // The Find() call chases the chains & shortens them for the next Find call.
+ // We are going to change this structure slightly. Numbers above a moving
+ // wave 'i' are unchanged. Numbers below 'j' point directly to their
+ // compacted live range with no further chaining. There are no chains or
+ // cycles below 'i', so the Find call no longer works.
+ uint j=1;
+ uint i;
+ for (i = 1; i < _lrg_map.max_lrg_id(); i++) {
+ uint lr = _lrg_map.uf_live_range_id(i);
+ // Ignore unallocated live ranges
+ if (!lr) {
+ continue;
+ }
+ assert(lr <= i, "");
+ _lrg_map.uf_map(i, ( lr == i ) ? j++ : _lrg_map.uf_live_range_id(lr));
+ }
+ // Now change the Node->LR mapping to reflect the compacted names
+ uint unique = _lrg_map.size();
+ for (i = 0; i < unique; i++) {
+ uint lrg_id = _lrg_map.live_range_id(i);
+ _lrg_map.map(i, _lrg_map.uf_live_range_id(lrg_id));
+ }
+
+ // Reset the Union-Find mapping
+ _lrg_map.reset_uf_map(j);
+}
+
void PhaseChaitin::Register_Allocate() {
// Above the OLD FP (and in registers) are the incoming arguments. Stack
@@ -231,14 +367,12 @@
// all copy-related live ranges low and then using the max copy-related
// live range as a cut-off for LIVE and the IFG. In other words, I can
// build a subset of LIVE and IFG just for copies.
- PhaseLive live(_cfg,_names,&live_arena);
+ PhaseLive live(_cfg, _lrg_map.names(), &live_arena);
// Need IFG for coalescing and coloring
- PhaseIFG ifg( &live_arena );
+ PhaseIFG ifg(&live_arena);
_ifg = &ifg;
- if (C->unique() > _names.Size()) _names.extend(C->unique()-1, 0);
-
// Come out of SSA world to the Named world. Assign (virtual) registers to
// Nodes. Use the same register for all inputs and the output of PhiNodes
// - effectively ending SSA form. This requires either coalescing live
@@ -258,9 +392,9 @@
_live = NULL; // Mark live as being not available
rm.reset_to_mark(); // Reclaim working storage
IndexSet::reset_memory(C, &live_arena);
- ifg.init(_maxlrg); // Empty IFG
+ ifg.init(_lrg_map.max_lrg_id()); // Empty IFG
gather_lrg_masks( false ); // Collect LRG masks
- live.compute( _maxlrg ); // Compute liveness
+ live.compute(_lrg_map.max_lrg_id()); // Compute liveness
_live = &live; // Mark LIVE as being available
}
@@ -270,19 +404,19 @@
// across any GC point where the derived value is live. So this code looks
// at all the GC points, and "stretches" the live range of any base pointer
// to the GC point.
- if( stretch_base_pointer_live_ranges(&live_arena) ) {
- NOT_PRODUCT( Compile::TracePhase t3("computeLive (sbplr)", &_t_computeLive, TimeCompiler); )
+ if (stretch_base_pointer_live_ranges(&live_arena)) {
+ NOT_PRODUCT(Compile::TracePhase t3("computeLive (sbplr)", &_t_computeLive, TimeCompiler);)
// Since some live range stretched, I need to recompute live
_live = NULL;
rm.reset_to_mark(); // Reclaim working storage
IndexSet::reset_memory(C, &live_arena);
- ifg.init(_maxlrg);
- gather_lrg_masks( false );
- live.compute( _maxlrg );
+ ifg.init(_lrg_map.max_lrg_id());
+ gather_lrg_masks(false);
+ live.compute(_lrg_map.max_lrg_id());
_live = &live;
}
// Create the interference graph using virtual copies
- build_ifg_virtual( ); // Include stack slots this time
+ build_ifg_virtual(); // Include stack slots this time
// Aggressive (but pessimistic) copy coalescing.
// This pass works on virtual copies. Any virtual copies which are not
@@ -296,8 +430,8 @@
// given Node and search them for an instance, i.e., time O(#MaxLRG)).
_ifg->SquareUp();
- PhaseAggressiveCoalesce coalesce( *this );
- coalesce.coalesce_driver( );
+ PhaseAggressiveCoalesce coalesce(*this);
+ coalesce.coalesce_driver();
// Insert un-coalesced copies. Visit all Phis. Where inputs to a Phi do
// not match the Phi itself, insert a copy.
coalesce.insert_copies(_matcher);
@@ -310,28 +444,36 @@
_live = NULL;
rm.reset_to_mark(); // Reclaim working storage
IndexSet::reset_memory(C, &live_arena);
- ifg.init(_maxlrg);
+ ifg.init(_lrg_map.max_lrg_id());
gather_lrg_masks( true );
- live.compute( _maxlrg );
+ live.compute(_lrg_map.max_lrg_id());
_live = &live;
}
// Build physical interference graph
uint must_spill = 0;
- must_spill = build_ifg_physical( &live_arena );
+ must_spill = build_ifg_physical(&live_arena);
// If we have a guaranteed spill, might as well spill now
- if( must_spill ) {
- if( !_maxlrg ) return;
+ if (must_spill) {
+ if(!_lrg_map.max_lrg_id()) {
+ return;
+ }
// Bail out if unique gets too large (ie - unique > MaxNodeLimit)
C->check_node_count(10*must_spill, "out of nodes before split");
- if (C->failing()) return;
- _maxlrg = Split(_maxlrg, &split_arena); // Split spilling LRG everywhere
+ if (C->failing()) {
+ return;
+ }
+
+ uint new_max_lrg_id = Split(_lrg_map.max_lrg_id(), &split_arena); // Split spilling LRG everywhere
+ _lrg_map.set_max_lrg_id(new_max_lrg_id);
// Bail out if unique gets too large (ie - unique > MaxNodeLimit - 2*NodeLimitFudgeFactor)
// or we failed to split
C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after physical split");
- if (C->failing()) return;
+ if (C->failing()) {
+ return;
+ }
- NOT_PRODUCT( C->verify_graph_edges(); )
+ NOT_PRODUCT(C->verify_graph_edges();)
compact(); // Compact LRGs; return new lower max lrg
@@ -340,23 +482,23 @@
_live = NULL;
rm.reset_to_mark(); // Reclaim working storage
IndexSet::reset_memory(C, &live_arena);
- ifg.init(_maxlrg); // Build a new interference graph
+ ifg.init(_lrg_map.max_lrg_id()); // Build a new interference graph
gather_lrg_masks( true ); // Collect intersect mask
- live.compute( _maxlrg ); // Compute LIVE
+ live.compute(_lrg_map.max_lrg_id()); // Compute LIVE
_live = &live;
}
- build_ifg_physical( &live_arena );
+ build_ifg_physical(&live_arena);
_ifg->SquareUp();
_ifg->Compute_Effective_Degree();
// Only do conservative coalescing if requested
- if( OptoCoalesce ) {
+ if (OptoCoalesce) {
// Conservative (and pessimistic) copy coalescing of those spills
- PhaseConservativeCoalesce coalesce( *this );
+ PhaseConservativeCoalesce coalesce(*this);
// If max live ranges greater than cutoff, don't color the stack.
// This cutoff can be larger than below since it is only done once.
- coalesce.coalesce_driver( );
+ coalesce.coalesce_driver();
}
- compress_uf_map_for_nodes();
+ _lrg_map.compress_uf_map_for_nodes();
#ifdef ASSERT
verify(&live_arena, true);
@@ -390,13 +532,18 @@
}
}
- if( !_maxlrg ) return;
- _maxlrg = Split(_maxlrg, &split_arena); // Split spilling LRG everywhere
+ if (!_lrg_map.max_lrg_id()) {
+ return;
+ }
+ uint new_max_lrg_id = Split(_lrg_map.max_lrg_id(), &split_arena); // Split spilling LRG everywhere
+ _lrg_map.set_max_lrg_id(new_max_lrg_id);
// Bail out if unique gets too large (ie - unique > MaxNodeLimit - 2*NodeLimitFudgeFactor)
- C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after split");
- if (C->failing()) return;
+ C->check_node_count(2 * NodeLimitFudgeFactor, "out of nodes after split");
+ if (C->failing()) {
+ return;
+ }
- compact(); // Compact LRGs; return new lower max lrg
+ compact(); // Compact LRGs; return new lower max lrg
// Nuke the live-ness and interference graph and LiveRanGe info
{
@@ -404,26 +551,26 @@
_live = NULL;
rm.reset_to_mark(); // Reclaim working storage
IndexSet::reset_memory(C, &live_arena);
- ifg.init(_maxlrg);
+ ifg.init(_lrg_map.max_lrg_id());
// Create LiveRanGe array.
// Intersect register masks for all USEs and DEFs
- gather_lrg_masks( true );
- live.compute( _maxlrg );
+ gather_lrg_masks(true);
+ live.compute(_lrg_map.max_lrg_id());
_live = &live;
}
- must_spill = build_ifg_physical( &live_arena );
+ must_spill = build_ifg_physical(&live_arena);
_ifg->SquareUp();
_ifg->Compute_Effective_Degree();
// Only do conservative coalescing if requested
- if( OptoCoalesce ) {
+ if (OptoCoalesce) {
// Conservative (and pessimistic) copy coalescing
- PhaseConservativeCoalesce coalesce( *this );
+ PhaseConservativeCoalesce coalesce(*this);
// Check for few live ranges determines how aggressive coalesce is.
- coalesce.coalesce_driver( );
+ coalesce.coalesce_driver();
}
- compress_uf_map_for_nodes();
+ _lrg_map.compress_uf_map_for_nodes();
#ifdef ASSERT
verify(&live_arena, true);
#endif
@@ -435,7 +582,7 @@
// Select colors by re-inserting LRGs back into the IFG in reverse order.
// Return whether or not something spills.
- spills = Select( );
+ spills = Select();
}
// Count number of Simplify-Select trips per coloring success.
@@ -452,9 +599,12 @@
// max_reg is past the largest *register* used.
// Convert that to a frame_slot number.
- if( _max_reg <= _matcher._new_SP )
+ if (_max_reg <= _matcher._new_SP) {
_framesize = C->out_preserve_stack_slots();
- else _framesize = _max_reg -_matcher._new_SP;
+ }
+ else {
+ _framesize = _max_reg -_matcher._new_SP;
+ }
assert((int)(_matcher._new_SP+_framesize) >= (int)_matcher._out_arg_limit, "framesize must be large enough");
// This frame must preserve the required fp alignment
@@ -462,8 +612,9 @@
assert( _framesize >= 0 && _framesize <= 1000000, "sanity check" );
#ifndef PRODUCT
_total_framesize += _framesize;
- if( (int)_framesize > _max_framesize )
+ if ((int)_framesize > _max_framesize) {
_max_framesize = _framesize;
+ }
#endif
// Convert CISC spills
@@ -475,15 +626,17 @@
log->elem("regalloc attempts='%d' success='%d'", _trip_cnt, !C->failing());
}
- if (C->failing()) return;
+ if (C->failing()) {
+ return;
+ }
- NOT_PRODUCT( C->verify_graph_edges(); )
+ NOT_PRODUCT(C->verify_graph_edges();)
// Move important info out of the live_arena to longer lasting storage.
- alloc_node_regs(_names.Size());
- for (uint i=0; i < _names.Size(); i++) {
- if (_names[i]) { // Live range associated with Node?
- LRG &lrg = lrgs(_names[i]);
+ alloc_node_regs(_lrg_map.size());
+ for (uint i=0; i < _lrg_map.size(); i++) {
+ if (_lrg_map.live_range_id(i)) { // Live range associated with Node?
+ LRG &lrg = lrgs(_lrg_map.live_range_id(i));
if (!lrg.alive()) {
set_bad(i);
} else if (lrg.num_regs() == 1) {
@@ -537,11 +690,11 @@
Node *n = b->_nodes[j];
// Pre-color to the zero live range, or pick virtual register
const RegMask &rm = n->out_RegMask();
- _names.map( n->_idx, rm.is_NotEmpty() ? lr_counter++ : 0 );
+ _lrg_map.map(n->_idx, rm.is_NotEmpty() ? lr_counter++ : 0);
}
}
// Reset the Union-Find mapping to be identity
- reset_uf_map(lr_counter);
+ _lrg_map.reset_uf_map(lr_counter);
}
@@ -551,7 +704,7 @@
void PhaseChaitin::gather_lrg_masks( bool after_aggressive ) {
// Nail down the frame pointer live range
- uint fp_lrg = n2lidx(_cfg._root->in(1)->in(TypeFunc::FramePtr));
+ uint fp_lrg = _lrg_map.live_range_id(_cfg._root->in(1)->in(TypeFunc::FramePtr));
lrgs(fp_lrg)._cost += 1e12; // Cost is infinite
// For all blocks
@@ -566,14 +719,14 @@
uint idx = n->is_Copy();
// Get virtual register number, same as LiveRanGe index
- uint vreg = n2lidx(n);
+ uint vreg = _lrg_map.live_range_id(n);
LRG &lrg = lrgs(vreg);
if( vreg ) { // No vreg means un-allocable (e.g. memory)
// Collect has-copy bit
if( idx ) {
lrg._has_copy = 1;
- uint clidx = n2lidx(n->in(idx));
+ uint clidx = _lrg_map.live_range_id(n->in(idx));
LRG ©_src = lrgs(clidx);
copy_src._has_copy = 1;
}
@@ -773,8 +926,10 @@
}
// Prepare register mask for each input
for( uint k = input_edge_start; k < cnt; k++ ) {
- uint vreg = n2lidx(n->in(k));
- if( !vreg ) continue;
+ uint vreg = _lrg_map.live_range_id(n->in(k));
+ if (!vreg) {
+ continue;
+ }
// If this instruction is CISC Spillable, add the flags
// bit to its appropriate input
@@ -857,7 +1012,7 @@
} // end for all blocks
// Final per-liverange setup
- for (uint i2=0; i2<_maxlrg; i2++) {
+ for (uint i2 = 0; i2 < _lrg_map.max_lrg_id(); i2++) {
LRG &lrg = lrgs(i2);
assert(!lrg._is_vector || !lrg._fat_proj, "sanity");
if (lrg.num_regs() > 1 && !lrg._fat_proj) {
@@ -879,7 +1034,7 @@
// The bit is checked in Simplify.
void PhaseChaitin::set_was_low() {
#ifdef ASSERT
- for( uint i = 1; i < _maxlrg; i++ ) {
+ for (uint i = 1; i < _lrg_map.max_lrg_id(); i++) {
int size = lrgs(i).num_regs();
uint old_was_lo = lrgs(i)._was_lo;
lrgs(i)._was_lo = 0;
@@ -913,7 +1068,7 @@
// Compute cost/area ratio, in case we spill. Build the lo-degree list.
void PhaseChaitin::cache_lrg_info( ) {
- for( uint i = 1; i < _maxlrg; i++ ) {
+ for (uint i = 1; i < _lrg_map.max_lrg_id(); i++) {
LRG &lrg = lrgs(i);
// Check for being of low degree: means we can be trivially colored.
@@ -949,10 +1104,10 @@
// Warm up the lo-degree no-copy list
int lo_no_copy = 0;
- for( uint i = 1; i < _maxlrg; i++ ) {
- if( (lrgs(i).lo_degree() && !lrgs(i)._has_copy) ||
+ for (uint i = 1; i < _lrg_map.max_lrg_id(); i++) {
+ if ((lrgs(i).lo_degree() && !lrgs(i)._has_copy) ||
!lrgs(i).alive() ||
- lrgs(i)._must_spill ) {
+ lrgs(i)._must_spill) {
lrgs(i)._next = lo_no_copy;
lo_no_copy = i;
}
@@ -1163,7 +1318,7 @@
OptoReg::Name PhaseChaitin::bias_color( LRG &lrg, int chunk ) {
// Check for "at_risk" LRG's
- uint risk_lrg = Find(lrg._risk_bias);
+ uint risk_lrg = _lrg_map.find(lrg._risk_bias);
if( risk_lrg != 0 ) {
// Walk the colored neighbors of the "at_risk" candidate
// Choose a color which is both legal and already taken by a neighbor
@@ -1179,7 +1334,7 @@
}
}
- uint copy_lrg = Find(lrg._copy_bias);
+ uint copy_lrg = _lrg_map.find(lrg._copy_bias);
if( copy_lrg != 0 ) {
// If he has a color,
if( !(*(_ifg->_yanked))[copy_lrg] ) {
@@ -1423,10 +1578,10 @@
void PhaseChaitin::copy_was_spilled( Node *src, Node *dst ) {
if( _spilled_once.test(src->_idx) ) {
_spilled_once.set(dst->_idx);
- lrgs(Find(dst))._was_spilled1 = 1;
+ lrgs(_lrg_map.find(dst))._was_spilled1 = 1;
if( _spilled_twice.test(src->_idx) ) {
_spilled_twice.set(dst->_idx);
- lrgs(Find(dst))._was_spilled2 = 1;
+ lrgs(_lrg_map.find(dst))._was_spilled2 = 1;
}
}
}
@@ -1471,7 +1626,7 @@
MachNode *mach = n->as_Mach();
inp = mach->operand_index(inp);
Node *src = n->in(inp); // Value to load or store
- LRG &lrg_cisc = lrgs( Find_const(src) );
+ LRG &lrg_cisc = lrgs(_lrg_map.find_const(src));
OptoReg::Name src_reg = lrg_cisc.reg();
// Doubles record the HIGH register of an adjacent pair.
src_reg = OptoReg::add(src_reg,1-lrg_cisc.num_regs());
@@ -1554,9 +1709,9 @@
Block *startb = _cfg._bbs[C->top()->_idx];
startb->_nodes.insert(startb->find_node(C->top()), base );
_cfg._bbs.map( base->_idx, startb );
- assert (n2lidx(base) == 0, "should not have LRG yet");
+ assert(_lrg_map.live_range_id(base) == 0, "should not have LRG yet");
}
- if (n2lidx(base) == 0) {
+ if (_lrg_map.live_range_id(base) == 0) {
new_lrg(base, maxlrg++);
}
assert(base->in(0) == _cfg._root &&
@@ -1566,7 +1721,7 @@
}
// Check for AddP-related opcodes
- if( !derived->is_Phi() ) {
+ if (!derived->is_Phi()) {
assert(derived->as_Mach()->ideal_Opcode() == Op_AddP, err_msg_res("but is: %s", derived->Name()));
Node *base = derived->in(AddPNode::Base);
derived_base_map[derived->_idx] = base;
@@ -1629,9 +1784,9 @@
// base pointer that is live across the Safepoint for oopmap building. The
// edge pairs get added in after sfpt->jvmtail()->oopoff(), but are in the
// required edge set.
-bool PhaseChaitin::stretch_base_pointer_live_ranges( ResourceArea *a ) {
+bool PhaseChaitin::stretch_base_pointer_live_ranges(ResourceArea *a) {
int must_recompute_live = false;
- uint maxlrg = _maxlrg;
+ uint maxlrg = _lrg_map.max_lrg_id();
Node **derived_base_map = (Node**)a->Amalloc(sizeof(Node*)*C->unique());
memset( derived_base_map, 0, sizeof(Node*)*C->unique() );
@@ -1669,15 +1824,18 @@
}
// Get value being defined
- uint lidx = n2lidx(n);
- if( lidx && lidx < _maxlrg /* Ignore the occasional brand-new live range */) {
+ uint lidx = _lrg_map.live_range_id(n);
+ // Ignore the occasional brand-new live range
+ if (lidx && lidx < _lrg_map.max_lrg_id()) {
// Remove from live-out set
liveout.remove(lidx);
// Copies do not define a new value and so do not interfere.
// Remove the copies source from the liveout set before interfering.
uint idx = n->is_Copy();
- if( idx ) liveout.remove( n2lidx(n->in(idx)) );
+ if (idx) {
+ liveout.remove(_lrg_map.live_range_id(n->in(idx)));
+ }
}
// Found a safepoint?
@@ -1695,21 +1853,21 @@
derived->bottom_type()->make_ptr()->is_ptr()->_offset == 0, "sanity");
// If its an OOP with a non-zero offset, then it is derived.
if( tj && tj->_offset != 0 && tj->isa_oop_ptr() ) {
- Node *base = find_base_for_derived( derived_base_map, derived, maxlrg );
- assert( base->_idx < _names.Size(), "" );
+ Node *base = find_base_for_derived(derived_base_map, derived, maxlrg);
+ assert(base->_idx < _lrg_map.size(), "");
// Add reaching DEFs of derived pointer and base pointer as a
// pair of inputs
- n->add_req( derived );
- n->add_req( base );
+ n->add_req(derived);
+ n->add_req(base);
// See if the base pointer is already live to this point.
// Since I'm working on the SSA form, live-ness amounts to
// reaching def's. So if I find the base's live range then
// I know the base's def reaches here.
- if( (n2lidx(base) >= _maxlrg ||// (Brand new base (hence not live) or
- !liveout.member( n2lidx(base) ) ) && // not live) AND
- (n2lidx(base) > 0) && // not a constant
- _cfg._bbs[base->_idx] != b ) { // base not def'd in blk)
+ if ((_lrg_map.live_range_id(base) >= _lrg_map.max_lrg_id() || // (Brand new base (hence not live) or
+ !liveout.member(_lrg_map.live_range_id(base))) && // not live) AND
+ (_lrg_map.live_range_id(base) > 0) && // not a constant
+ _cfg._bbs[base->_idx] != b) { // base not def'd in blk)
// Base pointer is not currently live. Since I stretched
// the base pointer to here and it crosses basic-block
// boundaries, the global live info is now incorrect.
@@ -1721,11 +1879,12 @@
} // End of if found a GC point
// Make all inputs live
- if( !n->is_Phi() ) { // Phi function uses come from prior block
- for( uint k = 1; k < n->req(); k++ ) {
- uint lidx = n2lidx(n->in(k));
- if( lidx < _maxlrg )
- liveout.insert( lidx );
+ if (!n->is_Phi()) { // Phi function uses come from prior block
+ for (uint k = 1; k < n->req(); k++) {
+ uint lidx = _lrg_map.live_range_id(n->in(k));
+ if (lidx < _lrg_map.max_lrg_id()) {
+ liveout.insert(lidx);
+ }
}
}
@@ -1733,11 +1892,12 @@
liveout.clear(); // Free the memory used by liveout.
} // End of forall blocks
- _maxlrg = maxlrg;
+ _lrg_map.set_max_lrg_id(maxlrg);
// If I created a new live range I need to recompute live
- if( maxlrg != _ifg->_maxlrg )
+ if (maxlrg != _ifg->_maxlrg) {
must_recompute_live = true;
+ }
return must_recompute_live != 0;
}
@@ -1745,16 +1905,17 @@
//------------------------------add_reference----------------------------------
// Extend the node to LRG mapping
-void PhaseChaitin::add_reference( const Node *node, const Node *old_node ) {
- _names.extend( node->_idx, n2lidx(old_node) );
+
+void PhaseChaitin::add_reference(const Node *node, const Node *old_node) {
+ _lrg_map.extend(node->_idx, _lrg_map.live_range_id(old_node));
}
//------------------------------dump-------------------------------------------
#ifndef PRODUCT
-void PhaseChaitin::dump( const Node *n ) const {
- uint r = (n->_idx < _names.Size() ) ? Find_const(n) : 0;
+void PhaseChaitin::dump(const Node *n) const {
+ uint r = (n->_idx < _lrg_map.size()) ? _lrg_map.find_const(n) : 0;
tty->print("L%d",r);
- if( r && n->Opcode() != Op_Phi ) {
+ if (r && n->Opcode() != Op_Phi) {
if( _node_regs ) { // Got a post-allocation copy of allocation?
tty->print("[");
OptoReg::Name second = get_reg_second(n);
@@ -1775,11 +1936,13 @@
tty->print("/N%d\t",n->_idx);
tty->print("%s === ", n->Name());
uint k;
- for( k = 0; k < n->req(); k++) {
+ for (k = 0; k < n->req(); k++) {
Node *m = n->in(k);
- if( !m ) tty->print("_ ");
+ if (!m) {
+ tty->print("_ ");
+ }
else {
- uint r = (m->_idx < _names.Size() ) ? Find_const(m) : 0;
+ uint r = (m->_idx < _lrg_map.size()) ? _lrg_map.find_const(m) : 0;
tty->print("L%d",r);
// Data MultiNode's can have projections with no real registers.
// Don't die while dumping them.
@@ -1810,8 +1973,10 @@
if( k < n->len() && n->in(k) ) tty->print("| ");
for( ; k < n->len(); k++ ) {
Node *m = n->in(k);
- if( !m ) break;
- uint r = (m->_idx < _names.Size() ) ? Find_const(m) : 0;
+ if(!m) {
+ break;
+ }
+ uint r = (m->_idx < _lrg_map.size()) ? _lrg_map.find_const(m) : 0;
tty->print("L%d",r);
tty->print("/N%d ",m->_idx);
}
@@ -1839,7 +2004,7 @@
tty->print("{");
uint i;
while ((i = elements.next()) != 0) {
- tty->print("L%d ", Find_const(i));
+ tty->print("L%d ", _lrg_map.find_const(i));
}
tty->print_cr("}");
}
@@ -1863,10 +2028,14 @@
// Dump LRG array
tty->print("--- Live RanGe Array ---\n");
- for(uint i2 = 1; i2 < _maxlrg; i2++ ) {
+ for (uint i2 = 1; i2 < _lrg_map.max_lrg_id(); i2++) {
tty->print("L%d: ",i2);
- if( i2 < _ifg->_maxlrg ) lrgs(i2).dump( );
- else tty->print_cr("new LRG");
+ if (i2 < _ifg->_maxlrg) {
+ lrgs(i2).dump();
+ }
+ else {
+ tty->print_cr("new LRG");
+ }
}
tty->print_cr("");
@@ -1939,7 +2108,7 @@
// Post allocation, use direct mappings, no LRG info available
print_reg( get_reg_first(n), this, buf );
} else {
- uint lidx = Find_const(n); // Grab LRG number
+ uint lidx = _lrg_map.find_const(n); // Grab LRG number
if( !_ifg ) {
sprintf(buf,"L%d",lidx); // No register binding yet
} else if( !lidx ) { // Special, not allocated value
@@ -1968,7 +2137,7 @@
if( WizardMode && (PrintCompilation || PrintOpto) ) {
// Display which live ranges need to be split and the allocator's state
tty->print_cr("Graph-Coloring Iteration %d will split the following live ranges", _trip_cnt);
- for( uint bidx = 1; bidx < _maxlrg; bidx++ ) {
+ for (uint bidx = 1; bidx < _lrg_map.max_lrg_id(); bidx++) {
if( lrgs(bidx).alive() && lrgs(bidx).reg() >= LRG::SPILL_REG ) {
tty->print("L%d: ", bidx);
lrgs(bidx).dump();
@@ -2099,14 +2268,17 @@
void PhaseChaitin::dump_lrg( uint lidx, bool defs_only ) const {
tty->print_cr("---dump of L%d---",lidx);
- if( _ifg ) {
- if( lidx >= _maxlrg ) {
+ if (_ifg) {
+ if (lidx >= _lrg_map.max_lrg_id()) {
tty->print("Attempt to print live range index beyond max live range.\n");
return;
}
tty->print("L%d: ",lidx);
- if( lidx < _ifg->_maxlrg ) lrgs(lidx).dump( );
- else tty->print_cr("new LRG");
+ if (lidx < _ifg->_maxlrg) {
+ lrgs(lidx).dump();
+ } else {
+ tty->print_cr("new LRG");
+ }
}
if( _ifg && lidx < _ifg->_maxlrg) {
tty->print("Neighbors: %d - ", _ifg->neighbor_cnt(lidx));
@@ -2121,8 +2293,8 @@
// For all instructions
for( uint j = 0; j < b->_nodes.size(); j++ ) {
Node *n = b->_nodes[j];
- if( Find_const(n) == lidx ) {
- if( !dump_once++ ) {
+ if (_lrg_map.find_const(n) == lidx) {
+ if (!dump_once++) {
tty->cr();
b->dump_head( &_cfg._bbs );
}
@@ -2133,11 +2305,13 @@
uint cnt = n->req();
for( uint k = 1; k < cnt; k++ ) {
Node *m = n->in(k);
- if (!m) continue; // be robust in the dumper
- if( Find_const(m) == lidx ) {
- if( !dump_once++ ) {
+ if (!m) {
+ continue; // be robust in the dumper
+ }
+ if (_lrg_map.find_const(m) == lidx) {
+ if (!dump_once++) {
tty->cr();
- b->dump_head( &_cfg._bbs );
+ b->dump_head(&_cfg._bbs);
}
dump(n);
}
--- a/hotspot/src/share/vm/opto/chaitin.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/opto/chaitin.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -265,18 +265,118 @@
int effective_degree( uint lidx ) const;
};
-// TEMPORARILY REPLACED WITH COMMAND LINE FLAG
+// The LiveRangeMap class is responsible for storing node to live range id mapping.
+// Each node is mapped to a live range id (a virtual register). Nodes that are
+// not considered for register allocation are given live range id 0.
+class LiveRangeMap VALUE_OBJ_CLASS_SPEC {
+
+private:
+
+ uint _max_lrg_id;
+
+ // Union-find map. Declared as a short for speed.
+ // Indexed by live-range number, it returns the compacted live-range number
+ LRG_List _uf_map;
+
+ // Map from Nodes to live ranges
+ LRG_List _names;
+
+ // Straight out of Tarjan's union-find algorithm
+ uint find_compress(const Node *node) {
+ uint lrg_id = find_compress(_names[node->_idx]);
+ _names.map(node->_idx, lrg_id);
+ return lrg_id;
+ }
+
+ uint find_compress(uint lrg);
+
+public:
+
+ const LRG_List& names() {
+ return _names;
+ }
+
+ uint max_lrg_id() const {
+ return _max_lrg_id;
+ }
+
+ void set_max_lrg_id(uint max_lrg_id) {
+ _max_lrg_id = max_lrg_id;
+ }
+
+ uint size() const {
+ return _names.Size();
+ }
+
+ uint live_range_id(uint idx) const {
+ return _names[idx];
+ }
+
+ uint live_range_id(const Node *node) const {
+ return _names[node->_idx];
+ }
+
+ uint uf_live_range_id(uint lrg_id) const {
+ return _uf_map[lrg_id];
+ }
-//// !!!!! Magic Constants need to move into ad file
-#ifdef SPARC
-//#define FLOAT_PRESSURE 30 /* SFLT_REG_mask.Size() - 1 */
-//#define INT_PRESSURE 23 /* NOTEMP_I_REG_mask.Size() - 1 */
-#define FLOAT_INCREMENT(regs) regs
-#else
-//#define FLOAT_PRESSURE 6
-//#define INT_PRESSURE 6
-#define FLOAT_INCREMENT(regs) 1
-#endif
+ void map(uint idx, uint lrg_id) {
+ _names.map(idx, lrg_id);
+ }
+
+ void uf_map(uint dst_lrg_id, uint src_lrg_id) {
+ _uf_map.map(dst_lrg_id, src_lrg_id);
+ }
+
+ void extend(uint idx, uint lrg_id) {
+ _names.extend(idx, lrg_id);
+ }
+
+ void uf_extend(uint dst_lrg_id, uint src_lrg_id) {
+ _uf_map.extend(dst_lrg_id, src_lrg_id);
+ }
+
+ LiveRangeMap(uint unique)
+ : _names(unique)
+ , _uf_map(unique)
+ , _max_lrg_id(0) {}
+
+ uint find_id( const Node *n ) {
+ uint retval = live_range_id(n);
+ assert(retval == find(n),"Invalid node to lidx mapping");
+ return retval;
+ }
+
+ // Reset the Union-Find map to identity
+ void reset_uf_map(uint max_lrg_id);
+
+ // Make all Nodes map directly to their final live range; no need for
+ // the Union-Find mapping after this call.
+ void compress_uf_map_for_nodes();
+
+ uint find(uint lidx) {
+ uint uf_lidx = _uf_map[lidx];
+ return (uf_lidx == lidx) ? uf_lidx : find_compress(lidx);
+ }
+
+ // Convert a Node into a Live Range Index - a lidx
+ uint find(const Node *node) {
+ uint lidx = live_range_id(node);
+ uint uf_lidx = _uf_map[lidx];
+ return (uf_lidx == lidx) ? uf_lidx : find_compress(node);
+ }
+
+ // Like Find above, but no path compress, so bad asymptotic behavior
+ uint find_const(uint lrg) const;
+
+ // Like Find above, but no path compress, so bad asymptotic behavior
+ uint find_const(const Node *node) const {
+ if(node->_idx >= _names.Size()) {
+ return 0; // not mapped, usual for debug dump
+ }
+ return find_const(_names[node->_idx]);
+ }
+};
//------------------------------Chaitin----------------------------------------
// Briggs-Chaitin style allocation, mostly.
@@ -286,7 +386,6 @@
int _trip_cnt;
int _alternate;
- uint _maxlrg; // Max live range number
LRG &lrgs(uint idx) const { return _ifg->lrgs(idx); }
PhaseLive *_live; // Liveness, used in the interference graph
PhaseIFG *_ifg; // Interference graph (for original chunk)
@@ -294,16 +393,6 @@
VectorSet _spilled_once; // Nodes that have been spilled
VectorSet _spilled_twice; // Nodes that have been spilled twice
- LRG_List _names; // Map from Nodes to Live RanGes
-
- // Union-find map. Declared as a short for speed.
- // Indexed by live-range number, it returns the compacted live-range number
- LRG_List _uf_map;
- // Reset the Union-Find map to identity
- void reset_uf_map( uint maxlrg );
- // Remove the need for the Union-Find mapping
- void compress_uf_map_for_nodes( );
-
// Combine the Live Range Indices for these 2 Nodes into a single live
// range. Future requests for any Node in either live range will
// return the live range index for the combined live range.
@@ -322,7 +411,34 @@
// Helper functions for Split()
uint split_DEF( Node *def, Block *b, int loc, uint max, Node **Reachblock, Node **debug_defs, GrowableArray<uint> splits, int slidx );
uint split_USE( Node *def, Block *b, Node *use, uint useidx, uint max, bool def_down, bool cisc_sp, GrowableArray<uint> splits, int slidx );
- int clone_projs( Block *b, uint idx, Node *con, Node *copy, uint &maxlrg );
+
+ bool clone_projs(Block *b, uint idx, Node *con, Node *copy, LiveRangeMap &lrg_map) {
+ bool found_projs = clone_projs_shared(b, idx, con, copy, lrg_map.max_lrg_id());
+
+ if(found_projs) {
+ uint max_lrg_id = lrg_map.max_lrg_id();
+ lrg_map.set_max_lrg_id(max_lrg_id + 1);
+ }
+
+ return found_projs;
+ }
+
+ //------------------------------clone_projs------------------------------------
+ // After cloning some rematerialized instruction, clone any MachProj's that
+ // follow it. Example: Intel zero is XOR, kills flags. Sparc FP constants
+ // use G3 as an address temp.
+ bool clone_projs(Block *b, uint idx, Node *con, Node *copy, uint &max_lrg_id) {
+ bool found_projs = clone_projs_shared(b, idx, con, copy, max_lrg_id);
+
+ if(found_projs) {
+ max_lrg_id++;
+ }
+
+ return found_projs;
+ }
+
+ bool clone_projs_shared(Block *b, uint idx, Node *con, Node *copy, uint max_lrg_id);
+
Node *split_Rematerialize(Node *def, Block *b, uint insidx, uint &maxlrg, GrowableArray<uint> splits,
int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru);
// True if lidx is used before any real register is def'd in the block
@@ -349,20 +465,11 @@
PhaseChaitin( uint unique, PhaseCFG &cfg, Matcher &matcher );
~PhaseChaitin() {}
- // Convert a Node into a Live Range Index - a lidx
- uint Find( const Node *n ) {
- uint lidx = n2lidx(n);
- uint uf_lidx = _uf_map[lidx];
- return (uf_lidx == lidx) ? uf_lidx : Find_compress(n);
- }
- uint Find_const( uint lrg ) const;
- uint Find_const( const Node *n ) const;
+ LiveRangeMap _lrg_map;
// Do all the real work of allocate
void Register_Allocate();
- uint n2lidx( const Node *n ) const { return _names[n->_idx]; }
-
float high_frequency_lrg() const { return _high_frequency_lrg; }
#ifndef PRODUCT
@@ -374,18 +481,6 @@
// all inputs to a PhiNode, effectively coalescing live ranges. Insert
// copies as needed.
void de_ssa();
- uint Find_compress( const Node *n );
- uint Find( uint lidx ) {
- uint uf_lidx = _uf_map[lidx];
- return (uf_lidx == lidx) ? uf_lidx : Find_compress(lidx);
- }
- uint Find_compress( uint lidx );
-
- uint Find_id( const Node *n ) {
- uint retval = n2lidx(n);
- assert(retval == Find(n),"Invalid node to lidx mapping");
- return retval;
- }
// Add edge between reg and everything in the vector.
// Same as _ifg->add_vector(reg,live) EXCEPT use the RegMask
--- a/hotspot/src/share/vm/opto/coalesce.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/opto/coalesce.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -35,159 +35,11 @@
#include "opto/regmask.hpp"
//=============================================================================
-//------------------------------reset_uf_map-----------------------------------
-void PhaseChaitin::reset_uf_map( uint maxlrg ) {
- _maxlrg = maxlrg;
- // Force the Union-Find mapping to be at least this large
- _uf_map.extend(_maxlrg,0);
- // Initialize it to be the ID mapping.
- for( uint i=0; i<_maxlrg; i++ )
- _uf_map.map(i,i);
-}
-
-//------------------------------compress_uf_map--------------------------------
-// Make all Nodes map directly to their final live range; no need for
-// the Union-Find mapping after this call.
-void PhaseChaitin::compress_uf_map_for_nodes( ) {
- // For all Nodes, compress mapping
- uint unique = _names.Size();
- for( uint i=0; i<unique; i++ ) {
- uint lrg = _names[i];
- uint compressed_lrg = Find(lrg);
- if( lrg != compressed_lrg )
- _names.map(i,compressed_lrg);
- }
-}
-
-//------------------------------Find-------------------------------------------
-// Straight out of Tarjan's union-find algorithm
-uint PhaseChaitin::Find_compress( uint lrg ) {
- uint cur = lrg;
- uint next = _uf_map[cur];
- while( next != cur ) { // Scan chain of equivalences
- assert( next < cur, "always union smaller" );
- cur = next; // until find a fixed-point
- next = _uf_map[cur];
- }
- // Core of union-find algorithm: update chain of
- // equivalences to be equal to the root.
- while( lrg != next ) {
- uint tmp = _uf_map[lrg];
- _uf_map.map(lrg, next);
- lrg = tmp;
- }
- return lrg;
-}
-
-//------------------------------Find-------------------------------------------
-// Straight out of Tarjan's union-find algorithm
-uint PhaseChaitin::Find_compress( const Node *n ) {
- uint lrg = Find_compress(_names[n->_idx]);
- _names.map(n->_idx,lrg);
- return lrg;
-}
-
-//------------------------------Find_const-------------------------------------
-// Like Find above, but no path compress, so bad asymptotic behavior
-uint PhaseChaitin::Find_const( uint lrg ) const {
- if( !lrg ) return lrg; // Ignore the zero LRG
- // Off the end? This happens during debugging dumps when you got
- // brand new live ranges but have not told the allocator yet.
- if( lrg >= _maxlrg ) return lrg;
- uint next = _uf_map[lrg];
- while( next != lrg ) { // Scan chain of equivalences
- assert( next < lrg, "always union smaller" );
- lrg = next; // until find a fixed-point
- next = _uf_map[lrg];
- }
- return next;
-}
-
-//------------------------------Find-------------------------------------------
-// Like Find above, but no path compress, so bad asymptotic behavior
-uint PhaseChaitin::Find_const( const Node *n ) const {
- if( n->_idx >= _names.Size() ) return 0; // not mapped, usual for debug dump
- return Find_const( _names[n->_idx] );
-}
-
-//------------------------------Union------------------------------------------
-// union 2 sets together.
-void PhaseChaitin::Union( const Node *src_n, const Node *dst_n ) {
- uint src = Find(src_n);
- uint dst = Find(dst_n);
- assert( src, "" );
- assert( dst, "" );
- assert( src < _maxlrg, "oob" );
- assert( dst < _maxlrg, "oob" );
- assert( src < dst, "always union smaller" );
- _uf_map.map(dst,src);
-}
-
-//------------------------------new_lrg----------------------------------------
-void PhaseChaitin::new_lrg( const Node *x, uint lrg ) {
- // Make the Node->LRG mapping
- _names.extend(x->_idx,lrg);
- // Make the Union-Find mapping an identity function
- _uf_map.extend(lrg,lrg);
-}
-
-//------------------------------clone_projs------------------------------------
-// After cloning some rematerialized instruction, clone any MachProj's that
-// follow it. Example: Intel zero is XOR, kills flags. Sparc FP constants
-// use G3 as an address temp.
-int PhaseChaitin::clone_projs( Block *b, uint idx, Node *con, Node *copy, uint &maxlrg ) {
- Block *bcon = _cfg._bbs[con->_idx];
- uint cindex = bcon->find_node(con);
- Node *con_next = bcon->_nodes[cindex+1];
- if( con_next->in(0) != con || !con_next->is_MachProj() )
- return false; // No MachProj's follow
-
- // Copy kills after the cloned constant
- Node *kills = con_next->clone();
- kills->set_req( 0, copy );
- b->_nodes.insert( idx, kills );
- _cfg._bbs.map( kills->_idx, b );
- new_lrg( kills, maxlrg++ );
- return true;
-}
-
-//------------------------------compact----------------------------------------
-// Renumber the live ranges to compact them. Makes the IFG smaller.
-void PhaseChaitin::compact() {
- // Current the _uf_map contains a series of short chains which are headed
- // by a self-cycle. All the chains run from big numbers to little numbers.
- // The Find() call chases the chains & shortens them for the next Find call.
- // We are going to change this structure slightly. Numbers above a moving
- // wave 'i' are unchanged. Numbers below 'j' point directly to their
- // compacted live range with no further chaining. There are no chains or
- // cycles below 'i', so the Find call no longer works.
- uint j=1;
- uint i;
- for( i=1; i < _maxlrg; i++ ) {
- uint lr = _uf_map[i];
- // Ignore unallocated live ranges
- if( !lr ) continue;
- assert( lr <= i, "" );
- _uf_map.map(i, ( lr == i ) ? j++ : _uf_map[lr]);
- }
- if( false ) // PrintOptoCompactLiveRanges
- printf("Compacted %d LRs from %d\n",i-j,i);
- // Now change the Node->LR mapping to reflect the compacted names
- uint unique = _names.Size();
- for( i=0; i<unique; i++ )
- _names.map(i,_uf_map[_names[i]]);
-
- // Reset the Union-Find mapping
- reset_uf_map(j);
-
-}
-
-//=============================================================================
//------------------------------Dump-------------------------------------------
#ifndef PRODUCT
-void PhaseCoalesce::dump( Node *n ) const {
+void PhaseCoalesce::dump(Node *n) const {
// Being a const function means I cannot use 'Find'
- uint r = _phc.Find(n);
+ uint r = _phc._lrg_map.find(n);
tty->print("L%d/N%d ",r,n->_idx);
}
@@ -235,9 +87,9 @@
//------------------------------combine_these_two------------------------------
// Combine the live ranges def'd by these 2 Nodes. N2 is an input to N1.
-void PhaseCoalesce::combine_these_two( Node *n1, Node *n2 ) {
- uint lr1 = _phc.Find(n1);
- uint lr2 = _phc.Find(n2);
+void PhaseCoalesce::combine_these_two(Node *n1, Node *n2) {
+ uint lr1 = _phc._lrg_map.find(n1);
+ uint lr2 = _phc._lrg_map.find(n2);
if( lr1 != lr2 && // Different live ranges already AND
!_phc._ifg->test_edge_sq( lr1, lr2 ) ) { // Do not interfere
LRG *lrg1 = &_phc.lrgs(lr1);
@@ -306,14 +158,18 @@
// I am about to clobber the dst_name, so the copy must be inserted
// after the last use. Last use is really first-use on a backwards scan.
uint i = b->end_idx()-1;
- while( 1 ) {
+ while(1) {
Node *n = b->_nodes[i];
// Check for end of virtual copies; this is also the end of the
// parallel renaming effort.
- if( n->_idx < _unique ) break;
+ if (n->_idx < _unique) {
+ break;
+ }
uint idx = n->is_Copy();
assert( idx || n->is_Con() || n->is_MachProj(), "Only copies during parallel renaming" );
- if( idx && _phc.Find(n->in(idx)) == dst_name ) break;
+ if (idx && _phc._lrg_map.find(n->in(idx)) == dst_name) {
+ break;
+ }
i--;
}
uint last_use_idx = i;
@@ -324,24 +180,29 @@
// There can be only 1 kill that exits any block and that is
// the last kill. Thus it is the first kill on a backwards scan.
i = b->end_idx()-1;
- while( 1 ) {
+ while (1) {
Node *n = b->_nodes[i];
// Check for end of virtual copies; this is also the end of the
// parallel renaming effort.
- if( n->_idx < _unique ) break;
+ if (n->_idx < _unique) {
+ break;
+ }
assert( n->is_Copy() || n->is_Con() || n->is_MachProj(), "Only copies during parallel renaming" );
- if( _phc.Find(n) == src_name ) {
+ if (_phc._lrg_map.find(n) == src_name) {
kill_src_idx = i;
break;
}
i--;
}
// Need a temp? Last use of dst comes after the kill of src?
- if( last_use_idx >= kill_src_idx ) {
+ if (last_use_idx >= kill_src_idx) {
// Need to break a cycle with a temp
uint idx = copy->is_Copy();
Node *tmp = copy->clone();
- _phc.new_lrg(tmp,_phc._maxlrg++);
+ uint max_lrg_id = _phc._lrg_map.max_lrg_id();
+ _phc.new_lrg(tmp, max_lrg_id);
+ _phc._lrg_map.set_max_lrg_id(max_lrg_id + 1);
+
// Insert new temp between copy and source
tmp ->set_req(idx,copy->in(idx));
copy->set_req(idx,tmp);
@@ -359,14 +220,14 @@
void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) {
// We do LRGs compressing and fix a liveout data only here since the other
// place in Split() is guarded by the assert which we never hit.
- _phc.compress_uf_map_for_nodes();
+ _phc._lrg_map.compress_uf_map_for_nodes();
// Fix block's liveout data for compressed live ranges.
- for(uint lrg = 1; lrg < _phc._maxlrg; lrg++ ) {
- uint compressed_lrg = _phc.Find(lrg);
- if( lrg != compressed_lrg ) {
- for( uint bidx = 0; bidx < _phc._cfg._num_blocks; bidx++ ) {
+ for (uint lrg = 1; lrg < _phc._lrg_map.max_lrg_id(); lrg++) {
+ uint compressed_lrg = _phc._lrg_map.find(lrg);
+ if (lrg != compressed_lrg) {
+ for (uint bidx = 0; bidx < _phc._cfg._num_blocks; bidx++) {
IndexSet *liveout = _phc._live->live(_phc._cfg._blocks[bidx]);
- if( liveout->member(lrg) ) {
+ if (liveout->member(lrg)) {
liveout->remove(lrg);
liveout->insert(compressed_lrg);
}
@@ -392,8 +253,9 @@
uint cidx = copy->is_Copy();
if( cidx ) {
Node *def = copy->in(cidx);
- if( _phc.Find(copy) == _phc.Find(def) )
- n->set_req(k,def);
+ if (_phc._lrg_map.find(copy) == _phc._lrg_map.find(def)) {
+ n->set_req(k, def);
+ }
}
}
@@ -401,7 +263,7 @@
uint cidx = n->is_Copy();
if( cidx ) {
Node *def = n->in(cidx);
- if( _phc.Find(n) == _phc.Find(def) ) {
+ if (_phc._lrg_map.find(n) == _phc._lrg_map.find(def)) {
n->replace_by(def);
n->set_req(cidx,NULL);
b->_nodes.remove(l);
@@ -410,16 +272,18 @@
}
}
- if( n->is_Phi() ) {
+ if (n->is_Phi()) {
// Get the chosen name for the Phi
- uint phi_name = _phc.Find( n );
+ uint phi_name = _phc._lrg_map.find(n);
// Ignore the pre-allocated specials
- if( !phi_name ) continue;
+ if (!phi_name) {
+ continue;
+ }
// Check for mismatch inputs to Phi
- for( uint j = 1; j<cnt; j++ ) {
+ for (uint j = 1; j < cnt; j++) {
Node *m = n->in(j);
- uint src_name = _phc.Find(m);
- if( src_name != phi_name ) {
+ uint src_name = _phc._lrg_map.find(m);
+ if (src_name != phi_name) {
Block *pred = _phc._cfg._bbs[b->pred(j)->_idx];
Node *copy;
assert(!m->is_Con() || m->is_Mach(), "all Con must be Mach");
@@ -430,18 +294,18 @@
// Insert the copy in the predecessor basic block
pred->add_inst(copy);
// Copy any flags as well
- _phc.clone_projs( pred, pred->end_idx(), m, copy, _phc._maxlrg );
+ _phc.clone_projs(pred, pred->end_idx(), m, copy, _phc._lrg_map);
} else {
const RegMask *rm = C->matcher()->idealreg2spillmask[m->ideal_reg()];
- copy = new (C) MachSpillCopyNode(m,*rm,*rm);
+ copy = new (C) MachSpillCopyNode(m, *rm, *rm);
// Find a good place to insert. Kinda tricky, use a subroutine
insert_copy_with_overlap(pred,copy,phi_name,src_name);
}
// Insert the copy in the use-def chain
- n->set_req( j, copy );
+ n->set_req(j, copy);
_phc._cfg._bbs.map( copy->_idx, pred );
// Extend ("register allocate") the names array for the copy.
- _phc._names.extend( copy->_idx, phi_name );
+ _phc._lrg_map.extend(copy->_idx, phi_name);
} // End of if Phi names do not match
} // End of for all inputs to Phi
} else { // End of if Phi
@@ -450,39 +314,40 @@
uint idx;
if( n->is_Mach() && (idx=n->as_Mach()->two_adr()) ) {
// Get the chosen name for the Node
- uint name = _phc.Find( n );
- assert( name, "no 2-address specials" );
+ uint name = _phc._lrg_map.find(n);
+ assert (name, "no 2-address specials");
// Check for name mis-match on the 2-address input
Node *m = n->in(idx);
- if( _phc.Find(m) != name ) {
+ if (_phc._lrg_map.find(m) != name) {
Node *copy;
assert(!m->is_Con() || m->is_Mach(), "all Con must be Mach");
// At this point it is unsafe to extend live ranges (6550579).
// Rematerialize only constants as we do for Phi above.
- if( m->is_Mach() && m->as_Mach()->is_Con() &&
- m->as_Mach()->rematerialize() ) {
+ if(m->is_Mach() && m->as_Mach()->is_Con() &&
+ m->as_Mach()->rematerialize()) {
copy = m->clone();
// Insert the copy in the basic block, just before us
- b->_nodes.insert( l++, copy );
- if( _phc.clone_projs( b, l, m, copy, _phc._maxlrg ) )
+ b->_nodes.insert(l++, copy);
+ if(_phc.clone_projs(b, l, m, copy, _phc._lrg_map)) {
l++;
+ }
} else {
const RegMask *rm = C->matcher()->idealreg2spillmask[m->ideal_reg()];
- copy = new (C) MachSpillCopyNode( m, *rm, *rm );
+ copy = new (C) MachSpillCopyNode(m, *rm, *rm);
// Insert the copy in the basic block, just before us
- b->_nodes.insert( l++, copy );
+ b->_nodes.insert(l++, copy);
}
// Insert the copy in the use-def chain
- n->set_req(idx, copy );
+ n->set_req(idx, copy);
// Extend ("register allocate") the names array for the copy.
- _phc._names.extend( copy->_idx, name );
+ _phc._lrg_map.extend(copy->_idx, name);
_phc._cfg._bbs.map( copy->_idx, b );
}
} // End of is two-adr
// Insert a copy at a debug use for a lrg which has high frequency
- if( b->_freq < OPTO_DEBUG_SPLIT_FREQ || b->is_uncommon(_phc._cfg._bbs) ) {
+ if (b->_freq < OPTO_DEBUG_SPLIT_FREQ || b->is_uncommon(_phc._cfg._bbs)) {
// Walk the debug inputs to the node and check for lrg freq
JVMState* jvms = n->jvms();
uint debug_start = jvms ? jvms->debug_start() : 999999;
@@ -490,9 +355,11 @@
for(uint inpidx = debug_start; inpidx < debug_end; inpidx++) {
// Do not split monitors; they are only needed for debug table
// entries and need no code.
- if( jvms->is_monitor_use(inpidx) ) continue;
+ if (jvms->is_monitor_use(inpidx)) {
+ continue;
+ }
Node *inp = n->in(inpidx);
- uint nidx = _phc.n2lidx(inp);
+ uint nidx = _phc._lrg_map.live_range_id(inp);
LRG &lrg = lrgs(nidx);
// If this lrg has a high frequency use/def
@@ -519,8 +386,10 @@
// Insert the copy in the basic block, just before us
b->_nodes.insert( l++, copy );
// Extend ("register allocate") the names array for the copy.
- _phc.new_lrg( copy, _phc._maxlrg++ );
- _phc._cfg._bbs.map( copy->_idx, b );
+ uint max_lrg_id = _phc._lrg_map.max_lrg_id();
+ _phc.new_lrg(copy, max_lrg_id);
+ _phc._lrg_map.set_max_lrg_id(max_lrg_id + 1);
+ _phc._cfg._bbs.map(copy->_idx, b);
//tty->print_cr("Split a debug use in Aggressive Coalesce");
} // End of if high frequency use/def
} // End of for all debug inputs
@@ -583,17 +452,17 @@
uint idx;
// 2-address instructions have a virtual Copy matching their input
// to their output
- if( n->is_Mach() && (idx = n->as_Mach()->two_adr()) ) {
+ if (n->is_Mach() && (idx = n->as_Mach()->two_adr())) {
MachNode *mach = n->as_Mach();
- combine_these_two( mach, mach->in(idx) );
+ combine_these_two(mach, mach->in(idx));
}
} // End of for all instructions in block
}
//=============================================================================
//------------------------------PhaseConservativeCoalesce----------------------
-PhaseConservativeCoalesce::PhaseConservativeCoalesce( PhaseChaitin &chaitin ) : PhaseCoalesce(chaitin) {
- _ulr.initialize(_phc._maxlrg);
+PhaseConservativeCoalesce::PhaseConservativeCoalesce(PhaseChaitin &chaitin) : PhaseCoalesce(chaitin) {
+ _ulr.initialize(_phc._lrg_map.max_lrg_id());
}
//------------------------------verify-----------------------------------------
@@ -673,10 +542,14 @@
// Else work back one in copy chain
prev_copy = prev_copy->in(prev_copy->is_Copy());
} else { // Else collect interferences
- uint lidx = _phc.Find(x);
+ uint lidx = _phc._lrg_map.find(x);
// Found another def of live-range being stretched?
- if( lidx == lr1 ) return max_juint;
- if( lidx == lr2 ) return max_juint;
+ if(lidx == lr1) {
+ return max_juint;
+ }
+ if(lidx == lr2) {
+ return max_juint;
+ }
// If we attempt to coalesce across a bound def
if( lrgs(lidx).is_bound() ) {
@@ -751,33 +624,43 @@
// See if I can coalesce a series of multiple copies together. I need the
// final dest copy and the original src copy. They can be the same Node.
// Compute the compatible register masks.
-bool PhaseConservativeCoalesce::copy_copy( Node *dst_copy, Node *src_copy, Block *b, uint bindex ) {
+bool PhaseConservativeCoalesce::copy_copy(Node *dst_copy, Node *src_copy, Block *b, uint bindex) {
- if( !dst_copy->is_SpillCopy() ) return false;
- if( !src_copy->is_SpillCopy() ) return false;
+ if (!dst_copy->is_SpillCopy()) {
+ return false;
+ }
+ if (!src_copy->is_SpillCopy()) {
+ return false;
+ }
Node *src_def = src_copy->in(src_copy->is_Copy());
- uint lr1 = _phc.Find(dst_copy);
- uint lr2 = _phc.Find(src_def );
+ uint lr1 = _phc._lrg_map.find(dst_copy);
+ uint lr2 = _phc._lrg_map.find(src_def);
// Same live ranges already?
- if( lr1 == lr2 ) return false;
+ if (lr1 == lr2) {
+ return false;
+ }
// Interfere?
- if( _phc._ifg->test_edge_sq( lr1, lr2 ) ) return false;
+ if (_phc._ifg->test_edge_sq(lr1, lr2)) {
+ return false;
+ }
// Not an oop->int cast; oop->oop, int->int, AND int->oop are OK.
- if( !lrgs(lr1)._is_oop && lrgs(lr2)._is_oop ) // not an oop->int cast
+ if (!lrgs(lr1)._is_oop && lrgs(lr2)._is_oop) { // not an oop->int cast
return false;
+ }
// Coalescing between an aligned live range and a mis-aligned live range?
// No, no! Alignment changes how we count degree.
- if( lrgs(lr1)._fat_proj != lrgs(lr2)._fat_proj )
+ if (lrgs(lr1)._fat_proj != lrgs(lr2)._fat_proj) {
return false;
+ }
// Sort; use smaller live-range number
Node *lr1_node = dst_copy;
Node *lr2_node = src_def;
- if( lr1 > lr2 ) {
+ if (lr1 > lr2) {
uint tmp = lr1; lr1 = lr2; lr2 = tmp;
lr1_node = src_def; lr2_node = dst_copy;
}
@@ -916,17 +799,5 @@
PhaseChaitin::_conserv_coalesce++; // Collect stats on success
continue;
}
-
- /* do not attempt pairs. About 1/2 of all pairs can be removed by
- post-alloc. The other set are too few to bother.
- Node *copy2 = copy1->in(idx1);
- uint idx2 = copy2->is_Copy();
- if( !idx2 ) continue;
- if( copy_copy(copy1,copy2,b,i) ) {
- i--; // Retry, same location in block
- PhaseChaitin::_conserv_coalesce_pair++; // Collect stats on success
- continue;
- }
- */
}
}
--- a/hotspot/src/share/vm/opto/coalesce.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/opto/coalesce.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -41,23 +41,25 @@
public:
// Coalesce copies
- PhaseCoalesce( PhaseChaitin &chaitin ) : Phase(Coalesce), _phc(chaitin) { }
+ PhaseCoalesce(PhaseChaitin &phc)
+ : Phase(Coalesce)
+ , _phc(phc) {}
virtual void verify() = 0;
// Coalesce copies
- void coalesce_driver( );
+ void coalesce_driver();
// Coalesce copies in this block
- virtual void coalesce( Block *b ) = 0;
+ virtual void coalesce(Block *b) = 0;
// Attempt to coalesce live ranges defined by these 2
- void combine_these_two( Node *n1, Node *n2 );
+ void combine_these_two(Node *n1, Node *n2);
- LRG &lrgs( uint lidx ) { return _phc.lrgs(lidx); }
+ LRG &lrgs(uint lidx) { return _phc.lrgs(lidx); }
#ifndef PRODUCT
// Dump internally name
- void dump( Node *n ) const;
+ void dump(Node *n) const;
// Dump whole shebang
void dump() const;
#endif
--- a/hotspot/src/share/vm/opto/compile.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/opto/compile.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -2127,22 +2127,19 @@
}
NOT_PRODUCT( verify_graph_edges(); )
- PhaseChaitin regalloc(unique(),cfg,m);
+ PhaseChaitin regalloc(unique(), cfg, m);
_regalloc = ®alloc;
{
TracePhase t2("regalloc", &_t_registerAllocation, true);
- // Perform any platform dependent preallocation actions. This is used,
- // for example, to avoid taking an implicit null pointer exception
- // using the frame pointer on win95.
- _regalloc->pd_preallocate_hook();
-
// Perform register allocation. After Chaitin, use-def chains are
// no longer accurate (at spill code) and so must be ignored.
// Node->LRG->reg mappings are still accurate.
_regalloc->Register_Allocate();
// Bail out if the allocator builds too many nodes
- if (failing()) return;
+ if (failing()) {
+ return;
+ }
}
// Prior to register allocation we kept empty basic blocks in case the
@@ -2160,9 +2157,6 @@
cfg.fixup_flow();
}
- // Perform any platform dependent postallocation verifications.
- debug_only( _regalloc->pd_postallocate_verify_hook(); )
-
// Apply peephole optimizations
if( OptoPeephole ) {
NOT_PRODUCT( TracePhase t2("peephole", &_t_peephole, TimeCompiler); )
--- a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -616,7 +616,7 @@
buffer[0] = 0;
_chaitin->dump_register(node, buffer);
print_prop("reg", buffer);
- print_prop("lrg", _chaitin->n2lidx(node));
+ print_prop("lrg", _chaitin->_lrg_map.live_range_id(node));
}
node->_in_dump_cnt--;
--- a/hotspot/src/share/vm/opto/ifg.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/opto/ifg.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -286,15 +286,14 @@
uint idx;
uint last = 0;
while ((idx = elements.next()) != 0) {
- assert( idx != i, "Must have empty diagonal");
- assert( pc->Find_const(idx) == idx, "Must not need Find" );
- assert( _adjs[idx].member(i), "IFG not square" );
- assert( !(*_yanked)[idx], "No yanked neighbors" );
- assert( last < idx, "not sorted increasing");
+ assert(idx != i, "Must have empty diagonal");
+ assert(pc->_lrg_map.find_const(idx) == idx, "Must not need Find");
+ assert(_adjs[idx].member(i), "IFG not square");
+ assert(!(*_yanked)[idx], "No yanked neighbors");
+ assert(last < idx, "not sorted increasing");
last = idx;
}
- assert( !lrgs(i)._degree_valid ||
- effective_degree(i) == lrgs(i).degree(), "degree is valid but wrong" );
+ assert(!lrgs(i)._degree_valid || effective_degree(i) == lrgs(i).degree(), "degree is valid but wrong");
}
}
#endif
@@ -342,10 +341,10 @@
Node *n = b->_nodes[j-1];
// Get value being defined
- uint r = n2lidx(n);
+ uint r = _lrg_map.live_range_id(n);
// Some special values do not allocate
- if( r ) {
+ if (r) {
// Remove from live-out set
liveout->remove(r);
@@ -353,16 +352,19 @@
// Copies do not define a new value and so do not interfere.
// Remove the copies source from the liveout set before interfering.
uint idx = n->is_Copy();
- if( idx ) liveout->remove( n2lidx(n->in(idx)) );
+ if (idx) {
+ liveout->remove(_lrg_map.live_range_id(n->in(idx)));
+ }
// Interfere with everything live
- interfere_with_live( r, liveout );
+ interfere_with_live(r, liveout);
}
// Make all inputs live
- if( !n->is_Phi() ) { // Phi function uses come from prior block
- for( uint k = 1; k < n->req(); k++ )
- liveout->insert( n2lidx(n->in(k)) );
+ if (!n->is_Phi()) { // Phi function uses come from prior block
+ for(uint k = 1; k < n->req(); k++) {
+ liveout->insert(_lrg_map.live_range_id(n->in(k)));
+ }
}
// 2-address instructions always have the defined value live
@@ -394,11 +396,12 @@
n->set_req( 2, tmp );
}
// Defined value interferes with all inputs
- uint lidx = n2lidx(n->in(idx));
- for( uint k = 1; k < n->req(); k++ ) {
- uint kidx = n2lidx(n->in(k));
- if( kidx != lidx )
- _ifg->add_edge( r, kidx );
+ uint lidx = _lrg_map.live_range_id(n->in(idx));
+ for (uint k = 1; k < n->req(); k++) {
+ uint kidx = _lrg_map.live_range_id(n->in(k));
+ if (kidx != lidx) {
+ _ifg->add_edge(r, kidx);
+ }
}
}
} // End of forall instructions in block
@@ -542,10 +545,10 @@
Node *n = b->_nodes[j - 1];
// Get value being defined
- uint r = n2lidx(n);
+ uint r = _lrg_map.live_range_id(n);
// Some special values do not allocate
- if( r ) {
+ if(r) {
// A DEF normally costs block frequency; rematerialized values are
// removed from the DEF sight, so LOWER costs here.
lrgs(r)._cost += n->rematerialize() ? 0 : b->_freq;
@@ -556,9 +559,11 @@
Node *def = n->in(0);
if( !n->is_Proj() ||
// Could also be a flags-projection of a dead ADD or such.
- (n2lidx(def) && !liveout.member(n2lidx(def)) ) ) {
+ (_lrg_map.live_range_id(def) && !liveout.member(_lrg_map.live_range_id(def)))) {
b->_nodes.remove(j - 1);
- if( lrgs(r)._def == n ) lrgs(r)._def = 0;
+ if (lrgs(r)._def == n) {
+ lrgs(r)._def = 0;
+ }
n->disconnect_inputs(NULL, C);
_cfg._bbs.map(n->_idx,NULL);
n->replace_by(C->top());
@@ -570,7 +575,7 @@
// Fat-projections kill many registers which cannot be used to
// hold live ranges.
- if( lrgs(r)._fat_proj ) {
+ if (lrgs(r)._fat_proj) {
// Count the int-only registers
RegMask itmp = lrgs(r).mask();
itmp.AND(*Matcher::idealreg2regmask[Op_RegI]);
@@ -636,12 +641,12 @@
// Copies do not define a new value and so do not interfere.
// Remove the copies source from the liveout set before interfering.
uint idx = n->is_Copy();
- if( idx ) {
- uint x = n2lidx(n->in(idx));
- if( liveout.remove( x ) ) {
+ if (idx) {
+ uint x = _lrg_map.live_range_id(n->in(idx));
+ if (liveout.remove(x)) {
lrgs(x)._area -= cost;
// Adjust register pressure.
- lower_pressure( &lrgs(x), j-1, b, pressure, hrp_index );
+ lower_pressure(&lrgs(x), j-1, b, pressure, hrp_index);
assert( pressure[0] == count_int_pressure (&liveout), "" );
assert( pressure[1] == count_float_pressure(&liveout), "" );
}
@@ -727,18 +732,21 @@
// the flags and assumes it's dead. This keeps the (useless)
// flag-setting behavior alive while also keeping the (useful)
// memory update effect.
- for( uint k = ((n->Opcode() == Op_SCMemProj) ? 0:1); k < n->req(); k++ ) {
+ for (uint k = ((n->Opcode() == Op_SCMemProj) ? 0:1); k < n->req(); k++) {
Node *def = n->in(k);
- uint x = n2lidx(def);
- if( !x ) continue;
+ uint x = _lrg_map.live_range_id(def);
+ if (!x) {
+ continue;
+ }
LRG &lrg = lrgs(x);
// No use-side cost for spilling debug info
- if( k < debug_start )
+ if (k < debug_start) {
// A USE costs twice block frequency (once for the Load, once
// for a Load-delay). Rematerialized uses only cost once.
lrg._cost += (def->rematerialize() ? b->_freq : (b->_freq + b->_freq));
+ }
// It is live now
- if( liveout.insert( x ) ) {
+ if (liveout.insert(x)) {
// Newly live things assumed live from here to top of block
lrg._area += cost;
// Adjust register pressure
--- a/hotspot/src/share/vm/opto/live.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/opto/live.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -44,7 +44,7 @@
// block is put on the worklist.
// The locally live-in stuff is computed once and added to predecessor
// live-out sets. This separate compilation is done in the outer loop below.
-PhaseLive::PhaseLive( const PhaseCFG &cfg, LRG_List &names, Arena *arena ) : Phase(LIVE), _cfg(cfg), _names(names), _arena(arena), _live(0) {
+PhaseLive::PhaseLive( const PhaseCFG &cfg, const LRG_List &names, Arena *arena ) : Phase(LIVE), _cfg(cfg), _names(names), _arena(arena), _live(0) {
}
void PhaseLive::compute(uint maxlrg) {
--- a/hotspot/src/share/vm/opto/live.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/opto/live.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -80,7 +80,7 @@
Block_List *_worklist; // Worklist for iterative solution
const PhaseCFG &_cfg; // Basic blocks
- LRG_List &_names; // Mapping from Nodes to live ranges
+ const LRG_List &_names; // Mapping from Nodes to live ranges
uint _maxlrg; // Largest live-range number
Arena *_arena;
@@ -91,7 +91,7 @@
void add_liveout( Block *p, IndexSet *lo, VectorSet &first_pass );
public:
- PhaseLive( const PhaseCFG &cfg, LRG_List &names, Arena *arena );
+ PhaseLive(const PhaseCFG &cfg, const LRG_List &names, Arena *arena);
~PhaseLive() {}
// Compute liveness info
void compute(uint maxlrg);
--- a/hotspot/src/share/vm/opto/output.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/opto/output.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1044,21 +1044,6 @@
debug_info->end_non_safepoint(pc_offset);
}
-
-
-// helper for fill_buffer bailout logic
-static void turn_off_compiler(Compile* C) {
- if (CodeCache::largest_free_block() >= CodeCacheMinimumFreeSpace*10) {
- // Do not turn off compilation if a single giant method has
- // blown the code cache size.
- C->record_failure("excessive request to CodeCache");
- } else {
- // Let CompilerBroker disable further compilations.
- C->record_failure("CodeCache is full");
- }
-}
-
-
//------------------------------init_buffer------------------------------------
CodeBuffer* Compile::init_buffer(uint* blk_starts) {
@@ -1158,7 +1143,7 @@
// Have we run out of code space?
if ((cb->blob() == NULL) || (!CompileBroker::should_compile_new_jobs())) {
- turn_off_compiler(this);
+ C->record_failure("CodeCache is full");
return NULL;
}
// Configure the code buffer.
@@ -1476,7 +1461,7 @@
// Verify that there is sufficient space remaining
cb->insts()->maybe_expand_to_ensure_remaining(MAX_inst_size);
if ((cb->blob() == NULL) || (!CompileBroker::should_compile_new_jobs())) {
- turn_off_compiler(this);
+ C->record_failure("CodeCache is full");
return;
}
@@ -1633,7 +1618,7 @@
// One last check for failed CodeBuffer::expand:
if ((cb->blob() == NULL) || (!CompileBroker::should_compile_new_jobs())) {
- turn_off_compiler(this);
+ C->record_failure("CodeCache is full");
return;
}
--- a/hotspot/src/share/vm/opto/parseHelper.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/opto/parseHelper.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -337,19 +337,21 @@
if (!count_invocations()) return;
// Get the Method* node.
- const TypePtr* adr_type = TypeMetadataPtr::make(method());
- Node *method_node = makecon(adr_type);
+ ciMethod* m = method();
+ address counters_adr = m->ensure_method_counters();
- // Load the interpreter_invocation_counter from the Method*.
- int offset = Method::interpreter_invocation_counter_offset_in_bytes();
- Node* adr_node = basic_plus_adr(method_node, method_node, offset);
- Node* cnt = make_load(NULL, adr_node, TypeInt::INT, T_INT, adr_type);
+ Node* ctrl = control();
+ const TypePtr* adr_type = TypeRawPtr::make(counters_adr);
+ Node *counters_node = makecon(adr_type);
+ Node* adr_iic_node = basic_plus_adr(counters_node, counters_node,
+ MethodCounters::interpreter_invocation_counter_offset_in_bytes());
+ Node* cnt = make_load(ctrl, adr_iic_node, TypeInt::INT, T_INT, adr_type);
test_counter_against_threshold(cnt, limit);
// Add one to the counter and store
Node* incr = _gvn.transform(new (C) AddINode(cnt, _gvn.intcon(1)));
- store_to_memory( NULL, adr_node, incr, T_INT, adr_type );
+ store_to_memory( ctrl, adr_iic_node, incr, T_INT, adr_type );
}
//----------------------------method_data_addressing---------------------------
--- a/hotspot/src/share/vm/opto/postaloc.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/opto/postaloc.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -56,7 +56,7 @@
int i;
for( i=0; i < limit; i++ ) {
if( def->is_Proj() && def->in(0)->is_Start() &&
- _matcher.is_save_on_entry(lrgs(n2lidx(def)).reg()) )
+ _matcher.is_save_on_entry(lrgs(_lrg_map.live_range_id(def)).reg()))
return true; // Direct use of callee-save proj
if( def->is_Copy() ) // Copies carry value through
def = def->in(def->is_Copy());
@@ -83,7 +83,7 @@
// Count 1 if deleting an instruction from the current block
if( oldb == current_block ) blk_adjust++;
_cfg._bbs.map(old->_idx,NULL);
- OptoReg::Name old_reg = lrgs(n2lidx(old)).reg();
+ OptoReg::Name old_reg = lrgs(_lrg_map.live_range_id(old)).reg();
if( regnd && (*regnd)[old_reg]==old ) { // Instruction is currently available?
value->map(old_reg,NULL); // Yank from value/regnd maps
regnd->map(old_reg,NULL); // This register's value is now unknown
@@ -164,7 +164,7 @@
// Not every pair of physical registers are assignment compatible,
// e.g. on sparc floating point registers are not assignable to integer
// registers.
- const LRG &def_lrg = lrgs(n2lidx(def));
+ const LRG &def_lrg = lrgs(_lrg_map.live_range_id(def));
OptoReg::Name def_reg = def_lrg.reg();
const RegMask &use_mask = n->in_RegMask(idx);
bool can_use = ( RegMask::can_represent(def_reg) ? (use_mask.Member(def_reg) != 0)
@@ -209,11 +209,12 @@
// Skip through any number of copies (that don't mod oop-i-ness)
Node *PhaseChaitin::skip_copies( Node *c ) {
int idx = c->is_Copy();
- uint is_oop = lrgs(n2lidx(c))._is_oop;
+ uint is_oop = lrgs(_lrg_map.live_range_id(c))._is_oop;
while (idx != 0) {
guarantee(c->in(idx) != NULL, "must not resurrect dead copy");
- if (lrgs(n2lidx(c->in(idx)))._is_oop != is_oop)
+ if (lrgs(_lrg_map.live_range_id(c->in(idx)))._is_oop != is_oop) {
break; // casting copy, not the same value
+ }
c = c->in(idx);
idx = c->is_Copy();
}
@@ -225,8 +226,8 @@
int PhaseChaitin::elide_copy( Node *n, int k, Block *current_block, Node_List &value, Node_List ®nd, bool can_change_regs ) {
int blk_adjust = 0;
- uint nk_idx = n2lidx(n->in(k));
- OptoReg::Name nk_reg = lrgs(nk_idx ).reg();
+ uint nk_idx = _lrg_map.live_range_id(n->in(k));
+ OptoReg::Name nk_reg = lrgs(nk_idx).reg();
// Remove obvious same-register copies
Node *x = n->in(k);
@@ -234,9 +235,13 @@
while( (idx=x->is_Copy()) != 0 ) {
Node *copy = x->in(idx);
guarantee(copy != NULL, "must not resurrect dead copy");
- if( lrgs(n2lidx(copy)).reg() != nk_reg ) break;
+ if(lrgs(_lrg_map.live_range_id(copy)).reg() != nk_reg) {
+ break;
+ }
blk_adjust += use_prior_register(n,k,copy,current_block,value,regnd);
- if( n->in(k) != copy ) break; // Failed for some cutout?
+ if (n->in(k) != copy) {
+ break; // Failed for some cutout?
+ }
x = copy; // Progress, try again
}
@@ -256,7 +261,7 @@
if (val == x && nk_idx != 0 &&
regnd[nk_reg] != NULL && regnd[nk_reg] != x &&
- n2lidx(x) == n2lidx(regnd[nk_reg])) {
+ _lrg_map.live_range_id(x) == _lrg_map.live_range_id(regnd[nk_reg])) {
// When rematerialzing nodes and stretching lifetimes, the
// allocator will reuse the original def for multidef LRG instead
// of the current reaching def because it can't know it's safe to
@@ -270,7 +275,7 @@
if (val == x) return blk_adjust; // No progress?
int n_regs = RegMask::num_registers(val->ideal_reg());
- uint val_idx = n2lidx(val);
+ uint val_idx = _lrg_map.live_range_id(val);
OptoReg::Name val_reg = lrgs(val_idx).reg();
// See if it happens to already be in the correct register!
@@ -499,12 +504,12 @@
for( j = 1; j < phi_dex; j++ ) {
uint k;
Node *phi = b->_nodes[j];
- uint pidx = n2lidx(phi);
- OptoReg::Name preg = lrgs(n2lidx(phi)).reg();
+ uint pidx = _lrg_map.live_range_id(phi);
+ OptoReg::Name preg = lrgs(_lrg_map.live_range_id(phi)).reg();
// Remove copies remaining on edges. Check for junk phi.
Node *u = NULL;
- for( k=1; k<phi->req(); k++ ) {
+ for (k = 1; k < phi->req(); k++) {
Node *x = phi->in(k);
if( phi != x && u != x ) // Found a different input
u = u ? NodeSentinel : x; // Capture unique input, or NodeSentinel for 2nd input
@@ -555,10 +560,10 @@
// alive and well at the use (or else the allocator fubar'd). Take
// advantage of this info to set a reaching def for the use-reg.
uint k;
- for( k = 1; k < n->req(); k++ ) {
+ for (k = 1; k < n->req(); k++) {
Node *def = n->in(k); // n->in(k) is a USE; def is the DEF for this USE
guarantee(def != NULL, "no disconnected nodes at this point");
- uint useidx = n2lidx(def); // useidx is the live range index for this USE
+ uint useidx = _lrg_map.live_range_id(def); // useidx is the live range index for this USE
if( useidx ) {
OptoReg::Name ureg = lrgs(useidx).reg();
@@ -566,7 +571,7 @@
int idx; // Skip occasional useless copy
while( (idx=def->is_Copy()) != 0 &&
def->in(idx) != NULL && // NULL should not happen
- ureg == lrgs(n2lidx(def->in(idx))).reg() )
+ ureg == lrgs(_lrg_map.live_range_id(def->in(idx))).reg())
def = def->in(idx);
Node *valdef = skip_copies(def); // tighten up val through non-useless copies
value.map(ureg,valdef); // record improved reaching-def info
@@ -594,8 +599,10 @@
j -= elide_copy( n, k, b, value, regnd, two_adr!=k );
// Unallocated Nodes define no registers
- uint lidx = n2lidx(n);
- if( !lidx ) continue;
+ uint lidx = _lrg_map.live_range_id(n);
+ if (!lidx) {
+ continue;
+ }
// Update the register defined by this instruction
OptoReg::Name nreg = lrgs(lidx).reg();
--- a/hotspot/src/share/vm/opto/reg_split.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/opto/reg_split.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -318,9 +318,13 @@
for( uint i = 1; i < def->req(); i++ ) {
Node *in = def->in(i);
// Check for single-def (LRG cannot redefined)
- uint lidx = n2lidx(in);
- if( lidx >= _maxlrg ) continue; // Value is a recent spill-copy
- if (lrgs(lidx).is_singledef()) continue;
+ uint lidx = _lrg_map.live_range_id(in);
+ if (lidx >= _lrg_map.max_lrg_id()) {
+ continue; // Value is a recent spill-copy
+ }
+ if (lrgs(lidx).is_singledef()) {
+ continue;
+ }
Block *b_def = _cfg._bbs[def->_idx];
int idx_def = b_def->find_node(def);
@@ -344,26 +348,28 @@
if( spill->req() > 1 ) {
for( uint i = 1; i < spill->req(); i++ ) {
Node *in = spill->in(i);
- uint lidx = Find_id(in);
+ uint lidx = _lrg_map.find_id(in);
// Walk backwards thru spill copy node intermediates
if (walkThru) {
- while ( in->is_SpillCopy() && lidx >= _maxlrg ) {
+ while (in->is_SpillCopy() && lidx >= _lrg_map.max_lrg_id()) {
in = in->in(1);
- lidx = Find_id(in);
+ lidx = _lrg_map.find_id(in);
}
- if (lidx < _maxlrg && lrgs(lidx).is_multidef()) {
+ if (lidx < _lrg_map.max_lrg_id() && lrgs(lidx).is_multidef()) {
// walkThru found a multidef LRG, which is unsafe to use, so
// just keep the original def used in the clone.
in = spill->in(i);
- lidx = Find_id(in);
+ lidx = _lrg_map.find_id(in);
}
}
- if( lidx < _maxlrg && lrgs(lidx).reg() >= LRG::SPILL_REG ) {
+ if (lidx < _lrg_map.max_lrg_id() && lrgs(lidx).reg() >= LRG::SPILL_REG) {
Node *rdef = Reachblock[lrg2reach[lidx]];
- if( rdef ) spill->set_req(i,rdef);
+ if (rdef) {
+ spill->set_req(i, rdef);
+ }
}
}
}
@@ -382,7 +388,7 @@
#endif
// See if the cloned def kills any flags, and copy those kills as well
uint i = insidx+1;
- if( clone_projs( b, i, def, spill, maxlrg ) ) {
+ if( clone_projs( b, i, def, spill, maxlrg) ) {
// Adjust the point where we go hi-pressure
if( i <= b->_ihrp_index ) b->_ihrp_index++;
if( i <= b->_fhrp_index ) b->_fhrp_index++;
@@ -424,17 +430,25 @@
//------------------------------prompt_use---------------------------------
// True if lidx is used before any real register is def'd in the block
bool PhaseChaitin::prompt_use( Block *b, uint lidx ) {
- if( lrgs(lidx)._was_spilled2 ) return false;
+ if (lrgs(lidx)._was_spilled2) {
+ return false;
+ }
// Scan block for 1st use.
for( uint i = 1; i <= b->end_idx(); i++ ) {
Node *n = b->_nodes[i];
// Ignore PHI use, these can be up or down
- if( n->is_Phi() ) continue;
- for( uint j = 1; j < n->req(); j++ )
- if( Find_id(n->in(j)) == lidx )
+ if (n->is_Phi()) {
+ continue;
+ }
+ for (uint j = 1; j < n->req(); j++) {
+ if (_lrg_map.find_id(n->in(j)) == lidx) {
return true; // Found 1st use!
- if( n->out_RegMask().is_NotEmpty() ) return false;
+ }
+ }
+ if (n->out_RegMask().is_NotEmpty()) {
+ return false;
+ }
}
return false;
}
@@ -464,23 +478,23 @@
bool u1, u2, u3;
Block *b, *pred;
PhiNode *phi;
- GrowableArray<uint> lidxs(split_arena, _maxlrg, 0, 0);
+ GrowableArray<uint> lidxs(split_arena, maxlrg, 0, 0);
// Array of counters to count splits per live range
- GrowableArray<uint> splits(split_arena, _maxlrg, 0, 0);
+ GrowableArray<uint> splits(split_arena, maxlrg, 0, 0);
#define NEW_SPLIT_ARRAY(type, size)\
(type*) split_arena->allocate_bytes((size) * sizeof(type))
//----------Setup Code----------
// Create a convenient mapping from lrg numbers to reaches/leaves indices
- uint *lrg2reach = NEW_SPLIT_ARRAY( uint, _maxlrg );
+ uint *lrg2reach = NEW_SPLIT_ARRAY(uint, maxlrg);
// Keep track of DEFS & Phis for later passes
defs = new Node_List();
phis = new Node_List();
// Gather info on which LRG's are spilling, and build maps
- for( bidx = 1; bidx < _maxlrg; bidx++ ) {
- if( lrgs(bidx).alive() && lrgs(bidx).reg() >= LRG::SPILL_REG ) {
+ for (bidx = 1; bidx < maxlrg; bidx++) {
+ if (lrgs(bidx).alive() && lrgs(bidx).reg() >= LRG::SPILL_REG) {
assert(!lrgs(bidx).mask().is_AllStack(),"AllStack should color");
lrg2reach[bidx] = spill_cnt;
spill_cnt++;
@@ -629,7 +643,7 @@
break;
}
// must be looking at a phi
- if( Find_id(n1) == lidxs.at(slidx) ) {
+ if (_lrg_map.find_id(n1) == lidxs.at(slidx)) {
// found the necessary phi
needs_phi = false;
has_phi = true;
@@ -651,11 +665,11 @@
Reachblock[slidx] = phi;
// add node to block & node_to_block mapping
- insert_proj( b, insidx++, phi, maxlrg++ );
+ insert_proj(b, insidx++, phi, maxlrg++);
non_phi++;
// Reset new phi's mapping to be the spilling live range
- _names.map(phi->_idx, lidx);
- assert(Find_id(phi) == lidx,"Bad update on Union-Find mapping");
+ _lrg_map.map(phi->_idx, lidx);
+ assert(_lrg_map.find_id(phi) == lidx, "Bad update on Union-Find mapping");
} // end if not found correct phi
// Here you have either found or created the Phi, so record it
assert(phi != NULL,"Must have a Phi Node here");
@@ -721,12 +735,12 @@
for( insidx = 1; insidx <= b->end_idx(); insidx++ ) {
Node *n = b->_nodes[insidx];
// Find the defining Node's live range index
- uint defidx = Find_id(n);
+ uint defidx = _lrg_map.find_id(n);
uint cnt = n->req();
- if( n->is_Phi() ) {
+ if (n->is_Phi()) {
// Skip phi nodes after removing dead copies.
- if( defidx < _maxlrg ) {
+ if (defidx < _lrg_map.max_lrg_id()) {
// Check for useless Phis. These appear if we spill, then
// coalesce away copies. Dont touch Phis in spilling live
// ranges; they are busy getting modifed in this pass.
@@ -744,8 +758,8 @@
}
}
assert( u, "at least 1 valid input expected" );
- if( i >= cnt ) { // Found one unique input
- assert(Find_id(n) == Find_id(u), "should be the same lrg");
+ if (i >= cnt) { // Found one unique input
+ assert(_lrg_map.find_id(n) == _lrg_map.find_id(u), "should be the same lrg");
n->replace_by(u); // Then replace with unique input
n->disconnect_inputs(NULL, C);
b->_nodes.remove(insidx);
@@ -793,16 +807,24 @@
while( insert_point > 0 ) {
Node *n = b->_nodes[insert_point];
// Hit top of block? Quit going backwards
- if( n->is_Phi() ) break;
+ if (n->is_Phi()) {
+ break;
+ }
// Found a def? Better split after it.
- if( n2lidx(n) == lidx ) break;
+ if (_lrg_map.live_range_id(n) == lidx) {
+ break;
+ }
// Look for a use
uint i;
- for( i = 1; i < n->req(); i++ )
- if( n2lidx(n->in(i)) == lidx )
+ for( i = 1; i < n->req(); i++ ) {
+ if (_lrg_map.live_range_id(n->in(i)) == lidx) {
break;
+ }
+ }
// Found a use? Better split after it.
- if( i < n->req() ) break;
+ if (i < n->req()) {
+ break;
+ }
insert_point--;
}
uint orig_eidx = b->end_idx();
@@ -812,8 +834,9 @@
return 0;
}
// Spill of NULL check mem op goes into the following block.
- if (b->end_idx() > orig_eidx)
+ if (b->end_idx() > orig_eidx) {
insidx++;
+ }
}
// This is a new DEF, so update UP
UPblock[slidx] = false;
@@ -832,13 +855,13 @@
} // end if crossing HRP Boundry
// If the LRG index is oob, then this is a new spillcopy, skip it.
- if( defidx >= _maxlrg ) {
+ if (defidx >= _lrg_map.max_lrg_id()) {
continue;
}
LRG &deflrg = lrgs(defidx);
uint copyidx = n->is_Copy();
// Remove coalesced copy from CFG
- if( copyidx && defidx == n2lidx(n->in(copyidx)) ) {
+ if (copyidx && defidx == _lrg_map.live_range_id(n->in(copyidx))) {
n->replace_by( n->in(copyidx) );
n->set_req( copyidx, NULL );
b->_nodes.remove(insidx--);
@@ -864,13 +887,13 @@
// If inpidx > old_last, then one of these new inputs is being
// handled. Skip the derived part of the pair, but process
// the base like any other input.
- if( inpidx > old_last && ((inpidx - oopoff) & 1) == DERIVED ) {
+ if (inpidx > old_last && ((inpidx - oopoff) & 1) == DERIVED) {
continue; // skip derived_debug added below
}
// Get lidx of input
- uint useidx = Find_id(n->in(inpidx));
+ uint useidx = _lrg_map.find_id(n->in(inpidx));
// Not a brand-new split, and it is a spill use
- if( useidx < _maxlrg && lrgs(useidx).reg() >= LRG::SPILL_REG ) {
+ if (useidx < _lrg_map.max_lrg_id() && lrgs(useidx).reg() >= LRG::SPILL_REG) {
// Check for valid reaching DEF
slidx = lrg2reach[useidx];
Node *def = Reachblock[slidx];
@@ -886,7 +909,7 @@
if (def == NULL || C->check_node_count(NodeLimitFudgeFactor, out_of_nodes)) {
return 0;
}
- _names.extend(def->_idx,0);
+ _lrg_map.extend(def->_idx, 0);
_cfg._bbs.map(def->_idx,b);
n->set_req(inpidx, def);
continue;
@@ -1186,10 +1209,10 @@
// ********** Split Left Over Mem-Mem Moves **********
// Check for mem-mem copies and split them now. Do not do this
// to copies about to be spilled; they will be Split shortly.
- if( copyidx ) {
+ if (copyidx) {
Node *use = n->in(copyidx);
- uint useidx = Find_id(use);
- if( useidx < _maxlrg && // This is not a new split
+ uint useidx = _lrg_map.find_id(use);
+ if (useidx < _lrg_map.max_lrg_id() && // This is not a new split
OptoReg::is_stack(deflrg.reg()) &&
deflrg.reg() < LRG::SPILL_REG ) { // And DEF is from stack
LRG &uselrg = lrgs(useidx);
@@ -1228,7 +1251,7 @@
uint member;
IndexSetIterator isi(liveout);
while ((member = isi.next()) != 0) {
- assert(defidx != Find_const(member), "Live out member has not been compressed");
+ assert(defidx != _lrg_map.find_const(member), "Live out member has not been compressed");
}
#endif
Reachblock[slidx] = NULL;
@@ -1261,7 +1284,7 @@
assert(phi->is_Phi(),"This list must only contain Phi Nodes");
Block *b = _cfg._bbs[phi->_idx];
// Grab the live range number
- uint lidx = Find_id(phi);
+ uint lidx = _lrg_map.find_id(phi);
uint slidx = lrg2reach[lidx];
// Update node to lidx map
new_lrg(phi, maxlrg++);
@@ -1296,11 +1319,13 @@
int insert = pred->end_idx();
while (insert >= 1 &&
pred->_nodes[insert - 1]->is_SpillCopy() &&
- Find(pred->_nodes[insert - 1]) >= lrgs_before_phi_split) {
+ _lrg_map.find(pred->_nodes[insert - 1]) >= lrgs_before_phi_split) {
insert--;
}
- def = split_Rematerialize( def, pred, insert, maxlrg, splits, slidx, lrg2reach, Reachblock, false );
- if( !def ) return 0; // Bail out
+ def = split_Rematerialize(def, pred, insert, maxlrg, splits, slidx, lrg2reach, Reachblock, false);
+ if (!def) {
+ return 0; // Bail out
+ }
}
// Update the Phi's input edge array
phi->set_req(i,def);
@@ -1316,7 +1341,7 @@
} // End for all inputs to the Phi
} // End for all Phi Nodes
// Update _maxlrg to save Union asserts
- _maxlrg = maxlrg;
+ _lrg_map.set_max_lrg_id(maxlrg);
//----------PASS 3----------
@@ -1328,47 +1353,51 @@
for( uint i = 1; i < phi->req(); i++ ) {
// Grab the input node
Node *n = phi->in(i);
- assert( n, "" );
- uint lidx = Find(n);
- uint pidx = Find(phi);
- if( lidx < pidx )
+ assert(n, "node should exist");
+ uint lidx = _lrg_map.find(n);
+ uint pidx = _lrg_map.find(phi);
+ if (lidx < pidx) {
Union(n, phi);
- else if( lidx > pidx )
+ }
+ else if(lidx > pidx) {
Union(phi, n);
+ }
} // End for all inputs to the Phi Node
} // End for all Phi Nodes
// Now union all two address instructions
- for( insidx = 0; insidx < defs->size(); insidx++ ) {
+ for (insidx = 0; insidx < defs->size(); insidx++) {
// Grab the def
n1 = defs->at(insidx);
// Set new lidx for DEF & handle 2-addr instructions
- if( n1->is_Mach() && ((twoidx = n1->as_Mach()->two_adr()) != 0) ) {
- assert( Find(n1->in(twoidx)) < maxlrg,"Assigning bad live range index");
+ if (n1->is_Mach() && ((twoidx = n1->as_Mach()->two_adr()) != 0)) {
+ assert(_lrg_map.find(n1->in(twoidx)) < maxlrg,"Assigning bad live range index");
// Union the input and output live ranges
- uint lr1 = Find(n1);
- uint lr2 = Find(n1->in(twoidx));
- if( lr1 < lr2 )
+ uint lr1 = _lrg_map.find(n1);
+ uint lr2 = _lrg_map.find(n1->in(twoidx));
+ if (lr1 < lr2) {
Union(n1, n1->in(twoidx));
- else if( lr1 > lr2 )
+ }
+ else if (lr1 > lr2) {
Union(n1->in(twoidx), n1);
+ }
} // End if two address
} // End for all defs
// DEBUG
#ifdef ASSERT
// Validate all live range index assignments
- for( bidx = 0; bidx < _cfg._num_blocks; bidx++ ) {
+ for (bidx = 0; bidx < _cfg._num_blocks; bidx++) {
b = _cfg._blocks[bidx];
- for( insidx = 0; insidx <= b->end_idx(); insidx++ ) {
+ for (insidx = 0; insidx <= b->end_idx(); insidx++) {
Node *n = b->_nodes[insidx];
- uint defidx = Find(n);
- assert(defidx < _maxlrg,"Bad live range index in Split");
+ uint defidx = _lrg_map.find(n);
+ assert(defidx < _lrg_map.max_lrg_id(), "Bad live range index in Split");
assert(defidx < maxlrg,"Bad live range index in Split");
}
}
// Issue a warning if splitting made no progress
int noprogress = 0;
- for( slidx = 0; slidx < spill_cnt; slidx++ ) {
- if( PrintOpto && WizardMode && splits.at(slidx) == 0 ) {
+ for (slidx = 0; slidx < spill_cnt; slidx++) {
+ if (PrintOpto && WizardMode && splits.at(slidx) == 0) {
tty->print_cr("Failed to split live range %d", lidxs.at(slidx));
//BREAKPOINT;
}
--- a/hotspot/src/share/vm/opto/regalloc.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/opto/regalloc.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -113,7 +113,7 @@
OptoReg::Name offset2reg( int stk_offset ) const;
// Get the register encoding associated with the Node
- int get_encode( const Node *n ) const {
+ int get_encode(const Node *n) const {
assert( n->_idx < _node_regs_max_index, "Exceeded _node_regs array");
OptoReg::Name first = _node_regs[n->_idx].first();
OptoReg::Name second = _node_regs[n->_idx].second();
@@ -122,15 +122,6 @@
return Matcher::_regEncode[first];
}
- // Platform dependent hook for actions prior to allocation
- void pd_preallocate_hook();
-
-#ifdef ASSERT
- // Platform dependent hook for verification after allocation. Will
- // only get called when compiling with asserts.
- void pd_postallocate_verify_hook();
-#endif
-
#ifndef PRODUCT
static int _total_framesize;
static int _max_framesize;
--- a/hotspot/src/share/vm/prims/whitebox.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/prims/whitebox.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -237,10 +237,10 @@
WB_END
-WB_ENTRY(void, WB_MakeMethodNotCompilable(JNIEnv* env, jobject o, jobject method))
+WB_ENTRY(void, WB_MakeMethodNotCompilable(JNIEnv* env, jobject o, jobject method, jint comp_level))
jmethodID jmid = reflected_method_to_jmid(thread, env, method);
methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
- mh->set_not_compilable();
+ mh->set_not_compilable(comp_level, true /* report */, "WhiteBox");
WB_END
WB_ENTRY(jboolean, WB_TestSetDontInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value))
@@ -278,6 +278,7 @@
methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
MutexLockerEx mu(Compile_lock);
MethodData* mdo = mh->method_data();
+ MethodCounters* mcs = mh->method_counters();
if (mdo != NULL) {
mdo->init();
@@ -288,20 +289,22 @@
}
}
- mh->backedge_counter()->init();
- mh->invocation_counter()->init();
- mh->set_interpreter_invocation_count(0);
- mh->set_interpreter_throwout_count(0);
mh->clear_not_c1_compilable();
mh->clear_not_c2_compilable();
mh->clear_not_c2_osr_compilable();
NOT_PRODUCT(mh->set_compiled_invocation_count(0));
+ if (mcs != NULL) {
+ mcs->backedge_counter()->init();
+ mcs->invocation_counter()->init();
+ mcs->set_interpreter_invocation_count(0);
+ mcs->set_interpreter_throwout_count(0);
#ifdef TIERED
- mh->set_rate(0.0F);
- mh->set_prev_event_count(0);
- mh->set_prev_time(0);
+ mcs->set_rate(0.0F);
+ mh->set_prev_event_count(0, THREAD);
+ mh->set_prev_time(0, THREAD);
#endif
+ }
WB_END
WB_ENTRY(jboolean, WB_IsInStringTable(JNIEnv* env, jobject o, jstring javaString))
@@ -398,28 +401,28 @@
{CC"NMTWaitForDataMerge", CC"()Z", (void*)&WB_NMTWaitForDataMerge},
#endif // INCLUDE_NMT
{CC"deoptimizeAll", CC"()V", (void*)&WB_DeoptimizeAll },
- {CC"deoptimizeMethod", CC"(Ljava/lang/reflect/Method;)I",
+ {CC"deoptimizeMethod", CC"(Ljava/lang/reflect/Executable;)I",
(void*)&WB_DeoptimizeMethod },
- {CC"isMethodCompiled", CC"(Ljava/lang/reflect/Method;)Z",
+ {CC"isMethodCompiled", CC"(Ljava/lang/reflect/Executable;)Z",
(void*)&WB_IsMethodCompiled },
- {CC"isMethodCompilable", CC"(Ljava/lang/reflect/Method;I)Z",
+ {CC"isMethodCompilable", CC"(Ljava/lang/reflect/Executable;I)Z",
(void*)&WB_IsMethodCompilable},
{CC"isMethodQueuedForCompilation",
- CC"(Ljava/lang/reflect/Method;)Z", (void*)&WB_IsMethodQueuedForCompilation},
+ CC"(Ljava/lang/reflect/Executable;)Z", (void*)&WB_IsMethodQueuedForCompilation},
{CC"makeMethodNotCompilable",
- CC"(Ljava/lang/reflect/Method;)V", (void*)&WB_MakeMethodNotCompilable},
+ CC"(Ljava/lang/reflect/Executable;I)V", (void*)&WB_MakeMethodNotCompilable},
{CC"testSetDontInlineMethod",
- CC"(Ljava/lang/reflect/Method;Z)Z", (void*)&WB_TestSetDontInlineMethod},
+ CC"(Ljava/lang/reflect/Executable;Z)Z", (void*)&WB_TestSetDontInlineMethod},
{CC"getMethodCompilationLevel",
- CC"(Ljava/lang/reflect/Method;)I", (void*)&WB_GetMethodCompilationLevel},
+ CC"(Ljava/lang/reflect/Executable;)I", (void*)&WB_GetMethodCompilationLevel},
{CC"getCompileQueuesSize",
CC"()I", (void*)&WB_GetCompileQueuesSize},
{CC"testSetForceInlineMethod",
- CC"(Ljava/lang/reflect/Method;Z)Z", (void*)&WB_TestSetForceInlineMethod},
+ CC"(Ljava/lang/reflect/Executable;Z)Z", (void*)&WB_TestSetForceInlineMethod},
{CC"enqueueMethodForCompilation",
- CC"(Ljava/lang/reflect/Method;I)Z", (void*)&WB_EnqueueMethodForCompilation},
+ CC"(Ljava/lang/reflect/Executable;I)Z", (void*)&WB_EnqueueMethodForCompilation},
{CC"clearMethodState",
- CC"(Ljava/lang/reflect/Method;)V", (void*)&WB_ClearMethodState},
+ CC"(Ljava/lang/reflect/Executable;)V", (void*)&WB_ClearMethodState},
{CC"isInStringTable", CC"(Ljava/lang/String;)Z", (void*)&WB_IsInStringTable },
{CC"fullGC", CC"()V", (void*)&WB_FullGC },
};
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -74,10 +74,11 @@
// update_rate() is called from select_task() while holding a compile queue lock.
void AdvancedThresholdPolicy::update_rate(jlong t, Method* m) {
+ JavaThread* THREAD = JavaThread::current();
if (is_old(m)) {
// We don't remove old methods from the queue,
// so we can just zero the rate.
- m->set_rate(0);
+ m->set_rate(0, THREAD);
return;
}
@@ -93,13 +94,13 @@
if (delta_s >= TieredRateUpdateMinTime) {
// And we must've taken the previous point at least 1ms before.
if (delta_t >= TieredRateUpdateMinTime && delta_e > 0) {
- m->set_prev_time(t);
- m->set_prev_event_count(event_count);
- m->set_rate((float)delta_e / (float)delta_t); // Rate is events per millisecond
+ m->set_prev_time(t, THREAD);
+ m->set_prev_event_count(event_count, THREAD);
+ m->set_rate((float)delta_e / (float)delta_t, THREAD); // Rate is events per millisecond
} else
if (delta_t > TieredRateUpdateMaxTime && delta_e == 0) {
// If nothing happened for 25ms, zero the rate. Don't modify prev values.
- m->set_rate(0);
+ m->set_rate(0, THREAD);
}
}
}
--- a/hotspot/src/share/vm/runtime/compilationPolicy.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/runtime/compilationPolicy.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -198,8 +198,10 @@
// BUT also make sure the method doesn't look like it was never executed.
// Set carry bit and reduce counter's value to min(count, CompileThreshold/2).
- m->invocation_counter()->set_carry();
- m->backedge_counter()->set_carry();
+ MethodCounters* mcs = m->method_counters();
+ assert(mcs != NULL, "MethodCounters cannot be NULL for profiling");
+ mcs->invocation_counter()->set_carry();
+ mcs->backedge_counter()->set_carry();
assert(!m->was_never_executed(), "don't reset to 0 -- could be mistaken for never-executed");
}
@@ -207,8 +209,10 @@
void NonTieredCompPolicy::reset_counter_for_back_branch_event(methodHandle m) {
// Delay next back-branch event but pump up invocation counter to triger
// whole method compilation.
- InvocationCounter* i = m->invocation_counter();
- InvocationCounter* b = m->backedge_counter();
+ MethodCounters* mcs = m->method_counters();
+ assert(mcs != NULL, "MethodCounters cannot be NULL for profiling");
+ InvocationCounter* i = mcs->invocation_counter();
+ InvocationCounter* b = mcs->backedge_counter();
// Don't set invocation_counter's value too low otherwise the method will
// look like immature (ic < ~5300) which prevents the inlining based on
@@ -227,7 +231,10 @@
class CounterDecay : public AllStatic {
static jlong _last_timestamp;
static void do_method(Method* m) {
- m->invocation_counter()->decay();
+ MethodCounters* mcs = m->method_counters();
+ if (mcs != NULL) {
+ mcs->invocation_counter()->decay();
+ }
}
public:
static void decay();
@@ -265,30 +272,44 @@
void NonTieredCompPolicy::reprofile(ScopeDesc* trap_scope, bool is_osr) {
ScopeDesc* sd = trap_scope;
+ MethodCounters* mcs;
+ InvocationCounter* c;
for (; !sd->is_top(); sd = sd->sender()) {
- // Reset ICs of inlined methods, since they can trigger compilations also.
- sd->method()->invocation_counter()->reset();
+ mcs = sd->method()->method_counters();
+ if (mcs != NULL) {
+ // Reset ICs of inlined methods, since they can trigger compilations also.
+ mcs->invocation_counter()->reset();
+ }
}
- InvocationCounter* c = sd->method()->invocation_counter();
- if (is_osr) {
- // It was an OSR method, so bump the count higher.
- c->set(c->state(), CompileThreshold);
- } else {
- c->reset();
+ mcs = sd->method()->method_counters();
+ if (mcs != NULL) {
+ c = mcs->invocation_counter();
+ if (is_osr) {
+ // It was an OSR method, so bump the count higher.
+ c->set(c->state(), CompileThreshold);
+ } else {
+ c->reset();
+ }
+ mcs->backedge_counter()->reset();
}
- sd->method()->backedge_counter()->reset();
}
// This method can be called by any component of the runtime to notify the policy
// that it's recommended to delay the complation of this method.
void NonTieredCompPolicy::delay_compilation(Method* method) {
- method->invocation_counter()->decay();
- method->backedge_counter()->decay();
+ MethodCounters* mcs = method->method_counters();
+ if (mcs != NULL) {
+ mcs->invocation_counter()->decay();
+ mcs->backedge_counter()->decay();
+ }
}
void NonTieredCompPolicy::disable_compilation(Method* method) {
- method->invocation_counter()->set_state(InvocationCounter::wait_for_nothing);
- method->backedge_counter()->set_state(InvocationCounter::wait_for_nothing);
+ MethodCounters* mcs = method->method_counters();
+ if (mcs != NULL) {
+ mcs->invocation_counter()->set_state(InvocationCounter::wait_for_nothing);
+ mcs->backedge_counter()->set_state(InvocationCounter::wait_for_nothing);
+ }
}
CompileTask* NonTieredCompPolicy::select_task(CompileQueue* compile_queue) {
@@ -371,8 +392,10 @@
#ifndef PRODUCT
void NonTieredCompPolicy::trace_frequency_counter_overflow(methodHandle m, int branch_bci, int bci) {
if (TraceInvocationCounterOverflow) {
- InvocationCounter* ic = m->invocation_counter();
- InvocationCounter* bc = m->backedge_counter();
+ MethodCounters* mcs = m->method_counters();
+ assert(mcs != NULL, "MethodCounters cannot be NULL for profiling");
+ InvocationCounter* ic = mcs->invocation_counter();
+ InvocationCounter* bc = mcs->backedge_counter();
ResourceMark rm;
const char* msg =
bci == InvocationEntryBci
--- a/hotspot/src/share/vm/runtime/fprofiler.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/runtime/fprofiler.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -421,7 +421,8 @@
void print_method_on(outputStream* st) {
ProfilerNode::print_method_on(st);
- if (Verbose) method()->invocation_counter()->print_short();
+ MethodCounters* mcs = method()->method_counters();
+ if (Verbose && mcs != NULL) mcs->invocation_counter()->print_short();
}
};
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -153,8 +153,10 @@
// Set carry flags on the counters if necessary
void SimpleThresholdPolicy::handle_counter_overflow(Method* method) {
- set_carry_if_necessary(method->invocation_counter());
- set_carry_if_necessary(method->backedge_counter());
+ MethodCounters *mcs = method->method_counters();
+ assert(mcs != NULL, "");
+ set_carry_if_necessary(mcs->invocation_counter());
+ set_carry_if_necessary(mcs->backedge_counter());
MethodData* mdo = method->method_data();
if (mdo != NULL) {
set_carry_if_necessary(mdo->invocation_counter());
--- a/hotspot/src/share/vm/runtime/thread.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/runtime/thread.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -1056,11 +1056,11 @@
#if INCLUDE_NMT
// native memory tracking
inline MemRecorder* get_recorder() const { return (MemRecorder*)_recorder; }
- inline void set_recorder(MemRecorder* rc) { _recorder = (volatile MemRecorder*)rc; }
+ inline void set_recorder(MemRecorder* rc) { _recorder = rc; }
private:
// per-thread memory recorder
- volatile MemRecorder* _recorder;
+ MemRecorder* volatile _recorder;
#endif // INCLUDE_NMT
// Suspend/resume support for JavaThread
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -77,6 +77,7 @@
#include "oops/klass.hpp"
#include "oops/markOop.hpp"
#include "oops/methodData.hpp"
+#include "oops/methodCounters.hpp"
#include "oops/method.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.hpp"
@@ -348,16 +349,17 @@
nonstatic_field(MethodData, _arg_local, intx) \
nonstatic_field(MethodData, _arg_stack, intx) \
nonstatic_field(MethodData, _arg_returned, intx) \
- nonstatic_field(Method, _constMethod, ConstMethod*) \
- nonstatic_field(Method, _method_data, MethodData*) \
- nonstatic_field(Method, _interpreter_invocation_count, int) \
+ nonstatic_field(MethodCounters, _interpreter_invocation_count, int) \
+ nonstatic_field(MethodCounters, _interpreter_throwout_count, u2) \
+ nonstatic_field(MethodCounters, _number_of_breakpoints, u2) \
+ nonstatic_field(MethodCounters, _invocation_counter, InvocationCounter) \
+ nonstatic_field(MethodCounters, _backedge_counter, InvocationCounter) \
+ nonstatic_field(Method, _constMethod, ConstMethod*) \
+ nonstatic_field(Method, _method_data, MethodData*) \
+ nonstatic_field(Method, _method_counters, MethodCounters*) \
nonstatic_field(Method, _access_flags, AccessFlags) \
nonstatic_field(Method, _vtable_index, int) \
nonstatic_field(Method, _method_size, u2) \
- nonstatic_field(Method, _interpreter_throwout_count, u2) \
- nonstatic_field(Method, _number_of_breakpoints, u2) \
- nonstatic_field(Method, _invocation_counter, InvocationCounter) \
- nonstatic_field(Method, _backedge_counter, InvocationCounter) \
nonproduct_nonstatic_field(Method, _compiled_invocation_count, int) \
volatile_nonstatic_field(Method, _code, nmethod*) \
nonstatic_field(Method, _i2i_entry, address) \
@@ -1115,7 +1117,6 @@
c2_nonstatic_field(PhaseChaitin, _lo_stk_degree, uint) \
c2_nonstatic_field(PhaseChaitin, _hi_degree, uint) \
c2_nonstatic_field(PhaseChaitin, _simplified, uint) \
- c2_nonstatic_field(PhaseChaitin, _maxlrg, uint) \
\
c2_nonstatic_field(Block, _nodes, Node_List) \
c2_nonstatic_field(Block, _succs, Block_Array) \
@@ -1382,6 +1383,7 @@
declare_type(ConstantPoolCache, MetaspaceObj) \
declare_type(MethodData, Metadata) \
declare_type(Method, Metadata) \
+ declare_type(MethodCounters, MetaspaceObj) \
declare_type(ConstMethod, MetaspaceObj) \
\
declare_toplevel_type(Symbol) \
--- a/hotspot/src/share/vm/runtime/vmThread.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/runtime/vmThread.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -123,7 +123,7 @@
_queue[prio]->set_next(_queue[prio]);
_queue[prio]->set_prev(_queue[prio]);
assert(queue_empty(prio), "drain corrupted queue");
-#ifdef DEBUG
+#ifdef ASSERT
int len = 0;
VM_Operation* cur;
for(cur = r; cur != NULL; cur=cur->next()) len++;
--- a/hotspot/src/share/vm/services/memTrackWorker.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/services/memTrackWorker.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -39,7 +39,7 @@
}
}
-MemTrackWorker::MemTrackWorker() {
+MemTrackWorker::MemTrackWorker(MemSnapshot* snapshot): _snapshot(snapshot) {
// create thread uses cgc thread type for now. We should revisit
// the option, or create new thread type.
_has_error = !os::create_thread(this, os::cgc_thread);
@@ -88,8 +88,7 @@
assert(MemTracker::is_on(), "native memory tracking is off");
this->initialize_thread_local_storage();
this->record_stack_base_and_size();
- MemSnapshot* snapshot = MemTracker::get_snapshot();
- assert(snapshot != NULL, "Worker should not be started");
+ assert(_snapshot != NULL, "Worker should not be started");
MemRecorder* rec;
unsigned long processing_generation = 0;
bool worker_idle = false;
@@ -109,7 +108,7 @@
}
// merge the recorder into staging area
- if (!snapshot->merge(rec)) {
+ if (!_snapshot->merge(rec)) {
MemTracker::shutdown(MemTracker::NMT_out_of_memory);
} else {
NOT_PRODUCT(_merge_count ++;)
@@ -132,7 +131,7 @@
_head = (_head + 1) % MAX_GENERATIONS;
}
// promote this generation data to snapshot
- if (!snapshot->promote(number_of_classes)) {
+ if (!_snapshot->promote(number_of_classes)) {
// failed to promote, means out of memory
MemTracker::shutdown(MemTracker::NMT_out_of_memory);
}
@@ -140,7 +139,7 @@
// worker thread is idle
worker_idle = true;
MemTracker::report_worker_idle();
- snapshot->wait(1000);
+ _snapshot->wait(1000);
ThreadCritical tc;
// check if more data arrived
if (!_gen[_head].has_more_recorder()) {
--- a/hotspot/src/share/vm/services/memTrackWorker.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/services/memTrackWorker.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -85,8 +85,10 @@
bool _has_error;
+ MemSnapshot* _snapshot;
+
public:
- MemTrackWorker();
+ MemTrackWorker(MemSnapshot* snapshot);
~MemTrackWorker();
_NOINLINE_ void* operator new(size_t size);
_NOINLINE_ void* operator new(size_t size, const std::nothrow_t& nothrow_constant);
--- a/hotspot/src/share/vm/services/memTracker.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/services/memTracker.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -53,12 +53,12 @@
}
-MemRecorder* MemTracker::_global_recorder = NULL;
+MemRecorder* volatile MemTracker::_global_recorder = NULL;
MemSnapshot* MemTracker::_snapshot = NULL;
MemBaseline MemTracker::_baseline;
Mutex* MemTracker::_query_lock = NULL;
-volatile MemRecorder* MemTracker::_merge_pending_queue = NULL;
-volatile MemRecorder* MemTracker::_pooled_recorders = NULL;
+MemRecorder* volatile MemTracker::_merge_pending_queue = NULL;
+MemRecorder* volatile MemTracker::_pooled_recorders = NULL;
MemTrackWorker* MemTracker::_worker_thread = NULL;
int MemTracker::_sync_point_skip_count = 0;
MemTracker::NMTLevel MemTracker::_tracking_level = MemTracker::NMT_off;
@@ -128,7 +128,7 @@
_snapshot = new (std::nothrow)MemSnapshot();
if (_snapshot != NULL) {
- if (!_snapshot->out_of_memory() && start_worker()) {
+ if (!_snapshot->out_of_memory() && start_worker(_snapshot)) {
_state = NMT_started;
NMT_track_callsite = (_tracking_level == NMT_detail && can_walk_stack());
return;
@@ -209,7 +209,7 @@
// delete all pooled recorders
void MemTracker::delete_all_pooled_recorders() {
// free all pooled recorders
- volatile MemRecorder* cur_head = _pooled_recorders;
+ MemRecorder* volatile cur_head = _pooled_recorders;
if (cur_head != NULL) {
MemRecorder* null_ptr = NULL;
while (cur_head != NULL && (void*)cur_head != Atomic::cmpxchg_ptr((void*)null_ptr,
@@ -543,14 +543,14 @@
/*
* Start worker thread.
*/
-bool MemTracker::start_worker() {
- assert(_worker_thread == NULL, "Just Check");
- _worker_thread = new (std::nothrow) MemTrackWorker();
- if (_worker_thread == NULL || _worker_thread->has_error()) {
- if (_worker_thread != NULL) {
- delete _worker_thread;
- _worker_thread = NULL;
- }
+bool MemTracker::start_worker(MemSnapshot* snapshot) {
+ assert(_worker_thread == NULL && _snapshot != NULL, "Just Check");
+ _worker_thread = new (std::nothrow) MemTrackWorker(snapshot);
+ if (_worker_thread == NULL) {
+ return false;
+ } else if (_worker_thread->has_error()) {
+ delete _worker_thread;
+ _worker_thread = NULL;
return false;
}
_worker_thread->start();
--- a/hotspot/src/share/vm/services/memTracker.hpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/services/memTracker.hpp Fri Apr 19 09:58:05 2013 -0700
@@ -421,7 +421,7 @@
private:
// start native memory tracking worker thread
- static bool start_worker();
+ static bool start_worker(MemSnapshot* snapshot);
// called by worker thread to complete shutdown process
static void final_shutdown();
@@ -475,18 +475,18 @@
// a thread can start to allocate memory before it is attached
// to VM 'Thread', those memory activities are recorded here.
// ThreadCritical is required to guard this global recorder.
- static MemRecorder* _global_recorder;
+ static MemRecorder* volatile _global_recorder;
// main thread id
debug_only(static intx _main_thread_tid;)
// pending recorders to be merged
- static volatile MemRecorder* _merge_pending_queue;
+ static MemRecorder* volatile _merge_pending_queue;
NOT_PRODUCT(static volatile jint _pending_recorder_count;)
// pooled memory recorders
- static volatile MemRecorder* _pooled_recorders;
+ static MemRecorder* volatile _pooled_recorders;
// memory recorder pool management, uses following
// counter to determine if a released memory recorder
--- a/hotspot/src/share/vm/services/runtimeService.cpp Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/src/share/vm/services/runtimeService.cpp Fri Apr 19 09:58:05 2013 -0700
@@ -120,6 +120,8 @@
// Print the time interval in which the app was executing
if (PrintGCApplicationConcurrentTime) {
+ gclog_or_tty->date_stamp(PrintGCDateStamps);
+ gclog_or_tty->stamp(PrintGCTimeStamps);
gclog_or_tty->print_cr("Application time: %3.7f seconds",
last_application_time_sec());
}
@@ -150,6 +152,8 @@
// Print the time interval for which the app was stopped
// during the current safepoint operation.
if (PrintGCApplicationStoppedTime) {
+ gclog_or_tty->date_stamp(PrintGCDateStamps);
+ gclog_or_tty->stamp(PrintGCTimeStamps);
gclog_or_tty->print_cr("Total time for which application threads "
"were stopped: %3.7f seconds",
last_safepoint_time_sec());
--- a/hotspot/test/Makefile Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/test/Makefile Fri Apr 19 09:58:05 2013 -0700
@@ -162,7 +162,9 @@
# jtreg tests
# Expect JT_HOME to be set for jtreg tests. (home for jtreg)
-JT_HOME = $(SLASH_JAVA)/re/jtreg/4.0/promoted/latest/binaries/jtreg
+ifndef JT_HOME
+ JT_HOME = $(SLASH_JAVA)/re/jtreg/4.0/promoted/latest/binaries/jtreg
+endif
ifdef JPRT_JTREG_HOME
JT_HOME = $(JPRT_JTREG_HOME)
endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6443505/Test6443505.java Fri Apr 19 09:58:05 2013 -0700
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 6443505
+ * @summary Some cases for CmpLTMask missed; also wrong code.
+ *
+ * @run main/othervm -Xcomp -XX:CompileOnly="Test6443505.compiled" Test6443505
+ */
+
+public class Test6443505 {
+
+ public static void main(String[] args) throws InterruptedException {
+ test(Integer.MIN_VALUE, 0);
+ test(0, Integer.MIN_VALUE);
+ test(Integer.MIN_VALUE, -1);
+ test(-1, Integer.MIN_VALUE);
+ test(Integer.MIN_VALUE, 1);
+ test(1, Integer.MIN_VALUE);
+
+ test(Integer.MAX_VALUE, 0);
+ test(0, Integer.MAX_VALUE);
+ test(Integer.MAX_VALUE, -1);
+ test(-1, Integer.MAX_VALUE);
+ test(Integer.MAX_VALUE, 1);
+ test(1, Integer.MAX_VALUE);
+
+ test(Integer.MIN_VALUE, Integer.MAX_VALUE);
+ test(Integer.MAX_VALUE, Integer.MIN_VALUE);
+
+ test(1, -1);
+ test(1, 0);
+ test(1, 1);
+ test(-1, -1);
+ test(-1, 0);
+ test(-1, 1);
+ test(0, -1);
+ test(0, 0);
+ test(0, 1);
+ }
+
+ public static void test(int a, int b) throws InterruptedException {
+ int C = compiled(4, a, b);
+ int I = interpreted(4, a, b);
+ if (C != I) {
+ System.err.println("#1 C = " + C + ", I = " + I);
+ System.err.println("#1 C != I, FAIL");
+ System.exit(97);
+ }
+
+ C = compiled(a, b, q, 4);
+ I = interpreted(a, b, q, 4);
+ if (C != I) {
+ System.err.println("#2 C = " + C + ", I = " + I);
+ System.err.println("#2 C != I, FAIL");
+ System.exit(97);
+ }
+
+ }
+
+ static int q = 4;
+
+ // If improperly compiled, uses carry/borrow bit, which is wrong.
+ // with -XX:+PrintOptoAssembly, look for cadd_cmpLTMask
+ static int compiled(int p, int x, int y) {
+ return (x < y) ? q + (x - y) : (x - y);
+ }
+
+ // interpreted reference
+ static int interpreted(int p, int x, int y) {
+ return (x < y) ? q + (x - y) : (x - y);
+ }
+
+ // Test new code with a range of cases
+ // with -XX:+PrintOptoAssembly, look for and_cmpLTMask
+ static int compiled(int x, int y, int q, int p) {
+ return (x < y) ? p + q : q;
+ }
+
+ // interpreted reference
+ static int interpreted(int x, int y, int q, int p) {
+ return (x < y) ? p + q : q;
+ }
+
+}
--- a/hotspot/test/compiler/whitebox/ClearMethodStateTest.java Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/test/compiler/whitebox/ClearMethodStateTest.java Fri Apr 19 09:58:05 2013 -0700
@@ -27,42 +27,61 @@
* @build ClearMethodStateTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ClearMethodStateTest
+ * @summary testing of WB::clearMethodState()
* @author igor.ignatyev@oracle.com
*/
public class ClearMethodStateTest extends CompilerWhiteBoxTest {
+
public static void main(String[] args) throws Exception {
- // to prevent inlining #method into #compile() and #test()
- WHITE_BOX.testSetDontInlineMethod(METHOD, true);
- new ClearMethodStateTest().runTest();
+ for (TestCase test : TestCase.values()) {
+ new ClearMethodStateTest(test).runTest();
+ }
+ }
+
+ public ClearMethodStateTest(TestCase testCase) {
+ super(testCase);
+ // to prevent inlining of #method
+ WHITE_BOX.testSetDontInlineMethod(method, true);
}
+
+ /**
+ * Tests {@code WB::clearMethodState()} by calling it before/after
+ * compilation. For non-tiered, checks that counters will be rested after
+ * clearing of method state.
+ *
+ * @throws Exception if one of the checks fails.
+ */
+ @Override
protected void test() throws Exception {
- checkNotCompiled(METHOD);
+ checkNotCompiled();
compile();
- checkCompiled(METHOD);
- WHITE_BOX.clearMethodState(METHOD);
- WHITE_BOX.deoptimizeMethod(METHOD);
- checkNotCompiled(METHOD);
+ WHITE_BOX.clearMethodState(method);
+ checkCompiled();
+ WHITE_BOX.clearMethodState(method);
+ WHITE_BOX.deoptimizeMethod(method);
+ checkNotCompiled();
if (!TIERED_COMPILATION) {
- WHITE_BOX.clearMethodState(METHOD);
+ WHITE_BOX.clearMethodState(method);
compile(COMPILE_THRESHOLD);
- checkCompiled(METHOD);
+ checkCompiled();
- WHITE_BOX.deoptimizeMethod(METHOD);
- checkNotCompiled(METHOD);
- WHITE_BOX.clearMethodState(METHOD);
+ WHITE_BOX.deoptimizeMethod(method);
+ checkNotCompiled();
+ WHITE_BOX.clearMethodState(method);
+ // invoke method one less time than needed to compile
if (COMPILE_THRESHOLD > 1) {
compile(COMPILE_THRESHOLD - 1);
- checkNotCompiled(METHOD);
+ checkNotCompiled();
} else {
- System.err.println("Warning: 'CompileThreshold' <= 1");
+ System.err.println("Warning: 'CompileThreshold' <= 1");
}
- method();
- checkCompiled(METHOD);
+ compile(1);
+ checkCompiled();
} else {
System.err.println(
"Warning: part of test is not applicable in Tiered");
--- a/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java Fri Apr 19 09:58:05 2013 -0700
@@ -21,68 +21,132 @@
* questions.
*/
+import com.sun.management.HotSpotDiagnosticMXBean;
+import com.sun.management.VMOption;
import sun.hotspot.WhiteBox;
import sun.management.ManagementFactoryHelper;
-import com.sun.management.HotSpotDiagnosticMXBean;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
import java.lang.reflect.Method;
+import java.util.Objects;
+import java.util.concurrent.Callable;
-/*
+/**
+ * Abstract class for WhiteBox testing of JIT.
+ *
* @author igor.ignatyev@oracle.com
*/
public abstract class CompilerWhiteBoxTest {
+ /** {@code CompLevel::CompLevel_none} -- Interpreter */
+ protected static int COMP_LEVEL_NONE = 0;
+ /** {@code CompLevel::CompLevel_any}, {@code CompLevel::CompLevel_all} */
+ protected static int COMP_LEVEL_ANY = -1;
+ /** Instance of WhiteBox */
protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
- protected static final Method METHOD = getMethod("method");
+ /** Value of {@code -XX:CompileThreshold} */
protected static final int COMPILE_THRESHOLD
= Integer.parseInt(getVMOption("CompileThreshold", "10000"));
+ /** Value of {@code -XX:BackgroundCompilation} */
protected static final boolean BACKGROUND_COMPILATION
= Boolean.valueOf(getVMOption("BackgroundCompilation", "true"));
+ /** Value of {@code -XX:TieredCompilation} */
protected static final boolean TIERED_COMPILATION
= Boolean.valueOf(getVMOption("TieredCompilation", "false"));
+ /** Value of {@code -XX:TieredStopAtLevel} */
+ protected static final int TIERED_STOP_AT_LEVEL
+ = Integer.parseInt(getVMOption("TieredStopAtLevel", "0"));
- protected static Method getMethod(String name) {
+ /**
+ * Returns value of VM option.
+ *
+ * @param name option's name
+ * @return value of option or {@code null}, if option doesn't exist
+ * @throws NullPointerException if name is null
+ */
+ protected static String getVMOption(String name) {
+ Objects.requireNonNull(name);
+ HotSpotDiagnosticMXBean diagnostic
+ = ManagementFactoryHelper.getDiagnosticMXBean();
+ VMOption tmp;
try {
- return CompilerWhiteBoxTest.class.getDeclaredMethod(name);
- } catch (NoSuchMethodException | SecurityException e) {
- throw new RuntimeException(
- "exception on getting method " + name, e);
+ tmp = diagnostic.getVMOption(name);
+ } catch (IllegalArgumentException e) {
+ tmp = null;
}
+ return (tmp == null ? null : tmp.getValue());
}
- protected static String getVMOption(String name) {
- String result;
- HotSpotDiagnosticMXBean diagnostic
- = ManagementFactoryHelper.getDiagnosticMXBean();
- result = diagnostic.getVMOption(name).getValue();
- return result;
- }
-
+ /**
+ * Returns value of VM option or default value.
+ *
+ * @param name option's name
+ * @param defaultValue default value
+ * @return value of option or {@code defaultValue}, if option doesn't exist
+ * @throws NullPointerException if name is null
+ * @see #getVMOption(String)
+ */
protected static String getVMOption(String name, String defaultValue) {
String result = getVMOption(name);
return result == null ? defaultValue : result;
}
- protected final void runTest() throws RuntimeException {
+ /** tested method */
+ protected final Executable method;
+ private final Callable<Integer> callable;
+
+ /**
+ * Constructor.
+ *
+ * @param testCase object, that contains tested method and way to invoke it.
+ */
+ protected CompilerWhiteBoxTest(TestCase testCase) {
+ Objects.requireNonNull(testCase);
+ System.out.println("TEST CASE:" + testCase.name());
+ method = testCase.executable;
+ callable = testCase.callable;
+ }
+
+ /**
+ * Template method for testing. Prints tested method's info before
+ * {@linkplain #test()} and after {@linkplain #test()} or on thrown
+ * exception.
+ *
+ * @throws RuntimeException if method {@linkplain #test()} throws any
+ * exception
+ * @see #test()
+ */
+ protected final void runTest() {
if (ManagementFactoryHelper.getCompilationMXBean() == null) {
System.err.println(
"Warning: test is not applicable in interpreted mode");
return;
}
System.out.println("at test's start:");
- printInfo(METHOD);
+ printInfo();
try {
test();
} catch (Exception e) {
System.out.printf("on exception '%s':", e.getMessage());
- printInfo(METHOD);
+ printInfo();
e.printStackTrace();
+ if (e instanceof RuntimeException) {
+ throw (RuntimeException) e;
+ }
throw new RuntimeException(e);
}
System.out.println("at test's end:");
- printInfo(METHOD);
+ printInfo();
}
- protected static void checkNotCompiled(Method method) {
+ /**
+ * Checks, that {@linkplain #method} is not compiled.
+ *
+ * @throws RuntimeException if {@linkplain #method} is in compiler queue or
+ * is compiled, or if {@linkplain #method} has zero
+ * compilation level.
+ */
+ protected final void checkNotCompiled() {
if (WHITE_BOX.isMethodQueuedForCompilation(method)) {
throw new RuntimeException(method + " must not be in queue");
}
@@ -94,10 +158,16 @@
}
}
- protected static void checkCompiled(Method method)
- throws InterruptedException {
+ /**
+ * Checks, that {@linkplain #method} is compiled.
+ *
+ * @throws RuntimeException if {@linkplain #method} isn't in compiler queue
+ * and isn't compiled, or if {@linkplain #method}
+ * has nonzero compilation level
+ */
+ protected final void checkCompiled() {
final long start = System.currentTimeMillis();
- waitBackgroundCompilation(method);
+ waitBackgroundCompilation();
if (WHITE_BOX.isMethodQueuedForCompilation(method)) {
System.err.printf("Warning: %s is still in queue after %dms%n",
method, System.currentTimeMillis() - start);
@@ -111,23 +181,30 @@
}
}
- protected static void waitBackgroundCompilation(Method method)
- throws InterruptedException {
+ /**
+ * Waits for completion of background compilation of {@linkplain #method}.
+ */
+ protected final void waitBackgroundCompilation() {
if (!BACKGROUND_COMPILATION) {
return;
}
final Object obj = new Object();
- synchronized (obj) {
- for (int i = 0; i < 10; ++i) {
- if (!WHITE_BOX.isMethodQueuedForCompilation(method)) {
- break;
+ for (int i = 0; i < 10
+ && WHITE_BOX.isMethodQueuedForCompilation(method); ++i) {
+ synchronized (obj) {
+ try {
+ obj.wait(1000);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
}
- obj.wait(1000);
}
}
}
- protected static void printInfo(Method method) {
+ /**
+ * Prints information about {@linkplain #method}.
+ */
+ protected final void printInfo() {
System.out.printf("%n%s:%n", method);
System.out.printf("\tcompilable:\t%b%n",
WHITE_BOX.isMethodCompilable(method));
@@ -141,22 +218,139 @@
WHITE_BOX.getCompileQueuesSize());
}
+ /**
+ * Executes testing.
+ */
protected abstract void test() throws Exception;
+ /**
+ * Tries to trigger compilation of {@linkplain #method} by call
+ * {@linkplain #callable} enough times.
+ *
+ * @return accumulated result
+ * @see #compile(int)
+ */
protected final int compile() {
return compile(Math.max(COMPILE_THRESHOLD, 150000));
}
+ /**
+ * Tries to trigger compilation of {@linkplain #method} by call
+ * {@linkplain #callable} specified times.
+ *
+ * @param count invocation count
+ * @return accumulated result
+ */
protected final int compile(int count) {
int result = 0;
+ Integer tmp;
for (int i = 0; i < count; ++i) {
- result += method();
+ try {
+ tmp = callable.call();
+ } catch (Exception e) {
+ tmp = null;
+ }
+ result += tmp == null ? 0 : tmp;
}
System.out.println("method was invoked " + count + " times");
return result;
}
+}
- protected int method() {
- return 42;
+/**
+ * Utility structure containing tested method and object to invoke it.
+ */
+enum TestCase {
+ /** constructor test case */
+ CONSTRUCTOR_TEST(Helper.CONSTRUCTOR, Helper.CONSTRUCTOR_CALLABLE),
+ /** method test case */
+ METOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE),
+ /** static method test case */
+ STATIC_TEST(Helper.STATIC, Helper.STATIC_CALLABLE);
+
+ /** tested method */
+ final Executable executable;
+ /** object to invoke {@linkplain #executable} */
+ final Callable<Integer> callable;
+
+ private TestCase(Executable executable, Callable<Integer> callable) {
+ this.executable = executable;
+ this.callable = callable;
+ }
+
+ private static class Helper {
+ private static final Callable<Integer> CONSTRUCTOR_CALLABLE
+ = new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return new Helper(1337).hashCode();
+ }
+ };
+
+ private static final Callable<Integer> METHOD_CALLABLE
+ = new Callable<Integer>() {
+ private final Helper helper = new Helper();
+
+ @Override
+ public Integer call() throws Exception {
+ return helper.method();
+ }
+ };
+
+ private static final Callable<Integer> STATIC_CALLABLE
+ = new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return staticMethod();
+ }
+ };
+
+ private static final Constructor CONSTRUCTOR;
+ private static final Method METHOD;
+ private static final Method STATIC;
+
+ static {
+ try {
+ CONSTRUCTOR = Helper.class.getDeclaredConstructor(int.class);
+ } catch (NoSuchMethodException | SecurityException e) {
+ throw new RuntimeException(
+ "exception on getting method Helper.<init>(int)", e);
+ }
+ try {
+ METHOD = Helper.class.getDeclaredMethod("method");
+ } catch (NoSuchMethodException | SecurityException e) {
+ throw new RuntimeException(
+ "exception on getting method Helper.method()", e);
+ }
+ try {
+ STATIC = Helper.class.getDeclaredMethod("staticMethod");
+ } catch (NoSuchMethodException | SecurityException e) {
+ throw new RuntimeException(
+ "exception on getting method Helper.staticMethod()", e);
+ }
+ }
+
+ private static int staticMethod() {
+ return 1138;
+ }
+
+ private int method() {
+ return 42;
+ }
+
+ private final int x;
+
+ public Helper() {
+ x = 0;
+ }
+
+ private Helper(int x) {
+ this.x = x;
+ }
+
+ @Override
+ public int hashCode() {
+ return x;
+ }
}
}
--- a/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java Fri Apr 19 09:58:05 2013 -0700
@@ -27,20 +27,34 @@
* @build DeoptimizeAllTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI DeoptimizeAllTest
+ * @summary testing of WB::deoptimizeAll()
* @author igor.ignatyev@oracle.com
*/
public class DeoptimizeAllTest extends CompilerWhiteBoxTest {
public static void main(String[] args) throws Exception {
- // to prevent inlining #method into #compile()
- WHITE_BOX.testSetDontInlineMethod(METHOD, true);
- new DeoptimizeAllTest().runTest();
+ for (TestCase test : TestCase.values()) {
+ new DeoptimizeAllTest(test).runTest();
+ }
+ }
+
+ public DeoptimizeAllTest(TestCase testCase) {
+ super(testCase);
+ // to prevent inlining of #method
+ WHITE_BOX.testSetDontInlineMethod(method, true);
}
+ /**
+ * Tests {@code WB::deoptimizeAll()} by calling it after
+ * compilation and checking that method isn't compiled.
+ *
+ * @throws Exception if one of the checks fails.
+ */
+ @Override
protected void test() throws Exception {
compile();
- checkCompiled(METHOD);
+ checkCompiled();
WHITE_BOX.deoptimizeAll();
- checkNotCompiled(METHOD);
+ checkNotCompiled();
}
}
--- a/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java Fri Apr 19 09:58:05 2013 -0700
@@ -27,20 +27,34 @@
* @build DeoptimizeMethodTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI DeoptimizeMethodTest
+ * @summary testing of WB::deoptimizeMethod()
* @author igor.ignatyev@oracle.com
*/
public class DeoptimizeMethodTest extends CompilerWhiteBoxTest {
public static void main(String[] args) throws Exception {
- // to prevent inlining #method into #compile()
- WHITE_BOX.testSetDontInlineMethod(METHOD, true);
- new DeoptimizeMethodTest().runTest();
+ for (TestCase test : TestCase.values()) {
+ new DeoptimizeMethodTest(test).runTest();
+ }
+ }
+
+ public DeoptimizeMethodTest(TestCase testCase) {
+ super(testCase);
+ // to prevent inlining of #method
+ WHITE_BOX.testSetDontInlineMethod(method, true);
}
+ /**
+ * Tests {@code WB::deoptimizeMethod()} by calling it after
+ * compilation and checking that method isn't compiled.
+ *
+ * @throws Exception if one of the checks fails.
+ */
+ @Override
protected void test() throws Exception {
compile();
- checkCompiled(METHOD);
- WHITE_BOX.deoptimizeMethod(METHOD);
- checkNotCompiled(METHOD);
+ checkCompiled();
+ WHITE_BOX.deoptimizeMethod(method);
+ checkNotCompiled();
}
}
--- a/hotspot/test/compiler/whitebox/EnqueueMethodForCompilationTest.java Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/test/compiler/whitebox/EnqueueMethodForCompilationTest.java Fri Apr 19 09:58:05 2013 -0700
@@ -27,48 +27,60 @@
* @build EnqueueMethodForCompilationTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI EnqueueMethodForCompilationTest
+ * @summary testing of WB::enqueueMethodForCompilation()
* @author igor.ignatyev@oracle.com
*/
public class EnqueueMethodForCompilationTest extends CompilerWhiteBoxTest {
+
public static void main(String[] args) throws Exception {
- // to prevent inlining #method into #compile()
- WHITE_BOX.testSetDontInlineMethod(METHOD, true);
- new EnqueueMethodForCompilationTest().runTest();
+ for (TestCase test : TestCase.values()) {
+ new EnqueueMethodForCompilationTest(test).runTest();
+ }
+ }
+
+ public EnqueueMethodForCompilationTest(TestCase testCase) {
+ super(testCase);
+ // to prevent inlining of #method
+ WHITE_BOX.testSetDontInlineMethod(method, true);
}
+ @Override
protected void test() throws Exception {
- checkNotCompiled(METHOD);
+ checkNotCompiled();
- WHITE_BOX.enqueueMethodForCompilation(METHOD, 0);
- if (WHITE_BOX.isMethodCompilable(METHOD, 0)) {
- throw new RuntimeException(METHOD + " is compilable at level 0");
+ // method can not be compiled on level 'none'
+ WHITE_BOX.enqueueMethodForCompilation(method, COMP_LEVEL_NONE);
+ if (WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_NONE)) {
+ throw new RuntimeException(method
+ + " is compilable at level COMP_LEVEL_NONE");
}
- checkNotCompiled(METHOD);
+ checkNotCompiled();
- WHITE_BOX.enqueueMethodForCompilation(METHOD, -1);
- checkNotCompiled(METHOD);
+ // COMP_LEVEL_ANY is inapplicable as level for compilation
+ WHITE_BOX.enqueueMethodForCompilation(method, COMP_LEVEL_ANY);
+ checkNotCompiled();
- WHITE_BOX.enqueueMethodForCompilation(METHOD, 5);
- if (!WHITE_BOX.isMethodCompilable(METHOD, 5)) {
- checkNotCompiled(METHOD);
- compile();
- checkCompiled(METHOD);
+ WHITE_BOX.enqueueMethodForCompilation(method, 5);
+ if (!WHITE_BOX.isMethodCompilable(method, 5)) {
+ checkNotCompiled();
+ compile();
+ checkCompiled();
} else {
- checkCompiled(METHOD);
+ checkCompiled();
}
- int compLevel = WHITE_BOX.getMethodCompilationLevel(METHOD);
- WHITE_BOX.deoptimizeMethod(METHOD);
- checkNotCompiled(METHOD);
+ int compLevel = WHITE_BOX.getMethodCompilationLevel(method);
+ WHITE_BOX.deoptimizeMethod(method);
+ checkNotCompiled();
- WHITE_BOX.enqueueMethodForCompilation(METHOD, compLevel);
- checkCompiled(METHOD);
- WHITE_BOX.deoptimizeMethod(METHOD);
- checkNotCompiled(METHOD);
+ WHITE_BOX.enqueueMethodForCompilation(method, compLevel);
+ checkCompiled();
+ WHITE_BOX.deoptimizeMethod(method);
+ checkNotCompiled();
compile();
- checkCompiled(METHOD);
- WHITE_BOX.deoptimizeMethod(METHOD);
- checkNotCompiled(METHOD);
+ checkCompiled();
+ WHITE_BOX.deoptimizeMethod(method);
+ checkNotCompiled();
}
}
--- a/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java Fri Apr 19 09:58:05 2013 -0700
@@ -28,9 +28,13 @@
* @build IsMethodCompilableTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI IsMethodCompilableTest
+ * @summary testing of WB::isMethodCompilable()
* @author igor.ignatyev@oracle.com
*/
public class IsMethodCompilableTest extends CompilerWhiteBoxTest {
+ /**
+ * Value of {@code -XX:PerMethodRecompilationCutoff}
+ */
protected static final long PER_METHOD_RECOMPILATION_CUTOFF;
static {
@@ -44,14 +48,28 @@
}
public static void main(String[] args) throws Exception {
- // to prevent inlining #method into #compile()
- WHITE_BOX.testSetDontInlineMethod(METHOD, true);
- new IsMethodCompilableTest().runTest();
+ for (TestCase test : TestCase.values()) {
+ new IsMethodCompilableTest(test).runTest();
+ }
+ }
+
+ public IsMethodCompilableTest(TestCase testCase) {
+ super(testCase);
+ // to prevent inlining of #method
+ WHITE_BOX.testSetDontInlineMethod(method, true);
}
+ /**
+ * Tests {@code WB::isMethodCompilable()} by recompilation of tested method
+ * 'PerMethodRecompilationCutoff' times and checks compilation status. Also
+ * checks that WB::clearMethodState() clears no-compilable flags.
+ *
+ * @throws Exception if one of the checks fails.
+ */
+ @Override
protected void test() throws Exception {
- if (!WHITE_BOX.isMethodCompilable(METHOD)) {
- throw new RuntimeException(METHOD + " must be compilable");
+ if (!WHITE_BOX.isMethodCompilable(method)) {
+ throw new RuntimeException(method + " must be compilable");
}
System.out.println("PerMethodRecompilationCutoff = "
+ PER_METHOD_RECOMPILATION_CUTOFF);
@@ -61,46 +79,47 @@
return;
}
- // deoptimze 'PerMethodRecompilationCutoff' times and clear state
+ // deoptimize 'PerMethodRecompilationCutoff' times and clear state
for (long i = 0L, n = PER_METHOD_RECOMPILATION_CUTOFF - 1; i < n; ++i) {
- compileAndDeoptimaze();
+ compileAndDeoptimize();
}
- if (!WHITE_BOX.isMethodCompilable(METHOD)) {
- throw new RuntimeException(METHOD + " is not compilable after "
+ if (!WHITE_BOX.isMethodCompilable(method)) {
+ throw new RuntimeException(method + " is not compilable after "
+ (PER_METHOD_RECOMPILATION_CUTOFF - 1) + " iterations");
}
- WHITE_BOX.clearMethodState(METHOD);
+ WHITE_BOX.clearMethodState(method);
- // deoptimze 'PerMethodRecompilationCutoff' + 1 times
+ // deoptimize 'PerMethodRecompilationCutoff' + 1 times
long i;
for (i = 0L; i < PER_METHOD_RECOMPILATION_CUTOFF
- && WHITE_BOX.isMethodCompilable(METHOD); ++i) {
- compileAndDeoptimaze();
+ && WHITE_BOX.isMethodCompilable(method); ++i) {
+ compileAndDeoptimize();
}
if (i != PER_METHOD_RECOMPILATION_CUTOFF) {
- throw new RuntimeException(METHOD + " is not compilable after "
- + i + " iterations, but must only after "
- + PER_METHOD_RECOMPILATION_CUTOFF);
+ throw new RuntimeException(method + " is not compilable after "
+ + i + " iterations, but must only after "
+ + PER_METHOD_RECOMPILATION_CUTOFF);
}
- if (WHITE_BOX.isMethodCompilable(METHOD)) {
- throw new RuntimeException(METHOD + " is still compilable after "
+ if (WHITE_BOX.isMethodCompilable(method)) {
+ throw new RuntimeException(method + " is still compilable after "
+ PER_METHOD_RECOMPILATION_CUTOFF + " iterations");
}
compile();
- checkNotCompiled(METHOD);
+ checkNotCompiled();
- WHITE_BOX.clearMethodState(METHOD);
- if (!WHITE_BOX.isMethodCompilable(METHOD)) {
- throw new RuntimeException(METHOD
- + " is compilable after clearMethodState()");
+ // WB.clearMethodState() must reset no-compilable flags
+ WHITE_BOX.clearMethodState(method);
+ if (!WHITE_BOX.isMethodCompilable(method)) {
+ throw new RuntimeException(method
+ + " is not compilable after clearMethodState()");
}
compile();
- checkCompiled(METHOD);
+ checkCompiled();
}
- private void compileAndDeoptimaze() throws Exception {
+ private void compileAndDeoptimize() throws Exception {
compile();
- waitBackgroundCompilation(METHOD);
- WHITE_BOX.deoptimizeMethod(METHOD);
+ waitBackgroundCompilation();
+ WHITE_BOX.deoptimizeMethod(method);
}
}
--- a/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java Fri Apr 19 09:58:05 2013 -0700
@@ -27,28 +27,85 @@
* @build MakeMethodNotCompilableTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI MakeMethodNotCompilableTest
+ * @summary testing of WB::makeMethodNotCompilable()
* @author igor.ignatyev@oracle.com
*/
public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest {
public static void main(String[] args) throws Exception {
- // to prevent inlining #method into #compile()
- WHITE_BOX.testSetDontInlineMethod(METHOD, true);
- new MakeMethodNotCompilableTest().runTest();
+ if (args.length == 0) {
+ for (TestCase test : TestCase.values()) {
+ new MakeMethodNotCompilableTest(test).runTest();
+ }
+ } else {
+ for (String name : args) {
+ new MakeMethodNotCompilableTest(
+ TestCase.valueOf(name)).runTest();
+ }
+ }
+ }
+
+ public MakeMethodNotCompilableTest(TestCase testCase) {
+ super(testCase);
+ // to prevent inlining of #method
+ WHITE_BOX.testSetDontInlineMethod(method, true);
}
- protected void test() throws Exception {
- if (!WHITE_BOX.isMethodCompilable(METHOD)) {
- throw new RuntimeException(METHOD + " must be compilable");
+ /**
+ * Tests {@code WB::makeMethodNotCompilable()} by calling it before
+ * compilation and checking that method isn't compiled. Also
+ * checks that WB::clearMethodState() clears no-compilable flags. For
+ * tiered, additional checks for all available levels are conducted.
+ *
+ * @throws Exception if one of the checks fails.
+ */
+ @Override
+ protected void test() throws Exception {
+ checkNotCompiled();
+ if (!WHITE_BOX.isMethodCompilable(method)) {
+ throw new RuntimeException(method + " must be compilable");
}
- WHITE_BOX.makeMethodNotCompilable(METHOD);
- if (WHITE_BOX.isMethodCompilable(METHOD)) {
- throw new RuntimeException(METHOD + " must be not compilable");
+
+ if (TIERED_COMPILATION) {
+ for (int i = 1, n = TIERED_STOP_AT_LEVEL + 1; i < n; ++i) {
+ WHITE_BOX.makeMethodNotCompilable(method, i);
+ if (WHITE_BOX.isMethodCompilable(method, i)) {
+ throw new RuntimeException(method
+ + " must be not compilable at level" + i);
+ }
+ WHITE_BOX.enqueueMethodForCompilation(method, i);
+ checkNotCompiled();
+
+ if (!WHITE_BOX.isMethodCompilable(method)) {
+ System.out.println(method
+ + " is not compilable after level " + i);
+ }
+ }
+
+ // WB.clearMethodState() must reset no-compilable flags
+ WHITE_BOX.clearMethodState(method);
+ if (!WHITE_BOX.isMethodCompilable(method)) {
+ throw new RuntimeException(method
+ + " is not compilable after clearMethodState()");
+ }
+ }
+ WHITE_BOX.makeMethodNotCompilable(method);
+ if (WHITE_BOX.isMethodCompilable(method)) {
+ throw new RuntimeException(method + " must be not compilable");
+ }
+
+ compile();
+ checkNotCompiled();
+ if (WHITE_BOX.isMethodCompilable(method)) {
+ throw new RuntimeException(method + " must be not compilable");
+ }
+ // WB.clearMethodState() must reset no-compilable flags
+ WHITE_BOX.clearMethodState(method);
+ if (!WHITE_BOX.isMethodCompilable(method)) {
+ throw new RuntimeException(method
+ + " is not compilable after clearMethodState()");
}
compile();
- checkNotCompiled(METHOD);
- if (WHITE_BOX.isMethodCompilable(METHOD)) {
- throw new RuntimeException(METHOD + " must be not compilable");
- }
+ checkCompiled();
}
}
--- a/hotspot/test/compiler/whitebox/SetDontInlineMethodTest.java Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/test/compiler/whitebox/SetDontInlineMethodTest.java Fri Apr 19 09:58:05 2013 -0700
@@ -27,33 +27,47 @@
* @build SetDontInlineMethodTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SetDontInlineMethodTest
+ * @summary testing of WB::testSetDontInlineMethod()
* @author igor.ignatyev@oracle.com
*/
public class SetDontInlineMethodTest extends CompilerWhiteBoxTest {
public static void main(String[] args) throws Exception {
- new SetDontInlineMethodTest().runTest();
+ for (TestCase test : TestCase.values()) {
+ new SetDontInlineMethodTest(test).runTest();
+ }
+ }
+
+ public SetDontInlineMethodTest(TestCase testCase) {
+ super(testCase);
}
+ /**
+ * Tests {@code WB::testSetDontInlineMethod()} by sequential calling it and
+ * checking of return value.
+ *
+ * @throws Exception if one of the checks fails.
+ */
+ @Override
protected void test() throws Exception {
- if (WHITE_BOX.testSetDontInlineMethod(METHOD, true)) {
- throw new RuntimeException("on start " + METHOD
+ if (WHITE_BOX.testSetDontInlineMethod(method, true)) {
+ throw new RuntimeException("on start " + method
+ " must be inlineable");
}
- if (!WHITE_BOX.testSetDontInlineMethod(METHOD, true)) {
- throw new RuntimeException("after first change to true " + METHOD
+ if (!WHITE_BOX.testSetDontInlineMethod(method, true)) {
+ throw new RuntimeException("after first change to true " + method
+ " must be not inlineable");
}
- if (!WHITE_BOX.testSetDontInlineMethod(METHOD, false)) {
- throw new RuntimeException("after second change to true " + METHOD
+ if (!WHITE_BOX.testSetDontInlineMethod(method, false)) {
+ throw new RuntimeException("after second change to true " + method
+ " must be still not inlineable");
}
- if (WHITE_BOX.testSetDontInlineMethod(METHOD, false)) {
- throw new RuntimeException("after first change to false" + METHOD
+ if (WHITE_BOX.testSetDontInlineMethod(method, false)) {
+ throw new RuntimeException("after first change to false" + method
+ " must be inlineable");
}
- if (WHITE_BOX.testSetDontInlineMethod(METHOD, false)) {
- throw new RuntimeException("after second change to false " + METHOD
+ if (WHITE_BOX.testSetDontInlineMethod(method, false)) {
+ throw new RuntimeException("after second change to false " + method
+ " must be inlineable");
}
}
--- a/hotspot/test/compiler/whitebox/SetForceInlineMethodTest.java Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/test/compiler/whitebox/SetForceInlineMethodTest.java Fri Apr 19 09:58:05 2013 -0700
@@ -27,33 +27,47 @@
* @build SetForceInlineMethodTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SetForceInlineMethodTest
+ * @summary testing of WB::testSetForceInlineMethod()
* @author igor.ignatyev@oracle.com
*/
public class SetForceInlineMethodTest extends CompilerWhiteBoxTest {
public static void main(String[] args) throws Exception {
- new SetForceInlineMethodTest().runTest();
+ for (TestCase test : TestCase.values()) {
+ new SetForceInlineMethodTest(test).runTest();
+ }
+ }
+
+ public SetForceInlineMethodTest(TestCase testCase) {
+ super(testCase);
}
+ /**
+ * Tests {@code WB::testSetForceInlineMethod()} by sequential calling it and
+ * checking of return value.
+ *
+ * @throws Exception if one of the checks fails.
+ */
+ @Override
protected void test() throws Exception {
- if (WHITE_BOX.testSetForceInlineMethod(METHOD, true)) {
- throw new RuntimeException("on start " + METHOD
+ if (WHITE_BOX.testSetForceInlineMethod(method, true)) {
+ throw new RuntimeException("on start " + method
+ " must be not force inlineable");
}
- if (!WHITE_BOX.testSetForceInlineMethod(METHOD, true)) {
- throw new RuntimeException("after first change to true " + METHOD
+ if (!WHITE_BOX.testSetForceInlineMethod(method, true)) {
+ throw new RuntimeException("after first change to true " + method
+ " must be force inlineable");
}
- if (!WHITE_BOX.testSetForceInlineMethod(METHOD, false)) {
- throw new RuntimeException("after second change to true " + METHOD
+ if (!WHITE_BOX.testSetForceInlineMethod(method, false)) {
+ throw new RuntimeException("after second change to true " + method
+ " must be still force inlineable");
}
- if (WHITE_BOX.testSetForceInlineMethod(METHOD, false)) {
- throw new RuntimeException("after first change to false" + METHOD
+ if (WHITE_BOX.testSetForceInlineMethod(method, false)) {
+ throw new RuntimeException("after first change to false" + method
+ " must be not force inlineable");
}
- if (WHITE_BOX.testSetForceInlineMethod(METHOD, false)) {
- throw new RuntimeException("after second change to false " + METHOD
+ if (WHITE_BOX.testSetForceInlineMethod(method, false)) {
+ throw new RuntimeException("after second change to false " + method
+ " must be not force inlineable");
}
}
--- a/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Thu Apr 18 10:30:11 2013 -0700
+++ b/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Fri Apr 19 09:58:05 2013 -0700
@@ -24,7 +24,7 @@
package sun.hotspot;
-import java.lang.reflect.Method;
+import java.lang.reflect.Executable;
import java.security.BasicPermission;
import sun.hotspot.parser.DiagnosticCommand;
@@ -90,22 +90,25 @@
// Compiler
public native void deoptimizeAll();
- public native boolean isMethodCompiled(Method method);
- public boolean isMethodCompilable(Method method) {
+ public native boolean isMethodCompiled(Executable method);
+ public boolean isMethodCompilable(Executable method) {
return isMethodCompilable(method, -1 /*any*/);
}
- public native boolean isMethodCompilable(Method method, int compLevel);
- public native boolean isMethodQueuedForCompilation(Method method);
- public native int deoptimizeMethod(Method method);
- public native void makeMethodNotCompilable(Method method);
- public native int getMethodCompilationLevel(Method method);
- public native boolean testSetDontInlineMethod(Method method, boolean value);
+ public native boolean isMethodCompilable(Executable method, int compLevel);
+ public native boolean isMethodQueuedForCompilation(Executable method);
+ public native int deoptimizeMethod(Executable method);
+ public void makeMethodNotCompilable(Executable method) {
+ makeMethodNotCompilable(method, -1 /*any*/);
+ }
+ public native void makeMethodNotCompilable(Executable method, int compLevel);
+ public native int getMethodCompilationLevel(Executable method);
+ public native boolean testSetDontInlineMethod(Executable method, boolean value);
public native int getCompileQueuesSize();
- public native boolean testSetForceInlineMethod(Method method, boolean value);
- public native boolean enqueueMethodForCompilation(Method method, int compLevel);
- public native void clearMethodState(Method method);
+ public native boolean testSetForceInlineMethod(Executable method, boolean value);
+ public native boolean enqueueMethodForCompilation(Executable method, int compLevel);
+ public native void clearMethodState(Executable method);
- //Intered strings
+ // Intered strings
public native boolean isInStringTable(String str);
// force Full GC