# HG changeset patch # User lana # Date 1327818114 28800 # Node ID 46e4f3b9cbfa27bab6be18888bfdb1bccb3ea303 # Parent 98dad53a8ba18aec7370082abf412022954f1268# Parent 7d3720d8c595d1519c31e9ff7366203fc2c61350 Merge diff -r 98dad53a8ba1 -r 46e4f3b9cbfa .hgtags --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa .hgtags-top-repo --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa corba/.hgtags --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/.hgtags --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1CollectedHeap.java --- 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 heapRegionIterator() { return hrs().heapRegionIterator(); } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1MonitoringSupport.java --- 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); } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSetBase.java --- /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); + } +} diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java --- 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); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/make/Makefile --- 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) diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/make/bsd/Makefile --- 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) diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/make/bsd/makefiles/buildtree.make --- 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 $@ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/make/bsd/makefiles/defs.make --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/make/bsd/makefiles/launcher.make --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/make/bsd/makefiles/vm.make --- 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) diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/make/defs.make --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/make/hotspot_version --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/make/jprt.properties --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/make/linux/makefiles/buildtree.make --- 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 $@ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/make/linux/makefiles/vm.make --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/make/solaris/makefiles/buildtree.make --- 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 $@ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/make/solaris/makefiles/vm.make --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/make/windows/build.bat --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/make/windows/create_obj_files.sh --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/make/windows/makefiles/projectcreator.make --- 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 \ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/make/windows/makefiles/vm.make --- 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: diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp --- 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; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.hpp --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/cpu/sparc/vm/frame_sparc.cpp --- 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(); } - diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/cpu/sparc/vm/frame_sparc.inline.hpp --- 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 { diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp --- 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 "); + 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<unpack())); - - assert(code_offset() - offset <= deopt_handler_size, "overflow"); + guarantee(code_offset() - offset <= deopt_handler_size, "overflow"); __ end_a_stub(); return offset; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/cpu/x86/vm/frame_x86.cpp --- 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(); +} diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/cpu/x86/vm/frame_x86.hpp --- 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; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/cpu/x86/vm/methodHandles_x86.cpp --- 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 "); + 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< - -#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; -} diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/os/bsd/vm/decoder_machO.cpp --- /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 + + diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/os/bsd/vm/decoder_machO.hpp --- /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 + diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/os/bsd/vm/os_bsd.cpp --- 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 - // "/jre/lib///libjvm.so". If "/jre/lib/" appears at + // "/jre/lib///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; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/os/linux/vm/decoder_linux.cpp --- 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 -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; } + diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/os/linux/vm/os_linux.cpp --- 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; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/os/posix/launcher/java_md.c --- 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) { diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/os/solaris/vm/decoder_solaris.cpp --- 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 -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); } + diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/os/solaris/vm/osThread_solaris.hpp --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/os/solaris/vm/os_solaris.cpp --- 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 # include # include +# include # include # include # include @@ -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; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/os/windows/vm/decoder_windows.cpp --- 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); } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/os/windows/vm/decoder_windows.hpp --- /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 +#include + +#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 + diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/os/windows/vm/os_windows.cpp --- 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; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/c1/c1_LIR.hpp --- 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)); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/c1/c1_LIRGenerator.cpp --- 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()); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/c1/c1_Runtime1.cpp --- 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; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/classfile/javaClasses.cpp --- 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++; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/classfile/symbolTable.cpp --- 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* 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. diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/classfile/symbolTable.hpp --- 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); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/classfile/systemDictionary.cpp --- 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); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/compiler/compileBroker.cpp --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/compiler/compileBroker.hpp --- 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(); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp --- 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); } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp --- 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"); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp --- 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); + } } } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp --- 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(); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp --- 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; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- 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(); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp --- 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++; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp --- 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); } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp --- 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) { diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp --- 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); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.hpp --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp --- 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 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 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 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 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 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.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 inline void FilterIntoCSClosure::do_oop_nv(T* p) { +template +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 inline void FilterOutOfRegionClosure::do_oop_nv(T* p) { +template +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 inline void G1ParScanClosure::do_oop_nv(T* p) { +template +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 inline void G1ParPushHeapRSClosure::do_oop_nv(T* p) { +template +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 inline void G1CMOopClosure::do_oop_nv(T* p) { +template +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 +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 +inline void G1Mux2Closure::do_oop_nv(T* p) { + // Apply first closure; then apply the second. + _c1->do_oop(p); + _c2->do_oop(p); +} + +template +inline void G1TriggerClosure::do_oop_nv(T* p) { + // Record that this closure was actually applied (triggered). + _triggered = true; +} + +template +inline void G1InvokeIfNotTriggeredClosure::do_oop_nv(T* p) { + if (!_trigger_cl->triggered()) { + _oop_cl->do_oop(p); + } +} + +template +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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp --- 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 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 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 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, diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp --- 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 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_implementation/g1/g1RemSet.inline.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 -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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_implementation/g1/g1_specialized_oop_closures.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 +template 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." diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp --- 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; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp --- 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) { diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp --- 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. diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp --- 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); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp --- 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*) \ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp --- 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. diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_interface/gcCause.cpp --- 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"; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/gc_interface/gcCause.hpp --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/interpreter/interpreterRuntime.cpp --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/oops/klass.cpp --- 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); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/oops/klass.hpp --- 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( diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/oops/methodKlass.cpp --- 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); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/oops/methodOop.hpp --- 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; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/opto/block.hpp --- 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 &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 &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 &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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/opto/gcm.cpp --- 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 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)) { diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/opto/lcm.cpp --- 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 &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 &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 &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_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); } } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/opto/memnode.cpp --- 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: diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/opto/memnode.hpp --- 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 { diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/opto/parseHelper.cpp --- 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())); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/prims/jni.cpp --- 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; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/prims/jniExport.hpp --- /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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/prims/jvmtiThreadState.cpp --- 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. diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/prims/jvmtiThreadState.hpp --- 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; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/prims/methodHandles.cpp --- 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_.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; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/prims/methodHandles.hpp --- 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 }; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp --- 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); } } } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/runtime/advancedThresholdPolicy.hpp --- 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. diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/runtime/arguments.cpp --- 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. diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/runtime/compilationPolicy.cpp --- 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));) } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/runtime/compilationPolicy.hpp --- 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* stack); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/runtime/frame.cpp --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/runtime/frame.hpp --- 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); }; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/runtime/globals.hpp --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/runtime/java.cpp --- 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(); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/runtime/mutexLocker.cpp --- 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) { diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/runtime/mutexLocker.hpp --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/runtime/os.cpp --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/runtime/os.hpp --- 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(); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/runtime/sharedRuntime.cpp --- 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 } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp --- 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); } } } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/runtime/simpleThresholdPolicy.hpp --- 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. diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/runtime/thread.cpp --- 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(); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/runtime/thread.hpp --- 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; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/runtime/vm_operations.hpp --- 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 { diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/services/diagnosticArgument.cpp --- 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::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(), diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/services/diagnosticCommand.cpp --- 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(true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); +#ifndef SERVICES_KERNEL // Heap dumping not supported + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); +#endif // SERVICES_KERNEL + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(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", diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/services/diagnosticCommand.hpp --- 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: diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/services/diagnosticCommand_ext.hpp --- /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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/services/diagnosticFramework.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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/services/g1MemoryPool.cpp --- 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() { diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/services/g1MemoryPool.hpp --- 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(); }; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/services/gcNotifier.cpp --- 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); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/services/management.cpp --- 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(true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); -#ifndef SERVICES_KERNEL // Heap dumping not supported - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); -#endif // SERVICES_KERNEL - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(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()); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/services/memoryManager.cpp --- 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. } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/services/memoryManager.hpp --- 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; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/trace/traceEventTypes.hpp --- /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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/trace/traceMacros.hpp --- /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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/trace/tracing.hpp --- /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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/utilities/bitMap.inline.hpp --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/utilities/decoder.cpp --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/utilities/decoder.hpp --- 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 -#include - -// 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/utilities/decoder_elf.cpp --- /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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/utilities/decoder_elf.hpp --- /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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/utilities/elfFile.cpp --- 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); } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/utilities/elfFile.hpp --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/utilities/elfStringTable.cpp --- 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; } } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/utilities/elfStringTable.hpp --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/utilities/elfSymbolTable.cpp --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/utilities/elfSymbolTable.hpp --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/utilities/exceptions.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. diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/utilities/globalDefinitions.hpp --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp --- 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); +} //---------------------------------------------------------------------------------------------------- diff -r 98dad53a8ba1 -r 46e4f3b9cbfa hotspot/src/share/vm/utilities/vmError.cpp --- 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) { diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jaxp/.hgtags --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jaxws/.hgtags --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/.hgtags --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/make/com/oracle/Makefile --- 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) + diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/make/com/oracle/net/Makefile --- /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 + diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/make/com/oracle/nio/Makefile --- /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 + diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/make/com/oracle/security/ucrypto/FILES_c.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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/make/com/oracle/security/ucrypto/Makefile --- /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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/make/com/oracle/security/ucrypto/mapfile-vers --- /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: + *; +}; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/make/com/oracle/util/Makefile --- /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 + diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/make/javax/sound/jsoundalsa/Makefile --- 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 \ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/make/sun/awt/Makefile --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/make/sun/security/pkcs11/mapfile-vers --- 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; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/bin/java.c --- 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()) { diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/java/lang/Class.java --- 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; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/java/lang/ClassValue.java --- 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 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 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 castEntry(Entry e) { return (Entry) 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 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.) + } + + /** 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. + *

