--- a/.hgtags Fri Jan 27 13:48:40 2012 +0000
+++ b/.hgtags Sat Jan 28 22:21:54 2012 -0800
@@ -143,3 +143,5 @@
0ff7113a0882ec82d642cb9f0297b4e497807ced jdk8-b19
6561530ea757c3f3a6fb171c9cc7b3885cdeca85 jdk8-b20
b3a426170188f52981cf4573a2f14d487fddab0d jdk8-b21
+e8f03541af27e38aafb619b96863e17f65ffe53b jdk8-b22
+498124337041ad53cbaa7eb110f3d7acd6d4eac4 jdk8-b23
--- a/.hgtags-top-repo Fri Jan 27 13:48:40 2012 +0000
+++ b/.hgtags-top-repo Sat Jan 28 22:21:54 2012 -0800
@@ -143,3 +143,5 @@
237bc29afbfc6f56a4fe4a6008e2befb59c44bac jdk8-b19
5a5eaf6374bcbe23530899579fed17a05b7705f3 jdk8-b20
cc771d92284f71765eca14d6d08703c4af254c04 jdk8-b21
+7ad075c809952e355d25030605da6af30456ed74 jdk8-b22
+60d6f64a86b1e511169d264727f6d51415978df0 jdk8-b23
--- a/corba/.hgtags Fri Jan 27 13:48:40 2012 +0000
+++ b/corba/.hgtags Sat Jan 28 22:21:54 2012 -0800
@@ -143,3 +143,5 @@
e1366c5d84ef984095a332bcee70b3938232d07d jdk8-b19
51d8b6cb18c0978ecfa4f33e1537d35ee01b69fa jdk8-b20
f157fc2a71a38ce44007a6f18d5b011824dce705 jdk8-b21
+a11d0062c445d5f36651c78650ab88aa594bcbff jdk8-b22
+5218eb256658442b62b05295aafa5b5f35252972 jdk8-b23
--- a/hotspot/.hgtags Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/.hgtags Sat Jan 28 22:21:54 2012 -0800
@@ -211,3 +211,7 @@
fe2c8764998112b7fefcd7d41599714813ae4327 jdk8-b20
9952d1c439d64c5fd4ad1236a63a62bd5a49d4c3 jdk8-b21
513351373923f74a7c91755748b95c9771e59f96 hs23-b10
+24727fb37561779077fdfa5a33342246f20e5c0f jdk8-b22
+dcc292399a39113957eebbd3e487b7e05e2c79fc hs23-b11
+e850d8e7ea54b91c7aa656e297f0f9f38dd4c296 jdk8-b23
+9e177d44b10fe92ecffa965fef9c5ac5433c1b46 hs23-b12
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1CollectedHeap.java Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1CollectedHeap.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -49,8 +49,12 @@
static private long g1CommittedFieldOffset;
// size_t _summary_bytes_used;
static private CIntegerField summaryBytesUsedField;
- // G1MonitoringSupport* _g1mm
+ // G1MonitoringSupport* _g1mm;
static private AddressField g1mmField;
+ // MasterOldRegionSet _old_set;
+ static private long oldSetFieldOffset;
+ // MasterHumongousRegionSet _humongous_set;
+ static private long humongousSetFieldOffset;
static {
VM.registerVMInitializedObserver(new Observer() {
@@ -67,12 +71,14 @@
g1CommittedFieldOffset = type.getField("_g1_committed").getOffset();
summaryBytesUsedField = type.getCIntegerField("_summary_bytes_used");
g1mmField = type.getAddressField("_g1mm");
+ oldSetFieldOffset = type.getField("_old_set").getOffset();
+ humongousSetFieldOffset = type.getField("_humongous_set").getOffset();
}
public long capacity() {
Address g1CommittedAddr = addr.addOffsetTo(g1CommittedFieldOffset);
- MemRegion g1_committed = new MemRegion(g1CommittedAddr);
- return g1_committed.byteSize();
+ MemRegion g1Committed = new MemRegion(g1CommittedAddr);
+ return g1Committed.byteSize();
}
public long used() {
@@ -94,6 +100,18 @@
return (G1MonitoringSupport) VMObjectFactory.newObject(G1MonitoringSupport.class, g1mmAddr);
}
+ public HeapRegionSetBase oldSet() {
+ Address oldSetAddr = addr.addOffsetTo(oldSetFieldOffset);
+ return (HeapRegionSetBase) VMObjectFactory.newObject(HeapRegionSetBase.class,
+ oldSetAddr);
+ }
+
+ public HeapRegionSetBase humongousSet() {
+ Address humongousSetAddr = addr.addOffsetTo(humongousSetFieldOffset);
+ return (HeapRegionSetBase) VMObjectFactory.newObject(HeapRegionSetBase.class,
+ humongousSetAddr);
+ }
+
private Iterator<HeapRegion> heapRegionIterator() {
return hrs().heapRegionIterator();
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1MonitoringSupport.java Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1MonitoringSupport.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -77,6 +77,10 @@
return edenUsedField.getValue(addr);
}
+ public long edenRegionNum() {
+ return edenUsed() / HeapRegion.grainBytes();
+ }
+
public long survivorCommitted() {
return survivorCommittedField.getValue(addr);
}
@@ -85,6 +89,10 @@
return survivorUsedField.getValue(addr);
}
+ public long survivorRegionNum() {
+ return survivorUsed() / HeapRegion.grainBytes();
+ }
+
public long oldCommitted() {
return oldCommittedField.getValue(addr);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSetBase.java Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 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.
+ *
+ */
+
+package sun.jvm.hotspot.gc_implementation.g1;
+
+import java.util.Iterator;
+import java.util.Observable;
+import java.util.Observer;
+
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.runtime.VM;
+import sun.jvm.hotspot.runtime.VMObject;
+import sun.jvm.hotspot.runtime.VMObjectFactory;
+import sun.jvm.hotspot.types.AddressField;
+import sun.jvm.hotspot.types.CIntegerField;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.TypeDataBase;
+
+// Mirror class for HeapRegionSetBase. Represents a group of regions.
+
+public class HeapRegionSetBase extends VMObject {
+ // size_t _length;
+ static private CIntegerField lengthField;
+ // size_t _region_num;
+ static private CIntegerField regionNumField;
+ // size_t _total_used_bytes;
+ static private CIntegerField totalUsedBytesField;
+
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ static private synchronized void initialize(TypeDataBase db) {
+ Type type = db.lookupType("HeapRegionSetBase");
+
+ lengthField = type.getCIntegerField("_length");
+ regionNumField = type.getCIntegerField("_region_num");
+ totalUsedBytesField = type.getCIntegerField("_total_used_bytes");
+ }
+
+ public long length() {
+ return lengthField.getValue(addr);
+ }
+
+ public long regionNum() {
+ return regionNumField.getValue(addr);
+ }
+
+ public long totalUsedBytes() {
+ return totalUsedBytesField.getValue(addr);
+ }
+
+ public HeapRegionSetBase(Address addr) {
+ super(addr);
+ }
+}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -67,6 +67,7 @@
printValue("SurvivorRatio = ", getFlagValue("SurvivorRatio", flagMap));
printValMB("PermSize = ", getFlagValue("PermSize", flagMap));
printValMB("MaxPermSize = ", getFlagValue("MaxPermSize", flagMap));
+ printValMB("G1HeapRegionSize = ", HeapRegion.grainBytes());
System.out.println();
System.out.println("Heap Usage:");
@@ -100,11 +101,20 @@
} else if (sharedHeap instanceof G1CollectedHeap) {
G1CollectedHeap g1h = (G1CollectedHeap) sharedHeap;
G1MonitoringSupport g1mm = g1h.g1mm();
- System.out.println("G1 Young Generation");
- printG1Space("Eden Space:", g1mm.edenUsed(), g1mm.edenCommitted());
- printG1Space("From Space:", g1mm.survivorUsed(), g1mm.survivorCommitted());
- printG1Space("To Space:", 0, 0);
- printG1Space("G1 Old Generation", g1mm.oldUsed(), g1mm.oldCommitted());
+ long edenRegionNum = g1mm.edenRegionNum();
+ long survivorRegionNum = g1mm.survivorRegionNum();
+ HeapRegionSetBase oldSet = g1h.oldSet();
+ HeapRegionSetBase humongousSet = g1h.humongousSet();
+ long oldRegionNum = oldSet.regionNum() + humongousSet.regionNum();
+ printG1Space("G1 Heap:", g1h.n_regions(),
+ g1h.used(), g1h.capacity());
+ System.out.println("G1 Young Generation:");
+ printG1Space("Eden Space:", edenRegionNum,
+ g1mm.edenUsed(), g1mm.edenCommitted());
+ printG1Space("Survivor Space:", survivorRegionNum,
+ g1mm.survivorUsed(), g1mm.survivorCommitted());
+ printG1Space("G1 Old Generation:", oldRegionNum,
+ g1mm.oldUsed(), g1mm.oldCommitted());
} else {
throw new RuntimeException("unknown SharedHeap type : " + heap.getClass());
}
@@ -216,9 +226,11 @@
System.out.println(alignment + (double)space.used() * 100.0 / space.capacity() + "% used");
}
- private void printG1Space(String spaceName, long used, long capacity) {
+ private void printG1Space(String spaceName, long regionNum,
+ long used, long capacity) {
long free = capacity - used;
System.out.println(spaceName);
+ printValue("regions = ", regionNum);
printValMB("capacity = ", capacity);
printValMB("used = ", used);
printValMB("free = ", free);
--- a/hotspot/make/Makefile Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/make/Makefile Sat Jan 28 22:21:54 2012 -0800
@@ -367,7 +367,7 @@
$(EXPORT_LIB_DIR)/%.jar: $(GEN_DIR)/%.jar
$(install-file)
-# Include files (jvmti.h, jvmticmlr.h, jni.h, $(JDK_INCLUDE_SUBDIR)/jni_md.h, jmm.h)
+# Include files (jvmti.h, jvmticmlr.h, jni.h, $(JDK_INCLUDE_SUBDIR)/jni_md.h, jmm.h, jfr.h)
$(EXPORT_INCLUDE_DIR)/%: $(GEN_DIR)/jvmtifiles/%
$(install-file)
@@ -384,6 +384,16 @@
$(EXPORT_INCLUDE_DIR)/%: $(HS_SRC_DIR)/share/vm/services/%
$(install-file)
+JFR_EXISTS=$(shell if [ -d $(HS_ALT_SRC) ]; then echo 1; else echo 0; fi)
+# export jfr.h
+ifeq ($JFR_EXISTS,1)
+$(EXPORT_INCLUDE_DIR)/%: $(HS_ALT_SRC)/share/vm/jfr/agent/%
+ $(install-file)
+else
+$(EXPORT_INCLUDE_DIR)/jfr.h:
+
+endif
+
# Doc files (jvmti.html)
$(EXPORT_DOCS_DIR)/platform/jvmti/%: $(DOCS_DIR)/%
$(install-file)
--- a/hotspot/make/bsd/Makefile Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/make/bsd/Makefile Sat Jan 28 22:21:54 2012 -0800
@@ -208,7 +208,7 @@
TARGETS_SHARK = $(addsuffix shark,$(TARGETS))
BUILDTREE_MAKE = $(GAMMADIR)/make/$(OSNAME)/makefiles/buildtree.make
-BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OSNAME) SRCARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH)
+BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OSNAME) SRCARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) LIBRARY_SUFFIX=$(LIBRARY_SUFFIX)
BUILDTREE_VARS += HOTSPOT_RELEASE_VERSION=$(HOTSPOT_RELEASE_VERSION) HOTSPOT_BUILD_VERSION=$(HOTSPOT_BUILD_VERSION) JRE_RELEASE_VERSION=$(JRE_RELEASE_VERSION)
BUILDTREE = $(MAKE) -f $(BUILDTREE_MAKE) $(BUILDTREE_VARS)
--- a/hotspot/make/bsd/makefiles/buildtree.make Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/make/bsd/makefiles/buildtree.make Sat Jan 28 22:21:54 2012 -0800
@@ -162,20 +162,6 @@
endif
endif
-ifeq ($(OS_VENDOR), Darwin)
- # MACOSX FIXME: we should be able to run test_gamma (see MACOSX_PORT-214)
- ifeq ($(ALWAYS_PASS_TEST_GAMMA),)
- # ALWAYS_PASS_TEST_GAMMA wasn't set so we default to true on MacOS X
- # until MACOSX_PORT-214 is fixed
- ALWAYS_PASS_TEST_GAMMA=true
- endif
-endif
-ifeq ($(ALWAYS_PASS_TEST_GAMMA), true)
- TEST_GAMMA_STATUS= echo 'exit 0';
-else
- TEST_GAMMA_STATUS=
-endif
-
BUILDTREE_VARS += HOTSPOT_RELEASE_VERSION=$(HS_BUILD_VER) HOTSPOT_BUILD_VERSION= JRE_RELEASE_VERSION=$(JRE_RELEASE_VERSION)
BUILDTREE = \
@@ -353,12 +339,10 @@
$(BUILDTREE_COMMENT); \
[ -n "$$JAVA_HOME" ] && { echo ": \$${JAVA_HOME:=$${JAVA_HOME}}"; }; \
{ \
- echo "LD_LIBRARY_PATH=.:$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/${LIBARCH}/native_threads:\$${JAVA_HOME}/jre/lib/${LIBARCH}:${GCC_LIB}"; \
- echo "DYLD_LIBRARY_PATH=.:$${DYLD_LIBRARY_PATH:+$$DYLD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/${LIBARCH}/native_threads:\$${JAVA_HOME}/jre/lib/${LIBARCH}:${GCC_LIB}"; \
echo "CLASSPATH=$${CLASSPATH:+$$CLASSPATH:}.:\$${JAVA_HOME}/jre/lib/rt.jar:\$${JAVA_HOME}/jre/lib/i18n.jar"; \
} | sed s:$${JAVA_HOME:--------}:\$${JAVA_HOME}:g; \
echo "HOTSPOT_BUILD_USER=\"$${LOGNAME:-$$USER} in `basename $(GAMMADIR)`\""; \
- echo "export JAVA_HOME LD_LIBRARY_PATH DYLD_LIBRARY_PATH CLASSPATH HOTSPOT_BUILD_USER"; \
+ echo "export JAVA_HOME CLASSPATH HOTSPOT_BUILD_USER"; \
) > $@
env.csh: env.sh
@@ -412,7 +396,7 @@
JAVA_FLAG/64 = -d64
WRONG_DATA_MODE_MSG = \
- echo "JAVA_HOME must point to $(DATA_MODE)bit JDK."
+ echo "JAVA_HOME must point to a $(DATA_MODE)-bit OpenJDK."
CROSS_COMPILING_MSG = \
echo "Cross compiling for ARCH $(CROSS_COMPILE_ARCH), skipping gamma run."
@@ -420,20 +404,78 @@
test_gamma: $(BUILDTREE_MAKE) $(GAMMADIR)/make/test/Queens.java
@echo Creating $@ ...
$(QUIETLY) ( \
- echo '#!/bin/sh'; \
+ echo "#!/bin/sh"; \
+ echo ""; \
$(BUILDTREE_COMMENT); \
- echo '. ./env.sh'; \
- echo "if [ \"$(CROSS_COMPILE_ARCH)\" != \"\" ]; then { $(CROSS_COMPILING_MSG); exit 0; }; fi"; \
- echo "if [ -z \$$JAVA_HOME ]; then { $(NO_JAVA_HOME_MSG); exit 0; }; fi"; \
- echo "if ! \$${JAVA_HOME}/bin/java $(JAVA_FLAG) -fullversion 2>&1 > /dev/null"; \
- echo "then"; \
- echo " $(WRONG_DATA_MODE_MSG); exit 0;"; \
+ echo ""; \
+ echo "# Include environment settings for gamma run"; \
+ echo ""; \
+ echo ". ./env.sh"; \
+ echo ""; \
+ echo "# Do not run gamma test for cross compiles"; \
+ echo ""; \
+ echo "if [ -n \"$(CROSS_COMPILE_ARCH)\" ]; then "; \
+ echo " $(CROSS_COMPILING_MSG)"; \
+ echo " exit 0"; \
+ echo "fi"; \
+ echo ""; \
+ echo "# Make sure JAVA_HOME is set as it is required for gamma"; \
+ echo ""; \
+ echo "if [ -z \"\$${JAVA_HOME}\" ]; then "; \
+ echo " $(NO_JAVA_HOME_MSG)"; \
+ echo " exit 0"; \
+ echo "fi"; \
+ echo ""; \
+ echo "# Check JAVA_HOME version to be used for the test"; \
+ echo ""; \
+ echo "\$${JAVA_HOME}/bin/java $(JAVA_FLAG) -fullversion > /dev/null 2>&1"; \
+ echo "if [ \$$? -ne 0 ]; then "; \
+ echo " $(WRONG_DATA_MODE_MSG)"; \
+ echo " exit 0"; \
echo "fi"; \
+ echo ""; \
+ echo "# Use gamma_g if it exists"; \
+ echo ""; \
+ echo "GAMMA_PROG=gamma"; \
+ echo "if [ -f gamma_g ]; then "; \
+ echo " GAMMA_PROG=gamma_g"; \
+ echo "fi"; \
+ echo ""; \
+ echo "if [ \"$(OS_VENDOR)\" = \"Darwin\" ]; then "; \
+ echo " # Ensure architecture for gamma and JAVA_HOME is the same."; \
+ echo " # NOTE: gamma assumes the OpenJDK directory layout."; \
+ echo ""; \
+ echo " GAMMA_ARCH=\"\`file \$${GAMMA_PROG} | awk '{print \$$NF}'\`\""; \
+ echo " JVM_LIB=\"\$${JAVA_HOME}/jre/lib/libjava.$(LIBRARY_SUFFIX)\""; \
+ echo " if [ ! -f \$${JVM_LIB} ]; then"; \
+ echo " JVM_LIB=\"\$${JAVA_HOME}/jre/lib/$${LIBARCH}/libjava.$(LIBRARY_SUFFIX)\""; \
+ echo " fi"; \
+ echo " if [ ! -f \$${JVM_LIB} ] || [ -z \"\`file \$${JVM_LIB} | grep \$${GAMMA_ARCH}\`\" ]; then "; \
+ echo " $(WRONG_DATA_MODE_MSG)"; \
+ echo " exit 0"; \
+ echo " fi"; \
+ echo "fi"; \
+ echo ""; \
+ echo "# Compile Queens program for test"; \
+ echo ""; \
echo "rm -f Queens.class"; \
echo "\$${JAVA_HOME}/bin/javac -d . $(GAMMADIR)/make/test/Queens.java"; \
- echo '[ -f gamma_g ] && { gamma=gamma_g; }'; \
- echo './$${gamma:-gamma} $(TESTFLAGS) Queens < /dev/null'; \
- $(TEST_GAMMA_STATUS) \
+ echo ""; \
+ echo "# Set library path solely for gamma launcher test run"; \
+ echo ""; \
+ echo "LD_LIBRARY_PATH=.:$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/${LIBARCH}/native_threads:\$${JAVA_HOME}/jre/lib/${LIBARCH}:${GCC_LIB}"; \
+ echo "export LD_LIBRARY_PATH"; \
+ echo "unset LD_LIBRARY_PATH_32"; \
+ echo "unset LD_LIBRARY_PATH_64"; \
+ echo ""; \
+ echo "if [ \"$(OS_VENDOR)\" = \"Darwin\" ]; then "; \
+ echo " DYLD_LIBRARY_PATH=.:$${DYLD_LIBRARY_PATH:+$$DYLD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/native_threads:\$${JAVA_HOME}/jre/lib:$${DYLD_LIBRARY_PATH:+$$DYLD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/${LIBARCH}/native_threads:\$${JAVA_HOME}/jre/lib/${LIBARCH}:${GCC_LIB}"; \
+ echo " export DYLD_LIBRARY_PATH"; \
+ echo "fi"; \
+ echo ""; \
+ echo "# Use the gamma launcher and JAVA_HOME to run the test"; \
+ echo ""; \
+ echo "./\$${GAMMA_PROG} $(TESTFLAGS) Queens < /dev/null"; \
) > $@
$(QUIETLY) chmod +x $@
--- a/hotspot/make/bsd/makefiles/defs.make Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/make/bsd/makefiles/defs.make Sat Jan 28 22:21:54 2012 -0800
@@ -142,6 +142,7 @@
# client and server subdirectories have symbolic links to ../libjsig.so
EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.$(LIBRARY_SUFFIX)
EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
+EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
ifndef BUILD_CLIENT_ONLY
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
@@ -150,7 +151,6 @@
ifneq ($(ZERO_BUILD), true)
ifeq ($(ARCH_DATA_MODEL), 32)
- EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX)
endif
--- a/hotspot/make/bsd/makefiles/launcher.make Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/make/bsd/makefiles/launcher.make Sat Jan 28 22:21:54 2012 -0800
@@ -50,7 +50,24 @@
LIBS_LAUNCHER += $(STATIC_STDCXX) $(LIBS)
else
LAUNCHER.o = launcher.o
- LFLAGS_LAUNCHER += -L`pwd`
+ LFLAGS_LAUNCHER += -L`pwd`
+
+ # The gamma launcher runs the JDK from $JAVA_HOME, overriding the JVM with a
+ # freshly built JVM at ./libjvm.{so|dylib}. This is accomplished by setting
+ # the library searchpath using ({DY}LD_LIBRARY_PATH) to find the local JVM
+ # first. Gamma dlopen()s libjava from $JAVA_HOME/jre/lib{/$arch}, which is
+ # statically linked with CoreFoundation framework libs. Unfortunately, gamma's
+ # unique searchpath results in some unresolved symbols in the framework
+ # libraries, because JDK libraries are inadvertently discovered first on the
+ # searchpath, e.g. libjpeg. On Mac OS X, filenames are case *insensitive*.
+ # So, the actual filename collision is libjpeg.dylib and libJPEG.dylib.
+ # To resolve this, gamma needs to also statically link with the CoreFoundation
+ # framework libraries.
+
+ ifeq ($(OS_VENDOR),Darwin)
+ LFLAGS_LAUNCHER += -framework CoreFoundation
+ endif
+
LIBS_LAUNCHER += -l$(JVM) $(LIBS)
endif
--- a/hotspot/make/bsd/makefiles/vm.make Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/make/bsd/makefiles/vm.make Sat Jan 28 22:21:54 2012 -0800
@@ -96,6 +96,10 @@
CPPFLAGS += -DDEFAULT_LIBPATH="\"$(DEFAULT_LIBPATH)\""
endif
+ifndef JAVASE_EMBEDDED
+CFLAGS += -DINCLUDE_TRACE
+endif
+
# CFLAGS_WARN holds compiler options to suppress/enable warnings.
CFLAGS += $(CFLAGS_WARN/BYFILE)
@@ -147,6 +151,12 @@
SOURCE_PATHS+=$(HS_COMMON_SRC)/cpu/$(Platform_arch)/vm
SOURCE_PATHS+=$(HS_COMMON_SRC)/os_cpu/$(Platform_os_arch)/vm
+ifndef JAVASE_EMBEDDED
+SOURCE_PATHS+=$(shell if [ -d $(HS_ALT_SRC)/share/vm/jfr ]; then \
+ find $(HS_ALT_SRC)/share/vm/jfr -type d; \
+ fi)
+endif
+
CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
CORE_PATHS+=$(GENERATED)/jvmtifiles
@@ -327,8 +337,8 @@
$(LIBJVM).dSYM: $(LIBJVM)
dsymutil $(LIBJVM)
-# no launcher or libjvm_db for macosx
-build: $(LIBJVM) $(LIBJSIG) $(BUILDLIBSAPROC) dtraceCheck $(LIBJVM).dSYM
+# no libjvm_db for macosx
+build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(BUILDLIBSAPROC) dtraceCheck $(LIBJVM).dSYM
echo "Doing vm.make build:"
else
build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC)
--- a/hotspot/make/defs.make Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/make/defs.make Sat Jan 28 22:21:54 2012 -0800
@@ -294,3 +294,7 @@
EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jni.h
EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/$(JDK_INCLUDE_SUBDIR)/jni_md.h
EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jmm.h
+
+ifndef JAVASE_EMBEDDED
+EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jfr.h
+endif
--- a/hotspot/make/hotspot_version Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/make/hotspot_version Sat Jan 28 22:21:54 2012 -0800
@@ -35,7 +35,7 @@
HS_MAJOR_VER=23
HS_MINOR_VER=0
-HS_BUILD_NUMBER=10
+HS_BUILD_NUMBER=12
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
--- a/hotspot/make/jprt.properties Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/make/jprt.properties Sat Jan 28 22:21:54 2012 -0800
@@ -174,6 +174,10 @@
jprt.my.linux.armsflt.ejdk7=linux_armsflt_2.6
jprt.my.linux.armsflt=${jprt.my.linux.armsflt.${jprt.tools.default.release}}
+jprt.my.macosx.x64.jdk8=macosx_x64_10.7
+jprt.my.macosx.x64.jdk7=macosx_x64_10.7
+jprt.my.macosx.x64=${jprt.my.macosx.x64.${jprt.tools.default.release}}
+
jprt.my.windows.i586.jdk8=windows_i586_5.1
jprt.my.windows.i586.jdk7=windows_i586_5.1
jprt.my.windows.i586.jdk7b107=windows_i586_5.0
@@ -211,6 +215,7 @@
${jprt.my.solaris.x64}-{product|fastdebug|debug}, \
${jprt.my.linux.i586}-{product|fastdebug|debug}, \
${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}
@@ -416,6 +421,30 @@
${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_G1, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_ParOldGC
+jprt.my.macosx.x64.test.targets = \
+ ${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_tiered, \
+ ${jprt.my.macosx.x64}-{product|fastdebug}-c2-jbb_ParallelGC, \
+ ${jprt.my.macosx.x64}-{product|fastdebug}-c2-jbb_G1, \
+ ${jprt.my.macosx.x64}-{product|fastdebug}-c2-jbb_ParOldGC
+
jprt.my.windows.i586.test.targets = \
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-jvm98, \
${jprt.my.windows.i586}-{product|fastdebug}-c2-jvm98_nontiered, \
@@ -492,6 +521,7 @@
${jprt.my.solaris.x64.test.targets}, \
${jprt.my.linux.i586.test.targets}, \
${jprt.my.linux.x64.test.targets}, \
+ ${jprt.my.macosx.x64.test.targets}, \
${jprt.my.windows.i586.test.targets}, \
${jprt.my.windows.x64.test.targets}, \
${jprt.test.targets.open}
@@ -538,6 +568,7 @@
${jprt.my.solaris.x64}-*-c2-servertest, \
${jprt.my.linux.i586}-*-c2-servertest, \
${jprt.my.linux.x64}-*-c2-servertest, \
+ ${jprt.my.macosx.x64}-*-c2-servertest, \
${jprt.my.windows.i586}-*-c2-servertest, \
${jprt.my.windows.x64}-*-c2-servertest
@@ -548,6 +579,7 @@
${jprt.my.solaris.x64}-fastdebug-c2-internalvmtests, \
${jprt.my.linux.i586}-fastdebug-c2-internalvmtests, \
${jprt.my.linux.x64}-fastdebug-c2-internalvmtests, \
+ ${jprt.my.macosx.x64}-fastdebug-c2-internalvmtests, \
${jprt.my.windows.i586}-fastdebug-c2-internalvmtests, \
${jprt.my.windows.x64}-fastdebug-c2-internalvmtests
--- a/hotspot/make/linux/makefiles/buildtree.make Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/make/linux/makefiles/buildtree.make Sat Jan 28 22:21:54 2012 -0800
@@ -326,11 +326,10 @@
$(BUILDTREE_COMMENT); \
[ -n "$$JAVA_HOME" ] && { echo ": \$${JAVA_HOME:=$${JAVA_HOME}}"; }; \
{ \
- echo "LD_LIBRARY_PATH=.:$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/${LIBARCH}/native_threads:\$${JAVA_HOME}/jre/lib/${LIBARCH}:${GCC_LIB}"; \
echo "CLASSPATH=$${CLASSPATH:+$$CLASSPATH:}.:\$${JAVA_HOME}/jre/lib/rt.jar:\$${JAVA_HOME}/jre/lib/i18n.jar"; \
} | sed s:$${JAVA_HOME:--------}:\$${JAVA_HOME}:g; \
echo "HOTSPOT_BUILD_USER=\"$${LOGNAME:-$$USER} in `basename $(GAMMADIR)`\""; \
- echo "export JAVA_HOME LD_LIBRARY_PATH CLASSPATH HOTSPOT_BUILD_USER"; \
+ echo "export JAVA_HOME CLASSPATH HOTSPOT_BUILD_USER"; \
) > $@
env.csh: env.sh
@@ -384,7 +383,7 @@
JAVA_FLAG/64 = -d64
WRONG_DATA_MODE_MSG = \
- echo "JAVA_HOME must point to $(DATA_MODE)bit JDK."
+ echo "JAVA_HOME must point to a $(DATA_MODE)-bit OpenJDK."
CROSS_COMPILING_MSG = \
echo "Cross compiling for ARCH $(CROSS_COMPILE_ARCH), skipping gamma run."
@@ -392,19 +391,78 @@
test_gamma: $(BUILDTREE_MAKE) $(GAMMADIR)/make/test/Queens.java
@echo Creating $@ ...
$(QUIETLY) ( \
- echo '#!/bin/sh'; \
+ echo "#!/bin/sh"; \
+ echo ""; \
$(BUILDTREE_COMMENT); \
- echo '. ./env.sh'; \
- echo "if [ \"$(CROSS_COMPILE_ARCH)\" != \"\" ]; then { $(CROSS_COMPILING_MSG); exit 0; }; fi"; \
- echo "if [ -z \$$JAVA_HOME ]; then { $(NO_JAVA_HOME_MSG); exit 0; }; fi"; \
- echo "if ! \$${JAVA_HOME}/bin/java $(JAVA_FLAG) -fullversion 2>&1 > /dev/null"; \
- echo "then"; \
- echo " $(WRONG_DATA_MODE_MSG); exit 0;"; \
+ echo ""; \
+ echo "# Include environment settings for gamma run"; \
+ echo ""; \
+ echo ". ./env.sh"; \
+ echo ""; \
+ echo "# Do not run gamma test for cross compiles"; \
+ echo ""; \
+ echo "if [ -n \"$(CROSS_COMPILE_ARCH)\" ]; then "; \
+ echo " $(CROSS_COMPILING_MSG)"; \
+ echo " exit 0"; \
+ echo "fi"; \
+ echo ""; \
+ echo "# Make sure JAVA_HOME is set as it is required for gamma"; \
+ echo ""; \
+ echo "if [ -z \"\$${JAVA_HOME}\" ]; then "; \
+ echo " $(NO_JAVA_HOME_MSG)"; \
+ echo " exit 0"; \
+ echo "fi"; \
+ echo ""; \
+ echo "# Check JAVA_HOME version to be used for the test"; \
+ echo ""; \
+ echo "\$${JAVA_HOME}/bin/java $(JAVA_FLAG) -fullversion > /dev/null 2>&1"; \
+ echo "if [ \$$? -ne 0 ]; then "; \
+ echo " $(WRONG_DATA_MODE_MSG)"; \
+ echo " exit 0"; \
echo "fi"; \
+ echo ""; \
+ echo "# Use gamma_g if it exists"; \
+ echo ""; \
+ echo "GAMMA_PROG=gamma"; \
+ echo "if [ -f gamma_g ]; then "; \
+ echo " GAMMA_PROG=gamma_g"; \
+ echo "fi"; \
+ echo ""; \
+ echo "if [ \"$(OS_VENDOR)\" = \"Darwin\" ]; then "; \
+ echo " # Ensure architecture for gamma and JAVA_HOME is the same."; \
+ echo " # NOTE: gamma assumes the OpenJDK directory layout."; \
+ echo ""; \
+ echo " GAMMA_ARCH=\"\`file \$${GAMMA_PROG} | awk '{print \$$NF}'\`\""; \
+ echo " JVM_LIB=\"\$${JAVA_HOME}/jre/lib/libjava.$(LIBRARY_SUFFIX)\""; \
+ echo " if [ ! -f \$${JVM_LIB} ]; then"; \
+ echo " JVM_LIB=\"\$${JAVA_HOME}/jre/lib/$${LIBARCH}/libjava.$(LIBRARY_SUFFIX)\""; \
+ echo " fi"; \
+ echo " if [ ! -f \$${JVM_LIB} ] || [ -z \"\`file \$${JVM_LIB} | grep \$${GAMMA_ARCH}\`\" ]; then "; \
+ echo " $(WRONG_DATA_MODE_MSG)"; \
+ echo " exit 0"; \
+ echo " fi"; \
+ echo "fi"; \
+ echo ""; \
+ echo "# Compile Queens program for test"; \
+ echo ""; \
echo "rm -f Queens.class"; \
echo "\$${JAVA_HOME}/bin/javac -d . $(GAMMADIR)/make/test/Queens.java"; \
- echo '[ -f gamma_g ] && { gamma=gamma_g; }'; \
- echo './$${gamma:-gamma} $(TESTFLAGS) Queens < /dev/null'; \
+ echo ""; \
+ echo "# Set library path solely for gamma launcher test run"; \
+ echo ""; \
+ echo "LD_LIBRARY_PATH=.:$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/${LIBARCH}/native_threads:\$${JAVA_HOME}/jre/lib/${LIBARCH}:${GCC_LIB}"; \
+ echo "export LD_LIBRARY_PATH"; \
+ echo "unset LD_LIBRARY_PATH_32"; \
+ echo "unset LD_LIBRARY_PATH_64"; \
+ echo ""; \
+ echo "if [ \"$(OS_VENDOR)\" = \"Darwin\" ]; then "; \
+ echo " DYLD_LIBRARY_PATH=.:$${DYLD_LIBRARY_PATH:+$$DYLD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/native_threads:\$${JAVA_HOME}/jre/lib:$${DYLD_LIBRARY_PATH:+$$DYLD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/${LIBARCH}/native_threads:\$${JAVA_HOME}/jre/lib/${LIBARCH}:${GCC_LIB}"; \
+ echo " export DYLD_LIBRARY_PATH"; \
+ echo "fi"; \
+ echo ""; \
+ echo "# Use the gamma launcher and JAVA_HOME to run the test"; \
+ echo ""; \
+ echo "./\$${GAMMA_PROG} $(TESTFLAGS) Queens < /dev/null"; \
) > $@
$(QUIETLY) chmod +x $@
--- a/hotspot/make/linux/makefiles/vm.make Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/make/linux/makefiles/vm.make Sat Jan 28 22:21:54 2012 -0800
@@ -98,6 +98,10 @@
${JRE_VERSION} \
${VM_DISTRO}
+ifndef JAVASE_EMBEDDED
+CFLAGS += -DINCLUDE_TRACE
+endif
+
# CFLAGS_WARN holds compiler options to suppress/enable warnings.
CFLAGS += $(CFLAGS_WARN/BYFILE)
@@ -143,6 +147,12 @@
SOURCE_PATHS+=$(HS_COMMON_SRC)/cpu/$(Platform_arch)/vm
SOURCE_PATHS+=$(HS_COMMON_SRC)/os_cpu/$(Platform_os_arch)/vm
+ifndef JAVASE_EMBEDDED
+SOURCE_PATHS+=$(shell if [ -d $(HS_ALT_SRC)/share/vm/jfr ]; then \
+ find $(HS_ALT_SRC)/share/vm/jfr -type d; \
+ fi)
+endif
+
CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
CORE_PATHS+=$(GENERATED)/jvmtifiles
--- a/hotspot/make/solaris/makefiles/buildtree.make Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/make/solaris/makefiles/buildtree.make Sat Jan 28 22:21:54 2012 -0800
@@ -118,7 +118,7 @@
BUILDTREE_MAKE = $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make
BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make \
- env.ksh env.csh jdkpath.sh .dbxrc test_gamma
+ env.sh env.csh jdkpath.sh .dbxrc test_gamma
BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
ARCH=$(ARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT)
@@ -313,22 +313,19 @@
echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
) > $@
-env.ksh: $(BUILDTREE_MAKE)
+env.sh: $(BUILDTREE_MAKE)
@echo Creating $@ ...
$(QUIETLY) ( \
$(BUILDTREE_COMMENT); \
[ -n "$$JAVA_HOME" ] && { echo ": \$${JAVA_HOME:=$${JAVA_HOME}}"; }; \
{ \
- echo "LD_LIBRARY_PATH=.:$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/${LIBARCH}/native_threads:\$${JAVA_HOME}/jre/lib/${LIBARCH}:${GCC_LIB}"; \
- echo "unset LD_LIBRARY_PATH_32"; \
- echo "unset LD_LIBRARY_PATH_64"; \
echo "CLASSPATH=$${CLASSPATH:+$$CLASSPATH:}.:\$${JAVA_HOME}/jre/lib/rt.jar:\$${JAVA_HOME}/jre/lib/i18n.jar"; \
} | sed s:$${JAVA_HOME:--------}:\$${JAVA_HOME}:g; \
echo "HOTSPOT_BUILD_USER=\"$${LOGNAME:-$$USER} in `basename $(GAMMADIR)`\""; \
echo "export JAVA_HOME LD_LIBRARY_PATH CLASSPATH HOTSPOT_BUILD_USER"; \
) > $@
-env.csh: env.ksh
+env.csh: env.sh
@echo Creating $@ ...
$(QUIETLY) ( \
$(BUILDTREE_COMMENT); \
@@ -384,23 +381,86 @@
JAVA_FLAG/64 = -d64
WRONG_DATA_MODE_MSG = \
- echo "JAVA_HOME must point to $(DATA_MODE)bit JDK."
+ echo "JAVA_HOME must point to a $(DATA_MODE)-bit OpenJDK."
+
+CROSS_COMPILING_MSG = \
+ echo "Cross compiling for ARCH $(CROSS_COMPILE_ARCH), skipping gamma run."
test_gamma: $(BUILDTREE_MAKE) $(GAMMADIR)/make/test/Queens.java
@echo Creating $@ ...
$(QUIETLY) ( \
- echo '#!/bin/ksh'; \
+ echo "#!/bin/sh"; \
+ echo ""; \
$(BUILDTREE_COMMENT); \
- echo '. ./env.ksh'; \
- echo "if [ -z \$$JAVA_HOME ]; then { $(NO_JAVA_HOME_MSG); exit 0; }; fi"; \
- echo "if ! \$${JAVA_HOME}/bin/java $(JAVA_FLAG) -fullversion 2>&1 > /dev/null"; \
- echo "then"; \
- echo " $(WRONG_DATA_MODE_MSG); exit 0;"; \
+ echo ""; \
+ echo "# Include environment settings for gamma run"; \
+ echo ""; \
+ echo ". ./env.sh"; \
+ echo ""; \
+ echo "# Do not run gamma test for cross compiles"; \
+ echo ""; \
+ echo "if [ -n \"$(CROSS_COMPILE_ARCH)\" ]; then "; \
+ echo " $(CROSS_COMPILING_MSG)"; \
+ echo " exit 0"; \
+ echo "fi"; \
+ echo ""; \
+ echo "# Make sure JAVA_HOME is set as it is required for gamma"; \
+ echo ""; \
+ echo "if [ -z \"\$${JAVA_HOME}\" ]; then "; \
+ echo " $(NO_JAVA_HOME_MSG)"; \
+ echo " exit 0"; \
+ echo "fi"; \
+ echo ""; \
+ echo "# Check JAVA_HOME version to be used for the test"; \
+ echo ""; \
+ echo "\$${JAVA_HOME}/bin/java $(JAVA_FLAG) -fullversion > /dev/null 2>&1"; \
+ echo "if [ \$$? -ne 0 ]; then "; \
+ echo " $(WRONG_DATA_MODE_MSG)"; \
+ echo " exit 0"; \
echo "fi"; \
+ echo ""; \
+ echo "# Use gamma_g if it exists"; \
+ echo ""; \
+ echo "GAMMA_PROG=gamma"; \
+ echo "if [ -f gamma_g ]; then "; \
+ echo " GAMMA_PROG=gamma_g"; \
+ echo "fi"; \
+ echo ""; \
+ echo "if [ \"$(OS_VENDOR)\" = \"Darwin\" ]; then "; \
+ echo " # Ensure architecture for gamma and JAVA_HOME is the same."; \
+ echo " # NOTE: gamma assumes the OpenJDK directory layout."; \
+ echo ""; \
+ echo " GAMMA_ARCH=\"\`file \$${GAMMA_PROG} | awk '{print \$$NF}'\`\""; \
+ echo " JVM_LIB=\"\$${JAVA_HOME}/jre/lib/libjava.$(LIBRARY_SUFFIX)\""; \
+ echo " if [ ! -f \$${JVM_LIB} ]; then"; \
+ echo " JVM_LIB=\"\$${JAVA_HOME}/jre/lib/$${LIBARCH}/libjava.$(LIBRARY_SUFFIX)\""; \
+ echo " fi"; \
+ echo " if [ ! -f \$${JVM_LIB} ] || [ -z \"\`file \$${JVM_LIB} | grep \$${GAMMA_ARCH}\`\" ]; then "; \
+ echo " $(WRONG_DATA_MODE_MSG)"; \
+ echo " exit 0"; \
+ echo " fi"; \
+ echo "fi"; \
+ echo ""; \
+ echo "# Compile Queens program for test"; \
+ echo ""; \
echo "rm -f Queens.class"; \
echo "\$${JAVA_HOME}/bin/javac -d . $(GAMMADIR)/make/test/Queens.java"; \
- echo '[ -f gamma_g ] && { gamma=gamma_g; }'; \
- echo './$${gamma:-gamma} $(TESTFLAGS) Queens < /dev/null'; \
+ echo ""; \
+ echo "# Set library path solely for gamma launcher test run"; \
+ echo ""; \
+ echo "LD_LIBRARY_PATH=.:$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/${LIBARCH}/native_threads:\$${JAVA_HOME}/jre/lib/${LIBARCH}:${GCC_LIB}"; \
+ echo "export LD_LIBRARY_PATH"; \
+ echo "unset LD_LIBRARY_PATH_32"; \
+ echo "unset LD_LIBRARY_PATH_64"; \
+ echo ""; \
+ echo "if [ \"$(OS_VENDOR)\" = \"Darwin\" ]; then "; \
+ echo " DYLD_LIBRARY_PATH=.:$${DYLD_LIBRARY_PATH:+$$DYLD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/native_threads:\$${JAVA_HOME}/jre/lib:$${DYLD_LIBRARY_PATH:+$$DYLD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/${LIBARCH}/native_threads:\$${JAVA_HOME}/jre/lib/${LIBARCH}:${GCC_LIB}"; \
+ echo " export DYLD_LIBRARY_PATH"; \
+ echo "fi"; \
+ echo ""; \
+ echo "# Use the gamma launcher and JAVA_HOME to run the test"; \
+ echo ""; \
+ echo "./\$${GAMMA_PROG} $(TESTFLAGS) Queens < /dev/null"; \
) > $@
$(QUIETLY) chmod +x $@
--- a/hotspot/make/solaris/makefiles/vm.make Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/make/solaris/makefiles/vm.make Sat Jan 28 22:21:54 2012 -0800
@@ -93,7 +93,7 @@
CFLAGS += $(CFLAGS/NOEX)
# Extra flags from gnumake's invocation or environment
-CFLAGS += $(EXTRA_CFLAGS)
+CFLAGS += $(EXTRA_CFLAGS) -DINCLUDE_TRACE
# Math Library (libm.so), do not use -lm.
# There might be two versions of libm.so on the build system:
@@ -160,6 +160,10 @@
SOURCE_PATHS+=$(HS_COMMON_SRC)/cpu/$(Platform_arch)/vm
SOURCE_PATHS+=$(HS_COMMON_SRC)/os_cpu/$(Platform_os_arch)/vm
+SOURCE_PATHS+=$(shell if [ -d $(HS_ALT_SRC)/share/vm/jfr ]; then \
+ find $(HS_ALT_SRC)/share/vm/jfr -type d; \
+ fi)
+
CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
CORE_PATHS+=$(GENERATED)/jvmtifiles
--- a/hotspot/make/windows/build.bat Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/make/windows/build.bat Sat Jan 28 22:21:54 2012 -0800
@@ -35,6 +35,8 @@
if %errorlevel% == 0 goto isia64
cl 2>&1 | grep "AMD64" >NUL
if %errorlevel% == 0 goto amd64
+cl 2>&1 | grep "x64" >NUL
+if %errorlevel% == 0 goto amd64
set ARCH=x86
set BUILDARCH=i486
set Platform_arch=x86
--- a/hotspot/make/windows/create_obj_files.sh Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/make/windows/create_obj_files.sh Sat Jan 28 22:21:54 2012 -0800
@@ -73,6 +73,13 @@
BASE_PATHS="${BASE_PATHS} ${GENERATED}/jvmtifiles"
+if [ -d "${ALTSRC}/share/vm/jfr" ]; then
+ BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr/agent"
+ BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr/agent/isolated_deps/util"
+ BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr/jvm"
+ BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr"
+fi
+
CORE_PATHS="${BASE_PATHS}"
# shared is already in BASE_PATHS. Should add vm/memory but that one is also in BASE_PATHS.
if [ -d "${ALTSRC}/share/vm/gc_implementation" ]; then
--- a/hotspot/make/windows/makefiles/projectcreator.make Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/make/windows/makefiles/projectcreator.make Sat Jan 28 22:21:54 2012 -0800
@@ -58,7 +58,8 @@
-absoluteInclude $(HOTSPOTBUILDSPACE)/%f/generated \
-ignorePath $(HOTSPOTBUILDSPACE)/%f/generated \
-ignorePath src\share\vm\adlc \
- -ignorePath src\share\vm\shark
+ -ignorePath src\share\vm\shark \
+ -ignorePath posix
# This is referenced externally by both the IDE and batch builds
ProjectCreatorOptions=
@@ -88,7 +89,7 @@
-jdkTargetRoot $(HOTSPOTJDKDIST) \
-define ALIGN_STACK_FRAMES \
-define VM_LITTLE_ENDIAN \
- -prelink "" "Generating vm.def..." "cd $(HOTSPOTBUILDSPACE)\%f\%b set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME) $(HOTSPOTMKSHOME)\sh $(HOTSPOTWORKSPACE)\make\windows\build_vm_def.sh $(LINK_VER)" \
+ -prelink "" "Generating vm.def..." "cd $(HOTSPOTBUILDSPACE)\%f\%b set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME) set JAVA_HOME=$(HOTSPOTJDKDIST) $(HOTSPOTMKSHOME)\sh $(HOTSPOTWORKSPACE)\make\windows\build_vm_def.sh $(LINK_VER)" \
-postbuild "" "Building hotspot.exe..." "cd $(HOTSPOTBUILDSPACE)\%f\%b set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME) nmake -f $(HOTSPOTWORKSPACE)\make\windows\projectfiles\common\Makefile LOCAL_MAKE=$(HOTSPOTBUILDSPACE)\%f\local.make JAVA_HOME=$(HOTSPOTJDKDIST) launcher" \
-ignoreFile jsig.c \
-ignoreFile jvmtiEnvRecommended.cpp \
--- a/hotspot/make/windows/makefiles/vm.make Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/make/windows/makefiles/vm.make Sat Jan 28 22:21:54 2012 -0800
@@ -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.
-#
+#
#
# Resource file containing VERSIONINFO
@@ -30,7 +30,7 @@
COMMONSRC=$(WorkSpace)\src
ALTSRC=$(WorkSpace)\src\closed
-!ifdef RELEASE
+!ifdef RELEASE
!ifdef DEVELOP
CPP_FLAGS=$(CPP_FLAGS) /D "DEBUG"
!else
@@ -74,6 +74,10 @@
CPP_FLAGS=$(CPP_FLAGS) /D "HOTSPOT_BUILD_USER=\"$(BuildUser)\""
CPP_FLAGS=$(CPP_FLAGS) /D "HOTSPOT_VM_DISTRO=\"$(HOTSPOT_VM_DISTRO)\""
+!ifndef JAVASE_EMBEDDED
+CPP_FLAGS=$(CPP_FLAGS) /D "INCLUDE_TRACE"
+!endif
+
CPP_FLAGS=$(CPP_FLAGS) $(CPP_INCLUDE_DIRS)
# Define that so jni.h is on correct side
@@ -97,7 +101,7 @@
!endif
# If you modify exports below please do the corresponding changes in
-# src/share/tools/ProjectCreator/WinGammaPlatformVC7.java
+# src/share/tools/ProjectCreator/WinGammaPlatformVC7.java
LINK_FLAGS=$(LINK_FLAGS) $(STACK_SIZE) /subsystem:windows /dll /base:0x8000000 \
/export:JNI_GetDefaultJavaVMInitArgs \
/export:JNI_CreateJavaVM \
@@ -170,6 +174,7 @@
VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/prims
VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/runtime
VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/services
+VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/trace
VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/utilities
VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/libadt
VM_PATH=$(VM_PATH);$(WorkSpace)/src/os/windows/vm
@@ -177,6 +182,13 @@
VM_PATH=$(VM_PATH);$(WorkSpace)/src/cpu/$(Platform_arch)/vm
VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/opto
+!if exists($(ALTSRC)\share\vm\jfr)
+VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr/agent
+VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr/agent/isolated_deps/util
+VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr/jvm
+VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr
+!endif
+
VM_PATH={$(VM_PATH)}
# Special case files not using precompiled header files.
@@ -263,6 +275,9 @@
{$(COMMONSRC)\share\vm\services}.cpp.obj::
$(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $<
+{$(COMMONSRC)\share\vm\trace}.cpp.obj::
+ $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $<
+
{$(COMMONSRC)\share\vm\utilities}.cpp.obj::
$(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $<
@@ -340,6 +355,9 @@
{$(ALTSRC)\share\vm\services}.cpp.obj::
$(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $<
+{$(ALTSRC)\share\vm\trace}.cpp.obj::
+ $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $<
+
{$(ALTSRC)\share\vm\utilities}.cpp.obj::
$(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $<
@@ -371,6 +389,18 @@
{..\generated\jvmtifiles}.cpp.obj::
$(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $<
+{$(ALTSRC)\share\vm\jfr}.cpp.obj::
+ $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $<
+
+{$(ALTSRC)\share\vm\jfr\agent}.cpp.obj::
+ $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $<
+
+{$(ALTSRC)\share\vm\jfr\agent\isolated_deps\util}.cpp.obj::
+ $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $<
+
+{$(ALTSRC)\share\vm\jfr\jvm}.cpp.obj::
+ $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $<
+
default::
_build_pch_file.obj:
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -391,7 +391,7 @@
__ call(Runtime1::entry_for(Runtime1::handle_exception_from_callee_id), relocInfo::runtime_call_type);
__ delayed()->nop();
__ should_not_reach_here();
- assert(code_offset() - offset <= exception_handler_size, "overflow");
+ guarantee(code_offset() - offset <= exception_handler_size, "overflow");
__ end_a_stub();
return offset;
@@ -474,8 +474,7 @@
AddressLiteral deopt_blob(SharedRuntime::deopt_blob()->unpack());
__ JUMP(deopt_blob, G3_scratch, 0); // sethi;jmp
__ delayed()->nop();
- assert(code_offset() - offset <= deopt_handler_size, "overflow");
- debug_only(__ stop("should have gone to the caller");)
+ guarantee(code_offset() - offset <= deopt_handler_size, "overflow");
__ end_a_stub();
return offset;
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -69,7 +69,7 @@
#else
call_stub_size = 20,
#endif // _LP64
- exception_handler_size = DEBUG_ONLY(1*K) NOT_DEBUG(10*4),
- deopt_handler_size = DEBUG_ONLY(1*K) NOT_DEBUG(10*4) };
+ exception_handler_size = DEBUG_ONLY(1*K) NOT_DEBUG(128),
+ deopt_handler_size = DEBUG_ONLY(1*K) NOT_DEBUG(64) };
#endif // CPU_SPARC_VM_C1_LIRASSEMBLER_SPARC_HPP
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -810,7 +810,7 @@
}
-#ifdef ASSERT
+#ifndef PRODUCT
#define DESCRIBE_FP_OFFSET(name) \
values.describe(frame_no, fp() + frame::name##_offset, #name)
@@ -820,11 +820,19 @@
values.describe(frame_no, sp() + w, err_msg("register save area word %d", w), 1);
}
- if (is_interpreted_frame()) {
+ if (is_ricochet_frame()) {
+ MethodHandles::RicochetFrame::describe(this, values, frame_no);
+ } else if (is_interpreted_frame()) {
DESCRIBE_FP_OFFSET(interpreter_frame_d_scratch_fp);
DESCRIBE_FP_OFFSET(interpreter_frame_l_scratch_fp);
DESCRIBE_FP_OFFSET(interpreter_frame_padding);
DESCRIBE_FP_OFFSET(interpreter_frame_oop_temp);
+
+ // esp, according to Lesp (e.g. not depending on bci), if seems valid
+ intptr_t* esp = *interpreter_frame_esp_addr();
+ if ((esp >= sp()) && (esp < fp())) {
+ values.describe(-1, esp, "*Lesp");
+ }
}
if (!is_compiled_frame()) {
@@ -844,4 +852,3 @@
// unused... but returns fp() to minimize changes introduced by 7087445
return fp();
}
-
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.inline.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/cpu/sparc/vm/frame_sparc.inline.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -82,6 +82,8 @@
inline intptr_t* frame::sender_sp() const { return fp(); }
+inline intptr_t* frame::real_fp() const { return fp(); }
+
// Used only in frame::oopmapreg_to_location
// This return a value in VMRegImpl::slot_size
inline int frame::pd_oop_map_offset_adjustment() const {
--- a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -177,7 +177,7 @@
BLOCK_COMMENT("ricochet_blob.bounce");
if (VerifyMethodHandles) RicochetFrame::verify_clean(_masm);
- trace_method_handle(_masm, "ricochet_blob.bounce");
+ trace_method_handle(_masm, "return/ricochet_blob.bounce");
__ JMP(L1_continuation, 0);
__ delayed()->nop();
@@ -268,14 +268,16 @@
}
// Emit code to verify that FP is pointing at a valid ricochet frame.
-#ifdef ASSERT
+#ifndef PRODUCT
enum {
ARG_LIMIT = 255, SLOP = 45,
// use this parameter for checking for garbage stack movements:
UNREASONABLE_STACK_MOVE = (ARG_LIMIT + SLOP)
// the slop defends against false alarms due to fencepost errors
};
+#endif
+#ifdef ASSERT
void MethodHandles::RicochetFrame::verify_clean(MacroAssembler* _masm) {
// The stack should look like this:
// ... keep1 | dest=42 | keep2 | magic | handler | magic | recursive args | [RF]
@@ -1001,31 +1003,142 @@
}
#ifndef PRODUCT
+void MethodHandles::RicochetFrame::describe(const frame* fr, FrameValues& values, int frame_no) {
+ RicochetFrame* rf = new RicochetFrame(*fr);
+
+ // ricochet slots (kept in registers for sparc)
+ values.describe(frame_no, rf->register_addr(I5_savedSP), err_msg("exact_sender_sp reg for #%d", frame_no));
+ values.describe(frame_no, rf->register_addr(L5_conversion), err_msg("conversion reg for #%d", frame_no));
+ values.describe(frame_no, rf->register_addr(L4_saved_args_base), err_msg("saved_args_base reg for #%d", frame_no));
+ values.describe(frame_no, rf->register_addr(L3_saved_args_layout), err_msg("saved_args_layout reg for #%d", frame_no));
+ values.describe(frame_no, rf->register_addr(L2_saved_target), err_msg("saved_target reg for #%d", frame_no));
+ values.describe(frame_no, rf->register_addr(L1_continuation), err_msg("continuation reg for #%d", frame_no));
+
+ // relevant ricochet targets (in caller frame)
+ values.describe(-1, rf->saved_args_base(), err_msg("*saved_args_base for #%d", frame_no));
+ values.describe(-1, (intptr_t *)(STACK_BIAS+(uintptr_t)rf->exact_sender_sp()), err_msg("*exact_sender_sp+STACK_BIAS for #%d", frame_no));
+}
+#endif // ASSERT
+
+#ifndef PRODUCT
extern "C" void print_method_handle(oop mh);
void trace_method_handle_stub(const char* adaptername,
oopDesc* mh,
- intptr_t* saved_sp) {
+ intptr_t* saved_sp,
+ intptr_t* args,
+ intptr_t* tracing_fp) {
bool has_mh = (strstr(adaptername, "return/") == NULL); // return adapters don't have mh
- tty->print_cr("MH %s mh="INTPTR_FORMAT " saved_sp=" INTPTR_FORMAT, adaptername, (intptr_t) mh, saved_sp);
- if (has_mh)
+
+ tty->print_cr("MH %s mh="INTPTR_FORMAT " saved_sp=" INTPTR_FORMAT " args=" INTPTR_FORMAT, adaptername, (intptr_t) mh, saved_sp, args);
+
+ if (Verbose) {
+ // dumping last frame with frame::describe
+
+ JavaThread* p = JavaThread::active();
+
+ ResourceMark rm;
+ PRESERVE_EXCEPTION_MARK; // may not be needed by safer and unexpensive here
+ FrameValues values;
+
+ // Note: We want to allow trace_method_handle from any call site.
+ // While trace_method_handle creates a frame, it may be entered
+ // without a valid return PC in O7 (e.g. not just after a call).
+ // Walking that frame could lead to failures due to that invalid PC.
+ // => carefully detect that frame when doing the stack walking
+
+ // walk up to the right frame using the "tracing_fp" argument
+ intptr_t* cur_sp = StubRoutines::Sparc::flush_callers_register_windows_func()();
+ frame cur_frame(cur_sp, frame::unpatchable, NULL);
+
+ while (cur_frame.fp() != (intptr_t *)(STACK_BIAS+(uintptr_t)tracing_fp)) {
+ cur_frame = os::get_sender_for_C_frame(&cur_frame);
+ }
+
+ // safely create a frame and call frame::describe
+ intptr_t *dump_sp = cur_frame.sender_sp();
+ intptr_t *dump_fp = cur_frame.link();
+
+ bool walkable = has_mh; // whether the traced frame shoud be walkable
+
+ // the sender for cur_frame is the caller of trace_method_handle
+ if (walkable) {
+ // The previous definition of walkable may have to be refined
+ // if new call sites cause the next frame constructor to start
+ // failing. Alternatively, frame constructors could be
+ // modified to support the current or future non walkable
+ // frames (but this is more intrusive and is not considered as
+ // part of this RFE, which will instead use a simpler output).
+ frame dump_frame = frame(dump_sp,
+ cur_frame.sp(), // younger_sp
+ false); // no adaptation
+ dump_frame.describe(values, 1);
+ } else {
+ // Robust dump for frames which cannot be constructed from sp/younger_sp
+ // Add descriptions without building a Java frame to avoid issues
+ values.describe(-1, dump_fp, "fp for #1 <not parsed, cannot trust pc>");
+ values.describe(-1, dump_sp, "sp");
+ }
+
+ bool has_args = has_mh; // whether Gargs is meaningful
+
+ // mark args, if seems valid (may not be valid for some adapters)
+ if (has_args) {
+ if ((args >= dump_sp) && (args < dump_fp)) {
+ values.describe(-1, args, "*G4_args");
+ }
+ }
+
+ // mark saved_sp, if seems valid (may not be valid for some adapters)
+ intptr_t *unbiased_sp = (intptr_t *)(STACK_BIAS+(uintptr_t)saved_sp);
+ if ((unbiased_sp >= dump_sp - UNREASONABLE_STACK_MOVE) && (unbiased_sp < dump_fp)) {
+ values.describe(-1, unbiased_sp, "*saved_sp+STACK_BIAS");
+ }
+
+ // Note: the unextended_sp may not be correct
+ tty->print_cr(" stack layout:");
+ values.print(p);
+ }
+
+ if (has_mh) {
print_method_handle(mh);
+ }
}
+
void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) {
if (!TraceMethodHandles) return;
BLOCK_COMMENT("trace_method_handle {");
// save: Gargs, O5_savedSP
- __ save_frame(16);
+ __ save_frame(16); // need space for saving required FPU state
+
__ set((intptr_t) adaptername, O0);
__ mov(G3_method_handle, O1);
__ mov(I5_savedSP, O2);
+ __ mov(Gargs, O3);
+ __ mov(I6, O4); // frame identifier for safe stack walking
+
+ // Save scratched registers that might be needed. Robustness is more
+ // important than optimizing the saves for this debug only code.
+
+ // save FP result, valid at some call sites (adapter_opt_return_float, ...)
+ Address d_save(FP, -sizeof(jdouble) + STACK_BIAS);
+ __ stf(FloatRegisterImpl::D, Ftos_d, d_save);
+ // Safely save all globals but G2 (handled by call_VM_leaf) and G7
+ // (OS reserved).
__ mov(G3_method_handle, L3);
__ mov(Gargs, L4);
__ mov(G5_method_type, L5);
- __ call_VM_leaf(L7, CAST_FROM_FN_PTR(address, trace_method_handle_stub));
+ __ mov(G6, L6);
+ __ mov(G1, L1);
+
+ __ call_VM_leaf(L2 /* for G2 */, CAST_FROM_FN_PTR(address, trace_method_handle_stub));
__ mov(L3, G3_method_handle);
__ mov(L4, Gargs);
__ mov(L5, G5_method_type);
+ __ mov(L6, G6);
+ __ mov(L1, G1);
+ __ ldf(FloatRegisterImpl::D, d_save, Ftos_d);
+
__ restore();
BLOCK_COMMENT("} trace_method_handle");
}
@@ -1045,7 +1158,7 @@
|(1<<java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS)
// OP_COLLECT_ARGS is below...
|(1<<java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS)
- |(!UseRicochetFrames ? 0 :
+ |(
java_lang_invoke_MethodTypeForm::vmlayout_offset_in_bytes() <= 0 ? 0 :
((1<<java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF)
|(1<<java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS)
@@ -1250,7 +1363,7 @@
move_typed_arg(_masm, arg_type, false,
prim_value_addr,
Address(O0_argslot, 0),
- O2_scratch); // must be an even register for !_LP64 long moves (uses O2/O3)
+ O2_scratch); // must be an even register for !_LP64 long moves (uses O2/O3)
}
if (direct_to_method) {
--- a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -145,6 +145,8 @@
}
static void verify_clean(MacroAssembler* _masm) NOT_DEBUG_RETURN;
+
+ static void describe(const frame* fr, FrameValues& values, int frame_no) PRODUCT_RETURN;
};
// Additional helper methods for MethodHandles code generation:
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -406,7 +406,7 @@
// search an exception handler (rax: exception oop, rdx: throwing pc)
__ call(RuntimeAddress(Runtime1::entry_for(Runtime1::handle_exception_from_callee_id)));
__ should_not_reach_here();
- assert(code_offset() - offset <= exception_handler_size, "overflow");
+ guarantee(code_offset() - offset <= exception_handler_size, "overflow");
__ end_a_stub();
return offset;
@@ -490,8 +490,7 @@
__ pushptr(here.addr());
__ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
-
- assert(code_offset() - offset <= deopt_handler_size, "overflow");
+ guarantee(code_offset() - offset <= deopt_handler_size, "overflow");
__ end_a_stub();
return offset;
--- a/hotspot/src/cpu/x86/vm/frame_x86.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -651,13 +651,15 @@
return &interpreter_frame_tos_address()[index];
}
-#ifdef ASSERT
+#ifndef PRODUCT
#define DESCRIBE_FP_OFFSET(name) \
values.describe(frame_no, fp() + frame::name##_offset, #name)
void frame::describe_pd(FrameValues& values, int frame_no) {
- if (is_interpreted_frame()) {
+ if (is_ricochet_frame()) {
+ MethodHandles::RicochetFrame::describe(this, values, frame_no);
+ } else if (is_interpreted_frame()) {
DESCRIBE_FP_OFFSET(interpreter_frame_sender_sp);
DESCRIBE_FP_OFFSET(interpreter_frame_last_sp);
DESCRIBE_FP_OFFSET(interpreter_frame_method);
@@ -667,7 +669,6 @@
DESCRIBE_FP_OFFSET(interpreter_frame_bcx);
DESCRIBE_FP_OFFSET(interpreter_frame_initial_sp);
}
-
}
#endif
@@ -675,3 +676,21 @@
// used to reset the saved FP
return fp();
}
+
+intptr_t* frame::real_fp() const {
+ if (_cb != NULL) {
+ // use the frame size if valid
+ int size = _cb->frame_size();
+ if ((size > 0) &&
+ (! is_ricochet_frame())) {
+ // Work-around: ricochet explicitly excluded because frame size is not
+ // constant for the ricochet blob but its frame_size could not, for
+ // some reasons, be declared as <= 0. This potentially confusing
+ // size declaration should be fixed as another CR.
+ return unextended_sp() + size;
+ }
+ }
+ // else rely on fp()
+ assert(! is_compiled_frame(), "unknown compiled frame size");
+ return fp();
+}
--- a/hotspot/src/cpu/x86/vm/frame_x86.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/cpu/x86/vm/frame_x86.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -188,6 +188,7 @@
frame(intptr_t* sp, intptr_t* fp);
// accessors for the instance variables
+ // Note: not necessarily the real 'frame pointer' (see real_fp)
intptr_t* fp() const { return _fp; }
inline address* sender_pc_addr() const;
--- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -279,14 +279,16 @@
}
// Emit code to verify that RBP is pointing at a valid ricochet frame.
-#ifdef ASSERT
+#ifndef PRODUCT
enum {
ARG_LIMIT = 255, SLOP = 4,
// use this parameter for checking for garbage stack movements:
UNREASONABLE_STACK_MOVE = (ARG_LIMIT + SLOP)
// the slop defends against false alarms due to fencepost errors
};
+#endif
+#ifdef ASSERT
void MethodHandles::RicochetFrame::verify_clean(MacroAssembler* _masm) {
// The stack should look like this:
// ... keep1 | dest=42 | keep2 | RF | magic | handler | magic | recursive args |
@@ -990,6 +992,26 @@
BLOCK_COMMENT("} move_return_value");
}
+#ifndef PRODUCT
+#define DESCRIBE_RICOCHET_OFFSET(rf, name) \
+ values.describe(frame_no, (intptr_t *) (((uintptr_t)rf) + MethodHandles::RicochetFrame::name##_offset_in_bytes()), #name)
+
+void MethodHandles::RicochetFrame::describe(const frame* fr, FrameValues& values, int frame_no) {
+ address bp = (address) fr->fp();
+ RicochetFrame* rf = (RicochetFrame*)(bp - sender_link_offset_in_bytes());
+
+ // ricochet slots
+ DESCRIBE_RICOCHET_OFFSET(rf, exact_sender_sp);
+ DESCRIBE_RICOCHET_OFFSET(rf, conversion);
+ DESCRIBE_RICOCHET_OFFSET(rf, saved_args_base);
+ DESCRIBE_RICOCHET_OFFSET(rf, saved_args_layout);
+ DESCRIBE_RICOCHET_OFFSET(rf, saved_target);
+ DESCRIBE_RICOCHET_OFFSET(rf, continuation);
+
+ // relevant ricochet targets (in caller frame)
+ values.describe(-1, rf->saved_args_base(), err_msg("*saved_args_base for #%d", frame_no));
+}
+#endif // ASSERT
#ifndef PRODUCT
extern "C" void print_method_handle(oop mh);
@@ -1001,11 +1023,12 @@
intptr_t* saved_bp) {
// called as a leaf from native code: do not block the JVM!
bool has_mh = (strstr(adaptername, "return/") == NULL); // return adapters don't have rcx_mh
+
intptr_t* last_sp = (intptr_t*) saved_bp[frame::interpreter_frame_last_sp_offset];
intptr_t* base_sp = last_sp;
typedef MethodHandles::RicochetFrame RicochetFrame;
RicochetFrame* rfp = (RicochetFrame*)((address)saved_bp - RicochetFrame::sender_link_offset_in_bytes());
- if (!UseRicochetFrames || Universe::heap()->is_in((address) rfp->saved_args_base())) {
+ if (Universe::heap()->is_in((address) rfp->saved_args_base())) {
// Probably an interpreter frame.
base_sp = (intptr_t*) saved_bp[frame::interpreter_frame_monitor_block_top_offset];
}
@@ -1030,13 +1053,64 @@
tty->cr();
if (last_sp != saved_sp && last_sp != NULL)
tty->print_cr("*** last_sp="PTR_FORMAT, (intptr_t)last_sp);
- int stack_dump_count = 16;
- if (stack_dump_count < (int)(saved_bp + 2 - saved_sp))
- stack_dump_count = (int)(saved_bp + 2 - saved_sp);
- if (stack_dump_count > 64) stack_dump_count = 48;
- for (i = 0; i < stack_dump_count; i += 4) {
- tty->print_cr(" dump at SP[%d] "PTR_FORMAT": "PTR_FORMAT" "PTR_FORMAT" "PTR_FORMAT" "PTR_FORMAT,
- i, (intptr_t) &entry_sp[i+0], entry_sp[i+0], entry_sp[i+1], entry_sp[i+2], entry_sp[i+3]);
+
+ {
+ // dumping last frame with frame::describe
+
+ JavaThread* p = JavaThread::active();
+
+ ResourceMark rm;
+ PRESERVE_EXCEPTION_MARK; // may not be needed by safer and unexpensive here
+ FrameValues values;
+
+ // Note: We want to allow trace_method_handle from any call site.
+ // While trace_method_handle creates a frame, it may be entered
+ // without a PC on the stack top (e.g. not just after a call).
+ // Walking that frame could lead to failures due to that invalid PC.
+ // => carefully detect that frame when doing the stack walking
+
+ // Current C frame
+ frame cur_frame = os::current_frame();
+
+ // Robust search of trace_calling_frame (independant of inlining).
+ // Assumes saved_regs comes from a pusha in the trace_calling_frame.
+ assert(cur_frame.sp() < saved_regs, "registers not saved on stack ?");
+ frame trace_calling_frame = os::get_sender_for_C_frame(&cur_frame);
+ while (trace_calling_frame.fp() < saved_regs) {
+ trace_calling_frame = os::get_sender_for_C_frame(&trace_calling_frame);
+ }
+
+ // safely create a frame and call frame::describe
+ intptr_t *dump_sp = trace_calling_frame.sender_sp();
+ intptr_t *dump_fp = trace_calling_frame.link();
+
+ bool walkable = has_mh; // whether the traced frame shoud be walkable
+
+ if (walkable) {
+ // The previous definition of walkable may have to be refined
+ // if new call sites cause the next frame constructor to start
+ // failing. Alternatively, frame constructors could be
+ // modified to support the current or future non walkable
+ // frames (but this is more intrusive and is not considered as
+ // part of this RFE, which will instead use a simpler output).
+ frame dump_frame = frame(dump_sp, dump_fp);
+ dump_frame.describe(values, 1);
+ } else {
+ // Stack may not be walkable (invalid PC above FP):
+ // Add descriptions without building a Java frame to avoid issues
+ values.describe(-1, dump_fp, "fp for #1 <not parsed, cannot trust pc>");
+ values.describe(-1, dump_sp, "sp for #1");
+ }
+
+ // mark saved_sp if seems valid
+ if (has_mh) {
+ if ((saved_sp >= dump_sp - UNREASONABLE_STACK_MOVE) && (saved_sp < dump_fp)) {
+ values.describe(-1, saved_sp, "*saved_sp");
+ }
+ }
+
+ tty->print_cr(" stack layout:");
+ values.print(p);
}
if (has_mh)
print_method_handle(mh);
@@ -1066,26 +1140,49 @@
void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) {
if (!TraceMethodHandles) return;
BLOCK_COMMENT("trace_method_handle {");
- __ push(rax);
- __ lea(rax, Address(rsp, wordSize * NOT_LP64(6) LP64_ONLY(14))); // entry_sp __ pusha();
+ __ enter();
+ __ andptr(rsp, -16); // align stack if needed for FPU state
__ pusha();
- __ mov(rbx, rsp);
- __ enter();
+ __ mov(rbx, rsp); // for retreiving saved_regs
+ // Note: saved_regs must be in the entered frame for the
+ // robust stack walking implemented in trace_method_handle_stub.
+
+ // save FP result, valid at some call sites (adapter_opt_return_float, ...)
+ __ increment(rsp, -2 * wordSize);
+ if (UseSSE >= 2) {
+ __ movdbl(Address(rsp, 0), xmm0);
+ } else if (UseSSE == 1) {
+ __ movflt(Address(rsp, 0), xmm0);
+ } else {
+ __ fst_d(Address(rsp, 0));
+ }
+
// incoming state:
// rcx: method handle
// r13 or rsi: saved sp
// To avoid calling convention issues, build a record on the stack and pass the pointer to that instead.
+ // Note: fix the increment below if pushing more arguments
__ push(rbp); // saved_bp
- __ push(rsi); // saved_sp
- __ push(rax); // entry_sp
+ __ push(saved_last_sp_register()); // saved_sp
+ __ push(rbp); // entry_sp (with extra align space)
__ push(rbx); // pusha saved_regs
__ push(rcx); // mh
- __ push(rcx); // adaptername
+ __ push(rcx); // slot for adaptername
__ movptr(Address(rsp, 0), (intptr_t) adaptername);
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub_wrapper), rsp);
- __ leave();
+ __ increment(rsp, 6 * wordSize); // MethodHandleStubArguments
+
+ if (UseSSE >= 2) {
+ __ movdbl(xmm0, Address(rsp, 0));
+ } else if (UseSSE == 1) {
+ __ movflt(xmm0, Address(rsp, 0));
+ } else {
+ __ fld_d(Address(rsp, 0));
+ }
+ __ increment(rsp, 2 * wordSize);
+
__ popa();
- __ pop(rax);
+ __ leave();
BLOCK_COMMENT("} trace_method_handle");
}
#endif //PRODUCT
@@ -1104,7 +1201,7 @@
|(1<<java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS)
//OP_COLLECT_ARGS is below...
|(1<<java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS)
- |(!UseRicochetFrames ? 0 :
+ |(
java_lang_invoke_MethodTypeForm::vmlayout_offset_in_bytes() <= 0 ? 0 :
((1<<java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF)
|(1<<java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS)
--- a/hotspot/src/cpu/x86/vm/methodHandles_x86.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -224,6 +224,8 @@
}
static void verify_clean(MacroAssembler* _masm) NOT_DEBUG_RETURN;
+
+ static void describe(const frame* fr, FrameValues& values, int frame_no) PRODUCT_RETURN;
};
// Additional helper methods for MethodHandles code generation:
--- a/hotspot/src/cpu/zero/vm/frame_zero.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/cpu/zero/vm/frame_zero.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -418,7 +418,7 @@
}
}
-#ifdef ASSERT
+#ifndef PRODUCT
void frame::describe_pd(FrameValues& values, int frame_no) {
--- a/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -72,6 +72,10 @@
return fp() + 1;
}
+inline intptr_t* frame::real_fp() const {
+ return fp();
+}
+
inline intptr_t* frame::link() const {
ShouldNotCallThis();
}
--- a/hotspot/src/cpu/zero/vm/methodHandles_zero.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/cpu/zero/vm/methodHandles_zero.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -29,43 +29,3 @@
adapter_code_size = 0
};
-#define TARGET_ARCH_NYI_6939861 1
-// ..#ifdef TARGET_ARCH_NYI_6939861
-// .. // Here are some backward compatible declarations until the 6939861 ports are updated.
-// .. #define _adapter_flyby (_EK_LIMIT + 10)
-// .. #define _adapter_ricochet (_EK_LIMIT + 11)
-// .. #define _adapter_opt_spread_1 _adapter_opt_spread_1_ref
-// .. #define _adapter_opt_spread_more _adapter_opt_spread_ref
-// .. enum {
-// .. _INSERT_NO_MASK = -1,
-// .. _INSERT_REF_MASK = 0,
-// .. _INSERT_INT_MASK = 1,
-// .. _INSERT_LONG_MASK = 3
-// .. };
-// .. static void get_ek_bound_mh_info(EntryKind ek, BasicType& arg_type, int& arg_mask, int& arg_slots) {
-// .. arg_type = ek_bound_mh_arg_type(ek);
-// .. arg_mask = 0;
-// .. arg_slots = type2size[arg_type];;
-// .. }
-// .. static void get_ek_adapter_opt_swap_rot_info(EntryKind ek, int& swap_bytes, int& rotate) {
-// .. int swap_slots = ek_adapter_opt_swap_slots(ek);
-// .. rotate = ek_adapter_opt_swap_mode(ek);
-// .. swap_bytes = swap_slots * Interpreter::stackElementSize;
-// .. }
-// .. static int get_ek_adapter_opt_spread_info(EntryKind ek) {
-// .. return ek_adapter_opt_spread_count(ek);
-// .. }
-// ..
-// .. static void insert_arg_slots(MacroAssembler* _masm,
-// .. RegisterOrConstant arg_slots,
-// .. int arg_mask,
-// .. Register argslot_reg,
-// .. Register temp_reg, Register temp2_reg, Register temp3_reg = noreg);
-// ..
-// .. static void remove_arg_slots(MacroAssembler* _masm,
-// .. RegisterOrConstant arg_slots,
-// .. Register argslot_reg,
-// .. Register temp_reg, Register temp2_reg, Register temp3_reg = noreg);
-// ..
-// .. static void trace_method_handle(MacroAssembler* _masm, const char* adaptername) PRODUCT_RETURN;
-// ..#endif //TARGET_ARCH_NYI_6939861
--- a/hotspot/src/os/bsd/vm/decoder_bsd.cpp Fri Jan 27 13:48:40 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 1997, 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 "prims/jvm.h"
-#include "utilities/decoder.hpp"
-
-#include <cxxabi.h>
-
-#ifdef __APPLE__
-
-void Decoder::initialize() {
- _initialized = true;
-}
-
-void Decoder::uninitialize() {
- _initialized = false;
-}
-
-bool Decoder::can_decode_C_frame_in_vm() {
- return false;
-}
-
-Decoder::decoder_status Decoder::decode(address addr, const char* filepath, char *buf, int buflen, int *offset) {
- return symbol_not_found;
-}
-
-
-#endif
-
-bool Decoder::demangle(const char* symbol, char *buf, int buflen) {
- int status;
- char* result;
- size_t size = (size_t)buflen;
-
- // Don't pass buf to __cxa_demangle. In case of the 'buf' is too small,
- // __cxa_demangle will call system "realloc" for additional memory, which
- // may use different malloc/realloc mechanism that allocates 'buf'.
- if ((result = abi::__cxa_demangle(symbol, NULL, NULL, &status)) != NULL) {
- jio_snprintf(buf, buflen, "%s", result);
- // call c library's free
- ::free(result);
- return true;
- }
- return false;
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os/bsd/vm/decoder_machO.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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"
+
+#ifdef __APPLE__
+#include "decoder_machO.hpp"
+#endif
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os/bsd/vm/decoder_machO.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef OS_BSD_VM_DECODER_MACHO_HPP
+#define OS_BSD_VM_DECODER_MACHO_HPP
+
+#ifdef __APPLE__
+
+#include "utilities/decoder.hpp"
+
+// Just a placehold for now
+class MachODecoder: public NullDecoder {
+public:
+ MachODecoder() { }
+ ~MachODecoder() { }
+};
+
+#endif
+
+#endif // OS_BSD_VM_DECODER_MACHO_HPP
+
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -301,6 +301,12 @@
#error Add appropriate cpu_arch setting
#endif
+// Compiler variant
+#ifdef COMPILER2
+#define COMPILER_VARIANT "server"
+#else
+#define COMPILER_VARIANT "client"
+#endif
#ifndef _ALLBSD_SOURCE
// pid_t gettid()
@@ -1920,7 +1926,7 @@
return true;
} else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
- dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
+ buf, buflen, offset, dlinfo.dli_fname)) {
return true;
}
}
@@ -2507,7 +2513,7 @@
static char saved_jvm_path[MAXPATHLEN] = {0};
-// Find the full path to the current module, libjvm.so or libjvm_g.so
+// Find the full path to the current module, libjvm or libjvm_g
void os::jvm_path(char *buf, jint buflen) {
// Error checking.
if (buflen < MAXPATHLEN) {
@@ -2532,11 +2538,11 @@
if (Arguments::created_by_gamma_launcher()) {
// Support for the gamma launcher. Typical value for buf is
- // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so". If "/jre/lib/" appears at
+ // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm". If "/jre/lib/" appears at
// the right place in the string, then assume we are installed in a JDK and
- // we're done. Otherwise, check for a JAVA_HOME environment variable and fix
- // up the path so it looks like libjvm.so is installed there (append a
- // fake suffix hotspot/libjvm.so).
+ // we're done. Otherwise, check for a JAVA_HOME environment variable and
+ // construct a path to the JVM being overridden.
+
const char *p = buf + strlen(buf) - 1;
for (int count = 0; p > buf && count < 5; ++count) {
for (--p; p > buf && *p != '/'; --p)
@@ -2550,7 +2556,7 @@
char* jrelib_p;
int len;
- // Check the current module name "libjvm.so" or "libjvm_g.so".
+ // Check the current module name "libjvm" or "libjvm_g".
p = strrchr(buf, '/');
assert(strstr(p, "/libjvm") == p, "invalid library name");
p = strstr(p, "_g") ? "_g" : "";
@@ -2563,19 +2569,32 @@
// modules image doesn't have "jre" subdirectory
len = strlen(buf);
jrelib_p = buf + len;
- snprintf(jrelib_p, buflen-len, "/jre/lib/%s", cpu_arch);
+
+ // Add the appropriate library subdir
+ snprintf(jrelib_p, buflen-len, "/jre/lib");
if (0 != access(buf, F_OK)) {
- snprintf(jrelib_p, buflen-len, "/lib/%s", cpu_arch);
+ snprintf(jrelib_p, buflen-len, "/lib");
}
+ // Add the appropriate client or server subdir
+ len = strlen(buf);
+ jrelib_p = buf + len;
+ snprintf(jrelib_p, buflen-len, "/%s", COMPILER_VARIANT);
+ if (0 != access(buf, F_OK)) {
+ snprintf(jrelib_p, buflen-len, "");
+ }
+
+ // If the path exists within JAVA_HOME, add the JVM library name
+ // to complete the path to JVM being overridden. Otherwise fallback
+ // to the path to the current library.
if (0 == access(buf, F_OK)) {
- // Use current module name "libjvm[_g].so" instead of
- // "libjvm"debug_only("_g")".so" since for fastdebug version
- // we should have "libjvm.so" but debug_only("_g") adds "_g"!
+ // Use current module name "libjvm[_g]" instead of
+ // "libjvm"debug_only("_g")"" since for fastdebug version
+ // we should have "libjvm" but debug_only("_g") adds "_g"!
len = strlen(buf);
- snprintf(buf + len, buflen-len, "/hotspot/libjvm%s.so", p);
+ snprintf(buf + len, buflen-len, "/libjvm%s%s", p, JNI_LIB_SUFFIX);
} else {
- // Go back to path of .so
+ // Fall back to path of current library
rp = realpath(dli_fname, buf);
if (rp == NULL)
return;
@@ -3570,26 +3589,28 @@
// It is only used when ThreadPriorityPolicy=1 and requires root privilege.
#if defined(_ALLBSD_SOURCE) && !defined(__APPLE__)
-int os::java_to_os_priority[MaxPriority + 1] = {
+int os::java_to_os_priority[CriticalPriority + 1] = {
19, // 0 Entry should never be used
0, // 1 MinPriority
3, // 2
6, // 3
- 10, // 4
- 15, // 5 NormPriority
- 18, // 6
-
- 21, // 7
- 25, // 8
- 28, // 9 NearMaxPriority
-
- 31 // 10 MaxPriority
+ 10, // 4
+ 15, // 5 NormPriority
+ 18, // 6
+
+ 21, // 7
+ 25, // 8
+ 28, // 9 NearMaxPriority
+
+ 31, // 10 MaxPriority
+
+ 31 // 11 CriticalPriority
};
#elif defined(__APPLE__)
/* Using Mach high-level priority assignments */
-int os::java_to_os_priority[MaxPriority + 1] = {
+int os::java_to_os_priority[CriticalPriority + 1] = {
0, // 0 Entry should never be used (MINPRI_USER)
27, // 1 MinPriority
@@ -3604,10 +3625,12 @@
34, // 8
35, // 9 NearMaxPriority
- 36 // 10 MaxPriority
+ 36, // 10 MaxPriority
+
+ 36 // 11 CriticalPriority
};
#else
-int os::java_to_os_priority[MaxPriority + 1] = {
+int os::java_to_os_priority[CriticalPriority + 1] = {
19, // 0 Entry should never be used
4, // 1 MinPriority
@@ -3622,7 +3645,9 @@
-3, // 8
-4, // 9 NearMaxPriority
- -5 // 10 MaxPriority
+ -5, // 10 MaxPriority
+
+ -5 // 11 CriticalPriority
};
#endif
@@ -3638,6 +3663,9 @@
ThreadPriorityPolicy = 0;
}
}
+ if (UseCriticalJavaThreadPriority) {
+ os::java_to_os_priority[MaxPriority] = os::java_to_os_priority[CriticalPriority];
+ }
return 0;
}
--- a/hotspot/src/os/linux/vm/decoder_linux.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/os/linux/vm/decoder_linux.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -23,11 +23,11 @@
*/
#include "prims/jvm.h"
-#include "utilities/decoder.hpp"
+#include "utilities/decoder_elf.hpp"
#include <cxxabi.h>
-bool Decoder::demangle(const char* symbol, char *buf, int buflen) {
+bool ElfDecoder::demangle(const char* symbol, char *buf, int buflen) {
int status;
char* result;
size_t size = (size_t)buflen;
@@ -43,3 +43,4 @@
}
return false;
}
+
--- a/hotspot/src/os/linux/vm/os_linux.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -1732,7 +1732,7 @@
return true;
} else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
- dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
+ buf, buflen, offset, dlinfo.dli_fname)) {
return true;
}
}
@@ -3383,7 +3383,7 @@
// this reason, the code should not be used as default (ThreadPriorityPolicy=0).
// It is only used when ThreadPriorityPolicy=1 and requires root privilege.
-int os::java_to_os_priority[MaxPriority + 1] = {
+int os::java_to_os_priority[CriticalPriority + 1] = {
19, // 0 Entry should never be used
4, // 1 MinPriority
@@ -3398,7 +3398,9 @@
-3, // 8
-4, // 9 NearMaxPriority
- -5 // 10 MaxPriority
+ -5, // 10 MaxPriority
+
+ -5 // 11 CriticalPriority
};
static int prio_init() {
@@ -3413,6 +3415,9 @@
ThreadPriorityPolicy = 0;
}
}
+ if (UseCriticalJavaThreadPriority) {
+ os::java_to_os_priority[MaxPriority] = os::java_to_os_priority[CriticalPriority];
+ }
return 0;
}
--- a/hotspot/src/os/posix/launcher/java_md.c Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/os/posix/launcher/java_md.c Sat Jan 28 22:21:54 2012 -0800
@@ -701,6 +701,14 @@
char libjava[MAXPATHLEN];
if (GetApplicationHome(path, pathsize)) {
+
+ /* Is the JRE universal, i.e. no arch dir? */
+ sprintf(libjava, "%s/jre/lib/" JAVA_DLL, path);
+ if (access(libjava, F_OK) == 0) {
+ strcat(path, "/jre");
+ goto found;
+ }
+
/* Is JRE co-located with the application? */
sprintf(libjava, "%s/lib/%s/" JAVA_DLL, path, arch);
if (access(libjava, F_OK) == 0) {
@@ -734,7 +742,7 @@
ifn->GetDefaultJavaVMInitArgs = JNI_GetDefaultJavaVMInitArgs;
return JNI_TRUE;
#else
- Dl_info dlinfo;
+ Dl_info dlinfo;
void *libjvm;
if (_launcher_debug) {
--- a/hotspot/src/os/solaris/vm/decoder_solaris.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/os/solaris/vm/decoder_solaris.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -22,10 +22,11 @@
*
*/
-#include "utilities/decoder.hpp"
+#include "utilities/decoder_elf.hpp"
#include <demangle.h>
-bool Decoder::demangle(const char* symbol, char *buf, int buflen) {
+bool ElfDecoder::demangle(const char* symbol, char *buf, int buflen) {
return !cplus_demangle(symbol, buf, (size_t)buflen);
}
+
--- a/hotspot/src/os/solaris/vm/osThread_solaris.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/os/solaris/vm/osThread_solaris.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -28,17 +28,17 @@
// This is embedded via include into the class OSThread
private:
-
- thread_t _thread_id; // Solaris thread id
- unsigned int _lwp_id; // lwp ID, only used with bound threads
- sigset_t _caller_sigmask; // Caller's signal mask
- bool _vm_created_thread; // true if the VM create this thread
- // false if primary thread or attached thread
+ thread_t _thread_id; // Solaris thread id
+ uint _lwp_id; // lwp ID, only used with bound threads
+ int _native_priority; // Saved native priority when starting
+ // a bound thread
+ sigset_t _caller_sigmask; // Caller's signal mask
+ bool _vm_created_thread; // true if the VM created this thread,
+ // false if primary thread or attached thread
public:
-
- thread_t thread_id() const { return _thread_id; }
-
- unsigned int lwp_id() const { return _lwp_id; }
+ thread_t thread_id() const { return _thread_id; }
+ uint lwp_id() const { return _lwp_id; }
+ int native_priority() const { return _native_priority; }
// Set and get state of _vm_created_thread flag
void set_vm_created() { _vm_created_thread = true; }
@@ -62,8 +62,9 @@
return true;
}
#endif
- void set_thread_id(thread_t id) { _thread_id = id; }
- void set_lwp_id(unsigned int id){ _lwp_id = id; }
+ void set_thread_id(thread_t id) { _thread_id = id; }
+ void set_lwp_id(uint id) { _lwp_id = id; }
+ void set_native_priority(int prio) { _native_priority = prio; }
// ***************************************************************
// interrupt support. interrupts (using signals) are used to get
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -114,6 +114,7 @@
# include <sys/rtpriocntl.h>
# include <sys/tspriocntl.h>
# include <sys/iapriocntl.h>
+# include <sys/fxpriocntl.h>
# include <sys/loadavg.h>
# include <string.h>
# include <stdio.h>
@@ -129,8 +130,8 @@
#ifdef _GNU_SOURCE
// See bug #6514594
extern "C" int madvise(caddr_t, size_t, int);
-extern "C" int memcntl(caddr_t addr, size_t len, int cmd, caddr_t arg,
- int attr, int mask);
+extern "C" int memcntl(caddr_t addr, size_t len, int cmd, caddr_t arg,
+ int attr, int mask);
#endif //_GNU_SOURCE
/*
@@ -215,8 +216,9 @@
#define MaximumPriority 127
// Values for ThreadPriorityPolicy == 1
-int prio_policy1[MaxPriority+1] = { -99999, 0, 16, 32, 48, 64,
- 80, 96, 112, 124, 127 };
+int prio_policy1[CriticalPriority+1] = {
+ -99999, 0, 16, 32, 48, 64,
+ 80, 96, 112, 124, 127, 127 };
// System parameters used internally
static clock_t clock_tics_per_sec = 100;
@@ -1048,15 +1050,22 @@
}
// If the creator called set priority before we started,
- // we need to call set priority now that we have an lwp.
- // Get the priority from libthread and set the priority
- // for the new Solaris lwp.
+ // we need to call set_native_priority now that we have an lwp.
+ // We used to get the priority from thr_getprio (we called
+ // thr_setprio way back in create_thread) and pass it to
+ // set_native_priority, but Solaris scales the priority
+ // in java_to_os_priority, so when we read it back here,
+ // we pass trash to set_native_priority instead of what's
+ // in java_to_os_priority. So we save the native priority
+ // in the osThread and recall it here.
+
if ( osthr->thread_id() != -1 ) {
if ( UseThreadPriorities ) {
- thr_getprio(osthr->thread_id(), &prio);
+ int prio = osthr->native_priority();
if (ThreadPriorityVerbose) {
- tty->print_cr("Starting Thread " INTPTR_FORMAT ", LWP is " INTPTR_FORMAT ", setting priority: %d\n",
- osthr->thread_id(), osthr->lwp_id(), prio );
+ tty->print_cr("Starting Thread " INTPTR_FORMAT ", LWP is "
+ INTPTR_FORMAT ", setting priority: %d\n",
+ osthr->thread_id(), osthr->lwp_id(), prio);
}
os::set_native_priority(thread, prio);
}
@@ -1353,13 +1362,12 @@
// Remember that we created this thread so we can set priority on it
osthread->set_vm_created();
- // Set the default thread priority otherwise use NormalPriority
-
- if ( UseThreadPriorities ) {
- thr_setprio(tid, (DefaultThreadPriority == -1) ?
+ // Set the default thread priority. If using bound threads, setting
+ // lwp priority will be delayed until thread start.
+ set_native_priority(thread,
+ DefaultThreadPriority == -1 ?
java_to_os_priority[NormPriority] :
DefaultThreadPriority);
- }
// Initial thread state is INITIALIZED, not SUSPENDED
osthread->set_state(INITIALIZED);
@@ -1997,7 +2005,7 @@
}
if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
- dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
+ buf, buflen, offset, dlinfo.dli_fname)) {
return true;
}
}
@@ -2015,7 +2023,7 @@
return true;
} else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
- dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
+ buf, buflen, offset, dlinfo.dli_fname)) {
return true;
}
}
@@ -3728,7 +3736,7 @@
} SchedInfo;
-static SchedInfo tsLimits, iaLimits, rtLimits;
+static SchedInfo tsLimits, iaLimits, rtLimits, fxLimits;
#ifdef ASSERT
static int ReadBackValidate = 1;
@@ -3739,6 +3747,8 @@
static int myCur = 0;
static bool priocntl_enable = false;
+static const int criticalPrio = 60; // FX/60 is critical thread class/priority on T4
+static int java_MaxPriority_to_os_priority = 0; // Saved mapping
// Call the version of priocntl suitable for all supported versions
// of Solaris. We need to call through this wrapper so that we can
@@ -3783,19 +3793,27 @@
if (os::Solaris::T2_libthread() || UseBoundThreads) {
// If ThreadPriorityPolicy is 1, switch tables
if (ThreadPriorityPolicy == 1) {
- for (i = 0 ; i < MaxPriority+1; i++)
+ for (i = 0 ; i < CriticalPriority+1; i++)
os::java_to_os_priority[i] = prio_policy1[i];
}
+ if (UseCriticalJavaThreadPriority) {
+ // MaxPriority always maps to the FX scheduling class and criticalPrio.
+ // See set_native_priority() and set_lwp_class_and_priority().
+ // Save original MaxPriority mapping in case attempt to
+ // use critical priority fails.
+ java_MaxPriority_to_os_priority = os::java_to_os_priority[MaxPriority];
+ // Set negative to distinguish from other priorities
+ os::java_to_os_priority[MaxPriority] = -criticalPrio;
+ }
}
// Not using Bound Threads, set to ThreadPolicy 1
else {
- for ( i = 0 ; i < MaxPriority+1; i++ ) {
+ for ( i = 0 ; i < CriticalPriority+1; i++ ) {
os::java_to_os_priority[i] = prio_policy1[i];
}
return 0;
}
-
// Get IDs for a set of well-known scheduling classes.
// TODO-FIXME: GETCLINFO returns the current # of classes in the
// the system. We should have a loop that iterates over the
@@ -3828,24 +3846,33 @@
rtLimits.maxPrio = ((rtinfo_t*)ClassInfo.pc_clinfo)->rt_maxpri;
rtLimits.minPrio = 0;
+ strcpy(ClassInfo.pc_clname, "FX");
+ ClassInfo.pc_cid = -1;
+ rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
+ if (rslt < 0) return errno;
+ assert(ClassInfo.pc_cid != -1, "cid for FX class is -1");
+ fxLimits.schedPolicy = ClassInfo.pc_cid;
+ fxLimits.maxPrio = ((fxinfo_t*)ClassInfo.pc_clinfo)->fx_maxupri;
+ fxLimits.minPrio = 0;
// Query our "current" scheduling class.
- // This will normally be IA,TS or, rarely, RT.
- memset (&ParmInfo, 0, sizeof(ParmInfo));
+ // This will normally be IA, TS or, rarely, FX or RT.
+ memset(&ParmInfo, 0, sizeof(ParmInfo));
ParmInfo.pc_cid = PC_CLNULL;
- rslt = (*priocntl_ptr) (PC_VERSION, P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo );
- if ( rslt < 0 ) return errno;
+ rslt = (*priocntl_ptr) (PC_VERSION, P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo);
+ if (rslt < 0) return errno;
myClass = ParmInfo.pc_cid;
// We now know our scheduling classId, get specific information
- // the class.
+ // about the class.
ClassInfo.pc_cid = myClass;
ClassInfo.pc_clname[0] = 0;
- rslt = (*priocntl_ptr) (PC_VERSION, (idtype)0, 0, PC_GETCLINFO, (caddr_t)&ClassInfo );
- if ( rslt < 0 ) return errno;
-
- if (ThreadPriorityVerbose)
- tty->print_cr ("lwp_priocntl_init: Class=%d(%s)...", myClass, ClassInfo.pc_clname);
+ rslt = (*priocntl_ptr) (PC_VERSION, (idtype)0, 0, PC_GETCLINFO, (caddr_t)&ClassInfo);
+ if (rslt < 0) return errno;
+
+ if (ThreadPriorityVerbose) {
+ tty->print_cr("lwp_priocntl_init: Class=%d(%s)...", myClass, ClassInfo.pc_clname);
+ }
memset(&ParmInfo, 0, sizeof(pcparms_t));
ParmInfo.pc_cid = PC_CLNULL;
@@ -3865,6 +3892,11 @@
myMin = tsLimits.minPrio;
myMax = tsLimits.maxPrio;
myMax = MIN2(myMax, (int)tsInfo->ts_uprilim); // clamp - restrict
+ } else if (ParmInfo.pc_cid == fxLimits.schedPolicy) {
+ fxparms_t *fxInfo = (fxparms_t*)ParmInfo.pc_clparms;
+ myMin = fxLimits.minPrio;
+ myMax = fxLimits.maxPrio;
+ myMax = MIN2(myMax, (int)fxInfo->fx_uprilim); // clamp - restrict
} else {
// No clue - punt
if (ThreadPriorityVerbose)
@@ -3872,8 +3904,9 @@
return EINVAL; // no clue, punt
}
- if (ThreadPriorityVerbose)
- tty->print_cr ("Thread priority Range: [%d..%d]\n", myMin, myMax);
+ if (ThreadPriorityVerbose) {
+ tty->print_cr ("Thread priority Range: [%d..%d]\n", myMin, myMax);
+ }
priocntl_enable = true; // Enable changing priorities
return 0;
@@ -3882,6 +3915,7 @@
#define IAPRI(x) ((iaparms_t *)((x).pc_clparms))
#define RTPRI(x) ((rtparms_t *)((x).pc_clparms))
#define TSPRI(x) ((tsparms_t *)((x).pc_clparms))
+#define FXPRI(x) ((fxparms_t *)((x).pc_clparms))
// scale_to_lwp_priority
@@ -3900,13 +3934,13 @@
}
-// set_lwp_priority
+// set_lwp_class_and_priority
//
-// Set the priority of the lwp. This call should only be made
-// when using bound threads (T2 threads are bound by default).
+// Set the class and priority of the lwp. This call should only
+// be made when using bound threads (T2 threads are bound by default).
//
-int set_lwp_priority (int ThreadID, int lwpid, int newPrio )
-{
+int set_lwp_class_and_priority(int ThreadID, int lwpid,
+ int newPrio, int new_class, bool scale) {
int rslt;
int Actual, Expected, prv;
pcparms_t ParmInfo; // for GET-SET
@@ -3927,19 +3961,20 @@
return EINVAL;
}
-
// If lwp hasn't started yet, just return
// the _start routine will call us again.
if ( lwpid <= 0 ) {
if (ThreadPriorityVerbose) {
- tty->print_cr ("deferring the set_lwp_priority of thread " INTPTR_FORMAT " to %d, lwpid not set",
+ tty->print_cr ("deferring the set_lwp_class_and_priority of thread "
+ INTPTR_FORMAT " to %d, lwpid not set",
ThreadID, newPrio);
}
return 0;
}
if (ThreadPriorityVerbose) {
- tty->print_cr ("set_lwp_priority(" INTPTR_FORMAT "@" INTPTR_FORMAT " %d) ",
+ tty->print_cr ("set_lwp_class_and_priority("
+ INTPTR_FORMAT "@" INTPTR_FORMAT " %d) ",
ThreadID, lwpid, newPrio);
}
@@ -3948,40 +3983,70 @@
rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ParmInfo);
if (rslt < 0) return errno;
- if (ParmInfo.pc_cid == rtLimits.schedPolicy) {
+ int cur_class = ParmInfo.pc_cid;
+ ParmInfo.pc_cid = (id_t)new_class;
+
+ if (new_class == rtLimits.schedPolicy) {
rtparms_t *rtInfo = (rtparms_t*)ParmInfo.pc_clparms;
- rtInfo->rt_pri = scale_to_lwp_priority (rtLimits.minPrio, rtLimits.maxPrio, newPrio);
+ rtInfo->rt_pri = scale ? scale_to_lwp_priority(rtLimits.minPrio,
+ rtLimits.maxPrio, newPrio)
+ : newPrio;
rtInfo->rt_tqsecs = RT_NOCHANGE;
rtInfo->rt_tqnsecs = RT_NOCHANGE;
if (ThreadPriorityVerbose) {
tty->print_cr("RT: %d->%d\n", newPrio, rtInfo->rt_pri);
}
- } else if (ParmInfo.pc_cid == iaLimits.schedPolicy) {
- iaparms_t *iaInfo = (iaparms_t*)ParmInfo.pc_clparms;
- int maxClamped = MIN2(iaLimits.maxPrio, (int)iaInfo->ia_uprilim);
- iaInfo->ia_upri = scale_to_lwp_priority(iaLimits.minPrio, maxClamped, newPrio);
- iaInfo->ia_uprilim = IA_NOCHANGE;
+ } else if (new_class == iaLimits.schedPolicy) {
+ iaparms_t* iaInfo = (iaparms_t*)ParmInfo.pc_clparms;
+ int maxClamped = MIN2(iaLimits.maxPrio,
+ cur_class == new_class
+ ? (int)iaInfo->ia_uprilim : iaLimits.maxPrio);
+ iaInfo->ia_upri = scale ? scale_to_lwp_priority(iaLimits.minPrio,
+ maxClamped, newPrio)
+ : newPrio;
+ iaInfo->ia_uprilim = cur_class == new_class
+ ? IA_NOCHANGE : (pri_t)iaLimits.maxPrio;
iaInfo->ia_mode = IA_NOCHANGE;
+ iaInfo->ia_nice = cur_class == new_class ? IA_NOCHANGE : NZERO;
if (ThreadPriorityVerbose) {
- tty->print_cr ("IA: [%d...%d] %d->%d\n",
- iaLimits.minPrio, maxClamped, newPrio, iaInfo->ia_upri);
+ tty->print_cr("IA: [%d...%d] %d->%d\n",
+ iaLimits.minPrio, maxClamped, newPrio, iaInfo->ia_upri);
}
- } else if (ParmInfo.pc_cid == tsLimits.schedPolicy) {
- tsparms_t *tsInfo = (tsparms_t*)ParmInfo.pc_clparms;
- int maxClamped = MIN2(tsLimits.maxPrio, (int)tsInfo->ts_uprilim);
- prv = tsInfo->ts_upri;
- tsInfo->ts_upri = scale_to_lwp_priority(tsLimits.minPrio, maxClamped, newPrio);
- tsInfo->ts_uprilim = IA_NOCHANGE;
+ } else if (new_class == tsLimits.schedPolicy) {
+ tsparms_t* tsInfo = (tsparms_t*)ParmInfo.pc_clparms;
+ int maxClamped = MIN2(tsLimits.maxPrio,
+ cur_class == new_class
+ ? (int)tsInfo->ts_uprilim : tsLimits.maxPrio);
+ tsInfo->ts_upri = scale ? scale_to_lwp_priority(tsLimits.minPrio,
+ maxClamped, newPrio)
+ : newPrio;
+ tsInfo->ts_uprilim = cur_class == new_class
+ ? TS_NOCHANGE : (pri_t)tsLimits.maxPrio;
if (ThreadPriorityVerbose) {
- tty->print_cr ("TS: %d [%d...%d] %d->%d\n",
- prv, tsLimits.minPrio, maxClamped, newPrio, tsInfo->ts_upri);
+ tty->print_cr("TS: [%d...%d] %d->%d\n",
+ tsLimits.minPrio, maxClamped, newPrio, tsInfo->ts_upri);
}
- if (prv == tsInfo->ts_upri) return 0;
+ } else if (new_class == fxLimits.schedPolicy) {
+ fxparms_t* fxInfo = (fxparms_t*)ParmInfo.pc_clparms;
+ int maxClamped = MIN2(fxLimits.maxPrio,
+ cur_class == new_class
+ ? (int)fxInfo->fx_uprilim : fxLimits.maxPrio);
+ fxInfo->fx_upri = scale ? scale_to_lwp_priority(fxLimits.minPrio,
+ maxClamped, newPrio)
+ : newPrio;
+ fxInfo->fx_uprilim = cur_class == new_class
+ ? FX_NOCHANGE : (pri_t)fxLimits.maxPrio;
+ fxInfo->fx_tqsecs = FX_NOCHANGE;
+ fxInfo->fx_tqnsecs = FX_NOCHANGE;
+ if (ThreadPriorityVerbose) {
+ tty->print_cr("FX: [%d...%d] %d->%d\n",
+ fxLimits.minPrio, maxClamped, newPrio, fxInfo->fx_upri);
+ }
} else {
- if ( ThreadPriorityVerbose ) {
- tty->print_cr ("Unknown scheduling class\n");
+ if (ThreadPriorityVerbose) {
+ tty->print_cr("Unknown new scheduling class %d\n", new_class);
}
- return EINVAL; // no clue, punt
+ return EINVAL; // no clue, punt
}
rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_SETPARMS, (caddr_t)&ParmInfo);
@@ -4016,16 +4081,20 @@
} else if (ParmInfo.pc_cid == tsLimits.schedPolicy) {
Actual = TSPRI(ReadBack)->ts_upri;
Expected = TSPRI(ParmInfo)->ts_upri;
+ } else if (ParmInfo.pc_cid == fxLimits.schedPolicy) {
+ Actual = FXPRI(ReadBack)->fx_upri;
+ Expected = FXPRI(ParmInfo)->fx_upri;
} else {
- if ( ThreadPriorityVerbose ) {
- tty->print_cr("set_lwp_priority: unexpected class in readback: %d\n", ParmInfo.pc_cid);
+ if (ThreadPriorityVerbose) {
+ tty->print_cr("set_lwp_class_and_priority: unexpected class in readback: %d\n",
+ ParmInfo.pc_cid);
}
}
if (Actual != Expected) {
- if ( ThreadPriorityVerbose ) {
- tty->print_cr ("set_lwp_priority(%d %d) Class=%d: actual=%d vs expected=%d\n",
- lwpid, newPrio, ReadBack.pc_cid, Actual, Expected);
+ if (ThreadPriorityVerbose) {
+ tty->print_cr ("set_lwp_class_and_priority(%d %d) Class=%d: actual=%d vs expected=%d\n",
+ lwpid, newPrio, ReadBack.pc_cid, Actual, Expected);
}
}
#endif
@@ -4033,8 +4102,6 @@
return 0;
}
-
-
// Solaris only gives access to 128 real priorities at a time,
// so we expand Java's ten to fill this range. This would be better
// if we dynamically adjusted relative priorities.
@@ -4055,8 +4122,7 @@
// which do not explicitly alter their thread priorities.
//
-
-int os::java_to_os_priority[MaxPriority + 1] = {
+int os::java_to_os_priority[CriticalPriority + 1] = {
-99999, // 0 Entry should never be used
0, // 1 MinPriority
@@ -4071,17 +4137,51 @@
127, // 8
127, // 9 NearMaxPriority
- 127 // 10 MaxPriority
+ 127, // 10 MaxPriority
+
+ -criticalPrio // 11 CriticalPriority
};
-
OSReturn os::set_native_priority(Thread* thread, int newpri) {
+ OSThread* osthread = thread->osthread();
+
+ // Save requested priority in case the thread hasn't been started
+ osthread->set_native_priority(newpri);
+
+ // Check for critical priority request
+ bool fxcritical = false;
+ if (newpri == -criticalPrio) {
+ fxcritical = true;
+ newpri = criticalPrio;
+ }
+
assert(newpri >= MinimumPriority && newpri <= MaximumPriority, "bad priority mapping");
- if ( !UseThreadPriorities ) return OS_OK;
- int status = thr_setprio(thread->osthread()->thread_id(), newpri);
- if ( os::Solaris::T2_libthread() || (UseBoundThreads && thread->osthread()->is_vm_created()) )
- status |= (set_lwp_priority (thread->osthread()->thread_id(),
- thread->osthread()->lwp_id(), newpri ));
+ if (!UseThreadPriorities) return OS_OK;
+
+ int status = 0;
+
+ if (!fxcritical) {
+ // Use thr_setprio only if we have a priority that thr_setprio understands
+ status = thr_setprio(thread->osthread()->thread_id(), newpri);
+ }
+
+ if (os::Solaris::T2_libthread() ||
+ (UseBoundThreads && osthread->is_vm_created())) {
+ int lwp_status =
+ set_lwp_class_and_priority(osthread->thread_id(),
+ osthread->lwp_id(),
+ newpri,
+ fxcritical ? fxLimits.schedPolicy : myClass,
+ !fxcritical);
+ if (lwp_status != 0 && fxcritical) {
+ // Try again, this time without changing the scheduling class
+ newpri = java_MaxPriority_to_os_priority;
+ lwp_status = set_lwp_class_and_priority(osthread->thread_id(),
+ osthread->lwp_id(),
+ newpri, myClass, false);
+ }
+ status |= lwp_status;
+ }
return (status == 0) ? OS_OK : OS_ERR;
}
--- a/hotspot/src/os/windows/vm/decoder_windows.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/os/windows/vm/decoder_windows.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,22 +24,24 @@
#include "precompiled.hpp"
#include "prims/jvm.h"
-#include "runtime/os.hpp"
-#include "utilities/decoder.hpp"
+#include "decoder_windows.hpp"
+
+WindowsDecoder::WindowsDecoder() {
+ _dbghelp_handle = NULL;
+ _can_decode_in_vm = false;
+ _pfnSymGetSymFromAddr64 = NULL;
+ _pfnUndecorateSymbolName = NULL;
-HMODULE Decoder::_dbghelp_handle = NULL;
-bool Decoder::_can_decode_in_vm = false;
-pfn_SymGetSymFromAddr64 Decoder::_pfnSymGetSymFromAddr64 = NULL;
-pfn_UndecorateSymbolName Decoder::_pfnUndecorateSymbolName = NULL;
+ _decoder_status = no_error;
+ initialize();
+}
-void Decoder::initialize() {
- if (!_initialized) {
- _initialized = true;
-
- HINSTANCE handle = os::win32::load_Windows_dll("dbghelp.dll", NULL, 0);
+void WindowsDecoder::initialize() {
+ if (!has_error() && _dbghelp_handle == NULL) {
+ HMODULE handle = ::LoadLibrary("dbghelp.dll");
if (!handle) {
_decoder_status = helper_not_found;
- return;
+ return;
}
_dbghelp_handle = handle;
@@ -70,32 +72,29 @@
// find out if jvm.dll contains private symbols, by decoding
// current function and comparing the result
- address addr = (address)Decoder::initialize;
+ address addr = (address)Decoder::decode;
char buf[MAX_PATH];
- if (decode(addr, buf, sizeof(buf), NULL) == no_error) {
- _can_decode_in_vm = !strcmp(buf, "Decoder::initialize");
+ if (decode(addr, buf, sizeof(buf), NULL)) {
+ _can_decode_in_vm = !strcmp(buf, "Decoder::decode");
}
}
}
-void Decoder::uninitialize() {
- assert(_initialized, "Decoder not yet initialized");
+void WindowsDecoder::uninitialize() {
_pfnSymGetSymFromAddr64 = NULL;
_pfnUndecorateSymbolName = NULL;
if (_dbghelp_handle != NULL) {
::FreeLibrary(_dbghelp_handle);
}
- _initialized = false;
+ _dbghelp_handle = NULL;
}
-bool Decoder::can_decode_C_frame_in_vm() {
- initialize();
- return _can_decode_in_vm;
+bool WindowsDecoder::can_decode_C_frame_in_vm() const {
+ return (!has_error() && _can_decode_in_vm);
}
-Decoder::decoder_status Decoder::decode(address addr, char *buf, int buflen, int *offset) {
- assert(_initialized, "Decoder not yet initialized");
+bool WindowsDecoder::decode(address addr, char *buf, int buflen, int* offset, const char* modulepath) {
if (_pfnSymGetSymFromAddr64 != NULL) {
PIMAGEHLP_SYMBOL64 pSymbol;
char symbolInfo[MAX_PATH + sizeof(IMAGEHLP_SYMBOL64)];
@@ -105,19 +104,20 @@
DWORD64 displacement;
if (_pfnSymGetSymFromAddr64(::GetCurrentProcess(), (DWORD64)addr, &displacement, pSymbol)) {
if (buf != NULL) {
- if (!demangle(pSymbol->Name, buf, buflen)) {
+ if (demangle(pSymbol->Name, buf, buflen)) {
jio_snprintf(buf, buflen, "%s", pSymbol->Name);
}
}
- if (offset != NULL) *offset = (int)displacement;
- return no_error;
+ if(offset != NULL) *offset = (int)displacement;
+ return true;
}
}
- return helper_not_found;
+ if (buf != NULL && buflen > 0) buf[0] = '\0';
+ if (offset != NULL) *offset = -1;
+ return false;
}
-bool Decoder::demangle(const char* symbol, char *buf, int buflen) {
- assert(_initialized, "Decoder not yet initialized");
+bool WindowsDecoder::demangle(const char* symbol, char *buf, int buflen) {
return _pfnUndecorateSymbolName != NULL &&
_pfnUndecorateSymbolName(symbol, buf, buflen, UNDNAME_COMPLETE);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os/windows/vm/decoder_windows.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef OS_WINDOWS_VM_DECODER_WINDOWS_HPP
+#define OS_WINDOWS_VM_DECIDER_WINDOWS_HPP
+
+#include <windows.h>
+#include <imagehlp.h>
+
+#include "utilities/decoder.hpp"
+
+// functions needed for decoding symbols
+typedef DWORD (WINAPI *pfn_SymSetOptions)(DWORD);
+typedef BOOL (WINAPI *pfn_SymInitialize)(HANDLE, PCTSTR, BOOL);
+typedef BOOL (WINAPI *pfn_SymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64);
+typedef DWORD (WINAPI *pfn_UndecorateSymbolName)(const char*, char*, DWORD, DWORD);
+
+class WindowsDecoder: public NullDecoder {
+
+public:
+ WindowsDecoder();
+ ~WindowsDecoder() { uninitialize(); };
+
+ bool can_decode_C_frame_in_vm() const;
+ bool demangle(const char* symbol, char *buf, int buflen);
+ bool decode(address addr, char *buf, int buflen, int* offset, const char* modulepath = NULL);
+
+private:
+ void initialize();
+ void uninitialize();
+
+private:
+ HMODULE _dbghelp_handle;
+ bool _can_decode_in_vm;
+ pfn_SymGetSymFromAddr64 _pfnSymGetSymFromAddr64;
+ pfn_UndecorateSymbolName _pfnUndecorateSymbolName;
+};
+
+#endif // OS_WINDOWS_VM_DECODER_WINDOWS_HPP
+
--- a/hotspot/src/os/windows/vm/os_windows.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -1391,7 +1391,7 @@
bool os::dll_address_to_function_name(address addr, char *buf,
int buflen, int *offset) {
- if (Decoder::decode(addr, buf, buflen, offset) == Decoder::no_error) {
+ if (Decoder::decode(addr, buf, buflen, offset)) {
return true;
}
if (offset != NULL) *offset = -1;
@@ -3296,7 +3296,7 @@
// so we compress Java's ten down to seven. It would be better
// if we dynamically adjusted relative priorities.
-int os::java_to_os_priority[MaxPriority + 1] = {
+int os::java_to_os_priority[CriticalPriority + 1] = {
THREAD_PRIORITY_IDLE, // 0 Entry should never be used
THREAD_PRIORITY_LOWEST, // 1 MinPriority
THREAD_PRIORITY_LOWEST, // 2
@@ -3307,10 +3307,11 @@
THREAD_PRIORITY_ABOVE_NORMAL, // 7
THREAD_PRIORITY_ABOVE_NORMAL, // 8
THREAD_PRIORITY_HIGHEST, // 9 NearMaxPriority
- THREAD_PRIORITY_HIGHEST // 10 MaxPriority
+ THREAD_PRIORITY_HIGHEST, // 10 MaxPriority
+ THREAD_PRIORITY_HIGHEST // 11 CriticalPriority
};
-int prio_policy1[MaxPriority + 1] = {
+int prio_policy1[CriticalPriority + 1] = {
THREAD_PRIORITY_IDLE, // 0 Entry should never be used
THREAD_PRIORITY_LOWEST, // 1 MinPriority
THREAD_PRIORITY_LOWEST, // 2
@@ -3321,17 +3322,21 @@
THREAD_PRIORITY_ABOVE_NORMAL, // 7
THREAD_PRIORITY_HIGHEST, // 8
THREAD_PRIORITY_HIGHEST, // 9 NearMaxPriority
- THREAD_PRIORITY_TIME_CRITICAL // 10 MaxPriority
+ THREAD_PRIORITY_TIME_CRITICAL, // 10 MaxPriority
+ THREAD_PRIORITY_TIME_CRITICAL // 11 CriticalPriority
};
static int prio_init() {
// If ThreadPriorityPolicy is 1, switch tables
if (ThreadPriorityPolicy == 1) {
int i;
- for (i = 0; i < MaxPriority + 1; i++) {
+ for (i = 0; i < CriticalPriority + 1; i++) {
os::java_to_os_priority[i] = prio_policy1[i];
}
}
+ if (UseCriticalJavaThreadPriority) {
+ os::java_to_os_priority[MaxPriority] = os::java_to_os_priority[CriticalPriority] ;
+ }
return 0;
}
--- a/hotspot/src/share/vm/c1/c1_LIR.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/c1/c1_LIR.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -1354,9 +1354,10 @@
CodeStub* _stub; // if this is a branch to a stub, this is the stub
public:
- LIR_OpBranch(LIR_Condition cond, Label* lbl)
+ LIR_OpBranch(LIR_Condition cond, BasicType type, Label* lbl)
: LIR_Op(lir_branch, LIR_OprFact::illegalOpr, (CodeEmitInfo*) NULL)
, _cond(cond)
+ , _type(type)
, _label(lbl)
, _block(NULL)
, _ublock(NULL)
@@ -2053,7 +2054,7 @@
void jump(CodeStub* stub) {
append(new LIR_OpBranch(lir_cond_always, T_ILLEGAL, stub));
}
- void branch(LIR_Condition cond, Label* lbl) { append(new LIR_OpBranch(cond, lbl)); }
+ void branch(LIR_Condition cond, BasicType type, Label* lbl) { append(new LIR_OpBranch(cond, type, lbl)); }
void branch(LIR_Condition cond, BasicType type, BlockBegin* block) {
assert(type != T_FLOAT && type != T_DOUBLE, "no fp comparisons");
append(new LIR_OpBranch(cond, type, block));
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -2350,7 +2350,7 @@
} else {
LabelObj* L = new LabelObj();
__ cmp(lir_cond_less, value, low_key);
- __ branch(lir_cond_less, L->label());
+ __ branch(lir_cond_less, T_INT, L->label());
__ cmp(lir_cond_lessEqual, value, high_key);
__ branch(lir_cond_lessEqual, T_INT, dest);
__ branch_destination(L->label());
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -413,8 +413,9 @@
}
bci = branch_bci + offset;
}
-
+ assert(!HAS_PENDING_EXCEPTION, "Should not have any exceptions pending");
osr_nm = CompilationPolicy::policy()->event(enclosing_method, method, branch_bci, bci, level, nm, THREAD);
+ assert(!HAS_PENDING_EXCEPTION, "Event handler should not throw any exceptions");
return osr_nm;
}
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -1347,7 +1347,13 @@
return _backtrace();
}
- inline void push(methodOop method, short bci, TRAPS) {
+ inline void push(methodOop method, int bci, TRAPS) {
+ // Smear the -1 bci to 0 since the array only holds unsigned
+ // shorts. The later line number lookup would just smear the -1
+ // to a 0 even if it could be recorded.
+ if (bci == SynchronizationEntryBCI) bci = 0;
+ assert(bci == (jushort)bci, "doesn't fit");
+
if (_index >= trace_chunk_size) {
methodHandle mhandle(THREAD, method);
expand(CHECK);
@@ -1574,8 +1580,13 @@
int chunk_count = 0;
for (;!st.at_end(); st.next()) {
- // add element
- bcis->ushort_at_put(chunk_count, st.bci());
+ // Add entry and smear the -1 bci to 0 since the array only holds
+ // unsigned shorts. The later line number lookup would just smear
+ // the -1 to a 0 even if it could be recorded.
+ int bci = st.bci();
+ if (bci == SynchronizationEntryBCI) bci = 0;
+ assert(bci == (jushort)bci, "doesn't fit");
+ bcis->ushort_at_put(chunk_count, bci);
methods->obj_at_put(chunk_count, st.method());
chunk_count++;
--- a/hotspot/src/share/vm/classfile/symbolTable.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/classfile/symbolTable.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -204,6 +204,24 @@
return s;
}
+// Look up the address of the literal in the SymbolTable for this Symbol*
+// Do not create any new symbols
+// Do not increment the reference count to keep this alive
+Symbol** SymbolTable::lookup_symbol_addr(Symbol* sym){
+ unsigned int hash = hash_symbol((char*)sym->bytes(), sym->utf8_length());
+ int index = the_table()->hash_to_index(hash);
+
+ for (HashtableEntry<Symbol*>* e = the_table()->bucket(index); e != NULL; e = e->next()) {
+ if (e->hash() == hash) {
+ Symbol* literal_sym = e->literal();
+ if (sym == literal_sym) {
+ return e->literal_addr();
+ }
+ }
+ }
+ return NULL;
+}
+
// Suggestion: Push unicode-based lookup all the way into the hashing
// and probing logic, so there is no need for convert_to_utf8 until
// an actual new Symbol* is created.
--- a/hotspot/src/share/vm/classfile/symbolTable.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/classfile/symbolTable.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -144,6 +144,9 @@
static void release(Symbol* sym);
+ // Look up the address of the literal in the SymbolTable for this Symbol*
+ static Symbol** lookup_symbol_addr(Symbol* sym);
+
// jchar (utf16) version of lookups
static Symbol* lookup_unicode(const jchar* name, int len, TRAPS);
static Symbol* lookup_only_unicode(const jchar* name, int len, unsigned int& hash);
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -2131,6 +2131,12 @@
}
}
+ // Assign a classid if one has not already been assigned. The
+ // counter does not need to be atomically incremented since this
+ // is only done while holding the SystemDictionary_lock.
+ // All loaded classes get a unique ID.
+ TRACE_INIT_ID(k);
+
// Check for a placeholder. If there, remove it and make a
// new system dictionary entry.
placeholders()->find_and_remove(p_index, p_hash, name, class_loader, THREAD);
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -855,23 +855,23 @@
// Note that this only sets the JavaThread _priority field, which by
// definition is limited to Java priorities and not OS priorities.
// The os-priority is set in the CompilerThread startup code itself
+
java_lang_Thread::set_priority(thread_oop(), NearMaxPriority);
- // CLEANUP PRIORITIES: This -if- statement hids a bug whereby the compiler
- // threads never have their OS priority set. The assumption here is to
- // enable the Performance group to do flag tuning, figure out a suitable
- // CompilerThreadPriority, and then remove this 'if' statement (and
- // comment) and unconditionally set the priority.
+
+ // Note that we cannot call os::set_priority because it expects Java
+ // priorities and we are *explicitly* using OS priorities so that it's
+ // possible to set the compiler thread priority higher than any Java
+ // thread.
- // Compiler Threads should be at the highest Priority
- if ( CompilerThreadPriority != -1 )
- os::set_native_priority( compiler_thread, CompilerThreadPriority );
- else
- os::set_native_priority( compiler_thread, os::java_to_os_priority[NearMaxPriority]);
-
- // Note that I cannot call os::set_priority because it expects Java
- // priorities and I am *explicitly* using OS priorities so that it's
- // possible to set the compiler thread priority higher than any Java
- // thread.
+ int native_prio = CompilerThreadPriority;
+ if (native_prio == -1) {
+ if (UseCriticalCompilerThreadPriority) {
+ native_prio = os::java_to_os_priority[CriticalPriority];
+ } else {
+ native_prio = os::java_to_os_priority[NearMaxPriority];
+ }
+ }
+ os::set_native_priority(compiler_thread, native_prio);
java_lang_Thread::set_daemon(thread_oop());
@@ -879,6 +879,7 @@
Threads::add(compiler_thread);
Thread::start(compiler_thread);
}
+
// Let go of Threads_lock before yielding
os::yield(); // make sure that the compiler thread is started early (especially helpful on SOLARIS)
@@ -961,7 +962,7 @@
methodHandle hot_method,
int hot_count,
const char* comment,
- TRAPS) {
+ Thread* thread) {
// do nothing if compiler thread(s) is not available
if (!_initialized ) {
return;
@@ -1037,7 +1038,7 @@
// Acquire our lock.
{
- MutexLocker locker(queue->lock(), THREAD);
+ MutexLocker locker(queue->lock(), thread);
// Make sure the method has not slipped into the queues since
// last we checked; note that those checks were "fast bail-outs".
@@ -1119,7 +1120,7 @@
nmethod* CompileBroker::compile_method(methodHandle method, int osr_bci,
int comp_level,
methodHandle hot_method, int hot_count,
- const char* comment, TRAPS) {
+ const char* comment, Thread* THREAD) {
// make sure arguments make sense
assert(method->method_holder()->klass_part()->oop_is_instance(), "not an instance method");
assert(osr_bci == InvocationEntryBci || (0 <= osr_bci && osr_bci < method->code_size()), "bci out of range");
@@ -1173,10 +1174,10 @@
assert(!HAS_PENDING_EXCEPTION, "No exception should be present");
// some prerequisites that are compiler specific
if (compiler(comp_level)->is_c2() || compiler(comp_level)->is_shark()) {
- method->constants()->resolve_string_constants(CHECK_0);
+ method->constants()->resolve_string_constants(CHECK_AND_CLEAR_NULL);
// Resolve all classes seen in the signature of the method
// we are compiling.
- methodOopDesc::load_signature_classes(method, CHECK_0);
+ methodOopDesc::load_signature_classes(method, CHECK_AND_CLEAR_NULL);
}
// If the method is native, do the lookup in the thread requesting
@@ -1230,7 +1231,7 @@
return NULL;
}
} else {
- compile_method_base(method, osr_bci, comp_level, hot_method, hot_count, comment, CHECK_0);
+ compile_method_base(method, osr_bci, comp_level, hot_method, hot_count, comment, THREAD);
}
// return requested nmethod
--- a/hotspot/src/share/vm/compiler/compileBroker.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/compiler/compileBroker.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -333,7 +333,7 @@
methodHandle hot_method,
int hot_count,
const char* comment,
- TRAPS);
+ Thread* thread);
static CompileQueue* compile_queue(int comp_level) {
if (is_c2_compile(comp_level)) return _c2_method_queue;
if (is_c1_compile(comp_level)) return _c1_method_queue;
@@ -363,7 +363,7 @@
int comp_level,
methodHandle hot_method,
int hot_count,
- const char* comment, TRAPS);
+ const char* comment, Thread* thread);
static void compiler_thread_loop();
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -75,10 +75,25 @@
set_name("Concurrent Mark-Sweep GC Thread");
if (os::create_thread(this, os::cgc_thread)) {
- // XXX: need to set this to low priority
- // unless "agressive mode" set; priority
- // should be just less than that of VMThread.
- os::set_priority(this, NearMaxPriority);
+ // An old comment here said: "Priority should be just less
+ // than that of VMThread". Since the VMThread runs at
+ // NearMaxPriority, the old comment was inaccurate, but
+ // changing the default priority to NearMaxPriority-1
+ // could change current behavior, so the default of
+ // NearMaxPriority stays in place.
+ //
+ // Note that there's a possibility of the VMThread
+ // starving if UseCriticalCMSThreadPriority is on.
+ // That won't happen on Solaris for various reasons,
+ // but may well happen on non-Solaris platforms.
+ int native_prio;
+ if (UseCriticalCMSThreadPriority) {
+ native_prio = os::java_to_os_priority[CriticalPriority];
+ } else {
+ native_prio = os::java_to_os_priority[NearMaxPriority];
+ }
+ os::set_native_priority(this, native_prio);
+
if (!DisableStartThread) {
os::start_thread(this);
}
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -42,8 +42,7 @@
#include "runtime/handles.inline.hpp"
#include "runtime/java.hpp"
-//
-// CMS Bit Map Wrapper
+// Concurrent marking bit map wrapper
CMBitMapRO::CMBitMapRO(ReservedSpace rs, int shifter) :
_bm((uintptr_t*)NULL,0),
@@ -53,13 +52,13 @@
ReservedSpace brs(ReservedSpace::allocation_align_size_up(
(_bmWordSize >> (_shifter + LogBitsPerByte)) + 1));
- guarantee(brs.is_reserved(), "couldn't allocate CMS bit map");
+ guarantee(brs.is_reserved(), "couldn't allocate concurrent marking bit map");
// For now we'll just commit all of the bit map up fromt.
// Later on we'll try to be more parsimonious with swap.
guarantee(_virtual_space.initialize(brs, brs.size()),
- "couldn't reseve backing store for CMS bit map");
+ "couldn't reseve backing store for concurrent marking bit map");
assert(_virtual_space.committed_size() == brs.size(),
- "didn't reserve backing store for all of CMS bit map?");
+ "didn't reserve backing store for all of concurrent marking bit map?");
_bm.set_map((uintptr_t*)_virtual_space.low());
assert(_virtual_space.committed_size() << (_shifter + LogBitsPerByte) >=
_bmWordSize, "inconsistency in bit map sizing");
@@ -104,17 +103,6 @@
return (int) (diff >> _shifter);
}
-bool CMBitMapRO::iterate(BitMapClosure* cl, MemRegion mr) {
- HeapWord* left = MAX2(_bmStartWord, mr.start());
- HeapWord* right = MIN2(_bmStartWord + _bmWordSize, mr.end());
- if (right > left) {
- // Right-open interval [leftOffset, rightOffset).
- return _bm.iterate(cl, heapWordToOffset(left), heapWordToOffset(right));
- } else {
- return true;
- }
-}
-
void CMBitMapRO::mostly_disjoint_range_union(BitMap* from_bitmap,
size_t from_start_index,
HeapWord* to_start_word,
@@ -431,8 +419,6 @@
assert(newOop->is_oop(), "Expected an oop");
assert(bm == NULL || bm->isMarked((HeapWord*)newOop),
"only grey objects on this stack");
- // iterate over the oops in this oop, marking and pushing
- // the ones in CMS generation.
newOop->oop_iterate(cl);
if (yield_after && _cm->do_yield_check()) {
res = false;
@@ -474,6 +460,84 @@
&& !nextMarkBitMap()->isMarked((HeapWord*)obj)));
}
+CMRootRegions::CMRootRegions() :
+ _young_list(NULL), _cm(NULL), _scan_in_progress(false),
+ _should_abort(false), _next_survivor(NULL) { }
+
+void CMRootRegions::init(G1CollectedHeap* g1h, ConcurrentMark* cm) {
+ _young_list = g1h->young_list();
+ _cm = cm;
+}
+
+void CMRootRegions::prepare_for_scan() {
+ assert(!scan_in_progress(), "pre-condition");
+
+ // Currently, only survivors can be root regions.
+ assert(_next_survivor == NULL, "pre-condition");
+ _next_survivor = _young_list->first_survivor_region();
+ _scan_in_progress = (_next_survivor != NULL);
+ _should_abort = false;
+}
+
+HeapRegion* CMRootRegions::claim_next() {
+ if (_should_abort) {
+ // If someone has set the should_abort flag, we return NULL to
+ // force the caller to bail out of their loop.
+ return NULL;
+ }
+
+ // Currently, only survivors can be root regions.
+ HeapRegion* res = _next_survivor;
+ if (res != NULL) {
+ MutexLockerEx x(RootRegionScan_lock, Mutex::_no_safepoint_check_flag);
+ // Read it again in case it changed while we were waiting for the lock.
+ res = _next_survivor;
+ if (res != NULL) {
+ if (res == _young_list->last_survivor_region()) {
+ // We just claimed the last survivor so store NULL to indicate
+ // that we're done.
+ _next_survivor = NULL;
+ } else {
+ _next_survivor = res->get_next_young_region();
+ }
+ } else {
+ // Someone else claimed the last survivor while we were trying
+ // to take the lock so nothing else to do.
+ }
+ }
+ assert(res == NULL || res->is_survivor(), "post-condition");
+
+ return res;
+}
+
+void CMRootRegions::scan_finished() {
+ assert(scan_in_progress(), "pre-condition");
+
+ // Currently, only survivors can be root regions.
+ if (!_should_abort) {
+ assert(_next_survivor == NULL, "we should have claimed all survivors");
+ }
+ _next_survivor = NULL;
+
+ {
+ MutexLockerEx x(RootRegionScan_lock, Mutex::_no_safepoint_check_flag);
+ _scan_in_progress = false;
+ RootRegionScan_lock->notify_all();
+ }
+}
+
+bool CMRootRegions::wait_until_scan_finished() {
+ if (!scan_in_progress()) return false;
+
+ {
+ MutexLockerEx x(RootRegionScan_lock, Mutex::_no_safepoint_check_flag);
+ while (scan_in_progress()) {
+ RootRegionScan_lock->wait(Mutex::_no_safepoint_check_flag);
+ }
+ }
+ return true;
+}
+
#ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away
#pragma warning( disable:4355 ) // 'this' : used in base member initializer list
#endif // _MSC_VER
@@ -498,6 +562,7 @@
_card_bm((rs.size() + CardTableModRefBS::card_size - 1) >>
CardTableModRefBS::card_shift,
false /* in_resource_area*/),
+
_prevMarkBitMap(&_markBitMap1),
_nextMarkBitMap(&_markBitMap2),
_at_least_one_mark_complete(false),
@@ -526,7 +591,11 @@
_cleanup_times(),
_total_counting_time(0.0),
_total_rs_scrub_time(0.0),
- _parallel_workers(NULL) {
+
+ _parallel_workers(NULL),
+
+ _count_card_bitmaps(NULL),
+ _count_marked_bytes(NULL) {
CMVerboseLevel verbose_level = (CMVerboseLevel) G1MarkingVerboseLevel;
if (verbose_level < no_verbose) {
verbose_level = no_verbose;
@@ -557,9 +626,16 @@
SATBMarkQueueSet& satb_qs = JavaThread::satb_mark_queue_set();
satb_qs.set_buffer_size(G1SATBBufferSize);
+ _root_regions.init(_g1h, this);
+
_tasks = NEW_C_HEAP_ARRAY(CMTask*, _max_task_num);
_accum_task_vtime = NEW_C_HEAP_ARRAY(double, _max_task_num);
+ _count_card_bitmaps = NEW_C_HEAP_ARRAY(BitMap, _max_task_num);
+ _count_marked_bytes = NEW_C_HEAP_ARRAY(size_t*, _max_task_num);
+
+ BitMap::idx_t card_bm_size = _card_bm.size();
+
// so that the assertion in MarkingTaskQueue::task_queue doesn't fail
_active_tasks = _max_task_num;
for (int i = 0; i < (int) _max_task_num; ++i) {
@@ -567,10 +643,26 @@
task_queue->initialize();
_task_queues->register_queue(i, task_queue);
- _tasks[i] = new CMTask(i, this, task_queue, _task_queues);
+ _count_card_bitmaps[i] = BitMap(card_bm_size, false);
+ _count_marked_bytes[i] = NEW_C_HEAP_ARRAY(size_t, max_regions);
+
+ _tasks[i] = new CMTask(i, this,
+ _count_marked_bytes[i],
+ &_count_card_bitmaps[i],
+ task_queue, _task_queues);
+
_accum_task_vtime[i] = 0.0;
}
+ // Calculate the card number for the bottom of the heap. Used
+ // in biasing indexes into the accounting card bitmaps.
+ _heap_bottom_card_num =
+ intptr_t(uintptr_t(_g1h->reserved_region().start()) >>
+ CardTableModRefBS::card_shift);
+
+ // Clear all the liveness counting data
+ clear_all_count_data();
+
if (ConcGCThreads > ParallelGCThreads) {
vm_exit_during_initialization("Can't have more ConcGCThreads "
"than ParallelGCThreads.");
@@ -750,11 +842,6 @@
ShouldNotReachHere();
}
-// This closure is used to mark refs into the g1 generation
-// from external roots in the CMS bit map.
-// Called at the first checkpoint.
-//
-
void ConcurrentMark::clearNextBitmap() {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
G1CollectorPolicy* g1p = g1h->g1_policy();
@@ -794,6 +881,9 @@
assert(!g1h->mark_in_progress(), "invariant");
}
+ // Clear the liveness counting data
+ clear_all_count_data();
+
// Repeat the asserts from above.
guarantee(cmThread()->during_cycle(), "invariant");
guarantee(!g1h->mark_in_progress(), "invariant");
@@ -854,6 +944,8 @@
satb_mq_set.set_active_all_threads(true, /* new active value */
false /* expected_active */);
+ _root_regions.prepare_for_scan();
+
// update_g1_committed() will be called at the end of an evac pause
// when marking is on. So, it's also called at the end of the
// initial-mark pause to update the heap end, if the heap expands
@@ -1147,6 +1239,69 @@
return 0;
}
+void ConcurrentMark::scanRootRegion(HeapRegion* hr, uint worker_id) {
+ // Currently, only survivors can be root regions.
+ assert(hr->next_top_at_mark_start() == hr->bottom(), "invariant");
+ G1RootRegionScanClosure cl(_g1h, this, worker_id);
+
+ const uintx interval = PrefetchScanIntervalInBytes;
+ HeapWord* curr = hr->bottom();
+ const HeapWord* end = hr->top();
+ while (curr < end) {
+ Prefetch::read(curr, interval);
+ oop obj = oop(curr);
+ int size = obj->oop_iterate(&cl);
+ assert(size == obj->size(), "sanity");
+ curr += size;
+ }
+}
+
+class CMRootRegionScanTask : public AbstractGangTask {
+private:
+ ConcurrentMark* _cm;
+
+public:
+ CMRootRegionScanTask(ConcurrentMark* cm) :
+ AbstractGangTask("Root Region Scan"), _cm(cm) { }
+
+ void work(uint worker_id) {
+ assert(Thread::current()->is_ConcurrentGC_thread(),
+ "this should only be done by a conc GC thread");
+
+ CMRootRegions* root_regions = _cm->root_regions();
+ HeapRegion* hr = root_regions->claim_next();
+ while (hr != NULL) {
+ _cm->scanRootRegion(hr, worker_id);
+ hr = root_regions->claim_next();
+ }
+ }
+};
+
+void ConcurrentMark::scanRootRegions() {
+ // scan_in_progress() will have been set to true only if there was
+ // at least one root region to scan. So, if it's false, we
+ // should not attempt to do any further work.
+ if (root_regions()->scan_in_progress()) {
+ _parallel_marking_threads = calc_parallel_marking_threads();
+ assert(parallel_marking_threads() <= max_parallel_marking_threads(),
+ "Maximum number of marking threads exceeded");
+ uint active_workers = MAX2(1U, parallel_marking_threads());
+
+ CMRootRegionScanTask task(this);
+ if (parallel_marking_threads() > 0) {
+ _parallel_workers->set_active_workers((int) active_workers);
+ _parallel_workers->run_task(&task);
+ } else {
+ task.work(0);
+ }
+
+ // It's possible that has_aborted() is true here without actually
+ // aborting the survivor scan earlier. This is OK as it's
+ // mainly used for sanity checking.
+ root_regions()->scan_finished();
+ }
+}
+
void ConcurrentMark::markFromRoots() {
// we might be tempted to assert that:
// assert(asynch == !SafepointSynchronize::is_at_safepoint(),
@@ -1225,6 +1380,10 @@
gclog_or_tty->print_cr("\nRemark led to restart for overflow.");
}
} else {
+ // Aggregate the per-task counting data that we have accumulated
+ // while marking.
+ aggregate_count_data();
+
SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
// We're done with marking.
// This is the end of the marking cycle, we're expected all
@@ -1262,48 +1421,41 @@
g1p->record_concurrent_mark_remark_end();
}
-#define CARD_BM_TEST_MODE 0
-
+// Used to calculate the # live objects per region
+// for verification purposes
class CalcLiveObjectsClosure: public HeapRegionClosure {
CMBitMapRO* _bm;
ConcurrentMark* _cm;
- bool _changed;
- bool _yield;
- size_t _words_done;
- size_t _tot_live;
- size_t _tot_used;
- size_t _regions_done;
- double _start_vtime_sec;
-
BitMap* _region_bm;
BitMap* _card_bm;
+
+ // Debugging
+ size_t _tot_words_done;
+ size_t _tot_live;
+ size_t _tot_used;
+
+ size_t _region_marked_bytes;
+
intptr_t _bottom_card_num;
- bool _final;
void mark_card_num_range(intptr_t start_card_num, intptr_t last_card_num) {
- for (intptr_t i = start_card_num; i <= last_card_num; i++) {
-#if CARD_BM_TEST_MODE
- guarantee(_card_bm->at(i - _bottom_card_num), "Should already be set.");
-#else
- _card_bm->par_at_put(i - _bottom_card_num, 1);
-#endif
+ assert(start_card_num <= last_card_num, "sanity");
+ BitMap::idx_t start_idx = start_card_num - _bottom_card_num;
+ BitMap::idx_t last_idx = last_card_num - _bottom_card_num;
+
+ for (BitMap::idx_t i = start_idx; i <= last_idx; i += 1) {
+ _card_bm->par_at_put(i, 1);
}
}
public:
- CalcLiveObjectsClosure(bool final,
- CMBitMapRO *bm, ConcurrentMark *cm,
+ CalcLiveObjectsClosure(CMBitMapRO *bm, ConcurrentMark *cm,
BitMap* region_bm, BitMap* card_bm) :
- _bm(bm), _cm(cm), _changed(false), _yield(true),
- _words_done(0), _tot_live(0), _tot_used(0),
- _region_bm(region_bm), _card_bm(card_bm),_final(final),
- _regions_done(0), _start_vtime_sec(0.0)
- {
- _bottom_card_num =
- intptr_t(uintptr_t(G1CollectedHeap::heap()->reserved_region().start()) >>
- CardTableModRefBS::card_shift);
- }
+ _bm(bm), _cm(cm), _region_bm(region_bm), _card_bm(card_bm),
+ _region_marked_bytes(0), _tot_words_done(0),
+ _tot_live(0), _tot_used(0),
+ _bottom_card_num(cm->heap_bottom_card_num()) { }
// It takes a region that's not empty (i.e., it has at least one
// live object in it and sets its corresponding bit on the region
@@ -1319,29 +1471,16 @@
_region_bm->par_at_put((BitMap::idx_t) index, true);
} else {
// Starts humongous case: calculate how many regions are part of
- // this humongous region and then set the bit range. It might
- // have been a bit more efficient to look at the object that
- // spans these humongous regions to calculate their number from
- // the object's size. However, it's a good idea to calculate
- // this based on the metadata itself, and not the region
- // contents, so that this code is not aware of what goes into
- // the humongous regions (in case this changes in the future).
+ // this humongous region and then set the bit range.
G1CollectedHeap* g1h = G1CollectedHeap::heap();
- size_t end_index = index + 1;
- while (end_index < g1h->n_regions()) {
- HeapRegion* chr = g1h->region_at(end_index);
- if (!chr->continuesHumongous()) break;
- end_index += 1;
- }
+ HeapRegion *last_hr = g1h->heap_region_containing_raw(hr->end() - 1);
+ size_t end_index = last_hr->hrs_index() + 1;
_region_bm->par_at_put_range((BitMap::idx_t) index,
(BitMap::idx_t) end_index, true);
}
}
bool doHeapRegion(HeapRegion* hr) {
- if (!_final && _regions_done == 0) {
- _start_vtime_sec = os::elapsedVTime();
- }
if (hr->continuesHumongous()) {
// We will ignore these here and process them when their
@@ -1355,48 +1494,41 @@
}
HeapWord* nextTop = hr->next_top_at_mark_start();
- HeapWord* start = hr->top_at_conc_mark_count();
- assert(hr->bottom() <= start && start <= hr->end() &&
- hr->bottom() <= nextTop && nextTop <= hr->end() &&
- start <= nextTop,
- "Preconditions.");
- // Otherwise, record the number of word's we'll examine.
+ HeapWord* start = hr->bottom();
+
+ assert(start <= hr->end() && start <= nextTop && nextTop <= hr->end(),
+ err_msg("Preconditions not met - "
+ "start: "PTR_FORMAT", nextTop: "PTR_FORMAT", end: "PTR_FORMAT,
+ start, nextTop, hr->end()));
+
+ // Record the number of word's we'll examine.
size_t words_done = (nextTop - start);
+
// Find the first marked object at or after "start".
start = _bm->getNextMarkedWordAddress(start, nextTop);
+
size_t marked_bytes = 0;
// Below, the term "card num" means the result of shifting an address
// by the card shift -- address 0 corresponds to card number 0. One
// must subtract the card num of the bottom of the heap to obtain a
// card table index.
+
// The first card num of the sequence of live cards currently being
// constructed. -1 ==> no sequence.
intptr_t start_card_num = -1;
+
// The last card num of the sequence of live cards currently being
// constructed. -1 ==> no sequence.
intptr_t last_card_num = -1;
while (start < nextTop) {
- if (_yield && _cm->do_yield_check()) {
- // We yielded. It might be for a full collection, in which case
- // all bets are off; terminate the traversal.
- if (_cm->has_aborted()) {
- _changed = false;
- return true;
- } else {
- // Otherwise, it might be a collection pause, and the region
- // we're looking at might be in the collection set. We'll
- // abandon this region.
- return false;
- }
- }
oop obj = oop(start);
int obj_sz = obj->size();
+
// The card num of the start of the current object.
intptr_t obj_card_num =
intptr_t(uintptr_t(start) >> CardTableModRefBS::card_shift);
-
HeapWord* obj_last = start + obj_sz - 1;
intptr_t obj_last_card_num =
intptr_t(uintptr_t(obj_last) >> CardTableModRefBS::card_shift);
@@ -1414,110 +1546,404 @@
start_card_num = obj_card_num;
}
}
-#if CARD_BM_TEST_MODE
- /*
- gclog_or_tty->print_cr("Setting bits from %d/%d.",
- obj_card_num - _bottom_card_num,
- obj_last_card_num - _bottom_card_num);
- */
- for (intptr_t j = obj_card_num; j <= obj_last_card_num; j++) {
- _card_bm->par_at_put(j - _bottom_card_num, 1);
- }
-#endif
}
// In any case, we set the last card num.
last_card_num = obj_last_card_num;
marked_bytes += (size_t)obj_sz * HeapWordSize;
+
// Find the next marked object after this one.
start = _bm->getNextMarkedWordAddress(start + 1, nextTop);
- _changed = true;
}
+
// Handle the last range, if any.
if (start_card_num != -1) {
mark_card_num_range(start_card_num, last_card_num);
}
- if (_final) {
- // Mark the allocated-since-marking portion...
- HeapWord* tp = hr->top();
- if (nextTop < tp) {
- start_card_num =
- intptr_t(uintptr_t(nextTop) >> CardTableModRefBS::card_shift);
- last_card_num =
- intptr_t(uintptr_t(tp) >> CardTableModRefBS::card_shift);
- mark_card_num_range(start_card_num, last_card_num);
- // This definitely means the region has live objects.
- set_bit_for_region(hr);
- }
+
+ // Mark the allocated-since-marking portion...
+ HeapWord* top = hr->top();
+ if (nextTop < top) {
+ start_card_num = intptr_t(uintptr_t(nextTop) >> CardTableModRefBS::card_shift);
+ last_card_num = intptr_t(uintptr_t(top) >> CardTableModRefBS::card_shift);
+
+ mark_card_num_range(start_card_num, last_card_num);
+
+ // This definitely means the region has live objects.
+ set_bit_for_region(hr);
}
- hr->add_to_marked_bytes(marked_bytes);
// Update the live region bitmap.
if (marked_bytes > 0) {
set_bit_for_region(hr);
}
- hr->set_top_at_conc_mark_count(nextTop);
+
+ // Set the marked bytes for the current region so that
+ // it can be queried by a calling verificiation routine
+ _region_marked_bytes = marked_bytes;
+
_tot_live += hr->next_live_bytes();
_tot_used += hr->used();
- _words_done = words_done;
-
- if (!_final) {
- ++_regions_done;
- if (_regions_done % 10 == 0) {
- double end_vtime_sec = os::elapsedVTime();
- double elapsed_vtime_sec = end_vtime_sec - _start_vtime_sec;
- if (elapsed_vtime_sec > (10.0 / 1000.0)) {
- jlong sleep_time_ms =
- (jlong) (elapsed_vtime_sec * _cm->cleanup_sleep_factor() * 1000.0);
- os::sleep(Thread::current(), sleep_time_ms, false);
- _start_vtime_sec = end_vtime_sec;
- }
- }
- }
+ _tot_words_done = words_done;
return false;
}
- bool changed() { return _changed; }
- void reset() { _changed = false; _words_done = 0; }
- void no_yield() { _yield = false; }
- size_t words_done() { return _words_done; }
- size_t tot_live() { return _tot_live; }
- size_t tot_used() { return _tot_used; }
+ size_t region_marked_bytes() const { return _region_marked_bytes; }
+
+ // Debugging
+ size_t tot_words_done() const { return _tot_words_done; }
+ size_t tot_live() const { return _tot_live; }
+ size_t tot_used() const { return _tot_used; }
+};
+
+// Heap region closure used for verifying the counting data
+// that was accumulated concurrently and aggregated during
+// the remark pause. This closure is applied to the heap
+// regions during the STW cleanup pause.
+
+class VerifyLiveObjectDataHRClosure: public HeapRegionClosure {
+ ConcurrentMark* _cm;
+ CalcLiveObjectsClosure _calc_cl;
+ BitMap* _region_bm; // Region BM to be verified
+ BitMap* _card_bm; // Card BM to be verified
+ bool _verbose; // verbose output?
+
+ BitMap* _exp_region_bm; // Expected Region BM values
+ BitMap* _exp_card_bm; // Expected card BM values
+
+ int _failures;
+
+public:
+ VerifyLiveObjectDataHRClosure(ConcurrentMark* cm,
+ BitMap* region_bm,
+ BitMap* card_bm,
+ BitMap* exp_region_bm,
+ BitMap* exp_card_bm,
+ bool verbose) :
+ _cm(cm),
+ _calc_cl(_cm->nextMarkBitMap(), _cm, exp_region_bm, exp_card_bm),
+ _region_bm(region_bm), _card_bm(card_bm), _verbose(verbose),
+ _exp_region_bm(exp_region_bm), _exp_card_bm(exp_card_bm),
+ _failures(0) { }
+
+ int failures() const { return _failures; }
+
+ bool doHeapRegion(HeapRegion* hr) {
+ if (hr->continuesHumongous()) {
+ // We will ignore these here and process them when their
+ // associated "starts humongous" region is processed (see
+ // set_bit_for_heap_region()). Note that we cannot rely on their
+ // associated "starts humongous" region to have their bit set to
+ // 1 since, due to the region chunking in the parallel region
+ // iteration, a "continues humongous" region might be visited
+ // before its associated "starts humongous".
+ return false;
+ }
+
+ int failures = 0;
+
+ // Call the CalcLiveObjectsClosure to walk the marking bitmap for
+ // this region and set the corresponding bits in the expected region
+ // and card bitmaps.
+ bool res = _calc_cl.doHeapRegion(hr);
+ assert(res == false, "should be continuing");
+
+ MutexLockerEx x((_verbose ? ParGCRareEvent_lock : NULL),
+ Mutex::_no_safepoint_check_flag);
+
+ // Verify that _top_at_conc_count == ntams
+ if (hr->top_at_conc_mark_count() != hr->next_top_at_mark_start()) {
+ if (_verbose) {
+ gclog_or_tty->print_cr("Region " SIZE_FORMAT ": top at conc count incorrect: "
+ "expected " PTR_FORMAT ", actual: " PTR_FORMAT,
+ hr->hrs_index(), hr->next_top_at_mark_start(),
+ hr->top_at_conc_mark_count());
+ }
+ failures += 1;
+ }
+
+ // Verify the marked bytes for this region.
+ size_t exp_marked_bytes = _calc_cl.region_marked_bytes();
+ size_t act_marked_bytes = hr->next_marked_bytes();
+
+ // We're not OK if expected marked bytes > actual marked bytes. It means
+ // we have missed accounting some objects during the actual marking.
+ if (exp_marked_bytes > act_marked_bytes) {
+ if (_verbose) {
+ gclog_or_tty->print_cr("Region " SIZE_FORMAT ": marked bytes mismatch: "
+ "expected: " SIZE_FORMAT ", actual: " SIZE_FORMAT,
+ hr->hrs_index(), exp_marked_bytes, act_marked_bytes);
+ }
+ failures += 1;
+ }
+
+ // Verify the bit, for this region, in the actual and expected
+ // (which was just calculated) region bit maps.
+ // We're not OK if the bit in the calculated expected region
+ // bitmap is set and the bit in the actual region bitmap is not.
+ BitMap::idx_t index = (BitMap::idx_t)hr->hrs_index();
+
+ bool expected = _exp_region_bm->at(index);
+ bool actual = _region_bm->at(index);
+ if (expected && !actual) {
+ if (_verbose) {
+ gclog_or_tty->print_cr("Region " SIZE_FORMAT ": region bitmap mismatch: "
+ "expected: %d, actual: %d",
+ hr->hrs_index(), expected, actual);
+ }
+ failures += 1;
+ }
+
+ // Verify that the card bit maps for the cards spanned by the current
+ // region match. We have an error if we have a set bit in the expected
+ // bit map and the corresponding bit in the actual bitmap is not set.
+
+ BitMap::idx_t start_idx = _cm->card_bitmap_index_for(hr->bottom());
+ BitMap::idx_t end_idx = _cm->card_bitmap_index_for(hr->top());
+
+ for (BitMap::idx_t i = start_idx; i < end_idx; i+=1) {
+ expected = _exp_card_bm->at(i);
+ actual = _card_bm->at(i);
+
+ if (expected && !actual) {
+ if (_verbose) {
+ gclog_or_tty->print_cr("Region " SIZE_FORMAT ": card bitmap mismatch at " SIZE_FORMAT ": "
+ "expected: %d, actual: %d",
+ hr->hrs_index(), i, expected, actual);
+ }
+ failures += 1;
+ }
+ }
+
+ if (failures > 0 && _verbose) {
+ gclog_or_tty->print_cr("Region " HR_FORMAT ", ntams: " PTR_FORMAT ", "
+ "marked_bytes: calc/actual " SIZE_FORMAT "/" SIZE_FORMAT,
+ HR_FORMAT_PARAMS(hr), hr->next_top_at_mark_start(),
+ _calc_cl.region_marked_bytes(), hr->next_marked_bytes());
+ }
+
+ _failures += failures;
+
+ // We could stop iteration over the heap when we
+ // find the first voilating region by returning true.
+ return false;
+ }
};
-void ConcurrentMark::calcDesiredRegions() {
- _region_bm.clear();
- _card_bm.clear();
- CalcLiveObjectsClosure calccl(false /*final*/,
- nextMarkBitMap(), this,
- &_region_bm, &_card_bm);
- G1CollectedHeap *g1h = G1CollectedHeap::heap();
- g1h->heap_region_iterate(&calccl);
-
- do {
- calccl.reset();
- g1h->heap_region_iterate(&calccl);
- } while (calccl.changed());
-}
+class G1ParVerifyFinalCountTask: public AbstractGangTask {
+protected:
+ G1CollectedHeap* _g1h;
+ ConcurrentMark* _cm;
+ BitMap* _actual_region_bm;
+ BitMap* _actual_card_bm;
+
+ uint _n_workers;
+
+ BitMap* _expected_region_bm;
+ BitMap* _expected_card_bm;
+
+ int _failures;
+ bool _verbose;
+
+public:
+ G1ParVerifyFinalCountTask(G1CollectedHeap* g1h,
+ BitMap* region_bm, BitMap* card_bm,
+ BitMap* expected_region_bm, BitMap* expected_card_bm)
+ : AbstractGangTask("G1 verify final counting"),
+ _g1h(g1h), _cm(_g1h->concurrent_mark()),
+ _actual_region_bm(region_bm), _actual_card_bm(card_bm),
+ _expected_region_bm(expected_region_bm), _expected_card_bm(expected_card_bm),
+ _failures(0), _verbose(false),
+ _n_workers(0) {
+ assert(VerifyDuringGC, "don't call this otherwise");
+
+ // Use the value already set as the number of active threads
+ // in the call to run_task().
+ if (G1CollectedHeap::use_parallel_gc_threads()) {
+ assert( _g1h->workers()->active_workers() > 0,
+ "Should have been previously set");
+ _n_workers = _g1h->workers()->active_workers();
+ } else {
+ _n_workers = 1;
+ }
+
+ assert(_expected_card_bm->size() == _actual_card_bm->size(), "sanity");
+ assert(_expected_region_bm->size() == _actual_region_bm->size(), "sanity");
+
+ _verbose = _cm->verbose_medium();
+ }
+
+ void work(uint worker_id) {
+ assert(worker_id < _n_workers, "invariant");
+
+ VerifyLiveObjectDataHRClosure verify_cl(_cm,
+ _actual_region_bm, _actual_card_bm,
+ _expected_region_bm,
+ _expected_card_bm,
+ _verbose);
+
+ if (G1CollectedHeap::use_parallel_gc_threads()) {
+ _g1h->heap_region_par_iterate_chunked(&verify_cl,
+ worker_id,
+ _n_workers,
+ HeapRegion::VerifyCountClaimValue);
+ } else {
+ _g1h->heap_region_iterate(&verify_cl);
+ }
+
+ Atomic::add(verify_cl.failures(), &_failures);
+ }
+
+ int failures() const { return _failures; }
+};
+
+// Final update of count data (during cleanup).
+// Adds [top_at_count, NTAMS) to the marked bytes for each
+// region. Sets the bits in the card bitmap corresponding
+// to the interval [top_at_count, top], and sets the
+// liveness bit for each region containing live data
+// in the region bitmap.
+
+class FinalCountDataUpdateClosure: public HeapRegionClosure {
+ ConcurrentMark* _cm;
+ BitMap* _region_bm;
+ BitMap* _card_bm;
+
+ size_t _total_live_bytes;
+ size_t _total_used_bytes;
+ size_t _total_words_done;
+
+ void set_card_bitmap_range(BitMap::idx_t start_idx, BitMap::idx_t last_idx) {
+ assert(start_idx <= last_idx, "sanity");
+
+ // Set the inclusive bit range [start_idx, last_idx].
+ // For small ranges (up to 8 cards) use a simple loop; otherwise
+ // use par_at_put_range.
+ if ((last_idx - start_idx) <= 8) {
+ for (BitMap::idx_t i = start_idx; i <= last_idx; i += 1) {
+ _card_bm->par_set_bit(i);
+ }
+ } else {
+ assert(last_idx < _card_bm->size(), "sanity");
+ // Note BitMap::par_at_put_range() is exclusive.
+ _card_bm->par_at_put_range(start_idx, last_idx+1, true);
+ }
+ }
+
+ // It takes a region that's not empty (i.e., it has at least one
+ // live object in it and sets its corresponding bit on the region
+ // bitmap to 1. If the region is "starts humongous" it will also set
+ // to 1 the bits on the region bitmap that correspond to its
+ // associated "continues humongous" regions.
+ void set_bit_for_region(HeapRegion* hr) {
+ assert(!hr->continuesHumongous(), "should have filtered those out");
+
+ size_t index = hr->hrs_index();
+ if (!hr->startsHumongous()) {
+ // Normal (non-humongous) case: just set the bit.
+ _region_bm->par_set_bit((BitMap::idx_t) index);
+ } else {
+ // Starts humongous case: calculate how many regions are part of
+ // this humongous region and then set the bit range.
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+ HeapRegion *last_hr = g1h->heap_region_containing_raw(hr->end() - 1);
+ size_t end_index = last_hr->hrs_index() + 1;
+ _region_bm->par_at_put_range((BitMap::idx_t) index,
+ (BitMap::idx_t) end_index, true);
+ }
+ }
+
+ public:
+ FinalCountDataUpdateClosure(ConcurrentMark* cm,
+ BitMap* region_bm,
+ BitMap* card_bm) :
+ _cm(cm), _region_bm(region_bm), _card_bm(card_bm),
+ _total_words_done(0), _total_live_bytes(0), _total_used_bytes(0) { }
+
+ bool doHeapRegion(HeapRegion* hr) {
+
+ if (hr->continuesHumongous()) {
+ // We will ignore these here and process them when their
+ // associated "starts humongous" region is processed (see
+ // set_bit_for_heap_region()). Note that we cannot rely on their
+ // associated "starts humongous" region to have their bit set to
+ // 1 since, due to the region chunking in the parallel region
+ // iteration, a "continues humongous" region might be visited
+ // before its associated "starts humongous".
+ return false;
+ }
+
+ HeapWord* start = hr->top_at_conc_mark_count();
+ HeapWord* ntams = hr->next_top_at_mark_start();
+ HeapWord* top = hr->top();
+
+ assert(hr->bottom() <= start && start <= hr->end() &&
+ hr->bottom() <= ntams && ntams <= hr->end(), "Preconditions.");
+
+ size_t words_done = ntams - hr->bottom();
+
+ if (start < ntams) {
+ // Region was changed between remark and cleanup pauses
+ // We need to add (ntams - start) to the marked bytes
+ // for this region, and set bits for the range
+ // [ card_idx(start), card_idx(ntams) ) in the card bitmap.
+ size_t live_bytes = (ntams - start) * HeapWordSize;
+ hr->add_to_marked_bytes(live_bytes);
+
+ // Record the new top at conc count
+ hr->set_top_at_conc_mark_count(ntams);
+
+ // The setting of the bits in the card bitmap takes place below
+ }
+
+ // Mark the allocated-since-marking portion...
+ if (ntams < top) {
+ // This definitely means the region has live objects.
+ set_bit_for_region(hr);
+ }
+
+ // Now set the bits for [start, top]
+ BitMap::idx_t start_idx = _cm->card_bitmap_index_for(start);
+ BitMap::idx_t last_idx = _cm->card_bitmap_index_for(top);
+ set_card_bitmap_range(start_idx, last_idx);
+
+ // Set the bit for the region if it contains live data
+ if (hr->next_marked_bytes() > 0) {
+ set_bit_for_region(hr);
+ }
+
+ _total_words_done += words_done;
+ _total_used_bytes += hr->used();
+ _total_live_bytes += hr->next_marked_bytes();
+
+ return false;
+ }
+
+ size_t total_words_done() const { return _total_words_done; }
+ size_t total_live_bytes() const { return _total_live_bytes; }
+ size_t total_used_bytes() const { return _total_used_bytes; }
+};
class G1ParFinalCountTask: public AbstractGangTask {
protected:
G1CollectedHeap* _g1h;
- CMBitMap* _bm;
+ ConcurrentMark* _cm;
+ BitMap* _actual_region_bm;
+ BitMap* _actual_card_bm;
+
uint _n_workers;
+
size_t *_live_bytes;
size_t *_used_bytes;
- BitMap* _region_bm;
- BitMap* _card_bm;
+
public:
- G1ParFinalCountTask(G1CollectedHeap* g1h, CMBitMap* bm,
- BitMap* region_bm, BitMap* card_bm)
- : AbstractGangTask("G1 final counting"), _g1h(g1h),
- _bm(bm), _region_bm(region_bm), _card_bm(card_bm),
- _n_workers(0)
- {
+ G1ParFinalCountTask(G1CollectedHeap* g1h, BitMap* region_bm, BitMap* card_bm)
+ : AbstractGangTask("G1 final counting"),
+ _g1h(g1h), _cm(_g1h->concurrent_mark()),
+ _actual_region_bm(region_bm), _actual_card_bm(card_bm),
+ _n_workers(0) {
// Use the value already set as the number of active threads
// in the call to run_task(). Needed for the allocation of
// _live_bytes and _used_bytes.
@@ -1539,29 +1965,32 @@
}
void work(uint worker_id) {
- CalcLiveObjectsClosure calccl(true /*final*/,
- _bm, _g1h->concurrent_mark(),
- _region_bm, _card_bm);
- calccl.no_yield();
+ assert(worker_id < _n_workers, "invariant");
+
+ FinalCountDataUpdateClosure final_update_cl(_cm,
+ _actual_region_bm,
+ _actual_card_bm);
+
if (G1CollectedHeap::use_parallel_gc_threads()) {
- _g1h->heap_region_par_iterate_chunked(&calccl, worker_id,
- (int) _n_workers,
+ _g1h->heap_region_par_iterate_chunked(&final_update_cl,
+ worker_id,
+ _n_workers,
HeapRegion::FinalCountClaimValue);
} else {
- _g1h->heap_region_iterate(&calccl);
+ _g1h->heap_region_iterate(&final_update_cl);
}
- assert(calccl.complete(), "Shouldn't have yielded!");
-
- assert(worker_id < _n_workers, "invariant");
- _live_bytes[worker_id] = calccl.tot_live();
- _used_bytes[worker_id] = calccl.tot_used();
- }
+
+ _live_bytes[worker_id] = final_update_cl.total_live_bytes();
+ _used_bytes[worker_id] = final_update_cl.total_used_bytes();
+ }
+
size_t live_bytes() {
size_t live_bytes = 0;
for (uint i = 0; i < _n_workers; ++i)
live_bytes += _live_bytes[i];
return live_bytes;
}
+
size_t used_bytes() {
size_t used_bytes = 0;
for (uint i = 0; i < _n_workers; ++i)
@@ -1724,8 +2153,7 @@
G1ParScrubRemSetTask(G1CollectedHeap* g1h,
BitMap* region_bm, BitMap* card_bm) :
AbstractGangTask("G1 ScrubRS"), _g1rs(g1h->g1_rem_set()),
- _region_bm(region_bm), _card_bm(card_bm)
- {}
+ _region_bm(region_bm), _card_bm(card_bm) { }
void work(uint worker_id) {
if (G1CollectedHeap::use_parallel_gc_threads()) {
@@ -1772,11 +2200,10 @@
uint n_workers;
// Do counting once more with the world stopped for good measure.
- G1ParFinalCountTask g1_par_count_task(g1h, nextMarkBitMap(),
- &_region_bm, &_card_bm);
+ G1ParFinalCountTask g1_par_count_task(g1h, &_region_bm, &_card_bm);
+
if (G1CollectedHeap::use_parallel_gc_threads()) {
- assert(g1h->check_heap_region_claim_values(
- HeapRegion::InitialClaimValue),
+ assert(g1h->check_heap_region_claim_values(HeapRegion::InitialClaimValue),
"sanity check");
g1h->set_par_threads();
@@ -1787,14 +2214,42 @@
// Done with the parallel phase so reset to 0.
g1h->set_par_threads(0);
- assert(g1h->check_heap_region_claim_values(
- HeapRegion::FinalCountClaimValue),
+ assert(g1h->check_heap_region_claim_values(HeapRegion::FinalCountClaimValue),
"sanity check");
} else {
n_workers = 1;
g1_par_count_task.work(0);
}
+ if (VerifyDuringGC) {
+ // Verify that the counting data accumulated during marking matches
+ // that calculated by walking the marking bitmap.
+
+ // Bitmaps to hold expected values
+ BitMap expected_region_bm(_region_bm.size(), false);
+ BitMap expected_card_bm(_card_bm.size(), false);
+
+ G1ParVerifyFinalCountTask g1_par_verify_task(g1h,
+ &_region_bm,
+ &_card_bm,
+ &expected_region_bm,
+ &expected_card_bm);
+
+ if (G1CollectedHeap::use_parallel_gc_threads()) {
+ g1h->set_par_threads((int)n_workers);
+ g1h->workers()->run_task(&g1_par_verify_task);
+ // Done with the parallel phase so reset to 0.
+ g1h->set_par_threads(0);
+
+ assert(g1h->check_heap_region_claim_values(HeapRegion::VerifyCountClaimValue),
+ "sanity check");
+ } else {
+ g1_par_verify_task.work(0);
+ }
+
+ guarantee(g1_par_verify_task.failures() == 0, "Unexpected accounting failures");
+ }
+
size_t known_garbage_bytes =
g1_par_count_task.used_bytes() - g1_par_count_task.live_bytes();
g1p->set_known_garbage_bytes(known_garbage_bytes);
@@ -1905,6 +2360,10 @@
// races with it goes around and waits for completeCleanup to finish.
g1h->increment_total_collections();
+ // We reclaimed old regions so we should calculate the sizes to make
+ // sure we update the old gen/space data.
+ g1h->g1mm()->update_sizes();
+
if (VerifyDuringGC) {
HandleMark hm; // handle scope
gclog_or_tty->print(" VerifyDuringGC:(after)");
@@ -1983,12 +2442,11 @@
class G1CMKeepAliveClosure: public OopClosure {
G1CollectedHeap* _g1;
ConcurrentMark* _cm;
- CMBitMap* _bitMap;
public:
- G1CMKeepAliveClosure(G1CollectedHeap* g1, ConcurrentMark* cm,
- CMBitMap* bitMap) :
- _g1(g1), _cm(cm),
- _bitMap(bitMap) {}
+ G1CMKeepAliveClosure(G1CollectedHeap* g1, ConcurrentMark* cm) :
+ _g1(g1), _cm(cm) {
+ assert(Thread::current()->is_VM_thread(), "otherwise fix worker id");
+ }
virtual void do_oop(narrowOop* p) { do_oop_work(p); }
virtual void do_oop( oop* p) { do_oop_work(p); }
@@ -2004,26 +2462,25 @@
}
if (_g1->is_in_g1_reserved(addr) && _g1->is_obj_ill(obj)) {
- _bitMap->mark(addr);
+ _cm->mark_and_count(obj);
_cm->mark_stack_push(obj);
}
}
};
class G1CMDrainMarkingStackClosure: public VoidClosure {
+ ConcurrentMark* _cm;
CMMarkStack* _markStack;
- CMBitMap* _bitMap;
G1CMKeepAliveClosure* _oopClosure;
public:
- G1CMDrainMarkingStackClosure(CMBitMap* bitMap, CMMarkStack* markStack,
+ G1CMDrainMarkingStackClosure(ConcurrentMark* cm, CMMarkStack* markStack,
G1CMKeepAliveClosure* oopClosure) :
- _bitMap(bitMap),
+ _cm(cm),
_markStack(markStack),
- _oopClosure(oopClosure)
- {}
+ _oopClosure(oopClosure) { }
void do_void() {
- _markStack->drain((OopClosure*)_oopClosure, _bitMap, false);
+ _markStack->drain((OopClosure*)_oopClosure, _cm->nextMarkBitMap(), false);
}
};
@@ -2102,8 +2559,7 @@
CMTask* _task;
public:
G1CMParDrainMarkingStackClosure(ConcurrentMark* cm, CMTask* task) :
- _cm(cm), _task(task)
- {}
+ _cm(cm), _task(task) { }
void do_void() {
do {
@@ -2242,9 +2698,9 @@
rp->setup_policy(clear_all_soft_refs);
assert(_markStack.isEmpty(), "mark stack should be empty");
- G1CMKeepAliveClosure g1_keep_alive(g1h, this, nextMarkBitMap());
+ G1CMKeepAliveClosure g1_keep_alive(g1h, this);
G1CMDrainMarkingStackClosure
- g1_drain_mark_stack(nextMarkBitMap(), &_markStack, &g1_keep_alive);
+ g1_drain_mark_stack(this, &_markStack, &g1_keep_alive);
// We use the work gang from the G1CollectedHeap and we utilize all
// the worker threads.
@@ -2616,18 +3072,6 @@
// during an evacuation pause). This was a late change to the code and
// is currently not being taken advantage of.
-class CMGlobalObjectClosure : public ObjectClosure {
-private:
- ConcurrentMark* _cm;
-
-public:
- void do_object(oop obj) {
- _cm->deal_with_reference(obj);
- }
-
- CMGlobalObjectClosure(ConcurrentMark* cm) : _cm(cm) { }
-};
-
void ConcurrentMark::deal_with_reference(oop obj) {
if (verbose_high()) {
gclog_or_tty->print_cr("[global] we're dealing with reference "PTR_FORMAT,
@@ -2672,6 +3116,18 @@
}
}
+class CMGlobalObjectClosure : public ObjectClosure {
+private:
+ ConcurrentMark* _cm;
+
+public:
+ void do_object(oop obj) {
+ _cm->deal_with_reference(obj);
+ }
+
+ CMGlobalObjectClosure(ConcurrentMark* cm) : _cm(cm) { }
+};
+
void ConcurrentMark::drainAllSATBBuffers() {
guarantee(false, "drainAllSATBBuffers(): don't call this any more");
@@ -2693,15 +3149,6 @@
assert(satb_mq_set.completed_buffers_num() == 0, "invariant");
}
-void ConcurrentMark::clear(oop p) {
- assert(p != NULL && p->is_oop(), "expected an oop");
- HeapWord* addr = (HeapWord*)p;
- assert(addr >= _nextMarkBitMap->startWord() ||
- addr < _nextMarkBitMap->endWord(), "in a region");
-
- _nextMarkBitMap->clear(addr);
-}
-
void ConcurrentMark::clearRangePrevBitmap(MemRegion mr) {
// Note we are overriding the read-only view of the prev map here, via
// the cast.
@@ -3015,6 +3462,192 @@
}
}
+// Aggregate the counting data that was constructed concurrently
+// with marking.
+class AggregateCountDataHRClosure: public HeapRegionClosure {
+ ConcurrentMark* _cm;
+ BitMap* _cm_card_bm;
+ size_t _max_task_num;
+
+ public:
+ AggregateCountDataHRClosure(ConcurrentMark *cm,
+ BitMap* cm_card_bm,
+ size_t max_task_num) :
+ _cm(cm), _cm_card_bm(cm_card_bm),
+ _max_task_num(max_task_num) { }
+
+ bool is_card_aligned(HeapWord* p) {
+ return ((uintptr_t(p) & (CardTableModRefBS::card_size - 1)) == 0);
+ }
+
+ bool doHeapRegion(HeapRegion* hr) {
+ if (hr->continuesHumongous()) {
+ // We will ignore these here and process them when their
+ // associated "starts humongous" region is processed.
+ // Note that we cannot rely on their associated
+ // "starts humongous" region to have their bit set to 1
+ // since, due to the region chunking in the parallel region
+ // iteration, a "continues humongous" region might be visited
+ // before its associated "starts humongous".
+ return false;
+ }
+
+ HeapWord* start = hr->bottom();
+ HeapWord* limit = hr->next_top_at_mark_start();
+ HeapWord* end = hr->end();
+
+ assert(start <= limit && limit <= hr->top() && hr->top() <= hr->end(),
+ err_msg("Preconditions not met - "
+ "start: "PTR_FORMAT", limit: "PTR_FORMAT", "
+ "top: "PTR_FORMAT", end: "PTR_FORMAT,
+ start, limit, hr->top(), hr->end()));
+
+ assert(hr->next_marked_bytes() == 0, "Precondition");
+
+ if (start == limit) {
+ // NTAMS of this region has not been set so nothing to do.
+ return false;
+ }
+
+ assert(is_card_aligned(start), "sanity");
+ assert(is_card_aligned(end), "sanity");
+
+ BitMap::idx_t start_idx = _cm->card_bitmap_index_for(start);
+ BitMap::idx_t limit_idx = _cm->card_bitmap_index_for(limit);
+ BitMap::idx_t end_idx = _cm->card_bitmap_index_for(end);
+
+ // If ntams is not card aligned then we bump the index for
+ // limit so that we get the card spanning ntams.
+ if (!is_card_aligned(limit)) {
+ limit_idx += 1;
+ }
+
+ assert(limit_idx <= end_idx, "or else use atomics");
+
+ // Aggregate the "stripe" in the count data associated with hr.
+ size_t hrs_index = hr->hrs_index();
+ size_t marked_bytes = 0;
+
+ for (int i = 0; (size_t)i < _max_task_num; i += 1) {
+ size_t* marked_bytes_array = _cm->count_marked_bytes_array_for(i);
+ BitMap* task_card_bm = _cm->count_card_bitmap_for(i);
+
+ // Fetch the marked_bytes in this region for task i and
+ // add it to the running total for this region.
+ marked_bytes += marked_bytes_array[hrs_index];
+
+ // Now union the bitmaps[0,max_task_num)[start_idx..limit_idx)
+ // into the global card bitmap.
+ BitMap::idx_t scan_idx = task_card_bm->get_next_one_offset(start_idx, limit_idx);
+
+ while (scan_idx < limit_idx) {
+ assert(task_card_bm->at(scan_idx) == true, "should be");
+ _cm_card_bm->set_bit(scan_idx);
+ assert(_cm_card_bm->at(scan_idx) == true, "should be");
+
+ // BitMap::get_next_one_offset() can handle the case when
+ // its left_offset parameter is greater than its right_offset
+ // parameter. If does, however, have an early exit if
+ // left_offset == right_offset. So let's limit the value
+ // passed in for left offset here.
+ BitMap::idx_t next_idx = MIN2(scan_idx + 1, limit_idx);
+ scan_idx = task_card_bm->get_next_one_offset(next_idx, limit_idx);
+ }
+ }
+
+ // Update the marked bytes for this region.
+ hr->add_to_marked_bytes(marked_bytes);
+
+ // Now set the top at count to NTAMS.
+ hr->set_top_at_conc_mark_count(limit);
+
+ // Next heap region
+ return false;
+ }
+};
+
+class G1AggregateCountDataTask: public AbstractGangTask {
+protected:
+ G1CollectedHeap* _g1h;
+ ConcurrentMark* _cm;
+ BitMap* _cm_card_bm;
+ size_t _max_task_num;
+ int _active_workers;
+
+public:
+ G1AggregateCountDataTask(G1CollectedHeap* g1h,
+ ConcurrentMark* cm,
+ BitMap* cm_card_bm,
+ size_t max_task_num,
+ int n_workers) :
+ AbstractGangTask("Count Aggregation"),
+ _g1h(g1h), _cm(cm), _cm_card_bm(cm_card_bm),
+ _max_task_num(max_task_num),
+ _active_workers(n_workers) { }
+
+ void work(uint worker_id) {
+ AggregateCountDataHRClosure cl(_cm, _cm_card_bm, _max_task_num);
+
+ if (G1CollectedHeap::use_parallel_gc_threads()) {
+ _g1h->heap_region_par_iterate_chunked(&cl, worker_id,
+ _active_workers,
+ HeapRegion::AggregateCountClaimValue);
+ } else {
+ _g1h->heap_region_iterate(&cl);
+ }
+ }
+};
+
+
+void ConcurrentMark::aggregate_count_data() {
+ int n_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
+ _g1h->workers()->active_workers() :
+ 1);
+
+ G1AggregateCountDataTask g1_par_agg_task(_g1h, this, &_card_bm,
+ _max_task_num, n_workers);
+
+ if (G1CollectedHeap::use_parallel_gc_threads()) {
+ assert(_g1h->check_heap_region_claim_values(HeapRegion::InitialClaimValue),
+ "sanity check");
+ _g1h->set_par_threads(n_workers);
+ _g1h->workers()->run_task(&g1_par_agg_task);
+ _g1h->set_par_threads(0);
+
+ assert(_g1h->check_heap_region_claim_values(HeapRegion::AggregateCountClaimValue),
+ "sanity check");
+ _g1h->reset_heap_region_claim_values();
+ } else {
+ g1_par_agg_task.work(0);
+ }
+}
+
+// Clear the per-worker arrays used to store the per-region counting data
+void ConcurrentMark::clear_all_count_data() {
+ // Clear the global card bitmap - it will be filled during
+ // liveness count aggregation (during remark) and the
+ // final counting task.
+ _card_bm.clear();
+
+ // Clear the global region bitmap - it will be filled as part
+ // of the final counting task.
+ _region_bm.clear();
+
+ size_t max_regions = _g1h->max_regions();
+ assert(_max_task_num != 0, "unitialized");
+
+ for (int i = 0; (size_t) i < _max_task_num; i += 1) {
+ BitMap* task_card_bm = count_card_bitmap_for(i);
+ size_t* marked_bytes_array = count_marked_bytes_array_for(i);
+
+ assert(task_card_bm->size() == _card_bm.size(), "size mismatch");
+ assert(marked_bytes_array != NULL, "uninitialized");
+
+ memset(marked_bytes_array, 0, (max_regions * sizeof(size_t)));
+ task_card_bm->clear();
+ }
+}
+
void ConcurrentMark::print_stats() {
if (verbose_stats()) {
gclog_or_tty->print_cr("---------------------------------------------------------------------");
@@ -3350,6 +3983,8 @@
void ConcurrentMark::abort() {
// Clear all marks to force marking thread to do nothing
_nextMarkBitMap->clearAll();
+ // Clear the liveness counting data
+ clear_all_count_data();
// Empty mark stack
clear_marking_state();
for (int i = 0; i < (int)_max_task_num; ++i) {
@@ -3402,23 +4037,15 @@
(_init_times.sum() + _remark_times.sum() +
_cleanup_times.sum())/1000.0);
gclog_or_tty->print_cr(" Total concurrent time = %8.2f s "
- "(%8.2f s marking, %8.2f s counting).",
+ "(%8.2f s marking).",
cmThread()->vtime_accum(),
- cmThread()->vtime_mark_accum(),
- cmThread()->vtime_count_accum());
+ cmThread()->vtime_mark_accum());
}
void ConcurrentMark::print_worker_threads_on(outputStream* st) const {
_parallel_workers->print_worker_threads_on(st);
}
-// Closures
-// XXX: there seems to be a lot of code duplication here;
-// should refactor and consolidate the shared code.
-
-// This closure is used to mark refs into the CMS generation in
-// the CMS bit map. Called at the first checkpoint.
-
// We take a break if someone is trying to stop the world.
bool ConcurrentMark::do_yield_check(uint worker_id) {
if (should_yield()) {
@@ -4704,6 +5331,8 @@
CMTask::CMTask(int task_id,
ConcurrentMark* cm,
+ size_t* marked_bytes,
+ BitMap* card_bm,
CMTaskQueue* task_queue,
CMTaskQueueSet* task_queues)
: _g1h(G1CollectedHeap::heap()),
@@ -4713,7 +5342,9 @@
_task_queue(task_queue),
_task_queues(task_queues),
_cm_oop_closure(NULL),
- _aborted_region(MemRegion()) {
+ _aborted_region(MemRegion()),
+ _marked_bytes_array(marked_bytes),
+ _card_bm(card_bm) {
guarantee(task_queue != NULL, "invariant");
guarantee(task_queues != NULL, "invariant");
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -84,8 +84,8 @@
}
// iteration
- bool iterate(BitMapClosure* cl) { return _bm.iterate(cl); }
- bool iterate(BitMapClosure* cl, MemRegion mr);
+ inline bool iterate(BitMapClosure* cl, MemRegion mr);
+ inline bool iterate(BitMapClosure* cl);
// Return the address corresponding to the next marked bit at or after
// "addr", and before "limit", if "limit" is non-NULL. If there is no
@@ -349,10 +349,62 @@
high_verbose // per object verbose
} CMVerboseLevel;
+class YoungList;
+
+// Root Regions are regions that are not empty at the beginning of a
+// marking cycle and which we might collect during an evacuation pause
+// while the cycle is active. Given that, during evacuation pauses, we
+// do not copy objects that are explicitly marked, what we have to do
+// for the root regions is to scan them and mark all objects reachable
+// from them. According to the SATB assumptions, we only need to visit
+// each object once during marking. So, as long as we finish this scan
+// before the next evacuation pause, we can copy the objects from the
+// root regions without having to mark them or do anything else to them.
+//
+// Currently, we only support root region scanning once (at the start
+// of the marking cycle) and the root regions are all the survivor
+// regions populated during the initial-mark pause.
+class CMRootRegions VALUE_OBJ_CLASS_SPEC {
+private:
+ YoungList* _young_list;
+ ConcurrentMark* _cm;
+
+ volatile bool _scan_in_progress;
+ volatile bool _should_abort;
+ HeapRegion* volatile _next_survivor;
+
+public:
+ CMRootRegions();
+ // We actually do most of the initialization in this method.
+ void init(G1CollectedHeap* g1h, ConcurrentMark* cm);
+
+ // Reset the claiming / scanning of the root regions.
+ void prepare_for_scan();
+
+ // Forces get_next() to return NULL so that the iteration aborts early.
+ void abort() { _should_abort = true; }
+
+ // Return true if the CM thread are actively scanning root regions,
+ // false otherwise.
+ bool scan_in_progress() { return _scan_in_progress; }
+
+ // Claim the next root region to scan atomically, or return NULL if
+ // all have been claimed.
+ HeapRegion* claim_next();
+
+ // Flag that we're done with root region scanning and notify anyone
+ // who's waiting on it. If aborted is false, assume that all regions
+ // have been claimed.
+ void scan_finished();
+
+ // If CM threads are still scanning root regions, wait until they
+ // are done. Return true if we had to wait, false otherwise.
+ bool wait_until_scan_finished();
+};
class ConcurrentMarkThread;
-class ConcurrentMark: public CHeapObj {
+class ConcurrentMark : public CHeapObj {
friend class ConcurrentMarkThread;
friend class CMTask;
friend class CMBitMapClosure;
@@ -386,7 +438,7 @@
FreeRegionList _cleanup_list;
- // CMS marking support structures
+ // Concurrent marking support structures
CMBitMap _markBitMap1;
CMBitMap _markBitMap2;
CMBitMapRO* _prevMarkBitMap; // completed mark bitmap
@@ -400,6 +452,9 @@
HeapWord* _heap_start;
HeapWord* _heap_end;
+ // Root region tracking and claiming.
+ CMRootRegions _root_regions;
+
// For gray objects
CMMarkStack _markStack; // Grey objects behind global finger.
CMRegionStack _regionStack; // Grey regions behind global finger.
@@ -426,7 +481,6 @@
WorkGangBarrierSync _first_overflow_barrier_sync;
WorkGangBarrierSync _second_overflow_barrier_sync;
-
// this is set by any task, when an overflow on the global data
// structures is detected.
volatile bool _has_overflown;
@@ -554,9 +608,9 @@
bool has_overflown() { return _has_overflown; }
void set_has_overflown() { _has_overflown = true; }
void clear_has_overflown() { _has_overflown = false; }
+ bool restart_for_overflow() { return _restart_for_overflow; }
bool has_aborted() { return _has_aborted; }
- bool restart_for_overflow() { return _restart_for_overflow; }
// Methods to enter the two overflow sync barriers
void enter_first_sync_barrier(int task_num);
@@ -578,6 +632,27 @@
}
}
+ // Live Data Counting data structures...
+ // These data structures are initialized at the start of
+ // marking. They are written to while marking is active.
+ // They are aggregated during remark; the aggregated values
+ // are then used to populate the _region_bm, _card_bm, and
+ // the total live bytes, which are then subsequently updated
+ // during cleanup.
+
+ // An array of bitmaps (one bit map per task). Each bitmap
+ // is used to record the cards spanned by the live objects
+ // marked by that task/worker.
+ BitMap* _count_card_bitmaps;
+
+ // Used to record the number of marked live bytes
+ // (for each region, by worker thread).
+ size_t** _count_marked_bytes;
+
+ // Card index of the bottom of the G1 heap. Used for biasing indices into
+ // the card bitmaps.
+ intptr_t _heap_bottom_card_num;
+
public:
// Manipulation of the global mark stack.
// Notice that the first mark_stack_push is CAS-based, whereas the
@@ -671,6 +746,8 @@
// Returns true if there are any aborted memory regions.
bool has_aborted_regions();
+ CMRootRegions* root_regions() { return &_root_regions; }
+
bool concurrent_marking_in_progress() {
return _concurrent_marking_in_progress;
}
@@ -703,6 +780,7 @@
ConcurrentMark(ReservedSpace rs, int max_regions);
~ConcurrentMark();
+
ConcurrentMarkThread* cmThread() { return _cmThread; }
CMBitMapRO* prevMarkBitMap() const { return _prevMarkBitMap; }
@@ -720,8 +798,17 @@
// G1CollectedHeap
// This notifies CM that a root during initial-mark needs to be
- // grayed. It is MT-safe.
- inline void grayRoot(oop obj, size_t word_size);
+ // grayed. It is MT-safe. word_size is the size of the object in
+ // words. It is passed explicitly as sometimes we cannot calculate
+ // it from the given object because it might be in an inconsistent
+ // state (e.g., in to-space and being copied). So the caller is
+ // responsible for dealing with this issue (e.g., get the size from
+ // the from-space image when the to-space image might be
+ // inconsistent) and always passing the size. hr is the region that
+ // contains the object and it's passed optionally from callers who
+ // might already have it (no point in recalculating it).
+ inline void grayRoot(oop obj, size_t word_size,
+ uint worker_id, HeapRegion* hr = NULL);
// It's used during evacuation pauses to gray a region, if
// necessary, and it's MT-safe. It assumes that the caller has
@@ -772,6 +859,13 @@
void checkpointRootsInitialPre();
void checkpointRootsInitialPost();
+ // Scan all the root regions and mark everything reachable from
+ // them.
+ void scanRootRegions();
+
+ // Scan a single root region and mark everything reachable from it.
+ void scanRootRegion(HeapRegion* hr, uint worker_id);
+
// Do concurrent phase of marking, to a tentative transitive closure.
void markFromRoots();
@@ -781,15 +875,13 @@
void checkpointRootsFinal(bool clear_all_soft_refs);
void checkpointRootsFinalWork();
- void calcDesiredRegions();
void cleanup();
void completeCleanup();
// Mark in the previous bitmap. NB: this is usually read-only, so use
// this carefully!
inline void markPrev(oop p);
- inline void markNext(oop p);
- void clear(oop p);
+
// Clears marks for all objects in the given range, for the prev,
// next, or both bitmaps. NB: the previous bitmap is usually
// read-only, so use this carefully!
@@ -913,6 +1005,114 @@
bool verbose_high() {
return _MARKING_VERBOSE_ && _verbose_level >= high_verbose;
}
+
+ // Counting data structure accessors
+
+ // Returns the card number of the bottom of the G1 heap.
+ // Used in biasing indices into accounting card bitmaps.
+ intptr_t heap_bottom_card_num() const {
+ return _heap_bottom_card_num;
+ }
+
+ // Returns the card bitmap for a given task or worker id.
+ BitMap* count_card_bitmap_for(uint worker_id) {
+ assert(0 <= worker_id && worker_id < _max_task_num, "oob");
+ assert(_count_card_bitmaps != NULL, "uninitialized");
+ BitMap* task_card_bm = &_count_card_bitmaps[worker_id];
+ assert(task_card_bm->size() == _card_bm.size(), "size mismatch");
+ return task_card_bm;
+ }
+
+ // Returns the array containing the marked bytes for each region,
+ // for the given worker or task id.
+ size_t* count_marked_bytes_array_for(uint worker_id) {
+ assert(0 <= worker_id && worker_id < _max_task_num, "oob");
+ assert(_count_marked_bytes != NULL, "uninitialized");
+ size_t* marked_bytes_array = _count_marked_bytes[worker_id];
+ assert(marked_bytes_array != NULL, "uninitialized");
+ return marked_bytes_array;
+ }
+
+ // Returns the index in the liveness accounting card table bitmap
+ // for the given address
+ inline BitMap::idx_t card_bitmap_index_for(HeapWord* addr);
+
+ // Counts the size of the given memory region in the the given
+ // marked_bytes array slot for the given HeapRegion.
+ // Sets the bits in the given card bitmap that are associated with the
+ // cards that are spanned by the memory region.
+ inline void count_region(MemRegion mr, HeapRegion* hr,
+ size_t* marked_bytes_array,
+ BitMap* task_card_bm);
+
+ // Counts the given memory region in the task/worker counting
+ // data structures for the given worker id.
+ inline void count_region(MemRegion mr, HeapRegion* hr, uint worker_id);
+
+ // Counts the given memory region in the task/worker counting
+ // data structures for the given worker id.
+ inline void count_region(MemRegion mr, uint worker_id);
+
+ // Counts the given object in the given task/worker counting
+ // data structures.
+ inline void count_object(oop obj, HeapRegion* hr,
+ size_t* marked_bytes_array,
+ BitMap* task_card_bm);
+
+ // Counts the given object in the task/worker counting data
+ // structures for the given worker id.
+ inline void count_object(oop obj, HeapRegion* hr, uint worker_id);
+
+ // Attempts to mark the given object and, if successful, counts
+ // the object in the given task/worker counting structures.
+ inline bool par_mark_and_count(oop obj, HeapRegion* hr,
+ size_t* marked_bytes_array,
+ BitMap* task_card_bm);
+
+ // Attempts to mark the given object and, if successful, counts
+ // the object in the task/worker counting structures for the
+ // given worker id.
+ inline bool par_mark_and_count(oop obj, size_t word_size,
+ HeapRegion* hr, uint worker_id);
+
+ // Attempts to mark the given object and, if successful, counts
+ // the object in the task/worker counting structures for the
+ // given worker id.
+ inline bool par_mark_and_count(oop obj, HeapRegion* hr, uint worker_id);
+
+ // Similar to the above routine but we don't know the heap region that
+ // contains the object to be marked/counted, which this routine looks up.
+ inline bool par_mark_and_count(oop obj, uint worker_id);
+
+ // Similar to the above routine but there are times when we cannot
+ // safely calculate the size of obj due to races and we, therefore,
+ // pass the size in as a parameter. It is the caller's reponsibility
+ // to ensure that the size passed in for obj is valid.
+ inline bool par_mark_and_count(oop obj, size_t word_size, uint worker_id);
+
+ // Unconditionally mark the given object, and unconditinally count
+ // the object in the counting structures for worker id 0.
+ // Should *not* be called from parallel code.
+ inline bool mark_and_count(oop obj, HeapRegion* hr);
+
+ // Similar to the above routine but we don't know the heap region that
+ // contains the object to be marked/counted, which this routine looks up.
+ // Should *not* be called from parallel code.
+ inline bool mark_and_count(oop obj);
+
+protected:
+ // Clear all the per-task bitmaps and arrays used to store the
+ // counting data.
+ void clear_all_count_data();
+
+ // Aggregates the counting data for each worker/task
+ // that was constructed while marking. Also sets
+ // the amount of marked bytes for each region and
+ // the top at concurrent mark count.
+ void aggregate_count_data();
+
+ // Verification routine
+ void verify_count_data();
};
// A class representing a marking task.
@@ -1031,6 +1231,12 @@
TruncatedSeq _marking_step_diffs_ms;
+ // Counting data structures. Embedding the task's marked_bytes_array
+ // and card bitmap into the actual task saves having to go through
+ // the ConcurrentMark object.
+ size_t* _marked_bytes_array;
+ BitMap* _card_bm;
+
// LOTS of statistics related with this task
#if _MARKING_STATS_
NumberSeq _all_clock_intervals_ms;
@@ -1196,6 +1402,7 @@
}
CMTask(int task_num, ConcurrentMark *cm,
+ size_t* marked_bytes, BitMap* card_bm,
CMTaskQueue* task_queue, CMTaskQueueSet* task_queues);
// it prints statistics associated with this task
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -28,6 +28,214 @@
#include "gc_implementation/g1/concurrentMark.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+// Returns the index in the liveness accounting card bitmap
+// for the given address
+inline BitMap::idx_t ConcurrentMark::card_bitmap_index_for(HeapWord* addr) {
+ // Below, the term "card num" means the result of shifting an address
+ // by the card shift -- address 0 corresponds to card number 0. One
+ // must subtract the card num of the bottom of the heap to obtain a
+ // card table index.
+
+ intptr_t card_num = intptr_t(uintptr_t(addr) >> CardTableModRefBS::card_shift);
+ return card_num - heap_bottom_card_num();
+}
+
+// Counts the given memory region in the given task/worker
+// counting data structures.
+inline void ConcurrentMark::count_region(MemRegion mr, HeapRegion* hr,
+ size_t* marked_bytes_array,
+ BitMap* task_card_bm) {
+ G1CollectedHeap* g1h = _g1h;
+ HeapWord* start = mr.start();
+ HeapWord* last = mr.last();
+ size_t region_size_bytes = mr.byte_size();
+ size_t index = hr->hrs_index();
+
+ assert(!hr->continuesHumongous(), "should not be HC region");
+ assert(hr == g1h->heap_region_containing(start), "sanity");
+ assert(hr == g1h->heap_region_containing(mr.last()), "sanity");
+ assert(marked_bytes_array != NULL, "pre-condition");
+ assert(task_card_bm != NULL, "pre-condition");
+
+ // Add to the task local marked bytes for this region.
+ marked_bytes_array[index] += region_size_bytes;
+
+ BitMap::idx_t start_idx = card_bitmap_index_for(start);
+ BitMap::idx_t last_idx = card_bitmap_index_for(last);
+
+ // The card bitmap is task/worker specific => no need to use 'par' routines.
+ // Set bits in the inclusive bit range [start_idx, last_idx].
+ //
+ // For small ranges use a simple loop; otherwise use set_range
+ // The range are the cards that are spanned by the object/region
+ // so 8 cards will allow objects/regions up to 4K to be handled
+ // using the loop.
+ if ((last_idx - start_idx) <= 8) {
+ for (BitMap::idx_t i = start_idx; i <= last_idx; i += 1) {
+ task_card_bm->set_bit(i);
+ }
+ } else {
+ assert(last_idx < task_card_bm->size(), "sanity");
+ // Note: BitMap::set_range() is exclusive.
+ task_card_bm->set_range(start_idx, last_idx+1);
+ }
+}
+
+// Counts the given memory region in the task/worker counting
+// data structures for the given worker id.
+inline void ConcurrentMark::count_region(MemRegion mr,
+ HeapRegion* hr,
+ uint worker_id) {
+ size_t* marked_bytes_array = count_marked_bytes_array_for(worker_id);
+ BitMap* task_card_bm = count_card_bitmap_for(worker_id);
+ count_region(mr, hr, marked_bytes_array, task_card_bm);
+}
+
+// Counts the given memory region, which may be a single object, in the
+// task/worker counting data structures for the given worker id.
+inline void ConcurrentMark::count_region(MemRegion mr, uint worker_id) {
+ HeapWord* addr = mr.start();
+ HeapRegion* hr = _g1h->heap_region_containing_raw(addr);
+ count_region(mr, hr, worker_id);
+}
+
+// Counts the given object in the given task/worker counting data structures.
+inline void ConcurrentMark::count_object(oop obj,
+ HeapRegion* hr,
+ size_t* marked_bytes_array,
+ BitMap* task_card_bm) {
+ MemRegion mr((HeapWord*)obj, obj->size());
+ count_region(mr, hr, marked_bytes_array, task_card_bm);
+}
+
+// Counts the given object in the task/worker counting data
+// structures for the given worker id.
+inline void ConcurrentMark::count_object(oop obj,
+ HeapRegion* hr,
+ uint worker_id) {
+ size_t* marked_bytes_array = count_marked_bytes_array_for(worker_id);
+ BitMap* task_card_bm = count_card_bitmap_for(worker_id);
+ HeapWord* addr = (HeapWord*) obj;
+ count_object(obj, hr, marked_bytes_array, task_card_bm);
+}
+
+// Attempts to mark the given object and, if successful, counts
+// the object in the given task/worker counting structures.
+inline bool ConcurrentMark::par_mark_and_count(oop obj,
+ HeapRegion* hr,
+ size_t* marked_bytes_array,
+ BitMap* task_card_bm) {
+ HeapWord* addr = (HeapWord*)obj;
+ if (_nextMarkBitMap->parMark(addr)) {
+ // Update the task specific count data for the object.
+ count_object(obj, hr, marked_bytes_array, task_card_bm);
+ return true;
+ }
+ return false;
+}
+
+// Attempts to mark the given object and, if successful, counts
+// the object in the task/worker counting structures for the
+// given worker id.
+inline bool ConcurrentMark::par_mark_and_count(oop obj,
+ size_t word_size,
+ HeapRegion* hr,
+ uint worker_id) {
+ HeapWord* addr = (HeapWord*)obj;
+ if (_nextMarkBitMap->parMark(addr)) {
+ MemRegion mr(addr, word_size);
+ count_region(mr, hr, worker_id);
+ return true;
+ }
+ return false;
+}
+
+// Attempts to mark the given object and, if successful, counts
+// the object in the task/worker counting structures for the
+// given worker id.
+inline bool ConcurrentMark::par_mark_and_count(oop obj,
+ HeapRegion* hr,
+ uint worker_id) {
+ HeapWord* addr = (HeapWord*)obj;
+ if (_nextMarkBitMap->parMark(addr)) {
+ // Update the task specific count data for the object.
+ count_object(obj, hr, worker_id);
+ return true;
+ }
+ return false;
+}
+
+// As above - but we don't know the heap region containing the
+// object and so have to supply it.
+inline bool ConcurrentMark::par_mark_and_count(oop obj, uint worker_id) {
+ HeapWord* addr = (HeapWord*)obj;
+ HeapRegion* hr = _g1h->heap_region_containing_raw(addr);
+ return par_mark_and_count(obj, hr, worker_id);
+}
+
+// Similar to the above routine but we already know the size, in words, of
+// the object that we wish to mark/count
+inline bool ConcurrentMark::par_mark_and_count(oop obj,
+ size_t word_size,
+ uint worker_id) {
+ HeapWord* addr = (HeapWord*)obj;
+ if (_nextMarkBitMap->parMark(addr)) {
+ // Update the task specific count data for the object.
+ MemRegion mr(addr, word_size);
+ count_region(mr, worker_id);
+ return true;
+ }
+ return false;
+}
+
+// Unconditionally mark the given object, and unconditinally count
+// the object in the counting structures for worker id 0.
+// Should *not* be called from parallel code.
+inline bool ConcurrentMark::mark_and_count(oop obj, HeapRegion* hr) {
+ HeapWord* addr = (HeapWord*)obj;
+ _nextMarkBitMap->mark(addr);
+ // Update the task specific count data for the object.
+ count_object(obj, hr, 0 /* worker_id */);
+ return true;
+}
+
+// As above - but we don't have the heap region containing the
+// object, so we have to supply it.
+inline bool ConcurrentMark::mark_and_count(oop obj) {
+ HeapWord* addr = (HeapWord*)obj;
+ HeapRegion* hr = _g1h->heap_region_containing_raw(addr);
+ return mark_and_count(obj, hr);
+}
+
+inline bool CMBitMapRO::iterate(BitMapClosure* cl, MemRegion mr) {
+ HeapWord* start_addr = MAX2(startWord(), mr.start());
+ HeapWord* end_addr = MIN2(endWord(), mr.end());
+
+ if (end_addr > start_addr) {
+ // Right-open interval [start-offset, end-offset).
+ BitMap::idx_t start_offset = heapWordToOffset(start_addr);
+ BitMap::idx_t end_offset = heapWordToOffset(end_addr);
+
+ start_offset = _bm.get_next_one_offset(start_offset, end_offset);
+ while (start_offset < end_offset) {
+ HeapWord* obj_addr = offsetToHeapWord(start_offset);
+ oop obj = (oop) obj_addr;
+ if (!cl->do_bit(start_offset)) {
+ return false;
+ }
+ HeapWord* next_addr = MIN2(obj_addr + obj->size(), end_addr);
+ BitMap::idx_t next_offset = heapWordToOffset(next_addr);
+ start_offset = _bm.get_next_one_offset(next_offset, end_offset);
+ }
+ }
+ return true;
+}
+
+inline bool CMBitMapRO::iterate(BitMapClosure* cl) {
+ MemRegion mr(startWord(), sizeInWords());
+ return iterate(cl, mr);
+}
+
inline void CMTask::push(oop obj) {
HeapWord* objAddr = (HeapWord*) obj;
assert(_g1h->is_in_g1_reserved(objAddr), "invariant");
@@ -84,7 +292,7 @@
HeapWord* objAddr = (HeapWord*) obj;
assert(obj->is_oop_or_null(true /* ignore mark word */), "Error");
- if (_g1h->is_in_g1_reserved(objAddr)) {
+ if (_g1h->is_in_g1_reserved(objAddr)) {
assert(obj != NULL, "null check is implicit");
if (!_nextMarkBitMap->isMarked(objAddr)) {
// Only get the containing region if the object is not marked on the
@@ -98,9 +306,9 @@
}
// we need to mark it first
- if (_nextMarkBitMap->parMark(objAddr)) {
+ if (_cm->par_mark_and_count(obj, hr, _marked_bytes_array, _card_bm)) {
// No OrderAccess:store_load() is needed. It is implicit in the
- // CAS done in parMark(objAddr) above
+ // CAS done in CMBitMap::parMark() call in the routine above.
HeapWord* global_finger = _cm->finger();
#if _CHECK_BOTH_FINGERS_
@@ -160,25 +368,20 @@
((CMBitMap*)_prevMarkBitMap)->mark((HeapWord*) p);
}
-inline void ConcurrentMark::markNext(oop p) {
- assert(!_nextMarkBitMap->isMarked((HeapWord*) p), "sanity");
- _nextMarkBitMap->mark((HeapWord*) p);
-}
-
-inline void ConcurrentMark::grayRoot(oop obj, size_t word_size) {
+inline void ConcurrentMark::grayRoot(oop obj, size_t word_size,
+ uint worker_id, HeapRegion* hr) {
+ assert(obj != NULL, "pre-condition");
HeapWord* addr = (HeapWord*) obj;
+ if (hr == NULL) {
+ hr = _g1h->heap_region_containing_raw(addr);
+ } else {
+ assert(hr->is_in(addr), "pre-condition");
+ }
+ assert(hr != NULL, "sanity");
+ // Given that we're looking for a region that contains an object
+ // header it's impossible to get back a HC region.
+ assert(!hr->continuesHumongous(), "sanity");
- // Currently we don't do anything with word_size but we will use it
- // in the very near future in the liveness calculation piggy-backing
- // changes.
-
-#ifdef ASSERT
- HeapRegion* hr = _g1h->heap_region_containing(addr);
- assert(hr != NULL, "sanity");
- assert(!hr->is_survivor(), "should not allocate survivors during IM");
- assert(addr < hr->next_top_at_mark_start(),
- err_msg("addr: "PTR_FORMAT" hr: "HR_FORMAT" NTAMS: "PTR_FORMAT,
- addr, HR_FORMAT_PARAMS(hr), hr->next_top_at_mark_start()));
// We cannot assert that word_size == obj->size() given that obj
// might not be in a consistent state (another thread might be in
// the process of copying it). So the best thing we can do is to
@@ -188,10 +391,11 @@
err_msg("size: "SIZE_FORMAT" capacity: "SIZE_FORMAT" "HR_FORMAT,
word_size * HeapWordSize, hr->capacity(),
HR_FORMAT_PARAMS(hr)));
-#endif // ASSERT
- if (!_nextMarkBitMap->isMarked(addr)) {
- _nextMarkBitMap->parMark(addr);
+ if (addr < hr->next_top_at_mark_start()) {
+ if (!_nextMarkBitMap->isMarked(addr)) {
+ par_mark_and_count(obj, word_size, hr, worker_id);
+ }
}
}
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -44,9 +44,7 @@
_started(false),
_in_progress(false),
_vtime_accum(0.0),
- _vtime_mark_accum(0.0),
- _vtime_count_accum(0.0)
-{
+ _vtime_mark_accum(0.0) {
create_and_start();
}
@@ -94,9 +92,36 @@
ResourceMark rm;
HandleMark hm;
double cycle_start = os::elapsedVTime();
- double mark_start_sec = os::elapsedTime();
char verbose_str[128];
+ // We have to ensure that we finish scanning the root regions
+ // before the next GC takes place. To ensure this we have to
+ // make sure that we do not join the STS until the root regions
+ // have been scanned. If we did then it's possible that a
+ // subsequent GC could block us from joining the STS and proceed
+ // without the root regions have been scanned which would be a
+ // correctness issue.
+
+ double scan_start = os::elapsedTime();
+ if (!cm()->has_aborted()) {
+ if (PrintGC) {
+ gclog_or_tty->date_stamp(PrintGCDateStamps);
+ gclog_or_tty->stamp(PrintGCTimeStamps);
+ gclog_or_tty->print_cr("[GC concurrent-root-region-scan-start]");
+ }
+
+ _cm->scanRootRegions();
+
+ double scan_end = os::elapsedTime();
+ if (PrintGC) {
+ gclog_or_tty->date_stamp(PrintGCDateStamps);
+ gclog_or_tty->stamp(PrintGCTimeStamps);
+ gclog_or_tty->print_cr("[GC concurrent-root-region-scan-end, %1.7lf]",
+ scan_end - scan_start);
+ }
+ }
+
+ double mark_start_sec = os::elapsedTime();
if (PrintGC) {
gclog_or_tty->date_stamp(PrintGCDateStamps);
gclog_or_tty->stamp(PrintGCTimeStamps);
@@ -148,36 +173,12 @@
}
} while (cm()->restart_for_overflow());
- double counting_start_time = os::elapsedVTime();
- if (!cm()->has_aborted()) {
- double count_start_sec = os::elapsedTime();
- if (PrintGC) {
- gclog_or_tty->date_stamp(PrintGCDateStamps);
- gclog_or_tty->stamp(PrintGCTimeStamps);
- gclog_or_tty->print_cr("[GC concurrent-count-start]");
- }
-
- _sts.join();
- _cm->calcDesiredRegions();
- _sts.leave();
-
- if (!cm()->has_aborted()) {
- double count_end_sec = os::elapsedTime();
- if (PrintGC) {
- gclog_or_tty->date_stamp(PrintGCDateStamps);
- gclog_or_tty->stamp(PrintGCTimeStamps);
- gclog_or_tty->print_cr("[GC concurrent-count-end, %1.7lf]",
- count_end_sec - count_start_sec);
- }
- }
- }
-
double end_time = os::elapsedVTime();
- _vtime_count_accum += (end_time - counting_start_time);
// Update the total virtual time before doing this, since it will try
// to measure it to get the vtime for this marking. We purposely
// neglect the presumably-short "completeCleanup" phase here.
_vtime_accum = (end_time - _vtime_start);
+
if (!cm()->has_aborted()) {
if (g1_policy->adaptive_young_list_length()) {
double now = os::elapsedTime();
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -40,7 +40,6 @@
double _vtime_accum; // Accumulated virtual time.
double _vtime_mark_accum;
- double _vtime_count_accum;
public:
virtual void run();
@@ -69,8 +68,6 @@
double vtime_accum();
// Marking virtual time so far
double vtime_mark_accum();
- // Counting virtual time so far.
- double vtime_count_accum() { return _vtime_count_accum; }
ConcurrentMark* cm() { return _cm; }
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -174,13 +174,10 @@
}
};
-YoungList::YoungList(G1CollectedHeap* g1h)
- : _g1h(g1h), _head(NULL),
- _length(0),
- _last_sampled_rs_lengths(0),
- _survivor_head(NULL), _survivor_tail(NULL), _survivor_length(0)
-{
- guarantee( check_list_empty(false), "just making sure..." );
+YoungList::YoungList(G1CollectedHeap* g1h) :
+ _g1h(g1h), _head(NULL), _length(0), _last_sampled_rs_lengths(0),
+ _survivor_head(NULL), _survivor_tail(NULL), _survivor_length(0) {
+ guarantee(check_list_empty(false), "just making sure...");
}
void YoungList::push_region(HeapRegion *hr) {
@@ -1029,6 +1026,15 @@
assert(isHumongous(word_size), "attempt_allocation_humongous() "
"should only be called for humongous allocations");
+ // Humongous objects can exhaust the heap quickly, so we should check if we
+ // need to start a marking cycle at each humongous object allocation. We do
+ // the check before we do the actual allocation. The reason for doing it
+ // before the allocation is that we avoid having to keep track of the newly
+ // allocated memory while we do a GC.
+ if (g1_policy()->need_to_start_conc_mark("concurrent humongous allocation", word_size)) {
+ collect(GCCause::_g1_humongous_allocation);
+ }
+
// We will loop until a) we manage to successfully perform the
// allocation or b) we successfully schedule a collection which
// fails to perform the allocation. b) is the only case when we'll
@@ -1111,7 +1117,11 @@
return _mutator_alloc_region.attempt_allocation_locked(word_size,
false /* bot_updates */);
} else {
- return humongous_obj_allocate(word_size);
+ HeapWord* result = humongous_obj_allocate(word_size);
+ if (result != NULL && g1_policy()->need_to_start_conc_mark("STW humongous allocation")) {
+ g1_policy()->set_initiate_conc_mark_if_possible();
+ }
+ return result;
}
ShouldNotReachHere();
@@ -1257,7 +1267,18 @@
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);
@@ -1286,7 +1307,8 @@
ref_processor_cm()->verify_no_references_recorded();
// Abandon current iterations of concurrent marking and concurrent
- // refinement, if any are in progress.
+ // 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.
@@ -2295,7 +2317,8 @@
bool G1CollectedHeap::should_do_concurrent_full_gc(GCCause::Cause cause) {
return
((cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) ||
- (cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent));
+ (cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent) ||
+ cause == GCCause::_g1_humongous_allocation);
}
#ifndef PRODUCT
@@ -3545,19 +3568,25 @@
verify_region_sets_optional();
verify_dirty_young_regions();
+ // This call will decide whether this pause is an initial-mark
+ // pause. If it is, during_initial_mark_pause() will return true
+ // for the duration of this pause.
+ g1_policy()->decide_on_conc_mark_initiation();
+
+ // We do not allow initial-mark to be piggy-backed on a mixed GC.
+ assert(!g1_policy()->during_initial_mark_pause() ||
+ g1_policy()->gcs_are_young(), "sanity");
+
+ // We also do not allow mixed GCs during marking.
+ assert(!mark_in_progress() || g1_policy()->gcs_are_young(), "sanity");
+
+ // Record whether this pause is an initial mark. When the current
+ // thread has completed its logging output and it's safe to signal
+ // the CM thread, the flag's value in the policy has been reset.
+ bool should_start_conc_mark = g1_policy()->during_initial_mark_pause();
+
+ // Inner scope for scope based logging, timers, and stats collection
{
- // This call will decide whether this pause is an initial-mark
- // pause. If it is, during_initial_mark_pause() will return true
- // for the duration of this pause.
- g1_policy()->decide_on_conc_mark_initiation();
-
- // We do not allow initial-mark to be piggy-backed on a mixed GC.
- assert(!g1_policy()->during_initial_mark_pause() ||
- g1_policy()->gcs_are_young(), "sanity");
-
- // We also do not allow mixed GCs during marking.
- assert(!mark_in_progress() || g1_policy()->gcs_are_young(), "sanity");
-
char verbose_str[128];
sprintf(verbose_str, "GC pause ");
if (g1_policy()->gcs_are_young()) {
@@ -3613,7 +3642,6 @@
Universe::verify(/* allow dirty */ false,
/* silent */ false,
/* option */ VerifyOption_G1UsePrevMarking);
-
}
COMPILER2_PRESENT(DerivedPointerTable::clear());
@@ -3656,6 +3684,18 @@
g1_policy()->record_collection_pause_start(start_time_sec,
start_used_bytes);
+ double scan_wait_start = os::elapsedTime();
+ // We have to wait until the CM threads finish scanning the
+ // root regions as it's the only way to ensure that all the
+ // objects on them have been correctly scanned before we start
+ // moving them during the GC.
+ bool waited = _cm->root_regions()->wait_until_scan_finished();
+ if (waited) {
+ double scan_wait_end = os::elapsedTime();
+ double wait_time_ms = (scan_wait_end - scan_wait_start) * 1000.0;
+ g1_policy()->record_root_region_scan_wait_time(wait_time_ms);
+ }
+
#if YOUNG_LIST_VERBOSE
gclog_or_tty->print_cr("\nAfter recording pause start.\nYoung_list:");
_young_list->print();
@@ -3765,16 +3805,14 @@
}
if (g1_policy()->during_initial_mark_pause()) {
+ // We have to do this before we notify the CM threads that
+ // they can start working to make sure that all the
+ // appropriate initialization is done on the CM object.
concurrent_mark()->checkpointRootsInitialPost();
set_marking_started();
- // CAUTION: after the doConcurrentMark() call below,
- // the concurrent marking thread(s) could be running
- // concurrently with us. Make sure that anything after
- // this point does not assume that we are the only GC thread
- // running. Note: of course, the actual marking work will
- // not start until the safepoint itself is released in
- // ConcurrentGCThread::safepoint_desynchronize().
- doConcurrentMark();
+ // Note that we don't actually trigger the CM thread at
+ // this point. We do that later when we're sure that
+ // the current thread has completed its logging output.
}
allocate_dummy_regions();
@@ -3884,6 +3922,15 @@
}
}
+ // The closing of the inner scope, immediately above, will complete
+ // the PrintGC logging output. The record_collection_pause_end() call
+ // above will complete the logging output of PrintGCDetails.
+ //
+ // It is not yet to safe, however, to tell the concurrent mark to
+ // start as we have some optional output below. We don't want the
+ // output from the concurrent mark thread interfering with this
+ // logging output either.
+
_hrs.verify_optional();
verify_region_sets_optional();
@@ -3901,6 +3948,21 @@
g1_rem_set()->print_summary_info();
}
+ // It should now be safe to tell the concurrent mark thread to start
+ // without its logging output interfering with the logging output
+ // that came from the pause.
+
+ if (should_start_conc_mark) {
+ // CAUTION: after the doConcurrentMark() call below,
+ // the concurrent marking thread(s) could be running
+ // concurrently with us. Make sure that anything after
+ // this point does not assume that we are the only GC thread
+ // running. Note: of course, the actual marking work will
+ // not start until the safepoint itself is released in
+ // ConcurrentGCThread::safepoint_desynchronize().
+ doConcurrentMark();
+ }
+
return true;
}
@@ -4162,7 +4224,7 @@
G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) :
ParGCAllocBuffer(gclab_word_size), _retired(false) { }
-G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, int queue_num)
+G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num)
: _g1h(g1h),
_refs(g1h->task_queue(queue_num)),
_dcq(&g1h->dirty_card_queue_set()),
@@ -4283,6 +4345,7 @@
G1ParScanThreadState* par_scan_state) :
_g1(g1), _g1_rem(_g1->g1_rem_set()), _cm(_g1->concurrent_mark()),
_par_scan_state(par_scan_state),
+ _worker_id(par_scan_state->queue_num()),
_during_initial_mark(_g1->g1_policy()->during_initial_mark_pause()),
_mark_in_progress(_g1->mark_in_progress()) { }
@@ -4294,7 +4357,7 @@
#endif // ASSERT
// We know that the object is not moving so it's safe to read its size.
- _cm->grayRoot(obj, (size_t) obj->size());
+ _cm->grayRoot(obj, (size_t) obj->size(), _worker_id);
}
void G1ParCopyHelper::mark_forwarded_object(oop from_obj, oop to_obj) {
@@ -4316,7 +4379,7 @@
// worker so we cannot trust that its to-space image is
// well-formed. So we have to read its size from its from-space
// image which we know should not be changing.
- _cm->grayRoot(to_obj, (size_t) from_obj->size());
+ _cm->grayRoot(to_obj, (size_t) from_obj->size(), _worker_id);
}
oop G1ParCopyHelper::copy_to_survivor_space(oop old) {
@@ -4406,6 +4469,8 @@
assert(barrier != G1BarrierRS || obj != NULL,
"Precondition: G1BarrierRS implies obj is non-NULL");
+ assert(_worker_id == _par_scan_state->queue_num(), "sanity");
+
// here the null check is implicit in the cset_fast_test() test
if (_g1->in_cset_fast_test(obj)) {
oop forwardee;
@@ -4424,7 +4489,7 @@
// When scanning the RS, we only care about objs in CS.
if (barrier == G1BarrierRS) {
- _par_scan_state->update_rs(_from, p, _par_scan_state->queue_num());
+ _par_scan_state->update_rs(_from, p, _worker_id);
}
} else {
// The object is not in collection set. If we're a root scanning
@@ -4436,7 +4501,7 @@
}
if (barrier == G1BarrierEvac && obj != NULL) {
- _par_scan_state->update_rs(_from, p, _par_scan_state->queue_num());
+ _par_scan_state->update_rs(_from, p, _worker_id);
}
if (do_gen_barrier && obj != NULL) {
@@ -5666,16 +5731,6 @@
// And the region is empty.
assert(!used_mr.is_empty(), "Should not have empty regions in a CS.");
-
- // If marking is in progress then clear any objects marked in
- // the current region. Note mark_in_progress() returns false,
- // even during an initial mark pause, until the set_marking_started()
- // call which takes place later in the pause.
- if (mark_in_progress()) {
- assert(!g1_policy()->during_initial_mark_pause(), "sanity");
- _cm->nextMarkBitMap()->clearRange(used_mr);
- }
-
free_region(cur, &pre_used, &local_free_list, false /* par */);
} else {
cur->uninstall_surv_rate_group();
@@ -5742,8 +5797,9 @@
}
void G1CollectedHeap::reset_free_regions_coming() {
+ assert(free_regions_coming(), "pre-condition");
+
{
- assert(free_regions_coming(), "pre-condition");
MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag);
_free_regions_coming = false;
SecondaryFreeList_lock->notify_all();
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -355,6 +355,7 @@
// explicitly started if:
// (a) cause == _gc_locker and +GCLockerInvokesConcurrent, or
// (b) cause == _java_lang_system_gc and +ExplicitGCInvokesConcurrent.
+ // (c) cause == _g1_humongous_allocation
bool should_do_concurrent_full_gc(GCCause::Cause cause);
// Keeps track of how many "full collections" (i.e., Full GCs or
@@ -1172,6 +1173,10 @@
_old_set.remove(hr);
}
+ size_t non_young_capacity_bytes() {
+ return _old_set.total_capacity_bytes() + _humongous_set.total_capacity_bytes();
+ }
+
void set_free_regions_coming();
void reset_free_regions_coming();
bool free_regions_coming() { return _free_regions_coming; }
@@ -1904,7 +1909,7 @@
G1ParScanPartialArrayClosure* _partial_scan_cl;
int _hash_seed;
- int _queue_num;
+ uint _queue_num;
size_t _term_attempts;
@@ -1948,7 +1953,7 @@
}
public:
- G1ParScanThreadState(G1CollectedHeap* g1h, int queue_num);
+ G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num);
~G1ParScanThreadState() {
FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base);
@@ -2040,7 +2045,7 @@
}
int* hash_seed() { return &_hash_seed; }
- int queue_num() { return _queue_num; }
+ uint queue_num() { return _queue_num; }
size_t term_attempts() const { return _term_attempts; }
void note_term_attempt() { _term_attempts++; }
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -141,6 +141,7 @@
_cur_clear_ct_time_ms(0.0),
_mark_closure_time_ms(0.0),
+ _root_region_scan_wait_time_ms(0.0),
_cur_ref_proc_time_ms(0.0),
_cur_ref_enq_time_ms(0.0),
@@ -213,8 +214,6 @@
_survivor_bytes_before_gc(0),
_capacity_before_gc(0),
- _prev_collection_pause_used_at_end_bytes(0),
-
_eden_cset_region_length(0),
_survivor_cset_region_length(0),
_old_cset_region_length(0),
@@ -905,19 +904,10 @@
gclog_or_tty->print(" (%s)", gcs_are_young() ? "young" : "mixed");
}
- if (!during_initial_mark_pause()) {
- // 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.
- update_survivors_policy();
- } else {
- // The marking phase has a "we only copy implicitly live
- // objects during marking" invariant. The easiest way to ensure it
- // holds is not to allocate any survivor regions and tenure all
- // objects. In the future we might change this and handle survivor
- // regions specially during marking.
- tenure_all_objects();
- }
+ // 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.
+ update_survivors_policy();
assert(_g1->used() == _g1->recalculate_used(),
err_msg("sanity, used: "SIZE_FORMAT" recalculate_used: "SIZE_FORMAT,
@@ -969,6 +959,9 @@
// This is initialized to zero here and is set during
// the evacuation pause if marking is in progress.
_cur_satb_drain_time_ms = 0.0;
+ // This is initialized to zero here and is set during the evacuation
+ // pause if we actually waited for the root region scanning to finish.
+ _root_region_scan_wait_time_ms = 0.0;
_last_gc_was_young = false;
@@ -1140,6 +1133,50 @@
return ret;
}
+bool G1CollectorPolicy::need_to_start_conc_mark(const char* source, size_t alloc_word_size) {
+ if (_g1->concurrent_mark()->cmThread()->during_cycle()) {
+ return false;
+ }
+
+ size_t marking_initiating_used_threshold =
+ (_g1->capacity() / 100) * InitiatingHeapOccupancyPercent;
+ size_t cur_used_bytes = _g1->non_young_capacity_bytes();
+ size_t alloc_byte_size = alloc_word_size * HeapWordSize;
+
+ if ((cur_used_bytes + alloc_byte_size) > marking_initiating_used_threshold) {
+ if (gcs_are_young()) {
+ ergo_verbose5(ErgoConcCycles,
+ "request concurrent cycle initiation",
+ ergo_format_reason("occupancy higher than threshold")
+ ergo_format_byte("occupancy")
+ ergo_format_byte("allocation request")
+ ergo_format_byte_perc("threshold")
+ ergo_format_str("source"),
+ cur_used_bytes,
+ alloc_byte_size,
+ marking_initiating_used_threshold,
+ (double) InitiatingHeapOccupancyPercent,
+ source);
+ return true;
+ } else {
+ ergo_verbose5(ErgoConcCycles,
+ "do not request concurrent cycle initiation",
+ ergo_format_reason("still doing mixed collections")
+ ergo_format_byte("occupancy")
+ ergo_format_byte("allocation request")
+ ergo_format_byte_perc("threshold")
+ ergo_format_str("source"),
+ cur_used_bytes,
+ alloc_byte_size,
+ marking_initiating_used_threshold,
+ (double) InitiatingHeapOccupancyPercent,
+ source);
+ }
+ }
+
+ return false;
+}
+
// Anything below that is considered to be zero
#define MIN_TIMER_GRANULARITY 0.0000001
@@ -1166,44 +1203,16 @@
#endif // PRODUCT
last_pause_included_initial_mark = during_initial_mark_pause();
- if (last_pause_included_initial_mark)
+ if (last_pause_included_initial_mark) {
record_concurrent_mark_init_end(0.0);
-
- size_t marking_initiating_used_threshold =
- (_g1->capacity() / 100) * InitiatingHeapOccupancyPercent;
-
- if (!_g1->mark_in_progress() && !_last_young_gc) {
- assert(!last_pause_included_initial_mark, "invariant");
- if (cur_used_bytes > marking_initiating_used_threshold) {
- if (cur_used_bytes > _prev_collection_pause_used_at_end_bytes) {
- assert(!during_initial_mark_pause(), "we should not see this here");
-
- ergo_verbose3(ErgoConcCycles,
- "request concurrent cycle initiation",
- ergo_format_reason("occupancy higher than threshold")
- ergo_format_byte("occupancy")
- ergo_format_byte_perc("threshold"),
- cur_used_bytes,
- marking_initiating_used_threshold,
- (double) InitiatingHeapOccupancyPercent);
-
- // Note: this might have already been set, if during the last
- // pause we decided to start a cycle but at the beginning of
- // this pause we decided to postpone it. That's OK.
- set_initiate_conc_mark_if_possible();
- } else {
- ergo_verbose2(ErgoConcCycles,
- "do not request concurrent cycle initiation",
- ergo_format_reason("occupancy lower than previous occupancy")
- ergo_format_byte("occupancy")
- ergo_format_byte("previous occupancy"),
- cur_used_bytes,
- _prev_collection_pause_used_at_end_bytes);
- }
- }
}
- _prev_collection_pause_used_at_end_bytes = cur_used_bytes;
+ if (!_last_young_gc && need_to_start_conc_mark("end of GC")) {
+ // Note: this might have already been set, if during the last
+ // pause we decided to start a cycle but at the beginning of
+ // this pause we decided to postpone it. That's OK.
+ set_initiate_conc_mark_if_possible();
+ }
_mmu_tracker->add_pause(end_time_sec - elapsed_ms/1000.0,
end_time_sec, false);
@@ -1257,6 +1266,10 @@
// is in progress.
other_time_ms -= _cur_satb_drain_time_ms;
+ // Subtract the root region scanning wait time. It's initialized to
+ // zero at the start of the pause.
+ other_time_ms -= _root_region_scan_wait_time_ms;
+
if (parallel) {
other_time_ms -= _cur_collection_par_time_ms;
} else {
@@ -1289,6 +1302,8 @@
// each other. Therefore we unconditionally record the SATB drain
// time - even if it's zero.
body_summary->record_satb_drain_time_ms(_cur_satb_drain_time_ms);
+ body_summary->record_root_region_scan_wait_time_ms(
+ _root_region_scan_wait_time_ms);
body_summary->record_ext_root_scan_time_ms(ext_root_scan_time);
body_summary->record_satb_filtering_time_ms(satb_filtering_time);
@@ -1385,6 +1400,9 @@
(last_pause_included_initial_mark) ? " (initial-mark)" : "",
elapsed_ms / 1000.0);
+ if (_root_region_scan_wait_time_ms > 0.0) {
+ print_stats(1, "Root Region Scan Waiting", _root_region_scan_wait_time_ms);
+ }
if (parallel) {
print_stats(1, "Parallel Time", _cur_collection_par_time_ms);
print_par_stats(2, "GC Worker Start", _par_last_gc_worker_start_times_ms);
@@ -1988,6 +2006,7 @@
if (summary->get_total_seq()->num() > 0) {
print_summary_sd(0, "Evacuation Pauses", summary->get_total_seq());
if (body_summary != NULL) {
+ print_summary(1, "Root Region Scan Wait", body_summary->get_root_region_scan_wait_seq());
if (parallel) {
print_summary(1, "Parallel Time", body_summary->get_parallel_seq());
print_summary(2, "Ext Root Scanning", body_summary->get_ext_root_scan_seq());
@@ -2029,15 +2048,17 @@
// parallel
NumberSeq* other_parts[] = {
body_summary->get_satb_drain_seq(),
+ body_summary->get_root_region_scan_wait_seq(),
body_summary->get_parallel_seq(),
body_summary->get_clear_ct_seq()
};
calc_other_times_ms = NumberSeq(summary->get_total_seq(),
- 3, other_parts);
+ 4, other_parts);
} else {
// serial
NumberSeq* other_parts[] = {
body_summary->get_satb_drain_seq(),
+ body_summary->get_root_region_scan_wait_seq(),
body_summary->get_update_rs_seq(),
body_summary->get_ext_root_scan_seq(),
body_summary->get_satb_filtering_seq(),
@@ -2045,7 +2066,7 @@
body_summary->get_obj_copy_seq()
};
calc_other_times_ms = NumberSeq(summary->get_total_seq(),
- 6, other_parts);
+ 7, other_parts);
}
check_other_times(1, summary->get_other_seq(), &calc_other_times_ms);
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -65,6 +65,7 @@
class MainBodySummary: public CHeapObj {
define_num_seq(satb_drain) // optional
+ define_num_seq(root_region_scan_wait)
define_num_seq(parallel) // parallel only
define_num_seq(ext_root_scan)
define_num_seq(satb_filtering)
@@ -177,7 +178,6 @@
double _cur_collection_start_sec;
size_t _cur_collection_pause_used_at_start_bytes;
size_t _cur_collection_pause_used_regions_at_start;
- size_t _prev_collection_pause_used_at_end_bytes;
double _cur_collection_par_time_ms;
double _cur_satb_drain_time_ms;
double _cur_clear_ct_time_ms;
@@ -716,6 +716,7 @@
double _mark_remark_start_sec;
double _mark_cleanup_start_sec;
double _mark_closure_time_ms;
+ double _root_region_scan_wait_time_ms;
// Update the young list target length either by setting it to the
// desired fixed value or by calculating it using G1's pause
@@ -800,6 +801,8 @@
GenRemSet::Name rem_set_name() { return GenRemSet::CardTable; }
+ 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.
@@ -816,6 +819,10 @@
_mark_closure_time_ms = mark_closure_time_ms;
}
+ void record_root_region_scan_wait_time(double time_ms) {
+ _root_region_scan_wait_time_ms = time_ms;
+ }
+
void record_concurrent_mark_remark_start();
void record_concurrent_mark_remark_end();
@@ -1146,11 +1153,6 @@
_survivor_surv_rate_group->stop_adding_regions();
}
- void tenure_all_objects() {
- _max_survivor_regions = 0;
- _tenuring_threshold = 0;
- }
-
void record_survivor_regions(size_t regions,
HeapRegion* head,
HeapRegion* tail) {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -70,16 +70,20 @@
OopsInHeapRegionClosure *_update_rset_cl;
bool _during_initial_mark;
bool _during_conc_mark;
+ uint _worker_id;
+
public:
RemoveSelfForwardPtrObjClosure(G1CollectedHeap* g1, ConcurrentMark* cm,
HeapRegion* hr,
OopsInHeapRegionClosure* update_rset_cl,
bool during_initial_mark,
- bool during_conc_mark) :
+ bool during_conc_mark,
+ uint worker_id) :
_g1(g1), _cm(cm), _hr(hr), _marked_bytes(0),
_update_rset_cl(update_rset_cl),
_during_initial_mark(during_initial_mark),
- _during_conc_mark(during_conc_mark) { }
+ _during_conc_mark(during_conc_mark),
+ _worker_id(worker_id) { }
size_t marked_bytes() { return _marked_bytes; }
@@ -123,7 +127,7 @@
// explicitly and all objects in the CSet are considered
// (implicitly) live. So, we won't mark them explicitly and
// we'll leave them over NTAMS.
- _cm->markNext(obj);
+ _cm->grayRoot(obj, obj_size, _worker_id, _hr);
}
_marked_bytes += (obj_size * HeapWordSize);
obj->set_mark(markOopDesc::prototype());
@@ -155,12 +159,14 @@
G1CollectedHeap* _g1h;
ConcurrentMark* _cm;
OopsInHeapRegionClosure *_update_rset_cl;
+ uint _worker_id;
public:
RemoveSelfForwardPtrHRClosure(G1CollectedHeap* g1h,
- OopsInHeapRegionClosure* update_rset_cl) :
+ OopsInHeapRegionClosure* update_rset_cl,
+ uint worker_id) :
_g1h(g1h), _update_rset_cl(update_rset_cl),
- _cm(_g1h->concurrent_mark()) { }
+ _worker_id(worker_id), _cm(_g1h->concurrent_mark()) { }
bool doHeapRegion(HeapRegion *hr) {
bool during_initial_mark = _g1h->g1_policy()->during_initial_mark_pause();
@@ -173,7 +179,8 @@
if (hr->evacuation_failed()) {
RemoveSelfForwardPtrObjClosure rspc(_g1h, _cm, hr, _update_rset_cl,
during_initial_mark,
- during_conc_mark);
+ during_conc_mark,
+ _worker_id);
MemRegion mr(hr->bottom(), hr->end());
// We'll recreate the prev marking info so we'll first clear
@@ -226,7 +233,7 @@
update_rset_cl = &immediate_update;
}
- RemoveSelfForwardPtrHRClosure rsfp_cl(_g1h, update_rset_cl);
+ RemoveSelfForwardPtrHRClosure rsfp_cl(_g1h, update_rset_cl, worker_id);
HeapRegion* hr = _g1h->start_cset_region_for_worker(worker_id);
_g1h->collection_set_iterate_from(hr, &rsfp_cl);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -89,16 +89,15 @@
//
// * Min Capacity
//
-// We set this to 0 for all spaces. We could consider setting the old
-// min capacity to the min capacity of the heap (see 7078465).
+// We set this to 0 for all spaces.
//
// * Max Capacity
//
// For jstat, we set the max capacity of all spaces to heap_capacity,
-// given that we don't always have a reasonably upper bound on how big
-// each space can grow. For the memory pools, we actually make the max
-// capacity undefined. We could consider setting the old max capacity
-// to the max capacity of the heap (see 7078465).
+// given that we don't always have a reasonable upper bound on how big
+// each space can grow. For the memory pools, we make the max
+// capacity undefined with the exception of the old memory pool for
+// which we make the max capacity same as the max heap capacity.
//
// If we had more accurate occupancy / capacity information per
// region set the above calculations would be greatly simplified and
--- a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -51,6 +51,7 @@
G1RemSet* _g1_rem;
ConcurrentMark* _cm;
G1ParScanThreadState* _par_scan_state;
+ uint _worker_id;
bool _during_initial_mark;
bool _mark_in_progress;
public:
@@ -219,6 +220,7 @@
// Closure for iterating over object fields during concurrent marking
class G1CMOopClosure : public OopClosure {
+private:
G1CollectedHeap* _g1h;
ConcurrentMark* _cm;
CMTask* _task;
@@ -229,4 +231,92 @@
virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
};
+// Closure to scan the root regions during concurrent marking
+class G1RootRegionScanClosure : public OopClosure {
+private:
+ G1CollectedHeap* _g1h;
+ ConcurrentMark* _cm;
+ uint _worker_id;
+public:
+ G1RootRegionScanClosure(G1CollectedHeap* g1h, ConcurrentMark* cm,
+ uint worker_id) :
+ _g1h(g1h), _cm(cm), _worker_id(worker_id) { }
+ template <class T> void do_oop_nv(T* p);
+ virtual void do_oop( oop* p) { do_oop_nv(p); }
+ virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
+};
+
+// Closure that applies the given two closures in sequence.
+// Used by the RSet refinement code (when updating RSets
+// during an evacuation pause) to record cards containing
+// pointers into the collection set.
+
+class G1Mux2Closure : public OopClosure {
+ OopClosure* _c1;
+ OopClosure* _c2;
+public:
+ G1Mux2Closure(OopClosure *c1, OopClosure *c2);
+ template <class T> void do_oop_nv(T* p);
+ virtual void do_oop(oop* p) { do_oop_nv(p); }
+ virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
+};
+
+// A closure that returns true if it is actually applied
+// to a reference
+
+class G1TriggerClosure : public OopClosure {
+ bool _triggered;
+public:
+ G1TriggerClosure();
+ bool triggered() const { return _triggered; }
+ template <class T> void do_oop_nv(T* p);
+ virtual void do_oop(oop* p) { do_oop_nv(p); }
+ virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
+};
+
+// A closure which uses a triggering closure to determine
+// whether to apply an oop closure.
+
+class G1InvokeIfNotTriggeredClosure: public OopClosure {
+ G1TriggerClosure* _trigger_cl;
+ OopClosure* _oop_cl;
+public:
+ G1InvokeIfNotTriggeredClosure(G1TriggerClosure* t, OopClosure* oc);
+ template <class T> void do_oop_nv(T* p);
+ virtual void do_oop(oop* p) { do_oop_nv(p); }
+ virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
+};
+
+class G1UpdateRSOrPushRefOopClosure: public OopClosure {
+ G1CollectedHeap* _g1;
+ G1RemSet* _g1_rem_set;
+ HeapRegion* _from;
+ OopsInHeapRegionClosure* _push_ref_cl;
+ bool _record_refs_into_cset;
+ int _worker_i;
+
+public:
+ G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h,
+ G1RemSet* rs,
+ OopsInHeapRegionClosure* push_ref_cl,
+ bool record_refs_into_cset,
+ int worker_i = 0);
+
+ void set_from(HeapRegion* from) {
+ assert(from != NULL, "from region must be non-NULL");
+ _from = from;
+ }
+
+ bool self_forwarded(oop obj) {
+ bool result = (obj->is_forwarded() && (obj->forwardee()== obj));
+ return result;
+ }
+
+ bool apply_to_weak_ref_discovered_field() { return true; }
+
+ template <class T> void do_oop_nv(T* p);
+ virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
+ virtual void do_oop(oop* p) { do_oop_nv(p); }
+};
+
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1OOPCLOSURES_HPP
--- a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -39,7 +39,8 @@
// perf-critical inner loop.
#define FILTERINTOCSCLOSURE_DOHISTOGRAMCOUNT 0
-template <class T> inline void FilterIntoCSClosure::do_oop_nv(T* p) {
+template <class T>
+inline void FilterIntoCSClosure::do_oop_nv(T* p) {
T heap_oop = oopDesc::load_heap_oop(p);
if (!oopDesc::is_null(heap_oop) &&
_g1->obj_in_cs(oopDesc::decode_heap_oop_not_null(heap_oop))) {
@@ -53,7 +54,8 @@
#define FILTEROUTOFREGIONCLOSURE_DOHISTOGRAMCOUNT 0
-template <class T> inline void FilterOutOfRegionClosure::do_oop_nv(T* p) {
+template <class T>
+inline void FilterOutOfRegionClosure::do_oop_nv(T* p) {
T heap_oop = oopDesc::load_heap_oop(p);
if (!oopDesc::is_null(heap_oop)) {
HeapWord* obj_hw = (HeapWord*)oopDesc::decode_heap_oop_not_null(heap_oop);
@@ -67,7 +69,8 @@
}
// This closure is applied to the fields of the objects that have just been copied.
-template <class T> inline void G1ParScanClosure::do_oop_nv(T* p) {
+template <class T>
+inline void G1ParScanClosure::do_oop_nv(T* p) {
T heap_oop = oopDesc::load_heap_oop(p);
if (!oopDesc::is_null(heap_oop)) {
@@ -96,7 +99,8 @@
}
}
-template <class T> inline void G1ParPushHeapRSClosure::do_oop_nv(T* p) {
+template <class T>
+inline void G1ParPushHeapRSClosure::do_oop_nv(T* p) {
T heap_oop = oopDesc::load_heap_oop(p);
if (!oopDesc::is_null(heap_oop)) {
@@ -111,7 +115,8 @@
}
}
-template <class T> inline void G1CMOopClosure::do_oop_nv(T* p) {
+template <class T>
+inline void G1CMOopClosure::do_oop_nv(T* p) {
assert(_g1h->is_in_g1_reserved((HeapWord*) p), "invariant");
assert(!_g1h->is_on_master_free_list(
_g1h->heap_region_containing((HeapWord*) p)), "invariant");
@@ -125,4 +130,97 @@
_task->deal_with_reference(obj);
}
+template <class T>
+inline void G1RootRegionScanClosure::do_oop_nv(T* p) {
+ T heap_oop = oopDesc::load_heap_oop(p);
+ if (!oopDesc::is_null(heap_oop)) {
+ oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+ HeapRegion* hr = _g1h->heap_region_containing((HeapWord*) obj);
+ if (hr != NULL) {
+ _cm->grayRoot(obj, obj->size(), _worker_id, hr);
+ }
+ }
+}
+
+template <class T>
+inline void G1Mux2Closure::do_oop_nv(T* p) {
+ // Apply first closure; then apply the second.
+ _c1->do_oop(p);
+ _c2->do_oop(p);
+}
+
+template <class T>
+inline void G1TriggerClosure::do_oop_nv(T* p) {
+ // Record that this closure was actually applied (triggered).
+ _triggered = true;
+}
+
+template <class T>
+inline void G1InvokeIfNotTriggeredClosure::do_oop_nv(T* p) {
+ if (!_trigger_cl->triggered()) {
+ _oop_cl->do_oop(p);
+ }
+}
+
+template <class T>
+inline void G1UpdateRSOrPushRefOopClosure::do_oop_nv(T* p) {
+ oop obj = oopDesc::load_decode_heap_oop(p);
+#ifdef ASSERT
+ // can't do because of races
+ // assert(obj == NULL || obj->is_oop(), "expected an oop");
+
+ // Do the safe subset of is_oop
+ if (obj != NULL) {
+#ifdef CHECK_UNHANDLED_OOPS
+ oopDesc* o = obj.obj();
+#else
+ oopDesc* o = obj;
+#endif // CHECK_UNHANDLED_OOPS
+ assert((intptr_t)o % MinObjAlignmentInBytes == 0, "not oop aligned");
+ assert(Universe::heap()->is_in_reserved(obj), "must be in heap");
+ }
+#endif // ASSERT
+
+ assert(_from != NULL, "from region must be non-NULL");
+
+ HeapRegion* to = _g1->heap_region_containing(obj);
+ if (to != NULL && _from != to) {
+ // The _record_refs_into_cset flag is true during the RSet
+ // updating part of an evacuation pause. It is false at all
+ // other times:
+ // * rebuilding the rembered sets after a full GC
+ // * during concurrent refinement.
+ // * updating the remembered sets of regions in the collection
+ // set in the event of an evacuation failure (when deferred
+ // updates are enabled).
+
+ if (_record_refs_into_cset && to->in_collection_set()) {
+ // We are recording references that point into the collection
+ // set and this particular reference does exactly that...
+ // If the referenced object has already been forwarded
+ // to itself, we are handling an evacuation failure and
+ // we have already visited/tried to copy this object
+ // there is no need to retry.
+ if (!self_forwarded(obj)) {
+ assert(_push_ref_cl != NULL, "should not be null");
+ // Push the reference in the refs queue of the G1ParScanThreadState
+ // instance for this worker thread.
+ _push_ref_cl->do_oop(p);
+ }
+
+ // Deferred updates to the CSet are either discarded (in the normal case),
+ // or processed (if an evacuation failure occurs) at the end
+ // of the collection.
+ // See G1RemSet::cleanup_after_oops_into_collection_set_do().
+ } else {
+ // We either don't care about pushing references that point into the
+ // collection set (i.e. we're not during an evacuation pause) _or_
+ // the reference doesn't point into the collection set. Either way
+ // we add the reference directly to the RSet of the region containing
+ // the referenced object.
+ _g1_rem_set->par_write_ref(_from, p, _worker_i);
+ }
+ }
+}
+
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1OOPCLOSURES_INLINE_HPP
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -569,40 +569,26 @@
static IntHistogram out_of_histo(50, 50);
-class TriggerClosure : public OopClosure {
- bool _trigger;
-public:
- TriggerClosure() : _trigger(false) { }
- bool value() const { return _trigger; }
- template <class T> void do_oop_nv(T* p) { _trigger = true; }
- virtual void do_oop(oop* p) { do_oop_nv(p); }
- virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
-};
+
+G1TriggerClosure::G1TriggerClosure() :
+ _triggered(false) { }
+
+G1InvokeIfNotTriggeredClosure::G1InvokeIfNotTriggeredClosure(G1TriggerClosure* t_cl,
+ OopClosure* oop_cl) :
+ _trigger_cl(t_cl), _oop_cl(oop_cl) { }
-class InvokeIfNotTriggeredClosure: public OopClosure {
- TriggerClosure* _t;
- OopClosure* _oc;
-public:
- InvokeIfNotTriggeredClosure(TriggerClosure* t, OopClosure* oc):
- _t(t), _oc(oc) { }
- template <class T> void do_oop_nv(T* p) {
- if (!_t->value()) _oc->do_oop(p);
- }
- virtual void do_oop(oop* p) { do_oop_nv(p); }
- virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
-};
+G1Mux2Closure::G1Mux2Closure(OopClosure *c1, OopClosure *c2) :
+ _c1(c1), _c2(c2) { }
-class Mux2Closure : public OopClosure {
- OopClosure* _c1;
- OopClosure* _c2;
-public:
- Mux2Closure(OopClosure *c1, OopClosure *c2) : _c1(c1), _c2(c2) { }
- template <class T> void do_oop_nv(T* p) {
- _c1->do_oop(p); _c2->do_oop(p);
- }
- virtual void do_oop(oop* p) { do_oop_nv(p); }
- virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
-};
+G1UpdateRSOrPushRefOopClosure::
+G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h,
+ G1RemSet* rs,
+ OopsInHeapRegionClosure* push_ref_cl,
+ bool record_refs_into_cset,
+ int worker_i) :
+ _g1(g1h), _g1_rem_set(rs), _from(NULL),
+ _record_refs_into_cset(record_refs_into_cset),
+ _push_ref_cl(push_ref_cl), _worker_i(worker_i) { }
bool G1RemSet::concurrentRefineOneCard_impl(jbyte* card_ptr, int worker_i,
bool check_for_refs_into_cset) {
@@ -629,17 +615,17 @@
assert((size_t)worker_i < n_workers(), "index of worker larger than _cset_rs_update_cl[].length");
oops_in_heap_closure = _cset_rs_update_cl[worker_i];
}
- UpdateRSOrPushRefOopClosure update_rs_oop_cl(_g1,
- _g1->g1_rem_set(),
- oops_in_heap_closure,
- check_for_refs_into_cset,
- worker_i);
+ G1UpdateRSOrPushRefOopClosure update_rs_oop_cl(_g1,
+ _g1->g1_rem_set(),
+ oops_in_heap_closure,
+ check_for_refs_into_cset,
+ worker_i);
update_rs_oop_cl.set_from(r);
- TriggerClosure trigger_cl;
+ G1TriggerClosure trigger_cl;
FilterIntoCSClosure into_cs_cl(NULL, _g1, &trigger_cl);
- InvokeIfNotTriggeredClosure invoke_cl(&trigger_cl, &into_cs_cl);
- Mux2Closure mux(&invoke_cl, &update_rs_oop_cl);
+ G1InvokeIfNotTriggeredClosure invoke_cl(&trigger_cl, &into_cs_cl);
+ G1Mux2Closure mux(&invoke_cl, &update_rs_oop_cl);
FilterOutOfRegionClosure filter_then_update_rs_oop_cl(r,
(check_for_refs_into_cset ?
@@ -688,7 +674,7 @@
_conc_refine_cards++;
}
- return trigger_cl.value();
+ return trigger_cl.triggered();
}
bool G1RemSet::concurrentRefineOneCard(jbyte* card_ptr, int worker_i,
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -191,44 +191,5 @@
virtual void do_oop( oop* p) { do_oop_work(p); }
};
-class UpdateRSOrPushRefOopClosure: public OopClosure {
- G1CollectedHeap* _g1;
- G1RemSet* _g1_rem_set;
- HeapRegion* _from;
- OopsInHeapRegionClosure* _push_ref_cl;
- bool _record_refs_into_cset;
- int _worker_i;
-
- template <class T> void do_oop_work(T* p);
-
-public:
- UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h,
- G1RemSet* rs,
- OopsInHeapRegionClosure* push_ref_cl,
- bool record_refs_into_cset,
- int worker_i = 0) :
- _g1(g1h),
- _g1_rem_set(rs),
- _from(NULL),
- _record_refs_into_cset(record_refs_into_cset),
- _push_ref_cl(push_ref_cl),
- _worker_i(worker_i) { }
-
- void set_from(HeapRegion* from) {
- assert(from != NULL, "from region must be non-NULL");
- _from = from;
- }
-
- bool self_forwarded(oop obj) {
- bool result = (obj->is_forwarded() && (obj->forwardee()== obj));
- return result;
- }
-
- virtual void do_oop(narrowOop* p) { do_oop_work(p); }
- virtual void do_oop(oop* p) { do_oop_work(p); }
-
- bool apply_to_weak_ref_discovered_field() { return true; }
-};
-
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1REMSET_HPP
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -85,66 +85,4 @@
}
}
-template <class T>
-inline void UpdateRSOrPushRefOopClosure::do_oop_work(T* p) {
- oop obj = oopDesc::load_decode_heap_oop(p);
-#ifdef ASSERT
- // can't do because of races
- // assert(obj == NULL || obj->is_oop(), "expected an oop");
-
- // Do the safe subset of is_oop
- if (obj != NULL) {
-#ifdef CHECK_UNHANDLED_OOPS
- oopDesc* o = obj.obj();
-#else
- oopDesc* o = obj;
-#endif // CHECK_UNHANDLED_OOPS
- assert((intptr_t)o % MinObjAlignmentInBytes == 0, "not oop aligned");
- assert(Universe::heap()->is_in_reserved(obj), "must be in heap");
- }
-#endif // ASSERT
-
- assert(_from != NULL, "from region must be non-NULL");
-
- HeapRegion* to = _g1->heap_region_containing(obj);
- if (to != NULL && _from != to) {
- // The _record_refs_into_cset flag is true during the RSet
- // updating part of an evacuation pause. It is false at all
- // other times:
- // * rebuilding the rembered sets after a full GC
- // * during concurrent refinement.
- // * updating the remembered sets of regions in the collection
- // set in the event of an evacuation failure (when deferred
- // updates are enabled).
-
- if (_record_refs_into_cset && to->in_collection_set()) {
- // We are recording references that point into the collection
- // set and this particular reference does exactly that...
- // If the referenced object has already been forwarded
- // to itself, we are handling an evacuation failure and
- // we have already visited/tried to copy this object
- // there is no need to retry.
- if (!self_forwarded(obj)) {
- assert(_push_ref_cl != NULL, "should not be null");
- // Push the reference in the refs queue of the G1ParScanThreadState
- // instance for this worker thread.
- _push_ref_cl->do_oop(p);
- }
-
- // Deferred updates to the CSet are either discarded (in the normal case),
- // or processed (if an evacuation failure occurs) at the end
- // of the collection.
- // See G1RemSet::cleanup_after_oops_into_collection_set_do().
- } else {
- // We either don't care about pushing references that point into the
- // collection set (i.e. we're not during an evacuation pause) _or_
- // the reference doesn't point into the collection set. Either way
- // we add the reference directly to the RSet of the region containing
- // the referenced object.
- _g1_rem_set->par_write_ref(_from, p, _worker_i);
- }
- }
-}
-
-
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1REMSET_INLINE_HPP
--- a/hotspot/src/share/vm/gc_implementation/g1/g1_specialized_oop_closures.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1_specialized_oop_closures.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -32,12 +32,14 @@
// Forward declarations.
enum G1Barrier {
- G1BarrierNone, G1BarrierRS, G1BarrierEvac
+ G1BarrierNone,
+ G1BarrierRS,
+ G1BarrierEvac
};
-template<bool do_gen_barrier, G1Barrier barrier,
- bool do_mark_object>
+template<bool do_gen_barrier, G1Barrier barrier, bool do_mark_object>
class G1ParCopyClosure;
+
class G1ParScanClosure;
class G1ParPushHeapRSClosure;
@@ -46,6 +48,13 @@
class FilterIntoCSClosure;
class FilterOutOfRegionClosure;
class G1CMOopClosure;
+class G1RootRegionScanClosure;
+
+// Specialized oop closures from g1RemSet.cpp
+class G1Mux2Closure;
+class G1TriggerClosure;
+class G1InvokeIfNotTriggeredClosure;
+class G1UpdateRSOrPushRefOopClosure;
#ifdef FURTHER_SPECIALIZED_OOP_OOP_ITERATE_CLOSURES
#error "FURTHER_SPECIALIZED_OOP_OOP_ITERATE_CLOSURES already defined."
@@ -57,7 +66,12 @@
f(G1ParPushHeapRSClosure,_nv) \
f(FilterIntoCSClosure,_nv) \
f(FilterOutOfRegionClosure,_nv) \
- f(G1CMOopClosure,_nv)
+ f(G1CMOopClosure,_nv) \
+ f(G1RootRegionScanClosure,_nv) \
+ f(G1Mux2Closure,_nv) \
+ f(G1TriggerClosure,_nv) \
+ f(G1InvokeIfNotTriggeredClosure,_nv) \
+ f(G1UpdateRSOrPushRefOopClosure,_nv)
#ifdef FURTHER_SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES
#error "FURTHER_SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES already defined."
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -659,7 +659,7 @@
// If we're within a stop-world GC, then we might look at a card in a
// GC alloc region that extends onto a GC LAB, which may not be
// parseable. Stop such at the "saved_mark" of the region.
- if (G1CollectedHeap::heap()->is_gc_active()) {
+ if (g1h->is_gc_active()) {
mr = mr.intersection(used_region_at_save_marks());
} else {
mr = mr.intersection(used_region());
@@ -688,53 +688,63 @@
OrderAccess::storeload();
}
+ // Cache the boundaries of the memory region in some const locals
+ HeapWord* const start = mr.start();
+ HeapWord* const end = mr.end();
+
// We used to use "block_start_careful" here. But we're actually happy
// to update the BOT while we do this...
- HeapWord* cur = block_start(mr.start());
- assert(cur <= mr.start(), "Postcondition");
+ HeapWord* cur = block_start(start);
+ assert(cur <= start, "Postcondition");
+
+ oop obj;
- while (cur <= mr.start()) {
- if (oop(cur)->klass_or_null() == NULL) {
+ HeapWord* next = cur;
+ while (next <= start) {
+ cur = next;
+ obj = oop(cur);
+ if (obj->klass_or_null() == NULL) {
// Ran into an unparseable point.
return cur;
}
// Otherwise...
- int sz = oop(cur)->size();
- if (cur + sz > mr.start()) break;
- // Otherwise, go on.
- cur = cur + sz;
+ next = (cur + obj->size());
}
- oop obj;
- obj = oop(cur);
- // If we finish this loop...
- assert(cur <= mr.start()
- && obj->klass_or_null() != NULL
- && cur + obj->size() > mr.start(),
+
+ // If we finish the above loop...We have a parseable object that
+ // begins on or before the start of the memory region, and ends
+ // inside or spans the entire region.
+
+ assert(obj == oop(cur), "sanity");
+ assert(cur <= start &&
+ obj->klass_or_null() != NULL &&
+ (cur + obj->size()) > start,
"Loop postcondition");
+
if (!g1h->is_obj_dead(obj)) {
obj->oop_iterate(cl, mr);
}
- HeapWord* next;
- while (cur < mr.end()) {
+ while (cur < end) {
obj = oop(cur);
if (obj->klass_or_null() == NULL) {
// Ran into an unparseable point.
return cur;
};
+
// Otherwise:
next = (cur + obj->size());
+
if (!g1h->is_obj_dead(obj)) {
- if (next < mr.end()) {
+ if (next < end || !obj->is_objArray()) {
+ // This object either does not span the MemRegion
+ // boundary, or if it does it's not an array.
+ // Apply closure to whole object.
obj->oop_iterate(cl);
} else {
- // this obj spans the boundary. If it's an array, stop at the
- // boundary.
- if (obj->is_objArray()) {
- obj->oop_iterate(cl, mr);
- } else {
- obj->oop_iterate(cl);
- }
+ // This obj is an array that spans the boundary.
+ // Stop at the boundary.
+ obj->oop_iterate(cl, mr);
}
}
cur = next;
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -374,7 +374,9 @@
ParVerifyClaimValue = 4,
RebuildRSClaimValue = 5,
CompleteMarkCSetClaimValue = 6,
- ParEvacFailureClaimValue = 7
+ ParEvacFailureClaimValue = 7,
+ AggregateCountClaimValue = 8,
+ VerifyCountClaimValue = 9
};
inline HeapWord* par_allocate_no_bot_updates(size_t word_size) {
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -72,10 +72,11 @@
}
inline void HeapRegion::note_start_of_copying(bool during_initial_mark) {
- if (during_initial_mark) {
- if (is_survivor()) {
- assert(false, "should not allocate survivors during IM");
- } else {
+ if (is_survivor()) {
+ // This is how we always allocate survivors.
+ assert(_next_top_at_mark_start == bottom(), "invariant");
+ } else {
+ if (during_initial_mark) {
// During initial-mark we'll explicitly mark any objects on old
// regions that are pointed to by roots. Given that explicit
// marks only make sense under NTAMS it'd be nice if we could
@@ -84,11 +85,6 @@
// NTAMS to the end of the region so all marks will be below
// NTAMS. We'll set it to the actual top when we retire this region.
_next_top_at_mark_start = end();
- }
- } else {
- if (is_survivor()) {
- // This is how we always allocate survivors.
- assert(_next_top_at_mark_start == bottom(), "invariant");
} else {
// We could have re-used this old region as to-space over a
// couple of GCs since the start of the concurrent marking
@@ -101,19 +97,15 @@
}
inline void HeapRegion::note_end_of_copying(bool during_initial_mark) {
- if (during_initial_mark) {
- if (is_survivor()) {
- assert(false, "should not allocate survivors during IM");
- } else {
+ if (is_survivor()) {
+ // This is how we always allocate survivors.
+ assert(_next_top_at_mark_start == bottom(), "invariant");
+ } else {
+ if (during_initial_mark) {
// See the comment for note_start_of_copying() for the details
// on this.
assert(_next_top_at_mark_start == end(), "pre-condition");
_next_top_at_mark_start = top();
- }
- } else {
- if (is_survivor()) {
- // This is how we always allocate survivors.
- assert(_next_top_at_mark_start == bottom(), "invariant");
} else {
// See the comment for note_start_of_copying() for the details
// on this.
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -59,6 +59,7 @@
class HeapRegionSetBase VALUE_OBJ_CLASS_SPEC {
friend class hrs_ext_msg;
friend class HRSPhaseSetter;
+ friend class VMStructs;
protected:
static size_t calculate_region_num(HeapRegion* hr);
--- a/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -40,6 +40,8 @@
nonstatic_field(G1CollectedHeap, _g1_committed, MemRegion) \
nonstatic_field(G1CollectedHeap, _summary_bytes_used, size_t) \
nonstatic_field(G1CollectedHeap, _g1mm, G1MonitoringSupport*) \
+ nonstatic_field(G1CollectedHeap, _old_set, HeapRegionSetBase) \
+ nonstatic_field(G1CollectedHeap, _humongous_set, HeapRegionSetBase) \
\
nonstatic_field(G1MonitoringSupport, _eden_committed, size_t) \
nonstatic_field(G1MonitoringSupport, _eden_used, size_t) \
@@ -47,6 +49,10 @@
nonstatic_field(G1MonitoringSupport, _survivor_used, size_t) \
nonstatic_field(G1MonitoringSupport, _old_committed, size_t) \
nonstatic_field(G1MonitoringSupport, _old_used, size_t) \
+ \
+ nonstatic_field(HeapRegionSetBase, _length, size_t) \
+ nonstatic_field(HeapRegionSetBase, _region_num, size_t) \
+ nonstatic_field(HeapRegionSetBase, _total_used_bytes, size_t) \
#define VM_TYPES_G1(declare_type, declare_toplevel_type) \
@@ -55,6 +61,7 @@
\
declare_type(HeapRegion, ContiguousSpace) \
declare_toplevel_type(HeapRegionSeq) \
+ declare_toplevel_type(HeapRegionSetBase) \
declare_toplevel_type(G1MonitoringSupport) \
\
declare_toplevel_type(G1CollectedHeap*) \
--- a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -74,8 +74,9 @@
G1CollectedHeap* g1h = G1CollectedHeap::heap();
assert(!_should_initiate_conc_mark ||
((_gc_cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) ||
- (_gc_cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent)),
- "only a GC locker or a System.gc() induced GC should start a cycle");
+ (_gc_cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent) ||
+ _gc_cause == GCCause::_g1_humongous_allocation),
+ "only a GC locker, a System.gc() or a hum allocation induced GC should start a cycle");
if (_word_size > 0) {
// An allocation has been requested. So, try to do that first.
--- a/hotspot/src/share/vm/gc_interface/gcCause.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_interface/gcCause.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -84,6 +84,9 @@
case _g1_inc_collection_pause:
return "G1 Evacuation Pause";
+ case _g1_humongous_allocation:
+ return "G1 Humongous Allocation";
+
case _last_ditch_collection:
return "Last ditch collection";
--- a/hotspot/src/share/vm/gc_interface/gcCause.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/gc_interface/gcCause.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -66,6 +66,7 @@
_adaptive_size_policy,
_g1_inc_collection_pause,
+ _g1_humongous_allocation,
_last_ditch_collection,
_last_gc_cause
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -859,7 +859,9 @@
const int branch_bci = branch_bcp != NULL ? method->bci_from(branch_bcp) : InvocationEntryBci;
const int bci = branch_bcp != NULL ? method->bci_from(fr.interpreter_frame_bcp()) : InvocationEntryBci;
+ assert(!HAS_PENDING_EXCEPTION, "Should not have any exceptions pending");
nmethod* osr_nm = CompilationPolicy::policy()->event(method, method, branch_bci, bci, CompLevel_none, NULL, thread);
+ assert(!HAS_PENDING_EXCEPTION, "Event handler should not throw any exceptions");
if (osr_nm != NULL) {
// We may need to do on-stack replacement which requires that no
--- a/hotspot/src/share/vm/oops/klass.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/oops/klass.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -158,6 +158,9 @@
kl->set_next_sibling(NULL);
kl->set_alloc_count(0);
kl->set_alloc_size(0);
+#ifdef TRACE_SET_KLASS_TRACE_ID
+ TRACE_SET_KLASS_TRACE_ID(kl, 0);
+#endif
kl->set_prototype_header(markOopDesc::prototype());
kl->set_biased_lock_revocation_count(0);
--- a/hotspot/src/share/vm/oops/klass.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/oops/klass.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -33,6 +33,7 @@
#include "oops/klassPS.hpp"
#include "oops/oop.hpp"
#include "runtime/orderAccess.hpp"
+#include "trace/traceMacros.hpp"
#include "utilities/accessFlags.hpp"
#ifndef SERIALGC
#include "gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp"
@@ -80,6 +81,7 @@
// [last_biased_lock_bulk_revocation_time] (64 bits)
// [prototype_header]
// [biased_lock_revocation_count]
+// [trace_id]
// Forward declarations.
@@ -263,6 +265,9 @@
markOop _prototype_header; // Used when biased locking is both enabled and disabled for this type
jint _biased_lock_revocation_count;
+#ifdef TRACE_DEFINE_KLASS_TRACE_ID
+ TRACE_DEFINE_KLASS_TRACE_ID;
+#endif
public:
// returns the enclosing klassOop
@@ -683,6 +688,9 @@
jlong last_biased_lock_bulk_revocation_time() { return _last_biased_lock_bulk_revocation_time; }
void set_last_biased_lock_bulk_revocation_time(jlong cur_time) { _last_biased_lock_bulk_revocation_time = cur_time; }
+#ifdef TRACE_DEFINE_KLASS_METHODS
+ TRACE_DEFINE_KLASS_METHODS;
+#endif
// garbage collection support
virtual void follow_weak_klass_links(
--- a/hotspot/src/share/vm/oops/methodKlass.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/oops/methodKlass.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -83,6 +83,7 @@
m->set_max_stack(0);
m->set_max_locals(0);
m->set_intrinsic_id(vmIntrinsics::_none);
+ m->set_jfr_towrite(false);
m->set_method_data(NULL);
m->set_interpreter_throwout_count(0);
m->set_vtable_index(methodOopDesc::garbage_vtable_index);
--- a/hotspot/src/share/vm/oops/methodOop.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/oops/methodOop.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -77,7 +77,7 @@
// | method_size | max_stack |
// | max_locals | size_of_parameters |
// |------------------------------------------------------|
-// | intrinsic_id, (unused) | throwout_count |
+// |intrinsic_id| flags | throwout_count |
// |------------------------------------------------------|
// | num_breakpoints | (unused) |
// |------------------------------------------------------|
@@ -124,6 +124,8 @@
u2 _max_locals; // Number of local variables used by this method
u2 _size_of_parameters; // size of the parameter block (receiver + arguments) in words
u1 _intrinsic_id; // vmSymbols::intrinsic_id (0 == _none)
+ u1 _jfr_towrite : 1, // Flags
+ : 7;
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
@@ -225,6 +227,7 @@
void clear_number_of_breakpoints() { _number_of_breakpoints = 0; }
// index into instanceKlass methods() array
+ // note: also used by jfr
u2 method_idnum() const { return constMethod()->method_idnum(); }
void set_method_idnum(u2 idnum) { constMethod()->set_method_idnum(idnum); }
@@ -650,6 +653,9 @@
void init_intrinsic_id(); // updates from _none if a match
static vmSymbols::SID klass_id_for_intrinsics(klassOop holder);
+ bool jfr_towrite() { return _jfr_towrite; }
+ void set_jfr_towrite(bool towrite) { _jfr_towrite = towrite; }
+
// On-stack replacement support
bool has_osr_nmethod(int level, bool match_level) {
return instanceKlass::cast(method_holder())->lookup_osr_nmethod(this, InvocationEntryBci, level, match_level) != NULL;
--- a/hotspot/src/share/vm/opto/block.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/opto/block.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -284,13 +284,13 @@
// helper function that adds caller save registers to MachProjNode
void add_call_kills(MachProjNode *proj, RegMask& regs, const char* save_policy, bool exclude_soe);
// Schedule a call next in the block
- uint sched_call(Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_List &worklist, int *ready_cnt, MachCallNode *mcall, VectorSet &next_call);
+ uint sched_call(Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_List &worklist, GrowableArray<int> &ready_cnt, MachCallNode *mcall, VectorSet &next_call);
// Perform basic-block local scheduling
- Node *select(PhaseCFG *cfg, Node_List &worklist, int *ready_cnt, VectorSet &next_call, uint sched_slot);
+ Node *select(PhaseCFG *cfg, Node_List &worklist, GrowableArray<int> &ready_cnt, VectorSet &next_call, uint sched_slot);
void set_next_call( Node *n, VectorSet &next_call, Block_Array &bbs );
void needed_for_next_call(Node *this_call, VectorSet &next_call, Block_Array &bbs);
- bool schedule_local(PhaseCFG *cfg, Matcher &m, int *ready_cnt, VectorSet &next_call);
+ bool schedule_local(PhaseCFG *cfg, Matcher &m, GrowableArray<int> &ready_cnt, VectorSet &next_call);
// Cleanup if any code lands between a Call and his Catch
void call_catch_cleanup(Block_Array &bbs);
// Detect implicit-null-check opportunities. Basically, find NULL checks
--- a/hotspot/src/share/vm/opto/gcm.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/opto/gcm.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -1344,8 +1344,8 @@
// Schedule locally. Right now a simple topological sort.
// Later, do a real latency aware scheduler.
- int *ready_cnt = NEW_RESOURCE_ARRAY(int,C->unique());
- memset( ready_cnt, -1, C->unique() * sizeof(int) );
+ uint max_idx = C->unique();
+ GrowableArray<int> ready_cnt(max_idx, max_idx, -1);
visited.Clear();
for (i = 0; i < _num_blocks; i++) {
if (!_blocks[i]->schedule_local(this, matcher, ready_cnt, visited)) {
--- a/hotspot/src/share/vm/opto/lcm.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/opto/lcm.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -404,7 +404,7 @@
// remaining cases (most), choose the instruction with the greatest latency
// (that is, the most number of pseudo-cycles required to the end of the
// routine). If there is a tie, choose the instruction with the most inputs.
-Node *Block::select(PhaseCFG *cfg, Node_List &worklist, int *ready_cnt, VectorSet &next_call, uint sched_slot) {
+Node *Block::select(PhaseCFG *cfg, Node_List &worklist, GrowableArray<int> &ready_cnt, VectorSet &next_call, uint sched_slot) {
// If only a single entry on the stack, use it
uint cnt = worklist.size();
@@ -465,7 +465,7 @@
// More than this instruction pending for successor to be ready,
// don't choose this if other opportunities are ready
- if (ready_cnt[use->_idx] > 1)
+ if (ready_cnt.at(use->_idx) > 1)
n_choice = 1;
}
@@ -565,7 +565,7 @@
//------------------------------sched_call-------------------------------------
-uint Block::sched_call( Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_List &worklist, int *ready_cnt, MachCallNode *mcall, VectorSet &next_call ) {
+uint Block::sched_call( Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_List &worklist, GrowableArray<int> &ready_cnt, MachCallNode *mcall, VectorSet &next_call ) {
RegMask regs;
// Schedule all the users of the call right now. All the users are
@@ -574,8 +574,9 @@
for (DUIterator_Fast imax, i = mcall->fast_outs(imax); i < imax; i++) {
Node* n = mcall->fast_out(i);
assert( n->is_MachProj(), "" );
- --ready_cnt[n->_idx];
- assert( !ready_cnt[n->_idx], "" );
+ int n_cnt = ready_cnt.at(n->_idx)-1;
+ ready_cnt.at_put(n->_idx, n_cnt);
+ assert( n_cnt == 0, "" );
// Schedule next to call
_nodes.map(node_cnt++, n);
// Collect defined registers
@@ -590,7 +591,9 @@
Node* m = n->fast_out(j); // Get user
if( bbs[m->_idx] != this ) continue;
if( m->is_Phi() ) continue;
- if( !--ready_cnt[m->_idx] )
+ int m_cnt = ready_cnt.at(m->_idx)-1;
+ ready_cnt.at_put(m->_idx, m_cnt);
+ if( m_cnt == 0 )
worklist.push(m);
}
@@ -655,7 +658,7 @@
//------------------------------schedule_local---------------------------------
// Topological sort within a block. Someday become a real scheduler.
-bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, int *ready_cnt, VectorSet &next_call) {
+bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray<int> &ready_cnt, VectorSet &next_call) {
// Already "sorted" are the block start Node (as the first entry), and
// the block-ending Node and any trailing control projections. We leave
// these alone. PhiNodes and ParmNodes are made to follow the block start
@@ -695,7 +698,7 @@
if( m && cfg->_bbs[m->_idx] == this && !m->is_top() )
local++; // One more block-local input
}
- ready_cnt[n->_idx] = local; // Count em up
+ ready_cnt.at_put(n->_idx, local); // Count em up
#ifdef ASSERT
if( UseConcMarkSweepGC || UseG1GC ) {
@@ -729,7 +732,7 @@
}
}
for(uint i2=i; i2<_nodes.size(); i2++ ) // Trailing guys get zapped count
- ready_cnt[_nodes[i2]->_idx] = 0;
+ ready_cnt.at_put(_nodes[i2]->_idx, 0);
// All the prescheduled guys do not hold back internal nodes
uint i3;
@@ -737,8 +740,10 @@
Node *n = _nodes[i3]; // Get pre-scheduled
for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
Node* m = n->fast_out(j);
- if( cfg->_bbs[m->_idx] ==this ) // Local-block user
- ready_cnt[m->_idx]--; // Fix ready count
+ if( cfg->_bbs[m->_idx] ==this ) { // Local-block user
+ int m_cnt = ready_cnt.at(m->_idx)-1;
+ ready_cnt.at_put(m->_idx, m_cnt); // Fix ready count
+ }
}
}
@@ -747,7 +752,7 @@
Node_List worklist;
for(uint i4=i3; i4<node_cnt; i4++ ) { // Put ready guys on worklist
Node *m = _nodes[i4];
- if( !ready_cnt[m->_idx] ) { // Zero ready count?
+ if( !ready_cnt.at(m->_idx) ) { // Zero ready count?
if (m->is_iteratively_computed()) {
// Push induction variable increments last to allow other uses
// of the phi to be scheduled first. The select() method breaks
@@ -775,14 +780,14 @@
for (uint j=0; j<_nodes.size(); j++) {
Node *n = _nodes[j];
int idx = n->_idx;
- tty->print("# ready cnt:%3d ", ready_cnt[idx]);
+ tty->print("# ready cnt:%3d ", ready_cnt.at(idx));
tty->print("latency:%3d ", cfg->_node_latency->at_grow(idx));
tty->print("%4d: %s\n", idx, n->Name());
}
}
#endif
- uint max_idx = matcher.C->unique();
+ uint max_idx = (uint)ready_cnt.length();
// Pull from worklist and schedule
while( worklist.size() ) { // Worklist is not ready
@@ -840,11 +845,13 @@
Node* m = n->fast_out(i5); // Get user
if( cfg->_bbs[m->_idx] != this ) continue;
if( m->is_Phi() ) continue;
- if (m->_idx > max_idx) { // new node, skip it
+ if (m->_idx >= max_idx) { // new node, skip it
assert(m->is_MachProj() && n->is_Mach() && n->as_Mach()->has_call(), "unexpected node types");
continue;
}
- if( !--ready_cnt[m->_idx] )
+ int m_cnt = ready_cnt.at(m->_idx)-1;
+ ready_cnt.at_put(m->_idx, m_cnt);
+ if( m_cnt == 0 )
worklist.push(m);
}
}
--- a/hotspot/src/share/vm/opto/memnode.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/opto/memnode.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -1718,8 +1718,10 @@
bool is_instance = (tinst != NULL) && tinst->is_known_instance_field();
if (ReduceFieldZeroing || is_instance) {
Node* value = can_see_stored_value(mem,phase);
- if (value != NULL && value->is_Con())
+ if (value != NULL && value->is_Con()) {
+ assert(value->bottom_type()->higher_equal(_type),"sanity");
return value->bottom_type();
+ }
}
if (is_instance) {
@@ -1759,6 +1761,20 @@
return LoadNode::Ideal(phase, can_reshape);
}
+const Type* LoadBNode::Value(PhaseTransform *phase) const {
+ Node* mem = in(MemNode::Memory);
+ Node* value = can_see_stored_value(mem,phase);
+ if (value != NULL && value->is_Con() &&
+ !value->bottom_type()->higher_equal(_type)) {
+ // If the input to the store does not fit with the load's result type,
+ // it must be truncated. We can't delay until Ideal call since
+ // a singleton Value is needed for split_thru_phi optimization.
+ int con = value->get_int();
+ return TypeInt::make((con << 24) >> 24);
+ }
+ return LoadNode::Value(phase);
+}
+
//--------------------------LoadUBNode::Ideal-------------------------------------
//
// If the previous store is to the same address as this load,
@@ -1775,6 +1791,20 @@
return LoadNode::Ideal(phase, can_reshape);
}
+const Type* LoadUBNode::Value(PhaseTransform *phase) const {
+ Node* mem = in(MemNode::Memory);
+ Node* value = can_see_stored_value(mem,phase);
+ if (value != NULL && value->is_Con() &&
+ !value->bottom_type()->higher_equal(_type)) {
+ // If the input to the store does not fit with the load's result type,
+ // it must be truncated. We can't delay until Ideal call since
+ // a singleton Value is needed for split_thru_phi optimization.
+ int con = value->get_int();
+ return TypeInt::make(con & 0xFF);
+ }
+ return LoadNode::Value(phase);
+}
+
//--------------------------LoadUSNode::Ideal-------------------------------------
//
// If the previous store is to the same address as this load,
@@ -1791,6 +1821,20 @@
return LoadNode::Ideal(phase, can_reshape);
}
+const Type* LoadUSNode::Value(PhaseTransform *phase) const {
+ Node* mem = in(MemNode::Memory);
+ Node* value = can_see_stored_value(mem,phase);
+ if (value != NULL && value->is_Con() &&
+ !value->bottom_type()->higher_equal(_type)) {
+ // If the input to the store does not fit with the load's result type,
+ // it must be truncated. We can't delay until Ideal call since
+ // a singleton Value is needed for split_thru_phi optimization.
+ int con = value->get_int();
+ return TypeInt::make(con & 0xFFFF);
+ }
+ return LoadNode::Value(phase);
+}
+
//--------------------------LoadSNode::Ideal--------------------------------------
//
// If the previous store is to the same address as this load,
@@ -1809,6 +1853,20 @@
return LoadNode::Ideal(phase, can_reshape);
}
+const Type* LoadSNode::Value(PhaseTransform *phase) const {
+ Node* mem = in(MemNode::Memory);
+ Node* value = can_see_stored_value(mem,phase);
+ if (value != NULL && value->is_Con() &&
+ !value->bottom_type()->higher_equal(_type)) {
+ // If the input to the store does not fit with the load's result type,
+ // it must be truncated. We can't delay until Ideal call since
+ // a singleton Value is needed for split_thru_phi optimization.
+ int con = value->get_int();
+ return TypeInt::make((con << 16) >> 16);
+ }
+ return LoadNode::Value(phase);
+}
+
//=============================================================================
//----------------------------LoadKlassNode::make------------------------------
// Polymorphic factory method:
--- a/hotspot/src/share/vm/opto/memnode.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/opto/memnode.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -215,6 +215,7 @@
virtual int Opcode() const;
virtual uint ideal_reg() const { return Op_RegI; }
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
+ virtual const Type *Value(PhaseTransform *phase) const;
virtual int store_Opcode() const { return Op_StoreB; }
virtual BasicType memory_type() const { return T_BYTE; }
};
@@ -228,6 +229,7 @@
virtual int Opcode() const;
virtual uint ideal_reg() const { return Op_RegI; }
virtual Node* Ideal(PhaseGVN *phase, bool can_reshape);
+ virtual const Type *Value(PhaseTransform *phase) const;
virtual int store_Opcode() const { return Op_StoreB; }
virtual BasicType memory_type() const { return T_BYTE; }
};
@@ -241,10 +243,25 @@
virtual int Opcode() const;
virtual uint ideal_reg() const { return Op_RegI; }
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
+ virtual const Type *Value(PhaseTransform *phase) const;
virtual int store_Opcode() const { return Op_StoreC; }
virtual BasicType memory_type() const { return T_CHAR; }
};
+//------------------------------LoadSNode--------------------------------------
+// Load a short (16bits signed) from memory
+class LoadSNode : public LoadNode {
+public:
+ LoadSNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::SHORT )
+ : LoadNode(c,mem,adr,at,ti) {}
+ virtual int Opcode() const;
+ virtual uint ideal_reg() const { return Op_RegI; }
+ virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
+ virtual const Type *Value(PhaseTransform *phase) const;
+ virtual int store_Opcode() const { return Op_StoreC; }
+ virtual BasicType memory_type() const { return T_SHORT; }
+};
+
//------------------------------LoadINode--------------------------------------
// Load an integer from memory
class LoadINode : public LoadNode {
@@ -433,19 +450,6 @@
};
-//------------------------------LoadSNode--------------------------------------
-// Load a short (16bits signed) from memory
-class LoadSNode : public LoadNode {
-public:
- LoadSNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::SHORT )
- : LoadNode(c,mem,adr,at,ti) {}
- virtual int Opcode() const;
- virtual uint ideal_reg() const { return Op_RegI; }
- virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
- virtual int store_Opcode() const { return Op_StoreC; }
- virtual BasicType memory_type() const { return T_SHORT; }
-};
-
//------------------------------StoreNode--------------------------------------
// Store value; requires Store, Address and Value
class StoreNode : public MemNode {
--- a/hotspot/src/share/vm/opto/parseHelper.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/opto/parseHelper.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -71,14 +71,14 @@
// Throw uncommon trap if class is not loaded or the value we are casting
// _from_ is not loaded, and value is not null. If the value _is_ NULL,
// then the checkcast does nothing.
- const TypeInstPtr *tp = _gvn.type(obj)->isa_instptr();
- if (!will_link || (tp && !tp->is_loaded())) {
+ const TypeOopPtr *tp = _gvn.type(obj)->isa_oopptr();
+ if (!will_link || (tp && tp->klass() && !tp->klass()->is_loaded())) {
if (C->log() != NULL) {
if (!will_link) {
C->log()->elem("assert_null reason='checkcast' klass='%d'",
C->log()->identify(klass));
}
- if (tp && !tp->is_loaded()) {
+ if (tp && tp->klass() && !tp->klass()->is_loaded()) {
// %%% Cannot happen?
C->log()->elem("assert_null reason='checkcast source' klass='%d'",
C->log()->identify(tp->klass()));
--- a/hotspot/src/share/vm/prims/jni.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/prims/jni.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -48,6 +48,7 @@
#include "oops/typeArrayOop.hpp"
#include "prims/jni.h"
#include "prims/jniCheck.hpp"
+#include "prims/jniExport.hpp"
#include "prims/jniFastGetField.hpp"
#include "prims/jvm.h"
#include "prims/jvm_misc.hpp"
@@ -66,6 +67,8 @@
#include "runtime/signature.hpp"
#include "runtime/vm_operations.hpp"
#include "services/runtimeService.hpp"
+#include "trace/tracing.hpp"
+#include "trace/traceEventTypes.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/events.hpp"
@@ -5139,6 +5142,11 @@
if (JvmtiExport::should_post_thread_life()) {
JvmtiExport::post_thread_start(thread);
}
+
+ EVENT_BEGIN(TraceEventThreadStart, event);
+ EVENT_COMMIT(event,
+ EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(thread->threadObj())));
+
// Check if we should compile all classes on bootclasspath
NOT_PRODUCT(if (CompileTheWorld) ClassLoader::compile_the_world();)
// Since this is not a JVM_ENTRY we have to set the thread state manually before leaving.
@@ -5337,6 +5345,10 @@
JvmtiExport::post_thread_start(thread);
}
+ EVENT_BEGIN(TraceEventThreadStart, event);
+ EVENT_COMMIT(event,
+ EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(thread->threadObj())));
+
*(JNIEnv**)penv = thread->jni_environment();
// Now leaving the VM, so change thread_state. This is normally automatically taken care
@@ -5464,8 +5476,7 @@
return ret;
}
- if (JvmtiExport::is_jvmti_version(version)) {
- ret = JvmtiExport::get_jvmti_interface(vm, penv, version);
+ if (JniExportedInterface::GetExportedInterface(vm, penv, version, &ret)) {
return ret;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/prims/jniExport.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_PRIMS_JNI_EXPORT_HPP
+#define SHARE_VM_PRIMS_JNI_EXPORT_HPP
+
+#include "prims/jni.h"
+#include "prims/jvmtiExport.hpp"
+
+class JniExportedInterface {
+ public:
+ static bool GetExportedInterface(JavaVM* vm, void** penv, jint version, jint* iface) {
+ if (JvmtiExport::is_jvmti_version(version)) {
+ *iface = JvmtiExport::get_jvmti_interface(vm, penv, version);
+ return true;
+ }
+ return false;
+ }
+};
+
+#endif // SHARE_VM_PRIMS_JNI_EXPORT_HPP
--- a/hotspot/src/share/vm/prims/jvmtiThreadState.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/prims/jvmtiThreadState.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -319,6 +319,15 @@
// clearing the flag indicates we are done with the PopFrame() dance
clr_pending_step_for_popframe();
+ // If exception was thrown in this frame, need to reset jvmti thread state.
+ // Single stepping may not get enabled correctly by the agent since
+ // exception state is passed in MethodExit event which may be sent at some
+ // time in the future. JDWP agent ignores MethodExit events if caused by
+ // an exception.
+ //
+ if (is_exception_detected()) {
+ clear_exception_detected();
+ }
// If step is pending for popframe then it may not be
// a repeat step. The new_bci and method_id is same as current_bci
// and current method_id after pop and step for recursive calls.
@@ -385,6 +394,15 @@
// the ForceEarlyReturn() dance
clr_pending_step_for_earlyret();
+ // If exception was thrown in this frame, need to reset jvmti thread state.
+ // Single stepping may not get enabled correctly by the agent since
+ // exception state is passed in MethodExit event which may be sent at some
+ // time in the future. JDWP agent ignores MethodExit events if caused by
+ // an exception.
+ //
+ if (is_exception_detected()) {
+ clear_exception_detected();
+ }
// If step is pending for earlyret then it may not be a repeat step.
// The new_bci and method_id is same as current_bci and current
// method_id after earlyret and step for recursive calls.
--- a/hotspot/src/share/vm/prims/jvmtiThreadState.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/prims/jvmtiThreadState.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -165,6 +165,10 @@
inline bool is_exception_caught() { return _exception_caught; }
inline void set_exception_detected() { _exception_detected = true;
_exception_caught = false; }
+ inline void clear_exception_detected() {
+ _exception_detected = false;
+ assert(_exception_caught == false, "_exception_caught is out of phase");
+ }
inline void set_exception_caught() { _exception_caught = true;
_exception_detected = false; }
--- a/hotspot/src/share/vm/prims/methodHandles.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -194,9 +194,6 @@
// MethodHandles::generate_adapters
//
void MethodHandles::generate_adapters() {
-#ifdef TARGET_ARCH_NYI_6939861
- if (FLAG_IS_DEFAULT(UseRicochetFrames)) UseRicochetFrames = false;
-#endif
if (!EnableInvokeDynamic || SystemDictionary::MethodHandle_klass() == NULL) return;
assert(_adapter_code == NULL, "generate only once");
@@ -230,18 +227,6 @@
}
-#ifdef TARGET_ARCH_NYI_6939861
-// these defs belong in methodHandles_<arch>.cpp
-frame MethodHandles::ricochet_frame_sender(const frame& fr, RegisterMap *map) {
- ShouldNotCallThis();
- return fr;
-}
-void MethodHandles::ricochet_frame_oops_do(const frame& fr, OopClosure* f, const RegisterMap* reg_map) {
- ShouldNotCallThis();
-}
-#endif //TARGET_ARCH_NYI_6939861
-
-
//------------------------------------------------------------------------------
// MethodHandles::ek_supported
//
@@ -251,28 +236,11 @@
case _adapter_unused_13:
return false; // not defined yet
case _adapter_prim_to_ref:
- return UseRicochetFrames && conv_op_supported(java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF);
+ return conv_op_supported(java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF);
case _adapter_collect_args:
- return UseRicochetFrames && conv_op_supported(java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS);
+ return conv_op_supported(java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS);
case _adapter_fold_args:
- return UseRicochetFrames && conv_op_supported(java_lang_invoke_AdapterMethodHandle::OP_FOLD_ARGS);
- case _adapter_opt_return_any:
- return UseRicochetFrames;
-#ifdef TARGET_ARCH_NYI_6939861
- // ports before 6939861 supported only three kinds of spread ops
- case _adapter_spread_args:
- // restrict spreads to three kinds:
- switch (ek) {
- case _adapter_opt_spread_0:
- case _adapter_opt_spread_1:
- case _adapter_opt_spread_more:
- break;
- default:
- return false;
- break;
- }
- break;
-#endif //TARGET_ARCH_NYI_6939861
+ return conv_op_supported(java_lang_invoke_AdapterMethodHandle::OP_FOLD_ARGS);
}
return true;
}
@@ -1988,9 +1956,6 @@
case _adapter_prim_to_ref: // boxer MH to use
case _adapter_collect_args: // method handle which collects the args
case _adapter_fold_args: // method handle which collects the args
- if (!UseRicochetFrames) {
- { err = "box/collect/fold operators are not supported"; break; }
- }
if (!java_lang_invoke_MethodHandle::is_instance(argument()))
{ err = "MethodHandle adapter argument required"; break; }
arg_mtype = Handle(THREAD, java_lang_invoke_MethodHandle::type(argument()));
@@ -2370,7 +2335,6 @@
case _adapter_prim_to_ref:
{
- assert(UseRicochetFrames, "else don't come here");
// vminfo will be the location to insert the return value
vminfo = argslot;
ek_opt = _adapter_opt_collect_ref;
@@ -2436,20 +2400,6 @@
case _adapter_spread_args:
{
-#ifdef TARGET_ARCH_NYI_6939861
- // ports before 6939861 supported only three kinds of spread ops
- if (!UseRicochetFrames) {
- int array_size = slots_pushed + 1;
- assert(array_size >= 0, "");
- vminfo = array_size;
- switch (array_size) {
- case 0: ek_opt = _adapter_opt_spread_0; break;
- case 1: ek_opt = _adapter_opt_spread_1; break;
- default: ek_opt = _adapter_opt_spread_more; break;
- }
- break;
- }
-#endif //TARGET_ARCH_NYI_6939861
// vminfo will be the required length of the array
int array_size = (slots_pushed + 1) / (type2size[dest] == 2 ? 2 : 1);
vminfo = array_size;
@@ -2494,7 +2444,6 @@
case _adapter_collect_args:
{
- assert(UseRicochetFrames, "else don't come here");
int elem_slots = argument_slot_count(java_lang_invoke_MethodHandle::type(argument()));
// vminfo will be the location to insert the return value
vminfo = argslot;
@@ -2563,7 +2512,6 @@
case _adapter_fold_args:
{
- assert(UseRicochetFrames, "else don't come here");
int elem_slots = argument_slot_count(java_lang_invoke_MethodHandle::type(argument()));
// vminfo will be the location to insert the return value
vminfo = argslot + elem_slots;
--- a/hotspot/src/share/vm/prims/methodHandles.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/prims/methodHandles.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -738,46 +738,6 @@
#ifdef TARGET_ARCH_ppc
# include "methodHandles_ppc.hpp"
#endif
-
-#ifdef TARGET_ARCH_NYI_6939861
- // Here are some backward compatible declarations until the 6939861 ports are updated.
- #define _adapter_flyby (_EK_LIMIT + 10)
- #define _adapter_ricochet (_EK_LIMIT + 11)
- #define _adapter_opt_spread_1 _adapter_opt_spread_1_ref
- #define _adapter_opt_spread_more _adapter_opt_spread_ref
- enum {
- _INSERT_NO_MASK = -1,
- _INSERT_REF_MASK = 0,
- _INSERT_INT_MASK = 1,
- _INSERT_LONG_MASK = 3
- };
- static void get_ek_bound_mh_info(EntryKind ek, BasicType& arg_type, int& arg_mask, int& arg_slots) {
- arg_type = ek_bound_mh_arg_type(ek);
- arg_mask = 0;
- arg_slots = type2size[arg_type];;
- }
- static void get_ek_adapter_opt_swap_rot_info(EntryKind ek, int& swap_bytes, int& rotate) {
- int swap_slots = ek_adapter_opt_swap_slots(ek);
- rotate = ek_adapter_opt_swap_mode(ek);
- swap_bytes = swap_slots * Interpreter::stackElementSize;
- }
- static int get_ek_adapter_opt_spread_info(EntryKind ek) {
- return ek_adapter_opt_spread_count(ek);
- }
-
- static void insert_arg_slots(MacroAssembler* _masm,
- RegisterOrConstant arg_slots,
- int arg_mask,
- Register argslot_reg,
- Register temp_reg, Register temp2_reg, Register temp3_reg = noreg);
-
- static void remove_arg_slots(MacroAssembler* _masm,
- RegisterOrConstant arg_slots,
- Register argslot_reg,
- Register temp_reg, Register temp2_reg, Register temp3_reg = noreg);
-
- static void trace_method_handle(MacroAssembler* _masm, const char* adaptername) PRODUCT_RETURN;
-#endif //TARGET_ARCH_NYI_6939861
};
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -271,13 +271,10 @@
}
// Create MDO if necessary.
-void AdvancedThresholdPolicy::create_mdo(methodHandle mh, TRAPS) {
+void AdvancedThresholdPolicy::create_mdo(methodHandle mh, JavaThread* THREAD) {
if (mh->is_native() || mh->is_abstract() || mh->is_accessor()) return;
if (mh->method_data() == NULL) {
- methodOopDesc::build_interpreter_method_data(mh, THREAD);
- if (HAS_PENDING_EXCEPTION) {
- CLEAR_PENDING_EXCEPTION;
- }
+ methodOopDesc::build_interpreter_method_data(mh, CHECK_AND_CLEAR);
}
}
@@ -426,22 +423,22 @@
}
// Update the rate and submit compile
-void AdvancedThresholdPolicy::submit_compile(methodHandle mh, int bci, CompLevel level, TRAPS) {
+void AdvancedThresholdPolicy::submit_compile(methodHandle mh, int bci, CompLevel level, JavaThread* thread) {
int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count();
update_rate(os::javaTimeMillis(), mh());
- CompileBroker::compile_method(mh, bci, level, mh, hot_count, "tiered", THREAD);
+ CompileBroker::compile_method(mh, bci, level, mh, hot_count, "tiered", thread);
}
// Handle the invocation event.
void AdvancedThresholdPolicy::method_invocation_event(methodHandle mh, methodHandle imh,
- CompLevel level, nmethod* nm, TRAPS) {
+ CompLevel level, nmethod* nm, JavaThread* thread) {
if (should_create_mdo(mh(), level)) {
- create_mdo(mh, THREAD);
+ create_mdo(mh, thread);
}
if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh, InvocationEntryBci)) {
CompLevel next_level = call_event(mh(), level);
if (next_level != level) {
- compile(mh, InvocationEntryBci, next_level, THREAD);
+ compile(mh, InvocationEntryBci, next_level, thread);
}
}
}
@@ -449,13 +446,13 @@
// Handle the back branch event. Notice that we can compile the method
// with a regular entry from here.
void AdvancedThresholdPolicy::method_back_branch_event(methodHandle mh, methodHandle imh,
- int bci, CompLevel level, nmethod* nm, TRAPS) {
+ int bci, CompLevel level, nmethod* nm, JavaThread* thread) {
if (should_create_mdo(mh(), level)) {
- create_mdo(mh, THREAD);
+ create_mdo(mh, thread);
}
// Check if MDO should be created for the inlined method
if (should_create_mdo(imh(), level)) {
- create_mdo(imh, THREAD);
+ create_mdo(imh, thread);
}
if (is_compilation_enabled()) {
@@ -463,7 +460,7 @@
CompLevel max_osr_level = (CompLevel)imh->highest_osr_comp_level();
// At the very least compile the OSR version
if (!CompileBroker::compilation_is_in_queue(imh, bci) && next_osr_level != level) {
- compile(imh, bci, next_osr_level, THREAD);
+ compile(imh, bci, next_osr_level, thread);
}
// Use loop event as an opportunity to also check if there's been
@@ -502,14 +499,14 @@
next_level = CompLevel_full_profile;
}
if (cur_level != next_level) {
- compile(mh, InvocationEntryBci, next_level, THREAD);
+ compile(mh, InvocationEntryBci, next_level, thread);
}
}
} else {
cur_level = comp_level(imh());
next_level = call_event(imh(), cur_level);
if (!CompileBroker::compilation_is_in_queue(imh, bci) && next_level != cur_level) {
- compile(imh, InvocationEntryBci, next_level, THREAD);
+ compile(imh, InvocationEntryBci, next_level, thread);
}
}
}
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -197,7 +197,7 @@
// determines whether we should do that.
inline bool should_create_mdo(methodOop method, CompLevel cur_level);
// Create MDO if necessary.
- void create_mdo(methodHandle mh, TRAPS);
+ void create_mdo(methodHandle mh, JavaThread* thread);
// Is method profiled enough?
bool is_method_profiled(methodOop method);
@@ -208,12 +208,12 @@
jlong start_time() const { return _start_time; }
// Submit a given method for compilation (and update the rate).
- virtual void submit_compile(methodHandle mh, int bci, CompLevel level, TRAPS);
+ virtual void submit_compile(methodHandle mh, int bci, CompLevel level, JavaThread* thread);
// event() from SimpleThresholdPolicy would call these.
virtual void method_invocation_event(methodHandle method, methodHandle inlinee,
- CompLevel level, nmethod* nm, TRAPS);
+ CompLevel level, nmethod* nm, JavaThread* thread);
virtual void method_back_branch_event(methodHandle method, methodHandle inlinee,
- int bci, CompLevel level, nmethod* nm, TRAPS);
+ int bci, CompLevel level, nmethod* nm, JavaThread* thread);
public:
AdvancedThresholdPolicy() : _start_time(0) { }
// Select task is called by CompileBroker. We should return a task or NULL.
--- a/hotspot/src/share/vm/runtime/arguments.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -1040,6 +1040,16 @@
}
#ifndef KERNEL
+static void disable_adaptive_size_policy(const char* collector_name) {
+ if (UseAdaptiveSizePolicy) {
+ if (FLAG_IS_CMDLINE(UseAdaptiveSizePolicy)) {
+ warning("disabling UseAdaptiveSizePolicy; it is incompatible with %s.",
+ collector_name);
+ }
+ FLAG_SET_DEFAULT(UseAdaptiveSizePolicy, false);
+ }
+}
+
// If the user has chosen ParallelGCThreads > 0, we set UseParNewGC
// if it's not explictly set or unset. If the user has chosen
// UseParNewGC and not explicitly set ParallelGCThreads we
@@ -1049,11 +1059,8 @@
"control point invariant");
assert(UseParNewGC, "Error");
- // Turn off AdaptiveSizePolicy by default for parnew until it is
- // complete.
- if (FLAG_IS_DEFAULT(UseAdaptiveSizePolicy)) {
- FLAG_SET_DEFAULT(UseAdaptiveSizePolicy, false);
- }
+ // Turn off AdaptiveSizePolicy for parnew until it is complete.
+ disable_adaptive_size_policy("UseParNewGC");
if (ParallelGCThreads == 0) {
FLAG_SET_DEFAULT(ParallelGCThreads,
@@ -1110,11 +1117,8 @@
FLAG_SET_ERGO(bool, UseParNewGC, true);
}
- // Turn off AdaptiveSizePolicy by default for cms until it is
- // complete.
- if (FLAG_IS_DEFAULT(UseAdaptiveSizePolicy)) {
- FLAG_SET_DEFAULT(UseAdaptiveSizePolicy, false);
- }
+ // Turn off AdaptiveSizePolicy for CMS until it is complete.
+ disable_adaptive_size_policy("UseConcMarkSweepGC");
// In either case, adjust ParallelGCThreads and/or UseParNewGC
// as needed.
--- a/hotspot/src/share/vm/runtime/compilationPolicy.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/runtime/compilationPolicy.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -306,29 +306,27 @@
return (current >= initial + target);
}
-nmethod* NonTieredCompPolicy::event(methodHandle method, methodHandle inlinee, int branch_bci, int bci, CompLevel comp_level, nmethod* nm, TRAPS) {
+nmethod* NonTieredCompPolicy::event(methodHandle method, methodHandle inlinee, int branch_bci,
+ int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread) {
assert(comp_level == CompLevel_none, "This should be only called from the interpreter");
NOT_PRODUCT(trace_frequency_counter_overflow(method, branch_bci, bci));
- if (JvmtiExport::can_post_interpreter_events()) {
- assert(THREAD->is_Java_thread(), "Wrong type of thread");
- if (((JavaThread*)THREAD)->is_interp_only_mode()) {
- // If certain JVMTI events (e.g. frame pop event) are requested then the
- // thread is forced to remain in interpreted code. This is
- // implemented partly by a check in the run_compiled_code
- // section of the interpreter whether we should skip running
- // compiled code, and partly by skipping OSR compiles for
- // interpreted-only threads.
- if (bci != InvocationEntryBci) {
- reset_counter_for_back_branch_event(method);
- return NULL;
- }
+ if (JvmtiExport::can_post_interpreter_events() && thread->is_interp_only_mode()) {
+ // If certain JVMTI events (e.g. frame pop event) are requested then the
+ // thread is forced to remain in interpreted code. This is
+ // implemented partly by a check in the run_compiled_code
+ // section of the interpreter whether we should skip running
+ // compiled code, and partly by skipping OSR compiles for
+ // interpreted-only threads.
+ if (bci != InvocationEntryBci) {
+ reset_counter_for_back_branch_event(method);
+ return NULL;
}
}
if (bci == InvocationEntryBci) {
// when code cache is full, compilation gets switched off, UseCompiler
// is set to false
if (!method->has_compiled_code() && UseCompiler) {
- method_invocation_event(method, CHECK_NULL);
+ method_invocation_event(method, thread);
} else {
// Force counter overflow on method entry, even if no compilation
// happened. (The method_invocation_event call does this also.)
@@ -344,7 +342,7 @@
NOT_PRODUCT(trace_osr_request(method, osr_nm, bci));
// when code cache is full, we should not compile any more...
if (osr_nm == NULL && UseCompiler) {
- method_back_branch_event(method, bci, CHECK_NULL);
+ method_back_branch_event(method, bci, thread);
osr_nm = method->lookup_osr_nmethod_for(bci, CompLevel_highest_tier, true);
}
if (osr_nm == NULL) {
@@ -395,7 +393,7 @@
// SimpleCompPolicy - compile current method
-void SimpleCompPolicy::method_invocation_event( methodHandle m, TRAPS) {
+void SimpleCompPolicy::method_invocation_event(methodHandle m, JavaThread* thread) {
int hot_count = m->invocation_count();
reset_counter_for_invocation_event(m);
const char* comment = "count";
@@ -405,18 +403,18 @@
if (nm == NULL ) {
const char* comment = "count";
CompileBroker::compile_method(m, InvocationEntryBci, CompLevel_highest_tier,
- m, hot_count, comment, CHECK);
+ m, hot_count, comment, thread);
}
}
}
-void SimpleCompPolicy::method_back_branch_event(methodHandle m, int bci, TRAPS) {
+void SimpleCompPolicy::method_back_branch_event(methodHandle m, int bci, JavaThread* thread) {
int hot_count = m->backedge_count();
const char* comment = "backedge_count";
if (is_compilation_enabled() && !m->is_not_osr_compilable() && can_be_compiled(m)) {
CompileBroker::compile_method(m, bci, CompLevel_highest_tier,
- m, hot_count, comment, CHECK);
+ m, hot_count, comment, thread);
NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, CompLevel_highest_tier, true));)
}
}
@@ -427,14 +425,13 @@
// Consider m for compilation
-void StackWalkCompPolicy::method_invocation_event(methodHandle m, TRAPS) {
+void StackWalkCompPolicy::method_invocation_event(methodHandle m, JavaThread* thread) {
int hot_count = m->invocation_count();
reset_counter_for_invocation_event(m);
const char* comment = "count";
if (is_compilation_enabled() && m->code() == NULL && can_be_compiled(m)) {
- ResourceMark rm(THREAD);
- JavaThread *thread = (JavaThread*)THREAD;
+ ResourceMark rm(thread);
frame fr = thread->last_frame();
assert(fr.is_interpreted_frame(), "must be interpreted");
assert(fr.interpreter_frame_method() == m(), "bad method");
@@ -461,17 +458,17 @@
assert(top != NULL, "findTopInlinableFrame returned null");
if (TraceCompilationPolicy) top->print();
CompileBroker::compile_method(top->top_method(), InvocationEntryBci, CompLevel_highest_tier,
- m, hot_count, comment, CHECK);
+ m, hot_count, comment, thread);
}
}
}
-void StackWalkCompPolicy::method_back_branch_event(methodHandle m, int bci, TRAPS) {
+void StackWalkCompPolicy::method_back_branch_event(methodHandle m, int bci, JavaThread* thread) {
int hot_count = m->backedge_count();
const char* comment = "backedge_count";
if (is_compilation_enabled() && !m->is_not_osr_compilable() && can_be_compiled(m)) {
- CompileBroker::compile_method(m, bci, CompLevel_highest_tier, m, hot_count, comment, CHECK);
+ CompileBroker::compile_method(m, bci, CompLevel_highest_tier, m, hot_count, comment, thread);
NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, CompLevel_highest_tier, true));)
}
--- a/hotspot/src/share/vm/runtime/compilationPolicy.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/runtime/compilationPolicy.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -64,7 +64,7 @@
virtual int compiler_count(CompLevel comp_level) = 0;
// main notification entry, return a pointer to an nmethod if the OSR is required,
// returns NULL otherwise.
- virtual nmethod* event(methodHandle method, methodHandle inlinee, int branch_bci, int bci, CompLevel comp_level, nmethod* nm, TRAPS) = 0;
+ virtual nmethod* event(methodHandle method, methodHandle inlinee, int branch_bci, int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread) = 0;
// safepoint() is called at the end of the safepoint
virtual void do_safepoint_work() = 0;
// reprofile request
@@ -105,15 +105,15 @@
virtual bool is_mature(methodOop method);
virtual void initialize();
virtual CompileTask* select_task(CompileQueue* compile_queue);
- virtual nmethod* event(methodHandle method, methodHandle inlinee, int branch_bci, int bci, CompLevel comp_level, nmethod* nm, TRAPS);
- virtual void method_invocation_event(methodHandle m, TRAPS) = 0;
- virtual void method_back_branch_event(methodHandle m, int bci, TRAPS) = 0;
+ virtual nmethod* event(methodHandle method, methodHandle inlinee, int branch_bci, int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread);
+ virtual void method_invocation_event(methodHandle m, JavaThread* thread) = 0;
+ virtual void method_back_branch_event(methodHandle m, int bci, JavaThread* thread) = 0;
};
class SimpleCompPolicy : public NonTieredCompPolicy {
public:
- virtual void method_invocation_event(methodHandle m, TRAPS);
- virtual void method_back_branch_event(methodHandle m, int bci, TRAPS);
+ virtual void method_invocation_event(methodHandle m, JavaThread* thread);
+ virtual void method_back_branch_event(methodHandle m, int bci, JavaThread* thread);
};
// StackWalkCompPolicy - existing C2 policy
@@ -121,8 +121,8 @@
#ifdef COMPILER2
class StackWalkCompPolicy : public NonTieredCompPolicy {
public:
- virtual void method_invocation_event(methodHandle m, TRAPS);
- virtual void method_back_branch_event(methodHandle m, int bci, TRAPS);
+ virtual void method_invocation_event(methodHandle m, JavaThread* thread);
+ virtual void method_back_branch_event(methodHandle m, int bci, JavaThread* thread);
private:
RFrame* findTopInlinableFrame(GrowableArray<RFrame*>* stack);
--- a/hotspot/src/share/vm/runtime/frame.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/runtime/frame.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -1315,7 +1315,6 @@
}
#endif
-
#ifdef ASSERT
void frame::interpreter_frame_verify_monitor(BasicObjectLock* value) const {
assert(is_interpreted_frame(), "Not an interpreted frame");
@@ -1331,27 +1330,35 @@
guarantee((current - low_mark) % monitor_size == 0 , "Misaligned bottom of BasicObjectLock*");
guarantee( current >= low_mark , "Current BasicObjectLock* below than low_mark");
}
+#endif
+#ifndef PRODUCT
+void frame::describe(FrameValues& values, int frame_no) {
+ // boundaries: sp and the 'real' frame pointer
+ values.describe(-1, sp(), err_msg("sp for #%d", frame_no), 1);
+ intptr_t* frame_pointer = real_fp(); // Note: may differ from fp()
-void frame::describe(FrameValues& values, int frame_no) {
+ // print frame info at the highest boundary
+ intptr_t* info_address = MAX2(sp(), frame_pointer);
+
+ if (info_address != frame_pointer) {
+ // print frame_pointer explicitly if not marked by the frame info
+ values.describe(-1, frame_pointer, err_msg("frame pointer for #%d", frame_no), 1);
+ }
+
if (is_entry_frame() || is_compiled_frame() || is_interpreted_frame() || is_native_frame()) {
// Label values common to most frames
values.describe(-1, unextended_sp(), err_msg("unextended_sp for #%d", frame_no));
- values.describe(-1, sp(), err_msg("sp for #%d", frame_no));
- if (is_compiled_frame()) {
- values.describe(-1, sp() + _cb->frame_size(), err_msg("computed fp for #%d", frame_no));
- } else {
- values.describe(-1, fp(), err_msg("fp for #%d", frame_no));
- }
}
+
if (is_interpreted_frame()) {
methodOop m = interpreter_frame_method();
int bci = interpreter_frame_bci();
// Label the method and current bci
- values.describe(-1, MAX2(sp(), fp()),
+ values.describe(-1, info_address,
FormatBuffer<1024>("#%d method %s @ %d", frame_no, m->name_and_sig_as_C_string(), bci), 2);
- values.describe(-1, MAX2(sp(), fp()),
+ values.describe(-1, info_address,
err_msg("- %d locals %d max stack", m->max_locals(), m->max_stack()), 1);
if (m->max_locals() > 0) {
intptr_t* l0 = interpreter_frame_local_at(0);
@@ -1383,21 +1390,36 @@
}
} else if (is_entry_frame()) {
// For now just label the frame
- values.describe(-1, MAX2(sp(), fp()), err_msg("#%d entry frame", frame_no), 2);
+ values.describe(-1, info_address, err_msg("#%d entry frame", frame_no), 2);
} else if (is_compiled_frame()) {
// For now just label the frame
nmethod* nm = cb()->as_nmethod_or_null();
- values.describe(-1, MAX2(sp(), fp()),
+ values.describe(-1, info_address,
FormatBuffer<1024>("#%d nmethod " INTPTR_FORMAT " for method %s%s", frame_no,
nm, nm->method()->name_and_sig_as_C_string(),
- is_deoptimized_frame() ? " (deoptimized" : ""), 2);
+ (_deopt_state == is_deoptimized) ?
+ " (deoptimized)" :
+ ((_deopt_state == unknown) ? " (state unknown)" : "")),
+ 2);
} else if (is_native_frame()) {
// For now just label the frame
nmethod* nm = cb()->as_nmethod_or_null();
- values.describe(-1, MAX2(sp(), fp()),
+ values.describe(-1, info_address,
FormatBuffer<1024>("#%d nmethod " INTPTR_FORMAT " for native method %s", frame_no,
nm, nm->method()->name_and_sig_as_C_string()), 2);
+ } else if (is_ricochet_frame()) {
+ values.describe(-1, info_address, err_msg("#%d ricochet frame", frame_no), 2);
+ } else {
+ // provide default info if not handled before
+ char *info = (char *) "special frame";
+ if ((_cb != NULL) &&
+ (_cb->name() != NULL)) {
+ info = (char *)_cb->name();
+ }
+ values.describe(-1, info_address, err_msg("#%d <%s>", frame_no, info), 2);
}
+
+ // platform dependent additional data
describe_pd(values, frame_no);
}
@@ -1414,7 +1436,7 @@
}
-#ifdef ASSERT
+#ifndef PRODUCT
void FrameValues::describe(int owner, intptr_t* location, const char* description, int priority) {
FrameValue fv;
@@ -1427,6 +1449,7 @@
}
+#ifdef ASSERT
void FrameValues::validate() {
_values.sort(compare);
bool error = false;
@@ -1452,7 +1475,7 @@
}
assert(!error, "invalid layout");
}
-
+#endif // ASSERT
void FrameValues::print(JavaThread* thread) {
_values.sort(compare);
@@ -1501,4 +1524,4 @@
}
}
-#endif
+#endif // ndef PRODUCT
--- a/hotspot/src/share/vm/runtime/frame.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/runtime/frame.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -221,6 +221,15 @@
// returns the stack pointer of the calling frame
intptr_t* sender_sp() const;
+ // Returns the real 'frame pointer' for the current frame.
+ // This is the value expected by the platform ABI when it defines a
+ // frame pointer register. It may differ from the effective value of
+ // the FP register when that register is used in the JVM for other
+ // purposes (like compiled frames on some platforms).
+ // On other platforms, it is defined so that the stack area used by
+ // this frame goes from real_fp() to sp().
+ intptr_t* real_fp() const;
+
// Deoptimization info, if needed (platform dependent).
// Stored in the initial_info field of the unroll info, to be used by
// the platform dependent deoptimization blobs.
@@ -485,7 +494,7 @@
};
-#ifdef ASSERT
+#ifndef PRODUCT
// A simple class to describe a location on the stack
class FrameValue VALUE_OBJ_CLASS_SPEC {
public:
@@ -515,7 +524,9 @@
// Used by frame functions to describe locations.
void describe(int owner, intptr_t* location, const char* description, int priority = 0);
+#ifdef ASSERT
void validate();
+#endif
void print(JavaThread* thread);
};
--- a/hotspot/src/share/vm/runtime/globals.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/runtime/globals.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -3477,16 +3477,19 @@
" Linux this policy requires root privilege.") \
\
product(bool, ThreadPriorityVerbose, false, \
- "print priority changes") \
+ "Print priority changes") \
\
product(intx, DefaultThreadPriority, -1, \
- "what native priority threads run at if not specified elsewhere (-1 means no change)") \
+ "The native priority at which threads run if not elsewhere " \
+ "specified (-1 means no change)") \
\
product(intx, CompilerThreadPriority, -1, \
- "what priority should compiler threads run at (-1 means no change)") \
+ "The native priority at which compiler threads should run " \
+ "(-1 means no change)") \
\
product(intx, VMThreadPriority, -1, \
- "what priority should VM threads run at (-1 means no change)") \
+ "The native priority at which the VM thread should run " \
+ "(-1 means no change)") \
\
product(bool, CompilerThreadHintNoPreempt, true, \
"(Solaris only) Give compiler threads an extra quanta") \
@@ -3505,6 +3508,15 @@
product(intx, JavaPriority9_To_OSPriority, -1, "Map Java priorities to OS priorities") \
product(intx, JavaPriority10_To_OSPriority,-1, "Map Java priorities to OS priorities") \
\
+ experimental(bool, UseCriticalJavaThreadPriority, false, \
+ "Java thread priority 10 maps to critical scheduling priority") \
+ \
+ experimental(bool, UseCriticalCompilerThreadPriority, false, \
+ "Compiler thread(s) run at critical scheduling priority") \
+ \
+ experimental(bool, UseCriticalCMSThreadPriority, false, \
+ "ConcurrentMarkSweep thread runs at critical scheduling priority")\
+ \
/* compiler debugging */ \
notproduct(intx, CompileTheWorldStartAt, 1, \
"First class to consider when using +CompileTheWorld") \
@@ -3574,7 +3586,7 @@
"Threshold at which tier 3 compilation is invoked (invocation " \
"minimum must be satisfied.") \
\
- product(intx, Tier3BackEdgeThreshold, 7000, \
+ product(intx, Tier3BackEdgeThreshold, 60000, \
"Back edge threshold at which tier 3 OSR compilation is invoked") \
\
product(intx, Tier4InvocationThreshold, 5000, \
@@ -3826,10 +3838,6 @@
develop(bool, StressMethodHandleWalk, false, \
"Process all method handles with MethodHandleWalk") \
\
- diagnostic(bool, UseRicochetFrames, true, \
- "use ricochet stack frames for method handle combination, " \
- "if the platform supports them") \
- \
experimental(bool, TrustFinalNonStaticFields, false, \
"trust final non-static declarations for constant folding") \
\
@@ -3875,7 +3883,7 @@
product(bool, UseVMInterruptibleIO, false, \
"(Unstable, Solaris-specific) Thread interrupt before or with " \
"EINTR for I/O operations results in OS_INTRPT. The default value"\
- " of this flag is true for JDK 6 and earliers")
+ " of this flag is true for JDK 6 and earlier")
/*
* Macros for factoring of globals
--- a/hotspot/src/share/vm/runtime/java.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/runtime/java.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -57,6 +57,8 @@
#include "runtime/task.hpp"
#include "runtime/timer.hpp"
#include "runtime/vm_operations.hpp"
+#include "trace/tracing.hpp"
+#include "trace/traceEventTypes.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/histogram.hpp"
@@ -502,6 +504,11 @@
if (JvmtiExport::should_post_thread_life()) {
JvmtiExport::post_thread_end(thread);
}
+
+ EVENT_BEGIN(TraceEventThreadEnd, event);
+ EVENT_COMMIT(event,
+ EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(thread->threadObj())));
+
// Always call even when there are not JVMTI environments yet, since environments
// may be attached late and JVMTI must track phases of VM execution
JvmtiExport::post_vm_death();
--- a/hotspot/src/share/vm/runtime/mutexLocker.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -126,13 +126,20 @@
Mutex* FreeList_lock = NULL;
Monitor* SecondaryFreeList_lock = NULL;
Mutex* OldSets_lock = NULL;
+Monitor* RootRegionScan_lock = NULL;
Mutex* MMUTracker_lock = NULL;
Mutex* HotCardCache_lock = NULL;
Monitor* GCTaskManager_lock = NULL;
Mutex* Management_lock = NULL;
-Monitor* Service_lock = NULL;
+Monitor* Service_lock = NULL;
+Mutex* Stacktrace_lock = NULL;
+
+Monitor* JfrQuery_lock = NULL;
+Monitor* JfrMsg_lock = NULL;
+Mutex* JfrBuffer_lock = NULL;
+Mutex* JfrStream_lock = NULL;
#define MAX_NUM_MUTEX 128
static Monitor * _mutex_array[MAX_NUM_MUTEX];
@@ -193,6 +200,7 @@
def(FreeList_lock , Mutex, leaf , true );
def(SecondaryFreeList_lock , Monitor, leaf , true );
def(OldSets_lock , Mutex , leaf , true );
+ def(RootRegionScan_lock , Monitor, leaf , true );
def(MMUTracker_lock , Mutex , leaf , true );
def(HotCardCache_lock , Mutex , special , true );
def(EvacFailureStack_lock , Mutex , nonleaf , true );
@@ -207,6 +215,7 @@
def(Patching_lock , Mutex , special, true ); // used for safepointing and code patching.
def(ObjAllocPost_lock , Monitor, special, false);
def(Service_lock , Monitor, special, true ); // used for service thread operations
+ def(Stacktrace_lock , Mutex, special, true ); // used for JFR stacktrace database
def(JmethodIdCreation_lock , Mutex , leaf, true ); // used for creating jmethodIDs.
def(SystemDictionary_lock , Monitor, leaf, true ); // lookups done by VM thread
@@ -271,6 +280,11 @@
def(Debug3_lock , Mutex , nonleaf+4, true );
def(ProfileVM_lock , Monitor, nonleaf+4, false); // used for profiling of the VMThread
def(CompileThread_lock , Monitor, nonleaf+5, false );
+
+ def(JfrQuery_lock , Monitor, nonleaf, true); // JFR locks, keep these in consecutive order
+ def(JfrMsg_lock , Monitor, nonleaf+2, true);
+ def(JfrBuffer_lock , Mutex, nonleaf+3, true);
+ def(JfrStream_lock , Mutex, nonleaf+4, true);
}
GCMutexLocker::GCMutexLocker(Monitor * mutex) {
--- a/hotspot/src/share/vm/runtime/mutexLocker.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -115,7 +115,7 @@
#ifndef PRODUCT
extern Mutex* FullGCALot_lock; // a lock to make FullGCALot MT safe
-#endif
+#endif // PRODUCT
extern Mutex* Debug1_lock; // A bunch of pre-allocated locks that can be used for tracing
extern Mutex* Debug2_lock; // down synchronization related bugs!
extern Mutex* Debug3_lock;
@@ -129,12 +129,19 @@
extern Mutex* FreeList_lock; // protects the free region list during safepoints
extern Monitor* SecondaryFreeList_lock; // protects the secondary free region list
extern Mutex* OldSets_lock; // protects the old region sets
+extern Monitor* RootRegionScan_lock; // used to notify that the CM threads have finished scanning the IM snapshot regions
extern Mutex* MMUTracker_lock; // protects the MMU
// tracker data structures
extern Mutex* HotCardCache_lock; // protects the hot card cache
extern Mutex* Management_lock; // a lock used to serialize JVM management
extern Monitor* Service_lock; // a lock used for service thread operation
+extern Mutex* Stacktrace_lock; // used to guard access to the stacktrace table
+
+extern Monitor* JfrQuery_lock; // protects JFR use
+extern Monitor* JfrMsg_lock; // protects JFR messaging
+extern Mutex* JfrBuffer_lock; // protects JFR buffer operations
+extern Mutex* JfrStream_lock; // protects JFR stream access
// A MutexLocker provides mutual exclusion with respect to a given mutex
// for the scope which contains the locker. The lock is an OS lock, not
--- a/hotspot/src/share/vm/runtime/os.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/runtime/os.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -1101,6 +1101,7 @@
"%/lib/jsse.jar:"
"%/lib/jce.jar:"
"%/lib/charsets.jar:"
+ "%/lib/jfr.jar:"
#ifdef __APPLE__
"%/lib/JObjC.jar:"
#endif
--- a/hotspot/src/share/vm/runtime/os.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/runtime/os.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -73,8 +73,9 @@
MinPriority = 1, // Minimum priority
NormPriority = 5, // Normal (non-daemon) priority
NearMaxPriority = 9, // High priority, used for VMThread
- MaxPriority = 10 // Highest priority, used for WatcherThread
+ MaxPriority = 10, // Highest priority, used for WatcherThread
// ensures that VMThread doesn't starve profiler
+ CriticalPriority = 11 // Critical thread priority
};
// Typedef for structured exception handling support
@@ -733,7 +734,7 @@
// Thread priority helpers (implemented in OS-specific part)
static OSReturn set_native_priority(Thread* thread, int native_prio);
static OSReturn get_native_priority(const Thread* const thread, int* priority_ptr);
- static int java_to_os_priority[MaxPriority + 1];
+ static int java_to_os_priority[CriticalPriority + 1];
// Hint to the underlying OS that a task switch would not be good.
// Void return because it's a hint and can fail.
static void hint_no_preempt();
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -121,7 +121,6 @@
void SharedRuntime::generate_ricochet_blob() {
if (!EnableInvokeDynamic) return; // leave it as a null
-#ifndef TARGET_ARCH_NYI_6939861
// allocate space for the code
ResourceMark rm;
// setup code generation tools
@@ -142,7 +141,6 @@
}
_ricochet_blob = RicochetBlob::create(&buffer, bounce_offset, exception_offset, frame_size_in_words);
-#endif
}
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -177,13 +177,11 @@
}
nmethod* SimpleThresholdPolicy::event(methodHandle method, methodHandle inlinee,
- int branch_bci, int bci, CompLevel comp_level, nmethod* nm, TRAPS) {
+ int branch_bci, int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread) {
if (comp_level == CompLevel_none &&
- JvmtiExport::can_post_interpreter_events()) {
- assert(THREAD->is_Java_thread(), "Should be java thread");
- if (((JavaThread*)THREAD)->is_interp_only_mode()) {
- return NULL;
- }
+ JvmtiExport::can_post_interpreter_events() &&
+ thread->is_interp_only_mode()) {
+ return NULL;
}
nmethod *osr_nm = NULL;
@@ -197,9 +195,9 @@
}
if (bci == InvocationEntryBci) {
- method_invocation_event(method, inlinee, comp_level, nm, THREAD);
+ method_invocation_event(method, inlinee, comp_level, nm, thread);
} else {
- method_back_branch_event(method, inlinee, bci, comp_level, nm, THREAD);
+ method_back_branch_event(method, inlinee, bci, comp_level, nm, thread);
// method == inlinee if the event originated in the main method
int highest_level = inlinee->highest_osr_comp_level();
if (highest_level > comp_level) {
@@ -210,7 +208,7 @@
}
// Check if the method can be compiled, change level if necessary
-void SimpleThresholdPolicy::compile(methodHandle mh, int bci, CompLevel level, TRAPS) {
+void SimpleThresholdPolicy::compile(methodHandle mh, int bci, CompLevel level, JavaThread* thread) {
assert(level <= TieredStopAtLevel, "Invalid compilation level");
if (level == CompLevel_none) {
return;
@@ -221,7 +219,7 @@
// pure C1.
if (!can_be_compiled(mh, level)) {
if (level == CompLevel_full_optimization && can_be_compiled(mh, CompLevel_simple)) {
- compile(mh, bci, CompLevel_simple, THREAD);
+ compile(mh, bci, CompLevel_simple, thread);
}
return;
}
@@ -232,14 +230,14 @@
if (PrintTieredEvents) {
print_event(COMPILE, mh, mh, bci, level);
}
- submit_compile(mh, bci, level, THREAD);
+ submit_compile(mh, bci, level, thread);
}
}
// Tell the broker to compile the method
-void SimpleThresholdPolicy::submit_compile(methodHandle mh, int bci, CompLevel level, TRAPS) {
+void SimpleThresholdPolicy::submit_compile(methodHandle mh, int bci, CompLevel level, JavaThread* thread) {
int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count();
- CompileBroker::compile_method(mh, bci, level, mh, hot_count, "tiered", THREAD);
+ CompileBroker::compile_method(mh, bci, level, mh, hot_count, "tiered", thread);
}
// Call and loop predicates determine whether a transition to a higher
@@ -366,11 +364,11 @@
// Handle the invocation event.
void SimpleThresholdPolicy::method_invocation_event(methodHandle mh, methodHandle imh,
- CompLevel level, nmethod* nm, TRAPS) {
+ CompLevel level, nmethod* nm, JavaThread* thread) {
if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh, InvocationEntryBci)) {
CompLevel next_level = call_event(mh(), level);
if (next_level != level) {
- compile(mh, InvocationEntryBci, next_level, THREAD);
+ compile(mh, InvocationEntryBci, next_level, thread);
}
}
}
@@ -378,7 +376,7 @@
// Handle the back branch event. Notice that we can compile the method
// with a regular entry from here.
void SimpleThresholdPolicy::method_back_branch_event(methodHandle mh, methodHandle imh,
- int bci, CompLevel level, nmethod* nm, TRAPS) {
+ int bci, CompLevel level, nmethod* nm, JavaThread* thread) {
// If the method is already compiling, quickly bail out.
if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh, bci)) {
// Use loop event as an opportinity to also check there's been
@@ -391,13 +389,13 @@
next_osr_level < CompLevel_full_optimization ? next_osr_level : cur_level);
bool is_compiling = false;
if (next_level != cur_level) {
- compile(mh, InvocationEntryBci, next_level, THREAD);
+ compile(mh, InvocationEntryBci, next_level, thread);
is_compiling = true;
}
// Do the OSR version
if (!is_compiling && next_osr_level != level) {
- compile(mh, bci, next_osr_level, THREAD);
+ compile(mh, bci, next_osr_level, thread);
}
}
}
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -67,9 +67,9 @@
// Print policy-specific information if necessary
virtual void print_specific(EventType type, methodHandle mh, methodHandle imh, int bci, CompLevel level) { }
// Check if the method can be compiled, change level if necessary
- void compile(methodHandle mh, int bci, CompLevel level, TRAPS);
+ void compile(methodHandle mh, int bci, CompLevel level, JavaThread* thread);
// Submit a given method for compilation
- virtual void submit_compile(methodHandle mh, int bci, CompLevel level, TRAPS);
+ virtual void submit_compile(methodHandle mh, int bci, CompLevel level, JavaThread* thread);
// Simple methods are as good being compiled with C1 as C2.
// This function tells if it's such a function.
inline bool is_trivial(methodOop method);
@@ -88,9 +88,9 @@
return CompLevel_none;
}
virtual void method_invocation_event(methodHandle method, methodHandle inlinee,
- CompLevel level, nmethod* nm, TRAPS);
+ CompLevel level, nmethod* nm, JavaThread* thread);
virtual void method_back_branch_event(methodHandle method, methodHandle inlinee,
- int bci, CompLevel level, nmethod* nm, TRAPS);
+ int bci, CompLevel level, nmethod* nm, JavaThread* thread);
public:
SimpleThresholdPolicy() : _c1_count(0), _c2_count(0) { }
virtual int compiler_count(CompLevel comp_level) {
@@ -104,7 +104,7 @@
virtual void disable_compilation(methodOop method) { }
virtual void reprofile(ScopeDesc* trap_scope, bool is_osr);
virtual nmethod* event(methodHandle method, methodHandle inlinee,
- int branch_bci, int bci, CompLevel comp_level, nmethod* nm, TRAPS);
+ int branch_bci, int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread);
// Select task is called by CompileBroker. We should return a task or NULL.
virtual CompileTask* select_task(CompileQueue* compile_queue);
// Tell the runtime if we think a given method is adequately profiled.
--- a/hotspot/src/share/vm/runtime/thread.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/runtime/thread.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -73,6 +73,7 @@
#include "services/attachListener.hpp"
#include "services/management.hpp"
#include "services/threadService.hpp"
+#include "trace/traceEventTypes.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/events.hpp"
@@ -232,6 +233,7 @@
CHECK_UNHANDLED_OOPS_ONLY(_gc_locked_out_count = 0;)
_jvmti_env_iteration_count = 0;
set_allocated_bytes(0);
+ set_trace_buffer(NULL);
_vm_operation_started_count = 0;
_vm_operation_completed_count = 0;
_current_pending_monitor = NULL;
@@ -1512,6 +1514,10 @@
JvmtiExport::post_thread_start(this);
}
+ EVENT_BEGIN(TraceEventThreadStart, event);
+ EVENT_COMMIT(event,
+ EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(this->threadObj())));
+
// We call another function to do the rest so we are sure that the stack addresses used
// from there will be lower than the stack base just computed
thread_main_inner();
@@ -1641,6 +1647,15 @@
}
}
+ // Called before the java thread exit since we want to read info
+ // from java_lang_Thread object
+ EVENT_BEGIN(TraceEventThreadEnd, event);
+ EVENT_COMMIT(event,
+ EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(this->threadObj())));
+
+ // Call after last event on thread
+ EVENT_THREAD_EXIT(this);
+
// Call Thread.exit(). We try 3 times in case we got another Thread.stop during
// the execution of the method. If that is not enough, then we don't really care. Thread.stop
// is deprecated anyhow.
@@ -3186,6 +3201,11 @@
return status;
}
+ // Must be run after init_ft which initializes ft_enabled
+ if (TRACE_INITIALIZE() != JNI_OK) {
+ vm_exit_during_initialization("Failed to initialize tracing backend");
+ }
+
// Should be done after the heap is fully created
main_thread->cache_global_variables();
@@ -3423,6 +3443,10 @@
create_vm_init_libraries();
}
+ if (!TRACE_START()) {
+ vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION));
+ }
+
// Notify JVMTI agents that VM initialization is complete - nop if no agents.
JvmtiExport::post_vm_initialized();
--- a/hotspot/src/share/vm/runtime/thread.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/runtime/thread.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -41,6 +41,7 @@
#include "runtime/stubRoutines.hpp"
#include "runtime/threadLocalStorage.hpp"
#include "runtime/unhandledOops.hpp"
+#include "trace/tracing.hpp"
#include "utilities/exceptions.hpp"
#include "utilities/top.hpp"
#ifndef SERIALGC
@@ -246,6 +247,8 @@
jlong _allocated_bytes; // Cumulative number of bytes allocated on
// the Java heap
+ TRACE_BUFFER _trace_buffer; // Thread-local buffer for tracing
+
int _vm_operation_started_count; // VM_Operation support
int _vm_operation_completed_count; // VM_Operation support
@@ -414,6 +417,9 @@
return allocated_bytes;
}
+ TRACE_BUFFER trace_buffer() { return _trace_buffer; }
+ void set_trace_buffer(TRACE_BUFFER buf) { _trace_buffer = buf; }
+
// VM operation support
int vm_operation_ticket() { return ++_vm_operation_started_count; }
int vm_operation_completed_count() { return _vm_operation_completed_count; }
--- a/hotspot/src/share/vm/runtime/vm_operations.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/runtime/vm_operations.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -93,6 +93,7 @@
template(HeapWalkOperation) \
template(HeapIterateOperation) \
template(ReportJavaOutOfMemory) \
+ template(JFRCheckpoint) \
template(Exit) \
class VM_Operation: public CHeapObj {
--- a/hotspot/src/share/vm/services/diagnosticArgument.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/services/diagnosticArgument.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -59,12 +59,13 @@
template <> void DCmdArgument<bool>::parse_value(const char* str,
size_t len, TRAPS) {
+ // len is the length of the current token starting at str
if (len == 0) {
set_value(true);
} else {
- if (strcasecmp(str, "true") == 0) {
+ if (len == strlen("true") && strncasecmp(str, "true", len) == 0) {
set_value(true);
- } else if (strcasecmp(str, "false") == 0) {
+ } else if (len == strlen("false") && strncasecmp(str, "false", len) == 0) {
set_value(false);
} else {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -31,6 +31,33 @@
#include "services/heapDumper.hpp"
#include "services/management.hpp"
+void DCmdRegistrant::register_dcmds(){
+ // Registration of the diagnostic commands
+ // First boolean argument specifies if the command is enabled
+ // Second boolean argument specifies if the command is hidden
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HelpDCmd>(true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VersionDCmd>(true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CommandLineDCmd>(true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintSystemPropertiesDCmd>(true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintVMFlagsDCmd>(true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMUptimeDCmd>(true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SystemGCDCmd>(true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RunFinalizationDCmd>(true, false));
+#ifndef SERVICES_KERNEL // Heap dumping not supported
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapDumpDCmd>(true, false));
+#endif // SERVICES_KERNEL
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHistogramDCmd>(true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(true, false));
+
+}
+
+#ifndef HAVE_EXTRA_DCMD
+void DCmdRegistrant::register_dcmds_ext(){
+ // Do nothing here
+}
+#endif
+
+
HelpDCmd::HelpDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap),
_all("-all", "Show help for all commands", "BOOLEAN", false, "false"),
_cmd("command name", "The name of the command for which we want help",
--- a/hotspot/src/share/vm/services/diagnosticCommand.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/services/diagnosticCommand.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -34,6 +34,7 @@
#include "services/diagnosticArgument.hpp"
#include "services/diagnosticCommand.hpp"
#include "services/diagnosticFramework.hpp"
+#include "services/diagnosticCommand_ext.hpp"
class HelpDCmd : public DCmdWithParser {
protected:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/services/diagnosticCommand_ext.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 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.
+ *
+ */
+
+#ifndef SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_EXT_HPP
+#define SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_EXT_HPP
+
+#undef HAVE_EXTRA_DCMD
+
+#endif // SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP
--- a/hotspot/src/share/vm/services/diagnosticFramework.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/services/diagnosticFramework.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -387,4 +387,17 @@
}
};
+// This class provides a convenient way to register Dcmds, without a need to change
+// management.cpp every time. Body of these two methods resides in
+// diagnosticCommand.cpp
+
+class DCmdRegistrant : public AllStatic {
+
+private:
+ static void register_dcmds();
+ static void register_dcmds_ext();
+
+ friend class Management;
+};
+
#endif // SHARE_VM_SERVICES_DIAGNOSTICFRAMEWORK_HPP
--- a/hotspot/src/share/vm/services/g1MemoryPool.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/services/g1MemoryPool.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -78,7 +78,7 @@
G1MemoryPoolSuper(g1h,
"G1 Old Gen",
g1h->g1mm()->old_space_committed(), /* init_size */
- _undefined_max,
+ g1h->g1mm()->old_gen_max(),
true /* support_usage_threshold */) { }
MemoryUsage G1OldGenPool::get_memory_usage() {
--- a/hotspot/src/share/vm/services/g1MemoryPool.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/services/g1MemoryPool.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -101,7 +101,7 @@
return _g1mm->old_space_used();
}
size_t max_size() const {
- return _undefined_max;
+ return _g1mm->old_gen_max();
}
MemoryUsage get_memory_usage();
};
--- a/hotspot/src/share/vm/services/gcNotifier.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/services/gcNotifier.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -44,7 +44,8 @@
// Make a copy of the last GC statistics
// GC may occur between now and the creation of the notification
int num_pools = MemoryService::num_memory_pools();
- GCStatInfo* stat = new GCStatInfo(num_pools);
+ // stat is deallocated inside GCNotificationRequest
+ GCStatInfo* stat = new(ResourceObj::C_HEAP) GCStatInfo(num_pools);
mgr->get_last_gc_stat(stat);
GCNotificationRequest *request = new GCNotificationRequest(os::javaTimeMillis(),mgr,action,cause,stat);
addRequest(request);
--- a/hotspot/src/share/vm/services/management.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/services/management.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -119,21 +119,8 @@
_optional_support.isThreadAllocatedMemorySupported = 1;
// Registration of the diagnostic commands
- // First boolean argument specifies if the command is enabled
- // Second boolean argument specifies if the command is hidden
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HelpDCmd>(true, false));
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VersionDCmd>(true, false));
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CommandLineDCmd>(true, false));
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintSystemPropertiesDCmd>(true, false));
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintVMFlagsDCmd>(true, false));
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMUptimeDCmd>(true, false));
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SystemGCDCmd>(true, false));
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RunFinalizationDCmd>(true, false));
-#ifndef SERVICES_KERNEL // Heap dumping not supported
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapDumpDCmd>(true, false));
-#endif // SERVICES_KERNEL
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHistogramDCmd>(true, false));
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(true, false));
+ DCmdRegistrant::register_dcmds();
+ DCmdRegistrant::register_dcmds_ext();
}
void Management::initialize(TRAPS) {
@@ -2047,15 +2034,15 @@
// Make a copy of the last GC statistics
// GC may occur while constructing the last GC information
int num_pools = MemoryService::num_memory_pools();
- GCStatInfo* stat = new GCStatInfo(num_pools);
- if (mgr->get_last_gc_stat(stat) == 0) {
+ GCStatInfo stat(num_pools);
+ if (mgr->get_last_gc_stat(&stat) == 0) {
gc_stat->gc_index = 0;
return;
}
- gc_stat->gc_index = stat->gc_index();
- gc_stat->start_time = Management::ticks_to_ms(stat->start_time());
- gc_stat->end_time = Management::ticks_to_ms(stat->end_time());
+ gc_stat->gc_index = stat.gc_index();
+ gc_stat->start_time = Management::ticks_to_ms(stat.start_time());
+ gc_stat->end_time = Management::ticks_to_ms(stat.end_time());
// Current implementation does not have GC extension attributes
gc_stat->num_gc_ext_attributes = 0;
@@ -2073,17 +2060,17 @@
objArrayHandle usage_after_gc_ah(THREAD, au);
for (int i = 0; i < num_pools; i++) {
- Handle before_usage = MemoryService::create_MemoryUsage_obj(stat->before_gc_usage_for_pool(i), CHECK);
+ Handle before_usage = MemoryService::create_MemoryUsage_obj(stat.before_gc_usage_for_pool(i), CHECK);
Handle after_usage;
- MemoryUsage u = stat->after_gc_usage_for_pool(i);
+ MemoryUsage u = stat.after_gc_usage_for_pool(i);
if (u.max_size() == 0 && u.used() > 0) {
// If max size == 0, this pool is a survivor space.
// Set max size = -1 since the pools will be swapped after GC.
MemoryUsage usage(u.init_size(), u.used(), u.committed(), (size_t)-1);
after_usage = MemoryService::create_MemoryUsage_obj(usage, CHECK);
} else {
- after_usage = MemoryService::create_MemoryUsage_obj(stat->after_gc_usage_for_pool(i), CHECK);
+ after_usage = MemoryService::create_MemoryUsage_obj(stat.after_gc_usage_for_pool(i), CHECK);
}
usage_before_gc_ah->obj_at_put(i, before_usage());
usage_after_gc_ah->obj_at_put(i, after_usage());
--- a/hotspot/src/share/vm/services/memoryManager.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/services/memoryManager.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -214,8 +214,8 @@
void GCMemoryManager::initialize_gc_stat_info() {
assert(MemoryService::num_memory_pools() > 0, "should have one or more memory pools");
- _last_gc_stat = new GCStatInfo(MemoryService::num_memory_pools());
- _current_gc_stat = new GCStatInfo(MemoryService::num_memory_pools());
+ _last_gc_stat = new(ResourceObj::C_HEAP) GCStatInfo(MemoryService::num_memory_pools());
+ _current_gc_stat = new(ResourceObj::C_HEAP) GCStatInfo(MemoryService::num_memory_pools());
// tracking concurrent collections we need two objects: one to update, and one to
// hold the publicly available "last (completed) gc" information.
}
--- a/hotspot/src/share/vm/services/memoryManager.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/services/memoryManager.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -108,7 +108,7 @@
const char* name() { return "CodeCacheManager"; }
};
-class GCStatInfo : public CHeapObj {
+class GCStatInfo : public ResourceObj {
private:
size_t _index;
jlong _start_time;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/trace/traceEventTypes.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 1997, 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.
+ *
+ */
+
+#ifndef SHARE_VM_TRACE_TRACE_EVENT_TYPES_HPP
+#define SHARE_VM_TRACE_TRACE_EVENT_TYPES_HPP
+
+/* Empty, just a placeholder for tracing events */
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/trace/traceMacros.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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_TRACE_TRACE_MACRO_HPP
+#define SHARE_VM_TRACE_TRACE_MACRO_HPP
+
+#define EVENT_BEGIN(type, name)
+#define EVENT_SET(name, field, value)
+#define EVENT_COMMIT(name, ...)
+#define EVENT_STARTED(name, time)
+#define EVENT_ENDED(name, time)
+#define EVENT_THREAD_EXIT(thread)
+
+#define TRACE_ENABLED 0
+
+#define TRACE_INIT_ID(k)
+#define TRACE_BUFFER void*
+
+#define TRACE_START() true
+#define TRACE_INITIALIZE() 0
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/trace/tracing.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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_TRACE_TRACING_HPP
+#define SHARE_VM_TRACE_TRACING_HPP
+
+#include "trace/traceMacros.hpp"
+
+#endif
--- a/hotspot/src/share/vm/utilities/bitMap.inline.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/utilities/bitMap.inline.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -178,8 +178,30 @@
for (; !(res & 1); res_offset++) {
res = res >> 1;
}
- assert(res_offset >= l_offset &&
- res_offset < r_offset, "just checking");
+
+#ifdef ASSERT
+ // In the following assert, if r_offset is not bitamp word aligned,
+ // checking that res_offset is strictly less than r_offset is too
+ // strong and will trip the assert.
+ //
+ // Consider the case where l_offset is bit 15 and r_offset is bit 17
+ // of the same map word, and where bits [15:16:17:18] == [00:00:00:01].
+ // All the bits in the range [l_offset:r_offset) are 0.
+ // The loop that calculates res_offset, above, would yield the offset
+ // of bit 18 because it's in the same map word as l_offset and there
+ // is a set bit in that map word above l_offset (i.e. res != NoBits).
+ //
+ // In this case, however, we can assert is that res_offset is strictly
+ // less than size() since we know that there is at least one set bit
+ // at an offset above, but in the same map word as, r_offset.
+ // Otherwise, if r_offset is word aligned then it will not be in the
+ // same map word as l_offset (unless it equals l_offset). So either
+ // there won't be a set bit between l_offset and the end of it's map
+ // word (i.e. res == NoBits), or res_offset will be less than r_offset.
+
+ idx_t limit = is_word_aligned(r_offset) ? r_offset : size();
+ assert(res_offset >= l_offset && res_offset < limit, "just checking");
+#endif // ASSERT
return MIN2(res_offset, r_offset);
}
// skip over all word length 0-bit runs
--- a/hotspot/src/share/vm/utilities/decoder.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/utilities/decoder.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -24,80 +24,85 @@
#include "precompiled.hpp"
#include "prims/jvm.h"
+#include "runtime/mutexLocker.hpp"
#include "utilities/decoder.hpp"
-Decoder::decoder_status Decoder::_decoder_status = Decoder::no_error;
-bool Decoder::_initialized = false;
-
-#if !defined(_WINDOWS) && !defined(__APPLE__)
-
-// Implementation of common functionalities among Solaris and Linux
-#include "utilities/elfFile.hpp"
-
-ElfFile* Decoder::_opened_elf_files = NULL;
-
-bool Decoder::can_decode_C_frame_in_vm() {
- return true;
-}
+#if defined(_WINDOWS)
+ #include "decoder_windows.hpp"
+#elif defined(__APPLE__)
+ #include "decoder_machO.hpp"
+#else
+ #include "decoder_elf.hpp"
+#endif
-void Decoder::initialize() {
- _initialized = true;
-}
+NullDecoder* Decoder::_decoder = NULL;
+NullDecoder Decoder::_do_nothing_decoder;
+Mutex* Decoder::_decoder_lock = new Mutex(Mutex::safepoint,
+ "DecoderLock");
-void Decoder::uninitialize() {
- if (_opened_elf_files != NULL) {
- delete _opened_elf_files;
- _opened_elf_files = NULL;
- }
- _initialized = false;
-}
+// _decoder_lock should already acquired before enter this method
+NullDecoder* Decoder::get_decoder() {
+ assert(_decoder_lock != NULL && _decoder_lock->owned_by_self(),
+ "Require DecoderLock to enter");
-Decoder::decoder_status Decoder::decode(address addr, const char* filepath, char *buf, int buflen, int *offset) {
- if (_decoder_status != no_error) {
- return _decoder_status;
- }
-
- ElfFile* file = get_elf_file(filepath);
- if (_decoder_status != no_error) {
- return _decoder_status;
+ if (_decoder != NULL) {
+ return _decoder;
}
- const char* symbol = file->decode(addr, offset);
- if (file->get_status() == out_of_memory) {
- _decoder_status = out_of_memory;
- return _decoder_status;
- } else if (symbol != NULL) {
- if (!demangle(symbol, buf, buflen)) {
- jio_snprintf(buf, buflen, "%s", symbol);
+ // Decoder is a secondary service. Although, it is good to have,
+ // but we can live without it.
+#if defined(_WINDOWS)
+ _decoder = new (std::nothrow) WindowsDecoder();
+#elif defined (__APPLE__)
+ _decoder = new (std::nothrow)MachODecoder();
+#else
+ _decoder = new (std::nothrow)ElfDecoder();
+#endif
+
+ if (_decoder == NULL || _decoder->has_error()) {
+ if (_decoder != NULL) {
+ delete _decoder;
}
- return no_error;
- } else {
- return symbol_not_found;
+ _decoder = &_do_nothing_decoder;
}
+ return _decoder;
+}
+
+bool Decoder::decode(address addr, char* buf, int buflen, int* offset, const char* modulepath) {
+ assert(_decoder_lock != NULL, "Just check");
+ MutexLockerEx locker(_decoder_lock, true);
+ NullDecoder* decoder = get_decoder();
+ assert(decoder != NULL, "null decoder");
+
+ return decoder->decode(addr, buf, buflen, offset, modulepath);
}
-ElfFile* Decoder::get_elf_file(const char* filepath) {
- if (_decoder_status != no_error) {
- return NULL;
- }
- ElfFile* file = _opened_elf_files;
- while (file != NULL) {
- if (file->same_elf_file(filepath)) {
- return file;
- }
- file = file->m_next;
+bool Decoder::demangle(const char* symbol, char* buf, int buflen) {
+ assert(_decoder_lock != NULL, "Just check");
+ MutexLockerEx locker(_decoder_lock, true);
+ NullDecoder* decoder = get_decoder();
+ assert(decoder != NULL, "null decoder");
+ return decoder->demangle(symbol, buf, buflen);
+}
+
+bool Decoder::can_decode_C_frame_in_vm() {
+ assert(_decoder_lock != NULL, "Just check");
+ MutexLockerEx locker(_decoder_lock, true);
+ NullDecoder* decoder = get_decoder();
+ assert(decoder != NULL, "null decoder");
+ return decoder->can_decode_C_frame_in_vm();
+}
+
+// shutdown real decoder and replace it with
+// _do_nothing_decoder
+void Decoder::shutdown() {
+ assert(_decoder_lock != NULL, "Just check");
+ MutexLockerEx locker(_decoder_lock, true);
+
+ if (_decoder != NULL && _decoder != &_do_nothing_decoder) {
+ delete _decoder;
}
- file = new ElfFile(filepath);
- if (file == NULL) {
- _decoder_status = out_of_memory;
- }
- if (_opened_elf_files != NULL) {
- file->m_next = _opened_elf_files;
- }
-
- _opened_elf_files = file;
- return file;
+ _decoder = &_do_nothing_decoder;
}
-#endif
--- a/hotspot/src/share/vm/utilities/decoder.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/utilities/decoder.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,83 +23,78 @@
*/
-#ifndef __DECODER_HPP
-#define __DECODER_HPP
+#ifndef SHARE_VM_UTILITIES_DECODER_HPP
+#define SHARE_VM_UTILITIES_DECODER_HPP
#include "memory/allocation.hpp"
-
-#ifdef _WINDOWS
-#include <windows.h>
-#include <imagehlp.h>
-
-// functions needed for decoding symbols
-typedef DWORD (WINAPI *pfn_SymSetOptions)(DWORD);
-typedef BOOL (WINAPI *pfn_SymInitialize)(HANDLE, PCTSTR, BOOL);
-typedef BOOL (WINAPI *pfn_SymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64);
-typedef DWORD (WINAPI *pfn_UndecorateSymbolName)(const char*, char*, DWORD, DWORD);
+#include "runtime/mutex.hpp"
-#elif defined(__APPLE__)
-
-#else
-
-class ElfFile;
-
-#endif // _WINDOWS
-
-
-class Decoder: public StackObj {
-
- public:
+class NullDecoder: public CHeapObj {
+public:
// status code for decoding native C frame
enum decoder_status {
- no_error, // successfully decoded frames
+ not_available = -10, // real decoder is not available
+ no_error = 0, // successfully decoded frames
out_of_memory, // out of memory
file_invalid, // invalid elf file
file_not_found, // could not found symbol file (on windows), such as jvm.pdb or jvm.map
helper_not_found, // could not load dbghelp.dll (Windows only)
helper_func_error, // decoding functions not found (Windows only)
- helper_init_error, // SymInitialize failed (Windows only)
- symbol_not_found // could not find the symbol
+ helper_init_error // SymInitialize failed (Windows only)
};
- public:
- Decoder() { initialize(); };
- ~Decoder() { uninitialize(); };
+ NullDecoder() {
+ _decoder_status = not_available;
+ }
+
+ ~NullDecoder() {};
+
+ virtual bool decode(address pc, char* buf, int buflen, int* offset,
+ const char* modulepath = NULL) {
+ return false;
+ }
+
+ virtual bool demangle(const char* symbol, char* buf, int buflen) {
+ return false;
+ }
+
+ virtual bool can_decode_C_frame_in_vm() const {
+ return false;
+ }
+ virtual decoder_status status() const {
+ return _decoder_status;
+ }
+
+ virtual bool has_error() const {
+ return is_error(_decoder_status);
+ }
+
+ static bool is_error(decoder_status status) {
+ return (status > 0);
+ }
+
+protected:
+ decoder_status _decoder_status;
+};
+
+
+class Decoder: AllStatic {
+public:
+ static bool decode(address pc, char* buf, int buflen, int* offset, const char* modulepath = NULL);
+ static bool demangle(const char* symbol, char* buf, int buflen);
static bool can_decode_C_frame_in_vm();
- static void initialize();
- static void uninitialize();
-
-#ifdef _WINDOWS
- static decoder_status decode(address addr, char *buf, int buflen, int *offset);
-#else
- static decoder_status decode(address addr, const char* filepath, char *buf, int buflen, int *offset);
-#endif
-
- static bool demangle(const char* symbol, char *buf, int buflen);
-
- static decoder_status get_status() { return _decoder_status; };
+ static void shutdown();
+protected:
+ static NullDecoder* get_decoder();
-#if !defined(_WINDOWS) && !defined(__APPLE__)
- private:
- static ElfFile* get_elf_file(const char* filepath);
-#endif // _WINDOWS
-
-
- private:
- static decoder_status _decoder_status;
- static bool _initialized;
+private:
+ static NullDecoder* _decoder;
+ static NullDecoder _do_nothing_decoder;
-#ifdef _WINDOWS
- static HMODULE _dbghelp_handle;
- static bool _can_decode_in_vm;
- static pfn_SymGetSymFromAddr64 _pfnSymGetSymFromAddr64;
- static pfn_UndecorateSymbolName _pfnUndecorateSymbolName;
-#elif __APPLE__
-#else
- static ElfFile* _opened_elf_files;
-#endif // _WINDOWS
+protected:
+ static Mutex* _decoder_lock;
};
-#endif // __DECODER_HPP
+#endif // SHARE_VM_UTILITIES_DECODER_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/utilities/decoder_elf.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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"
+
+#if !defined(_WINDOWS) && !defined(__APPLE__)
+#include "decoder_elf.hpp"
+
+ElfDecoder::~ElfDecoder() {
+ if (_opened_elf_files != NULL) {
+ delete _opened_elf_files;
+ _opened_elf_files = NULL;
+ }
+}
+
+bool ElfDecoder::decode(address addr, char *buf, int buflen, int* offset, const char* filepath) {
+ assert(filepath, "null file path");
+ assert(buf != NULL && buflen > 0, "Invalid buffer");
+ if (has_error()) return false;
+ ElfFile* file = get_elf_file(filepath);
+ if (file == NULL) {
+ return false;
+ }
+
+ if (!file->decode(addr, buf, buflen, offset)) {
+ return false;
+ }
+ if (buf[0] != '\0') {
+ demangle(buf, buf, buflen);
+ }
+ return true;
+}
+
+ElfFile* ElfDecoder::get_elf_file(const char* filepath) {
+ ElfFile* file;
+
+ file = _opened_elf_files;
+ while (file != NULL) {
+ if (file->same_elf_file(filepath)) {
+ return file;
+ }
+ file = file->next();
+ }
+
+ file = new (std::nothrow)ElfFile(filepath);
+ if (file != NULL) {
+ if (_opened_elf_files != NULL) {
+ file->set_next(_opened_elf_files);
+ }
+ _opened_elf_files = file;
+ }
+
+ return file;
+}
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/utilities/decoder_elf.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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_UTILITIES_DECODER_ELF_HPP
+#define SHARE_VM_UTILITIES_DECODER_ELF_HPP
+
+#if !defined(_WINDOWS) && !defined(__APPLE__)
+
+#include "utilities/decoder.hpp"
+#include "utilities/elfFile.hpp"
+
+class ElfDecoder: public NullDecoder {
+
+public:
+ ElfDecoder() {
+ _opened_elf_files = NULL;
+ _decoder_status = no_error;
+ }
+ ~ElfDecoder();
+
+ bool can_decode_C_frame_in_vm() const { return true; }
+
+ bool demangle(const char* symbol, char *buf, int buflen);
+ bool decode(address addr, char *buf, int buflen, int* offset, const char* filepath = NULL);
+
+private:
+ ElfFile* get_elf_file(const char* filepath);
+
+private:
+ ElfFile* _opened_elf_files;
+};
+
+#endif
+#endif // SHARE_VM_UTILITIES_DECODER_ELF_HPP
--- a/hotspot/src/share/vm/utilities/elfFile.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/utilities/elfFile.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -44,7 +44,7 @@
m_string_tables = NULL;
m_symbol_tables = NULL;
m_next = NULL;
- m_status = Decoder::no_error;
+ m_status = NullDecoder::no_error;
int len = strlen(filepath) + 1;
m_filepath = (const char*)os::malloc(len * sizeof(char));
@@ -54,10 +54,10 @@
if (m_file != NULL) {
load_tables();
} else {
- m_status = Decoder::file_not_found;
+ m_status = NullDecoder::file_not_found;
}
} else {
- m_status = Decoder::out_of_memory;
+ m_status = NullDecoder::out_of_memory;
}
}
@@ -96,41 +96,41 @@
bool ElfFile::load_tables() {
assert(m_file, "file not open");
- assert(m_status == Decoder::no_error, "already in error");
+ assert(!NullDecoder::is_error(m_status), "already in error");
// read elf file header
if (fread(&m_elfHdr, sizeof(m_elfHdr), 1, m_file) != 1) {
- m_status = Decoder::file_invalid;
+ m_status = NullDecoder::file_invalid;
return false;
}
if (!is_elf_file(m_elfHdr)) {
- m_status = Decoder::file_invalid;
+ m_status = NullDecoder::file_invalid;
return false;
}
// walk elf file's section headers, and load string tables
Elf_Shdr shdr;
if (!fseek(m_file, m_elfHdr.e_shoff, SEEK_SET)) {
- if (m_status != Decoder::no_error) return false;
+ if (NullDecoder::is_error(m_status)) return false;
for (int index = 0; index < m_elfHdr.e_shnum; index ++) {
if (fread((void*)&shdr, sizeof(Elf_Shdr), 1, m_file) != 1) {
- m_status = Decoder::file_invalid;
+ m_status = NullDecoder::file_invalid;
return false;
}
// string table
if (shdr.sh_type == SHT_STRTAB) {
ElfStringTable* table = new (std::nothrow) ElfStringTable(m_file, shdr, index);
if (table == NULL) {
- m_status = Decoder::out_of_memory;
+ m_status = NullDecoder::out_of_memory;
return false;
}
add_string_table(table);
} else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) {
ElfSymbolTable* table = new (std::nothrow) ElfSymbolTable(m_file, shdr);
if (table == NULL) {
- m_status = Decoder::out_of_memory;
+ m_status = NullDecoder::out_of_memory;
return false;
}
add_symbol_table(table);
@@ -140,32 +140,33 @@
return true;
}
-const char* ElfFile::decode(address addr, int* offset) {
+bool ElfFile::decode(address addr, char* buf, int buflen, int* offset) {
// something already went wrong, just give up
- if (m_status != Decoder::no_error) {
- return NULL;
+ if (NullDecoder::is_error(m_status)) {
+ return false;
}
-
ElfSymbolTable* symbol_table = m_symbol_tables;
int string_table_index;
int pos_in_string_table;
int off = INT_MAX;
bool found_symbol = false;
while (symbol_table != NULL) {
- if (Decoder::no_error == symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off)) {
+ if (symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off)) {
found_symbol = true;
}
symbol_table = symbol_table->m_next;
}
- if (!found_symbol) return NULL;
+ if (!found_symbol) return false;
ElfStringTable* string_table = get_string_table(string_table_index);
+
if (string_table == NULL) {
- m_status = Decoder::file_invalid;
- return NULL;
+ m_status = NullDecoder::file_invalid;
+ return false;
}
if (offset) *offset = off;
- return string_table->string_at(pos_in_string_table);
+
+ return string_table->string_at(pos_in_string_table, buf, buflen);
}
--- a/hotspot/src/share/vm/utilities/elfFile.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/utilities/elfFile.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,8 +22,8 @@
*
*/
-#ifndef __ELF_FILE_HPP
-#define __ELF_FILE_HPP
+#ifndef SHARE_VM_UTILITIES_ELF_FILE_HPP
+#define SHARE_VM_UTILITIES_ELF_FILE_HPP
#if !defined(_WINDOWS) && !defined(__APPLE__)
@@ -83,12 +83,12 @@
// part of code to be very defensive, and bait out if anything went wrong.
class ElfFile: public CHeapObj {
- friend class Decoder;
+ friend class ElfDecoder;
public:
ElfFile(const char* filepath);
~ElfFile();
- const char* decode(address addr, int* offset);
+ bool decode(address addr, char* buf, int buflen, int* offset);
const char* filepath() {
return m_filepath;
}
@@ -99,7 +99,7 @@
return (m_filepath && !strcmp(filepath, m_filepath));
}
- Decoder::decoder_status get_status() {
+ NullDecoder::decoder_status get_status() {
return m_status;
}
@@ -119,8 +119,9 @@
// return a string table at specified section index
ElfStringTable* get_string_table(int index);
- // look up an address and return the nearest symbol
- const char* look_up(Elf_Shdr shdr, address addr, int* offset);
+protected:
+ ElfFile* next() const { return m_next; }
+ void set_next(ElfFile* file) { m_next = file; }
protected:
ElfFile* m_next;
@@ -131,17 +132,17 @@
FILE* m_file;
// Elf header
- Elf_Ehdr m_elfHdr;
+ Elf_Ehdr m_elfHdr;
// symbol tables
- ElfSymbolTable* m_symbol_tables;
+ ElfSymbolTable* m_symbol_tables;
// string tables
- ElfStringTable* m_string_tables;
+ ElfStringTable* m_string_tables;
- Decoder::decoder_status m_status;
+ NullDecoder::decoder_status m_status;
};
#endif // _WINDOWS
-#endif // __ELF_FILE_HPP
+#endif // SHARE_VM_UTILITIES_ELF_FILE_HPP
--- a/hotspot/src/share/vm/utilities/elfStringTable.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/utilities/elfStringTable.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -38,7 +38,7 @@
m_index = index;
m_next = NULL;
m_file = file;
- m_status = Decoder::no_error;
+ m_status = NullDecoder::no_error;
// try to load the string table
long cur_offset = ftell(file);
@@ -48,7 +48,7 @@
if (fseek(file, shdr.sh_offset, SEEK_SET) ||
fread((void*)m_table, shdr.sh_size, 1, file) != 1 ||
fseek(file, cur_offset, SEEK_SET)) {
- m_status = Decoder::file_invalid;
+ m_status = NullDecoder::file_invalid;
os::free((void*)m_table);
m_table = NULL;
}
@@ -67,22 +67,23 @@
}
}
-const char* ElfStringTable::string_at(int pos) {
- if (m_status != Decoder::no_error) {
- return NULL;
+bool ElfStringTable::string_at(int pos, char* buf, int buflen) {
+ if (NullDecoder::is_error(m_status)) {
+ return false;
}
if (m_table != NULL) {
- return (const char*)(m_table + pos);
+ jio_snprintf(buf, buflen, "%s", (const char*)(m_table + pos));
+ return true;
} else {
long cur_pos = ftell(m_file);
if (cur_pos == -1 ||
fseek(m_file, m_shdr.sh_offset + pos, SEEK_SET) ||
- fread(m_symbol, 1, MAX_SYMBOL_LEN, m_file) <= 0 ||
+ fread(buf, 1, buflen, m_file) <= 0 ||
fseek(m_file, cur_pos, SEEK_SET)) {
- m_status = Decoder::file_invalid;
- return NULL;
+ m_status = NullDecoder::file_invalid;
+ return false;
}
- return (const char*)m_symbol;
+ return true;
}
}
--- a/hotspot/src/share/vm/utilities/elfStringTable.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/utilities/elfStringTable.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,8 +22,8 @@
*
*/
-#ifndef __ELF_STRING_TABLE_HPP
-#define __ELF_STRING_TABLE_HPP
+#ifndef SHARE_VM_UTILITIES_ELF_STRING_TABLE_HPP
+#define SHARE_VM_UTILITIES_ELF_STRING_TABLE_HPP
#if !defined(_WINDOWS) && !defined(__APPLE__)
@@ -35,9 +35,6 @@
// The string table represents a string table section in an elf file.
// Whenever there is enough memory, it will load whole string table as
// one blob. Otherwise, it will load string from file when requested.
-
-#define MAX_SYMBOL_LEN 256
-
class ElfStringTable: CHeapObj {
friend class ElfFile;
public:
@@ -48,10 +45,10 @@
int index() { return m_index; };
// get string at specified offset
- const char* string_at(int offset);
+ bool string_at(int offset, char* buf, int buflen);
// get status code
- Decoder::decoder_status get_status() { return m_status; };
+ NullDecoder::decoder_status get_status() { return m_status; };
protected:
ElfStringTable* m_next;
@@ -69,13 +66,10 @@
// section header
Elf_Shdr m_shdr;
- // buffer for reading individual string
- char m_symbol[MAX_SYMBOL_LEN];
-
// error code
- Decoder::decoder_status m_status;
+ NullDecoder::decoder_status m_status;
};
-#endif // _WINDOWS
+#endif // _WINDOWS and _APPLE
-#endif // __ELF_STRING_TABLE_HPP
+#endif // SHARE_VM_UTILITIES_ELF_STRING_TABLE_HPP
--- a/hotspot/src/share/vm/utilities/elfSymbolTable.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/utilities/elfSymbolTable.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -34,7 +34,7 @@
m_symbols = NULL;
m_next = NULL;
m_file = file;
- m_status = Decoder::no_error;
+ m_status = NullDecoder::no_error;
// try to load the string table
long cur_offset = ftell(file);
@@ -45,16 +45,16 @@
if (fseek(file, shdr.sh_offset, SEEK_SET) ||
fread((void*)m_symbols, shdr.sh_size, 1, file) != 1 ||
fseek(file, cur_offset, SEEK_SET)) {
- m_status = Decoder::file_invalid;
+ m_status = NullDecoder::file_invalid;
os::free(m_symbols);
m_symbols = NULL;
}
}
- if (m_status == Decoder::no_error) {
+ if (!NullDecoder::is_error(m_status)) {
memcpy(&m_shdr, &shdr, sizeof(Elf_Shdr));
}
} else {
- m_status = Decoder::file_invalid;
+ m_status = NullDecoder::file_invalid;
}
}
@@ -68,13 +68,13 @@
}
}
-Decoder::decoder_status ElfSymbolTable::lookup(address addr, int* stringtableIndex, int* posIndex, int* offset) {
+bool ElfSymbolTable::lookup(address addr, int* stringtableIndex, int* posIndex, int* offset) {
assert(stringtableIndex, "null string table index pointer");
assert(posIndex, "null string table offset pointer");
assert(offset, "null offset pointer");
- if (m_status != Decoder::no_error) {
- return m_status;
+ if (NullDecoder::is_error(m_status)) {
+ return false;
}
address pc = 0;
@@ -97,8 +97,8 @@
long cur_pos;
if ((cur_pos = ftell(m_file)) == -1 ||
fseek(m_file, m_shdr.sh_offset, SEEK_SET)) {
- m_status = Decoder::file_invalid;
- return m_status;
+ m_status = NullDecoder::file_invalid;
+ return false;
}
Elf_Sym sym;
@@ -114,13 +114,13 @@
}
}
} else {
- m_status = Decoder::file_invalid;
- return m_status;
+ m_status = NullDecoder::file_invalid;
+ return false;
}
}
fseek(m_file, cur_pos, SEEK_SET);
}
- return m_status;
+ return true;
}
#endif // _WINDOWS
--- a/hotspot/src/share/vm/utilities/elfSymbolTable.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/utilities/elfSymbolTable.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,8 +22,8 @@
*
*/
-#ifndef __ELF_SYMBOL_TABLE_HPP
-#define __ELF_SYMBOL_TABLE_HPP
+#ifndef SHARE_VM_UTILITIES_ELF_SYMBOL_TABLE_HPP
+#define SHARE_VM_UTILITIES_ELF_SYMBOL_TABLE_HPP
#if !defined(_WINDOWS) && !defined(__APPLE__)
@@ -45,9 +45,9 @@
~ElfSymbolTable();
// search the symbol that is nearest to the specified address.
- Decoder::decoder_status lookup(address addr, int* stringtableIndex, int* posIndex, int* offset);
+ bool lookup(address addr, int* stringtableIndex, int* posIndex, int* offset);
- Decoder::decoder_status get_status() { return m_status; };
+ NullDecoder::decoder_status get_status() { return m_status; };
protected:
ElfSymbolTable* m_next;
@@ -62,9 +62,9 @@
// section header
Elf_Shdr m_shdr;
- Decoder::decoder_status m_status;
+ NullDecoder::decoder_status m_status;
};
-#endif // _WINDOWS
+#endif // _WINDOWS and _APPLE
-#endif // __ELF_SYMBOL_TABLE_HPP
+#endif // SHARE_VM_UTILITIES_ELF_SYMBOL_TABLE_HPP
--- a/hotspot/src/share/vm/utilities/exceptions.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/utilities/exceptions.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -189,6 +189,13 @@
#define CHECK_NULL CHECK_(NULL)
#define CHECK_false CHECK_(false)
+#define CHECK_AND_CLEAR THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; return; } (0
+#define CHECK_AND_CLEAR_(result) THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; return result; } (0
+#define CHECK_AND_CLEAR_0 CHECK_AND_CLEAR_(0)
+#define CHECK_AND_CLEAR_NH CHECK_AND_CLEAR_(Handle())
+#define CHECK_AND_CLEAR_NULL CHECK_AND_CLEAR_(NULL)
+#define CHECK_AND_CLEAR_false CHECK_AND_CLEAR_(false)
+
// The THROW... macros should be used to throw an exception. They require a THREAD variable to be
// visible within the scope containing the THROW. Usually this is achieved by declaring the function
// with a TRAPS argument.
@@ -258,7 +265,6 @@
ShouldNotReachHere(); \
} (0
-
// ExceptionMark is a stack-allocated helper class for local exception handling.
// It is used with the EXCEPTION_MARK macro.
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -298,6 +298,11 @@
const juint max_juint = (juint)-1; // 0xFFFFFFFF largest juint
const julong max_julong = (julong)-1; // 0xFF....FF largest julong
+typedef jbyte s1;
+typedef jshort s2;
+typedef jint s4;
+typedef jlong s8;
+
//----------------------------------------------------------------------------------------------------
// JVM spec restrictions
--- a/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp Sat Jan 28 22:21:54 2012 -0800
@@ -130,6 +130,9 @@
//----------------------------------------------------------------------------------------------------
// Non-standard stdlib-like stuff:
inline int strcasecmp(const char *s1, const char *s2) { return _stricmp(s1,s2); }
+inline int strncasecmp(const char *s1, const char *s2, size_t n) {
+ return _strnicmp(s1,s2,n);
+}
//----------------------------------------------------------------------------------------------------
--- a/hotspot/src/share/vm/utilities/vmError.cpp Fri Jan 27 13:48:40 2012 +0000
+++ b/hotspot/src/share/vm/utilities/vmError.cpp Sat Jan 28 22:21:54 2012 -0800
@@ -571,8 +571,6 @@
if (fr.pc()) {
st->print_cr("Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)");
- // initialize decoder to decode C frames
- Decoder decoder;
int count = 0;
while (count++ < StackPrintLimit) {
--- a/jaxp/.hgtags Fri Jan 27 13:48:40 2012 +0000
+++ b/jaxp/.hgtags Sat Jan 28 22:21:54 2012 -0800
@@ -143,3 +143,5 @@
dffeb62b1a7fc8b316bf58fe5479323f3661894e jdk8-b19
f052abb8f37444ba77858913887d0d92795dd6b8 jdk8-b20
d41eeadf5c1344b88c5051a997aec9e1ad7ce1db jdk8-b21
+cf9d6ec44f891236ad18451021d6dcd57dc82f7b jdk8-b22
+95102fd334183d15dc98a95dd0d749527b6c7300 jdk8-b23
--- a/jaxws/.hgtags Fri Jan 27 13:48:40 2012 +0000
+++ b/jaxws/.hgtags Sat Jan 28 22:21:54 2012 -0800
@@ -143,3 +143,5 @@
b73b733214aa43648d69a2da51e6b48fda902a2d jdk8-b19
2b2818e3386f4510c390f6aea90d77e1c6a5bf9e jdk8-b20
c266cab0e3fff05f2048c23046c14d60f7102175 jdk8-b21
+8d3df89b0f2d3c603b2edb0f5e24af1245397cc6 jdk8-b22
+25ce7a0004874273f6aeda14e7c3538cba34bdf1 jdk8-b23
--- a/jdk/.hgtags Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/.hgtags Sat Jan 28 22:21:54 2012 -0800
@@ -143,3 +143,5 @@
3778f85773055e81eab6c5ef828935ecca241810 jdk8-b19
39e938cd1b82ec3aab0a9aa66fd8a0457cd0c9c2 jdk8-b20
664fa4fb0ee411ef048903c479f8b962fcdb2f4b jdk8-b21
+dda27c73d8db4a9c7a23872b6f0c5106edcb2021 jdk8-b22
+54202e0148ec7d4570cab5bc9b00d216a7677569 jdk8-b23
--- a/jdk/make/com/oracle/Makefile Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/make/com/oracle/Makefile Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 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
@@ -25,15 +25,24 @@
BUILDDIR = ../..
PRODUCT = oracle
+#SUBDIRS_MAKEFLAGS += JAVAC_MAX_WARNINGS=true
+#SUBDIRS_MAKEFLAGS += JAVAC_WARNINGS_FATAL=true
+#SUBDIRS_MAKEFLAGS += JAVAC_LINT_OPTIONS=-Xlint:all,-deprecation,-path
include $(BUILDDIR)/common/Defs.gmk
-#
-# Files to compile
-#
-AUTO_FILES_JAVA_DIRS = com/oracle
+# build com/oracle/security/ucrypto on Solaris platform for non-OpenJDK builds
+UCRYPTO =
+ifndef OPENJDK
+ ifeq ($(PLATFORM), solaris)
+ UCRYPTO = security/ucrypto
+ endif
+endif
-#
-# Rules
-#
-include $(BUILDDIR)/common/Classes.gmk
+
+SUBDIRS = net nio util $(UCRYPTO)
+include $(BUILDDIR)/common/Subdirs.gmk
+
+all build clean clobber::
+ $(SUBDIRS-loop)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/com/oracle/net/Makefile Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 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. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+BUILDDIR = ../../..
+PACKAGE = com.oracle.net
+PRODUCT = oracle
+include $(BUILDDIR)/common/Defs.gmk
+
+#
+# Files
+#
+AUTO_FILES_JAVA_DIRS = com/oracle/net
+
+#
+# Rules
+#
+include $(BUILDDIR)/common/Classes.gmk
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/com/oracle/nio/Makefile Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 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. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+BUILDDIR = ../../..
+PACKAGE = com.oracle.nio
+PRODUCT = oracle
+include $(BUILDDIR)/common/Defs.gmk
+
+#
+# Files
+#
+AUTO_FILES_JAVA_DIRS = com/oracle/nio
+
+#
+# Rules
+#
+include $(BUILDDIR)/common/Classes.gmk
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/com/oracle/security/ucrypto/FILES_c.gmk Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 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. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+ifndef OPENJDK
+FILES_c = \
+ nativeFunc.c \
+ nativeCrypto.c
+endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/com/oracle/security/ucrypto/Makefile Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,270 @@
+#
+# Copyright (c) 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. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+#
+# Makefile for building ucrypto.jar and its native libraries.
+#
+# This file was modified from make/sun/security/pkcs11/Makefile.
+#
+#
+# (The terms "OpenJDK" and "JDK" below refer to OpenJDK and Oracle
+# JDK builds respectively.)
+#
+# This Makefile does the "real" build of the Ucrypto provider files.
+# Since the sources are unavailable for OpenJDK, this Makefile is only
+# useful for JDK.
+#
+#
+# Main Targets (JDK on Solaris):
+#
+# all The usual, ucrypto.jar plus the native libraries.
+# builds and installs the prebuilt/signed jar.
+#
+# clobber/clean Cleans up the temp directory, ucrypto.jar, the
+# native libraries, and the config file from the
+# build area
+#
+# jar Builds, signs and installs ucrypto.jar
+# (Can only be done on machines with access to
+# the signing keystore)
+#
+# Other lesser-used Targets (JDK on Solaris):
+#
+# build-jar Builds ucrypto.jar (no sign/install)
+#
+# sign Builds/signs ucrypto.jar (no install)
+#
+# release Builds all targets in preparation
+# for workspace integration.
+# (Can only be done on machines with access to
+# the signing keystore)
+#
+# install-prebuilt Installs the pre-built jar files
+#
+# NOTE: None of the above target will update the prebuilt provider binary
+# under the closed workspace. To update it, you must explicitly copy the
+# binary from either the tmp/signed or lib/ext directory.
+#
+# This makefile was written to support parallel target execution.
+#
+
+BUILDDIR = ../../../..
+
+include $(BUILDDIR)/common/Defs.gmk
+
+ifndef OPENJDK
+ ifneq ($(PLATFORM), solaris)
+ all:
+ else
+ PACKAGE = com.oracle.security.ucrypto
+ LIBRARY = j2ucrypto
+ PRODUCT = oracle
+
+ #
+ # The following is for when we need to do postprocessing
+ # (signing/obfuscation) against a read-only build. If the OUTPUTDIR
+ # isn't writable, the build currently crashes out.
+ #
+ ifdef ALT_JCE_BUILD_DIR
+ # =====================================================
+ # Where to place the output, in case we're building from a read-only
+ # build area. (e.g. a release engineering build.)
+ JCE_BUILD_DIR=${ALT_JCE_BUILD_DIR}
+ IGNORE_WRITABLE_OUTPUTDIR_TEST=true
+ else
+ JCE_BUILD_DIR=${TEMPDIR}
+ endif
+
+ JAVAC_MAX_WARNINGS=false
+ JAVAC_LINT_OPTIONS=-Xlint:all,-deprecation
+ JAVAC_WARNINGS_FATAL=true
+
+ #
+ # C and Java Files
+ #
+ include FILES_c.gmk
+
+ #
+ # Subdirectories of these are automatically included.
+ #
+ AUTO_FILES_JAVA_DIRS = com/oracle/security/ucrypto
+
+ #
+ # Java files that define native methods
+ #
+ FILES_export = \
+ com/oracle/security/ucrypto/UcryptoProvider.java \
+ com/oracle/security/ucrypto/NativeCipher.java \
+ com/oracle/security/ucrypto/NativeDigest.java \
+ com/oracle/security/ucrypto/NativeKey.java \
+ com/oracle/security/ucrypto/NativeRSASignature.java \
+ com/oracle/security/ucrypto/NativeRSACipher.java
+
+ #
+ # Find native code
+ #
+ vpath %.c \
+ $(CLOSED_PLATFORM_SRC)/native/com/oracle/security/ucrypto
+
+ #
+ # Find include files
+ #
+ OTHER_INCLUDES += \
+ -I$(CLOSED_PLATFORM_SRC)/native/com/oracle/security/ucrypto
+
+ #
+ # Rules
+ #
+ CLASSDESTDIR = $(TEMPDIR)/classes
+ JAVAHFLAGS = -bootclasspath \
+ "$(CLASSDESTDIR)$(CLASSPATH_SEPARATOR)$(CLASSBINDIR)"
+
+ include $(BUILDDIR)/common/Mapfile-vers.gmk
+ include $(BUILDDIR)/common/Library.gmk
+
+ #
+ # Libraries to link
+ #
+ OTHER_LDLIBS = -ldl
+
+ # Default config file
+ UCRYPTO_CFG_SRC = $(CLOSED_SRC)/share/lib/security/ucrypto-solaris.cfg
+ UCRYPTO_CFG_BUILD = $(LIBDIR)/security/ucrypto-solaris.cfg
+
+ #
+ # We use a variety of subdirectories in the $(TEMPDIR) depending on what
+ # part of the build we're doing. Build is initially done in the unsigned
+ # area and when files are signed, they will be placed in the appropriate area.
+ #
+ UNSIGNED_DIR = $(TEMPDIR)/unsigned
+
+ #
+ # Rules
+ #
+ all: ucrypto-cfg build-jar install-prebuilt
+ $(build-warning)
+
+ ucrypto-cfg: $(UCRYPTO_CFG_BUILD)
+
+ $(UCRYPTO_CFG_BUILD): $(UCRYPTO_CFG_SRC)
+ $(install-file)
+
+ include $(BUILDDIR)/javax/crypto/Defs-jce.gmk
+
+
+ # =====================================================
+ # Build the unsigned ucrypto.jar file.
+ #
+
+ JAR_DESTFILE = $(EXTDIR)/ucrypto.jar
+
+ #
+ # The ucrypto.jar needs to be in the extension class directory,
+ # therefore none of its classes can appear in $(CLASSBINDIR).
+ # Currently no one is using any of the internals, so these files
+ # should not have been built.
+ #
+
+ #
+ # Since the -C option to jar is used below, each directory entry must be
+ # preceded with the appropriate directory to "cd" into.
+ #
+ JAR_DIRS = $(patsubst %, -C $(CLASSDESTDIR) %, $(AUTO_FILES_JAVA_DIRS))
+
+ build-jar: $(UNSIGNED_DIR)/ucrypto.jar
+
+ #
+ # Build ucrypto.jar.
+ #
+ $(UNSIGNED_DIR)/ucrypto.jar: build
+ $(prep-target)
+ $(BOOT_JAR_CMD) cf $@ $(JAR_DIRS) \
+ $(BOOT_JAR_JFLAGS)
+ @$(java-vm-cleanup)
+
+ #
+ # Sign ucrypto.jar
+ #
+ SIGNED_DIR = $(JCE_BUILD_DIR)/signed
+
+ sign: $(SIGNED_DIR)/ucrypto.jar
+
+ ifndef ALT_JCE_BUILD_DIR
+ $(SIGNED_DIR)/ucrypto.jar: $(UNSIGNED_DIR)/ucrypto.jar
+ else
+ #
+ # We have to remove the build dependency, otherwise, we'll try to rebuild it
+ # which we can't do on a read-only filesystem.
+ #
+ $(SIGNED_DIR)/ucrypto.jar:
+ @if [ ! -r $(UNSIGNED_DIR)/ucrypto.jar ] ; then \
+ $(ECHO) "Couldn't find $(UNSIGNED_DIR)/ucrypto.jar"; \
+ exit 1; \
+ fi
+ endif
+ $(call sign-file, $(UNSIGNED_DIR)/ucrypto.jar)
+
+
+ # =====================================================
+ # Create the Release Engineering files. Signed builds, etc.
+ #
+
+ release: $(SIGNED_DIR)/ucrypto.jar
+ $(RM) $(JCE_BUILD_DIR)/release/ucrypto.jar
+ $(MKDIR) -p $(JCE_BUILD_DIR)/release
+ $(CP) $(SIGNED_DIR)/ucrypto.jar $(JCE_BUILD_DIR)/release
+ $(release-warning)
+
+
+ # =====================================================
+ # Install routines.
+ #
+
+ #
+ # Install ucrypto.jar, depending on which type is requested.
+ #
+ jar: $(JAR_DESTFILE)
+ $(release-warning)
+
+ $(JAR_DESTFILE): $(SIGNED_DIR)/ucrypto.jar
+ $(install-file)
+
+ install-prebuilt:
+ @$(ECHO) "\n>>>Installing prebuilt OracleUcrypto provider..."
+ $(RM) $(JAR_DESTFILE)
+ $(CP) $(PREBUILT_DIR)/ucrypto/ucrypto.jar $(JAR_DESTFILE)
+
+
+ # =====================================================
+ # Support routines.
+ #
+ clobber clean::
+ $(RM) -r $(JAR_DESTFILE) $(TEMPDIR) $(JCE_BUILD_DIR)
+ $(RM) -r $(UCRYPTO_CFG_BUILD)
+
+ .PHONY: build-jar jar sign release install-prebuilt
+
+ endif #ifneq ($(PLATFORM), solaris)
+endif #ifndef OPENJDK
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/com/oracle/security/ucrypto/mapfile-vers Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,69 @@
+#
+# Copyright (c) 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. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# Define public interface.
+
+SUNWprivate_1.1 {
+ global:
+ JNI_OnLoad;
+ Java_com_oracle_security_ucrypto_UcryptoProvider_loadLibraries;
+ Java_com_oracle_security_ucrypto_UcryptoProvider_getMechList;
+ Java_com_oracle_security_ucrypto_NativeDigest_nativeInit;
+ Java_com_oracle_security_ucrypto_NativeDigest_nativeUpdate;
+ Java_com_oracle_security_ucrypto_NativeDigest_nativeDigest;
+ Java_com_oracle_security_ucrypto_NativeDigest_nativeClone;
+ Java_com_oracle_security_ucrypto_NativeDigest_nativeFree;
+ Java_com_oracle_security_ucrypto_NativeCipher_nativeInit;
+ Java_com_oracle_security_ucrypto_NativeCipher_nativeUpdate;
+ Java_com_oracle_security_ucrypto_NativeCipher_nativeFinal;
+ Java_com_oracle_security_ucrypto_NativeKey_nativeFree;
+ Java_com_oracle_security_ucrypto_NativeKey_00024RSAPrivateCrt_nativeInit;
+ Java_com_oracle_security_ucrypto_NativeKey_00024RSAPublic_nativeInit;
+ Java_com_oracle_security_ucrypto_NativeRSASignature_nativeInit;
+ Java_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII;
+ Java_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZJI;
+ Java_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal;
+ Java_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic;
+
+ JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeInit;
+ JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeUpdate;
+ JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeDigest;
+ JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeClone;
+ JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeFree;
+ JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeInit;
+ JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeUpdate;
+ JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeFinal;
+ JavaCritical_com_oracle_security_ucrypto_NativeKey_nativeFree;
+ JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPrivateCrt_nativeInit;
+ JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPublic_nativeInit;
+ JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeInit;
+ JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII;
+ JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZJI;
+ JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal;
+ JavaCritical_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic;
+
+ local:
+ *;
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/com/oracle/util/Makefile Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 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. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+BUILDDIR = ../../..
+PACKAGE = com.oracle.util
+PRODUCT = oracle
+include $(BUILDDIR)/common/Defs.gmk
+
+#
+# Files
+#
+AUTO_FILES_JAVA_DIRS = com/oracle/util
+
+#
+# Rules
+#
+include $(BUILDDIR)/common/Classes.gmk
+
--- a/jdk/make/javax/sound/jsoundalsa/Makefile Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/make/javax/sound/jsoundalsa/Makefile Sat Jan 28 22:21:54 2012 -0800
@@ -65,7 +65,7 @@
$(MIDIFILES_export) \
$(PORTFILES_export)
-LDFLAGS += -lasound
+OTHER_LDLIBS += -lasound
CPPFLAGS += \
-DUSE_DAUDIO=TRUE \
--- a/jdk/make/sun/awt/Makefile Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/make/sun/awt/Makefile Sat Jan 28 22:21:54 2012 -0800
@@ -367,7 +367,8 @@
FONTCONFIGS_SRC = $(CLOSED_SRC)/solaris/classes/sun/awt/fontconfigs
_FONTCONFIGS = \
fontconfig.properties \
- fontconfig.RedHat.5.5.properties \
+ fontconfig.RedHat.5.properties \
+ fontconfig.RedHat.6.properties \
fontconfig.Turbo.properties \
fontconfig.SuSE.10.properties \
fontconfig.SuSE.11.properties
--- a/jdk/make/sun/security/pkcs11/mapfile-vers Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/make/sun/security/pkcs11/mapfile-vers Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 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
@@ -47,8 +47,8 @@
Java_sun_security_pkcs11_wrapper_PKCS11_C_1CloseSession;
# Java_sun_security_pkcs11_wrapper_PKCS11_C_1CloseAllSessions;
Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSessionInfo;
-# Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetOperationState;
-# Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetOperationState;
+ Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetOperationState;
+ Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetOperationState;
Java_sun_security_pkcs11_wrapper_PKCS11_C_1Login;
Java_sun_security_pkcs11_wrapper_PKCS11_C_1Logout;
Java_sun_security_pkcs11_wrapper_PKCS11_C_1CreateObject;
--- a/jdk/src/share/bin/java.c Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/bin/java.c Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 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
@@ -1225,14 +1225,7 @@
"checkAndLoadMain",
"(ZILjava/lang/String;)Ljava/lang/Class;"));
- switch (mode) {
- case LM_CLASS:
- str = NewPlatformString(env, name);
- break;
- default:
- str = (*env)->NewStringUTF(env, name);
- break;
- }
+ str = NewPlatformString(env, name);
result = (*env)->CallStaticObjectMethod(env, cls, mid, USE_STDERR, mode, str);
if (JLI_IsTraceLauncher()) {
--- a/jdk/src/share/classes/java/lang/Class.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/java/lang/Class.java Sat Jan 28 22:21:54 2012 -0800
@@ -3118,4 +3118,9 @@
AnnotationType getAnnotationType() {
return annotationType;
}
+
+ /* Backing store of user-defined values pertaining to this class.
+ * Maintained by the ClassValue class.
+ */
+ transient ClassValue.ClassValueMap classValueMap;
}
--- a/jdk/src/share/classes/java/lang/ClassValue.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/java/lang/ClassValue.java Sat Jan 28 22:21:54 2012 -0800
@@ -25,9 +25,14 @@
package java.lang;
+import java.lang.ClassValue.ClassValueMap;
import java.util.WeakHashMap;
+import java.lang.ref.WeakReference;
import java.util.concurrent.atomic.AtomicInteger;
+import static java.lang.ClassValue.ClassValueMap.probeHomeLocation;
+import static java.lang.ClassValue.ClassValueMap.probeBackupLocations;
+
/**
* Lazily associate a computed value with (potentially) every type.
* For example, if a dynamic language needs to construct a message dispatch
@@ -92,14 +97,22 @@
* @see #computeValue
*/
public T get(Class<?> type) {
- ClassValueMap map = getMap(type);
- if (map != null) {
- Object x = map.get(this);
- if (x != null) {
- return (T) map.unmaskNull(x);
- }
- }
- return setComputedValue(type);
+ // non-racing this.hashCodeForCache : final int
+ Entry<?>[] cache;
+ Entry<T> e = probeHomeLocation(cache = getCacheCarefully(type), this);
+ // racing e : current value <=> stale value from current cache or from stale cache
+ // invariant: e is null or an Entry with readable Entry.version and Entry.value
+ if (match(e))
+ // invariant: No false positive matches. False negatives are OK if rare.
+ // The key fact that makes this work: if this.version == e.version,
+ // then this thread has a right to observe (final) e.value.
+ return e.value();
+ // The fast path can fail for any of these reasons:
+ // 1. no entry has been computed yet
+ // 2. hash code collision (before or after reduction mod cache.length)
+ // 3. an entry has been removed (either on this type or another)
+ // 4. the GC has somehow managed to delete e.version and clear the reference
+ return getFromBackup(cache, type);
}
/**
@@ -157,83 +170,582 @@
*/
public void remove(Class<?> type) {
ClassValueMap map = getMap(type);
- if (map != null) {
- synchronized (map) {
- map.remove(this);
+ map.removeEntry(this);
+ }
+
+ // Possible functionality for JSR 292 MR 1
+ /*public*/ void put(Class<?> type, T value) {
+ ClassValueMap map = getMap(type);
+ map.changeEntry(this, value);
+ }
+
+ /// --------
+ /// Implementation...
+ /// --------
+
+ /** Return the cache, if it exists, else a dummy empty cache. */
+ private static Entry<?>[] getCacheCarefully(Class<?> type) {
+ // racing type.classValueMap{.cacheArray} : null => new Entry[X] <=> new Entry[Y]
+ ClassValueMap map = type.classValueMap;
+ if (map == null) return EMPTY_CACHE;
+ Entry<?>[] cache = map.getCache();
+ return cache;
+ // invariant: returned value is safe to dereference and check for an Entry
+ }
+
+ /** Initial, one-element, empty cache used by all Class instances. Must never be filled. */
+ private static final Entry<?>[] EMPTY_CACHE = { null };
+
+ /**
+ * Slow tail of ClassValue.get to retry at nearby locations in the cache,
+ * or take a slow lock and check the hash table.
+ * Called only if the first probe was empty or a collision.
+ * This is a separate method, so compilers can process it independently.
+ */
+ private T getFromBackup(Entry<?>[] cache, Class<?> type) {
+ Entry<T> e = probeBackupLocations(cache, this);
+ if (e != null)
+ return e.value();
+ return getFromHashMap(type);
+ }
+
+ // Hack to suppress warnings on the (T) cast, which is a no-op.
+ @SuppressWarnings("unchecked")
+ Entry<T> castEntry(Entry<?> e) { return (Entry<T>) e; }
+
+ /** Called when the fast path of get fails, and cache reprobe also fails.
+ */
+ private T getFromHashMap(Class<?> type) {
+ // The fail-safe recovery is to fall back to the underlying classValueMap.
+ ClassValueMap map = getMap(type);
+ for (;;) {
+ Entry<T> e = map.startEntry(this);
+ if (!e.isPromise())
+ return e.value();
+ try {
+ // Try to make a real entry for the promised version.
+ e = makeEntry(e.version(), computeValue(type));
+ } finally {
+ // Whether computeValue throws or returns normally,
+ // be sure to remove the empty entry.
+ e = map.finishEntry(this, e);
}
+ if (e != null)
+ return e.value();
+ // else try again, in case a racing thread called remove (so e == null)
}
}
- /// Implementation...
- // FIXME: Use a data structure here similar that of ThreadLocal (7030453).
+ /** Check that e is non-null, matches this ClassValue, and is live. */
+ boolean match(Entry<?> e) {
+ // racing e.version : null (blank) => unique Version token => null (GC-ed version)
+ // non-racing this.version : v1 => v2 => ... (updates are read faithfully from volatile)
+ return (e != null && e.get() == this.version);
+ // invariant: No false positives on version match. Null is OK for false negative.
+ // invariant: If version matches, then e.value is readable (final set in Entry.<init>)
+ }
+
+ /** Internal hash code for accessing Class.classValueMap.cacheArray. */
+ final int hashCodeForCache = nextHashCode.getAndAdd(HASH_INCREMENT) & HASH_MASK;
+
+ /** Value stream for hashCodeForCache. See similar structure in ThreadLocal. */
+ private static final AtomicInteger nextHashCode = new AtomicInteger();
- private static final AtomicInteger STORE_BARRIER = new AtomicInteger();
+ /** Good for power-of-two tables. See similar structure in ThreadLocal. */
+ private static final int HASH_INCREMENT = 0x61c88647;
+
+ /** Mask a hash code to be positive but not too large, to prevent wraparound. */
+ static final int HASH_MASK = (-1 >>> 2);
+
+ /**
+ * Private key for retrieval of this object from ClassValueMap.
+ */
+ static class Identity {
+ }
+ /**
+ * This ClassValue's identity, expressed as an opaque object.
+ * The main object {@code ClassValue.this} is incorrect since
+ * subclasses may override {@code ClassValue.equals}, which
+ * could confuse keys in the ClassValueMap.
+ */
+ final Identity identity = new Identity();
- /** Slow path for {@link #get}. */
- private T setComputedValue(Class<?> type) {
- ClassValueMap map = getMap(type);
- if (map == null) {
- map = initializeMap(type);
+ /**
+ * Current version for retrieving this class value from the cache.
+ * Any number of computeValue calls can be cached in association with one version.
+ * But the version changes when a remove (on any type) is executed.
+ * A version change invalidates all cache entries for the affected ClassValue,
+ * by marking them as stale. Stale cache entries do not force another call
+ * to computeValue, but they do require a synchronized visit to a backing map.
+ * <p>
+ * All user-visible state changes on the ClassValue take place under
+ * a lock inside the synchronized methods of ClassValueMap.
+ * Readers (of ClassValue.get) are notified of such state changes
+ * when this.version is bumped to a new token.
+ * This variable must be volatile so that an unsynchronized reader
+ * will receive the notification without delay.
+ * <p>
+ * If version were not volatile, one thread T1 could persistently hold onto
+ * a stale value this.value == V1, while while another thread T2 advances
+ * (under a lock) to this.value == V2. This will typically be harmless,
+ * but if T1 and T2 interact causally via some other channel, such that
+ * T1's further actions are constrained (in the JMM) to happen after
+ * the V2 event, then T1's observation of V1 will be an error.
+ * <p>
+ * The practical effect of making this.version be volatile is that it cannot
+ * be hoisted out of a loop (by an optimizing JIT) or otherwise cached.
+ * Some machines may also require a barrier instruction to execute
+ * before this.version.
+ */
+ private volatile Version<T> version = new Version<>(this);
+ Version<T> version() { return version; }
+ void bumpVersion() { version = new Version<>(this); }
+ static class Version<T> {
+ private final ClassValue<T> classValue;
+ private final Entry<T> promise = new Entry<>(this);
+ Version(ClassValue<T> classValue) { this.classValue = classValue; }
+ ClassValue<T> classValue() { return classValue; }
+ Entry<T> promise() { return promise; }
+ boolean isLive() { return classValue.version() == this; }
+ }
+
+ /** One binding of a value to a class via a ClassValue.
+ * States are:<ul>
+ * <li> promise if value == Entry.this
+ * <li> else dead if version == null
+ * <li> else stale if version != classValue.version
+ * <li> else live </ul>
+ * Promises are never put into the cache; they only live in the
+ * backing map while a computeValue call is in flight.
+ * Once an entry goes stale, it can be reset at any time
+ * into the dead state.
+ */
+ static class Entry<T> extends WeakReference<Version<T>> {
+ final Object value; // usually of type T, but sometimes (Entry)this
+ Entry(Version<T> version, T value) {
+ super(version);
+ this.value = value; // for a regular entry, value is of type T
}
- T value = computeValue(type);
- STORE_BARRIER.lazySet(0);
- // All stores pending from computeValue are completed.
- synchronized (map) {
- // Warm up the table with a null entry.
- map.preInitializeEntry(this);
+ private void assertNotPromise() { assert(!isPromise()); }
+ /** For creating a promise. */
+ Entry(Version<T> version) {
+ super(version);
+ this.value = this; // for a promise, value is not of type T, but Entry!
+ }
+ /** Fetch the value. This entry must not be a promise. */
+ @SuppressWarnings("unchecked") // if !isPromise, type is T
+ T value() { assertNotPromise(); return (T) value; }
+ boolean isPromise() { return value == this; }
+ Version<T> version() { return get(); }
+ ClassValue<T> classValueOrNull() {
+ Version<T> v = version();
+ return (v == null) ? null : v.classValue();
+ }
+ boolean isLive() {
+ Version<T> v = version();
+ if (v == null) return false;
+ if (v.isLive()) return true;
+ clear();
+ return false;
+ }
+ Entry<T> refreshVersion(Version<T> v2) {
+ assertNotPromise();
+ @SuppressWarnings("unchecked") // if !isPromise, type is T
+ Entry<T> e2 = new Entry<>(v2, (T) value);
+ clear();
+ // value = null -- caller must drop
+ return e2;
}
- STORE_BARRIER.lazySet(0);
- // All stores pending from table expansion are completed.
- synchronized (map) {
- value = (T) map.initializeEntry(this, value);
- // One might fear a possible race condition here
- // if the code for map.put has flushed the write
- // to map.table[*] before the writes to the Map.Entry
- // are done. This is not possible, since we have
- // warmed up the table with an empty entry.
+ static final Entry<?> DEAD_ENTRY = new Entry<>(null, null);
+ }
+
+ /** Return the backing map associated with this type. */
+ private static ClassValueMap getMap(Class<?> type) {
+ // racing type.classValueMap : null (blank) => unique ClassValueMap
+ // if a null is observed, a map is created (lazily, synchronously, uniquely)
+ // all further access to that map is synchronized
+ ClassValueMap map = type.classValueMap;
+ if (map != null) return map;
+ return initializeMap(type);
+ }
+
+ private static final Object CRITICAL_SECTION = new Object();
+ private static ClassValueMap initializeMap(Class<?> type) {
+ ClassValueMap map;
+ synchronized (CRITICAL_SECTION) { // private object to avoid deadlocks
+ // happens about once per type
+ if ((map = type.classValueMap) == null)
+ type.classValueMap = map = new ClassValueMap(type);
}
- return value;
+ return map;
+ }
+
+ static <T> Entry<T> makeEntry(Version<T> explicitVersion, T value) {
+ // Note that explicitVersion might be different from this.version.
+ return new Entry<>(explicitVersion, value);
+
+ // As soon as the Entry is put into the cache, the value will be
+ // reachable via a data race (as defined by the Java Memory Model).
+ // This race is benign, assuming the value object itself can be
+ // read safely by multiple threads. This is up to the user.
+ //
+ // The entry and version fields themselves can be safely read via
+ // a race because they are either final or have controlled states.
+ // If the pointer from the entry to the version is still null,
+ // or if the version goes immediately dead and is nulled out,
+ // the reader will take the slow path and retry under a lock.
}
- // Replace this map by a per-class slot.
- private static final WeakHashMap<Class<?>, ClassValueMap> ROOT
- = new WeakHashMap<Class<?>, ClassValueMap>();
+ // The following class could also be top level and non-public:
+
+ /** A backing map for all ClassValues, relative a single given type.
+ * Gives a fully serialized "true state" for each pair (ClassValue cv, Class type).
+ * Also manages an unserialized fast-path cache.
+ */
+ static class ClassValueMap extends WeakHashMap<ClassValue.Identity, Entry<?>> {
+ private final Class<?> type;
+ private Entry<?>[] cacheArray;
+ private int cacheLoad, cacheLoadLimit;
+
+ /** Number of entries initially allocated to each type when first used with any ClassValue.
+ * It would be pointless to make this much smaller than the Class and ClassValueMap objects themselves.
+ * Must be a power of 2.
+ */
+ private static final int INITIAL_ENTRIES = 32;
+
+ /** Build a backing map for ClassValues, relative the given type.
+ * Also, create an empty cache array and install it on the class.
+ */
+ ClassValueMap(Class<?> type) {
+ this.type = type;
+ sizeCache(INITIAL_ENTRIES);
+ }
+
+ Entry<?>[] getCache() { return cacheArray; }
- private static ClassValueMap getMap(Class<?> type) {
- type.getClass(); // test for null
- return ROOT.get(type);
- }
-
- private static ClassValueMap initializeMap(Class<?> type) {
- synchronized (ClassValue.class) {
- ClassValueMap map = ROOT.get(type);
- if (map == null)
- ROOT.put(type, map = new ClassValueMap());
- return map;
+ /** Initiate a query. Store a promise (placeholder) if there is no value yet. */
+ synchronized
+ <T> Entry<T> startEntry(ClassValue<T> classValue) {
+ @SuppressWarnings("unchecked") // one map has entries for all value types <T>
+ Entry<T> e = (Entry<T>) get(classValue.identity);
+ Version<T> v = classValue.version();
+ if (e == null) {
+ e = v.promise();
+ // The presence of a promise means that a value is pending for v.
+ // Eventually, finishEntry will overwrite the promise.
+ put(classValue.identity, e);
+ // Note that the promise is never entered into the cache!
+ return e;
+ } else if (e.isPromise()) {
+ // Somebody else has asked the same question.
+ // Let the races begin!
+ if (e.version() != v) {
+ e = v.promise();
+ put(classValue.identity, e);
+ }
+ return e;
+ } else {
+ // there is already a completed entry here; report it
+ if (e.version() != v) {
+ // There is a stale but valid entry here; make it fresh again.
+ // Once an entry is in the hash table, we don't care what its version is.
+ e = e.refreshVersion(v);
+ put(classValue.identity, e);
+ }
+ // Add to the cache, to enable the fast path, next time.
+ checkCacheLoad();
+ addToCache(classValue, e);
+ return e;
+ }
}
- }
- static class ClassValueMap extends WeakHashMap<ClassValue, Object> {
- /** Make sure this table contains an Entry for the given key, even if it is empty. */
- void preInitializeEntry(ClassValue key) {
- if (!this.containsKey(key))
- this.put(key, null);
+ /** Finish a query. Overwrite a matching placeholder. Drop stale incoming values. */
+ synchronized
+ <T> Entry<T> finishEntry(ClassValue<T> classValue, Entry<T> e) {
+ @SuppressWarnings("unchecked") // one map has entries for all value types <T>
+ Entry<T> e0 = (Entry<T>) get(classValue.identity);
+ if (e == e0) {
+ // We can get here during exception processing, unwinding from computeValue.
+ assert(e.isPromise());
+ remove(classValue.identity);
+ return null;
+ } else if (e0 != null && e0.isPromise() && e0.version() == e.version()) {
+ // If e0 matches the intended entry, there has not been a remove call
+ // between the previous startEntry and now. So now overwrite e0.
+ Version<T> v = classValue.version();
+ if (e.version() != v)
+ e = e.refreshVersion(v);
+ put(classValue.identity, e);
+ // Add to the cache, to enable the fast path, next time.
+ checkCacheLoad();
+ addToCache(classValue, e);
+ return e;
+ } else {
+ // Some sort of mismatch; caller must try again.
+ return null;
+ }
+ }
+
+ /** Remove an entry. */
+ synchronized
+ void removeEntry(ClassValue<?> classValue) {
+ // make all cache elements for this guy go stale:
+ if (remove(classValue.identity) != null) {
+ classValue.bumpVersion();
+ removeStaleEntries(classValue);
+ }
}
- /** Make sure this table contains a non-empty Entry for the given key. */
- Object initializeEntry(ClassValue key, Object value) {
- Object prior = this.get(key);
- if (prior != null) {
- return unmaskNull(prior);
+
+ /** Change the value for an entry. */
+ synchronized
+ <T> void changeEntry(ClassValue<T> classValue, T value) {
+ @SuppressWarnings("unchecked") // one map has entries for all value types <T>
+ Entry<T> e0 = (Entry<T>) get(classValue.identity);
+ Version<T> version = classValue.version();
+ if (e0 != null) {
+ if (e0.version() == version && e0.value() == value)
+ // no value change => no version change needed
+ return;
+ classValue.bumpVersion();
+ removeStaleEntries(classValue);
}
- this.put(key, maskNull(value));
- return value;
+ Entry<T> e = makeEntry(version, value);
+ put(classValue.identity, e);
+ // Add to the cache, to enable the fast path, next time.
+ checkCacheLoad();
+ addToCache(classValue, e);
+ }
+
+ /// --------
+ /// Cache management.
+ /// --------
+
+ // Statics do not need synchronization.
+
+ /** Load the cache entry at the given (hashed) location. */
+ static Entry<?> loadFromCache(Entry<?>[] cache, int i) {
+ // non-racing cache.length : constant
+ // racing cache[i & (mask)] : null <=> Entry
+ return cache[i & (cache.length-1)];
+ // invariant: returned value is null or well-constructed (ready to match)
+ }
+
+ /** Look in the cache, at the home location for the given ClassValue. */
+ static <T> Entry<T> probeHomeLocation(Entry<?>[] cache, ClassValue<T> classValue) {
+ return classValue.castEntry(loadFromCache(cache, classValue.hashCodeForCache));
+ }
+
+ /** Given that first probe was a collision, retry at nearby locations. */
+ static <T> Entry<T> probeBackupLocations(Entry<?>[] cache, ClassValue<T> classValue) {
+ if (PROBE_LIMIT <= 0) return null;
+ // Probe the cache carefully, in a range of slots.
+ int mask = (cache.length-1);
+ int home = (classValue.hashCodeForCache & mask);
+ Entry<?> e2 = cache[home]; // victim, if we find the real guy
+ if (e2 == null) {
+ return null; // if nobody is at home, no need to search nearby
+ }
+ // assume !classValue.match(e2), but do not assert, because of races
+ int pos2 = -1;
+ for (int i = home + 1; i < home + PROBE_LIMIT; i++) {
+ Entry<?> e = cache[i & mask];
+ if (e == null) {
+ break; // only search within non-null runs
+ }
+ if (classValue.match(e)) {
+ // relocate colliding entry e2 (from cache[home]) to first empty slot
+ cache[home] = e;
+ if (pos2 >= 0) {
+ cache[i & mask] = Entry.DEAD_ENTRY;
+ } else {
+ pos2 = i;
+ }
+ cache[pos2 & mask] = ((entryDislocation(cache, pos2, e2) < PROBE_LIMIT)
+ ? e2 // put e2 here if it fits
+ : Entry.DEAD_ENTRY);
+ return classValue.castEntry(e);
+ }
+ // Remember first empty slot, if any:
+ if (!e.isLive() && pos2 < 0) pos2 = i;
+ }
+ return null;
}
- Object maskNull(Object x) {
- return x == null ? this : x;
+ /** How far out of place is e? */
+ private static int entryDislocation(Entry<?>[] cache, int pos, Entry<?> e) {
+ ClassValue<?> cv = e.classValueOrNull();
+ if (cv == null) return 0; // entry is not live!
+ int mask = (cache.length-1);
+ return (pos - cv.hashCodeForCache) & mask;
+ }
+
+ /// --------
+ /// Below this line all functions are private, and assume synchronized access.
+ /// --------
+
+ private void sizeCache(int length) {
+ assert((length & (length-1)) == 0); // must be power of 2
+ cacheLoad = 0;
+ cacheLoadLimit = (int) ((double) length * CACHE_LOAD_LIMIT / 100);
+ cacheArray = new Entry<?>[length];
+ }
+
+ /** Make sure the cache load stays below its limit, if possible. */
+ private void checkCacheLoad() {
+ if (cacheLoad >= cacheLoadLimit) {
+ reduceCacheLoad();
+ }
+ }
+ private void reduceCacheLoad() {
+ removeStaleEntries();
+ if (cacheLoad < cacheLoadLimit)
+ return; // win
+ Entry<?>[] oldCache = getCache();
+ if (oldCache.length > HASH_MASK)
+ return; // lose
+ sizeCache(oldCache.length * 2);
+ for (Entry<?> e : oldCache) {
+ if (e != null && e.isLive()) {
+ addToCache(e);
+ }
+ }
+ }
+
+ /** Remove stale entries in the given range.
+ * Should be executed under a Map lock.
+ */
+ private void removeStaleEntries(Entry<?>[] cache, int begin, int count) {
+ if (PROBE_LIMIT <= 0) return;
+ int mask = (cache.length-1);
+ int removed = 0;
+ for (int i = begin; i < begin + count; i++) {
+ Entry<?> e = cache[i & mask];
+ if (e == null || e.isLive())
+ continue; // skip null and live entries
+ Entry<?> replacement = null;
+ if (PROBE_LIMIT > 1) {
+ // avoid breaking up a non-null run
+ replacement = findReplacement(cache, i);
+ }
+ cache[i & mask] = replacement;
+ if (replacement == null) removed += 1;
+ }
+ cacheLoad = Math.max(0, cacheLoad - removed);
}
- Object unmaskNull(Object x) {
- return x == this ? null : x;
+
+ /** Clearing a cache slot risks disconnecting following entries
+ * from the head of a non-null run, which would allow them
+ * to be found via reprobes. Find an entry after cache[begin]
+ * to plug into the hole, or return null if none is needed.
+ */
+ private Entry<?> findReplacement(Entry<?>[] cache, int home1) {
+ Entry<?> replacement = null;
+ int haveReplacement = -1, replacementPos = 0;
+ int mask = (cache.length-1);
+ for (int i2 = home1 + 1; i2 < home1 + PROBE_LIMIT; i2++) {
+ Entry<?> e2 = cache[i2 & mask];
+ if (e2 == null) break; // End of non-null run.
+ if (!e2.isLive()) continue; // Doomed anyway.
+ int dis2 = entryDislocation(cache, i2, e2);
+ if (dis2 == 0) continue; // e2 already optimally placed
+ int home2 = i2 - dis2;
+ if (home2 <= home1) {
+ // e2 can replace entry at cache[home1]
+ if (home2 == home1) {
+ // Put e2 exactly where he belongs.
+ haveReplacement = 1;
+ replacementPos = i2;
+ replacement = e2;
+ } else if (haveReplacement <= 0) {
+ haveReplacement = 0;
+ replacementPos = i2;
+ replacement = e2;
+ }
+ // And keep going, so we can favor larger dislocations.
+ }
+ }
+ if (haveReplacement >= 0) {
+ if (cache[(replacementPos+1) & mask] != null) {
+ // Be conservative, to avoid breaking up a non-null run.
+ cache[replacementPos & mask] = (Entry<?>) Entry.DEAD_ENTRY;
+ } else {
+ cache[replacementPos & mask] = null;
+ cacheLoad -= 1;
+ }
+ }
+ return replacement;
+ }
+
+ /** Remove stale entries in the range near classValue. */
+ private void removeStaleEntries(ClassValue<?> classValue) {
+ removeStaleEntries(getCache(), classValue.hashCodeForCache, PROBE_LIMIT);
+ }
+
+ /** Remove all stale entries, everywhere. */
+ private void removeStaleEntries() {
+ Entry[] cache = getCache();
+ removeStaleEntries(cache, 0, cache.length + PROBE_LIMIT - 1);
}
+
+ /** Add the given entry to the cache, in its home location, unless it is out of date. */
+ private <T> void addToCache(Entry<T> e) {
+ ClassValue<T> classValue = e.classValueOrNull();
+ if (classValue != null)
+ addToCache(classValue, e);
+ }
+
+ /** Add the given entry to the cache, in its home location. */
+ private <T> void addToCache(ClassValue<T> classValue, Entry<T> e) {
+ if (PROBE_LIMIT <= 0) return; // do not fill cache
+ // Add e to the cache.
+ Entry<?>[] cache = getCache();
+ int mask = (cache.length-1);
+ int home = classValue.hashCodeForCache & mask;
+ Entry<?> e2 = placeInCache(cache, home, e, false);
+ if (e2 == null) return; // done
+ if (PROBE_LIMIT > 1) {
+ // try to move e2 somewhere else in his probe range
+ int dis2 = entryDislocation(cache, home, e2);
+ int home2 = home - dis2;
+ for (int i2 = home2; i2 < home2 + PROBE_LIMIT; i2++) {
+ if (placeInCache(cache, i2 & mask, e2, true) == null) {
+ return;
+ }
+ }
+ }
+ // Note: At this point, e2 is just dropped from the cache.
+ }
+
+ /** Store the given entry. Update cacheLoad, and return any live victim.
+ * 'Gently' means return self rather than dislocating a live victim.
+ */
+ private Entry<?> placeInCache(Entry<?>[] cache, int pos, Entry<?> e, boolean gently) {
+ Entry<?> e2 = overwrittenEntry(cache[pos]);
+ if (gently && e2 != null) {
+ // do not overwrite a live entry
+ return e;
+ } else {
+ cache[pos] = e;
+ return e2;
+ }
+ }
+
+ /** Note an entry that is about to be overwritten.
+ * If it is not live, quietly replace it by null.
+ * If it is an actual null, increment cacheLoad,
+ * because the caller is going to store something
+ * in its place.
+ */
+ private <T> Entry<T> overwrittenEntry(Entry<T> e2) {
+ if (e2 == null) cacheLoad += 1;
+ else if (e2.isLive()) return e2;
+ return null;
+ }
+
+ /** Percent loading of cache before resize. */
+ private static final int CACHE_LOAD_LIMIT = 67; // 0..100
+ /** Maximum number of probes to attempt. */
+ private static final int PROBE_LIMIT = 6; // 1..
+ // N.B. Set PROBE_LIMIT=0 to disable all fast paths.
}
}
--- a/jdk/src/share/classes/java/lang/Math.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/java/lang/Math.java Sat Jan 28 22:21:54 2012 -0800
@@ -818,8 +818,9 @@
return (a >= b) ? a : b;
}
- private static long negativeZeroFloatBits = Float.floatToIntBits(-0.0f);
- private static long negativeZeroDoubleBits = Double.doubleToLongBits(-0.0d);
+ // Use raw bit-wise conversions on guaranteed non-NaN arguments.
+ private static long negativeZeroFloatBits = Float.floatToRawIntBits(-0.0f);
+ private static long negativeZeroDoubleBits = Double.doubleToRawLongBits(-0.0d);
/**
* Returns the greater of two {@code float} values. That is,
@@ -836,9 +837,12 @@
* @return the larger of {@code a} and {@code b}.
*/
public static float max(float a, float b) {
- if (a != a) return a; // a is NaN
- if ((a == 0.0f) && (b == 0.0f)
- && (Float.floatToIntBits(a) == negativeZeroFloatBits)) {
+ if (a != a)
+ return a; // a is NaN
+ if ((a == 0.0f) &&
+ (b == 0.0f) &&
+ (Float.floatToRawIntBits(a) == negativeZeroFloatBits)) {
+ // Raw conversion ok since NaN can't map to -0.0.
return b;
}
return (a >= b) ? a : b;
@@ -859,9 +863,12 @@
* @return the larger of {@code a} and {@code b}.
*/
public static double max(double a, double b) {
- if (a != a) return a; // a is NaN
- if ((a == 0.0d) && (b == 0.0d)
- && (Double.doubleToLongBits(a) == negativeZeroDoubleBits)) {
+ if (a != a)
+ return a; // a is NaN
+ if ((a == 0.0d) &&
+ (b == 0.0d) &&
+ (Double.doubleToRawLongBits(a) == negativeZeroDoubleBits)) {
+ // Raw conversion ok since NaN can't map to -0.0.
return b;
}
return (a >= b) ? a : b;
@@ -910,9 +917,12 @@
* @return the smaller of {@code a} and {@code b}.
*/
public static float min(float a, float b) {
- if (a != a) return a; // a is NaN
- if ((a == 0.0f) && (b == 0.0f)
- && (Float.floatToIntBits(b) == negativeZeroFloatBits)) {
+ if (a != a)
+ return a; // a is NaN
+ if ((a == 0.0f) &&
+ (b == 0.0f) &&
+ (Float.floatToRawIntBits(b) == negativeZeroFloatBits)) {
+ // Raw conversion ok since NaN can't map to -0.0.
return b;
}
return (a <= b) ? a : b;
@@ -933,9 +943,12 @@
* @return the smaller of {@code a} and {@code b}.
*/
public static double min(double a, double b) {
- if (a != a) return a; // a is NaN
- if ((a == 0.0d) && (b == 0.0d)
- && (Double.doubleToLongBits(b) == negativeZeroDoubleBits)) {
+ if (a != a)
+ return a; // a is NaN
+ if ((a == 0.0d) &&
+ (b == 0.0d) &&
+ (Double.doubleToRawLongBits(b) == negativeZeroDoubleBits)) {
+ // Raw conversion ok since NaN can't map to -0.0.
return b;
}
return (a <= b) ? a : b;
@@ -1900,7 +1913,7 @@
/**
* Returns a floating-point power of two in the normal range.
*/
- public static float powerOfTwoF(int n) {
+ static float powerOfTwoF(int n) {
assert(n >= FloatConsts.MIN_EXPONENT && n <= FloatConsts.MAX_EXPONENT);
return Float.intBitsToFloat(((n + FloatConsts.EXP_BIAS) <<
(FloatConsts.SIGNIFICAND_WIDTH-1))
--- a/jdk/src/share/classes/java/lang/Object.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/java/lang/Object.java Sat Jan 28 22:21:54 2012 -0800
@@ -58,8 +58,7 @@
*
* @return The {@code Class} object that represents the runtime
* class of this object.
- * @see Class Literals, section 15.8.2 of
- * <cite>The Java™ Language Specification</cite>.
+ * @jls 15.8.2 Class Literals
*/
public final native Class<?> getClass();
@@ -92,7 +91,7 @@
* objects. (This is typically implemented by converting the internal
* address of the object into an integer, but this implementation
* technique is not required by the
- * Java<font size="-2"><sup>TM</sup></font> programming language.)
+ * Java™ programming language.)
*
* @return a hash code value for this object.
* @see java.lang.Object#equals(java.lang.Object)
@@ -203,7 +202,7 @@
* exception at run time.
*
* @return a clone of this instance.
- * @exception CloneNotSupportedException if the object's class does not
+ * @throws CloneNotSupportedException if the object's class does not
* support the {@code Cloneable} interface. Subclasses
* that override the {@code clone} method can also
* throw this exception to indicate that an instance cannot
@@ -264,7 +263,7 @@
* <p>
* Only one thread at a time can own an object's monitor.
*
- * @exception IllegalMonitorStateException if the current thread is not
+ * @throws IllegalMonitorStateException if the current thread is not
* the owner of this object's monitor.
* @see java.lang.Object#notifyAll()
* @see java.lang.Object#wait()
@@ -288,7 +287,7 @@
* description of the ways in which a thread can become the owner of
* a monitor.
*
- * @exception IllegalMonitorStateException if the current thread is not
+ * @throws IllegalMonitorStateException if the current thread is not
* the owner of this object's monitor.
* @see java.lang.Object#notify()
* @see java.lang.Object#wait()
@@ -368,11 +367,11 @@
* a monitor.
*
* @param timeout the maximum time to wait in milliseconds.
- * @exception IllegalArgumentException if the value of timeout is
+ * @throws IllegalArgumentException if the value of timeout is
* negative.
- * @exception IllegalMonitorStateException if the current thread is not
+ * @throws IllegalMonitorStateException if the current thread is not
* the owner of the object's monitor.
- * @exception InterruptedException if any thread interrupted the
+ * @throws InterruptedException if any thread interrupted the
* current thread before or while the current thread
* was waiting for a notification. The <i>interrupted
* status</i> of the current thread is cleared when
@@ -433,12 +432,12 @@
* @param timeout the maximum time to wait in milliseconds.
* @param nanos additional time, in nanoseconds range
* 0-999999.
- * @exception IllegalArgumentException if the value of timeout is
+ * @throws IllegalArgumentException if the value of timeout is
* negative or the value of nanos is
* not in the range 0-999999.
- * @exception IllegalMonitorStateException if the current thread is not
+ * @throws IllegalMonitorStateException if the current thread is not
* the owner of this object's monitor.
- * @exception InterruptedException if any thread interrupted the
+ * @throws InterruptedException if any thread interrupted the
* current thread before or while the current thread
* was waiting for a notification. The <i>interrupted
* status</i> of the current thread is cleared when
@@ -489,9 +488,9 @@
* description of the ways in which a thread can become the owner of
* a monitor.
*
- * @exception IllegalMonitorStateException if the current thread is not
+ * @throws IllegalMonitorStateException if the current thread is not
* the owner of the object's monitor.
- * @exception InterruptedException if any thread interrupted the
+ * @throws InterruptedException if any thread interrupted the
* current thread before or while the current thread
* was waiting for a notification. The <i>interrupted
* status</i> of the current thread is cleared when
@@ -510,7 +509,7 @@
* system resources or to perform other cleanup.
* <p>
* The general contract of {@code finalize} is that it is invoked
- * if and when the Java<font size="-2"><sup>TM</sup></font> virtual
+ * if and when the Java™ virtual
* machine has determined that there is no longer any
* means by which this object can be accessed by any thread that has
* not yet died, except as a result of an action taken by the
@@ -549,6 +548,9 @@
* ignored.
*
* @throws Throwable the {@code Exception} raised by this method
+ * @see java.lang.ref.WeakReference
+ * @see java.lang.ref.PhantomReference
+ * @jls 12.6 Finalization of Class Instances
*/
protected void finalize() throws Throwable { }
}
--- a/jdk/src/share/classes/java/lang/StrictMath.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/java/lang/StrictMath.java Sat Jan 28 22:21:54 2012 -0800
@@ -161,6 +161,8 @@
* in radians.
*/
public static strictfp double toRadians(double angdeg) {
+ // Do not delegate to Math.toRadians(angdeg) because
+ // this method has the strictfp modifier.
return angdeg / 180.0 * PI;
}
@@ -176,6 +178,8 @@
* in degrees.
*/
public static strictfp double toDegrees(double angrad) {
+ // Do not delegate to Math.toDegrees(angrad) because
+ // this method has the strictfp modifier.
return angrad * 180.0 / PI;
}
@@ -708,7 +712,7 @@
* @return the absolute value of the argument.
*/
public static int abs(int a) {
- return (a < 0) ? -a : a;
+ return Math.abs(a);
}
/**
@@ -725,7 +729,7 @@
* @return the absolute value of the argument.
*/
public static long abs(long a) {
- return (a < 0) ? -a : a;
+ return Math.abs(a);
}
/**
@@ -744,7 +748,7 @@
* @return the absolute value of the argument.
*/
public static float abs(float a) {
- return (a <= 0.0F) ? 0.0F - a : a;
+ return Math.abs(a);
}
/**
@@ -763,7 +767,7 @@
* @return the absolute value of the argument.
*/
public static double abs(double a) {
- return (a <= 0.0D) ? 0.0D - a : a;
+ return Math.abs(a);
}
/**
@@ -777,7 +781,7 @@
* @return the larger of {@code a} and {@code b}.
*/
public static int max(int a, int b) {
- return (a >= b) ? a : b;
+ return Math.max(a, b);
}
/**
@@ -791,13 +795,9 @@
* @return the larger of {@code a} and {@code b}.
*/
public static long max(long a, long b) {
- return (a >= b) ? a : b;
+ return Math.max(a, b);
}
- // Use raw bit-wise conversions on guaranteed non-NaN arguments.
- private static long negativeZeroFloatBits = Float.floatToRawIntBits(-0.0f);
- private static long negativeZeroDoubleBits = Double.doubleToRawLongBits(-0.0d);
-
/**
* Returns the greater of two {@code float} values. That is,
* the result is the argument closer to positive infinity. If the
@@ -813,15 +813,7 @@
* @return the larger of {@code a} and {@code b}.
*/
public static float max(float a, float b) {
- if (a != a)
- return a; // a is NaN
- if ((a == 0.0f) &&
- (b == 0.0f) &&
- (Float.floatToRawIntBits(a) == negativeZeroFloatBits)) {
- // Raw conversion ok since NaN can't map to -0.0.
- return b;
- }
- return (a >= b) ? a : b;
+ return Math.max(a, b);
}
/**
@@ -839,15 +831,7 @@
* @return the larger of {@code a} and {@code b}.
*/
public static double max(double a, double b) {
- if (a != a)
- return a; // a is NaN
- if ((a == 0.0d) &&
- (b == 0.0d) &&
- (Double.doubleToRawLongBits(a) == negativeZeroDoubleBits)) {
- // Raw conversion ok since NaN can't map to -0.0.
- return b;
- }
- return (a >= b) ? a : b;
+ return Math.max(a, b);
}
/**
@@ -861,7 +845,7 @@
* @return the smaller of {@code a} and {@code b}.
*/
public static int min(int a, int b) {
- return (a <= b) ? a : b;
+ return Math.min(a, b);
}
/**
@@ -875,7 +859,7 @@
* @return the smaller of {@code a} and {@code b}.
*/
public static long min(long a, long b) {
- return (a <= b) ? a : b;
+ return Math.min(a, b);
}
/**
@@ -893,15 +877,7 @@
* @return the smaller of {@code a} and {@code b.}
*/
public static float min(float a, float b) {
- if (a != a)
- return a; // a is NaN
- if ((a == 0.0f) &&
- (b == 0.0f) &&
- (Float.floatToRawIntBits(b) == negativeZeroFloatBits)) {
- // Raw conversion ok since NaN can't map to -0.0.
- return b;
- }
- return (a <= b) ? a : b;
+ return Math.min(a, b);
}
/**
@@ -919,15 +895,7 @@
* @return the smaller of {@code a} and {@code b}.
*/
public static double min(double a, double b) {
- if (a != a)
- return a; // a is NaN
- if ((a == 0.0d) &&
- (b == 0.0d) &&
- (Double.doubleToRawLongBits(b) == negativeZeroDoubleBits)) {
- // Raw conversion ok since NaN can't map to -0.0.
- return b;
- }
- return (a <= b) ? a : b;
+ return Math.min(a, b);
}
/**
--- a/jdk/src/share/classes/java/lang/Throwable.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/java/lang/Throwable.java Sat Jan 28 22:21:54 2012 -0800
@@ -625,7 +625,7 @@
* at Resource2.close(Resource2.java:20)
* at Foo4.main(Foo4.java:5)
* Caused by: java.lang.Exception: Rats, you caught me
- * at Resource2$CloseFailException.<init>(Resource2.java:45)
+ * at Resource2$CloseFailException.<init>(Resource2.java:45)
* ... 2 more
* </pre>
*/
--- a/jdk/src/share/classes/java/lang/invoke/AdapterMethodHandle.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/AdapterMethodHandle.java Sat Jan 28 22:21:54 2012 -0800
@@ -378,6 +378,7 @@
}
/** Construct an adapter conversion descriptor for a single-argument conversion. */
+ @SuppressWarnings("cast") // some (int) casts below provide clarity but trigger warnings
private static long makeConv(int convOp, int argnum, int src, int dest) {
assert(src == (src & CONV_TYPE_MASK));
assert(dest == (dest & CONV_TYPE_MASK));
@@ -390,6 +391,7 @@
insertStackMove(stackMove)
);
}
+ @SuppressWarnings("cast") // some (int) casts below provide clarity but trigger warnings
private static long makeDupConv(int convOp, int argnum, int stackMove) {
// simple argument motion, requiring one slot to specify
assert(convOp == OP_DUP_ARGS || convOp == OP_DROP_ARGS);
@@ -401,6 +403,7 @@
insertStackMove(stackMove)
);
}
+ @SuppressWarnings("cast") // some (int) casts below provide clarity but trigger warnings
private static long makeSwapConv(int convOp, int srcArg, byte srcType, int destSlot, byte destType) {
// more complex argument motion, requiring two slots to specify
assert(convOp == OP_SWAP_ARGS || convOp == OP_ROT_ARGS);
@@ -411,6 +414,7 @@
(int) destSlot << CONV_VMINFO_SHIFT
);
}
+ @SuppressWarnings("cast") // some (int) casts below provide clarity but trigger warnings
private static long makeSpreadConv(int convOp, int argnum, int src, int dest, int stackMove) {
// spreading or collecting, at a particular slot location
assert(convOp == OP_SPREAD_ARGS || convOp == OP_COLLECT_ARGS || convOp == OP_FOLD_ARGS);
--- a/jdk/src/share/classes/java/lang/invoke/MemberName.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/MemberName.java Sat Jan 28 22:21:54 2012 -0800
@@ -353,7 +353,7 @@
assert(isResolved());
}
/** Create a name for the given reflected constructor. The resulting name will be in a resolved state. */
- public MemberName(Constructor ctor) {
+ public MemberName(Constructor<?> ctor) {
Object[] typeInfo = { void.class, ctor.getParameterTypes() };
init(ctor.getDeclaringClass(), CONSTRUCTOR_NAME, typeInfo, flagsMods(IS_CONSTRUCTOR, ctor.getModifiers()));
// fill in vmtarget, vmindex while we have ctor in hand:
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java Sat Jan 28 22:21:54 2012 -0800
@@ -275,7 +275,7 @@
* generates a single invokevirtual instruction with
* the symbolic type descriptor indicated in the following comment.
* In these examples, the helper method {@code assertEquals} is assumed to
- * be a method which calls {@link Objects.equals java.util.Objects#equals}
+ * be a method which calls {@link java.util.Objects#equals(Object,Object) Objects.equals }
* on its arguments, and asserts that the result is true.
*
* <h3>Exceptions</h3>
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java Sat Jan 28 22:21:54 2012 -0800
@@ -112,7 +112,7 @@
assert(cookedConstructor.type().equals(ctype));
ctype = ctype.dropParameterTypes(0, 1);
cookedConstructor = AdapterMethodHandle.makeCollectArguments(cookedConstructor, returner, 0, true);
- MethodHandle allocator = new AllocateObject(allocateClass);
+ AllocateObject allocator = new AllocateObject(allocateClass);
// allocate() => new C(void)
assert(allocator.type().equals(MethodType.methodType(allocateClass)));
ctype = ctype.dropParameterTypes(0, 1);
@@ -120,19 +120,19 @@
return fold;
}
- static final class AllocateObject<C> extends BoundMethodHandle {
+ static final class AllocateObject /*<C>*/ extends BoundMethodHandle {
private static final Unsafe unsafe = Unsafe.getUnsafe();
- private final Class<C> allocateClass;
+ private final Class<?> /*<C>*/ allocateClass;
// for allocation only:
- private AllocateObject(Class<C> allocateClass) {
+ private AllocateObject(Class<?> /*<C>*/ allocateClass) {
super(ALLOCATE.asType(MethodType.methodType(allocateClass, AllocateObject.class)));
this.allocateClass = allocateClass;
}
@SuppressWarnings("unchecked")
- private C allocate() throws InstantiationException {
- return (C) unsafe.allocateInstance(allocateClass);
+ private Object /*C*/ allocate() throws InstantiationException {
+ return unsafe.allocateInstance(allocateClass);
}
static final MethodHandle ALLOCATE;
static {
@@ -148,8 +148,8 @@
MethodHandle accessField(MemberName member, boolean isSetter,
Class<?> lookupClass) {
// Use sun. misc.Unsafe to dig up the dirt on the field.
- MethodHandle mh = new FieldAccessor(member, isSetter);
- return mh;
+ FieldAccessor accessor = new FieldAccessor(member, isSetter);
+ return accessor;
}
static
@@ -175,7 +175,7 @@
return mhs[isSetter ? 1 : 0];
}
- static final class FieldAccessor<C,V> extends BoundMethodHandle {
+ static final class FieldAccessor /*<C,V>*/ extends BoundMethodHandle {
private static final Unsafe unsafe = Unsafe.getUnsafe();
final Object base; // for static refs only
final long offset;
@@ -190,26 +190,24 @@
@Override
String debugString() { return addTypeString(name, this); }
- int getFieldI(C obj) { return unsafe.getInt(obj, offset); }
- void setFieldI(C obj, int x) { unsafe.putInt(obj, offset, x); }
- long getFieldJ(C obj) { return unsafe.getLong(obj, offset); }
- void setFieldJ(C obj, long x) { unsafe.putLong(obj, offset, x); }
- float getFieldF(C obj) { return unsafe.getFloat(obj, offset); }
- void setFieldF(C obj, float x) { unsafe.putFloat(obj, offset, x); }
- double getFieldD(C obj) { return unsafe.getDouble(obj, offset); }
- void setFieldD(C obj, double x) { unsafe.putDouble(obj, offset, x); }
- boolean getFieldZ(C obj) { return unsafe.getBoolean(obj, offset); }
- void setFieldZ(C obj, boolean x) { unsafe.putBoolean(obj, offset, x); }
- byte getFieldB(C obj) { return unsafe.getByte(obj, offset); }
- void setFieldB(C obj, byte x) { unsafe.putByte(obj, offset, x); }
- short getFieldS(C obj) { return unsafe.getShort(obj, offset); }
- void setFieldS(C obj, short x) { unsafe.putShort(obj, offset, x); }
- char getFieldC(C obj) { return unsafe.getChar(obj, offset); }
- void setFieldC(C obj, char x) { unsafe.putChar(obj, offset, x); }
- @SuppressWarnings("unchecked")
- V getFieldL(C obj) { return (V) unsafe.getObject(obj, offset); }
- @SuppressWarnings("unchecked")
- void setFieldL(C obj, V x) { unsafe.putObject(obj, offset, x); }
+ int getFieldI(Object /*C*/ obj) { return unsafe.getInt(obj, offset); }
+ void setFieldI(Object /*C*/ obj, int x) { unsafe.putInt(obj, offset, x); }
+ long getFieldJ(Object /*C*/ obj) { return unsafe.getLong(obj, offset); }
+ void setFieldJ(Object /*C*/ obj, long x) { unsafe.putLong(obj, offset, x); }
+ float getFieldF(Object /*C*/ obj) { return unsafe.getFloat(obj, offset); }
+ void setFieldF(Object /*C*/ obj, float x) { unsafe.putFloat(obj, offset, x); }
+ double getFieldD(Object /*C*/ obj) { return unsafe.getDouble(obj, offset); }
+ void setFieldD(Object /*C*/ obj, double x) { unsafe.putDouble(obj, offset, x); }
+ boolean getFieldZ(Object /*C*/ obj) { return unsafe.getBoolean(obj, offset); }
+ void setFieldZ(Object /*C*/ obj, boolean x) { unsafe.putBoolean(obj, offset, x); }
+ byte getFieldB(Object /*C*/ obj) { return unsafe.getByte(obj, offset); }
+ void setFieldB(Object /*C*/ obj, byte x) { unsafe.putByte(obj, offset, x); }
+ short getFieldS(Object /*C*/ obj) { return unsafe.getShort(obj, offset); }
+ void setFieldS(Object /*C*/ obj, short x) { unsafe.putShort(obj, offset, x); }
+ char getFieldC(Object /*C*/ obj) { return unsafe.getChar(obj, offset); }
+ void setFieldC(Object /*C*/ obj, char x) { unsafe.putChar(obj, offset, x); }
+ Object /*V*/ getFieldL(Object /*C*/ obj) { return unsafe.getObject(obj, offset); }
+ void setFieldL(Object /*C*/ obj, Object /*V*/ x) { unsafe.putObject(obj, offset, x); }
// cast (V) is OK here, since we wrap convertArguments around the MH.
static Object staticBase(final MemberName field) {
@@ -244,8 +242,9 @@
void setStaticS(short x) { unsafe.putShort(base, offset, x); }
char getStaticC() { return unsafe.getChar(base, offset); }
void setStaticC(char x) { unsafe.putChar(base, offset, x); }
- V getStaticL() { return (V) unsafe.getObject(base, offset); }
- void setStaticL(V x) { unsafe.putObject(base, offset, x); }
+ @SuppressWarnings("unchecked") // (V) is for internal clarity but triggers warning
+ Object /*V*/ getStaticL() { return unsafe.getObject(base, offset); }
+ void setStaticL(Object /*V*/ x) { unsafe.putObject(base, offset, x); }
static String fname(Class<?> vclass, boolean isSetter, boolean isStatic) {
String stem;
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java Sat Jan 28 22:21:54 2012 -0800
@@ -150,7 +150,7 @@
}
return intfc.cast(Proxy.newProxyInstance(
intfc.getClassLoader(),
- new Class[]{ intfc, WrapperInstance.class },
+ new Class<?>[]{ intfc, WrapperInstance.class },
new InvocationHandler() {
private Object getArg(String name) {
if ((Object)name == "getWrapperInstanceTarget") return target;
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java Sat Jan 28 22:21:54 2012 -0800
@@ -948,10 +948,11 @@
public MethodHandle unreflect(Method m) throws IllegalAccessException {
MemberName method = new MemberName(m);
assert(method.isMethod());
- if (!m.isAccessible()) checkMethod(method.getDeclaringClass(), method, method.isStatic());
+ if (m.isAccessible())
+ return MethodHandleImpl.findMethod(method, true, /*no lookupClass*/ null);
+ checkMethod(method.getDeclaringClass(), method, method.isStatic());
MethodHandle mh = MethodHandleImpl.findMethod(method, true, lookupClassOrNull());
- if (!m.isAccessible()) mh = restrictProtectedReceiver(method, mh);
- return mh;
+ return restrictProtectedReceiver(method, mh);
}
/**
@@ -1006,11 +1007,17 @@
* is set and {@code asVarargsCollector} fails
* @throws NullPointerException if the argument is null
*/
+ @SuppressWarnings("rawtypes") // Will be Constructor<?> after JSR 292 MR
public MethodHandle unreflectConstructor(Constructor c) throws IllegalAccessException {
MemberName ctor = new MemberName(c);
assert(ctor.isConstructor());
- if (!c.isAccessible()) checkAccess(c.getDeclaringClass(), ctor);
- MethodHandle rawCtor = MethodHandleImpl.findMethod(ctor, false, lookupClassOrNull());
+ MethodHandle rawCtor;
+ if (c.isAccessible()) {
+ rawCtor = MethodHandleImpl.findMethod(ctor, false, /*no lookupClass*/ null);
+ } else {
+ checkAccess(c.getDeclaringClass(), ctor);
+ rawCtor = MethodHandleImpl.findMethod(ctor, false, lookupClassOrNull());
+ }
MethodHandle allocator = MethodHandleImpl.makeAllocator(rawCtor);
return fixVarargs(allocator, rawCtor);
}
@@ -1225,7 +1232,7 @@
? "expected a static field"
: "expected a non-static field", this);
if (trusted)
- return MethodHandleImpl.accessField(field, isSetter, lookupClassOrNull());
+ return MethodHandleImpl.accessField(field, isSetter, /*no lookupClass*/ null);
checkAccess(refc, field);
MethodHandle mh = MethodHandleImpl.accessField(field, isSetter, lookupClassOrNull());
return restrictProtectedReceiver(field, mh);
--- a/jdk/src/share/classes/java/nio/file/FileTreeWalker.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/java/nio/file/FileTreeWalker.java Sat Jan 28 22:21:54 2012 -0800
@@ -92,7 +92,7 @@
(System.getSecurityManager() == null))
{
BasicFileAttributes cached = ((BasicFileAttributesHolder)file).get();
- if (!followLinks || !cached.isSymbolicLink())
+ if (cached != null && (!followLinks || !cached.isSymbolicLink()))
attrs = cached;
}
IOException exc = null;
--- a/jdk/src/share/classes/java/nio/file/Files.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/java/nio/file/Files.java Sat Jan 28 22:21:54 2012 -0800
@@ -1431,7 +1431,7 @@
* <li>It is <i>transitive</i>: for three {@code Paths}
* {@code f}, {@code g}, and {@code h}, if {@code isSameFile(f,g)} returns
* {@code true} and {@code isSameFile(g,h)} returns {@code true}, then
- * {@code isSameFile(g,h)} will return return {@code true}.
+ * {@code isSameFile(f,h)} will return return {@code true}.
* </ul>
*
* @param path
--- a/jdk/src/share/classes/java/nio/file/Path.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/java/nio/file/Path.java Sat Jan 28 22:21:54 2012 -0800
@@ -72,7 +72,7 @@
* directory and is UTF-8 encoded.
* <pre>
* Path path = FileSystems.getDefault().getPath("logs", "access.log");
- * BufferReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8);
+ * BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8);
* </pre>
*
* <a name="interop"><h4>Interoperability</h4></a>
--- a/jdk/src/share/classes/sun/invoke/util/ValueConversions.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/invoke/util/ValueConversions.java Sat Jan 28 22:21:54 2012 -0800
@@ -55,9 +55,9 @@
private static final Lookup IMPL_LOOKUP = MethodHandles.lookup();
private static EnumMap<Wrapper, MethodHandle>[] newWrapperCaches(int n) {
- @SuppressWarnings("unchecked")
+ @SuppressWarnings("unchecked") // generic array creation
EnumMap<Wrapper, MethodHandle>[] caches
- = (EnumMap<Wrapper, MethodHandle>[]) new EnumMap[n]; // unchecked warning expected here
+ = (EnumMap<Wrapper, MethodHandle>[]) new EnumMap<?,?>[n];
for (int i = 0; i < n; i++)
caches[i] = new EnumMap<>(Wrapper.class);
return caches;
@@ -1097,7 +1097,7 @@
}
private static MethodHandle buildNewArray(int nargs) {
- return MethodHandles.insertArguments(NEW_ARRAY, 0, (int) nargs);
+ return MethodHandles.insertArguments(NEW_ARRAY, 0, nargs);
}
private static final MethodHandle[] FILLERS = new MethodHandle[MAX_ARITY+1];
@@ -1122,7 +1122,7 @@
}
MethodHandle leftFill = filler(leftLen); // recursive fill
MethodHandle rightFill = FILL_ARRAYS[rightLen];
- rightFill = MethodHandles.insertArguments(rightFill, 1, (int) leftLen); // [leftLen..nargs-1]
+ rightFill = MethodHandles.insertArguments(rightFill, 1, leftLen); // [leftLen..nargs-1]
// Combine the two fills: right(left(newArray(nargs), x1..x20), x21..x23)
MethodHandle mh = filler(0); // identity function produces result
--- a/jdk/src/share/classes/sun/invoke/util/Wrapper.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/invoke/util/Wrapper.java Sat Jan 28 22:21:54 2012 -0800
@@ -31,7 +31,7 @@
BYTE(Byte.class, byte.class, 'B', (Byte)(byte)0, new byte[0], Format.signed(8)),
SHORT(Short.class, short.class, 'S', (Short)(short)0, new short[0], Format.signed(16)),
CHAR(Character.class, char.class, 'C', (Character)(char)0, new char[0], Format.unsigned(16)),
- INT(Integer.class, int.class, 'I', (Integer)(int)0, new int[0], Format.signed(32)),
+ INT(Integer.class, int.class, 'I', (Integer)/*(int)*/0, new int[0], Format.signed(32)),
LONG(Long.class, long.class, 'J', (Long)(long)0, new long[0], Format.signed(64)),
FLOAT(Float.class, float.class, 'F', (Float)(float)0, new float[0], Format.floating(32)),
DOUBLE(Double.class, double.class, 'D', (Double)(double)0, new double[0], Format.floating(64)),
@@ -539,7 +539,7 @@
switch (basicTypeChar) {
case 'L': throw newIllegalArgumentException("cannot wrap to object type");
case 'V': return null;
- case 'I': return Integer.valueOf((int)x);
+ case 'I': return Integer.valueOf(x);
case 'J': return Long.valueOf(x);
case 'F': return Float.valueOf(x);
case 'D': return Double.valueOf(x);
--- a/jdk/src/share/classes/sun/management/Agent.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/Agent.java Sat Jan 28 22:21:54 2012 -0800
@@ -216,11 +216,8 @@
adaptorClass.getMethod("initialize",
String.class, Properties.class);
initializeMethod.invoke(null,snmpPort,props);
- } catch (ClassNotFoundException x) {
- // The SNMP packages are not present: throws an exception.
- throw new UnsupportedOperationException("Unsupported management property: " + SNMP_PORT,x);
- } catch (NoSuchMethodException x) {
- // should not happen...
+ } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException x) {
+ // snmp runtime doesn't exist - initialization fails
throw new UnsupportedOperationException("Unsupported management property: " + SNMP_PORT,x);
} catch (InvocationTargetException x) {
final Throwable cause = x.getCause();
@@ -230,9 +227,6 @@
throw (Error) cause;
// should not happen...
throw new UnsupportedOperationException("Unsupported management property: " + SNMP_PORT,cause);
- } catch (IllegalAccessException x) {
- // should not happen...
- throw new UnsupportedOperationException("Unsupported management property: " + SNMP_PORT,x);
}
}
@@ -273,8 +267,8 @@
} catch (IOException e) {
error(CONFIG_FILE_CLOSE_FAILED, fname);
}
- }
- }
+ }
+ }
}
public static void startAgent() throws Exception {
@@ -309,7 +303,7 @@
// invoke the premain(String args) method
Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(cname);
Method premain = clz.getMethod("premain",
- new Class[] { String.class });
+ new Class<?>[] { String.class });
premain.invoke(null, /* static */
new Object[] { args });
} catch (ClassNotFoundException ex) {
--- a/jdk/src/share/classes/sun/management/ConnectorAddressLink.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/ConnectorAddressLink.java Sat Jan 28 22:21:54 2012 -0800
@@ -117,11 +117,11 @@
} catch (IllegalArgumentException iae) {
throw new IOException(iae.getMessage());
}
- List counters =
+ List<Counter> counters =
new PerfInstrumentation(bb).findByPattern(CONNECTOR_ADDRESS_COUNTER);
- Iterator i = counters.iterator();
+ Iterator<Counter> i = counters.iterator();
if (i.hasNext()) {
- Counter c = (Counter) i.next();
+ Counter c = i.next();
return (String) c.getValue();
} else {
return null;
@@ -167,13 +167,13 @@
} catch (IllegalArgumentException iae) {
throw new IOException(iae.getMessage());
}
- List counters = new PerfInstrumentation(bb).getAllCounters();
- Map<String, String> properties = new HashMap<String, String>();
- for (Object c : counters) {
- String name = ((Counter) c).getName();
+ List<Counter> counters = new PerfInstrumentation(bb).getAllCounters();
+ Map<String, String> properties = new HashMap<>();
+ for (Counter c : counters) {
+ String name = c.getName();
if (name.startsWith(REMOTE_CONNECTOR_COUNTER_PREFIX) &&
!name.equals(CONNECTOR_ADDRESS_COUNTER)) {
- properties.put(name, ((Counter) c).getValue().toString());
+ properties.put(name, c.getValue().toString());
}
}
return properties;
--- a/jdk/src/share/classes/sun/management/Flag.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/Flag.java Sat Jan 28 22:21:54 2012 -0800
@@ -91,7 +91,7 @@
Flag[] flags = new Flag[numFlags];
int count = getFlags(names, flags, numFlags);
- List<Flag> result = new ArrayList<Flag>();
+ List<Flag> result = new ArrayList<>();
for (Flag f : flags) {
if (f != null) {
result.add(f);
--- a/jdk/src/share/classes/sun/management/GarbageCollectionNotifInfoCompositeData.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/GarbageCollectionNotifInfoCompositeData.java Sat Jan 28 22:21:54 2012 -0800
@@ -69,11 +69,7 @@
Field f = cl.getDeclaredField("builder");
f.setAccessible(true);
return (GcInfoBuilder)f.get(gcNotifInfo.getGcInfo());
- } catch(ClassNotFoundException e) {
- return null;
- } catch(NoSuchFieldException e) {
- return null;
- } catch(IllegalAccessException e) {
+ } catch(ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
return null;
}
}
@@ -82,7 +78,7 @@
synchronized(compositeTypeByBuilder) {
gict = compositeTypeByBuilder.get(builder);
if(gict == null) {
- OpenType[] gcNotifInfoItemTypes = new OpenType[] {
+ OpenType<?>[] gcNotifInfoItemTypes = new OpenType<?>[] {
SimpleType.STRING,
SimpleType.STRING,
SimpleType.STRING,
@@ -141,7 +137,7 @@
GC_INFO
};
private static HashMap<GcInfoBuilder,CompositeType> compositeTypeByBuilder =
- new HashMap<GcInfoBuilder,CompositeType>();
+ new HashMap<>();
public static String getGcName(CompositeData cd) {
String gcname = getString(cd, GC_NAME);
@@ -195,7 +191,7 @@
private static synchronized CompositeType getBaseGcNotifInfoCompositeType() {
if (baseGcNotifInfoCompositeType == null) {
try {
- OpenType[] baseGcNotifInfoItemTypes = new OpenType[] {
+ OpenType<?>[] baseGcNotifInfoItemTypes = new OpenType<?>[] {
SimpleType.STRING,
SimpleType.STRING,
SimpleType.STRING,
--- a/jdk/src/share/classes/sun/management/GarbageCollectorImpl.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/GarbageCollectorImpl.java Sat Jan 28 22:21:54 2012 -0800
@@ -70,14 +70,11 @@
private String[] poolNames = null;
synchronized String[] getAllPoolNames() {
if (poolNames == null) {
- List pools = ManagementFactory.getMemoryPoolMXBeans();
+ List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();
poolNames = new String[pools.size()];
int i = 0;
- for (ListIterator iter = pools.listIterator();
- iter.hasNext();
- i++) {
- MemoryPoolMXBean p = (MemoryPoolMXBean) iter.next();
- poolNames[i] = p.getName();
+ for (MemoryPoolMXBean m : pools) {
+ poolNames[i++] = m.getName();
}
}
return poolNames;
--- a/jdk/src/share/classes/sun/management/GcInfoBuilder.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/GcInfoBuilder.java Sat Jan 28 22:21:54 2012 -0800
@@ -104,7 +104,7 @@
int itemCount = numGcInfoItems + gcExtItemCount;
allItemNames = new String[itemCount];
String[] allItemDescs = new String[itemCount];
- OpenType[] allItemTypes = new OpenType[itemCount];
+ OpenType<?>[] allItemTypes = new OpenType<?>[itemCount];
System.arraycopy(gcInfoItemNames, 0, allItemNames, 0, numGcInfoItems);
System.arraycopy(gcInfoItemNames, 0, allItemDescs, 0, numGcInfoItems);
--- a/jdk/src/share/classes/sun/management/GcInfoCompositeData.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/GcInfoCompositeData.java Sat Jan 28 22:21:54 2012 -0800
@@ -76,11 +76,7 @@
Field f = cl.getDeclaredField("builder");
f.setAccessible(true);
return (GcInfoBuilder)f.get(info);
- } catch(ClassNotFoundException e) {
- return null;
- } catch(NoSuchFieldException e) {
- return null;
- } catch(IllegalAccessException e) {
+ } catch(ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
return null;
}
}
@@ -92,11 +88,7 @@
Field f = cl.getDeclaredField("extAttributes");
f.setAccessible(true);
return (Object[])f.get(info);
- } catch(ClassNotFoundException e) {
- return null;
- } catch(NoSuchFieldException e) {
- return null;
- } catch(IllegalAccessException e) {
+ } catch(ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
return null;
}
}
@@ -180,10 +172,7 @@
Method m = GcInfo.class.getMethod("getMemoryUsageBeforeGc");
memoryUsageMapType =
MappedMXBeanType.getMappedType(m.getGenericReturnType());
- } catch (NoSuchMethodException e) {
- // Should never reach here
- throw new AssertionError(e);
- } catch (OpenDataException e) {
+ } catch (NoSuchMethodException | OpenDataException e) {
// Should never reach here
throw new AssertionError(e);
}
@@ -197,7 +186,7 @@
static synchronized OpenType[] getBaseGcInfoItemTypes() {
if (baseGcInfoItemTypes == null) {
OpenType<?> memoryUsageOpenType = memoryUsageMapType.getOpenType();
- baseGcInfoItemTypes = new OpenType[] {
+ baseGcInfoItemTypes = new OpenType<?>[] {
SimpleType.LONG,
SimpleType.LONG,
SimpleType.LONG,
@@ -225,10 +214,7 @@
try {
TabularData td = (TabularData) cd.get(MEMORY_USAGE_BEFORE_GC);
return cast(memoryUsageMapType.toJavaTypeData(td));
- } catch (InvalidObjectException e) {
- // Should never reach here
- throw new AssertionError(e);
- } catch (OpenDataException e) {
+ } catch (InvalidObjectException | OpenDataException e) {
// Should never reach here
throw new AssertionError(e);
}
@@ -244,10 +230,7 @@
TabularData td = (TabularData) cd.get(MEMORY_USAGE_AFTER_GC);
//return (Map<String,MemoryUsage>)
return cast(memoryUsageMapType.toJavaTypeData(td));
- } catch (InvalidObjectException e) {
- // Should never reach here
- throw new AssertionError(e);
- } catch (OpenDataException e) {
+ } catch (InvalidObjectException | OpenDataException e) {
// Should never reach here
throw new AssertionError(e);
}
--- a/jdk/src/share/classes/sun/management/HotSpotDiagnostic.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/HotSpotDiagnostic.java Sat Jan 28 22:21:54 2012 -0800
@@ -48,7 +48,7 @@
public List<VMOption> getDiagnosticOptions() {
List<Flag> allFlags = Flag.getAllFlags();
- List<VMOption> result = new ArrayList<VMOption>();
+ List<VMOption> result = new ArrayList<>();
for (Flag flag : allFlags) {
if (flag.isWriteable() && flag.isExternal()) {
result.add(flag.getVMOption());
--- a/jdk/src/share/classes/sun/management/HotspotCompilation.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/HotspotCompilation.java Sat Jan 28 22:21:54 2012 -0800
@@ -120,13 +120,13 @@
// current implementation. We first look up in the SUN_CI namespace
// since most counters are in SUN_CI namespace.
- if ((c = (Counter) counters.get(SUN_CI + name)) != null) {
+ if ((c = counters.get(SUN_CI + name)) != null) {
return c;
}
- if ((c = (Counter) counters.get(COM_SUN_CI + name)) != null) {
+ if ((c = counters.get(COM_SUN_CI + name)) != null) {
return c;
}
- if ((c = (Counter) counters.get(JAVA_CI + name)) != null) {
+ if ((c = counters.get(JAVA_CI + name)) != null) {
return c;
}
@@ -136,10 +136,8 @@
private void initCompilerCounters() {
// Build a tree map of the current list of performance counters
- ListIterator iter = getInternalCompilerCounters().listIterator();
- counters = new TreeMap<String, Counter>();
- while (iter.hasNext()) {
- Counter c = (Counter) iter.next();
+ counters = new TreeMap<>();
+ for (Counter c: getInternalCompilerCounters()) {
counters.put(c.getName(), c);
}
@@ -200,7 +198,7 @@
}
public java.util.List<CompilerThreadStat> getCompilerThreadStats() {
- List<CompilerThreadStat> list = new ArrayList<CompilerThreadStat>(threads.length);
+ List<CompilerThreadStat> list = new ArrayList<>(threads.length);
int i = 0;
if (threads[0] == null) {
// no adaptor thread
--- a/jdk/src/share/classes/sun/management/HotspotThread.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/HotspotThread.java Sat Jan 28 22:21:54 2012 -0800
@@ -58,7 +58,7 @@
String[] names = new String[count];
long[] times = new long[count];
int numThreads = getInternalThreadTimes0(names, times);
- Map<String, Long> result = new HashMap<String, Long>(numThreads);
+ Map<String, Long> result = new HashMap<>(numThreads);
for (int i = 0; i < numThreads; i++) {
result.put(names[i], new Long(times[i]));
}
--- a/jdk/src/share/classes/sun/management/LazyCompositeData.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/LazyCompositeData.java Sat Jan 28 22:21:54 2012 -0800
@@ -81,7 +81,7 @@
return compositeData().toString();
}
- public Collection values() {
+ public Collection<?> values() {
return compositeData().values();
}
@@ -153,16 +153,15 @@
// We can't use CompositeType.isValue() since it returns false
// if the type name doesn't match.
- Set allItems = type1.keySet();
+ Set<String> allItems = type1.keySet();
// Check all items in the type1 exist in type2
if (!type2.keySet().containsAll(allItems))
return false;
- for (Iterator iter = allItems.iterator(); iter.hasNext(); ) {
- String item = (String) iter.next();
- OpenType ot1 = type1.getType(item);
- OpenType ot2 = type2.getType(item);
+ for (String item: allItems) {
+ OpenType<?> ot1 = type1.getType(item);
+ OpenType<?> ot2 = type2.getType(item);
if (ot1 instanceof CompositeType) {
if (! (ot2 instanceof CompositeType))
return false;
@@ -183,8 +182,8 @@
protected static boolean isTypeMatched(TabularType type1, TabularType type2) {
if (type1 == type2) return true;
- List list1 = type1.getIndexNames();
- List list2 = type2.getIndexNames();
+ List<String> list1 = type1.getIndexNames();
+ List<String> list2 = type2.getIndexNames();
// check if the list of index names are the same
if (!list1.equals(list2))
--- a/jdk/src/share/classes/sun/management/ManagementFactoryHelper.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/ManagementFactoryHelper.java Sat Jan 28 22:21:54 2012 -0800
@@ -110,7 +110,7 @@
public static List<MemoryPoolMXBean> getMemoryPoolMXBeans() {
MemoryPoolMXBean[] pools = MemoryImpl.getMemoryPools();
- List<MemoryPoolMXBean> list = new ArrayList<MemoryPoolMXBean>(pools.length);
+ List<MemoryPoolMXBean> list = new ArrayList<>(pools.length);
for (MemoryPoolMXBean p : pools) {
list.add(p);
}
@@ -119,7 +119,7 @@
public static List<MemoryManagerMXBean> getMemoryManagerMXBeans() {
MemoryManagerMXBean[] mgrs = MemoryImpl.getMemoryManagers();
- List<MemoryManagerMXBean> result = new ArrayList<MemoryManagerMXBean>(mgrs.length);
+ List<MemoryManagerMXBean> result = new ArrayList<>(mgrs.length);
for (MemoryManagerMXBean m : mgrs) {
result.add(m);
}
@@ -128,7 +128,7 @@
public static List<GarbageCollectorMXBean> getGarbageCollectorMXBeans() {
MemoryManagerMXBean[] mgrs = MemoryImpl.getMemoryManagers();
- List<GarbageCollectorMXBean> result = new ArrayList<GarbageCollectorMXBean>(mgrs.length);
+ List<GarbageCollectorMXBean> result = new ArrayList<>(mgrs.length);
for (MemoryManagerMXBean m : mgrs) {
if (GarbageCollectorMXBean.class.isInstance(m)) {
result.add(GarbageCollectorMXBean.class.cast(m));
--- a/jdk/src/share/classes/sun/management/MappedMXBeanType.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/MappedMXBeanType.java Sat Jan 28 22:21:54 2012 -0800
@@ -62,18 +62,18 @@
@SuppressWarnings("unchecked")
public abstract class MappedMXBeanType {
private static final WeakHashMap<Type,MappedMXBeanType> convertedTypes =
- new WeakHashMap<Type,MappedMXBeanType>();
+ new WeakHashMap<>();
boolean isBasicType = false;
- OpenType openType = inProgress;
- Class mappedTypeClass;
+ OpenType<?> openType = inProgress;
+ Class<?> mappedTypeClass;
static synchronized MappedMXBeanType newMappedType(Type javaType)
throws OpenDataException {
MappedMXBeanType mt = null;
if (javaType instanceof Class) {
- final Class c = (Class) javaType;
+ final Class<?> c = (Class<?>) javaType;
if (c.isEnum()) {
mt = new EnumMXBeanType(c);
} else if (c.isArray()) {
@@ -85,7 +85,7 @@
final ParameterizedType pt = (ParameterizedType) javaType;
final Type rawType = pt.getRawType();
if (rawType instanceof Class) {
- final Class rc = (Class) rawType;
+ final Class<?> rc = (Class<?>) rawType;
if (rc == List.class) {
mt = new ListMXBeanType(pt);
} else if (rc == Map.class) {
@@ -106,7 +106,7 @@
}
// basic types do not require data mapping
- static synchronized MappedMXBeanType newBasicType(Class c, OpenType ot)
+ static synchronized MappedMXBeanType newBasicType(Class<?> c, OpenType<?> ot)
throws OpenDataException {
MappedMXBeanType mt = new BasicMXBeanType(c, ot);
convertedTypes.put(c, mt);
@@ -127,7 +127,7 @@
}
// Convert a class to an OpenType
- public static synchronized OpenType toOpenType(Type t)
+ public static synchronized OpenType<?> toOpenType(Type t)
throws OpenDataException {
MappedMXBeanType mt = getMappedType(t);
return mt.getOpenType();
@@ -152,7 +152,7 @@
}
// Return the mapped open type
- OpenType getOpenType() {
+ OpenType<?> getOpenType() {
return openType;
}
@@ -168,7 +168,7 @@
}
// Return the mapped open type
- Class getMappedTypeClass() {
+ Class<?> getMappedTypeClass() {
return mappedTypeClass;
}
@@ -192,8 +192,8 @@
// T <-> T (no conversion)
//
static class BasicMXBeanType extends MappedMXBeanType {
- final Class basicType;
- BasicMXBeanType(Class c, OpenType openType) {
+ final Class<?> basicType;
+ BasicMXBeanType(Class<?> c, OpenType<?> openType) {
this.basicType = c;
this.openType = openType;
this.mappedTypeClass = c;
@@ -228,7 +228,7 @@
//
static class EnumMXBeanType extends MappedMXBeanType {
final Class enumClass;
- EnumMXBeanType(Class c) {
+ EnumMXBeanType(Class<?> c) {
this.enumClass = c;
this.openType = STRING;
this.mappedTypeClass = String.class;
@@ -269,16 +269,16 @@
// E[] <-> openTypeData(E)[]
//
static class ArrayMXBeanType extends MappedMXBeanType {
- final Class arrayClass;
+ final Class<?> arrayClass;
protected MappedMXBeanType componentType;
protected MappedMXBeanType baseElementType;
- ArrayMXBeanType(Class c) throws OpenDataException {
+ ArrayMXBeanType(Class<?> c) throws OpenDataException {
this.arrayClass = c;
this.componentType = getMappedType(c.getComponentType());
StringBuilder className = new StringBuilder();
- Class et = c;
+ Class<?> et = c;
int dim;
for (dim = 0; et.isArray(); dim++) {
className.append('[');
@@ -299,7 +299,7 @@
throw ode;
}
- openType = new ArrayType(dim, baseElementType.getOpenType());
+ openType = new ArrayType<>(dim, baseElementType.getOpenType());
}
protected ArrayMXBeanType() {
@@ -395,7 +395,7 @@
throw ode;
}
- openType = new ArrayType(dim, baseElementType.getOpenType());
+ openType = new ArrayType<>(dim, baseElementType.getOpenType());
}
Type getJavaType() {
@@ -428,7 +428,7 @@
throw new OpenDataException("Element Type for " + pt +
" not supported");
}
- final Class et = (Class) argTypes[0];
+ final Class<?> et = (Class<?>) argTypes[0];
if (et.isArray()) {
throw new OpenDataException("Element Type for " + pt +
" not supported");
@@ -445,7 +445,7 @@
ode.initCause(e);
throw ode;
}
- openType = new ArrayType(1, paramType.getOpenType());
+ openType = new ArrayType<>(1, paramType.getOpenType());
}
Type getJavaType() {
@@ -473,7 +473,7 @@
throws OpenDataException, InvalidObjectException {
final Object[] openArray = (Object[]) data;
- List<Object> result = new ArrayList<Object>(openArray.length);
+ List<Object> result = new ArrayList<>(openArray.length);
for (Object o : openArray) {
result.add(paramType.toJavaTypeData(o));
}
@@ -514,7 +514,7 @@
// FIXME: generate typeName for generic
typeName = "Map<" + keyType.getName() + "," +
valueType.getName() + ">";
- final OpenType[] mapItemTypes = new OpenType[] {
+ final OpenType<?>[] mapItemTypes = new OpenType<?>[] {
keyType.getOpenType(),
valueType.getOpenType(),
};
@@ -543,7 +543,7 @@
final TabularData table = new TabularDataSupport(tabularType);
final CompositeType rowType = tabularType.getRowType();
- for (Map.Entry entry : map.entrySet()) {
+ for (Map.Entry<Object, Object> entry : map.entrySet()) {
final Object key = keyType.toOpenTypeData(entry.getKey());
final Object value = valueType.toOpenTypeData(entry.getValue());
final CompositeData row =
@@ -560,7 +560,7 @@
final TabularData td = (TabularData) data;
- Map<Object, Object> result = new HashMap<Object, Object>();
+ Map<Object, Object> result = new HashMap<>();
for (CompositeData row : (Collection<CompositeData>) td.values()) {
Object key = keyType.toJavaTypeData(row.get(KEY));
Object value = valueType.toJavaTypeData(row.get(VALUE));
@@ -607,7 +607,7 @@
final boolean isCompositeData;
Method fromMethod = null;
- CompositeDataMXBeanType(Class c) throws OpenDataException {
+ CompositeDataMXBeanType(Class<?> c) throws OpenDataException {
this.javaClass = c;
this.mappedTypeClass = COMPOSITE_DATA_CLASS;
@@ -639,8 +639,8 @@
return javaClass.getMethods();
}
});
- final List<String> names = new ArrayList<String>();
- final List<OpenType> types = new ArrayList<OpenType>();
+ final List<String> names = new ArrayList<>();
+ final List<OpenType<?>> types = new ArrayList<>();
/* Select public methods that look like "T getX()" or "boolean
isX()", where T is not void and X is not the empty
@@ -678,7 +678,7 @@
c.getName(),
nameArray, // field names
nameArray, // field descriptions
- types.toArray(new OpenType[0]));
+ types.toArray(new OpenType<?>[0]));
}
}
@@ -722,7 +722,7 @@
// so that no other classes are sent over the wire
CompositeData cd = (CompositeData) data;
CompositeType ct = cd.getCompositeType();
- String[] itemNames = (String[]) ct.keySet().toArray(new String[0]);
+ String[] itemNames = ct.keySet().toArray(new String[0]);
Object[] itemValues = cd.getAll(itemNames);
return new CompositeDataSupport(ct, itemNames, itemValues);
}
@@ -779,9 +779,9 @@
}
private static final long serialVersionUID = -3413063475064374490L;
}
- private static final OpenType inProgress;
+ private static final OpenType<?> inProgress;
static {
- OpenType t;
+ OpenType<?> t;
try {
t = new InProgress();
} catch (OpenDataException e) {
@@ -799,8 +799,8 @@
static {
try {
for (int i = 0; i < simpleTypes.length; i++) {
- final OpenType t = simpleTypes[i];
- Class c;
+ final OpenType<?> t = simpleTypes[i];
+ Class<?> c;
try {
c = Class.forName(t.getClassName(), false,
String.class.getClassLoader());
@@ -816,7 +816,7 @@
if (c.getName().startsWith("java.lang.")) {
try {
final Field typeField = c.getField("TYPE");
- final Class primitiveType = (Class) typeField.get(null);
+ final Class<?> primitiveType = (Class<?>) typeField.get(null);
MappedMXBeanType.newBasicType(primitiveType, t);
} catch (NoSuchFieldException e) {
// OK: must not be a primitive wrapper
--- a/jdk/src/share/classes/sun/management/MonitorInfoCompositeData.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/MonitorInfoCompositeData.java Sat Jan 28 22:21:54 2012 -0800
@@ -92,7 +92,7 @@
monitorInfoCompositeType = (CompositeType)
MappedMXBeanType.toOpenType(MonitorInfo.class);
Set<String> s = monitorInfoCompositeType.keySet();
- monitorInfoItemNames = (String[]) s.toArray(new String[0]);
+ monitorInfoItemNames = s.toArray(new String[0]);
} catch (OpenDataException e) {
// Should never reach here
throw new AssertionError(e);
--- a/jdk/src/share/classes/sun/management/NotificationEmitterSupport.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/NotificationEmitterSupport.java Sat Jan 28 22:21:54 2012 -0800
@@ -71,7 +71,7 @@
efficient solution would be to clone the listener list
every time a notification is sent. */
synchronized (listenerLock) {
- List<ListenerInfo> newList = new ArrayList<ListenerInfo>(listenerList.size() + 1);
+ List<ListenerInfo> newList = new ArrayList<>(listenerList.size() + 1);
newList.addAll(listenerList);
newList.add(new ListenerInfo(listener, filter, handback));
listenerList = newList;
@@ -82,12 +82,12 @@
throws ListenerNotFoundException {
synchronized (listenerLock) {
- List<ListenerInfo> newList = new ArrayList<ListenerInfo>(listenerList);
+ List<ListenerInfo> newList = new ArrayList<>(listenerList);
/* We scan the list of listeners in reverse order because
in forward order we would have to repeat the loop with
the same index after a remove. */
for (int i=newList.size()-1; i>=0; i--) {
- ListenerInfo li = (ListenerInfo)newList.get(i);
+ ListenerInfo li = newList.get(i);
if (li.listener == listener)
newList.remove(i);
@@ -106,10 +106,10 @@
boolean found = false;
synchronized (listenerLock) {
- List<ListenerInfo> newList = new ArrayList<ListenerInfo>(listenerList);
+ List<ListenerInfo> newList = new ArrayList<>(listenerList);
final int size = newList.size();
for (int i = 0; i < size; i++) {
- ListenerInfo li = (ListenerInfo) newList.get(i);
+ ListenerInfo li = newList.get(i);
if (li.listener == listener) {
found = true;
@@ -148,7 +148,7 @@
final int size = currentList.size();
for (int i = 0; i < size; i++) {
- ListenerInfo li = (ListenerInfo) currentList.get(i);
+ ListenerInfo li = currentList.get(i);
if (li.filter == null
|| li.filter.isNotificationEnabled(notification)) {
--- a/jdk/src/share/classes/sun/management/RuntimeImpl.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/RuntimeImpl.java Sat Jan 28 22:21:54 2012 -0800
@@ -128,7 +128,7 @@
public Map<String,String> getSystemProperties() {
Properties sysProps = System.getProperties();
- Map<String,String> map = new HashMap<String, String>();
+ Map<String,String> map = new HashMap<>();
// Properties.entrySet() does not include the entries in
// the default properties. So use Properties.stringPropertyNames()
--- a/jdk/src/share/classes/sun/management/ThreadInfoCompositeData.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/ThreadInfoCompositeData.java Sat Jan 28 22:21:54 2012 -0800
@@ -190,7 +190,7 @@
threadInfoV6Attributes.length;
String[] v5ItemNames = new String[numV5Attributes];
String[] v5ItemDescs = new String[numV5Attributes];
- OpenType[] v5ItemTypes = new OpenType[numV5Attributes];
+ OpenType<?>[] v5ItemTypes = new OpenType<?>[numV5Attributes];
int i = 0;
for (String n : itemNames) {
if (isV5Attribute(n)) {
--- a/jdk/src/share/classes/sun/management/counter/perf/PerfInstrumentation.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/counter/perf/PerfInstrumentation.java Sat Jan 28 22:21:54 2012 -0800
@@ -73,7 +73,7 @@
buffer.position(prologue.getEntryOffset());
nextEntry = buffer.position();
// rebuild all the counters
- map = new TreeMap<String, Counter>();
+ map = new TreeMap<>();
}
boolean hasNext() {
@@ -154,7 +154,7 @@
map.put(c.getName(), c);
}
}
- return new ArrayList<Counter>(map.values());
+ return new ArrayList<>(map.values());
}
public synchronized List<Counter> findByPattern(String patternString) {
@@ -167,7 +167,8 @@
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher("");
- List<Counter> matches = new ArrayList<Counter>();
+ List<Counter> matches = new ArrayList<>();
+
for (Map.Entry<String,Counter> me: map.entrySet()) {
String name = me.getKey();
--- a/jdk/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java Sat Jan 28 22:21:54 2012 -0800
@@ -234,14 +234,15 @@
"authenticated Subject is null");
}
final Set<Principal> principals = subject.getPrincipals();
- for (Principal p: principals) {
- if (properties.containsKey(p.getName())) {
+ for (Principal p1: principals) {
+ if (properties.containsKey(p1.getName())) {
return;
}
}
- final Set<String> principalsStr = new HashSet<String>();
- for (Principal p: principals) {
- principalsStr.add(p.getName());
+
+ final Set<String> principalsStr = new HashSet<>();
+ for (Principal p2: principals) {
+ principalsStr.add(p2.getName());
}
throw new SecurityException(
"Access denied! No entries found in the access file [" +
@@ -255,9 +256,9 @@
if (fname == null) {
return p;
}
- FileInputStream fin = new FileInputStream(fname);
- p.load(fin);
- fin.close();
+ try (FileInputStream fin = new FileInputStream(fname)) {
+ p.load(fin);
+ }
return p;
}
private final Map<String, Object> environment;
@@ -430,7 +431,7 @@
try {
// Export remote connector address and associated configuration
// properties to the instrumentation buffer.
- Map<String, String> properties = new HashMap<String, String>();
+ Map<String, String> properties = new HashMap<>();
properties.put("remoteAddress", url.toString());
properties.put("authenticate", useAuthenticationStr);
properties.put("ssl", useSslStr);
@@ -456,7 +457,7 @@
System.setProperty("java.rmi.server.randomIDs", "true");
// This RMI server should not keep the VM alive
- Map<String, Object> env = new HashMap<String, Object>();
+ Map<String, Object> env = new HashMap<>();
env.put(RMIExporter.EXPORTER_ATTRIBUTE, new PermanentExporter());
// The local connector server need only be available via the
@@ -599,12 +600,9 @@
try {
// Load the SSL keystore properties from the config file
Properties p = new Properties();
- InputStream in = new FileInputStream(sslConfigFileName);
- try {
+ try (InputStream in = new FileInputStream(sslConfigFileName)) {
BufferedInputStream bin = new BufferedInputStream(in);
p.load(bin);
- } finally {
- in.close();
}
String keyStore =
p.getProperty("javax.net.ssl.keyStore");
@@ -628,11 +626,8 @@
KeyStore ks = null;
if (keyStore != null) {
ks = KeyStore.getInstance(KeyStore.getDefaultType());
- FileInputStream ksfis = new FileInputStream(keyStore);
- try {
+ try (FileInputStream ksfis = new FileInputStream(keyStore)) {
ks.load(ksfis, keyStorePasswd);
- } finally {
- ksfis.close();
}
}
KeyManagerFactory kmf = KeyManagerFactory.getInstance(
@@ -642,11 +637,8 @@
KeyStore ts = null;
if (trustStore != null) {
ts = KeyStore.getInstance(KeyStore.getDefaultType());
- FileInputStream tsfis = new FileInputStream(trustStore);
- try {
+ try (FileInputStream tsfis = new FileInputStream(trustStore)) {
ts.load(tsfis, trustStorePasswd);
- } finally {
- tsfis.close();
}
}
TrustManagerFactory tmf = TrustManagerFactory.getInstance(
@@ -689,7 +681,7 @@
JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
- Map<String, Object> env = new HashMap<String, Object>();
+ Map<String, Object> env = new HashMap<>();
PermanentExporter exporter = new PermanentExporter();
--- a/jdk/src/share/classes/sun/management/snmp/AdaptorBootstrap.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/AdaptorBootstrap.java Sat Jan 28 22:21:54 2012 -0800
@@ -118,21 +118,22 @@
/**
* Retrieve the Trap Target List from the ACL file.
**/
+ @SuppressWarnings("unchecked")
private static List<NotificationTarget> getTargetList(InetAddressAcl acl,
int defaultTrapPort) {
final ArrayList<NotificationTarget> result =
- new ArrayList<NotificationTarget>();
+ new ArrayList<>();
if (acl != null) {
if (log.isDebugOn())
log.debug("getTargetList",Agent.getText("jmxremote.AdaptorBootstrap.getTargetList.processing"));
- final Enumeration td=acl.getTrapDestinations();
+ final Enumeration td = acl.getTrapDestinations();
for (; td.hasMoreElements() ;) {
final InetAddress targetAddr = (InetAddress)td.nextElement();
final Enumeration tc =
acl.getTrapCommunities(targetAddr);
for (;tc.hasMoreElements() ;) {
- final String community = (String) tc.nextElement();
+ final String community = (String)tc.nextElement();
final NotificationTarget target =
new NotificationTargetImpl(targetAddr,
defaultTrapPort,
--- a/jdk/src/share/classes/sun/management/snmp/jvminstr/JVM_MANAGEMENT_MIB_IMPL.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvminstr/JVM_MANAGEMENT_MIB_IMPL.java Sat Jan 28 22:21:54 2012 -0800
@@ -90,14 +90,14 @@
SnmpOidTable table = null;
if(tableRef == null) {
table = new JVM_MANAGEMENT_MIBOidTable();
- tableRef = new WeakReference<SnmpOidTable>(table);
+ tableRef = new WeakReference<>(table);
return table;
}
table = tableRef.get();
if(table == null) {
table = new JVM_MANAGEMENT_MIBOidTable();
- tableRef = new WeakReference<SnmpOidTable>(table);
+ tableRef = new WeakReference<>(table);
}
return table;
@@ -198,7 +198,7 @@
* List of notification targets.
*/
private ArrayList<NotificationTarget> notificationTargets =
- new ArrayList<NotificationTarget>();
+ new ArrayList<>();
private final NotificationEmitter emitter;
private final NotificationHandler handler;
@@ -215,7 +215,7 @@
}
private synchronized void sendTrap(SnmpOid trap, SnmpVarBindList list) {
- final Iterator iterator = notificationTargets.iterator();
+ final Iterator<NotificationTarget> iterator = notificationTargets.iterator();
final SnmpAdaptorServer adaptor =
(SnmpAdaptorServer) getSnmpAdaptor();
@@ -232,7 +232,7 @@
while(iterator.hasNext()) {
NotificationTarget target = null;
try {
- target = (NotificationTarget) iterator.next();
+ target = iterator.next();
SnmpPeer peer =
new SnmpPeer(target.getAddress(), target.getPort());
SnmpParameters p = new SnmpParameters();
--- a/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmMemGCTableMetaImpl.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmMemGCTableMetaImpl.java Sat Jan 28 22:21:54 2012 -0800
@@ -58,6 +58,8 @@
*/
public class JvmMemGCTableMetaImpl extends JvmMemGCTableMeta {
+ static final long serialVersionUID = 8250461197108867607L;
+
/**
* This class acts as a filter over the SnmpTableHandler
* used for the JvmMemoryManagerTable. It filters out
--- a/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmMemManagerTableMetaImpl.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmMemManagerTableMetaImpl.java Sat Jan 28 22:21:54 2012 -0800
@@ -61,12 +61,17 @@
*/
public class JvmMemManagerTableMetaImpl extends JvmMemManagerTableMeta {
+ static final long serialVersionUID = 36176771566817592L;
+
/**
* A concrete implementation of {@link SnmpNamedListTableCache}, for the
* jvmMemManagerTable.
**/
private static class JvmMemManagerTableCache
extends SnmpNamedListTableCache {
+
+ static final long serialVersionUID = 6564294074653009240L;
+
/**
* Create a weak cache for the jvmMemManagerTable.
* @param validity validity of the cached data, in ms.
@@ -87,7 +92,7 @@
* <code>MemoryManagerMXBean</code> in the list.
* @return <code>((MemoryManagerMXBean)item).getName()</code>
**/
- protected String getKey(Object context, List rawDatas,
+ protected String getKey(Object context, List<?> rawDatas,
int rank, Object item) {
if (item == null) return null;
final String name = ((MemoryManagerMXBean)item).getName();
@@ -99,7 +104,7 @@
* Call <code>getTableHandler(JvmContextFactory.getUserData())</code>.
**/
public SnmpTableHandler getTableHandler() {
- final Map userData = JvmContextFactory.getUserData();
+ final Map<Object, Object> userData = JvmContextFactory.getUserData();
return getTableDatas(userData);
}
@@ -114,7 +119,7 @@
* Call ManagementFactory.getMemoryManagerMXBeans() to
* load the raw data of this table.
**/
- protected List loadRawDatas(Map userData) {
+ protected List<MemoryManagerMXBean> loadRawDatas(Map<Object, Object> userData) {
return ManagementFactory.getMemoryManagerMXBeans();
}
--- a/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmMemMgrPoolRelTableMetaImpl.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmMemMgrPoolRelTableMetaImpl.java Sat Jan 28 22:21:54 2012 -0800
@@ -64,13 +64,17 @@
public class JvmMemMgrPoolRelTableMetaImpl extends JvmMemMgrPoolRelTableMeta
implements Serializable {
+ static final long serialVersionUID = 1896509775012355443L;
+
/**
* A concrete implementation of {@link SnmpTableCache}, for the
* jvmMemMgrPoolRelTable.
**/
+
private static class JvmMemMgrPoolRelTableCache
extends SnmpTableCache {
+ static final long serialVersionUID = 6059937161990659184L;
final private JvmMemMgrPoolRelTableMetaImpl meta;
/**
@@ -87,7 +91,7 @@
* Call <code>getTableDatas(JvmContextFactory.getUserData())</code>.
**/
public SnmpTableHandler getTableHandler() {
- final Map userData = JvmContextFactory.getUserData();
+ final Map<Object,Object> userData = JvmContextFactory.getUserData();
return getTableDatas(userData);
}
@@ -101,7 +105,7 @@
return buildPoolIndexMap((SnmpCachedData)handler);
// not optimizable... too bad.
- final Map<String, SnmpOid> m = new HashMap<String, SnmpOid>();
+ final Map<String, SnmpOid> m = new HashMap<>();
SnmpOid index=null;
while ((index = handler.getNext(index))!=null) {
final MemoryPoolMXBean mpm =
@@ -124,7 +128,7 @@
final SnmpOid[] indexes = cached.indexes;
final Object[] datas = cached.datas;
final int len = indexes.length;
- final Map<String, SnmpOid> m = new HashMap<String, SnmpOid>(len);
+ final Map<String, SnmpOid> m = new HashMap<>(len);
for (int i=0; i<len; i++) {
final SnmpOid index = indexes[i];
if (index == null) continue;
@@ -165,13 +169,13 @@
final long time = System.currentTimeMillis();
// Build a Map poolname -> index
- final Map poolIndexMap = buildPoolIndexMap(mpHandler);
+ final Map<String,SnmpOid> poolIndexMap = buildPoolIndexMap(mpHandler);
// For each memory manager, get the list of memory pools
// For each memory pool, find its index in the memory pool table
// Create a row in the relation table.
final TreeMap<SnmpOid, Object> table =
- new TreeMap<SnmpOid, Object>(SnmpCachedData.oidComparator);
+ new TreeMap<>(SnmpCachedData.oidComparator);
updateTreeMap(table,userData,mmHandler,mpHandler,poolIndexMap);
return new SnmpCachedData(time,table);
@@ -207,7 +211,7 @@
protected void updateTreeMap(TreeMap<SnmpOid, Object> table, Object userData,
MemoryManagerMXBean mmm,
SnmpOid mmIndex,
- Map poolIndexMap) {
+ Map<String, SnmpOid> poolIndexMap) {
// The MemoryManager index is an int, so it's the first
// and only subidentifier.
@@ -230,7 +234,7 @@
for (int i = 0; i < mpList.length; i++) {
final String mpmName = mpList[i];
if (mpmName == null) continue;
- final SnmpOid mpIndex = (SnmpOid)poolIndexMap.get(mpmName);
+ final SnmpOid mpIndex = poolIndexMap.get(mpmName);
if (mpIndex == null) continue;
// The MemoryPool index is an int, so it's the first
@@ -261,7 +265,7 @@
protected void updateTreeMap(TreeMap<SnmpOid, Object> table, Object userData,
SnmpTableHandler mmHandler,
SnmpTableHandler mpHandler,
- Map poolIndexMap) {
+ Map<String, SnmpOid> poolIndexMap) {
if (mmHandler instanceof SnmpCachedData) {
updateTreeMap(table,userData,(SnmpCachedData)mmHandler,
mpHandler,poolIndexMap);
@@ -280,7 +284,7 @@
protected void updateTreeMap(TreeMap<SnmpOid, Object> table, Object userData,
SnmpCachedData mmHandler,
SnmpTableHandler mpHandler,
- Map poolIndexMap) {
+ Map<String, SnmpOid> poolIndexMap) {
final SnmpOid[] indexes = mmHandler.indexes;
final Object[] datas = mmHandler.datas;
--- a/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmMemPoolTableMetaImpl.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmMemPoolTableMetaImpl.java Sat Jan 28 22:21:54 2012 -0800
@@ -61,11 +61,16 @@
*/
public class JvmMemPoolTableMetaImpl extends JvmMemPoolTableMeta {
+ static final long serialVersionUID = -2525820976094284957L;
+
/**
* A concrete implementation of {@link SnmpNamedListTableCache}, for the
* jvmMemPoolTable.
**/
private static class JvmMemPoolTableCache extends SnmpNamedListTableCache {
+
+ static final long serialVersionUID = -1755520683086760574L;
+
/**
* Create a weak cache for the jvmMemPoolTable.
* @param validity validity of the cached data, in ms.
@@ -86,7 +91,7 @@
* <code>MemoryPoolMXBean</code> in the list.
* @return <code>((MemoryPoolMXBean)item).getName()</code>
**/
- protected String getKey(Object context, List rawDatas,
+ protected String getKey(Object context, List<?> rawDatas,
int rank, Object item) {
if (item == null) return null;
final String name = ((MemoryPoolMXBean)item).getName();
@@ -98,7 +103,7 @@
* Call <code>getTableDatas(JvmContextFactory.getUserData())</code>.
**/
public SnmpTableHandler getTableHandler() {
- final Map userData = JvmContextFactory.getUserData();
+ final Map<Object, Object> userData = JvmContextFactory.getUserData();
return getTableDatas(userData);
}
@@ -113,7 +118,7 @@
* Call ManagementFactory.getMemoryPoolMXBeans() to
* load the raw data of this table.
**/
- protected List loadRawDatas(Map userData) {
+ protected List<MemoryPoolMXBean> loadRawDatas(Map<Object, Object> userData) {
return ManagementFactory.getMemoryPoolMXBeans();
}
}
--- a/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmMemoryImpl.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmMemoryImpl.java Sat Jan 28 22:21:54 2012 -0800
@@ -275,7 +275,7 @@
*/
public EnumJvmMemoryGCCall getJvmMemoryGCCall()
throws SnmpStatusException {
- final Map m = JvmContextFactory.getUserData();
+ final Map<Object,Object> m = JvmContextFactory.getUserData();
if (m != null) {
final EnumJvmMemoryGCCall cached
--- a/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmMemoryMetaImpl.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmMemoryMetaImpl.java Sat Jan 28 22:21:54 2012 -0800
@@ -50,6 +50,8 @@
* The class is used for representing SNMP metadata for the "JvmMemory" group.
*/
public class JvmMemoryMetaImpl extends JvmMemoryMeta {
+
+ static final long serialVersionUID = -6500448253825893071L;
/**
* Constructor for the metadata associated to "JvmMemory".
*/
--- a/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmOSImpl.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmOSImpl.java Sat Jan 28 22:21:54 2012 -0800
@@ -47,6 +47,8 @@
*/
public class JvmOSImpl implements JvmOSMBean, Serializable {
+ static final long serialVersionUID = 1839834731763310809L;
+
/**
* Constructor for the "JvmOS" group.
* If the group contains a table, the entries created through an
--- a/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRTBootClassPathEntryImpl.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRTBootClassPathEntryImpl.java Sat Jan 28 22:21:54 2012 -0800
@@ -44,6 +44,8 @@
public class JvmRTBootClassPathEntryImpl
implements JvmRTBootClassPathEntryMBean, Serializable {
+ static final long serialVersionUID = -2282652055235913013L;
+
private final String item;
private final int index;
--- a/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRTBootClassPathTableMetaImpl.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRTBootClassPathTableMetaImpl.java Sat Jan 28 22:21:54 2012 -0800
@@ -71,6 +71,8 @@
public class JvmRTBootClassPathTableMetaImpl
extends JvmRTBootClassPathTableMeta {
+ static final long serialVersionUID = -8659886610487538299L;
+
private SnmpTableCache cache;
/**
@@ -78,6 +80,7 @@
* JvmRTBootClassPathTable.
**/
private static class JvmRTBootClassPathTableCache extends SnmpTableCache {
+ static final long serialVersionUID = -2637458695413646098L;
private JvmRTBootClassPathTableMetaImpl meta;
JvmRTBootClassPathTableCache(JvmRTBootClassPathTableMetaImpl meta,
@@ -90,7 +93,7 @@
* Call <code>getTableDatas(JvmContextFactory.getUserData())</code>.
**/
public SnmpTableHandler getTableHandler() {
- final Map userData = JvmContextFactory.getUserData();
+ final Map<Object,Object> userData = JvmContextFactory.getUserData();
return getTableDatas(userData);
}
--- a/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRTClassPathEntryImpl.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRTClassPathEntryImpl.java Sat Jan 28 22:21:54 2012 -0800
@@ -44,6 +44,7 @@
public class JvmRTClassPathEntryImpl implements JvmRTClassPathEntryMBean,
Serializable {
+ static final long serialVersionUID = 8524792845083365742L;
private final String item;
private final int index;
--- a/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRTClassPathTableMetaImpl.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRTClassPathTableMetaImpl.java Sat Jan 28 22:21:54 2012 -0800
@@ -70,6 +70,8 @@
*/
public class JvmRTClassPathTableMetaImpl extends JvmRTClassPathTableMeta {
+ static final long serialVersionUID = -6914494148818455166L;
+
private SnmpTableCache cache;
/**
@@ -77,6 +79,7 @@
* JvmRTClassPathTable.
**/
private static class JvmRTClassPathTableCache extends SnmpTableCache {
+ static final long serialVersionUID = 3805032372592117315L;
private JvmRTClassPathTableMetaImpl meta;
JvmRTClassPathTableCache(JvmRTClassPathTableMetaImpl meta,
@@ -89,7 +92,7 @@
* Call <code>getTableDatas(JvmContextFactory.getUserData())</code>.
**/
public SnmpTableHandler getTableHandler() {
- final Map userData = JvmContextFactory.getUserData();
+ final Map<Object, Object> userData = JvmContextFactory.getUserData();
return getTableDatas(userData);
}
--- a/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRTInputArgsEntryImpl.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRTInputArgsEntryImpl.java Sat Jan 28 22:21:54 2012 -0800
@@ -44,6 +44,7 @@
public class JvmRTInputArgsEntryImpl implements JvmRTInputArgsEntryMBean,
Serializable {
+ static final long serialVersionUID = 1000306518436503395L;
private final String item;
private final int index;
--- a/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRTInputArgsTableMetaImpl.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRTInputArgsTableMetaImpl.java Sat Jan 28 22:21:54 2012 -0800
@@ -70,6 +70,7 @@
*/
public class JvmRTInputArgsTableMetaImpl extends JvmRTInputArgsTableMeta {
+ static final long serialVersionUID = -2083438094888099238L;
private SnmpTableCache cache;
/**
@@ -77,6 +78,8 @@
* JvmRTInputArgsTable.
**/
private static class JvmRTInputArgsTableCache extends SnmpTableCache {
+
+ static final long serialVersionUID = 1693751105464785192L;
private JvmRTInputArgsTableMetaImpl meta;
JvmRTInputArgsTableCache(JvmRTInputArgsTableMetaImpl meta,
@@ -89,7 +92,7 @@
* Call <code>getTableDatas(JvmContextFactory.getUserData())</code>.
**/
public SnmpTableHandler getTableHandler() {
- final Map userData = JvmContextFactory.getUserData();
+ final Map<Object,Object> userData = JvmContextFactory.getUserData();
return getTableDatas(userData);
}
--- a/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRTLibraryPathEntryImpl.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRTLibraryPathEntryImpl.java Sat Jan 28 22:21:54 2012 -0800
@@ -44,6 +44,7 @@
public class JvmRTLibraryPathEntryImpl implements JvmRTLibraryPathEntryMBean,
Serializable {
+ static final long serialVersionUID = -3322438153507369765L;
private final String item;
private final int index;
--- a/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRTLibraryPathTableMetaImpl.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRTLibraryPathTableMetaImpl.java Sat Jan 28 22:21:54 2012 -0800
@@ -70,6 +70,7 @@
*/
public class JvmRTLibraryPathTableMetaImpl extends JvmRTLibraryPathTableMeta {
+ static final long serialVersionUID = 6713252710712502068L;
private SnmpTableCache cache;
/**
@@ -77,6 +78,7 @@
* JvmRTLibraryPathTable.
**/
private static class JvmRTLibraryPathTableCache extends SnmpTableCache {
+ static final long serialVersionUID = 2035304445719393195L;
private JvmRTLibraryPathTableMetaImpl meta;
JvmRTLibraryPathTableCache(JvmRTLibraryPathTableMetaImpl meta,
@@ -89,7 +91,7 @@
* Call <code>getTableDatas(JvmContextFactory.getUserData())</code>.
**/
public SnmpTableHandler getTableHandler() {
- final Map userData = JvmContextFactory.getUserData();
+ final Map<Object,Object> userData = JvmContextFactory.getUserData();
return getTableDatas(userData);
}
--- a/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRuntimeMetaImpl.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRuntimeMetaImpl.java Sat Jan 28 22:21:54 2012 -0800
@@ -68,6 +68,7 @@
*/
public class JvmRuntimeMetaImpl extends JvmRuntimeMeta {
+ static final long serialVersionUID = -6570428414857608618L;
/**
* Constructor for the metadata associated to "JvmRuntime".
*/
--- a/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmThreadInstanceEntryImpl.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmThreadInstanceEntryImpl.java Sat Jan 28 22:21:54 2012 -0800
@@ -53,6 +53,8 @@
public class JvmThreadInstanceEntryImpl
implements JvmThreadInstanceEntryMBean, Serializable {
+ static final long serialVersionUID = 910173589985461347L;
+
public final static class ThreadStateMap {
public final static class Byte0 {
public final static byte inNative = (byte)0x80; // bit 1
--- a/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmThreadInstanceTableMetaImpl.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmThreadInstanceTableMetaImpl.java Sat Jan 28 22:21:54 2012 -0800
@@ -78,6 +78,8 @@
public class JvmThreadInstanceTableMetaImpl
extends JvmThreadInstanceTableMeta {
+ static final long serialVersionUID = -8432271929226397492L;
+
/**
* Maximum depth of the stacktrace that might be returned through
* SNMP.
@@ -135,6 +137,7 @@
private static class JvmThreadInstanceTableCache
extends SnmpTableCache {
+ static final long serialVersionUID = 4947330124563406878L;
final private JvmThreadInstanceTableMetaImpl meta;
/**
@@ -151,7 +154,7 @@
* Call <code>getTableDatas(JvmContextFactory.getUserData())</code>.
**/
public SnmpTableHandler getTableHandler() {
- final Map userData = JvmContextFactory.getUserData();
+ final Map<Object, Object> userData = JvmContextFactory.getUserData();
return getTableDatas(userData);
}
@@ -172,7 +175,7 @@
SnmpOid indexes[] = new SnmpOid[id.length];
final TreeMap<SnmpOid, Object> table =
- new TreeMap<SnmpOid, Object>(SnmpCachedData.oidComparator);
+ new TreeMap<>(SnmpCachedData.oidComparator);
for(int i = 0; i < id.length; i++) {
log.debug("", "Making index for thread id [" + id[i] +"]");
//indexes[i] = makeOid(id[i]);
@@ -277,7 +280,7 @@
// Get the request contextual cache (userData).
//
- final Map m = JvmContextFactory.getUserData();
+ final Map<Object,Object> m = JvmContextFactory.getUserData();
// Get the handler.
//
--- a/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmThreadingMetaImpl.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmThreadingMetaImpl.java Sat Jan 28 22:21:54 2012 -0800
@@ -66,6 +66,8 @@
*/
public class JvmThreadingMetaImpl extends JvmThreadingMeta {
+ static final long serialVersionUID = -2104788458393251457L;
+
/**
* Constructor for the metadata associated to "JvmThreading".
*/
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmClassesVerboseLevel.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmClassesVerboseLevel.java Sat Jan 28 22:21:54 2012 -0800
@@ -43,10 +43,11 @@
*/
public class EnumJvmClassesVerboseLevel extends Enumerated implements Serializable {
+ static final long serialVersionUID = -620710366914810374L;
protected static Hashtable<Integer, String> intTable =
- new Hashtable<Integer, String>();
+ new Hashtable<>();
protected static Hashtable<String, Integer> stringTable =
- new Hashtable<String, Integer>();
+ new Hashtable<>();
static {
intTable.put(new Integer(2), "verbose");
intTable.put(new Integer(1), "silent");
@@ -70,11 +71,11 @@
super(x);
}
- protected Hashtable getIntTable() {
+ protected Hashtable<Integer,String> getIntTable() {
return intTable ;
}
- protected Hashtable getStringTable() {
+ protected Hashtable<String,Integer> getStringTable() {
return stringTable ;
}
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmJITCompilerTimeMonitoring.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmJITCompilerTimeMonitoring.java Sat Jan 28 22:21:54 2012 -0800
@@ -43,10 +43,11 @@
*/
public class EnumJvmJITCompilerTimeMonitoring extends Enumerated implements Serializable {
+ static final long serialVersionUID = 3953565918146461236L;
protected static Hashtable<Integer, String> intTable =
- new Hashtable<Integer, String>();
+ new Hashtable<>();
protected static Hashtable<String, Integer> stringTable =
- new Hashtable<String, Integer>();
+ new Hashtable<>();
static {
intTable.put(new Integer(2), "supported");
intTable.put(new Integer(1), "unsupported");
@@ -70,11 +71,11 @@
super(x);
}
- protected Hashtable getIntTable() {
+ protected Hashtable<Integer, String> getIntTable() {
return intTable ;
}
- protected Hashtable getStringTable() {
+ protected Hashtable<String, Integer> getStringTable() {
return stringTable ;
}
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmMemManagerState.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmMemManagerState.java Sat Jan 28 22:21:54 2012 -0800
@@ -43,10 +43,12 @@
*/
public class EnumJvmMemManagerState extends Enumerated implements Serializable {
+ static final long serialVersionUID = 8249515157795166343L;
+
protected static Hashtable<Integer, String> intTable =
- new Hashtable<Integer, String>();
+ new Hashtable<>();
protected static Hashtable<String, Integer> stringTable =
- new Hashtable<String, Integer>();
+ new Hashtable<>();
static {
intTable.put(new Integer(2), "valid");
intTable.put(new Integer(1), "invalid");
@@ -70,11 +72,11 @@
super(x);
}
- protected Hashtable getIntTable() {
+ protected Hashtable<Integer, String> getIntTable() {
return intTable ;
}
- protected Hashtable getStringTable() {
+ protected Hashtable<String, Integer> getStringTable() {
return stringTable ;
}
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmMemPoolCollectThreshdSupport.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmMemPoolCollectThreshdSupport.java Sat Jan 28 22:21:54 2012 -0800
@@ -43,10 +43,11 @@
*/
public class EnumJvmMemPoolCollectThreshdSupport extends Enumerated implements Serializable {
+ static final long serialVersionUID = 8610091819732806282L;
protected static Hashtable<Integer, String> intTable =
- new Hashtable<Integer, String>();
+ new Hashtable<>();
protected static Hashtable<String, Integer> stringTable =
- new Hashtable<String, Integer>();
+ new Hashtable<>();
static {
intTable.put(new Integer(2), "supported");
intTable.put(new Integer(1), "unsupported");
@@ -70,11 +71,11 @@
super(x);
}
- protected Hashtable getIntTable() {
+ protected Hashtable<Integer, String> getIntTable() {
return intTable ;
}
- protected Hashtable getStringTable() {
+ protected Hashtable<String, Integer> getStringTable() {
return stringTable ;
}
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmMemPoolState.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmMemPoolState.java Sat Jan 28 22:21:54 2012 -0800
@@ -43,10 +43,11 @@
*/
public class EnumJvmMemPoolState extends Enumerated implements Serializable {
+ static final long serialVersionUID = 3038175407527743027L;
protected static Hashtable<Integer, String> intTable =
- new Hashtable<Integer, String>();
+ new Hashtable<>();
protected static Hashtable<String, Integer> stringTable =
- new Hashtable<String, Integer>();
+ new Hashtable<>();
static {
intTable.put(new Integer(2), "valid");
intTable.put(new Integer(1), "invalid");
@@ -70,11 +71,11 @@
super(x);
}
- protected Hashtable getIntTable() {
+ protected Hashtable<Integer,String> getIntTable() {
return intTable ;
}
- protected Hashtable getStringTable() {
+ protected Hashtable<String,Integer> getStringTable() {
return stringTable ;
}
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmMemPoolThreshdSupport.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmMemPoolThreshdSupport.java Sat Jan 28 22:21:54 2012 -0800
@@ -43,10 +43,11 @@
*/
public class EnumJvmMemPoolThreshdSupport extends Enumerated implements Serializable {
+ static final long serialVersionUID = 7014693561120661029L;
protected static Hashtable<Integer, String> intTable =
- new Hashtable<Integer, String>();
+ new Hashtable<>();
protected static Hashtable<String, Integer> stringTable =
- new Hashtable<String, Integer>();
+ new Hashtable<>();
static {
intTable.put(new Integer(2), "supported");
intTable.put(new Integer(1), "unsupported");
@@ -70,11 +71,11 @@
super(x);
}
- protected Hashtable getIntTable() {
+ protected Hashtable<Integer,String> getIntTable() {
return intTable ;
}
- protected Hashtable getStringTable() {
+ protected Hashtable<String,Integer> getStringTable() {
return stringTable ;
}
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmMemPoolType.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmMemPoolType.java Sat Jan 28 22:21:54 2012 -0800
@@ -43,10 +43,11 @@
*/
public class EnumJvmMemPoolType extends Enumerated implements Serializable {
+ static final long serialVersionUID = -7214498472962396555L;
protected static Hashtable<Integer, String> intTable =
- new Hashtable<Integer, String>();
+ new Hashtable<>();
protected static Hashtable<String, Integer> stringTable =
- new Hashtable<String, Integer>();
+ new Hashtable<>();
static {
intTable.put(new Integer(2), "heap");
intTable.put(new Integer(1), "nonheap");
@@ -70,11 +71,11 @@
super(x);
}
- protected Hashtable getIntTable() {
+ protected Hashtable<Integer,String> getIntTable() {
return intTable ;
}
- protected Hashtable getStringTable() {
+ protected Hashtable<String,Integer> getStringTable() {
return stringTable ;
}
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmMemoryGCCall.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmMemoryGCCall.java Sat Jan 28 22:21:54 2012 -0800
@@ -43,10 +43,11 @@
*/
public class EnumJvmMemoryGCCall extends Enumerated implements Serializable {
+ static final long serialVersionUID = -2869147994287351375L;
protected static Hashtable<Integer, String> intTable =
- new Hashtable<Integer, String>();
+ new Hashtable<>();
protected static Hashtable<String, Integer> stringTable =
- new Hashtable<String, Integer>();
+ new Hashtable<>();
static {
intTable.put(new Integer(2), "supported");
intTable.put(new Integer(5), "failed");
@@ -76,11 +77,11 @@
super(x);
}
- protected Hashtable getIntTable() {
+ protected Hashtable<Integer, String> getIntTable() {
return intTable ;
}
- protected Hashtable getStringTable() {
+ protected Hashtable<String, Integer> getStringTable() {
return stringTable ;
}
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmMemoryGCVerboseLevel.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmMemoryGCVerboseLevel.java Sat Jan 28 22:21:54 2012 -0800
@@ -43,10 +43,11 @@
*/
public class EnumJvmMemoryGCVerboseLevel extends Enumerated implements Serializable {
+ static final long serialVersionUID = 1362427628755978190L;
protected static Hashtable<Integer, String> intTable =
- new Hashtable<Integer, String>();
+ new Hashtable<>();
protected static Hashtable<String, Integer> stringTable =
- new Hashtable<String, Integer>();
+ new Hashtable<>();
static {
intTable.put(new Integer(2), "verbose");
intTable.put(new Integer(1), "silent");
@@ -70,11 +71,11 @@
super(x);
}
- protected Hashtable getIntTable() {
+ protected Hashtable<Integer,String> getIntTable() {
return intTable ;
}
- protected Hashtable getStringTable() {
+ protected Hashtable<String,Integer> getStringTable() {
return stringTable ;
}
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmRTBootClassPathSupport.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmRTBootClassPathSupport.java Sat Jan 28 22:21:54 2012 -0800
@@ -43,10 +43,11 @@
*/
public class EnumJvmRTBootClassPathSupport extends Enumerated implements Serializable {
+ static final long serialVersionUID = -5957542680437939894L;
protected static Hashtable<Integer, String> intTable =
- new Hashtable<Integer, String>();
+ new Hashtable<>();
protected static Hashtable<String, Integer> stringTable =
- new Hashtable<String, Integer>();
+ new Hashtable<>();
static {
intTable.put(new Integer(2), "supported");
intTable.put(new Integer(1), "unsupported");
@@ -70,11 +71,11 @@
super(x);
}
- protected Hashtable getIntTable() {
+ protected Hashtable<Integer, String> getIntTable() {
return intTable ;
}
- protected Hashtable getStringTable() {
+ protected Hashtable<String, Integer> getStringTable() {
return stringTable ;
}
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmThreadContentionMonitoring.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmThreadContentionMonitoring.java Sat Jan 28 22:21:54 2012 -0800
@@ -43,10 +43,11 @@
*/
public class EnumJvmThreadContentionMonitoring extends Enumerated implements Serializable {
+ static final long serialVersionUID = -6411827583604137210L;
protected static Hashtable<Integer, String> intTable =
- new Hashtable<Integer, String>();
+ new Hashtable<>();
protected static Hashtable<String, Integer> stringTable =
- new Hashtable<String, Integer>();
+ new Hashtable<>();
static {
intTable.put(new Integer(3), "enabled");
intTable.put(new Integer(4), "disabled");
@@ -72,11 +73,11 @@
super(x);
}
- protected Hashtable getIntTable() {
+ protected Hashtable<Integer,String> getIntTable() {
return intTable ;
}
- protected Hashtable getStringTable() {
+ protected Hashtable<String,Integer> getStringTable() {
return stringTable ;
}
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmThreadCpuTimeMonitoring.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmThreadCpuTimeMonitoring.java Sat Jan 28 22:21:54 2012 -0800
@@ -43,10 +43,11 @@
*/
public class EnumJvmThreadCpuTimeMonitoring extends Enumerated implements Serializable {
+ static final long serialVersionUID = -532837824105215699L;
protected static Hashtable<Integer, String> intTable =
- new Hashtable<Integer, String>();
+ new Hashtable<>();
protected static Hashtable<String, Integer> stringTable =
- new Hashtable<String, Integer>();
+ new Hashtable<>();
static {
intTable.put(new Integer(3), "enabled");
intTable.put(new Integer(4), "disabled");
@@ -72,11 +73,11 @@
super(x);
}
- protected Hashtable getIntTable() {
+ protected Hashtable<Integer,String> getIntTable() {
return intTable ;
}
- protected Hashtable getStringTable() {
+ protected Hashtable<String,Integer> getStringTable() {
return stringTable ;
}
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JVM_MANAGEMENT_MIB.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JVM_MANAGEMENT_MIB.java Sat Jan 28 22:21:54 2012 -0800
@@ -53,6 +53,7 @@
*/
public abstract class JVM_MANAGEMENT_MIB extends SnmpMib implements Serializable {
+ static final long serialVersionUID = 6895037919735816732L;
/**
* Default constructor. Initialize the Mib tree.
*/
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JVM_MANAGEMENT_MIBOidTable.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JVM_MANAGEMENT_MIBOidTable.java Sat Jan 28 22:21:54 2012 -0800
@@ -47,6 +47,7 @@
*/
public class JVM_MANAGEMENT_MIBOidTable extends SnmpOidTableSupport implements Serializable {
+ static final long serialVersionUID = -5010870014488732061L;
/**
* Default constructor. Initialize the Mib tree.
*/
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmClassLoadingMeta.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmClassLoadingMeta.java Sat Jan 28 22:21:54 2012 -0800
@@ -70,6 +70,7 @@
public class JvmClassLoadingMeta extends SnmpMibGroup
implements Serializable, SnmpStandardMetaServer {
+ static final long serialVersionUID = 5722857476941218568L;
/**
* Constructor for the metadata associated to "JvmClassLoading".
*/
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmCompilationMeta.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmCompilationMeta.java Sat Jan 28 22:21:54 2012 -0800
@@ -70,6 +70,7 @@
public class JvmCompilationMeta extends SnmpMibGroup
implements Serializable, SnmpStandardMetaServer {
+ static final long serialVersionUID = -95492874115033638L;
/**
* Constructor for the metadata associated to "JvmCompilation".
*/
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmMemGCEntryMeta.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmMemGCEntryMeta.java Sat Jan 28 22:21:54 2012 -0800
@@ -71,6 +71,7 @@
public class JvmMemGCEntryMeta extends SnmpMibEntry
implements Serializable, SnmpStandardMetaServer {
+ static final long serialVersionUID = 6082082529298387063L;
/**
* Constructor for the metadata associated to "JvmMemGCEntry".
*/
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmMemGCTableMeta.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmMemGCTableMeta.java Sat Jan 28 22:21:54 2012 -0800
@@ -68,6 +68,7 @@
*/
public class JvmMemGCTableMeta extends SnmpMibTable implements Serializable {
+ static final long serialVersionUID = -8843296871149264612L;
/**
* Constructor for the table. Initialize metadata for "JvmMemGCTableMeta".
* The reference on the MBean server is updated so the entries created through an SNMP SET will be AUTOMATICALLY REGISTERED in Java DMK.
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmMemManagerEntryMeta.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmMemManagerEntryMeta.java Sat Jan 28 22:21:54 2012 -0800
@@ -71,6 +71,7 @@
public class JvmMemManagerEntryMeta extends SnmpMibEntry
implements Serializable, SnmpStandardMetaServer {
+ static final long serialVersionUID = 8166956416408970453L;
/**
* Constructor for the metadata associated to "JvmMemManagerEntry".
*/
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmMemManagerTableMeta.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmMemManagerTableMeta.java Sat Jan 28 22:21:54 2012 -0800
@@ -68,6 +68,7 @@
*/
public class JvmMemManagerTableMeta extends SnmpMibTable implements Serializable {
+ static final long serialVersionUID = 5026520607518015233L;
/**
* Constructor for the table. Initialize metadata for "JvmMemManagerTableMeta".
* The reference on the MBean server is updated so the entries created through an SNMP SET will be AUTOMATICALLY REGISTERED in Java DMK.
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmMemMgrPoolRelEntryMeta.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmMemMgrPoolRelEntryMeta.java Sat Jan 28 22:21:54 2012 -0800
@@ -71,6 +71,7 @@
public class JvmMemMgrPoolRelEntryMeta extends SnmpMibEntry
implements Serializable, SnmpStandardMetaServer {
+ static final long serialVersionUID = 7414270971113459798L;
/**
* Constructor for the metadata associated to "JvmMemMgrPoolRelEntry".
*/
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmMemMgrPoolRelTableMeta.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmMemMgrPoolRelTableMeta.java Sat Jan 28 22:21:54 2012 -0800
@@ -68,6 +68,7 @@
*/
public class JvmMemMgrPoolRelTableMeta extends SnmpMibTable implements Serializable {
+ static final long serialVersionUID = -310733366542788998L;
/**
* Constructor for the table. Initialize metadata for "JvmMemMgrPoolRelTableMeta".
* The reference on the MBean server is updated so the entries created through an SNMP SET will be AUTOMATICALLY REGISTERED in Java DMK.
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmMemPoolEntryMeta.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmMemPoolEntryMeta.java Sat Jan 28 22:21:54 2012 -0800
@@ -71,6 +71,7 @@
public class JvmMemPoolEntryMeta extends SnmpMibEntry
implements Serializable, SnmpStandardMetaServer {
+ static final long serialVersionUID = 7220682779249102830L;
/**
* Constructor for the metadata associated to "JvmMemPoolEntry".
*/
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmMemPoolTableMeta.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmMemPoolTableMeta.java Sat Jan 28 22:21:54 2012 -0800
@@ -68,6 +68,8 @@
*/
public class JvmMemPoolTableMeta extends SnmpMibTable implements Serializable {
+ static final long serialVersionUID = -2799470815264898659L;
+
/**
* Constructor for the table. Initialize metadata for "JvmMemPoolTableMeta".
* The reference on the MBean server is updated so the entries created through an SNMP SET will be AUTOMATICALLY REGISTERED in Java DMK.
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmOSMeta.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmOSMeta.java Sat Jan 28 22:21:54 2012 -0800
@@ -70,6 +70,8 @@
public class JvmOSMeta extends SnmpMibGroup
implements Serializable, SnmpStandardMetaServer {
+ static final long serialVersionUID = -2024138733580127133L;
+
/**
* Constructor for the metadata associated to "JvmOS".
*/
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRTBootClassPathEntryMeta.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRTBootClassPathEntryMeta.java Sat Jan 28 22:21:54 2012 -0800
@@ -71,6 +71,7 @@
public class JvmRTBootClassPathEntryMeta extends SnmpMibEntry
implements Serializable, SnmpStandardMetaServer {
+ static final long serialVersionUID = 7703840715080588941L;
/**
* Constructor for the metadata associated to "JvmRTBootClassPathEntry".
*/
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRTBootClassPathTableMeta.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRTBootClassPathTableMeta.java Sat Jan 28 22:21:54 2012 -0800
@@ -68,6 +68,7 @@
*/
public class JvmRTBootClassPathTableMeta extends SnmpMibTable implements Serializable {
+ static final long serialVersionUID = 42471379600792135L;
/**
* Constructor for the table. Initialize metadata for "JvmRTBootClassPathTableMeta".
* The reference on the MBean server is updated so the entries created through an SNMP SET will be AUTOMATICALLY REGISTERED in Java DMK.
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRTClassPathEntryMeta.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRTClassPathEntryMeta.java Sat Jan 28 22:21:54 2012 -0800
@@ -71,6 +71,7 @@
public class JvmRTClassPathEntryMeta extends SnmpMibEntry
implements Serializable, SnmpStandardMetaServer {
+ static final long serialVersionUID = 3388703998226830801L;
/**
* Constructor for the metadata associated to "JvmRTClassPathEntry".
*/
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRTClassPathTableMeta.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRTClassPathTableMeta.java Sat Jan 28 22:21:54 2012 -0800
@@ -68,6 +68,7 @@
*/
public class JvmRTClassPathTableMeta extends SnmpMibTable implements Serializable {
+ static final long serialVersionUID = -1518727175345404443L;
/**
* Constructor for the table. Initialize metadata for "JvmRTClassPathTableMeta".
* The reference on the MBean server is updated so the entries created through an SNMP SET will be AUTOMATICALLY REGISTERED in Java DMK.
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRTInputArgsEntryMeta.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRTInputArgsEntryMeta.java Sat Jan 28 22:21:54 2012 -0800
@@ -71,6 +71,7 @@
public class JvmRTInputArgsEntryMeta extends SnmpMibEntry
implements Serializable, SnmpStandardMetaServer {
+ static final long serialVersionUID = -7729576810347358025L;
/**
* Constructor for the metadata associated to "JvmRTInputArgsEntry".
*/
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRTInputArgsTableMeta.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRTInputArgsTableMeta.java Sat Jan 28 22:21:54 2012 -0800
@@ -68,6 +68,7 @@
*/
public class JvmRTInputArgsTableMeta extends SnmpMibTable implements Serializable {
+ static final long serialVersionUID = 5395531763015738645L;
/**
* Constructor for the table. Initialize metadata for "JvmRTInputArgsTableMeta".
* The reference on the MBean server is updated so the entries created through an SNMP SET will be AUTOMATICALLY REGISTERED in Java DMK.
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRTLibraryPathEntryMeta.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRTLibraryPathEntryMeta.java Sat Jan 28 22:21:54 2012 -0800
@@ -71,6 +71,7 @@
public class JvmRTLibraryPathEntryMeta extends SnmpMibEntry
implements Serializable, SnmpStandardMetaServer {
+ static final long serialVersionUID = -5851555586263475792L;
/**
* Constructor for the metadata associated to "JvmRTLibraryPathEntry".
*/
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRTLibraryPathTableMeta.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRTLibraryPathTableMeta.java Sat Jan 28 22:21:54 2012 -0800
@@ -68,6 +68,7 @@
*/
public class JvmRTLibraryPathTableMeta extends SnmpMibTable implements Serializable {
+ static final long serialVersionUID = -632403620113109468L;
/**
* Constructor for the table. Initialize metadata for "JvmRTLibraryPathTableMeta".
* The reference on the MBean server is updated so the entries created through an SNMP SET will be AUTOMATICALLY REGISTERED in Java DMK.
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRuntimeMeta.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRuntimeMeta.java Sat Jan 28 22:21:54 2012 -0800
@@ -70,6 +70,7 @@
public class JvmRuntimeMeta extends SnmpMibGroup
implements Serializable, SnmpStandardMetaServer {
+ static final long serialVersionUID = 1994595220765880109L;
/**
* Constructor for the metadata associated to "JvmRuntime".
*/
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmThreadInstanceEntryMeta.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmThreadInstanceEntryMeta.java Sat Jan 28 22:21:54 2012 -0800
@@ -71,6 +71,7 @@
public class JvmThreadInstanceEntryMeta extends SnmpMibEntry
implements Serializable, SnmpStandardMetaServer {
+ static final long serialVersionUID = -2015330111801477399L;
/**
* Constructor for the metadata associated to "JvmThreadInstanceEntry".
*/
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmThreadInstanceTableMeta.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmThreadInstanceTableMeta.java Sat Jan 28 22:21:54 2012 -0800
@@ -68,6 +68,7 @@
*/
public class JvmThreadInstanceTableMeta extends SnmpMibTable implements Serializable {
+ static final long serialVersionUID = 2519514732589115954L;
/**
* Constructor for the table. Initialize metadata for "JvmThreadInstanceTableMeta".
* The reference on the MBean server is updated so the entries created through an SNMP SET will be AUTOMATICALLY REGISTERED in Java DMK.
--- a/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmThreadingMeta.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvmmib/JvmThreadingMeta.java Sat Jan 28 22:21:54 2012 -0800
@@ -70,6 +70,7 @@
public class JvmThreadingMeta extends SnmpMibGroup
implements Serializable, SnmpStandardMetaServer {
+ static final long serialVersionUID = 5223833578005322854L;
/**
* Constructor for the metadata associated to "JvmThreading".
*/
--- a/jdk/src/share/classes/sun/management/snmp/util/MibLogger.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/util/MibLogger.java Sat Jan 28 22:21:54 2012 -0800
@@ -32,7 +32,7 @@
final Logger logger;
final String className;
- static String getClassName(Class clazz) {
+ static String getClassName(Class<?> clazz) {
if (clazz == null) return null;
if (clazz.isArray())
return getClassName(clazz.getComponentType()) + "[]";
@@ -44,7 +44,7 @@
else return fullname.substring(lastpoint+1,len);
}
- static String getLoggerName(Class clazz) {
+ static String getLoggerName(Class<?> clazz) {
if (clazz == null) return "sun.management.snmp.jvminstr";
Package p = clazz.getPackage();
if (p == null) return "sun.management.snmp.jvminstr";
@@ -53,11 +53,11 @@
else return pname;
}
- public MibLogger(Class clazz) {
+ public MibLogger(Class<?> clazz) {
this(getLoggerName(clazz),getClassName(clazz));
}
- public MibLogger(Class clazz, String postfix) {
+ public MibLogger(Class<?> clazz, String postfix) {
this(getLoggerName(clazz)+((postfix==null)?"":"."+postfix),
getClassName(clazz));
}
--- a/jdk/src/share/classes/sun/management/snmp/util/SnmpListTableCache.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/util/SnmpListTableCache.java Sat Jan 28 22:21:54 2012 -0800
@@ -59,7 +59,7 @@
* <var>rawDatas</var> list iterator.
* @param item The raw data object for which an index must be determined.
**/
- protected abstract SnmpOid getIndex(Object context, List rawDatas,
+ protected abstract SnmpOid getIndex(Object context, List<?> rawDatas,
int rank, Object item);
/**
@@ -75,7 +75,7 @@
* extracted.
* @return By default <var>item</var> is returned.
**/
- protected Object getData(Object context, List rawDatas,
+ protected Object getData(Object context, List<?> rawDatas,
int rank, Object item) {
return item;
}
@@ -95,14 +95,14 @@
* computed.
* @return the computed cached data.
**/
- protected SnmpCachedData updateCachedDatas(Object context, List rawDatas) {
+ protected SnmpCachedData updateCachedDatas(Object context, List<?> rawDatas) {
final int size = ((rawDatas == null)?0:rawDatas.size());
if (size == 0) return null;
final long time = System.currentTimeMillis();
- final Iterator it = rawDatas.iterator();
+ final Iterator<?> it = rawDatas.iterator();
final TreeMap<SnmpOid, Object> map =
- new TreeMap<SnmpOid, Object>(SnmpCachedData.oidComparator);
+ new TreeMap<>(SnmpCachedData.oidComparator);
for (int rank=0; it.hasNext() ; rank++) {
final Object item = it.next();
final SnmpOid index = getIndex(context, rawDatas, rank, item);
--- a/jdk/src/share/classes/sun/management/snmp/util/SnmpNamedListTableCache.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/util/SnmpNamedListTableCache.java Sat Jan 28 22:21:54 2012 -0800
@@ -55,7 +55,7 @@
* This map associate an entry name with the SnmpOid index that's
* been allocated for it.
**/
- protected TreeMap names = new TreeMap();
+ protected TreeMap<String, SnmpOid> names = new TreeMap<>();
/**
* The last allocate index.
@@ -80,7 +80,7 @@
* <var>rawDatas</var> list iterator.
* @param item The raw data object for which a key name must be determined.
**/
- protected abstract String getKey(Object context, List rawDatas,
+ protected abstract String getKey(Object context, List<?> rawDatas,
int rank, Object item);
/**
@@ -97,7 +97,7 @@
* <var>rawDatas</var> list iterator.
* @param item The raw data object for which an index must be determined.
**/
- protected SnmpOid makeIndex(Object context, List rawDatas,
+ protected SnmpOid makeIndex(Object context, List<?> rawDatas,
int rank, Object item) {
// check we are in the limits of an unsigned32.
@@ -151,7 +151,7 @@
* <var>rawDatas</var> list iterator.
* @param item The raw data object for which an index must be determined.
**/
- protected SnmpOid getIndex(Object context, List rawDatas,
+ protected SnmpOid getIndex(Object context, List<?> rawDatas,
int rank, Object item) {
final String key = getKey(context,rawDatas,rank,item);
final Object index = (names==null||key==null)?null:names.get(key);
@@ -174,8 +174,8 @@
* @param rawDatas The table datas from which the cached data will be
* computed.
**/
- protected SnmpCachedData updateCachedDatas(Object context, List rawDatas) {
- TreeMap ctxt = new TreeMap();
+ protected SnmpCachedData updateCachedDatas(Object context, List<?> rawDatas) {
+ TreeMap<String,SnmpOid> ctxt = new TreeMap<>();
final SnmpCachedData result =
super.updateCachedDatas(context,rawDatas);
names = ctxt;
@@ -191,7 +191,7 @@
* the {@link JvmContextFactory}.
*
**/
- protected abstract List loadRawDatas(Map userData);
+ protected abstract List<?> loadRawDatas(Map<Object,Object> userData);
/**
*The name under which the raw data is to be found/put in
@@ -212,16 +212,16 @@
* the request contextual cache.
*
**/
- protected List getRawDatas(Map<Object, Object> userData, String key) {
- List rawDatas = null;
+ protected List<?> getRawDatas(Map<Object, Object> userData, String key) {
+ List<?> rawDatas = null;
// Look for memory manager list in request contextual cache.
if (userData != null)
- rawDatas = (List) userData.get(key);
+ rawDatas = (List<?>)userData.get(key);
if (rawDatas == null) {
// No list in contextual cache, get it from API
- rawDatas = loadRawDatas(userData);
+ rawDatas = loadRawDatas(userData);
// Put list in cache...
@@ -250,12 +250,12 @@
(context instanceof Map)?Util.<Map<Object, Object>>cast(context):null;
// Look for memory manager list in request contextual cache.
- final List rawDatas = getRawDatas(userData,getRawDatasKey());
+ final List<?> rawDatas = getRawDatas(userData,getRawDatasKey());
log.debug("updateCachedDatas","rawDatas.size()=" +
((rawDatas==null)?"<no data>":""+rawDatas.size()));
- TreeMap ctxt = new TreeMap();
+ TreeMap<String,SnmpOid> ctxt = new TreeMap<>();
final SnmpCachedData result =
super.updateCachedDatas(ctxt,rawDatas);
names = ctxt;
--- a/jdk/src/share/classes/sun/management/snmp/util/SnmpTableCache.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/util/SnmpTableCache.java Sat Jan 28 22:21:54 2012 -0800
@@ -98,7 +98,7 @@
final SnmpCachedData cached = getCachedDatas();
if (cached != null) return cached;
final SnmpCachedData computedDatas = updateCachedDatas(context);
- if (validity != 0) datas = new WeakReference<SnmpCachedData>(computedDatas);
+ if (validity != 0) datas = new WeakReference<>(computedDatas);
return computedDatas;
}
--- a/jdk/src/share/classes/sun/misc/VM.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/misc/VM.java Sat Jan 28 22:21:54 2012 -0800
@@ -168,7 +168,7 @@
//
// The initial value of this field is arbitrary; during JRE initialization
// it will be reset to the value specified on the command line, if any,
- // otherwise to Runtime.getRuntime.maxDirectMemory().
+ // otherwise to Runtime.getRuntime().maxMemory().
//
private static long directMemory = 64 * 1024 * 1024;
--- a/jdk/src/share/classes/sun/net/www/http/HttpClient.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/net/www/http/HttpClient.java Sat Jan 28 22:21:54 2012 -0800
@@ -47,8 +47,6 @@
private boolean inCache;
- protected CookieHandler cookieHandler;
-
// Http requests we send
MessageHeader requests;
@@ -201,14 +199,6 @@
}
setConnectTimeout(to);
- // get the cookieHandler if there is any
- cookieHandler = java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<CookieHandler>() {
- public CookieHandler run() {
- return CookieHandler.getDefault();
- }
- });
-
capture = HttpCapture.getCapture(url);
openServer();
}
@@ -656,6 +646,7 @@
// we've finished parsing http headers
// check if there are any applicable cookies to set (in cache)
+ CookieHandler cookieHandler = httpuc.getCookieHandler();
if (cookieHandler != null) {
URI uri = ParseUtil.toURI(url);
// NOTE: That cast from Map shouldn't be necessary but
--- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Sat Jan 28 22:21:54 2012 -0800
@@ -2633,8 +2633,7 @@
if (filteredHeaders != null)
return filteredHeaders;
- filteredHeaders = new HashMap<>();
- Map<String, List<String>> headers;
+ Map<String, List<String>> headers, tmpMap = new HashMap<>();
if (cachedHeaders != null)
headers = cachedHeaders.getHeaders();
@@ -2650,11 +2649,10 @@
filteredVals.add(fVal);
}
if (!filteredVals.isEmpty())
- filteredHeaders.put(key,
- Collections.unmodifiableList(filteredVals));
+ tmpMap.put(key, Collections.unmodifiableList(filteredVals));
}
- return filteredHeaders;
+ return filteredHeaders = Collections.unmodifiableMap(tmpMap);
}
/**
@@ -2905,6 +2903,10 @@
return readTimeout < 0 ? 0 : readTimeout;
}
+ public CookieHandler getCookieHandler() {
+ return cookieHandler;
+ }
+
String getMethod() {
return method;
}
--- a/jdk/src/share/classes/sun/net/www/protocol/https/HttpsClient.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/net/www/protocol/https/HttpsClient.java Sat Jan 28 22:21:54 2012 -0800
@@ -36,7 +36,6 @@
import java.net.UnknownHostException;
import java.net.InetSocketAddress;
import java.net.Proxy;
-import java.net.CookieHandler;
import java.security.Principal;
import java.security.cert.*;
import java.util.StringTokenizer;
@@ -268,13 +267,6 @@
port = getDefaultPort();
}
setConnectTimeout(connectTimeout);
- // get the cookieHandler if there is any
- cookieHandler = java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<CookieHandler>() {
- public CookieHandler run() {
- return CookieHandler.getDefault();
- }
- });
openServer();
}
--- a/jdk/src/share/classes/sun/security/krb5/internal/rcache/CacheTable.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/security/krb5/internal/rcache/CacheTable.java Sat Jan 28 22:21:54 2012 -0800
@@ -31,8 +31,6 @@
package sun.security.krb5.internal.rcache;
import java.util.Hashtable;
-import sun.security.krb5.internal.KerberosTime;
-
/**
* This class implements Hashtable to store the replay caches.
@@ -60,12 +58,15 @@
}
rc = new ReplayCache(principal, this);
rc.put(time, currTime);
- super.put(principal, rc);
+ if (!rc.isEmpty()) {
+ super.put(principal, rc);
+ }
}
else {
rc.put(time, currTime);
- // re-insert the entry, since rc.put could have removed the entry
- super.put(principal, rc);
+ if (rc.isEmpty()) {
+ super.remove(rc);
+ }
if (DEBUG) {
System.out.println("replay cache found.");
}
--- a/jdk/src/share/classes/sun/security/krb5/internal/rcache/ReplayCache.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/security/krb5/internal/rcache/ReplayCache.java Sat Jan 28 22:21:54 2012 -0800
@@ -31,8 +31,6 @@
package sun.security.krb5.internal.rcache;
-import sun.security.krb5.KrbException;
-import sun.security.krb5.Config;
import sun.security.krb5.internal.Krb5;
import java.util.LinkedList;
import java.util.ListIterator;
@@ -48,10 +46,13 @@
private static final long serialVersionUID = 2997933194993803994L;
+ // These 3 fields are now useless, keep for serialization compatibility
private String principal;
private CacheTable table;
private int nap = 10 * 60 * 1000; //10 minutes break
+
private boolean DEBUG = Krb5.DEBUG;
+
/**
* Constructs a ReplayCache for a client principal in specified <code>CacheTable</code>.
* @param p client principal name.
@@ -125,20 +126,11 @@
if (DEBUG) {
printList();
}
-
- // if there are no entries in the replay cache,
- // remove the replay cache from the table.
- if (this.size() == 0) {
- table.remove(principal);
- }
- if (DEBUG) {
- printList();
- }
}
/**
- * Printes out the debug message.
+ * Prints out the debug message.
*/
private void printList() {
Object[] total = toArray();
--- a/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -870,7 +870,7 @@
@Override
protected int engineGetKeySize(Key key) throws InvalidKeyException {
int n = P11SecretKeyFactory.convertKey
- (token, key, keyAlgorithm).keyLength();
+ (token, key, keyAlgorithm).length();
return n;
}
--- a/jdk/src/share/classes/sun/security/pkcs11/P11Digest.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11Digest.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -49,13 +49,12 @@
* @author Andreas Sterbenz
* @since 1.5
*/
-final class P11Digest extends MessageDigestSpi {
+final class P11Digest extends MessageDigestSpi implements Cloneable {
- /* unitialized, fields uninitialized, no session acquired */
+ /* fields initialized, no session acquired */
private final static int S_BLANK = 1;
- // data in buffer, all fields valid, session acquired
- // but digest not initialized
+ /* data in buffer, session acquired, but digest not initialized */
private final static int S_BUFFERED = 2;
/* session initialized for digesting */
@@ -69,8 +68,8 @@
// algorithm name
private final String algorithm;
- // mechanism id
- private final long mechanism;
+ // mechanism id object
+ private final CK_MECHANISM mechanism;
// length of the digest in bytes
private final int digestLength;
@@ -81,11 +80,8 @@
// current state, one of S_* above
private int state;
- // one byte buffer for the update(byte) method, initialized on demand
- private byte[] oneByte;
-
// buffer to reduce number of JNI calls
- private final byte[] buffer;
+ private byte[] buffer;
// offset into the buffer
private int bufOfs;
@@ -94,7 +90,7 @@
super();
this.token = token;
this.algorithm = algorithm;
- this.mechanism = mechanism;
+ this.mechanism = new CK_MECHANISM(mechanism);
switch ((int)mechanism) {
case (int)CKM_MD2:
case (int)CKM_MD5:
@@ -117,7 +113,6 @@
}
buffer = new byte[BUFFER_SIZE];
state = S_BLANK;
- engineReset();
}
// see JCA spec
@@ -125,44 +120,31 @@
return digestLength;
}
- private void cancelOperation() {
- token.ensureValid();
- if (session == null) {
- return;
- }
- if ((state != S_INIT) || (token.explicitCancel == false)) {
- return;
- }
- // need to explicitly "cancel" active op by finishing it
- try {
- token.p11.C_DigestFinal(session.id(), buffer, 0, buffer.length);
- } catch (PKCS11Exception e) {
- throw new ProviderException("cancel() failed", e);
- } finally {
- state = S_BUFFERED;
- }
- }
-
private void fetchSession() {
token.ensureValid();
if (state == S_BLANK) {
- engineReset();
+ try {
+ session = token.getOpSession();
+ state = S_BUFFERED;
+ } catch (PKCS11Exception e) {
+ throw new ProviderException("No more session available", e);
+ }
}
}
// see JCA spec
protected void engineReset() {
- try {
- cancelOperation();
- bufOfs = 0;
- if (session == null) {
- session = token.getOpSession();
+ token.ensureValid();
+
+ if (session != null) {
+ if (state == S_INIT && token.explicitCancel == true) {
+ session = token.killSession(session);
+ } else {
+ session = token.releaseSession(session);
}
- state = S_BUFFERED;
- } catch (PKCS11Exception e) {
- state = S_BLANK;
- throw new ProviderException("reset() failed, ", e);
}
+ state = S_BLANK;
+ bufOfs = 0;
}
// see JCA spec
@@ -180,18 +162,22 @@
protected int engineDigest(byte[] digest, int ofs, int len)
throws DigestException {
if (len < digestLength) {
- throw new DigestException("Length must be at least " + digestLength);
+ throw new DigestException("Length must be at least " +
+ digestLength);
}
+
fetchSession();
try {
int n;
if (state == S_BUFFERED) {
- n = token.p11.C_DigestSingle(session.id(),
- new CK_MECHANISM(mechanism),
- buffer, 0, bufOfs, digest, ofs, len);
+ n = token.p11.C_DigestSingle(session.id(), mechanism, buffer, 0,
+ bufOfs, digest, ofs, len);
+ bufOfs = 0;
} else {
if (bufOfs != 0) {
- doUpdate(buffer, 0, bufOfs);
+ token.p11.C_DigestUpdate(session.id(), 0, buffer, 0,
+ bufOfs);
+ bufOfs = 0;
}
n = token.p11.C_DigestFinal(session.id(), digest, ofs, len);
}
@@ -202,36 +188,44 @@
} catch (PKCS11Exception e) {
throw new ProviderException("digest() failed", e);
} finally {
- state = S_BLANK;
- bufOfs = 0;
- session = token.releaseSession(session);
+ engineReset();
}
}
// see JCA spec
protected void engineUpdate(byte in) {
- if (oneByte == null) {
- oneByte = new byte[1];
- }
- oneByte[0] = in;
- engineUpdate(oneByte, 0, 1);
+ byte[] temp = { in };
+ engineUpdate(temp, 0, 1);
}
// see JCA spec
protected void engineUpdate(byte[] in, int ofs, int len) {
- fetchSession();
if (len <= 0) {
return;
}
- if ((bufOfs != 0) && (bufOfs + len > buffer.length)) {
- doUpdate(buffer, 0, bufOfs);
- bufOfs = 0;
- }
- if (bufOfs + len > buffer.length) {
- doUpdate(in, ofs, len);
- } else {
- System.arraycopy(in, ofs, buffer, bufOfs, len);
- bufOfs += len;
+
+ fetchSession();
+ try {
+ if (state == S_BUFFERED) {
+ token.p11.C_DigestInit(session.id(), mechanism);
+ state = S_INIT;
+ }
+ if ((bufOfs != 0) && (bufOfs + len > buffer.length)) {
+ // process the buffered data
+ token.p11.C_DigestUpdate(session.id(), 0, buffer, 0, bufOfs);
+ bufOfs = 0;
+ }
+ if (bufOfs + len > buffer.length) {
+ // process the new data
+ token.p11.C_DigestUpdate(session.id(), 0, in, ofs, len);
+ } else {
+ // buffer the new data
+ System.arraycopy(in, ofs, buffer, bufOfs, len);
+ bufOfs += len;
+ }
+ } catch (PKCS11Exception e) {
+ engineReset();
+ throw new ProviderException("update() failed", e);
}
}
@@ -239,11 +233,7 @@
// the master secret is sensitive. We may want to consider making this
// method public in a future release.
protected void implUpdate(SecretKey key) throws InvalidKeyException {
- fetchSession();
- if (bufOfs != 0) {
- doUpdate(buffer, 0, bufOfs);
- bufOfs = 0;
- }
+
// SunJSSE calls this method only if the key does not have a RAW
// encoding, i.e. if it is sensitive. Therefore, no point in calling
// SecretKeyFactory to try to convert it. Just verify it ourselves.
@@ -252,60 +242,77 @@
}
P11Key p11Key = (P11Key)key;
if (p11Key.token != token) {
- throw new InvalidKeyException("Not a P11Key of this provider: " + key);
+ throw new InvalidKeyException("Not a P11Key of this provider: " +
+ key);
}
+
+ fetchSession();
try {
if (state == S_BUFFERED) {
- token.p11.C_DigestInit(session.id(), new CK_MECHANISM(mechanism));
+ token.p11.C_DigestInit(session.id(), mechanism);
state = S_INIT;
}
+
+ if (bufOfs != 0) {
+ token.p11.C_DigestUpdate(session.id(), 0, buffer, 0, bufOfs);
+ bufOfs = 0;
+ }
token.p11.C_DigestKey(session.id(), p11Key.keyID);
} catch (PKCS11Exception e) {
+ engineReset();
throw new ProviderException("update(SecretKey) failed", e);
}
}
// see JCA spec
protected void engineUpdate(ByteBuffer byteBuffer) {
- fetchSession();
int len = byteBuffer.remaining();
if (len <= 0) {
return;
}
+
if (byteBuffer instanceof DirectBuffer == false) {
super.engineUpdate(byteBuffer);
return;
}
+
+ fetchSession();
long addr = ((DirectBuffer)byteBuffer).address();
int ofs = byteBuffer.position();
try {
if (state == S_BUFFERED) {
- token.p11.C_DigestInit(session.id(), new CK_MECHANISM(mechanism));
+ token.p11.C_DigestInit(session.id(), mechanism);
state = S_INIT;
- if (bufOfs != 0) {
- doUpdate(buffer, 0, bufOfs);
- bufOfs = 0;
- }
+ }
+ if (bufOfs != 0) {
+ token.p11.C_DigestUpdate(session.id(), 0, buffer, 0, bufOfs);
+ bufOfs = 0;
}
token.p11.C_DigestUpdate(session.id(), addr + ofs, null, 0, len);
byteBuffer.position(ofs + len);
} catch (PKCS11Exception e) {
+ engineReset();
throw new ProviderException("update() failed", e);
}
}
- private void doUpdate(byte[] in, int ofs, int len) {
- if (len <= 0) {
- return;
- }
+ public Object clone() throws CloneNotSupportedException {
+ P11Digest copy = (P11Digest) super.clone();
+ copy.buffer = buffer.clone();
try {
- if (state == S_BUFFERED) {
- token.p11.C_DigestInit(session.id(), new CK_MECHANISM(mechanism));
- state = S_INIT;
+ if (session != null) {
+ copy.session = copy.token.getOpSession();
}
- token.p11.C_DigestUpdate(session.id(), 0, in, ofs, len);
+ if (state == S_INIT) {
+ byte[] stateValues =
+ token.p11.C_GetOperationState(session.id());
+ token.p11.C_SetOperationState(copy.session.id(),
+ stateValues, 0, 0);
+ }
} catch (PKCS11Exception e) {
- throw new ProviderException("update() failed", e);
+ throw (CloneNotSupportedException)
+ (new CloneNotSupportedException(algorithm).initCause(e));
}
+ return copy;
}
}
--- a/jdk/src/share/classes/sun/security/pkcs11/P11Key.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11Key.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -46,6 +46,7 @@
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
import sun.security.util.DerValue;
+import sun.security.util.Length;
/**
* Key implementation classes.
@@ -61,7 +62,7 @@
* @author Andreas Sterbenz
* @since 1.5
*/
-abstract class P11Key implements Key {
+abstract class P11Key implements Key, Length {
private final static String PUBLIC = "public";
private final static String PRIVATE = "private";
@@ -212,7 +213,11 @@
return s1;
}
- int keyLength() {
+ /**
+ * Return bit length of the key.
+ */
+ @Override
+ public int length() {
return keyLength;
}
--- a/jdk/src/share/classes/sun/security/pkcs11/P11RSACipher.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11RSACipher.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -216,7 +216,7 @@
} else {
throw new InvalidKeyException("Unknown key type: " + p11Key);
}
- int n = (p11Key.keyLength() + 7) >> 3;
+ int n = (p11Key.length() + 7) >> 3;
outputSize = n;
buffer = new byte[n];
maxInputSize = ((padType == PAD_PKCS1 && encrypt) ?
@@ -495,7 +495,7 @@
// see JCE spec
protected int engineGetKeySize(Key key) throws InvalidKeyException {
- int n = P11KeyFactory.convertKey(token, key, algorithm).keyLength();
+ int n = P11KeyFactory.convertKey(token, key, algorithm).length();
return n;
}
}
--- a/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -272,7 +272,7 @@
if (keyAlgorithm.equals("DSA")) {
signature = new byte[40];
} else {
- signature = new byte[(p11Key.keyLength() + 7) >> 3];
+ signature = new byte[(p11Key.length() + 7) >> 3];
}
if (type == T_UPDATE) {
token.p11.C_VerifyFinal(session.id(), signature);
@@ -357,7 +357,7 @@
if (keyAlgorithm.equals("RSA") && publicKey != p11Key) {
int keyLen;
if (publicKey instanceof P11Key) {
- keyLen = ((P11Key) publicKey).keyLength();
+ keyLen = ((P11Key) publicKey).length();
} else {
keyLen = ((RSAKey) publicKey).getModulus().bitLength();
}
@@ -618,7 +618,7 @@
private byte[] pkcs1Pad(byte[] data) {
try {
- int len = (p11Key.keyLength() + 7) >> 3;
+ int len = (p11Key.length() + 7) >> 3;
RSAPadding padding = RSAPadding.getInstance
(RSAPadding.PAD_BLOCKTYPE_1, len);
byte[] padded = padding.pad(data);
--- a/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -606,24 +606,32 @@
m(CKM_DES_CBC));
d(CIP, "DES/CBC/PKCS5Padding", P11Cipher,
m(CKM_DES_CBC_PAD, CKM_DES_CBC));
- d(CIP, "DES/ECB", P11Cipher, s("DES"),
+ d(CIP, "DES/ECB/NoPadding", P11Cipher,
+ m(CKM_DES_ECB));
+ d(CIP, "DES/ECB/PKCS5Padding", P11Cipher, s("DES"),
m(CKM_DES_ECB));
d(CIP, "DESede/CBC/NoPadding", P11Cipher,
m(CKM_DES3_CBC));
d(CIP, "DESede/CBC/PKCS5Padding", P11Cipher,
m(CKM_DES3_CBC_PAD, CKM_DES3_CBC));
- d(CIP, "DESede/ECB", P11Cipher, s("DESede"),
+ d(CIP, "DESede/ECB/NoPadding", P11Cipher,
+ m(CKM_DES3_ECB));
+ d(CIP, "DESede/ECB/PKCS5Padding", P11Cipher, s("DESede"),
m(CKM_DES3_ECB));
d(CIP, "AES/CBC/NoPadding", P11Cipher,
m(CKM_AES_CBC));
d(CIP, "AES/CBC/PKCS5Padding", P11Cipher,
m(CKM_AES_CBC_PAD, CKM_AES_CBC));
- d(CIP, "AES/ECB", P11Cipher, s("AES"),
+ d(CIP, "AES/ECB/NoPadding", P11Cipher,
+ m(CKM_AES_ECB));
+ d(CIP, "AES/ECB/PKCS5Padding", P11Cipher, s("AES"),
m(CKM_AES_ECB));
d(CIP, "AES/CTR/NoPadding", P11Cipher,
m(CKM_AES_CTR));
- d(CIP, "Blowfish/CBC", P11Cipher,
+ d(CIP, "Blowfish/CBC/NoPadding", P11Cipher,
+ m(CKM_BLOWFISH_CBC));
+ d(CIP, "Blowfish/CBC/PKCS5Padding", P11Cipher,
m(CKM_BLOWFISH_CBC));
// XXX RSA_X_509, RSA_OAEP not yet supported
--- a/jdk/src/share/classes/sun/security/pkcs11/wrapper/PKCS11.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/security/pkcs11/wrapper/PKCS11.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
@@ -133,14 +133,15 @@
* @preconditions (pkcs11ModulePath <> null)
* @postconditions
*/
- PKCS11(String pkcs11ModulePath, String functionListName) throws IOException {
+ PKCS11(String pkcs11ModulePath, String functionListName)
+ throws IOException {
connect(pkcs11ModulePath, functionListName);
this.pkcs11ModulePath = pkcs11ModulePath;
}
- public static synchronized PKCS11 getInstance(String pkcs11ModulePath, String functionList,
- CK_C_INITIALIZE_ARGS pInitArgs, boolean omitInitialize)
- throws IOException, PKCS11Exception {
+ public static synchronized PKCS11 getInstance(String pkcs11ModulePath,
+ String functionList, CK_C_INITIALIZE_ARGS pInitArgs,
+ boolean omitInitialize) throws IOException, PKCS11Exception {
// we may only call C_Initialize once per native .so/.dll
// so keep a cache using the (non-canonicalized!) path
PKCS11 pkcs11 = moduleMap.get(pkcs11ModulePath);
@@ -177,7 +178,8 @@
* @preconditions (pkcs11ModulePath <> null)
* @postconditions
*/
- private native void connect(String pkcs11ModulePath, String functionListName) throws IOException;
+ private native void connect(String pkcs11ModulePath, String functionListName)
+ throws IOException;
/**
* Disconnects the PKCS#11 library from this object. After calling this
@@ -255,7 +257,8 @@
* @preconditions
* @postconditions (result <> null)
*/
- public native long[] C_GetSlotList(boolean tokenPresent) throws PKCS11Exception;
+ public native long[] C_GetSlotList(boolean tokenPresent)
+ throws PKCS11Exception;
/**
@@ -287,7 +290,8 @@
* @preconditions
* @postconditions (result <> null)
*/
- public native CK_TOKEN_INFO C_GetTokenInfo(long slotID) throws PKCS11Exception;
+ public native CK_TOKEN_INFO C_GetTokenInfo(long slotID)
+ throws PKCS11Exception;
/**
@@ -322,7 +326,8 @@
* @preconditions
* @postconditions (result <> null)
*/
- public native CK_MECHANISM_INFO C_GetMechanismInfo(long slotID, long type) throws PKCS11Exception;
+ public native CK_MECHANISM_INFO C_GetMechanismInfo(long slotID, long type)
+ throws PKCS11Exception;
/**
@@ -339,7 +344,8 @@
* @preconditions
* @postconditions
*/
-// public native void C_InitToken(long slotID, char[] pPin, char[] pLabel) throws PKCS11Exception;
+// public native void C_InitToken(long slotID, char[] pPin, char[] pLabel)
+// throws PKCS11Exception;
/**
@@ -354,7 +360,8 @@
* @preconditions
* @postconditions
*/
-// public native void C_InitPIN(long hSession, char[] pPin) throws PKCS11Exception;
+// public native void C_InitPIN(long hSession, char[] pPin)
+// throws PKCS11Exception;
/**
@@ -371,7 +378,8 @@
* @preconditions
* @postconditions
*/
-// public native void C_SetPIN(long hSession, char[] pOldPin, char[] pNewPin) throws PKCS11Exception;
+// public native void C_SetPIN(long hSession, char[] pOldPin, char[] pNewPin)
+// throws PKCS11Exception;
@@ -398,7 +406,8 @@
* @preconditions
* @postconditions
*/
- public native long C_OpenSession(long slotID, long flags, Object pApplication, CK_NOTIFY Notify) throws PKCS11Exception;
+ public native long C_OpenSession(long slotID, long flags,
+ Object pApplication, CK_NOTIFY Notify) throws PKCS11Exception;
/**
@@ -440,7 +449,8 @@
* @preconditions
* @postconditions (result <> null)
*/
- public native CK_SESSION_INFO C_GetSessionInfo(long hSession) throws PKCS11Exception;
+ public native CK_SESSION_INFO C_GetSessionInfo(long hSession)
+ throws PKCS11Exception;
/**
@@ -457,7 +467,8 @@
* @preconditions
* @postconditions (result <> null)
*/
-// public native byte[] C_GetOperationState(long hSession) throws PKCS11Exception;
+ public native byte[] C_GetOperationState(long hSession)
+ throws PKCS11Exception;
/**
@@ -478,7 +489,8 @@
* @preconditions
* @postconditions
*/
-// public native void C_SetOperationState(long hSession, byte[] pOperationState, long hEncryptionKey, long hAuthenticationKey) throws PKCS11Exception;
+ public native void C_SetOperationState(long hSession, byte[] pOperationState,
+ long hEncryptionKey, long hAuthenticationKey) throws PKCS11Exception;
/**
@@ -495,7 +507,8 @@
* @preconditions
* @postconditions
*/
- public native void C_Login(long hSession, long userType, char[] pPin) throws PKCS11Exception;
+ public native void C_Login(long hSession, long userType, char[] pPin)
+ throws PKCS11Exception;
/**
@@ -531,7 +544,8 @@
* @preconditions
* @postconditions
*/
- public native long C_CreateObject(long hSession, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
+ public native long C_CreateObject(long hSession, CK_ATTRIBUTE[] pTemplate)
+ throws PKCS11Exception;
/**
@@ -552,7 +566,8 @@
* @preconditions
* @postconditions
*/
- public native long C_CopyObject(long hSession, long hObject, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
+ public native long C_CopyObject(long hSession, long hObject,
+ CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
/**
@@ -567,7 +582,8 @@
* @preconditions
* @postconditions
*/
- public native void C_DestroyObject(long hSession, long hObject) throws PKCS11Exception;
+ public native void C_DestroyObject(long hSession, long hObject)
+ throws PKCS11Exception;
/**
@@ -584,7 +600,8 @@
* @preconditions
* @postconditions
*/
-// public native long C_GetObjectSize(long hSession, long hObject) throws PKCS11Exception;
+// public native long C_GetObjectSize(long hSession, long hObject)
+// throws PKCS11Exception;
/**
@@ -604,7 +621,8 @@
* @preconditions (pTemplate <> null)
* @postconditions (result <> null)
*/
- public native void C_GetAttributeValue(long hSession, long hObject, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
+ public native void C_GetAttributeValue(long hSession, long hObject,
+ CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
/**
@@ -623,7 +641,8 @@
* @preconditions (pTemplate <> null)
* @postconditions
*/
- public native void C_SetAttributeValue(long hSession, long hObject, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
+ public native void C_SetAttributeValue(long hSession, long hObject,
+ CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
/**
@@ -640,7 +659,8 @@
* @preconditions
* @postconditions
*/
- public native void C_FindObjectsInit(long hSession, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
+ public native void C_FindObjectsInit(long hSession, CK_ATTRIBUTE[] pTemplate)
+ throws PKCS11Exception;
/**
@@ -659,7 +679,8 @@
* @preconditions
* @postconditions (result <> null)
*/
- public native long[] C_FindObjects(long hSession, long ulMaxObjectCount) throws PKCS11Exception;
+ public native long[] C_FindObjects(long hSession, long ulMaxObjectCount)
+ throws PKCS11Exception;
/**
@@ -695,7 +716,8 @@
* @preconditions
* @postconditions
*/
- public native void C_EncryptInit(long hSession, CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception;
+ public native void C_EncryptInit(long hSession, CK_MECHANISM pMechanism,
+ long hKey) throws PKCS11Exception;
/**
@@ -713,7 +735,8 @@
* @preconditions (pData <> null)
* @postconditions (result <> null)
*/
- public native int C_Encrypt(long hSession, byte[] in, int inOfs, int inLen, byte[] out, int outOfs, int outLen) throws PKCS11Exception;
+ public native int C_Encrypt(long hSession, byte[] in, int inOfs, int inLen,
+ byte[] out, int outOfs, int outLen) throws PKCS11Exception;
/**
@@ -732,7 +755,9 @@
* @preconditions (pPart <> null)
* @postconditions
*/
- public native int C_EncryptUpdate(long hSession, long directIn, byte[] in, int inOfs, int inLen, long directOut, byte[] out, int outOfs, int outLen) throws PKCS11Exception;
+ public native int C_EncryptUpdate(long hSession, long directIn, byte[] in,
+ int inOfs, int inLen, long directOut, byte[] out, int outOfs,
+ int outLen) throws PKCS11Exception;
/**
@@ -749,7 +774,8 @@
* @preconditions
* @postconditions (result <> null)
*/
- public native int C_EncryptFinal(long hSession, long directOut, byte[] out, int outOfs, int outLen) throws PKCS11Exception;
+ public native int C_EncryptFinal(long hSession, long directOut, byte[] out,
+ int outOfs, int outLen) throws PKCS11Exception;
/**
@@ -766,7 +792,8 @@
* @preconditions
* @postconditions
*/
- public native void C_DecryptInit(long hSession, CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception;
+ public native void C_DecryptInit(long hSession, CK_MECHANISM pMechanism,
+ long hKey) throws PKCS11Exception;
/**
@@ -785,7 +812,8 @@
* @preconditions (pEncryptedPart <> null)
* @postconditions (result <> null)
*/
- public native int C_Decrypt(long hSession, byte[] in, int inOfs, int inLen, byte[] out, int outOfs, int outLen) throws PKCS11Exception;
+ public native int C_Decrypt(long hSession, byte[] in, int inOfs, int inLen,
+ byte[] out, int outOfs, int outLen) throws PKCS11Exception;
/**
@@ -805,7 +833,9 @@
* @preconditions (pEncryptedPart <> null)
* @postconditions
*/
- public native int C_DecryptUpdate(long hSession, long directIn, byte[] in, int inOfs, int inLen, long directOut, byte[] out, int outOfs, int outLen) throws PKCS11Exception;
+ public native int C_DecryptUpdate(long hSession, long directIn, byte[] in,
+ int inOfs, int inLen, long directOut, byte[] out, int outOfs,
+ int outLen) throws PKCS11Exception;
/**
@@ -822,7 +852,8 @@
* @preconditions
* @postconditions (result <> null)
*/
- public native int C_DecryptFinal(long hSession, long directOut, byte[] out, int outOfs, int outLen) throws PKCS11Exception;
+ public native int C_DecryptFinal(long hSession, long directOut, byte[] out,
+ int outOfs, int outLen) throws PKCS11Exception;
@@ -842,7 +873,8 @@
* @preconditions
* @postconditions
*/
- public native void C_DigestInit(long hSession, CK_MECHANISM pMechanism) throws PKCS11Exception;
+ public native void C_DigestInit(long hSession, CK_MECHANISM pMechanism)
+ throws PKCS11Exception;
// note that C_DigestSingle does not exist in PKCS#11
@@ -863,7 +895,9 @@
* @preconditions (data <> null)
* @postconditions (result <> null)
*/
- public native int C_DigestSingle(long hSession, CK_MECHANISM pMechanism, byte[] in, int inOfs, int inLen, byte[] digest, int digestOfs, int digestLen) throws PKCS11Exception;
+ public native int C_DigestSingle(long hSession, CK_MECHANISM pMechanism,
+ byte[] in, int inOfs, int inLen, byte[] digest, int digestOfs,
+ int digestLen) throws PKCS11Exception;
/**
@@ -879,7 +913,8 @@
* @preconditions (pPart <> null)
* @postconditions
*/
- public native void C_DigestUpdate(long hSession, long directIn, byte[] in, int inOfs, int inLen) throws PKCS11Exception;
+ public native void C_DigestUpdate(long hSession, long directIn, byte[] in,
+ int inOfs, int inLen) throws PKCS11Exception;
/**
@@ -896,7 +931,8 @@
* @preconditions
* @postconditions
*/
- public native void C_DigestKey(long hSession, long hKey) throws PKCS11Exception;
+ public native void C_DigestKey(long hSession, long hKey)
+ throws PKCS11Exception;
/**
@@ -912,7 +948,8 @@
* @preconditions
* @postconditions (result <> null)
*/
- public native int C_DigestFinal(long hSession, byte[] pDigest, int digestOfs, int digestLen) throws PKCS11Exception;
+ public native int C_DigestFinal(long hSession, byte[] pDigest, int digestOfs,
+ int digestLen) throws PKCS11Exception;
@@ -937,7 +974,8 @@
* @preconditions
* @postconditions
*/
- public native void C_SignInit(long hSession, CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception;
+ public native void C_SignInit(long hSession, CK_MECHANISM pMechanism,
+ long hKey) throws PKCS11Exception;
/**
@@ -957,7 +995,8 @@
* @preconditions (pData <> null)
* @postconditions (result <> null)
*/
- public native byte[] C_Sign(long hSession, byte[] pData) throws PKCS11Exception;
+ public native byte[] C_Sign(long hSession, byte[] pData)
+ throws PKCS11Exception;
/**
@@ -974,7 +1013,8 @@
* @preconditions (pPart <> null)
* @postconditions
*/
- public native void C_SignUpdate(long hSession, long directIn, byte[] in, int inOfs, int inLen) throws PKCS11Exception;
+ public native void C_SignUpdate(long hSession, long directIn, byte[] in,
+ int inOfs, int inLen) throws PKCS11Exception;
/**
@@ -991,7 +1031,8 @@
* @preconditions
* @postconditions (result <> null)
*/
- public native byte[] C_SignFinal(long hSession, int expectedLen) throws PKCS11Exception;
+ public native byte[] C_SignFinal(long hSession, int expectedLen)
+ throws PKCS11Exception;
/**
@@ -1009,7 +1050,8 @@
* @preconditions
* @postconditions
*/
- public native void C_SignRecoverInit(long hSession, CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception;
+ public native void C_SignRecoverInit(long hSession, CK_MECHANISM pMechanism,
+ long hKey) throws PKCS11Exception;
/**
@@ -1028,7 +1070,9 @@
* @preconditions (pData <> null)
* @postconditions (result <> null)
*/
- public native int C_SignRecover(long hSession, byte[] in, int inOfs, int inLen, byte[] out, int outOufs, int outLen) throws PKCS11Exception;
+ public native int C_SignRecover(long hSession, byte[] in, int inOfs,
+ int inLen, byte[] out, int outOufs, int outLen)
+ throws PKCS11Exception;
@@ -1052,7 +1096,8 @@
* @preconditions
* @postconditions
*/
- public native void C_VerifyInit(long hSession, CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception;
+ public native void C_VerifyInit(long hSession, CK_MECHANISM pMechanism,
+ long hKey) throws PKCS11Exception;
/**
@@ -1071,7 +1116,8 @@
* @preconditions (pData <> null) and (pSignature <> null)
* @postconditions
*/
- public native void C_Verify(long hSession, byte[] pData, byte[] pSignature) throws PKCS11Exception;
+ public native void C_Verify(long hSession, byte[] pData, byte[] pSignature)
+ throws PKCS11Exception;
/**
@@ -1088,7 +1134,8 @@
* @preconditions (pPart <> null)
* @postconditions
*/
- public native void C_VerifyUpdate(long hSession, long directIn, byte[] in, int inOfs, int inLen) throws PKCS11Exception;
+ public native void C_VerifyUpdate(long hSession, long directIn, byte[] in,
+ int inOfs, int inLen) throws PKCS11Exception;
/**
@@ -1104,7 +1151,8 @@
* @preconditions (pSignature <> null)
* @postconditions
*/
- public native void C_VerifyFinal(long hSession, byte[] pSignature) throws PKCS11Exception;
+ public native void C_VerifyFinal(long hSession, byte[] pSignature)
+ throws PKCS11Exception;
/**
@@ -1122,7 +1170,8 @@
* @preconditions
* @postconditions
*/
- public native void C_VerifyRecoverInit(long hSession, CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception;
+ public native void C_VerifyRecoverInit(long hSession,
+ CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception;
/**
@@ -1140,7 +1189,9 @@
* @preconditions (pSignature <> null)
* @postconditions (result <> null)
*/
- public native int C_VerifyRecover(long hSession, byte[] in, int inOfs, int inLen, byte[] out, int outOufs, int outLen) throws PKCS11Exception;
+ public native int C_VerifyRecover(long hSession, byte[] in, int inOfs,
+ int inLen, byte[] out, int outOufs, int outLen)
+ throws PKCS11Exception;
@@ -1164,7 +1215,8 @@
* @preconditions (pPart <> null)
* @postconditions
*/
-// public native byte[] C_DigestEncryptUpdate(long hSession, byte[] pPart) throws PKCS11Exception;
+// public native byte[] C_DigestEncryptUpdate(long hSession, byte[] pPart)
+// throws PKCS11Exception;
/**
@@ -1184,7 +1236,8 @@
* @preconditions (pEncryptedPart <> null)
* @postconditions
*/
-// public native byte[] C_DecryptDigestUpdate(long hSession, byte[] pEncryptedPart) throws PKCS11Exception;
+// public native byte[] C_DecryptDigestUpdate(long hSession,
+// byte[] pEncryptedPart) throws PKCS11Exception;
/**
@@ -1204,7 +1257,8 @@
* @preconditions (pPart <> null)
* @postconditions
*/
-// public native byte[] C_SignEncryptUpdate(long hSession, byte[] pPart) throws PKCS11Exception;
+// public native byte[] C_SignEncryptUpdate(long hSession, byte[] pPart)
+// throws PKCS11Exception;
/**
@@ -1224,7 +1278,8 @@
* @preconditions (pEncryptedPart <> null)
* @postconditions
*/
-// public native byte[] C_DecryptVerifyUpdate(long hSession, byte[] pEncryptedPart) throws PKCS11Exception;
+// public native byte[] C_DecryptVerifyUpdate(long hSession,
+// byte[] pEncryptedPart) throws PKCS11Exception;
@@ -1250,7 +1305,8 @@
* @preconditions
* @postconditions
*/
- public native long C_GenerateKey(long hSession, CK_MECHANISM pMechanism, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
+ public native long C_GenerateKey(long hSession, CK_MECHANISM pMechanism,
+ CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
/**
@@ -1280,9 +1336,8 @@
* @postconditions (result <> null) and (result.length == 2)
*/
public native long[] C_GenerateKeyPair(long hSession,
- CK_MECHANISM pMechanism,
- CK_ATTRIBUTE[] pPublicKeyTemplate,
- CK_ATTRIBUTE[] pPrivateKeyTemplate) throws PKCS11Exception;
+ CK_MECHANISM pMechanism, CK_ATTRIBUTE[] pPublicKeyTemplate,
+ CK_ATTRIBUTE[] pPrivateKeyTemplate) throws PKCS11Exception;
@@ -1305,7 +1360,8 @@
* @preconditions
* @postconditions (result <> null)
*/
- public native byte[] C_WrapKey(long hSession, CK_MECHANISM pMechanism, long hWrappingKey, long hKey) throws PKCS11Exception;
+ public native byte[] C_WrapKey(long hSession, CK_MECHANISM pMechanism,
+ long hWrappingKey, long hKey) throws PKCS11Exception;
/**
@@ -1331,8 +1387,8 @@
* @postconditions
*/
public native long C_UnwrapKey(long hSession, CK_MECHANISM pMechanism,
- long hUnwrappingKey, byte[] pWrappedKey,
- CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
+ long hUnwrappingKey, byte[] pWrappedKey, CK_ATTRIBUTE[] pTemplate)
+ throws PKCS11Exception;
/**
@@ -1356,7 +1412,7 @@
* @postconditions
*/
public native long C_DeriveKey(long hSession, CK_MECHANISM pMechanism,
- long hBaseKey, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
+ long hBaseKey, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
@@ -1377,7 +1433,8 @@
* @preconditions (pSeed <> null)
* @postconditions
*/
- public native void C_SeedRandom(long hSession, byte[] pSeed) throws PKCS11Exception;
+ public native void C_SeedRandom(long hSession, byte[] pSeed)
+ throws PKCS11Exception;
/**
@@ -1393,7 +1450,8 @@
* @preconditions (randomData <> null)
* @postconditions
*/
- public native void C_GenerateRandom(long hSession, byte[] randomData) throws PKCS11Exception;
+ public native void C_GenerateRandom(long hSession, byte[] randomData)
+ throws PKCS11Exception;
@@ -1413,7 +1471,8 @@
* @preconditions
* @postconditions
*/
-// public native void C_GetFunctionStatus(long hSession) throws PKCS11Exception;
+// public native void C_GetFunctionStatus(long hSession)
+// throws PKCS11Exception;
/**
@@ -1450,7 +1509,8 @@
* @preconditions (pRserved == null)
* @postconditions
*/
-// public native long C_WaitForSlotEvent(long flags, Object pRserved) throws PKCS11Exception;
+// public native long C_WaitForSlotEvent(long flags, Object pRserved)
+// throws PKCS11Exception;
/**
* Returns the string representation of this object.
@@ -1476,7 +1536,8 @@
// parent. Used for tokens that only support single threaded access
static class SynchronizedPKCS11 extends PKCS11 {
- SynchronizedPKCS11(String pkcs11ModulePath, String functionListName) throws IOException {
+ SynchronizedPKCS11(String pkcs11ModulePath, String functionListName)
+ throws IOException {
super(pkcs11ModulePath, functionListName);
}
@@ -1484,7 +1545,8 @@
super.C_Initialize(pInitArgs);
}
- public synchronized void C_Finalize(Object pReserved) throws PKCS11Exception {
+ public synchronized void C_Finalize(Object pReserved)
+ throws PKCS11Exception {
super.C_Finalize(pReserved);
}
@@ -1492,39 +1554,48 @@
return super.C_GetInfo();
}
- public synchronized long[] C_GetSlotList(boolean tokenPresent) throws PKCS11Exception {
+ public synchronized long[] C_GetSlotList(boolean tokenPresent)
+ throws PKCS11Exception {
return super.C_GetSlotList(tokenPresent);
}
- public synchronized CK_SLOT_INFO C_GetSlotInfo(long slotID) throws PKCS11Exception {
+ public synchronized CK_SLOT_INFO C_GetSlotInfo(long slotID)
+ throws PKCS11Exception {
return super.C_GetSlotInfo(slotID);
}
- public synchronized CK_TOKEN_INFO C_GetTokenInfo(long slotID) throws PKCS11Exception {
+ public synchronized CK_TOKEN_INFO C_GetTokenInfo(long slotID)
+ throws PKCS11Exception {
return super.C_GetTokenInfo(slotID);
}
- public synchronized long[] C_GetMechanismList(long slotID) throws PKCS11Exception {
+ public synchronized long[] C_GetMechanismList(long slotID)
+ throws PKCS11Exception {
return super.C_GetMechanismList(slotID);
}
- public synchronized CK_MECHANISM_INFO C_GetMechanismInfo(long slotID, long type) throws PKCS11Exception {
+ public synchronized CK_MECHANISM_INFO C_GetMechanismInfo(long slotID,
+ long type) throws PKCS11Exception {
return super.C_GetMechanismInfo(slotID, type);
}
- public synchronized long C_OpenSession(long slotID, long flags, Object pApplication, CK_NOTIFY Notify) throws PKCS11Exception {
+ public synchronized long C_OpenSession(long slotID, long flags,
+ Object pApplication, CK_NOTIFY Notify) throws PKCS11Exception {
return super.C_OpenSession(slotID, flags, pApplication, Notify);
}
- public synchronized void C_CloseSession(long hSession) throws PKCS11Exception {
+ public synchronized void C_CloseSession(long hSession)
+ throws PKCS11Exception {
super.C_CloseSession(hSession);
}
- public synchronized CK_SESSION_INFO C_GetSessionInfo(long hSession) throws PKCS11Exception {
+ public synchronized CK_SESSION_INFO C_GetSessionInfo(long hSession)
+ throws PKCS11Exception {
return super.C_GetSessionInfo(hSession);
}
- public synchronized void C_Login(long hSession, long userType, char[] pPin) throws PKCS11Exception {
+ public synchronized void C_Login(long hSession, long userType, char[] pPin)
+ throws PKCS11Exception {
super.C_Login(hSession, userType, pPin);
}
@@ -1532,157 +1603,207 @@
super.C_Logout(hSession);
}
- public synchronized long C_CreateObject(long hSession, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
+ public synchronized long C_CreateObject(long hSession,
+ CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
return super.C_CreateObject(hSession, pTemplate);
}
- public synchronized long C_CopyObject(long hSession, long hObject, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
+ public synchronized long C_CopyObject(long hSession, long hObject,
+ CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
return super.C_CopyObject(hSession, hObject, pTemplate);
}
- public synchronized void C_DestroyObject(long hSession, long hObject) throws PKCS11Exception {
+ public synchronized void C_DestroyObject(long hSession, long hObject)
+ throws PKCS11Exception {
super.C_DestroyObject(hSession, hObject);
}
- public synchronized void C_GetAttributeValue(long hSession, long hObject, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
+ public synchronized void C_GetAttributeValue(long hSession, long hObject,
+ CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
super.C_GetAttributeValue(hSession, hObject, pTemplate);
}
- public synchronized void C_SetAttributeValue(long hSession, long hObject, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
+ public synchronized void C_SetAttributeValue(long hSession, long hObject,
+ CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
super.C_SetAttributeValue(hSession, hObject, pTemplate);
}
- public synchronized void C_FindObjectsInit(long hSession, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
+ public synchronized void C_FindObjectsInit(long hSession,
+ CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
super.C_FindObjectsInit(hSession, pTemplate);
}
- public synchronized long[] C_FindObjects(long hSession, long ulMaxObjectCount) throws PKCS11Exception {
+ public synchronized long[] C_FindObjects(long hSession,
+ long ulMaxObjectCount) throws PKCS11Exception {
return super.C_FindObjects(hSession, ulMaxObjectCount);
}
- public synchronized void C_FindObjectsFinal(long hSession) throws PKCS11Exception {
+ public synchronized void C_FindObjectsFinal(long hSession)
+ throws PKCS11Exception {
super.C_FindObjectsFinal(hSession);
}
- public synchronized void C_EncryptInit(long hSession, CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception {
+ public synchronized void C_EncryptInit(long hSession,
+ CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception {
super.C_EncryptInit(hSession, pMechanism, hKey);
}
- public synchronized int C_Encrypt(long hSession, byte[] in, int inOfs, int inLen, byte[] out, int outOfs, int outLen) throws PKCS11Exception {
+ public synchronized int C_Encrypt(long hSession, byte[] in, int inOfs,
+ int inLen, byte[] out, int outOfs, int outLen)
+ throws PKCS11Exception {
return super.C_Encrypt(hSession, in, inOfs, inLen, out, outOfs, outLen);
}
- public synchronized int C_EncryptUpdate(long hSession, long directIn, byte[] in, int inOfs, int inLen, long directOut, byte[] out, int outOfs, int outLen) throws PKCS11Exception {
- return super.C_EncryptUpdate(hSession, directIn, in, inOfs, inLen, directOut, out, outOfs, outLen);
+ public synchronized int C_EncryptUpdate(long hSession, long directIn,
+ byte[] in, int inOfs, int inLen, long directOut, byte[] out,
+ int outOfs, int outLen) throws PKCS11Exception {
+ return super.C_EncryptUpdate(hSession, directIn, in, inOfs, inLen,
+ directOut, out, outOfs, outLen);
}
- public synchronized int C_EncryptFinal(long hSession, long directOut, byte[] out, int outOfs, int outLen) throws PKCS11Exception {
+ public synchronized int C_EncryptFinal(long hSession, long directOut,
+ byte[] out, int outOfs, int outLen) throws PKCS11Exception {
return super.C_EncryptFinal(hSession, directOut, out, outOfs, outLen);
}
- public synchronized void C_DecryptInit(long hSession, CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception {
+ public synchronized void C_DecryptInit(long hSession,
+ CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception {
super.C_DecryptInit(hSession, pMechanism, hKey);
}
- public synchronized int C_Decrypt(long hSession, byte[] in, int inOfs, int inLen, byte[] out, int outOfs, int outLen) throws PKCS11Exception {
+ public synchronized int C_Decrypt(long hSession, byte[] in, int inOfs,
+ int inLen, byte[] out, int outOfs, int outLen)
+ throws PKCS11Exception {
return super.C_Decrypt(hSession, in, inOfs, inLen, out, outOfs, outLen);
}
- public synchronized int C_DecryptUpdate(long hSession, long directIn, byte[] in, int inOfs, int inLen, long directOut, byte[] out, int outOfs, int outLen) throws PKCS11Exception {
- return super.C_DecryptUpdate(hSession, directIn, in, inOfs, inLen, directOut, out, outOfs, outLen);
+ public synchronized int C_DecryptUpdate(long hSession, long directIn,
+ byte[] in, int inOfs, int inLen, long directOut, byte[] out,
+ int outOfs, int outLen) throws PKCS11Exception {
+ return super.C_DecryptUpdate(hSession, directIn, in, inOfs, inLen,
+ directOut, out, outOfs, outLen);
}
- public synchronized int C_DecryptFinal(long hSession, long directOut, byte[] out, int outOfs, int outLen) throws PKCS11Exception {
+ public synchronized int C_DecryptFinal(long hSession, long directOut,
+ byte[] out, int outOfs, int outLen) throws PKCS11Exception {
return super.C_DecryptFinal(hSession, directOut, out, outOfs, outLen);
}
- public synchronized void C_DigestInit(long hSession, CK_MECHANISM pMechanism) throws PKCS11Exception {
+ public synchronized void C_DigestInit(long hSession, CK_MECHANISM pMechanism)
+ throws PKCS11Exception {
super.C_DigestInit(hSession, pMechanism);
}
- public synchronized int C_DigestSingle(long hSession, CK_MECHANISM pMechanism, byte[] in, int inOfs, int inLen, byte[] digest, int digestOfs, int digestLen) throws PKCS11Exception {
- return super.C_DigestSingle(hSession, pMechanism, in, inOfs, inLen, digest, digestOfs, digestLen);
+ public synchronized int C_DigestSingle(long hSession,
+ CK_MECHANISM pMechanism, byte[] in, int inOfs, int inLen,
+ byte[] digest, int digestOfs, int digestLen) throws PKCS11Exception {
+ return super.C_DigestSingle(hSession, pMechanism, in, inOfs, inLen,
+ digest, digestOfs, digestLen);
}
- public synchronized void C_DigestUpdate(long hSession, long directIn, byte[] in, int inOfs, int inLen) throws PKCS11Exception {
+ public synchronized void C_DigestUpdate(long hSession, long directIn,
+ byte[] in, int inOfs, int inLen) throws PKCS11Exception {
super.C_DigestUpdate(hSession, directIn, in, inOfs, inLen);
}
- public synchronized void C_DigestKey(long hSession, long hKey) throws PKCS11Exception {
+ public synchronized void C_DigestKey(long hSession, long hKey)
+ throws PKCS11Exception {
super.C_DigestKey(hSession, hKey);
}
- public synchronized int C_DigestFinal(long hSession, byte[] pDigest, int digestOfs, int digestLen) throws PKCS11Exception {
+ public synchronized int C_DigestFinal(long hSession, byte[] pDigest,
+ int digestOfs, int digestLen) throws PKCS11Exception {
return super.C_DigestFinal(hSession, pDigest, digestOfs, digestLen);
}
- public synchronized void C_SignInit(long hSession, CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception {
+ public synchronized void C_SignInit(long hSession, CK_MECHANISM pMechanism,
+ long hKey) throws PKCS11Exception {
super.C_SignInit(hSession, pMechanism, hKey);
}
- public synchronized byte[] C_Sign(long hSession, byte[] pData) throws PKCS11Exception {
+ public synchronized byte[] C_Sign(long hSession, byte[] pData)
+ throws PKCS11Exception {
return super.C_Sign(hSession, pData);
}
- public synchronized void C_SignUpdate(long hSession, long directIn, byte[] in, int inOfs, int inLen) throws PKCS11Exception {
+ public synchronized void C_SignUpdate(long hSession, long directIn,
+ byte[] in, int inOfs, int inLen) throws PKCS11Exception {
super.C_SignUpdate(hSession, directIn, in, inOfs, inLen);
}
- public synchronized byte[] C_SignFinal(long hSession, int expectedLen) throws PKCS11Exception {
+ public synchronized byte[] C_SignFinal(long hSession, int expectedLen)
+ throws PKCS11Exception {
return super.C_SignFinal(hSession, expectedLen);
}
- public synchronized void C_SignRecoverInit(long hSession, CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception {
+ public synchronized void C_SignRecoverInit(long hSession,
+ CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception {
super.C_SignRecoverInit(hSession, pMechanism, hKey);
}
- public synchronized int C_SignRecover(long hSession, byte[] in, int inOfs, int inLen, byte[] out, int outOufs, int outLen) throws PKCS11Exception {
- return super.C_SignRecover(hSession, in, inOfs, inLen, out, outOufs, outLen);
+ public synchronized int C_SignRecover(long hSession, byte[] in, int inOfs,
+ int inLen, byte[] out, int outOufs, int outLen)
+ throws PKCS11Exception {
+ return super.C_SignRecover(hSession, in, inOfs, inLen, out, outOufs,
+ outLen);
}
- public synchronized void C_VerifyInit(long hSession, CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception {
+ public synchronized void C_VerifyInit(long hSession, CK_MECHANISM pMechanism,
+ long hKey) throws PKCS11Exception {
super.C_VerifyInit(hSession, pMechanism, hKey);
}
- public synchronized void C_Verify(long hSession, byte[] pData, byte[] pSignature) throws PKCS11Exception {
+ public synchronized void C_Verify(long hSession, byte[] pData,
+ byte[] pSignature) throws PKCS11Exception {
super.C_Verify(hSession, pData, pSignature);
}
- public synchronized void C_VerifyUpdate(long hSession, long directIn, byte[] in, int inOfs, int inLen) throws PKCS11Exception {
+ public synchronized void C_VerifyUpdate(long hSession, long directIn,
+ byte[] in, int inOfs, int inLen) throws PKCS11Exception {
super.C_VerifyUpdate(hSession, directIn, in, inOfs, inLen);
}
- public synchronized void C_VerifyFinal(long hSession, byte[] pSignature) throws PKCS11Exception {
+ public synchronized void C_VerifyFinal(long hSession, byte[] pSignature)
+ throws PKCS11Exception {
super.C_VerifyFinal(hSession, pSignature);
}
- public synchronized void C_VerifyRecoverInit(long hSession, CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception {
+ public synchronized void C_VerifyRecoverInit(long hSession,
+ CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception {
super.C_VerifyRecoverInit(hSession, pMechanism, hKey);
}
- public synchronized int C_VerifyRecover(long hSession, byte[] in, int inOfs, int inLen, byte[] out, int outOufs, int outLen) throws PKCS11Exception {
- return super.C_VerifyRecover(hSession, in, inOfs, inLen, out, outOufs, outLen);
+ public synchronized int C_VerifyRecover(long hSession, byte[] in, int inOfs,
+ int inLen, byte[] out, int outOufs, int outLen)
+ throws PKCS11Exception {
+ return super.C_VerifyRecover(hSession, in, inOfs, inLen, out, outOufs,
+ outLen);
}
- public synchronized long C_GenerateKey(long hSession, CK_MECHANISM pMechanism, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
+ public synchronized long C_GenerateKey(long hSession,
+ CK_MECHANISM pMechanism, CK_ATTRIBUTE[] pTemplate)
+ throws PKCS11Exception {
return super.C_GenerateKey(hSession, pMechanism, pTemplate);
}
public synchronized long[] C_GenerateKeyPair(long hSession,
- CK_MECHANISM pMechanism,
- CK_ATTRIBUTE[] pPublicKeyTemplate,
- CK_ATTRIBUTE[] pPrivateKeyTemplate) throws PKCS11Exception {
- return super.C_GenerateKeyPair(hSession, pMechanism, pPublicKeyTemplate, pPrivateKeyTemplate);
+ CK_MECHANISM pMechanism, CK_ATTRIBUTE[] pPublicKeyTemplate,
+ CK_ATTRIBUTE[] pPrivateKeyTemplate)
+ throws PKCS11Exception {
+ return super.C_GenerateKeyPair(hSession, pMechanism, pPublicKeyTemplate,
+ pPrivateKeyTemplate);
}
- public synchronized byte[] C_WrapKey(long hSession, CK_MECHANISM pMechanism, long hWrappingKey, long hKey) throws PKCS11Exception {
+ public synchronized byte[] C_WrapKey(long hSession, CK_MECHANISM pMechanism,
+ long hWrappingKey, long hKey) throws PKCS11Exception {
return super.C_WrapKey(hSession, pMechanism, hWrappingKey, hKey);
}
public synchronized long C_UnwrapKey(long hSession, CK_MECHANISM pMechanism,
- long hUnwrappingKey, byte[] pWrappedKey,
- CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
- return super.C_UnwrapKey(hSession, pMechanism, hUnwrappingKey, pWrappedKey, pTemplate);
+ long hUnwrappingKey, byte[] pWrappedKey, CK_ATTRIBUTE[] pTemplate)
+ throws PKCS11Exception {
+ return super.C_UnwrapKey(hSession, pMechanism, hUnwrappingKey,
+ pWrappedKey, pTemplate);
}
public synchronized long C_DeriveKey(long hSession, CK_MECHANISM pMechanism,
@@ -1690,14 +1811,14 @@
return super.C_DeriveKey(hSession, pMechanism, hBaseKey, pTemplate);
}
- public synchronized void C_SeedRandom(long hSession, byte[] pSeed) throws PKCS11Exception {
+ public synchronized void C_SeedRandom(long hSession, byte[] pSeed)
+ throws PKCS11Exception {
super.C_SeedRandom(hSession, pSeed);
}
- public synchronized void C_GenerateRandom(long hSession, byte[] randomData) throws PKCS11Exception {
+ public synchronized void C_GenerateRandom(long hSession, byte[] randomData)
+ throws PKCS11Exception {
super.C_GenerateRandom(hSession, randomData);
}
-
}
-
}
--- a/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -957,7 +957,8 @@
if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
preferableSignatureAlgorithm =
SignatureAndHashAlgorithm.getPreferableAlgorithm(
- peerSupportedSignAlgs, signingKey.getAlgorithm());
+ peerSupportedSignAlgs, signingKey.getAlgorithm(),
+ signingKey);
if (preferableSignatureAlgorithm == null) {
throw new SSLHandshakeException(
--- a/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -1024,37 +1024,39 @@
}
break;
case K_DHE_RSA:
+ // need RSA certs for authentication
+ if (setupPrivateKeyAndChain("RSA") == false) {
+ return false;
+ }
+
// get preferable peer signature algorithm for server key exchange
if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
preferableSignatureAlgorithm =
SignatureAndHashAlgorithm.getPreferableAlgorithm(
- supportedSignAlgs, "RSA");
+ supportedSignAlgs, "RSA", privateKey);
if (preferableSignatureAlgorithm == null) {
return false;
}
}
+ setupEphemeralDHKeys(suite.exportable);
+ break;
+ case K_ECDHE_RSA:
// need RSA certs for authentication
if (setupPrivateKeyAndChain("RSA") == false) {
return false;
}
- setupEphemeralDHKeys(suite.exportable);
- break;
- case K_ECDHE_RSA:
+
// get preferable peer signature algorithm for server key exchange
if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
preferableSignatureAlgorithm =
SignatureAndHashAlgorithm.getPreferableAlgorithm(
- supportedSignAlgs, "RSA");
+ supportedSignAlgs, "RSA", privateKey);
if (preferableSignatureAlgorithm == null) {
return false;
}
}
- // need RSA certs for authentication
- if (setupPrivateKeyAndChain("RSA") == false) {
- return false;
- }
if (setupEphemeralECDHKeys() == false) {
return false;
}
--- a/jdk/src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -27,6 +27,7 @@
import java.security.AlgorithmConstraints;
import java.security.CryptoPrimitive;
+import java.security.PrivateKey;
import java.util.Set;
import java.util.HashSet;
@@ -37,6 +38,8 @@
import java.util.Collections;
import java.util.ArrayList;
+import sun.security.util.KeyLength;
+
/**
* Signature and hash algorithm.
*
@@ -231,6 +234,14 @@
static SignatureAndHashAlgorithm getPreferableAlgorithm(
Collection<SignatureAndHashAlgorithm> algorithms, String expected) {
+ return SignatureAndHashAlgorithm.getPreferableAlgorithm(
+ algorithms, expected, null);
+ }
+
+ static SignatureAndHashAlgorithm getPreferableAlgorithm(
+ Collection<SignatureAndHashAlgorithm> algorithms,
+ String expected, PrivateKey signingKey) {
+
if (expected == null && !algorithms.isEmpty()) {
for (SignatureAndHashAlgorithm sigAlg : algorithms) {
if (sigAlg.priority <= SUPPORTED_ALG_PRIORITY_MAX_NUM) {
@@ -241,17 +252,58 @@
return null; // no supported algorithm
}
+ if (expected == null ) {
+ return null; // no expected algorithm, no supported algorithm
+ }
+
+ /*
+ * Need to check RSA key length to match the length of hash value
+ */
+ int maxDigestLength = Integer.MAX_VALUE;
+ if (signingKey != null &&
+ "rsa".equalsIgnoreCase(signingKey.getAlgorithm()) &&
+ expected.equalsIgnoreCase("rsa")) {
+ /*
+ * RSA keys of 512 bits have been shown to be practically
+ * breakable, it does not make much sense to use the strong
+ * hash algorithm for keys whose key size less than 512 bits.
+ * So it is not necessary to caculate the required max digest
+ * length exactly.
+ *
+ * If key size is greater than or equals to 768, there is no max
+ * digest length limitation in currect implementation.
+ *
+ * If key size is greater than or equals to 512, but less than
+ * 768, the digest length should be less than or equal to 32 bytes.
+ *
+ * If key size is less than 512, the digest length should be
+ * less than or equal to 20 bytes.
+ */
+ int keySize = KeyLength.getKeySize(signingKey);
+ if (keySize >= 768) {
+ maxDigestLength = HashAlgorithm.SHA512.length;
+ } else if ((keySize >= 512) && (keySize < 768)) {
+ maxDigestLength = HashAlgorithm.SHA256.length;
+ } else if ((keySize > 0) && (keySize < 512)) {
+ maxDigestLength = HashAlgorithm.SHA1.length;
+ } // Otherwise, cannot determine the key size, prefer the most
+ // perferable hash algorithm.
+ }
for (SignatureAndHashAlgorithm algorithm : algorithms) {
int signValue = algorithm.id & 0xFF;
- if ((expected.equalsIgnoreCase("dsa") &&
- signValue == SignatureAlgorithm.DSA.value) ||
- (expected.equalsIgnoreCase("rsa") &&
- signValue == SignatureAlgorithm.RSA.value) ||
- (expected.equalsIgnoreCase("ecdsa") &&
- signValue == SignatureAlgorithm.ECDSA.value) ||
- (expected.equalsIgnoreCase("ec") &&
- signValue == SignatureAlgorithm.ECDSA.value)) {
+ if (expected.equalsIgnoreCase("rsa") &&
+ signValue == SignatureAlgorithm.RSA.value) {
+ if (algorithm.hash.length <= maxDigestLength) {
+ return algorithm;
+ }
+ } else if (
+ (expected.equalsIgnoreCase("dsa") &&
+ signValue == SignatureAlgorithm.DSA.value) ||
+ (expected.equalsIgnoreCase("ecdsa") &&
+ signValue == SignatureAlgorithm.ECDSA.value) ||
+ (expected.equalsIgnoreCase("ec") &&
+ signValue == SignatureAlgorithm.ECDSA.value)) {
return algorithm;
}
}
@@ -260,25 +312,28 @@
}
static enum HashAlgorithm {
- UNDEFINED("undefined", "", -1),
- NONE( "none", "NONE", 0),
- MD5( "md5", "MD5", 1),
- SHA1( "sha1", "SHA-1", 2),
- SHA224( "sha224", "SHA-224", 3),
- SHA256( "sha256", "SHA-256", 4),
- SHA384( "sha384", "SHA-384", 5),
- SHA512( "sha512", "SHA-512", 6);
+ UNDEFINED("undefined", "", -1, -1),
+ NONE( "none", "NONE", 0, -1),
+ MD5( "md5", "MD5", 1, 16),
+ SHA1( "sha1", "SHA-1", 2, 20),
+ SHA224( "sha224", "SHA-224", 3, 28),
+ SHA256( "sha256", "SHA-256", 4, 32),
+ SHA384( "sha384", "SHA-384", 5, 48),
+ SHA512( "sha512", "SHA-512", 6, 64);
final String name; // not the standard signature algorithm name
// except the UNDEFINED, other names are defined
// by TLS 1.2 protocol
final String standardName; // the standard MessageDigest algorithm name
final int value;
+ final int length; // digest length in bytes, -1 means not applicable
- private HashAlgorithm(String name, String standardName, int value) {
+ private HashAlgorithm(String name, String standardName,
+ int value, int length) {
this.name = name;
this.standardName = standardName;
this.value = value;
+ this.length = length;
}
static HashAlgorithm valueOf(int value) {
--- a/jdk/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -33,11 +33,6 @@
import java.security.Security;
import java.security.PrivilegedAction;
import java.security.AccessController;
-import java.security.interfaces.ECKey;
-import java.security.interfaces.RSAKey;
-import java.security.interfaces.DSAKey;
-import javax.crypto.SecretKey;
-import javax.crypto.interfaces.DHKey;
import java.util.Locale;
import java.util.Set;
@@ -443,40 +438,15 @@
// Does this key constraint disable the specified key?
public boolean disables(Key key) {
- int size = -1;
-
- // it is a SecretKey
- if (key instanceof SecretKey) {
- SecretKey sk = (SecretKey)key;
- if (sk.getFormat().equals("RAW") && sk.getEncoded() != null) {
- size = sk.getEncoded().length * 8;
-
- }
- }
-
- // it is an asymmetric key
- if (key instanceof RSAKey) {
- RSAKey pubk = (RSAKey)key;
- size = pubk.getModulus().bitLength();
- } else if (key instanceof ECKey) {
- ECKey pubk = (ECKey)key;
- size = pubk.getParams().getOrder().bitLength();
- } else if (key instanceof DSAKey) {
- DSAKey pubk = (DSAKey)key;
- size = pubk.getParams().getP().bitLength();
- } else if (key instanceof DHKey) {
- DHKey pubk = (DHKey)key;
- size = pubk.getParams().getP().bitLength();
- } // else, it is not a key we know.
+ int size = KeyLength.getKeySize(key);
if (size == 0) {
return true; // we don't allow any key of size 0.
- }
-
- if (size >= 0) {
+ } else if (size > 0) {
return ((size < minSize) || (size > maxSize) ||
(prohibitedSize == size));
- }
+ } // Otherwise, the key size is not accessible. Conservatively,
+ // please don't disable such keys.
return false;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/security/util/KeyLength.java Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+import java.security.Key;
+import java.security.PrivilegedAction;
+import java.security.AccessController;
+import java.security.interfaces.ECKey;
+import java.security.interfaces.RSAKey;
+import java.security.interfaces.DSAKey;
+import javax.crypto.SecretKey;
+import javax.crypto.interfaces.DHKey;
+
+/**
+ * A utility class to get key length
+ */
+public final class KeyLength {
+
+ /**
+ * Returns the key size of the given key object in bits.
+ *
+ * @param key the key object, cannot be null
+ * @return the key size of the given key object in bits, or -1 if the
+ * key size is not accessible
+ */
+ final public static int getKeySize(Key key) {
+ int size = -1;
+
+ if (key instanceof Length) {
+ try {
+ Length ruler = (Length)key;
+ size = ruler.length();
+ } catch (UnsupportedOperationException usoe) {
+ // ignore the exception
+ }
+
+ if (size >= 0) {
+ return size;
+ }
+ }
+
+ // try to parse the length from key specification
+ if (key instanceof SecretKey) {
+ SecretKey sk = (SecretKey)key;
+ String format = sk.getFormat();
+ if ("RAW".equals(format) && sk.getEncoded() != null) {
+ size = (sk.getEncoded().length * 8);
+ } // Otherwise, it may be a unextractable key of PKCS#11, or
+ // a key we are not able to handle.
+ } else if (key instanceof RSAKey) {
+ RSAKey pubk = (RSAKey)key;
+ size = pubk.getModulus().bitLength();
+ } else if (key instanceof ECKey) {
+ ECKey pubk = (ECKey)key;
+ size = pubk.getParams().getOrder().bitLength();
+ } else if (key instanceof DSAKey) {
+ DSAKey pubk = (DSAKey)key;
+ size = pubk.getParams().getP().bitLength();
+ } else if (key instanceof DHKey) {
+ DHKey pubk = (DHKey)key;
+ size = pubk.getParams().getP().bitLength();
+ } // Otherwise, it may be a unextractable key of PKCS#11, or
+ // a key we are not able to handle.
+
+ return size;
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/security/util/Length.java Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+/**
+ * The Length interface defines the length of an object
+ */
+public interface Length {
+
+ /**
+ * Gets the length of this object
+ * <p>
+ * Note that if a class of java.security.Key implements this interfaces,
+ * the length should be measured in bits.
+ *
+ * @return the length of this object
+ * @throws UnsupportedOperationException if the operation is not supported
+ */
+ public int length();
+}
--- a/jdk/src/share/lib/security/java.security-solaris Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/lib/security/java.security-solaris Sat Jan 28 22:21:54 2012 -0800
@@ -43,16 +43,17 @@
#
# List of providers and their preference orders (see above):
#
-security.provider.1=sun.security.pkcs11.SunPKCS11 ${java.home}/lib/security/sunpkcs11-solaris.cfg
-security.provider.2=sun.security.provider.Sun
-security.provider.3=sun.security.rsa.SunRsaSign
-security.provider.4=sun.security.ec.SunEC
-security.provider.5=com.sun.net.ssl.internal.ssl.Provider
-security.provider.6=com.sun.crypto.provider.SunJCE
-security.provider.7=sun.security.jgss.SunProvider
-security.provider.8=com.sun.security.sasl.Provider
-security.provider.9=org.jcp.xml.dsig.internal.dom.XMLDSigRI
-security.provider.10=sun.security.smartcardio.SunPCSC
+security.provider.1=com.oracle.security.ucrypto.UcryptoProvider ${java.home}/lib/security/ucrypto-solaris.cfg
+security.provider.2=sun.security.pkcs11.SunPKCS11 ${java.home}/lib/security/sunpkcs11-solaris.cfg
+security.provider.3=sun.security.provider.Sun
+security.provider.4=sun.security.rsa.SunRsaSign
+security.provider.5=sun.security.ec.SunEC
+security.provider.6=com.sun.net.ssl.internal.ssl.Provider
+security.provider.7=com.sun.crypto.provider.SunJCE
+security.provider.8=sun.security.jgss.SunProvider
+security.provider.9=com.sun.security.sasl.Provider
+security.provider.10=org.jcp.xml.dsig.internal.dom.XMLDSigRI
+security.provider.11=sun.security.smartcardio.SunPCSC
#
# Select the source of seed data for SecureRandom. By default an
--- a/jdk/src/share/lib/security/sunpkcs11-solaris.cfg Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/lib/security/sunpkcs11-solaris.cfg Sat Jan 28 22:21:54 2012 -0800
@@ -17,23 +17,27 @@
attributes = compatibility
disabledMechanisms = {
-# the following mechanisms are disabled due to lack of digest cloning support
-# need to fix 6414899 first
+ CKM_DSA_KEY_PAIR_GEN
+# the following mechanisms are disabled due to CKR_SAVED_STATE_INVALID bug
+# (Solaris bug 7058108)
CKM_MD2
CKM_MD5
CKM_SHA_1
+# the following mechanisms are disabled due to no cloning support
+# (Solaris bug 7050617)
CKM_SHA256
CKM_SHA384
CKM_SHA512
- CKM_DSA_KEY_PAIR_GEN
-# the following mechanisms are disabled due to performance issues (Solaris bug 6337157)
+# the following mechanisms are disabled due to performance issues
+# (Solaris bug 6337157)
CKM_DSA_SHA1
CKM_MD5_RSA_PKCS
CKM_SHA1_RSA_PKCS
CKM_SHA256_RSA_PKCS
CKM_SHA384_RSA_PKCS
CKM_SHA512_RSA_PKCS
-# the following mechanisms are disabled to ensure backward compatibility (Solaris bug 6545046)
+# the following mechanisms are disabled to ensure backward compatibility
+# (Solaris bug 6545046)
CKM_DES_CBC_PAD
CKM_DES3_CBC_PAD
CKM_AES_CBC_PAD
--- a/jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11wrapper.h Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11wrapper.h Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
@@ -96,8 +96,8 @@
#define P11_ENABLE_C_CLOSESESSION
#undef P11_ENABLE_C_CLOSEALLSESSIONS
#define P11_ENABLE_C_GETSESSIONINFO
-#undef P11_ENABLE_C_GETOPERATIONSTATE
-#undef P11_ENABLE_C_SETOPERATIONSTATE
+#define P11_ENABLE_C_GETOPERATIONSTATE
+#define P11_ENABLE_C_SETOPERATIONSTATE
#define P11_ENABLE_C_LOGIN
#define P11_ENABLE_C_LOGOUT
#define P11_ENABLE_C_CREATEOBJECT
--- a/jdk/src/solaris/classes/sun/java2d/xr/XRCompositeManager.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/solaris/classes/sun/java2d/xr/XRCompositeManager.java Sat Jan 28 22:21:54 2012 -0800
@@ -28,6 +28,9 @@
import java.awt.*;
import java.awt.geom.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
import sun.font.*;
import sun.java2d.*;
import sun.java2d.jules.*;
@@ -83,7 +86,13 @@
con = new XRBackendNative();
// con = XRBackendJava.getInstance();
- String gradProp = System.getProperty("sun.java2d.xrgradcache");
+ String gradProp =
+ AccessController.doPrivileged(new PrivilegedAction<String>() {
+ public String run() {
+ return System.getProperty("sun.java2d.xrgradcache");
+ }
+ });
+
enableGradCache = gradProp == null ||
!(gradProp.equalsIgnoreCase("false") ||
gradProp.equalsIgnoreCase("f"));
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixChannelFactory.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixChannelFactory.java Sat Jan 28 22:21:54 2012 -0800
@@ -36,8 +36,6 @@
import sun.misc.SharedSecrets;
import sun.misc.JavaIOFileDescriptorAccess;
-import com.sun.nio.file.ExtendedOpenOption;
-
import static sun.nio.fs.UnixNativeDispatcher.*;
import static sun.nio.fs.UnixConstants.*;
@@ -86,13 +84,13 @@
}
continue;
}
- if (option == LinkOption.NOFOLLOW_LINKS) {
+ if (option == LinkOption.NOFOLLOW_LINKS && supportsNoFollowLinks()) {
flags.noFollowLinks = true;
continue;
}
if (option == null)
throw new NullPointerException();
- throw new UnsupportedOperationException();
+ throw new UnsupportedOperationException(option + " not supported");
}
return flags;
}
@@ -220,6 +218,15 @@
// follow links by default
boolean followLinks = true;
if (!flags.createNew && (flags.noFollowLinks || flags.deleteOnClose)) {
+ if (flags.deleteOnClose && !supportsNoFollowLinks()) {
+ try {
+ if (UnixFileAttributes.get(path, false).isSymbolicLink())
+ throw new UnixException("DELETE_ON_CLOSE specified and file is a symbolic link");
+ } catch (UnixException x) {
+ if (!flags.create || x.errno() != ENOENT)
+ throw x;
+ }
+ }
followLinks = false;
oflags |= O_NOFOLLOW;
}
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java Sat Jan 28 22:21:54 2012 -0800
@@ -395,7 +395,7 @@
// can't return SecureDirectoryStream on kernels that don't support
// openat, etc.
- if (!supportsAtSysCalls()) {
+ if (!supportsAtSysCalls() || !supportsNoFollowLinks()) {
try {
long ptr = opendir(dir);
return new UnixDirectoryStream(dir, ptr, filter);
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixNativeDispatcher.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixNativeDispatcher.java Sat Jan 28 22:21:54 2012 -0800
@@ -548,6 +548,10 @@
return hasAtSysCalls;
}
+ static boolean supportsNoFollowLinks() {
+ return UnixConstants.O_NOFOLLOW != 0;
+ }
+
// initialize syscalls and fieldIDs
private static native int init();
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java Sat Jan 28 22:21:54 2012 -0800
@@ -767,8 +767,11 @@
// package-private
int openForAttributeAccess(boolean followLinks) throws IOException {
int flags = O_RDONLY;
- if (!followLinks)
+ if (!followLinks) {
+ if (!supportsNoFollowLinks())
+ throw new IOException("NOFOLLOW_LINKS is not supported on this platform");
flags |= O_NOFOLLOW;
+ }
try {
return open(this, flags, 0);
} catch (UnixException x) {
--- a/jdk/src/solaris/native/java/net/net_util_md.c Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/solaris/native/java/net/net_util_md.c Sat Jan 28 22:21:54 2012 -0800
@@ -588,7 +588,7 @@
int plen, scope, dad_status, if_idx;
if ((f = fopen("/proc/net/if_inet6", "r")) != NULL) {
- while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
+ while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %08x %02x %02x %02x %20s\n",
addr6p[0], addr6p[1], addr6p[2], addr6p[3],
addr6p[4], addr6p[5], addr6p[6], addr6p[7],
&if_idx, &plen, &scope, &dad_status, devname) == 13) {
@@ -1078,7 +1078,7 @@
int plen, scope, dad_status, if_idx;
if ((f = fopen("/proc/net/if_inet6", "r")) != NULL) {
- while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
+ while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %08x %02x %02x %02x %20s\n",
addr6p[0], addr6p[1], addr6p[2], addr6p[3],
addr6p[4], addr6p[5], addr6p[6], addr6p[7],
&if_idx, &plen, &scope, &dad_status, devname) == 13) {
--- a/jdk/src/solaris/native/sun/nio/fs/genUnixConstants.c Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/solaris/native/sun/nio/fs/genUnixConstants.c Sat Jan 28 22:21:54 2012 -0800
@@ -64,7 +64,12 @@
DEFX(O_TRUNC);
DEFX(O_SYNC);
DEFX(O_DSYNC);
+#ifdef O_NOFOLLOW
DEFX(O_NOFOLLOW);
+#else
+ // not supported (dummy values will not be used at runtime).
+ emitX("O_NOFOLLOW", 0x0);
+#endif
// mode masks
emitX("S_IAMB",
--- a/jdk/src/windows/classes/sun/security/mscapi/Key.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/windows/classes/sun/security/mscapi/Key.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
package sun.security.mscapi;
+import sun.security.util.Length;
+
/**
* The handle for an RSA or DSA key using the Microsoft Crypto API.
*
@@ -35,7 +37,7 @@
* @since 1.6
* @author Stanley Man-Kit Ho
*/
-abstract class Key implements java.security.Key
+abstract class Key implements java.security.Key, Length
{
// Native handle
@@ -81,7 +83,8 @@
/**
* Return bit length of the key.
*/
- public int bitLength()
+ @Override
+ public int length()
{
return keyLength;
}
--- a/jdk/src/windows/classes/sun/security/mscapi/RSACipher.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/windows/classes/sun/security/mscapi/RSACipher.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -235,12 +235,12 @@
mode = encrypt ? MODE_ENCRYPT : MODE_VERIFY;
publicKey = (sun.security.mscapi.Key)key;
privateKey = null;
- outputSize = publicKey.bitLength() / 8;
+ outputSize = publicKey.length() / 8;
} else if (key instanceof PrivateKey) {
mode = encrypt ? MODE_SIGN : MODE_DECRYPT;
privateKey = (sun.security.mscapi.Key)key;
publicKey = null;
- outputSize = privateKey.bitLength() / 8;
+ outputSize = privateKey.length() / 8;
} else {
throw new InvalidKeyException("Unknown key type: " + key);
}
@@ -395,7 +395,7 @@
protected int engineGetKeySize(Key key) throws InvalidKeyException {
if (key instanceof sun.security.mscapi.Key) {
- return ((sun.security.mscapi.Key) key).bitLength();
+ return ((sun.security.mscapi.Key) key).length();
} else if (key instanceof RSAKey) {
return ((RSAKey) key).getModulus().bitLength();
--- a/jdk/src/windows/classes/sun/security/mscapi/RSASignature.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/src/windows/classes/sun/security/mscapi/RSASignature.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -290,7 +290,7 @@
// Check against the local and global values to make sure
// the sizes are ok. Round up to nearest byte.
- RSAKeyFactory.checkKeyLengths(((privateKey.bitLength() + 7) & ~7),
+ RSAKeyFactory.checkKeyLengths(((privateKey.length() + 7) & ~7),
null, RSAKeyPairGenerator.KEY_SIZE_MIN,
RSAKeyPairGenerator.KEY_SIZE_MAX);
--- a/jdk/test/Makefile Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/test/Makefile Sat Jan 28 22:21:54 2012 -0800
@@ -555,7 +555,8 @@
# Stable agentvm testruns (minus items from PROBLEM_LIST)
JDK_ALL_TARGETS += jdk_security3
jdk_security3: $(call TestDirs, com/sun/security lib/security javax/security \
- sun/security com/sun/org/apache/xml/internal/security)
+ sun/security com/sun/org/apache/xml/internal/security \
+ com/oracle/secrity/ucrypto)
$(call SharedLibraryPermissions,sun/security)
$(call RunAgentvmBatch)
--- a/jdk/test/ProblemList.txt Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/test/ProblemList.txt Sat Jan 28 22:21:54 2012 -0800
@@ -195,19 +195,22 @@
# jdk_lang
+# 7123972
+java/lang/annotation/loaderLeak/Main.java generic-all
+
# 7079093
java/lang/instrument/ManifestTest.sh windows-all
-############################################################################
-
-# jdk_management
-
# 6944188
java/lang/management/ThreadMXBean/ThreadStateTest.java generic-all
# 7067973
java/lang/management/MemoryMXBean/CollectionUsageThreshold.java generic-all
+############################################################################
+
+# jdk_management
+
# Failing, bug was filed: 6959636
javax/management/loading/LibraryLoader/LibraryLoaderTest.java generic-all
@@ -289,6 +292,9 @@
# jdk_misc
+# 6988950
+demo/jvmti/compiledMethodLoad/CompiledMethodLoadTest.java generic-all
+
# Need to be marked othervm, or changed to be samevm safe
com/sun/jndi/rmi/registry/RegistryContext/UnbindIdempotent.java generic-all
@@ -387,9 +393,6 @@
# 6962637
java/io/File/MaxPathLength.java windows-all
-# 6671616
-java/io/File/BlockIsDirectory.java solaris-all
-
# 7076644
java/io/File/Basic.java windows-all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/oracle/security/ucrypto/TestAES.java Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,339 @@
+/*
+ * Copyright (c) 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.
+ */
+
+/*
+ * @test
+ * @bug 7088989
+ * @summary Ensure the AES ciphers of OracleUcrypto provider works correctly
+ */
+import java.io.*;
+import java.security.*;
+import java.security.spec.*;
+import java.util.*;
+import javax.crypto.*;
+import javax.crypto.spec.*;
+
+public class TestAES extends UcryptoTest {
+
+ private static final String[] PADDEDCIPHER_ALGOS = {
+ "AES/ECB/PKCS5Padding",
+ "AES/CBC/PKCS5Padding",
+ "AES/CFB128/PKCS5Padding"
+ };
+
+ private static final String[] CIPHER_ALGOS = {
+ "AES/ECB/NoPadding",
+ "AES/CBC/NoPadding",
+ "AES/CFB128/NoPadding",
+ "AES/CTR/NoPadding",
+ };
+
+ private static final SecretKey CIPHER_KEY =
+ new SecretKeySpec(new byte[16], "AES");
+
+ public static void main(String[] args) throws Exception {
+ main(new TestAES(), null);
+ }
+
+ public void doTest(Provider prov) throws Exception {
+ // Provider for testing Interoperability
+ Provider sunJCEProv = Security.getProvider("SunJCE");
+
+ testCipherInterop(CIPHER_ALGOS, CIPHER_KEY, prov, sunJCEProv);
+ testCipherInterop(PADDEDCIPHER_ALGOS, CIPHER_KEY, prov, sunJCEProv);
+
+ testCipherOffset(CIPHER_ALGOS, CIPHER_KEY, prov);
+ testCipherOffset(PADDEDCIPHER_ALGOS, CIPHER_KEY, prov);
+
+ testCipherKeyWrapping(PADDEDCIPHER_ALGOS, CIPHER_KEY, prov, sunJCEProv);
+ testCipherGCM(CIPHER_KEY, prov);
+ }
+
+ private static void testCipherInterop(String[] algos, SecretKey key,
+ Provider p,
+ Provider interopP) {
+ boolean testPassed = true;
+ byte[] in = new byte[32];
+ (new SecureRandom()).nextBytes(in);
+
+ for (String algo : algos) {
+ try {
+ // check ENC
+ Cipher c;
+ try {
+ c = Cipher.getInstance(algo, p);
+ } catch (NoSuchAlgorithmException nsae) {
+ System.out.println("Skipping Unsupported CIP algo: " + algo);
+ continue;
+ }
+ c.init(Cipher.ENCRYPT_MODE, key, (AlgorithmParameters)null, null);
+ byte[] eout = c.doFinal(in, 0, in.length);
+
+ AlgorithmParameters params = c.getParameters();
+ Cipher c2 = Cipher.getInstance(algo, interopP);
+ c2.init(Cipher.ENCRYPT_MODE, key, params, null);
+ byte[] eout2 = c2.doFinal(in, 0, in.length);
+
+ if (!Arrays.equals(eout, eout2)) {
+ System.out.println(algo + ": DIFF FAILED");
+ testPassed = false;
+ } else {
+ System.out.println(algo + ": ENC Passed");
+ }
+
+ // check DEC
+ c.init(Cipher.DECRYPT_MODE, key, params, null);
+ byte[] dout = c.doFinal(eout);
+ c2.init(Cipher.DECRYPT_MODE, key, params, null);
+ byte[] dout2 = c2.doFinal(eout2);
+
+ if (!Arrays.equals(dout, dout2)) {
+ System.out.println(algo + ": DIFF FAILED");
+ testPassed = false;
+ } else {
+ System.out.println(algo + ": DEC Passed");
+ }
+ } catch(Exception ex) {
+ System.out.println("Unexpected Exception: " + algo);
+ ex.printStackTrace();
+ testPassed = false;
+ }
+ }
+
+ if (!testPassed) {
+ throw new RuntimeException("One or more CIPHER test failed!");
+ } else {
+ System.out.println("CIPHER Interop Tests Passed");
+ }
+ }
+
+ private static void testCipherOffset(String[] algos, SecretKey key,
+ Provider p) {
+ boolean testPassed = true;
+ byte[] in = new byte[16];
+ (new SecureRandom()).nextBytes(in);
+ int blockSize = 16;
+
+ for (int j = 1; j < (in.length - 1); j++) {
+ System.out.println("Input offset size: " + j);
+ for (int i = 0; i < algos.length; i++) {
+ try {
+ // check ENC
+ Cipher c;
+ try {
+ c = Cipher.getInstance(algos[i], p);
+ } catch (NoSuchAlgorithmException nsae) {
+ System.out.println("Skip Unsupported CIP algo: " + algos[i]);
+ continue;
+ }
+ c.init(Cipher.ENCRYPT_MODE, key, (AlgorithmParameters)null, null);
+ byte[] eout = new byte[c.getOutputSize(in.length)];
+ int firstPartLen = in.length - j - 1;
+ //System.out.print("1st UPDATE: " + firstPartLen);
+ int k = c.update(in, 0, firstPartLen, eout, 0);
+ k += c.update(in, firstPartLen, 1, eout, k);
+ k += c.doFinal(in, firstPartLen+1, j, eout, k);
+
+ AlgorithmParameters params = c.getParameters();
+
+ Cipher c2 = Cipher.getInstance(algos[i], p);
+ c2.init(Cipher.ENCRYPT_MODE, key, params, null);
+ byte[] eout2 = new byte[c2.getOutputSize(in.length)];
+ int k2 = c2.update(in, 0, j, eout2, 0);
+ k2 += c2.update(in, j, 1, eout2, k2);
+ k2 += c2.doFinal(in, j+1, firstPartLen, eout2, k2);
+
+ if (!checkArrays(eout, k, eout2, k2)) testPassed = false;
+
+ // check DEC
+ c.init(Cipher.DECRYPT_MODE, key, params, null);
+ byte[] dout = new byte[c.getOutputSize(eout.length)];
+ k = c.update(eout, 0, firstPartLen, dout, 0);
+ k += c.update(eout, firstPartLen, 1, dout, k);
+ k += c.doFinal(eout, firstPartLen+1, eout.length - firstPartLen - 1, dout, k);
+ if (!checkArrays(in, in.length, dout, k)) testPassed = false;
+ } catch(Exception ex) {
+ System.out.println("Unexpected Exception: " + algos[i]);
+ ex.printStackTrace();
+ testPassed = false;
+ }
+ }
+ }
+ if (!testPassed) {
+ throw new RuntimeException("One or more CIPHER test failed!");
+ } else {
+ System.out.println("CIPHER Offset Tests Passed");
+ }
+ }
+
+ private static void testCipherKeyWrapping(String[] algos, SecretKey key,
+ Provider p, Provider interopP)
+ throws NoSuchAlgorithmException {
+ boolean testPassed = true;
+
+ // Test SecretKey, PrivateKey and PublicKey
+ Key[] tbwKeys = new Key[3];
+ int[] tbwKeyTypes = { Cipher.SECRET_KEY, Cipher.PRIVATE_KEY, Cipher.PUBLIC_KEY };
+ tbwKeys[0] = new SecretKeySpec(new byte[20], "Blowfish");
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+ kpg.initialize(1024);
+ KeyPair kp = kpg.generateKeyPair();
+ tbwKeys[1] = kp.getPrivate();
+ tbwKeys[2] = kp.getPublic();
+
+ for (int i = 0; i < algos.length; i++) {
+ try {
+ System.out.println(algos[i] + " - Native WRAP/Java UNWRAP");
+
+ Cipher c1;
+ try {
+ c1 = Cipher.getInstance(algos[i], p);
+ } catch (NoSuchAlgorithmException nsae) {
+ System.out.println("Skipping Unsupported CIP algo: " + algos[i]);
+ continue;
+ }
+ c1.init(Cipher.WRAP_MODE, key, (AlgorithmParameters)null, null);
+ AlgorithmParameters params = c1.getParameters();
+ Cipher c2 = Cipher.getInstance(algos[i], interopP);
+ c2.init(Cipher.UNWRAP_MODE, key, params, null);
+
+ for (int j = 0; j < tbwKeys.length ; j++) {
+ byte[] wrappedKey = c1.wrap(tbwKeys[j]);
+ Key recovered = c2.unwrap(wrappedKey,
+ tbwKeys[j].getAlgorithm(), tbwKeyTypes[j]);
+ if (!checkKeys(tbwKeys[j], recovered)) testPassed = false;
+ }
+
+ System.out.println(algos[i] + " - Java WRAP/Native UNWRAP");
+ c1 = Cipher.getInstance(algos[i], interopP);
+ c1.init(Cipher.WRAP_MODE, key, (AlgorithmParameters)null, null);
+ params = c1.getParameters();
+ c2 = Cipher.getInstance(algos[i], p);
+ c2.init(Cipher.UNWRAP_MODE, key, params, null);
+
+ for (int j = 0; j < tbwKeys.length ; j++) {
+ byte[] wrappedKey = c1.wrap(tbwKeys[j]);
+ Key recovered = c2.unwrap(wrappedKey,
+ tbwKeys[j].getAlgorithm(), tbwKeyTypes[j]);
+ if (!checkKeys(tbwKeys[j], recovered)) testPassed = false;
+ }
+
+ } catch(Exception ex) {
+ System.out.println("Unexpected Exception: " + algos[i]);
+ ex.printStackTrace();
+ testPassed = false;
+ }
+ }
+ if (!testPassed) {
+ throw new RuntimeException("One or more CIPHER test failed!");
+ } else {
+ System.out.println("CIPHER KeyWrapping Tests Passed");
+ }
+ }
+
+
+ private static void testCipherGCM(SecretKey key,
+ Provider p) {
+ boolean testPassed = true;
+ byte[] in = new byte[16];
+ (new SecureRandom()).nextBytes(in);
+
+ byte[] iv = new byte[16];
+ (new SecureRandom()).nextBytes(iv);
+
+
+ String algo = "AES/GCM/NoPadding";
+ int tagLen[] = { 128, 120, 112, 104, 96, 64, 32 };
+
+ try {
+ Cipher c;
+ try {
+ c = Cipher.getInstance(algo, p);
+ } catch (NoSuchAlgorithmException nsae) {
+ System.out.println("Skipping Unsupported CIP algo: " + algo);
+ return;
+ }
+ for (int i = 0; i < tagLen.length; i++) {
+ AlgorithmParameterSpec paramSpec = new GCMParameterSpec(tagLen[i], iv);
+ // check ENC
+ c.init(Cipher.ENCRYPT_MODE, key, paramSpec, null);
+ c.updateAAD(iv);
+ byte[] eout = c.doFinal(in, 0, in.length);
+
+ AlgorithmParameters param = c.getParameters();
+ // check DEC
+ c.init(Cipher.DECRYPT_MODE, key, param, null);
+ c.updateAAD(iv);
+ byte[] dout = c.doFinal(eout, 0, eout.length);
+
+ if (!Arrays.equals(dout, in)) {
+ System.out.println(algo + ": PT and RT DIFF FAILED");
+ testPassed = false;
+ } else {
+ System.out.println(algo + ": tagLen " + tagLen[i] + " done");
+ }
+ }
+ } catch(Exception ex) {
+ System.out.println("Unexpected Exception: " + algo);
+ ex.printStackTrace();
+ testPassed = false;
+ }
+ if (!testPassed) {
+ throw new RuntimeException("One or more CIPHER test failed!");
+ } else {
+ System.out.println("CIPHER GCM Tests Passed");
+ }
+ }
+
+ private static boolean checkArrays(byte[] a1, int a1Len, byte[] a2, int a2Len) {
+ boolean equal = true;
+ if (a1Len != a2Len) {
+ System.out.println("DIFFERENT OUT LENGTH");
+ equal = false;
+ } else {
+ for (int p = 0; p < a1Len; p++) {
+ if (a1[p] != a2[p]) {
+ System.out.println("DIFF FAILED");
+ equal = false;
+ break;
+ }
+ }
+ }
+ return equal;
+ }
+
+ private static boolean checkKeys(Key k1, Key k2) {
+ boolean equal = true;
+ if (!k1.getAlgorithm().equalsIgnoreCase(k2.getAlgorithm())) {
+ System.out.println("DIFFERENT Key Algorithm");
+ equal = false;
+ } else if (!k1.getFormat().equalsIgnoreCase(k2.getFormat())) {
+ System.out.println("DIFFERENT Key Format");
+ equal = false;
+ } else if (!Arrays.equals(k1.getEncoded(), k2.getEncoded())) {
+ System.out.println("DIFFERENT Key Encoding");
+ equal = false;
+ }
+ return equal;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/oracle/security/ucrypto/TestDigest.java Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 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.
+ */
+
+/*
+ * @test
+ * @bug 7088989
+ * @summary Ensure the various message digests works correctly
+ */
+import java.io.*;
+import java.security.*;
+import java.security.spec.*;
+import java.util.*;
+import javax.crypto.*;
+import javax.crypto.spec.*;
+
+public class TestDigest extends UcryptoTest {
+
+ private static final String[] MD_ALGOS = {
+ "MD5",
+ "SHA",
+ "SHA-256",
+ "SHA-384",
+ "SHA-512"
+ };
+
+ public static void main(String[] args) throws Exception {
+ main(new TestDigest(), null);
+ }
+
+ public void doTest(Provider p) {
+ boolean testPassed = true;
+ byte[] msg = new byte[200];
+ (new SecureRandom()).nextBytes(msg);
+ String interopProvName = "SUN";
+
+ for (String a : MD_ALGOS) {
+ try {
+ MessageDigest md, md2;
+ try {
+ md = MessageDigest.getInstance(a, p);
+ } catch (NoSuchAlgorithmException nsae) {
+ System.out.println("Skipping Unsupported MD algo: " + a);
+ continue;
+ }
+ md2 = MessageDigest.getInstance(a, interopProvName);
+ // Test Interoperability for update+digest calls
+ for (int i = 0; i < 3; i++) {
+ md.update(msg);
+ byte[] digest = md.digest();
+ md2.update(msg);
+ byte[] digest2 = md2.digest();
+ if (!Arrays.equals(digest, digest2)) {
+ System.out.println("DIFF1 FAILED for: " + a + " at iter " + i);
+ testPassed = false;
+ }
+ }
+
+ // Test Interoperability for digest calls
+ md = MessageDigest.getInstance(a, p);
+ md2 = MessageDigest.getInstance(a, interopProvName);
+
+ for (int i = 0; i < 3; i++) {
+ byte[] digest = md.digest();
+ byte[] digest2 = md2.digest();
+ if (!Arrays.equals(digest, digest2)) {
+ System.out.println("DIFF2 FAILED for: " + a + " at iter " + i);
+ testPassed = false;
+ }
+ }
+
+ // Test Cloning functionality
+ md = MessageDigest.getInstance(a, p);
+ md2 = (MessageDigest) md.clone(); // clone right after construction
+ byte[] digest = md.digest();
+ byte[] digest2 = md2.digest();
+ if (!Arrays.equals(digest, digest2)) {
+ System.out.println("DIFF-3.1 FAILED for: " + a);
+ testPassed = false;
+ }
+ md.update(msg);
+ md2 = (MessageDigest) md.clone(); // clone again after update call
+ digest = md.digest();
+ digest2 = md2.digest();
+ if (!Arrays.equals(digest, digest2)) {
+ System.out.println("DIFF-3.2 FAILED for: " + a);
+ testPassed = false;
+ }
+ md2 = (MessageDigest) md.clone(); // clone after digest
+ digest = md.digest();
+ digest2 = md2.digest();
+ if (!Arrays.equals(digest, digest2)) {
+ System.out.println("DIFF-3.3 FAILED for: " + a);
+ testPassed = false;
+ }
+ } catch(Exception ex) {
+ System.out.println("Unexpected Exception: " + a);
+ ex.printStackTrace();
+ testPassed = false;
+ }
+ }
+ if (!testPassed) {
+ throw new RuntimeException("One or more MD test failed!");
+ } else {
+ System.out.println("MD Tests Passed");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/oracle/security/ucrypto/TestRSA.java Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,421 @@
+/*
+ * Copyright (c) 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.
+ */
+
+/*
+ * @test
+ * @bug 7088989
+ * @summary Ensure the RSA ciphers and signatures works correctly
+ */
+import java.io.*;
+import java.security.*;
+import java.security.spec.*;
+import java.util.*;
+import java.math.*;
+import javax.crypto.*;
+
+public class TestRSA extends UcryptoTest {
+
+ // KAT
+ private static final byte PLAINTEXT[] = Arrays.copyOf
+ (new String("Known plaintext message utilized" +
+ "for RSA Encryption & Decryption" +
+ "block, SHA1, SHA256, SHA384 and" +
+ "SHA512 RSA Signature KAT tests.").getBytes(), 128);
+
+ private static final byte MOD[] = {
+ (byte)0xd5, (byte)0x84, (byte)0x95, (byte)0x07, (byte)0xf4, (byte)0xd0,
+ (byte)0x1f, (byte)0x82, (byte)0xf3, (byte)0x79, (byte)0xf4, (byte)0x99,
+ (byte)0x48, (byte)0x10, (byte)0xe1, (byte)0x71, (byte)0xa5, (byte)0x62,
+ (byte)0x22, (byte)0xa3, (byte)0x4b, (byte)0x00, (byte)0xe3, (byte)0x5b,
+ (byte)0x3a, (byte)0xcc, (byte)0x10, (byte)0x83, (byte)0xe0, (byte)0xaf,
+ (byte)0x61, (byte)0x13, (byte)0x54, (byte)0x6a, (byte)0xa2, (byte)0x6a,
+ (byte)0x2c, (byte)0x5e, (byte)0xb3, (byte)0xcc, (byte)0xa3, (byte)0x71,
+ (byte)0x9a, (byte)0xb2, (byte)0x3e, (byte)0x78, (byte)0xec, (byte)0xb5,
+ (byte)0x0e, (byte)0x6e, (byte)0x31, (byte)0x3b, (byte)0x77, (byte)0x1f,
+ (byte)0x6e, (byte)0x94, (byte)0x41, (byte)0x60, (byte)0xd5, (byte)0x6e,
+ (byte)0xd9, (byte)0xc6, (byte)0xf9, (byte)0x29, (byte)0xc3, (byte)0x40,
+ (byte)0x36, (byte)0x25, (byte)0xdb, (byte)0xea, (byte)0x0b, (byte)0x07,
+ (byte)0xae, (byte)0x76, (byte)0xfd, (byte)0x99, (byte)0x29, (byte)0xf4,
+ (byte)0x22, (byte)0xc1, (byte)0x1a, (byte)0x8f, (byte)0x05, (byte)0xfe,
+ (byte)0x98, (byte)0x09, (byte)0x07, (byte)0x05, (byte)0xc2, (byte)0x0f,
+ (byte)0x0b, (byte)0x11, (byte)0x83, (byte)0x39, (byte)0xca, (byte)0xc7,
+ (byte)0x43, (byte)0x63, (byte)0xff, (byte)0x33, (byte)0x80, (byte)0xe7,
+ (byte)0xc3, (byte)0x78, (byte)0xae, (byte)0xf1, (byte)0x73, (byte)0x52,
+ (byte)0x98, (byte)0x1d, (byte)0xde, (byte)0x5c, (byte)0x53, (byte)0x6e,
+ (byte)0x01, (byte)0x73, (byte)0x0d, (byte)0x12, (byte)0x7e, (byte)0x77,
+ (byte)0x03, (byte)0xf1, (byte)0xef, (byte)0x1b, (byte)0xc8, (byte)0xa8,
+ (byte)0x0f, (byte)0x97
+ };
+
+ private static final byte PUB_EXP[] = {(byte)0x01, (byte)0x00, (byte)0x01};
+
+ private static final byte PRIV_EXP[] = {
+ (byte)0x85, (byte)0x27, (byte)0x47, (byte)0x61, (byte)0x4c, (byte)0xd4,
+ (byte)0xb5, (byte)0xb2, (byte)0x0e, (byte)0x70, (byte)0x91, (byte)0x8f,
+ (byte)0x3d, (byte)0x97, (byte)0xf9, (byte)0x5f, (byte)0xcc, (byte)0x09,
+ (byte)0x65, (byte)0x1c, (byte)0x7c, (byte)0x5b, (byte)0xb3, (byte)0x6d,
+ (byte)0x63, (byte)0x3f, (byte)0x7b, (byte)0x55, (byte)0x22, (byte)0xbb,
+ (byte)0x7c, (byte)0x48, (byte)0x77, (byte)0xae, (byte)0x80, (byte)0x56,
+ (byte)0xc2, (byte)0x10, (byte)0xd5, (byte)0x03, (byte)0xdb, (byte)0x31,
+ (byte)0xaf, (byte)0x8d, (byte)0x54, (byte)0xd4, (byte)0x48, (byte)0x99,
+ (byte)0xa8, (byte)0xc4, (byte)0x23, (byte)0x43, (byte)0xb8, (byte)0x48,
+ (byte)0x0b, (byte)0xc7, (byte)0xbc, (byte)0xf5, (byte)0xcc, (byte)0x64,
+ (byte)0x72, (byte)0xbf, (byte)0x59, (byte)0x06, (byte)0x04, (byte)0x1c,
+ (byte)0x32, (byte)0xf5, (byte)0x14, (byte)0x2e, (byte)0x6e, (byte)0xe2,
+ (byte)0x0f, (byte)0x5c, (byte)0xde, (byte)0x36, (byte)0x3c, (byte)0x6e,
+ (byte)0x7c, (byte)0x4d, (byte)0xcc, (byte)0xd3, (byte)0x00, (byte)0x6e,
+ (byte)0xe5, (byte)0x45, (byte)0x46, (byte)0xef, (byte)0x4d, (byte)0x25,
+ (byte)0x46, (byte)0x6d, (byte)0x7f, (byte)0xed, (byte)0xbb, (byte)0x4f,
+ (byte)0x4d, (byte)0x9f, (byte)0xda, (byte)0x87, (byte)0x47, (byte)0x8f,
+ (byte)0x74, (byte)0x44, (byte)0xb7, (byte)0xbe, (byte)0x9d, (byte)0xf5,
+ (byte)0xdd, (byte)0xd2, (byte)0x4c, (byte)0xa5, (byte)0xab, (byte)0x74,
+ (byte)0xe5, (byte)0x29, (byte)0xa1, (byte)0xd2, (byte)0x45, (byte)0x3b,
+ (byte)0x33, (byte)0xde, (byte)0xd5, (byte)0xae, (byte)0xf7, (byte)0x03,
+ (byte)0x10, (byte)0x21
+ };
+
+ private static final byte PRIME_P[] = {
+ (byte)0xf9, (byte)0x74, (byte)0x8f, (byte)0x16, (byte)0x02, (byte)0x6b,
+ (byte)0xa0, (byte)0xee, (byte)0x7f, (byte)0x28, (byte)0x97, (byte)0x91,
+ (byte)0xdc, (byte)0xec, (byte)0xc0, (byte)0x7c, (byte)0x49, (byte)0xc2,
+ (byte)0x85, (byte)0x76, (byte)0xee, (byte)0x66, (byte)0x74, (byte)0x2d,
+ (byte)0x1a, (byte)0xb8, (byte)0xf7, (byte)0x2f, (byte)0x11, (byte)0x5b,
+ (byte)0x36, (byte)0xd8, (byte)0x46, (byte)0x33, (byte)0x3b, (byte)0xd8,
+ (byte)0xf3, (byte)0x2d, (byte)0xa1, (byte)0x03, (byte)0x83, (byte)0x2b,
+ (byte)0xec, (byte)0x35, (byte)0x43, (byte)0x32, (byte)0xff, (byte)0xdd,
+ (byte)0x81, (byte)0x7c, (byte)0xfd, (byte)0x65, (byte)0x13, (byte)0x04,
+ (byte)0x7c, (byte)0xfc, (byte)0x03, (byte)0x97, (byte)0xf0, (byte)0xd5,
+ (byte)0x62, (byte)0xdc, (byte)0x0d, (byte)0xbf
+ };
+
+ private static final byte PRIME_Q[] = {
+ (byte)0xdb, (byte)0x1e, (byte)0xa7, (byte)0x3d, (byte)0xe7, (byte)0xfa,
+ (byte)0x8b, (byte)0x04, (byte)0x83, (byte)0x48, (byte)0xf3, (byte)0xa5,
+ (byte)0x31, (byte)0x9d, (byte)0x35, (byte)0x5e, (byte)0x4d, (byte)0x54,
+ (byte)0x77, (byte)0xcc, (byte)0x84, (byte)0x09, (byte)0xf3, (byte)0x11,
+ (byte)0x0d, (byte)0x54, (byte)0xed, (byte)0x85, (byte)0x39, (byte)0xa9,
+ (byte)0xca, (byte)0xa8, (byte)0xea, (byte)0xae, (byte)0x19, (byte)0x9c,
+ (byte)0x75, (byte)0xdb, (byte)0x88, (byte)0xb8, (byte)0x04, (byte)0x8d,
+ (byte)0x54, (byte)0xc6, (byte)0xa4, (byte)0x80, (byte)0xf8, (byte)0x93,
+ (byte)0xf0, (byte)0xdb, (byte)0x19, (byte)0xef, (byte)0xd7, (byte)0x87,
+ (byte)0x8a, (byte)0x8f, (byte)0x5a, (byte)0x09, (byte)0x2e, (byte)0x54,
+ (byte)0xf3, (byte)0x45, (byte)0x24, (byte)0x29
+ };
+
+ private static final byte EXP_P[] = {
+ (byte)0x6a, (byte)0xd1, (byte)0x25, (byte)0x80, (byte)0x18, (byte)0x33,
+ (byte)0x3c, (byte)0x2b, (byte)0x44, (byte)0x19, (byte)0xfe, (byte)0xa5,
+ (byte)0x40, (byte)0x03, (byte)0xc4, (byte)0xfc, (byte)0xb3, (byte)0x9c,
+ (byte)0xef, (byte)0x07, (byte)0x99, (byte)0x58, (byte)0x17, (byte)0xc1,
+ (byte)0x44, (byte)0xa3, (byte)0x15, (byte)0x7d, (byte)0x7b, (byte)0x22,
+ (byte)0x22, (byte)0xdf, (byte)0x03, (byte)0x58, (byte)0x66, (byte)0xf5,
+ (byte)0x24, (byte)0x54, (byte)0x52, (byte)0x91, (byte)0x2d, (byte)0x76,
+ (byte)0xfe, (byte)0x63, (byte)0x64, (byte)0x4e, (byte)0x0f, (byte)0x50,
+ (byte)0x2b, (byte)0x65, (byte)0x79, (byte)0x1f, (byte)0xf1, (byte)0xbf,
+ (byte)0xc7, (byte)0x41, (byte)0x26, (byte)0xcc, (byte)0xc6, (byte)0x1c,
+ (byte)0xa9, (byte)0x83, (byte)0x6f, (byte)0x03
+ };
+
+ private static final byte EXP_Q[] = {
+ (byte)0x12, (byte)0x84, (byte)0x1a, (byte)0x99, (byte)0xce, (byte)0x9a,
+ (byte)0x8b, (byte)0x58, (byte)0xcc, (byte)0x47, (byte)0x43, (byte)0xdf,
+ (byte)0x77, (byte)0xbb, (byte)0xd3, (byte)0x20, (byte)0xae, (byte)0xe4,
+ (byte)0x2e, (byte)0x63, (byte)0x67, (byte)0xdc, (byte)0xf7, (byte)0x5f,
+ (byte)0x3f, (byte)0x83, (byte)0x27, (byte)0xb7, (byte)0x14, (byte)0x52,
+ (byte)0x56, (byte)0xbf, (byte)0xc3, (byte)0x65, (byte)0x06, (byte)0xe1,
+ (byte)0x03, (byte)0xcc, (byte)0x93, (byte)0x57, (byte)0x09, (byte)0x7b,
+ (byte)0x6f, (byte)0xe8, (byte)0x81, (byte)0x4a, (byte)0x2c, (byte)0xb7,
+ (byte)0x43, (byte)0xa9, (byte)0x20, (byte)0x1d, (byte)0xf6, (byte)0x56,
+ (byte)0x8b, (byte)0xcc, (byte)0xe5, (byte)0x4c, (byte)0xd5, (byte)0x4f,
+ (byte)0x74, (byte)0x67, (byte)0x29, (byte)0x51
+ };
+
+ private static final byte CRT_COEFF[] = {
+ (byte)0x23, (byte)0xab, (byte)0xf4, (byte)0x03, (byte)0x2f, (byte)0x29,
+ (byte)0x95, (byte)0x74, (byte)0xac, (byte)0x1a, (byte)0x33, (byte)0x96,
+ (byte)0x62, (byte)0xed, (byte)0xf7, (byte)0xf6, (byte)0xae, (byte)0x07,
+ (byte)0x2a, (byte)0x2e, (byte)0xe8, (byte)0xab, (byte)0xfb, (byte)0x1e,
+ (byte)0xb9, (byte)0xb2, (byte)0x88, (byte)0x1e, (byte)0x85, (byte)0x05,
+ (byte)0x42, (byte)0x64, (byte)0x03, (byte)0xb2, (byte)0x8b, (byte)0xc1,
+ (byte)0x81, (byte)0x75, (byte)0xd7, (byte)0xba, (byte)0xaa, (byte)0xd4,
+ (byte)0x31, (byte)0x3c, (byte)0x8a, (byte)0x96, (byte)0x23, (byte)0x9d,
+ (byte)0x3f, (byte)0x06, (byte)0x3e, (byte)0x44, (byte)0xa9, (byte)0x62,
+ (byte)0x2f, (byte)0x61, (byte)0x5a, (byte)0x51, (byte)0x82, (byte)0x2c,
+ (byte)0x04, (byte)0x85, (byte)0x73, (byte)0xd1
+ };
+
+ private static KeyPair genRSAKey(int keyLength) throws Exception {
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+ kpg.initialize(keyLength);
+ return kpg.generateKeyPair();
+ }
+
+ private static KeyPair genPredefinedRSAKeyPair() throws Exception {
+ KeyFactory kf = KeyFactory.getInstance("RSA");
+ BigInteger mod = new BigInteger(MOD);
+ BigInteger pub = new BigInteger(PUB_EXP);
+
+ PrivateKey privKey = kf.generatePrivate
+ (new RSAPrivateCrtKeySpec
+ (mod, pub, new BigInteger(PRIV_EXP),
+ new BigInteger(PRIME_P), new BigInteger(PRIME_Q),
+ new BigInteger(EXP_P), new BigInteger(EXP_Q),
+ new BigInteger(CRT_COEFF)));
+ PublicKey pubKey = kf.generatePublic(new RSAPublicKeySpec(mod, pub));
+ return new KeyPair(pubKey, privKey);
+ }
+
+ private static final String CIP_ALGOS[] = {
+ "RSA/ECB/NoPadding",
+ "RSA/ECB/PKCS1Padding"
+ };
+ private static final int INPUT_SIZE_REDUCTION[] = {
+ 0,
+ 11,
+ };
+ private static final String SIG_ALGOS[] = {
+ "MD5WithRSA",
+ "SHA1WithRSA",
+ "SHA256WithRSA",
+ "SHA384WithRSA",
+ "SHA512WithRSA"
+ };
+
+ private static KeyPair kp[] = null;
+
+ public static void main(String argv[]) throws Exception {
+ main(new TestRSA(), null);
+ }
+
+ public void doTest(Provider prov) throws Exception {
+ // first test w/ predefine KeyPair
+ KeyPair pkp = genPredefinedRSAKeyPair();
+ System.out.println("Test against Predefined RSA Key Pair");
+ testCipher(pkp, 128, true, prov);
+ testSignature(pkp, true, prov);
+
+ for (int i = 0; i < 10; i++) {
+ // then test w/ various key lengths
+ int keyLens[] = { 1024, 2048 };
+ kp = new KeyPair[keyLens.length];
+
+ testCipher(keyLens, false, prov);
+ testSignature(keyLens, false, prov);
+ }
+ }
+
+
+ private static void testCipher(KeyPair kp, int inputSizeInBytes,
+ boolean checkInterop, Provider prov)
+ throws Exception {
+ Cipher c1, c2;
+ for (int i = 0; i < CIP_ALGOS.length; i++) {
+ String algo = CIP_ALGOS[i];
+ try {
+ c1 = Cipher.getInstance(algo, prov);
+ } catch (NoSuchAlgorithmException nsae) {
+ System.out.println("Skip unsupported Cipher algo: " + algo);
+ continue;
+ }
+
+ if (checkInterop) {
+ c2 = Cipher.getInstance(algo, "SunJCE");
+ } else {
+ c2 = Cipher.getInstance(algo, prov);
+ }
+ byte[] data = Arrays.copyOf
+ (PLAINTEXT, inputSizeInBytes - INPUT_SIZE_REDUCTION[i]);
+
+ testEncryption(c1, c2, kp, data);
+ }
+ }
+
+ private static void testCipher(int keyLens[], boolean checkInterop,
+ Provider prov)
+ throws Exception {
+ // RSA CipherText will always differ due to the random nonce in padding
+ // so we check whether both
+ // 1) Java Encrypt/C Decrypt
+ // 2) C Encrypt/Java Decrypt
+ // works
+ Cipher c1, c2;
+ for (int i = 0; i < CIP_ALGOS.length; i++) {
+ String algo = CIP_ALGOS[i];
+ try {
+ c1 = Cipher.getInstance(algo, prov);
+ } catch (NoSuchAlgorithmException nsae) {
+ System.out.println("Skip unsupported Cipher algo: " + algo);
+ continue;
+ }
+
+ if (checkInterop) {
+ c2 = Cipher.getInstance(algo, "SunJCE");
+ } else {
+ c2 = Cipher.getInstance(algo, prov);
+ }
+
+ for (int h = 0; h < keyLens.length; h++) {
+ // Defer key pair generation until now when it'll soon be used.
+ if (kp[h] == null) {
+ kp[h] = genRSAKey(keyLens[h]);
+ }
+ System.out.println("\tTesting Cipher " + algo + " w/ KeySize " + keyLens[h]);
+ byte[] data = Arrays.copyOf
+ (PLAINTEXT, keyLens[h]/8 - INPUT_SIZE_REDUCTION[i]);
+ testEncryption(c1, c2, kp[h], data);
+ }
+ }
+ }
+
+ private static void testEncryption(Cipher c1, Cipher c2, KeyPair kp, byte[] data)
+ throws Exception {
+ // C1 Encrypt + C2 Decrypt
+ byte[] out1 = null;
+ byte[] recoveredText = null;
+ try {
+ c1.init(Cipher.ENCRYPT_MODE, kp.getPublic());
+ out1 = c1.doFinal(data);
+ c2.init(Cipher.DECRYPT_MODE, kp.getPrivate());
+ recoveredText = c2.doFinal(out1);
+ } catch (Exception ex) {
+ System.out.println("\tDEC ERROR: unexpected exception");
+ ex.printStackTrace();
+ throw ex;
+ }
+ if(!Arrays.equals(recoveredText, data)) {
+ throw new RuntimeException("\tDEC ERROR: different PT bytes!");
+ }
+ // C2 Encrypt + C1 Decrypt
+ byte[] cipherText = null;
+ try {
+ c2.init(Cipher.ENCRYPT_MODE, kp.getPublic());
+ cipherText = c2.doFinal(data);
+ c1.init(Cipher.DECRYPT_MODE, kp.getPrivate());
+ try {
+ out1 = c1.doFinal(cipherText);
+ } catch (Exception ex) {
+ System.out.println("\tENC ERROR: invalid encrypted output");
+ ex.printStackTrace();
+ throw ex;
+ }
+ } catch (Exception ex) {
+ System.out.println("\tENC ERROR: unexpected exception");
+ ex.printStackTrace();
+ throw ex;
+ }
+ if (!Arrays.equals(out1, data)) {
+ throw new RuntimeException("\tENC ERROR: Decrypted result DIFF!");
+ }
+ System.out.println("\t=> PASS");
+ }
+
+ private static void testSignature(KeyPair kp, boolean checkInterop,
+ Provider prov) throws Exception {
+ byte[] data = PLAINTEXT;
+ Signature sig1, sig2;
+ for (int i = 0; i < SIG_ALGOS.length; i++) {
+ String algo = SIG_ALGOS[i];
+ try {
+ sig1 = Signature.getInstance(algo, prov);
+ } catch (NoSuchAlgorithmException nsae) {
+ System.out.println("Skip unsupported Signature algo: " + algo);
+ continue;
+ }
+
+ if (checkInterop) {
+ sig2 = Signature.getInstance(algo, "SunRsaSign");
+ } else {
+ sig2 = Signature.getInstance(algo, prov);
+ }
+ testSigning(sig1, sig2, kp, data);
+ }
+ }
+
+ private static void testSignature(int keyLens[], boolean checkInterop,
+ Provider prov) throws Exception {
+ byte[] data = PLAINTEXT;
+ Signature sig1, sig2;
+ for (int i = 0; i < SIG_ALGOS.length; i++) {
+ String algo = SIG_ALGOS[i];
+ try {
+ sig1 = Signature.getInstance(algo, prov);
+ } catch (NoSuchAlgorithmException nsae) {
+ System.out.println("Skip unsupported Signature algo: " + algo);
+ continue;
+ }
+
+ if (checkInterop) {
+ sig2 = Signature.getInstance(algo, "SunRsaSign");
+ } else {
+ sig2 = Signature.getInstance(algo, prov);
+ }
+
+ for (int h = 0; h < keyLens.length; h++) {
+ // Defer key pair generation until now when it'll soon be used.
+ if (kp[h] == null) {
+ kp[h] = genRSAKey(keyLens[h]);
+ }
+ System.out.println("\tTesting Signature " + algo + " w/ KeySize " + keyLens[h]);
+
+ testSigning(sig1, sig2, kp[h], data);
+ }
+ }
+ }
+
+ private static void testSigning(Signature sig1, Signature sig2, KeyPair kp, byte[] data)
+ throws Exception {
+ boolean sameSig = false;
+ byte[] out = null;
+ try {
+ sig1.initSign(kp.getPrivate());
+ sig1.update(data);
+ out = sig1.sign();
+ } catch (Exception ex) {
+ System.out.println("\tSIGN ERROR: unexpected exception!");
+ ex.printStackTrace();
+ }
+
+ sig2.initSign(kp.getPrivate());
+ sig2.update(data);
+ byte[] out2 = sig2.sign();
+ if (!Arrays.equals(out2, out)) {
+ throw new RuntimeException("\tSIGN ERROR: Signature DIFF!");
+ }
+
+ boolean verify = false;
+ try {
+ System.out.println("\tVERIFY1 using native out");
+ sig1.initVerify(kp.getPublic());
+ sig1.update(data);
+ verify = sig1.verify(out);
+ if (!verify) {
+ throw new RuntimeException("VERIFY1 FAIL!");
+ }
+ } catch (Exception ex) {
+ System.out.println("\tVERIFY1 ERROR: unexpected exception!");
+ ex.printStackTrace();
+ throw ex;
+ }
+ System.out.println("\t=> PASS");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/oracle/security/ucrypto/UcryptoTest.java Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 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.
+ */
+
+
+// common infrastructure for OracleUcrypto provider tests
+
+import java.io.*;
+import java.util.*;
+import java.lang.reflect.*;
+
+import java.security.*;
+
+public abstract class UcryptoTest {
+
+ protected static final boolean hasUcrypto;
+ static {
+ hasUcrypto = (Security.getProvider("OracleUcrypto") != null);
+ }
+
+ private static Provider getCustomizedUcrypto(String config) throws Exception {
+ Class clazz = Class.forName("com.oracle.security.ucrypto.OracleUcrypto");
+ Constructor cons = clazz.getConstructor(new Class[] {String.class});
+ Object obj = cons.newInstance(new Object[] {config});
+ return (Provider)obj;
+ }
+
+ public abstract void doTest(Provider p) throws Exception;
+
+ public static void main(UcryptoTest test, String config) throws Exception {
+ Provider prov = null;
+ if (hasUcrypto) {
+ if (config != null) {
+ prov = getCustomizedUcrypto(config);
+ } else {
+ prov = Security.getProvider("OracleUcrypto");
+ }
+ }
+ if (prov == null) {
+ // un-available, skip testing...
+ System.out.println("No OracleUcrypto provider found, skipping test");
+ return;
+ }
+ test.doTest(prov);
+ }
+}
--- a/jdk/test/java/io/File/BlockIsDirectory.java Fri Jan 27 13:48:40 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please 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 4113217
- @summary Test File.isDirectory on block device
- */
-
-import java.io.*;
-import java.util.*;
-
-public class BlockIsDirectory {
- public static void main( String args[] ) throws Exception {
- String osname = System.getProperty("os.name");
- if (osname.equals("SunOS")) {
- File dir = new File("/dev/dsk");
- String dirList[] = dir.list();
-
- File aFile = new File( "/dev/dsk/" + dirList[0] );
-
- boolean result = aFile.isDirectory();
- if (result == true)
- throw new RuntimeException(
- "IsDirectory returns true for block device.");
- }
- if (osname.equals("Linux")) {
- File dir = new File("/dev/ide0");
- if (dir.exists()) {
- boolean result = dir.isDirectory();
- if (result == true)
- throw new RuntimeException(
- "IsDirectory returns true for block device.");
- }
- dir = new File("/dev/scd0");
- if (dir.exists()) {
- boolean result = dir.isDirectory();
- if (result == true)
- throw new RuntimeException(
- "IsDirectory returns true for block device.");
- }
- }
- }
-}
--- a/jdk/test/java/io/FileInputStream/LargeFileAvailable.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/test/java/io/FileInputStream/LargeFileAvailable.java Sat Jan 28 22:21:54 2012 -0800
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6402006
+ * @bug 6402006 7030573
* @summary Test if available returns correct value when reading
* a large file.
*/
@@ -35,23 +35,35 @@
import static java.nio.file.StandardOpenOption.*;
public class LargeFileAvailable {
- private static final long FILESIZE = 7405576182L;
public static void main(String args[]) throws Exception {
- File file = createLargeFile(FILESIZE);
+ // Create a temporary file in the current directory.
+ // Use it to check if we have 7G available for
+ // a large sparse file test. As a fallback use whatever
+ // space is available, so the test can proceed.
+ File file = File.createTempFile("largefile", null, new File("."));
+ long spaceavailable = file.getUsableSpace();
+ long filesize = Math.min(spaceavailable, 7405576182L);
+ if (spaceavailable == 0L) {
+ // A full disk is considered fatal.
+ throw new RuntimeException("No space available for temp file.");
+ }
+
+ createLargeFile(filesize, file);
+
try (FileInputStream fis = new FileInputStream(file)) {
- if (file.length() != FILESIZE) {
- throw new RuntimeException("unexpected file size = " + file.length());
+ if (file.length() != filesize) {
+ throw new RuntimeException("unexpected file size = "
+ + file.length());
}
- long bigSkip = 3110608882L;
- long remaining = FILESIZE;
+ long bigSkip = Math.min(filesize/2, 3110608882L);
+ long remaining = filesize;
remaining -= skipBytes(fis, bigSkip, remaining);
remaining -= skipBytes(fis, 10L, remaining);
remaining -= skipBytes(fis, bigSkip, remaining);
if (fis.available() != (int) remaining) {
- throw new RuntimeException("available() returns " +
- fis.available() +
- " but expected " + remaining);
+ throw new RuntimeException("available() returns "
+ + fis.available() + " but expected " + remaining);
}
} finally {
file.delete();
@@ -64,39 +76,41 @@
throws IOException {
long skip = is.skip(toSkip);
if (skip != toSkip) {
- throw new RuntimeException("skip() returns " + skip +
- " but expected " + toSkip);
+ throw new RuntimeException("skip() returns " + skip
+ + " but expected " + toSkip);
}
long remaining = avail - skip;
int expected = remaining >= Integer.MAX_VALUE
? Integer.MAX_VALUE
: (int) remaining;
- System.out.println("Skipped " + skip + " bytes " +
- " available() returns " + expected +
+ System.out.println("Skipped " + skip + " bytes "
+ + " available() returns " + expected +
" remaining=" + remaining);
if (is.available() != expected) {
- throw new RuntimeException("available() returns " +
- is.available() + " but expected " + expected);
+ throw new RuntimeException("available() returns "
+ + is.available() + " but expected " + expected);
}
return skip;
}
- private static File createLargeFile(long filesize) throws Exception {
- // Create a large file as a sparse file if possible
- File largefile = File.createTempFile("largefile", null);
- // re-create as a sparse file
- Files.delete(largefile.toPath());
+ private static void createLargeFile(long filesize,
+ File file) throws Exception {
+ // Recreate a large file as a sparse file if possible
+ Files.delete(file.toPath());
+
try (FileChannel fc =
- FileChannel.open(largefile.toPath(),
- CREATE_NEW, WRITE, SPARSE)) {
+ FileChannel.open(file.toPath(),
+ CREATE_NEW, WRITE, SPARSE)) {
ByteBuffer bb = ByteBuffer.allocate(1).put((byte)1);
bb.rewind();
- int rc = fc.write(bb, filesize-1);
+ int rc = fc.write(bb, filesize - 1);
+
if (rc != 1) {
- throw new RuntimeException("Failed to write 1 byte to the large file");
+ throw new RuntimeException("Failed to write 1 byte"
+ + " to the large file");
}
}
- return largefile;
+ return;
}
}
--- a/jdk/test/java/lang/invoke/CallSiteTest.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/test/java/lang/invoke/CallSiteTest.java Sat Jan 28 22:21:54 2012 -0800
@@ -43,7 +43,7 @@
import static java.lang.invoke.MethodType.*;
public class CallSiteTest {
- private final static Class CLASS = CallSiteTest.class;
+ private final static Class<?> CLASS = CallSiteTest.class;
private static CallSite mcs;
private static CallSite vcs;
--- a/jdk/test/java/lang/invoke/ClassValueTest.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/test/java/lang/invoke/ClassValueTest.java Sat Jan 28 22:21:54 2012 -0800
@@ -38,10 +38,6 @@
package test.java.lang.invoke;
-import java.util.*;
-
-import java.lang.invoke.*;
-
import org.junit.*;
import static org.junit.Assert.*;
@@ -61,7 +57,7 @@
}
}
- static final Class[] CLASSES = {
+ static final Class<?>[] CLASSES = {
String.class,
Integer.class,
int.class,
@@ -73,11 +69,11 @@
@Test
public void testGet() {
countForCV1 = 0;
- for (Class c : CLASSES) {
+ for (Class<?> c : CLASSES) {
assertEquals(nameForCV1(c), CV1.get(c));
}
assertEquals(CLASSES.length, countForCV1);
- for (Class c : CLASSES) {
+ for (Class<?> c : CLASSES) {
assertEquals(nameForCV1(c), CV1.get(c));
}
assertEquals(CLASSES.length, countForCV1);
@@ -85,7 +81,7 @@
@Test
public void testRemove() {
- for (Class c : CLASSES) {
+ for (Class<?> c : CLASSES) {
CV1.get(c);
}
countForCV1 = 0;
@@ -94,7 +90,7 @@
CV1.remove(CLASSES[i]);
}
assertEquals(0, countForCV1); // no change
- for (Class c : CLASSES) {
+ for (Class<?> c : CLASSES) {
assertEquals(nameForCV1(c), CV1.get(c));
}
assertEquals(REMCOUNT, countForCV1);
@@ -124,7 +120,7 @@
for (int pass = 0; pass <= 2; pass++) {
for (int i1 = 0; i1 < CVN_COUNT1; i1++) {
eachClass:
- for (Class c : CLASSES) {
+ for (Class<?> c : CLASSES) {
for (int i2 = 0; i2 < CVN_COUNT2; i2++) {
int n = i1*CVN_COUNT2 + i2;
assertEquals(0, countForCVN);
@@ -156,8 +152,10 @@
}
}
assertEquals(countForCVN, 0);
- for (int n = 0; n < cvns.length; n++) {
- for (Class c : CLASSES) {
+ System.out.println("[rechecking values]");
+ for (int i = 0; i < cvns.length * 10; i++) {
+ int n = i % cvns.length;
+ for (Class<?> c : CLASSES) {
assertEquals(nameForCVN(c, n), cvns[n].get(c));
}
}
--- a/jdk/test/java/lang/invoke/InvokeGenericTest.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/test/java/lang/invoke/InvokeGenericTest.java Sat Jan 28 22:21:54 2012 -0800
@@ -45,6 +45,7 @@
*
* @author jrose
*/
+@SuppressWarnings("cast") // various casts help emphasize arguments to invokeExact
public class InvokeGenericTest {
// How much output?
static int verbosity = 0;
@@ -129,7 +130,7 @@
}
}
- static List<Object> calledLog = new ArrayList<Object>();
+ static List<Object> calledLog = new ArrayList<>();
static Object logEntry(String name, Object... args) {
return Arrays.asList(name, Arrays.asList(args));
}
@@ -237,8 +238,7 @@
else
try {
return param.newInstance();
- } catch (InstantiationException ex) {
- } catch (IllegalAccessException ex) {
+ } catch (InstantiationException | IllegalAccessException ex) {
}
return null; // random class not Object, String, Integer, etc.
}
@@ -274,9 +274,11 @@
return zeroArgs(params.toArray(new Class<?>[0]));
}
+ @SafeVarargs @SuppressWarnings("varargs")
static <T, E extends T> T[] array(Class<T[]> atype, E... a) {
return Arrays.copyOf(a, a.length, atype);
}
+ @SafeVarargs @SuppressWarnings("varargs")
static <T> T[] cat(T[] a, T... b) {
int alen = a.length, blen = b.length;
if (blen == 0) return a;
@@ -311,7 +313,7 @@
int beg, int end, Class<?> argType) {
MethodType targetType = target.type();
end = Math.min(end, targetType.parameterCount());
- ArrayList<Class<?>> argTypes = new ArrayList<Class<?>>(targetType.parameterList());
+ ArrayList<Class<?>> argTypes = new ArrayList<>(targetType.parameterList());
Collections.fill(argTypes.subList(beg, end), argType);
MethodType ttype2 = MethodType.methodType(targetType.returnType(), argTypes);
return target.asType(ttype2);
@@ -320,7 +322,7 @@
// This lookup is good for all members in and under InvokeGenericTest.
static final Lookup LOOKUP = MethodHandles.lookup();
- Map<List<Class<?>>, MethodHandle> CALLABLES = new HashMap<List<Class<?>>, MethodHandle>();
+ Map<List<Class<?>>, MethodHandle> CALLABLES = new HashMap<>();
MethodHandle callable(List<Class<?>> params) {
MethodHandle mh = CALLABLES.get(params);
if (mh == null) {
@@ -353,8 +355,8 @@
countTest();
String[] args = { "one", "two" };
MethodHandle mh = callable(Object.class, String.class);
- Object res; List resl;
- res = resl = (List) mh.invoke((String)args[0], (Object)args[1]);
+ Object res; List<?> resl;
+ res = resl = (List<?>) mh.invoke((String)args[0], (Object)args[1]);
//System.out.println(res);
assertEquals(Arrays.asList(args), res);
}
@@ -365,8 +367,8 @@
countTest();
int[] args = { 1, 2 };
MethodHandle mh = callable(Object.class, Object.class);
- Object res; List resl;
- res = resl = (List) mh.invoke(args[0], args[1]);
+ Object res; List<?> resl;
+ res = resl = (List<?>) mh.invoke(args[0], args[1]);
//System.out.println(res);
assertEquals(Arrays.toString(args), res.toString());
}
@@ -377,8 +379,8 @@
countTest();
String[] args = { "one", "two" };
MethodHandle mh = callable(Object.class, String.class);
- Object res; List resl;
- res = resl = (List) mh.invoke((String)args[0], (Object)args[1]);
+ Object res; List<?> resl;
+ res = resl = (List<?>) mh.invoke((String)args[0], (Object)args[1]);
//System.out.println(res);
assertEquals(Arrays.asList(args), res);
}
@@ -440,9 +442,9 @@
* A void return type is possible iff the first type is void.class.
*/
static List<MethodType> allMethodTypes(int minargc, int maxargc, Class<?>... types) {
- ArrayList<MethodType> result = new ArrayList<MethodType>();
+ ArrayList<MethodType> result = new ArrayList<>();
if (types.length > 0) {
- ArrayList<MethodType> argcTypes = new ArrayList<MethodType>();
+ ArrayList<MethodType> argcTypes = new ArrayList<>();
// build arity-zero types first
for (Class<?> rtype : types) {
argcTypes.add(MethodType.methodType(rtype));
@@ -456,7 +458,7 @@
if (argc >= maxargc)
break;
ArrayList<MethodType> prevTypes = argcTypes;
- argcTypes = new ArrayList<MethodType>();
+ argcTypes = new ArrayList<>();
for (MethodType prevType : prevTypes) {
for (Class<?> ptype : types) {
argcTypes.add(prevType.insertParameterTypes(argc, ptype));
@@ -524,8 +526,8 @@
countTest();
Object[] args = { 1, 2 };
MethodHandle mh = callable(Object.class, int.class);
- Object res; List resl; int resi;
- res = resl = (List) mh.invoke((int)args[0], (Object)args[1]);
+ Object res; List<?> resl; int resi;
+ res = resl = (List<?>) mh.invoke((int)args[0], (Object)args[1]);
//System.out.println(res);
assertEquals(Arrays.asList(args), res);
mh = MethodHandles.identity(int.class);
--- a/jdk/test/java/lang/invoke/JavaDocExamplesTest.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/test/java/lang/invoke/JavaDocExamplesTest.java Sat Jan 28 22:21:54 2012 -0800
@@ -54,6 +54,7 @@
/**
* @author jrose
*/
+@SuppressWarnings("LocalVariableHidesMemberVariable")
public class JavaDocExamplesTest {
/** Wrapper for running the JUnit tests in this module.
* Put JUnit on the classpath!
@@ -336,6 +337,7 @@
}}
}
+ @SuppressWarnings("rawtypes")
@Test public void testAsVarargsCollector() throws Throwable {
{{
{} /// JAVADOC
--- a/jdk/test/java/lang/invoke/MethodHandlesTest.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/test/java/lang/invoke/MethodHandlesTest.java Sat Jan 28 22:21:54 2012 -0800
@@ -176,7 +176,7 @@
}
}
- static List<Object> calledLog = new ArrayList<Object>();
+ static List<Object> calledLog = new ArrayList<>();
static Object logEntry(String name, Object... args) {
return Arrays.asList(name, Arrays.asList(args));
}
@@ -211,6 +211,7 @@
return dst.cast(value);
}
+ @SuppressWarnings("cast") // primitive cast to (long) is part of the pattern
static Object castToWrapperOrNull(long value, Class<?> dst) {
if (dst == int.class || dst == Integer.class)
return (int)(value);
@@ -284,8 +285,7 @@
else
try {
return param.newInstance();
- } catch (InstantiationException ex) {
- } catch (IllegalAccessException ex) {
+ } catch (InstantiationException | IllegalAccessException ex) {
}
return null; // random class not Object, String, Integer, etc.
}
@@ -302,9 +302,11 @@
return args;
}
+ @SafeVarargs @SuppressWarnings("varargs")
static <T, E extends T> T[] array(Class<T[]> atype, E... a) {
return Arrays.copyOf(a, a.length, atype);
}
+ @SafeVarargs @SuppressWarnings("varargs")
static <T> T[] cat(T[] a, T... b) {
int alen = a.length, blen = b.length;
if (blen == 0) return a;
@@ -354,14 +356,14 @@
try {
LIST_TO_STRING = PRIVATE.findStatic(PRIVATE.lookupClass(), "listToString",
MethodType.methodType(String.class, List.class));
- } catch (Exception ex) { throw new RuntimeException(ex); }
+ } catch (NoSuchMethodException | IllegalAccessException ex) { throw new RuntimeException(ex); }
list = MethodHandles.filterReturnValue(list, LIST_TO_STRING);
} else if (rtype.isPrimitive()) {
if (LIST_TO_INT == null)
try {
LIST_TO_INT = PRIVATE.findStatic(PRIVATE.lookupClass(), "listToInt",
MethodType.methodType(int.class, List.class));
- } catch (Exception ex) { throw new RuntimeException(ex); }
+ } catch (NoSuchMethodException | IllegalAccessException ex) { throw new RuntimeException(ex); }
list = MethodHandles.filterReturnValue(list, LIST_TO_INT);
list = MethodHandles.explicitCastArguments(list, listType);
} else {
@@ -370,8 +372,8 @@
return list.asType(listType);
}
private static MethodHandle LIST_TO_STRING, LIST_TO_INT;
- private static String listToString(List x) { return x.toString(); }
- private static int listToInt(List x) { return x.toString().hashCode(); }
+ private static String listToString(List<?> x) { return x.toString(); }
+ private static int listToInt(List<?> x) { return x.toString().hashCode(); }
static MethodHandle changeArgTypes(MethodHandle target, Class<?> argType) {
return changeArgTypes(target, 0, 999, argType);
@@ -380,7 +382,7 @@
int beg, int end, Class<?> argType) {
MethodType targetType = target.type();
end = Math.min(end, targetType.parameterCount());
- ArrayList<Class<?>> argTypes = new ArrayList<Class<?>>(targetType.parameterList());
+ ArrayList<Class<?>> argTypes = new ArrayList<>(targetType.parameterList());
Collections.fill(argTypes.subList(beg, end), argType);
MethodType ttype2 = MethodType.methodType(targetType.returnType(), argTypes);
return target.asType(ttype2);
@@ -405,6 +407,7 @@
final String name;
public Example() { name = "Example#"+nextArg(); }
protected Example(String name) { this.name = name; }
+ @SuppressWarnings("LeakingThisInConstructor")
protected Example(int x) { this(); called("protected <init>", this, x); }
@Override public String toString() { return name; }
@@ -441,6 +444,7 @@
static class SubExample extends Example {
@Override public void v0() { called("Sub/v0", this); }
@Override void pkg_v0() { called("Sub/pkg_v0", this); }
+ @SuppressWarnings("LeakingThisInConstructor")
private SubExample(int x) { called("<init>", this, x); }
public SubExample() { super("SubExample#"+nextArg()); }
}
@@ -912,7 +916,7 @@
static final Object[][] CASES;
static {
- ArrayList<Object[]> cases = new ArrayList<Object[]>();
+ ArrayList<Object[]> cases = new ArrayList<>();
Object types[][] = {
{'L',Object.class}, {'R',String.class},
{'I',int.class}, {'J',long.class},
@@ -931,12 +935,12 @@
Field field;
try {
field = HasFields.class.getDeclaredField(name);
- } catch (Exception ex) {
+ } catch (NoSuchFieldException | SecurityException ex) {
throw new InternalError("no field HasFields."+name);
}
try {
value = field.get(fields);
- } catch (Exception ex) {
+ } catch (IllegalArgumentException | IllegalAccessException ex) {
throw new InternalError("cannot fetch field HasFields."+name);
}
if (type == float.class) {
@@ -1257,7 +1261,7 @@
List<Object> array2list(Object array) {
int length = Array.getLength(array);
- ArrayList<Object> model = new ArrayList<Object>(length);
+ ArrayList<Object> model = new ArrayList<>(length);
for (int i = 0; i < length; i++)
model.add(Array.get(array, i));
return model;
@@ -1288,7 +1292,7 @@
String name = pfx+"id";
try {
return PRIVATE.findStatic(Callee.class, name, type);
- } catch (Exception ex) {
+ } catch (NoSuchMethodException | IllegalAccessException ex) {
throw new RuntimeException(ex);
}
}
@@ -1365,7 +1369,7 @@
MethodHandle vac = vac0.asVarargsCollector(Object[].class);
testConvert(true, vac.asType(MethodType.genericMethodType(0)), null, "vac");
testConvert(true, vac.asType(MethodType.genericMethodType(0)), null, "vac");
- for (Class<?> at : new Class[] { Object.class, String.class, Integer.class }) {
+ for (Class<?> at : new Class<?>[] { Object.class, String.class, Integer.class }) {
testConvert(true, vac.asType(MethodType.genericMethodType(1)), null, "vac", at);
testConvert(true, vac.asType(MethodType.genericMethodType(2)), null, "vac", at, at);
}
@@ -1514,7 +1518,7 @@
public void testSpreadArguments() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("spreadArguments");
- for (Class<?> argType : new Class[]{Object.class, Integer.class, int.class}) {
+ for (Class<?> argType : new Class<?>[]{Object.class, Integer.class, int.class}) {
if (verbosity >= 3)
System.out.println("spreadArguments "+argType);
for (int nargs = 0; nargs < 50; nargs++) {
@@ -1538,7 +1542,7 @@
Object[] args = randomArgs(target2.type().parameterArray());
// make sure the target does what we think it does:
if (pos == 0 && nargs < 5 && !argType.isPrimitive()) {
- Object[] check = (Object[]) (Object) target.invokeWithArguments(args);
+ Object[] check = (Object[]) target.invokeWithArguments(args);
assertArrayEquals(args, check);
switch (nargs) {
case 0:
@@ -1555,7 +1559,7 @@
break;
}
}
- List<Class<?>> newParams = new ArrayList<Class<?>>(target2.type().parameterList());
+ List<Class<?>> newParams = new ArrayList<>(target2.type().parameterList());
{ // modify newParams in place
List<Class<?>> spreadParams = newParams.subList(pos, nargs);
spreadParams.clear(); spreadParams.add(arrayType);
@@ -1608,7 +1612,7 @@
public void testCollectArguments() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("collectArguments");
- for (Class<?> argType : new Class[]{Object.class, Integer.class, int.class}) {
+ for (Class<?> argType : new Class<?>[]{Object.class, Integer.class, int.class}) {
if (verbosity >= 3)
System.out.println("collectArguments "+argType);
for (int nargs = 0; nargs < 50; nargs++) {
@@ -1670,12 +1674,13 @@
MethodHandle target = varargsArray(nargs + ins);
Object[] args = randomArgs(target.type().parameterArray());
List<Object> resList = Arrays.asList(args);
- List<Object> argsToPass = new ArrayList<Object>(resList);
+ List<Object> argsToPass = new ArrayList<>(resList);
List<Object> argsToInsert = argsToPass.subList(pos, pos + ins);
if (verbosity >= 3)
System.out.println("insert: "+argsToInsert+" into "+target);
+ @SuppressWarnings("cast") // cast to spread Object... is helpful
MethodHandle target2 = MethodHandles.insertArguments(target, pos,
- (Object[]) argsToInsert.toArray());
+ (Object[]/*...*/) argsToInsert.toArray());
argsToInsert.clear(); // remove from argsToInsert
Object res2 = target2.invokeWithArguments(argsToPass);
Object res2List = Arrays.asList((Object[])res2);
@@ -1693,7 +1698,7 @@
Class<?> classOfVCList = varargsList(1).invokeWithArguments(0).getClass();
assertTrue(List.class.isAssignableFrom(classOfVCList));
for (int nargs = 0; nargs <= 3; nargs++) {
- for (Class<?> rtype : new Class[] { Object.class,
+ for (Class<?> rtype : new Class<?>[] { Object.class,
List.class,
int.class,
byte.class,
@@ -1790,7 +1795,7 @@
System.out.println("fold "+target+" with "+combine);
MethodHandle target2 = MethodHandles.foldArguments(target, combine);
// Simulate expected effect of combiner on arglist:
- List<Object> expected = new ArrayList<Object>(argsToPass);
+ List<Object> expected = new ArrayList<>(argsToPass);
List<Object> argsToFold = expected.subList(pos, pos + fold);
if (verbosity >= 3)
System.out.println("fold: "+argsToFold+" into "+target2);
@@ -1822,9 +1827,9 @@
MethodHandle target = varargsArray(nargs);
Object[] args = randomArgs(target.type().parameterArray());
MethodHandle target2 = MethodHandles.dropArguments(target, pos,
- Collections.nCopies(drop, Object.class).toArray(new Class[0]));
+ Collections.nCopies(drop, Object.class).toArray(new Class<?>[0]));
List<Object> resList = Arrays.asList(args);
- List<Object> argsToDrop = new ArrayList<Object>(resList);
+ List<Object> argsToDrop = new ArrayList<>(resList);
for (int i = drop; i > 0; i--) {
argsToDrop.add(pos, "blort#"+i);
}
@@ -1840,11 +1845,11 @@
if (CAN_SKIP_WORKING) return;
startTest("exactInvoker, genericInvoker, varargsInvoker, dynamicInvoker");
// exactInvoker, genericInvoker, varargsInvoker[0..N], dynamicInvoker
- Set<MethodType> done = new HashSet<MethodType>();
+ Set<MethodType> done = new HashSet<>();
for (int i = 0; i <= 6; i++) {
if (CAN_TEST_LIGHTLY && i > 3) break;
MethodType gtype = MethodType.genericMethodType(i);
- for (Class<?> argType : new Class[]{Object.class, Integer.class, int.class}) {
+ for (Class<?> argType : new Class<?>[]{Object.class, Integer.class, int.class}) {
for (int j = -1; j < i; j++) {
MethodType type = gtype;
if (j < 0)
@@ -1873,7 +1878,7 @@
assertTrue(target.isVarargsCollector());
target = target.asType(type);
Object[] args = randomArgs(type.parameterArray());
- List<Object> targetPlusArgs = new ArrayList<Object>(Arrays.asList(args));
+ List<Object> targetPlusArgs = new ArrayList<>(Arrays.asList(args));
targetPlusArgs.add(0, target);
int code = (Integer) invokee(args);
Object log = logEntry("invokee", args);
@@ -1960,7 +1965,7 @@
.appendParameterTypes(Object[].class)
.insertParameterTypes(0, MethodHandle.class));
assertEquals(expType, inv.type());
- List<Object> targetPlusVarArgs = new ArrayList<Object>(targetPlusArgs);
+ List<Object> targetPlusVarArgs = new ArrayList<>(targetPlusArgs);
List<Object> tailList = targetPlusVarArgs.subList(1+k, 1+nargs);
Object[] tail = tailList.toArray();
tailList.clear(); tailList.add(tail);
@@ -2191,7 +2196,7 @@
if (throwMode == THROW_NOTHING) {
assertSame(arg0, returned);
} else if (throwMode == THROW_CAUGHT) {
- List<Object> catchArgs = new ArrayList<Object>(Arrays.asList(args));
+ List<Object> catchArgs = new ArrayList<>(Arrays.asList(args));
// catcher receives an initial subsequence of target arguments:
catchArgs.subList(nargs - catchDrops, nargs).clear();
// catcher also receives the exception, prepended:
@@ -2317,12 +2322,13 @@
INT_IDENTITY = PRIVATE.findStatic(
Surprise.class, "intIdentity",
MethodType.methodType(int.class, int.class));
- } catch (Exception ex) {
+ } catch (NoSuchMethodException | IllegalAccessException ex) {
throw new RuntimeException(ex);
}
}
}
+ @SuppressWarnings("ConvertToStringSwitch")
void testCastFailure(String mode, int okCount) throws Throwable {
countTest(false);
if (verbosity > 2) System.out.println("mode="+mode);
@@ -2418,13 +2424,14 @@
}
public interface Fooable {
// overloads:
- Object foo(Object x, String y);
- List foo(String x, int y);
- Object foo(String x);
+ Object foo(Object x, String y);
+ List<?> foo(String x, int y);
+ Object foo(String x);
}
static Object fooForFooable(String x, Object... y) {
return called("fooForFooable/"+x, y);
}
+ @SuppressWarnings("serial") // not really a public API, just a test case
public static class MyCheckedException extends Exception {
}
public interface WillThrow {
@@ -2453,7 +2460,7 @@
{
countTest();
if (verbosity >= 2) System.out.println("Appendable");
- ArrayList<List> appendResults = new ArrayList<List>();
+ ArrayList<List<?>> appendResults = new ArrayList<>();
MethodHandle append = lookup.bind(appendResults, "add", MethodType.methodType(boolean.class, Object.class));
append = append.asType(MethodType.methodType(void.class, List.class)); // specialize the type
MethodHandle asList = lookup.findStatic(Arrays.class, "asList", MethodType.methodType(List.class, Object[].class));
@@ -2475,11 +2482,11 @@
formatter.format(fmt, fmtArgs);
String actual = "";
if (verbosity >= 3) System.out.println("appendResults="+appendResults);
- for (List l : appendResults) {
+ for (List<?> l : appendResults) {
Object x = l.get(0);
switch (l.size()) {
case 1: actual += x; continue;
- case 3: actual += ((String)x).substring((int)l.get(1), (int)l.get(2)); continue;
+ case 3: actual += ((String)x).substring((int)(Object)l.get(1), (int)(Object)l.get(2)); continue;
}
actual += l;
}
@@ -2551,7 +2558,7 @@
}
}
// Test error checking on bad interfaces:
- for (Class<?> nonSMI : new Class[] { Object.class,
+ for (Class<?> nonSMI : new Class<?>[] { Object.class,
String.class,
CharSequence.class,
java.io.Serializable.class,
@@ -2579,7 +2586,7 @@
}
}
// Test error checking on interfaces with the wrong method type:
- for (Class<?> intfc : new Class[] { Runnable.class /*arity 0*/,
+ for (Class<?> intfc : new Class<?>[] { Runnable.class /*arity 0*/,
Fooable.class /*arity 1 & 2*/ }) {
int badArity = 1; // known to be incompatible
if (verbosity > 2) System.out.println(intfc.getName());
@@ -2657,7 +2664,7 @@
Object a8, Object a9)
{ return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
static MethodHandle[] makeArrays() {
- ArrayList<MethodHandle> arrays = new ArrayList<MethodHandle>();
+ ArrayList<MethodHandle> arrays = new ArrayList<>();
MethodHandles.Lookup lookup = IMPL_LOOKUP;
for (;;) {
int nargs = arrays.size();
@@ -2746,7 +2753,7 @@
Object a8, Object a9)
{ return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
static MethodHandle[] makeLists() {
- ArrayList<MethodHandle> lists = new ArrayList<MethodHandle>();
+ ArrayList<MethodHandle> lists = new ArrayList<>();
MethodHandles.Lookup lookup = IMPL_LOOKUP;
for (;;) {
int nargs = lists.size();
@@ -2769,7 +2776,7 @@
static {
try {
AS_LIST = IMPL_LOOKUP.findStatic(Arrays.class, "asList", MethodType.methodType(List.class, Object[].class));
- } catch (Exception ex) { throw new RuntimeException(ex); }
+ } catch (NoSuchMethodException | IllegalAccessException ex) { throw new RuntimeException(ex); }
}
/** Return a method handle that takes the indicated number of Object
--- a/jdk/test/java/lang/invoke/MethodTypeTest.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/test/java/lang/invoke/MethodTypeTest.java Sat Jan 28 22:21:54 2012 -0800
@@ -29,6 +29,7 @@
package test.java.lang.invoke;
+import java.io.IOException;
import java.lang.invoke.MethodType;
import java.lang.reflect.Method;
@@ -378,7 +379,7 @@
public void testHashCode() {
System.out.println("hashCode");
MethodType instance = mt_viS;
- ArrayList<Class<?>> types = new ArrayList<Class<?>>();
+ ArrayList<Class<?>> types = new ArrayList<>();
types.add(instance.returnType());
types.addAll(instance.parameterList());
int expResult = types.hashCode();
@@ -556,7 +557,7 @@
Object decode;
try {
decode = readSerial(wire);
- } catch (Exception ex) {
+ } catch (IOException | ClassNotFoundException ex) {
decode = ex; // oops!
}
assertEquals(mt, decode);
--- a/jdk/test/java/lang/invoke/PermuteArgsTest.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/test/java/lang/invoke/PermuteArgsTest.java Sat Jan 28 22:21:54 2012 -0800
@@ -45,7 +45,7 @@
import static java.lang.invoke.MethodType.*;
public class PermuteArgsTest {
- private static final Class CLASS = PermuteArgsTest.class;
+ private static final Class<?> CLASS = PermuteArgsTest.class;
private static final int MAX_ARITY = Integer.getInteger(CLASS.getSimpleName()+".MAX_ARITY", 8);
private static final boolean DRY_RUN = Boolean.getBoolean(CLASS.getSimpleName()+".DRY_RUN");
private static final boolean VERBOSE = Boolean.getBoolean(CLASS.getSimpleName()+".VERBOSE") || DRY_RUN;
@@ -99,12 +99,12 @@
return Arrays.asList(w, x, y, z);
}
static Object listI_etc(int... va) {
- ArrayList<Object> res = new ArrayList<Object>();
+ ArrayList<Object> res = new ArrayList<>();
for (int x : va) res.add(x);
return res;
}
static Object listIJL_etc(int x, long y, Object z, Object... va) {
- ArrayList<Object> res = new ArrayList<Object>();
+ ArrayList<Object> res = new ArrayList<>();
res.addAll(Arrays.asList(x, y, z));
res.addAll(Arrays.asList(va));
return res;
@@ -168,7 +168,7 @@
mh1 = adjustArity(mh, arity);
} catch (IllegalArgumentException ex) {
System.out.println("*** mh = "+name+" : "+mh+"; arity = "+arity+" => "+ex);
- ex.printStackTrace();
+ ex.printStackTrace(System.out);
break; // cannot get this arity for this type
}
test("("+arity+")"+name, mh1);
@@ -213,7 +213,7 @@
}
static void testPermutations(MethodHandle mh) throws Throwable {
- HashSet<String> done = new HashSet<String>();
+ HashSet<String> done = new HashSet<>();
MethodType mt = mh.type();
int[] perm = nullPerm(mt.parameterCount());
final int MARGIN = (perm.length <= 10 ? 2 : 0);
@@ -326,8 +326,8 @@
Class<?> pt = ptypes[i];
Object arg;
if (pt == Void.class) arg = null;
- else if (pt == int.class) arg = (int) i + 101;
- else if (pt == long.class) arg = (long) i + 10_000_000_001L;
+ else if (pt == int.class) arg = i + 101;
+ else if (pt == long.class) arg = i + 10_000_000_001L;
else arg = "#" + (i + 1);
args[i] = arg;
}
--- a/jdk/test/java/lang/invoke/RicochetTest.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/test/java/lang/invoke/RicochetTest.java Sat Jan 28 22:21:54 2012 -0800
@@ -40,7 +40,6 @@
import static java.lang.invoke.MethodType.*;
import static java.lang.invoke.MethodHandles.*;
import static org.junit.Assert.*;
-import static org.junit.Assume.*;
/**
@@ -48,7 +47,7 @@
* @author jrose
*/
public class RicochetTest {
- private static final Class CLASS = RicochetTest.class;
+ private static final Class<?> CLASS = RicochetTest.class;
private static final int MAX_ARITY = Integer.getInteger(CLASS.getSimpleName()+".MAX_ARITY", 40);
public static void main(String... av) throws Throwable {
@@ -148,7 +147,7 @@
for (int nargs = 0; nargs <= MAX; nargs++) {
if (nargs > 30 && nargs < MAX-20) nargs += 10;
int[] args = new int[nargs];
- for (int j = 0; j < args.length; j++) args[j] = (int)(j + 11);
+ for (int j = 0; j < args.length; j++) args[j] = j + 11;
//System.out.println("testIntSpreads "+Arrays.toString(args));
int[] args1 = (int[]) id.invokeExact(args);
assertArrayEquals(args, args1);
@@ -388,6 +387,7 @@
java.util.Random random;
final MethodHandle[] fns;
int depth;
+ @SuppressWarnings("LeakingThisInConstructor")
RFCB(int seed) throws Throwable {
this.random = new java.util.Random(seed);
this.fns = new MethodHandle[Math.max(29, (1 << MAX_DEPTH-2)/3)];
@@ -408,7 +408,7 @@
case 1:
Throwable ex = new RuntimeException();
ex.fillInStackTrace();
- if (VERBOSITY >= 2) ex.printStackTrace();
+ if (VERBOSITY >= 2) ex.printStackTrace(System.out);
x = "ST; " + x;
break;
case 2:
@@ -467,7 +467,7 @@
return mh.invokeWithArguments(args);
} catch (Throwable ex) {
System.out.println("threw: "+mh+Arrays.asList(args));
- ex.printStackTrace();
+ ex.printStackTrace(System.out);
return ex;
}
}
@@ -515,8 +515,8 @@
private static long opJ(long x) { return (long) opI((int)x); }
private static Object opL2(Object x, Object y) { return (Object) opI2((int)x, (int)y); }
private static Object opL(Object x) { return (Object) opI((int)x); }
- private static int opL2_I(Object x, Object y) { return (int) opI2((int)x, (int)y); }
- private static int opL_I(Object x) { return (int) opI((int)x); }
+ private static int opL2_I(Object x, Object y) { return opI2((int)x, (int)y); }
+ private static int opL_I(Object x) { return opI((int)x); }
private static long opL_J(Object x) { return (long) opI((int)x); }
private static final MethodHandle opI, opI2, opI3, opI4, opI_L, opJ, opJ2, opJ3, opL2, opL, opL2_I, opL_I, opL_J;
static {
@@ -570,8 +570,8 @@
INT_LISTERS[i] = lister;
LONG_LISTERS[i] = llister;
if (i == 0) break;
- lister = insertArguments(lister, i-1, (int)0);
- llister = insertArguments(llister, i-1, (long)0);
+ lister = insertArguments(lister, i-1, 0);
+ llister = insertArguments(llister, i-1, 0L);
}
}
--- a/jdk/test/java/lang/invoke/ThrowExceptionsTest.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/test/java/lang/invoke/ThrowExceptionsTest.java Sat Jan 28 22:21:54 2012 -0800
@@ -40,7 +40,7 @@
import static java.lang.invoke.MethodType.*;
public class ThrowExceptionsTest {
- private static final Class CLASS = ThrowExceptionsTest.class;
+ private static final Class<?> CLASS = ThrowExceptionsTest.class;
private static final Lookup LOOKUP = lookup();
public static void main(String argv[]) throws Throwable {
@@ -132,9 +132,9 @@
int tc = testCases;
try {
m.invoke(this);
- } catch (Throwable ex) {
+ } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
System.out.println("*** "+ex);
- ex.printStackTrace();
+ ex.printStackTrace(System.out);
}
if (testCases == tc) testCases++;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/HttpURLConnection/UnmodifiableMaps.java Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 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.
+ */
+
+/**
+ * @test
+ * @bug 7128648
+ * @summary HttpURLConnection.getHeaderFields should return an unmodifiable Map
+ */
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.net.HttpURLConnection;
+import java.util.Collection;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+import com.sun.net.httpserver.Headers;
+
+public class UnmodifiableMaps {
+
+ void test(String[] args) throws Exception {
+ HttpServer server = startHttpServer();
+ try {
+ InetSocketAddress address = server.getAddress();
+ URI uri = new URI("http://" + InetAddress.getLocalHost().getHostAddress()
+ + ":" + address.getPort() + "/foo");
+ doClient(uri);
+ } finally {
+ server.stop(0);
+ }
+ }
+
+ void doClient(URI uri) throws Exception {
+ HttpURLConnection uc = (HttpURLConnection) uri.toURL().openConnection();
+
+ // Test1: getRequestProperties is unmodifiable
+ System.out.println("Check getRequestProperties");
+ checkUnmodifiable(uc.getRequestProperties());
+ uc.addRequestProperty("X", "V");
+ uc.addRequestProperty("X1", "V1");
+ checkUnmodifiable(uc.getRequestProperties());
+
+ int resp = uc.getResponseCode();
+ check(resp == 200,
+ "Unexpected response code. Expected 200, got " + resp);
+
+ // Test2: getHeaderFields is unmodifiable
+ System.out.println("Check getHeaderFields");
+ checkUnmodifiable(uc.getHeaderFields());
+ // If the implementation does caching, check again.
+ checkUnmodifiable(uc.getHeaderFields());
+ }
+
+ // HTTP Server
+ HttpServer startHttpServer() throws IOException {
+ HttpServer httpServer = HttpServer.create(new InetSocketAddress(0), 0);
+ httpServer.createContext("/foo", new SimpleHandler());
+ httpServer.start();
+ return httpServer;
+ }
+
+ class SimpleHandler implements HttpHandler {
+ @Override
+ public void handle(HttpExchange t) throws IOException {
+ Headers respHeaders = t.getResponseHeaders();
+ // ensure some response headers, over the usual ones
+ respHeaders.add("RespHdr1", "Value1");
+ respHeaders.add("RespHdr2", "Value2");
+ respHeaders.add("RespHdr3", "Value3");
+ t.sendResponseHeaders(200, -1);
+ t.close();
+ }
+ }
+
+ void checkUnmodifiable(Map<String,List<String>> map) {
+ checkUnmodifiableMap(map);
+
+ // Now check the individual values
+ Collection<List<String>> values = map.values();
+ for (List<String> value : values) {
+ checkUnmodifiableList(value);
+ }
+ }
+
+ void checkUnmodifiableMap(final Map<String,List<String>> map) {
+ expectThrow( new Runnable() {
+ public void run() { map.clear(); }});
+ expectThrow( new Runnable() {
+ public void run() { map.put("X", new ArrayList<String>()); }});
+ expectThrow( new Runnable() {
+ public void run() { map.remove("X"); }});
+ }
+
+ void checkUnmodifiableList(final List<String> list) {
+ expectThrow( new Runnable() {
+ public void run() { list.clear(); }});
+ expectThrow( new Runnable() {
+ public void run() { list.add("X"); }});
+ expectThrow( new Runnable() {
+ public void run() { list.remove("X"); }});
+ }
+
+ void expectThrow(Runnable r) {
+ try { r.run(); fail("Excepted UOE to be thrown."); Thread.dumpStack(); }
+ catch (UnsupportedOperationException e) { pass(); }
+ }
+
+ volatile int passed = 0, failed = 0;
+ void pass() {passed++;}
+ void fail() {failed++;}
+ void fail(String msg) {System.err.println(msg); fail();}
+ void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ void check(boolean cond, String failMessage) {if (cond) pass(); else fail(failMessage);}
+ public static void main(String[] args) throws Throwable {
+ Class<?> k = new Object(){}.getClass().getEnclosingClass();
+ try {k.getMethod("instanceMain",String[].class)
+ .invoke( k.newInstance(), (Object) args);}
+ catch (Throwable e) {throw e.getCause();}}
+ public void instanceMain(String[] args) throws Throwable {
+ try {test(args);} catch (Throwable t) {unexpected(t);}
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+}
+
--- a/jdk/test/java/security/Provider/DefaultPKCS11.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/test/java/security/Provider/DefaultPKCS11.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -57,7 +57,10 @@
System.out.println("Test only applies to Solaris 10 and later, skipping");
return;
}
- if (ps[0].getName().equals("SunPKCS11-Solaris") == false) {
+ // SunPKCS11-Solaris provider should be either the first one or
+ // the second one
+ if (ps[0].getName().equals("SunPKCS11-Solaris") == false &&
+ ps[1].getName().equals("SunPKCS11-Solaris") == false) {
throw new Exception("SunPKCS11-Solaris provider not installed");
}
System.out.println("OK");
--- a/jdk/test/javax/crypto/Cipher/GetMaxAllowed.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/test/javax/crypto/Cipher/GetMaxAllowed.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 4807942
+ * @bug 4807942 7033170
* @summary Test the Cipher.getMaxAllowedKeyLength(String) and
* getMaxAllowedParameterSpec(String) methods
* @author Valerie Peng
@@ -40,7 +40,7 @@
public class GetMaxAllowed {
- private static void runTest(boolean isUnlimited) throws Exception {
+ private static void runTest1(boolean isUnlimited) throws Exception {
System.out.println("Testing " + (isUnlimited? "un":"") +
"limited policy...");
@@ -78,6 +78,20 @@
System.out.println("All tests passed");
}
+ private static void runTest2() throws Exception {
+ System.out.println("Testing against Security.getAlgorithms()");
+
+ Set<String> algorithms = Security.getAlgorithms("Cipher");
+
+ for (String algorithm: algorithms) {
+ int keylength = -1;
+
+ // if 7033170 is not fixed, NoSuchAlgorithmException is thrown
+ keylength = Cipher.getMaxAllowedKeyLength(algorithm);
+
+ }
+ }
+
public static void main(String[] args) throws Exception {
// decide if the installed jurisdiction policy file is the
// unlimited version
@@ -88,6 +102,9 @@
} catch (InvalidKeyException ike) {
isUnlimited = false;
}
- runTest(isUnlimited);
+ runTest1(isUnlimited);
+
+ // test using the set of algorithms returned by Security.getAlgorithms()
+ runTest2();
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/security/auth/x500/X500Principal/NameFormat.java Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 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.
+ */
+
+/*
+ * @test
+ * @bug 4505980 5109882 7049963 7090565
+ * @summary X500Principal input name parsing issues and wrong exception thrown
+ * @run main/othervm -Djava.security.debug=x509,ava NameFormat
+ *
+ * The debug=ava above must be set in order to check for escaped hex chars.
+ */
+import javax.security.auth.x500.X500Principal;
+
+public class NameFormat {
+
+ public static void main(String[] args) throws Exception {
+
+ // tests for leading/trailing escaped/non-escaped spaces
+
+ testName("cn=\\ duke ", "RFC1779", "CN=\" duke\"", 1);
+ testName("cn=\\ duke ", "RFC2253", "CN=\\ duke", 2);
+ testName("cn=\\ duke ", "CANONICAL", "cn=duke", 3);
+ testName("cn=\\ duke ", "toString", "CN=\" duke\"", 4);
+
+ testName("cn= duke", "RFC1779", "CN=duke", 5);
+ testName("cn= duke", "RFC2253", "CN=duke", 6);
+ testName("cn= duke", "CANONICAL", "cn=duke", 7);
+ testName("cn= duke", "toString", "CN=duke", 8);
+
+ testName("cn=duke\\ ", "RFC1779", "CN=\"duke \"", 9);
+ testName("cn=duke\\ ", "RFC2253", "CN=duke\\ ", 10);
+ testName("cn=duke\\ ", "CANONICAL", "cn=duke", 11);
+ testName("cn=duke\\ ", "toString", "CN=\"duke \"", 12);
+
+ testName("cn=duke\\ , ou= sun\\ ", "RFC1779",
+ "CN=\"duke \", OU=\"sun \"", 13);
+ testName("cn=duke\\ , ou= sun\\ ", "RFC2253",
+ "CN=duke\\ ,OU=sun\\ ", 14);
+ testName("cn=duke\\ , ou= sun\\ ", "CANONICAL",
+ "cn=duke,ou=sun", 15);
+ testName("cn=duke\\ , ou= sun\\ ", "toString",
+ "CN=\"duke \", OU=\"sun \"", 16);
+
+ // tests for trailing escaped backslash
+
+ testName("cn=duke \\\\\\,test,O=java", "CANONICAL",
+ "cn=duke \\\\\\,test,o=java", 17);
+
+ testName("cn=duke\\\\, o=java", "CANONICAL",
+ "cn=duke\\\\,o=java", 18);
+
+ X500Principal p = new X500Principal("cn=duke \\\\\\,test,o=java");
+ X500Principal p2 = new X500Principal(p.getName("CANONICAL"));
+ if (p.getName("CANONICAL").equals(p2.getName("CANONICAL"))) {
+ System.out.println("test 19 succeeded");
+ } else {
+ throw new SecurityException("test 19 failed\n" +
+ p.getName("CANONICAL") + " not equal to " +
+ p2.getName("CANONICAL"));
+ }
+
+ try {
+ p = new X500Principal("cn=duke \\\\,test,o=java");
+ throw new SecurityException("test 19.5 failed:\n" +
+ p.getName("CANONICAL"));
+ } catch (IllegalArgumentException iae) {
+ System.out.println("test 19.5 succeeded");
+ iae.printStackTrace();
+ }
+
+ // tests for wrong exception thrown
+ try {
+ byte[] encoding = {
+ (byte)0x17, (byte)0x80, (byte)0x70, (byte)0x41,
+ (byte)0x6b, (byte)0x15, (byte)0xdc, (byte)0x84,
+ (byte)0xef, (byte)0x58, (byte)0xac, (byte)0x88,
+ (byte)0xae, (byte)0xb0, (byte)0x19, (byte)0x7c,
+ (byte)0x6f, (byte)0xea, (byte)0xf5, (byte)0x56,
+ };
+ p = new X500Principal(new java.io.DataInputStream
+ (new java.io.ByteArrayInputStream(encoding)));
+ } catch (IllegalArgumentException iae) {
+ System.out.println("test 20 succeeded");
+ iae.printStackTrace();
+ } catch (Exception e) {
+ System.out.println("test 20 failed");
+ throw e;
+ }
+
+ // tests for escaping '+' in canonical form
+
+ testName("cn=se\\+an, ou= sun\\ ", "CANONICAL",
+ "cn=se\\+an,ou=sun", 21);
+
+ // tests for embedded hex pairs
+
+ testName("CN=Before\\0dAfter,DC=example,DC=net", "toString",
+ "CN=Before\\0DAfter, DC=example, DC=net", 22);
+ testName("CN=Before\\0dAfter,DC=example,DC=net", "RFC1779",
+ "CN=Before\\0DAfter, " +
+ "OID.0.9.2342.19200300.100.1.25=example, " +
+ "OID.0.9.2342.19200300.100.1.25=net", 23);
+ testName("CN=Before\\0dAfter,DC=example,DC=net", "RFC2253",
+ "CN=Before\\0DAfter,DC=example,DC=net", 24);
+ testName("CN=Before\\0dAfter,DC=example,DC=net", "CANONICAL",
+ "cn=before\\0dafter,dc=#16076578616d706c65,dc=#16036e6574", 25);
+
+ testName("CN=Lu\\C4\\8Di\\C4\\87", "toString",
+ "CN=Lu\\C4\\8Di\\C4\\87", 26);
+ testName("CN=Lu\\C4\\8Di\\C4\\87", "RFC1779",
+ "CN=Lu\\C4\\8Di\\C4\\87", 27);
+ testName("CN=Lu\\C4\\8Di\\C4\\87", "RFC2253",
+ "CN=Lu\\C4\\8Di\\C4\\87", 28);
+ testName("CN=Lu\\C4\\8Di\\C4\\87", "CANONICAL",
+ "cn=lu\\c4\\8di\\c4\\87", 29);
+
+ try {
+ p = new X500Principal("cn=\\gg");
+ throw new SecurityException("test 30 failed");
+ } catch (IllegalArgumentException iae) {
+ System.out.println("test 30 succeeded");
+ }
+
+ // tests for invalid escaped chars
+
+ try {
+ p = new X500Principal("cn=duke \\test");
+ throw new SecurityException("test 31 failed");
+ } catch (IllegalArgumentException iae) {
+ System.out.println("test 31 succeeded");
+ }
+
+ try {
+ p = new X500Principal("cn=duke \\?test");
+ throw new SecurityException("test 32 failed");
+ } catch (IllegalArgumentException iae) {
+ System.out.println("test 32 succeeded");
+ }
+
+ // tests for X500Name using RFC2253 as format
+
+ try {
+ // invalid non-escaped leading space
+ sun.security.x509.X500Name name =
+ new sun.security.x509.X500Name("cn= duke test", "RFC2253");
+ throw new SecurityException("test 33 failed");
+ } catch (java.io.IOException ioe) {
+ ioe.printStackTrace();
+ System.out.println("test 33 succeeded");
+ }
+
+ try {
+ // invalid non-escaped trailing space
+ sun.security.x509.X500Name name =
+ new sun.security.x509.X500Name("cn=duke test ", "RFC2253");
+ throw new SecurityException("test 34 failed");
+ } catch (java.io.IOException ioe) {
+ System.out.println("test 34 succeeded");
+ }
+
+ testName("CN=SPECIAL CHARS,OU=\\#\\\"\\,\\<\\>\\+\\;,O=foo, " +
+ "L=bar, ST=baz, C=JP", "RFC1779",
+ "CN=SPECIAL CHARS, OU=\"#\\\",<>+;\", O=foo, L=bar, " +
+ "ST=baz, C=JP", 35);
+
+ // test that double-quoted string is not escaped in RFC 1779 format
+ testName("CN=\"\\\"Duke\\\"\"", "RFC1779", "CN=\"Duke\"", 36);
+ }
+
+ public static void testName(String in, String outFormat,
+ String expect, int n)
+ throws Exception {
+
+ X500Principal p = new X500Principal(in);
+ if (outFormat.equalsIgnoreCase("toString")) {
+ if (p.toString().equals(expect)) {
+ System.out.println("test " + n + " succeeded");
+ } else {
+ throw new SecurityException("test " + n + " failed:\n" +
+ "expected '" + expect + "'\n" +
+ "got '" + p.toString() + "'");
+ }
+ } else {
+ if (p.getName(outFormat).equals(expect)) {
+ System.out.println("test " + n + " succeeded");
+ } else {
+ throw new SecurityException("test " + n + " failed:\n" +
+ "expected '" + expect + "'\n" +
+ "got '" + p.getName(outFormat) + "'");
+ }
+ }
+ }
+}
--- a/jdk/test/sun/invoke/util/ValueConversionsTest.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/test/sun/invoke/util/ValueConversionsTest.java Sat Jan 28 22:21:54 2012 -0800
@@ -27,11 +27,9 @@
import sun.invoke.util.Wrapper;
import java.lang.invoke.MethodType;
import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collections;
-import org.junit.Ignore;
import org.junit.Test;
import static org.junit.Assert.*;
@@ -52,7 +50,7 @@
* @author jrose
*/
public class ValueConversionsTest {
- private static final Class CLASS = ValueConversionsTest.class;
+ private static final Class<?> CLASS = ValueConversionsTest.class;
private static final int MAX_ARITY = Integer.getInteger(CLASS.getSimpleName()+".MAX_ARITY", 40);
private static final int START_ARITY = Integer.getInteger(CLASS.getSimpleName()+".START_ARITY", 0);
private static final boolean EXHAUSTIVE = Boolean.getBoolean(CLASS.getSimpleName()+".EXHAUSTIVE");
@@ -165,7 +163,7 @@
Object expResult = box;
Object result = null;
switch (w) {
- case INT: result = boxer.invokeExact((int)n); break;
+ case INT: result = boxer.invokeExact(/*int*/n); break;
case LONG: result = boxer.invokeExact((long)n); break;
case FLOAT: result = boxer.invokeExact((float)n); break;
case DOUBLE: result = boxer.invokeExact((double)n); break;
@@ -361,6 +359,7 @@
assert(stype == MethodType.methodType(arrayType, arrayType));
if (nargs <= 5) {
// invoke target as a spreader also:
+ @SuppressWarnings("cast")
Object res2 = spreader.invokeWithArguments((Object)res);
String res2String = toArrayString(res2);
assertEquals(Arrays.toString(args), res2String);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/www/http/HttpClient/CookieHttpClientTest.java Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 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.
+ */
+
+/*
+ * @test
+ * @bug 7129083
+ * @summary Cookiemanager does not store cookies if url is read
+ * before setting cookiemanager
+ */
+
+import java.net.CookieHandler;
+import java.net.CookieManager;
+import java.net.CookiePolicy;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.URL;
+import java.io.InputStream;
+import java.io.IOException;
+
+public class CookieHttpClientTest implements Runnable {
+ final ServerSocket ss;
+ static final int TIMEOUT = 10 * 1000;
+
+ static final String replyString = "HTTP/1.1 200 OK\r\n" +
+ "Set-Cookie: name=test\r\n" +
+ "Content-Length: 10\r\n\r\n" +
+ "1234567890";
+
+ // HTTP server, reply with Set-Cookie
+ @Override
+ public void run() {
+ Socket s = null;
+ try {
+ s = ss.accept();
+ s.setSoTimeout(TIMEOUT);
+ readOneRequest(s.getInputStream());
+ s.getOutputStream().write(replyString.getBytes());
+
+ readOneRequest(s.getInputStream());
+ s.getOutputStream().write(replyString.getBytes());
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ try { if (s != null) { s.close(); } ss.close(); }
+ catch (IOException unused) { /* gulp!burp! */ }
+ }
+ }
+
+ static final byte[] requestEnd = new byte[] {'\r', '\n', '\r', '\n' };
+
+ // Read until the end of a HTTP request
+ static void readOneRequest(InputStream is) throws IOException {
+ int requestEndCount = 0, r;
+ while ((r = is.read()) != -1) {
+ if (r == requestEnd[requestEndCount]) {
+ requestEndCount++;
+ if (requestEndCount == 4) {
+ break;
+ }
+ } else {
+ requestEndCount = 0;
+ }
+ }
+ }
+
+ CookieHttpClientTest() throws Exception {
+ /* start the server */
+ ss = new ServerSocket(0);
+ (new Thread(this)).start();
+
+ URL url = new URL("http://localhost:" + ss.getLocalPort() +"/");
+
+ // Run without a CookieHandler first
+ InputStream in = url.openConnection().getInputStream();
+ while (in.read() != -1); // read response body so connection can be reused
+
+ // Set a CookeHandler and retest using the HttpClient from the KAC
+ CookieManager manager = new CookieManager(null, CookiePolicy.ACCEPT_ALL);
+ CookieHandler.setDefault(manager);
+
+ in = url.openConnection().getInputStream();
+ while (in.read() != -1);
+
+ if (manager.getCookieStore().getCookies().isEmpty()) {
+ throw new RuntimeException("Failed: No cookies in the cookie Handler.");
+ }
+ }
+
+ public static void main(String args[]) throws Exception {
+ new CookieHttpClientTest();
+ }
+}
--- a/jdk/test/sun/security/krb5/auto/Context.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/test/sun/security/krb5/auto/Context.java Sat Jan 28 22:21:54 2012 -0800
@@ -76,7 +76,6 @@
private Subject s;
private ExtendedGSSContext x;
- private boolean f; // context established?
private String name;
private GSSCredential cred; // see static method delegated().
@@ -194,7 +193,6 @@
return null;
}
}, null);
- f = false;
}
/**
@@ -228,7 +226,6 @@
return null;
}
}, null);
- f = false;
}
/**
@@ -502,6 +499,29 @@
return sb.toString();
}
+ public byte[] take(final byte[] in) throws Exception {
+ return doAs(new Action() {
+ @Override
+ public byte[] run(Context me, byte[] input) throws Exception {
+ if (me.x.isEstablished()) {
+ System.out.println(name + " side established");
+ if (input != null) {
+ throw new Exception("Context established but " +
+ "still receive token at " + name);
+ }
+ return null;
+ } else {
+ System.out.println(name + " call initSecContext");
+ if (me.x.isInitiator()) {
+ return me.x.initSecContext(input, 0, input.length);
+ } else {
+ return me.x.acceptSecContext(input, 0, input.length);
+ }
+ }
+ }
+ }, in);
+ }
+
/**
* Handshake (security context establishment process) between two Contexts
* @param c the initiator
@@ -510,54 +530,9 @@
*/
static public void handshake(final Context c, final Context s) throws Exception {
byte[] t = new byte[0];
- while (!c.f || !s.f) {
- t = c.doAs(new Action() {
- @Override
- public byte[] run(Context me, byte[] input) throws Exception {
- if (me.x.isEstablished()) {
- me.f = true;
- System.out.println(c.name + " side established");
- if (input != null) {
- throw new Exception("Context established but " +
- "still receive token at " + c.name);
- }
- return null;
- } else {
- System.out.println(c.name + " call initSecContext");
- if (usingStream) {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- me.x.initSecContext(new ByteArrayInputStream(input), os);
- return os.size() == 0 ? null : os.toByteArray();
- } else {
- return me.x.initSecContext(input, 0, input.length);
- }
- }
- }
- }, t);
-
- t = s.doAs(new Action() {
- @Override
- public byte[] run(Context me, byte[] input) throws Exception {
- if (me.x.isEstablished()) {
- me.f = true;
- System.out.println(s.name + " side established");
- if (input != null) {
- throw new Exception("Context established but " +
- "still receive token at " + s.name);
- }
- return null;
- } else {
- System.out.println(s.name + " called acceptSecContext");
- if (usingStream) {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- me.x.acceptSecContext(new ByteArrayInputStream(input), os);
- return os.size() == 0 ? null : os.toByteArray();
- } else {
- return me.x.acceptSecContext(input, 0, input.length);
- }
- }
- }
- }, t);
+ while (!c.x.isEstablished() || !s.x.isEstablished()) {
+ t = c.take(t);
+ t = s.take(t);
}
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/ReplayCache.java Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2012 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 7118809
+ * @run main/othervm ReplayCache
+ * @summary rcache deadlock
+ */
+
+import org.ietf.jgss.GSSException;
+import sun.security.jgss.GSSUtil;
+import sun.security.krb5.KrbException;
+import sun.security.krb5.internal.Krb5;
+
+public class ReplayCache {
+
+ public static void main(String[] args)
+ throws Exception {
+
+ new OneKDC(null).writeJAASConf();
+
+ Context c, s;
+ c = Context.fromJAAS("client");
+ s = Context.fromJAAS("server");
+
+ c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
+ s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
+
+ byte[] first = c.take(new byte[0]);
+ s.take(first);
+
+ s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
+ try {
+ s.take(first); // Replay the last token sent
+ throw new Exception("This method should fail");
+ } catch (GSSException gsse) {
+ KrbException ke = (KrbException)gsse.getCause();
+ if (ke.returnCode() != Krb5.KRB_AP_ERR_REPEAT) {
+ throw gsse;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/mscapi/ShortRSAKey1024.sh Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,85 @@
+#!/bin/sh
+
+#
+# Copyright (c) 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.
+#
+
+
+# @test
+# @bug 7106773
+# @summary 512 bits RSA key cannot work with SHA384 and SHA512
+# @run shell ShortRSAKey1024.sh
+
+# set a few environment variables so that the shell-script can run stand-alone
+# in the source directory
+if [ "${TESTSRC}" = "" ] ; then
+ TESTSRC="."
+fi
+
+if [ "${TESTCLASSES}" = "" ] ; then
+ TESTCLASSES="."
+fi
+
+if [ "${TESTJAVA}" = "" ] ; then
+ echo "TESTJAVA not set. Test cannot execute."
+ echo "FAILED!!!"
+ exit 1
+fi
+
+OS=`uname -s`
+case "$OS" in
+ Windows* | CYGWIN* )
+
+ echo "Creating a temporary RSA keypair in the Windows-My store..."
+ ${TESTJAVA}/bin/keytool \
+ -genkeypair \
+ -storetype Windows-My \
+ -keyalg RSA \
+ -alias 7106773.1024 \
+ -keysize 1024 \
+ -dname "cn=localhost,c=US" \
+ -noprompt
+
+ echo
+ echo "Running the test..."
+ ${TESTJAVA}/bin/javac -d . ${TESTSRC}\\ShortRSAKeyWithinTLS.java
+ ${TESTJAVA}/bin/java ShortRSAKeyWithinTLS 7106773.1024 1024 \
+ TLSv1.2 TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+
+ rc=$?
+
+ echo
+ echo "Removing the temporary RSA keypair from the Windows-My store..."
+ ${TESTJAVA}/bin/keytool \
+ -delete \
+ -storetype Windows-My \
+ -alias 7106773.1024
+
+ echo done.
+ exit $rc
+ ;;
+
+ * )
+ echo "This test is not intended for '$OS' - passing test"
+ exit 0
+ ;;
+esac
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/mscapi/ShortRSAKey512.sh Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,86 @@
+#!/bin/sh
+
+#
+# Copyright (c) 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.
+#
+
+
+# @test
+# @bug 7106773
+# @summary 512 bits RSA key cannot work with SHA384 and SHA512
+# @run shell ShortRSAKey512.sh
+
+# set a few environment variables so that the shell-script can run stand-alone
+# in the source directory
+if [ "${TESTSRC}" = "" ] ; then
+ TESTSRC="."
+fi
+
+if [ "${TESTCLASSES}" = "" ] ; then
+ TESTCLASSES="."
+fi
+
+if [ "${TESTJAVA}" = "" ] ; then
+ echo "TESTJAVA not set. Test cannot execute."
+ echo "FAILED!!!"
+ exit 1
+fi
+
+OS=`uname -s`
+case "$OS" in
+ Windows* | CYGWIN* )
+
+ echo "Creating a temporary RSA keypair in the Windows-My store..."
+ ${TESTJAVA}/bin/keytool \
+ -genkeypair \
+ -storetype Windows-My \
+ -keyalg RSA \
+ -alias 7106773.512 \
+ -keysize 512 \
+ -dname "cn=localhost,c=US" \
+ -noprompt
+
+ echo
+ echo "Running the test..."
+ ${TESTJAVA}/bin/javac -d . ${TESTSRC}\\ShortRSAKeyWithinTLS.java
+ ${TESTJAVA}/bin/java ShortRSAKeyWithinTLS 7106773.512 512 \
+ TLSv1.2 TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+
+
+ rc=$?
+
+ echo
+ echo "Removing the temporary RSA keypair from the Windows-My store..."
+ ${TESTJAVA}/bin/keytool \
+ -delete \
+ -storetype Windows-My \
+ -alias 7106773.512
+
+ echo done.
+ exit $rc
+ ;;
+
+ * )
+ echo "This test is not intended for '$OS' - passing test"
+ exit 0
+ ;;
+esac
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/mscapi/ShortRSAKey768.sh Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,85 @@
+#!/bin/sh
+
+#
+# Copyright (c) 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.
+#
+
+
+# @test
+# @bug 7106773
+# @summary 512 bits RSA key cannot work with SHA384 and SHA512
+# @run shell ShortRSAKey768.sh
+
+# set a few environment variables so that the shell-script can run stand-alone
+# in the source directory
+if [ "${TESTSRC}" = "" ] ; then
+ TESTSRC="."
+fi
+
+if [ "${TESTCLASSES}" = "" ] ; then
+ TESTCLASSES="."
+fi
+
+if [ "${TESTJAVA}" = "" ] ; then
+ echo "TESTJAVA not set. Test cannot execute."
+ echo "FAILED!!!"
+ exit 1
+fi
+
+OS=`uname -s`
+case "$OS" in
+ Windows* | CYGWIN* )
+
+ echo "Creating a temporary RSA keypair in the Windows-My store..."
+ ${TESTJAVA}/bin/keytool \
+ -genkeypair \
+ -storetype Windows-My \
+ -keyalg RSA \
+ -alias 7106773.768 \
+ -keysize 768 \
+ -dname "cn=localhost,c=US" \
+ -noprompt
+
+ echo
+ echo "Running the test..."
+ ${TESTJAVA}/bin/javac -d . ${TESTSRC}\\ShortRSAKeyWithinTLS.java
+ ${TESTJAVA}/bin/java ShortRSAKeyWithinTLS 7106773.768 768 \
+ TLSv1.2 TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+
+ rc=$?
+
+ echo
+ echo "Removing the temporary RSA keypair from the Windows-My store..."
+ ${TESTJAVA}/bin/keytool \
+ -delete \
+ -storetype Windows-My \
+ -alias 7106773.768
+
+ echo done.
+ exit $rc
+ ;;
+
+ * )
+ echo "This test is not intended for '$OS' - passing test"
+ exit 0
+ ;;
+esac
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/mscapi/ShortRSAKeyWithinTLS.java Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,355 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.security.*;
+import javax.net.*;
+import javax.net.ssl.*;
+import java.lang.reflect.*;
+
+import sun.security.util.KeyLength;
+
+public class ShortRSAKeyWithinTLS {
+
+ /*
+ * =============================================================
+ * Set the various variables needed for the tests, then
+ * specify what tests to run on each side.
+ */
+
+ /*
+ * Should we run the client or server in a separate thread?
+ * Both sides can throw exceptions, but do you have a preference
+ * as to which side should be the main thread.
+ */
+ static boolean separateServerThread = false;
+
+ /*
+ * Is the server ready to serve?
+ */
+ volatile static boolean serverReady = false;
+
+ /*
+ * Turn on SSL debugging?
+ */
+ static boolean debug = false;
+
+ /*
+ * If the client or server is doing some kind of object creation
+ * that the other side depends on, and that thread prematurely
+ * exits, you may experience a hang. The test harness will
+ * terminate all hung threads after its timeout has expired,
+ * currently 3 minutes by default, but you might try to be
+ * smart about it....
+ */
+
+ /*
+ * Define the server side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ void doServerSide() throws Exception {
+
+ // load the key store
+ KeyStore ks = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
+ ks.load(null, null);
+ System.out.println("Loaded keystore: Windows-MY");
+
+ // check key size
+ checkKeySize(ks);
+
+ // initialize the SSLContext
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+ kmf.init(ks, null);
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+ tmf.init(ks);
+
+ SSLContext ctx = SSLContext.getInstance("TLS");
+ ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+
+ ServerSocketFactory ssf = ctx.getServerSocketFactory();
+ SSLServerSocket sslServerSocket = (SSLServerSocket)
+ ssf.createServerSocket(serverPort);
+ sslServerSocket.setNeedClientAuth(true);
+ serverPort = sslServerSocket.getLocalPort();
+ System.out.println("serverPort = " + serverPort);
+
+ /*
+ * Signal Client, we're ready for his connect.
+ */
+ serverReady = true;
+
+ SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslIS.read();
+ sslOS.write(85);
+ sslOS.flush();
+
+ sslSocket.close();
+ }
+
+ /*
+ * Define the client side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ void doClientSide() throws Exception {
+
+ /*
+ * Wait for server to get started.
+ */
+ while (!serverReady) {
+ Thread.sleep(50);
+ }
+
+ // load the key store
+ KeyStore ks = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
+ ks.load(null, null);
+ System.out.println("Loaded keystore: Windows-MY");
+
+ // initialize the SSLContext
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+ kmf.init(ks, null);
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+ tmf.init(ks);
+
+ SSLContext ctx = SSLContext.getInstance("TLS");
+ ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+
+ SSLSocketFactory sslsf = ctx.getSocketFactory();
+ SSLSocket sslSocket = (SSLSocket)
+ sslsf.createSocket("localhost", serverPort);
+
+ if (clientProtocol != null) {
+ sslSocket.setEnabledProtocols(new String[] {clientProtocol});
+ }
+
+ if (clientCiperSuite != null) {
+ sslSocket.setEnabledCipherSuites(new String[] {clientCiperSuite});
+ }
+
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslOS.write(280);
+ sslOS.flush();
+ sslIS.read();
+
+ sslSocket.close();
+ }
+
+ private void checkKeySize(KeyStore ks) throws Exception {
+ PrivateKey privateKey = null;
+ PublicKey publicKey = null;
+
+ if (ks.containsAlias(keyAlias)) {
+ System.out.println("Loaded entry: " + keyAlias);
+ privateKey = (PrivateKey)ks.getKey(keyAlias, null);
+ publicKey = (PublicKey)ks.getCertificate(keyAlias).getPublicKey();
+
+ int privateKeySize = KeyLength.getKeySize(privateKey);
+ if (privateKeySize != keySize) {
+ throw new Exception("Expected key size is " + keySize +
+ ", but the private key size is " + privateKeySize);
+ }
+
+ int publicKeySize = KeyLength.getKeySize(publicKey);
+ if (publicKeySize != keySize) {
+ throw new Exception("Expected key size is " + keySize +
+ ", but the public key size is " + publicKeySize);
+ }
+ }
+ }
+
+ /*
+ * =============================================================
+ * The remainder is just support stuff
+ */
+
+ // use any free port by default
+ volatile int serverPort = 0;
+
+ volatile Exception serverException = null;
+ volatile Exception clientException = null;
+
+ private static String keyAlias;
+ private static int keySize;
+ private static String clientProtocol = null;
+ private static String clientCiperSuite = null;
+
+ private static void parseArguments(String[] args) {
+ keyAlias = args[0];
+ keySize = Integer.parseInt(args[1]);
+
+ if (args.length > 2) {
+ clientProtocol = args[2];
+ }
+
+ if (args.length > 3) {
+ clientCiperSuite = args[3];
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ if (debug) {
+ System.setProperty("javax.net.debug", "all");
+ }
+
+ // Get the customized arguments.
+ parseArguments(args);
+
+ new ShortRSAKeyWithinTLS();
+ }
+
+ Thread clientThread = null;
+ Thread serverThread = null;
+
+ /*
+ * Primary constructor, used to drive remainder of the test.
+ *
+ * Fork off the other side, then do your work.
+ */
+ ShortRSAKeyWithinTLS() throws Exception {
+ try {
+ if (separateServerThread) {
+ startServer(true);
+ startClient(false);
+ } else {
+ startClient(true);
+ startServer(false);
+ }
+ } catch (Exception e) {
+ // swallow for now. Show later
+ }
+
+ /*
+ * Wait for other side to close down.
+ */
+ if (separateServerThread) {
+ serverThread.join();
+ } else {
+ clientThread.join();
+ }
+
+ /*
+ * When we get here, the test is pretty much over.
+ * Which side threw the error?
+ */
+ Exception local;
+ Exception remote;
+ String whichRemote;
+
+ if (separateServerThread) {
+ remote = serverException;
+ local = clientException;
+ whichRemote = "server";
+ } else {
+ remote = clientException;
+ local = serverException;
+ whichRemote = "client";
+ }
+
+ /*
+ * If both failed, return the curthread's exception, but also
+ * print the remote side Exception
+ */
+ if ((local != null) && (remote != null)) {
+ System.out.println(whichRemote + " also threw:");
+ remote.printStackTrace();
+ System.out.println();
+ throw local;
+ }
+
+ if (remote != null) {
+ throw remote;
+ }
+
+ if (local != null) {
+ throw local;
+ }
+ }
+
+ void startServer(boolean newThread) throws Exception {
+ if (newThread) {
+ serverThread = new Thread() {
+ public void run() {
+ try {
+ doServerSide();
+ } catch (Exception e) {
+ /*
+ * Our server thread just died.
+ *
+ * Release the client, if not active already...
+ */
+ System.err.println("Server died...");
+ serverReady = true;
+ serverException = e;
+ }
+ }
+ };
+ serverThread.start();
+ } else {
+ try {
+ doServerSide();
+ } catch (Exception e) {
+ serverException = e;
+ } finally {
+ serverReady = true;
+ }
+ }
+ }
+
+ void startClient(boolean newThread) throws Exception {
+ if (newThread) {
+ clientThread = new Thread() {
+ public void run() {
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ /*
+ * Our client thread just died.
+ */
+ System.err.println("Client died...");
+ clientException = e;
+ }
+ }
+ };
+ clientThread.start();
+ } else {
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ clientException = e;
+ }
+ }
+ }
+}
+
--- a/jdk/test/sun/security/pkcs11/KeyStore/ClientAuth.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/test/sun/security/pkcs11/KeyStore/ClientAuth.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -155,6 +155,14 @@
SSLSocket sslSocket = (SSLSocket)
sslsf.createSocket("localhost", serverPort);
+ if (clientProtocol != null) {
+ sslSocket.setEnabledProtocols(new String[] {clientProtocol});
+ }
+
+ if (clientCiperSuite != null) {
+ sslSocket.setEnabledCipherSuites(new String[] {clientCiperSuite});
+ }
+
InputStream sslIS = sslSocket.getInputStream();
OutputStream sslOS = sslSocket.getOutputStream();
@@ -176,7 +184,22 @@
volatile Exception serverException = null;
volatile Exception clientException = null;
+ private static String clientProtocol = null;
+ private static String clientCiperSuite = null;
+
+ private static void parseArguments(String[] args) {
+ if (args.length > 0) {
+ clientProtocol = args[0];
+ }
+
+ if (args.length > 1) {
+ clientCiperSuite = args[1];
+ }
+ }
+
public static void main(String[] args) throws Exception {
+ // Get the customized arguments.
+ parseArguments(args);
main(new ClientAuth());
}
--- a/jdk/test/sun/security/pkcs11/KeyStore/ClientAuth.sh Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/test/sun/security/pkcs11/KeyStore/ClientAuth.sh Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 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
@@ -22,8 +22,9 @@
#
# @test
-# @bug 4938185
+# @bug 4938185 7106773
# @summary KeyStore support for NSS cert/key databases
+# 512 bits RSA key cannot work with SHA384 and SHA512
#
# @run shell ClientAuth.sh
@@ -126,6 +127,7 @@
${TESTSRC}${FS}ClientAuth.java
# run test
+echo "Run ClientAuth ..."
${TESTJAVA}${FS}bin${FS}java \
-classpath ${TESTCLASSES}${PS}${TESTSRC}${FS}loader.jar \
-DDIR=${TESTSRC}${FS}ClientAuthData${FS} \
@@ -140,5 +142,26 @@
# save error status
status=$?
+# return if failed
+if [ "${status}" != "0" ] ; then
+ exit $status
+fi
+
+# run test with specified TLS protocol and cipher suite
+echo "Run ClientAuth TLSv1.2 TLS_DHE_RSA_WITH_AES_128_CBC_SHA"
+${TESTJAVA}${FS}bin${FS}java \
+ -classpath ${TESTCLASSES}${PS}${TESTSRC}${FS}loader.jar \
+ -DDIR=${TESTSRC}${FS}ClientAuthData${FS} \
+ -DCUSTOM_DB_DIR=${TESTCLASSES} \
+ -DCUSTOM_P11_CONFIG=${TESTSRC}${FS}ClientAuthData${FS}p11-nss.txt \
+ -DNO_DEFAULT=true \
+ -DNO_DEIMOS=true \
+ -Dtest.src=${TESTSRC} \
+ -Dtest.classes=${TESTCLASSES} \
+ ClientAuth TLSv1.2 TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+
+# save error status
+status=$?
+
# return
exit $status
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/pkcs11/MessageDigest/TestCloning.java Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 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.
+ */
+
+/**
+ * @test
+ * @bug 6414899
+ * @summary Ensure the cloning functionality works.
+ * @author Valerie Peng
+ * @library ..
+ */
+
+import java.util.*;
+
+import java.security.*;
+
+public class TestCloning extends PKCS11Test {
+
+ private static final String[] ALGOS = {
+ "MD2", "MD5", "SHA1", "SHA-256", "SHA-384", "SHA-512"
+ };
+
+ public static void main(String[] args) throws Exception {
+ main(new TestCloning());
+ }
+
+ private static final byte[] data1 = new byte[10];
+ private static final byte[] data2 = new byte[10*1024];
+
+
+ public void main(Provider p) throws Exception {
+ Random r = new Random();
+ byte[] data1 = new byte[10];
+ byte[] data2 = new byte[2*1024];
+ r.nextBytes(data1);
+ r.nextBytes(data2);
+ System.out.println("Testing against provider " + p.getName());
+ for (int i = 0; i < ALGOS.length; i++) {
+ if (p.getService("MessageDigest", ALGOS[i]) == null) {
+ System.out.println(ALGOS[i] + " is not supported, skipping");
+ continue;
+ } else {
+ System.out.println("Testing " + ALGOS[i] + " of " + p.getName());
+ MessageDigest md = MessageDigest.getInstance(ALGOS[i], p);
+ try {
+ md = testCloning(md, p);
+ // repeat the test again after generating digest once
+ for (int j = 0; j < 10; j++) {
+ md = testCloning(md, p);
+ }
+ } catch (Exception ex) {
+ if (ALGOS[i] == "MD2" &&
+ p.getName().equalsIgnoreCase("SunPKCS11-NSS")) {
+ // known bug in NSS; ignore for now
+ System.out.println("Ignore Known bug in MD2 of NSS");
+ continue;
+ }
+ throw ex;
+ }
+ }
+ }
+ }
+
+ private static MessageDigest testCloning(MessageDigest mdObj, Provider p)
+ throws Exception {
+
+ // copy#0: clone at state BLANK w/o any data
+ MessageDigest mdCopy0 = (MessageDigest) mdObj.clone();
+
+ // copy#1: clone again at state BUFFERED w/ very short data
+ mdObj.update(data1);
+ mdCopy0.update(data1);
+ MessageDigest mdCopy1 = (MessageDigest) mdObj.clone();
+
+ // copy#2: clone again after updating it w/ long data to trigger
+ // the state into INIT
+ mdObj.update(data2);
+ mdCopy0.update(data2);
+ mdCopy1.update(data2);
+ MessageDigest mdCopy2 = (MessageDigest) mdObj.clone();
+
+ // copy#3: clone again after updating it w/ very short data
+ mdObj.update(data1);
+ mdCopy0.update(data1);
+ mdCopy1.update(data1);
+ mdCopy2.update(data1);
+ MessageDigest mdCopy3 = (MessageDigest) mdObj.clone();
+
+ // copy#4: clone again after updating it w/ long data
+ mdObj.update(data2);
+ mdCopy0.update(data2);
+ mdCopy1.update(data2);
+ mdCopy2.update(data2);
+ mdCopy3.update(data2);
+ MessageDigest mdCopy4 = (MessageDigest) mdObj.clone();
+
+ // check digest equalities
+ byte[] answer = mdObj.digest();
+ byte[] result0 = mdCopy0.digest();
+ byte[] result1 = mdCopy1.digest();
+ byte[] result2 = mdCopy2.digest();
+ byte[] result3 = mdCopy3.digest();
+ byte[] result4 = mdCopy4.digest();
+
+
+ check(answer, result0, "copy0");
+ check(answer, result1, "copy1");
+ check(answer, result2, "copy2");
+ check(answer, result3, "copy3");
+ check(answer, result4, "copy4");
+
+ return mdCopy3;
+ }
+
+ private static void check(byte[] d1, byte[] d2, String copyName)
+ throws Exception {
+ if (Arrays.equals(d1, d2) == false) {
+ throw new RuntimeException(copyName + " digest mismatch!");
+ }
+ }
+}
+
--- a/jdk/test/sun/security/ssl/javax/net/ssl/SSLContextVersion.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/SSLContextVersion.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -91,7 +91,7 @@
ciphers = parameters.getCipherSuites();
if (protocols.length == 0 || ciphers.length == 0) {
- throw new Exception("No default protocols or cipher suites");
+ throw new Exception("No supported protocols or cipher suites");
}
isMatch = false;
@@ -104,7 +104,7 @@
}
if (!isMatch) {
- throw new Exception("No matched default protocol");
+ throw new Exception("No matched supported protocol");
}
System.out.println("\t... Success");
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/TLSv12/ShortRSAKey512.java Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,414 @@
+/*
+ * Copyright (c) 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7106773
+ * @summary 512 bits RSA key cannot work with SHA384 and SHA512
+ *
+ * SunJSSE does not support dynamic system properties, no way to re-use
+ * system properties in samevm/agentvm mode.
+ * @run main/othervm ShortRSAKey512 PKIX
+ * @run main/othervm ShortRSAKey512 SunX509
+ */
+
+import java.net.*;
+import java.util.*;
+import java.io.*;
+import javax.net.ssl.*;
+import java.security.KeyStore;
+import java.security.KeyFactory;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.spec.*;
+import java.security.interfaces.*;
+import sun.misc.BASE64Decoder;
+
+
+public class ShortRSAKey512 {
+
+ /*
+ * =============================================================
+ * Set the various variables needed for the tests, then
+ * specify what tests to run on each side.
+ */
+
+ /*
+ * Should we run the client or server in a separate thread?
+ * Both sides can throw exceptions, but do you have a preference
+ * as to which side should be the main thread.
+ */
+ static boolean separateServerThread = false;
+
+ /*
+ * Where do we find the keystores?
+ */
+ // Certificates and key used in the test.
+ static String trustedCertStr =
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" +
+ "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
+ "MTEwODE5MDE1MjE5WhcNMzIwNzI5MDE1MjE5WjA7MQswCQYDVQQGEwJVUzENMAsG\n" +
+ "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n" +
+ "KoZIhvcNAQEBBQADgY0AMIGJAoGBAM8orG08DtF98TMSscjGsidd1ZoN4jiDpi8U\n" +
+ "ICz+9dMm1qM1d7O2T+KH3/mxyox7Rc2ZVSCaUD0a3CkhPMnlAx8V4u0H+E9sqso6\n" +
+ "iDW3JpOyzMExvZiRgRG/3nvp55RMIUV4vEHOZ1QbhuqG4ebN0Vz2DkRft7+flthf\n" +
+ "vDld6f5JAgMBAAGjgaUwgaIwHQYDVR0OBBYEFLl81dnfp0wDrv0OJ1sxlWzH83Xh\n" +
+ "MGMGA1UdIwRcMFqAFLl81dnfp0wDrv0OJ1sxlWzH83XhoT+kPTA7MQswCQYDVQQG\n" +
+ "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
+ "Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEE\n" +
+ "BQADgYEALlgaH1gWtoBZ84EW8Hu6YtGLQ/L9zIFmHonUPZwn3Pr//icR9Sqhc3/l\n" +
+ "pVTxOINuFHLRz4BBtEylzRIOPzK3tg8XwuLb1zd0db90x3KBCiAL6E6cklGEPwLe\n" +
+ "XYMHDn9eDsaq861Tzn6ZwzMgw04zotPMoZN0mVd/3Qca8UJFucE=\n" +
+ "-----END CERTIFICATE-----";
+
+ static String targetCertStr =
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIICNDCCAZ2gAwIBAgIBDDANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" +
+ "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
+ "MTExMTA3MTM1NTUyWhcNMzEwNzI1MTM1NTUyWjBPMQswCQYDVQQGEwJVUzENMAsG\n" +
+ "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxEjAQBgNV\n" +
+ "BAMTCWxvY2FsaG9zdDBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3Pb49OSPfOD2G\n" +
+ "HSXFCFx1GJEZfqG9ZUf7xuIi/ra5dLjPGAaoY5QF2QOa8VnOriQCXDfyXHxsuRnE\n" +
+ "OomxL7EVAgMBAAGjeDB2MAsGA1UdDwQEAwID6DAdBgNVHQ4EFgQUXNCJK3/dtCIc\n" +
+ "xb+zlA/JINlvs/MwHwYDVR0jBBgwFoAUuXzV2d+nTAOu/Q4nWzGVbMfzdeEwJwYD\n" +
+ "VR0lBCAwHgYIKwYBBQUHAwEGCCsGAQUFBwMCBggrBgEFBQcDAzANBgkqhkiG9w0B\n" +
+ "AQQFAAOBgQB2qIDUxA2caMPpGtUACZAPRUtrGssCINIfItETXJZCx/cRuZ5sP4D9\n" +
+ "N1acoNDn0hCULe3lhXAeTC9NZ97680yJzregQMV5wATjo1FGsKY30Ma+sc/nfzQW\n" +
+ "+h/7RhYtoG0OTsiaDCvyhI6swkNJzSzrAccPY4+ZgU8HiDLzZTmM3Q==\n" +
+ "-----END CERTIFICATE-----";
+
+ // Private key in the format of PKCS#8, key size is 512 bits.
+ static String targetPrivateKey =
+ "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAtz2+PTkj3zg9hh0l\n" +
+ "xQhcdRiRGX6hvWVH+8biIv62uXS4zxgGqGOUBdkDmvFZzq4kAlw38lx8bLkZxDqJ\n" +
+ "sS+xFQIDAQABAkByx/5Oo2hQ/w2q4L8z+NTRlJ3vdl8iIDtC/4XPnfYfnGptnpG6\n" +
+ "ZThQRvbMZiai0xHQPQMszvAHjZVme1eDl3EBAiEA3aKJHynPVCEJhpfCLWuMwX5J\n" +
+ "1LntwJO7NTOyU5m8rPECIQDTpzn5X44r2rzWBDna/Sx7HW9IWCxNgUD2Eyi2nA7W\n" +
+ "ZQIgJerEorw4aCAuzQPxiGu57PB6GRamAihEAtoRTBQlH0ECIQDN08FgTtnesgCU\n" +
+ "DFYLLcw1CiHvc7fZw4neBDHCrC8NtQIgA8TOUkGnpCZlQ0KaI8KfKWI+vxFcgFnH\n" +
+ "3fnqsTgaUs4=";
+
+ static char passphrase[] = "passphrase".toCharArray();
+
+ /*
+ * Is the server ready to serve?
+ */
+ volatile static boolean serverReady = false;
+
+ /*
+ * Turn on SSL debugging?
+ */
+ static boolean debug = false;
+
+ /*
+ * Define the server side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ void doServerSide() throws Exception {
+ SSLContext context = generateSSLContext(null, targetCertStr,
+ targetPrivateKey);
+ SSLServerSocketFactory sslssf = context.getServerSocketFactory();
+ SSLServerSocket sslServerSocket =
+ (SSLServerSocket)sslssf.createServerSocket(serverPort);
+ serverPort = sslServerSocket.getLocalPort();
+
+ /*
+ * Signal Client, we're ready for his connect.
+ */
+ serverReady = true;
+
+ SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept();
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslIS.read();
+ sslOS.write('A');
+ sslOS.flush();
+
+ sslSocket.close();
+ }
+
+ /*
+ * Define the client side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ void doClientSide() throws Exception {
+
+ /*
+ * Wait for server to get started.
+ */
+ while (!serverReady) {
+ Thread.sleep(50);
+ }
+
+ SSLContext context = generateSSLContext(trustedCertStr, null, null);
+ SSLSocketFactory sslsf = context.getSocketFactory();
+
+ SSLSocket sslSocket =
+ (SSLSocket)sslsf.createSocket("localhost", serverPort);
+
+ // enable TLSv1.2 only
+ sslSocket.setEnabledProtocols(new String[] {"TLSv1.2"});
+
+ // enable a block cipher
+ sslSocket.setEnabledCipherSuites(
+ new String[] {"TLS_DHE_RSA_WITH_AES_128_CBC_SHA"});
+
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslOS.write('B');
+ sslOS.flush();
+ sslIS.read();
+
+ sslSocket.close();
+ }
+
+ /*
+ * =============================================================
+ * The remainder is just support stuff
+ */
+ private static String tmAlgorithm; // trust manager
+
+ private static void parseArguments(String[] args) {
+ tmAlgorithm = args[0];
+ }
+
+ private static SSLContext generateSSLContext(String trustedCertStr,
+ String keyCertStr, String keySpecStr) throws Exception {
+
+ // generate certificate from cert string
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+
+ // create a key store
+ KeyStore ks = KeyStore.getInstance("JKS");
+ ks.load(null, null);
+
+ // import the trused cert
+ Certificate trusedCert = null;
+ ByteArrayInputStream is = null;
+ if (trustedCertStr != null) {
+ is = new ByteArrayInputStream(trustedCertStr.getBytes());
+ trusedCert = cf.generateCertificate(is);
+ is.close();
+
+ ks.setCertificateEntry("RSA Export Signer", trusedCert);
+ }
+
+ if (keyCertStr != null) {
+ // generate the private key.
+ PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
+ new BASE64Decoder().decodeBuffer(keySpecStr));
+ KeyFactory kf = KeyFactory.getInstance("RSA");
+ RSAPrivateKey priKey =
+ (RSAPrivateKey)kf.generatePrivate(priKeySpec);
+
+ // generate certificate chain
+ is = new ByteArrayInputStream(keyCertStr.getBytes());
+ Certificate keyCert = cf.generateCertificate(is);
+ is.close();
+
+ Certificate[] chain = null;
+ if (trusedCert != null) {
+ chain = new Certificate[2];
+ chain[0] = keyCert;
+ chain[1] = trusedCert;
+ } else {
+ chain = new Certificate[1];
+ chain[0] = keyCert;
+ }
+
+ // import the key entry.
+ ks.setKeyEntry("Whatever", priKey, passphrase, chain);
+ }
+
+ // create SSL context
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm);
+ tmf.init(ks);
+
+ SSLContext ctx = SSLContext.getInstance("TLS");
+ if (keyCertStr != null && !keyCertStr.isEmpty()) {
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
+ kmf.init(ks, passphrase);
+
+ ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+ ks = null;
+ } else {
+ ctx.init(null, tmf.getTrustManagers(), null);
+ }
+
+ return ctx;
+ }
+
+
+ // use any free port by default
+ volatile int serverPort = 0;
+
+ volatile Exception serverException = null;
+ volatile Exception clientException = null;
+
+ public static void main(String[] args) throws Exception {
+ if (debug)
+ System.setProperty("javax.net.debug", "all");
+
+ /*
+ * Get the customized arguments.
+ */
+ parseArguments(args);
+
+ /*
+ * Start the tests.
+ */
+ new ShortRSAKey512();
+ }
+
+ Thread clientThread = null;
+ Thread serverThread = null;
+
+ /*
+ * Primary constructor, used to drive remainder of the test.
+ *
+ * Fork off the other side, then do your work.
+ */
+ ShortRSAKey512() throws Exception {
+ try {
+ if (separateServerThread) {
+ startServer(true);
+ startClient(false);
+ } else {
+ startClient(true);
+ startServer(false);
+ }
+ } catch (Exception e) {
+ // swallow for now. Show later
+ }
+
+ /*
+ * Wait for other side to close down.
+ */
+ if (separateServerThread) {
+ serverThread.join();
+ } else {
+ clientThread.join();
+ }
+
+ /*
+ * When we get here, the test is pretty much over.
+ * Which side threw the error?
+ */
+ Exception local;
+ Exception remote;
+ String whichRemote;
+
+ if (separateServerThread) {
+ remote = serverException;
+ local = clientException;
+ whichRemote = "server";
+ } else {
+ remote = clientException;
+ local = serverException;
+ whichRemote = "client";
+ }
+
+ /*
+ * If both failed, return the curthread's exception, but also
+ * print the remote side Exception
+ */
+ if ((local != null) && (remote != null)) {
+ System.out.println(whichRemote + " also threw:");
+ remote.printStackTrace();
+ System.out.println();
+ throw local;
+ }
+
+ if (remote != null) {
+ throw remote;
+ }
+
+ if (local != null) {
+ throw local;
+ }
+ }
+
+ void startServer(boolean newThread) throws Exception {
+ if (newThread) {
+ serverThread = new Thread() {
+ public void run() {
+ try {
+ doServerSide();
+ } catch (Exception e) {
+ /*
+ * Our server thread just died.
+ *
+ * Release the client, if not active already...
+ */
+ System.err.println("Server died...");
+ serverReady = true;
+ serverException = e;
+ }
+ }
+ };
+ serverThread.start();
+ } else {
+ try {
+ doServerSide();
+ } catch (Exception e) {
+ serverException = e;
+ } finally {
+ serverReady = true;
+ }
+ }
+ }
+
+ void startClient(boolean newThread) throws Exception {
+ if (newThread) {
+ clientThread = new Thread() {
+ public void run() {
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ /*
+ * Our client thread just died.
+ */
+ System.err.println("Client died...");
+ clientException = e;
+ }
+ }
+ };
+ clientThread.start();
+ } else {
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ clientException = e;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/CookieHttpsClientTest.java Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 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.
+ */
+
+/*
+ * @test
+ * @bug 7129083
+ * @summary Cookiemanager does not store cookies if url is read
+ * before setting cookiemanager
+ */
+
+import java.net.CookieHandler;
+import java.net.CookieManager;
+import java.net.CookiePolicy;
+import java.net.URL;
+import java.io.InputStream;
+import java.io.IOException;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+
+public class CookieHttpsClientTest {
+ static final int TIMEOUT = 10 * 1000;
+
+ static final String replyString = "HTTP/1.1 200 OK\r\n" +
+ "Set-Cookie: name=test\r\n" +
+ "Content-Length: 10\r\n\r\n" +
+ "1234567890";
+
+ /*
+ * =============================================================
+ * Set the various variables needed for the tests, then
+ * specify what tests to run on each side.
+ */
+
+ /*
+ * Should we run the client or server in a separate thread?
+ * Both sides can throw exceptions, but do you have a preference
+ * as to which side should be the main thread.
+ */
+ static boolean separateServerThread = true;
+
+ /*
+ * Where do we find the keystores?
+ */
+ static String pathToStores = "../../../../../../etc";
+ static String keyStoreFile = "keystore";
+ static String trustStoreFile = "truststore";
+ static String passwd = "passphrase";
+
+ /*
+ * Is the server ready to serve?
+ */
+ volatile static boolean serverReady = false;
+
+ /*
+ * Turn on SSL debugging?
+ */
+ static boolean debug = false;
+
+ /*
+ * Define the server side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ void doServerSide() throws Exception {
+ SSLServerSocketFactory sslssf =
+ (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
+ SSLServerSocket sslServerSocket =
+ (SSLServerSocket) sslssf.createServerSocket(serverPort);
+ serverPort = sslServerSocket.getLocalPort();
+
+ /*
+ * Signal Client, we're ready for his connect.
+ */
+ serverReady = true;
+ SSLSocket sslSocket = null;
+ try {
+ sslSocket = (SSLSocket) sslServerSocket.accept();
+ sslSocket.setSoTimeout(TIMEOUT);
+ readOneRequest(sslSocket.getInputStream());
+ sslSocket.getOutputStream().write(replyString.getBytes());
+
+ readOneRequest(sslSocket.getInputStream());
+ sslSocket.getOutputStream().write(replyString.getBytes());
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ if (sslSocket != null) { sslSocket.close(); }
+ sslServerSocket.close();
+ } catch (IOException unused) { /* gulp!burp! */ }
+ }
+ }
+
+ /*
+ * Define the client side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ void doClientSide() throws Exception {
+ // Wait for server to get started.
+ while (!serverReady) {
+ Thread.sleep(50);
+ }
+
+ HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
+ public boolean verify(String hostname, SSLSession session) {
+ return true;
+ }});
+
+ URL url = new URL("https://localhost:" + serverPort +"/");
+
+ // Run without a CookieHandler first
+ InputStream in = url.openConnection().getInputStream();
+ while (in.read() != -1); // read response body so connection can be reused
+
+ // Set a CookeHandler and retest using the HttpClient from the KAC
+ CookieManager manager = new CookieManager(null, CookiePolicy.ACCEPT_ALL);
+ CookieHandler.setDefault(manager);
+
+ in = url.openConnection().getInputStream();
+ while (in.read() != -1);
+
+ if (manager.getCookieStore().getCookies().isEmpty()) {
+ throw new RuntimeException("Failed: No cookies in the cookie Handler.");
+ }
+ }
+
+ static final byte[] requestEnd = new byte[] {'\r', '\n', '\r', '\n' };
+
+ // Read until the end of a HTTP request
+ static void readOneRequest(InputStream is) throws IOException {
+ int requestEndCount = 0, r;
+ while ((r = is.read()) != -1) {
+ if (r == requestEnd[requestEndCount]) {
+ requestEndCount++;
+ if (requestEndCount == 4) {
+ break;
+ }
+ } else {
+ requestEndCount = 0;
+ }
+ }
+ }
+
+ /*
+ * =============================================================
+ * The remainder is just support stuff
+ */
+
+ // use any free port by default
+ volatile int serverPort = 0;
+
+ volatile Exception serverException = null;
+ volatile Exception clientException = null;
+
+ public static void main(String args[]) throws Exception {
+ String keyFilename =
+ System.getProperty("test.src", "./") + "/" + pathToStores +
+ "/" + keyStoreFile;
+ String trustFilename =
+ System.getProperty("test.src", "./") + "/" + pathToStores +
+ "/" + trustStoreFile;
+
+ System.setProperty("javax.net.ssl.keyStore", keyFilename);
+ System.setProperty("javax.net.ssl.keyStorePassword", passwd);
+ System.setProperty("javax.net.ssl.trustStore", trustFilename);
+ System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+
+ if (debug)
+ System.setProperty("javax.net.debug", "all");
+
+ new CookieHttpsClientTest();
+ }
+
+ Thread clientThread = null;
+ Thread serverThread = null;
+ /*
+ * Primary constructor, used to drive remainder of the test.
+ *
+ * Fork off the other side, then do your work.
+ */
+ CookieHttpsClientTest() throws Exception {
+ if (separateServerThread) {
+ startServer(true);
+ startClient(false);
+ } else {
+ startClient(true);
+ startServer(false);
+ }
+
+ /*
+ * Wait for other side to close down.
+ */
+ if (separateServerThread) {
+ serverThread.join();
+ } else {
+ clientThread.join();
+ }
+
+ /*
+ * When we get here, the test is pretty much over.
+ *
+ * If the main thread excepted, that propagates back
+ * immediately. If the other thread threw an exception, we
+ * should report back.
+ */
+ if (serverException != null)
+ throw serverException;
+ if (clientException != null)
+ throw clientException;
+ }
+
+ void startServer(boolean newThread) throws Exception {
+ if (newThread) {
+ serverThread = new Thread() {
+ public void run() {
+ try {
+ doServerSide();
+ } catch (Exception e) {
+ /*
+ * Our server thread just died.
+ *
+ * Release the client, if not active already...
+ */
+ System.err.println("Server died...");
+ serverReady = true;
+ serverException = e;
+ }
+ }
+ };
+ serverThread.start();
+ } else {
+ doServerSide();
+ }
+ }
+
+ void startClient(boolean newThread) throws Exception {
+ if (newThread) {
+ clientThread = new Thread() {
+ public void run() {
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ /*
+ * Our client thread just died.
+ */
+ System.err.println("Client died...");
+ clientException = e;
+ }
+ }
+ };
+ clientThread.start();
+ } else {
+ doClientSide();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/I18NJarTest.java Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 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.
+ */
+
+/*
+ * @test
+ * @bug 7125442
+ * @summary ensures a jar path as well as a class located in a path containing
+ * unicode characters are launched.
+ * @compile -XDignore.symbol.file I18NJarTest.java TestHelper.java
+ * @run main/othervm I18NJarTest
+ */
+import java.io.File;
+import java.util.Locale;
+
+/*
+ * Note 1: the system must have the correct Locale, in order for the test to
+ * work correctly, on those systems that do not comply, the test will succeed.
+ * Here are some guidelines to set the locale correctly.
+ * On Windows: ControlPanel->Regional Settings,
+ * ensure that "Japanese" is selected and checked, and in
+ * "Code page conversion tables", the following must be checked,
+ * 932 (ANSI/OEM - Japanese Shift-JIS).
+ * On Unix: use "locale -a" verify one of these exist ja_JP.UTF-8 or
+ * ja_JP.utf8 or ja_JP.ujis, and export one of them with LC_ALL.
+ *
+ *
+ * Note 2: since we need to set the locale, it is safest to execute this test
+ * in its own VM (othervm mode), such that the ensuing tests can run unperturbed,
+ * regardless of the outcome.
+ */
+public class I18NJarTest {
+ private static final File cwd = new File(".");
+ private static final File dir = new File("\uFF66\uFF67\uFF68\uFF69");
+ private static final String encoding = System.getProperty("sun.jnu.encoding", "");
+
+ public static void main(String... args) throws Exception {
+ boolean localeAvailable = false;
+ for (Locale l : Locale.getAvailableLocales()) {
+ if (l.toLanguageTag().equals(Locale.JAPAN.toLanguageTag())) {
+ localeAvailable = true;
+ break;
+ }
+ }
+ if (!localeAvailable) {
+ System.out.println("Warning: locale: " + Locale.JAPAN
+ + " not found, test passes vacuosly");
+ return;
+ }
+ if (encoding.equals("MS932") || encoding.equals("UTF-8")) {
+ Locale.setDefault(Locale.JAPAN);
+ System.out.println("using locale " + Locale.JAPAN +
+ ", encoding " + encoding);
+ } else {
+ System.out.println("Warning: current encoding is " + encoding +
+ "this test requires MS932 <Ja> or UTF-8," +
+ " test passes vacuosly");
+ return;
+ }
+ dir.mkdir();
+ File dirfile = new File(dir, "foo.jar");
+ TestHelper.createJar(dirfile,
+ "public static void main(String... args) {",
+ "System.out.println(\"Hello World\");",
+ "System.exit(0);",
+ "}");
+
+ // remove the class files, to ensure that the class is indeed picked up
+ // from the jar file and not from ambient classpath.
+ File[] classFiles = cwd.listFiles(TestHelper.createFilter(TestHelper.CLASS_FILE_EXT));
+ for (File f : classFiles) {
+ f.delete();
+ }
+
+ // test with a jar file
+ TestHelper.TestResult tr = TestHelper.doExec(TestHelper.javaCmd,
+ "-jar", dirfile.getAbsolutePath());
+ System.out.println(tr);
+ if (!tr.isOK()) {
+ throw new RuntimeException("TEST FAILED");
+ }
+
+ // test the same class but by specifying it as a classpath
+ tr = TestHelper.doExec(TestHelper.javaCmd, "-cp",
+ dirfile.getAbsolutePath(), "Foo");
+ System.out.println(tr);
+ if (!tr.isOK()) {
+ throw new RuntimeException("TEST FAILED");
+ }
+ }
+}
--- a/jdk/test/tools/launcher/TestHelper.java Fri Jan 27 13:48:40 2012 +0000
+++ b/jdk/test/tools/launcher/TestHelper.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -21,23 +21,24 @@
* questions.
*/
-import java.nio.file.attribute.BasicFileAttributes;
-import java.nio.file.FileVisitResult;
-import java.nio.file.SimpleFileVisitor;
-import javax.tools.ToolProvider;
import java.io.BufferedReader;
import java.io.File;
+import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
+import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.Files;
+import java.nio.file.FileVisitResult;
+import java.nio.file.SimpleFileVisitor;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.tools.JavaCompiler;
+import javax.tools.ToolProvider;
import static java.nio.file.StandardCopyOption.*;
@@ -68,6 +69,10 @@
static final boolean isDualMode = isSolaris;
static final boolean isSparc = System.getProperty("os.arch").startsWith("sparc");
+ static final String JAVA_FILE_EXT = ".java";
+ static final String CLASS_FILE_EXT = ".class";
+ static final String JAR_FILE_EXT = ".jar";
+
static int testExitValue = 0;
static {
@@ -303,6 +308,19 @@
}
}
+ static FileFilter createFilter(final String extension) {
+ return new FileFilter() {
+ @Override
+ public boolean accept(File pathname) {
+ String name = pathname.getName();
+ if (name.endsWith(extension)) {
+ return true;
+ }
+ return false;
+ }
+ };
+ }
+
/*
* A class to encapsulate the test results and stuff, with some ease
* of use methods to check the test results.
--- a/langtools/.hgtags Fri Jan 27 13:48:40 2012 +0000
+++ b/langtools/.hgtags Sat Jan 28 22:21:54 2012 -0800
@@ -143,3 +143,5 @@
77b2c066084cbc75150efc6603a713c558329813 jdk8-b19
ffd294128a48cbb90ce8f0569f82b61f1f164a18 jdk8-b20
bcb21abf1c4177baf4574f99709513dcd4474727 jdk8-b21
+390a7828ae18324030c0546b6452d51093ffa451 jdk8-b22
+601ffcc6551d5414ef871be306c3a26396cf16a7 jdk8-b23
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Fri Jan 27 13:48:40 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -3600,39 +3600,44 @@
@Override
public Type visitCapturedType(CapturedType t, Void s) {
- Type bound = visitWildcardType(t.wildcard, null);
- return (bound.contains(t)) ?
- erasure(bound) :
- bound;
+ Type w_bound = t.wildcard.type;
+ Type bound = w_bound.contains(t) ?
+ erasure(w_bound) :
+ visit(w_bound);
+ return rewriteAsWildcardType(visit(bound), t.wildcard.bound, t.wildcard.kind);
}
@Override
public Type visitTypeVar(TypeVar t, Void s) {
if (rewriteTypeVars) {
- Type bound = high ?
- (t.bound.contains(t) ?
+ Type bound = t.bound.contains(t) ?
erasure(t.bound) :
- visit(t.bound)) :
- syms.botType;
- return rewriteAsWildcardType(bound, t);
+ visit(t.bound);
+ return rewriteAsWildcardType(bound, t, EXTENDS);
+ } else {
+ return t;
}
- else
- return t;
}
@Override
public Type visitWildcardType(WildcardType t, Void s) {
- Type bound = high ? t.getExtendsBound() :
- t.getSuperBound();
- if (bound == null)
- bound = high ? syms.objectType : syms.botType;
- return rewriteAsWildcardType(visit(bound), t.bound);
+ Type bound2 = visit(t.type);
+ return t.type == bound2 ? t : rewriteAsWildcardType(bound2, t.bound, t.kind);
}
- private Type rewriteAsWildcardType(Type bound, TypeVar formal) {
- return high ?
- makeExtendsWildcard(B(bound), formal) :
- makeSuperWildcard(B(bound), formal);
+ private Type rewriteAsWildcardType(Type bound, TypeVar formal, BoundKind bk) {
+ switch (bk) {
+ case EXTENDS: return high ?
+ makeExtendsWildcard(B(bound), formal) :
+ makeExtendsWildcard(syms.objectType, formal);
+ case SUPER: return high ?
+ makeSuperWildcard(syms.botType, formal) :
+ makeSuperWildcard(B(bound), formal);
+ case UNBOUND: return makeExtendsWildcard(syms.objectType, formal);
+ default:
+ Assert.error("Invalid bound kind " + bk);
+ return null;
+ }
}
Type B(Type t) {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Fri Jan 27 13:48:40 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -332,25 +332,29 @@
//replace uninferred type-vars
targs = types.subst(targs,
that.tvars,
- instaniateAsUninferredVars(undetvars, that.tvars));
+ instantiateAsUninferredVars(undetvars, that.tvars));
}
return chk.checkType(warn.pos(), that.inst(targs, types), to);
}
//where
- private List<Type> instaniateAsUninferredVars(List<Type> undetvars, List<Type> tvars) {
+ private List<Type> instantiateAsUninferredVars(List<Type> undetvars, List<Type> tvars) {
+ Assert.check(undetvars.length() == tvars.length());
ListBuffer<Type> new_targs = ListBuffer.lb();
- //step 1 - create syntethic captured vars
+ //step 1 - create synthetic captured vars
for (Type t : undetvars) {
UndetVar uv = (UndetVar)t;
Type newArg = new CapturedType(t.tsym.name, t.tsym, uv.inst, syms.botType, null);
new_targs = new_targs.append(newArg);
}
//step 2 - replace synthetic vars in their bounds
+ List<Type> formals = tvars;
for (Type t : new_targs.toList()) {
CapturedType ct = (CapturedType)t;
ct.bound = types.subst(ct.bound, tvars, new_targs.toList());
- WildcardType wt = new WildcardType(ct.bound, BoundKind.EXTENDS, syms.boundClass);
+ WildcardType wt = new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass);
+ wt.bound = (TypeVar)formals.head;
ct.wildcard = wt;
+ formals = formals.tail;
}
return new_targs.toList();
}
--- a/langtools/src/share/classes/javax/lang/model/element/Element.java Fri Jan 27 13:48:40 2012 +0000
+++ b/langtools/src/share/classes/javax/lang/model/element/Element.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -214,14 +214,13 @@
* Returns the elements that are, loosely speaking, directly
* enclosed by this element.
*
- * A class or interface is considered to enclose the fields,
- * methods, constructors, and member types that it directly
- * declares. This includes any (implicit) default constructor and
- * the implicit {@code values} and {@code valueOf} methods of an
- * enum type.
+ * A {@linkplain TypeElement#getEnclosedElements class or
+ * interface} is considered to enclose the fields, methods,
+ * constructors, and member types that it directly declares.
*
- * A package encloses the top-level classes and interfaces within
- * it, but is not considered to enclose subpackages.
+ * A {@linkplain PackageElement#getEnclosedElements package}
+ * encloses the top-level classes and interfaces within it, but is
+ * not considered to enclose subpackages.
*
* Other kinds of elements are not currently considered to enclose
* any elements; however, that may change as this API or the
@@ -231,6 +230,8 @@
* methods in {@link ElementFilter}.
*
* @return the enclosed elements, or an empty list if none
+ * @see PackageElement#getEnclosedElements
+ * @see TypeElement#getEnclosedElements
* @see Elements#getAllMembers
* @jls 8.8.9 Default Constructor
* @jls 8.9 Enums
--- a/langtools/src/share/classes/javax/lang/model/element/PackageElement.java Fri Jan 27 13:48:40 2012 +0000
+++ b/langtools/src/share/classes/javax/lang/model/element/PackageElement.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
package javax.lang.model.element;
+import java.util.List;
+
/**
* Represents a package program element. Provides access to information
* about the package and its members.
@@ -49,7 +51,7 @@
/**
* Returns the simple name of this package. For an unnamed
- * package, an empty name is returned
+ * package, an empty name is returned.
*
* @return the simple name of this package or an empty name if
* this is an unnamed package
@@ -58,6 +60,18 @@
Name getSimpleName();
/**
+ * Returns the {@linkplain NestingKind#TOP_LEVEL top-level}
+ * classes and interfaces within this package. Note that
+ * subpackages are <em>not</em> considered to be enclosed by a
+ * package.
+ *
+ * @return the top-level classes and interfaces within this
+ * package
+ */
+ @Override
+ List<? extends Element> getEnclosedElements();
+
+ /**
* Returns {@code true} is this is an unnamed package and {@code
* false} otherwise.
*
--- a/langtools/src/share/classes/javax/lang/model/element/TypeElement.java Fri Jan 27 13:48:40 2012 +0000
+++ b/langtools/src/share/classes/javax/lang/model/element/TypeElement.java Sat Jan 28 22:21:54 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -61,7 +61,12 @@
*/
public interface TypeElement extends Element, Parameterizable, QualifiedNameable {
/**
- * {@inheritDoc}
+ * Returns the fields, methods, constructors, and member types
+ * that are directly declared in this class or interface.
+ *
+ * This includes any (implicit) default constructor and
+ * the implicit {@code values} and {@code valueOf} methods of an
+ * enum type.
*
* <p> Note that as a particular instance of the {@linkplain
* javax.lang.model.element general accuracy requirements} and the
@@ -75,6 +80,7 @@
*
* @return the enclosed elements in proper order, or an empty list if none
*/
+ @Override
List<? extends Element> getEnclosedElements();
/**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/7123100/T7123100a.java Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,16 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 7123100
+ * @summary javac fails with java.lang.StackOverflowError
+ * @compile/fail/ref=T7123100a.out -Werror -Xlint:unchecked -XDrawDiagnostics T7123100a.java
+ */
+
+class T7123100a {
+ <E extends Enum<E>> E m() {
+ return null;
+ }
+
+ <Z> void test() {
+ Z z = (Z)m();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/7123100/T7123100a.out Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,4 @@
+T7123100a.java:14:19: compiler.warn.prob.found.req: (compiler.misc.unchecked.cast.to.type), compiler.misc.type.captureof: 1, ?, Z
+- compiler.err.warnings.and.werror
+1 error
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/7123100/T7123100b.java Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,12 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 7123100
+ * @summary javac fails with java.lang.StackOverflowError
+ * @compile/fail/ref=T7123100b.out -Werror -Xlint:unchecked -XDrawDiagnostics T7123100b.java
+ */
+
+class T7123100b {
+ <Z> void test(Enum<?> e) {
+ Z z = (Z)e;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/7123100/T7123100b.out Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,4 @@
+T7123100b.java:10:18: compiler.warn.prob.found.req: (compiler.misc.unchecked.cast.to.type), java.lang.Enum<compiler.misc.type.captureof: 1, ?>, Z
+- compiler.err.warnings.and.werror
+1 error
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/7123100/T7123100c.java Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,16 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 7123100
+ * @summary javac fails with java.lang.StackOverflowError
+ * @compile/fail/ref=T7123100c.out -Werror -Xlint:unchecked -XDrawDiagnostics T7123100c.java
+ */
+
+class T7123100c {
+ <E> E m(E e) {
+ return null;
+ }
+
+ <Z> void test(Enum<?> e) {
+ Z z = (Z)m(e);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/7123100/T7123100c.out Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,4 @@
+T7123100c.java:14:19: compiler.warn.prob.found.req: (compiler.misc.unchecked.cast.to.type), java.lang.Enum<compiler.misc.type.captureof: 1, ?>, Z
+- compiler.err.warnings.and.werror
+1 error
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/7123100/T7123100d.java Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,16 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 7123100
+ * @summary javac fails with java.lang.StackOverflowError
+ * @compile/fail/ref=T7123100d.out -Werror -Xlint:unchecked -XDrawDiagnostics T7123100d.java
+ */
+
+class T7123100d {
+ <E extends Enum<E>> E m(Enum<E> e) {
+ return null;
+ }
+
+ <Z> void test(Enum<?> e) {
+ Z z = (Z)m(e);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/7123100/T7123100d.out Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,4 @@
+T7123100d.java:14:19: compiler.warn.prob.found.req: (compiler.misc.unchecked.cast.to.type), compiler.misc.type.captureof: 1, ?, Z
+- compiler.err.warnings.and.werror
+1 error
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/7126754/T7126754.java Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @author mcimadamore
+ * @bug 7005671
+ * @summary Generics compilation failure casting List<? extends Set...> to List<Set...>
+ * @compile/fail/ref=T7126754.out -Xlint:unchecked -Werror -XDrawDiagnostics T7126754.java
+ */
+
+import java.util.List;
+
+class T7126754 {
+ List<? extends List<? extends String>> c = null;
+ List<List<? extends String>> d = (List<List<? extends String>>)c;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/7126754/T7126754.out Sat Jan 28 22:21:54 2012 -0800
@@ -0,0 +1,4 @@
+T7126754.java:13:68: compiler.warn.prob.found.req: (compiler.misc.unchecked.cast.to.type), java.util.List<compiler.misc.type.captureof: 1, ? extends java.util.List<? extends java.lang.String>>, java.util.List<java.util.List<? extends java.lang.String>>
+- compiler.err.warnings.and.werror
+1 error
+1 warning
--- a/langtools/test/tools/javac/diags/CheckExamples.java Fri Jan 27 13:48:40 2012 +0000
+++ b/langtools/test/tools/javac/diags/CheckExamples.java Sat Jan 28 22:21:54 2012 -0800
@@ -23,10 +23,13 @@
/*
* @test
- * @bug 6968063
+ * @bug 6968063 7127924
* @summary provide examples of code that generate diagnostics
* @build Example CheckExamples
- * @run main CheckExamples
+ * @run main/othervm CheckExamples
+ */
+/*
+ * See CR 7127924 for info on why othervm is used.
*/
import java.io.*;
--- a/langtools/test/tools/javac/diags/MessageInfo.java Fri Jan 27 13:48:40 2012 +0000
+++ b/langtools/test/tools/javac/diags/MessageInfo.java Sat Jan 28 22:21:54 2012 -0800
@@ -23,10 +23,13 @@
/**
* @test
- * @bug 7013272
+ * @bug 7013272 7127924
* @summary Automatically generate info about how compiler resource keys are used
* @build Example ArgTypeCompilerFactory MessageFile MessageInfo
- * @run main MessageInfo
+ * @run main/othervm MessageInfo
+ */
+/*
+ * See CR 7127924 for info on why othervm is used.
*/
import java.io.*;
--- a/langtools/test/tools/javac/diags/RunExamples.java Fri Jan 27 13:48:40 2012 +0000
+++ b/langtools/test/tools/javac/diags/RunExamples.java Sat Jan 28 22:21:54 2012 -0800
@@ -23,10 +23,13 @@
/**
* @test
- * @bug 6968063
+ * @bug 6968063 7127924
* @summary provide examples of code that generate diagnostics
* @build ArgTypeCompilerFactory Example HTMLWriter RunExamples
- * @run main RunExamples
+ * @run main/othervm RunExamples
+ */
+/*
+ * See CR 7127924 for info on why othervm is used.
*/
import java.io.*;