+ * 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. + *

+ * 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. + *

+ * 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 version = new Version<>(this); + Version version() { return version; } + void bumpVersion() { version = new Version<>(this); } + static class Version { + private final ClassValue classValue; + private final Entry promise = new Entry<>(this); + Version(ClassValue classValue) { this.classValue = classValue; } + ClassValue classValue() { return classValue; } + Entry promise() { return promise; } + boolean isLive() { return classValue.version() == this; } + } + + /** One binding of a value to a class via a ClassValue. + * States are:

    + *
  • promise if value == Entry.this + *
  • else dead if version == null + *
  • else stale if version != classValue.version + *
  • else live
+ * 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 extends WeakReference> { + final Object value; // usually of type T, but sometimes (Entry)this + Entry(Version 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 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 version() { return get(); } + ClassValue classValueOrNull() { + Version v = version(); + return (v == null) ? null : v.classValue(); + } + boolean isLive() { + Version v = version(); + if (v == null) return false; + if (v.isLive()) return true; + clear(); + return false; + } + Entry refreshVersion(Version v2) { + assertNotPromise(); + @SuppressWarnings("unchecked") // if !isPromise, type is T + Entry 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 Entry makeEntry(Version 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, ClassValueMap> ROOT - = new WeakHashMap, 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> { + 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 + Entry startEntry(ClassValue classValue) { + @SuppressWarnings("unchecked") // one map has entries for all value types + Entry e = (Entry) get(classValue.identity); + Version 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 { - /** 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 + Entry finishEntry(ClassValue classValue, Entry e) { + @SuppressWarnings("unchecked") // one map has entries for all value types + Entry e0 = (Entry) 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 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 + void changeEntry(ClassValue classValue, T value) { + @SuppressWarnings("unchecked") // one map has entries for all value types + Entry e0 = (Entry) get(classValue.identity); + Version 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 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 Entry probeHomeLocation(Entry[] cache, ClassValue classValue) { + return classValue.castEntry(loadFromCache(cache, classValue.hashCodeForCache)); + } + + /** Given that first probe was a collision, retry at nearby locations. */ + static Entry probeBackupLocations(Entry[] cache, ClassValue 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 void addToCache(Entry e) { + ClassValue classValue = e.classValueOrNull(); + if (classValue != null) + addToCache(classValue, e); + } + + /** Add the given entry to the cache, in its home location. */ + private void addToCache(ClassValue classValue, Entry 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 Entry overwrittenEntry(Entry 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. } } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/java/lang/Math.java --- 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)) diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/java/lang/Object.java --- 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 - * The Java™ Language Specification. + * @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 - * JavaTM 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 @@ *

* 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 interrupted * status 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 interrupted * status 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 interrupted * status of the current thread is cleared when @@ -510,7 +509,7 @@ * system resources or to perform other cleanup. *

* The general contract of {@code finalize} is that it is invoked - * if and when the JavaTM 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 { } } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/java/lang/StrictMath.java --- 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); } /** diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/java/lang/Throwable.java --- 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.(Resource2.java:45) + * at Resource2$CloseFailException.<init>(Resource2.java:45) * ... 2 more * */ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/java/lang/invoke/AdapterMethodHandle.java --- 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); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/java/lang/invoke/MemberName.java --- 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: diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/java/lang/invoke/MethodHandle.java --- 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. * *

Exceptions

diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java --- 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 extends BoundMethodHandle { + static final class AllocateObject /**/ extends BoundMethodHandle { private static final Unsafe unsafe = Unsafe.getUnsafe(); - private final Class allocateClass; + private final Class /**/ allocateClass; // for allocation only: - private AllocateObject(Class allocateClass) { + private AllocateObject(Class /**/ 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 extends BoundMethodHandle { + static final class FieldAccessor /**/ 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; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java --- 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; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/java/lang/invoke/MethodHandles.java --- 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); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/java/nio/file/FileTreeWalker.java --- 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; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/java/nio/file/Files.java --- 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 @@ *
  • It is transitive: 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}. * * * @param path diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/java/nio/file/Path.java --- 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. *
      *     Path path = FileSystems.getDefault().getPath("logs", "access.log");
    - *     BufferReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8);
    + *     BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8);
      * 
    * *

    Interoperability

    diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/invoke/util/ValueConversions.java --- 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[] newWrapperCaches(int n) { - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // generic array creation EnumMap[] caches - = (EnumMap[]) new EnumMap[n]; // unchecked warning expected here + = (EnumMap[]) 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/invoke/util/Wrapper.java --- 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); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/Agent.java --- 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) { diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/ConnectorAddressLink.java --- 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 counters = new PerfInstrumentation(bb).findByPattern(CONNECTOR_ADDRESS_COUNTER); - Iterator i = counters.iterator(); + Iterator 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 properties = new HashMap(); - for (Object c : counters) { - String name = ((Counter) c).getName(); + List counters = new PerfInstrumentation(bb).getAllCounters(); + Map 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; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/Flag.java --- 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 result = new ArrayList(); + List result = new ArrayList<>(); for (Flag f : flags) { if (f != null) { result.add(f); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/GarbageCollectionNotifInfoCompositeData.java --- 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 compositeTypeByBuilder = - new HashMap(); + 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, diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/GarbageCollectorImpl.java --- 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 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; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/GcInfoBuilder.java --- 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); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/GcInfoCompositeData.java --- 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) 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); } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/HotSpotDiagnostic.java --- 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 getDiagnosticOptions() { List allFlags = Flag.getAllFlags(); - List result = new ArrayList(); + List result = new ArrayList<>(); for (Flag flag : allFlags) { if (flag.isWriteable() && flag.isExternal()) { result.add(flag.getVMOption()); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/HotspotCompilation.java --- 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(); - 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 getCompilerThreadStats() { - List list = new ArrayList(threads.length); + List list = new ArrayList<>(threads.length); int i = 0; if (threads[0] == null) { // no adaptor thread diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/HotspotThread.java --- 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 result = new HashMap(numThreads); + Map result = new HashMap<>(numThreads); for (int i = 0; i < numThreads; i++) { result.put(names[i], new Long(times[i])); } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/LazyCompositeData.java --- 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 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 list1 = type1.getIndexNames(); + List list2 = type2.getIndexNames(); // check if the list of index names are the same if (!list1.equals(list2)) diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/ManagementFactoryHelper.java --- 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 getMemoryPoolMXBeans() { MemoryPoolMXBean[] pools = MemoryImpl.getMemoryPools(); - List list = new ArrayList(pools.length); + List list = new ArrayList<>(pools.length); for (MemoryPoolMXBean p : pools) { list.add(p); } @@ -119,7 +119,7 @@ public static List getMemoryManagerMXBeans() { MemoryManagerMXBean[] mgrs = MemoryImpl.getMemoryManagers(); - List result = new ArrayList(mgrs.length); + List result = new ArrayList<>(mgrs.length); for (MemoryManagerMXBean m : mgrs) { result.add(m); } @@ -128,7 +128,7 @@ public static List getGarbageCollectorMXBeans() { MemoryManagerMXBean[] mgrs = MemoryImpl.getMemoryManagers(); - List result = new ArrayList(mgrs.length); + List result = new ArrayList<>(mgrs.length); for (MemoryManagerMXBean m : mgrs) { if (GarbageCollectorMXBean.class.isInstance(m)) { result.add(GarbageCollectorMXBean.class.cast(m)); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/MappedMXBeanType.java --- 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 convertedTypes = - new WeakHashMap(); + 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 result = new ArrayList(openArray.length); + List 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 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 result = new HashMap(); + Map result = new HashMap<>(); for (CompositeData row : (Collection) 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 names = new ArrayList(); - final List types = new ArrayList(); + final List names = new ArrayList<>(); + final List> 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/MonitorInfoCompositeData.java --- 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 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); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/NotificationEmitterSupport.java --- 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 newList = new ArrayList(listenerList.size() + 1); + List 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 newList = new ArrayList(listenerList); + List 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 newList = new ArrayList(listenerList); + List 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)) { diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/RuntimeImpl.java --- 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 getSystemProperties() { Properties sysProps = System.getProperties(); - Map map = new HashMap(); + Map map = new HashMap<>(); // Properties.entrySet() does not include the entries in // the default properties. So use Properties.stringPropertyNames() diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/ThreadInfoCompositeData.java --- 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)) { diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/counter/perf/PerfInstrumentation.java --- 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(); + map = new TreeMap<>(); } boolean hasNext() { @@ -154,7 +154,7 @@ map.put(c.getName(), c); } } - return new ArrayList(map.values()); + return new ArrayList<>(map.values()); } public synchronized List findByPattern(String patternString) { @@ -167,7 +167,8 @@ Pattern pattern = Pattern.compile(patternString); Matcher matcher = pattern.matcher(""); - List matches = new ArrayList(); + List matches = new ArrayList<>(); + for (Map.Entry me: map.entrySet()) { String name = me.getKey(); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java --- 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 principals = subject.getPrincipals(); - for (Principal p: principals) { - if (properties.containsKey(p.getName())) { + for (Principal p1: principals) { + if (properties.containsKey(p1.getName())) { return; } } - final Set principalsStr = new HashSet(); - for (Principal p: principals) { - principalsStr.add(p.getName()); + + final Set 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 environment; @@ -430,7 +431,7 @@ try { // Export remote connector address and associated configuration // properties to the instrumentation buffer. - Map properties = new HashMap(); + Map 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 env = new HashMap(); + Map 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 env = new HashMap(); + Map env = new HashMap<>(); PermanentExporter exporter = new PermanentExporter(); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/AdaptorBootstrap.java --- 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 getTargetList(InetAddressAcl acl, int defaultTrapPort) { final ArrayList result = - new ArrayList(); + 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, diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvminstr/JVM_MANAGEMENT_MIB_IMPL.java --- 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(table); + tableRef = new WeakReference<>(table); return table; } table = tableRef.get(); if(table == null) { table = new JVM_MANAGEMENT_MIBOidTable(); - tableRef = new WeakReference(table); + tableRef = new WeakReference<>(table); } return table; @@ -198,7 +198,7 @@ * List of notification targets. */ private ArrayList notificationTargets = - new ArrayList(); + 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 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(); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvminstr/JvmMemGCTableMetaImpl.java --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvminstr/JvmMemManagerTableMetaImpl.java --- 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 @@ * MemoryManagerMXBean in the list. * @return ((MemoryManagerMXBean)item).getName() **/ - 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 getTableHandler(JvmContextFactory.getUserData()). **/ public SnmpTableHandler getTableHandler() { - final Map userData = JvmContextFactory.getUserData(); + final Map 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 loadRawDatas(Map userData) { return ManagementFactory.getMemoryManagerMXBeans(); } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvminstr/JvmMemMgrPoolRelTableMetaImpl.java --- 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 getTableDatas(JvmContextFactory.getUserData()). **/ public SnmpTableHandler getTableHandler() { - final Map userData = JvmContextFactory.getUserData(); + final Map userData = JvmContextFactory.getUserData(); return getTableDatas(userData); } @@ -101,7 +105,7 @@ return buildPoolIndexMap((SnmpCachedData)handler); // not optimizable... too bad. - final Map m = new HashMap(); + final Map 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 m = new HashMap(len); + final Map m = new HashMap<>(len); for (int i=0; i index - final Map poolIndexMap = buildPoolIndexMap(mpHandler); + final Map 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 table = - new TreeMap(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 table, Object userData, MemoryManagerMXBean mmm, SnmpOid mmIndex, - Map poolIndexMap) { + Map 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 table, Object userData, SnmpTableHandler mmHandler, SnmpTableHandler mpHandler, - Map poolIndexMap) { + Map poolIndexMap) { if (mmHandler instanceof SnmpCachedData) { updateTreeMap(table,userData,(SnmpCachedData)mmHandler, mpHandler,poolIndexMap); @@ -280,7 +284,7 @@ protected void updateTreeMap(TreeMap table, Object userData, SnmpCachedData mmHandler, SnmpTableHandler mpHandler, - Map poolIndexMap) { + Map poolIndexMap) { final SnmpOid[] indexes = mmHandler.indexes; final Object[] datas = mmHandler.datas; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvminstr/JvmMemPoolTableMetaImpl.java --- 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 @@ * MemoryPoolMXBean in the list. * @return ((MemoryPoolMXBean)item).getName() **/ - 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 getTableDatas(JvmContextFactory.getUserData()). **/ public SnmpTableHandler getTableHandler() { - final Map userData = JvmContextFactory.getUserData(); + final Map 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 loadRawDatas(Map userData) { return ManagementFactory.getMemoryPoolMXBeans(); } } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvminstr/JvmMemoryImpl.java --- 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 m = JvmContextFactory.getUserData(); if (m != null) { final EnumJvmMemoryGCCall cached diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvminstr/JvmMemoryMetaImpl.java --- 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". */ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvminstr/JvmOSImpl.java --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRTBootClassPathEntryImpl.java --- 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; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRTBootClassPathTableMetaImpl.java --- 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 getTableDatas(JvmContextFactory.getUserData()). **/ public SnmpTableHandler getTableHandler() { - final Map userData = JvmContextFactory.getUserData(); + final Map userData = JvmContextFactory.getUserData(); return getTableDatas(userData); } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRTClassPathEntryImpl.java --- 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; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRTClassPathTableMetaImpl.java --- 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 getTableDatas(JvmContextFactory.getUserData()). **/ public SnmpTableHandler getTableHandler() { - final Map userData = JvmContextFactory.getUserData(); + final Map userData = JvmContextFactory.getUserData(); return getTableDatas(userData); } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRTInputArgsEntryImpl.java --- 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; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRTInputArgsTableMetaImpl.java --- 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 getTableDatas(JvmContextFactory.getUserData()). **/ public SnmpTableHandler getTableHandler() { - final Map userData = JvmContextFactory.getUserData(); + final Map userData = JvmContextFactory.getUserData(); return getTableDatas(userData); } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRTLibraryPathEntryImpl.java --- 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; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRTLibraryPathTableMetaImpl.java --- 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 getTableDatas(JvmContextFactory.getUserData()). **/ public SnmpTableHandler getTableHandler() { - final Map userData = JvmContextFactory.getUserData(); + final Map userData = JvmContextFactory.getUserData(); return getTableDatas(userData); } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvminstr/JvmRuntimeMetaImpl.java --- 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". */ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvminstr/JvmThreadInstanceEntryImpl.java --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvminstr/JvmThreadInstanceTableMetaImpl.java --- 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 getTableDatas(JvmContextFactory.getUserData()). **/ public SnmpTableHandler getTableHandler() { - final Map userData = JvmContextFactory.getUserData(); + final Map userData = JvmContextFactory.getUserData(); return getTableDatas(userData); } @@ -172,7 +175,7 @@ SnmpOid indexes[] = new SnmpOid[id.length]; final TreeMap table = - new TreeMap(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 m = JvmContextFactory.getUserData(); // Get the handler. // diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvminstr/JvmThreadingMetaImpl.java --- 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". */ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmClassesVerboseLevel.java --- 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 intTable = - new Hashtable(); + new Hashtable<>(); protected static Hashtable stringTable = - new Hashtable(); + 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 getIntTable() { return intTable ; } - protected Hashtable getStringTable() { + protected Hashtable getStringTable() { return stringTable ; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmJITCompilerTimeMonitoring.java --- 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 intTable = - new Hashtable(); + new Hashtable<>(); protected static Hashtable stringTable = - new Hashtable(); + 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 getIntTable() { return intTable ; } - protected Hashtable getStringTable() { + protected Hashtable getStringTable() { return stringTable ; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmMemManagerState.java --- 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 intTable = - new Hashtable(); + new Hashtable<>(); protected static Hashtable stringTable = - new Hashtable(); + 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 getIntTable() { return intTable ; } - protected Hashtable getStringTable() { + protected Hashtable getStringTable() { return stringTable ; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmMemPoolCollectThreshdSupport.java --- 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 intTable = - new Hashtable(); + new Hashtable<>(); protected static Hashtable stringTable = - new Hashtable(); + 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 getIntTable() { return intTable ; } - protected Hashtable getStringTable() { + protected Hashtable getStringTable() { return stringTable ; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmMemPoolState.java --- 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 intTable = - new Hashtable(); + new Hashtable<>(); protected static Hashtable stringTable = - new Hashtable(); + 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 getIntTable() { return intTable ; } - protected Hashtable getStringTable() { + protected Hashtable getStringTable() { return stringTable ; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmMemPoolThreshdSupport.java --- 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 intTable = - new Hashtable(); + new Hashtable<>(); protected static Hashtable stringTable = - new Hashtable(); + 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 getIntTable() { return intTable ; } - protected Hashtable getStringTable() { + protected Hashtable getStringTable() { return stringTable ; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmMemPoolType.java --- 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 intTable = - new Hashtable(); + new Hashtable<>(); protected static Hashtable stringTable = - new Hashtable(); + 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 getIntTable() { return intTable ; } - protected Hashtable getStringTable() { + protected Hashtable getStringTable() { return stringTable ; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmMemoryGCCall.java --- 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 intTable = - new Hashtable(); + new Hashtable<>(); protected static Hashtable stringTable = - new Hashtable(); + 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 getIntTable() { return intTable ; } - protected Hashtable getStringTable() { + protected Hashtable getStringTable() { return stringTable ; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmMemoryGCVerboseLevel.java --- 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 intTable = - new Hashtable(); + new Hashtable<>(); protected static Hashtable stringTable = - new Hashtable(); + 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 getIntTable() { return intTable ; } - protected Hashtable getStringTable() { + protected Hashtable getStringTable() { return stringTable ; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmRTBootClassPathSupport.java --- 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 intTable = - new Hashtable(); + new Hashtable<>(); protected static Hashtable stringTable = - new Hashtable(); + 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 getIntTable() { return intTable ; } - protected Hashtable getStringTable() { + protected Hashtable getStringTable() { return stringTable ; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmThreadContentionMonitoring.java --- 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 intTable = - new Hashtable(); + new Hashtable<>(); protected static Hashtable stringTable = - new Hashtable(); + 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 getIntTable() { return intTable ; } - protected Hashtable getStringTable() { + protected Hashtable getStringTable() { return stringTable ; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/EnumJvmThreadCpuTimeMonitoring.java --- 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 intTable = - new Hashtable(); + new Hashtable<>(); protected static Hashtable stringTable = - new Hashtable(); + 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 getIntTable() { return intTable ; } - protected Hashtable getStringTable() { + protected Hashtable getStringTable() { return stringTable ; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JVM_MANAGEMENT_MIB.java --- 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. */ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JVM_MANAGEMENT_MIBOidTable.java --- 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. */ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JvmClassLoadingMeta.java --- 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". */ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JvmCompilationMeta.java --- 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". */ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JvmMemGCEntryMeta.java --- 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". */ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JvmMemGCTableMeta.java --- 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. diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JvmMemManagerEntryMeta.java --- 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". */ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JvmMemManagerTableMeta.java --- 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. diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JvmMemMgrPoolRelEntryMeta.java --- 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". */ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JvmMemMgrPoolRelTableMeta.java --- 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. diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JvmMemPoolEntryMeta.java --- 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". */ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JvmMemPoolTableMeta.java --- 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. diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JvmOSMeta.java --- 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". */ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRTBootClassPathEntryMeta.java --- 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". */ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRTBootClassPathTableMeta.java --- 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. diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRTClassPathEntryMeta.java --- 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". */ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRTClassPathTableMeta.java --- 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. diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRTInputArgsEntryMeta.java --- 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". */ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRTInputArgsTableMeta.java --- 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. diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRTLibraryPathEntryMeta.java --- 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". */ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRTLibraryPathTableMeta.java --- 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. diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JvmRuntimeMeta.java --- 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". */ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JvmThreadInstanceEntryMeta.java --- 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". */ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JvmThreadInstanceTableMeta.java --- 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. diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/jvmmib/JvmThreadingMeta.java --- 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". */ diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/util/MibLogger.java --- 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)); } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/util/SnmpListTableCache.java --- 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 @@ * rawDatas 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 item 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 map = - new TreeMap(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); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/util/SnmpNamedListTableCache.java --- 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 names = new TreeMap<>(); /** * The last allocate index. @@ -80,7 +80,7 @@ * rawDatas 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 @@ * rawDatas 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 @@ * rawDatas 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 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 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 userData, String key) { - List rawDatas = null; + protected List getRawDatas(Map 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.>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)?"":""+rawDatas.size())); - TreeMap ctxt = new TreeMap(); + TreeMap ctxt = new TreeMap<>(); final SnmpCachedData result = super.updateCachedDatas(ctxt,rawDatas); names = ctxt; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/management/snmp/util/SnmpTableCache.java --- 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(computedDatas); + if (validity != 0) datas = new WeakReference<>(computedDatas); return computedDatas; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/misc/VM.java --- 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; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/net/www/http/HttpClient.java --- 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() { - 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java --- 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> headers; + Map> 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; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/net/www/protocol/https/HttpsClient.java --- 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() { - public CookieHandler run() { - return CookieHandler.getDefault(); - } - }); openServer(); } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/security/krb5/internal/rcache/CacheTable.java --- 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."); } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/security/krb5/internal/rcache/ReplayCache.java --- 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 CacheTable. * @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(); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java --- 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; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/security/pkcs11/P11Digest.java --- 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; } } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/security/pkcs11/P11Key.java --- 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; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/security/pkcs11/P11RSACipher.java --- 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; } } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/security/pkcs11/P11Signature.java --- 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); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/security/pkcs11/wrapper/PKCS11.java --- 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); } - } - } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java --- 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( diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java --- 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; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java --- 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 algorithms, String expected) { + return SignatureAndHashAlgorithm.getPreferableAlgorithm( + algorithms, expected, null); + } + + static SignatureAndHashAlgorithm getPreferableAlgorithm( + Collection 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) { diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java --- 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; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/security/util/KeyLength.java --- /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; + } +} + diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/classes/sun/security/util/Length.java --- /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 + *

    + * 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(); +} diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/lib/security/java.security-solaris --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/lib/security/sunpkcs11-solaris.cfg --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11wrapper.h --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/solaris/classes/sun/java2d/xr/XRCompositeManager.java --- 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() { + public String run() { + return System.getProperty("sun.java2d.xrgradcache"); + } + }); + enableGradCache = gradProp == null || !(gradProp.equalsIgnoreCase("false") || gradProp.equalsIgnoreCase("f")); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/solaris/classes/sun/nio/fs/UnixChannelFactory.java --- 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; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java --- 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); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/solaris/classes/sun/nio/fs/UnixNativeDispatcher.java --- 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(); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/solaris/classes/sun/nio/fs/UnixPath.java --- 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) { diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/solaris/native/java/net/net_util_md.c --- 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) { diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/solaris/native/sun/nio/fs/genUnixConstants.c --- 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", diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/windows/classes/sun/security/mscapi/Key.java --- 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; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/windows/classes/sun/security/mscapi/RSACipher.java --- 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(); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/src/windows/classes/sun/security/mscapi/RSASignature.java --- 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); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/Makefile --- 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) diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/ProblemList.txt --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/com/oracle/security/ucrypto/TestAES.java --- /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; + } +} diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/com/oracle/security/ucrypto/TestDigest.java --- /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"); + } + } +} diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/com/oracle/security/ucrypto/TestRSA.java --- /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"); + } +} diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/com/oracle/security/ucrypto/UcryptoTest.java --- /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); + } +} diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/java/io/File/BlockIsDirectory.java --- 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."); - } - } - } -} diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/java/io/FileInputStream/LargeFileAvailable.java --- 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; } } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/java/lang/invoke/CallSiteTest.java --- 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; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/java/lang/invoke/ClassValueTest.java --- 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)); } } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/java/lang/invoke/InvokeGenericTest.java --- 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 calledLog = new ArrayList(); + static List 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[] array(Class atype, E... a) { return Arrays.copyOf(a, a.length, atype); } + @SafeVarargs @SuppressWarnings("varargs") static 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> argTypes = new ArrayList>(targetType.parameterList()); + ArrayList> 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>, MethodHandle> CALLABLES = new HashMap>, MethodHandle>(); + Map>, MethodHandle> CALLABLES = new HashMap<>(); MethodHandle callable(List> 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 allMethodTypes(int minargc, int maxargc, Class... types) { - ArrayList result = new ArrayList(); + ArrayList result = new ArrayList<>(); if (types.length > 0) { - ArrayList argcTypes = new ArrayList(); + ArrayList 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 prevTypes = argcTypes; - argcTypes = new ArrayList(); + 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); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/java/lang/invoke/JavaDocExamplesTest.java --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/java/lang/invoke/MethodHandlesTest.java --- 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 calledLog = new ArrayList(); + static List 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[] array(Class atype, E... a) { return Arrays.copyOf(a, a.length, atype); } + @SafeVarargs @SuppressWarnings("varargs") static 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> argTypes = new ArrayList>(targetType.parameterList()); + ArrayList> 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 ", 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("", this, x); } public SubExample() { super("SubExample#"+nextArg()); } } @@ -912,7 +916,7 @@ static final Object[][] CASES; static { - ArrayList cases = new ArrayList(); + ArrayList 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 array2list(Object array) { int length = Array.getLength(array); - ArrayList model = new ArrayList(length); + ArrayList 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> newParams = new ArrayList>(target2.type().parameterList()); + List> newParams = new ArrayList<>(target2.type().parameterList()); { // modify newParams in place List> 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 resList = Arrays.asList(args); - List argsToPass = new ArrayList(resList); + List argsToPass = new ArrayList<>(resList); List 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 expected = new ArrayList(argsToPass); + List expected = new ArrayList<>(argsToPass); List 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 resList = Arrays.asList(args); - List argsToDrop = new ArrayList(resList); + List 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 done = new HashSet(); + Set 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 targetPlusArgs = new ArrayList(Arrays.asList(args)); + List 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 targetPlusVarArgs = new ArrayList(targetPlusArgs); + List targetPlusVarArgs = new ArrayList<>(targetPlusArgs); List 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 catchArgs = new ArrayList(Arrays.asList(args)); + List 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 appendResults = new ArrayList(); + ArrayList> 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 arrays = new ArrayList(); + ArrayList 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 lists = new ArrayList(); + ArrayList 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/java/lang/invoke/MethodTypeTest.java --- 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> types = new ArrayList>(); + ArrayList> 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); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/java/lang/invoke/PermuteArgsTest.java --- 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 res = new ArrayList(); + ArrayList 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 res = new ArrayList(); + ArrayList 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 done = new HashSet(); + HashSet 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; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/java/lang/invoke/RicochetTest.java --- 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); } } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/java/lang/invoke/ThrowExceptionsTest.java --- 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++; } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/java/net/HttpURLConnection/UnmodifiableMaps.java --- /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> map) { + checkUnmodifiableMap(map); + + // Now check the individual values + Collection> values = map.values(); + for (List value : values) { + checkUnmodifiableList(value); + } + } + + void checkUnmodifiableMap(final Map> map) { + expectThrow( new Runnable() { + public void run() { map.clear(); }}); + expectThrow( new Runnable() { + public void run() { map.put("X", new ArrayList()); }}); + expectThrow( new Runnable() { + public void run() { map.remove("X"); }}); + } + + void checkUnmodifiableList(final List 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");} +} + diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/java/security/Provider/DefaultPKCS11.java --- 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"); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/javax/crypto/Cipher/GetMaxAllowed.java --- 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 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(); } } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/javax/security/auth/x500/X500Principal/NameFormat.java --- /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) + "'"); + } + } + } +} diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/sun/invoke/util/ValueConversionsTest.java --- 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); diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/sun/net/www/http/HttpClient/CookieHttpClientTest.java --- /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(); + } +} diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/sun/security/krb5/auto/Context.java --- 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); } } } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/sun/security/krb5/auto/ReplayCache.java --- /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; + } + } + } +} diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/sun/security/mscapi/ShortRSAKey1024.sh --- /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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/sun/security/mscapi/ShortRSAKey512.sh --- /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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/sun/security/mscapi/ShortRSAKey768.sh --- /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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/sun/security/mscapi/ShortRSAKeyWithinTLS.java --- /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; + } + } + } +} + diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/sun/security/pkcs11/KeyStore/ClientAuth.java --- 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()); } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/sun/security/pkcs11/KeyStore/ClientAuth.sh --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/sun/security/pkcs11/MessageDigest/TestCloning.java --- /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!"); + } + } +} + diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/sun/security/ssl/javax/net/ssl/SSLContextVersion.java --- 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"); } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/sun/security/ssl/javax/net/ssl/TLSv12/ShortRSAKey512.java --- /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; + } + } + } +} diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/CookieHttpsClientTest.java --- /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(); + } + } +} diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/tools/launcher/I18NJarTest.java --- /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 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"); + } + } +} diff -r 98dad53a8ba1 -r 46e4f3b9cbfa jdk/test/tools/launcher/TestHelper.java --- 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. diff -r 98dad53a8ba1 -r 46e4f3b9cbfa langtools/.hgtags --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa langtools/src/share/classes/com/sun/tools/javac/code/Types.java --- 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) { diff -r 98dad53a8ba1 -r 46e4f3b9cbfa langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java --- 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 instaniateAsUninferredVars(List undetvars, List tvars) { + private List instantiateAsUninferredVars(List undetvars, List tvars) { + Assert.check(undetvars.length() == tvars.length()); ListBuffer 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 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(); } diff -r 98dad53a8ba1 -r 46e4f3b9cbfa langtools/src/share/classes/javax/lang/model/element/Element.java --- 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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa langtools/src/share/classes/javax/lang/model/element/PackageElement.java --- 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 not considered to be enclosed by a + * package. + * + * @return the top-level classes and interfaces within this + * package + */ + @Override + List getEnclosedElements(); + + /** * Returns {@code true} is this is an unnamed package and {@code * false} otherwise. * diff -r 98dad53a8ba1 -r 46e4f3b9cbfa langtools/src/share/classes/javax/lang/model/element/TypeElement.java --- 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. * *

    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 getEnclosedElements(); /** diff -r 98dad53a8ba1 -r 46e4f3b9cbfa langtools/test/tools/javac/cast/7123100/T7123100a.java --- /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 m() { + return null; + } + + void test() { + Z z = (Z)m(); + } +} diff -r 98dad53a8ba1 -r 46e4f3b9cbfa langtools/test/tools/javac/cast/7123100/T7123100a.out --- /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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa langtools/test/tools/javac/cast/7123100/T7123100b.java --- /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 { + void test(Enum e) { + Z z = (Z)e; + } +} diff -r 98dad53a8ba1 -r 46e4f3b9cbfa langtools/test/tools/javac/cast/7123100/T7123100b.out --- /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, Z +- compiler.err.warnings.and.werror +1 error +1 warning diff -r 98dad53a8ba1 -r 46e4f3b9cbfa langtools/test/tools/javac/cast/7123100/T7123100c.java --- /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 m(E e) { + return null; + } + + void test(Enum e) { + Z z = (Z)m(e); + } +} diff -r 98dad53a8ba1 -r 46e4f3b9cbfa langtools/test/tools/javac/cast/7123100/T7123100c.out --- /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, Z +- compiler.err.warnings.and.werror +1 error +1 warning diff -r 98dad53a8ba1 -r 46e4f3b9cbfa langtools/test/tools/javac/cast/7123100/T7123100d.java --- /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 m(Enum e) { + return null; + } + + void test(Enum e) { + Z z = (Z)m(e); + } +} diff -r 98dad53a8ba1 -r 46e4f3b9cbfa langtools/test/tools/javac/cast/7123100/T7123100d.out --- /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 diff -r 98dad53a8ba1 -r 46e4f3b9cbfa langtools/test/tools/javac/cast/7126754/T7126754.java --- /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 to List + * @compile/fail/ref=T7126754.out -Xlint:unchecked -Werror -XDrawDiagnostics T7126754.java + */ + +import java.util.List; + +class T7126754 { + List> c = null; + List> d = (List>)c; +} diff -r 98dad53a8ba1 -r 46e4f3b9cbfa langtools/test/tools/javac/cast/7126754/T7126754.out --- /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>, java.util.List> +- compiler.err.warnings.and.werror +1 error +1 warning diff -r 98dad53a8ba1 -r 46e4f3b9cbfa langtools/test/tools/javac/diags/CheckExamples.java --- 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.*; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa langtools/test/tools/javac/diags/MessageInfo.java --- 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.*; diff -r 98dad53a8ba1 -r 46e4f3b9cbfa langtools/test/tools/javac/diags/RunExamples.java --- 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.*;