# HG changeset patch # User lana # Date 1328858242 28800 # Node ID 5561a4c99825bcda174ff3e32c1f8a3983c4ec05 # Parent fc06525cb3458f9c40a153017ec721979cf15eab# Parent 6c805d8ed4e5449ea5e4d158c7bdbd7b0b70efd1 Merge diff -r fc06525cb345 -r 5561a4c99825 .hgtags --- a/.hgtags Thu Feb 09 18:26:57 2012 +0400 +++ b/.hgtags Thu Feb 09 23:17:22 2012 -0800 @@ -145,3 +145,5 @@ b3a426170188f52981cf4573a2f14d487fddab0d jdk8-b21 e8f03541af27e38aafb619b96863e17f65ffe53b jdk8-b22 498124337041ad53cbaa7eb110f3d7acd6d4eac4 jdk8-b23 +7d3720d8c595d1519c31e9ff7366203fc2c61350 jdk8-b24 +0071a6d64113a35ba345bb1580c256de5ce17d3e jdk8-b25 diff -r fc06525cb345 -r 5561a4c99825 .hgtags-top-repo --- a/.hgtags-top-repo Thu Feb 09 18:26:57 2012 +0400 +++ b/.hgtags-top-repo Thu Feb 09 23:17:22 2012 -0800 @@ -145,3 +145,5 @@ cc771d92284f71765eca14d6d08703c4af254c04 jdk8-b21 7ad075c809952e355d25030605da6af30456ed74 jdk8-b22 60d6f64a86b1e511169d264727f6d51415978df0 jdk8-b23 +1a5f1d6b98d6827cdb529a4abe6e52a886d944f4 jdk8-b24 +221a378e06a326f45e5d89e2123cd6323e0181d1 jdk8-b25 diff -r fc06525cb345 -r 5561a4c99825 corba/.hgtags --- a/corba/.hgtags Thu Feb 09 18:26:57 2012 +0400 +++ b/corba/.hgtags Thu Feb 09 23:17:22 2012 -0800 @@ -145,3 +145,5 @@ f157fc2a71a38ce44007a6f18d5b011824dce705 jdk8-b21 a11d0062c445d5f36651c78650ab88aa594bcbff jdk8-b22 5218eb256658442b62b05295aafa5b5f35252972 jdk8-b23 +b98f0e6dddf987df565029a1f58417fc1844c3f3 jdk8-b24 +e45d6b406d5f91ff5256a5c82456ab1e7eb8becd jdk8-b25 diff -r fc06525cb345 -r 5561a4c99825 hotspot/.hgtags --- a/hotspot/.hgtags Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/.hgtags Thu Feb 09 23:17:22 2012 -0800 @@ -215,3 +215,8 @@ dcc292399a39113957eebbd3e487b7e05e2c79fc hs23-b11 e850d8e7ea54b91c7aa656e297f0f9f38dd4c296 jdk8-b23 9e177d44b10fe92ecffa965fef9c5ac5433c1b46 hs23-b12 +a80fd4f45d7aaa154ed2f86a129f3c9c4035ec7a jdk8-b24 +b22de824749922986ce4d442bed029916b832807 hs23-b13 +64b46f975ab82948c1e021e17775ff4fab8bc40e hs23-b14 +9ad8feb5afbddec46d3cfe29fb5f73c2e99d5a43 jdk8-b25 +d71e662fe03741b6de498ca2077220148405a978 hs23-b15 diff -r fc06525cb345 -r 5561a4c99825 hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/LoaderConstraintTable.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/LoaderConstraintTable.java Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/LoaderConstraintTable.java Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 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 @@ -42,15 +42,6 @@ private static synchronized void initialize(TypeDataBase db) { Type type = db.lookupType("LoaderConstraintTable"); - nofBuckets = db.lookupIntConstant("LoaderConstraintTable::_nof_buckets").intValue(); - } - - // Fields - private static int nofBuckets; - - // Accessors - public static int getNumOfBuckets() { - return nofBuckets; } public LoaderConstraintTable(Address addr) { diff -r fc06525cb345 -r 5561a4c99825 hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/SystemDictionary.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/SystemDictionary.java Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/SystemDictionary.java Thu Feb 09 23:17:22 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 @@ -36,7 +36,6 @@ private static AddressField placeholdersField; private static AddressField loaderConstraintTableField; private static sun.jvm.hotspot.types.OopField javaSystemLoaderField; - private static int nofBuckets; private static sun.jvm.hotspot.types.OopField objectKlassField; private static sun.jvm.hotspot.types.OopField classLoaderKlassField; @@ -62,7 +61,6 @@ placeholdersField = type.getAddressField("_placeholders"); loaderConstraintTableField = type.getAddressField("_loader_constraints"); javaSystemLoaderField = type.getOopField("_java_system_loader"); - nofBuckets = db.lookupIntConstant("SystemDictionary::_nof_buckets").intValue(); objectKlassField = type.getOopField(WK_KLASS("Object_klass")); classLoaderKlassField = type.getOopField(WK_KLASS("ClassLoader_klass")); @@ -142,10 +140,6 @@ return newOop(javaSystemLoaderField.getValue()); } - public static int getNumOfBuckets() { - return nofBuckets; - } - private static Oop newOop(OopHandle handle) { return VM.getVM().getObjectHeap().newOop(handle); } diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/Makefile --- a/hotspot/make/Makefile Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/Makefile Thu Feb 09 23:17:22 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 @@ -89,19 +89,31 @@ ZERO_VM_TARGETS=productzero fastdebugzero optimizedzero jvmgzero SHARK_VM_TARGETS=productshark fastdebugshark optimizedshark jvmgshark +COMMON_VM_PRODUCT_TARGETS=product product1 productkernel docs export_product +COMMON_VM_FASTDEBUG_TARGETS=fastdebug fastdebug1 fastdebugkernel docs export_fastdebug +COMMON_VM_DEBUG_TARGETS=jvmg jvmg1 jvmgkernel docs export_debug + # JDK directory list JDK_DIRS=bin include jre lib demo all: all_product all_fastdebug -ifndef BUILD_CLIENT_ONLY -all_product: product product1 productkernel docs export_product -all_fastdebug: fastdebug fastdebug1 fastdebugkernel docs export_fastdebug -all_debug: jvmg jvmg1 jvmgkernel docs export_debug -else + +ifdef BUILD_CLIENT_ONLY all_product: product1 docs export_product all_fastdebug: fastdebug1 docs export_fastdebug all_debug: jvmg1 docs export_debug +else +ifeq ($(MACOSX_UNIVERSAL),true) +all_product: universal_product +all_fastdebug: universal_fastdebug +all_debug: universal_debug +else +all_product: $(COMMON_VM_PRODUCT_TARGETS) +all_fastdebug: $(COMMON_VM_FASTDEBUG_TARGETS) +all_debug: $(COMMON_VM_DEBUG_TARGETS) endif +endif + all_optimized: optimized optimized1 optimizedkernel docs export_optimized allzero: all_productzero all_fastdebugzero @@ -232,20 +244,19 @@ $(MAKE) VM_SUBDIR=${VM_DEBUG} EXPORT_SUBDIR=/debug generic_export export_optimized: $(MAKE) VM_SUBDIR=optimized EXPORT_SUBDIR=/optimized generic_export -export_product_jdk: +export_product_jdk:: $(MAKE) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR) \ VM_SUBDIR=product generic_export -export_optimized_jdk: +export_optimized_jdk:: $(MAKE) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR) \ VM_SUBDIR=optimized generic_export -export_fastdebug_jdk: +export_fastdebug_jdk:: $(MAKE) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR)/fastdebug \ VM_SUBDIR=fastdebug generic_export -export_debug_jdk: +export_debug_jdk:: $(MAKE) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR)/debug \ VM_SUBDIR=${VM_DEBUG} generic_export - # Export file copy rules XUSAGE=$(HS_SRC_DIR)/share/vm/Xusage.txt DOCS_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_docs @@ -444,14 +455,14 @@ endif $(JDK_IMAGE_DIR)/bin/java -server -version -copy_product_jdk: +copy_product_jdk:: $(RM) -r $(JDK_IMAGE_DIR) $(MKDIR) -p $(JDK_IMAGE_DIR) ($(CD) $(JDK_IMPORT_PATH) && \ $(TAR) -cf - $(JDK_DIRS)) | \ ($(CD) $(JDK_IMAGE_DIR) && $(TAR) -xf -) -copy_fastdebug_jdk: +copy_fastdebug_jdk:: $(RM) -r $(JDK_IMAGE_DIR)/fastdebug $(MKDIR) -p $(JDK_IMAGE_DIR)/fastdebug if [ -d $(JDK_IMPORT_PATH)/fastdebug ] ; then \ @@ -464,7 +475,7 @@ ($(CD) $(JDK_IMAGE_DIR)/fastdebug && $(TAR) -xf -) ; \ fi -copy_debug_jdk: +copy_debug_jdk:: $(RM) -r $(JDK_IMAGE_DIR)/debug $(MKDIR) -p $(JDK_IMAGE_DIR)/debug if [ -d $(JDK_IMPORT_PATH)/debug ] ; then \ @@ -481,36 +492,6 @@ ($(CD) $(JDK_IMAGE_DIR)/debug && $(TAR) -xf -) ; \ fi -# macosx universal builds - -ifeq ($(MACOSX_UNIVERSAL), true) -$(UNIVERSAL_LIPO_LIST): - lipo -create -output $@ $(EXPORT_JRE_LIB_DIR)/{i386,amd64}/$(subst $(EXPORT_JRE_LIB_DIR)/,,$@) - -$(UNIVERSAL_COPY_LIST): - $(CP) $(EXPORT_JRE_LIB_DIR)/i386/$(subst $(EXPORT_JRE_LIB_DIR)/,,$@) $@ - -universalize: $(UNIVERSAL_LIPO_LIST) $(UNIVERSAL_COPY_LIST) -endif - -universal_product: - $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=32 MACOSX_UNIVERSAL=true all_product - $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=64 MACOSX_UNIVERSAL=true all_product - $(MKDIR) -p $(EXPORT_JRE_LIB_DIR)/{client,server} - $(QUIETLY) $(MAKE) MACOSX_UNIVERSAL=true universalize - -universal_fastdebug: - $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=32 MACOSX_UNIVERSAL=true all_fastdebug - $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=64 MACOSX_UNIVERSAL=true all_fastdebug - $(MKDIR) -p $(EXPORT_JRE_LIB_DIR)/{client,server} - $(QUIETLY) $(MAKE) MACOSX_UNIVERSAL=true universalize - -universal_debug: - $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=32 MACOSX_UNIVERSAL=true all_debug - $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=64 MACOSX_UNIVERSAL=true all_debug - $(MKDIR) -p $(EXPORT_JRE_LIB_DIR)/{client,server} - $(QUIETLY) $(MAKE) MACOSX_UNIVERSAL=true universalize - # # Check target # @@ -630,6 +611,13 @@ @$(ECHO) \ " $(MAKE) ALT_JDK_IMPORT_PATH=/opt/java/jdk$(JDK_VERSION)" +# Universal build support +ifeq ($(OS_VENDOR), Darwin) +ifeq ($(MACOSX_UNIVERSAL),true) +include $(GAMMADIR)/make/$(OSNAME)/makefiles/universal.gmk +endif +endif + # JPRT rule to build this workspace include $(GAMMADIR)/make/jprt.gmk @@ -639,6 +627,4 @@ export_product export_fastdebug export_debug export_optimized \ export_jdk_product export_jdk_fastdebug export_jdk_debug \ create_jdk copy_jdk update_jdk test_jdk \ - copy_product_jdk copy_fastdebug_jdk copy_debug_jdk universalize \ - universal_product - + copy_product_jdk copy_fastdebug_jdk copy_debug_jdk diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/bsd/makefiles/adlc.make --- a/hotspot/make/bsd/makefiles/adlc.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/bsd/makefiles/adlc.make Thu Feb 09 23:17:22 2012 -0800 @@ -61,10 +61,10 @@ INCLUDES += $(Src_Dirs_I:%=-I%) # set flags for adlc compilation -CPPFLAGS = $(SYSDEFS) $(INCLUDES) +CXXFLAGS = $(SYSDEFS) $(INCLUDES) # Force assertions on. -CPPFLAGS += -DASSERT +CXXFLAGS += -DASSERT # CFLAGS_WARN holds compiler options to suppress/enable warnings. # Compiler warnings are treated as errors @@ -111,7 +111,7 @@ $(EXEC) : $(OBJECTS) @echo Making adlc - $(QUIETLY) $(HOST.LINK_NOPROF.CC) -o $(EXEC) $(OBJECTS) + $(QUIETLY) $(HOST.LINK_NOPROF.CXX) -o $(EXEC) $(OBJECTS) # Random dependencies: $(OBJECTS): opcodes.hpp classes.hpp adlc.hpp adlcVMDeps.hpp adlparse.hpp archDesc.hpp arena.hpp dict2.hpp filebuff.hpp forms.hpp formsopt.hpp formssel.hpp @@ -213,14 +213,14 @@ $(OUTDIR)/%.o: %.cpp @echo Compiling $< $(QUIETLY) $(REMOVE_TARGET) - $(QUIETLY) $(HOST.COMPILE.CC) -o $@ $< $(COMPILE_DONE) + $(QUIETLY) $(HOST.COMPILE.CXX) -o $@ $< $(COMPILE_DONE) # Some object files are given a prefix, to disambiguate # them from objects of the same name built for the VM. $(OUTDIR)/adlc-%.o: %.cpp @echo Compiling $< $(QUIETLY) $(REMOVE_TARGET) - $(QUIETLY) $(HOST.COMPILE.CC) -o $@ $< $(COMPILE_DONE) + $(QUIETLY) $(HOST.COMPILE.CXX) -o $@ $< $(COMPILE_DONE) # ######################################################################### diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/bsd/makefiles/defs.make --- a/hotspot/make/bsd/makefiles/defs.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/bsd/makefiles/defs.make Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ # -# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 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 @@ -171,10 +171,36 @@ EXPORT_LIST += $(ADD_SA_BINARIES/$(HS_ARCH)) -UNIVERSAL_LIPO_LIST += $(EXPORT_JRE_LIB_DIR)/libjsig.$(LIBRARY_SUFFIX) -UNIVERSAL_LIPO_LIST += $(EXPORT_JRE_LIB_DIR)/libsaproc.$(LIBRARY_SUFFIX) -UNIVERSAL_LIPO_LIST += $(EXPORT_JRE_LIB_DIR)/server/libjvm.$(LIBRARY_SUFFIX) +# Universal build settings +ifeq ($(OS_VENDOR), Darwin) + # Build universal binaries by default on Mac OS X + MACOSX_UNIVERSAL = true + ifneq ($(ALT_MACOSX_UNIVERSAL),) + MACOSX_UNIVERSAL = $(ALT_MACOSX_UNIVERSAL) + endif + MAKE_ARGS += MACOSX_UNIVERSAL=$(MACOSX_UNIVERSAL) + + # Universal settings + ifeq ($(MACOSX_UNIVERSAL), true) -UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/server/Xusage.txt -UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/client/Xusage.txt -UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/client/libjvm.$(LIBRARY_SUFFIX) + # Set universal export path but avoid using ARCH or PLATFORM subdirs + EXPORT_PATH=$(OUTPUTDIR)/export-universal$(EXPORT_SUBDIR) + ifneq ($(ALT_EXPORT_PATH),) + EXPORT_PATH=$(ALT_EXPORT_PATH) + endif + + # Set universal image dir + JDK_IMAGE_DIR=$(OUTPUTDIR)/jdk-universal$(EXPORT_SUBDIR) + + # Binaries to 'universalize' if built + UNIVERSAL_LIPO_LIST += $(EXPORT_JRE_LIB_DIR)/libjsig.$(LIBRARY_SUFFIX) + UNIVERSAL_LIPO_LIST += $(EXPORT_JRE_LIB_DIR)/libsaproc.$(LIBRARY_SUFFIX) + UNIVERSAL_LIPO_LIST += $(EXPORT_JRE_LIB_DIR)/server/libjvm.$(LIBRARY_SUFFIX) + UNIVERSAL_LIPO_LIST += $(EXPORT_JRE_LIB_DIR)/client/libjvm.$(LIBRARY_SUFFIX) + + # Files to simply copy in place + UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/server/Xusage.txt + UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/client/Xusage.txt + + endif +endif diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/bsd/makefiles/dtrace.make --- a/hotspot/make/bsd/makefiles/dtrace.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/bsd/makefiles/dtrace.make Thu Feb 09 23:17:22 2012 -0800 @@ -105,11 +105,11 @@ lib$(GENOFFS).dylib: $(DTRACE_SRCDIR)/$(GENOFFS).cpp $(DTRACE_SRCDIR)/$(GENOFFS).h \ $(LIBJVM.o) - $(QUIETLY) $(CCC) $(CPPFLAGS) $(GENOFFS_CFLAGS) $(SHARED_FLAG) $(PICFLAG) \ + $(QUIETLY) $(CXX) $(CXXFLAGS) $(GENOFFS_CFLAGS) $(SHARED_FLAG) $(PICFLAG) \ $(LFLAGS_GENOFFS) -o $@ $(DTRACE_SRCDIR)/$(GENOFFS).cpp -ljvm $(GENOFFS): $(DTRACE_SRCDIR)/$(GENOFFS)Main.c lib$(GENOFFS).dylib - $(QUIETLY) $(LINK.CC) -o $@ $(DTRACE_SRCDIR)/$(GENOFFS)Main.c \ + $(QUIETLY) $(LINK.CXX) -o $@ $(DTRACE_SRCDIR)/$(GENOFFS)Main.c \ ./lib$(GENOFFS).dylib # $@.tmp is created first to avoid an empty $(JVMOFFS).h if an error occurs. @@ -135,7 +135,7 @@ fi $(JVMOFFS.o): $(JVMOFFS).h $(JVMOFFS).cpp - $(QUIETLY) $(CCC) -c -I. -o $@ $(ARCHFLAG) -D$(TYPE) $(JVMOFFS).cpp + $(QUIETLY) $(CXX) -c -I. -o $@ $(ARCHFLAG) -D$(TYPE) $(JVMOFFS).cpp $(LIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS.o) $(XLIBJVM_DB) $(LIBJVM_DB_MAPFILE) @echo Making $@ diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/bsd/makefiles/gcc.make --- a/hotspot/make/bsd/makefiles/gcc.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/bsd/makefiles/gcc.make Thu Feb 09 23:17:22 2012 -0800 @@ -25,20 +25,19 @@ OS_VENDOR = $(shell uname -s) #------------------------------------------------------------------------ -# CC, CPP & AS +# CC, CXX & AS # When cross-compiling the ALT_COMPILER_PATH points # to the cross-compilation toolset ifdef CROSS_COMPILE_ARCH - CPP = $(ALT_COMPILER_PATH)/g++ + CXX = $(ALT_COMPILER_PATH)/g++ CC = $(ALT_COMPILER_PATH)/gcc - HOSTCPP = g++ + HOSTCXX = g++ HOSTCC = gcc else ifneq ($(OS_VENDOR), Darwin) CXX = g++ - CPP = $(CXX) CC = gcc - HOSTCPP = $(CPP) + HOSTCXX = $(CXX) HOSTCC = $(CC) endif @@ -53,7 +52,6 @@ ifeq ($(origin CC), default) CC = llvm-gcc endif - CPP = $(CXX) ifeq ($(ARCH), i486) LLVM_SUPPORTS_STACKREALIGN := $(shell \ @@ -67,11 +65,11 @@ CXX32 ?= g++-4.0 CC32 ?= gcc-4.0 endif - CPP = $(CXX32) + CXX = $(CXX32) CC = $(CC32) endif - HOSTCPP = $(CPP) + HOSTCXX = $(CXX) HOSTCC = $(CC) endif diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/bsd/makefiles/launcher.make --- a/hotspot/make/bsd/makefiles/launcher.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/bsd/makefiles/launcher.make Thu Feb 09 23:17:22 2012 -0800 @@ -71,10 +71,10 @@ LIBS_LAUNCHER += -l$(JVM) $(LIBS) endif -LINK_LAUNCHER = $(LINK.c) +LINK_LAUNCHER = $(LINK.CC) -LINK_LAUNCHER/PRE_HOOK = $(LINK_LIB.CC/PRE_HOOK) -LINK_LAUNCHER/POST_HOOK = $(LINK_LIB.CC/POST_HOOK) +LINK_LAUNCHER/PRE_HOOK = $(LINK_LIB.CXX/PRE_HOOK) +LINK_LAUNCHER/POST_HOOK = $(LINK_LIB.CXX/POST_HOOK) LAUNCHER_OUT = launcher @@ -90,11 +90,11 @@ $(LAUNCHER_OUT)/%.o: $(LAUNCHERDIR_SHARE)/%.c $(QUIETLY) [ -d $(LAUNCHER_OUT) ] || { mkdir -p $(LAUNCHER_OUT); } - $(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CPPFLAGS) + $(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CXXFLAGS) $(LAUNCHER_OUT)/%.o: $(LAUNCHERDIR)/%.c $(QUIETLY) [ -d $(LAUNCHER_OUT) ] || { mkdir -p $(LAUNCHER_OUT); } - $(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CPPFLAGS) + $(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CXXFLAGS) $(LAUNCHER): $(OBJS) $(LIBJVM) $(LAUNCHER_MAPFILE) $(QUIETLY) echo Linking launcher... diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/bsd/makefiles/product.make --- a/hotspot/make/bsd/makefiles/product.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/bsd/makefiles/product.make Thu Feb 09 23:17:22 2012 -0800 @@ -55,4 +55,4 @@ STRIP_AOUT = $(STRIP) -x $@ || exit 1; # Don't strip in VM build; JDK build will strip libraries later -# LINK_LIB.CC/POST_HOOK += $(STRIP_$(LINK_INTO)) +# LINK_LIB.CXX/POST_HOOK += $(STRIP_$(LINK_INTO)) diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/bsd/makefiles/rules.make --- a/hotspot/make/bsd/makefiles/rules.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/bsd/makefiles/rules.make Thu Feb 09 23:17:22 2012 -0800 @@ -27,52 +27,39 @@ # Tell make that .cpp is important .SUFFIXES: .cpp $(SUFFIXES) -# For now. Other makefiles use CPP as the c++ compiler, but that should really -# name the preprocessor. -ifeq ($(CCC),) -CCC = $(CPP) -endif - DEMANGLER = c++filt DEMANGLE = $(DEMANGLER) < $@ > .$@ && mv -f .$@ $@ -# $(CC) is the c compiler (cc/gcc), $(CCC) is the c++ compiler (CC/g++). -C_COMPILE = $(CC) $(CPPFLAGS) $(CFLAGS) -CC_COMPILE = $(CCC) $(CPPFLAGS) $(CFLAGS) +# $(CC) is the c compiler (cc/gcc), $(CXX) is the c++ compiler (CC/g++). +CC_COMPILE = $(CC) $(CXXFLAGS) $(CFLAGS) +CXX_COMPILE = $(CXX) $(CXXFLAGS) $(CFLAGS) AS.S = $(AS) $(ASFLAGS) -COMPILE.c = $(C_COMPILE) -c -GENASM.c = $(C_COMPILE) -S -LINK.c = $(CC) $(LFLAGS) $(AOUT_FLAGS) $(PROF_AOUT_FLAGS) -LINK_LIB.c = $(CC) $(LFLAGS) $(SHARED_FLAG) -PREPROCESS.c = $(C_COMPILE) -E +COMPILE.CC = $(CC_COMPILE) -c +GENASM.CC = $(CC_COMPILE) -S +LINK.CC = $(CC) $(LFLAGS) $(AOUT_FLAGS) $(PROF_AOUT_FLAGS) +LINK_LIB.CC = $(CC) $(LFLAGS) $(SHARED_FLAG) +PREPROCESS.CC = $(CC_COMPILE) -E -COMPILE.CC = $(CC_COMPILE) -c -GENASM.CC = $(CC_COMPILE) -S -LINK.CC = $(CCC) $(LFLAGS) $(AOUT_FLAGS) $(PROF_AOUT_FLAGS) -LINK_NOPROF.CC = $(CCC) $(LFLAGS) $(AOUT_FLAGS) -LINK_LIB.CC = $(CCC) $(LFLAGS) $(SHARED_FLAG) -PREPROCESS.CC = $(CC_COMPILE) -E +COMPILE.CXX = $(CXX_COMPILE) -c +GENASM.CXX = $(CXX_COMPILE) -S +LINK.CXX = $(CXX) $(LFLAGS) $(AOUT_FLAGS) $(PROF_AOUT_FLAGS) +LINK_NOPROF.CXX = $(CXX) $(LFLAGS) $(AOUT_FLAGS) +LINK_LIB.CXX = $(CXX) $(LFLAGS) $(SHARED_FLAG) +PREPROCESS.CXX = $(CXX_COMPILE) -E # cross compiling the jvm with c2 requires host compilers to build # adlc tool -HOST.CC_COMPILE = $(HOSTCPP) $(CPPFLAGS) $(CFLAGS) -HOST.COMPILE.CC = $(HOST.CC_COMPILE) -c -HOST.LINK_NOPROF.CC = $(HOSTCPP) $(LFLAGS) $(AOUT_FLAGS) +HOST.CXX_COMPILE = $(HOSTCXX) $(CXXFLAGS) $(CFLAGS) +HOST.COMPILE.CXX = $(HOST.CXX_COMPILE) -c +HOST.LINK_NOPROF.CXX = $(HOSTCXX) $(LFLAGS) $(AOUT_FLAGS) # Effect of REMOVE_TARGET is to delete out-of-date files during "gnumake -k". REMOVE_TARGET = rm -f $@ -# Synonyms. -COMPILE.cpp = $(COMPILE.CC) -GENASM.cpp = $(GENASM.CC) -LINK.cpp = $(LINK.CC) -LINK_LIB.cpp = $(LINK_LIB.CC) -PREPROCESS.cpp = $(PREPROCESS.CC) - # Note use of ALT_BOOTDIR to explicitly specify location of java and # javac; this is the same environment variable used in the J2SE build # process for overriding the default spec, which is BOOTDIR. @@ -161,14 +148,14 @@ %.o: %.cpp @echo Compiling $< $(QUIETLY) $(REMOVE_TARGET) - $(QUIETLY) $(COMPILE.CC) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE) + $(QUIETLY) $(COMPILE.CXX) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE) else %.o: %.cpp @echo Compiling $< $(QUIETLY) $(REMOVE_TARGET) $(QUIETLY) $(if $(findstring $@, $(NONPIC_OBJ_FILES)), \ - $(subst $(VM_PICFLAG), ,$(COMPILE.CC)) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE), \ - $(COMPILE.CC) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE)) + $(subst $(VM_PICFLAG), ,$(COMPILE.CXX)) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE), \ + $(COMPILE.CXX) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE)) endif %.o: %.s @@ -178,13 +165,13 @@ %.s: %.cpp @echo Generating assembly for $< - $(QUIETLY) $(GENASM.CC) -o $@ $< + $(QUIETLY) $(GENASM.CXX) -o $@ $< $(QUIETLY) $(DEMANGLE) $(COMPILE_DONE) # Intermediate files (for debugging macros) %.i: %.cpp @echo Preprocessing $< to $@ - $(QUIETLY) $(PREPROCESS.CC) $< > $@ $(COMPILE_DONE) + $(QUIETLY) $(PREPROCESS.CXX) $< > $@ $(COMPILE_DONE) # Override gnumake built-in rules which do sccs get operations badly. # (They put the checked out code in the current directory, not in the diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/bsd/makefiles/sparcWorks.make --- a/hotspot/make/bsd/makefiles/sparcWorks.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/bsd/makefiles/sparcWorks.make Thu Feb 09 23:17:22 2012 -0800 @@ -23,13 +23,13 @@ # #------------------------------------------------------------------------ -# CC, CPP & AS +# CC, CXX & AS -CPP = CC +CXX = CC CC = cc AS = $(CC) -c -HOSTCPP = $(CPP) +HOSTCXX = $(CXX) HOSTCC = $(CC) ARCHFLAG = $(ARCHFLAG/$(BUILDARCH)) diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/bsd/makefiles/universal.gmk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/make/bsd/makefiles/universal.gmk Thu Feb 09 23:17:22 2012 -0800 @@ -0,0 +1,113 @@ +# +# Copyright (c) 2006, 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. +# +# + +# macosx universal builds +universal_product: + $(MAKE) MACOSX_UNIVERSAL=true all_product_universal +universal_fastdebug: + $(MAKE) MACOSX_UNIVERSAL=true all_fastdebug_universal +universal_debug: + $(MAKE) MACOSX_UNIVERSAL=true all_debug_universal + + +# Universal builds include 1 or more architectures in a single binary +all_product_universal: +# $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=32 $(COMMON_VM_PRODUCT_TARGETS) + $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=64 $(COMMON_VM_PRODUCT_TARGETS) + $(QUIETLY) $(MAKE) EXPORT_SUBDIR= universalize +all_fastdebug_universal: +# $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=32 $(COMMON_VM_FASTDEBUG_TARGETS) + $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=64 $(COMMON_VM_FASTDEBUG_TARGETS) + $(QUIETLY) $(MAKE) EXPORT_SUBDIR=/fastdebug universalize +all_debug_universal: +# $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=32 $(COMMON_VM_DEBUG_TARGETS) + $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=64 $(COMMON_VM_DEBUG_TARGETS) + $(QUIETLY) $(MAKE) EXPORT_SUBDIR=/debug universalize + + +# Consolidate architecture builds into a single Universal binary +universalize: $(UNIVERSAL_LIPO_LIST) $(UNIVERSAL_COPY_LIST) + $(RM) -r $(EXPORT_PATH)/jre/lib/{i386,amd64} + + +# Package built libraries in a universal binary +$(UNIVERSAL_LIPO_LIST): + BUILT_LIPO_FILES="`find $(EXPORT_JRE_LIB_DIR)/{i386,amd64}/$(subst $(EXPORT_JRE_LIB_DIR)/,,$@) 2>/dev/null`"; \ + if [ -n "$${BUILT_LIPO_FILES}" ]; then \ + $(MKDIR) -p $(shell dirname $@); \ + lipo -create -output $@ $${BUILT_LIPO_FILES}; \ + fi + + +# Copy built non-universal binaries in place +$(UNIVERSAL_COPY_LIST): + BUILT_COPY_FILES="`find $(EXPORT_JRE_LIB_DIR)/{i386,amd64}/$(subst $(EXPORT_JRE_LIB_DIR)/,,$@) 2>/dev/null`"; \ + if [ -n "$${BUILT_COPY_FILES}" ]; then \ + for i in $${BUILT_COPY_FILES}; do \ + if [ -f $${i} ]; then \ + $(MKDIR) -p $(shell dirname $@); \ + $(CP) $${i} $@; \ + fi; \ + done; \ + fi + + +# Replace arch specific binaries with universal binaries +export_universal: + $(RM) -r $(EXPORT_PATH)/jre/lib/{i386,amd64} + $(RM) -r $(JDK_IMAGE_DIR)/jre/lib/{i386,amd64} + $(RM) $(JDK_IMAGE_DIR)/jre/lib/{client,server}/libjsig.$(LIBRARY_SUFFIX) + ($(CD) $(EXPORT_PATH) && \ + $(TAR) -cf - *) | \ + ($(CD) $(JDK_IMAGE_DIR) && $(TAR) -xpf -) + + +# Overlay universal binaries +copy_universal: + $(RM) -r $(JDK_IMAGE_DIR)$(COPY_SUBDIR)/jre/lib/{i386,amd64} + $(RM) $(JDK_IMAGE_DIR)$(COPY_SUBDIR)/jre/lib/{client,server}/libjsig.$(LIBRARY_SUFFIX) + ($(CD) $(EXPORT_PATH)$(COPY_SUBDIR) && \ + $(TAR) -cf - *) | \ + ($(CD) $(JDK_IMAGE_DIR)$(COPY_SUBDIR) && $(TAR) -xpf -) + + +# Additional processing for universal builds +export_product_jdk:: + $(MAKE) EXPORT_SUBDIR= export_universal +export_optimized_jdk:: + $(MAKE) EXPORT_SUBDIR= export_universal +export_fastdebug_jdk:: + $(MAKE) EXPORT_SUBDIR=/fastdebug export_universal +export_debug_jdk:: + $(MAKE) EXPORT_SUBDIR=/debug export_universal +copy_product_jdk:: + $(MAKE) COPY_SUBDIR= copy_universal +copy_fastdebug_jdk:: + $(MAKE) COPY_SUBDIR=/fastdebug copy_universal +copy_debug_jdk:: + $(MAKE) COPY_SUBDIR=/debug copy_universal + +.PHONY: universal_product universal_fastdebug universal_debug \ + all_product_universal all_fastdebug_universal all_debug_universal \ + universalize export_universal copy_universal diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/bsd/makefiles/vm.make --- a/hotspot/make/bsd/makefiles/vm.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/bsd/makefiles/vm.make Thu Feb 09 23:17:22 2012 -0800 @@ -82,18 +82,22 @@ BUILD_USER = -DHOTSPOT_BUILD_USER="\"$(HOTSPOT_BUILD_USER)\"" VM_DISTRO = -DHOTSPOT_VM_DISTRO="\"$(HOTSPOT_VM_DISTRO)\"" -CPPFLAGS = \ +CXXFLAGS = \ ${SYSDEFS} \ ${INCLUDES} \ ${BUILD_VERSION} \ ${BUILD_TARGET} \ ${BUILD_USER} \ ${HS_LIB_ARCH} \ - ${JRE_VERSION} \ ${VM_DISTRO} +# This is VERY important! The version define must only be supplied to vm_version.o +# If not, ccache will not re-use the cache at all, since the version string might contain +# a time and date. +vm_version.o: CXXFLAGS += ${JRE_VERSION} + ifdef DEFAULT_LIBPATH -CPPFLAGS += -DDEFAULT_LIBPATH="\"$(DEFAULT_LIBPATH)\"" +CXXFLAGS += -DDEFAULT_LIBPATH="\"$(DEFAULT_LIBPATH)\"" endif ifndef JAVASE_EMBEDDED @@ -260,9 +264,9 @@ ifeq ($(STATIC_CXX), true) LFLAGS_VM += $(STATIC_LIBGCC) LIBS_VM += $(STATIC_STDCXX) - LINK_VM = $(LINK_LIB.c) + LINK_VM = $(LINK_LIB.CC) else - LINK_VM = $(LINK_LIB.CC) + LINK_VM = $(LINK_LIB.CXX) endif LIBS_VM += $(LIBS) @@ -280,7 +284,7 @@ $(PRECOMPILED_HEADER): $(QUIETLY) echo Generating precompiled header $@ $(QUIETLY) mkdir -p $(PRECOMPILED_HEADER_DIR) - $(QUIETLY) $(COMPILE.CC) $(DEPFLAGS) -x c++-header $(PRECOMPILED_HEADER_SRC) -o $@ $(COMPILE_DONE) + $(QUIETLY) $(COMPILE.CXX) $(DEPFLAGS) -x c++-header $(PRECOMPILED_HEADER_SRC) -o $@ $(COMPILE_DONE) # making the library: @@ -305,10 +309,10 @@ $(LIBJVM): $(LIBJVM.o) $(LIBJVM_MAPFILE) $(LD_SCRIPT) $(QUIETLY) { \ echo Linking vm...; \ - $(LINK_LIB.CC/PRE_HOOK) \ + $(LINK_LIB.CXX/PRE_HOOK) \ $(LINK_VM) $(LD_SCRIPT_FLAG) \ $(LFLAGS_VM) -o $@ $(LIBJVM.o) $(LIBS_VM); \ - $(LINK_LIB.CC/POST_HOOK) \ + $(LINK_LIB.CXX/POST_HOOK) \ rm -f $@.1; ln -s $@ $@.1; \ [ -f $(LIBJVM_G) ] || { ln -s $@ $(LIBJVM_G); ln -s $@.1 $(LIBJVM_G).1; }; \ } diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/defs.make --- a/hotspot/make/defs.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/defs.make Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ # -# Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 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 @@ -185,6 +185,15 @@ BOOTDIR=$(ALT_BOOTDIR) endif +# Select name of the export directory and honor ALT overrides +EXPORT_PATH=$(OUTPUTDIR)/export-$(PLATFORM)$(EXPORT_SUBDIR) +ifneq ($(ALT_EXPORT_PATH),) + EXPORT_PATH=$(ALT_EXPORT_PATH) +endif + +# Default jdk image if one is created for you with create_jdk +JDK_IMAGE_DIR=$(OUTPUTDIR)/jdk-$(PLATFORM) + # The platform dependent defs.make defines platform specific variable such # as ARCH, EXPORT_LIST etc. We must place the include here after BOOTDIR is defined. include $(GAMMADIR)/make/$(OSNAME)/makefiles/defs.make @@ -263,15 +272,6 @@ # includes this make/defs.make file. MAKE_ARGS += HOTSPOT_BUILD_VERSION=$(HOTSPOT_BUILD_VERSION) -# Select name of export directory -EXPORT_PATH=$(OUTPUTDIR)/export-$(PLATFORM)$(EXPORT_SUBDIR) -ifneq ($(ALT_EXPORT_PATH),) - EXPORT_PATH=$(ALT_EXPORT_PATH) -endif - -# Default jdk image if one is created for you with create_jdk -JDK_IMAGE_DIR=$(OUTPUTDIR)/jdk-$(PLATFORM) - # Various export sub directories EXPORT_INCLUDE_DIR = $(EXPORT_PATH)/include EXPORT_DOCS_DIR = $(EXPORT_PATH)/docs diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/hotspot_version --- a/hotspot/make/hotspot_version Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/hotspot_version Thu Feb 09 23:17:22 2012 -0800 @@ -35,7 +35,7 @@ HS_MAJOR_VER=23 HS_MINOR_VER=0 -HS_BUILD_NUMBER=12 +HS_BUILD_NUMBER=15 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/jprt.properties --- a/hotspot/make/jprt.properties Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/jprt.properties Thu Feb 09 23:17:22 2012 -0800 @@ -438,12 +438,12 @@ ${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.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, \ diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/linux/makefiles/adlc.make --- a/hotspot/make/linux/makefiles/adlc.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/linux/makefiles/adlc.make Thu Feb 09 23:17:22 2012 -0800 @@ -61,10 +61,10 @@ INCLUDES += $(Src_Dirs_I:%=-I%) # set flags for adlc compilation -CPPFLAGS = $(SYSDEFS) $(INCLUDES) +CXXFLAGS = $(SYSDEFS) $(INCLUDES) # Force assertions on. -CPPFLAGS += -DASSERT +CXXFLAGS += -DASSERT # CFLAGS_WARN holds compiler options to suppress/enable warnings. # Compiler warnings are treated as errors @@ -109,7 +109,7 @@ $(EXEC) : $(OBJECTS) @echo Making adlc - $(QUIETLY) $(HOST.LINK_NOPROF.CC) -o $(EXEC) $(OBJECTS) + $(QUIETLY) $(HOST.LINK_NOPROF.CXX) -o $(EXEC) $(OBJECTS) # Random dependencies: $(OBJECTS): opcodes.hpp classes.hpp adlc.hpp adlcVMDeps.hpp adlparse.hpp archDesc.hpp arena.hpp dict2.hpp filebuff.hpp forms.hpp formsopt.hpp formssel.hpp @@ -211,14 +211,14 @@ $(OUTDIR)/%.o: %.cpp @echo Compiling $< $(QUIETLY) $(REMOVE_TARGET) - $(QUIETLY) $(HOST.COMPILE.CC) -o $@ $< $(COMPILE_DONE) + $(QUIETLY) $(HOST.COMPILE.CXX) -o $@ $< $(COMPILE_DONE) # Some object files are given a prefix, to disambiguate # them from objects of the same name built for the VM. $(OUTDIR)/adlc-%.o: %.cpp @echo Compiling $< $(QUIETLY) $(REMOVE_TARGET) - $(QUIETLY) $(HOST.COMPILE.CC) -o $@ $< $(COMPILE_DONE) + $(QUIETLY) $(HOST.COMPILE.CXX) -o $@ $< $(COMPILE_DONE) # ######################################################################### diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/linux/makefiles/gcc.make --- a/hotspot/make/linux/makefiles/gcc.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/linux/makefiles/gcc.make Thu Feb 09 23:17:22 2012 -0800 @@ -23,19 +23,19 @@ # #------------------------------------------------------------------------ -# CC, CPP & AS +# CC, CXX & AS # When cross-compiling the ALT_COMPILER_PATH points # to the cross-compilation toolset ifdef CROSS_COMPILE_ARCH -CPP = $(ALT_COMPILER_PATH)/g++ +CXX = $(ALT_COMPILER_PATH)/g++ CC = $(ALT_COMPILER_PATH)/gcc -HOSTCPP = g++ +HOSTCXX = g++ HOSTCC = gcc else -CPP = g++ +CXX = g++ CC = gcc -HOSTCPP = $(CPP) +HOSTCXX = $(CXX) HOSTCC = $(CC) endif diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/linux/makefiles/launcher.make --- a/hotspot/make/linux/makefiles/launcher.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/linux/makefiles/launcher.make Thu Feb 09 23:17:22 2012 -0800 @@ -54,10 +54,10 @@ LIBS_LAUNCHER += -l$(JVM) $(LIBS) endif -LINK_LAUNCHER = $(LINK.c) +LINK_LAUNCHER = $(LINK.CC) -LINK_LAUNCHER/PRE_HOOK = $(LINK_LIB.CC/PRE_HOOK) -LINK_LAUNCHER/POST_HOOK = $(LINK_LIB.CC/POST_HOOK) +LINK_LAUNCHER/PRE_HOOK = $(LINK_LIB.CXX/PRE_HOOK) +LINK_LAUNCHER/POST_HOOK = $(LINK_LIB.CXX/POST_HOOK) LAUNCHER_OUT = launcher @@ -73,11 +73,11 @@ $(LAUNCHER_OUT)/%.o: $(LAUNCHERDIR_SHARE)/%.c $(QUIETLY) [ -d $(LAUNCHER_OUT) ] || { mkdir -p $(LAUNCHER_OUT); } - $(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CPPFLAGS) + $(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CXXFLAGS) $(LAUNCHER_OUT)/%.o: $(LAUNCHERDIR)/%.c $(QUIETLY) [ -d $(LAUNCHER_OUT) ] || { mkdir -p $(LAUNCHER_OUT); } - $(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CPPFLAGS) + $(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CXXFLAGS) $(LAUNCHER): $(OBJS) $(LIBJVM) $(LAUNCHER_MAPFILE) $(QUIETLY) echo Linking launcher... diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/linux/makefiles/product.make --- a/hotspot/make/linux/makefiles/product.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/linux/makefiles/product.make Thu Feb 09 23:17:22 2012 -0800 @@ -52,4 +52,4 @@ # If we can create .debuginfo files, then the VM is stripped in vm.make # and this macro is not used. -# LINK_LIB.CC/POST_HOOK += $(STRIP_$(LINK_INTO)) +# LINK_LIB.CXX/POST_HOOK += $(STRIP_$(LINK_INTO)) diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/linux/makefiles/rules.make --- a/hotspot/make/linux/makefiles/rules.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/linux/makefiles/rules.make Thu Feb 09 23:17:22 2012 -0800 @@ -27,52 +27,39 @@ # Tell make that .cpp is important .SUFFIXES: .cpp $(SUFFIXES) -# For now. Other makefiles use CPP as the c++ compiler, but that should really -# name the preprocessor. -ifeq ($(CCC),) -CCC = $(CPP) -endif - DEMANGLER = c++filt DEMANGLE = $(DEMANGLER) < $@ > .$@ && mv -f .$@ $@ -# $(CC) is the c compiler (cc/gcc), $(CCC) is the c++ compiler (CC/g++). -C_COMPILE = $(CC) $(CPPFLAGS) $(CFLAGS) -CC_COMPILE = $(CCC) $(CPPFLAGS) $(CFLAGS) +# $(CC) is the c compiler (cc/gcc), $(CXX) is the c++ compiler (CC/g++). +CC_COMPILE = $(CC) $(CXXFLAGS) $(CFLAGS) +CXX_COMPILE = $(CXX) $(CXXFLAGS) $(CFLAGS) AS.S = $(AS) $(ASFLAGS) -COMPILE.c = $(C_COMPILE) -c -GENASM.c = $(C_COMPILE) -S -LINK.c = $(CC) $(LFLAGS) $(AOUT_FLAGS) $(PROF_AOUT_FLAGS) -LINK_LIB.c = $(CC) $(LFLAGS) $(SHARED_FLAG) -PREPROCESS.c = $(C_COMPILE) -E +COMPILE.CC = $(CC_COMPILE) -c +GENASM.CC = $(CC_COMPILE) -S +LINK.CC = $(CC) $(LFLAGS) $(AOUT_FLAGS) $(PROF_AOUT_FLAGS) +LINK_LIB.CC = $(CC) $(LFLAGS) $(SHARED_FLAG) +PREPROCESS.CC = $(CC_COMPILE) -E -COMPILE.CC = $(CC_COMPILE) -c -GENASM.CC = $(CC_COMPILE) -S -LINK.CC = $(CCC) $(LFLAGS) $(AOUT_FLAGS) $(PROF_AOUT_FLAGS) -LINK_NOPROF.CC = $(CCC) $(LFLAGS) $(AOUT_FLAGS) -LINK_LIB.CC = $(CCC) $(LFLAGS) $(SHARED_FLAG) -PREPROCESS.CC = $(CC_COMPILE) -E +COMPILE.CXX = $(CXX_COMPILE) -c +GENASM.CXX = $(CXX_COMPILE) -S +LINK.CXX = $(CXX) $(LFLAGS) $(AOUT_FLAGS) $(PROF_AOUT_FLAGS) +LINK_NOPROF.CXX = $(CXX) $(LFLAGS) $(AOUT_FLAGS) +LINK_LIB.CXX = $(CXX) $(LFLAGS) $(SHARED_FLAG) +PREPROCESS.CXX = $(CXX_COMPILE) -E # cross compiling the jvm with c2 requires host compilers to build # adlc tool -HOST.CC_COMPILE = $(HOSTCPP) $(CPPFLAGS) $(CFLAGS) -HOST.COMPILE.CC = $(HOST.CC_COMPILE) -c -HOST.LINK_NOPROF.CC = $(HOSTCPP) $(LFLAGS) $(AOUT_FLAGS) +HOST.CXX_COMPILE = $(HOSTCXX) $(CXXFLAGS) $(CFLAGS) +HOST.COMPILE.CXX = $(HOST.CXX_COMPILE) -c +HOST.LINK_NOPROF.CXX = $(HOSTCXX) $(LFLAGS) $(AOUT_FLAGS) # Effect of REMOVE_TARGET is to delete out-of-date files during "gnumake -k". REMOVE_TARGET = rm -f $@ -# Synonyms. -COMPILE.cpp = $(COMPILE.CC) -GENASM.cpp = $(GENASM.CC) -LINK.cpp = $(LINK.CC) -LINK_LIB.cpp = $(LINK_LIB.CC) -PREPROCESS.cpp = $(PREPROCESS.CC) - # Note use of ALT_BOOTDIR to explicitly specify location of java and # javac; this is the same environment variable used in the J2SE build # process for overriding the default spec, which is BOOTDIR. @@ -161,14 +148,14 @@ %.o: %.cpp @echo Compiling $< $(QUIETLY) $(REMOVE_TARGET) - $(QUIETLY) $(COMPILE.CC) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE) + $(QUIETLY) $(COMPILE.CXX) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE) else %.o: %.cpp @echo Compiling $< $(QUIETLY) $(REMOVE_TARGET) $(QUIETLY) $(if $(findstring $@, $(NONPIC_OBJ_FILES)), \ - $(subst $(VM_PICFLAG), ,$(COMPILE.CC)) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE), \ - $(COMPILE.CC) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE)) + $(subst $(VM_PICFLAG), ,$(COMPILE.CXX)) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE), \ + $(COMPILE.CXX) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE)) endif %.o: %.s @@ -178,13 +165,13 @@ %.s: %.cpp @echo Generating assembly for $< - $(QUIETLY) $(GENASM.CC) -o $@ $< + $(QUIETLY) $(GENASM.CXX) -o $@ $< $(QUIETLY) $(DEMANGLE) $(COMPILE_DONE) # Intermediate files (for debugging macros) %.i: %.cpp @echo Preprocessing $< to $@ - $(QUIETLY) $(PREPROCESS.CC) $< > $@ $(COMPILE_DONE) + $(QUIETLY) $(PREPROCESS.CXX) $< > $@ $(COMPILE_DONE) # Override gnumake built-in rules which do sccs get operations badly. # (They put the checked out code in the current directory, not in the diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/linux/makefiles/sparcWorks.make --- a/hotspot/make/linux/makefiles/sparcWorks.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/linux/makefiles/sparcWorks.make Thu Feb 09 23:17:22 2012 -0800 @@ -23,13 +23,13 @@ # #------------------------------------------------------------------------ -# CC, CPP & AS +# CC, CXX & AS -CPP = CC +CXX = CC CC = cc AS = $(CC) -c -HOSTCPP = $(CPP) +HOSTCXX = $(CXX) HOSTCC = $(CC) ARCHFLAG = $(ARCHFLAG/$(BUILDARCH)) diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/linux/makefiles/vm.make --- a/hotspot/make/linux/makefiles/vm.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/linux/makefiles/vm.make Thu Feb 09 23:17:22 2012 -0800 @@ -88,16 +88,20 @@ BUILD_USER = -DHOTSPOT_BUILD_USER="\"$(HOTSPOT_BUILD_USER)\"" VM_DISTRO = -DHOTSPOT_VM_DISTRO="\"$(HOTSPOT_VM_DISTRO)\"" -CPPFLAGS = \ +CXXFLAGS = \ ${SYSDEFS} \ ${INCLUDES} \ ${BUILD_VERSION} \ ${BUILD_TARGET} \ ${BUILD_USER} \ ${HS_LIB_ARCH} \ - ${JRE_VERSION} \ ${VM_DISTRO} +# This is VERY important! The version define must only be supplied to vm_version.o +# If not, ccache will not re-use the cache at all, since the version string might contain +# a time and date. +vm_version.o: CXXFLAGS += ${JRE_VERSION} + ifndef JAVASE_EMBEDDED CFLAGS += -DINCLUDE_TRACE endif @@ -272,13 +276,13 @@ LIBS_VM += $(LLVM_LIBS) endif -LINK_VM = $(LINK_LIB.c) +LINK_VM = $(LINK_LIB.CC) # rule for building precompiled header $(PRECOMPILED_HEADER): $(QUIETLY) echo Generating precompiled header $@ $(QUIETLY) mkdir -p $(PRECOMPILED_HEADER_DIR) - $(QUIETLY) $(COMPILE.CC) $(DEPFLAGS) -x c++-header $(PRECOMPILED_HEADER_SRC) -o $@ $(COMPILE_DONE) + $(QUIETLY) $(COMPILE.CXX) $(DEPFLAGS) -x c++-header $(PRECOMPILED_HEADER_SRC) -o $@ $(COMPILE_DONE) # making the library: @@ -308,10 +312,10 @@ $(LIBJVM): $(LIBJVM.o) $(LIBJVM_MAPFILE) $(LD_SCRIPT) $(QUIETLY) { \ echo Linking vm...; \ - $(LINK_LIB.CC/PRE_HOOK) \ + $(LINK_LIB.CXX/PRE_HOOK) \ $(LINK_VM) $(LD_SCRIPT_FLAG) \ $(LFLAGS_VM) -o $@ $(LIBJVM.o) $(LIBS_VM); \ - $(LINK_LIB.CC/POST_HOOK) \ + $(LINK_LIB.CXX/POST_HOOK) \ rm -f $@.1; ln -s $@ $@.1; \ [ -f $(LIBJVM_G) ] || { ln -s $@ $(LIBJVM_G); ln -s $@.1 $(LIBJVM_G).1; }; \ if [ \"$(CROSS_COMPILE_ARCH)\" = \"\" ] ; then \ diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/solaris/makefiles/adlc.make --- a/hotspot/make/solaris/makefiles/adlc.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/solaris/makefiles/adlc.make Thu Feb 09 23:17:22 2012 -0800 @@ -62,10 +62,10 @@ INCLUDES += $(Src_Dirs_I:%=-I%) # set flags for adlc compilation -CPPFLAGS = $(SYSDEFS) $(INCLUDES) +CXXFLAGS = $(SYSDEFS) $(INCLUDES) # Force assertions on. -CPPFLAGS += -DASSERT +CXXFLAGS += -DASSERT ifndef USE_GCC # We need libCstd.so for adlc @@ -130,7 +130,7 @@ $(EXEC) : $(OBJECTS) @echo Making adlc - $(QUIETLY) $(LINK_NOPROF.CC) -o $(EXEC) $(OBJECTS) + $(QUIETLY) $(LINK_NOPROF.CXX) -o $(EXEC) $(OBJECTS) # Random dependencies: $(OBJECTS): opcodes.hpp classes.hpp adlc.hpp adlcVMDeps.hpp adlparse.hpp archDesc.hpp arena.hpp dict2.hpp filebuff.hpp forms.hpp formsopt.hpp formssel.hpp @@ -228,14 +228,14 @@ $(OUTDIR)/%.o: %.cpp @echo Compiling $< $(QUIETLY) $(REMOVE_TARGET) - $(QUIETLY) $(COMPILE.CC) -o $@ $< $(COMPILE_DONE) + $(QUIETLY) $(COMPILE.CXX) -o $@ $< $(COMPILE_DONE) # Some object files are given a prefix, to disambiguate # them from objects of the same name built for the VM. $(OUTDIR)/adlc-%.o: %.cpp @echo Compiling $< $(QUIETLY) $(REMOVE_TARGET) - $(QUIETLY) $(COMPILE.CC) -o $@ $< $(COMPILE_DONE) + $(QUIETLY) $(COMPILE.CXX) -o $@ $< $(COMPILE_DONE) # ######################################################################### diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/solaris/makefiles/dtrace.make --- a/hotspot/make/solaris/makefiles/dtrace.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/solaris/makefiles/dtrace.make Thu Feb 09 23:17:22 2012 -0800 @@ -150,11 +150,11 @@ lib$(GENOFFS).so: $(DTRACE_SRCDIR)/$(GENOFFS).cpp $(DTRACE_SRCDIR)/$(GENOFFS).h \ $(LIBJVM.o) - $(QUIETLY) $(CCC) $(CPPFLAGS) $(GENOFFS_CFLAGS) $(SHARED_FLAG) $(PICFLAG) \ + $(QUIETLY) $(CXX) $(CXXFLAGS) $(GENOFFS_CFLAGS) $(SHARED_FLAG) $(PICFLAG) \ $(LFLAGS_GENOFFS) -o $@ $(DTRACE_SRCDIR)/$(GENOFFS).cpp -lc $(GENOFFS): $(DTRACE_SRCDIR)/$(GENOFFS)Main.c lib$(GENOFFS).so - $(QUIETLY) $(LINK.CC) -z nodefs -o $@ $(DTRACE_SRCDIR)/$(GENOFFS)Main.c \ + $(QUIETLY) $(LINK.CXX) -z nodefs -o $@ $(DTRACE_SRCDIR)/$(GENOFFS)Main.c \ ./lib$(GENOFFS).so CONDITIONALLY_UPDATE_JVMOFFS_TARGET = \ @@ -178,7 +178,7 @@ $(QUIETLY) $(CONDITIONALLY_UPDATE_JVMOFFS_TARGET) $(JVMOFFS.o): $(JVMOFFS).h $(JVMOFFS).cpp - $(QUIETLY) $(CCC) -c -I. -o $@ $(ARCHFLAG) -D$(TYPE) $(JVMOFFS).cpp + $(QUIETLY) $(CXX) -c -I. -o $@ $(ARCHFLAG) -D$(TYPE) $(JVMOFFS).cpp $(LIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS.o) $(XLIBJVM_DB) $(LIBJVM_DB_MAPFILE) @echo Making $@ diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/solaris/makefiles/gcc.make --- a/hotspot/make/solaris/makefiles/gcc.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/solaris/makefiles/gcc.make Thu Feb 09 23:17:22 2012 -0800 @@ -23,9 +23,9 @@ # #------------------------------------------------------------------------ -# CC, CPP & AS +# CC, CXX & AS -CPP = g++ +CXX = g++ CC = gcc AS = $(CC) -c @@ -36,12 +36,12 @@ CC_VER_MAJOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f1) CC_VER_MINOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f2) -# Check for the versions of C++ and C compilers ($CPP and $CC) used. +# Check for the versions of C++ and C compilers ($CXX and $CC) used. # Get the last thing on the line that looks like x.x+ (x is a digit). COMPILER_REV := \ -$(shell $(CPP) -dumpversion | sed 's/egcs-//' | cut -d'.' -f1) -C_COMPILER_REV := \ +$(shell $(CXX) -dumpversion | sed 's/egcs-//' | cut -d'.' -f1) +CC_COMPILER_REV := \ $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f2) diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/solaris/makefiles/launcher.make --- a/hotspot/make/solaris/makefiles/launcher.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/solaris/makefiles/launcher.make Thu Feb 09 23:17:22 2012 -0800 @@ -52,10 +52,10 @@ LIBS_LAUNCHER += -l$(JVM) $(LIBS) endif -LINK_LAUNCHER = $(LINK.CC) +LINK_LAUNCHER = $(LINK.CXX) -LINK_LAUNCHER/PRE_HOOK = $(LINK_LIB.CC/PRE_HOOK) -LINK_LAUNCHER/POST_HOOK = $(LINK_LIB.CC/POST_HOOK) +LINK_LAUNCHER/PRE_HOOK = $(LINK_LIB.CXX/PRE_HOOK) +LINK_LAUNCHER/POST_HOOK = $(LINK_LIB.CXX/POST_HOOK) ifeq ("${Platform_compiler}", "sparcWorks") # Enable the following LAUNCHERFLAGS addition if you need to compare the @@ -86,11 +86,11 @@ $(LAUNCHER_OUT)/%.o: $(LAUNCHERDIR_SHARE)/%.c $(QUIETLY) [ -d $(LAUNCHER_OUT) ] || { mkdir -p $(LAUNCHER_OUT); } - $(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CPPFLAGS) + $(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CXXFLAGS) $(LAUNCHER_OUT)/%.o: $(LAUNCHERDIR)/%.c $(QUIETLY) [ -d $(LAUNCHER_OUT) ] || { mkdir -p $(LAUNCHER_OUT); } - $(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CPPFLAGS) + $(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CXXFLAGS) $(LAUNCHER): $(OBJS) $(LIBJVM) $(LAUNCHER_MAPFILE) ifeq ($(filter -sbfast -xsbfast, $(CFLAGS_BROWSE)),) diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/solaris/makefiles/product.make --- a/hotspot/make/solaris/makefiles/product.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/solaris/makefiles/product.make Thu Feb 09 23:17:22 2012 -0800 @@ -70,7 +70,7 @@ # If we can create .debuginfo files, then the VM is stripped in vm.make # and this macro is not used. -# LINK_LIB.CC/POST_HOOK += $(STRIP_LIB.CC/POST_HOOK) +# LINK_LIB.CXX/POST_HOOK += $(STRIP_LIB.CXX/POST_HOOK) G_SUFFIX = SYSDEFS += -DPRODUCT diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/solaris/makefiles/rules.make --- a/hotspot/make/solaris/makefiles/rules.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/solaris/makefiles/rules.make Thu Feb 09 23:17:22 2012 -0800 @@ -27,44 +27,31 @@ # Tell make that .cpp is important .SUFFIXES: .cpp $(SUFFIXES) -# For now. Other makefiles use CPP as the c++ compiler, but that should really -# name the preprocessor. -ifeq ($(CCC),) -CCC = $(CPP) -endif - DEMANGLER = c++filt DEMANGLE = $(DEMANGLER) < $@ > .$@ && mv -f .$@ $@ -# $(CC) is the c compiler (cc/gcc), $(CCC) is the c++ compiler (CC/g++). -C_COMPILE = $(CC) $(CPPFLAGS) $(CFLAGS) -CC_COMPILE = $(CCC) $(CPPFLAGS) $(CFLAGS) +# $(CC) is the c compiler (cc/gcc), $(CXX) is the c++ compiler (CC/g++). +CC_COMPILE = $(CC) $(CXXFLAGS) $(CFLAGS) +CXX_COMPILE = $(CXX) $(CXXFLAGS) $(CFLAGS) AS.S = $(AS) $(ASFLAGS) -COMPILE.c = $(C_COMPILE) -c -GENASM.c = $(C_COMPILE) -S -LINK.c = $(CC) $(LFLAGS) $(AOUT_FLAGS) $(PROF_AOUT_FLAGS) -LINK_LIB.c = $(CC) $(LFLAGS) $(SHARED_FLAG) -PREPROCESS.c = $(C_COMPILE) -E +COMPILE.CC = $(CC_COMPILE) -c +GENASM.CC = $(CC_COMPILE) -S +LINK.CC = $(CC) $(LFLAGS) $(AOUT_FLAGS) $(PROF_AOUT_FLAGS) +LINK_LIB.CC = $(CC) $(LFLAGS) $(SHARED_FLAG) +PREPROCESS.CC = $(CC_COMPILE) -E -COMPILE.CC = $(CC_COMPILE) -c -GENASM.CC = $(CC_COMPILE) -S -LINK.CC = $(CCC) $(LFLAGS) $(AOUT_FLAGS) $(PROF_AOUT_FLAGS) -LINK_NOPROF.CC = $(CCC) $(LFLAGS) $(AOUT_FLAGS) -LINK_LIB.CC = $(CCC) $(LFLAGS) $(SHARED_FLAG) -PREPROCESS.CC = $(CC_COMPILE) -E +COMPILE.CXX = $(CXX_COMPILE) -c +GENASM.CXX = $(CXX_COMPILE) -S +LINK.CXX = $(CXX) $(LFLAGS) $(AOUT_FLAGS) $(PROF_AOUT_FLAGS) +LINK_NOPROF.CXX = $(CXX) $(LFLAGS) $(AOUT_FLAGS) +LINK_LIB.CXX = $(CXX) $(LFLAGS) $(SHARED_FLAG) +PREPROCESS.CXX = $(CXX_COMPILE) -E # Effect of REMOVE_TARGET is to delete out-of-date files during "gnumake -k". REMOVE_TARGET = rm -f $@ -# Synonyms. -COMPILE.cpp = $(COMPILE.CC) -GENASM.cpp = $(GENASM.CC) -LINK.cpp = $(LINK.CC) -LINK_LIB.cpp = $(LINK_LIB.CC) -PREPROCESS.cpp = $(PREPROCESS.CC) - # Note use of ALT_BOOTDIR to explicitly specify location of java and # javac; this is the same environment variable used in the J2SE build # process for overriding the default spec, which is BOOTDIR. @@ -153,14 +140,14 @@ %.o: %.cpp @echo Compiling $< $(QUIETLY) $(REMOVE_TARGET) - $(QUIETLY) $(COMPILE.CC) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE) + $(QUIETLY) $(COMPILE.CXX) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE) else %.o: %.cpp @echo Compiling $< $(QUIETLY) $(REMOVE_TARGET) $(QUIETLY) $(if $(findstring $@, $(NONPIC_OBJ_FILES)), \ - $(subst $(VM_PICFLAG), ,$(COMPILE.CC)) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE), \ - $(COMPILE.CC) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE)) + $(subst $(VM_PICFLAG), ,$(COMPILE.CXX)) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE), \ + $(COMPILE.CXX) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE)) endif %.o: %.s @@ -170,13 +157,13 @@ %.s: %.cpp @echo Generating assembly for $< - $(QUIETLY) $(GENASM.CC) -o $@ $< + $(QUIETLY) $(GENASM.CXX) -o $@ $< $(QUIETLY) $(DEMANGLE) $(COMPILE_DONE) # Intermediate files (for debugging macros) %.i: %.cpp @echo Preprocessing $< to $@ - $(QUIETLY) $(PREPROCESS.CC) $< > $@ $(COMPILE_DONE) + $(QUIETLY) $(PREPROCESS.CXX) $< > $@ $(COMPILE_DONE) # Override gnumake built-in rules which do sccs get operations badly. # (They put the checked out code in the current directory, not in the diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/solaris/makefiles/saproc.make --- a/hotspot/make/solaris/makefiles/saproc.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/solaris/makefiles/saproc.make Thu Feb 09 23:17:22 2012 -0800 @@ -93,7 +93,7 @@ exit 1; \ fi @echo Making SA debugger back-end... - $(QUIETLY) $(CPP) \ + $(QUIETLY) $(CXX) \ $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \ -I$(SASRCDIR) \ -I$(GENERATED) \ diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/solaris/makefiles/sparcWorks.make --- a/hotspot/make/solaris/makefiles/sparcWorks.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/solaris/makefiles/sparcWorks.make Thu Feb 09 23:17:22 2012 -0800 @@ -26,7 +26,7 @@ # tell make which C and C++ compilers to use CC = cc -CPP = CC +CXX = CC # Note that this 'as' is an older version of the Sun Studio 'fbe', and will # use the older style options. The 'fbe' options will match 'cc' and 'CC'. @@ -37,23 +37,23 @@ REORDER_FLAG = -xF -# Check for the versions of C++ and C compilers ($CPP and $CC) used. +# Check for the versions of C++ and C compilers ($CXX and $CC) used. # Get the last thing on the line that looks like x.x+ (x is a digit). COMPILER_REV := \ -$(shell $(CPP) -V 2>&1 | sed -n 's/^.*[ ,\t]C++[ ,\t]\([1-9]\.[0-9][0-9]*\).*/\1/p') -C_COMPILER_REV := \ +$(shell $(CXX) -V 2>&1 | sed -n 's/^.*[ ,\t]C++[ ,\t]\([1-9]\.[0-9][0-9]*\).*/\1/p') +CC_COMPILER_REV := \ $(shell $(CC) -V 2>&1 | sed -n 's/^.*[ ,\t]C[ ,\t]\([1-9]\.[0-9][0-9]*\).*/\1/p') # Pick which compiler is validated ifeq ($(JRE_RELEASE_VER),1.6.0) # Validated compiler for JDK6 is SS11 (5.8) VALIDATED_COMPILER_REVS := 5.8 - VALIDATED_C_COMPILER_REVS := 5.8 + VALIDATED_CC_COMPILER_REVS := 5.8 else # Validated compiler for JDK7 is SS12 update 1 + patches (5.10) VALIDATED_COMPILER_REVS := 5.10 - VALIDATED_C_COMPILER_REVS := 5.10 + VALIDATED_CC_COMPILER_REVS := 5.10 endif # Warning messages about not using the above validated versions @@ -67,13 +67,13 @@ warning.) endif -ENFORCE_C_COMPILER_REV${ENFORCE_C_COMPILER_REV} := $(strip ${VALIDATED_C_COMPILER_REVS}) -ifeq ($(filter ${ENFORCE_C_COMPILER_REV},${C_COMPILER_REV}),) -PRINTABLE_C_REVS := $(subst $(shell echo ' '), or ,${ENFORCE_C_COMPILER_REV}) +ENFORCE_CC_COMPILER_REV${ENFORCE_CC_COMPILER_REV} := $(strip ${VALIDATED_CC_COMPILER_REVS}) +ifeq ($(filter ${ENFORCE_CC_COMPILER_REV},${CC_COMPILER_REV}),) +PRINTABLE_C_REVS := $(subst $(shell echo ' '), or ,${ENFORCE_CC_COMPILER_REV}) dummy_var_to_enforce_c_compiler_rev := $(shell \ - echo >&2 WARNING: You are using cc version ${C_COMPILER_REV} and \ + echo >&2 WARNING: You are using cc version ${CC_COMPILER_REV} and \ should be using version ${PRINTABLE_C_REVS}.; \ - echo >&2 Set ENFORCE_C_COMPILER_REV=${C_COMPILER_REV} to avoid this \ + echo >&2 Set ENFORCE_CC_COMPILER_REV=${CC_COMPILER_REV} to avoid this \ warning.) endif @@ -98,7 +98,7 @@ } \ END { exit rc; }' -LINK_LIB.CC/PRE_HOOK += $(JVM_CHECK_SYMBOLS) || exit 1; +LINK_LIB.CXX/PRE_HOOK += $(JVM_CHECK_SYMBOLS) || exit 1; # New architecture options started in SS12 (5.9), we need both styles to build. # The older arch options for SS11 (5.8) or older and also for /usr/ccs/bin/as. @@ -518,7 +518,7 @@ #FASTDEBUG_CFLAGS += -Qoption ccfe -xglobalstatic ifeq (${COMPILER_REV_NUMERIC}, 502) -COMPILER_DATE := $(shell $(CPP) -V 2>&1 | sed -n '/^.*[ ]C++[ ]\([1-9]\.[0-9][0-9]*\)/p' | awk '{ print $$NF; }') +COMPILER_DATE := $(shell $(CXX) -V 2>&1 | sed -n '/^.*[ ]C++[ ]\([1-9]\.[0-9][0-9]*\)/p' | awk '{ print $$NF; }') ifeq (${COMPILER_DATE}, 2001/01/31) # disable -g0 in fastdebug since SC6.1 dated 2001/01/31 seems to be buggy # use an innocuous value because it will get -g if it's empty @@ -568,7 +568,7 @@ # removing repeated lines. The data can be extracted from # binaries in the field by using "mcs -p libjvm.so" or the older # command "what libjvm.so". -LINK_LIB.CC/POST_HOOK += $(MCS) -c $@ || exit 1; +LINK_LIB.CXX/POST_HOOK += $(MCS) -c $@ || exit 1; # (The exit 1 is necessary to cause a build failure if the command fails and # multiple commands are strung together, and the final semicolon is necessary # since the hook must terminate itself as a valid command.) @@ -576,7 +576,7 @@ # Also, strip debug and line number information (worth about 1.7Mb). # If we can create .debuginfo files, then the VM is stripped in vm.make # and this macro is not used. -STRIP_LIB.CC/POST_HOOK = $(STRIP) -x $@ || exit 1; -# STRIP_LIB.CC/POST_HOOK is incorporated into LINK_LIB.CC/POST_HOOK +STRIP_LIB.CXX/POST_HOOK = $(STRIP) -x $@ || exit 1; +# STRIP_LIB.CXX/POST_HOOK is incorporated into LINK_LIB.CXX/POST_HOOK # in certain configurations, such as product.make. Other configurations, # such as debug.make, do not include the strip operation. diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/solaris/makefiles/vm.make --- a/hotspot/make/solaris/makefiles/vm.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/solaris/makefiles/vm.make Thu Feb 09 23:17:22 2012 -0800 @@ -76,16 +76,20 @@ BUILD_USER = -DHOTSPOT_BUILD_USER="\"$(HOTSPOT_BUILD_USER)\"" VM_DISTRO = -DHOTSPOT_VM_DISTRO="\"$(HOTSPOT_VM_DISTRO)\"" -CPPFLAGS = \ +CXXFLAGS = \ ${SYSDEFS} \ ${INCLUDES} \ ${BUILD_VERSION} \ ${BUILD_TARGET} \ ${BUILD_USER} \ ${HS_LIB_ARCH} \ - ${JRE_VERSION} \ ${VM_DISTRO} +# This is VERY important! The version define must only be supplied to vm_version.o +# If not, ccache will not re-use the cache at all, since the version string might contain +# a time and date. +vm_version.o: CXXFLAGS += ${JRE_VERSION} + # CFLAGS_WARN holds compiler options to suppress/enable warnings. CFLAGS += $(CFLAGS_WARN) @@ -265,17 +269,17 @@ endif ifdef USE_GCC -LINK_VM = $(LINK_LIB.c) +LINK_VM = $(LINK_LIB.CC) else -LINK_VM = $(LINK_LIB.CC) +LINK_VM = $(LINK_LIB.CXX) endif # making the library: $(LIBJVM): $(LIBJVM.o) $(LIBJVM_MAPFILE) ifeq ($(filter -sbfast -xsbfast, $(CFLAGS_BROWSE)),) @echo Linking vm... - $(QUIETLY) $(LINK_LIB.CC/PRE_HOOK) + $(QUIETLY) $(LINK_LIB.CXX/PRE_HOOK) $(QUIETLY) $(LINK_VM) $(LFLAGS_VM) -o $@ $(LIBJVM.o) $(LIBS_VM) - $(QUIETLY) $(LINK_LIB.CC/POST_HOOK) + $(QUIETLY) $(LINK_LIB.CXX/POST_HOOK) $(QUIETLY) rm -f $@.1 && ln -s $@ $@.1 $(QUIETLY) [ -f $(LIBJVM_G) ] || ln -s $@ $(LIBJVM_G) $(QUIETLY) [ -f $(LIBJVM_G).1 ] || ln -s $@.1 $(LIBJVM_G).1 diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/windows/build_vm_def.sh --- a/hotspot/make/windows/build_vm_def.sh Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/windows/build_vm_def.sh Thu Feb 09 23:17:22 2012 -0800 @@ -57,10 +57,10 @@ # When called from IDE the first param should contain the link version, otherwise may be nill if [ "x$1" != "x" ]; then -LINK_VER="$1" +LD_VER="$1" fi -if [ "x$LINK_VER" != "x800" -a "x$LINK_VER" != "x900" -a "x$LINK_VER" != "x1000" ]; then +if [ "x$LD_VER" != "x800" -a "x$LD_VER" != "x900" -a "x$LD_VER" != "x1000" ]; then $DUMPBIN /symbols *.obj | "$GREP" "??_7.*@@6B@" | "$GREP" -v "type_info" | "$AWK" '{print $7}' | "$SORT" | "$UNIQ" > vm2.def else # Can't use pipes when calling cl.exe or link.exe from IDE. Using transit file vm3.def diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/windows/get_msc_ver.sh --- a/hotspot/make/windows/get_msc_ver.sh Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/windows/get_msc_ver.sh Thu Feb 09 23:17:22 2012 -0800 @@ -72,8 +72,8 @@ echo "MSC_VER_RAW=$MSC_VER_RAW" fi -if [ "x$FORCE_LINK_VER" != "x" ]; then - echo "LINK_VER=$FORCE_LINK_VER" +if [ "x$FORCE_LD_VER" != "x" ]; then + echo "LD_VER=$FORCE_LD_VER" else # use the "link" command that is co-located with the "cl" command cl_cmd=`which cl` @@ -83,11 +83,11 @@ # which can't find "cl" so just use which ever "link" we find link_cmd="link" fi - LINK_VER_RAW=`"$link_cmd" 2>&1 | "$HEAD" -n 1 | "$SED" 's/.*Version[\ ]*\([0-9][0-9.]*\).*/\1/'` - LINK_VER_MAJOR=`"$ECHO" $LINK_VER_RAW | "$CUT" -d'.' -f1` - LINK_VER_MINOR=`"$ECHO" $LINK_VER_RAW | "$CUT" -d'.' -f2` - LINK_VER_MICRO=`"$ECHO" $LINK_VER_RAW | "$CUT" -d'.' -f3` - LINK_VER=`"$EXPR" $LINK_VER_MAJOR \* 100 + $LINK_VER_MINOR` - echo "LINK_VER=$LINK_VER" - echo "LINK_VER_RAW=$LINK_VER_RAW" + LD_VER_RAW=`"$link_cmd" 2>&1 | "$HEAD" -n 1 | "$SED" 's/.*Version[\ ]*\([0-9][0-9.]*\).*/\1/'` + LD_VER_MAJOR=`"$ECHO" $LD_VER_RAW | "$CUT" -d'.' -f1` + LD_VER_MINOR=`"$ECHO" $LD_VER_RAW | "$CUT" -d'.' -f2` + LD_VER_MICRO=`"$ECHO" $LD_VER_RAW | "$CUT" -d'.' -f3` + LD_VER=`"$EXPR" $LD_VER_MAJOR \* 100 + $LD_VER_MINOR` + echo "LD_VER=$LD_VER" + echo "LD_VER_RAW=$LD_VER_RAW" fi diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/windows/makefiles/adlc.make --- a/hotspot/make/windows/makefiles/adlc.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/windows/makefiles/adlc.make Thu Feb 09 23:17:22 2012 -0800 @@ -45,9 +45,9 @@ ADLCFLAGS=-q -T -U_LP64 !endif -ADLC_CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_DEPRECATE +ADLC_CXX_FLAGS=$(CXX_FLAGS) /D _CRT_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_DEPRECATE -CPP_INCLUDE_DIRS=\ +CXX_INCLUDE_DIRS=\ /I "..\generated" \ /I "$(WorkSpace)\src\share\vm" \ /I "$(WorkSpace)\src\os\windows\vm" \ @@ -94,14 +94,14 @@ $(AdlcOutDir)\dfa_$(Platform_arch_model).cpp {$(WorkSpace)\src\share\vm\adlc}.cpp.obj:: - $(CPP) $(ADLC_CPP_FLAGS) $(EXH_FLAGS) $(CPP_INCLUDE_DIRS) /c $< + $(CXX) $(ADLC_CXX_FLAGS) $(EXH_FLAGS) $(CXX_INCLUDE_DIRS) /c $< {$(WorkSpace)\src\share\vm\opto}.cpp.obj:: - $(CPP) $(ADLC_CPP_FLAGS) $(EXH_FLAGS) $(CPP_INCLUDE_DIRS) /c $< + $(CXX) $(ADLC_CXX_FLAGS) $(EXH_FLAGS) $(CXX_INCLUDE_DIRS) /c $< adlc.exe: main.obj adlparse.obj archDesc.obj arena.obj dfa.obj dict2.obj filebuff.obj \ forms.obj formsopt.obj formssel.obj opcodes.obj output_c.obj output_h.obj - $(LINK) $(LINK_FLAGS) /subsystem:console /out:$@ $** + $(LD) $(LD_FLAGS) /subsystem:console /out:$@ $** !if "$(MT)" != "" # The previous link command created a .manifest file that we want to # insert into the linked artifact so we do not need to track it diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/windows/makefiles/compile.make --- a/hotspot/make/windows/makefiles/compile.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/windows/makefiles/compile.make Thu Feb 09 23:17:22 2012 -0800 @@ -23,9 +23,9 @@ # # Generic compiler settings -CPP=cl.exe +CXX=cl.exe -# CPP Flags: (these vary slightly from VC6->VS2003->VS2005 compilers) +# CXX Flags: (these vary slightly from VC6->VS2003->VS2005 compilers) # /nologo Supress copyright message at every cl.exe startup # /W3 Warning level 3 # /Zi Include debugging information @@ -50,47 +50,47 @@ # improving the quality of crash log stack traces involving jvm.dll. # These are always used in all compiles -CPP_FLAGS=/nologo /W3 /WX +CXX_FLAGS=/nologo /W3 /WX # Let's add debug information always too. -CPP_FLAGS=$(CPP_FLAGS) /Zi +CXX_FLAGS=$(CXX_FLAGS) /Zi # Based on BUILDARCH we add some flags and select the default compiler name !if "$(BUILDARCH)" == "ia64" MACHINE=IA64 DEFAULT_COMPILER_NAME=VS2003 -CPP_FLAGS=$(CPP_FLAGS) /D "CC_INTERP" /D "_LP64" /D "IA64" +CXX_FLAGS=$(CXX_FLAGS) /D "CC_INTERP" /D "_LP64" /D "IA64" !endif !if "$(BUILDARCH)" == "amd64" MACHINE=AMD64 DEFAULT_COMPILER_NAME=VS2005 -CPP_FLAGS=$(CPP_FLAGS) /D "_LP64" /D "AMD64" +CXX_FLAGS=$(CXX_FLAGS) /D "_LP64" /D "AMD64" LP64=1 !endif !if "$(BUILDARCH)" == "i486" MACHINE=I386 DEFAULT_COMPILER_NAME=VS2003 -CPP_FLAGS=$(CPP_FLAGS) /D "IA32" +CXX_FLAGS=$(CXX_FLAGS) /D "IA32" !endif # Sanity check, this is the default if not amd64, ia64, or i486 !ifndef DEFAULT_COMPILER_NAME -CPP=ARCH_ERROR +CXX=ARCH_ERROR !endif -CPP_FLAGS=$(CPP_FLAGS) /D "WIN32" /D "_WINDOWS" +CXX_FLAGS=$(CXX_FLAGS) /D "WIN32" /D "_WINDOWS" # Must specify this for sharedRuntimeTrig.cpp -CPP_FLAGS=$(CPP_FLAGS) /D "VM_LITTLE_ENDIAN" +CXX_FLAGS=$(CXX_FLAGS) /D "VM_LITTLE_ENDIAN" # Used for platform dispatching -CPP_FLAGS=$(CPP_FLAGS) /D TARGET_OS_FAMILY_windows -CPP_FLAGS=$(CPP_FLAGS) /D TARGET_ARCH_$(Platform_arch) -CPP_FLAGS=$(CPP_FLAGS) /D TARGET_ARCH_MODEL_$(Platform_arch_model) -CPP_FLAGS=$(CPP_FLAGS) /D TARGET_OS_ARCH_windows_$(Platform_arch) -CPP_FLAGS=$(CPP_FLAGS) /D TARGET_OS_ARCH_MODEL_windows_$(Platform_arch_model) -CPP_FLAGS=$(CPP_FLAGS) /D TARGET_COMPILER_visCPP +CXX_FLAGS=$(CXX_FLAGS) /D TARGET_OS_FAMILY_windows +CXX_FLAGS=$(CXX_FLAGS) /D TARGET_ARCH_$(Platform_arch) +CXX_FLAGS=$(CXX_FLAGS) /D TARGET_ARCH_MODEL_$(Platform_arch_model) +CXX_FLAGS=$(CXX_FLAGS) /D TARGET_OS_ARCH_windows_$(Platform_arch) +CXX_FLAGS=$(CXX_FLAGS) /D TARGET_OS_ARCH_MODEL_windows_$(Platform_arch_model) +CXX_FLAGS=$(CXX_FLAGS) /D TARGET_COMPILER_visCPP # MSC_VER is a 4 digit number that tells us what compiler is being used @@ -150,14 +150,14 @@ # Always add the _STATIC_CPPLIB flag STATIC_CPPLIB_OPTION = /D _STATIC_CPPLIB /D _DISABLE_DEPRECATE_STATIC_CPPLIB MS_RUNTIME_OPTION = $(MS_RUNTIME_OPTION) $(STATIC_CPPLIB_OPTION) -CPP_FLAGS=$(CPP_FLAGS) $(MS_RUNTIME_OPTION) +CXX_FLAGS=$(CXX_FLAGS) $(MS_RUNTIME_OPTION) # How /GX option is spelled GX_OPTION = /GX # Optimization settings for various versions of the compilers and types of # builds. Three basic sets of settings: product, fastdebug, and debug. -# These get added into CPP_FLAGS as needed by other makefiles. +# These get added into CXX_FLAGS as needed by other makefiles. !if "$(COMPILER_NAME)" == "VC6" PRODUCT_OPT_OPTION = /Ox /Os /Gy /GF FASTDEBUG_OPT_OPTION = /Ox /Os /Gy /GF @@ -180,7 +180,7 @@ # externals at link time. Even with /GS-, you need bufferoverflowU.lib. # NOTE: Currently we decided to not use /GS- BUFFEROVERFLOWLIB = bufferoverflowU.lib -LINK_FLAGS = /manifest $(LINK_FLAGS) $(BUFFEROVERFLOWLIB) +LD_FLAGS = /manifest $(LD_FLAGS) $(BUFFEROVERFLOWLIB) # Manifest Tool - used in VS2005 and later to adjust manifests stored # as resources inside build artifacts. MT=mt.exe @@ -191,7 +191,7 @@ FASTDEBUG_OPT_OPTION = /O2 /Oy- DEBUG_OPT_OPTION = /Od GX_OPTION = /EHsc -LINK_FLAGS = /manifest $(LINK_FLAGS) +LD_FLAGS = /manifest $(LD_FLAGS) # Manifest Tool - used in VS2005 and later to adjust manifests stored # as resources inside build artifacts. MT=mt.exe @@ -202,12 +202,12 @@ FASTDEBUG_OPT_OPTION = /O2 /Oy- DEBUG_OPT_OPTION = /Od GX_OPTION = /EHsc -LINK_FLAGS = /manifest $(LINK_FLAGS) +LD_FLAGS = /manifest $(LD_FLAGS) # Manifest Tool - used in VS2005 and later to adjust manifests stored # as resources inside build artifacts. MT=mt.exe !if "$(BUILDARCH)" == "i486" -LINK_FLAGS = /SAFESEH $(LINK_FLAGS) +LD_FLAGS = /SAFESEH $(LD_FLAGS) !endif !endif @@ -225,15 +225,15 @@ !endif # Generic linker settings -LINK=link.exe -LINK_FLAGS= $(LINK_FLAGS) kernel32.lib user32.lib gdi32.lib winspool.lib \ +LD=link.exe +LD_FLAGS= $(LD_FLAGS) kernel32.lib user32.lib gdi32.lib winspool.lib \ comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib \ uuid.lib Wsock32.lib winmm.lib /nologo /machine:$(MACHINE) /opt:REF \ /opt:ICF,8 /map /debug !if $(MSC_VER) >= 1600 -LINK_FLAGS= $(LINK_FLAGS) psapi.lib +LD_FLAGS= $(LD_FLAGS) psapi.lib !endif # Resource compiler settings @@ -250,7 +250,7 @@ /D "HS_INTERNAL_NAME=$(HS_INTERNAL_NAME)" \ /D "HS_NAME=$(HS_NAME)" -# Need this to match the CPP_FLAGS settings +# Need this to match the CXX_FLAGS settings !if "$(MFC_DEBUG)" == "true" RC_FLAGS = $(RC_FLAGS) /D "_DEBUG" !endif diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/windows/makefiles/debug.make --- a/hotspot/make/windows/makefiles/debug.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/windows/makefiles/debug.make Thu Feb 09 23:17:22 2012 -0800 @@ -38,7 +38,7 @@ !include ../local.make !include compile.make -CPP_FLAGS=$(CPP_FLAGS) $(DEBUG_OPT_OPTION) +CXX_FLAGS=$(CXX_FLAGS) $(DEBUG_OPT_OPTION) !include $(WorkSpace)/make/windows/makefiles/vm.make !include local.make @@ -52,8 +52,8 @@ sh $(WorkSpace)/make/windows/build_vm_def.sh $(AOUT): $(Res_Files) $(Obj_Files) vm.def - $(LINK) @<< - $(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files) + $(LD) @<< + $(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files) << !if "$(MT)" != "" # The previous link command created a .manifest file that we want to diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/windows/makefiles/fastdebug.make --- a/hotspot/make/windows/makefiles/fastdebug.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/windows/makefiles/fastdebug.make Thu Feb 09 23:17:22 2012 -0800 @@ -38,7 +38,7 @@ !include ../local.make !include compile.make -CPP_FLAGS=$(CPP_FLAGS) $(FASTDEBUG_OPT_OPTION) +CXX_FLAGS=$(CXX_FLAGS) $(FASTDEBUG_OPT_OPTION) !include $(WorkSpace)/make/windows/makefiles/vm.make !include local.make @@ -52,8 +52,8 @@ sh $(WorkSpace)/make/windows/build_vm_def.sh $(AOUT): $(Res_Files) $(Obj_Files) vm.def - $(LINK) @<< - $(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files) + $(LD) @<< + $(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files) << !if "$(MT)" != "" # The previous link command created a .manifest file that we want to diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/windows/makefiles/launcher.make --- a/hotspot/make/windows/makefiles/launcher.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/windows/makefiles/launcher.make Thu Feb 09 23:17:22 2012 -0800 @@ -23,7 +23,7 @@ # -LAUNCHER_FLAGS=$(CPP_FLAGS) $(ARCHFLAG) \ +LAUNCHER_FLAGS=$(CXX_FLAGS) $(ARCHFLAG) \ /D FULL_VERSION=\"$(HOTSPOT_RELEASE_VERSION)\" \ /D JDK_MAJOR_VERSION=\"$(JDK_MAJOR_VERSION)\" \ /D JDK_MINOR_VERSION=\"$(JDK_MINOR_VERSION)\" \ @@ -39,18 +39,18 @@ /I $(WorkSpace)\src\cpu\$(Platform_arch)\vm \ /I $(WorkSpace)\src\os\windows\vm -LINK_FLAGS=/manifest $(HS_INTERNAL_NAME).lib kernel32.lib user32.lib /nologo /machine:$(MACHINE) /map /debug /subsystem:console +LD_FLAGS=/manifest $(HS_INTERNAL_NAME).lib kernel32.lib user32.lib /nologo /machine:$(MACHINE) /map /debug /subsystem:console !if "$(COMPILER_NAME)" == "VS2005" # This VS2005 compiler has /GS as a default and requires bufferoverflowU.lib # on the link command line, otherwise we get missing __security_check_cookie # externals at link time. Even with /GS-, you need bufferoverflowU.lib. BUFFEROVERFLOWLIB = bufferoverflowU.lib -LINK_FLAGS = $(LINK_FLAGS) $(BUFFEROVERFLOWLIB) +LD_FLAGS = $(LD_FLAGS) $(BUFFEROVERFLOWLIB) !endif !if "$(COMPILER_NAME)" == "VS2010" && "$(BUILDARCH)" == "i486" -LINK_FLAGS = /SAFESEH $(LINK_FLAGS) +LD_FLAGS = /SAFESEH $(LD_FLAGS) !endif LAUNCHERDIR = $(WorkSpace)/src/os/windows/launcher @@ -60,14 +60,14 @@ {$(LAUNCHERDIR)}.c{$(OUTDIR)}.obj: -mkdir $(OUTDIR) 2>NUL >NUL - $(CPP) $(LAUNCHER_FLAGS) /c /Fo$@ $< + $(CXX) $(LAUNCHER_FLAGS) /c /Fo$@ $< {$(LAUNCHERDIR_SHARE)}.c{$(OUTDIR)}.obj: -mkdir $(OUTDIR) 2>NUL >NUL - $(CPP) $(LAUNCHER_FLAGS) /c /Fo$@ $< + $(CXX) $(LAUNCHER_FLAGS) /c /Fo$@ $< $(OUTDIR)\*.obj: $(LAUNCHERDIR)\*.c $(LAUNCHERDIR)\*.h $(LAUNCHERDIR_SHARE)\*.c $(LAUNCHERDIR_SHARE)\*.h launcher: $(OUTDIR)\java.obj $(OUTDIR)\java_md.obj $(OUTDIR)\jli_util.obj echo $(JAVA_HOME) > jdkpath.txt - $(LINK) $(LINK_FLAGS) /out:hotspot.exe $** + $(LD) $(LD_FLAGS) /out:hotspot.exe $** diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/windows/makefiles/product.make --- a/hotspot/make/windows/makefiles/product.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/windows/makefiles/product.make Thu Feb 09 23:17:22 2012 -0800 @@ -37,7 +37,7 @@ !include ../local.make !include compile.make -CPP_FLAGS=$(CPP_FLAGS) $(PRODUCT_OPT_OPTION) +CXX_FLAGS=$(CXX_FLAGS) $(PRODUCT_OPT_OPTION) RELEASE= @@ -54,16 +54,16 @@ # Kernel doesn't need exported vtbl symbols. !if "$(Variant)" == "kernel" $(AOUT): $(Res_Files) $(Obj_Files) - $(LINK) @<< - $(LINK_FLAGS) /out:$@ /implib:$*.lib $(Obj_Files) $(Res_Files) + $(LD) @<< + $(LD_FLAGS) /out:$@ /implib:$*.lib $(Obj_Files) $(Res_Files) << !else vm.def: $(Obj_Files) sh $(WorkSpace)/make/windows/build_vm_def.sh $(AOUT): $(Res_Files) $(Obj_Files) vm.def - $(LINK) @<< - $(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files) + $(LD) @<< + $(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files) << !endif !if "$(MT)" != "" diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/windows/makefiles/projectcreator.make --- a/hotspot/make/windows/makefiles/projectcreator.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/windows/makefiles/projectcreator.make Thu Feb 09 23:17:22 2012 -0800 @@ -89,7 +89,7 @@ -jdkTargetRoot $(HOTSPOTJDKDIST) \ -define ALIGN_STACK_FRAMES \ -define VM_LITTLE_ENDIAN \ - -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)" \ + -prelink "" "Generating vm.def..." "cd $(HOTSPOTBUILDSPACE)\%f\%b set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME) set JAVA_HOME=$(HOTSPOTJDKDIST) $(HOTSPOTMKSHOME)\sh $(HOTSPOTWORKSPACE)\make\windows\build_vm_def.sh $(LD_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 fc06525cb345 -r 5561a4c99825 hotspot/make/windows/makefiles/sa.make --- a/hotspot/make/windows/makefiles/sa.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/windows/makefiles/sa.make Thu Feb 09 23:17:22 2012 -0800 @@ -91,16 +91,16 @@ !if "$(COMPILER_NAME)" == "VS2005" # On amd64, VS2005 compiler requires bufferoverflowU.lib on the link command line, # otherwise we get missing __security_check_cookie externals at link time. -SA_LINK_FLAGS = bufferoverflowU.lib +SA_LD_FLAGS = bufferoverflowU.lib !endif !else SA_CFLAGS = /nologo $(MS_RUNTIME_OPTION) /W3 /Gm $(GX_OPTION) /ZI /Od /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c !endif !if "$(MT)" != "" -SA_LINK_FLAGS = /manifest $(SA_LINK_FLAGS) +SA_LD_FLAGS = /manifest $(SA_LD_FLAGS) !endif SASRCFILE = $(AGENT_DIR)/src/os/win32/windbg/sawindbg.cpp -SA_LFLAGS = $(SA_LINK_FLAGS) /nologo /subsystem:console /map /debug /machine:$(MACHINE) +SA_LFLAGS = $(SA_LD_FLAGS) /nologo /subsystem:console /map /debug /machine:$(MACHINE) # Note that we do not keep sawindbj.obj around as it would then # get included in the dumpbin command in build_vm_def.sh @@ -110,14 +110,14 @@ # Use ";#2" for .dll and ";#1" for .exe in the MT command below: $(SAWINDBG): $(SASRCFILE) set INCLUDE=$(SA_INCLUDE)$(INCLUDE) - $(CPP) @<< + $(CXX) @<< /I"$(BootStrapDir)/include" /I"$(BootStrapDir)/include/win32" /I"$(GENERATED)" $(SA_CFLAGS) $(SASRCFILE) /out:sawindbg.obj << set LIB=$(SA_LIB)$(LIB) - $(LINK) /out:$@ /DLL sawindbg.obj dbgeng.lib $(SA_LFLAGS) + $(LD) /out:$@ /DLL sawindbg.obj dbgeng.lib $(SA_LFLAGS) !if "$(MT)" != "" $(MT) /manifest $(@F).manifest /outputresource:$(@F);#2 !endif diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/windows/makefiles/sanity.make --- a/hotspot/make/windows/makefiles/sanity.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/windows/makefiles/sanity.make Thu Feb 09 23:17:22 2012 -0800 @@ -31,5 +31,5 @@ echo *** WARNING *** unrecognized cl.exe version $(MSC_VER) ($(RAW_MSC_VER)). Use FORCE_MSC_VER to override automatic detection. checkLink: - @ if "$(LINK_VER)" NEQ "710" if "$(LINK_VER)" NEQ "800" if "$(LINK_VER)" NEQ "900" if "$(LINK_VER)" NEQ "1000" \ - echo *** WARNING *** unrecognized link.exe version $(LINK_VER) ($(RAW_LINK_VER)). Use FORCE_LINK_VER to override automatic detection. + @ if "$(LD_VER)" NEQ "710" if "$(LD_VER)" NEQ "800" if "$(LD_VER)" NEQ "900" if "$(LD_VER)" NEQ "1000" \ + echo *** WARNING *** unrecognized link.exe version $(LD_VER) ($(RAW_LD_VER)). Use FORCE_LD_VER to override automatic detection. diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/windows/makefiles/shared.make --- a/hotspot/make/windows/makefiles/shared.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/windows/makefiles/shared.make Thu Feb 09 23:17:22 2012 -0800 @@ -30,8 +30,8 @@ DIR=. !endif -!ifndef CPP -CPP=cl.exe +!ifndef CXX +CXX=cl.exe !endif diff -r fc06525cb345 -r 5561a4c99825 hotspot/make/windows/makefiles/vm.make --- a/hotspot/make/windows/makefiles/vm.make Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/make/windows/makefiles/vm.make Thu Feb 09 23:17:22 2012 -0800 @@ -32,12 +32,12 @@ !ifdef RELEASE !ifdef DEVELOP -CPP_FLAGS=$(CPP_FLAGS) /D "DEBUG" +CXX_FLAGS=$(CXX_FLAGS) /D "DEBUG" !else -CPP_FLAGS=$(CPP_FLAGS) /D "PRODUCT" +CXX_FLAGS=$(CXX_FLAGS) /D "PRODUCT" !endif !else -CPP_FLAGS=$(CPP_FLAGS) /D "ASSERT" +CXX_FLAGS=$(CXX_FLAGS) /D "ASSERT" !endif !if "$(Variant)" == "core" @@ -45,19 +45,19 @@ !endif !if "$(Variant)" == "kernel" -CPP_FLAGS=$(CPP_FLAGS) /D "KERNEL" +CXX_FLAGS=$(CXX_FLAGS) /D "KERNEL" !endif !if "$(Variant)" == "compiler1" -CPP_FLAGS=$(CPP_FLAGS) /D "COMPILER1" +CXX_FLAGS=$(CXX_FLAGS) /D "COMPILER1" !endif !if "$(Variant)" == "compiler2" -CPP_FLAGS=$(CPP_FLAGS) /D "COMPILER2" +CXX_FLAGS=$(CXX_FLAGS) /D "COMPILER2" !endif !if "$(Variant)" == "tiered" -CPP_FLAGS=$(CPP_FLAGS) /D "COMPILER1" /D "COMPILER2" +CXX_FLAGS=$(CXX_FLAGS) /D "COMPILER1" /D "COMPILER2" !endif !if "$(BUILDARCH)" == "i486" @@ -67,21 +67,21 @@ !endif # The following variables are defined in the generated local.make file. -CPP_FLAGS=$(CPP_FLAGS) /D "HOTSPOT_RELEASE_VERSION=\"$(HS_BUILD_VER)\"" -CPP_FLAGS=$(CPP_FLAGS) /D "JRE_RELEASE_VERSION=\"$(JRE_RELEASE_VER)\"" -CPP_FLAGS=$(CPP_FLAGS) /D "HOTSPOT_LIB_ARCH=\"$(HOTSPOT_LIB_ARCH)\"" -CPP_FLAGS=$(CPP_FLAGS) /D "HOTSPOT_BUILD_TARGET=\"$(BUILD_FLAVOR)\"" -CPP_FLAGS=$(CPP_FLAGS) /D "HOTSPOT_BUILD_USER=\"$(BuildUser)\"" -CPP_FLAGS=$(CPP_FLAGS) /D "HOTSPOT_VM_DISTRO=\"$(HOTSPOT_VM_DISTRO)\"" +CXX_FLAGS=$(CXX_FLAGS) /D "HOTSPOT_RELEASE_VERSION=\"$(HS_BUILD_VER)\"" +CXX_FLAGS=$(CXX_FLAGS) /D "JRE_RELEASE_VERSION=\"$(JRE_RELEASE_VER)\"" +CXX_FLAGS=$(CXX_FLAGS) /D "HOTSPOT_LIB_ARCH=\"$(HOTSPOT_LIB_ARCH)\"" +CXX_FLAGS=$(CXX_FLAGS) /D "HOTSPOT_BUILD_TARGET=\"$(BUILD_FLAVOR)\"" +CXX_FLAGS=$(CXX_FLAGS) /D "HOTSPOT_BUILD_USER=\"$(BuildUser)\"" +CXX_FLAGS=$(CXX_FLAGS) /D "HOTSPOT_VM_DISTRO=\"$(HOTSPOT_VM_DISTRO)\"" !ifndef JAVASE_EMBEDDED -CPP_FLAGS=$(CPP_FLAGS) /D "INCLUDE_TRACE" +CXX_FLAGS=$(CXX_FLAGS) /D "INCLUDE_TRACE" !endif -CPP_FLAGS=$(CPP_FLAGS) $(CPP_INCLUDE_DIRS) +CXX_FLAGS=$(CXX_FLAGS) $(CXX_INCLUDE_DIRS) # Define that so jni.h is on correct side -CPP_FLAGS=$(CPP_FLAGS) /D "_JNI_IMPLEMENTATION_" +CXX_FLAGS=$(CXX_FLAGS) /D "_JNI_IMPLEMENTATION_" !if "$(BUILDARCH)" == "ia64" STACK_SIZE="/STACK:1048576,262144" @@ -102,7 +102,7 @@ # If you modify exports below please do the corresponding changes in # src/share/tools/ProjectCreator/WinGammaPlatformVC7.java -LINK_FLAGS=$(LINK_FLAGS) $(STACK_SIZE) /subsystem:windows /dll /base:0x8000000 \ +LD_FLAGS=$(LD_FLAGS) $(STACK_SIZE) /subsystem:windows /dll /base:0x8000000 \ /export:JNI_GetDefaultJavaVMInitArgs \ /export:JNI_CreateJavaVM \ /export:JVM_FindClassFromBootLoader \ @@ -118,25 +118,25 @@ /export:JVM_GetThreadStateValues \ /export:JVM_InitAgentProperties -CPP_INCLUDE_DIRS=/I "..\generated" +CXX_INCLUDE_DIRS=/I "..\generated" !if exists($(ALTSRC)\share\vm) -CPP_INCLUDE_DIRS=$(CPP_INCLUDE_DIRS) /I "$(ALTSRC)\share\vm" +CXX_INCLUDE_DIRS=$(CXX_INCLUDE_DIRS) /I "$(ALTSRC)\share\vm" !endif !if exists($(ALTSRC)\os\windows\vm) -CPP_INCLUDE_DIRS=$(CPP_INCLUDE_DIRS) /I "$(ALTSRC)\os\windows\vm" +CXX_INCLUDE_DIRS=$(CXX_INCLUDE_DIRS) /I "$(ALTSRC)\os\windows\vm" !endif !if exists($(ALTSRC)\os_cpu\windows_$(Platform_arch)\vm) -CPP_INCLUDE_DIRS=$(CPP_INCLUDE_DIRS) /I "$(ALTSRC)\os_cpu\windows_$(Platform_arch)\vm" +CXX_INCLUDE_DIRS=$(CXX_INCLUDE_DIRS) /I "$(ALTSRC)\os_cpu\windows_$(Platform_arch)\vm" !endif !if exists($(ALTSRC)\cpu\$(Platform_arch)\vm) -CPP_INCLUDE_DIRS=$(CPP_INCLUDE_DIRS) /I "$(ALTSRC)\cpu\$(Platform_arch)\vm" +CXX_INCLUDE_DIRS=$(CXX_INCLUDE_DIRS) /I "$(ALTSRC)\cpu\$(Platform_arch)\vm" !endif -CPP_INCLUDE_DIRS=$(CPP_INCLUDE_DIRS) \ +CXX_INCLUDE_DIRS=$(CXX_INCLUDE_DIRS) \ /I "$(COMMONSRC)\share\vm" \ /I "$(COMMONSRC)\share\vm\precompiled" \ /I "$(COMMONSRC)\share\vm\prims" \ @@ -144,12 +144,12 @@ /I "$(COMMONSRC)\os_cpu\windows_$(Platform_arch)\vm" \ /I "$(COMMONSRC)\cpu\$(Platform_arch)\vm" -CPP_DONT_USE_PCH=/D DONT_USE_PRECOMPILED_HEADER +CXX_DONT_USE_PCH=/D DONT_USE_PRECOMPILED_HEADER !if "$(USE_PRECOMPILED_HEADER)" != "0" -CPP_USE_PCH=/Fp"vm.pch" /Yu"precompiled.hpp" +CXX_USE_PCH=/Fp"vm.pch" /Yu"precompiled.hpp" !else -CPP_USE_PCH=$(CPP_DONT_USE_PCH) +CXX_USE_PCH=$(CXX_DONT_USE_PCH) !endif # Where to find the source code for the virtual machine (is this used?) @@ -194,101 +194,101 @@ # Special case files not using precompiled header files. c1_RInfo_$(Platform_arch).obj: $(WorkSpace)\src\cpu\$(Platform_arch)\vm\c1_RInfo_$(Platform_arch).cpp - $(CPP) $(CPP_FLAGS) $(CPP_DONT_USE_PCH) /c $(WorkSpace)\src\cpu\$(Platform_arch)\vm\c1_RInfo_$(Platform_arch).cpp + $(CXX) $(CXX_FLAGS) $(CXX_DONT_USE_PCH) /c $(WorkSpace)\src\cpu\$(Platform_arch)\vm\c1_RInfo_$(Platform_arch).cpp os_windows.obj: $(WorkSpace)\src\os\windows\vm\os_windows.cpp - $(CPP) $(CPP_FLAGS) $(CPP_DONT_USE_PCH) /c $(WorkSpace)\src\os\windows\vm\os_windows.cpp + $(CXX) $(CXX_FLAGS) $(CXX_DONT_USE_PCH) /c $(WorkSpace)\src\os\windows\vm\os_windows.cpp os_windows_$(Platform_arch).obj: $(WorkSpace)\src\os_cpu\windows_$(Platform_arch)\vm\os_windows_$(Platform_arch).cpp - $(CPP) $(CPP_FLAGS) $(CPP_DONT_USE_PCH) /c $(WorkSpace)\src\os_cpu\windows_$(Platform_arch)\vm\os_windows_$(Platform_arch).cpp + $(CXX) $(CXX_FLAGS) $(CXX_DONT_USE_PCH) /c $(WorkSpace)\src\os_cpu\windows_$(Platform_arch)\vm\os_windows_$(Platform_arch).cpp osThread_windows.obj: $(WorkSpace)\src\os\windows\vm\osThread_windows.cpp - $(CPP) $(CPP_FLAGS) $(CPP_DONT_USE_PCH) /c $(WorkSpace)\src\os\windows\vm\osThread_windows.cpp + $(CXX) $(CXX_FLAGS) $(CXX_DONT_USE_PCH) /c $(WorkSpace)\src\os\windows\vm\osThread_windows.cpp conditionVar_windows.obj: $(WorkSpace)\src\os\windows\vm\conditionVar_windows.cpp - $(CPP) $(CPP_FLAGS) $(CPP_DONT_USE_PCH) /c $(WorkSpace)\src\os\windows\vm\conditionVar_windows.cpp + $(CXX) $(CXX_FLAGS) $(CXX_DONT_USE_PCH) /c $(WorkSpace)\src\os\windows\vm\conditionVar_windows.cpp getThread_windows_$(Platform_arch).obj: $(WorkSpace)\src\os_cpu\windows_$(Platform_arch)\vm\getThread_windows_$(Platform_arch).cpp - $(CPP) $(CPP_FLAGS) $(CPP_DONT_USE_PCH) /c $(WorkSpace)\src\os_cpu\windows_$(Platform_arch)\vm\getThread_windows_$(Platform_arch).cpp + $(CXX) $(CXX_FLAGS) $(CXX_DONT_USE_PCH) /c $(WorkSpace)\src\os_cpu\windows_$(Platform_arch)\vm\getThread_windows_$(Platform_arch).cpp opcodes.obj: $(WorkSpace)\src\share\vm\opto\opcodes.cpp - $(CPP) $(CPP_FLAGS) $(CPP_DONT_USE_PCH) /c $(WorkSpace)\src\share\vm\opto\opcodes.cpp + $(CXX) $(CXX_FLAGS) $(CXX_DONT_USE_PCH) /c $(WorkSpace)\src\share\vm\opto\opcodes.cpp bytecodeInterpreter.obj: $(WorkSpace)\src\share\vm\interpreter\bytecodeInterpreter.cpp - $(CPP) $(CPP_FLAGS) $(CPP_DONT_USE_PCH) /c $(WorkSpace)\src\share\vm\interpreter\bytecodeInterpreter.cpp + $(CXX) $(CXX_FLAGS) $(CXX_DONT_USE_PCH) /c $(WorkSpace)\src\share\vm\interpreter\bytecodeInterpreter.cpp bytecodeInterpreterWithChecks.obj: ..\generated\jvmtifiles\bytecodeInterpreterWithChecks.cpp - $(CPP) $(CPP_FLAGS) $(CPP_DONT_USE_PCH) /c ..\generated\jvmtifiles\bytecodeInterpreterWithChecks.cpp + $(CXX) $(CXX_FLAGS) $(CXX_DONT_USE_PCH) /c ..\generated\jvmtifiles\bytecodeInterpreterWithChecks.cpp # Default rules for the Virtual Machine {$(COMMONSRC)\share\vm\c1}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(COMMONSRC)\share\vm\compiler}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(COMMONSRC)\share\vm\code}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(COMMONSRC)\share\vm\interpreter}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(COMMONSRC)\share\vm\ci}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(COMMONSRC)\share\vm\classfile}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(COMMONSRC)\share\vm\gc_implementation\parallelScavenge}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(COMMONSRC)\share\vm\gc_implementation\shared}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(COMMONSRC)\share\vm\gc_implementation\parNew}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(COMMONSRC)\share\vm\gc_implementation\concurrentMarkSweep}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(COMMONSRC)\share\vm\gc_implementation\g1}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(COMMONSRC)\share\vm\gc_interface}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(COMMONSRC)\share\vm\asm}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(COMMONSRC)\share\vm\memory}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(COMMONSRC)\share\vm\oops}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(COMMONSRC)\share\vm\prims}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(COMMONSRC)\share\vm\runtime}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(COMMONSRC)\share\vm\services}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(COMMONSRC)\share\vm\trace}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(COMMONSRC)\share\vm\utilities}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(COMMONSRC)\share\vm\libadt}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(COMMONSRC)\share\vm\opto}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(COMMONSRC)\os\windows\vm}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< # This guy should remain a single colon rule because # otherwise we can't specify the output filename. @@ -296,113 +296,113 @@ @$(RC) $(RC_FLAGS) /fo"$@" $< {$(COMMONSRC)\cpu\$(Platform_arch)\vm}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(COMMONSRC)\os_cpu\windows_$(Platform_arch)\vm}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\c1}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\compiler}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\code}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\interpreter}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\ci}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\classfile}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\gc_implementation\parallelScavenge}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\gc_implementation\shared}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\gc_implementation\parNew}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\gc_implementation\concurrentMarkSweep}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\gc_implementation\g1}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\gc_interface}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\asm}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\memory}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\oops}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\prims}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\runtime}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\services}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\trace}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\utilities}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\libadt}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\opto}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\os\windows\vm}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< # otherwise we can't specify the output filename. {$(ALTSRC)\os\windows\vm}.rc.res: @$(RC) $(RC_FLAGS) /fo"$@" $< {$(ALTSRC)\cpu\$(Platform_arch)\vm}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\os_cpu\windows_$(Platform_arch)\vm}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {..\generated\incls}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {..\generated\adfiles}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {..\generated\jvmtifiles}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\jfr}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\jfr\agent}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\jfr\agent\isolated_deps\util}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< {$(ALTSRC)\share\vm\jfr\jvm}.cpp.obj:: - $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $< default:: _build_pch_file.obj: @echo #include "precompiled.hpp" > ../generated/_build_pch_file.cpp - $(CPP) $(CPP_FLAGS) /Fp"vm.pch" /Yc"precompiled.hpp" /c ../generated/_build_pch_file.cpp + $(CXX) $(CXX_FLAGS) /Fp"vm.pch" /Yc"precompiled.hpp" /c ../generated/_build_pch_file.cpp diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/cpu/sparc/vm/assembler_sparc.hpp --- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Thu Feb 09 23:17:22 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 @@ -2134,6 +2134,7 @@ // address pseudos: make these names unlike instruction names to avoid confusion inline intptr_t load_pc_address( Register reg, int bytes_to_skip ); inline void load_contents(const AddressLiteral& addrlit, Register d, int offset = 0); + inline void load_bool_contents(const AddressLiteral& addrlit, Register d, int offset = 0); inline void load_ptr_contents(const AddressLiteral& addrlit, Register d, int offset = 0); inline void store_contents(Register s, const AddressLiteral& addrlit, Register temp, int offset = 0); inline void store_ptr_contents(Register s, const AddressLiteral& addrlit, Register temp, int offset = 0); @@ -2249,7 +2250,7 @@ // this platform we assume byte size inline void stbool(Register d, const Address& a) { stb(d, a); } - inline void ldbool(const Address& a, Register d) { ldsb(a, d); } + inline void ldbool(const Address& a, Register d) { ldub(a, d); } inline void movbool( bool boolconst, Register d) { mov( (int) boolconst, d); } // klass oop manipulations if compressed diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp --- a/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp Thu Feb 09 23:17:22 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 @@ -692,6 +692,17 @@ } +inline void MacroAssembler::load_bool_contents(const AddressLiteral& addrlit, Register d, int offset) { + assert_not_delayed(); + if (ForceUnreachable) { + patchable_sethi(addrlit, d); + } else { + sethi(addrlit, d); + } + ldub(d, addrlit.low10() + offset, d); +} + + inline void MacroAssembler::load_ptr_contents(const AddressLiteral& addrlit, Register d, int offset) { assert_not_delayed(); if (ForceUnreachable) { diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp Thu Feb 09 23:17:22 2012 -0800 @@ -472,7 +472,7 @@ __ load_klass(src_reg, tmp_reg); Address ref_type_adr(tmp_reg, instanceKlass::reference_type_offset()); - __ ld(ref_type_adr, tmp_reg); + __ ldub(ref_type_adr, tmp_reg); // _reference_type field is of type ReferenceType (enum) assert(REF_NONE == 0, "check this code"); diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp --- a/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -42,7 +42,7 @@ #else define_pd_global(bool, ProfileInterpreter, true); #endif // CC_INTERP -define_pd_global(bool, TieredCompilation, true); +define_pd_global(bool, TieredCompilation, trueInTiered); define_pd_global(intx, CompileThreshold, 10000); define_pd_global(intx, BackEdgeThreshold, 140000); diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/cpu/sparc/vm/frame_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp Thu Feb 09 23:17:22 2012 -0800 @@ -28,6 +28,7 @@ #include "oops/markOop.hpp" #include "oops/methodOop.hpp" #include "oops/oop.inline.hpp" +#include "prims/methodHandles.hpp" #include "runtime/frame.inline.hpp" #include "runtime/handles.inline.hpp" #include "runtime/javaCalls.hpp" diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Thu Feb 09 23:17:22 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 @@ -321,6 +321,16 @@ return (r->reg2stack() + SharedRuntime::out_preserve_stack_slots()) * VMRegImpl::stack_slot_size; } +static VMRegPair reg64_to_VMRegPair(Register r) { + VMRegPair ret; + if (wordSize == 8) { + ret.set2(r->as_VMReg()); + } else { + ret.set_pair(r->successor()->as_VMReg(), r->as_VMReg()); + } + return ret; +} + // --------------------------------------------------------------------------- // Read the array of BasicTypes from a signature, and compute where the // arguments should go. Values in the VMRegPair regs array refer to 4-byte (VMRegImpl::stack_slot_size) @@ -1444,6 +1454,25 @@ } +static void move_ptr(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { + if (src.first()->is_stack()) { + if (dst.first()->is_stack()) { + // stack to stack + __ ld_ptr(FP, reg2offset(src.first()) + STACK_BIAS, L5); + __ st_ptr(L5, SP, reg2offset(dst.first()) + STACK_BIAS); + } else { + // stack to reg + __ ld_ptr(FP, reg2offset(src.first()) + STACK_BIAS, dst.first()->as_Register()); + } + } else if (dst.first()->is_stack()) { + // reg to stack + __ st_ptr(src.first()->as_Register(), SP, reg2offset(dst.first()) + STACK_BIAS); + } else { + __ mov(src.first()->as_Register(), dst.first()->as_Register()); + } +} + + // An oop arg. Must pass a handle not the oop itself static void object_move(MacroAssembler* masm, OopMap* map, @@ -1748,6 +1777,166 @@ } } + +static void save_or_restore_arguments(MacroAssembler* masm, + const int stack_slots, + const int total_in_args, + const int arg_save_area, + OopMap* map, + VMRegPair* in_regs, + BasicType* in_sig_bt) { + // if map is non-NULL then the code should store the values, + // otherwise it should load them. + if (map != NULL) { + // Fill in the map + for (int i = 0; i < total_in_args; i++) { + if (in_sig_bt[i] == T_ARRAY) { + if (in_regs[i].first()->is_stack()) { + int offset_in_older_frame = in_regs[i].first()->reg2stack() + SharedRuntime::out_preserve_stack_slots(); + map->set_oop(VMRegImpl::stack2reg(offset_in_older_frame + stack_slots)); + } else if (in_regs[i].first()->is_Register()) { + map->set_oop(in_regs[i].first()); + } else { + ShouldNotReachHere(); + } + } + } + } + + // Save or restore double word values + int handle_index = 0; + for (int i = 0; i < total_in_args; i++) { + int slot = handle_index + arg_save_area; + int offset = slot * VMRegImpl::stack_slot_size; + if (in_sig_bt[i] == T_LONG && in_regs[i].first()->is_Register()) { + const Register reg = in_regs[i].first()->as_Register(); + if (reg->is_global()) { + handle_index += 2; + assert(handle_index <= stack_slots, "overflow"); + if (map != NULL) { + __ stx(reg, SP, offset + STACK_BIAS); + } else { + __ ldx(SP, offset + STACK_BIAS, reg); + } + } + } else if (in_sig_bt[i] == T_DOUBLE && in_regs[i].first()->is_FloatRegister()) { + handle_index += 2; + assert(handle_index <= stack_slots, "overflow"); + if (map != NULL) { + __ stf(FloatRegisterImpl::D, in_regs[i].first()->as_FloatRegister(), SP, offset + STACK_BIAS); + } else { + __ ldf(FloatRegisterImpl::D, SP, offset + STACK_BIAS, in_regs[i].first()->as_FloatRegister()); + } + } + } + // Save floats + for (int i = 0; i < total_in_args; i++) { + int slot = handle_index + arg_save_area; + int offset = slot * VMRegImpl::stack_slot_size; + if (in_sig_bt[i] == T_FLOAT && in_regs[i].first()->is_FloatRegister()) { + handle_index++; + assert(handle_index <= stack_slots, "overflow"); + if (map != NULL) { + __ stf(FloatRegisterImpl::S, in_regs[i].first()->as_FloatRegister(), SP, offset + STACK_BIAS); + } else { + __ ldf(FloatRegisterImpl::S, SP, offset + STACK_BIAS, in_regs[i].first()->as_FloatRegister()); + } + } + } + +} + + +// Check GC_locker::needs_gc and enter the runtime if it's true. This +// keeps a new JNI critical region from starting until a GC has been +// forced. Save down any oops in registers and describe them in an +// OopMap. +static void check_needs_gc_for_critical_native(MacroAssembler* masm, + const int stack_slots, + const int total_in_args, + const int arg_save_area, + OopMapSet* oop_maps, + VMRegPair* in_regs, + BasicType* in_sig_bt) { + __ block_comment("check GC_locker::needs_gc"); + Label cont; + AddressLiteral sync_state(GC_locker::needs_gc_address()); + __ load_bool_contents(sync_state, G3_scratch); + __ cmp_zero_and_br(Assembler::equal, G3_scratch, cont); + __ delayed()->nop(); + + // Save down any values that are live in registers and call into the + // runtime to halt for a GC + OopMap* map = new OopMap(stack_slots * 2, 0 /* arg_slots*/); + save_or_restore_arguments(masm, stack_slots, total_in_args, + arg_save_area, map, in_regs, in_sig_bt); + + __ mov(G2_thread, L7_thread_cache); + + __ set_last_Java_frame(SP, noreg); + + __ block_comment("block_for_jni_critical"); + __ call(CAST_FROM_FN_PTR(address, SharedRuntime::block_for_jni_critical), relocInfo::runtime_call_type); + __ delayed()->mov(L7_thread_cache, O0); + oop_maps->add_gc_map( __ offset(), map); + + __ restore_thread(L7_thread_cache); // restore G2_thread + __ reset_last_Java_frame(); + + // Reload all the register arguments + save_or_restore_arguments(masm, stack_slots, total_in_args, + arg_save_area, NULL, in_regs, in_sig_bt); + + __ bind(cont); +#ifdef ASSERT + if (StressCriticalJNINatives) { + // Stress register saving + OopMap* map = new OopMap(stack_slots * 2, 0 /* arg_slots*/); + save_or_restore_arguments(masm, stack_slots, total_in_args, + arg_save_area, map, in_regs, in_sig_bt); + // Destroy argument registers + for (int i = 0; i < total_in_args; i++) { + if (in_regs[i].first()->is_Register()) { + const Register reg = in_regs[i].first()->as_Register(); + if (reg->is_global()) { + __ mov(G0, reg); + } + } else if (in_regs[i].first()->is_FloatRegister()) { + __ fneg(FloatRegisterImpl::D, in_regs[i].first()->as_FloatRegister(), in_regs[i].first()->as_FloatRegister()); + } + } + + save_or_restore_arguments(masm, stack_slots, total_in_args, + arg_save_area, NULL, in_regs, in_sig_bt); + } +#endif +} + +// Unpack an array argument into a pointer to the body and the length +// if the array is non-null, otherwise pass 0 for both. +static void unpack_array_argument(MacroAssembler* masm, VMRegPair reg, BasicType in_elem_type, VMRegPair body_arg, VMRegPair length_arg) { + // Pass the length, ptr pair + Label is_null, done; + if (reg.first()->is_stack()) { + VMRegPair tmp = reg64_to_VMRegPair(L2); + // Load the arg up from the stack + move_ptr(masm, reg, tmp); + reg = tmp; + } + __ cmp(reg.first()->as_Register(), G0); + __ brx(Assembler::equal, false, Assembler::pt, is_null); + __ delayed()->add(reg.first()->as_Register(), arrayOopDesc::base_offset_in_bytes(in_elem_type), L4); + move_ptr(masm, reg64_to_VMRegPair(L4), body_arg); + __ ld(reg.first()->as_Register(), arrayOopDesc::length_offset_in_bytes(), L4); + move32_64(masm, reg64_to_VMRegPair(L4), length_arg); + __ ba_short(done); + __ bind(is_null); + // Pass zeros + move_ptr(masm, reg64_to_VMRegPair(G0), body_arg); + move32_64(masm, reg64_to_VMRegPair(G0), length_arg); + __ bind(done); +} + // --------------------------------------------------------------------------- // Generate a native wrapper for a given method. The method takes arguments // in the Java compiled code convention, marshals them to the native @@ -1762,6 +1951,13 @@ BasicType *in_sig_bt, VMRegPair *in_regs, BasicType ret_type) { + bool is_critical_native = true; + address native_func = method->critical_native_function(); + if (native_func == NULL) { + native_func = method->native_function(); + is_critical_native = false; + } + assert(native_func != NULL, "must have function"); // Native nmethod wrappers never take possesion of the oop arguments. // So the caller will gc the arguments. The only thing we need an @@ -1841,22 +2037,70 @@ // we convert the java signature to a C signature by inserting // the hidden arguments as arg[0] and possibly arg[1] (static method) - int total_c_args = total_in_args + 1; - if (method->is_static()) { - total_c_args++; + int total_c_args = total_in_args; + int total_save_slots = 6 * VMRegImpl::slots_per_word; + if (!is_critical_native) { + total_c_args += 1; + if (method->is_static()) { + total_c_args++; + } + } else { + for (int i = 0; i < total_in_args; i++) { + if (in_sig_bt[i] == T_ARRAY) { + // These have to be saved and restored across the safepoint + total_c_args++; + } + } } BasicType* out_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_c_args); - VMRegPair * out_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_c_args); + VMRegPair* out_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_c_args); + BasicType* in_elem_bt = NULL; int argc = 0; - out_sig_bt[argc++] = T_ADDRESS; - if (method->is_static()) { - out_sig_bt[argc++] = T_OBJECT; - } - - for (int i = 0; i < total_in_args ; i++ ) { - out_sig_bt[argc++] = in_sig_bt[i]; + if (!is_critical_native) { + out_sig_bt[argc++] = T_ADDRESS; + if (method->is_static()) { + out_sig_bt[argc++] = T_OBJECT; + } + + for (int i = 0; i < total_in_args ; i++ ) { + out_sig_bt[argc++] = in_sig_bt[i]; + } + } else { + Thread* THREAD = Thread::current(); + in_elem_bt = NEW_RESOURCE_ARRAY(BasicType, total_in_args); + SignatureStream ss(method->signature()); + for (int i = 0; i < total_in_args ; i++ ) { + if (in_sig_bt[i] == T_ARRAY) { + // Arrays are passed as int, elem* pair + out_sig_bt[argc++] = T_INT; + out_sig_bt[argc++] = T_ADDRESS; + Symbol* atype = ss.as_symbol(CHECK_NULL); + const char* at = atype->as_C_string(); + if (strlen(at) == 2) { + assert(at[0] == '[', "must be"); + switch (at[1]) { + case 'B': in_elem_bt[i] = T_BYTE; break; + case 'C': in_elem_bt[i] = T_CHAR; break; + case 'D': in_elem_bt[i] = T_DOUBLE; break; + case 'F': in_elem_bt[i] = T_FLOAT; break; + case 'I': in_elem_bt[i] = T_INT; break; + case 'J': in_elem_bt[i] = T_LONG; break; + case 'S': in_elem_bt[i] = T_SHORT; break; + case 'Z': in_elem_bt[i] = T_BOOLEAN; break; + default: ShouldNotReachHere(); + } + } + } else { + out_sig_bt[argc++] = in_sig_bt[i]; + in_elem_bt[i] = T_VOID; + } + if (in_sig_bt[i] != T_VOID) { + assert(in_sig_bt[i] == ss.type(), "must match"); + ss.next(); + } + } } // Now figure out where the args must be stored and how much stack space @@ -1866,6 +2110,35 @@ int out_arg_slots; out_arg_slots = c_calling_convention(out_sig_bt, out_regs, total_c_args); + if (is_critical_native) { + // Critical natives may have to call out so they need a save area + // for register arguments. + int double_slots = 0; + int single_slots = 0; + for ( int i = 0; i < total_in_args; i++) { + if (in_regs[i].first()->is_Register()) { + const Register reg = in_regs[i].first()->as_Register(); + switch (in_sig_bt[i]) { + case T_ARRAY: + case T_BOOLEAN: + case T_BYTE: + case T_SHORT: + case T_CHAR: + case T_INT: assert(reg->is_in(), "don't need to save these"); break; + case T_LONG: if (reg->is_global()) double_slots++; break; + default: ShouldNotReachHere(); + } + } else if (in_regs[i].first()->is_FloatRegister()) { + switch (in_sig_bt[i]) { + case T_FLOAT: single_slots++; break; + case T_DOUBLE: double_slots++; break; + default: ShouldNotReachHere(); + } + } + } + total_save_slots = double_slots * 2 + single_slots; + } + // Compute framesize for the wrapper. We need to handlize all oops in // registers. We must create space for them here that is disjoint from // the windowed save area because we have no control over when we might @@ -1885,12 +2158,11 @@ // Now the space for the inbound oop handle area - int oop_handle_offset = stack_slots; - stack_slots += 6*VMRegImpl::slots_per_word; + int oop_handle_offset = round_to(stack_slots, 2); + stack_slots += total_save_slots; // Now any space we need for handlizing a klass if static method - int oop_temp_slot_offset = 0; int klass_slot_offset = 0; int klass_offset = -1; int lock_slot_offset = 0; @@ -1954,6 +2226,10 @@ __ verify_thread(); + if (is_critical_native) { + check_needs_gc_for_critical_native(masm, stack_slots, total_in_args, + oop_handle_offset, oop_maps, in_regs, in_sig_bt); + } // // We immediately shuffle the arguments so that any vm call we have to @@ -1982,7 +2258,6 @@ // caller. // OopMap* map = new OopMap(stack_slots * 2, 0 /* arg_slots*/); - int c_arg = total_c_args - 1; // Record sp-based slot for receiver on stack for non-static methods int receiver_offset = -1; @@ -2002,7 +2277,7 @@ #endif /* ASSERT */ - for ( int i = total_in_args - 1; i >= 0 ; i--, c_arg-- ) { + for ( int i = total_in_args - 1, c_arg = total_c_args - 1; i >= 0 ; i--, c_arg-- ) { #ifdef ASSERT if (in_regs[i].first()->is_Register()) { @@ -2019,7 +2294,13 @@ switch (in_sig_bt[i]) { case T_ARRAY: + if (is_critical_native) { + unpack_array_argument(masm, in_regs[i], in_elem_bt[i], out_regs[c_arg], out_regs[c_arg - 1]); + c_arg--; + break; + } case T_OBJECT: + assert(!is_critical_native, "no oop arguments"); object_move(masm, map, oop_handle_offset, stack_slots, in_regs[i], out_regs[c_arg], ((i == 0) && (!is_static)), &receiver_offset); @@ -2029,7 +2310,7 @@ case T_FLOAT: float_move(masm, in_regs[i], out_regs[c_arg]); - break; + break; case T_DOUBLE: assert( i + 1 < total_in_args && @@ -2051,7 +2332,7 @@ // Pre-load a static method's oop into O1. Used both by locking code and // the normal JNI call code. - if (method->is_static()) { + if (method->is_static() && !is_critical_native) { __ set_oop_constant(JNIHandles::make_local(Klass::cast(method->method_holder())->java_mirror()), O1); // Now handlize the static class mirror in O1. It's known not-null. @@ -2064,13 +2345,13 @@ const Register L6_handle = L6; if (method->is_synchronized()) { + assert(!is_critical_native, "unhandled"); __ mov(O1, L6_handle); } // We have all of the arguments setup at this point. We MUST NOT touch any Oregs // except O6/O7. So if we must call out we must push a new frame. We immediately // push a new frame and flush the windows. - #ifdef _LP64 intptr_t thepc = (intptr_t) __ pc(); { @@ -2202,32 +2483,28 @@ } // get JNIEnv* which is first argument to native - - __ add(G2_thread, in_bytes(JavaThread::jni_environment_offset()), O0); + if (!is_critical_native) { + __ add(G2_thread, in_bytes(JavaThread::jni_environment_offset()), O0); + } // Use that pc we placed in O7 a while back as the current frame anchor - __ set_last_Java_frame(SP, O7); + // We flushed the windows ages ago now mark them as flushed before transitioning. + __ set(JavaFrameAnchor::flushed, G3_scratch); + __ st(G3_scratch, G2_thread, JavaThread::frame_anchor_offset() + JavaFrameAnchor::flags_offset()); + // Transition from _thread_in_Java to _thread_in_native. __ set(_thread_in_native, G3_scratch); - __ st(G3_scratch, G2_thread, JavaThread::thread_state_offset()); - - // We flushed the windows ages ago now mark them as flushed - - // mark windows as flushed - __ set(JavaFrameAnchor::flushed, G3_scratch); - - Address flags(G2_thread, JavaThread::frame_anchor_offset() + JavaFrameAnchor::flags_offset()); #ifdef _LP64 - AddressLiteral dest(method->native_function()); + AddressLiteral dest(native_func); __ relocate(relocInfo::runtime_call_type); __ jumpl_to(dest, O7, O7); #else - __ call(method->native_function(), relocInfo::runtime_call_type); + __ call(native_func, relocInfo::runtime_call_type); #endif - __ delayed()->st(G3_scratch, flags); + __ delayed()->st(G3_scratch, G2_thread, JavaThread::thread_state_offset()); __ restore_thread(L7_thread_cache); // restore G2_thread @@ -2259,6 +2536,7 @@ ShouldNotReachHere(); } + Label after_transition; // must we block? // Block, if necessary, before resuming in _thread_in_Java state. @@ -2303,22 +2581,34 @@ // a distinct one for this pc // save_native_result(masm, ret_type, stack_slots); - __ call_VM_leaf(L7_thread_cache, - CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans), - G2_thread); + if (!is_critical_native) { + __ call_VM_leaf(L7_thread_cache, + CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans), + G2_thread); + } else { + __ call_VM_leaf(L7_thread_cache, + CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans_and_transition), + G2_thread); + } // Restore any method result value restore_native_result(masm, ret_type, stack_slots); + + if (is_critical_native) { + // The call above performed the transition to thread_in_Java so + // skip the transition logic below. + __ ba(after_transition); + __ delayed()->nop(); + } + __ bind(no_block); } // thread state is thread_in_native_trans. Any safepoint blocking has already // happened so we can now change state to _thread_in_Java. - - __ set(_thread_in_Java, G3_scratch); __ st(G3_scratch, G2_thread, JavaThread::thread_state_offset()); - + __ bind(after_transition); Label no_reguard; __ ld(G2_thread, JavaThread::stack_guard_state_offset(), G3_scratch); @@ -2416,12 +2706,14 @@ __ verify_oop(I0); } - // reset handle block - __ ld_ptr(G2_thread, in_bytes(JavaThread::active_handles_offset()), L5); - __ st_ptr(G0, L5, JNIHandleBlock::top_offset_in_bytes()); - - __ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), G3_scratch); - check_forward_pending_exception(masm, G3_scratch); + if (!is_critical_native) { + // reset handle block + __ ld_ptr(G2_thread, in_bytes(JavaThread::active_handles_offset()), L5); + __ st_ptr(G0, L5, JNIHandleBlock::top_offset_in_bytes()); + + __ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), G3_scratch); + check_forward_pending_exception(masm, G3_scratch); + } // Return @@ -2450,6 +2742,10 @@ (is_static ? in_ByteSize(klass_offset) : in_ByteSize(receiver_offset)), in_ByteSize(lock_offset), oop_maps); + + if (is_critical_native) { + nm->set_lazy_critical_native(true); + } return nm; } @@ -2473,17 +2769,6 @@ static int fp_offset[ConcreteRegisterImpl::number_of_registers] = { 0 }; static bool offsets_initialized = false; -static VMRegPair reg64_to_VMRegPair(Register r) { - VMRegPair ret; - if (wordSize == 8) { - ret.set2(r->as_VMReg()); - } else { - ret.set_pair(r->successor()->as_VMReg(), r->as_VMReg()); - } - return ret; -} - - nmethod *SharedRuntime::generate_dtrace_nmethod( MacroAssembler *masm, methodHandle method) { diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp --- a/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp Thu Feb 09 23:17:22 2012 -0800 @@ -520,7 +520,7 @@ __ load_klass(tmp_reg, src_reg); Address ref_type_adr(tmp_reg, instanceKlass::reference_type_offset()); - __ cmpl(ref_type_adr, REF_NONE); + __ cmpb(ref_type_adr, REF_NONE); __ jcc(Assembler::equal, _continuation); // Is marking active? diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/cpu/x86/vm/c2_globals_x86.hpp --- a/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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,7 +44,7 @@ #else define_pd_global(bool, ProfileInterpreter, true); #endif // CC_INTERP -define_pd_global(bool, TieredCompilation, true); +define_pd_global(bool, TieredCompilation, trueInTiered); define_pd_global(intx, CompileThreshold, 10000); define_pd_global(intx, BackEdgeThreshold, 100000); diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/cpu/x86/vm/frame_x86.cpp --- a/hotspot/src/cpu/x86/vm/frame_x86.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp Thu Feb 09 23:17:22 2012 -0800 @@ -28,6 +28,7 @@ #include "oops/markOop.hpp" #include "oops/methodOop.hpp" #include "oops/oop.inline.hpp" +#include "prims/methodHandles.hpp" #include "runtime/frame.inline.hpp" #include "runtime/handles.inline.hpp" #include "runtime/javaCalls.hpp" diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/cpu/x86/vm/methodHandles_x86.cpp --- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp Thu Feb 09 23:17:22 2012 -0800 @@ -2364,23 +2364,19 @@ // grab another temp Register rsi_temp = rsi; - { if (rsi_temp == saved_last_sp) __ push(saved_last_sp); } - // (preceding push must be done after argslot address is taken!) -#define UNPUSH_RSI \ - { if (rsi_temp == saved_last_sp) __ pop(saved_last_sp); } // arx_argslot points both to the array and to the first output arg vmarg = Address(rax_argslot, 0); // Get the array value. - Register rsi_array = rsi_temp; + Register rdi_array = rdi_temp; Register rdx_array_klass = rdx_temp; BasicType elem_type = ek_adapter_opt_spread_type(ek); int elem_slots = type2size[elem_type]; // 1 or 2 int array_slots = 1; // array is always a T_OBJECT int length_offset = arrayOopDesc::length_offset_in_bytes(); int elem0_offset = arrayOopDesc::base_offset_in_bytes(elem_type); - __ movptr(rsi_array, vmarg); + __ movptr(rdi_array, vmarg); Label L_array_is_empty, L_insert_arg_space, L_copy_args, L_args_done; if (length_can_be_zero) { @@ -2391,12 +2387,30 @@ __ testl(rbx_temp, rbx_temp); __ jcc(Assembler::notZero, L_skip); } - __ testptr(rsi_array, rsi_array); - __ jcc(Assembler::zero, L_array_is_empty); + __ testptr(rdi_array, rdi_array); + __ jcc(Assembler::notZero, L_skip); + + // If 'rsi' contains the 'saved_last_sp' (this is only the + // case in a 32-bit version of the VM) we have to save 'rsi' + // on the stack because later on (at 'L_array_is_empty') 'rsi' + // will be overwritten. + { if (rsi_temp == saved_last_sp) __ push(saved_last_sp); } + // Also prepare a handy macro which restores 'rsi' if required. +#define UNPUSH_RSI \ + { if (rsi_temp == saved_last_sp) __ pop(saved_last_sp); } + + __ jmp(L_array_is_empty); __ bind(L_skip); } - __ null_check(rsi_array, oopDesc::klass_offset_in_bytes()); - __ load_klass(rdx_array_klass, rsi_array); + __ null_check(rdi_array, oopDesc::klass_offset_in_bytes()); + __ load_klass(rdx_array_klass, rdi_array); + + // Save 'rsi' if required (see comment above). Do this only + // after the null check such that the exception handler which is + // called in the case of a null pointer exception will not be + // confused by the extra value on the stack (it expects the + // return pointer on top of the stack) + { if (rsi_temp == saved_last_sp) __ push(saved_last_sp); } // Check the array type. Register rbx_klass = rbx_temp; @@ -2404,18 +2418,18 @@ load_klass_from_Class(_masm, rbx_klass); Label ok_array_klass, bad_array_klass, bad_array_length; - __ check_klass_subtype(rdx_array_klass, rbx_klass, rdi_temp, ok_array_klass); + __ check_klass_subtype(rdx_array_klass, rbx_klass, rsi_temp, ok_array_klass); // If we get here, the type check failed! __ jmp(bad_array_klass); __ BIND(ok_array_klass); // Check length. if (length_constant >= 0) { - __ cmpl(Address(rsi_array, length_offset), length_constant); + __ cmpl(Address(rdi_array, length_offset), length_constant); } else { Register rbx_vminfo = rbx_temp; load_conversion_vminfo(_masm, rbx_vminfo, rcx_amh_conversion); - __ cmpl(rbx_vminfo, Address(rsi_array, length_offset)); + __ cmpl(rbx_vminfo, Address(rdi_array, length_offset)); } __ jcc(Assembler::notEqual, bad_array_length); @@ -2427,9 +2441,9 @@ __ lea(rdx_argslot_limit, Address(rax_argslot, Interpreter::stackElementSize)); // 'stack_move' is negative number of words to insert // This number already accounts for elem_slots. - Register rdi_stack_move = rdi_temp; - load_stack_move(_masm, rdi_stack_move, rcx_recv, true); - __ cmpptr(rdi_stack_move, 0); + Register rsi_stack_move = rsi_temp; + load_stack_move(_masm, rsi_stack_move, rcx_recv, true); + __ cmpptr(rsi_stack_move, 0); assert(stack_move_unit() < 0, "else change this comparison"); __ jcc(Assembler::less, L_insert_arg_space); __ jcc(Assembler::equal, L_copy_args); @@ -2440,12 +2454,12 @@ __ jmp(L_args_done); // no spreading to do __ BIND(L_insert_arg_space); // come here in the usual case, stack_move < 0 (2 or more spread arguments) - Register rsi_temp = rsi_array; // spill this - insert_arg_slots(_masm, rdi_stack_move, - rax_argslot, rbx_temp, rsi_temp); + Register rdi_temp = rdi_array; // spill this + insert_arg_slots(_masm, rsi_stack_move, + rax_argslot, rbx_temp, rdi_temp); // reload the array since rsi was killed // reload from rdx_argslot_limit since rax_argslot is now decremented - __ movptr(rsi_array, Address(rdx_argslot_limit, -Interpreter::stackElementSize)); + __ movptr(rdi_array, Address(rdx_argslot_limit, -Interpreter::stackElementSize)); } else if (length_constant >= 1) { int new_slots = (length_constant * elem_slots) - array_slots; insert_arg_slots(_masm, new_slots * stack_move_unit(), @@ -2468,16 +2482,16 @@ if (length_constant == -1) { // [rax_argslot, rdx_argslot_limit) is the area we are inserting into. // Array element [0] goes at rdx_argslot_limit[-wordSize]. - Register rsi_source = rsi_array; - __ lea(rsi_source, Address(rsi_array, elem0_offset)); + Register rdi_source = rdi_array; + __ lea(rdi_source, Address(rdi_array, elem0_offset)); Register rdx_fill_ptr = rdx_argslot_limit; Label loop; __ BIND(loop); __ addptr(rdx_fill_ptr, -Interpreter::stackElementSize * elem_slots); move_typed_arg(_masm, elem_type, true, - Address(rdx_fill_ptr, 0), Address(rsi_source, 0), - rbx_temp, rdi_temp); - __ addptr(rsi_source, type2aelembytes(elem_type)); + Address(rdx_fill_ptr, 0), Address(rdi_source, 0), + rbx_temp, rsi_temp); + __ addptr(rdi_source, type2aelembytes(elem_type)); __ cmpptr(rdx_fill_ptr, rax_argslot); __ jcc(Assembler::above, loop); } else if (length_constant == 0) { @@ -2488,8 +2502,8 @@ for (int index = 0; index < length_constant; index++) { slot_offset -= Interpreter::stackElementSize * elem_slots; // fill backward move_typed_arg(_masm, elem_type, true, - Address(rax_argslot, slot_offset), Address(rsi_array, elem_offset), - rbx_temp, rdi_temp); + Address(rax_argslot, slot_offset), Address(rdi_array, elem_offset), + rbx_temp, rsi_temp); elem_offset += type2aelembytes(elem_type); } } diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp --- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Thu Feb 09 23:17:22 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 @@ -1091,12 +1091,238 @@ } } + +static void save_or_restore_arguments(MacroAssembler* masm, + const int stack_slots, + const int total_in_args, + const int arg_save_area, + OopMap* map, + VMRegPair* in_regs, + BasicType* in_sig_bt) { + // if map is non-NULL then the code should store the values, + // otherwise it should load them. + int handle_index = 0; + // Save down double word first + for ( int i = 0; i < total_in_args; i++) { + if (in_regs[i].first()->is_XMMRegister() && in_sig_bt[i] == T_DOUBLE) { + int slot = handle_index * VMRegImpl::slots_per_word + arg_save_area; + int offset = slot * VMRegImpl::stack_slot_size; + handle_index += 2; + assert(handle_index <= stack_slots, "overflow"); + if (map != NULL) { + __ movdbl(Address(rsp, offset), in_regs[i].first()->as_XMMRegister()); + } else { + __ movdbl(in_regs[i].first()->as_XMMRegister(), Address(rsp, offset)); + } + } + if (in_regs[i].first()->is_Register() && in_sig_bt[i] == T_LONG) { + int slot = handle_index * VMRegImpl::slots_per_word + arg_save_area; + int offset = slot * VMRegImpl::stack_slot_size; + handle_index += 2; + assert(handle_index <= stack_slots, "overflow"); + if (map != NULL) { + __ movl(Address(rsp, offset), in_regs[i].first()->as_Register()); + if (in_regs[i].second()->is_Register()) { + __ movl(Address(rsp, offset + 4), in_regs[i].second()->as_Register()); + } + } else { + __ movl(in_regs[i].first()->as_Register(), Address(rsp, offset)); + if (in_regs[i].second()->is_Register()) { + __ movl(in_regs[i].second()->as_Register(), Address(rsp, offset + 4)); + } + } + } + } + // Save or restore single word registers + for ( int i = 0; i < total_in_args; i++) { + if (in_regs[i].first()->is_Register()) { + int slot = handle_index++ * VMRegImpl::slots_per_word + arg_save_area; + int offset = slot * VMRegImpl::stack_slot_size; + assert(handle_index <= stack_slots, "overflow"); + if (in_sig_bt[i] == T_ARRAY && map != NULL) { + map->set_oop(VMRegImpl::stack2reg(slot));; + } + + // Value is in an input register pass we must flush it to the stack + const Register reg = in_regs[i].first()->as_Register(); + switch (in_sig_bt[i]) { + case T_ARRAY: + if (map != NULL) { + __ movptr(Address(rsp, offset), reg); + } else { + __ movptr(reg, Address(rsp, offset)); + } + break; + case T_BOOLEAN: + case T_CHAR: + case T_BYTE: + case T_SHORT: + case T_INT: + if (map != NULL) { + __ movl(Address(rsp, offset), reg); + } else { + __ movl(reg, Address(rsp, offset)); + } + break; + case T_OBJECT: + default: ShouldNotReachHere(); + } + } else if (in_regs[i].first()->is_XMMRegister()) { + if (in_sig_bt[i] == T_FLOAT) { + int slot = handle_index++ * VMRegImpl::slots_per_word + arg_save_area; + int offset = slot * VMRegImpl::stack_slot_size; + assert(handle_index <= stack_slots, "overflow"); + if (map != NULL) { + __ movflt(Address(rsp, offset), in_regs[i].first()->as_XMMRegister()); + } else { + __ movflt(in_regs[i].first()->as_XMMRegister(), Address(rsp, offset)); + } + } + } else if (in_regs[i].first()->is_stack()) { + if (in_sig_bt[i] == T_ARRAY && map != NULL) { + int offset_in_older_frame = in_regs[i].first()->reg2stack() + SharedRuntime::out_preserve_stack_slots(); + map->set_oop(VMRegImpl::stack2reg(offset_in_older_frame + stack_slots)); + } + } + } +} + +// Check GC_locker::needs_gc and enter the runtime if it's true. This +// keeps a new JNI critical region from starting until a GC has been +// forced. Save down any oops in registers and describe them in an +// OopMap. +static void check_needs_gc_for_critical_native(MacroAssembler* masm, + Register thread, + int stack_slots, + int total_c_args, + int total_in_args, + int arg_save_area, + OopMapSet* oop_maps, + VMRegPair* in_regs, + BasicType* in_sig_bt) { + __ block_comment("check GC_locker::needs_gc"); + Label cont; + __ cmp8(ExternalAddress((address)GC_locker::needs_gc_address()), false); + __ jcc(Assembler::equal, cont); + + // Save down any incoming oops and call into the runtime to halt for a GC + + OopMap* map = new OopMap(stack_slots * 2, 0 /* arg_slots*/); + + save_or_restore_arguments(masm, stack_slots, total_in_args, + arg_save_area, map, in_regs, in_sig_bt); + + address the_pc = __ pc(); + oop_maps->add_gc_map( __ offset(), map); + __ set_last_Java_frame(thread, rsp, noreg, the_pc); + + __ block_comment("block_for_jni_critical"); + __ push(thread); + __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::block_for_jni_critical))); + __ increment(rsp, wordSize); + + __ get_thread(thread); + __ reset_last_Java_frame(thread, false, true); + + save_or_restore_arguments(masm, stack_slots, total_in_args, + arg_save_area, NULL, in_regs, in_sig_bt); + + __ bind(cont); +#ifdef ASSERT + if (StressCriticalJNINatives) { + // Stress register saving + OopMap* map = new OopMap(stack_slots * 2, 0 /* arg_slots*/); + save_or_restore_arguments(masm, stack_slots, total_in_args, + arg_save_area, map, in_regs, in_sig_bt); + // Destroy argument registers + for (int i = 0; i < total_in_args - 1; i++) { + if (in_regs[i].first()->is_Register()) { + const Register reg = in_regs[i].first()->as_Register(); + __ xorptr(reg, reg); + } else if (in_regs[i].first()->is_XMMRegister()) { + __ xorpd(in_regs[i].first()->as_XMMRegister(), in_regs[i].first()->as_XMMRegister()); + } else if (in_regs[i].first()->is_FloatRegister()) { + ShouldNotReachHere(); + } else if (in_regs[i].first()->is_stack()) { + // Nothing to do + } else { + ShouldNotReachHere(); + } + if (in_sig_bt[i] == T_LONG || in_sig_bt[i] == T_DOUBLE) { + i++; + } + } + + save_or_restore_arguments(masm, stack_slots, total_in_args, + arg_save_area, NULL, in_regs, in_sig_bt); + } +#endif +} + +// Unpack an array argument into a pointer to the body and the length +// if the array is non-null, otherwise pass 0 for both. +static void unpack_array_argument(MacroAssembler* masm, VMRegPair reg, BasicType in_elem_type, VMRegPair body_arg, VMRegPair length_arg) { + Register tmp_reg = rax; + assert(!body_arg.first()->is_Register() || body_arg.first()->as_Register() != tmp_reg, + "possible collision"); + assert(!length_arg.first()->is_Register() || length_arg.first()->as_Register() != tmp_reg, + "possible collision"); + + // Pass the length, ptr pair + Label is_null, done; + VMRegPair tmp(tmp_reg->as_VMReg()); + if (reg.first()->is_stack()) { + // Load the arg up from the stack + simple_move32(masm, reg, tmp); + reg = tmp; + } + __ testptr(reg.first()->as_Register(), reg.first()->as_Register()); + __ jccb(Assembler::equal, is_null); + __ lea(tmp_reg, Address(reg.first()->as_Register(), arrayOopDesc::base_offset_in_bytes(in_elem_type))); + simple_move32(masm, tmp, body_arg); + // load the length relative to the body. + __ movl(tmp_reg, Address(tmp_reg, arrayOopDesc::length_offset_in_bytes() - + arrayOopDesc::base_offset_in_bytes(in_elem_type))); + simple_move32(masm, tmp, length_arg); + __ jmpb(done); + __ bind(is_null); + // Pass zeros + __ xorptr(tmp_reg, tmp_reg); + simple_move32(masm, tmp, body_arg); + simple_move32(masm, tmp, length_arg); + __ bind(done); +} + + // --------------------------------------------------------------------------- // Generate a native wrapper for a given method. The method takes arguments // in the Java compiled code convention, marshals them to the native // convention (handlizes oops, etc), transitions to native, makes the call, // returns to java state (possibly blocking), unhandlizes any result and // returns. +// +// Critical native functions are a shorthand for the use of +// GetPrimtiveArrayCritical and disallow the use of any other JNI +// functions. The wrapper is expected to unpack the arguments before +// passing them to the callee and perform checks before and after the +// native call to ensure that they GC_locker +// lock_critical/unlock_critical semantics are followed. Some other +// parts of JNI setup are skipped like the tear down of the JNI handle +// block and the check for pending exceptions it's impossible for them +// to be thrown. +// +// They are roughly structured like this: +// if (GC_locker::needs_gc()) +// SharedRuntime::block_for_jni_critical(); +// tranistion to thread_in_native +// unpack arrray arguments and call native entry point +// check for safepoint in progress +// check if any thread suspend flags are set +// call into JVM and possible unlock the JNI critical +// if a GC was suppressed while in the critical native. +// transition back to thread_in_Java +// return to caller +// nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, methodHandle method, int compile_id, @@ -1105,6 +1331,13 @@ BasicType *in_sig_bt, VMRegPair *in_regs, BasicType ret_type) { + bool is_critical_native = true; + address native_func = method->critical_native_function(); + if (native_func == NULL) { + native_func = method->native_function(); + is_critical_native = false; + } + assert(native_func != NULL, "must have function"); // An OopMap for lock (and class if static) OopMapSet *oop_maps = new OopMapSet(); @@ -1115,30 +1348,72 @@ // we convert the java signature to a C signature by inserting // the hidden arguments as arg[0] and possibly arg[1] (static method) - int total_c_args = total_in_args + 1; - if (method->is_static()) { - total_c_args++; + int total_c_args = total_in_args; + if (!is_critical_native) { + total_c_args += 1; + if (method->is_static()) { + total_c_args++; + } + } else { + for (int i = 0; i < total_in_args; i++) { + if (in_sig_bt[i] == T_ARRAY) { + total_c_args++; + } + } } BasicType* out_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_c_args); - VMRegPair* out_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_c_args); + VMRegPair* out_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_c_args); + BasicType* in_elem_bt = NULL; int argc = 0; - out_sig_bt[argc++] = T_ADDRESS; - if (method->is_static()) { - out_sig_bt[argc++] = T_OBJECT; + if (!is_critical_native) { + out_sig_bt[argc++] = T_ADDRESS; + if (method->is_static()) { + out_sig_bt[argc++] = T_OBJECT; + } + + for (int i = 0; i < total_in_args ; i++ ) { + out_sig_bt[argc++] = in_sig_bt[i]; + } + } else { + Thread* THREAD = Thread::current(); + in_elem_bt = NEW_RESOURCE_ARRAY(BasicType, total_in_args); + SignatureStream ss(method->signature()); + for (int i = 0; i < total_in_args ; i++ ) { + if (in_sig_bt[i] == T_ARRAY) { + // Arrays are passed as int, elem* pair + out_sig_bt[argc++] = T_INT; + out_sig_bt[argc++] = T_ADDRESS; + Symbol* atype = ss.as_symbol(CHECK_NULL); + const char* at = atype->as_C_string(); + if (strlen(at) == 2) { + assert(at[0] == '[', "must be"); + switch (at[1]) { + case 'B': in_elem_bt[i] = T_BYTE; break; + case 'C': in_elem_bt[i] = T_CHAR; break; + case 'D': in_elem_bt[i] = T_DOUBLE; break; + case 'F': in_elem_bt[i] = T_FLOAT; break; + case 'I': in_elem_bt[i] = T_INT; break; + case 'J': in_elem_bt[i] = T_LONG; break; + case 'S': in_elem_bt[i] = T_SHORT; break; + case 'Z': in_elem_bt[i] = T_BOOLEAN; break; + default: ShouldNotReachHere(); + } + } + } else { + out_sig_bt[argc++] = in_sig_bt[i]; + in_elem_bt[i] = T_VOID; + } + if (in_sig_bt[i] != T_VOID) { + assert(in_sig_bt[i] == ss.type(), "must match"); + ss.next(); + } + } } - int i; - for (i = 0; i < total_in_args ; i++ ) { - out_sig_bt[argc++] = in_sig_bt[i]; - } - - // Now figure out where the args must be stored and how much stack space - // they require (neglecting out_preserve_stack_slots but space for storing - // the 1st six register arguments). It's weird see int_stk_helper. - // + // they require. int out_arg_slots; out_arg_slots = c_calling_convention(out_sig_bt, out_regs, total_c_args); @@ -1151,9 +1426,44 @@ int stack_slots = SharedRuntime::out_preserve_stack_slots() + out_arg_slots; // Now the space for the inbound oop handle area + int total_save_slots = 2 * VMRegImpl::slots_per_word; // 2 arguments passed in registers + if (is_critical_native) { + // Critical natives may have to call out so they need a save area + // for register arguments. + int double_slots = 0; + int single_slots = 0; + for ( int i = 0; i < total_in_args; i++) { + if (in_regs[i].first()->is_Register()) { + const Register reg = in_regs[i].first()->as_Register(); + switch (in_sig_bt[i]) { + case T_ARRAY: + case T_BOOLEAN: + case T_BYTE: + case T_SHORT: + case T_CHAR: + case T_INT: single_slots++; break; + case T_LONG: double_slots++; break; + default: ShouldNotReachHere(); + } + } else if (in_regs[i].first()->is_XMMRegister()) { + switch (in_sig_bt[i]) { + case T_FLOAT: single_slots++; break; + case T_DOUBLE: double_slots++; break; + default: ShouldNotReachHere(); + } + } else if (in_regs[i].first()->is_FloatRegister()) { + ShouldNotReachHere(); + } + } + total_save_slots = double_slots * 2 + single_slots; + // align the save area + if (double_slots != 0) { + stack_slots = round_to(stack_slots, 2); + } + } int oop_handle_offset = stack_slots; - stack_slots += 2*VMRegImpl::slots_per_word; + stack_slots += total_save_slots; // Now any space we need for handlizing a klass if static method @@ -1161,7 +1471,6 @@ int klass_offset = -1; int lock_slot_offset = 0; bool is_static = false; - int oop_temp_slot_offset = 0; if (method->is_static()) { klass_slot_offset = stack_slots; @@ -1221,7 +1530,7 @@ // First thing make an ic check to see if we should even be here // We are free to use all registers as temps without saving them and - // restoring them except rbp,. rbp, is the only callee save register + // restoring them except rbp. rbp is the only callee save register // as far as the interpreter and the compiler(s) are concerned. @@ -1230,7 +1539,6 @@ Label hit; Label exception_pending; - __ verify_oop(receiver); __ cmpptr(ic_reg, Address(receiver, oopDesc::klass_offset_in_bytes())); __ jcc(Assembler::equal, hit); @@ -1292,11 +1600,10 @@ // Generate a new frame for the wrapper. __ enter(); - // -2 because return address is already present and so is saved rbp, + // -2 because return address is already present and so is saved rbp __ subptr(rsp, stack_size - 2*wordSize); - // Frame is now completed as far a size and linkage. - + // Frame is now completed as far as size and linkage. int frame_complete = ((intptr_t)__ pc()) - start; // Calculate the difference between rsp and rbp,. We need to know it @@ -1319,7 +1626,6 @@ // Compute the rbp, offset for any slots used after the jni call int lock_slot_rbp_offset = (lock_slot_offset*VMRegImpl::stack_slot_size) - fp_adjustment; - int oop_temp_slot_rbp_offset = (oop_temp_slot_offset*VMRegImpl::stack_slot_size) - fp_adjustment; // We use rdi as a thread pointer because it is callee save and // if we load it once it is usable thru the entire wrapper @@ -1332,6 +1638,10 @@ __ get_thread(thread); + if (is_critical_native) { + check_needs_gc_for_critical_native(masm, thread, stack_slots, total_c_args, total_in_args, + oop_handle_offset, oop_maps, in_regs, in_sig_bt); + } // // We immediately shuffle the arguments so that any vm call we have to @@ -1353,7 +1663,7 @@ // vectors we have in our possession. We simply walk the java vector to // get the source locations and the c vector to get the destinations. - int c_arg = method->is_static() ? 2 : 1 ; + int c_arg = is_critical_native ? 0 : (method->is_static() ? 2 : 1 ); // Record rsp-based slot for receiver on stack for non-static methods int receiver_offset = -1; @@ -1373,10 +1683,16 @@ // Are free to temporaries if we have to do stack to steck moves. // All inbound args are referenced based on rbp, and all outbound args via rsp. - for (i = 0; i < total_in_args ; i++, c_arg++ ) { + for (int i = 0; i < total_in_args ; i++, c_arg++ ) { switch (in_sig_bt[i]) { case T_ARRAY: + if (is_critical_native) { + unpack_array_argument(masm, in_regs[i], in_elem_bt[i], out_regs[c_arg + 1], out_regs[c_arg]); + c_arg++; + break; + } case T_OBJECT: + assert(!is_critical_native, "no oop arguments"); object_move(masm, map, oop_handle_offset, stack_slots, in_regs[i], out_regs[c_arg], ((i == 0) && (!is_static)), &receiver_offset); @@ -1408,7 +1724,7 @@ // Pre-load a static method's oop into rsi. Used both by locking code and // the normal JNI call code. - if (method->is_static()) { + if (method->is_static() && !is_critical_native) { // load opp into a register __ movoop(oop_handle_reg, JNIHandles::make_local(Klass::cast(method->method_holder())->java_mirror())); @@ -1463,6 +1779,7 @@ // Lock a synchronized method if (method->is_synchronized()) { + assert(!is_critical_native, "unhandled"); const int mark_word_offset = BasicLock::displaced_header_offset_in_bytes(); @@ -1529,14 +1846,15 @@ // get JNIEnv* which is first argument to native - - __ lea(rdx, Address(thread, in_bytes(JavaThread::jni_environment_offset()))); - __ movptr(Address(rsp, 0), rdx); + if (!is_critical_native) { + __ lea(rdx, Address(thread, in_bytes(JavaThread::jni_environment_offset()))); + __ movptr(Address(rsp, 0), rdx); + } // Now set thread in native __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native); - __ call(RuntimeAddress(method->native_function())); + __ call(RuntimeAddress(native_func)); // WARNING - on Windows Java Natives use pascal calling convention and pop the // arguments off of the stack. We could just re-adjust the stack pointer here @@ -1591,6 +1909,8 @@ __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std())); } + Label after_transition; + // check for safepoint operation in progress and/or pending suspend requests { Label Continue; @@ -1611,17 +1931,29 @@ // save_native_result(masm, ret_type, stack_slots); __ push(thread); - __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, - JavaThread::check_special_condition_for_native_trans))); + if (!is_critical_native) { + __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, + JavaThread::check_special_condition_for_native_trans))); + } else { + __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, + JavaThread::check_special_condition_for_native_trans_and_transition))); + } __ increment(rsp, wordSize); // Restore any method result value restore_native_result(masm, ret_type, stack_slots); + if (is_critical_native) { + // The call above performed the transition to thread_in_Java so + // skip the transition logic below. + __ jmpb(after_transition); + } + __ bind(Continue); } // change thread state __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_Java); + __ bind(after_transition); Label reguard; Label reguard_done; @@ -1710,15 +2042,15 @@ __ verify_oop(rax); } - // reset handle block - __ movptr(rcx, Address(thread, JavaThread::active_handles_offset())); - - __ movptr(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD); - - // Any exception pending? - __ cmpptr(Address(thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD); - __ jcc(Assembler::notEqual, exception_pending); - + if (!is_critical_native) { + // reset handle block + __ movptr(rcx, Address(thread, JavaThread::active_handles_offset())); + __ movptr(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD); + + // Any exception pending? + __ cmpptr(Address(thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD); + __ jcc(Assembler::notEqual, exception_pending); + } // no exception, we're almost done @@ -1829,16 +2161,18 @@ // BEGIN EXCEPTION PROCESSING - // Forward the exception - __ bind(exception_pending); - - // remove possible return value from FPU register stack - __ empty_FPU_stack(); - - // pop our frame - __ leave(); - // and forward the exception - __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); + if (!is_critical_native) { + // Forward the exception + __ bind(exception_pending); + + // remove possible return value from FPU register stack + __ empty_FPU_stack(); + + // pop our frame + __ leave(); + // and forward the exception + __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); + } __ flush(); @@ -1851,6 +2185,11 @@ (is_static ? in_ByteSize(klass_offset) : in_ByteSize(receiver_offset)), in_ByteSize(lock_slot_offset*VMRegImpl::stack_slot_size), oop_maps); + + if (is_critical_native) { + nm->set_lazy_critical_native(true); + } + return nm; } diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp --- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Feb 09 23:17:22 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 @@ -938,6 +938,25 @@ } } +static void move_ptr(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { + if (src.first()->is_stack()) { + if (dst.first()->is_stack()) { + // stack to stack + __ movq(rax, Address(rbp, reg2offset_in(src.first()))); + __ movq(Address(rsp, reg2offset_out(dst.first())), rax); + } else { + // stack to reg + __ movq(dst.first()->as_Register(), Address(rbp, reg2offset_in(src.first()))); + } + } else if (dst.first()->is_stack()) { + // reg to stack + __ movq(Address(rsp, reg2offset_out(dst.first())), src.first()->as_Register()); + } else { + if (dst.first() != src.first()) { + __ movq(dst.first()->as_Register(), src.first()->as_Register()); + } + } +} // An oop arg. Must pass a handle not the oop itself static void object_move(MacroAssembler* masm, @@ -1152,6 +1171,203 @@ } } + +static void save_or_restore_arguments(MacroAssembler* masm, + const int stack_slots, + const int total_in_args, + const int arg_save_area, + OopMap* map, + VMRegPair* in_regs, + BasicType* in_sig_bt) { + // if map is non-NULL then the code should store the values, + // otherwise it should load them. + int handle_index = 0; + // Save down double word first + for ( int i = 0; i < total_in_args; i++) { + if (in_regs[i].first()->is_XMMRegister() && in_sig_bt[i] == T_DOUBLE) { + int slot = handle_index * VMRegImpl::slots_per_word + arg_save_area; + int offset = slot * VMRegImpl::stack_slot_size; + handle_index += 2; + assert(handle_index <= stack_slots, "overflow"); + if (map != NULL) { + __ movdbl(Address(rsp, offset), in_regs[i].first()->as_XMMRegister()); + } else { + __ movdbl(in_regs[i].first()->as_XMMRegister(), Address(rsp, offset)); + } + } + if (in_regs[i].first()->is_Register() && + (in_sig_bt[i] == T_LONG || in_sig_bt[i] == T_ARRAY)) { + int slot = handle_index * VMRegImpl::slots_per_word + arg_save_area; + int offset = slot * VMRegImpl::stack_slot_size; + handle_index += 2; + assert(handle_index <= stack_slots, "overflow"); + if (map != NULL) { + __ movq(Address(rsp, offset), in_regs[i].first()->as_Register()); + if (in_sig_bt[i] == T_ARRAY) { + map->set_oop(VMRegImpl::stack2reg(slot));; + } + } else { + __ movq(in_regs[i].first()->as_Register(), Address(rsp, offset)); + } + } + } + // Save or restore single word registers + for ( int i = 0; i < total_in_args; i++) { + if (in_regs[i].first()->is_Register()) { + int slot = handle_index++ * VMRegImpl::slots_per_word + arg_save_area; + int offset = slot * VMRegImpl::stack_slot_size; + assert(handle_index <= stack_slots, "overflow"); + + // Value is in an input register pass we must flush it to the stack + const Register reg = in_regs[i].first()->as_Register(); + switch (in_sig_bt[i]) { + case T_BOOLEAN: + case T_CHAR: + case T_BYTE: + case T_SHORT: + case T_INT: + if (map != NULL) { + __ movl(Address(rsp, offset), reg); + } else { + __ movl(reg, Address(rsp, offset)); + } + break; + case T_ARRAY: + case T_LONG: + // handled above + break; + case T_OBJECT: + default: ShouldNotReachHere(); + } + } else if (in_regs[i].first()->is_XMMRegister()) { + if (in_sig_bt[i] == T_FLOAT) { + int slot = handle_index++ * VMRegImpl::slots_per_word + arg_save_area; + int offset = slot * VMRegImpl::stack_slot_size; + assert(handle_index <= stack_slots, "overflow"); + if (map != NULL) { + __ movflt(Address(rsp, offset), in_regs[i].first()->as_XMMRegister()); + } else { + __ movflt(in_regs[i].first()->as_XMMRegister(), Address(rsp, offset)); + } + } + } else if (in_regs[i].first()->is_stack()) { + if (in_sig_bt[i] == T_ARRAY && map != NULL) { + int offset_in_older_frame = in_regs[i].first()->reg2stack() + SharedRuntime::out_preserve_stack_slots(); + map->set_oop(VMRegImpl::stack2reg(offset_in_older_frame + stack_slots)); + } + } + } +} + + +// Check GC_locker::needs_gc and enter the runtime if it's true. This +// keeps a new JNI critical region from starting until a GC has been +// forced. Save down any oops in registers and describe them in an +// OopMap. +static void check_needs_gc_for_critical_native(MacroAssembler* masm, + int stack_slots, + int total_c_args, + int total_in_args, + int arg_save_area, + OopMapSet* oop_maps, + VMRegPair* in_regs, + BasicType* in_sig_bt) { + __ block_comment("check GC_locker::needs_gc"); + Label cont; + __ cmp8(ExternalAddress((address)GC_locker::needs_gc_address()), false); + __ jcc(Assembler::equal, cont); + + // Save down any incoming oops and call into the runtime to halt for a GC + + OopMap* map = new OopMap(stack_slots * 2, 0 /* arg_slots*/); + save_or_restore_arguments(masm, stack_slots, total_in_args, + arg_save_area, map, in_regs, in_sig_bt); + + address the_pc = __ pc(); + oop_maps->add_gc_map( __ offset(), map); + __ set_last_Java_frame(rsp, noreg, the_pc); + + __ block_comment("block_for_jni_critical"); + __ movptr(c_rarg0, r15_thread); + __ mov(r12, rsp); // remember sp + __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows + __ andptr(rsp, -16); // align stack as required by ABI + __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::block_for_jni_critical))); + __ mov(rsp, r12); // restore sp + __ reinit_heapbase(); + + __ reset_last_Java_frame(false, true); + + save_or_restore_arguments(masm, stack_slots, total_in_args, + arg_save_area, NULL, in_regs, in_sig_bt); + + __ bind(cont); +#ifdef ASSERT + if (StressCriticalJNINatives) { + // Stress register saving + OopMap* map = new OopMap(stack_slots * 2, 0 /* arg_slots*/); + save_or_restore_arguments(masm, stack_slots, total_in_args, + arg_save_area, map, in_regs, in_sig_bt); + // Destroy argument registers + for (int i = 0; i < total_in_args - 1; i++) { + if (in_regs[i].first()->is_Register()) { + const Register reg = in_regs[i].first()->as_Register(); + __ xorptr(reg, reg); + } else if (in_regs[i].first()->is_XMMRegister()) { + __ xorpd(in_regs[i].first()->as_XMMRegister(), in_regs[i].first()->as_XMMRegister()); + } else if (in_regs[i].first()->is_FloatRegister()) { + ShouldNotReachHere(); + } else if (in_regs[i].first()->is_stack()) { + // Nothing to do + } else { + ShouldNotReachHere(); + } + if (in_sig_bt[i] == T_LONG || in_sig_bt[i] == T_DOUBLE) { + i++; + } + } + + save_or_restore_arguments(masm, stack_slots, total_in_args, + arg_save_area, NULL, in_regs, in_sig_bt); + } +#endif +} + +// Unpack an array argument into a pointer to the body and the length +// if the array is non-null, otherwise pass 0 for both. +static void unpack_array_argument(MacroAssembler* masm, VMRegPair reg, BasicType in_elem_type, VMRegPair body_arg, VMRegPair length_arg) { + Register tmp_reg = rax; + assert(!body_arg.first()->is_Register() || body_arg.first()->as_Register() != tmp_reg, + "possible collision"); + assert(!length_arg.first()->is_Register() || length_arg.first()->as_Register() != tmp_reg, + "possible collision"); + + // Pass the length, ptr pair + Label is_null, done; + VMRegPair tmp; + tmp.set_ptr(tmp_reg->as_VMReg()); + if (reg.first()->is_stack()) { + // Load the arg up from the stack + move_ptr(masm, reg, tmp); + reg = tmp; + } + __ testptr(reg.first()->as_Register(), reg.first()->as_Register()); + __ jccb(Assembler::equal, is_null); + __ lea(tmp_reg, Address(reg.first()->as_Register(), arrayOopDesc::base_offset_in_bytes(in_elem_type))); + move_ptr(masm, tmp, body_arg); + // load the length relative to the body. + __ movl(tmp_reg, Address(tmp_reg, arrayOopDesc::length_offset_in_bytes() - + arrayOopDesc::base_offset_in_bytes(in_elem_type))); + move32_64(masm, tmp, length_arg); + __ jmpb(done); + __ bind(is_null); + // Pass zeros + __ xorptr(tmp_reg, tmp_reg); + move_ptr(masm, tmp, body_arg); + move32_64(masm, tmp, length_arg); + __ bind(done); +} + // --------------------------------------------------------------------------- // Generate a native wrapper for a given method. The method takes arguments // in the Java compiled code convention, marshals them to the native @@ -1166,10 +1382,14 @@ BasicType *in_sig_bt, VMRegPair *in_regs, BasicType ret_type) { - // Native nmethod wrappers never take possesion of the oop arguments. - // So the caller will gc the arguments. The only thing we need an - // oopMap for is if the call is static - // + bool is_critical_native = true; + address native_func = method->critical_native_function(); + if (native_func == NULL) { + native_func = method->native_function(); + is_critical_native = false; + } + assert(native_func != NULL, "must have function"); + // An OopMap for lock (and class if static) OopMapSet *oop_maps = new OopMapSet(); intptr_t start = (intptr_t)__ pc(); @@ -1180,27 +1400,72 @@ // we convert the java signature to a C signature by inserting // the hidden arguments as arg[0] and possibly arg[1] (static method) - int total_c_args = total_in_args + 1; - if (method->is_static()) { - total_c_args++; + int total_c_args = total_in_args; + if (!is_critical_native) { + total_c_args += 1; + if (method->is_static()) { + total_c_args++; + } + } else { + for (int i = 0; i < total_in_args; i++) { + if (in_sig_bt[i] == T_ARRAY) { + total_c_args++; + } + } } BasicType* out_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_c_args); - VMRegPair* out_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_c_args); + VMRegPair* out_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_c_args); + BasicType* in_elem_bt = NULL; int argc = 0; - out_sig_bt[argc++] = T_ADDRESS; - if (method->is_static()) { - out_sig_bt[argc++] = T_OBJECT; - } - - for (int i = 0; i < total_in_args ; i++ ) { - out_sig_bt[argc++] = in_sig_bt[i]; + if (!is_critical_native) { + out_sig_bt[argc++] = T_ADDRESS; + if (method->is_static()) { + out_sig_bt[argc++] = T_OBJECT; + } + + for (int i = 0; i < total_in_args ; i++ ) { + out_sig_bt[argc++] = in_sig_bt[i]; + } + } else { + Thread* THREAD = Thread::current(); + in_elem_bt = NEW_RESOURCE_ARRAY(BasicType, total_in_args); + SignatureStream ss(method->signature()); + for (int i = 0; i < total_in_args ; i++ ) { + if (in_sig_bt[i] == T_ARRAY) { + // Arrays are passed as int, elem* pair + out_sig_bt[argc++] = T_INT; + out_sig_bt[argc++] = T_ADDRESS; + Symbol* atype = ss.as_symbol(CHECK_NULL); + const char* at = atype->as_C_string(); + if (strlen(at) == 2) { + assert(at[0] == '[', "must be"); + switch (at[1]) { + case 'B': in_elem_bt[i] = T_BYTE; break; + case 'C': in_elem_bt[i] = T_CHAR; break; + case 'D': in_elem_bt[i] = T_DOUBLE; break; + case 'F': in_elem_bt[i] = T_FLOAT; break; + case 'I': in_elem_bt[i] = T_INT; break; + case 'J': in_elem_bt[i] = T_LONG; break; + case 'S': in_elem_bt[i] = T_SHORT; break; + case 'Z': in_elem_bt[i] = T_BOOLEAN; break; + default: ShouldNotReachHere(); + } + } + } else { + out_sig_bt[argc++] = in_sig_bt[i]; + in_elem_bt[i] = T_VOID; + } + if (in_sig_bt[i] != T_VOID) { + assert(in_sig_bt[i] == ss.type(), "must match"); + ss.next(); + } + } } // Now figure out where the args must be stored and how much stack space // they require. - // int out_arg_slots; out_arg_slots = c_calling_convention(out_sig_bt, out_regs, total_c_args); @@ -1213,13 +1478,47 @@ int stack_slots = SharedRuntime::out_preserve_stack_slots() + out_arg_slots; // Now the space for the inbound oop handle area + int total_save_slots = 6 * VMRegImpl::slots_per_word; // 6 arguments passed in registers + if (is_critical_native) { + // Critical natives may have to call out so they need a save area + // for register arguments. + int double_slots = 0; + int single_slots = 0; + for ( int i = 0; i < total_in_args; i++) { + if (in_regs[i].first()->is_Register()) { + const Register reg = in_regs[i].first()->as_Register(); + switch (in_sig_bt[i]) { + case T_ARRAY: + case T_BOOLEAN: + case T_BYTE: + case T_SHORT: + case T_CHAR: + case T_INT: single_slots++; break; + case T_LONG: double_slots++; break; + default: ShouldNotReachHere(); + } + } else if (in_regs[i].first()->is_XMMRegister()) { + switch (in_sig_bt[i]) { + case T_FLOAT: single_slots++; break; + case T_DOUBLE: double_slots++; break; + default: ShouldNotReachHere(); + } + } else if (in_regs[i].first()->is_FloatRegister()) { + ShouldNotReachHere(); + } + } + total_save_slots = double_slots * 2 + single_slots; + // align the save area + if (double_slots != 0) { + stack_slots = round_to(stack_slots, 2); + } + } int oop_handle_offset = stack_slots; - stack_slots += 6*VMRegImpl::slots_per_word; + stack_slots += total_save_slots; // Now any space we need for handlizing a klass if static method - int oop_temp_slot_offset = 0; int klass_slot_offset = 0; int klass_offset = -1; int lock_slot_offset = 0; @@ -1272,7 +1571,6 @@ int stack_size = stack_slots * VMRegImpl::stack_slot_size; - // First thing make an ic check to see if we should even be here // We are free to use all registers as temps without saving them and @@ -1283,22 +1581,22 @@ const Register ic_reg = rax; const Register receiver = j_rarg0; - Label ok; + Label hit; Label exception_pending; assert_different_registers(ic_reg, receiver, rscratch1); __ verify_oop(receiver); __ load_klass(rscratch1, receiver); __ cmpq(ic_reg, rscratch1); - __ jcc(Assembler::equal, ok); + __ jcc(Assembler::equal, hit); __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); - __ bind(ok); - // Verified entry point must be aligned __ align(8); + __ bind(hit); + int vep_offset = ((intptr_t)__ pc()) - start; // The instruction at the verified entry point must be 5 bytes or longer @@ -1319,9 +1617,8 @@ // -2 because return address is already present and so is saved rbp __ subptr(rsp, stack_size - 2*wordSize); - // Frame is now completed as far as size and linkage. - - int frame_complete = ((intptr_t)__ pc()) - start; + // Frame is now completed as far as size and linkage. + int frame_complete = ((intptr_t)__ pc()) - start; #ifdef ASSERT { @@ -1341,7 +1638,10 @@ const Register oop_handle_reg = r14; - + if (is_critical_native) { + check_needs_gc_for_critical_native(masm, stack_slots, total_c_args, total_in_args, + oop_handle_offset, oop_maps, in_regs, in_sig_bt); + } // // We immediately shuffle the arguments so that any vm call we have to @@ -1390,9 +1690,36 @@ #endif /* ASSERT */ - + if (is_critical_native) { + // The mapping of Java and C arguments passed in registers are + // rotated by one, which helps when passing arguments to regular + // Java method but for critical natives that creates a cycle which + // can cause arguments to be killed before they are used. Break + // the cycle by moving the first argument into a temporary + // register. + for (int i = 0; i < total_c_args; i++) { + if (in_regs[i].first()->is_Register() && + in_regs[i].first()->as_Register() == rdi) { + __ mov(rbx, rdi); + in_regs[i].set1(rbx->as_VMReg()); + } + } + } + + // This may iterate in two different directions depending on the + // kind of native it is. The reason is that for regular JNI natives + // the incoming and outgoing registers are offset upwards and for + // critical natives they are offset down. int c_arg = total_c_args - 1; - for ( int i = total_in_args - 1; i >= 0 ; i--, c_arg-- ) { + int stride = -1; + int init = total_in_args - 1; + if (is_critical_native) { + // stride forwards + c_arg = 0; + stride = 1; + init = 0; + } + for (int i = init, count = 0; count < total_in_args; i += stride, c_arg += stride, count++ ) { #ifdef ASSERT if (in_regs[i].first()->is_Register()) { assert(!reg_destroyed[in_regs[i].first()->as_Register()->encoding()], "destroyed reg!"); @@ -1407,7 +1734,20 @@ #endif /* ASSERT */ switch (in_sig_bt[i]) { case T_ARRAY: + if (is_critical_native) { + unpack_array_argument(masm, in_regs[i], in_elem_bt[i], out_regs[c_arg + 1], out_regs[c_arg]); + c_arg++; +#ifdef ASSERT + if (out_regs[c_arg].first()->is_Register()) { + reg_destroyed[out_regs[c_arg].first()->as_Register()->encoding()] = true; + } else if (out_regs[c_arg].first()->is_XMMRegister()) { + freg_destroyed[out_regs[c_arg].first()->as_XMMRegister()->encoding()] = true; + } +#endif + break; + } case T_OBJECT: + assert(!is_critical_native, "no oop arguments"); object_move(masm, map, oop_handle_offset, stack_slots, in_regs[i], out_regs[c_arg], ((i == 0) && (!is_static)), &receiver_offset); @@ -1443,7 +1783,7 @@ // Pre-load a static method's oop into r14. Used both by locking code and // the normal JNI call code. - if (method->is_static()) { + if (method->is_static() && !is_critical_native) { // load oop into a register __ movoop(oop_handle_reg, JNIHandles::make_local(Klass::cast(method->method_holder())->java_mirror())); @@ -1509,6 +1849,7 @@ Label lock_done; if (method->is_synchronized()) { + assert(!is_critical_native, "unhandled"); const int mark_word_offset = BasicLock::displaced_header_offset_in_bytes(); @@ -1572,13 +1913,14 @@ // get JNIEnv* which is first argument to native - - __ lea(c_rarg0, Address(r15_thread, in_bytes(JavaThread::jni_environment_offset()))); + if (!is_critical_native) { + __ lea(c_rarg0, Address(r15_thread, in_bytes(JavaThread::jni_environment_offset()))); + } // Now set thread in native __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_native); - __ call(RuntimeAddress(method->native_function())); + __ call(RuntimeAddress(native_func)); // Either restore the MXCSR register after returning from the JNI Call // or verify that it wasn't changed. @@ -1634,6 +1976,7 @@ } } + Label after_transition; // check for safepoint operation in progress and/or pending suspend requests { @@ -1659,16 +2002,28 @@ __ mov(r12, rsp); // remember sp __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows __ andptr(rsp, -16); // align stack as required by ABI - __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans))); + if (!is_critical_native) { + __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans))); + } else { + __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans_and_transition))); + } __ mov(rsp, r12); // restore sp __ reinit_heapbase(); // Restore any method result value restore_native_result(masm, ret_type, stack_slots); + + if (is_critical_native) { + // The call above performed the transition to thread_in_Java so + // skip the transition logic below. + __ jmpb(after_transition); + } + __ bind(Continue); } // change thread state __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_Java); + __ bind(after_transition); Label reguard; Label reguard_done; @@ -1746,17 +2101,21 @@ __ verify_oop(rax); } - // reset handle block - __ movptr(rcx, Address(r15_thread, JavaThread::active_handles_offset())); - __ movptr(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); + if (!is_critical_native) { + // reset handle block + __ movptr(rcx, Address(r15_thread, JavaThread::active_handles_offset())); + __ movptr(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); + } // pop our frame __ leave(); - // Any exception pending? - __ cmpptr(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD); - __ jcc(Assembler::notEqual, exception_pending); + if (!is_critical_native) { + // Any exception pending? + __ cmpptr(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD); + __ jcc(Assembler::notEqual, exception_pending); + } // Return @@ -1764,12 +2123,13 @@ // Unexpected paths are out of line and go here - // forward the exception - __ bind(exception_pending); - - // and forward the exception - __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); - + if (!is_critical_native) { + // forward the exception + __ bind(exception_pending); + + // and forward the exception + __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); + } // Slow path locking & unlocking if (method->is_synchronized()) { @@ -1876,6 +2236,11 @@ (is_static ? in_ByteSize(klass_offset) : in_ByteSize(receiver_offset)), in_ByteSize(lock_slot_offset*VMRegImpl::stack_slot_size), oop_maps); + + if (is_critical_native) { + nm->set_lazy_critical_native(true); + } + return nm; } diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp --- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Thu Feb 09 23:17:22 2012 -0800 @@ -2978,7 +2978,9 @@ int frame_complete = __ pc() - start; // Set up last_Java_sp and last_Java_fp - __ set_last_Java_frame(rsp, rbp, NULL); + address the_pc = __ pc(); + __ set_last_Java_frame(rsp, rbp, the_pc); + __ andptr(rsp, -(StackAlignmentInBytes)); // Align stack // Call runtime if (arg1 != noreg) { @@ -2997,7 +2999,7 @@ oop_maps->add_gc_map(__ pc() - start, map); - __ reset_last_Java_frame(true, false); + __ reset_last_Java_frame(true, true); __ leave(); // required for proper stackwalking of RuntimeStub frame diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/os/solaris/vm/os_solaris.cpp --- a/hotspot/src/os/solaris/vm/os_solaris.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Thu Feb 09 23:17:22 2012 -0800 @@ -4007,7 +4007,6 @@ 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); diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/os/windows/vm/os_windows.cpp --- a/hotspot/src/os/windows/vm/os_windows.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/os/windows/vm/os_windows.cpp Thu Feb 09 23:17:22 2012 -0800 @@ -2088,7 +2088,6 @@ #elif _M_AMD64 PCONTEXT ctx = exceptionInfo->ContextRecord; address pc = (address)ctx->Rip; - NOT_PRODUCT(Events::log("idiv overflow exception at " INTPTR_FORMAT , pc)); assert(pc[0] == 0xF7, "not an idiv opcode"); assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands"); assert(ctx->Rax == min_jint, "unexpected idiv exception"); @@ -2100,7 +2099,6 @@ #else PCONTEXT ctx = exceptionInfo->ContextRecord; address pc = (address)ctx->Eip; - NOT_PRODUCT(Events::log("idiv overflow exception at " INTPTR_FORMAT , pc)); assert(pc[0] == 0xF7, "not an idiv opcode"); assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands"); assert(ctx->Eax == min_jint, "unexpected idiv exception"); @@ -5336,4 +5334,3 @@ } #endif - diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp --- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Thu Feb 09 23:17:22 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 @@ -362,7 +362,7 @@ } intptr_t* _get_previous_fp() { -#if defined(SPARC_WORKS) || defined(__clang__) +#if defined(SPARC_WORKS) || defined(__clang__) || defined(__llvm__) register intptr_t **ebp; __asm__("mov %%"SPELL_REG_FP", %0":"=r"(ebp)); #else diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/tools/ProjectCreator/BuildConfig.java --- a/hotspot/src/share/tools/ProjectCreator/BuildConfig.java Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/tools/ProjectCreator/BuildConfig.java Thu Feb 09 23:17:22 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 @@ -243,6 +243,7 @@ sysDefines.add("_WINDOWS"); sysDefines.add("HOTSPOT_BUILD_USER=\\\""+System.getProperty("user.name")+"\\\""); sysDefines.add("HOTSPOT_BUILD_TARGET=\\\""+get("Build")+"\\\""); + sysDefines.add("INCLUDE_TRACE"); sysDefines.add("_JNI_IMPLEMENTATION_"); if (vars.get("PlatformName").equals("Win32")) { sysDefines.add("HOTSPOT_LIB_ARCH=\\\"i386\\\""); diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/c1/c1_GraphBuilder.cpp --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Thu Feb 09 23:17:22 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 @@ -1592,6 +1592,7 @@ // this happened while running the JCK invokevirtual tests under doit. TKR ciMethod* cha_monomorphic_target = NULL; ciMethod* exact_target = NULL; + Value better_receiver = NULL; if (UseCHA && DeoptC1 && klass->is_loaded() && target->is_loaded() && !target->is_method_handle_invoke()) { Value receiver = NULL; @@ -1653,6 +1654,18 @@ ciInstanceKlass* singleton = NULL; if (target->holder()->nof_implementors() == 1) { singleton = target->holder()->implementor(0); + + assert(holder->is_interface(), "invokeinterface to non interface?"); + ciInstanceKlass* decl_interface = (ciInstanceKlass*)holder; + // the number of implementors for decl_interface is less or + // equal to the number of implementors for target->holder() so + // if number of implementors of target->holder() == 1 then + // number of implementors for decl_interface is 0 or 1. If + // it's 0 then no class implements decl_interface and there's + // no point in inlining. + if (!holder->is_loaded() || decl_interface->nof_implementors() != 1) { + singleton = NULL; + } } if (singleton) { cha_monomorphic_target = target->find_monomorphic_target(calling_klass, target->holder(), singleton); @@ -1667,7 +1680,9 @@ CheckCast* c = new CheckCast(klass, receiver, copy_state_for_exception()); c->set_incompatible_class_change_check(); c->set_direct_compare(klass->is_final()); - append_split(c); + // pass the result of the checkcast so that the compiler has + // more accurate type info in the inlinee + better_receiver = append_split(c); } } } @@ -1709,7 +1724,7 @@ } if (!success) { // static binding => check if callee is ok - success = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL)); + success = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL), better_receiver); } CHECK_BAILOUT(); @@ -3034,7 +3049,7 @@ } -bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known) { +bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known, Value receiver) { // Clear out any existing inline bailout condition clear_inline_bailout(); @@ -3056,7 +3071,7 @@ } else if (callee->is_abstract()) { INLINE_BAILOUT("abstract") } else { - return try_inline_full(callee, holder_known); + return try_inline_full(callee, holder_known, NULL, receiver); } } @@ -3405,7 +3420,7 @@ } -bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, BlockBegin* cont_block) { +bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, BlockBegin* cont_block, Value receiver) { assert(!callee->is_native(), "callee must not be native"); if (CompilationPolicy::policy()->should_not_inline(compilation()->env(), callee)) { INLINE_BAILOUT("inlining prohibited by policy"); @@ -3541,6 +3556,9 @@ Value arg = caller_state->stack_at_inc(i); // NOTE: take base() of arg->type() to avoid problems storing // constants + if (receiver != NULL && par_no == 0) { + arg = receiver; + } store_local(callee_state, arg, arg->type()->base(), par_no); } } @@ -3683,56 +3701,61 @@ // Get the two MethodHandle inputs from the Phi. Value op1 = phi->operand_at(0); Value op2 = phi->operand_at(1); - ciMethodHandle* mh1 = op1->type()->as_ObjectType()->constant_value()->as_method_handle(); - ciMethodHandle* mh2 = op2->type()->as_ObjectType()->constant_value()->as_method_handle(); - - // Set the callee to have access to the class and signature in - // the MethodHandleCompiler. - mh1->set_callee(callee); - mh1->set_caller(method()); - mh2->set_callee(callee); - mh2->set_caller(method()); - - // Get adapters for the MethodHandles. - ciMethod* mh1_adapter = mh1->get_method_handle_adapter(); - ciMethod* mh2_adapter = mh2->get_method_handle_adapter(); - - if (mh1_adapter != NULL && mh2_adapter != NULL) { - set_inline_cleanup_info(); - - // Build the If guard - BlockBegin* one = new BlockBegin(next_bci()); - BlockBegin* two = new BlockBegin(next_bci()); - BlockBegin* end = new BlockBegin(next_bci()); - Instruction* iff = append(new If(phi, If::eql, false, op1, one, two, NULL, false)); - block()->set_end(iff->as_BlockEnd()); - - // Connect up the states - one->merge(block()->end()->state()); - two->merge(block()->end()->state()); - - // Save the state for the second inlinee - ValueStack* state_before = copy_state_before(); - - // Parse first adapter - _last = _block = one; - if (!try_inline_full(mh1_adapter, /*holder_known=*/ true, end)) { - restore_inline_cleanup_info(); - block()->clear_end(); // remove appended iff - return false; + ObjectType* op1type = op1->type()->as_ObjectType(); + ObjectType* op2type = op2->type()->as_ObjectType(); + + if (op1type->is_constant() && op2type->is_constant()) { + ciMethodHandle* mh1 = op1type->constant_value()->as_method_handle(); + ciMethodHandle* mh2 = op2type->constant_value()->as_method_handle(); + + // Set the callee to have access to the class and signature in + // the MethodHandleCompiler. + mh1->set_callee(callee); + mh1->set_caller(method()); + mh2->set_callee(callee); + mh2->set_caller(method()); + + // Get adapters for the MethodHandles. + ciMethod* mh1_adapter = mh1->get_method_handle_adapter(); + ciMethod* mh2_adapter = mh2->get_method_handle_adapter(); + + if (mh1_adapter != NULL && mh2_adapter != NULL) { + set_inline_cleanup_info(); + + // Build the If guard + BlockBegin* one = new BlockBegin(next_bci()); + BlockBegin* two = new BlockBegin(next_bci()); + BlockBegin* end = new BlockBegin(next_bci()); + Instruction* iff = append(new If(phi, If::eql, false, op1, one, two, NULL, false)); + block()->set_end(iff->as_BlockEnd()); + + // Connect up the states + one->merge(block()->end()->state()); + two->merge(block()->end()->state()); + + // Save the state for the second inlinee + ValueStack* state_before = copy_state_before(); + + // Parse first adapter + _last = _block = one; + if (!try_inline_full(mh1_adapter, /*holder_known=*/ true, end, NULL)) { + restore_inline_cleanup_info(); + block()->clear_end(); // remove appended iff + return false; + } + + // Parse second adapter + _last = _block = two; + _state = state_before; + if (!try_inline_full(mh2_adapter, /*holder_known=*/ true, end, NULL)) { + restore_inline_cleanup_info(); + block()->clear_end(); // remove appended iff + return false; + } + + connect_to_end(end); + return true; } - - // Parse second adapter - _last = _block = two; - _state = state_before; - if (!try_inline_full(mh2_adapter, /*holder_known=*/ true, end)) { - restore_inline_cleanup_info(); - block()->clear_end(); // remove appended iff - return false; - } - - connect_to_end(end); - return true; } } } diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/c1/c1_GraphBuilder.hpp --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp Thu Feb 09 23:17:22 2012 -0800 @@ -337,9 +337,9 @@ void fill_sync_handler(Value lock, BlockBegin* sync_handler, bool default_handler = false); // inliners - bool try_inline( ciMethod* callee, bool holder_known); + bool try_inline( ciMethod* callee, bool holder_known, Value receiver = NULL); bool try_inline_intrinsics(ciMethod* callee); - bool try_inline_full( ciMethod* callee, bool holder_known, BlockBegin* cont_block = NULL); + bool try_inline_full( ciMethod* callee, bool holder_known, BlockBegin* cont_block, Value receiver); bool try_inline_jsr(int jsr_dest_bci); // JSR 292 support diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/c1/c1_Runtime1.cpp --- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp Thu Feb 09 23:17:22 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 @@ -597,7 +597,6 @@ JRT_ENTRY(void, Runtime1::throw_range_check_exception(JavaThread* thread, int index)) NOT_PRODUCT(_throw_range_check_exception_count++;) - Events::log("throw_range_check"); char message[jintAsStringSize]; sprintf(message, "%d", index); SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), message); @@ -606,7 +605,6 @@ JRT_ENTRY(void, Runtime1::throw_index_exception(JavaThread* thread, int index)) NOT_PRODUCT(_throw_index_exception_count++;) - Events::log("throw_index"); char message[16]; sprintf(message, "%d", index); SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_IndexOutOfBoundsException(), message); @@ -804,11 +802,7 @@ // Note also that in the presence of inlining it is not guaranteed // that caller_method() == caller_code->method() - int bci = vfst.bci(); - - Events::log("patch_code @ " INTPTR_FORMAT , caller_frame.pc()); - Bytecodes::Code code = caller_method()->java_code_at(bci); #ifndef PRODUCT diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/c1/c1_ValueMap.cpp --- a/hotspot/src/share/vm/c1/c1_ValueMap.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/c1/c1_ValueMap.cpp Thu Feb 09 23:17:22 2012 -0800 @@ -125,6 +125,7 @@ // otherwise it is possible that they are not evaluated f->pin(Instruction::PinGlobalValueNumbering); } + assert(x->type()->tag() == f->type()->tag(), "should have same type"); return f; diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp --- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp Thu Feb 09 23:17:22 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 @@ -359,7 +359,7 @@ case Bytecodes::_nop: break; case Bytecodes::_aconst_null: - state.apush(empty_map); + state.apush(unknown_obj); break; case Bytecodes::_iconst_m1: case Bytecodes::_iconst_0: @@ -392,6 +392,8 @@ if (tag.is_long() || tag.is_double()) { // Only longs and doubles use 2 stack slots. state.lpush(); + } else if (tag.basic_type() == T_OBJECT) { + state.apush(unknown_obj); } else { state.spush(); } diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/ci/ciEnv.hpp --- a/hotspot/src/share/vm/ci/ciEnv.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/ci/ciEnv.hpp Thu Feb 09 23:17:22 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 @@ -284,6 +284,20 @@ // Return state of appropriate compilability int compilable() { return _compilable; } + const char* retry_message() const { + switch (_compilable) { + case ciEnv::MethodCompilable_not_at_tier: + return "retry at different tier"; + case ciEnv::MethodCompilable_never: + return "not retryable"; + case ciEnv::MethodCompilable: + return NULL; + default: + ShouldNotReachHere(); + return NULL; + } + } + bool break_at_compile() { return _break_at_compile; } void set_break_at_compile(bool z) { _break_at_compile = z; } diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/classfile/dictionary.cpp --- a/hotspot/src/share/vm/classfile/dictionary.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/classfile/dictionary.cpp Thu Feb 09 23:17:22 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 @@ -618,7 +618,8 @@ ResourceMark rm; HandleMark hm; - tty->print_cr("Java system dictionary (classes=%d)", number_of_entries()); + tty->print_cr("Java system dictionary (table_size=%d, classes=%d)", + table_size(), number_of_entries()); tty->print_cr("^ indicates that initiating loader is different from " "defining loader"); diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/classfile/systemDictionary.cpp --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Thu Feb 09 23:17:22 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 @@ -64,6 +64,9 @@ int SystemDictionary::_number_of_modifications = 0; +int SystemDictionary::_sdgeneration = 0; +const int SystemDictionary::_primelist[_prime_array_size] = {1009,2017,4049,5051,10103, + 20201,40423,99991}; oop SystemDictionary::_system_loader_lock_obj = NULL; @@ -1178,8 +1181,8 @@ klassOop SystemDictionary::find_shared_class(Symbol* class_name) { if (shared_dictionary() != NULL) { - unsigned int d_hash = dictionary()->compute_hash(class_name, Handle()); - int d_index = dictionary()->hash_to_index(d_hash); + unsigned int d_hash = shared_dictionary()->compute_hash(class_name, Handle()); + int d_index = shared_dictionary()->hash_to_index(d_hash); return shared_dictionary()->find_shared_class(d_index, d_hash, class_name); } else { return NULL; @@ -1750,7 +1753,21 @@ placeholders()->oops_do(blk); } - +// Calculate a "good" systemdictionary size based +// on predicted or current loaded classes count +int SystemDictionary::calculate_systemdictionary_size(int classcount) { + int newsize = _old_default_sdsize; + if ((classcount > 0) && !DumpSharedSpaces) { + int desiredsize = classcount/_average_depth_goal; + for (newsize = _primelist[_sdgeneration]; _sdgeneration < _prime_array_size -1; + newsize = _primelist[++_sdgeneration]) { + if (desiredsize <= newsize) { + break; + } + } + } + return newsize; +} bool SystemDictionary::do_unloading(BoolObjectClosure* is_alive) { bool result = dictionary()->do_unloading(is_alive); constraints()->purge_loader_constraints(is_alive); @@ -1873,7 +1890,8 @@ // Allocate arrays assert(dictionary() == NULL, "SystemDictionary should only be initialized once"); - _dictionary = new Dictionary(_nof_buckets); + _sdgeneration = 0; + _dictionary = new Dictionary(calculate_systemdictionary_size(PredictedLoadedClassCount)); _placeholders = new PlaceholderTable(_nof_buckets); _number_of_modifications = 0; _loader_constraints = new LoaderConstraintTable(_loader_constraint_size); diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/classfile/systemDictionary.hpp --- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp Thu Feb 09 23:17:22 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 @@ -346,6 +346,8 @@ // loaders. Returns "true" iff something was unloaded. static bool do_unloading(BoolObjectClosure* is_alive); + static int calculate_systemdictionary_size(int loadedclasses); + // Applies "f->do_oop" to all root oops in the system dictionary. static void oops_do(OopClosure* f); @@ -538,12 +540,20 @@ _loader_constraint_size = 107, // number of entries in constraint table _resolution_error_size = 107, // number of entries in resolution error table _invoke_method_size = 139, // number of entries in invoke method table - _nof_buckets = 1009 // number of buckets in hash table + _nof_buckets = 1009, // number of buckets in hash table for placeholders + _old_default_sdsize = 1009, // backward compat for system dictionary size + _prime_array_size = 8, // array of primes for system dictionary size + _average_depth_goal = 3 // goal for lookup length }; // Static variables + // hashtable sizes for system dictionary to allow growth + // prime numbers for system dictionary size + static int _sdgeneration; + static const int _primelist[_prime_array_size]; + // Hashtable holding loaded classes. static Dictionary* _dictionary; diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/code/compiledIC.cpp --- a/hotspot/src/share/vm/code/compiledIC.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/code/compiledIC.cpp Thu Feb 09 23:17:22 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 @@ -165,7 +165,6 @@ instruction_address(), method->print_value_string(), entry); } - Events::log("compiledIC " INTPTR_FORMAT " --> megamorphic " INTPTR_FORMAT, this, (address)method()); // We can't check this anymore. With lazy deopt we could have already // cleaned this IC entry before we even return. This is possible if // we ran out of space in the inline cache buffer trying to do the diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/code/nmethod.cpp --- a/hotspot/src/share/vm/code/nmethod.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/code/nmethod.cpp Thu Feb 09 23:17:22 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 @@ -462,6 +462,7 @@ _speculatively_disconnected = 0; _has_unsafe_access = 0; _has_method_handle_invokes = 0; + _lazy_critical_native = 0; _marked_for_deoptimization = 0; _lock_count = 0; _stack_traversal_mark = 0; @@ -704,7 +705,6 @@ xtty->tail("print_native_nmethod"); } } - Events::log("Create nmethod " INTPTR_FORMAT, this); } // For dtrace wrappers @@ -781,7 +781,6 @@ xtty->tail("print_dtrace_nmethod"); } } - Events::log("Create nmethod " INTPTR_FORMAT, this); } #endif // def HAVE_DTRACE_H @@ -889,13 +888,6 @@ if (printnmethods || PrintDebugInfo || PrintRelocations || PrintDependencies || PrintExceptionHandlers) { print_nmethod(printnmethods); } - - // Note: Do not verify in here as the CodeCache_lock is - // taken which would conflict with the CompiledIC_lock - // which taken during the verification of call sites. - // (was bug - gri 10/25/99) - - Events::log("Create nmethod " INTPTR_FORMAT, this); } @@ -1386,7 +1378,7 @@ assert_locked_or_safepoint(CodeCache_lock); // completely deallocate this method - EventMark m("flushing nmethod " INTPTR_FORMAT " %s", this, ""); + Events::log(JavaThread::current(), "flushing nmethod " INTPTR_FORMAT, this); if (PrintMethodFlushing) { tty->print_cr("*flushing nmethod %3d/" INTPTR_FORMAT ". Live blobs:" UINT32_FORMAT "/Free CodeCache:" SIZE_FORMAT "Kb", _compile_id, this, CodeCache::nof_blobs(), CodeCache::unallocated_capacity()/1024); diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/code/nmethod.hpp --- a/hotspot/src/share/vm/code/nmethod.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/code/nmethod.hpp Thu Feb 09 23:17:22 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 @@ -175,6 +175,7 @@ // set during construction unsigned int _has_unsafe_access:1; // May fault due to unsafe access. unsigned int _has_method_handle_invokes:1; // Has this method MethodHandle invokes? + unsigned int _lazy_critical_native:1; // Lazy JNI critical native // Protected by Patching_lock unsigned char _state; // {alive, not_entrant, zombie, unloaded} @@ -430,7 +431,10 @@ void set_has_method_handle_invokes(bool z) { _has_method_handle_invokes = z; } bool is_speculatively_disconnected() const { return _speculatively_disconnected; } - void set_speculatively_disconnected(bool z) { _speculatively_disconnected = z; } + void set_speculatively_disconnected(bool z) { _speculatively_disconnected = z; } + + bool is_lazy_critical_native() const { return _lazy_critical_native; } + void set_lazy_critical_native(bool z) { _lazy_critical_native = z; } int comp_level() const { return _comp_level; } diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/compiler/compileBroker.cpp --- a/hotspot/src/share/vm/compiler/compileBroker.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Thu Feb 09 23:17:22 2012 -0800 @@ -44,6 +44,7 @@ #include "runtime/sharedRuntime.hpp" #include "runtime/sweeper.hpp" #include "utilities/dtrace.hpp" +#include "utilities/events.hpp" #ifdef COMPILER1 #include "c1/c1_Compiler.hpp" #endif @@ -189,6 +190,43 @@ GrowableArray* CompileBroker::_method_threads = NULL; +class CompilationLog : public StringEventLog { + public: + CompilationLog() : StringEventLog("Compilation events") { + } + + void log_compile(JavaThread* thread, CompileTask* task) { + StringLogMessage lm; + stringStream msg = lm.stream(); + // msg.time_stamp().update_to(tty->time_stamp().ticks()); + task->print_compilation(&msg, true); + log(thread, "%s", (const char*)lm); + } + + void log_nmethod(JavaThread* thread, nmethod* nm) { + log(thread, "nmethod " INTPTR_FORMAT " code ["INTPTR_FORMAT ", " INTPTR_FORMAT "]", + nm, nm->code_begin(), nm->code_end()); + } + + void log_failure(JavaThread* thread, CompileTask* task, const char* reason, const char* retry_message) { + StringLogMessage lm; + lm.print("%4d COMPILE SKIPPED: %s", task->compile_id(), reason); + if (retry_message != NULL) { + lm.append(" (%s)", retry_message); + } + lm.print("\n"); + log(thread, "%s", (const char*)lm); + } +}; + +static CompilationLog* _compilation_log = NULL; + +void compileBroker_init() { + if (LogEvents) { + _compilation_log = new CompilationLog(); + } +} + CompileTaskWrapper::CompileTaskWrapper(CompileTask* task) { CompilerThread* thread = CompilerThread::current(); thread->set_task(task); @@ -326,8 +364,12 @@ // ------------------------------------------------------------------ // CompileTask::print_compilation_impl -void CompileTask::print_compilation_impl(outputStream* st, methodOop method, int compile_id, int comp_level, bool is_osr_method, int osr_bci, bool is_blocking, const char* msg) { - st->print("%7d ", (int) st->time_stamp().milliseconds()); // print timestamp +void CompileTask::print_compilation_impl(outputStream* st, methodOop method, int compile_id, int comp_level, + bool is_osr_method, int osr_bci, bool is_blocking, + const char* msg, bool short_form) { + if (!short_form) { + st->print("%7d ", (int) st->time_stamp().milliseconds()); // print timestamp + } st->print("%4d ", compile_id); // print compilation number // For unloaded methods the transition to zombie occurs after the @@ -370,7 +412,9 @@ if (msg != NULL) { st->print(" %s", msg); } - st->cr(); + if (!short_form) { + st->cr(); + } } // ------------------------------------------------------------------ @@ -426,12 +470,12 @@ // ------------------------------------------------------------------ // CompileTask::print_compilation -void CompileTask::print_compilation(outputStream* st) { +void CompileTask::print_compilation(outputStream* st, bool short_form) { oop rem = JNIHandles::resolve(method_handle()); assert(rem != NULL && rem->is_method(), "must be"); methodOop method = (methodOop) rem; bool is_osr_method = osr_bci() != InvocationEntryBci; - print_compilation_impl(st, method, compile_id(), comp_level(), is_osr_method, osr_bci(), is_blocking()); + print_compilation_impl(st, method, compile_id(), comp_level(), is_osr_method, osr_bci(), is_blocking(), NULL, short_form); } // ------------------------------------------------------------------ @@ -1649,6 +1693,10 @@ CompilerThread* thread = CompilerThread::current(); ResourceMark rm(thread); + if (LogEvents) { + _compilation_log->log_compile(thread, task); + } + // Common flags. uint compile_id = task->compile_id(); int osr_bci = task->osr_bci(); @@ -1717,22 +1765,30 @@ ci_env.record_method_not_compilable("compile failed", !TieredCompilation); } + // Copy this bit to the enclosing block: + compilable = ci_env.compilable(); + if (ci_env.failing()) { - // Copy this bit to the enclosing block: - compilable = ci_env.compilable(); + const char* retry_message = ci_env.retry_message(); + if (_compilation_log != NULL) { + _compilation_log->log_failure(thread, task, ci_env.failure_reason(), retry_message); + } if (PrintCompilation) { - const char* reason = ci_env.failure_reason(); - if (compilable == ciEnv::MethodCompilable_not_at_tier) { - tty->print_cr("%4d COMPILE SKIPPED: %s (retry at different tier)", compile_id, reason); - } else if (compilable == ciEnv::MethodCompilable_never) { - tty->print_cr("%4d COMPILE SKIPPED: %s (not retryable)", compile_id, reason); - } else if (compilable == ciEnv::MethodCompilable) { - tty->print_cr("%4d COMPILE SKIPPED: %s", compile_id, reason); + tty->print("%4d COMPILE SKIPPED: %s", compile_id, ci_env.failure_reason()); + if (retry_message != NULL) { + tty->print(" (%s)", retry_message); } + tty->cr(); } } else { task->mark_success(); task->set_num_inlined_bytecodes(ci_env.num_inlined_bytecodes()); + if (_compilation_log != NULL) { + nmethod* code = task->code(); + if (code != NULL) { + _compilation_log->log_nmethod(thread, code); + } + } } } pop_jni_handle_block(); diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/compiler/compileBroker.hpp --- a/hotspot/src/share/vm/compiler/compileBroker.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/compiler/compileBroker.hpp Thu Feb 09 23:17:22 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 @@ -98,12 +98,16 @@ void set_prev(CompileTask* prev) { _prev = prev; } private: - static void print_compilation_impl(outputStream* st, methodOop method, int compile_id, int comp_level, bool is_osr_method = false, int osr_bci = -1, bool is_blocking = false, const char* msg = NULL); + static void print_compilation_impl(outputStream* st, methodOop method, int compile_id, int comp_level, + bool is_osr_method = false, int osr_bci = -1, bool is_blocking = false, + const char* msg = NULL, bool short_form = false); public: - void print_compilation(outputStream* st = tty); + void print_compilation(outputStream* st = tty, bool short_form = false); static void print_compilation(outputStream* st, const nmethod* nm, const char* msg = NULL) { - print_compilation_impl(st, nm->method(), nm->compile_id(), nm->comp_level(), nm->is_osr_method(), nm->is_osr_method() ? nm->osr_entry_bci() : -1, /*is_blocking*/ false, msg); + print_compilation_impl(st, nm->method(), nm->compile_id(), nm->comp_level(), + nm->is_osr_method(), nm->is_osr_method() ? nm->osr_entry_bci() : -1, /*is_blocking*/ false, + msg); } static void print_inlining(outputStream* st, ciMethod* method, int inline_level, int bci, const char* msg = NULL); diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Feb 09 23:17:22 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 @@ -5594,6 +5594,7 @@ GenCollectedHeap::StrongRootsScope srs(gch); workers->run_task(&tsk); } else { + ReferenceProcessorMTDiscoveryMutator mt(ref_processor(), false); GenCollectedHeap::StrongRootsScope srs(gch); tsk.work(0); } @@ -5608,6 +5609,8 @@ ResourceMark rm; HandleMark hm; GenCollectedHeap* gch = GenCollectedHeap::heap(); + ReferenceProcessorMTDiscoveryMutator mt(ref_processor(), false); + MarkRefsIntoAndScanClosure mrias_cl(_span, ref_processor(), &_markBitMap, &_modUnionTable, &_markStack, &_revisitStack, this, diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Feb 09 23:17:22 2012 -0800 @@ -1238,9 +1238,7 @@ SvcGCMarker sgcm(SvcGCMarker::FULL); ResourceMark rm; - if (PrintHeapAtGC) { - Universe::print_heap_before_gc(); - } + print_heap_before_gc(); HRSPhaseSetter x(HRSPhaseFullGC); verify_region_sets_optional(); @@ -1492,9 +1490,7 @@ _hrs.verify_optional(); verify_region_sets_optional(); - if (PrintHeapAtGC) { - Universe::print_heap_after_gc(); - } + print_heap_after_gc(); g1mm()->update_sizes(); post_full_gc_dump(); @@ -3560,9 +3556,7 @@ SvcGCMarker sgcm(SvcGCMarker::MINOR); ResourceMark rm; - if (PrintHeapAtGC) { - Universe::print_heap_before_gc(); - } + print_heap_before_gc(); HRSPhaseSetter x(HRSPhaseEvacuation); verify_region_sets_optional(); @@ -3937,9 +3931,7 @@ TASKQUEUE_STATS_ONLY(if (ParallelGCVerbose) print_taskqueue_stats()); TASKQUEUE_STATS_ONLY(reset_taskqueue_stats()); - if (PrintHeapAtGC) { - Universe::print_heap_after_gc(); - } + print_heap_after_gc(); g1mm()->update_sizes(); if (G1SummarizeRSetStats && diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Thu Feb 09 23:17:22 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 @@ -126,7 +126,6 @@ void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading, bool clear_all_softrefs) { // Recursively traverse all live objects and mark them - EventMark m("1 mark object"); TraceTime tm("phase 1", PrintGC && Verbose, true, gclog_or_tty); GenMarkSweep::trace(" 1"); @@ -292,7 +291,6 @@ G1CollectedHeap* g1h = G1CollectedHeap::heap(); Generation* pg = g1h->perm_gen(); - EventMark m("2 compute new addresses"); TraceTime tm("phase 2", PrintGC && Verbose, true, gclog_or_tty); GenMarkSweep::trace("2"); @@ -337,7 +335,6 @@ Generation* pg = g1h->perm_gen(); // Adjust the pointers to reflect the new locations - EventMark m("3 adjust pointers"); TraceTime tm("phase 3", PrintGC && Verbose, true, gclog_or_tty); GenMarkSweep::trace("3"); @@ -402,7 +399,6 @@ G1CollectedHeap* g1h = G1CollectedHeap::heap(); Generation* pg = g1h->perm_gen(); - EventMark m("4 compact heap"); TraceTime tm("phase 4", PrintGC && Verbose, true, gclog_or_tty); GenMarkSweep::trace("4"); diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Thu Feb 09 23:17:22 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 @@ -132,9 +132,7 @@ AdaptiveSizePolicyOutput(size_policy, heap->total_collections()); - if (PrintHeapAtGC) { - Universe::print_heap_before_gc(); - } + heap->print_heap_before_gc(); // Fill in TLABs heap->accumulate_statistics_all_tlabs(); @@ -377,9 +375,7 @@ NOT_PRODUCT(ref_processor()->verify_no_references_recorded()); - if (PrintHeapAtGC) { - Universe::print_heap_after_gc(); - } + heap->print_heap_after_gc(); heap->post_full_gc_dump(); @@ -504,7 +500,6 @@ void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) { // Recursively traverse all live objects and mark them - EventMark m("1 mark object"); TraceTime tm("phase 1", PrintGCDetails && Verbose, true, gclog_or_tty); trace(" 1"); @@ -563,7 +558,6 @@ void PSMarkSweep::mark_sweep_phase2() { - EventMark m("2 compute new addresses"); TraceTime tm("phase 2", PrintGCDetails && Verbose, true, gclog_or_tty); trace("2"); @@ -608,7 +602,6 @@ void PSMarkSweep::mark_sweep_phase3() { // Adjust the pointers to reflect the new locations - EventMark m("3 adjust pointers"); TraceTime tm("phase 3", PrintGCDetails && Verbose, true, gclog_or_tty); trace("3"); diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Thu Feb 09 23:17:22 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 @@ -983,9 +983,7 @@ // We need to track unique mark sweep invocations as well. _total_invocations++; - if (PrintHeapAtGC) { - Universe::print_heap_before_gc(); - } + heap->print_heap_before_gc(); // Fill in TLABs heap->accumulate_statistics_all_tlabs(); @@ -1838,7 +1836,6 @@ void PSParallelCompact::summary_phase(ParCompactionManager* cm, bool maximum_compaction) { - EventMark m("2 summarize"); TraceTime tm("summary phase", print_phases(), true, gclog_or_tty); // trace("2"); @@ -2237,9 +2234,7 @@ collection_exit.update(); - if (PrintHeapAtGC) { - Universe::print_heap_after_gc(); - } + heap->print_heap_after_gc(); if (PrintGCTaskTimeStamps) { gclog_or_tty->print_cr("VM-Thread " INT64_FORMAT " " INT64_FORMAT " " INT64_FORMAT, @@ -2352,7 +2347,6 @@ void PSParallelCompact::marking_phase(ParCompactionManager* cm, bool maximum_heap_compaction) { // Recursively traverse all live objects and mark them - EventMark m("1 mark object"); TraceTime tm("marking phase", print_phases(), true, gclog_or_tty); ParallelScavengeHeap* heap = gc_heap(); @@ -2438,7 +2432,6 @@ void PSParallelCompact::adjust_roots() { // Adjust the pointers to reflect the new locations - EventMark m("3 adjust roots"); TraceTime tm("adjust roots", print_phases(), true, gclog_or_tty); // General strong roots. @@ -2469,7 +2462,6 @@ } void PSParallelCompact::compact_perm(ParCompactionManager* cm) { - EventMark m("4 compact perm"); TraceTime tm("compact perm gen", print_phases(), true, gclog_or_tty); // trace("4"); @@ -2647,7 +2639,6 @@ } void PSParallelCompact::compact() { - EventMark m("5 compact"); // trace("5"); TraceTime tm("compaction phase", print_phases(), true, gclog_or_tty); @@ -3502,4 +3493,3 @@ _updated_int_array_klass_obj = (klassOop) summary_data().calc_new_pointer(Universe::intArrayKlassObj()); } - diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Thu Feb 09 23:17:22 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 @@ -295,9 +295,7 @@ heap->record_gen_tops_before_GC(); } - if (PrintHeapAtGC) { - Universe::print_heap_before_gc(); - } + heap->print_heap_before_gc(); assert(!NeverTenure || _tenuring_threshold == markOopDesc::max_age + 1, "Sanity"); assert(!AlwaysTenure || _tenuring_threshold == 0, "Sanity"); @@ -643,9 +641,7 @@ Universe::verify(false); } - if (PrintHeapAtGC) { - Universe::print_heap_after_gc(); - } + heap->print_heap_after_gc(); if (ZapUnusedHeapArea) { young_gen->eden_space()->check_mangled_unused_area_complete(); diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/gc_interface/collectedHeap.cpp --- a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp Thu Feb 09 23:17:22 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 @@ -51,6 +51,31 @@ size_t CollectedHeap::_filler_array_max_size = 0; +template <> +void EventLogBase::print(outputStream* st, GCMessage& m) { + st->print_cr("GC heap %s", m.is_before ? "before" : "after"); + st->print_raw(m); +} + +void GCHeapLog::log_heap(bool before) { + if (!should_log()) { + return; + } + + jlong timestamp = os::javaTimeNanos() / NANOSECS_PER_MILLISEC; + MutexLockerEx ml(&_mutex, Mutex::_no_safepoint_check_flag); + int index = compute_log_index(); + _records[index].thread = NULL; // Its the GC thread so it's not that interesting. + _records[index].timestamp = timestamp; + _records[index].data.is_before = before; + stringStream st(_records[index].data.buffer(), _records[index].data.size()); + if (before) { + Universe::print_heap_before_gc(&st); + } else { + Universe::print_heap_after_gc(&st); + } +} + // Memory state functions. @@ -81,6 +106,12 @@ 80, GCCause::to_string(_gc_lastcause), CHECK); } _defer_initial_card_mark = false; // strengthened by subclass in pre_initialize() below. + // Create the ring log + if (LogEvents) { + _gc_heap_log = new GCHeapLog(); + } else { + _gc_heap_log = NULL; + } } void CollectedHeap::pre_initialize() { diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/gc_interface/collectedHeap.hpp --- a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp Thu Feb 09 23:17:22 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 @@ -31,6 +31,7 @@ #include "runtime/handles.hpp" #include "runtime/perfData.hpp" #include "runtime/safepoint.hpp" +#include "utilities/events.hpp" // A "CollectedHeap" is an implementation of a java heap for HotSpot. This // is an abstract class: there may be many different kinds of heaps. This @@ -43,6 +44,29 @@ class Thread; class CollectorPolicy; +class GCMessage : public FormatBuffer<1024> { + public: + bool is_before; + + public: + GCMessage() {} +}; + +class GCHeapLog : public EventLogBase { + private: + void log_heap(bool before); + + public: + GCHeapLog() : EventLogBase("GC Heap History") {} + + void log_heap_before() { + log_heap(true); + } + void log_heap_after() { + log_heap(false); + } +}; + // // CollectedHeap // SharedHeap @@ -62,6 +86,8 @@ // Used for filler objects (static, but initialized in ctor). static size_t _filler_array_max_size; + GCHeapLog* _gc_heap_log; + // Used in support of ReduceInitialCardMarks; only consulted if COMPILER2 is being used bool _defer_initial_card_mark; @@ -618,6 +644,27 @@ // Default implementation does nothing. virtual void print_tracing_info() const = 0; + // If PrintHeapAtGC is set call the appropriate routi + void print_heap_before_gc() { + if (PrintHeapAtGC) { + Universe::print_heap_before_gc(); + } + if (_gc_heap_log != NULL) { + _gc_heap_log->log_heap_before(); + } + } + void print_heap_after_gc() { + if (PrintHeapAtGC) { + Universe::print_heap_after_gc(); + } + if (_gc_heap_log != NULL) { + _gc_heap_log->log_heap_after(); + } + } + + // Allocate GCHeapLog during VM startup + static void initialize_heap_log(); + // Heap verification virtual void verify(bool allow_dirty, bool silent, VerifyOption option) = 0; diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/memory/gcLocker.cpp --- a/hotspot/src/share/vm/memory/gcLocker.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/memory/gcLocker.cpp Thu Feb 09 23:17:22 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 @@ -31,38 +31,93 @@ volatile jint GC_locker::_lock_count = 0; volatile bool GC_locker::_needs_gc = false; volatile bool GC_locker::_doing_gc = false; +jlong GC_locker::_wait_begin = 0; + +#ifdef ASSERT +volatile jint GC_locker::_debug_jni_lock_count = 0; +#endif + + +#ifdef ASSERT +void GC_locker::verify_critical_count() { + if (SafepointSynchronize::is_at_safepoint()) { + assert(!needs_gc() || _debug_jni_lock_count == _jni_lock_count, "must agree"); + int count = 0; + // Count the number of threads with critical operations in progress + for (JavaThread* thr = Threads::first(); thr; thr = thr->next()) { + if (thr->in_critical()) { + count++; + } + } + if (_jni_lock_count != count) { + tty->print_cr("critical counts don't match: %d != %d", _jni_lock_count, count); + for (JavaThread* thr = Threads::first(); thr; thr = thr->next()) { + if (thr->in_critical()) { + tty->print_cr(INTPTR_FORMAT " in_critical %d", thr, thr->in_critical()); + } + } + } + assert(_jni_lock_count == count, "must be equal"); + } +} +#endif + +bool GC_locker::check_active_before_gc() { + assert(SafepointSynchronize::is_at_safepoint(), "only read at safepoint"); + if (is_active() && !_needs_gc) { + verify_critical_count(); + _needs_gc = true; + if (PrintJNIGCStalls && PrintGCDetails) { + ResourceMark rm; // JavaThread::name() allocates to convert to UTF8 + _wait_begin = os::javaTimeNanos() / NANOSECS_PER_MILLISEC; + gclog_or_tty->print_cr(INT64_FORMAT ": Setting _needs_gc. Thread \"%s\" %d locked.", + _wait_begin, Thread::current()->name(), _jni_lock_count); + } + + } + return is_active(); +} void GC_locker::stall_until_clear() { assert(!JavaThread::current()->in_critical(), "Would deadlock"); - if (PrintJNIGCStalls && PrintGCDetails) { - ResourceMark rm; // JavaThread::name() allocates to convert to UTF8 - gclog_or_tty->print_cr( - "Allocation failed. Thread \"%s\" is stalled by JNI critical section.", - JavaThread::current()->name()); + MutexLocker ml(JNICritical_lock); + + if (needs_gc()) { + if (PrintJNIGCStalls && PrintGCDetails) { + ResourceMark rm; // JavaThread::name() allocates to convert to UTF8 + gclog_or_tty->print_cr(INT64_FORMAT ": Allocation failed. Thread \"%s\" is stalled by JNI critical section, %d locked.", + (os::javaTimeNanos() / NANOSECS_PER_MILLISEC) - _wait_begin, Thread::current()->name(), _jni_lock_count); + } } - MutexLocker ml(JNICritical_lock); + // Wait for _needs_gc to be cleared - while (GC_locker::needs_gc()) { + while (needs_gc()) { JNICritical_lock->wait(); } } -void GC_locker::jni_lock_slow() { +void GC_locker::jni_lock(JavaThread* thread) { + assert(!thread->in_critical(), "shouldn't currently be in a critical region"); MutexLocker mu(JNICritical_lock); // Block entering threads if we know at least one thread is in a // JNI critical region and we need a GC. // We check that at least one thread is in a critical region before // blocking because blocked threads are woken up by a thread exiting // a JNI critical region. - while ((is_jni_active() && needs_gc()) || _doing_gc) { + while ((needs_gc() && is_jni_active()) || _doing_gc) { JNICritical_lock->wait(); } - jni_lock(); + thread->enter_critical(); + _jni_lock_count++; + increment_debug_jni_lock_count(); } -void GC_locker::jni_unlock_slow() { +void GC_locker::jni_unlock(JavaThread* thread) { + assert(thread->in_last_critical(), "should be exiting critical region"); MutexLocker mu(JNICritical_lock); - jni_unlock(); + _jni_lock_count--; + decrement_debug_jni_lock_count(); + thread->exit_critical(); if (needs_gc() && !is_jni_active()) { // We're the last thread out. Cause a GC to occur. // GC will also check is_active, so this check is not @@ -74,11 +129,17 @@ { // Must give up the lock while at a safepoint MutexUnlocker munlock(JNICritical_lock); + if (PrintJNIGCStalls && PrintGCDetails) { + ResourceMark rm; // JavaThread::name() allocates to convert to UTF8 + gclog_or_tty->print_cr(INT64_FORMAT ": Thread \"%s\" is performing GC after exiting critical section, %d locked", + (os::javaTimeNanos() / NANOSECS_PER_MILLISEC) - _wait_begin, Thread::current()->name(), _jni_lock_count); + } Universe::heap()->collect(GCCause::_gc_locker); } _doing_gc = false; } - clear_needs_gc(); + + _needs_gc = false; JNICritical_lock->notify_all(); } } diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/memory/gcLocker.hpp --- a/hotspot/src/share/vm/memory/gcLocker.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/memory/gcLocker.hpp Thu Feb 09 23:17:22 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 @@ -51,53 +51,70 @@ class GC_locker: public AllStatic { private: - static volatile jint _jni_lock_count; // number of jni active instances + // The _jni_lock_count keeps track of the number of threads that are + // currently in a critical region. It's only kept up to date when + // _needs_gc is true. The current value is computed during + // safepointing and decremented during the slow path of GC_locker + // unlocking. + static volatile jint _jni_lock_count; // number of jni active instances. + static volatile jint _lock_count; // number of other active instances static volatile bool _needs_gc; // heap is filling, we need a GC // note: bool is typedef'd as jint static volatile bool _doing_gc; // unlock_critical() is doing a GC + static jlong _wait_begin; // Timestamp for the setting of _needs_gc. + // Used only by printing code. + +#ifdef ASSERT + // This lock count is updated for all operations and is used to + // validate the jni_lock_count that is computed during safepoints. + static volatile jint _debug_jni_lock_count; +#endif + // Accessors static bool is_jni_active() { + assert(_needs_gc, "only valid when _needs_gc is set"); return _jni_lock_count > 0; } - static void set_needs_gc() { - assert(SafepointSynchronize::is_at_safepoint(), - "needs_gc is only set at a safepoint"); - _needs_gc = true; - } - - static void clear_needs_gc() { - assert_lock_strong(JNICritical_lock); - _needs_gc = false; - } + // At a safepoint, visit all threads and count the number of active + // critical sections. This is used to ensure that all active + // critical sections are exited before a new one is started. + static void verify_critical_count() NOT_DEBUG_RETURN; - static void jni_lock() { - Atomic::inc(&_jni_lock_count); - CHECK_UNHANDLED_OOPS_ONLY( - if (CheckUnhandledOops) { Thread::current()->_gc_locked_out_count++; }) - assert(Universe::heap() == NULL || !Universe::heap()->is_gc_active(), - "locking failed"); - } - - static void jni_unlock() { - Atomic::dec(&_jni_lock_count); - CHECK_UNHANDLED_OOPS_ONLY( - if (CheckUnhandledOops) { Thread::current()->_gc_locked_out_count--; }) - } - - static void jni_lock_slow(); - static void jni_unlock_slow(); + static void jni_lock(JavaThread* thread); + static void jni_unlock(JavaThread* thread); public: // Accessors static bool is_active(); static bool needs_gc() { return _needs_gc; } + // Shorthand - static bool is_active_and_needs_gc() { return is_active() && needs_gc();} + static bool is_active_and_needs_gc() { return needs_gc() && is_active(); } - // Calls set_needs_gc() if is_active() is true. Returns is_active(). + // In debug mode track the locking state at all times + static void increment_debug_jni_lock_count() { +#ifdef ASSERT + assert(_debug_jni_lock_count >= 0, "bad value"); + Atomic::inc(&_debug_jni_lock_count); +#endif + } + static void decrement_debug_jni_lock_count() { +#ifdef ASSERT + assert(_debug_jni_lock_count > 0, "bad value"); + Atomic::dec(&_debug_jni_lock_count); +#endif + } + + // Set the current lock count + static void set_jni_lock_count(int count) { + _jni_lock_count = count; + verify_critical_count(); + } + + // Sets _needs_gc if is_active() is true. Returns is_active(). static bool check_active_before_gc(); // Stalls the caller (who should not be in a jni critical section) @@ -131,22 +148,24 @@ // JNI critical regions are the only participants in this scheme // because they are, by spec, well bounded while in a critical region. // - // Each of the following two method is split into a fast path and a slow - // path. JNICritical_lock is only grabbed in the slow path. + // Each of the following two method is split into a fast path and a + // slow path. JNICritical_lock is only grabbed in the slow path. // _needs_gc is initially false and every java thread will go - // through the fast path (which does the same thing as the slow path - // when _needs_gc is false). When GC happens at a safepoint, - // GC_locker::is_active() is checked. Since there is no safepoint in the - // fast path of lock_critical() and unlock_critical(), there is no race - // condition between the fast path and GC. After _needs_gc is set at a - // safepoint, every thread will go through the slow path after the safepoint. - // Since after a safepoint, each of the following two methods is either - // entered from the method entry and falls into the slow path, or is - // resumed from the safepoints in the method, which only exist in the slow - // path. So when _needs_gc is set, the slow path is always taken, till - // _needs_gc is cleared. + // through the fast path, which simply increments or decrements the + // current thread's critical count. When GC happens at a safepoint, + // GC_locker::is_active() is checked. Since there is no safepoint in + // the fast path of lock_critical() and unlock_critical(), there is + // no race condition between the fast path and GC. After _needs_gc + // is set at a safepoint, every thread will go through the slow path + // after the safepoint. Since after a safepoint, each of the + // following two methods is either entered from the method entry and + // falls into the slow path, or is resumed from the safepoints in + // the method, which only exist in the slow path. So when _needs_gc + // is set, the slow path is always taken, till _needs_gc is cleared. static void lock_critical(JavaThread* thread); static void unlock_critical(JavaThread* thread); + + static address needs_gc_address() { return (address) &_needs_gc; } }; diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/memory/gcLocker.inline.hpp --- a/hotspot/src/share/vm/memory/gcLocker.inline.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/memory/gcLocker.inline.hpp Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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,16 +28,11 @@ #include "memory/gcLocker.hpp" inline bool GC_locker::is_active() { + assert(_needs_gc || SafepointSynchronize::is_at_safepoint(), "only read at safepoint"); + verify_critical_count(); return _lock_count > 0 || _jni_lock_count > 0; } -inline bool GC_locker::check_active_before_gc() { - if (is_active()) { - set_needs_gc(); - } - return is_active(); -} - inline void GC_locker::lock() { // cast away volatile Atomic::inc(&_lock_count); @@ -56,24 +51,28 @@ inline void GC_locker::lock_critical(JavaThread* thread) { if (!thread->in_critical()) { - if (!needs_gc()) { - jni_lock(); - } else { - jni_lock_slow(); + if (needs_gc()) { + // jni_lock call calls enter_critical under the lock so that the + // global lock count and per thread count are in agreement. + jni_lock(thread); + return; } + increment_debug_jni_lock_count(); } thread->enter_critical(); } inline void GC_locker::unlock_critical(JavaThread* thread) { + if (thread->in_last_critical()) { + if (needs_gc()) { + // jni_unlock call calls exit_critical under the lock so that + // the global lock count and per thread count are in agreement. + jni_unlock(thread); + return; + } + decrement_debug_jni_lock_count(); + } thread->exit_critical(); - if (!thread->in_critical()) { - if (!needs_gc()) { - jni_unlock(); - } else { - jni_unlock_slow(); - } - } } #endif // SHARE_VM_MEMORY_GCLOCKER_INLINE_HPP diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/memory/genCollectedHeap.cpp --- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -479,11 +479,9 @@ const size_t perm_prev_used = perm_gen()->used(); - if (PrintHeapAtGC) { - Universe::print_heap_before_gc(); - if (Verbose) { - gclog_or_tty->print_cr("GC Cause: %s", GCCause::to_string(gc_cause())); - } + print_heap_before_gc(); + if (Verbose) { + gclog_or_tty->print_cr("GC Cause: %s", GCCause::to_string(gc_cause())); } { @@ -685,9 +683,7 @@ AdaptiveSizePolicy* sp = gen_policy()->size_policy(); AdaptiveSizePolicyOutput(sp, total_collections()); - if (PrintHeapAtGC) { - Universe::print_heap_after_gc(); - } + print_heap_after_gc(); #ifdef TRACESPINNING ParallelTaskTerminator::print_termination_counts(); diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/memory/genMarkSweep.cpp --- a/hotspot/src/share/vm/memory/genMarkSweep.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/memory/genMarkSweep.cpp Thu Feb 09 23:17:22 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 @@ -254,7 +254,6 @@ void GenMarkSweep::mark_sweep_phase1(int level, bool clear_all_softrefs) { // Recursively traverse all live objects and mark them - EventMark m("1 mark object"); TraceTime tm("phase 1", PrintGC && Verbose, true, gclog_or_tty); trace(" 1"); @@ -325,7 +324,6 @@ GenCollectedHeap* gch = GenCollectedHeap::heap(); Generation* pg = gch->perm_gen(); - EventMark m("2 compute new addresses"); TraceTime tm("phase 2", PrintGC && Verbose, true, gclog_or_tty); trace("2"); @@ -350,7 +348,6 @@ Generation* pg = gch->perm_gen(); // Adjust the pointers to reflect the new locations - EventMark m("3 adjust pointers"); TraceTime tm("phase 3", PrintGC && Verbose, true, gclog_or_tty); trace("3"); @@ -411,7 +408,6 @@ GenCollectedHeap* gch = GenCollectedHeap::heap(); Generation* pg = gch->perm_gen(); - EventMark m("4 compact heap"); TraceTime tm("phase 4", PrintGC && Verbose, true, gclog_or_tty); trace("4"); diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/oops/arrayOop.cpp --- a/hotspot/src/share/vm/oops/arrayOop.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/oops/arrayOop.cpp Thu Feb 09 23:17:22 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 @@ -29,6 +29,7 @@ #ifndef PRODUCT #include "oops/arrayOop.hpp" +#include "oops/oop.inline.hpp" #include "utilities/globalDefinitions.hpp" bool arrayOopDesc::check_max_length_overflow(BasicType type) { diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/oops/constantPoolOop.cpp --- a/hotspot/src/share/vm/oops/constantPoolOop.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/oops/constantPoolOop.cpp Thu Feb 09 23:17:22 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 @@ -269,7 +269,7 @@ methodOop constantPoolOopDesc::method_at_if_loaded(constantPoolHandle cpool, int which, Bytecodes::Code invoke_code) { assert(!constantPoolCacheOopDesc::is_secondary_index(which), "no indy instruction here"); - if (cpool->cache() == NULL) return false; // nothing to load yet + if (cpool->cache() == NULL) return NULL; // nothing to load yet int cache_index = which - CPCACHE_INDEX_TAG; if (!(cache_index >= 0 && cache_index < cpool->cache()->length())) { if (PrintMiscellaneous && (Verbose||WizardMode)) { diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/oops/instanceKlass.hpp --- a/hotspot/src/share/vm/oops/instanceKlass.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Thu Feb 09 23:17:22 2012 -0800 @@ -240,7 +240,6 @@ Thread* _init_thread; // Pointer to current thread doing initialization (to handle recusive initialization) int _vtable_len; // length of Java vtable (in words) int _itable_len; // length of Java itable (in words) - ReferenceType _reference_type; // reference type OopMapCache* volatile _oop_map_cache; // OopMapCache for all methods in the klass (allocated lazily) JNIid* _jni_ids; // First JNI identifier for static fields in this class jmethodID* _methods_jmethod_ids; // jmethodIDs corresponding to method_idnum, or NULL if none @@ -265,6 +264,8 @@ // _idnum_allocated_count. u1 _init_state; // state of class + u1 _reference_type; // reference type + // embedded Java vtable follows here // embedded Java itables follows here // embedded static fields follows here @@ -407,8 +408,11 @@ void eager_initialize(Thread *thread); // reference type - ReferenceType reference_type() const { return _reference_type; } - void set_reference_type(ReferenceType t) { _reference_type = t; } + ReferenceType reference_type() const { return (ReferenceType)_reference_type; } + void set_reference_type(ReferenceType t) { + assert(t == (u1)t, "overflow"); + _reference_type = (u1)t; + } static ByteSize reference_type_offset() { return in_ByteSize(sizeof(klassOopDesc) + offset_of(instanceKlass, _reference_type)); } @@ -570,9 +574,9 @@ void set_method_annotations_of(int idnum, typeArrayOop anno) { set_methods_annotations_of(idnum, anno, &_methods_annotations); } void set_method_parameter_annotations_of(int idnum, typeArrayOop anno) - { set_methods_annotations_of(idnum, anno, &_methods_annotations); } + { set_methods_annotations_of(idnum, anno, &_methods_parameter_annotations); } void set_method_default_annotations_of(int idnum, typeArrayOop anno) - { set_methods_annotations_of(idnum, anno, &_methods_annotations); } + { set_methods_annotations_of(idnum, anno, &_methods_default_annotations); } // allocation DEFINE_ALLOCATE_PERMANENT(instanceKlass); diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/oops/klass.cpp --- a/hotspot/src/share/vm/oops/klass.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/oops/klass.cpp Thu Feb 09 23:17:22 2012 -0800 @@ -158,9 +158,7 @@ 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 fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/oops/klass.hpp --- a/hotspot/src/share/vm/oops/klass.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/oops/klass.hpp Thu Feb 09 23:17:22 2012 -0800 @@ -265,9 +265,7 @@ 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 @@ -688,9 +686,7 @@ 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 fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/oops/methodOop.cpp --- a/hotspot/src/share/vm/oops/methodOop.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/oops/methodOop.cpp Thu Feb 09 23:17:22 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 @@ -596,6 +596,11 @@ clear_code(); } +address methodOopDesc::critical_native_function() { + methodHandle mh(this); + return NativeLookup::lookup_critical_entry(mh); +} + void methodOopDesc::set_signature_handler(address handler) { address* signature_handler = signature_handler_addr(); diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/oops/methodOop.hpp --- a/hotspot/src/share/vm/oops/methodOop.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/oops/methodOop.hpp Thu Feb 09 23:17:22 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 @@ -403,6 +403,8 @@ native_bind_event_is_interesting = true }; address native_function() const { return *(native_function_addr()); } + address critical_native_function(); + // Must specify a real function (not NULL). // Use clear_native_function() to unregister. void set_native_function(address function, bool post_event_flag); diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/opto/graphKit.cpp --- a/hotspot/src/share/vm/opto/graphKit.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/opto/graphKit.cpp Thu Feb 09 23:17:22 2012 -0800 @@ -1522,6 +1522,11 @@ const TypeOopPtr* val_type, BasicType bt, bool use_precise) { + // Transformation of a value which could be NULL pointer (CastPP #NULL) + // could be delayed during Parse (for example, in adjust_map_after_if()). + // Execute transformation here to avoid barrier generation in such case. + if (_gvn.type(val) == TypePtr::NULL_PTR) + val = _gvn.makecon(TypePtr::NULL_PTR); set_control(ctl); if (stopped()) return top(); // Dead path ? diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/opto/library_call.cpp --- a/hotspot/src/share/vm/opto/library_call.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/opto/library_call.cpp Thu Feb 09 23:17:22 2012 -0800 @@ -2153,7 +2153,7 @@ // // if (offset == java_lang_ref_Reference::_reference_offset) { // if (base != null) { - // if (klass(base)->reference_type() != REF_NONE)) { + // if (instance_of(base, java.lang.ref.Reference)) { // pre_barrier(_, pre_val, ...); // } // } @@ -2165,8 +2165,6 @@ IdealKit ideal(this); #define __ ideal. - const int reference_type_offset = in_bytes(instanceKlass::reference_type_offset()); - Node* referent_off = __ ConX(java_lang_ref_Reference::referent_offset); __ if_then(offset, BoolTest::eq, referent_off, unlikely); { @@ -2678,7 +2676,13 @@ cas = _gvn.transform(new (C, 5) CompareAndSwapLNode(control(), mem, adr, newval, oldval)); break; case T_OBJECT: - // reference stores need a store barrier. + // Transformation of a value which could be NULL pointer (CastPP #NULL) + // could be delayed during Parse (for example, in adjust_map_after_if()). + // Execute transformation here to avoid barrier generation in such case. + if (_gvn.type(newval) == TypePtr::NULL_PTR) + newval = _gvn.makecon(TypePtr::NULL_PTR); + + // Reference stores need a store barrier. // (They don't if CAS fails, but it isn't worth checking.) pre_barrier(true /* do_load*/, control(), base, adr, alias_idx, newval, value_type->make_oopptr(), diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/opto/loopnode.cpp --- a/hotspot/src/share/vm/opto/loopnode.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/opto/loopnode.cpp Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -898,7 +898,7 @@ Node* CountedLoopNode::match_incr_with_optional_truncation( Node* expr, Node** trunc1, Node** trunc2, const TypeInt** trunc_type) { // Quick cutouts: - if (expr == NULL || expr->req() != 3) return false; + if (expr == NULL || expr->req() != 3) return NULL; Node *t1 = NULL; Node *t2 = NULL; diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/opto/macro.cpp --- a/hotspot/src/share/vm/opto/macro.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/opto/macro.cpp Thu Feb 09 23:17:22 2012 -0800 @@ -234,11 +234,20 @@ } } else { // G1 pre/post barriers - assert(p2x->outcnt() == 2, "expects 2 users: Xor and URShift nodes"); + assert(p2x->outcnt() <= 2, "expects 1 or 2 users: Xor and URShift nodes"); // It could be only one user, URShift node, in Object.clone() instrinsic // but the new allocation is passed to arraycopy stub and it could not // be scalar replaced. So we don't check the case. + // An other case of only one user (Xor) is when the value check for NULL + // in G1 post barrier is folded after CCP so the code which used URShift + // is removed. + + // Take Region node before eliminating post barrier since it also + // eliminates CastP2X node when it has only one user. + Node* this_region = p2x->in(0); + assert(this_region != NULL, ""); + // Remove G1 post barrier. // Search for CastP2X->Xor->URShift->Cmp path which @@ -263,8 +272,6 @@ // Remove G1 pre barrier. // Search "if (marking != 0)" check and set it to "false". - Node* this_region = p2x->in(0); - assert(this_region != NULL, ""); // There is no G1 pre barrier if previous stored value is NULL // (for example, after initialization). if (this_region->is_Region() && this_region->req() == 3) { @@ -292,7 +299,7 @@ } // Now CastP2X can be removed since it is used only on dead path // which currently still alive until igvn optimize it. - assert(p2x->unique_out()->Opcode() == Op_URShiftX, ""); + assert(p2x->outcnt() == 0 || p2x->unique_out()->Opcode() == Op_URShiftX, ""); _igvn.replace_node(p2x, top()); } } diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/prims/jvm.cpp --- a/hotspot/src/share/vm/prims/jvm.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/prims/jvm.cpp Thu Feb 09 23:17:22 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 @@ -2716,7 +2716,9 @@ } oop java_thread = JNIHandles::resolve_non_null(jthread); JavaThread* receiver = java_lang_Thread::thread(java_thread); - Events::log("JVM_StopThread thread JavaThread " INTPTR_FORMAT " as oop " INTPTR_FORMAT " [exception " INTPTR_FORMAT "]", receiver, (address)java_thread, throwable); + Events::log_exception(JavaThread::current(), + "JVM_StopThread thread JavaThread " INTPTR_FORMAT " as oop " INTPTR_FORMAT " [exception " INTPTR_FORMAT "]", + receiver, (address)java_thread, throwable); // First check if thread is alive if (receiver != NULL) { // Check if exception is getting thrown at self (use oop equality, since the diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/prims/nativeLookup.cpp --- a/hotspot/src/share/vm/prims/nativeLookup.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/prims/nativeLookup.cpp Thu Feb 09 23:17:22 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 @@ -91,6 +91,19 @@ } +char* NativeLookup::critical_jni_name(methodHandle method) { + stringStream st; + // Prefix + st.print("JavaCritical_"); + // Klass name + mangle_name_on(&st, method->klass_name()); + st.print("_"); + // Method name + mangle_name_on(&st, method->name()); + return st.as_string(); +} + + char* NativeLookup::long_jni_name(methodHandle method) { // Signature ignore the wrapping parenteses and the trailing return type stringStream st; @@ -193,6 +206,34 @@ } +address NativeLookup::lookup_critical_style(methodHandle method, char* pure_name, const char* long_name, int args_size, bool os_style) { + if (!method->has_native_function()) { + return NULL; + } + + address current_entry = method->native_function(); + + char dll_name[JVM_MAXPATHLEN]; + int offset; + if (os::dll_address_to_library_name(current_entry, dll_name, sizeof(dll_name), &offset)) { + char ebuf[32]; + void* dll = os::dll_load(dll_name, ebuf, sizeof(ebuf)); + if (dll != NULL) { + // Compute complete JNI name for style + stringStream st; + if (os_style) os::print_jni_name_prefix_on(&st, args_size); + st.print_raw(pure_name); + st.print_raw(long_name); + if (os_style) os::print_jni_name_suffix_on(&st, args_size); + char* jni_name = st.as_string(); + return (address)os::dll_lookup(dll, jni_name); + } + } + + return NULL; +} + + // Check all the formats of native implementation name to see if there is one // for the specified method. address NativeLookup::lookup_entry(methodHandle method, bool& in_base_library, TRAPS) { @@ -228,6 +269,58 @@ return entry; // NULL indicates not found } +// Check all the formats of native implementation name to see if there is one +// for the specified method. +address NativeLookup::lookup_critical_entry(methodHandle method) { + if (!CriticalJNINatives) return NULL; + + if (method->is_synchronized() || + !method->is_static()) { + // Only static non-synchronized methods are allowed + return NULL; + } + + ResourceMark rm; + address entry = NULL; + + Symbol* signature = method->signature(); + for (int end = 0; end < signature->utf8_length(); end++) { + if (signature->byte_at(end) == 'L') { + // Don't allow object types + return NULL; + } + } + + // Compute critical name + char* critical_name = critical_jni_name(method); + + // Compute argument size + int args_size = 1 // JNIEnv + + (method->is_static() ? 1 : 0) // class for static methods + + method->size_of_parameters(); // actual parameters + + + // 1) Try JNI short style + entry = lookup_critical_style(method, critical_name, "", args_size, true); + if (entry != NULL) return entry; + + // Compute long name + char* long_name = long_jni_name(method); + + // 2) Try JNI long style + entry = lookup_critical_style(method, critical_name, long_name, args_size, true); + if (entry != NULL) return entry; + + // 3) Try JNI short style without os prefix/suffix + entry = lookup_critical_style(method, critical_name, "", args_size, false); + if (entry != NULL) return entry; + + // 4) Try JNI long style without os prefix/suffix + entry = lookup_critical_style(method, critical_name, long_name, args_size, false); + + return entry; // NULL indicates not found +} + // Check if there are any JVM TI prefixes which have been applied to the native method name. // If any are found, remove them before attemping the look up of the // native implementation again. diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/prims/nativeLookup.hpp --- a/hotspot/src/share/vm/prims/nativeLookup.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/prims/nativeLookup.hpp Thu Feb 09 23:17:22 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 @@ -36,15 +36,18 @@ // JNI name computation static char* pure_jni_name(methodHandle method); static char* long_jni_name(methodHandle method); + static char* critical_jni_name(methodHandle method); // Style specific lookup static address lookup_style(methodHandle method, char* pure_name, const char* long_name, int args_size, bool os_style, bool& in_base_library, TRAPS); + static address lookup_critical_style(methodHandle method, char* pure_name, const char* long_name, int args_size, bool os_style); static address lookup_base (methodHandle method, bool& in_base_library, TRAPS); static address lookup_entry(methodHandle method, bool& in_base_library, TRAPS); static address lookup_entry_prefixed(methodHandle method, bool& in_base_library, TRAPS); public: // Lookup native function. May throw UnsatisfiedLinkError. static address lookup(methodHandle method, bool& in_base_library, TRAPS); + static address lookup_critical_entry(methodHandle method); // Lookup native functions in base library. static address base_library_lookup(const char* class_name, const char* method_name, const char* signature); diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/runtime/arguments.cpp --- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/runtime/arguments.cpp Thu Feb 09 23:17:22 2012 -0800 @@ -1400,10 +1400,11 @@ void Arguments::set_parallel_gc_flags() { assert(UseParallelGC || UseParallelOldGC, "Error"); - // If parallel old was requested, automatically enable parallel scavenge. - if (UseParallelOldGC && !UseParallelGC && FLAG_IS_DEFAULT(UseParallelGC)) { - FLAG_SET_DEFAULT(UseParallelGC, true); + // Enable ParallelOld unless it was explicitly disabled (cmd line or rc file). + if (FLAG_IS_DEFAULT(UseParallelOldGC)) { + FLAG_SET_DEFAULT(UseParallelOldGC, true); } + FLAG_SET_DEFAULT(UseParallelGC, true); // If no heap maximum was requested explicitly, use some reasonable fraction // of the physical memory, up to a maximum of 1GB. diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/runtime/deoptimization.cpp --- a/hotspot/src/share/vm/runtime/deoptimization.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/runtime/deoptimization.cpp Thu Feb 09 23:17:22 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 @@ -339,7 +339,6 @@ #ifdef ASSERT assert(cb->is_deoptimization_stub() || cb->is_uncommon_trap_stub(), "just checking"); - Events::log("fetch unroll sp " INTPTR_FORMAT, unpack_sp); #endif #else intptr_t* unpack_sp = stub_frame.sender(&dummy_map).unextended_sp(); @@ -577,6 +576,8 @@ tty->print_cr("DEOPT UNPACKING thread " INTPTR_FORMAT " vframeArray " INTPTR_FORMAT " mode %d", thread, array, exec_mode); } #endif + Events::log(thread, "DEOPT UNPACKING pc=" INTPTR_FORMAT " sp=" INTPTR_FORMAT " mode %d", + stub_frame.pc(), stub_frame.sp(), exec_mode); UnrollBlock* info = array->unroll_block(); @@ -981,6 +982,7 @@ #endif // COMPILER2 vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray* chunk) { + Events::log(thread, "DEOPT PACKING pc=" INTPTR_FORMAT " sp=" INTPTR_FORMAT, fr.pc(), fr.sp()); #ifndef PRODUCT if (TraceDeoptimization) { @@ -1026,7 +1028,6 @@ // Compare the vframeArray to the collected vframes assert(array->structural_compare(thread, chunk), "just checking"); - Events::log("# vframes = %d", (intptr_t)chunk->length()); #ifndef PRODUCT if (TraceDeoptimization) { @@ -1124,8 +1125,6 @@ gather_statistics(Reason_constraint, Action_none, Bytecodes::_illegal); - EventMark m("Deoptimization (pc=" INTPTR_FORMAT ", sp=" INTPTR_FORMAT ")", fr.pc(), fr.id()); - // Patch the nmethod so that when execution returns to it we will // deopt the execution state and return to the interpreter. fr.deoptimize(thread); @@ -1239,6 +1238,10 @@ // before we are done with it. nmethodLocker nl(fr.pc()); + // Log a message + Events::log_deopt_message(thread, "Uncommon trap %d fr.pc " INTPTR_FORMAT, + trap_request, fr.pc()); + { ResourceMark rm; @@ -1249,7 +1252,6 @@ DeoptAction action = trap_request_action(trap_request); jint unloaded_class_index = trap_request_index(trap_request); // CP idx or -1 - Events::log("Uncommon trap occurred @" INTPTR_FORMAT " unloaded_class_index = %d", fr.pc(), (int) trap_request); vframe* vf = vframe::new_vframe(&fr, ®_map, thread); compiledVFrame* cvf = compiledVFrame::cast(vf); diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/runtime/frame.cpp --- a/hotspot/src/share/vm/runtime/frame.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/runtime/frame.cpp Thu Feb 09 23:17:22 2012 -0800 @@ -570,7 +570,7 @@ InterpreterCodelet* desc = Interpreter::codelet_containing(pc()); if (desc != NULL) { st->print("~"); - desc->print(); + desc->print_on(st); NOT_PRODUCT(begin = desc->code_begin(); end = desc->code_end();) } else { st->print("~interpreter"); diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/runtime/globals.hpp --- a/hotspot/src/share/vm/runtime/globals.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/runtime/globals.hpp Thu Feb 09 23:17:22 2012 -0800 @@ -26,6 +26,17 @@ #define SHARE_VM_RUNTIME_GLOBALS_HPP #include "utilities/debug.hpp" + +// use this for flags that are true per default in the tiered build +// but false in non-tiered builds, and vice versa +#ifdef TIERED +#define trueInTiered true +#define falseInTiered false +#else +#define trueInTiered false +#define falseInTiered true +#endif + #ifdef TARGET_ARCH_x86 # include "globals_x86.hpp" #endif @@ -353,16 +364,6 @@ #define falseInProduct true #endif -// use this for flags that are true per default in the tiered build -// but false in non-tiered builds, and vice versa -#ifdef TIERED -#define trueInTiered true -#define falseInTiered false -#else -#define trueInTiered false -#define falseInTiered true -#endif - #ifdef JAVASE_EMBEDDED #define falseInEmbedded false #else @@ -658,6 +659,12 @@ develop(bool, SpecialArraysEquals, true, \ "special version of Arrays.equals(char[],char[])") \ \ + product(bool, CriticalJNINatives, true, \ + "check for critical JNI entry points") \ + \ + notproduct(bool, StressCriticalJNINatives, false, \ + "Exercise register saving code in critical natives") \ + \ product(bool, UseSSE42Intrinsics, false, \ "SSE4.2 versions of intrinsics") \ \ @@ -735,8 +742,11 @@ product(bool, MaxFDLimit, true, \ "Bump the number of file descriptors to max in solaris.") \ \ - notproduct(bool, LogEvents, trueInDebug, \ - "Enable Event log") \ + diagnostic(bool, LogEvents, true, \ + "Enable the various ring buffer event logs") \ + \ + diagnostic(intx, LogEventsBufferEntries, 10, \ + "Enable the various ring buffer event logs") \ \ product(bool, BytecodeVerificationRemote, true, \ "Enables the Java bytecode verifier for remote classes") \ @@ -1042,6 +1052,9 @@ notproduct(bool, PrintSystemDictionaryAtExit, false, \ "Prints the system dictionary at exit") \ \ + experimental(intx, PredictedLoadedClassCount, 0, \ + "Experimental: Tune loaded class cache starting size.") \ + \ diagnostic(bool, UnsyncloadClass, false, \ "Unstable: VM calls loadClass unsynchronized. Custom " \ "class loader must call VM synchronized for findClass " \ diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/runtime/init.cpp --- a/hotspot/src/share/vm/runtime/init.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/runtime/init.cpp Thu Feb 09 23:17:22 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 @@ -65,7 +65,7 @@ void InlineCacheBuffer_init(); void compilerOracle_init(); void compilationPolicy_init(); - +void compileBroker_init(); // Initialization after compiler initialization bool universe_post_init(); // must happen after compiler_init @@ -120,6 +120,7 @@ InlineCacheBuffer_init(); compilerOracle_init(); compilationPolicy_init(); + compileBroker_init(); VMRegImpl::set_regName(); if (!universe_post_init()) { diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/runtime/mutex.cpp --- a/hotspot/src/share/vm/runtime/mutex.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/runtime/mutex.cpp Thu Feb 09 23:17:22 2012 -0800 @@ -1,6 +1,6 @@ /* - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1296,10 +1296,6 @@ assert(this->rank() >= 0, "bad lock rank"); - if (LogMultipleMutexLocking && locks != NULL) { - Events::log("thread " INTPTR_FORMAT " locks %s, already owns %s", new_owner, name(), locks->name()); - } - // Deadlock avoidance rules require us to acquire Mutexes only in // a global total order. For example m1 is the lowest ranked mutex // that the thread holds and m2 is the mutex the thread is trying @@ -1343,10 +1339,6 @@ #ifdef ASSERT Monitor *locks = old_owner->owned_locks(); - if (LogMultipleMutexLocking && locks != this) { - Events::log("thread " INTPTR_FORMAT " unlocks %s, still owns %s", old_owner, this->name(), locks->name()); - } - // remove "this" from the owned locks list Monitor *prev = NULL; diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/runtime/safepoint.cpp --- a/hotspot/src/share/vm/runtime/safepoint.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/runtime/safepoint.cpp Thu Feb 09 23:17:22 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 @@ -95,6 +95,7 @@ SafepointSynchronize::SynchronizeState volatile SafepointSynchronize::_state = SafepointSynchronize::_not_synchronized; volatile int SafepointSynchronize::_waiting_to_block = 0; volatile int SafepointSynchronize::_safepoint_counter = 0; +int SafepointSynchronize::_current_jni_active_count = 0; long SafepointSynchronize::_end_of_last_safepoint = 0; static volatile int PageArmed = 0 ; // safepoint polling page is RO|RW vs PROT_NONE static volatile int TryingToBlock = 0 ; // proximate value -- for advisory use only @@ -135,9 +136,11 @@ RuntimeService::record_safepoint_begin(); - { MutexLocker mu(Safepoint_lock); + // Reset the count of active JNI critical threads + _current_jni_active_count = 0; + // Set number of threads to wait for, before we initiate the callbacks _waiting_to_block = nof_threads; TryingToBlock = 0 ; @@ -375,6 +378,9 @@ OrderAccess::fence(); + // Update the count of active JNI critical regions + GC_locker::set_jni_lock_count(_current_jni_active_count); + if (TraceSafepoint) { VM_Operation *op = VMThread::vm_operation(); tty->print_cr("Entering safepoint region: %s", (op != NULL) ? op->name() : "no vm operation"); @@ -392,7 +398,6 @@ // Record how much time spend on the above cleanup tasks update_statistics_on_cleanup_end(os::javaTimeNanos()); } - } } // Wake up all threads, so they are ready to resume execution after the safepoint @@ -539,6 +544,42 @@ } +// See if the thread is running inside a lazy critical native and +// update the thread critical count if so. Also set a suspend flag to +// cause the native wrapper to return into the JVM to do the unlock +// once the native finishes. +void SafepointSynchronize::check_for_lazy_critical_native(JavaThread *thread, JavaThreadState state) { + if (state == _thread_in_native && + thread->has_last_Java_frame() && + thread->frame_anchor()->walkable()) { + // This thread might be in a critical native nmethod so look at + // the top of the stack and increment the critical count if it + // is. + frame wrapper_frame = thread->last_frame(); + CodeBlob* stub_cb = wrapper_frame.cb(); + if (stub_cb != NULL && + stub_cb->is_nmethod() && + stub_cb->as_nmethod_or_null()->is_lazy_critical_native()) { + // A thread could potentially be in a critical native across + // more than one safepoint, so only update the critical state on + // the first one. When it returns it will perform the unlock. + if (!thread->do_critical_native_unlock()) { +#ifdef ASSERT + if (!thread->in_critical()) { + GC_locker::increment_debug_jni_lock_count(); + } +#endif + thread->enter_critical(); + // Make sure the native wrapper calls back on return to + // perform the needed critical unlock. + thread->set_critical_native_unlock(); + } + } + } +} + + + // ------------------------------------------------------------------------------------------------------- // Implementation of Safepoint callback point @@ -585,6 +626,11 @@ _waiting_to_block--; thread->safepoint_state()->set_has_called_back(true); + if (thread->in_critical()) { + // Notice that this thread is in a critical section + increment_jni_active_count(); + } + // Consider (_waiting_to_block < 2) to pipeline the wakeup of the VM thread if (_waiting_to_block == 0) { Safepoint_lock->notify_all(); @@ -861,8 +907,13 @@ // running, but are actually at a safepoint. We will happily // agree and update the safepoint state here. if (SafepointSynchronize::safepoint_safe(_thread, state)) { - roll_forward(_at_safepoint); - return; + roll_forward(_at_safepoint); + SafepointSynchronize::check_for_lazy_critical_native(_thread, state); + if (_thread->in_critical()) { + // Notice that this thread is in a critical section + SafepointSynchronize::increment_jni_active_count(); + } + return; } if (state == _thread_in_vm) { diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/runtime/safepoint.hpp --- a/hotspot/src/share/vm/runtime/safepoint.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/runtime/safepoint.hpp Thu Feb 09 23:17:22 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 @@ -29,6 +29,7 @@ #include "code/nmethod.hpp" #include "memory/allocation.hpp" #include "runtime/extendedPC.hpp" +#include "runtime/mutexLocker.hpp" #include "runtime/os.hpp" #include "utilities/ostream.hpp" @@ -92,6 +93,7 @@ private: static volatile SynchronizeState _state; // Threads might read this flag directly, without acquireing the Threads_lock static volatile int _waiting_to_block; // number of threads we are waiting for to block + static int _current_jni_active_count; // Counts the number of active critical natives during the safepoint // This counter is used for fast versions of jni_GetField. // An even value means there is no ongoing safepoint operations. @@ -138,6 +140,8 @@ static bool safepoint_safe(JavaThread *thread, JavaThreadState state); + static void check_for_lazy_critical_native(JavaThread *thread, JavaThreadState state); + // Query inline static bool is_at_safepoint() { return _state == _synchronized; } inline static bool is_synchronizing() { return _state == _synchronizing; } @@ -146,6 +150,11 @@ return (_state != _not_synchronized); } + inline static void increment_jni_active_count() { + assert_locked_or_safepoint(Safepoint_lock); + _current_jni_active_count++; + } + // Called when a thread volantary blocks static void block(JavaThread *thread); static void signal_thread_at_safepoint() { _waiting_to_block--; } diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/runtime/sharedRuntime.cpp --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Feb 09 23:17:22 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 @@ -886,9 +886,9 @@ // for AbortVMOnException flag NOT_PRODUCT(Exceptions::debug_check_abort("java.lang.NullPointerException")); if (exception_kind == IMPLICIT_NULL) { - Events::log("Implicit null exception at " INTPTR_FORMAT " to " INTPTR_FORMAT, pc, target_pc); + Events::log_exception(thread, "Implicit null exception at " INTPTR_FORMAT " to " INTPTR_FORMAT, pc, target_pc); } else { - Events::log("Implicit division by zero exception at " INTPTR_FORMAT " to " INTPTR_FORMAT, pc, target_pc); + Events::log_exception(thread, "Implicit division by zero exception at " INTPTR_FORMAT " to " INTPTR_FORMAT, pc, target_pc); } return target_pc; } @@ -1541,7 +1541,6 @@ if (caller.is_compiled_frame() && !caller.is_deoptimized_frame()) { address pc = caller.pc(); - Events::log("update call-site at pc " INTPTR_FORMAT, pc); // Default call_addr is the location of the "basic" call. // Determine the address of the call we a reresolving. With @@ -2679,6 +2678,20 @@ return nm; } +JRT_ENTRY_NO_ASYNC(void, SharedRuntime::block_for_jni_critical(JavaThread* thread)) + assert(thread == JavaThread::current(), "must be"); + // The code is about to enter a JNI lazy critical native method and + // _needs_gc is true, so if this thread is already in a critical + // section then just return, otherwise this thread should block + // until needs_gc has been cleared. + if (thread->in_critical()) { + return; + } + // Lock and unlock a critical section to give the system a chance to block + GC_locker::lock_critical(thread); + GC_locker::unlock_critical(thread); +JRT_END + #ifdef HAVE_DTRACE_H // Create a dtrace nmethod for this method. The wrapper converts the // java compiled calling convention to the native convention, makes a dummy call diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/runtime/sharedRuntime.hpp --- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp Thu Feb 09 23:17:22 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 @@ -462,6 +462,9 @@ VMRegPair *regs, BasicType ret_type ); + // Block before entering a JNI critical method + static void block_for_jni_critical(JavaThread* thread); + #ifdef HAVE_DTRACE_H // Generate a dtrace wrapper for a given method. The method takes arguments // in the Java compiled code convention, marshals them to the native diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/runtime/thread.cpp --- a/hotspot/src/share/vm/runtime/thread.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/runtime/thread.cpp Thu Feb 09 23:17:22 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 @@ -33,6 +33,7 @@ #include "interpreter/linkResolver.hpp" #include "interpreter/oopMapCache.hpp" #include "jvmtifiles/jvmtiEnv.hpp" +#include "memory/gcLocker.inline.hpp" #include "memory/oopFactory.hpp" #include "memory/universe.inline.hpp" #include "oops/instanceKlass.hpp" @@ -1600,8 +1601,6 @@ // java.lang.Thread.dispatchUncaughtException if (uncaught_exception.not_null()) { Handle group(this, java_lang_Thread::threadGroup(threadObj())); - Events::log("uncaught exception INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT", - (address)uncaught_exception(), (address)threadObj(), (address)group()); { EXCEPTION_MARK; // Check if the method Thread.dispatchUncaughtException() exists. If so @@ -2280,6 +2279,26 @@ } } +// This is a variant of the normal +// check_special_condition_for_native_trans with slightly different +// semantics for use by critical native wrappers. It does all the +// normal checks but also performs the transition back into +// thread_in_Java state. This is required so that critical natives +// can potentially block and perform a GC if they are the last thread +// exiting the GC_locker. +void JavaThread::check_special_condition_for_native_trans_and_transition(JavaThread *thread) { + check_special_condition_for_native_trans(thread); + + // Finish the transition + thread->set_thread_state(_thread_in_Java); + + if (thread->do_critical_native_unlock()) { + ThreadInVMfromJavaNoAsyncException tiv(thread); + GC_locker::unlock_critical(thread); + thread->clear_critical_native_unlock(); + } +} + // We need to guarantee the Threads_lock here, since resumes are not // allowed during safepoint synchronization // Can only resume from an external suspension @@ -3885,7 +3904,7 @@ ThreadService::add_thread(p, daemon); // Possible GC point. - Events::log("Thread added: " INTPTR_FORMAT, p); + Events::log(p, "Thread added: " INTPTR_FORMAT, p); } void Threads::remove(JavaThread* p) { @@ -3930,7 +3949,7 @@ } // unlock Threads_lock // Since Events::log uses a lock, we grab it outside the Threads_lock - Events::log("Thread exited: " INTPTR_FORMAT, p); + Events::log(p, "Thread exited: " INTPTR_FORMAT, p); } // Threads_lock must be held when this is called (or must be called during a safepoint) diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/runtime/thread.hpp --- a/hotspot/src/share/vm/runtime/thread.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/runtime/thread.hpp Thu Feb 09 23:17:22 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 @@ -182,7 +182,8 @@ _ext_suspended = 0x40000000U, // thread has self-suspended _deopt_suspend = 0x10000000U, // thread needs to self suspend for deopt - _has_async_exception = 0x00000001U // there is a pending async exception + _has_async_exception = 0x00000001U, // there is a pending async exception + _critical_native_unlock = 0x00000002U // Must call back to unlock JNI critical lock }; // various suspension related flags - atomically updated @@ -350,6 +351,15 @@ clear_suspend_flag(_has_async_exception); } + bool do_critical_native_unlock() const { return (_suspend_flags & _critical_native_unlock) != 0; } + + void set_critical_native_unlock() { + set_suspend_flag(_critical_native_unlock); + } + void clear_critical_native_unlock() { + clear_suspend_flag(_critical_native_unlock); + } + // Support for Unhandled Oop detection #ifdef CHECK_UNHANDLED_OOPS private: @@ -1038,6 +1048,11 @@ // Check for async exception in addition to safepoint and suspend request. static void check_special_condition_for_native_trans(JavaThread *thread); + // Same as check_special_condition_for_native_trans but finishes the + // transition into thread_in_Java mode so that it can potentially + // block. + static void check_special_condition_for_native_trans_and_transition(JavaThread *thread); + bool is_ext_suspend_completed(bool called_by_wait, int delay, uint32_t *bits); bool is_ext_suspend_completed_with_lock(uint32_t *bits) { MutexLockerEx ml(SR_lock(), Mutex::_no_safepoint_check_flag); @@ -1310,8 +1325,10 @@ // JNI critical regions. These can nest. bool in_critical() { return _jni_active_critical > 0; } - void enter_critical() { assert(Thread::current() == this, - "this must be current thread"); + bool in_last_critical() { return _jni_active_critical == 1; } + void enter_critical() { assert(Thread::current() == this || + Thread::current()->is_VM_thread() && SafepointSynchronize::is_synchronizing(), + "this must be current thread or synchronizing"); _jni_active_critical++; } void exit_critical() { assert(Thread::current() == this, "this must be current thread"); diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/runtime/vmStructs.cpp --- a/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -314,7 +314,7 @@ nonstatic_field(instanceKlass, _init_thread, Thread*) \ nonstatic_field(instanceKlass, _vtable_len, int) \ nonstatic_field(instanceKlass, _itable_len, int) \ - nonstatic_field(instanceKlass, _reference_type, ReferenceType) \ + nonstatic_field(instanceKlass, _reference_type, u1) \ volatile_nonstatic_field(instanceKlass, _oop_map_cache, OopMapCache*) \ nonstatic_field(instanceKlass, _jni_ids, JNIid*) \ nonstatic_field(instanceKlass, _osr_nmethods_head, nmethod*) \ @@ -2261,13 +2261,6 @@ \ declare_constant(SymbolTable::symbol_table_size) \ \ - /********************/ \ - /* SystemDictionary */ \ - /********************/ \ - \ - declare_constant(SystemDictionary::_loader_constraint_size) \ - declare_constant(SystemDictionary::_nof_buckets) \ - \ /***********************************/ \ /* LoaderConstraintTable constants */ \ /***********************************/ \ diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/runtime/vm_version.cpp --- a/hotspot/src/share/vm/runtime/vm_version.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/runtime/vm_version.cpp Thu Feb 09 23:17:22 2012 -0800 @@ -165,6 +165,13 @@ return VM_RELEASE; } +// NOTE: do *not* use stringStream. this function is called by +// fatal error handlers. if the crash is in native thread, +// stringStream cannot get resource allocated and will SEGV. +const char* Abstract_VM_Version::jre_release_version() { + return JRE_RELEASE_VERSION; +} + #define OS LINUX_ONLY("linux") \ WINDOWS_ONLY("windows") \ SOLARIS_ONLY("solaris") \ diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/runtime/vm_version.hpp --- a/hotspot/src/share/vm/runtime/vm_version.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/runtime/vm_version.hpp Thu Feb 09 23:17:22 2012 -0800 @@ -71,6 +71,7 @@ // Internal version providing additional build information static const char* internal_vm_info_string(); + static const char* jre_release_version(); // does HW support an 8-byte compare-exchange operation? static bool supports_cx8() {return _supports_cx8;} diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/trace/traceMacros.hpp --- a/hotspot/src/share/vm/trace/traceMacros.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/trace/traceMacros.hpp Thu Feb 09 23:17:22 2012 -0800 @@ -40,4 +40,8 @@ #define TRACE_START() true #define TRACE_INITIALIZE() 0 +#define TRACE_SET_KLASS_TRACE_ID(x1, x2) do { } while (0) +#define TRACE_DEFINE_KLASS_METHODS typedef int ___IGNORED_hs_trace_type1 +#define TRACE_DEFINE_KLASS_TRACE_ID typedef int ___IGNORED_hs_trace_type2 + #endif diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/utilities/debug.cpp --- a/hotspot/src/share/vm/utilities/debug.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/utilities/debug.cpp Thu Feb 09 23:17:22 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 @@ -601,18 +601,6 @@ } -extern "C" void events() { - Command c("events"); - Events::print_last(tty, 50); -} - - -extern "C" void nevents(int n) { - Command c("events"); - Events::print_last(tty, n); -} - - // Given a heap address that was valid before the most recent GC, if // the oop that used to contain it is still live, prints the new // location of the oop and the address. Useful for tracking down diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/utilities/debug.hpp --- a/hotspot/src/share/vm/utilities/debug.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/utilities/debug.hpp Thu Feb 09 23:17:22 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 @@ -33,16 +33,23 @@ // Simple class to format the ctor arguments into a fixed-sized buffer. template class FormatBuffer { -public: + public: inline FormatBuffer(const char * format, ...); inline void append(const char* format, ...); + inline void print(const char* format, ...); + inline void printv(const char* format, va_list ap); operator const char *() const { return _buf; } -private: + char* buffer() { return _buf; } + int size() { return bufsz; } + + private: FormatBuffer(const FormatBuffer &); // prevent copies -private: + protected: char _buf[bufsz]; + + inline FormatBuffer(); }; template @@ -54,6 +61,24 @@ } template +FormatBuffer::FormatBuffer() { + _buf[0] = '\0'; +} + +template +void FormatBuffer::print(const char * format, ...) { + va_list argp; + va_start(argp, format); + jio_vsnprintf(_buf, bufsz, format, argp); + va_end(argp); +} + +template +void FormatBuffer::printv(const char * format, va_list argp) { + jio_vsnprintf(_buf, bufsz, format, argp); +} + +template void FormatBuffer::append(const char* format, ...) { // Given that the constructor does a vsnprintf we can assume that // _buf is already initialized. diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/utilities/events.cpp --- a/hotspot/src/share/vm/utilities/events.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/utilities/events.cpp Thu Feb 09 23:17:22 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 @@ -26,6 +26,7 @@ #include "memory/allocation.inline.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/osThread.hpp" +#include "runtime/threadCritical.hpp" #include "runtime/threadLocalStorage.hpp" #include "runtime/timer.hpp" #include "utilities/events.hpp" @@ -43,184 +44,40 @@ #endif -#ifndef PRODUCT - -//////////////////////////////////////////////////////////////////////////// -// Event - -typedef u4 EventID; - -class Event VALUE_OBJ_CLASS_SPEC { - private: - jlong _time_tick; - intx _thread_id; - const char* _format; - int _indent; - intptr_t _arg_1; - intptr_t _arg_2; - intptr_t _arg_3; - - // only EventBuffer::add_event() can assign event id - friend class EventBuffer; - EventID _id; - - public: - - void clear() { _format = NULL; } - - EventID id() const { return _id; } - - void fill(int indent, const char* format, intptr_t arg_1, intptr_t arg_2, intptr_t arg_3) { - _format = format; - _arg_1 = arg_1; - _arg_2 = arg_2; - _arg_3 = arg_3; - - _indent = indent; - - _thread_id = os::current_thread_id(); - _time_tick = os::elapsed_counter(); - } - - void print_on(outputStream *st) { - if (_format == NULL) return; - st->print(" %d", _thread_id); - st->print(" %3.2g ", (double)_time_tick / os::elapsed_frequency()); - st->fill_to(20); - for (int index = 0; index < _indent; index++) { - st->print("| "); - } - st->print_cr(_format, _arg_1, _arg_2, _arg_3); - } -}; - -//////////////////////////////////////////////////////////////////////////// -// EventBuffer -// -// Simple lock-free event queue. Every event has a unique 32-bit id. -// It's fine if two threads add events at the same time, because they -// will get different event id, and then write to different buffer location. -// However, it is assumed that add_event() is quick enough (or buffer size -// is big enough), so when one thread is adding event, there can't be more -// than "size" events created by other threads; otherwise we'll end up having -// two threads writing to the same location. - -class EventBuffer : AllStatic { - private: - static Event* buffer; - static int size; - static jint indent; - static volatile EventID _current_event_id; - - static EventID get_next_event_id() { - return (EventID)Atomic::add(1, (jint*)&_current_event_id); - } - - public: - static void inc_indent() { Atomic::inc(&indent); } - static void dec_indent() { Atomic::dec(&indent); } +EventLog* Events::_logs = NULL; +StringEventLog* Events::_messages = NULL; +StringEventLog* Events::_exceptions = NULL; +StringEventLog* Events::_deopt_messages = NULL; - static bool get_event(EventID id, Event* event) { - int index = (int)(id % size); - if (buffer[index].id() == id) { - memcpy(event, &buffer[index], sizeof(Event)); - // check id again; if buffer[index] is being updated by another thread, - // event->id() will contain different value. - return (event->id() == id); - } else { - // id does not match - id is invalid, or event is overwritten - return false; - } - } - - // add a new event to the queue; if EventBuffer is full, this call will - // overwrite the oldest event in the queue - static EventID add_event(const char* format, - intptr_t arg_1, intptr_t arg_2, intptr_t arg_3) { - // assign a unique id - EventID id = get_next_event_id(); - - // event will be copied to buffer[index] - int index = (int)(id % size); - - // first, invalidate id, buffer[index] can't have event with id = index + 2 - buffer[index]._id = index + 2; - - // make sure everyone has seen that buffer[index] is invalid - OrderAccess::fence(); - - // ... before updating its value - buffer[index].fill(indent, format, arg_1, arg_2, arg_3); - - // finally, set up real event id, now buffer[index] contains valid event - OrderAccess::release_store(&(buffer[index]._id), id); - - return id; - } - - static void print_last(outputStream *st, int number) { - st->print_cr("[Last %d events in the event buffer]", number); - st->print_cr("------------------------"); +EventLog::EventLog() { + // This normally done during bootstrap when we're only single + // threaded but use a ThreadCritical to ensure inclusion in case + // some are created slightly late. + ThreadCritical tc; + _next = Events::_logs; + Events::_logs = this; +} - int count = 0; - EventID id = _current_event_id; - while (count < number) { - Event event; - if (get_event(id, &event)) { - event.print_on(st); - } - id--; - count++; - } - } - - static void print_all(outputStream* st) { - print_last(st, size); - } - - static void init() { - // Allocate the event buffer - size = EventLogLength; - buffer = NEW_C_HEAP_ARRAY(Event, size); - - _current_event_id = 0; - - // Clear the event buffer - for (int index = 0; index < size; index++) { - buffer[index]._id = index + 1; // index + 1 is invalid id - buffer[index].clear(); - } - } -}; - -Event* EventBuffer::buffer; -int EventBuffer::size; -volatile EventID EventBuffer::_current_event_id; -int EventBuffer::indent; - -//////////////////////////////////////////////////////////////////////////// -// Events - -// Events::log() is safe for signal handlers -void Events::log(const char* format, ...) { - if (LogEvents) { - va_list ap; - va_start(ap, format); - intptr_t arg_1 = va_arg(ap, intptr_t); - intptr_t arg_2 = va_arg(ap, intptr_t); - intptr_t arg_3 = va_arg(ap, intptr_t); - va_end(ap); - - EventBuffer::add_event(format, arg_1, arg_2, arg_3); +// For each registered event logger, print out the current contents of +// the buffer. This is normally called when the JVM is crashing. +void Events::print_all(outputStream* out) { + EventLog* log = _logs; + while (log != NULL) { + log->print_log_on(out); + log = log->next(); } } -void Events::print_all(outputStream *st) { - EventBuffer::print_all(st); +void Events::init() { + if (LogEvents) { + _messages = new StringEventLog("Events"); + _exceptions = new StringEventLog("Internal exceptions"); + _deopt_messages = new StringEventLog("Deoptimization events"); + } } -void Events::print_last(outputStream *st, int number) { - EventBuffer::print_last(st, number); +void eventlog_init() { + Events::init(); } /////////////////////////////////////////////////////////////////////////// @@ -230,37 +87,17 @@ if (LogEvents) { va_list ap; va_start(ap, format); - intptr_t arg_1 = va_arg(ap, intptr_t); - intptr_t arg_2 = va_arg(ap, intptr_t); - intptr_t arg_3 = va_arg(ap, intptr_t); + // Save a copy of begin message and log it. + _buffer.printv(format, ap); + Events::log(NULL, _buffer); va_end(ap); - - EventBuffer::add_event(format, arg_1, arg_2, arg_3); - EventBuffer::inc_indent(); } } EventMark::~EventMark() { if (LogEvents) { - EventBuffer::dec_indent(); - EventBuffer::add_event("done", 0, 0, 0); + // Append " done" to the begin message and log it + _buffer.append(" done"); + Events::log(NULL, _buffer); } } - -/////////////////////////////////////////////////////////////////////////// - -void eventlog_init() { - EventBuffer::init(); -} - -int print_all_events(outputStream *st) { - EventBuffer::print_all(st); - return 1; -} - -#else - -void eventlog_init() {} -int print_all_events(outputStream *st) { return 0; } - -#endif // PRODUCT diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/utilities/events.hpp --- a/hotspot/src/share/vm/utilities/events.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/utilities/events.hpp Thu Feb 09 23:17:22 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 @@ -26,7 +26,10 @@ #define SHARE_VM_UTILITIES_EVENTS_HPP #include "memory/allocation.hpp" +#include "runtime/mutexLocker.hpp" +#include "runtime/thread.hpp" #include "utilities/top.hpp" +#include "utilities/vmError.hpp" // Events and EventMark provide interfaces to log events taking place in the vm. // This facility is extremly useful for post-mortem debugging. The eventlog @@ -47,26 +50,246 @@ // Max 3 arguments are saved for each logged event. // -class Events : AllStatic { +// The base event log dumping class that is registered for dumping at +// crash time. This is a very generic interface that is mainly here +// for completeness. Normally the templated EventLogBase would be +// subclassed to provide different log types. +class EventLog : public CHeapObj { + friend class Events; + + private: + EventLog* _next; + + EventLog* next() const { return _next; } + public: - // Logs an event, format as printf - static void log(const char* format, ...) PRODUCT_RETURN; + // Automatically registers the log so that it will be printed during + // crashes. + EventLog(); + + virtual void print_log_on(outputStream* out) = 0; +}; + + +// A templated subclass of EventLog that provides basic ring buffer +// functionality. Most event loggers should subclass this, possibly +// providing a more featureful log function if the existing copy +// semantics aren't appropriate. The name is used as the label of the +// log when it is dumped during a crash. +template class EventLogBase : public EventLog { + template class EventRecord { + public: + jlong timestamp; + Thread* thread; + X data; + }; + + protected: + Mutex _mutex; + const char* _name; + int _length; + int _index; + int _count; + EventRecord* _records; + + public: + EventLogBase(const char* name, int length = LogEventsBufferEntries): + _name(name), + _length(length), + _count(0), + _index(0), + _mutex(Mutex::event, name) { + _records = new EventRecord[length]; + } - // Prints all events in the buffer - static void print_all(outputStream* st) PRODUCT_RETURN; + // move the ring buffer to next open slot and return the index of + // the slot to use for the current message. Should only be called + // while mutex is held. + int compute_log_index() { + int index = _index; + if (_count < _length) _count++; + _index++; + if (_index >= _length) _index = 0; + return index; + } + + bool should_log() { + // Don't bother adding new entries when we're crashing. This also + // avoids mutating the ring buffer when printing the log. + return !VMError::fatal_error_in_progress(); + } + + // Print the contents of the log + void print_log_on(outputStream* out); + + private: + void print_log_impl(outputStream* out); + + // Print a single element. A templated implementation might need to + // be declared by subclasses. + void print(outputStream* out, T& e); - // Prints last number events from the event buffer - static void print_last(outputStream *st, int number) PRODUCT_RETURN; + void print(outputStream* out, EventRecord& e) { + out->print("Event: " INT64_FORMAT " ", e.timestamp); + if (e.thread != NULL) { + out->print("Thread " INTPTR_FORMAT " ", e.thread); + } + print(out, e.data); + } +}; + +// A simple wrapper class for fixed size text messages. +class StringLogMessage : public FormatBuffer<132> { + public: + // Wrap this buffer in a stringStream. + stringStream stream() { + return stringStream(_buf, sizeof(_buf)); + } +}; + +// A simple ring buffer of fixed size text messages. +class StringEventLog : public EventLogBase { + public: + StringEventLog(const char* name, int count = LogEventsBufferEntries) : EventLogBase(name, count) {} + + void logv(Thread* thread, const char* format, va_list ap) { + if (!should_log()) return; + + jlong timestamp = os::javaTimeNanos() / NANOSECS_PER_MILLISEC; + MutexLockerEx ml(&_mutex, Mutex::_no_safepoint_check_flag); + int index = compute_log_index(); + _records[index].thread = thread; + _records[index].timestamp = timestamp; + _records[index].data.printv(format, ap); + } + + void log(Thread* thread, const char* format, ...) { + va_list ap; + va_start(ap, format); + logv(thread, format, ap); + va_end(ap); + } + }; + + +class Events : AllStatic { + friend class EventLog; + + private: + static EventLog* _logs; + + // A log for generic messages that aren't well categorized. + static StringEventLog* _messages; + + // A log for internal exception related messages, like internal + // throws and implicit exceptions. + static StringEventLog* _exceptions; + + // Deoptization related messages + static StringEventLog* _deopt_messages; + + public: + static void print_all(outputStream* out); + + static void print() { + print_all(tty); + } + + // Logs a generic message with timestamp and format as printf. + static void log(Thread* thread, const char* format, ...); + + // Log exception related message + static void log_exception(Thread* thread, const char* format, ...); + + static void log_deopt_message(Thread* thread, const char* format, ...); + + // Register default loggers + static void init(); +}; + + +inline void Events::log(Thread* thread, const char* format, ...) { + if (LogEvents) { + va_list ap; + va_start(ap, format); + _messages->logv(thread, format, ap); + va_end(ap); + } +} + +inline void Events::log_exception(Thread* thread, const char* format, ...) { + if (LogEvents) { + va_list ap; + va_start(ap, format); + _exceptions->logv(thread, format, ap); + va_end(ap); + } +} + +inline void Events::log_deopt_message(Thread* thread, const char* format, ...) { + if (LogEvents) { + va_list ap; + va_start(ap, format); + _deopt_messages->logv(thread, format, ap); + va_end(ap); + } +} + + +template +inline void EventLogBase::print_log_on(outputStream* out) { + if (ThreadLocalStorage::get_thread_slow() == NULL) { + // Not a regular Java thread so don't bother locking + print_log_impl(out); + } else { + MutexLockerEx ml(&_mutex, Mutex::_no_safepoint_check_flag); + print_log_impl(out); + } +} + +// Dump the ring buffer entries that current have entries. +template +inline void EventLogBase::print_log_impl(outputStream* out) { + out->print_cr("%s (%d events):", _name, _count); + if (_count == 0) { + out->print_cr("No events"); + return; + } + + if (_count < _length) { + for (int i = 0; i < _count; i++) { + print(out, _records[i]); + } + } else { + for (int i = _index; i < _length; i++) { + print(out, _records[i]); + } + for (int i = 0; i < _index; i++) { + print(out, _records[i]); + } + } + out->cr(); +} + +// Implement a printing routine for the StringLogMessage +template <> +inline void EventLogBase::print(outputStream* out, StringLogMessage& lm) { + out->print_raw(lm); + out->cr(); +} + +// Place markers for the beginning and end up of a set of events. +// These end up in the default log. class EventMark : public StackObj { + StringLogMessage _buffer; + public: // log a begin event, format as printf - EventMark(const char* format, ...) PRODUCT_RETURN; + EventMark(const char* format, ...); // log an end event - ~EventMark() PRODUCT_RETURN; + ~EventMark(); }; -int print_all_events(outputStream *st); - #endif // SHARE_VM_UTILITIES_EVENTS_HPP diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/utilities/exceptions.cpp --- a/hotspot/src/share/vm/utilities/exceptions.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/utilities/exceptions.cpp Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -160,7 +160,7 @@ thread->set_pending_exception(h_exception(), file, line); // vm log - Events::log("throw_exception " INTPTR_FORMAT, (address)h_exception()); + Events::log_exception(thread, "Threw " INTPTR_FORMAT " at %s:%d", (address)h_exception(), file, line); } diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/utilities/hashtable.hpp --- a/hotspot/src/share/vm/utilities/hashtable.hpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/utilities/hashtable.hpp Thu Feb 09 23:17:22 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 @@ -183,7 +183,6 @@ // Accessor int entry_size() const { return _entry_size; } - int table_size() { return _table_size; } // The following method is MT-safe and may be used with caution. BasicHashtableEntry* bucket(int i); @@ -195,6 +194,7 @@ BasicHashtableEntry* new_entry(unsigned int hashValue); public: + int table_size() { return _table_size; } void set_entry(int index, BasicHashtableEntry* entry); void add_entry(int index, BasicHashtableEntry* entry); diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/utilities/vmError.cpp --- a/hotspot/src/share/vm/utilities/vmError.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/utilities/vmError.cpp Thu Feb 09 23:17:22 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 @@ -36,6 +36,7 @@ #include "utilities/decoder.hpp" #include "utilities/defaultStream.hpp" #include "utilities/errorReporter.hpp" +#include "utilities/events.hpp" #include "utilities/top.hpp" #include "utilities/vmError.hpp" @@ -693,7 +694,14 @@ st->cr(); } - STEP(200, "(printing dynamic libraries)" ) + STEP(200, "(printing ring buffers)" ) + + if (_verbose) { + Events::print_all(st); + st->cr(); + } + + STEP(205, "(printing dynamic libraries)" ) if (_verbose) { // dynamic libraries, or memory map diff -r fc06525cb345 -r 5561a4c99825 hotspot/src/share/vm/utilities/xmlstream.cpp --- a/hotspot/src/share/vm/utilities/xmlstream.cpp Thu Feb 09 18:26:57 2012 +0400 +++ b/hotspot/src/share/vm/utilities/xmlstream.cpp Thu Feb 09 23:17:22 2012 -0800 @@ -192,8 +192,11 @@ _element_close_stack_ptr = cur_tag + strlen(cur_tag) + 1; _element_depth -= 1; } - if (bad_tag && !VMThread::should_terminate() && !is_error_reported()) + if (bad_tag && !VMThread::should_terminate() && !VM_Exit::vm_exited() && + !is_error_reported()) + { assert(false, "bad tag in log"); + } } #endif diff -r fc06525cb345 -r 5561a4c99825 hotspot/test/compiler/7090976/Test7090976.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/7090976/Test7090976.java Thu Feb 09 23:17:22 2012 -0800 @@ -0,0 +1,82 @@ +/* + * 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 7090976 + * @summary Eclipse/CDT causes a JVM crash while indexing C++ code + * + * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement Test7090976 + */ + +public class Test7090976 { + + static interface I1 { + public void m1(); + }; + + static interface I2 { + public void m2(); + }; + + static interface I extends I1,I2 { + } + + static class A implements I1 { + int v = 0; + int v2; + + public void m1() { + v2 = v; + } + } + + static class B implements I2 { + Object v = new Object(); + Object v2; + + public void m2() { + v2 = v; + } + } + + private void test(A a) + { + if (a instanceof I) { + I i = (I)a; + i.m1(); + i.m2(); + } + } + + public static void main(String[] args) + { + Test7090976 t = new Test7090976(); + A a = new A(); + B b = new B(); + for (int i = 0; i < 10000; i++) { + t.test(a); + } + } +} diff -r fc06525cb345 -r 5561a4c99825 hotspot/test/compiler/7141637/SpreadNullArg.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/7141637/SpreadNullArg.java Thu Feb 09 23:17:22 2012 -0800 @@ -0,0 +1,62 @@ +/* + * Copyright 2011 SAP AG. All Rights Reserved. + * 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 SpreadNullArg + * @bug 7141637 + * @summary verifies that the MethodHandle spread adapter can gracefully handle null arguments. + * @run main SpreadNullArg + * @author volker.simonis@gmail.com + */ + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +public class SpreadNullArg { + + public static void main(String args[]) { + + MethodType mt_ref_arg = MethodType.methodType(int.class, Integer.class); + MethodHandle mh_spreadInvoker = MethodHandles.spreadInvoker(mt_ref_arg, 0); + MethodHandle mh_spread_target; + int result = 42; + + try { + mh_spread_target = + MethodHandles.lookup().findStatic(SpreadNullArg.class, "target_spread_arg", mt_ref_arg); + result = (int) mh_spreadInvoker.invokeExact(mh_spread_target, (Object[]) null); + } catch(NullPointerException e) { + // Expected exception - do nothing! + } catch(Throwable e) { + throw new Error(e); + } + + if (result != 42) throw new Error("Expected NullPointerException was not thrown"); + } + + public static int target_spread_arg(Integer i1) { + return i1.intValue(); + } + +} diff -r fc06525cb345 -r 5561a4c99825 jaxp/.hgtags --- a/jaxp/.hgtags Thu Feb 09 18:26:57 2012 +0400 +++ b/jaxp/.hgtags Thu Feb 09 23:17:22 2012 -0800 @@ -145,3 +145,5 @@ d41eeadf5c1344b88c5051a997aec9e1ad7ce1db jdk8-b21 cf9d6ec44f891236ad18451021d6dcd57dc82f7b jdk8-b22 95102fd334183d15dc98a95dd0d749527b6c7300 jdk8-b23 +7836655e2495646c462f13de73dcc3ada197b64f jdk8-b24 +bb694c151fc7b5c8f9edc8af6a80738530feacaf jdk8-b25 diff -r fc06525cb345 -r 5561a4c99825 jaxws/.hgtags --- a/jaxws/.hgtags Thu Feb 09 18:26:57 2012 +0400 +++ b/jaxws/.hgtags Thu Feb 09 23:17:22 2012 -0800 @@ -145,3 +145,5 @@ c266cab0e3fff05f2048c23046c14d60f7102175 jdk8-b21 8d3df89b0f2d3c603b2edb0f5e24af1245397cc6 jdk8-b22 25ce7a0004874273f6aeda14e7c3538cba34bdf1 jdk8-b23 +e0d90803439b174fe0b0033e09d50444ba12498f jdk8-b24 +b376d901e006cd9e0c59733c84e190aace23eec6 jdk8-b25 diff -r fc06525cb345 -r 5561a4c99825 jdk/.hgtags --- a/jdk/.hgtags Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/.hgtags Thu Feb 09 23:17:22 2012 -0800 @@ -145,3 +145,5 @@ 664fa4fb0ee411ef048903c479f8b962fcdb2f4b jdk8-b21 dda27c73d8db4a9c7a23872b6f0c5106edcb2021 jdk8-b22 54202e0148ec7d4570cab5bc9b00d216a7677569 jdk8-b23 +34029a0c69bba882264a29fc822f8283fd15f104 jdk8-b24 +ec17fbe5b8fbc52da070eec43b4711d9354b2ab8 jdk8-b25 diff -r fc06525cb345 -r 5561a4c99825 jdk/make/com/oracle/Makefile --- a/jdk/make/com/oracle/Makefile Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/make/com/oracle/Makefile Thu Feb 09 23:17:22 2012 -0800 @@ -38,8 +38,14 @@ endif endif +JFR = +ifndef OPENJDK +ifndef JAVASE_EMBEDDED + JFR = jfr +endif +endif -SUBDIRS = net nio util $(UCRYPTO) +SUBDIRS = $(JFR) net nio util $(UCRYPTO) include $(BUILDDIR)/common/Subdirs.gmk diff -r fc06525cb345 -r 5561a4c99825 jdk/make/com/oracle/jfr/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/make/com/oracle/jfr/Makefile Thu Feb 09 23:17:22 2012 -0800 @@ -0,0 +1,73 @@ +# +# 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. 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 = oracle.jrockit.jfr +LIBRARY = jfr +PRODUCT = oracle +include $(BUILDDIR)/common/Defs.gmk + +# +# Use mapfile +# +FILES_m = $(CLOSED_SHARE_SRC)/native/oracle/jfr/mapfile-vers +include $(BUILDDIR)/common/Mapfile-vers.gmk + +# +# Files to compile +# +FILES_c = VMJFR.c + +AUTO_FILES_JAVA_DIRS = com/oracle/jrockit/jfr oracle/jrockit/jfr + +# Find C source files +# +vpath %.c $(CLOSED_SHARE_SRC)/native/oracle/jfr + +# +# Library to compile. +# +include $(BUILDDIR)/common/Library.gmk + +JVMLIB = +JAVALIB = +OTHER_LDLIBS = + +clean clobber:: + $(RM) -r $(CLASSDESTDIR)/com/oracle/jrockit/jfr + $(RM) -r $(CLASSDESTDIR)/oracle/jrockit/jfr + + +# Copy pre-shipped .jfs files +JFR_LIBDIR = $(LIBDIR)/jfr +JFR_SRCDIR = $(CLOSED_SHARE_SRC)/lib/jfr + +$(JFR_LIBDIR)/%.jfs: $(JFR_SRCDIR)/%.jfs + $(install-file) + +JFS_FILES := $(subst $(JFR_SRCDIR),$(JFR_LIBDIR),$(wildcard $(JFR_SRCDIR)/*.jfs)) + +all build : $(JFS_FILES) + diff -r fc06525cb345 -r 5561a4c99825 jdk/make/common/Defs.gmk --- a/jdk/make/common/Defs.gmk Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/make/common/Defs.gmk Thu Feb 09 23:17:22 2012 -0800 @@ -425,7 +425,12 @@ # namely jni.h, jvm.h, and jni_utils.h, plus their platform-specific # relatives. # -VPATH.h = $(PLATFORM_SRC)/javavm/export$(CLASSPATH_SEPARATOR)$(SHARE_SRC)/javavm/export +VPATH0.h = $(PLATFORM_SRC)/javavm/export$(CLASSPATH_SEPARATOR)$(SHARE_SRC)/javavm/export +ifdef OPENJDK + VPATH.h = $(VPATH0.h) +else + VPATH.h = $(CLOSED_SHARE_SRC)/javavm/export$(CLASSPATH_SEPARATOR)$(VPATH0.h) +endif vpath %.h $(VPATH.h) # diff -r fc06525cb345 -r 5561a4c99825 jdk/make/common/Release.gmk --- a/jdk/make/common/Release.gmk Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/make/common/Release.gmk Thu Feb 09 23:17:22 2012 -0800 @@ -381,6 +381,11 @@ sun/tools/jinfo \ sun/tools/jmap +# classes that go into jfr.jar +JFR_CLASSES_DIRS= \ + com/oracle/jrockit/jfr \ + oracle/jrockit/jfr + # classes that go into jsse.jar JSSE_CLASSES_DIRS = \ sun/security/provider/Sun.class \ @@ -583,6 +588,23 @@ $(ECHO) "sun/tools/jstack/" >> $@ $(ECHO) "sun/tools/jinfo/" >> $@ $(ECHO) "sun/tools/jmap/" >> $@ +ifndef OPENJDK +ifndef JAVASE_EMBEDDED + $(ECHO) "com/oracle/jrockit/jfr/" >> $@ + $(ECHO) "com/oracle/jrockit/jfr/client/" >> $@ + $(ECHO) "com/oracle/jrockit/jfr/management/" >> $@ + $(ECHO) "oracle/jrockit/jfr/" >> $@ + $(ECHO) "oracle/jrockit/jfr/events/" >> $@ + $(ECHO) "oracle/jrockit/jfr/openmbean/" >> $@ + $(ECHO) "oracle/jrockit/jfr/parser/" >> $@ + $(ECHO) "oracle/jrockit/jfr/settings/" >> $@ + $(ECHO) "oracle/jrockit/jfr/tools/" >> $@ + $(ECHO) "oracle/jrockit/jfr/util/" >> $@ + $(ECHO) "oracle/jrockit/jfr/util/log/" >> $@ + $(ECHO) "oracle/jrockit/jfr/util/os/" >> $@ + $(ECHO) "oracle/jrockit/jfr/util/text/" >> $@ +endif +endif # File order list for rt.jar @@ -607,6 +629,20 @@ $(MV) $@.temp $@ @($(CD) $(CLASSBINDIR) && $(java-vm-cleanup)) +# Create the jfr.jar containing Java Flight Recorder implementation +JFR_JAR= +ifndef OPENJDK +ifndef JAVASE_EMBEDDED +JFR_JAR=$(ABS_TEMPDIR)/jfr-orig.jar +$(JFR_JAR): $(OTHER_JAR_MANIFEST_FILE) + $(prep-target) + $(CD) $(CLASSBINDIR) && \ + $(BOOT_JAR_CMD) $(CREATE_JAR_OPTS) $(OTHER_JAR_MANIFEST_FILE) $@ \ + $(JFR_CLASSES_DIRS) $(BOOT_JAR_JFLAGS) + @$(CD) $(CLASSBINDIR) && $(java-vm-cleanup) +endif +endif + # Create the rt.jar file list & non-class files list JARSPLIT_JARFILE = $(BUILDTOOLJARDIR)/jarsplit.jar @@ -741,7 +777,7 @@ # drive names like C: initial-image-jre:: initial-image-jre-setup \ $(JRE_DOCFILES) \ - $(RT_JAR) $(RESOURCES_JAR) $(JSSE_JAR) \ + $(RT_JAR) $(RESOURCES_JAR) $(JSSE_JAR) $(JFR_JAR) \ $(BUILDMETAINDEX_JARFILE) @# Copy in bin directory $(CD) $(OUTPUTDIR) && $(FIND) bin -depth | $(CPIO) -pdum $(JRE_IMAGE_DIR) @@ -769,6 +805,9 @@ $(CP) $(RT_JAR) $(JRE_IMAGE_DIR)/lib/rt.jar $(CP) $(RESOURCES_JAR) $(JRE_IMAGE_DIR)/lib/resources.jar $(CP) $(JSSE_JAR) $(JRE_IMAGE_DIR)/lib/jsse.jar +ifneq ($(JFR_JAR),) + $(CP) $(JFR_JAR) $(JRE_IMAGE_DIR)/lib/jfr.jar +endif @# Generate meta-index to make boot and extension class loaders lazier $(CD) $(JRE_IMAGE_DIR)/lib && \ $(BOOT_JAVA_CMD) -jar $(BUILDMETAINDEX_JARFILE) \ diff -r fc06525cb345 -r 5561a4c99825 jdk/make/jprt.properties --- a/jdk/make/jprt.properties Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/make/jprt.properties Thu Feb 09 23:17:22 2012 -0800 @@ -62,18 +62,32 @@ # Default jdk test targets (testset=default) jprt.make.rule.default.test.targets= \ - ${jprt.my.test.target.set:TESTNAME=jdk_beans1}, \ + ${jprt.my.test.target.set:TESTNAME=jdk_lang}, \ + ${jprt.my.test.target.set:TESTNAME=jdk_math} + +# Default vm test targets (testset=core) +jprt.vm.core.test.targets= \ + ${jprt.vm.default.test.targets} + +# Core jdk test targets (testset=core) +jprt.make.rule.core.test.targets= \ + ${jprt.make.rule.default.test.targets}, \ + ${jprt.my.test.target.set:TESTNAME=jdk_util}, \ ${jprt.my.test.target.set:TESTNAME=jdk_io}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_lang}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_math}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_misc}, \ ${jprt.my.test.target.set:TESTNAME=jdk_net}, \ ${jprt.my.test.target.set:TESTNAME=jdk_nio1}, \ ${jprt.my.test.target.set:TESTNAME=jdk_nio2}, \ ${jprt.my.test.target.set:TESTNAME=jdk_nio3}, \ ${jprt.my.test.target.set:TESTNAME=jdk_security1}, \ + ${jprt.my.test.target.set:TESTNAME=jdk_security2}, \ + ${jprt.my.test.target.set:TESTNAME=jdk_security3}, \ + ${jprt.my.test.target.set:TESTNAME=jdk_rmi}, \ + ${jprt.my.test.target.set:TESTNAME=jdk_management1}, \ + ${jprt.my.test.target.set:TESTNAME=jdk_management2}, \ ${jprt.my.test.target.set:TESTNAME=jdk_text}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_util} + ${jprt.my.test.target.set:TESTNAME=jdk_tools1}, \ + ${jprt.my.test.target.set:TESTNAME=jdk_tools2}, \ + ${jprt.my.test.target.set:TESTNAME=jdk_misc} # All vm test targets (testset=all) jprt.vm.all.test.targets= \ @@ -83,19 +97,13 @@ # All jdk test targets (testset=all) jprt.make.rule.all.test.targets= \ - ${jprt.make.rule.default.test.targets}, \ + ${jprt.make.rule.core.test.targets}, \ ${jprt.my.test.target.set:TESTNAME=jdk_awt}, \ + ${jprt.my.test.target.set:TESTNAME=jdk_beans1}, \ ${jprt.my.test.target.set:TESTNAME=jdk_beans2}, \ ${jprt.my.test.target.set:TESTNAME=jdk_beans3}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_management1}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_management2}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_rmi}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_security2}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_security3}, \ ${jprt.my.test.target.set:TESTNAME=jdk_sound}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_swing}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_tools1}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_tools2} + ${jprt.my.test.target.set:TESTNAME=jdk_swing} # JCK test targets in test/Makefile (no windows) jprt.my.jck.test.target.set= \ diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath2Filter.java --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath2Filter.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath2Filter.java Thu Feb 09 23:17:22 2012 -0800 @@ -148,8 +148,8 @@ } - input.addNodeFilter(new XPath2NodeFilter(convertNodeListToSet(unionNodes), - convertNodeListToSet(substractNodes),convertNodeListToSet(intersectNodes))); + input.addNodeFilter(new XPath2NodeFilter(unionNodes, substractNodes, + intersectNodes)); input.setNodeSet(true); return input; } catch (TransformerException ex) { @@ -170,32 +170,20 @@ throw new TransformationException("empty", ex); } } - static Set convertNodeListToSet(List l){ - Set result=new HashSet(); - - for (NodeList rootNodes : l) { - int length = rootNodes.getLength(); - for (int i = 0; i < length; i++) { - Node rootNode = rootNodes.item(i); - result.add(rootNode); - } - } - return result; - } } class XPath2NodeFilter implements NodeFilter { - boolean hasUnionNodes; - boolean hasSubstractNodes; - boolean hasIntersectNodes; - XPath2NodeFilter(Set unionNodes, Set substractNodes, - Set intersectNodes) { - this.unionNodes=unionNodes; - hasUnionNodes=!unionNodes.isEmpty(); - this.substractNodes=substractNodes; - hasSubstractNodes=!substractNodes.isEmpty(); - this.intersectNodes=intersectNodes; - hasIntersectNodes=!intersectNodes.isEmpty(); + boolean hasUnionFilter; + boolean hasSubstractFilter; + boolean hasIntersectFilter; + XPath2NodeFilter(List unionNodes, List substractNodes, + List intersectNodes) { + hasUnionFilter=!unionNodes.isEmpty(); + this.unionNodes=convertNodeListToSet(unionNodes); + hasSubstractFilter=!substractNodes.isEmpty(); + this.substractNodes=convertNodeListToSet(substractNodes); + hasIntersectFilter=!intersectNodes.isEmpty(); + this.intersectNodes=convertNodeListToSet(intersectNodes); } Set unionNodes; Set substractNodes; @@ -208,16 +196,16 @@ public int isNodeInclude(Node currentNode) { int result=1; - if (hasSubstractNodes && rooted(currentNode, substractNodes)) { + if (hasSubstractFilter && rooted(currentNode, substractNodes)) { result = -1; - } else if (hasIntersectNodes && !rooted(currentNode, intersectNodes)) { + } else if (hasIntersectFilter && !rooted(currentNode, intersectNodes)) { result = 0; } //TODO OPTIMIZE if (result==1) return 1; - if (hasUnionNodes) { + if (hasUnionFilter) { if (rooted(currentNode, unionNodes)) { return 1; } @@ -231,7 +219,7 @@ int inUnion=-1; public int isNodeIncludeDO(Node n, int level) { int result=1; - if (hasSubstractNodes) { + if (hasSubstractFilter) { if ((inSubstract==-1) || (level<=inSubstract)) { if (inList(n, substractNodes)) { inSubstract=level; @@ -244,7 +232,7 @@ } } if (result!=-1){ - if (hasIntersectNodes) { + if (hasIntersectFilter) { if ((inIntersect==-1) || (level<=inIntersect)) { if (!inList(n, intersectNodes)) { inIntersect=-1; @@ -260,7 +248,7 @@ inUnion=-1; if (result==1) return 1; - if (hasUnionNodes) { + if (hasUnionFilter) { if ((inUnion==-1) && inList(n, unionNodes)) { inUnion=level; } @@ -280,6 +268,9 @@ * @return if rooted bye the rootnodes */ static boolean rooted(Node currentNode, Set nodeList ) { + if (nodeList.isEmpty()) { + return false; + } if (nodeList.contains(currentNode)) { return true; } @@ -302,4 +293,17 @@ static boolean inList(Node currentNode, Set nodeList ) { return nodeList.contains(currentNode); } + + private static Set convertNodeListToSet(List l){ + Set result=new HashSet(); + + for (NodeList rootNodes : l) { + int length = rootNodes.getLength(); + for (int i = 0; i < length; i++) { + Node rootNode = rootNodes.item(i); + result.add(rootNode); + } + } + return result; + } } diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java --- a/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java Thu Feb 09 23:17:22 2012 -0800 @@ -6431,7 +6431,8 @@ * @see #setKeyColumns */ public int[] getKeyColumns() throws SQLException { - return keyCols; + int[]keyColumns = this.keyCols; + return (keyColumns == null) ? null : Arrays.copyOf(keyColumns, keyColumns.length); } diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/com/sun/rowset/internal/BaseRow.java --- a/jdk/src/share/classes/com/sun/rowset/internal/BaseRow.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/com/sun/rowset/internal/BaseRow.java Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 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 @@ -27,6 +27,7 @@ import java.sql.*; import java.io.*; +import java.util.Arrays; /** * The abstract base class from which the classes Row @@ -65,7 +66,8 @@ * original values */ public Object[] getOrigRow() { - return origVals; + Object[] origRow = this.origVals; + return (origRow == null) ? null: Arrays.copyOf(origRow, origRow.length); } /** diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java --- a/jdk/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java Thu Feb 09 23:17:22 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 @@ -48,7 +48,7 @@ * for this field is set with the java.io.Writer object given * as the second argument to the writeXML method. */ - private java.io.Writer writer; + private transient java.io.Writer writer; /** * The java.util.Stack object that this WebRowSetXmlWriter @@ -205,16 +205,11 @@ //Changed to beginSection and endSection for maps for proper indentation beginSection("map"); - java.util.Map typeMap = caller.getTypeMap(); - if (typeMap != null) { - Iterator i = typeMap.keySet().iterator(); - Class c; - String type; - while (i.hasNext()) { - type = (String)i.next(); - c = (Class)typeMap.get(type); - propString("type", type); - propString("class", c.getName()); + Map> typeMap = caller.getTypeMap(); + if(typeMap != null) { + for(Map.Entry> mm : typeMap.entrySet()) { + propString("type", mm.getKey()); + propString("class", mm.getValue().getName()); } } endSection("map"); diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/java/io/DataInput.java --- a/jdk/src/share/classes/java/io/DataInput.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/java/io/DataInput.java Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2006, 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 @@ -26,12 +26,12 @@ package java.io; /** - * The DataInput interface provides + * The {@code DataInput} interface provides * for reading bytes from a binary stream and * reconstructing from them data in any of * the Java primitive types. There is also * a - * facility for reconstructing a String + * facility for reconstructing a {@code String} * from data in * modified UTF-8 * format. @@ -39,12 +39,12 @@ * It is generally true of all the reading * routines in this interface that if end of * file is reached before the desired number - * of bytes has been read, an EOFException - * (which is a kind of IOException) + * of bytes has been read, an {@code EOFException} + * (which is a kind of {@code IOException}) * is thrown. If any byte cannot be read for - * any reason other than end of file, an IOException - * other than EOFException is - * thrown. In particular, an IOException + * any reason other than end of file, an {@code IOException} + * other than {@code EOFException} is + * thrown. In particular, an {@code IOException} * may be thrown if the input stream has been * closed. * @@ -58,8 +58,8 @@ * Note that in the following tables, the most significant bit appears in the * far left-hand column. *

- * All characters in the range '\u0001' to - * '\u007F' are represented by a single byte: + * All characters in the range {@code '\u005Cu0001'} to + * {@code '\u005Cu007F'} are represented by a single byte: * *

* * *

- * The null character '\u0000' and characters in the - * range '\u0080' to '\u07FF' are + * The null character {@code '\u005Cu0000'} and characters in the + * range {@code '\u005Cu0080'} to {@code '\u005Cu07FF'} are * represented by a pair of bytes: * *

@@ -123,8 +123,8 @@ *
* *
- * char values in the range '\u0800' to - * '\uFFFF' are represented by three bytes: + * {@code char} values in the range {@code '\u005Cu0800'} to + * {@code '\u005CuFFFF'} are represented by three bytes: * *
*
- *
  • The null byte '\u0000' is encoded in 2-byte format + *
  • The null byte {@code '\u005Cu0000'} is encoded in 2-byte format * rather than 1-byte, so that the encoded strings never have * embedded nulls. *
  • Only the 1-byte, 2-byte, and 3-byte formats are used. @@ -195,36 +195,36 @@ /** * Reads some bytes from an input * stream and stores them into the buffer - * array b. The number of bytes + * array {@code b}. The number of bytes * read is equal - * to the length of b. + * to the length of {@code b}. *

    * This method blocks until one of the * following conditions occurs:

    *

      - *
    • b.length + *
    • {@code b.length} * bytes of input data are available, in which * case a normal return is made. * *
    • End of - * file is detected, in which case an EOFException + * file is detected, in which case an {@code EOFException} * is thrown. * *
    • An I/O error occurs, in - * which case an IOException other - * than EOFException is thrown. + * which case an {@code IOException} other + * than {@code EOFException} is thrown. *
    *

    - * If b is null, - * a NullPointerException is thrown. - * If b.length is zero, then + * If {@code b} is {@code null}, + * a {@code NullPointerException} is thrown. + * If {@code b.length} is zero, then * no bytes are read. Otherwise, the first - * byte read is stored into element b[0], - * the next one into b[1], and + * byte read is stored into element {@code b[0]}, + * the next one into {@code b[1]}, and * so on. * If an exception is thrown from * this method, then it may be that some but - * not all bytes of b have been + * not all bytes of {@code b} have been * updated with data from the input stream. * * @param b the buffer into which the data is read. @@ -236,7 +236,7 @@ /** * - * Reads len + * Reads {@code len} * bytes from * an input stream. *

    @@ -244,32 +244,32 @@ * blocks until one of the following conditions * occurs:

    *

      - *
    • len bytes + *
    • {@code len} bytes * of input data are available, in which case * a normal return is made. * *
    • End of file - * is detected, in which case an EOFException + * is detected, in which case an {@code EOFException} * is thrown. * *
    • An I/O error occurs, in - * which case an IOException other - * than EOFException is thrown. + * which case an {@code IOException} other + * than {@code EOFException} is thrown. *
    *

    - * If b is null, - * a NullPointerException is thrown. - * If off is negative, or len - * is negative, or off+len is - * greater than the length of the array b, - * then an IndexOutOfBoundsException + * If {@code b} is {@code null}, + * a {@code NullPointerException} is thrown. + * If {@code off} is negative, or {@code len} + * is negative, or {@code off+len} is + * greater than the length of the array {@code b}, + * then an {@code IndexOutOfBoundsException} * is thrown. - * If len is zero, + * If {@code len} is zero, * then no bytes are read. Otherwise, the first - * byte read is stored into element b[off], - * the next one into b[off+1], + * byte read is stored into element {@code b[off]}, + * the next one into {@code b[off+1]}, * and so on. The number of bytes read is, - * at most, equal to len. + * at most, equal to {@code len}. * * @param b the buffer into which the data is read. * @param off an int specifying the offset into the data. @@ -282,7 +282,7 @@ /** * Makes an attempt to skip over - * n bytes + * {@code n} bytes * of data from the input * stream, discarding the skipped bytes. However, * it may skip @@ -290,10 +290,10 @@ * bytes, possibly zero. This may result from * any of a * number of conditions; reaching - * end of file before n bytes + * end of file before {@code n} bytes * have been skipped is * only one possibility. - * This method never throws an EOFException. + * This method never throws an {@code EOFException}. * The actual * number of bytes skipped is returned. * @@ -305,13 +305,13 @@ /** * Reads one input byte and returns - * true if that byte is nonzero, - * false if that byte is zero. + * {@code true} if that byte is nonzero, + * {@code false} if that byte is zero. * This method is suitable for reading - * the byte written by the writeBoolean - * method of interface DataOutput. + * the byte written by the {@code writeBoolean} + * method of interface {@code DataOutput}. * - * @return the boolean value read. + * @return the {@code boolean} value read. * @exception EOFException if this stream reaches the end before reading * all the bytes. * @exception IOException if an I/O error occurs. @@ -321,11 +321,11 @@ /** * Reads and returns one input byte. * The byte is treated as a signed value in - * the range -128 through 127, + * the range {@code -128} through {@code 127}, * inclusive. * This method is suitable for - * reading the byte written by the writeByte - * method of interface DataOutput. + * reading the byte written by the {@code writeByte} + * method of interface {@code DataOutput}. * * @return the 8-bit value read. * @exception EOFException if this stream reaches the end before reading @@ -336,16 +336,16 @@ /** * Reads one input byte, zero-extends - * it to type int, and returns + * it to type {@code int}, and returns * the result, which is therefore in the range - * 0 - * through 255. + * {@code 0} + * through {@code 255}. * This method is suitable for reading - * the byte written by the writeByte - * method of interface DataOutput - * if the argument to writeByte + * the byte written by the {@code writeByte} + * method of interface {@code DataOutput} + * if the argument to {@code writeByte} * was intended to be a value in the range - * 0 through 255. + * {@code 0} through {@code 255}. * * @return the unsigned 8-bit value read. * @exception EOFException if this stream reaches the end before reading @@ -356,8 +356,8 @@ /** * Reads two input bytes and returns - * a short value. Let a - * be the first byte read and b + * a {@code short} value. Let {@code a} + * be the first byte read and {@code b} * be the second byte. The value * returned * is: @@ -365,8 +365,8 @@ * * This method * is suitable for reading the bytes written - * by the writeShort method of - * interface DataOutput. + * by the {@code writeShort} method of + * interface {@code DataOutput}. * * @return the 16-bit value read. * @exception EOFException if this stream reaches the end before reading @@ -377,19 +377,19 @@ /** * Reads two input bytes and returns - * an int value in the range 0 - * through 65535. Let a + * an {@code int} value in the range {@code 0} + * through {@code 65535}. Let {@code a} * be the first byte read and - * b + * {@code b} * be the second byte. The value returned is: *

    (((a & 0xff) << 8) | (b & 0xff))
          * 
    * This method is suitable for reading the bytes - * written by the writeShort method - * of interface DataOutput if - * the argument to writeShort + * written by the {@code writeShort} method + * of interface {@code DataOutput} if + * the argument to {@code writeShort} * was intended to be a value in the range - * 0 through 65535. + * {@code 0} through {@code 65535}. * * @return the unsigned 16-bit value read. * @exception EOFException if this stream reaches the end before reading @@ -399,19 +399,19 @@ int readUnsignedShort() throws IOException; /** - * Reads two input bytes and returns a char value. - * Let a - * be the first byte read and b + * Reads two input bytes and returns a {@code char} value. + * Let {@code a} + * be the first byte read and {@code b} * be the second byte. The value * returned is: *

    (char)((a << 8) | (b & 0xff))
          * 
    * This method * is suitable for reading bytes written by - * the writeChar method of interface - * DataOutput. + * the {@code writeChar} method of interface + * {@code DataOutput}. * - * @return the char value read. + * @return the {@code char} value read. * @exception EOFException if this stream reaches the end before reading * all the bytes. * @exception IOException if an I/O error occurs. @@ -420,18 +420,17 @@ /** * Reads four input bytes and returns an - * int value. Let a-d + * {@code int} value. Let {@code a-d} * be the first through fourth bytes read. The value returned is: - *

    -     * 
    +     * 

    
          * (((a & 0xff) << 24) | ((b & 0xff) << 16) |
          *  ((c & 0xff) << 8) | (d & 0xff))
          * 
    * This method is suitable - * for reading bytes written by the writeInt - * method of interface DataOutput. + * for reading bytes written by the {@code writeInt} + * method of interface {@code DataOutput}. * - * @return the int value read. + * @return the {@code int} value read. * @exception EOFException if this stream reaches the end before reading * all the bytes. * @exception IOException if an I/O error occurs. @@ -440,10 +439,10 @@ /** * Reads eight input bytes and returns - * a long value. Let a-h + * a {@code long} value. Let {@code a-h} * be the first through eighth bytes read. * The value returned is: - *

     
    +     * 

    
          * (((long)(a & 0xff) << 56) |
          *  ((long)(b & 0xff) << 48) |
          *  ((long)(c & 0xff) << 40) |
    @@ -455,10 +454,10 @@
          * 
    *

    * This method is suitable - * for reading bytes written by the writeLong - * method of interface DataOutput. + * for reading bytes written by the {@code writeLong} + * method of interface {@code DataOutput}. * - * @return the long value read. + * @return the {@code long} value read. * @exception EOFException if this stream reaches the end before reading * all the bytes. * @exception IOException if an I/O error occurs. @@ -467,18 +466,18 @@ /** * Reads four input bytes and returns - * a float value. It does this - * by first constructing an int + * a {@code float} value. It does this + * by first constructing an {@code int} * value in exactly the manner - * of the readInt - * method, then converting this int - * value to a float in - * exactly the manner of the method Float.intBitsToFloat. + * of the {@code readInt} + * method, then converting this {@code int} + * value to a {@code float} in + * exactly the manner of the method {@code Float.intBitsToFloat}. * This method is suitable for reading - * bytes written by the writeFloat - * method of interface DataOutput. + * bytes written by the {@code writeFloat} + * method of interface {@code DataOutput}. * - * @return the float value read. + * @return the {@code float} value read. * @exception EOFException if this stream reaches the end before reading * all the bytes. * @exception IOException if an I/O error occurs. @@ -487,18 +486,18 @@ /** * Reads eight input bytes and returns - * a double value. It does this - * by first constructing a long + * a {@code double} value. It does this + * by first constructing a {@code long} * value in exactly the manner - * of the readlong - * method, then converting this long - * value to a double in exactly - * the manner of the method Double.longBitsToDouble. + * of the {@code readlong} + * method, then converting this {@code long} + * value to a {@code double} in exactly + * the manner of the method {@code Double.longBitsToDouble}. * This method is suitable for reading - * bytes written by the writeDouble - * method of interface DataOutput. + * bytes written by the {@code writeDouble} + * method of interface {@code DataOutput}. * - * @return the double value read. + * @return the {@code double} value read. * @exception EOFException if this stream reaches the end before reading * all the bytes. * @exception IOException if an I/O error occurs. @@ -512,35 +511,35 @@ * until it encounters a line terminator or * end of * file; the characters read are then - * returned as a String. Note + * returned as a {@code String}. Note * that because this * method processes bytes, * it does not support input of the full Unicode * character set. *

    * If end of file is encountered - * before even one byte can be read, then null + * before even one byte can be read, then {@code null} * is returned. Otherwise, each byte that is - * read is converted to type char - * by zero-extension. If the character '\n' + * read is converted to type {@code char} + * by zero-extension. If the character {@code '\n'} * is encountered, it is discarded and reading - * ceases. If the character '\r' + * ceases. If the character {@code '\r'} * is encountered, it is discarded and, if * the following byte converts to the - * character '\n', then that is + * character {@code '\n'}, then that is * discarded also; reading then ceases. If * end of file is encountered before either - * of the characters '\n' and - * '\r' is encountered, reading - * ceases. Once reading has ceased, a String + * of the characters {@code '\n'} and + * {@code '\r'} is encountered, reading + * ceases. Once reading has ceased, a {@code String} * is returned that contains all the characters * read and not discarded, taken in order. * Note that every character in this string - * will have a value less than \u0100, - * that is, (char)256. + * will have a value less than {@code \u005Cu0100}, + * that is, {@code (char)256}. * * @return the next line of text from the input stream, - * or null if the end of file is + * or {@code null} if the end of file is * encountered before a byte can be read. * @exception IOException if an I/O error occurs. */ @@ -550,15 +549,15 @@ * Reads in a string that has been encoded using a * modified UTF-8 * format. - * The general contract of readUTF + * The general contract of {@code readUTF} * is that it reads a representation of a Unicode * character string encoded in modified * UTF-8 format; this string of characters - * is then returned as a String. + * is then returned as a {@code String}. *

    * First, two bytes are read and used to * construct an unsigned 16-bit integer in - * exactly the manner of the readUnsignedShort + * exactly the manner of the {@code readUnsignedShort} * method . This integer value is called the * UTF length and specifies the number * of additional bytes to be read. These bytes @@ -570,58 +569,58 @@ * next group. *

    * If the first byte of a group - * matches the bit pattern 0xxxxxxx - * (where x means "may be 0 - * or 1"), then the group consists + * matches the bit pattern {@code 0xxxxxxx} + * (where {@code x} means "may be {@code 0} + * or {@code 1}"), then the group consists * of just that byte. The byte is zero-extended * to form a character. *

    * If the first byte - * of a group matches the bit pattern 110xxxxx, - * then the group consists of that byte a - * and a second byte b. If there - * is no byte b (because byte - * a was the last of the bytes - * to be read), or if byte b does - * not match the bit pattern 10xxxxxx, - * then a UTFDataFormatException + * of a group matches the bit pattern {@code 110xxxxx}, + * then the group consists of that byte {@code a} + * and a second byte {@code b}. If there + * is no byte {@code b} (because byte + * {@code a} was the last of the bytes + * to be read), or if byte {@code b} does + * not match the bit pattern {@code 10xxxxxx}, + * then a {@code UTFDataFormatException} * is thrown. Otherwise, the group is converted * to the character:

    *

    (char)(((a& 0x1F) << 6) | (b & 0x3F))
          * 
    * If the first byte of a group - * matches the bit pattern 1110xxxx, - * then the group consists of that byte a - * and two more bytes b and c. - * If there is no byte c (because - * byte a was one of the last + * matches the bit pattern {@code 1110xxxx}, + * then the group consists of that byte {@code a} + * and two more bytes {@code b} and {@code c}. + * If there is no byte {@code c} (because + * byte {@code a} was one of the last * two of the bytes to be read), or either - * byte b or byte c - * does not match the bit pattern 10xxxxxx, - * then a UTFDataFormatException + * byte {@code b} or byte {@code c} + * does not match the bit pattern {@code 10xxxxxx}, + * then a {@code UTFDataFormatException} * is thrown. Otherwise, the group is converted * to the character:

    *

    
          * (char)(((a & 0x0F) << 12) | ((b & 0x3F) << 6) | (c & 0x3F))
          * 
    * If the first byte of a group matches the - * pattern 1111xxxx or the pattern - * 10xxxxxx, then a UTFDataFormatException + * pattern {@code 1111xxxx} or the pattern + * {@code 10xxxxxx}, then a {@code UTFDataFormatException} * is thrown. *

    * If end of file is encountered * at any time during this entire process, - * then an EOFException is thrown. + * then an {@code EOFException} is thrown. *

    * After every group has been converted to * a character by this process, the characters * are gathered, in the same order in which * their corresponding groups were read from - * the input stream, to form a String, + * the input stream, to form a {@code String}, * which is returned. *

    - * The writeUTF - * method of interface DataOutput + * The {@code writeUTF} + * method of interface {@code DataOutput} * may be used to write data that is suitable * for reading by this method. * @return a Unicode string. diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/java/io/LineNumberInputStream.java --- a/jdk/src/share/classes/java/io/LineNumberInputStream.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/java/io/LineNumberInputStream.java Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2004, 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 @@ -30,13 +30,13 @@ * functionality of keeping track of the current line number. *

    * A line is a sequence of bytes ending with a carriage return - * character ('\r'), a newline character - * ('\n'), or a carriage return character followed + * character ({@code '\u005Cr'}), a newline character + * ({@code '\u005Cn'}), or a carriage return character followed * immediately by a linefeed character. In all three cases, the line * terminating character(s) are returned as a single newline character. *

    - * The line number begins at 0, and is incremented by - * 1 when a read returns a newline character. + * The line number begins at {@code 0}, and is incremented by + * {@code 1} when a {@code read} returns a newline character. * * @author Arthur van Hoff * @see java.io.LineNumberReader @@ -66,22 +66,22 @@ /** * Reads the next byte of data from this input stream. The value - * byte is returned as an int in the range - * 0 to 255. If no byte is available + * byte is returned as an {@code int} in the range + * {@code 0} to {@code 255}. If no byte is available * because the end of the stream has been reached, the value - * -1 is returned. This method blocks until input data + * {@code -1} is returned. This method blocks until input data * is available, the end of the stream is detected, or an exception * is thrown. *

    - * The read method of - * LineNumberInputStream calls the read + * The {@code read} method of + * {@code LineNumberInputStream} calls the {@code read} * method of the underlying input stream. It checks for carriage * returns and newline characters in the input, and modifies the * current line number as appropriate. A carriage-return character or * a carriage return followed by a newline character are both * converted into a single newline character. * - * @return the next byte of data, or -1 if the end of this + * @return the next byte of data, or {@code -1} if the end of this * stream is reached. * @exception IOException if an I/O error occurs. * @see java.io.FilterInputStream#in @@ -111,18 +111,18 @@ } /** - * Reads up to len bytes of data from this input stream + * Reads up to {@code len} bytes of data from this input stream * into an array of bytes. This method blocks until some input is available. *

    - * The read method of - * LineNumberInputStream repeatedly calls the - * read method of zero arguments to fill in the byte array. + * The {@code read} method of + * {@code LineNumberInputStream} repeatedly calls the + * {@code read} method of zero arguments to fill in the byte array. * * @param b the buffer into which the data is read. * @param off the start offset of the data. * @param len the maximum number of bytes read. * @return the total number of bytes read into the buffer, or - * -1 if there is no more data because the end of + * {@code -1} if there is no more data because the end of * this stream has been reached. * @exception IOException if an I/O error occurs. * @see java.io.LineNumberInputStream#read() @@ -160,15 +160,15 @@ } /** - * Skips over and discards n bytes of data from this - * input stream. The skip method may, for a variety of + * Skips over and discards {@code n} bytes of data from this + * input stream. The {@code skip} method may, for a variety of * reasons, end up skipping over some smaller number of bytes, - * possibly 0. The actual number of bytes skipped is - * returned. If n is negative, no bytes are skipped. + * possibly {@code 0}. The actual number of bytes skipped is + * returned. If {@code n} is negative, no bytes are skipped. *

    - * The skip method of LineNumberInputStream creates + * The {@code skip} method of {@code LineNumberInputStream} creates * a byte array and then repeatedly reads into it until - * n bytes have been read or the end of the stream has + * {@code n} bytes have been read or the end of the stream has * been reached. * * @param n the number of bytes to be skipped. @@ -225,12 +225,12 @@ *

    * Note that if the underlying input stream is able to supply * k input characters without blocking, the - * LineNumberInputStream can guarantee only to provide + * {@code LineNumberInputStream} can guarantee only to provide * k/2 characters without blocking, because the * k characters from the underlying input stream might - * consist of k/2 pairs of '\r' and - * '\n', which are converted to just - * k/2 '\n' characters. + * consist of k/2 pairs of {@code '\u005Cr'} and + * {@code '\u005Cn'}, which are converted to just + * k/2 {@code '\u005Cn'} characters. * * @return the number of bytes that can be read from this input stream * without blocking. @@ -243,12 +243,12 @@ /** * Marks the current position in this input stream. A subsequent - * call to the reset method repositions this stream at + * call to the {@code reset} method repositions this stream at * the last marked position so that subsequent reads re-read the same bytes. *

    - * The mark method of - * LineNumberInputStream remembers the current line - * number in a private variable, and then calls the mark + * The {@code mark} method of + * {@code LineNumberInputStream} remembers the current line + * number in a private variable, and then calls the {@code mark} * method of the underlying input stream. * * @param readlimit the maximum limit of bytes that can be read before @@ -264,12 +264,12 @@ /** * Repositions this stream to the position at the time the - * mark method was last called on this input stream. + * {@code mark} method was last called on this input stream. *

    - * The reset method of - * LineNumberInputStream resets the line number to be - * the line number at the time the mark method was - * called, and then calls the reset method of the + * The {@code reset} method of + * {@code LineNumberInputStream} resets the line number to be + * the line number at the time the {@code mark} method was + * called, and then calls the {@code reset} method of the * underlying input stream. *

    * Stream marks are intended to be used in diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/java/io/RandomAccessFile.java --- a/jdk/src/share/classes/java/io/RandomAccessFile.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/java/io/RandomAccessFile.java Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -41,16 +41,16 @@ * the file pointer past the bytes written. Output operations that write * past the current end of the implied array cause the array to be * extended. The file pointer can be read by the - * getFilePointer method and set by the seek + * {@code getFilePointer} method and set by the {@code seek} * method. *

    * It is generally true of all the reading routines in this class that * if end-of-file is reached before the desired number of bytes has been - * read, an EOFException (which is a kind of - * IOException) is thrown. If any byte cannot be read for - * any reason other than end-of-file, an IOException other - * than EOFException is thrown. In particular, an - * IOException may be thrown if the stream has been closed. + * read, an {@code EOFException} (which is a kind of + * {@code IOException}) is thrown. If any byte cannot be read for + * any reason other than end-of-file, an {@code IOException} other + * than {@code EOFException} is thrown. In particular, an + * {@code IOException} may be thrown if the stream has been closed. * * @author unascribed * @since JDK1.0 @@ -82,12 +82,12 @@ * href="#mode">RandomAccessFile(File,String) constructor. * *

    - * If there is a security manager, its checkRead method - * is called with the name argument + * If there is a security manager, its {@code checkRead} method + * is called with the {@code name} argument * as its argument to see if read access to the file is allowed. * If the mode allows writing, the security manager's - * checkWrite method - * is also called with the name argument + * {@code checkWrite} method + * is also called with the {@code name} argument * as its argument to see if write access to the file is allowed. * * @param name the system-dependent filename @@ -103,9 +103,9 @@ * that name cannot be created, or if some other error occurs * while opening or creating the file * @exception SecurityException if a security manager exists and its - * checkRead method denies read access to the file + * {@code checkRead} method denies read access to the file * or the mode is "rw" and the security manager's - * checkWrite method denies write access to the file + * {@code checkWrite} method denies write access to the file * @see java.lang.SecurityException * @see java.lang.SecurityManager#checkRead(java.lang.String) * @see java.lang.SecurityManager#checkWrite(java.lang.String) @@ -164,10 +164,10 @@ * updates to both the file's content and its metadata to be written, which * generally requires at least one more low-level I/O operation. * - *

    If there is a security manager, its checkRead method is - * called with the pathname of the file argument as its + *

    If there is a security manager, its {@code checkRead} method is + * called with the pathname of the {@code file} argument as its * argument to see if read access to the file is allowed. If the mode - * allows writing, the security manager's checkWrite method is + * allows writing, the security manager's {@code checkWrite} method is * also called with the path argument to see if write access to the file is * allowed. * @@ -185,9 +185,9 @@ * that name cannot be created, or if some other error occurs * while opening or creating the file * @exception SecurityException if a security manager exists and its - * checkRead method denies read access to the file + * {@code checkRead} method denies read access to the file * or the mode is "rw" and the security manager's - * checkWrite method denies write access to the file + * {@code checkWrite} method denies write access to the file * @see java.lang.SecurityManager#checkRead(java.lang.String) * @see java.lang.SecurityManager#checkWrite(java.lang.String) * @see java.nio.channels.FileChannel#force(boolean) @@ -253,7 +253,7 @@ * object associated with this file. * *

    The {@link java.nio.channels.FileChannel#position() - * position} of the returned channel will always be equal to + * position} of the returned channel will always be equal to * this object's file-pointer offset as returned by the {@link * #getFilePointer getFilePointer} method. Changing this object's * file-pointer offset, whether explicitly or by reading or writing bytes, @@ -277,9 +277,9 @@ /** * Opens a file and returns the file descriptor. The file is - * opened in read-write mode if the O_RDWR bit in mode + * opened in read-write mode if the O_RDWR bit in {@code mode} * is true, else the file is opened as read-only. - * If the name refers to a directory, an IOException + * If the {@code name} refers to a directory, an IOException * is thrown. * * @param name the name of the file @@ -293,15 +293,15 @@ /** * Reads a byte of data from this file. The byte is returned as an - * integer in the range 0 to 255 (0x00-0x0ff). This + * integer in the range 0 to 255 ({@code 0x00-0x0ff}). This * method blocks if no input is yet available. *

    - * Although RandomAccessFile is not a subclass of - * InputStream, this method behaves in exactly the same + * Although {@code RandomAccessFile} is not a subclass of + * {@code InputStream}, this method behaves in exactly the same * way as the {@link InputStream#read()} method of - * InputStream. + * {@code InputStream}. * - * @return the next byte of data, or -1 if the end of the + * @return the next byte of data, or {@code -1} if the end of the * file has been reached. * @exception IOException if an I/O error occurs. Not thrown if * end-of-file has been reached. @@ -318,59 +318,59 @@ private native int readBytes(byte b[], int off, int len) throws IOException; /** - * Reads up to len bytes of data from this file into an + * Reads up to {@code len} bytes of data from this file into an * array of bytes. This method blocks until at least one byte of input * is available. *

    - * Although RandomAccessFile is not a subclass of - * InputStream, this method behaves in exactly the + * Although {@code RandomAccessFile} is not a subclass of + * {@code InputStream}, this method behaves in exactly the * same way as the {@link InputStream#read(byte[], int, int)} method of - * InputStream. + * {@code InputStream}. * * @param b the buffer into which the data is read. - * @param off the start offset in array b + * @param off the start offset in array {@code b} * at which the data is written. * @param len the maximum number of bytes read. * @return the total number of bytes read into the buffer, or - * -1 if there is no more data because the end of + * {@code -1} if there is no more data because the end of * the file has been reached. * @exception IOException If the first byte cannot be read for any reason * other than end of file, or if the random access file has been closed, or if * some other I/O error occurs. - * @exception NullPointerException If b is null. - * @exception IndexOutOfBoundsException If off is negative, - * len is negative, or len is greater than - * b.length - off + * @exception NullPointerException If {@code b} is {@code null}. + * @exception IndexOutOfBoundsException If {@code off} is negative, + * {@code len} is negative, or {@code len} is greater than + * {@code b.length - off} */ public int read(byte b[], int off, int len) throws IOException { return readBytes(b, off, len); } /** - * Reads up to b.length bytes of data from this file + * Reads up to {@code b.length} bytes of data from this file * into an array of bytes. This method blocks until at least one byte * of input is available. *

    - * Although RandomAccessFile is not a subclass of - * InputStream, this method behaves in exactly the + * Although {@code RandomAccessFile} is not a subclass of + * {@code InputStream}, this method behaves in exactly the * same way as the {@link InputStream#read(byte[])} method of - * InputStream. + * {@code InputStream}. * * @param b the buffer into which the data is read. * @return the total number of bytes read into the buffer, or - * -1 if there is no more data because the end of + * {@code -1} if there is no more data because the end of * this file has been reached. * @exception IOException If the first byte cannot be read for any reason * other than end of file, or if the random access file has been closed, or if * some other I/O error occurs. - * @exception NullPointerException If b is null. + * @exception NullPointerException If {@code b} is {@code null}. */ public int read(byte b[]) throws IOException { return readBytes(b, 0, b.length); } /** - * Reads b.length bytes from this file into the byte + * Reads {@code b.length} bytes from this file into the byte * array, starting at the current file pointer. This method reads * repeatedly from the file until the requested number of bytes are * read. This method blocks until the requested number of bytes are @@ -386,7 +386,7 @@ } /** - * Reads exactly len bytes from this file into the byte + * Reads exactly {@code len} bytes from this file into the byte * array, starting at the current file pointer. This method reads * repeatedly from the file until the requested number of bytes are * read. This method blocks until the requested number of bytes are @@ -410,15 +410,15 @@ } /** - * Attempts to skip over n bytes of input discarding the + * Attempts to skip over {@code n} bytes of input discarding the * skipped bytes. *

    * * This method may skip over some smaller number of bytes, possibly zero. * This may result from any of a number of conditions; reaching end of - * file before n bytes have been skipped is only one - * possibility. This method never throws an EOFException. - * The actual number of bytes skipped is returned. If n + * file before {@code n} bytes have been skipped is only one + * possibility. This method never throws an {@code EOFException}. + * The actual number of bytes skipped is returned. If {@code n} * is negative, no bytes are skipped. * * @param n the number of bytes to be skipped. @@ -451,7 +451,7 @@ * Writes the specified byte to this file. The write starts at * the current file pointer. * - * @param b the byte to be written. + * @param b the {@code byte} to be written. * @exception IOException if an I/O error occurs. */ public native void write(int b) throws IOException; @@ -467,7 +467,7 @@ private native void writeBytes(byte b[], int off, int len) throws IOException; /** - * Writes b.length bytes from the specified byte array + * Writes {@code b.length} bytes from the specified byte array * to this file, starting at the current file pointer. * * @param b the data. @@ -478,8 +478,8 @@ } /** - * Writes len bytes from the specified byte array - * starting at offset off to this file. + * Writes {@code len} bytes from the specified byte array + * starting at offset {@code off} to this file. * * @param b the data. * @param off the start offset in the data. @@ -512,8 +512,8 @@ * @param pos the offset position, measured in bytes from the * beginning of the file, at which to set the file * pointer. - * @exception IOException if pos is less than - * 0 or if an I/O error occurs. + * @exception IOException if {@code pos} is less than + * {@code 0} or if an I/O error occurs. */ public native void seek(long pos) throws IOException; @@ -529,14 +529,14 @@ * Sets the length of this file. * *

    If the present length of the file as returned by the - * length method is greater than the newLength + * {@code length} method is greater than the {@code newLength} * argument then the file will be truncated. In this case, if the file - * offset as returned by the getFilePointer method is greater - * than newLength then after this method returns the offset - * will be equal to newLength. + * offset as returned by the {@code getFilePointer} method is greater + * than {@code newLength} then after this method returns the offset + * will be equal to {@code newLength}. * *

    If the present length of the file as returned by the - * length method is smaller than the newLength + * {@code length} method is smaller than the {@code newLength} * argument then the file will be extended. In this case, the contents of * the extended portion of the file are not defined. * @@ -584,14 +584,14 @@ // /** - * Reads a boolean from this file. This method reads a + * Reads a {@code boolean} from this file. This method reads a * single byte from the file, starting at the current file pointer. - * A value of 0 represents - * false. Any other value represents true. + * A value of {@code 0} represents + * {@code false}. Any other value represents {@code true}. * This method blocks until the byte is read, the end of the stream * is detected, or an exception is thrown. * - * @return the boolean value read. + * @return the {@code boolean} value read. * @exception EOFException if this file has reached the end. * @exception IOException if an I/O error occurs. */ @@ -605,7 +605,7 @@ /** * Reads a signed eight-bit value from this file. This method reads a * byte from the file, starting from the current file pointer. - * If the byte read is b, where + * If the byte read is {@code b}, where * 0 <= b <= 255, * then the result is: *

    @@ -616,7 +616,7 @@
          * is detected, or an exception is thrown.
          *
          * @return     the next byte of this file as a signed eight-bit
    -     *             byte.
    +     *             {@code byte}.
          * @exception  EOFException  if this file has reached the end.
          * @exception  IOException   if an I/O error occurs.
          */
    @@ -651,8 +651,8 @@
          * Reads a signed 16-bit number from this file. The method reads two
          * bytes from this file, starting at the current file pointer.
          * If the two bytes read, in order, are
    -     * b1 and b2, where each of the two values is
    -     * between 0 and 255, inclusive, then the
    +     * {@code b1} and {@code b2}, where each of the two values is
    +     * between {@code 0} and {@code 255}, inclusive, then the
          * result is equal to:
          * 
          *     (short)((b1 << 8) | b2)
    @@ -679,7 +679,7 @@
          * Reads an unsigned 16-bit number from this file. This method reads
          * two bytes from the file, starting at the current file pointer.
          * If the bytes read, in order, are
    -     * b1 and b2, where
    +     * {@code b1} and {@code b2}, where
          * 0 <= b1, b2 <= 255,
          * then the result is equal to:
          * 
    @@ -707,7 +707,7 @@
          * Reads a character from this file. This method reads two
          * bytes from the file, starting at the current file pointer.
          * If the bytes read, in order, are
    -     * b1 and b2, where
    +     * {@code b1} and {@code b2}, where
          * 0 <= b1, b2 <= 255,
          * then the result is equal to:
          * 
    @@ -718,7 +718,7 @@
          * stream is detected, or an exception is thrown.
          *
          * @return     the next two bytes of this file, interpreted as a
    -     *                  char.
    +     *                  {@code char}.
          * @exception  EOFException  if this file reaches the end before reading
          *               two bytes.
          * @exception  IOException   if an I/O error occurs.
    @@ -734,8 +734,8 @@
         /**
          * Reads a signed 32-bit integer from this file. This method reads 4
          * bytes from the file, starting at the current file pointer.
    -     * If the bytes read, in order, are b1,
    -     * b2, b3, and b4, where
    +     * If the bytes read, in order, are {@code b1},
    +     * {@code b2}, {@code b3}, and {@code b4}, where
          * 0 <= b1, b2, b3, b4 <= 255,
          * then the result is equal to:
          * 
    @@ -746,7 +746,7 @@
          * stream is detected, or an exception is thrown.
          *
          * @return     the next four bytes of this file, interpreted as an
    -     *             int.
    +     *             {@code int}.
          * @exception  EOFException  if this file reaches the end before reading
          *               four bytes.
          * @exception  IOException   if an I/O error occurs.
    @@ -765,9 +765,9 @@
          * Reads a signed 64-bit integer from this file. This method reads eight
          * bytes from the file, starting at the current file pointer.
          * If the bytes read, in order, are
    -     * b1, b2, b3,
    -     * b4, b5, b6,
    -     * b7, and b8, where:
    +     * {@code b1}, {@code b2}, {@code b3},
    +     * {@code b4}, {@code b5}, {@code b6},
    +     * {@code b7}, and {@code b8,} where:
          * 
          *     0 <= b1, b2, b3, b4, b5, b6, b7, b8 <=255,
          * 
    @@ -784,7 +784,7 @@ * stream is detected, or an exception is thrown. * * @return the next eight bytes of this file, interpreted as a - * long. + * {@code long}. * @exception EOFException if this file reaches the end before reading * eight bytes. * @exception IOException if an I/O error occurs. @@ -794,18 +794,18 @@ } /** - * Reads a float from this file. This method reads an - * int value, starting at the current file pointer, - * as if by the readInt method - * and then converts that int to a float - * using the intBitsToFloat method in class - * Float. + * Reads a {@code float} from this file. This method reads an + * {@code int} value, starting at the current file pointer, + * as if by the {@code readInt} method + * and then converts that {@code int} to a {@code float} + * using the {@code intBitsToFloat} method in class + * {@code Float}. *

    * This method blocks until the four bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next four bytes of this file, interpreted as a - * float. + * {@code float}. * @exception EOFException if this file reaches the end before reading * four bytes. * @exception IOException if an I/O error occurs. @@ -817,18 +817,18 @@ } /** - * Reads a double from this file. This method reads a - * long value, starting at the current file pointer, - * as if by the readLong method - * and then converts that long to a double - * using the longBitsToDouble method in - * class Double. + * Reads a {@code double} from this file. This method reads a + * {@code long} value, starting at the current file pointer, + * as if by the {@code readLong} method + * and then converts that {@code long} to a {@code double} + * using the {@code longBitsToDouble} method in + * class {@code Double}. *

    * This method blocks until the eight bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next eight bytes of this file, interpreted as a - * double. + * {@code double}. * @exception EOFException if this file reaches the end before reading * eight bytes. * @exception IOException if an I/O error occurs. @@ -849,7 +849,7 @@ * therefore, support the full Unicode character set. * *

    A line of text is terminated by a carriage-return character - * ('\r'), a newline character ('\n'), a + * ({@code '\u005Cr'}), a newline character ({@code '\u005Cn'}), a * carriage-return character immediately followed by a newline character, * or the end of the file. Line-terminating characters are discarded and * are not included as part of the string returned. @@ -901,7 +901,7 @@ *

    * The first two bytes are read, starting from the current file * pointer, as if by - * readUnsignedShort. This value gives the number of + * {@code readUnsignedShort}. This value gives the number of * following bytes that are in the encoded string, not * the length of the resulting string. The following bytes are then * interpreted as bytes encoding characters in the modified UTF-8 format @@ -923,13 +923,13 @@ } /** - * Writes a boolean to the file as a one-byte value. The - * value true is written out as the value - * (byte)1; the value false is written out - * as the value (byte)0. The write starts at + * Writes a {@code boolean} to the file as a one-byte value. The + * value {@code true} is written out as the value + * {@code (byte)1}; the value {@code false} is written out + * as the value {@code (byte)0}. The write starts at * the current position of the file pointer. * - * @param v a boolean value to be written. + * @param v a {@code boolean} value to be written. * @exception IOException if an I/O error occurs. */ public final void writeBoolean(boolean v) throws IOException { @@ -938,10 +938,10 @@ } /** - * Writes a byte to the file as a one-byte value. The + * Writes a {@code byte} to the file as a one-byte value. The * write starts at the current position of the file pointer. * - * @param v a byte value to be written. + * @param v a {@code byte} value to be written. * @exception IOException if an I/O error occurs. */ public final void writeByte(int v) throws IOException { @@ -950,10 +950,10 @@ } /** - * Writes a short to the file as two bytes, high byte first. + * Writes a {@code short} to the file as two bytes, high byte first. * The write starts at the current position of the file pointer. * - * @param v a short to be written. + * @param v a {@code short} to be written. * @exception IOException if an I/O error occurs. */ public final void writeShort(int v) throws IOException { @@ -963,11 +963,11 @@ } /** - * Writes a char to the file as a two-byte value, high + * Writes a {@code char} to the file as a two-byte value, high * byte first. The write starts at the current position of the * file pointer. * - * @param v a char value to be written. + * @param v a {@code char} value to be written. * @exception IOException if an I/O error occurs. */ public final void writeChar(int v) throws IOException { @@ -977,10 +977,10 @@ } /** - * Writes an int to the file as four bytes, high byte first. + * Writes an {@code int} to the file as four bytes, high byte first. * The write starts at the current position of the file pointer. * - * @param v an int to be written. + * @param v an {@code int} to be written. * @exception IOException if an I/O error occurs. */ public final void writeInt(int v) throws IOException { @@ -992,10 +992,10 @@ } /** - * Writes a long to the file as eight bytes, high byte first. + * Writes a {@code long} to the file as eight bytes, high byte first. * The write starts at the current position of the file pointer. * - * @param v a long to be written. + * @param v a {@code long} to be written. * @exception IOException if an I/O error occurs. */ public final void writeLong(long v) throws IOException { @@ -1011,13 +1011,13 @@ } /** - * Converts the float argument to an int using the - * floatToIntBits method in class Float, - * and then writes that int value to the file as a + * Converts the float argument to an {@code int} using the + * {@code floatToIntBits} method in class {@code Float}, + * and then writes that {@code int} value to the file as a * four-byte quantity, high byte first. The write starts at the * current position of the file pointer. * - * @param v a float value to be written. + * @param v a {@code float} value to be written. * @exception IOException if an I/O error occurs. * @see java.lang.Float#floatToIntBits(float) */ @@ -1026,13 +1026,13 @@ } /** - * Converts the double argument to a long using the - * doubleToLongBits method in class Double, - * and then writes that long value to the file as an + * Converts the double argument to a {@code long} using the + * {@code doubleToLongBits} method in class {@code Double}, + * and then writes that {@code long} value to the file as an * eight-byte quantity, high byte first. The write starts at the current * position of the file pointer. * - * @param v a double value to be written. + * @param v a {@code double} value to be written. * @exception IOException if an I/O error occurs. * @see java.lang.Double#doubleToLongBits(double) */ @@ -1060,10 +1060,10 @@ /** * Writes a string to the file as a sequence of characters. Each * character is written to the data output stream as if by the - * writeChar method. The write starts at the current + * {@code writeChar} method. The write starts at the current * position of the file pointer. * - * @param s a String value to be written. + * @param s a {@code String} value to be written. * @exception IOException if an I/O error occurs. * @see java.io.RandomAccessFile#writeChar(int) */ @@ -1087,7 +1087,7 @@ *

    * First, two bytes are written to the file, starting at the * current file pointer, as if by the - * writeShort method giving the number of bytes to + * {@code writeShort} method giving the number of bytes to * follow. This value is the number of bytes actually written out, * not the length of the string. Following the length, each character * of the string is output, in sequence, using the modified UTF-8 encoding diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/java/io/StreamTokenizer.java --- a/jdk/src/share/classes/java/io/StreamTokenizer.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/java/io/StreamTokenizer.java Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2005, 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 @@ -28,7 +28,7 @@ import java.util.Arrays; /** - * The StreamTokenizer class takes an input stream and + * The {@code StreamTokenizer} class takes an input stream and * parses it into "tokens", allowing the tokens to be * read one at a time. The parsing process is controlled by a table * and a number of flags that can be set to various states. The @@ -36,7 +36,7 @@ * strings, and various comment styles. *

    * Each byte read from the input stream is regarded as a character - * in the range '\u0000' through '\u00FF'. + * in the range {@code '\u005Cu0000'} through {@code '\u005Cu00FF'}. * The character value is used to look up five possible attributes of * the character: white space, alphabetic, * numeric, string quote, and comment character. @@ -53,8 +53,8 @@ *

    * A typical application first constructs an instance of this class, * sets up the syntax tables, and then repeatedly loops calling the - * nextToken method in each iteration of the loop until - * it returns the value TT_EOF. + * {@code nextToken} method in each iteration of the loop until + * it returns the value {@code TT_EOF}. * * @author James Gosling * @see java.io.StreamTokenizer#nextToken() @@ -99,19 +99,19 @@ private static final byte CT_COMMENT = 16; /** - * After a call to the nextToken method, this field + * After a call to the {@code nextToken} method, this field * contains the type of the token just read. For a single character * token, its value is the single character, converted to an integer. * For a quoted string token, its value is the quote character. * Otherwise, its value is one of the following: *

      - *
    • TT_WORD indicates that the token is a word. - *
    • TT_NUMBER indicates that the token is a number. - *
    • TT_EOL indicates that the end of line has been read. + *
    • {@code TT_WORD} indicates that the token is a word. + *
    • {@code TT_NUMBER} indicates that the token is a number. + *
    • {@code TT_EOL} indicates that the end of line has been read. * The field can only have this value if the - * eolIsSignificant method has been called with the - * argument true. - *
    • TT_EOF indicates that the end of the input stream + * {@code eolIsSignificant} method has been called with the + * argument {@code true}. + *
    • {@code TT_EOF} indicates that the end of the input stream * has been reached. *
    *

    @@ -160,8 +160,8 @@ * the string. *

    * The current token is a word when the value of the - * ttype field is TT_WORD. The current token is - * a quoted string token when the value of the ttype field is + * {@code ttype} field is {@code TT_WORD}. The current token is + * a quoted string token when the value of the {@code ttype} field is * a quote character. *

    * The initial value of this field is null. @@ -175,7 +175,7 @@ /** * If the current token is a number, this field contains the value * of that number. The current token is a number when the value of - * the ttype field is TT_NUMBER. + * the {@code ttype} field is {@code TT_NUMBER}. *

    * The initial value of this field is 0.0. * @@ -201,14 +201,14 @@ * stream. The stream tokenizer is initialized to the following * default state: *

      - *
    • All byte values 'A' through 'Z', - * 'a' through 'z', and - * '\u00A0' through '\u00FF' are + *
    • All byte values {@code 'A'} through {@code 'Z'}, + * {@code 'a'} through {@code 'z'}, and + * {@code '\u005Cu00A0'} through {@code '\u005Cu00FF'} are * considered to be alphabetic. - *
    • All byte values '\u0000' through - * '\u0020' are considered to be white space. - *
    • '/' is a comment character. - *
    • Single quote '\'' and double quote '"' + *
    • All byte values {@code '\u005Cu0000'} through + * {@code '\u005Cu0020'} are considered to be white space. + *
    • {@code '/'} is a comment character. + *
    • Single quote {@code '\u005C''} and double quote {@code '"'} * are string quote characters. *
    • Numbers are parsed. *
    • Ends of lines are treated as white space, not as separate tokens. @@ -252,7 +252,7 @@ /** * Resets this tokenizer's syntax table so that all characters are - * "ordinary." See the ordinaryChar method + * "ordinary." See the {@code ordinaryChar} method * for more information on a character being ordinary. * * @see java.io.StreamTokenizer#ordinaryChar(int) @@ -305,7 +305,7 @@ * Specifies that all characters c in the range * low <= c <= high * are "ordinary" in this tokenizer. See the - * ordinaryChar method for more information on a + * {@code ordinaryChar} method for more information on a * character being ordinary. * * @param low the low end of the range. @@ -327,12 +327,12 @@ * character has as a comment character, word component, string * delimiter, white space, or number character. When such a character * is encountered by the parser, the parser treats it as a - * single-character token and sets ttype field to the + * single-character token and sets {@code ttype} field to the * character value. * *

      Making a line terminator character "ordinary" may interfere - * with the ability of a StreamTokenizer to count - * lines. The lineno method may no longer reflect + * with the ability of a {@code StreamTokenizer} to count + * lines. The {@code lineno} method may no longer reflect * the presence of such terminator characters in its line count. * * @param ch the character. @@ -361,9 +361,9 @@ * Specifies that matching pairs of this character delimit string * constants in this tokenizer. *

      - * When the nextToken method encounters a string - * constant, the ttype field is set to the string - * delimiter and the sval field is set to the body of + * When the {@code nextToken} method encounters a string + * constant, the {@code ttype} field is set to the string + * delimiter and the {@code sval} field is set to the body of * the string. *

      * If a string quote character is encountered, then a string is @@ -371,7 +371,7 @@ * the string quote character, up to (but not including) the next * occurrence of that same string quote character, or a line * terminator, or end of file. The usual escape sequences such as - * "\n" and "\t" are recognized and + * {@code "\u005Cn"} and {@code "\u005Ct"} are recognized and * converted to single characters as the string is parsed. * *

      Any other attribute settings for the specified character are cleared. @@ -398,9 +398,9 @@ *

      * When the parser encounters a word token that has the format of a * double precision floating-point number, it treats the token as a - * number rather than a word, by setting the ttype - * field to the value TT_NUMBER and putting the numeric - * value of the token into the nval field. + * number rather than a word, by setting the {@code ttype} + * field to the value {@code TT_NUMBER} and putting the numeric + * value of the token into the {@code nval} field. * * @see java.io.StreamTokenizer#nval * @see java.io.StreamTokenizer#TT_NUMBER @@ -416,21 +416,21 @@ /** * Determines whether or not ends of line are treated as tokens. * If the flag argument is true, this tokenizer treats end of lines - * as tokens; the nextToken method returns - * TT_EOL and also sets the ttype field to + * as tokens; the {@code nextToken} method returns + * {@code TT_EOL} and also sets the {@code ttype} field to * this value when an end of line is read. *

      * A line is a sequence of characters ending with either a - * carriage-return character ('\r') or a newline - * character ('\n'). In addition, a carriage-return + * carriage-return character ({@code '\u005Cr'}) or a newline + * character ({@code '\u005Cn'}). In addition, a carriage-return * character followed immediately by a newline character is treated * as a single end-of-line token. *

      - * If the flag is false, end-of-line characters are + * If the {@code flag} is false, end-of-line characters are * treated as white space and serve only to separate tokens. * - * @param flag true indicates that end-of-line characters - * are separate tokens; false indicates that + * @param flag {@code true} indicates that end-of-line characters + * are separate tokens; {@code false} indicates that * end-of-line characters are white space. * @see java.io.StreamTokenizer#nextToken() * @see java.io.StreamTokenizer#ttype @@ -442,14 +442,14 @@ /** * Determines whether or not the tokenizer recognizes C-style comments. - * If the flag argument is true, this stream tokenizer + * If the flag argument is {@code true}, this stream tokenizer * recognizes C-style comments. All text between successive - * occurrences of /* and */ are discarded. + * occurrences of {@code /*} and */ are discarded. *

      - * If the flag argument is false, then C-style comments + * If the flag argument is {@code false}, then C-style comments * are not treated specially. * - * @param flag true indicates to recognize and ignore + * @param flag {@code true} indicates to recognize and ignore * C-style comments. */ public void slashStarComments(boolean flag) { @@ -458,15 +458,15 @@ /** * Determines whether or not the tokenizer recognizes C++-style comments. - * If the flag argument is true, this stream tokenizer + * If the flag argument is {@code true}, this stream tokenizer * recognizes C++-style comments. Any occurrence of two consecutive - * slash characters ('/') is treated as the beginning of + * slash characters ({@code '/'}) is treated as the beginning of * a comment that extends to the end of the line. *

      - * If the flag argument is false, then C++-style + * If the flag argument is {@code false}, then C++-style * comments are not treated specially. * - * @param flag true indicates to recognize and ignore + * @param flag {@code true} indicates to recognize and ignore * C++-style comments. */ public void slashSlashComments(boolean flag) { @@ -475,16 +475,16 @@ /** * Determines whether or not word token are automatically lowercased. - * If the flag argument is true, then the value in the - * sval field is lowercased whenever a word token is - * returned (the ttype field has the - * value TT_WORD by the nextToken method + * If the flag argument is {@code true}, then the value in the + * {@code sval} field is lowercased whenever a word token is + * returned (the {@code ttype} field has the + * value {@code TT_WORD} by the {@code nextToken} method * of this tokenizer. *

      - * If the flag argument is false, then the - * sval field is not modified. + * If the flag argument is {@code false}, then the + * {@code sval} field is not modified. * - * @param fl true indicates that all word tokens should + * @param fl {@code true} indicates that all word tokens should * be lowercased. * @see java.io.StreamTokenizer#nextToken() * @see java.io.StreamTokenizer#ttype @@ -506,9 +506,9 @@ /** * Parses the next token from the input stream of this tokenizer. - * The type of the next token is returned in the ttype + * The type of the next token is returned in the {@code ttype} * field. Additional information about the token may be in the - * nval field or the sval field of this + * {@code nval} field or the {@code sval} field of this * tokenizer. *

      * Typical clients of this @@ -516,7 +516,7 @@ * calling nextToken to parse successive tokens until TT_EOF * is returned. * - * @return the value of the ttype field. + * @return the value of the {@code ttype} field. * @exception IOException if an I/O error occurs. * @see java.io.StreamTokenizer#nval * @see java.io.StreamTokenizer#sval @@ -752,10 +752,10 @@ } /** - * Causes the next call to the nextToken method of this - * tokenizer to return the current value in the ttype - * field, and not to modify the value in the nval or - * sval field. + * Causes the next call to the {@code nextToken} method of this + * tokenizer to return the current value in the {@code ttype} + * field, and not to modify the value in the {@code nval} or + * {@code sval} field. * * @see java.io.StreamTokenizer#nextToken() * @see java.io.StreamTokenizer#nval diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/java/lang/AbstractStringBuilder.java --- a/jdk/src/share/classes/java/lang/AbstractStringBuilder.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/java/lang/AbstractStringBuilder.java Thu Feb 09 23:17:22 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 @@ -91,10 +91,10 @@ * array is allocated with greater capacity. The new capacity is the * larger of: *

        - *
      • The minimumCapacity argument. - *
      • Twice the old capacity, plus 2. + *
      • The {@code minimumCapacity} argument. + *
      • Twice the old capacity, plus {@code 2}. *
      - * If the minimumCapacity argument is nonpositive, this + * If the {@code minimumCapacity} argument is nonpositive, this * method takes no action and simply returns. * * @param minimumCapacity the minimum desired capacity. @@ -147,26 +147,26 @@ * Sets the length of the character sequence. * The sequence is changed to a new character sequence * whose length is specified by the argument. For every nonnegative - * index k less than newLength, the character at + * index k less than {@code newLength}, the character at * index k in the new character sequence is the same as the * character at index k in the old sequence if k is less * than the length of the old character sequence; otherwise, it is the - * null character '\u0000'. + * null character {@code '\u005Cu0000'}. * - * In other words, if the newLength argument is less than + * In other words, if the {@code newLength} argument is less than * the current length, the length is changed to the specified length. *

      - * If the newLength argument is greater than or equal + * If the {@code newLength} argument is greater than or equal * to the current length, sufficient null characters - * ('\u0000') are appended so that - * length becomes the newLength argument. + * ({@code '\u005Cu0000'}) are appended so that + * length becomes the {@code newLength} argument. *

      - * The newLength argument must be greater than or equal - * to 0. + * The {@code newLength} argument must be greater than or equal + * to {@code 0}. * * @param newLength the new length * @throws IndexOutOfBoundsException if the - * newLength argument is negative. + * {@code newLength} argument is negative. */ public void setLength(int newLength) { if (newLength < 0) @@ -182,21 +182,21 @@ } /** - * Returns the char value in this sequence at the specified index. - * The first char value is at index 0, the next at index - * 1, and so on, as in array indexing. + * Returns the {@code char} value in this sequence at the specified index. + * The first {@code char} value is at index {@code 0}, the next at index + * {@code 1}, and so on, as in array indexing. *

      * The index argument must be greater than or equal to - * 0, and less than the length of this sequence. + * {@code 0}, and less than the length of this sequence. * - *

      If the char value specified by the index is a + *

      If the {@code char} value specified by the index is a * surrogate, the surrogate * value is returned. * - * @param index the index of the desired char value. - * @return the char value at the specified index. - * @throws IndexOutOfBoundsException if index is - * negative or greater than or equal to length(). + * @param index the index of the desired {@code char} value. + * @return the {@code char} value at the specified index. + * @throws IndexOutOfBoundsException if {@code index} is + * negative or greater than or equal to {@code length()}. */ public char charAt(int index) { if ((index < 0) || (index >= count)) @@ -206,22 +206,22 @@ /** * Returns the character (Unicode code point) at the specified - * index. The index refers to char values - * (Unicode code units) and ranges from 0 to - * {@link #length()} - 1. + * index. The index refers to {@code char} values + * (Unicode code units) and ranges from {@code 0} to + * {@link #length()}{@code - 1}. * - *

      If the char value specified at the given index + *

      If the {@code char} value specified at the given index * is in the high-surrogate range, the following index is less * than the length of this sequence, and the - * char value at the following index is in the + * {@code char} value at the following index is in the * low-surrogate range, then the supplementary code point * corresponding to this surrogate pair is returned. Otherwise, - * the char value at the given index is returned. + * the {@code char} value at the given index is returned. * - * @param index the index to the char values + * @param index the index to the {@code char} values * @return the code point value of the character at the - * index - * @exception IndexOutOfBoundsException if the index + * {@code index} + * @exception IndexOutOfBoundsException if the {@code index} * argument is negative or not less than the length of this * sequence. */ @@ -234,22 +234,22 @@ /** * Returns the character (Unicode code point) before the specified - * index. The index refers to char values - * (Unicode code units) and ranges from 1 to {@link + * index. The index refers to {@code char} values + * (Unicode code units) and ranges from {@code 1} to {@link * #length()}. * - *

      If the char value at (index - 1) - * is in the low-surrogate range, (index - 2) is not - * negative, and the char value at (index - - * 2) is in the high-surrogate range, then the + *

      If the {@code char} value at {@code (index - 1)} + * is in the low-surrogate range, {@code (index - 2)} is not + * negative, and the {@code char} value at {@code (index - + * 2)} is in the high-surrogate range, then the * supplementary code point value of the surrogate pair is - * returned. If the char value at index - - * 1 is an unpaired low-surrogate or a high-surrogate, the + * returned. If the {@code char} value at {@code index - + * 1} is an unpaired low-surrogate or a high-surrogate, the * surrogate value is returned. * * @param index the index following the code point that should be returned * @return the Unicode code point value before the given index. - * @exception IndexOutOfBoundsException if the index + * @exception IndexOutOfBoundsException if the {@code index} * argument is less than 1 or greater than the length * of this sequence. */ @@ -264,22 +264,22 @@ /** * Returns the number of Unicode code points in the specified text * range of this sequence. The text range begins at the specified - * beginIndex and extends to the char at - * index endIndex - 1. Thus the length (in - * chars) of the text range is - * endIndex-beginIndex. Unpaired surrogates within + * {@code beginIndex} and extends to the {@code char} at + * index {@code endIndex - 1}. Thus the length (in + * {@code char}s) of the text range is + * {@code endIndex-beginIndex}. Unpaired surrogates within * this sequence count as one code point each. * - * @param beginIndex the index to the first char of + * @param beginIndex the index to the first {@code char} of * the text range. - * @param endIndex the index after the last char of + * @param endIndex the index after the last {@code char} of * the text range. * @return the number of Unicode code points in the specified text * range * @exception IndexOutOfBoundsException if the - * beginIndex is negative, or endIndex + * {@code beginIndex} is negative, or {@code endIndex} * is larger than the length of this sequence, or - * beginIndex is larger than endIndex. + * {@code beginIndex} is larger than {@code endIndex}. */ public int codePointCount(int beginIndex, int endIndex) { if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) { @@ -290,22 +290,22 @@ /** * Returns the index within this sequence that is offset from the - * given index by codePointOffset code + * given {@code index} by {@code codePointOffset} code * points. Unpaired surrogates within the text range given by - * index and codePointOffset count as + * {@code index} and {@code codePointOffset} count as * one code point each. * * @param index the index to be offset * @param codePointOffset the offset in code points * @return the index within this sequence - * @exception IndexOutOfBoundsException if index + * @exception IndexOutOfBoundsException if {@code index} * is negative or larger then the length of this sequence, - * or if codePointOffset is positive and the subsequence - * starting with index has fewer than - * codePointOffset code points, - * or if codePointOffset is negative and the subsequence - * before index has fewer than the absolute value of - * codePointOffset code points. + * or if {@code codePointOffset} is positive and the subsequence + * starting with {@code index} has fewer than + * {@code codePointOffset} code points, + * or if {@code codePointOffset} is negative and the subsequence + * before {@code index} has fewer than the absolute value of + * {@code codePointOffset} code points. */ public int offsetByCodePoints(int index, int codePointOffset) { if (index < 0 || index > count) { @@ -317,12 +317,12 @@ /** * Characters are copied from this sequence into the - * destination character array dst. The first character to - * be copied is at index srcBegin; the last character to - * be copied is at index srcEnd-1. The total number of - * characters to be copied is srcEnd-srcBegin. The - * characters are copied into the subarray of dst starting - * at index dstBegin and ending at index: + * destination character array {@code dst}. The first character to + * be copied is at index {@code srcBegin}; the last character to + * be copied is at index {@code srcEnd-1}. The total number of + * characters to be copied is {@code srcEnd-srcBegin}. The + * characters are copied into the subarray of {@code dst} starting + * at index {@code dstBegin} and ending at index: *

            * dstbegin + (srcEnd-srcBegin) - 1
            * 
      @@ -330,19 +330,19 @@ * @param srcBegin start copying at this offset. * @param srcEnd stop copying at this offset. * @param dst the array to copy the data into. - * @param dstBegin offset into dst. - * @throws NullPointerException if dst is - * null. + * @param dstBegin offset into {@code dst}. + * @throws NullPointerException if {@code dst} is + * {@code null}. * @throws IndexOutOfBoundsException if any of the following is true: *
        - *
      • srcBegin is negative - *
      • dstBegin is negative - *
      • the srcBegin argument is greater than - * the srcEnd argument. - *
      • srcEnd is greater than - * this.length(). - *
      • dstBegin+srcEnd-srcBegin is greater than - * dst.length + *
      • {@code srcBegin} is negative + *
      • {@code dstBegin} is negative + *
      • the {@code srcBegin} argument is greater than + * the {@code srcEnd} argument. + *
      • {@code srcEnd} is greater than + * {@code this.length()}. + *
      • {@code dstBegin+srcEnd-srcBegin} is greater than + * {@code dst.length} *
      */ public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) @@ -357,18 +357,18 @@ } /** - * The character at the specified index is set to ch. This + * The character at the specified index is set to {@code ch}. This * sequence is altered to represent a new character sequence that is * identical to the old character sequence, except that it contains the - * character ch at position index. + * character {@code ch} at position {@code index}. *

      * The index argument must be greater than or equal to - * 0, and less than the length of this sequence. + * {@code 0}, and less than the length of this sequence. * * @param index the index of the character to modify. * @param ch the new character. - * @throws IndexOutOfBoundsException if index is - * negative or greater than or equal to length(). + * @throws IndexOutOfBoundsException if {@code index} is + * negative or greater than or equal to {@code length()}. */ public void setCharAt(int index, char ch) { if ((index < 0) || (index >= count)) @@ -741,21 +741,21 @@ } /** - * Removes the char at the specified position in this - * sequence. This sequence is shortened by one char. + * Removes the {@code char} at the specified position in this + * sequence. This sequence is shortened by one {@code char}. * *

      Note: If the character at the given index is a supplementary * character, this method does not remove the entire character. If * correct handling of supplementary characters is required, - * determine the number of chars to remove by calling - * Character.charCount(thisSequence.codePointAt(index)), - * where thisSequence is this sequence. + * determine the number of {@code char}s to remove by calling + * {@code Character.charCount(thisSequence.codePointAt(index))}, + * where {@code thisSequence} is this sequence. * - * @param index Index of char to remove + * @param index Index of {@code char} to remove * @return This object. - * @throws StringIndexOutOfBoundsException if the index + * @throws StringIndexOutOfBoundsException if the {@code index} * is negative or greater than or equal to - * length(). + * {@code length()}. */ public AbstractStringBuilder deleteCharAt(int index) { if ((index < 0) || (index >= count)) @@ -767,12 +767,12 @@ /** * Replaces the characters in a substring of this sequence - * with characters in the specified String. The substring - * begins at the specified start and extends to the character - * at index end - 1 or to the end of the + * with characters in the specified {@code String}. The substring + * begins at the specified {@code start} and extends to the character + * at index {@code end - 1} or to the end of the * sequence if no such character exists. First the * characters in the substring are removed and then the specified - * String is inserted at start. (This + * {@code String} is inserted at {@code start}. (This * sequence will be lengthened to accommodate the * specified String if necessary.) * @@ -780,9 +780,9 @@ * @param end The ending index, exclusive. * @param str String that will replace previous contents. * @return This object. - * @throws StringIndexOutOfBoundsException if start - * is negative, greater than length(), or - * greater than end. + * @throws StringIndexOutOfBoundsException if {@code start} + * is negative, greater than {@code length()}, or + * greater than {@code end}. */ public AbstractStringBuilder replace(int start, int end, String str) { if (start < 0) @@ -805,14 +805,14 @@ } /** - * Returns a new String that contains a subsequence of + * Returns a new {@code String} that contains a subsequence of * characters currently contained in this character sequence. The * substring begins at the specified index and extends to the end of * this sequence. * * @param start The beginning index, inclusive. * @return The new string. - * @throws StringIndexOutOfBoundsException if start is + * @throws StringIndexOutOfBoundsException if {@code start} is * less than zero, or greater than the length of this object. */ public String substring(int start) { @@ -850,18 +850,18 @@ } /** - * Returns a new String that contains a subsequence of + * Returns a new {@code String} that contains a subsequence of * characters currently contained in this sequence. The - * substring begins at the specified start and - * extends to the character at index end - 1. + * substring begins at the specified {@code start} and + * extends to the character at index {@code end - 1}. * * @param start The beginning index, inclusive. * @param end The ending index, exclusive. * @return The new string. - * @throws StringIndexOutOfBoundsException if start - * or end are negative or greater than - * length(), or start is - * greater than end. + * @throws StringIndexOutOfBoundsException if {@code start} + * or {@code end} are negative or greater than + * {@code length()}, or {@code start} is + * greater than {@code end}. */ public String substring(int start, int end) { if (start < 0) @@ -1254,15 +1254,15 @@ *

            * this.toString().startsWith(str, k)
            * 
      - * is true. + * is {@code true}. * * @param str any string. * @return if the string argument occurs as a substring within this * object, then the index of the first character of the first * such substring is returned; if it does not occur as a - * substring, -1 is returned. - * @throws java.lang.NullPointerException if str is - * null. + * substring, {@code -1} is returned. + * @throws java.lang.NullPointerException if {@code str} is + * {@code null}. */ public int indexOf(String str) { return indexOf(str, 0); @@ -1282,8 +1282,8 @@ * @param fromIndex the index from which to start the search. * @return the index within this string of the first occurrence of the * specified substring, starting at the specified index. - * @throws java.lang.NullPointerException if str is - * null. + * @throws java.lang.NullPointerException if {@code str} is + * {@code null}. */ public int indexOf(String str, int fromIndex) { return String.indexOf(value, 0, count, @@ -1293,7 +1293,7 @@ /** * Returns the index within this string of the rightmost occurrence * of the specified substring. The rightmost empty string "" is - * considered to occur at the index value this.length(). + * considered to occur at the index value {@code this.length()}. * The returned index is the largest value k such that *
            * this.toString().startsWith(str, k)
      @@ -1304,9 +1304,9 @@
            * @return  if the string argument occurs one or more times as a substring
            *          within this object, then the index of the first character of
            *          the last such substring is returned. If it does not occur as
      -     *          a substring, -1 is returned.
      -     * @throws  java.lang.NullPointerException  if str is
      -     *          null.
      +     *          a substring, {@code -1} is returned.
      +     * @throws  java.lang.NullPointerException  if {@code str} is
      +     *          {@code null}.
            */
           public int lastIndexOf(String str) {
               return lastIndexOf(str, count);
      @@ -1326,8 +1326,8 @@
            * @param   fromIndex   the index to start the search from.
            * @return  the index within this sequence of the last occurrence of the
            *          specified substring.
      -     * @throws  java.lang.NullPointerException if str is
      -     *          null.
      +     * @throws  java.lang.NullPointerException if {@code str} is
      +     *          {@code null}.
            */
           public int lastIndexOf(String str, int fromIndex) {
               return String.lastIndexOf(value, 0, count,
      @@ -1342,8 +1342,8 @@
            * is never reversed.
            *
            * Let n be the character length of this character sequence
      -     * (not the length in char values) just prior to
      -     * execution of the reverse method. Then the
      +     * (not the length in {@code char} values) just prior to
      +     * execution of the {@code reverse} method. Then the
            * character at index k in the new character sequence is
            * equal to the character at index n-k-1 in the old
            * character sequence.
      @@ -1351,7 +1351,7 @@
            * 

      Note that the reverse operation may result in producing * surrogate pairs that were unpaired low-surrogates and * high-surrogates before the operation. For example, reversing - * "\uDC00\uD800" produces "\uD800\uDC00" which is + * "\u005CuDC00\u005CuD800" produces "\u005CuD800\u005CuDC00" which is * a valid surrogate pair. * * @return a reference to this object. @@ -1387,11 +1387,11 @@ /** * Returns a string representing the data in this sequence. - * A new String object is allocated and initialized to + * A new {@code String} object is allocated and initialized to * contain the character sequence currently represented by this - * object. This String is then returned. Subsequent + * object. This {@code String} is then returned. Subsequent * changes to this sequence do not affect the contents of the - * String. + * {@code String}. * * @return a string representation of this sequence of characters. */ diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/java/lang/Byte.java --- a/jdk/src/share/classes/java/lang/Byte.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/java/lang/Byte.java Thu Feb 09 23:17:22 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 @@ -110,8 +110,8 @@ * determined by whether {@link java.lang.Character#digit(char, * int)} returns a nonnegative value) except that the first * character may be an ASCII minus sign {@code '-'} - * ('\u002D') to indicate a negative value or an - * ASCII plus sign {@code '+'} ('\u002B') to + * ({@code '\u005Cu002D'}) to indicate a negative value or an + * ASCII plus sign {@code '+'} ({@code '\u005Cu002B'}) to * indicate a positive value. The resulting {@code byte} value is * returned. * @@ -127,8 +127,8 @@ * *

    • Any character of the string is not a digit of the * specified radix, except that the first character may be a minus - * sign {@code '-'} ('\u002D') or plus sign - * {@code '+'} ('\u002B') provided that the + * sign {@code '-'} ({@code '\u005Cu002D'}) or plus sign + * {@code '+'} ({@code '\u005Cu002B'}) provided that the * string is longer than length 1. * *
    • The value represented by the string is not a value of type @@ -157,9 +157,9 @@ * Parses the string argument as a signed decimal {@code * byte}. The characters in the string must all be decimal digits, * except that the first character may be an ASCII minus sign - * {@code '-'} ('\u002D') to indicate a negative + * {@code '-'} ({@code '\u005Cu002D'}) to indicate a negative * value or an ASCII plus sign {@code '+'} - * ('\u002B') to indicate a positive value. The + * ({@code '\u005Cu002B'}) to indicate a positive value. The * resulting {@code byte} value is returned, exactly as if the * argument and the radix 10 were given as arguments to the {@link * #parseByte(java.lang.String, int)} method. @@ -446,6 +446,47 @@ } /** + * Converts the argument to an {@code int} by an unsigned + * conversion. In an unsigned conversion to an {@code int}, the + * high-order 24 bits of the {@code int} are zero and the + * low-order 8 bits are equal to the bits of the {@code byte} argument. + * + * Consequently, zero and positive {@code byte} values are mapped + * to a numerically equal {@code int} value and negative {@code + * byte} values are mapped to an {@code int} value equal to the + * input plus 28. + * + * @param x the value to convert to an unsigned {@code int} + * @return the argument converted to {@code int} by an unsigned + * conversion + * @since 1.8 + */ + public static int toUnsignedInt(byte x) { + return ((int) x) & 0xff; + } + + /** + * Converts the argument to a {@code long} by an unsigned + * conversion. In an unsigned conversion to a {@code long}, the + * high-order 56 bits of the {@code long} are zero and the + * low-order 8 bits are equal to the bits of the {@code byte} argument. + * + * Consequently, zero and positive {@code byte} values are mapped + * to a numerically equal {@code long} value and negative {@code + * byte} values are mapped to a {@code long} value equal to the + * input plus 28. + * + * @param x the value to convert to an unsigned {@code long} + * @return the argument converted to {@code long} by an unsigned + * conversion + * @since 1.8 + */ + public static long toUnsignedLong(byte x) { + return ((long) x) & 0xffL; + } + + + /** * The number of bits used to represent a {@code byte} value in two's * complement binary form. * diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/java/lang/Double.java --- a/jdk/src/share/classes/java/lang/Double.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/java/lang/Double.java Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -140,7 +140,7 @@ *
    • Otherwise, the result is a string that represents the sign and * magnitude (absolute value) of the argument. If the sign is negative, * the first character of the result is '{@code -}' - * ('\u002D'); if the sign is positive, no sign character + * ({@code '\u005Cu002D'}); if the sign is positive, no sign character * appears in the result. As for the magnitude m: *
        *
      • If m is infinity, it is represented by the characters @@ -156,7 +156,7 @@ *
      • If m is greater than or equal to 10-3 but less * than 107, then it is represented as the integer part of * m, in decimal form with no leading zeroes, followed by - * '{@code .}' ('\u002E'), followed by one or + * '{@code .}' ({@code '\u005Cu002E'}), followed by one or * more decimal digits representing the fractional part of m. * *
      • If m is less than 10-3 or greater than or @@ -168,9 +168,9 @@ * 10n so that 1 ≤ a {@literal <} 10. The * magnitude is then represented as the integer part of a, * as a single decimal digit, followed by '{@code .}' - * ('\u002E'), followed by decimal digits + * ({@code '\u005Cu002E'}), followed by decimal digits * representing the fractional part of a, followed by the - * letter '{@code E}' ('\u0045'), followed + * letter '{@code E}' ({@code '\u005Cu0045'}), followed * by a representation of n as a decimal integer, as * produced by the method {@link Integer#toString(int)}. *
      @@ -208,7 +208,7 @@ *
    • Otherwise, the result is a string that represents the sign * and magnitude of the argument. If the sign is negative, the * first character of the result is '{@code -}' - * ('\u002D'); if the sign is positive, no sign + * ({@code '\u005Cu002D'}); if the sign is positive, no sign * character appears in the result. As for the magnitude m: * *
        diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/java/lang/Float.java --- a/jdk/src/share/classes/java/lang/Float.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/java/lang/Float.java Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -138,7 +138,7 @@ *
      • Otherwise, the result is a string that represents the sign and * magnitude (absolute value) of the argument. If the sign is * negative, the first character of the result is - * '{@code -}' ('\u002D'); if the sign is + * '{@code -}' ({@code '\u005Cu002D'}); if the sign is * positive, no sign character appears in the result. As for * the magnitude m: *
          @@ -154,7 +154,7 @@ * less than 107, then it is represented as the * integer part of m, in decimal form with no leading * zeroes, followed by '{@code .}' - * ('\u002E'), followed by one or more + * ({@code '\u005Cu002E'}), followed by one or more * decimal digits representing the fractional part of * m. *
        • If m is less than 10-3 or greater than or @@ -166,10 +166,10 @@ * 10n so that 1 ≤ a {@literal <} 10. * The magnitude is then represented as the integer part of * a, as a single decimal digit, followed by - * '{@code .}' ('\u002E'), followed by + * '{@code .}' ({@code '\u005Cu002E'}), followed by * decimal digits representing the fractional part of * a, followed by the letter '{@code E}' - * ('\u0045'), followed by a representation + * ({@code '\u005Cu0045'}), followed by a representation * of n as a decimal integer, as produced by the * method {@link java.lang.Integer#toString(int)}. * @@ -210,7 +210,7 @@ *
        • Otherwise, the result is a string that represents the sign and * magnitude (absolute value) of the argument. If the sign is negative, * the first character of the result is '{@code -}' - * ('\u002D'); if the sign is positive, no sign character + * ({@code '\u005Cu002D'}); if the sign is positive, no sign character * appears in the result. As for the magnitude m: * *
            diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/java/lang/Integer.java --- a/jdk/src/share/classes/java/lang/Integer.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/java/lang/Integer.java Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -93,13 +93,13 @@ * *

            If the first argument is negative, the first element of the * result is the ASCII minus character {@code '-'} - * ('\u002D'). If the first argument is not + * ({@code '\u005Cu002D'}). If the first argument is not * negative, no sign character appears in the result. * *

            The remaining characters of the result represent the magnitude * of the first argument. If the magnitude is zero, it is * represented by a single zero character {@code '0'} - * ('\u0030'); otherwise, the first character of + * ({@code '\u005Cu0030'}); otherwise, the first character of * the representation of the magnitude will not be the zero * character. The following ASCII characters are used as digits: * @@ -107,9 +107,9 @@ * {@code 0123456789abcdefghijklmnopqrstuvwxyz} *

    • * - * These are '\u0030' through - * '\u0039' and '\u0061' through - * '\u007A'. If {@code radix} is + * These are {@code '\u005Cu0030'} through + * {@code '\u005Cu0039'} and {@code '\u005Cu0061'} through + * {@code '\u005Cu007A'}. If {@code radix} is * N, then the first N of these characters * are used as radix-N digits in the order shown. Thus, * the digits for hexadecimal (radix 16) are @@ -128,7 +128,6 @@ * @see java.lang.Character#MIN_RADIX */ public static String toString(int i, int radix) { - if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) radix = 10; @@ -159,6 +158,36 @@ } /** + * Returns a string representation of the first argument as an + * unsigned integer value in the radix specified by the second + * argument. + * + *

      If the radix is smaller than {@code Character.MIN_RADIX} + * or larger than {@code Character.MAX_RADIX}, then the radix + * {@code 10} is used instead. + * + *

      Note that since the first argument is treated as an unsigned + * value, no leading sign character is printed. + * + *

      If the magnitude is zero, it is represented by a single zero + * character {@code '0'} ({@code '\u005Cu0030'}); otherwise, + * the first character of the representation of the magnitude will + * not be the zero character. + * + *

      The behavior of radixes and the characters used as digits + * are the same as {@link #toString(int, int) toString}. + * + * @param i an integer to be converted to an unsigned string. + * @param radix the radix to use in the string representation. + * @return an unsigned string representation of the argument in the specified radix. + * @see #toString(int, int) + * @since 1.8 + */ + public static String toUnsignedString(int i, int radix) { + return Long.toString(toUnsignedLong(i), radix); + } + + /** * Returns a string representation of the integer argument as an * unsigned integer in base 16. * @@ -166,20 +195,26 @@ * if the argument is negative; otherwise, it is equal to the * argument. This value is converted to a string of ASCII digits * in hexadecimal (base 16) with no extra leading - * {@code 0}s. If the unsigned magnitude is zero, it is - * represented by a single zero character {@code '0'} - * ('\u0030'); otherwise, the first character of - * the representation of the unsigned magnitude will not be the - * zero character. The following characters are used as - * hexadecimal digits: + * {@code 0}s. + * + *

      The value of the argument can be recovered from the returned + * string {@code s} by calling {@link + * Integer#parseUnsignedInt(String, int) + * Integer.parseUnsignedInt(s, 16)}. + * + *

      If the unsigned magnitude is zero, it is represented by a + * single zero character {@code '0'} ({@code '\u005Cu0030'}); + * otherwise, the first character of the representation of the + * unsigned magnitude will not be the zero character. The + * following characters are used as hexadecimal digits: * *

      * {@code 0123456789abcdef} *
      * - * These are the characters '\u0030' through - * '\u0039' and '\u0061' through - * '\u0066'. If uppercase letters are + * These are the characters {@code '\u005Cu0030'} through + * {@code '\u005Cu0039'} and {@code '\u005Cu0061'} through + * {@code '\u005Cu0066'}. If uppercase letters are * desired, the {@link java.lang.String#toUpperCase()} method may * be called on the result: * @@ -190,10 +225,12 @@ * @param i an integer to be converted to a string. * @return the string representation of the unsigned integer value * represented by the argument in hexadecimal (base 16). + * @see #parseUnsignedInt(String, int) + * @see #toUnsignedString(int, int) * @since JDK1.0.2 */ public static String toHexString(int i) { - return toUnsignedString(i, 4); + return toUnsignedString0(i, 4); } /** @@ -205,27 +242,33 @@ * argument. This value is converted to a string of ASCII digits * in octal (base 8) with no extra leading {@code 0}s. * + *

      The value of the argument can be recovered from the returned + * string {@code s} by calling {@link + * Integer#parseUnsignedInt(String, int) + * Integer.parseUnsignedInt(s, 8)}. + * *

      If the unsigned magnitude is zero, it is represented by a - * single zero character {@code '0'} - * ('\u0030'); otherwise, the first character of - * the representation of the unsigned magnitude will not be the - * zero character. The following characters are used as octal - * digits: + * single zero character {@code '0'} ({@code '\u005Cu0030'}); + * otherwise, the first character of the representation of the + * unsigned magnitude will not be the zero character. The + * following characters are used as octal digits: * *

      * {@code 01234567} *
      * - * These are the characters '\u0030' through - * '\u0037'. + * These are the characters {@code '\u005Cu0030'} through + * {@code '\u005Cu0037'}. * * @param i an integer to be converted to a string. * @return the string representation of the unsigned integer value * represented by the argument in octal (base 8). + * @see #parseUnsignedInt(String, int) + * @see #toUnsignedString(int, int) * @since JDK1.0.2 */ public static String toOctalString(int i) { - return toUnsignedString(i, 3); + return toUnsignedString0(i, 3); } /** @@ -236,27 +279,34 @@ * if the argument is negative; otherwise it is equal to the * argument. This value is converted to a string of ASCII digits * in binary (base 2) with no extra leading {@code 0}s. - * If the unsigned magnitude is zero, it is represented by a - * single zero character {@code '0'} - * ('\u0030'); otherwise, the first character of - * the representation of the unsigned magnitude will not be the - * zero character. The characters {@code '0'} - * ('\u0030') and {@code '1'} - * ('\u0031') are used as binary digits. + * + *

      The value of the argument can be recovered from the returned + * string {@code s} by calling {@link + * Integer#parseUnsignedInt(String, int) + * Integer.parseUnsignedInt(s, 2)}. + * + *

      If the unsigned magnitude is zero, it is represented by a + * single zero character {@code '0'} ({@code '\u005Cu0030'}); + * otherwise, the first character of the representation of the + * unsigned magnitude will not be the zero character. The + * characters {@code '0'} ({@code '\u005Cu0030'}) and {@code + * '1'} ({@code '\u005Cu0031'}) are used as binary digits. * * @param i an integer to be converted to a string. * @return the string representation of the unsigned integer value * represented by the argument in binary (base 2). + * @see #parseUnsignedInt(String, int) + * @see #toUnsignedString(int, int) * @since JDK1.0.2 */ public static String toBinaryString(int i) { - return toUnsignedString(i, 1); + return toUnsignedString0(i, 1); } /** * Convert the integer to an unsigned number. */ - private static String toUnsignedString(int i, int shift) { + private static String toUnsignedString0(int i, int shift) { char[] buf = new char[32]; int charPos = 32; int radix = 1 << shift; @@ -335,6 +385,24 @@ } /** + * Returns a string representation of the argument as an unsigned + * decimal value. + * + * The argument is converted to unsigned decimal representation + * and returned as a string exactly as if the argument and radix + * 10 were given as arguments to the {@link #toUnsignedString(int, + * int)} method. + * + * @param i an integer to be converted to an unsigned string. + * @return an unsigned string representation of the argument. + * @see #toUnsignedString(int, int) + * @since 1.8 + */ + public static String toUnsignedString(int i) { + return Long.toString(toUnsignedLong(i)); + } + + /** * Places characters representing the integer i into the * character array buf. The characters are placed into * the buffer backwards starting with the least significant @@ -393,9 +461,9 @@ * must all be digits of the specified radix (as determined by * whether {@link java.lang.Character#digit(char, int)} returns a * nonnegative value), except that the first character may be an - * ASCII minus sign {@code '-'} ('\u002D') to + * ASCII minus sign {@code '-'} ({@code '\u005Cu002D'}) to * indicate a negative value or an ASCII plus sign {@code '+'} - * ('\u002B') to indicate a positive value. The + * ({@code '\u005Cu002B'}) to indicate a positive value. The * resulting integer value is returned. * *

      An exception of type {@code NumberFormatException} is @@ -410,8 +478,8 @@ * *

    • Any character of the string is not a digit of the specified * radix, except that the first character may be a minus sign - * {@code '-'} ('\u002D') or plus sign - * {@code '+'} ('\u002B') provided that the + * {@code '-'} ({@code '\u005Cu002D'}) or plus sign + * {@code '+'} ({@code '\u005Cu002B'}) provided that the * string is longer than length 1. * *
    • The value represented by the string is not a value of type @@ -511,8 +579,8 @@ * Parses the string argument as a signed decimal integer. The * characters in the string must all be decimal digits, except * that the first character may be an ASCII minus sign {@code '-'} - * ('\u002D') to indicate a negative value or an - * ASCII plus sign {@code '+'} ('\u002B') to + * ({@code '\u005Cu002D'}) to indicate a negative value or an + * ASCII plus sign {@code '+'} ({@code '\u005Cu002B'}) to * indicate a positive value. The resulting integer value is * returned, exactly as if the argument and the radix 10 were * given as arguments to the {@link #parseInt(java.lang.String, @@ -529,6 +597,102 @@ } /** + * Parses the string argument as an unsigned integer in the radix + * specified by the second argument. An unsigned integer maps the + * values usually associated with negative numbers to positive + * numbers larger than {@code MAX_VALUE}. + * + * The characters in the string must all be digits of the + * specified radix (as determined by whether {@link + * java.lang.Character#digit(char, int)} returns a nonnegative + * value), except that the first character may be an ASCII plus + * sign {@code '+'} ({@code '\u005Cu002B'}). The resulting + * integer value is returned. + * + *

      An exception of type {@code NumberFormatException} is + * thrown if any of the following situations occurs: + *

        + *
      • The first argument is {@code null} or is a string of + * length zero. + * + *
      • The radix is either smaller than + * {@link java.lang.Character#MIN_RADIX} or + * larger than {@link java.lang.Character#MAX_RADIX}. + * + *
      • Any character of the string is not a digit of the specified + * radix, except that the first character may be a plus sign + * {@code '+'} ({@code '\u005Cu002B'}) provided that the + * string is longer than length 1. + * + *
      • The value represented by the string is larger than the + * largest unsigned {@code int}, 232-1. + * + *
      + * + * + * @param s the {@code String} containing the unsigned integer + * representation to be parsed + * @param radix the radix to be used while parsing {@code s}. + * @return the integer represented by the string argument in the + * specified radix. + * @throws NumberFormatException if the {@code String} + * does not contain a parsable {@code int}. + * @since 1.8 + */ + public static int parseUnsignedInt(String s, int radix) + throws NumberFormatException { + if (s == null) { + throw new NumberFormatException("null"); + } + + int len = s.length(); + if (len > 0) { + char firstChar = s.charAt(0); + if (firstChar == '-') { + throw new + NumberFormatException(String.format("Illegal leading minus sign " + + "on unsigned string %s.", s)); + } else { + if (len <= 5 || // Integer.MAX_VALUE in Character.MAX_RADIX is 6 digits + (radix == 10 && len <= 9) ) { // Integer.MAX_VALUE in base 10 is 10 digits + return parseInt(s, radix); + } else { + long ell = Long.parseLong(s, radix); + if ((ell & 0xffff_ffff_0000_0000L) == 0) { + return (int) ell; + } else { + throw new + NumberFormatException(String.format("String value %s exceeds " + + "range of unsigned int.", s)); + } + } + } + } else { + throw NumberFormatException.forInputString(s); + } + } + + /** + * Parses the string argument as an unsigned decimal integer. The + * characters in the string must all be decimal digits, except + * that the first character may be an an ASCII plus sign {@code + * '+'} ({@code '\u005Cu002B'}). The resulting integer value + * is returned, exactly as if the argument and the radix 10 were + * given as arguments to the {@link + * #parseUnsignedInt(java.lang.String, int)} method. + * + * @param s a {@code String} containing the unsigned {@code int} + * representation to be parsed + * @return the unsigned integer value represented by the argument in decimal. + * @throws NumberFormatException if the string does not contain a + * parsable unsigned integer. + * @since 1.8 + */ + public static int parseUnsignedInt(String s) throws NumberFormatException { + return parseUnsignedInt(s, 10); + } + + /** * Returns an {@code Integer} object holding the value * extracted from the specified {@code String} when parsed * with the radix given by the second argument. The first argument @@ -1030,6 +1194,83 @@ return (x < y) ? -1 : ((x == y) ? 0 : 1); } + /** + * Compares two {@code int} values numerically treating the values + * as unsigned. + * + * @param x the first {@code int} to compare + * @param y the second {@code int} to compare + * @return the value {@code 0} if {@code x == y}; a value less + * than {@code 0} if {@code x < y} as unsigned values; and + * a value greater than {@code 0} if {@code x > y} as + * unsigned values + * @since 1.8 + */ + public static int compareUnsigned(int x, int y) { + return compare(x + MIN_VALUE, y + MIN_VALUE); + } + + /** + * Converts the argument to a {@code long} by an unsigned + * conversion. In an unsigned conversion to a {@code long}, the + * high-order 32 bits of the {@code long} are zero and the + * low-order 32 bits are equal to the bits of the integer + * argument. + * + * Consequently, zero and positive {@code int} values are mapped + * to a numerically equal {@code long} value and negative {@code + * int} values are mapped to a {@code long} value equal to the + * input plus 232. + * + * @param x the value to convert to an unsigned {@code long} + * @return the argument converted to {@code long} by an unsigned + * conversion + * @since 1.8 + */ + public static long toUnsignedLong(int x) { + return ((long) x) & 0xffffffffL; + } + + /** + * Returns the unsigned quotient of dividing the first argument by + * the second where each argument and the result is interpreted as + * an unsigned value. + * + *

      Note that in two's complement arithmetic, the three other + * basic arithmetic operations of add, subtract, and multiply are + * bit-wise identical if the two operands are regarded as both + * being signed or both being unsigned. Therefore separate {@code + * addUnsigned}, etc. methods are not provided. + * + * @param dividend the value to be divided + * @param divisor the value doing the dividing + * @return the unsigned quotient of the first argument divided by + * the second argument + * @see #remainderUnsigned + * @since 1.8 + */ + public static int divideUnsigned(int dividend, int divisor) { + // In lieu of tricky code, for now just use long arithmetic. + return (int)(toUnsignedLong(dividend) / toUnsignedLong(divisor)); + } + + /** + * Returns the unsigned remainder from dividing the first argument + * by the second where each argument and the result is interpreted + * as an unsigned value. + * + * @param dividend the value to be divided + * @param divisor the value doing the dividing + * @return the unsigned remainder of the first argument divided by + * the second argument + * @see #divideUnsigned + * @since 1.8 + */ + public static int remainderUnsigned(int dividend, int divisor) { + // In lieu of tricky code, for now just use long arithmetic. + return (int)(toUnsignedLong(dividend) % toUnsignedLong(divisor)); + } + // Bit twiddling diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/java/lang/Long.java --- a/jdk/src/share/classes/java/lang/Long.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/java/lang/Long.java Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 java.lang; +import java.math.*; + /** * The {@code Long} class wraps a value of the primitive type {@code * long} in an object. An object of type {@code Long} contains a @@ -79,13 +81,13 @@ * *

      If the first argument is negative, the first element of the * result is the ASCII minus sign {@code '-'} - * ('\u002d'). If the first argument is not + * ({@code '\u005Cu002d'}). If the first argument is not * negative, no sign character appears in the result. * *

      The remaining characters of the result represent the magnitude * of the first argument. If the magnitude is zero, it is * represented by a single zero character {@code '0'} - * ('\u0030'); otherwise, the first character of + * ({@code '\u005Cu0030'}); otherwise, the first character of * the representation of the magnitude will not be the zero * character. The following ASCII characters are used as digits: * @@ -93,9 +95,9 @@ * {@code 0123456789abcdefghijklmnopqrstuvwxyz} *

    * - * These are '\u0030' through - * '\u0039' and '\u0061' through - * '\u007a'. If {@code radix} is + * These are {@code '\u005Cu0030'} through + * {@code '\u005Cu0039'} and {@code '\u005Cu0061'} through + * {@code '\u005Cu007a'}. If {@code radix} is * N, then the first N of these characters * are used as radix-N digits in the order shown. Thus, * the digits for hexadecimal (radix 16) are @@ -140,6 +142,88 @@ } /** + * Returns a string representation of the first argument as an + * unsigned integer value in the radix specified by the second + * argument. + * + *

    If the radix is smaller than {@code Character.MIN_RADIX} + * or larger than {@code Character.MAX_RADIX}, then the radix + * {@code 10} is used instead. + * + *

    Note that since the first argument is treated as an unsigned + * value, no leading sign character is printed. + * + *

    If the magnitude is zero, it is represented by a single zero + * character {@code '0'} ({@code '\u005Cu0030'}); otherwise, + * the first character of the representation of the magnitude will + * not be the zero character. + * + *

    The behavior of radixes and the characters used as digits + * are the same as {@link #toString(long, int) toString}. + * + * @param i an integer to be converted to an unsigned string. + * @param radix the radix to use in the string representation. + * @return an unsigned string representation of the argument in the specified radix. + * @see #toString(long, int) + * @since 1.8 + */ + public static String toUnsignedString(long i, int radix) { + if (i >= 0) + return toString(i, radix); + else { + switch (radix) { + case 2: + return toBinaryString(i); + + case 4: + return toUnsignedString0(i, 2); + + case 8: + return toOctalString(i); + + case 10: + /* + * We can get the effect of an unsigned division by 10 + * on a long value by first shifting right, yielding a + * positive value, and then dividing by 5. This + * allows the last digit and preceding digits to be + * isolated more quickly than by an initial conversion + * to BigInteger. + */ + long quot = (i >>> 1) / 5; + long rem = i - quot * 10; + return toString(quot) + rem; + + case 16: + return toHexString(i); + + case 32: + return toUnsignedString0(i, 5); + + default: + return toUnsignedBigInteger(i).toString(radix); + } + } + } + + /** + * Return a BigInteger equal to the unsigned value of the + * argument. + */ + private static BigInteger toUnsignedBigInteger(long i) { + if (i >= 0L) + return BigInteger.valueOf(i); + else { + int upper = (int) (i >>> 32); + int lower = (int) i; + + // return (upper << 32) + lower + return (BigInteger.valueOf(Integer.toUnsignedLong(upper))).shiftLeft(32). + add(BigInteger.valueOf(Integer.toUnsignedLong(lower))); + } + } + + /** * Returns a string representation of the {@code long} * argument as an unsigned integer in base 16. * @@ -147,20 +231,26 @@ * 264 if the argument is negative; otherwise, it is * equal to the argument. This value is converted to a string of * ASCII digits in hexadecimal (base 16) with no extra - * leading {@code 0}s. If the unsigned magnitude is zero, it - * is represented by a single zero character {@code '0'} - * ('\u0030'); otherwise, the first character of - * the representation of the unsigned magnitude will not be the - * zero character. The following characters are used as - * hexadecimal digits: + * leading {@code 0}s. + * + *

    The value of the argument can be recovered from the returned + * string {@code s} by calling {@link + * Long#parseUnsignedLong(String, int) Long.parseUnsignedLong(s, + * 16)}. + * + *

    If the unsigned magnitude is zero, it is represented by a + * single zero character {@code '0'} ({@code '\u005Cu0030'}); + * otherwise, the first character of the representation of the + * unsigned magnitude will not be the zero character. The + * following characters are used as hexadecimal digits: * *

    * {@code 0123456789abcdef} *
    * - * These are the characters '\u0030' through - * '\u0039' and '\u0061' through - * '\u0066'. If uppercase letters are desired, + * These are the characters {@code '\u005Cu0030'} through + * {@code '\u005Cu0039'} and {@code '\u005Cu0061'} through + * {@code '\u005Cu0066'}. If uppercase letters are desired, * the {@link java.lang.String#toUpperCase()} method may be called * on the result: * @@ -172,10 +262,12 @@ * @return the string representation of the unsigned {@code long} * value represented by the argument in hexadecimal * (base 16). + * @see #parseUnsignedLong(String, int) + * @see #toUnsignedString(long, int) * @since JDK 1.0.2 */ public static String toHexString(long i) { - return toUnsignedString(i, 4); + return toUnsignedString0(i, 4); } /** @@ -188,27 +280,33 @@ * ASCII digits in octal (base 8) with no extra leading * {@code 0}s. * + *

    The value of the argument can be recovered from the returned + * string {@code s} by calling {@link + * Long#parseUnsignedLong(String, int) Long.parseUnsignedLong(s, + * 8)}. + * *

    If the unsigned magnitude is zero, it is represented by a - * single zero character {@code '0'} - * ('\u0030'); otherwise, the first character of - * the representation of the unsigned magnitude will not be the - * zero character. The following characters are used as octal - * digits: + * single zero character {@code '0'} ({@code '\u005Cu0030'}); + * otherwise, the first character of the representation of the + * unsigned magnitude will not be the zero character. The + * following characters are used as octal digits: * *

    * {@code 01234567} *
    * - * These are the characters '\u0030' through - * '\u0037'. + * These are the characters {@code '\u005Cu0030'} through + * {@code '\u005Cu0037'}. * * @param i a {@code long} to be converted to a string. * @return the string representation of the unsigned {@code long} * value represented by the argument in octal (base 8). + * @see #parseUnsignedLong(String, int) + * @see #toUnsignedString(long, int) * @since JDK 1.0.2 */ public static String toOctalString(long i) { - return toUnsignedString(i, 3); + return toUnsignedString0(i, 3); } /** @@ -219,27 +317,35 @@ * 264 if the argument is negative; otherwise, it is * equal to the argument. This value is converted to a string of * ASCII digits in binary (base 2) with no extra leading - * {@code 0}s. If the unsigned magnitude is zero, it is - * represented by a single zero character {@code '0'} - * ('\u0030'); otherwise, the first character of - * the representation of the unsigned magnitude will not be the - * zero character. The characters {@code '0'} - * ('\u0030') and {@code '1'} - * ('\u0031') are used as binary digits. + * {@code 0}s. + * + *

    The value of the argument can be recovered from the returned + * string {@code s} by calling {@link + * Long#parseUnsignedLong(String, int) Long.parseUnsignedLong(s, + * 2)}. + * + *

    If the unsigned magnitude is zero, it is represented by a + * single zero character {@code '0'} ({@code '\u005Cu0030'}); + * otherwise, the first character of the representation of the + * unsigned magnitude will not be the zero character. The + * characters {@code '0'} ({@code '\u005Cu0030'}) and {@code + * '1'} ({@code '\u005Cu0031'}) are used as binary digits. * * @param i a {@code long} to be converted to a string. * @return the string representation of the unsigned {@code long} * value represented by the argument in binary (base 2). + * @see #parseUnsignedLong(String, int) + * @see #toUnsignedString(long, int) * @since JDK 1.0.2 */ public static String toBinaryString(long i) { - return toUnsignedString(i, 1); + return toUnsignedString0(i, 1); } /** * Convert the integer to an unsigned number. */ - private static String toUnsignedString(long i, int shift) { + private static String toUnsignedString0(long i, int shift) { char[] buf = new char[64]; int charPos = 64; int radix = 1 << shift; @@ -271,6 +377,24 @@ } /** + * Returns a string representation of the argument as an unsigned + * decimal value. + * + * The argument is converted to unsigned decimal representation + * and returned as a string exactly as if the argument and radix + * 10 were given as arguments to the {@link #toUnsignedString(long, + * int)} method. + * + * @param i an integer to be converted to an unsigned string. + * @return an unsigned string representation of the argument. + * @see #toUnsignedString(long, int) + * @since 1.8 + */ + public static String toUnsignedString(long i) { + return toUnsignedString(i, 10); + } + + /** * Places characters representing the integer i into the * character array buf. The characters are placed into * the buffer backwards starting with the least significant @@ -343,14 +467,14 @@ * string must all be digits of the specified radix (as determined * by whether {@link java.lang.Character#digit(char, int)} returns * a nonnegative value), except that the first character may be an - * ASCII minus sign {@code '-'} ('\u002D') to + * ASCII minus sign {@code '-'} ({@code '\u005Cu002D'}) to * indicate a negative value or an ASCII plus sign {@code '+'} - * ('\u002B') to indicate a positive value. The + * ({@code '\u005Cu002B'}) to indicate a positive value. The * resulting {@code long} value is returned. * *

    Note that neither the character {@code L} - * ('\u004C') nor {@code l} - * ('\u006C') is permitted to appear at the end + * ({@code '\u005Cu004C'}) nor {@code l} + * ({@code '\u005Cu006C'}) is permitted to appear at the end * of the string as a type indicator, as would be permitted in * Java programming language source code - except that either * {@code L} or {@code l} may appear as a digit for a @@ -369,8 +493,8 @@ * *

  • Any character of the string is not a digit of the specified * radix, except that the first character may be a minus sign - * {@code '-'} ('\u002d') or plus sign {@code - * '+'} ('\u002B') provided that the string is + * {@code '-'} ({@code '\u005Cu002d'}) or plus sign {@code + * '+'} ({@code '\u005Cu002B'}) provided that the string is * longer than length 1. * *
  • The value represented by the string is not a value of type @@ -460,16 +584,16 @@ * Parses the string argument as a signed decimal {@code long}. * The characters in the string must all be decimal digits, except * that the first character may be an ASCII minus sign {@code '-'} - * (\u002D') to indicate a negative value or an - * ASCII plus sign {@code '+'} ('\u002B') to + * ({@code \u005Cu002D'}) to indicate a negative value or an + * ASCII plus sign {@code '+'} ({@code '\u005Cu002B'}) to * indicate a positive value. The resulting {@code long} value is * returned, exactly as if the argument and the radix {@code 10} * were given as arguments to the {@link * #parseLong(java.lang.String, int)} method. * *

    Note that neither the character {@code L} - * ('\u004C') nor {@code l} - * ('\u006C') is permitted to appear at the end + * ({@code '\u005Cu004C'}) nor {@code l} + * ({@code '\u005Cu006C'}) is permitted to appear at the end * of the string as a type indicator, as would be permitted in * Java programming language source code. * @@ -485,6 +609,121 @@ } /** + * Parses the string argument as an unsigned {@code long} in the + * radix specified by the second argument. An unsigned integer + * maps the values usually associated with negative numbers to + * positive numbers larger than {@code MAX_VALUE}. + * + * The characters in the string must all be digits of the + * specified radix (as determined by whether {@link + * java.lang.Character#digit(char, int)} returns a nonnegative + * value), except that the first character may be an ASCII plus + * sign {@code '+'} ({@code '\u005Cu002B'}). The resulting + * integer value is returned. + * + *

    An exception of type {@code NumberFormatException} is + * thrown if any of the following situations occurs: + *

      + *
    • The first argument is {@code null} or is a string of + * length zero. + * + *
    • The radix is either smaller than + * {@link java.lang.Character#MIN_RADIX} or + * larger than {@link java.lang.Character#MAX_RADIX}. + * + *
    • Any character of the string is not a digit of the specified + * radix, except that the first character may be a plus sign + * {@code '+'} ({@code '\u005Cu002B'}) provided that the + * string is longer than length 1. + * + *
    • The value represented by the string is larger than the + * largest unsigned {@code long}, 264-1. + * + *
    + * + * + * @param s the {@code String} containing the unsigned integer + * representation to be parsed + * @param radix the radix to be used while parsing {@code s}. + * @return the unsigned {@code long} represented by the string + * argument in the specified radix. + * @throws NumberFormatException if the {@code String} + * does not contain a parsable {@code long}. + * @since 1.8 + */ + public static long parseUnsignedLong(String s, int radix) + throws NumberFormatException { + if (s == null) { + throw new NumberFormatException("null"); + } + + int len = s.length(); + if (len > 0) { + char firstChar = s.charAt(0); + if (firstChar == '-') { + throw new + NumberFormatException(String.format("Illegal leading minus sign " + + "on unsigned string %s.", s)); + } else { + if (len <= 12 || // Long.MAX_VALUE in Character.MAX_RADIX is 13 digits + (radix == 10 && len <= 18) ) { // Long.MAX_VALUE in base 10 is 19 digits + return parseLong(s, radix); + } + + // No need for range checks on len due to testing above. + long first = parseLong(s.substring(0, len - 1), radix); + int second = Character.digit(s.charAt(len - 1), radix); + if (second < 0) { + throw new NumberFormatException("Bad digit at end of " + s); + } + long result = first * radix + second; + if (compareUnsigned(result, first) < 0) { + /* + * The maximum unsigned value, (2^64)-1, takes at + * most one more digit to represent than the + * maximum signed value, (2^63)-1. Therefore, + * parsing (len - 1) digits will be appropriately + * in-range of the signed parsing. In other + * words, if parsing (len -1) digits overflows + * signed parsing, parsing len digits will + * certainly overflow unsigned parsing. + * + * The compareUnsigned check above catches + * situations where an unsigned overflow occurs + * incorporating the contribution of the final + * digit. + */ + throw new NumberFormatException(String.format("String value %s exceeds " + + "range of unsigned long.", s)); + } + return result; + } + } else { + throw NumberFormatException.forInputString(s); + } + } + + /** + * Parses the string argument as an unsigned decimal {@code long}. The + * characters in the string must all be decimal digits, except + * that the first character may be an an ASCII plus sign {@code + * '+'} ({@code '\u005Cu002B'}). The resulting integer value + * is returned, exactly as if the argument and the radix 10 were + * given as arguments to the {@link + * #parseUnsignedLong(java.lang.String, int)} method. + * + * @param s a {@code String} containing the unsigned {@code long} + * representation to be parsed + * @return the unsigned {@code long} value represented by the decimal string argument + * @throws NumberFormatException if the string does not contain a + * parsable unsigned integer. + * @since 1.8 + */ + public static long parseUnsignedLong(String s) throws NumberFormatException { + return parseUnsignedLong(s, 10); + } + + /** * Returns a {@code Long} object holding the value * extracted from the specified {@code String} when parsed * with the radix given by the second argument. The first @@ -909,8 +1148,8 @@ * * *

    Note that, in every case, neither {@code L} - * ('\u004C') nor {@code l} - * ('\u006C') is permitted to appear at the end + * ({@code '\u005Cu004C'}) nor {@code l} + * ({@code '\u005Cu006C'}) is permitted to appear at the end * of the property value as a type indicator, as would be * permitted in Java programming language source code. * @@ -977,6 +1216,85 @@ return (x < y) ? -1 : ((x == y) ? 0 : 1); } + /** + * Compares two {@code long} values numerically treating the values + * as unsigned. + * + * @param x the first {@code long} to compare + * @param y the second {@code long} to compare + * @return the value {@code 0} if {@code x == y}; a value less + * than {@code 0} if {@code x < y} as unsigned values; and + * a value greater than {@code 0} if {@code x > y} as + * unsigned values + * @since 1.8 + */ + public static int compareUnsigned(long x, long y) { + return compare(x + MIN_VALUE, y + MIN_VALUE); + } + + + /** + * Returns the unsigned quotient of dividing the first argument by + * the second where each argument and the result is interpreted as + * an unsigned value. + * + *

    Note that in two's complement arithmetic, the three other + * basic arithmetic operations of add, subtract, and multiply are + * bit-wise identical if the two operands are regarded as both + * being signed or both being unsigned. Therefore separate {@code + * addUnsigned}, etc. methods are not provided. + * + * @param dividend the value to be divided + * @param divisor the value doing the dividing + * @return the unsigned quotient of the first argument divided by + * the second argument + * @see #remainderUnsigned + * @since 1.8 + */ + public static long divideUnsigned(long dividend, long divisor) { + if (divisor < 0L) { // signed comparison + // Answer must be 0 or 1 depending on relative magnitude + // of dividend and divisor. + return (compareUnsigned(dividend, divisor)) < 0 ? 0L :1L; + } + + if (dividend > 0) // Both inputs non-negative + return dividend/divisor; + else { + /* + * For simple code, leveraging BigInteger. Longer and faster + * code written directly in terms of operations on longs is + * possible; see "Hacker's Delight" for divide and remainder + * algorithms. + */ + return toUnsignedBigInteger(dividend). + divide(toUnsignedBigInteger(divisor)).longValue(); + } + } + + /** + * Returns the unsigned remainder from dividing the first argument + * by the second where each argument and the result is interpreted + * as an unsigned value. + * + * @param dividend the value to be divided + * @param divisor the value doing the dividing + * @return the unsigned remainder of the first argument divided by + * the second argument + * @see #divideUnsigned + * @since 1.8 + */ + public static long remainderUnsigned(long dividend, long divisor) { + if (dividend > 0 && divisor > 0) { // signed comparisons + return dividend % divisor; + } else { + if (compareUnsigned(dividend, divisor) < 0) // Avoid explicit check for 0 divisor + return dividend; + else + return toUnsignedBigInteger(dividend). + remainder(toUnsignedBigInteger(divisor)).longValue(); + } + } // Bit Twiddling diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/java/lang/Short.java --- a/jdk/src/share/classes/java/lang/Short.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/java/lang/Short.java Thu Feb 09 23:17:22 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 @@ -80,8 +80,8 @@ * determined by whether {@link java.lang.Character#digit(char, * int)} returns a nonnegative value) except that the first * character may be an ASCII minus sign {@code '-'} - * ('\u002D') to indicate a negative value or an - * ASCII plus sign {@code '+'} ('\u002B') to + * ({@code '\u005Cu002D'}) to indicate a negative value or an + * ASCII plus sign {@code '+'} ({@code '\u005Cu002B'}) to * indicate a positive value. The resulting {@code short} value * is returned. * @@ -97,8 +97,8 @@ * *

  • Any character of the string is not a digit of the * specified radix, except that the first character may be a minus - * sign {@code '-'} ('\u002D') or plus sign - * {@code '+'} ('\u002B') provided that the + * sign {@code '-'} ({@code '\u005Cu002D'}) or plus sign + * {@code '+'} ({@code '\u005Cu002B'}) provided that the * string is longer than length 1. * *
  • The value represented by the string is not a value of type @@ -126,9 +126,9 @@ * Parses the string argument as a signed decimal {@code * short}. The characters in the string must all be decimal * digits, except that the first character may be an ASCII minus - * sign {@code '-'} ('\u002D') to indicate a + * sign {@code '-'} ({@code '\u005Cu002D'}) to indicate a * negative value or an ASCII plus sign {@code '+'} - * ('\u002B') to indicate a positive value. The + * ({@code '\u005Cu002B'}) to indicate a positive value. The * resulting {@code short} value is returned, exactly as if the * argument and the radix 10 were given as arguments to the {@link * #parseShort(java.lang.String, int)} method. @@ -469,6 +469,47 @@ return (short) (((i & 0xFF00) >> 8) | (i << 8)); } + + /** + * Converts the argument to an {@code int} by an unsigned + * conversion. In an unsigned conversion to an {@code int}, the + * high-order 16 bits of the {@code int} are zero and the + * low-order 16 bits are equal to the bits of the {@code short} argument. + * + * Consequently, zero and positive {@code short} values are mapped + * to a numerically equal {@code int} value and negative {@code + * short} values are mapped to an {@code int} value equal to the + * input plus 216. + * + * @param x the value to convert to an unsigned {@code int} + * @return the argument converted to {@code int} by an unsigned + * conversion + * @since 1.8 + */ + public static int toUnsignedInt(short x) { + return ((int) x) & 0xffff; + } + + /** + * Converts the argument to a {@code long} by an unsigned + * conversion. In an unsigned conversion to a {@code long}, the + * high-order 48 bits of the {@code long} are zero and the + * low-order 16 bits are equal to the bits of the {@code short} argument. + * + * Consequently, zero and positive {@code short} values are mapped + * to a numerically equal {@code long} value and negative {@code + * short} values are mapped to a {@code long} value equal to the + * input plus 216. + * + * @param x the value to convert to an unsigned {@code long} + * @return the argument converted to {@code long} by an unsigned + * conversion + * @since 1.8 + */ + public static long toUnsignedLong(short x) { + return ((long) x) & 0xffffL; + } + /** use serialVersionUID from JDK 1.1. for interoperability */ private static final long serialVersionUID = 7515723908773894738L; } diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/java/lang/String.java --- a/jdk/src/share/classes/java/lang/String.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/java/lang/String.java Thu Feb 09 23:17:22 2012 -0800 @@ -39,8 +39,8 @@ import java.util.regex.PatternSyntaxException; /** - * The String class represents character strings. All - * string literals in Java programs, such as "abc", are + * The {@code String} class represents character strings. All + * string literals in Java programs, such as {@code "abc"}, are * implemented as instances of this class. *

    * Strings are constant; their values cannot be changed after they @@ -63,7 +63,7 @@ * String d = cde.substring(1, 2); *

  • *

    - * The class String includes methods for examining + * The class {@code String} includes methods for examining * individual characters of the sequence, for comparing strings, for * searching strings, for extracting substrings, and for creating a * copy of a string with all characters translated to uppercase or to @@ -73,10 +73,10 @@ * The Java language provides special support for the string * concatenation operator ( + ), and for conversion of * other objects to strings. String concatenation is implemented - * through the StringBuilder(or StringBuffer) - * class and its append method. + * through the {@code StringBuilder}(or {@code StringBuffer}) + * class and its {@code append} method. * String conversions are implemented through the method - * toString, defined by Object and + * {@code toString}, defined by {@code Object} and * inherited by all classes in Java. For additional information on * string concatenation and conversion, see Gosling, Joy, and Steele, * The Java Language Specification. @@ -85,16 +85,16 @@ * or method in this class will cause a {@link NullPointerException} to be * thrown. * - *

    A String represents a string in the UTF-16 format + *

    A {@code String} represents a string in the UTF-16 format * in which supplementary characters are represented by surrogate * pairs (see the section Unicode - * Character Representations in the Character class for + * Character Representations in the {@code Character} class for * more information). - * Index values refer to char code units, so a supplementary - * character uses two positions in a String. - *

    The String class provides methods for dealing with + * Index values refer to {@code char} code units, so a supplementary + * character uses two positions in a {@code String}. + *

    The {@code String} class provides methods for dealing with * Unicode code points (i.e., characters), in addition to those for - * dealing with Unicode code units (i.e., char values). + * dealing with Unicode code units (i.e., {@code char} values). * * @author Lee Boynton * @author Arthur van Hoff @@ -131,9 +131,9 @@ * A String instance is written initially into an ObjectOutputStream in the * following format: *

    -     *      TC_STRING (utf String)
    +     *      {@code TC_STRING} (utf String)
          * 
    - * The String is written by method DataOutput.writeUTF. + * The String is written by method {@code DataOutput.writeUTF}. * A new handle is generated to refer to all future references to the * string instance within the stream. */ @@ -673,20 +673,20 @@ } /** - * Returns the char value at the - * specified index. An index ranges from 0 to - * length() - 1. The first char value of the sequence - * is at index 0, the next at index 1, + * Returns the {@code char} value at the + * specified index. An index ranges from {@code 0} to + * {@code length() - 1}. The first {@code char} value of the sequence + * is at index {@code 0}, the next at index {@code 1}, * and so on, as for array indexing. * - *

    If the char value specified by the index is a + *

    If the {@code char} value specified by the index is a * surrogate, the surrogate * value is returned. * - * @param index the index of the char value. - * @return the char value at the specified index of this string. - * The first char value is at index 0. - * @exception IndexOutOfBoundsException if the index + * @param index the index of the {@code char} value. + * @return the {@code char} value at the specified index of this string. + * The first {@code char} value is at index {@code 0}. + * @exception IndexOutOfBoundsException if the {@code index} * argument is negative or not less than the length of this * string. */ @@ -699,22 +699,22 @@ /** * Returns the character (Unicode code point) at the specified - * index. The index refers to char values - * (Unicode code units) and ranges from 0 to - * {@link #length()} - 1. + * index. The index refers to {@code char} values + * (Unicode code units) and ranges from {@code 0} to + * {@link #length()}{@code - 1}. * - *

    If the char value specified at the given index + *

    If the {@code char} value specified at the given index * is in the high-surrogate range, the following index is less - * than the length of this String, and the - * char value at the following index is in the + * than the length of this {@code String}, and the + * {@code char} value at the following index is in the * low-surrogate range, then the supplementary code point * corresponding to this surrogate pair is returned. Otherwise, - * the char value at the given index is returned. + * the {@code char} value at the given index is returned. * - * @param index the index to the char values + * @param index the index to the {@code char} values * @return the code point value of the character at the - * index - * @exception IndexOutOfBoundsException if the index + * {@code index} + * @exception IndexOutOfBoundsException if the {@code index} * argument is negative or not less than the length of this * string. * @since 1.5 @@ -728,22 +728,22 @@ /** * Returns the character (Unicode code point) before the specified - * index. The index refers to char values - * (Unicode code units) and ranges from 1 to {@link + * index. The index refers to {@code char} values + * (Unicode code units) and ranges from {@code 1} to {@link * CharSequence#length() length}. * - *

    If the char value at (index - 1) - * is in the low-surrogate range, (index - 2) is not - * negative, and the char value at (index - - * 2) is in the high-surrogate range, then the + *

    If the {@code char} value at {@code (index - 1)} + * is in the low-surrogate range, {@code (index - 2)} is not + * negative, and the {@code char} value at {@code (index - + * 2)} is in the high-surrogate range, then the * supplementary code point value of the surrogate pair is - * returned. If the char value at index - - * 1 is an unpaired low-surrogate or a high-surrogate, the + * returned. If the {@code char} value at {@code index - + * 1} is an unpaired low-surrogate or a high-surrogate, the * surrogate value is returned. * * @param index the index following the code point that should be returned * @return the Unicode code point value before the given index. - * @exception IndexOutOfBoundsException if the index + * @exception IndexOutOfBoundsException if the {@code index} * argument is less than 1 or greater than the length * of this string. * @since 1.5 @@ -758,23 +758,23 @@ /** * Returns the number of Unicode code points in the specified text - * range of this String. The text range begins at the - * specified beginIndex and extends to the - * char at index endIndex - 1. Thus the - * length (in chars) of the text range is - * endIndex-beginIndex. Unpaired surrogates within + * range of this {@code String}. The text range begins at the + * specified {@code beginIndex} and extends to the + * {@code char} at index {@code endIndex - 1}. Thus the + * length (in {@code char}s) of the text range is + * {@code endIndex-beginIndex}. Unpaired surrogates within * the text range count as one code point each. * - * @param beginIndex the index to the first char of + * @param beginIndex the index to the first {@code char} of * the text range. - * @param endIndex the index after the last char of + * @param endIndex the index after the last {@code char} of * the text range. * @return the number of Unicode code points in the specified text * range * @exception IndexOutOfBoundsException if the - * beginIndex is negative, or endIndex - * is larger than the length of this String, or - * beginIndex is larger than endIndex. + * {@code beginIndex} is negative, or {@code endIndex} + * is larger than the length of this {@code String}, or + * {@code beginIndex} is larger than {@code endIndex}. * @since 1.5 */ public int codePointCount(int beginIndex, int endIndex) { @@ -785,23 +785,23 @@ } /** - * Returns the index within this String that is - * offset from the given index by - * codePointOffset code points. Unpaired surrogates - * within the text range given by index and - * codePointOffset count as one code point each. + * Returns the index within this {@code String} that is + * offset from the given {@code index} by + * {@code codePointOffset} code points. Unpaired surrogates + * within the text range given by {@code index} and + * {@code codePointOffset} count as one code point each. * * @param index the index to be offset * @param codePointOffset the offset in code points - * @return the index within this String - * @exception IndexOutOfBoundsException if index + * @return the index within this {@code String} + * @exception IndexOutOfBoundsException if {@code index} * is negative or larger then the length of this - * String, or if codePointOffset is positive - * and the substring starting with index has fewer - * than codePointOffset code points, - * or if codePointOffset is negative and the substring - * before index has fewer than the absolute value - * of codePointOffset code points. + * {@code String}, or if {@code codePointOffset} is positive + * and the substring starting with {@code index} has fewer + * than {@code codePointOffset} code points, + * or if {@code codePointOffset} is negative and the substring + * before {@code index} has fewer than the absolute value + * of {@code codePointOffset} code points. * @since 1.5 */ public int offsetByCodePoints(int index, int codePointOffset) { @@ -824,11 +824,11 @@ * Copies characters from this string into the destination character * array. *

    - * The first character to be copied is at index srcBegin; - * the last character to be copied is at index srcEnd-1 + * The first character to be copied is at index {@code srcBegin}; + * the last character to be copied is at index {@code srcEnd-1} * (thus the total number of characters to be copied is - * srcEnd-srcBegin). The characters are copied into the - * subarray of dst starting at index dstBegin + * {@code srcEnd-srcBegin}). The characters are copied into the + * subarray of {@code dst} starting at index {@code dstBegin} * and ending at index: *

          *     dstbegin + (srcEnd-srcBegin) - 1
    @@ -842,13 +842,13 @@
          * @param      dstBegin   the start offset in the destination array.
          * @exception IndexOutOfBoundsException If any of the following
          *            is true:
    -     *            
    • srcBegin is negative. - *
    • srcBegin is greater than srcEnd - *
    • srcEnd is greater than the length of this + *
      • {@code srcBegin} is negative. + *
      • {@code srcBegin} is greater than {@code srcEnd} + *
      • {@code srcEnd} is greater than the length of this * string - *
      • dstBegin is negative - *
      • dstBegin+(srcEnd-srcBegin) is larger than - * dst.length
      + *
    • {@code dstBegin} is negative + *
    • {@code dstBegin+(srcEnd-srcBegin)} is larger than + * {@code dst.length}
    */ public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) { if (srcBegin < 0) { @@ -1135,14 +1135,14 @@ * Compares two strings lexicographically. * The comparison is based on the Unicode value of each character in * the strings. The character sequence represented by this - * String object is compared lexicographically to the + * {@code String} object is compared lexicographically to the * character sequence represented by the argument string. The result is - * a negative integer if this String object + * a negative integer if this {@code String} object * lexicographically precedes the argument string. The result is a - * positive integer if this String object lexicographically + * positive integer if this {@code String} object lexicographically * follows the argument string. The result is zero if the strings - * are equal; compareTo returns 0 exactly when - * the {@link #equals(Object)} method would return true. + * are equal; {@code compareTo} returns {@code 0} exactly when + * the {@link #equals(Object)} method would return {@code true}. *

    * This is the definition of lexicographic ordering. If two strings are * different, then either they have different characters at some index @@ -1151,25 +1151,25 @@ * positions, let k be the smallest such index; then the string * whose character at position k has the smaller value, as * determined by using the < operator, lexicographically precedes the - * other string. In this case, compareTo returns the - * difference of the two character values at position k in + * other string. In this case, {@code compareTo} returns the + * difference of the two character values at position {@code k} in * the two string -- that is, the value: *

          * this.charAt(k)-anotherString.charAt(k)
          * 
    * If there is no index position at which they differ, then the shorter * string lexicographically precedes the longer string. In this case, - * compareTo returns the difference of the lengths of the + * {@code compareTo} returns the difference of the lengths of the * strings -- that is, the value: *
          * this.length()-anotherString.length()
          * 
    * - * @param anotherString the String to be compared. - * @return the value 0 if the argument string is equal to - * this string; a value less than 0 if this string + * @param anotherString the {@code String} to be compared. + * @return the value {@code 0} if the argument string is equal to + * this string; a value less than {@code 0} if this string * is lexicographically less than the string argument; and a - * value greater than 0 if this string is + * value greater than {@code 0} if this string is * lexicographically greater than the string argument. */ public int compareTo(String anotherString) { @@ -1205,8 +1205,8 @@ } /** - * A Comparator that orders String objects as by - * compareToIgnoreCase. This comparator is serializable. + * A Comparator that orders {@code String} objects as by + * {@code compareToIgnoreCase}. This comparator is serializable. *

    * Note that this Comparator does not take locale into account, * and will result in an unsatisfactory ordering for certain locales. @@ -1253,9 +1253,9 @@ /** * Compares two strings lexicographically, ignoring case * differences. This method returns an integer whose sign is that of - * calling compareTo with normalized versions of the strings + * calling {@code compareTo} with normalized versions of the strings * where case differences have been eliminated by calling - * Character.toLowerCase(Character.toUpperCase(character)) on + * {@code Character.toLowerCase(Character.toUpperCase(character))} on * each character. *

    * Note that this method does not take locale into account, @@ -1263,7 +1263,7 @@ * The java.text package provides collators to allow * locale-sensitive ordering. * - * @param str the String to be compared. + * @param str the {@code String} to be compared. * @return a negative integer, zero, or a positive integer as the * specified String is greater than, equal to, or less * than this String, ignoring case considerations. @@ -1301,9 +1301,9 @@ * @param ooffset the starting offset of the subregion in the string * argument. * @param len the number of characters to compare. - * @return true if the specified subregion of this string + * @return {@code true} if the specified subregion of this string * exactly matches the specified subregion of the string argument; - * false otherwise. + * {@code false} otherwise. */ public boolean regionMatches(int toffset, String other, int ooffset, int len) { @@ -1360,7 +1360,7 @@ *

    * * - * @param ignoreCase if true, ignore case when comparing + * @param ignoreCase if {@code true}, ignore case when comparing * characters. * @param toffset the starting offset of the subregion in this * string. @@ -1368,10 +1368,10 @@ * @param ooffset the starting offset of the subregion in the string * argument. * @param len the number of characters to compare. - * @return true if the specified subregion of this string + * @return {@code true} if the specified subregion of this string * matches the specified subregion of the string argument; - * false otherwise. Whether the matching is exact - * or case insensitive depends on the ignoreCase + * {@code false} otherwise. Whether the matching is exact + * or case insensitive depends on the {@code ignoreCase} * argument. */ public boolean regionMatches(boolean ignoreCase, int toffset, @@ -1420,12 +1420,12 @@ * * @param prefix the prefix. * @param toffset where to begin looking in this string. - * @return true if the character sequence represented by the + * @return {@code true} if the character sequence represented by the * argument is a prefix of the substring of this object starting - * at index toffset; false otherwise. - * The result is false if toffset is + * at index {@code toffset}; {@code false} otherwise. + * The result is {@code false} if {@code toffset} is * negative or greater than the length of this - * String object; otherwise the result is the same + * {@code String} object; otherwise the result is the same * as the result of the expression *
          *          this.substring(toffset).startsWith(prefix)
    @@ -1453,12 +1453,12 @@
          * Tests if this string starts with the specified prefix.
          *
          * @param   prefix   the prefix.
    -     * @return  true if the character sequence represented by the
    +     * @return  {@code true} if the character sequence represented by the
          *          argument is a prefix of the character sequence represented by
    -     *          this string; false otherwise.
    -     *          Note also that true will be returned if the
    +     *          this string; {@code false} otherwise.
    +     *          Note also that {@code true} will be returned if the
          *          argument is an empty string or is equal to this
    -     *          String object as determined by the
    +     *          {@code String} object as determined by the
          *          {@link #equals(Object)} method.
          * @since   1. 0
          */
    @@ -1470,11 +1470,11 @@
          * Tests if this string ends with the specified suffix.
          *
          * @param   suffix   the suffix.
    -     * @return  true if the character sequence represented by the
    +     * @return  {@code true} if the character sequence represented by the
          *          argument is a suffix of the character sequence represented by
    -     *          this object; false otherwise. Note that the
    -     *          result will be true if the argument is the
    -     *          empty string or is equal to this String object
    +     *          this object; {@code false} otherwise. Note that the
    +     *          result will be {@code true} if the argument is the
    +     *          empty string or is equal to this {@code String} object
          *          as determined by the {@link #equals(Object)} method.
          */
         public boolean endsWith(String suffix) {
    @@ -1483,13 +1483,13 @@
     
         /**
          * Returns a hash code for this string. The hash code for a
    -     * String object is computed as
    +     * {@code String} object is computed as
          * 
          * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
          * 
    - * using int arithmetic, where s[i] is the - * ith character of the string, n is the length of - * the string, and ^ indicates exponentiation. + * using {@code int} arithmetic, where {@code s[i]} is the + * ith character of the string, {@code n} is the length of + * the string, and {@code ^} indicates exponentiation. * (The hash value of the empty string is zero.) * * @return a hash code value for this object. @@ -1512,26 +1512,26 @@ /** * Returns the index within this string of the first occurrence of * the specified character. If a character with value - * ch occurs in the character sequence represented by - * this String object, then the index (in Unicode + * {@code ch} occurs in the character sequence represented by + * this {@code String} object, then the index (in Unicode * code units) of the first such occurrence is returned. For - * values of ch in the range from 0 to 0xFFFF + * values of {@code ch} in the range from 0 to 0xFFFF * (inclusive), this is the smallest value k such that: *
          * this.charAt(k) == ch
          * 
    - * is true. For other values of ch, it is the + * is true. For other values of {@code ch}, it is the * smallest value k such that: *
          * this.codePointAt(k) == ch
          * 
    * is true. In either case, if no such character occurs in this - * string, then -1 is returned. + * string, then {@code -1} is returned. * * @param ch a character (Unicode code point). * @return the index of the first occurrence of the character in the * character sequence represented by this object, or - * -1 if the character does not occur. + * {@code -1} if the character does not occur. */ public int indexOf(int ch) { return indexOf(ch, 0); @@ -1541,39 +1541,39 @@ * Returns the index within this string of the first occurrence of the * specified character, starting the search at the specified index. *

    - * If a character with value ch occurs in the - * character sequence represented by this String - * object at an index no smaller than fromIndex, then + * If a character with value {@code ch} occurs in the + * character sequence represented by this {@code String} + * object at an index no smaller than {@code fromIndex}, then * the index of the first such occurrence is returned. For values - * of ch in the range from 0 to 0xFFFF (inclusive), + * of {@code ch} in the range from 0 to 0xFFFF (inclusive), * this is the smallest value k such that: *

          * (this.charAt(k) == ch) && (k >= fromIndex)
          * 
    - * is true. For other values of ch, it is the + * is true. For other values of {@code ch}, it is the * smallest value k such that: *
          * (this.codePointAt(k) == ch) && (k >= fromIndex)
          * 
    * is true. In either case, if no such character occurs in this - * string at or after position fromIndex, then - * -1 is returned. + * string at or after position {@code fromIndex}, then + * {@code -1} is returned. * *

    - * There is no restriction on the value of fromIndex. If it + * There is no restriction on the value of {@code fromIndex}. If it * is negative, it has the same effect as if it were zero: this entire * string may be searched. If it is greater than the length of this * string, it has the same effect as if it were equal to the length of - * this string: -1 is returned. + * this string: {@code -1} is returned. * - *

    All indices are specified in char values + *

    All indices are specified in {@code char} values * (Unicode code units). * * @param ch a character (Unicode code point). * @param fromIndex the index to start the search from. * @return the index of the first occurrence of the character in the * character sequence represented by this object that is greater - * than or equal to fromIndex, or -1 + * than or equal to {@code fromIndex}, or {@code -1} * if the character does not occur. */ public int indexOf(int ch, int fromIndex) { @@ -1622,26 +1622,26 @@ /** * Returns the index within this string of the last occurrence of - * the specified character. For values of ch in the + * the specified character. For values of {@code ch} in the * range from 0 to 0xFFFF (inclusive), the index (in Unicode code * units) returned is the largest value k such that: *

          * this.charAt(k) == ch
          * 
    - * is true. For other values of ch, it is the + * is true. For other values of {@code ch}, it is the * largest value k such that: *
          * this.codePointAt(k) == ch
          * 
    * is true. In either case, if no such character occurs in this - * string, then -1 is returned. The - * String is searched backwards starting at the last + * string, then {@code -1} is returned. The + * {@code String} is searched backwards starting at the last * character. * * @param ch a character (Unicode code point). * @return the index of the last occurrence of the character in the * character sequence represented by this object, or - * -1 if the character does not occur. + * {@code -1} if the character does not occur. */ public int lastIndexOf(int ch) { return lastIndexOf(ch, count - 1); @@ -1650,27 +1650,27 @@ /** * Returns the index within this string of the last occurrence of * the specified character, searching backward starting at the - * specified index. For values of ch in the range + * specified index. For values of {@code ch} in the range * from 0 to 0xFFFF (inclusive), the index returned is the largest * value k such that: *
          * (this.charAt(k) == ch) && (k <= fromIndex)
          * 
    - * is true. For other values of ch, it is the + * is true. For other values of {@code ch}, it is the * largest value k such that: *
          * (this.codePointAt(k) == ch) && (k <= fromIndex)
          * 
    * is true. In either case, if no such character occurs in this - * string at or before position fromIndex, then - * -1 is returned. + * string at or before position {@code fromIndex}, then + * {@code -1} is returned. * - *

    All indices are specified in char values + *

    All indices are specified in {@code char} values * (Unicode code units). * * @param ch a character (Unicode code point). * @param fromIndex the index to start the search from. There is no - * restriction on the value of fromIndex. If it is + * restriction on the value of {@code fromIndex}. If it is * greater than or equal to the length of this string, it has * the same effect as if it were equal to one less than the * length of this string: this entire string may be searched. @@ -1678,7 +1678,7 @@ * -1 is returned. * @return the index of the last occurrence of the character in the * character sequence represented by this object that is less - * than or equal to fromIndex, or -1 + * than or equal to {@code fromIndex}, or {@code -1} * if the character does not occur before that point. */ public int lastIndexOf(int ch, int fromIndex) { @@ -1921,8 +1921,8 @@ * @param beginIndex the beginning index, inclusive. * @return the specified substring. * @exception IndexOutOfBoundsException if - * beginIndex is negative or larger than the - * length of this String object. + * {@code beginIndex} is negative or larger than the + * length of this {@code String} object. */ public String substring(int beginIndex) { return substring(beginIndex, count); @@ -1930,9 +1930,9 @@ /** * Returns a new string that is a substring of this string. The - * substring begins at the specified beginIndex and - * extends to the character at index endIndex - 1. - * Thus the length of the substring is endIndex-beginIndex. + * substring begins at the specified {@code beginIndex} and + * extends to the character at index {@code endIndex - 1}. + * Thus the length of the substring is {@code endIndex-beginIndex}. *

    * Examples: *

    @@ -1944,11 +1944,11 @@
          * @param      endIndex     the ending index, exclusive.
          * @return     the specified substring.
          * @exception  IndexOutOfBoundsException  if the
    -     *             beginIndex is negative, or
    -     *             endIndex is larger than the length of
    -     *             this String object, or
    -     *             beginIndex is larger than
    -     *             endIndex.
    +     *             {@code beginIndex} is negative, or
    +     *             {@code endIndex} is larger than the length of
    +     *             this {@code String} object, or
    +     *             {@code beginIndex} is larger than
    +     *             {@code endIndex}.
          */
         public String substring(int beginIndex, int endIndex) {
             if (beginIndex < 0) {
    @@ -1999,11 +1999,11 @@
         /**
          * Concatenates the specified string to the end of this string.
          * 

    - * If the length of the argument string is 0, then this - * String object is returned. Otherwise, a new - * String object is created, representing a character + * If the length of the argument string is {@code 0}, then this + * {@code String} object is returned. Otherwise, a new + * {@code String} object is created, representing a character * sequence that is the concatenation of the character sequence - * represented by this String object and the character + * represented by this {@code String} object and the character * sequence represented by the argument string.

    * Examples: *

    @@ -2011,8 +2011,8 @@
          * "to".concat("get").concat("her") returns "together"
          * 
    * - * @param str the String that is concatenated to the end - * of this String. + * @param str the {@code String} that is concatenated to the end + * of this {@code String}. * @return a string that represents the concatenation of this object's * characters followed by the string argument's characters. */ @@ -2029,16 +2029,16 @@ /** * Returns a new string resulting from replacing all occurrences of - * oldChar in this string with newChar. + * {@code oldChar} in this string with {@code newChar}. *

    - * If the character oldChar does not occur in the - * character sequence represented by this String object, - * then a reference to this String object is returned. - * Otherwise, a new String object is created that + * If the character {@code oldChar} does not occur in the + * character sequence represented by this {@code String} object, + * then a reference to this {@code String} object is returned. + * Otherwise, a new {@code String} object is created that * represents a character sequence identical to the character sequence - * represented by this String object, except that every - * occurrence of oldChar is replaced by an occurrence - * of newChar. + * represented by this {@code String} object, except that every + * occurrence of {@code oldChar} is replaced by an occurrence + * of {@code newChar}. *

    * Examples: *

    @@ -2054,7 +2054,7 @@
          * @param   oldChar   the old character.
          * @param   newChar   the new character.
          * @return  a string derived from this string by replacing every
    -     *          occurrence of oldChar with newChar.
    +     *          occurrence of {@code oldChar} with {@code newChar}.
          */
         public String replace(char oldChar, char newChar) {
             if (oldChar != newChar) {
    @@ -2119,8 +2119,8 @@
          * sequence of char values.
          *
          * @param s the sequence to search for
    -     * @return true if this string contains s, false otherwise
    -     * @throws NullPointerException if s is null
    +     * @return true if this string contains {@code s}, false otherwise
    +     * @throws NullPointerException if {@code s} is {@code null}
          * @since 1.5
          */
         public boolean contains(CharSequence s) {
    @@ -2223,8 +2223,8 @@
          * @param  target The sequence of char values to be replaced
          * @param  replacement The replacement sequence of char values
          * @return  The resulting string
    -     * @throws NullPointerException if target or
    -     *         replacement is null.
    +     * @throws NullPointerException if {@code target} or
    +     *         {@code replacement} is {@code null}.
          * @since 1.5
          */
         public String replace(CharSequence target, CharSequence replacement) {
    @@ -2407,11 +2407,11 @@
         }
     
         /**
    -     * Converts all of the characters in this String to lower
    -     * case using the rules of the given Locale.  Case mapping is based
    +     * Converts all of the characters in this {@code String} to lower
    +     * case using the rules of the given {@code Locale}.  Case mapping is based
          * on the Unicode Standard version specified by the {@link java.lang.Character Character}
          * class. Since case mappings are not always 1:1 char mappings, the resulting
    -     * String may be a different length than the original String.
    +     * {@code String} may be a different length than the original {@code String}.
          * 

    * Examples of lowercase mappings are in the following table: *

  • @@ -2452,7 +2452,7 @@ *
    * * @param locale use the case transformation rules for this locale - * @return the String, converted to lowercase. + * @return the {@code String}, converted to lowercase. * @see java.lang.String#toLowerCase() * @see java.lang.String#toUpperCase() * @see java.lang.String#toUpperCase(Locale) @@ -2553,22 +2553,22 @@ } /** - * Converts all of the characters in this String to lower + * Converts all of the characters in this {@code String} to lower * case using the rules of the default locale. This is equivalent to calling - * toLowerCase(Locale.getDefault()). + * {@code toLowerCase(Locale.getDefault())}. *

    * Note: This method is locale sensitive, and may produce unexpected * results if used for strings that are intended to be interpreted locale * independently. * Examples are programming language identifiers, protocol keys, and HTML * tags. - * For instance, "TITLE".toLowerCase() in a Turkish locale - * returns "t\u005Cu0131tle", where '\u005Cu0131' is the + * For instance, {@code "TITLE".toLowerCase()} in a Turkish locale + * returns {@code "t\u005Cu0131tle"}, where '\u005Cu0131' is the * LATIN SMALL LETTER DOTLESS I character. * To obtain correct results for locale insensitive strings, use - * toLowerCase(Locale.ENGLISH). + * {@code toLowerCase(Locale.ENGLISH)}. *

    - * @return the String, converted to lowercase. + * @return the {@code String}, converted to lowercase. * @see java.lang.String#toLowerCase(Locale) */ public String toLowerCase() { @@ -2576,11 +2576,11 @@ } /** - * Converts all of the characters in this String to upper - * case using the rules of the given Locale. Case mapping is based + * Converts all of the characters in this {@code String} to upper + * case using the rules of the given {@code Locale}. Case mapping is based * on the Unicode Standard version specified by the {@link java.lang.Character Character} * class. Since case mappings are not always 1:1 char mappings, the resulting - * String may be a different length than the original String. + * {@code String} may be a different length than the original {@code String}. *

    * Examples of locale-sensitive and 1:M case mappings are in the following table. *

    @@ -2617,7 +2617,7 @@ * * * @param locale use the case transformation rules for this locale - * @return the String, converted to uppercase. + * @return the {@code String}, converted to uppercase. * @see java.lang.String#toUpperCase() * @see java.lang.String#toLowerCase() * @see java.lang.String#toLowerCase(Locale) @@ -2716,22 +2716,22 @@ } /** - * Converts all of the characters in this String to upper + * Converts all of the characters in this {@code String} to upper * case using the rules of the default locale. This method is equivalent to - * toUpperCase(Locale.getDefault()). + * {@code toUpperCase(Locale.getDefault())}. *

    * Note: This method is locale sensitive, and may produce unexpected * results if used for strings that are intended to be interpreted locale * independently. * Examples are programming language identifiers, protocol keys, and HTML * tags. - * For instance, "title".toUpperCase() in a Turkish locale - * returns "T\u005Cu0130TLE", where '\u005Cu0130' is the + * For instance, {@code "title".toUpperCase()} in a Turkish locale + * returns {@code "T\u005Cu0130TLE"}, where '\u005Cu0130' is the * LATIN CAPITAL LETTER I WITH DOT ABOVE character. * To obtain correct results for locale insensitive strings, use - * toUpperCase(Locale.ENGLISH). + * {@code toUpperCase(Locale.ENGLISH)}. *

    - * @return the String, converted to uppercase. + * @return the {@code String}, converted to uppercase. * @see java.lang.String#toUpperCase(Locale) */ public String toUpperCase() { @@ -2742,21 +2742,21 @@ * Returns a copy of the string, with leading and trailing whitespace * omitted. *

    - * If this String object represents an empty character + * If this {@code String} object represents an empty character * sequence, or the first and last characters of character sequence - * represented by this String object both have codes - * greater than '\u0020' (the space character), then a - * reference to this String object is returned. + * represented by this {@code String} object both have codes + * greater than {@code '\u005Cu0020'} (the space character), then a + * reference to this {@code String} object is returned. *

    * Otherwise, if there is no character with a code greater than - * '\u0020' in the string, then a new - * String object representing an empty string is created + * {@code '\u005Cu0020'} in the string, then a new + * {@code String} object representing an empty string is created * and returned. *

    * Otherwise, let k be the index of the first character in the - * string whose code is greater than '\u0020', and let + * string whose code is greater than {@code '\u005Cu0020'}, and let * m be the index of the last character in the string whose code - * is greater than '\u0020'. A new String + * is greater than {@code '\u005Cu0020'}. A new {@code String} * object is created, representing the substring of this string that * begins with the character at index k and ends with the * character at index m-that is, the result of @@ -2893,12 +2893,12 @@ } /** - * Returns the string representation of the Object argument. + * Returns the string representation of the {@code Object} argument. * - * @param obj an Object. - * @return if the argument is null, then a string equal to - * "null"; otherwise, the value of - * obj.toString() is returned. + * @param obj an {@code Object}. + * @return if the argument is {@code null}, then a string equal to + * {@code "null"}; otherwise, the value of + * {@code obj.toString()} is returned. * @see java.lang.Object#toString() */ public static String valueOf(Object obj) { @@ -2906,12 +2906,12 @@ } /** - * Returns the string representation of the char array + * Returns the string representation of the {@code char} array * argument. The contents of the character array are copied; subsequent * modification of the character array does not affect the newly * created string. * - * @param data a char array. + * @param data a {@code char} array. * @return a newly allocated string representing the same sequence of * characters contained in the character array argument. */ @@ -2921,24 +2921,24 @@ /** * Returns the string representation of a specific subarray of the - * char array argument. + * {@code char} array argument. *

    - * The offset argument is the index of the first - * character of the subarray. The count argument + * The {@code offset} argument is the index of the first + * character of the subarray. The {@code count} argument * specifies the length of the subarray. The contents of the subarray * are copied; subsequent modification of the character array does not * affect the newly created string. * * @param data the character array. * @param offset the initial offset into the value of the - * String. - * @param count the length of the value of the String. + * {@code String}. + * @param count the length of the value of the {@code String}. * @return a string representing the sequence of characters contained * in the subarray of the character array argument. - * @exception IndexOutOfBoundsException if offset is - * negative, or count is negative, or - * offset+count is larger than - * data.length. + * @exception IndexOutOfBoundsException if {@code offset} is + * negative, or {@code count} is negative, or + * {@code offset+count} is larger than + * {@code data.length}. */ public static String valueOf(char data[], int offset, int count) { return new String(data, offset, count); @@ -2951,7 +2951,7 @@ * @param data the character array. * @param offset initial offset of the subarray. * @param count length of the subarray. - * @return a String that contains the characters of the + * @return a {@code String} that contains the characters of the * specified subarray of the character array. */ public static String copyValueOf(char data[], int offset, int count) { @@ -2964,7 +2964,7 @@ * array specified. * * @param data the character array. - * @return a String that contains the characters of the + * @return a {@code String} that contains the characters of the * character array. */ public static String copyValueOf(char data[]) { @@ -2972,24 +2972,24 @@ } /** - * Returns the string representation of the boolean argument. + * Returns the string representation of the {@code boolean} argument. * - * @param b a boolean. - * @return if the argument is true, a string equal to - * "true" is returned; otherwise, a string equal to - * "false" is returned. + * @param b a {@code boolean}. + * @return if the argument is {@code true}, a string equal to + * {@code "true"} is returned; otherwise, a string equal to + * {@code "false"} is returned. */ public static String valueOf(boolean b) { return b ? "true" : "false"; } /** - * Returns the string representation of the char + * Returns the string representation of the {@code char} * argument. * - * @param c a char. - * @return a string of length 1 containing - * as its single character the argument c. + * @param c a {@code char}. + * @return a string of length {@code 1} containing + * as its single character the argument {@code c}. */ public static String valueOf(char c) { char data[] = {c}; @@ -2997,13 +2997,13 @@ } /** - * Returns the string representation of the int argument. + * Returns the string representation of the {@code int} argument. *

    * The representation is exactly the one returned by the - * Integer.toString method of one argument. + * {@code Integer.toString} method of one argument. * - * @param i an int. - * @return a string representation of the int argument. + * @param i an {@code int}. + * @return a string representation of the {@code int} argument. * @see java.lang.Integer#toString(int, int) */ public static String valueOf(int i) { @@ -3011,13 +3011,13 @@ } /** - * Returns the string representation of the long argument. + * Returns the string representation of the {@code long} argument. *

    * The representation is exactly the one returned by the - * Long.toString method of one argument. + * {@code Long.toString} method of one argument. * - * @param l a long. - * @return a string representation of the long argument. + * @param l a {@code long}. + * @return a string representation of the {@code long} argument. * @see java.lang.Long#toString(long) */ public static String valueOf(long l) { @@ -3025,13 +3025,13 @@ } /** - * Returns the string representation of the float argument. + * Returns the string representation of the {@code float} argument. *

    * The representation is exactly the one returned by the - * Float.toString method of one argument. + * {@code Float.toString} method of one argument. * - * @param f a float. - * @return a string representation of the float argument. + * @param f a {@code float}. + * @return a string representation of the {@code float} argument. * @see java.lang.Float#toString(float) */ public static String valueOf(float f) { @@ -3039,13 +3039,13 @@ } /** - * Returns the string representation of the double argument. + * Returns the string representation of the {@code double} argument. *

    * The representation is exactly the one returned by the - * Double.toString method of one argument. + * {@code Double.toString} method of one argument. * - * @param d a double. - * @return a string representation of the double argument. + * @param d a {@code double}. + * @return a string representation of the {@code double} argument. * @see java.lang.Double#toString(double) */ public static String valueOf(double d) { @@ -3056,17 +3056,17 @@ * Returns a canonical representation for the string object. *

    * A pool of strings, initially empty, is maintained privately by the - * class String. + * class {@code String}. *

    * When the intern method is invoked, if the pool already contains a - * string equal to this String object as determined by + * string equal to this {@code String} object as determined by * the {@link #equals(Object)} method, then the string from the pool is - * returned. Otherwise, this String object is added to the - * pool and a reference to this String object is returned. + * returned. Otherwise, this {@code String} object is added to the + * pool and a reference to this {@code String} object is returned. *

    - * It follows that for any two strings s and t, - * s.intern() == t.intern() is true - * if and only if s.equals(t) is true. + * It follows that for any two strings {@code s} and {@code t}, + * {@code s.intern() == t.intern()} is {@code true} + * if and only if {@code s.equals(t)} is {@code true}. *

    * All literal strings and string-valued constant expressions are * interned. String literals are defined in section 3.10.5 of the diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/java/text/SimpleDateFormat.java --- a/jdk/src/share/classes/java/text/SimpleDateFormat.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/java/text/SimpleDateFormat.java Thu Feb 09 23:17:22 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 @@ -1646,8 +1646,7 @@ // determine the local time. (6645292) int dstAmount = (nameIndex >= 3) ? tz.getDSTSavings() : 0; if (!(useSameName || (nameIndex >= 3 && dstAmount == 0))) { - calb.set(Calendar.ZONE_OFFSET, tz.getRawOffset()) - .set(Calendar.DST_OFFSET, dstAmount); + calb.set(Calendar.DST_OFFSET, dstAmount); } return (start + zoneNames[nameIndex].length()); } diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/java/util/Calendar.java --- a/jdk/src/share/classes/java/util/Calendar.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/java/util/Calendar.java Thu Feb 09 23:17:22 2012 -0800 @@ -2705,7 +2705,7 @@ * removed from the serialization stream; this will probably happen in the * near future. */ - private void writeObject(ObjectOutputStream stream) + private synchronized void writeObject(ObjectOutputStream stream) throws IOException { // Try to compute the time correctly, for the future (stream diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/java/util/CurrencyData.properties --- a/jdk/src/share/classes/java/util/CurrencyData.properties Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/java/util/CurrencyData.properties Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ # -# Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 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 @@ -29,7 +29,7 @@ # It is a serial number that accompanies with each amendment, such as # 'MAxxx.doc' -dataVersion=151 +dataVersion=153 # List of all valid ISO 4217 currency codes. # To ensure compatibility, do not remove codes. @@ -583,7 +583,7 @@ minor0=\ ADP-BEF-BIF-BYB-BYR-CLF-CLP-DJF-ESP-GNF-\ GRD-ISK-ITL-JPY-KMF-KRW-LUF-MGF-PYG-PTE-RWF-\ - TPE-TRL-VUV-XAF-XOF-XPF + TPE-TRL-VND-VUV-XAF-XOF-XPF minor1= minor3=\ BHD-IQD-JOD-KWD-LYD-OMR-TND diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/java/util/EnumMap.java --- a/jdk/src/share/classes/java/util/EnumMap.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/java/util/EnumMap.java Thu Feb 09 23:17:22 2012 -0800 @@ -106,7 +106,15 @@ /** * Distinguished non-null value for representing null values. */ - private static final Object NULL = new Integer(0); + private static final Object NULL = new Object() { + public int hashCode() { + return 0; + } + + public String toString() { + return "java.util.EnumMap.NULL"; + } + }; private Object maskNull(Object value) { return (value == null ? NULL : value); diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/java/util/Properties.java --- a/jdk/src/share/classes/java/util/Properties.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/java/util/Properties.java Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2010, 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 @@ -37,8 +37,8 @@ import java.lang.reflect.*; /** - * The Properties class represents a persistent set of - * properties. The Properties can be saved to a stream + * The {@code Properties} class represents a persistent set of + * properties. The {@code Properties} can be saved to a stream * or loaded from a stream. Each key and its corresponding value in * the property list is a string. *

    @@ -46,17 +46,17 @@ * "defaults"; this second property list is searched if * the property key is not found in the original property list. *

    - * Because Properties inherits from Hashtable, the - * put and putAll methods can be applied to a - * Properties object. Their use is strongly discouraged as they + * Because {@code Properties} inherits from {@code Hashtable}, the + * {@code put} and {@code putAll} methods can be applied to a + * {@code Properties} object. Their use is strongly discouraged as they * allow the caller to insert entries whose keys or values are not - * Strings. The setProperty method should be used - * instead. If the store or save method is called - * on a "compromised" Properties object that contains a - * non-String key or value, the call will fail. Similarly, - * the call to the propertyNames or list method - * will fail if it is called on a "compromised" Properties - * object that contains a non-String key. + * {@code Strings}. The {@code setProperty} method should be used + * instead. If the {@code store} or {@code save} method is called + * on a "compromised" {@code Properties} object that contains a + * non-{@code String} key or value, the call will fail. Similarly, + * the call to the {@code propertyNames} or {@code list} method + * will fail if it is called on a "compromised" {@code Properties} + * object that contains a non-{@code String} key. * *

    * The {@link #load(java.io.Reader) load(Reader)} / @@ -146,15 +146,15 @@ } /** - * Calls the Hashtable method put. Provided for + * Calls the Hashtable method {@code put}. Provided for * parallelism with the getProperty method. Enforces use of * strings for property keys and values. The value returned is the - * result of the Hashtable call to put. + * result of the Hashtable call to {@code put}. * * @param key the key to be placed into this property list. * @param value the value corresponding to key. * @return the previous value of the specified key in this property - * list, or null if it did not have one. + * list, or {@code null} if it did not have one. * @see #getProperty * @since 1.2 */ @@ -171,13 +171,13 @@ * kinds of line, natural lines and logical lines. * A natural line is defined as a line of * characters that is terminated either by a set of line terminator - * characters (\n or \r or \r\n) + * characters ({@code \n} or {@code \r} or {@code \r\n}) * or by the end of the stream. A natural line may be either a blank line, * a comment line, or hold all or some of a key-element pair. A logical * line holds all the data of a key-element pair, which may be spread * out across several adjacent natural lines by escaping * the line terminator sequence with a backslash character - * \. Note that a comment line cannot be extended + * {@code \}. Note that a comment line cannot be extended * in this manner; every natural line that is a comment must have * its own comment indicator, as described below. Lines are read from * input until the end of the stream is reached. @@ -185,13 +185,13 @@ *

    * A natural line that contains only white space characters is * considered blank and is ignored. A comment line has an ASCII - * '#' or '!' as its first non-white + * {@code '#'} or {@code '!'} as its first non-white * space character; comment lines are also ignored and do not * encode key-element information. In addition to line * terminators, this format considers the characters space - * (' ', '\u0020'), tab - * ('\t', '\u0009'), and form feed - * ('\f', '\u000C') to be white + * ({@code ' '}, {@code '\u005Cu0020'}), tab + * ({@code '\t'}, {@code '\u005Cu0009'}), and form feed + * ({@code '\f'}, {@code '\u005Cu000C'}) to be white * space. * *

    @@ -215,31 +215,31 @@ *

    * The key contains all of the characters in the line starting * with the first non-white space character and up to, but not - * including, the first unescaped '=', - * ':', or white space character other than a line + * including, the first unescaped {@code '='}, + * {@code ':'}, or white space character other than a line * terminator. All of these key termination characters may be * included in the key by escaping them with a preceding backslash * character; for example,

    * - * \:\=

    + * {@code \:\=}

    * - * would be the two-character key ":=". Line - * terminator characters can be included using \r and - * \n escape sequences. Any white space after the + * would be the two-character key {@code ":="}. Line + * terminator characters can be included using {@code \r} and + * {@code \n} escape sequences. Any white space after the * key is skipped; if the first non-white space character after - * the key is '=' or ':', then it is + * the key is {@code '='} or {@code ':'}, then it is * ignored and any white space characters after it are also * skipped. All remaining characters on the line become part of * the associated element string; if there are no remaining * characters, the element is the empty string - * "". Once the raw character sequences + * {@code ""}. Once the raw character sequences * constituting the key and element are identified, escape * processing is performed as described above. * *

    * As an example, each of the following three lines specifies the key - * "Truth" and the associated element value - * "Beauty": + * {@code "Truth"} and the associated element value + * {@code "Beauty"}: *

    *

          * Truth = Beauty
    @@ -254,11 +254,11 @@
          *                                  cantaloupe, watermelon, \
          *                                  kiwi, mango
          * 
    - * The key is "fruits" and the associated element is: + * The key is {@code "fruits"} and the associated element is: *

    *

    "apple, banana, pear, cantaloupe, watermelon, kiwi, mango"
    - * Note that a space appears before each \ so that a space - * will appear after each comma in the final result; the \, + * Note that a space appears before each {@code \} so that a space + * will appear after each comma in the final result; the {@code \}, * line terminator, and leading white space on the continuation line are * merely discarded and are not replaced by one or more other * characters. @@ -267,8 +267,8 @@ *

    *

    cheeses
          * 
    - * specifies that the key is "cheeses" and the associated - * element is the empty string "".

    + * specifies that the key is {@code "cheeses"} and the associated + * element is the empty string {@code ""}.

    *

    * * @@ -283,17 +283,17 @@ *

      *
    • Octal escapes are not recognized. * - *
    • The character sequence \b does not + *
    • The character sequence {@code \b} does not * represent a backspace character. * *
    • The method does not treat a backslash character, - * \, before a non-valid escape character as an + * {@code \}, before a non-valid escape character as an * error; the backslash is silently dropped. For example, in a - * Java string the sequence "\z" would cause a + * Java string the sequence {@code "\z"} would cause a * compile time error. In contrast, this method silently drops * the backslash. Therefore, this method treats the two character - * sequence "\b" as equivalent to the single - * character 'b'. + * sequence {@code "\b"} as equivalent to the single + * character {@code 'b'}. * *
    • Escapes are not necessary for single and double quotes; * however, by the rule above, single and double quote characters @@ -689,20 +689,20 @@ } /** - * Calls the store(OutputStream out, String comments) method + * Calls the {@code store(OutputStream out, String comments)} method * and suppresses IOExceptions that were thrown. * * @deprecated This method does not throw an IOException if an I/O error * occurs while saving the property list. The preferred way to save a - * properties list is via the store(OutputStream out, - * String comments) method or the - * storeToXML(OutputStream os, String comment) method. + * properties list is via the {@code store(OutputStream out, + * String comments)} method or the + * {@code storeToXML(OutputStream os, String comment)} method. * * @param out an output stream. * @param comments a description of the property list. - * @exception ClassCastException if this Properties object + * @exception ClassCastException if this {@code Properties} object * contains any keys or values that are not - * Strings. + * {@code Strings}. */ @Deprecated public void save(OutputStream out, String comments) { @@ -714,37 +714,37 @@ /** * Writes this property list (key and element pairs) in this - * Properties table to the output character stream in a + * {@code Properties} table to the output character stream in a * format suitable for using the {@link #load(java.io.Reader) load(Reader)} * method. *

      - * Properties from the defaults table of this Properties + * Properties from the defaults table of this {@code Properties} * table (if any) are not written out by this method. *

      - * If the comments argument is not null, then an ASCII # + * If the comments argument is not null, then an ASCII {@code #} * character, the comments string, and a line separator are first written - * to the output stream. Thus, the comments can serve as an + * to the output stream. Thus, the {@code comments} can serve as an * identifying comment. Any one of a line feed ('\n'), a carriage * return ('\r'), or a carriage return followed immediately by a line feed - * in comments is replaced by a line separator generated by the Writer - * and if the next character in comments is not character # or - * character ! then an ASCII # is written out + * in comments is replaced by a line separator generated by the {@code Writer} + * and if the next character in comments is not character {@code #} or + * character {@code !} then an ASCII {@code #} is written out * after that line separator. *

      * Next, a comment line is always written, consisting of an ASCII - * # character, the current date and time (as if produced - * by the toString method of Date for the - * current time), and a line separator as generated by the Writer. + * {@code #} character, the current date and time (as if produced + * by the {@code toString} method of {@code Date} for the + * current time), and a line separator as generated by the {@code Writer}. *

      - * Then every entry in this Properties table is + * Then every entry in this {@code Properties} table is * written out, one per line. For each entry the key string is - * written, then an ASCII =, then the associated + * written, then an ASCII {@code =}, then the associated * element string. For the key, all space characters are - * written with a preceding \ character. For the + * written with a preceding {@code \} character. For the * element, leading space characters, but not embedded or trailing - * space characters, are written with a preceding \ - * character. The key and element characters #, - * !, =, and : are written + * space characters, are written with a preceding {@code \} + * character. The key and element characters {@code #}, + * {@code !}, {@code =}, and {@code :} are written * with a preceding backslash to ensure that they are properly loaded. *

      * After the entries have been written, the output stream is flushed. @@ -755,9 +755,9 @@ * @param comments a description of the property list. * @exception IOException if writing this property list to the specified * output stream throws an IOException. - * @exception ClassCastException if this Properties object - * contains any keys or values that are not Strings. - * @exception NullPointerException if writer is null. + * @exception ClassCastException if this {@code Properties} object + * contains any keys or values that are not {@code Strings}. + * @exception NullPointerException if {@code writer} is null. * @since 1.6 */ public void store(Writer writer, String comments) @@ -771,11 +771,11 @@ /** * Writes this property list (key and element pairs) in this - * Properties table to the output stream in a format suitable - * for loading into a Properties table using the + * {@code Properties} table to the output stream in a format suitable + * for loading into a {@code Properties} table using the * {@link #load(InputStream) load(InputStream)} method. *

      - * Properties from the defaults table of this Properties + * Properties from the defaults table of this {@code Properties} * table (if any) are not written out by this method. *

      * This method outputs the comments, properties keys and values in @@ -786,12 +786,12 @@ *

    • The stream is written using the ISO 8859-1 character encoding. * *
    • Characters not in Latin-1 in the comments are written as - * \uxxxx for their appropriate unicode + * {@code \u005Cu}xxxx for their appropriate unicode * hexadecimal value xxxx. * - *
    • Characters less than \u0020 and characters greater - * than \u007E in property keys or values are written - * as \uxxxx for the appropriate hexadecimal + *
    • Characters less than {@code \u005Cu0020} and characters greater + * than {@code \u005Cu007E} in property keys or values are written + * as {@code \u005Cu}xxxx for the appropriate hexadecimal * value xxxx. *
    *

    @@ -802,9 +802,9 @@ * @param comments a description of the property list. * @exception IOException if writing this property list to the specified * output stream throws an IOException. - * @exception ClassCastException if this Properties object - * contains any keys or values that are not Strings. - * @exception NullPointerException if out is null. + * @exception ClassCastException if this {@code Properties} object + * contains any keys or values that are not {@code Strings}. + * @exception NullPointerException if {@code out} is null. * @since 1.2 */ public void store(OutputStream out, String comments) @@ -857,7 +857,7 @@ * results in an IOException. * @throws InvalidPropertiesFormatException Data on input stream does not * constitute a valid XML document with the mandated document type. - * @throws NullPointerException if in is null. + * @throws NullPointerException if {@code in} is null. * @see #storeToXML(OutputStream, String, String) * @since 1.5 */ @@ -879,14 +879,14 @@ * props.storeToXML(os, comment, "UTF-8");. * * @param os the output stream on which to emit the XML document. - * @param comment a description of the property list, or null + * @param comment a description of the property list, or {@code null} * if no comment is desired. * @throws IOException if writing to the specified output stream * results in an IOException. - * @throws NullPointerException if os is null. - * @throws ClassCastException if this Properties object + * @throws NullPointerException if {@code os} is null. + * @throws ClassCastException if this {@code Properties} object * contains any keys or values that are not - * Strings. + * {@code Strings}. * @see #loadFromXML(InputStream) * @since 1.5 */ @@ -907,13 +907,13 @@ * <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> * * - *

    If the specified comment is null then no comment + *

    If the specified comment is {@code null} then no comment * will be stored in the document. * *

    The specified stream remains open after this method returns. * * @param os the output stream on which to emit the XML document. - * @param comment a description of the property list, or null + * @param comment a description of the property list, or {@code null} * if no comment is desired. * @param encoding the name of a supported * @@ -921,11 +921,11 @@ * * @throws IOException if writing to the specified output stream * results in an IOException. - * @throws NullPointerException if os is null, - * or if encoding is null. - * @throws ClassCastException if this Properties object + * @throws NullPointerException if {@code os} is {@code null}, + * or if {@code encoding} is {@code null}. + * @throws ClassCastException if this {@code Properties} object * contains any keys or values that are not - * Strings. + * {@code Strings}. * @see #loadFromXML(InputStream) * @since 1.5 */ @@ -941,7 +941,7 @@ * Searches for the property with the specified key in this property list. * If the key is not found in this property list, the default property list, * and its defaults, recursively, are then checked. The method returns - * null if the property is not found. + * {@code null} if the property is not found. * * @param key the property key. * @return the value in this property list with the specified key value. diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/java/util/concurrent/FutureTask.java --- a/jdk/src/share/classes/java/util/concurrent/FutureTask.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/java/util/concurrent/FutureTask.java Thu Feb 09 23:17:22 2012 -0800 @@ -34,51 +34,111 @@ */ package java.util.concurrent; -import java.util.concurrent.locks.*; +import java.util.concurrent.locks.LockSupport; /** * A cancellable asynchronous computation. This class provides a base * implementation of {@link Future}, with methods to start and cancel * a computation, query to see if the computation is complete, and * retrieve the result of the computation. The result can only be - * retrieved when the computation has completed; the get - * method will block if the computation has not yet completed. Once + * retrieved when the computation has completed; the {@code get} + * methods will block if the computation has not yet completed. Once * the computation has completed, the computation cannot be restarted - * or cancelled. + * or cancelled (unless the computation is invoked using + * {@link #runAndReset}). * - *

    A FutureTask can be used to wrap a {@link Callable} or - * {@link java.lang.Runnable} object. Because FutureTask - * implements Runnable, a FutureTask can be - * submitted to an {@link Executor} for execution. + *

    A {@code FutureTask} can be used to wrap a {@link Callable} or + * {@link Runnable} object. Because {@code FutureTask} implements + * {@code Runnable}, a {@code FutureTask} can be submitted to an + * {@link Executor} for execution. * *

    In addition to serving as a standalone class, this class provides - * protected functionality that may be useful when creating + * {@code protected} functionality that may be useful when creating * customized task classes. * * @since 1.5 * @author Doug Lea - * @param The result type returned by this FutureTask's get method + * @param The result type returned by this FutureTask's {@code get} methods */ public class FutureTask implements RunnableFuture { - /** Synchronization control for FutureTask */ - private final Sync sync; + /* + * Revision notes: This differs from previous versions of this + * class that relied on AbstractQueuedSynchronizer, mainly to + * avoid surprising users about retaining interrupt status during + * cancellation races. Sync control in the current design relies + * on a "state" field updated via CAS to track completion, along + * with a simple Treiber stack to hold waiting threads. + * + * Style note: As usual, we bypass overhead of using + * AtomicXFieldUpdaters and instead directly use Unsafe intrinsics. + */ /** - * Creates a FutureTask that will, upon running, execute the - * given Callable. + * The run state of this task, initially NEW. The run state + * transitions to a terminal state only in methods set, + * setException, and cancel. During completion, state may take on + * transient values of COMPLETING (while outcome is being set) or + * INTERRUPTING (only while interrupting the runner to satisfy a + * cancel(true)). Transitions from these intermediate to final + * states use cheaper ordered/lazy writes because values are unique + * and cannot be further modified. + * + * Possible state transitions: + * NEW -> COMPLETING -> NORMAL + * NEW -> COMPLETING -> EXCEPTIONAL + * NEW -> CANCELLED + * NEW -> INTERRUPTING -> INTERRUPTED + */ + private volatile int state; + private static final int NEW = 0; + private static final int COMPLETING = 1; + private static final int NORMAL = 2; + private static final int EXCEPTIONAL = 3; + private static final int CANCELLED = 4; + private static final int INTERRUPTING = 5; + private static final int INTERRUPTED = 6; + + /** The underlying callable; nulled out after running */ + private Callable callable; + /** The result to return or exception to throw from get() */ + private Object outcome; // non-volatile, protected by state reads/writes + /** The thread running the callable; CASed during run() */ + private volatile Thread runner; + /** Treiber stack of waiting threads */ + private volatile WaitNode waiters; + + /** + * Returns result or throws exception for completed task. + * + * @param s completed state value + */ + @SuppressWarnings("unchecked") + private V report(int s) throws ExecutionException { + Object x = outcome; + if (s == NORMAL) + return (V)x; + if (s >= CANCELLED) + throw new CancellationException(); + throw new ExecutionException((Throwable)x); + } + + /** + * Creates a {@code FutureTask} that will, upon running, execute the + * given {@code Callable}. * * @param callable the callable task - * @throws NullPointerException if callable is null + * @throws NullPointerException if the callable is null */ public FutureTask(Callable callable) { if (callable == null) throw new NullPointerException(); - sync = new Sync(callable); + this.callable = callable; + this.state = NEW; // ensure visibility of callable } /** - * Creates a FutureTask that will, upon running, execute the - * given Runnable, and arrange that get will return the + * Creates a {@code FutureTask} that will, upon running, execute the + * given {@code Runnable}, and arrange that {@code get} will return the * given result on successful completion. * * @param runnable the runnable task @@ -86,29 +146,46 @@ * you don't need a particular result, consider using * constructions of the form: * {@code Future f = new FutureTask(runnable, null)} - * @throws NullPointerException if runnable is null + * @throws NullPointerException if the runnable is null */ public FutureTask(Runnable runnable, V result) { - sync = new Sync(Executors.callable(runnable, result)); + this.callable = Executors.callable(runnable, result); + this.state = NEW; // ensure visibility of callable } public boolean isCancelled() { - return sync.innerIsCancelled(); + return state >= CANCELLED; } public boolean isDone() { - return sync.innerIsDone(); + return state != NEW; } public boolean cancel(boolean mayInterruptIfRunning) { - return sync.innerCancel(mayInterruptIfRunning); + if (state != NEW) + return false; + if (mayInterruptIfRunning) { + if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, INTERRUPTING)) + return false; + Thread t = runner; + if (t != null) + t.interrupt(); + UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); // final state + } + else if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, CANCELLED)) + return false; + finishCompletion(); + return true; } /** * @throws CancellationException {@inheritDoc} */ public V get() throws InterruptedException, ExecutionException { - return sync.innerGet(); + int s = state; + if (s <= COMPLETING) + s = awaitDone(false, 0L); + return report(s); } /** @@ -116,12 +193,18 @@ */ public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { - return sync.innerGet(unit.toNanos(timeout)); + if (unit == null) + throw new NullPointerException(); + int s = state; + if (s <= COMPLETING && + (s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING) + throw new TimeoutException(); + return report(s); } /** * Protected method invoked when this task transitions to state - * isDone (whether normally or via cancellation). The + * {@code isDone} (whether normally or via cancellation). The * default implementation does nothing. Subclasses may override * this method to invoke completion callbacks or perform * bookkeeping. Note that you can query status inside the @@ -131,230 +214,269 @@ protected void done() { } /** - * Sets the result of this Future to the given value unless + * Sets the result of this future to the given value unless * this future has already been set or has been cancelled. - * This method is invoked internally by the run method + * + *

    This method is invoked internally by the {@link #run} method * upon successful completion of the computation. + * * @param v the value */ protected void set(V v) { - sync.innerSet(v); + if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) { + outcome = v; + UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state + finishCompletion(); + } } /** - * Causes this future to report an ExecutionException - * with the given throwable as its cause, unless this Future has + * Causes this future to report an {@link ExecutionException} + * with the given throwable as its cause, unless this future has * already been set or has been cancelled. - * This method is invoked internally by the run method + * + *

    This method is invoked internally by the {@link #run} method * upon failure of the computation. + * * @param t the cause of failure */ protected void setException(Throwable t) { - sync.innerSetException(t); + if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) { + outcome = t; + UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); // final state + finishCompletion(); + } } - // The following (duplicated) doc comment can be removed once - // - // 6270645: Javadoc comments should be inherited from most derived - // superinterface or superclass - // is fixed. - /** - * Sets this Future to the result of its computation - * unless it has been cancelled. - */ public void run() { - sync.innerRun(); + if (state != NEW || + !UNSAFE.compareAndSwapObject(this, runnerOffset, + null, Thread.currentThread())) + return; + try { + Callable c = callable; + if (c != null && state == NEW) { + V result; + boolean ran; + try { + result = c.call(); + ran = true; + } catch (Throwable ex) { + result = null; + ran = false; + setException(ex); + } + if (ran) + set(result); + } + } finally { + // runner must be non-null until state is settled to + // prevent concurrent calls to run() + runner = null; + // state must be re-read after nulling runner to prevent + // leaked interrupts + int s = state; + if (s >= INTERRUPTING) + handlePossibleCancellationInterrupt(s); + } } /** * Executes the computation without setting its result, and then - * resets this Future to initial state, failing to do so if the + * resets this future to initial state, failing to do so if the * computation encounters an exception or is cancelled. This is * designed for use with tasks that intrinsically execute more * than once. + * * @return true if successfully run and reset */ protected boolean runAndReset() { - return sync.innerRunAndReset(); + if (state != NEW || + !UNSAFE.compareAndSwapObject(this, runnerOffset, + null, Thread.currentThread())) + return false; + boolean ran = false; + int s = state; + try { + Callable c = callable; + if (c != null && s == NEW) { + try { + c.call(); // don't set result + ran = true; + } catch (Throwable ex) { + setException(ex); + } + } + } finally { + // runner must be non-null until state is settled to + // prevent concurrent calls to run() + runner = null; + // state must be re-read after nulling runner to prevent + // leaked interrupts + s = state; + if (s >= INTERRUPTING) + handlePossibleCancellationInterrupt(s); + } + return ran && s == NEW; + } + + /** + * Ensures that any interrupt from a possible cancel(true) is only + * delivered to a task while in run or runAndReset. + */ + private void handlePossibleCancellationInterrupt(int s) { + // It is possible for our interrupter to stall before getting a + // chance to interrupt us. Let's spin-wait patiently. + if (s == INTERRUPTING) + while (state == INTERRUPTING) + Thread.yield(); // wait out pending interrupt + + // assert state == INTERRUPTED; + + // We want to clear any interrupt we may have received from + // cancel(true). However, it is permissible to use interrupts + // as an independent mechanism for a task to communicate with + // its caller, and there is no way to clear only the + // cancellation interrupt. + // + // Thread.interrupted(); + } + + /** + * Simple linked list nodes to record waiting threads in a Treiber + * stack. See other classes such as Phaser and SynchronousQueue + * for more detailed explanation. + */ + static final class WaitNode { + volatile Thread thread; + volatile WaitNode next; + WaitNode() { thread = Thread.currentThread(); } } /** - * Synchronization control for FutureTask. Note that this must be - * a non-static inner class in order to invoke the protected - * done method. For clarity, all inner class support - * methods are same as outer, prefixed with "inner". - * - * Uses AQS sync state to represent run status + * Removes and signals all waiting threads, invokes done(), and + * nulls out callable. */ - private final class Sync extends AbstractQueuedSynchronizer { - private static final long serialVersionUID = -7828117401763700385L; - - /** State value representing that task is ready to run */ - private static final int READY = 0; - /** State value representing that task is running */ - private static final int RUNNING = 1; - /** State value representing that task ran */ - private static final int RAN = 2; - /** State value representing that task was cancelled */ - private static final int CANCELLED = 4; - - /** The underlying callable */ - private final Callable callable; - /** The result to return from get() */ - private V result; - /** The exception to throw from get() */ - private Throwable exception; - - /** - * The thread running task. When nulled after set/cancel, this - * indicates that the results are accessible. Must be - * volatile, to ensure visibility upon completion. - */ - private volatile Thread runner; - - Sync(Callable callable) { - this.callable = callable; - } - - private boolean ranOrCancelled(int state) { - return (state & (RAN | CANCELLED)) != 0; - } - - /** - * Implements AQS base acquire to succeed if ran or cancelled - */ - protected int tryAcquireShared(int ignore) { - return innerIsDone() ? 1 : -1; - } - - /** - * Implements AQS base release to always signal after setting - * final done status by nulling runner thread. - */ - protected boolean tryReleaseShared(int ignore) { - runner = null; - return true; - } - - boolean innerIsCancelled() { - return getState() == CANCELLED; - } - - boolean innerIsDone() { - return ranOrCancelled(getState()) && runner == null; - } - - V innerGet() throws InterruptedException, ExecutionException { - acquireSharedInterruptibly(0); - if (getState() == CANCELLED) - throw new CancellationException(); - if (exception != null) - throw new ExecutionException(exception); - return result; - } - - V innerGet(long nanosTimeout) throws InterruptedException, ExecutionException, TimeoutException { - if (!tryAcquireSharedNanos(0, nanosTimeout)) - throw new TimeoutException(); - if (getState() == CANCELLED) - throw new CancellationException(); - if (exception != null) - throw new ExecutionException(exception); - return result; - } - - void innerSet(V v) { - for (;;) { - int s = getState(); - if (s == RAN) - return; - if (s == CANCELLED) { - // aggressively release to set runner to null, - // in case we are racing with a cancel request - // that will try to interrupt runner - releaseShared(0); - return; + private void finishCompletion() { + // assert state > COMPLETING; + for (WaitNode q; (q = waiters) != null;) { + if (UNSAFE.compareAndSwapObject(this, waitersOffset, q, null)) { + for (;;) { + Thread t = q.thread; + if (t != null) { + q.thread = null; + LockSupport.unpark(t); + } + WaitNode next = q.next; + if (next == null) + break; + q.next = null; // unlink to help gc + q = next; } - if (compareAndSetState(s, RAN)) { - result = v; - releaseShared(0); - done(); - return; - } + break; } } - void innerSetException(Throwable t) { - for (;;) { - int s = getState(); - if (s == RAN) - return; - if (s == CANCELLED) { - // aggressively release to set runner to null, - // in case we are racing with a cancel request - // that will try to interrupt runner - releaseShared(0); - return; - } - if (compareAndSetState(s, RAN)) { - exception = t; - releaseShared(0); - done(); - return; - } + done(); + + callable = null; // to reduce footprint + } + + /** + * Awaits completion or aborts on interrupt or timeout. + * + * @param timed true if use timed waits + * @param nanos time to wait, if timed + * @return state upon completion + */ + private int awaitDone(boolean timed, long nanos) + throws InterruptedException { + final long deadline = timed ? System.nanoTime() + nanos : 0L; + WaitNode q = null; + boolean queued = false; + for (;;) { + if (Thread.interrupted()) { + removeWaiter(q); + throw new InterruptedException(); } - } - boolean innerCancel(boolean mayInterruptIfRunning) { - for (;;) { - int s = getState(); - if (ranOrCancelled(s)) - return false; - if (compareAndSetState(s, CANCELLED)) - break; - } - if (mayInterruptIfRunning) { - Thread r = runner; - if (r != null) - r.interrupt(); + int s = state; + if (s > COMPLETING) { + if (q != null) + q.thread = null; + return s; } - releaseShared(0); - done(); - return true; - } - - void innerRun() { - if (!compareAndSetState(READY, RUNNING)) - return; - - runner = Thread.currentThread(); - if (getState() == RUNNING) { // recheck after setting thread - V result; - try { - result = callable.call(); - } catch (Throwable ex) { - setException(ex); - return; + else if (s == COMPLETING) // cannot time out yet + Thread.yield(); + else if (q == null) + q = new WaitNode(); + else if (!queued) + queued = UNSAFE.compareAndSwapObject(this, waitersOffset, + q.next = waiters, q); + else if (timed) { + nanos = deadline - System.nanoTime(); + if (nanos <= 0L) { + removeWaiter(q); + return state; } - set(result); - } else { - releaseShared(0); // cancel + LockSupport.parkNanos(this, nanos); } + else + LockSupport.park(this); } + } - boolean innerRunAndReset() { - if (!compareAndSetState(READY, RUNNING)) - return false; - try { - runner = Thread.currentThread(); - if (getState() == RUNNING) - callable.call(); // don't set result - runner = null; - return compareAndSetState(RUNNING, READY); - } catch (Throwable ex) { - setException(ex); - return false; + /** + * Tries to unlink a timed-out or interrupted wait node to avoid + * accumulating garbage. Internal nodes are simply unspliced + * without CAS since it is harmless if they are traversed anyway + * by releasers. To avoid effects of unsplicing from already + * removed nodes, the list is retraversed in case of an apparent + * race. This is slow when there are a lot of nodes, but we don't + * expect lists to be long enough to outweigh higher-overhead + * schemes. + */ + private void removeWaiter(WaitNode node) { + if (node != null) { + node.thread = null; + retry: + for (;;) { // restart on removeWaiter race + for (WaitNode pred = null, q = waiters, s; q != null; q = s) { + s = q.next; + if (q.thread != null) + pred = q; + else if (pred != null) { + pred.next = s; + if (pred.thread == null) // check for race + continue retry; + } + else if (!UNSAFE.compareAndSwapObject(this, waitersOffset, + q, s)) + continue retry; + } + break; } } } + + // Unsafe mechanics + private static final sun.misc.Unsafe UNSAFE; + private static final long stateOffset; + private static final long runnerOffset; + private static final long waitersOffset; + static { + try { + UNSAFE = sun.misc.Unsafe.getUnsafe(); + Class k = FutureTask.class; + stateOffset = UNSAFE.objectFieldOffset + (k.getDeclaredField("state")); + runnerOffset = UNSAFE.objectFieldOffset + (k.getDeclaredField("runner")); + waitersOffset = UNSAFE.objectFieldOffset + (k.getDeclaredField("waiters")); + } catch (Exception e) { + throw new Error(e); + } + } + } diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/javax/crypto/Cipher.java --- a/jdk/src/share/classes/javax/crypto/Cipher.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/javax/crypto/Cipher.java Thu Feb 09 23:17:22 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 @@ -26,6 +26,8 @@ package javax.crypto; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import java.util.regex.*; @@ -389,16 +391,15 @@ return matches(regexp, value) ? S_YES : S_NO; } - // Map for previously compiled patterns - // XXX use ConcurrentHashMap once available - private final static Map patternCache = - Collections.synchronizedMap(new HashMap()); + // ConcurrentMap for previously compiled patterns + private final static ConcurrentMap patternCache = + new ConcurrentHashMap(); private static boolean matches(String regexp, String str) { Pattern pattern = patternCache.get(regexp); if (pattern == null) { pattern = Pattern.compile(regexp); - patternCache.put(regexp, pattern); + patternCache.putIfAbsent(regexp, pattern); } return pattern.matcher(str.toUpperCase(Locale.ENGLISH)).matches(); } diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/javax/sql/rowset/serial/SQLInputImpl.java --- a/jdk/src/share/classes/javax/sql/rowset/serial/SQLInputImpl.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/javax/sql/rowset/serial/SQLInputImpl.java Thu Feb 09 23:17:22 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 @@ -25,6 +25,7 @@ package javax.sql.rowset.serial; import java.sql.*; +import java.util.Arrays; import java.util.Map; /** @@ -119,7 +120,7 @@ "object with null parameters"); } // assign our local reference to the attribute stream - attrib = attributes; + attrib = Arrays.copyOf(attributes, attributes.length); // init the index point before the head of the stream idx = -1; // set the map diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/javax/sql/rowset/serial/SQLOutputImpl.java --- a/jdk/src/share/classes/javax/sql/rowset/serial/SQLOutputImpl.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/javax/sql/rowset/serial/SQLOutputImpl.java Thu Feb 09 23:17:22 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 @@ -25,11 +25,10 @@ package javax.sql.rowset.serial; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; import java.sql.*; -import javax.sql.*; -import java.io.*; -import java.lang.String; -import java.math.*; import java.util.Map; import java.util.Vector; @@ -444,16 +443,15 @@ * will need to track if a field is SQL null for itself */ if (x == null) { - attribs.add(x); - return; + attribs.add(null); + } else { + /* + * We have to write out a SerialStruct that contains + * the name of this class otherwise we don't know + * what to re-instantiate during readSQL() + */ + attribs.add(new SerialStruct(x, map)); } - - /* - * We have to write out a SerialStruct that contains - * the name of this class otherwise we don't know - * what to re-instantiate during readSQL() - */ - attribs.add(new SerialStruct(x, map)); } /** @@ -470,10 +468,10 @@ @SuppressWarnings("unchecked") public void writeRef(Ref x) throws SQLException { if (x == null) { - attribs.add(x); - return; + attribs.add(null); + } else { + attribs.add(new SerialRef(x)); } - attribs.add(new SerialRef(x)); } /** @@ -490,10 +488,10 @@ @SuppressWarnings("unchecked") public void writeBlob(Blob x) throws SQLException { if (x == null) { - attribs.add(x); - return; + attribs.add(null); + } else { + attribs.add(new SerialBlob(x)); } - attribs.add(new SerialBlob(x)); } /** @@ -510,10 +508,10 @@ @SuppressWarnings("unchecked") public void writeClob(Clob x) throws SQLException { if (x == null) { - attribs.add(x); - return; + attribs.add(null); + } else { + attribs.add(new SerialClob(x)); } - attribs.add(new SerialClob(x)); } /** @@ -554,10 +552,10 @@ @SuppressWarnings("unchecked") public void writeArray(Array x) throws SQLException { if (x == null) { - attribs.add(x); - return; + attribs.add(null); + } else { + attribs.add(new SerialArray(x, map)); } - attribs.add(new SerialArray(x, map)); } /** @@ -574,11 +572,10 @@ @SuppressWarnings("unchecked") public void writeURL(java.net.URL url) throws SQLException { if (url == null) { - attribs.add(url); - return; + attribs.add(null); + } else { + attribs.add(new SerialDatalink(url)); } - attribs.add(new SerialDatalink(url)); - } diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/javax/sql/rowset/serial/SerialStruct.java --- a/jdk/src/share/classes/javax/sql/rowset/serial/SerialStruct.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/javax/sql/rowset/serial/SerialStruct.java Thu Feb 09 23:17:22 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 @@ -29,6 +29,7 @@ import javax.sql.*; import java.io.*; import java.math.*; +import java.util.Arrays; import java.util.Map; import java.util.Vector; @@ -174,7 +175,8 @@ * @throws SerialException if an error occurs */ public Object[] getAttributes() throws SerialException { - return attribs; + Object[] val = this.attribs; + return (val == null) ? null : Arrays.copyOf(val, val.length); } /** @@ -197,7 +199,8 @@ public Object[] getAttributes(Map> map) throws SerialException { - return attribs; + Object[] val = this.attribs; + return (val == null) ? null : Arrays.copyOf(val, val.length); } diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/sun/security/ssl/EngineArgs.java --- a/jdk/src/share/classes/sun/security/ssl/EngineArgs.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/sun/security/ssl/EngineArgs.java Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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,7 +25,6 @@ package sun.security.ssl; -import javax.net.ssl.*; import java.nio.*; /* @@ -157,6 +156,7 @@ int amount = Math.min(appData[i].remaining(), spaceLeft); appData[i].limit(appData[i].position() + amount); netData.put(appData[i]); + appRemaining -= amount; spaceLeft -= amount; } } @@ -209,10 +209,16 @@ /* * In the case of Exception, we want to reset the positions * to appear as though no data has been consumed or produced. + * + * Currently, this method is only called as we are preparing to + * fail out, and thus we don't need to actually recalculate + * appRemaining. If that assumption changes, that variable should + * be updated here. */ void resetPos() { netData.position(netPos); for (int i = offset; i < offset + len; i++) { + // See comment above about recalculating appRemaining. appData[i].position(appPoss[i]); } } diff -r fc06525cb345 -r 5561a4c99825 jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java --- a/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java Thu Feb 09 23:17:22 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 @@ -1165,7 +1165,7 @@ ea.resetPos(); fatal(Alerts.alert_internal_error, - "problem unwrapping net record", e); + "problem wrapping app data", e); return null; // make compiler happy } finally { /* diff -r fc06525cb345 -r 5561a4c99825 jdk/src/solaris/classes/sun/tools/attach/LinuxVirtualMachine.java --- a/jdk/src/solaris/classes/sun/tools/attach/LinuxVirtualMachine.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/solaris/classes/sun/tools/attach/LinuxVirtualMachine.java Thu Feb 09 23:17:22 2012 -0800 @@ -37,8 +37,12 @@ * Linux implementation of HotSpotVirtualMachine */ public class LinuxVirtualMachine extends HotSpotVirtualMachine { - // temp directory for socket file - private static final String tmpdir = System.getProperty("java.io.tmpdir"); + // "/tmp" is used as a global well-known location for the files + // .java_pid. and .attach_pid. It is important that this + // location is the same for all processes, otherwise the tools + // will not be able to find all Hotspot processes. + // Any changes to this needs to be synchronized with HotSpot. + private static final String tmpdir = "/tmp"; // Indicates if this machine uses the old LinuxThreads static boolean isLinuxThreads; @@ -261,20 +265,12 @@ } // Return the socket file for the given process. - // Checks working directory of process for .java_pid. If not - // found it looks in temp directory. private String findSocketFile(int pid) { - // First check for a .java_pid file in the working directory - // of the target process - String fn = ".java_pid" + pid; - String path = "/proc/" + pid + "/cwd/" + fn; - File f = new File(path); + File f = new File(tmpdir, ".java_pid" + pid); if (!f.exists()) { - // Not found, so try temp directory - f = new File(tmpdir, fn); - path = f.exists() ? f.getPath() : null; + return null; } - return path; + return f.getPath(); } // On Solaris/Linux a simple handshake is used to start the attach mechanism diff -r fc06525cb345 -r 5561a4c99825 jdk/src/solaris/classes/sun/tools/attach/SolarisVirtualMachine.java --- a/jdk/src/solaris/classes/sun/tools/attach/SolarisVirtualMachine.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/solaris/classes/sun/tools/attach/SolarisVirtualMachine.java Thu Feb 09 23:17:22 2012 -0800 @@ -38,11 +38,12 @@ * Solaris implementation of HotSpotVirtualMachine. */ public class SolarisVirtualMachine extends HotSpotVirtualMachine { - // Use /tmp instead of /var/tmp on Solaris as /tmp is the default used by - // HotSpot when the property is not set on the command line. - private static final String tmpdir1 = System.getProperty("java.io.tmpdir"); - private static final String tmpdir = - (tmpdir1.equals("/var/tmp") || tmpdir1.equals("/var/tmp/")) ? "/tmp" : tmpdir1; + // "/tmp" is used as a global well-known location for the files + // .java_pid. and .attach_pid. It is important that this + // location is the same for all processes, otherwise the tools + // will not be able to find all Hotspot processes. + // Any changes to this needs to be synchronized with HotSpot. + private static final String tmpdir = "/tmp"; // door descriptor; private int fd = -1; @@ -191,19 +192,10 @@ } } - // The door is attached to .java_pid in the target VM's working - // directory or temporary directory. + // The door is attached to .java_pid in the temporary directory. private int openDoor(int pid) throws IOException { - // First check for a .java_pid file in the working directory - // of the target process - String fn = ".java_pid" + pid; - String path = "/proc/" + pid + "/cwd/" + fn; - try { - fd = open(path); - } catch (FileNotFoundException fnf) { - path = tmpdir + "/" + fn; - fd = open(path); - } + String path = tmpdir + "/.java_pid" + pid;; + fd = open(path); // Check that the file owner/permission to avoid attaching to // bogus process diff -r fc06525cb345 -r 5561a4c99825 jdk/src/solaris/native/java/lang/UNIXProcess_md.c --- a/jdk/src/solaris/native/java/lang/UNIXProcess_md.c Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/solaris/native/java/lang/UNIXProcess_md.c Thu Feb 09 23:17:22 2012 -0800 @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include #include #include diff -r fc06525cb345 -r 5561a4c99825 jdk/src/windows/native/sun/font/fontpath.c --- a/jdk/src/windows/native/sun/font/fontpath.c Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/src/windows/native/sun/font/fontpath.c Thu Feb 09 23:17:22 2012 -0800 @@ -185,6 +185,12 @@ return 0; } +/* This HDC is initialised and released in the populate family map + * JNI entry point, and used within the call which would otherwise + * create many DCs. + */ +static HDC screenDC = NULL; + static int DifferentFamily(wchar_t *family, wchar_t* fullName) { LOGFONTW lfw; CheckFamilyInfo info; @@ -202,7 +208,7 @@ memset(&lfw, 0, sizeof(lfw)); wcscpy(lfw.lfFaceName, fullName); lfw.lfCharSet = DEFAULT_CHARSET; - EnumFontFamiliesExW(GetDC(NULL), &lfw, + EnumFontFamiliesExW(screenDC, &lfw, (FONTENUMPROCW)CheckFontFamilyProcW, (LPARAM)(&info), 0L); @@ -299,7 +305,7 @@ memset(&lfa, 0, sizeof(lfa)); strcpy(lfa.lfFaceName, lpelfe->elfLogFont.lfFaceName); lfa.lfCharSet = lpelfe->elfLogFont.lfCharSet; - EnumFontFamiliesExA(GetDC(NULL), &lfa, + EnumFontFamiliesExA(screenDC, &lfa, (FONTENUMPROCA)EnumFontFacesInFamilyProcA, lParam, 0L); return 1; @@ -353,7 +359,7 @@ memset(&lfw, 0, sizeof(lfw)); wcscpy(lfw.lfFaceName, lpelfe->elfLogFont.lfFaceName); lfw.lfCharSet = lpelfe->elfLogFont.lfCharSet; - EnumFontFamiliesExW(GetDC(NULL), &lfw, + EnumFontFamiliesExW(screenDC, &lfw, (FONTENUMPROCW)EnumFontFacesInFamilyProcW, lParam, 0L); return 1; @@ -613,13 +619,17 @@ return; } + screenDC = GetDC(NULL); + if (screenDC == NULL) { + return; + } /* Enumerate fonts via GDI to build maps of fonts and families */ if (IS_NT) { LOGFONTW lfw; memset(&lfw, 0, sizeof(lfw)); lfw.lfCharSet = DEFAULT_CHARSET; /* all charsets */ wcscpy(lfw.lfFaceName, L""); /* one face per family (CHECK) */ - EnumFontFamiliesExW(GetDC(NULL), &lfw, + EnumFontFamiliesExW(screenDC, &lfw, (FONTENUMPROCW)EnumFamilyNamesW, (LPARAM)(&fmi), 0L); } else { @@ -627,7 +637,7 @@ memset(&lfa, 0, sizeof(lfa)); lfa.lfCharSet = DEFAULT_CHARSET; /* all charsets */ strcpy(lfa.lfFaceName, ""); /* one face per family */ - ret = EnumFontFamiliesExA(GetDC(NULL), &lfa, + ret = EnumFontFamiliesExA(screenDC, &lfa, (FONTENUMPROCA)EnumFamilyNamesA, (LPARAM)(&fmi), 0L); } @@ -637,6 +647,8 @@ ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, fontKeyName, 0L, KEY_READ, &hkeyFonts); if (ret != ERROR_SUCCESS) { + ReleaseDC(NULL, screenDC); + screenDC = NULL; return; } @@ -653,6 +665,8 @@ dwMaxValueNameLen >= MAX_BUFFER || dwMaxValueDataLen >= MAX_BUFFER) { RegCloseKey(hkeyFonts); + ReleaseDC(NULL, screenDC); + screenDC = NULL; return; } for (nval = 0; nval < dwNumValues; nval++ ) { @@ -692,4 +706,6 @@ } } RegCloseKey(hkeyFonts); + ReleaseDC(NULL, screenDC); + screenDC = NULL; } diff -r fc06525cb345 -r 5561a4c99825 jdk/test/Makefile --- a/jdk/test/Makefile Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/test/Makefile Thu Feb 09 23:17:22 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 @@ -556,7 +556,7 @@ 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 \ - com/oracle/secrity/ucrypto) + com/oracle/security/ucrypto) $(call SharedLibraryPermissions,sun/security) $(call RunAgentvmBatch) diff -r fc06525cb345 -r 5561a4c99825 jdk/test/ProblemList.txt --- a/jdk/test/ProblemList.txt Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/test/ProblemList.txt Thu Feb 09 23:17:22 2012 -0800 @@ -476,6 +476,9 @@ java/rmi/server/RMISocketFactory/useSocketFactory/registry/UseCustomSocketFactory.java generic-all java/rmi/server/UnicastRemoteObject/unexportObject/UnexportLeak.java generic-all +# 7132247 +java/rmi/registry/readTest/readTest.sh windows-all + ############################################################################ # jdk_security @@ -575,13 +578,13 @@ # Filed 6979016 sun/tools/jconsole/ResourceCheckTest.sh generic-all +# 7132203 +sun/jvmstat/monitor/MonitoredVm/CR6672135.java generic-all + ############################################################################ # jdk_util -# Filed 7027061 -java/util/Locale/Bug6989440.java windows-all - # Filed 6933803 java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java generic-all diff -r fc06525cb345 -r 5561a4c99825 jdk/test/java/lang/Integer/Unsigned.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/Integer/Unsigned.java Thu Feb 09 23:17:22 2012 -0800 @@ -0,0 +1,396 @@ +/* + * Copyright (c) 2009, 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 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 4504839 4215269 6322074 + * @summary Basic tests for unsigned operations. + * @author Joseph D. Darcy + */ +public class Unsigned { + public static void main(String... args) { + int errors = 0; + + errors += testRoundtrip(); + errors += testByteToUnsignedInt(); + errors += testShortToUnsignedInt(); + errors += testUnsignedCompare(); + errors += testToUnsignedLong(); + errors += testToStringUnsigned(); + errors += testParseUnsignedInt(); + errors += testDivideAndRemainder(); + + if (errors > 0) { + throw new RuntimeException(errors + " errors found in unsigned operations."); + } + } + + private static int testRoundtrip() { + int errors = 0; + + int[] data = {-1, 0, 1}; + + for(int datum : data) { + if (Integer.parseUnsignedInt(Integer.toBinaryString(datum), 2) != datum) { + errors++; + System.err.println("Bad binary roundtrip conversion of " + datum); + } + + if (Integer.parseUnsignedInt(Integer.toOctalString(datum), 8) != datum) { + errors++; + System.err.println("Bad octal roundtrip conversion of " + datum); + } + + if (Integer.parseUnsignedInt(Integer.toHexString(datum), 16) != datum) { + errors++; + System.err.println("Bad hex roundtrip conversion of " + datum); + } + } + return errors; + } + + private static int testByteToUnsignedInt() { + int errors = 0; + + for(int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) { + byte datum = (byte) i; + int ui = Byte.toUnsignedInt(datum); + + if ( (ui & (~0xff)) != 0 || + ((byte)ui != datum )) { + errors++; + System.err.printf("Bad conversion of byte %d to unsigned int %d%n", + datum, ui); + } + } + return errors; + } + + private static int testShortToUnsignedInt() { + int errors = 0; + + for(int i = Short.MIN_VALUE; i <= Short.MAX_VALUE; i++) { + short datum = (short) i; + int ui = Short.toUnsignedInt(datum); + + if ( (ui & (~0xffff)) != 0 || + ((short)ui != datum )) { + errors++; + System.err.printf("Bad conversion of short %d to unsigned int %d%n", + datum, ui); + } + } + return errors; + } + + private static int testUnsignedCompare() { + int errors = 0; + + int[] data = { + 0, + 1, + 2, + 3, + 0x8000_0000, + 0x8000_0001, + 0x8000_0002, + 0x8000_0003, + 0xFFFF_FFFE, + 0xFFFF_FFFF, + }; + + for(int i : data) { + for(int j : data) { + int libraryResult = Integer.compareUnsigned(i, j); + int libraryResultRev = Integer.compareUnsigned(j, i); + int localResult = compUnsigned(i, j); + + if (i == j) { + if (libraryResult != 0) { + errors++; + System.err.printf("Value 0x%x did not compare as " + + "an unsigned value equal to itself; got %d%n", + i, libraryResult); + } + } + + if (Integer.signum(libraryResult) != Integer.signum(localResult)) { + errors++; + System.err.printf("Unsigned compare of 0x%x to 0x%x%n:" + + "\texpected sign of %d, got %d%n", + i, j, localResult, libraryResult); + } + + if (Integer.signum(libraryResult) != + -Integer.signum(libraryResultRev)) { + errors++; + System.err.printf("signum(compareUnsigned(x, y)) != -signum(compareUnsigned(y,x))" + + " for \t0x%x and 0x%x, computed %d and %d%n", + i, j, libraryResult, libraryResultRev); + } + } + } + + return errors; + } + + /** + * Straightforward compare unsigned algorithm. + */ + private static int compUnsigned(int x, int y) { + int sign_x = x & Integer.MIN_VALUE; + int sign_y = y & Integer.MIN_VALUE; + + int mant_x = x & (~Integer.MIN_VALUE); + int mant_y = y & (~Integer.MIN_VALUE); + + if (sign_x == sign_y) + return Integer.compare(mant_x, mant_y); + else { + if (sign_x == 0) + return -1; // sign x is 0, sign y is 1 => (x < y) + else + return 1; // sign x is 1, sign y is 0 => (x > y) + } + } + + private static int testToUnsignedLong() { + int errors = 0; + + int[] data = { + 0, + 1, + 2, + 3, + 0x1234_5678, + 0x8000_0000, + 0x8000_0001, + 0x8000_0002, + 0x8000_0003, + 0x8765_4321, + 0xFFFF_FFFE, + 0xFFFF_FFFF, + }; + + for(int datum : data) { + long result = Integer.toUnsignedLong(datum); + + // High-order bits should be zero + if ((result & 0xffff_ffff_0000_0000L) != 0L) { + errors++; + System.err.printf("High bits set converting 0x%x to 0x%x%n", + datum, result); + } + + // Lower-order bits should be equal to datum. + int lowOrder = (int)(result & 0x0000_0000_ffff_ffffL); + if (lowOrder != datum ) { + errors++; + System.err.printf("Low bits not preserved converting 0x%x to 0x%x%n", + datum, result); + } + } + return errors; + } + + private static int testToStringUnsigned() { + int errors = 0; + + int[] data = { + 0, + 1, + 2, + 3, + 99999, + 100000, + 999999, + 100000, + 999999999, + 1000000000, + 0x1234_5678, + 0x8000_0000, + 0x8000_0001, + 0x8000_0002, + 0x8000_0003, + 0x8765_4321, + 0xFFFF_FFFE, + 0xFFFF_FFFF, + }; + + for(int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) { + for(int datum : data) { + String result1 = Integer.toUnsignedString(datum, radix); + String result2 = Long.toString(Integer.toUnsignedLong(datum), radix); + + if (!result1.equals(result2)) { + errors++; + System.err.printf("Unexpected string difference converting 0x%x:" + + "\t%s %s%n", + datum, result1, result2); + } + + if (radix == 10) { + String result3 = Integer.toUnsignedString(datum); + if (!result2.equals(result3)) { + errors++; + System.err.printf("Unexpected string difference converting 0x%x:" + + "\t%s %s%n", + datum, result3, result2); + } + } + + int parseResult = Integer.parseUnsignedInt(result1, radix); + + if (parseResult != datum) { + errors++; + System.err.printf("Bad roundtrip conversion of %d in base %d" + + "\tconverting back ''%s'' resulted in %d%n", + datum, radix, result1, parseResult); + } + } + } + + return errors; + } + + private static final long MAX_UNSIGNED_INT = Integer.toUnsignedLong(0xffff_ffff); + + private static int testParseUnsignedInt() { + int errors = 0; + + // Values include those between signed Integer.MAX_VALUE and + // unsignted int MAX_VALUE. + long[] inRange = { + 0L, + 1L, + 10L, + 2147483646L, // MAX_VALUE - 1 + 2147483647L, // MAX_VALUE + 2147483648L, // MAX_VALUE + 1 + + MAX_UNSIGNED_INT - 1L, + MAX_UNSIGNED_INT, + }; + + for(long value : inRange) { + for(int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) { + String longString = Long.toString(value, radix); + int intResult = Integer.parseUnsignedInt(longString, radix); + + if (Integer.toUnsignedLong(intResult) != value) { + errors++; + System.err.printf("Bad roundtrip conversion of %d in base %d" + + "\tconverting back ''%s'' resulted in %d%n", + value, radix, longString, intResult); + } + } + } + + String[] outOfRange = { + null, + "", + "-1", + Long.toString(MAX_UNSIGNED_INT + 1L), + Long.toString(Long.MAX_VALUE) + }; + + for(String s : outOfRange) { + try { + int result = Integer.parseUnsignedInt(s); + errors++; // Should not reach here + System.err.printf("Unexpected got %d from an unsigned conversion of %s", + result, s); + } catch(NumberFormatException nfe) { + ; // Correct result + } + } + + return errors; + } + + private static int testDivideAndRemainder() { + int errors = 0; + + long[] inRange = { + 0L, + 1L, + 2L, + 2147483646L, // MAX_VALUE - 1 + 2147483647L, // MAX_VALUE + 2147483648L, // MAX_VALUE + 1 + + MAX_UNSIGNED_INT - 1L, + MAX_UNSIGNED_INT, + }; + + for(long dividend : inRange) { + for(long divisor : inRange) { + int quotient; + long longQuotient; + + int remainder; + long longRemainder; + + if (divisor == 0) { + try { + quotient = Integer.divideUnsigned((int) dividend, (int) divisor); + errors++; + } catch(ArithmeticException ea) { + ; // Expected + } + + try { + remainder = Integer.remainderUnsigned((int) dividend, (int) divisor); + errors++; + } catch(ArithmeticException ea) { + ; // Expected + } + } else { + quotient = Integer.divideUnsigned((int) dividend, (int) divisor); + longQuotient = dividend / divisor; + + if (quotient != (int)longQuotient) { + errors++; + System.err.printf("Unexpected unsigned divide result %s on %s/%s%n", + Integer.toUnsignedString(quotient), + Integer.toUnsignedString((int) dividend), + Integer.toUnsignedString((int) divisor)); + } + + remainder = Integer.remainderUnsigned((int) dividend, (int) divisor); + longRemainder = dividend % divisor; + + if (remainder != (int)longRemainder) { + errors++; + System.err.printf("Unexpected unsigned remainder result %s on %s%%%s%n", + Integer.toUnsignedString(remainder), + Integer.toUnsignedString((int) dividend), + Integer.toUnsignedString((int) divisor)); + } + } + } + } + + return errors; + } +} diff -r fc06525cb345 -r 5561a4c99825 jdk/test/java/lang/Long/Unsigned.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/Long/Unsigned.java Thu Feb 09 23:17:22 2012 -0800 @@ -0,0 +1,388 @@ +/* + * Copyright (c) 2009, 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 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 4504839 4215269 6322074 + * @summary Basic tests for unsigned operations + * @author Joseph D. Darcy + */ + +import java.math.*; + +public class Unsigned { + public static void main(String... args) { + int errors = 0; + + errors += testRoundtrip(); + errors += testByteToUnsignedLong(); + errors += testShortToUnsignedLong(); + errors += testUnsignedCompare(); + errors += testToStringUnsigned(); + errors += testParseUnsignedLong(); + errors += testDivideAndRemainder(); + + if (errors > 0) { + throw new RuntimeException(errors + " errors found in unsigned operations."); + } + } + + private static final BigInteger TWO = BigInteger.valueOf(2L); + + private static int testRoundtrip() { + int errors = 0; + + long[] data = {-1L, 0L, 1L}; + + for(long datum : data) { + if (Long.parseUnsignedLong(Long.toBinaryString(datum), 2) != datum) { + errors++; + System.err.println("Bad binary roundtrip conversion of " + datum); + } + + if (Long.parseUnsignedLong(Long.toOctalString(datum), 8) != datum) { + errors++; + System.err.println("Bad octal roundtrip conversion of " + datum); + } + + if (Long.parseUnsignedLong(Long.toHexString(datum), 16) != datum) { + errors++; + System.err.println("Bad hex roundtrip conversion of " + datum); + } + } + return errors; + } + + private static int testByteToUnsignedLong() { + int errors = 0; + + for(int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) { + byte datum = (byte) i; + long ui = Byte.toUnsignedLong(datum); + + if ( (ui & (~0xffL)) != 0L || + ((byte)ui != datum )) { + errors++; + System.err.printf("Bad conversion of byte %d to unsigned long %d%n", + datum, ui); + } + } + return errors; + } + + private static int testShortToUnsignedLong() { + int errors = 0; + + for(int i = Short.MIN_VALUE; i <= Short.MAX_VALUE; i++) { + short datum = (short) i; + long ui = Short.toUnsignedLong(datum); + + if ( (ui & (~0xffffL)) != 0L || + ((short)ui != datum )) { + errors++; + System.err.printf("Bad conversion of short %d to unsigned long %d%n", + datum, ui); + } + } + return errors; + } + private static int testUnsignedCompare() { + int errors = 0; + + long[] data = { + 0L, + 1L, + 2L, + 3L, + 0x00000000_80000000L, + 0x00000000_FFFFFFFFL, + 0x00000001_00000000L, + 0x80000000_00000000L, + 0x80000000_00000001L, + 0x80000000_00000002L, + 0x80000000_00000003L, + 0x80000000_80000000L, + 0xFFFFFFFF_FFFFFFFEL, + 0xFFFFFFFF_FFFFFFFFL, + }; + + for(long i : data) { + for(long j : data) { + long libraryResult = Long.compareUnsigned(i, j); + long libraryResultRev = Long.compareUnsigned(j, i); + long localResult = compUnsigned(i, j); + + if (i == j) { + if (libraryResult != 0) { + errors++; + System.err.printf("Value 0x%x did not compare as " + + "an unsigned equal to itself; got %d%n", + i, libraryResult); + } + } + + if (Long.signum(libraryResult) != Long.signum(localResult)) { + errors++; + System.err.printf("Unsigned compare of 0x%x to 0x%x%n:" + + "\texpected sign of %d, got %d%n", + i, j, localResult, libraryResult); + } + + if (Long.signum(libraryResult) != + -Long.signum(libraryResultRev)) { + errors++; + System.err.printf("signum(compareUnsigned(x, y)) != -signum(compareUnsigned(y,x))" + + " for \t0x%x and 0x%x, computed %d and %d%n", + i, j, libraryResult, libraryResultRev); + } + } + } + + return errors; + } + + private static int compUnsigned(long x, long y) { + BigInteger big_x = toUnsignedBigInt(x); + BigInteger big_y = toUnsignedBigInt(y); + + return big_x.compareTo(big_y); + } + + private static BigInteger toUnsignedBigInt(long x) { + if (x >= 0) + return BigInteger.valueOf(x); + else { + int upper = (int)(((long)x) >> 32); + int lower = (int) x; + + BigInteger bi = // (upper << 32) + lower + (BigInteger.valueOf(Integer.toUnsignedLong(upper))).shiftLeft(32). + add(BigInteger.valueOf(Integer.toUnsignedLong(lower))); + + // System.out.printf("%n\t%d%n\t%s%n", x, bi.toString()); + return bi; + } + } + + private static int testToStringUnsigned() { + int errors = 0; + + long[] data = { + 0L, + 1L, + 2L, + 3L, + 99999L, + 100000L, + 999999L, + 100000L, + 999999999L, + 1000000000L, + 0x1234_5678L, + 0x8000_0000L, + 0x8000_0001L, + 0x8000_0002L, + 0x8000_0003L, + 0x8765_4321L, + 0xFFFF_FFFEL, + 0xFFFF_FFFFL, + + // Long-range values + 999_999_999_999L, + 1_000_000_000_000L, + + 999_999_999_999_999_999L, + 1_000_000_000_000_000_000L, + + 0xFFFF_FFFF_FFFF_FFFEL, + 0xFFFF_FFFF_FFFF_FFFFL, + }; + + for(int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) { + for(long datum : data) { + String result1 = Long.toUnsignedString(datum, radix); + String result2 = toUnsignedBigInt(datum).toString(radix); + + if (!result1.equals(result2)) { + errors++; + System.err.printf("Unexpected string difference converting 0x%x:" + + "\t%s %s%n", + datum, result1, result2); + } + + if (radix == 10) { + String result3 = Long.toUnsignedString(datum); + if (!result2.equals(result3)) { + errors++; + System.err.printf("Unexpected string difference converting 0x%x:" + + "\t%s %s%n", + datum, result3, result2); + } + } + + long parseResult = Long.parseUnsignedLong(result1, radix); + + if (parseResult != datum) { + errors++; + System.err.printf("Bad roundtrip conversion of %d in base %d" + + "\tconverting back ''%s'' resulted in %d%n", + datum, radix, result1, parseResult); + } + } + } + + return errors; + } + + private static int testParseUnsignedLong() { + int errors = 0; + long maxUnsignedInt = Integer.toUnsignedLong(0xffff_ffff); + + // Values include those between signed Long.MAX_VALUE and + // unsignted Long MAX_VALUE. + BigInteger[] inRange = { + BigInteger.valueOf(0L), + BigInteger.valueOf(1L), + BigInteger.valueOf(10L), + BigInteger.valueOf(2147483646L), // Integer.MAX_VALUE - 1 + BigInteger.valueOf(2147483647L), // Integer.MAX_VALUE + BigInteger.valueOf(2147483648L), // Integer.MAX_VALUE + 1 + + BigInteger.valueOf(maxUnsignedInt - 1L), + BigInteger.valueOf(maxUnsignedInt), + + BigInteger.valueOf(Long.MAX_VALUE - 1L), + BigInteger.valueOf(Long.MAX_VALUE), + BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE), + + TWO.pow(64).subtract(BigInteger.ONE) + }; + + for(BigInteger value : inRange) { + for(int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) { + String bigString = value.toString(radix); + long longResult = Long.parseUnsignedLong(bigString, radix); + + if (!toUnsignedBigInt(longResult).equals(value)) { + errors++; + System.err.printf("Bad roundtrip conversion of %d in base %d" + + "\tconverting back ''%s'' resulted in %d%n", + value, radix, bigString, longResult); + } + } + } + + String[] outOfRange = { + null, + "", + "-1", + TWO.pow(64).toString(), + }; + + for(String s : outOfRange) { + try { + long result = Long.parseUnsignedLong(s); + errors++; // Should not reach here + System.err.printf("Unexpected got %d from an unsigned conversion of %s", + result, s); + } catch(NumberFormatException nfe) { + ; // Correct result + } + } + + return errors; + } + + private static int testDivideAndRemainder() { + int errors = 0; + long MAX_UNSIGNED_INT = Integer.toUnsignedLong(0xffff_ffff); + + BigInteger[] inRange = { + BigInteger.valueOf(0L), + BigInteger.valueOf(1L), + BigInteger.valueOf(10L), + BigInteger.valueOf(2147483646L), // Integer.MAX_VALUE - 1 + BigInteger.valueOf(2147483647L), // Integer.MAX_VALUE + BigInteger.valueOf(2147483648L), // Integer.MAX_VALUE + 1 + + BigInteger.valueOf(MAX_UNSIGNED_INT - 1L), + BigInteger.valueOf(MAX_UNSIGNED_INT), + + BigInteger.valueOf(Long.MAX_VALUE - 1L), + BigInteger.valueOf(Long.MAX_VALUE), + BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE), + + TWO.pow(64).subtract(BigInteger.ONE) + }; + + for(BigInteger dividend : inRange) { + for(BigInteger divisor : inRange) { + long quotient; + BigInteger longQuotient; + + long remainder; + BigInteger longRemainder; + + if (divisor.equals(BigInteger.ZERO)) { + try { + quotient = Long.divideUnsigned(dividend.longValue(), divisor.longValue()); + errors++; + } catch(ArithmeticException ea) { + ; // Expected + } + + try { + remainder = Long.remainderUnsigned(dividend.longValue(), divisor.longValue()); + errors++; + } catch(ArithmeticException ea) { + ; // Expected + } + } else { + quotient = Long.divideUnsigned(dividend.longValue(), divisor.longValue()); + longQuotient = dividend.divide(divisor); + + if (quotient != longQuotient.longValue()) { + errors++; + System.err.printf("Unexpected unsigned divide result %s on %s/%s%n", + Long.toUnsignedString(quotient), + Long.toUnsignedString(dividend.longValue()), + Long.toUnsignedString(divisor.longValue())); + } + + remainder = Long.remainderUnsigned(dividend.longValue(), divisor.longValue()); + longRemainder = dividend.remainder(divisor); + + if (remainder != longRemainder.longValue()) { + errors++; + System.err.printf("Unexpected unsigned remainder result %s on %s%%%s%n", + Long.toUnsignedString(remainder), + Long.toUnsignedString(dividend.longValue()), + Long.toUnsignedString(divisor.longValue())); + } + } + } + } + + return errors; + } +} diff -r fc06525cb345 -r 5561a4c99825 jdk/test/java/text/Format/DateFormat/Bug7130335.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/text/Format/DateFormat/Bug7130335.java Thu Feb 09 23:17:22 2012 -0800 @@ -0,0 +1,66 @@ +/* + * 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 7130335 + * @summary Make sure that round-trip conversion (format/parse) works + * with old timestamps in Europe/Moscow. + */ +import java.text.*; +import java.util.*; + +public class Bug7130335 { + private static final TimeZone MOSCOW = TimeZone.getTimeZone("Europe/Moscow"); + + public static void main(String[] args) throws Exception { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z", Locale.US); + sdf.setTimeZone(MOSCOW); + Calendar cal = new GregorianCalendar(MOSCOW); + cal.clear(); + // Try both +03:00 and +02:00 + cal.set(1922, Calendar.SEPTEMBER, 30); + test(sdf, cal); + cal.add(Calendar.DAY_OF_YEAR, 1); + test(sdf, cal); + cal.set(1991, Calendar.MARCH, 31); + // in daylight saving time + test(sdf, cal); + cal.add(Calendar.DAY_OF_YEAR, 1); + test(sdf, cal); + // Try the current timestamp + cal.setTimeInMillis(System.currentTimeMillis()); + test(sdf, cal); + } + + private static void test(SimpleDateFormat sdf, Calendar cal) throws Exception { + Date d = cal.getTime(); + String f = sdf.format(d); + System.out.println(f); + Date pd = sdf.parse(f); + String p = sdf.format(pd); + if (!d.equals(pd) || !f.equals(p)) { + throw new RuntimeException("format: " + f + ", parse: " + p); + } + } +} diff -r fc06525cb345 -r 5561a4c99825 jdk/test/java/util/Calendar/Bug7017458.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/util/Calendar/Bug7017458.java Thu Feb 09 23:17:22 2012 -0800 @@ -0,0 +1,125 @@ +/* + * 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 7017458 + * @summary Test of multithreaded serialization/deserialization of Calendar. + */ + +import java.io.*; +import java.util.Calendar; + +public class Bug7017458 { + + static volatile boolean err = false; + + public static void main(String[] args) { + try { + new Bug7017458().perform(); + } + catch (Exception e) { + e.printStackTrace(); + err = true; + } + + if (err) { + throw new RuntimeException("Multithreaded serialization/deserialization test failed."); + } else { + System.out.println("Multithreaded serialization/deserialization test passed."); + } + } + + public void perform() throws Exception { + int nbThreads = 8; + Calendar cal = Calendar.getInstance(); + SerializationThread[] threads = new SerializationThread[nbThreads]; + for (int i = 0; i < nbThreads; i++) { + threads[i] = new SerializationThread(cal); + } + for (int i = 0; i < nbThreads; i++) { + threads[i].start(); + } + for (int i = 0; i < nbThreads; i++) { + threads[i].join(); + } + + DeserializationThread[] threads2 = new DeserializationThread[nbThreads]; + for (int i = 0; i < nbThreads; i++) { + threads2[i] = new DeserializationThread(threads[i].data); + } + for (int i = 0; i < nbThreads; i++) { + threads2[i].start(); + } + for (int i = 0; i < nbThreads; i++) { + threads2[i].join(); + } + } + + public class SerializationThread extends Thread { + private Calendar cal; + public byte[] data; + + public SerializationThread(Calendar cal) { + this.cal = cal; + } + + public void run() { + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(cal); + oos.flush(); + oos.close(); + data = baos.toByteArray(); + } + catch (Exception e) { + e.printStackTrace(); + err = true; + } + } + } + + public class DeserializationThread extends Thread { + public Calendar cal; + public byte[] data; + + public DeserializationThread(byte[] data) { + this.data = data; + } + + public void run() { + try { + ByteArrayInputStream bais = new ByteArrayInputStream(data); + ObjectInputStream ois = new ObjectInputStream(bais); + cal = (Calendar) ois.readObject(); + ois.close(); + } + catch (Exception e) { + e.printStackTrace(); + err = true; + } + } + } +} + diff -r fc06525cb345 -r 5561a4c99825 jdk/test/java/util/Currency/tablea1.txt --- a/jdk/test/java/util/Currency/tablea1.txt Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/test/java/util/Currency/tablea1.txt Thu Feb 09 23:17:22 2012 -0800 @@ -1,12 +1,12 @@ # # -# Based on BSi's ISO4217 data - "TABLE A1.doc" + amendments up until MA151.doc -# (As of 7 April 2011) +# Based on BSi's ISO4217 data - "TABLE A1.doc" + amendments up until MA153.doc +# (As of 12 January 2012) # # Version FILEVERSION=1 -DATAVERSION=151 +DATAVERSION=153 # ISO 4217 currency data AF AFN 971 2 @@ -267,7 +267,7 @@ UZ UZS 860 2 VU VUV 548 0 VE VEF 937 2 -VN VND 704 2 +VN VND 704 0 VG USD 840 2 VI USD 840 2 WF XPF 953 0 diff -r fc06525cb345 -r 5561a4c99825 jdk/test/java/util/EnumMap/UniqueNullValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/util/EnumMap/UniqueNullValue.java Thu Feb 09 23:17:22 2012 -0800 @@ -0,0 +1,60 @@ +/* + * 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. + */ + +/* + * Portions Copyright (c) 2012, IBM Corporation + */ + +/* + * @test + * @bug 7123229 + * @summary (coll) EnumMap.containsValue(null) returns true + * @author ngmr + */ + +import java.util.EnumMap; +import java.util.Map; + +public class UniqueNullValue { + static enum TestEnum { e00, e01 } + + public static void main(String[] args) { + Map map = new EnumMap<>(TestEnum.class); + + map.put(TestEnum.e00, 0); + if (false == map.containsValue(0)) { + throw new RuntimeException("EnumMap unexpectedly missing 0 value"); + } + if (map.containsValue(null)) { + throw new RuntimeException("EnumMap unexpectedly holds null value"); + } + + map.put(TestEnum.e00, null); + if (map.containsValue(0)) { + throw new RuntimeException("EnumMap unexpectedly holds 0 value"); + } + if (false == map.containsValue(null)) { + throw new RuntimeException("EnumMap unexpectedly missing null value"); + } + } +} diff -r fc06525cb345 -r 5561a4c99825 jdk/test/java/util/concurrent/FutureTask/DoneTimedGetLoops.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/util/concurrent/FutureTask/DoneTimedGetLoops.java Thu Feb 09 23:17:22 2012 -0800 @@ -0,0 +1,163 @@ +/* + * 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. + */ + +/* + * Written by Martin Buchholz with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* + * @test + * @run main DoneTimedGetLoops 300 + * @summary isDone returning true guarantees that subsequent timed get + * will never throw TimeoutException. + */ + +import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.*; + +@SuppressWarnings({"unchecked", "rawtypes", "deprecation"}) +public class DoneTimedGetLoops { + final long testDurationMillisDefault = 10L * 1000L; + final long testDurationMillis; + + static class PublicFutureTask extends FutureTask { + final static Runnable noop = new Runnable() { public void run() {} }; + PublicFutureTask() { super(noop, null); } + public void set(Boolean v) { super.set(v); } + public void setException(Throwable t) { super.setException(t); } + } + + DoneTimedGetLoops(String[] args) { + testDurationMillis = (args.length > 0) ? + Long.valueOf(args[0]) : testDurationMillisDefault; + } + + void test(String[] args) throws Throwable { + final long testDurationNanos = testDurationMillis * 1000L * 1000L; + final long quittingTimeNanos = System.nanoTime() + testDurationNanos; + final long timeoutMillis = 10L * 1000L; + + final AtomicReference normalRef + = new AtomicReference(); + final AtomicReference abnormalRef + = new AtomicReference(); + + final Throwable throwable = new Throwable(); + + abstract class CheckedThread extends Thread { + CheckedThread(String name) { + super(name); + setDaemon(true); + start(); + } + /** Polls for quitting time. */ + protected boolean quittingTime() { + return System.nanoTime() - quittingTimeNanos > 0; + } + /** Polls occasionally for quitting time. */ + protected boolean quittingTime(long i) { + return (i % 1024) == 0 && quittingTime(); + } + abstract protected void realRun() throws Exception; + public void run() { + try { realRun(); } catch (Throwable t) { unexpected(t); } + } + } + + Thread setter = new CheckedThread("setter") { + protected void realRun() { + while (! quittingTime()) { + PublicFutureTask future = new PublicFutureTask(); + normalRef.set(future); + future.set(Boolean.TRUE); + }}}; + + Thread setterException = new CheckedThread("setterException") { + protected void realRun() { + while (! quittingTime()) { + PublicFutureTask future = new PublicFutureTask(); + abnormalRef.set(future); + future.setException(throwable); + }}}; + + Thread doneTimedGetNormal = new CheckedThread("doneTimedGetNormal") { + protected void realRun() throws Exception { + while (! quittingTime()) { + PublicFutureTask future = normalRef.get(); + if (future != null) { + while (!future.isDone()) + ; + check(future.get(0L, TimeUnit.HOURS) == Boolean.TRUE); + }}}}; + + Thread doneTimedGetAbnormal = new CheckedThread("doneTimedGetAbnormal") { + protected void realRun() throws Exception { + while (! quittingTime()) { + PublicFutureTask future = abnormalRef.get(); + if (future != null) { + while (!future.isDone()) + ; + try { future.get(0L, TimeUnit.HOURS); fail(); } + catch (ExecutionException t) { + check(t.getCause() == throwable); + } + }}}}; + + for (Thread thread : new Thread[] { + setter, + setterException, + doneTimedGetNormal, + doneTimedGetAbnormal }) { + thread.join(timeoutMillis + testDurationMillis); + if (thread.isAlive()) { + System.err.printf("Hung thread: %s%n", thread.getName()); + failed++; + for (StackTraceElement e : thread.getStackTrace()) + System.err.println(e); + // Kludge alert + thread.stop(); + thread.join(timeoutMillis); + } + } + } + + //--------------------- Infrastructure --------------------------- + volatile int passed = 0, failed = 0; + void pass() {passed++;} + void fail() {failed++; Thread.dumpStack();} + void fail(String msg) {System.err.println(msg); fail();} + void unexpected(Throwable t) {failed++; t.printStackTrace();} + void check(boolean cond) {if (cond) pass(); else fail();} + void equal(Object x, Object y) { + if (x == null ? y == null : x.equals(y)) pass(); + else fail(x + " not equal to " + y);} + public static void main(String[] args) throws Throwable { + new DoneTimedGetLoops(args).instanceMain(args);} + 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 fc06525cb345 -r 5561a4c99825 jdk/test/java/util/concurrent/FutureTask/ExplicitSet.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/util/concurrent/FutureTask/ExplicitSet.java Thu Feb 09 23:17:22 2012 -0800 @@ -0,0 +1,87 @@ +/* + * 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 7132378 + * @summary Race in FutureTask if used with explicit set ( not Runnable ) + * @author Chris Hegarty + */ + +import java.util.concurrent.Callable; +import java.util.concurrent.FutureTask; + +public class ExplicitSet { + + static void realMain(String[] args) throws Throwable { + for (int i = 1; i <= 10000; i++) { + //System.out.print("."); + test(); + } + } + + static void test() throws Throwable { + final SettableTask task = new SettableTask(); + + Thread thread = new Thread() { public void run() { + try { + check(task.get() != null); + } catch (Exception e) { unexpected(e); } + }}; + thread.start(); + + task.set(Boolean.TRUE); + thread.join(5000); + } + + static class SettableTask extends FutureTask { + SettableTask() { + super(new Callable() { + public Boolean call() { + fail ("The task should never be run!"); + return null; + }; + }); + } + + @Override + public void set(Boolean b) { + super.set(b); + } + } + + //--------------------- Infrastructure --------------------------- + static volatile int passed = 0, failed = 0; + static void pass() {passed++;} + static void fail() {failed++; Thread.dumpStack();} + static void fail(String msg) {System.out.println(msg); fail();} + static void unexpected(Throwable t) {failed++; t.printStackTrace();} + static void check(boolean cond) {if (cond) pass(); else fail();} + static void equal(Object x, Object y) { + if (x == null ? y == null : x.equals(y)) pass(); + else fail(x + " not equal to " + y);} + public static void main(String[] args) throws Throwable { + try {realMain(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 fc06525cb345 -r 5561a4c99825 jdk/test/javax/xml/crypto/dsig/KeySelectors.java --- a/jdk/test/javax/xml/crypto/dsig/KeySelectors.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/test/javax/xml/crypto/dsig/KeySelectors.java Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2007, 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 @@ -22,7 +22,9 @@ */ import java.io.*; -import java.security.*; +import java.security.Key; +import java.security.KeyException; +import java.security.PublicKey; import java.security.cert.*; import java.util.*; import javax.crypto.SecretKey; @@ -76,7 +78,7 @@ } public byte[] getEncoded() { - return (byte[]) bytes.clone(); + return bytes.clone(); } }; } @@ -196,9 +198,9 @@ * matching public key. */ static class CollectionKeySelector extends KeySelector { - private CertificateFactory certFac; + private CertificateFactory cf; private File certDir; - private Vector certs; + private Vector certs; private static final int MATCH_SUBJECT = 0; private static final int MATCH_ISSUER = 1; private static final int MATCH_SERIAL = 2; @@ -208,24 +210,24 @@ CollectionKeySelector(File dir) { certDir = dir; try { - certFac = CertificateFactory.getInstance("X509"); + cf = CertificateFactory.getInstance("X509"); } catch (CertificateException ex) { // not going to happen } - certs = new Vector(); + certs = new Vector(); File[] files = new File(certDir, "certs").listFiles(); for (int i = 0; i < files.length; i++) { - try { - certs.add(certFac.generateCertificate - (new FileInputStream(files[i]))); + try (FileInputStream fis = new FileInputStream(files[i])) { + certs.add((X509Certificate)cf.generateCertificate(fis)); } catch (Exception ex) { } } } - Vector match(int matchType, Object value, Vector pool) { - Vector matchResult = new Vector(); + Vector match(int matchType, Object value, + Vector pool) { + Vector matchResult = new Vector<>(); for (int j=0; j < pool.size(); j++) { - X509Certificate c = (X509Certificate) pool.get(j); + X509Certificate c = pool.get(j); switch (matchType) { case MATCH_SUBJECT: try { @@ -286,19 +288,18 @@ if (xmlStructure instanceof KeyName) { String name = ((KeyName)xmlStructure).getName(); PublicKey pk = null; - try { + File certFile = new File(new File(certDir, "certs"), + name.toLowerCase() + ".crt"); + try (FileInputStream fis = new FileInputStream(certFile)) { // Lookup the public key using the key name 'Xxx', // i.e. the public key is in "certs/xxx.crt". - File certFile = new File(new File(certDir, "certs"), - name.toLowerCase()+".crt"); X509Certificate cert = (X509Certificate) - certFac.generateCertificate - (new FileInputStream(certFile)); + cf.generateCertificate(fis); pk = cert.getPublicKey(); } catch (FileNotFoundException e) { // assume KeyName contains subject DN and search // collection of certs for match - Vector result = + Vector result = match(MATCH_SUBJECT, name, certs); int numOfMatches = (result==null? 0:result.size()); if (numOfMatches != 1) { @@ -306,7 +307,7 @@ ((numOfMatches==0?"No":"More than one") + " match found"); } - pk =((X509Certificate)result.get(0)).getPublicKey(); + pk = result.get(0).getPublicKey(); } return new SimpleKSResult(pk); } else if (xmlStructure instanceof RetrievalMethod) { @@ -316,10 +317,12 @@ String type = rm.getType(); if (type.equals(X509Data.RAW_X509_CERTIFICATE_TYPE)) { String uri = rm.getURI(); - X509Certificate cert = (X509Certificate) - certFac.generateCertificate - (new FileInputStream(new File(certDir, uri))); - return new SimpleKSResult(cert.getPublicKey()); + try (FileInputStream fis = + new FileInputStream(new File(certDir, uri))) { + X509Certificate cert = (X509Certificate) + cf.generateCertificate(fis); + return new SimpleKSResult(cert.getPublicKey()); + } } else { throw new KeySelectorException ("Unsupported RetrievalMethod type"); @@ -327,7 +330,7 @@ } else if (xmlStructure instanceof X509Data) { List content = ((X509Data)xmlStructure).getContent(); int size = content.size(); - Vector result = null; + Vector result = null; // Lookup the public key using the information // specified in X509Data element, i.e. searching // over the collection of certificate files under @@ -357,8 +360,7 @@ ((numOfMatches==0?"No":"More than one") + " match found"); } - return new SimpleKSResult(((X509Certificate) - result.get(0)).getPublicKey()); + return new SimpleKSResult(result.get(0).getPublicKey()); } } catch (Exception ex) { throw new KeySelectorException(ex); diff -r fc06525cb345 -r 5561a4c99825 jdk/test/javax/xml/crypto/dsig/ValidationTests.java --- a/jdk/test/javax/xml/crypto/dsig/ValidationTests.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/test/javax/xml/crypto/dsig/ValidationTests.java Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2009, 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 @@ -23,7 +23,7 @@ /** * @test - * @bug 4635230 6365103 6366054 6824440 + * @bug 4635230 6365103 6366054 6824440 7131084 * @summary Basic unit tests for validating XML Signatures with JSR 105 * @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java * X509KeySelector.java ValidationTests.java @@ -43,10 +43,6 @@ import javax.xml.crypto.dsig.XMLSignatureException; import javax.xml.crypto.dsig.XMLSignatureFactory; -/** - * This is a testcase to validate all "merlin-xmldsig-twenty-three" - * testcases from Baltimore - */ public class ValidationTests { private static SignatureValidator validator; @@ -61,25 +57,14 @@ private final static String STYLESHEET_B64 = "http://www.w3.org/Signature/2002/04/xml-stylesheet.b64"; - private final static String[] FILES = { - "signature-enveloped-dsa.xml", - "signature-enveloping-b64-dsa.xml", - "signature-enveloping-dsa.xml", - "signature-enveloping-rsa.xml", - "signature-enveloping-hmac-sha1.xml", - "signature-external-dsa.xml", - "signature-external-b64-dsa.xml", - "signature-retrievalmethod-rawx509crt.xml", - "signature-keyname.xml", - "signature-x509-crt-crl.xml", - "signature-x509-crt.xml", - "signature-x509-is.xml", - "signature-x509-ski.xml", - "signature-x509-sn.xml", -// "signature.xml", - "exc-signature.xml", - "sign-spec.xml" - }; + static class Test { + String file; + KeySelector ks; + Test(String file, KeySelector ks) { + this.file = file; + this.ks = ks; + } + } static KeySelector skks; static { @@ -98,26 +83,34 @@ private final static KeySelector RXKS = new KeySelectors.RawX509KeySelector(); private final static KeySelector XKS = null; - private final static KeySelector[] KEY_SELECTORS = { - KVKS, - KVKS, - KVKS, - KVKS, - SKKS, - KVKS, - KVKS, - CKS, - CKS, - RXKS, - RXKS, - CKS, - CKS, - CKS, -// XKS, - KVKS, - RXKS + private static URIDereferencer httpUd = null; + + private final static Test[] VALID_TESTS = { + new Test("signature-enveloped-dsa.xml", KVKS), + new Test("signature-enveloping-b64-dsa.xml", KVKS), + new Test("signature-enveloping-dsa.xml", KVKS), + new Test("signature-enveloping-rsa.xml", KVKS), + new Test("signature-enveloping-hmac-sha1.xml", SKKS), + new Test("signature-external-dsa.xml", KVKS), + new Test("signature-external-b64-dsa.xml", KVKS), + new Test("signature-retrievalmethod-rawx509crt.xml", CKS), + new Test("signature-keyname.xml", CKS), + new Test("signature-x509-crt-crl.xml", RXKS), + new Test("signature-x509-crt.xml", RXKS), + new Test("signature-x509-is.xml", CKS), + new Test("signature-x509-ski.xml", CKS), + new Test("signature-x509-sn.xml", CKS), + new Test("signature.xml", XKS), + new Test("exc-signature.xml", KVKS), + new Test("sign-spec.xml", RXKS), + new Test("xmldsig-xfilter2.xml", KVKS) }; - private static URIDereferencer httpUd = null; + + private final static Test[] INVALID_TESTS = { + new Test("signature-enveloping-hmac-sha1-40.xml", SKKS), + new Test("signature-enveloping-hmac-sha1-trunclen-0-attack.xml", SKKS), + new Test("signature-enveloping-hmac-sha1-trunclen-8-attack.xml", SKKS) + }; public static void main(String args[]) throws Exception { httpUd = new HttpURIDereferencer(); @@ -125,9 +118,9 @@ validator = new SignatureValidator(new File(DATA_DIR)); boolean atLeastOneFailed = false; - for (int i=0; i < FILES.length; i++) { - System.out.println("Validating " + FILES[i]); - if (test_signature(FILES[i], KEY_SELECTORS[i])) { + for (Test test : VALID_TESTS) { + System.out.println("Validating " + test.file); + if (test_signature(test)) { System.out.println("PASSED"); } else { System.out.println("FAILED"); @@ -136,41 +129,23 @@ } // test with reference caching enabled System.out.println("Validating sign-spec.xml with caching enabled"); - if (test_signature("sign-spec.xml", RXKS, true)) { + if (test_signature(new Test("sign-spec.xml", RXKS), true)) { System.out.println("PASSED"); } else { System.out.println("FAILED"); atLeastOneFailed = true; } - System.out.println("Validating signature-enveloping-hmac-sha1-40.xml"); - try { - test_signature("signature-enveloping-hmac-sha1-40.xml", SKKS, false); - System.out.println("FAILED"); - atLeastOneFailed = true; - } catch (XMLSignatureException xse) { - System.out.println(xse.getMessage()); - System.out.println("PASSED"); - } - - System.out.println("Validating signature-enveloping-hmac-sha1-trunclen-0-attack.xml"); - try { - test_signature("signature-enveloping-hmac-sha1-trunclen-0-attack.xml", SKKS, false); - System.out.println("FAILED"); - atLeastOneFailed = true; - } catch (XMLSignatureException xse) { - System.out.println(xse.getMessage()); - System.out.println("PASSED"); - } - - System.out.println("Validating signature-enveloping-hmac-sha1-trunclen-8-attack.xml"); - try { - test_signature("signature-enveloping-hmac-sha1-trunclen-8-attack.xml", SKKS, false); - System.out.println("FAILED"); - atLeastOneFailed = true; - } catch (XMLSignatureException xse) { - System.out.println(xse.getMessage()); - System.out.println("PASSED"); + for (Test test : INVALID_TESTS) { + System.out.println("Validating " + test.file); + try { + test_signature(test); + System.out.println("FAILED"); + atLeastOneFailed = true; + } catch (XMLSignatureException xse) { + System.out.println(xse.getMessage()); + System.out.println("PASSED"); + } } if (atLeastOneFailed) { @@ -179,20 +154,21 @@ } } - public static boolean test_signature(String file, KeySelector ks) - throws Exception { - return test_signature(file, ks, false); + public static boolean test_signature(Test test) throws Exception { + return test_signature(test, false); } - public static boolean test_signature(String file, KeySelector ks, - boolean cache) throws Exception { - if (ks == null) { + public static boolean test_signature(Test test, boolean cache) + throws Exception + { + if (test.ks == null) { KeyStore keystore = KeyStore.getInstance("JKS"); - keystore.load - (new FileInputStream(KEYSTORE), "changeit".toCharArray()); - ks = new X509KeySelector(keystore, false); + try (FileInputStream fis = new FileInputStream(KEYSTORE)) { + keystore.load(fis, "changeit".toCharArray()); + test.ks = new X509KeySelector(keystore, false); + } } - return validator.validate(file, ks, httpUd, cache); + return validator.validate(test.file, test.ks, httpUd, cache); } /** diff -r fc06525cb345 -r 5561a4c99825 jdk/test/javax/xml/crypto/dsig/X509KeySelector.java --- a/jdk/test/javax/xml/crypto/dsig/X509KeySelector.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/test/javax/xml/crypto/dsig/X509KeySelector.java Thu Feb 09 23:17:22 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 @@ -205,9 +205,9 @@ */ private KeySelectorResult keyStoreSelect(CertSelector cs) throws KeyStoreException { - Enumeration aliases = ks.aliases(); + Enumeration aliases = ks.aliases(); while (aliases.hasMoreElements()) { - String alias = (String) aliases.nextElement(); + String alias = aliases.nextElement(); Certificate cert = ks.getCertificate(alias); if (cert != null && cs.match(cert)) { return new SimpleKeySelectorResult(cert.getPublicKey()); @@ -301,7 +301,7 @@ } catch (IOException ioe) { throw new KeySelectorException(ioe); } - Collection certs = new ArrayList(); + Collection certs = new ArrayList<>(); Iterator xi = xd.getContent().iterator(); while (xi.hasNext()) { @@ -345,7 +345,7 @@ System.arraycopy(ski, 0, encodedSki, 2, ski.length); subjectcs.setSubjectKeyIdentifier(encodedSki); } else if (o instanceof X509Certificate) { - certs.add((X509Certificate) o); + certs.add((X509Certificate)o); // check X509CRL // not supported: should use CertPath API } else { @@ -359,9 +359,7 @@ } if (!certs.isEmpty() && !trusted) { // try to find public key in certs in X509Data - Iterator i = certs.iterator(); - while (i.hasNext()) { - X509Certificate cert = (X509Certificate) i.next(); + for (X509Certificate cert : certs) { if (subjectcs.match(cert)) { return new SimpleKeySelectorResult(cert.getPublicKey()); } diff -r fc06525cb345 -r 5561a4c99825 jdk/test/javax/xml/crypto/dsig/data/xmldsig-xfilter2.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/crypto/dsig/data/xmldsig-xfilter2.xml Thu Feb 09 23:17:22 2012 -0800 @@ -0,0 +1,7 @@ + //FooBar //NotToBeSigned //ReallyToBeSigned 6S7pEM13ZCDvVUbP9XB8iRWFbAI= / 2jmj7l5rSw0yVb/vlWAYkK/YBwk=cJBwfPGWSI9CiuFinTvWJLbF8bGVK5SRB/N/NjCM5IMxakBjra+KSg==

    /X9TgR11EilS30qcLuzk5/YRt1I870QAwx4/gLZRJmlFXUAiUftZPY1Y+r/F9bow9subVWzXgTuA +HTRv8mZgt2uZUKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fGqKYVDwT7g/bTxR7DAjVUE1oWkTL2dfOu +K2HXKu/yIgMZndFIAcc=

    l2BQjxUjC8yykrmCouuEC/BYHPU=9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3 +zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKL +Zl6Ae1UlZAFMO/7PSSo=5LRac3QkDCDOPaeNF5dJQ2r0hgIWZomZV7Z9pHrRqMoepJD5xnJpJY7aA4eUSS+AHS1qOm5I6VTZ +68hsOdPZCDFF/DiR38BzTxi4ZD0PhtmOjBh32lSNG1nhEq6e9RsyzhUw5FVYHAPnCx2bX4/8Rz8i +EMuG0IcCiAbbzsCfGBw= \ No newline at end of file diff -r fc06525cb345 -r 5561a4c99825 jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/EngineArgs/DebugReportsOneExtraByte.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/EngineArgs/DebugReportsOneExtraByte.java Thu Feb 09 23:17:22 2012 -0800 @@ -0,0 +1,401 @@ +/* + * Copyright (c) 2003, 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. + */ + +/* + * test + * @bug 7126889 + * @summary Incorrect SSLEngine debug output + * + * Debug output was reporting n+1 bytes of data was written when it was + * really was n. + * + * SunJSSE does not support dynamic system properties, no way to re-use + * system properties in samevm/agentvm mode. + */ + +/** + * A SSLEngine usage example which simplifies the presentation + * by removing the I/O and multi-threading concerns. + * + * The test creates two SSLEngines, simulating a client and server. + * The "transport" layer consists two byte buffers: think of them + * as directly connected pipes. + * + * Note, this is a *very* simple example: real code will be much more + * involved. For example, different threading and I/O models could be + * used, transport mechanisms could close unexpectedly, and so on. + * + * When this application runs, notice that several messages + * (wrap/unwrap) pass before any application data is consumed or + * produced. (For more information, please see the SSL/TLS + * specifications.) There may several steps for a successful handshake, + * so it's typical to see the following series of operations: + * + * client server message + * ====== ====== ======= + * wrap() ... ClientHello + * ... unwrap() ClientHello + * ... wrap() ServerHello/Certificate + * unwrap() ... ServerHello/Certificate + * wrap() ... ClientKeyExchange + * wrap() ... ChangeCipherSpec + * wrap() ... Finished + * ... unwrap() ClientKeyExchange + * ... unwrap() ChangeCipherSpec + * ... unwrap() Finished + * ... wrap() ChangeCipherSpec + * ... wrap() Finished + * unwrap() ... ChangeCipherSpec + * unwrap() ... Finished + */ + +import javax.net.ssl.*; +import javax.net.ssl.SSLEngineResult.*; +import java.io.*; +import java.security.*; +import java.nio.*; + +public class DebugReportsOneExtraByte { + + /* + * Enables logging of the SSLEngine operations. + */ + private static boolean logging = true; + + /* + * Enables the JSSE system debugging system property: + * + * -Djavax.net.debug=all + * + * This gives a lot of low-level information about operations underway, + * including specific handshake messages, and might be best examined + * after gaining some familiarity with this application. + */ + private static boolean debug = false; + + private SSLContext sslc; + + private SSLEngine clientEngine; // client Engine + private ByteBuffer clientOut; // write side of clientEngine + private ByteBuffer clientIn; // read side of clientEngine + + private SSLEngine serverEngine; // server Engine + private ByteBuffer serverOut; // write side of serverEngine + private ByteBuffer serverIn; // read side of serverEngine + + /* + * For data transport, this example uses local ByteBuffers. This + * isn't really useful, but the purpose of this example is to show + * SSLEngine concepts, not how to do network transport. + */ + private ByteBuffer cTOs; // "reliable" transport client->server + private ByteBuffer sTOc; // "reliable" transport server->client + + /* + * The following is to set up the keystores. + */ + private static String pathToStores = "../../../../../../../etc"; + private static String keyStoreFile = "keystore"; + private static String trustStoreFile = "truststore"; + private static String passwd = "passphrase"; + + private static String keyFilename = + System.getProperty("test.src", ".") + "/" + pathToStores + + "/" + keyStoreFile; + private static String trustFilename = + System.getProperty("test.src", ".") + "/" + pathToStores + + "/" + trustStoreFile; + + /* + * Main entry point for this test. + */ + public static void main(String args[]) throws Exception { + if (debug) { + System.setProperty("javax.net.debug", "all"); + } + + DebugReportsOneExtraByte test = new DebugReportsOneExtraByte(); + test.runTest(); + + System.out.println("Test Passed."); + } + + /* + * Create an initialized SSLContext to use for these tests. + */ + public DebugReportsOneExtraByte() throws Exception { + + KeyStore ks = KeyStore.getInstance("JKS"); + KeyStore ts = KeyStore.getInstance("JKS"); + + char[] passphrase = "passphrase".toCharArray(); + + ks.load(new FileInputStream(keyFilename), passphrase); + ts.load(new FileInputStream(trustFilename), passphrase); + + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + kmf.init(ks, passphrase); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); + tmf.init(ts); + + SSLContext sslCtx = SSLContext.getInstance("TLS"); + + sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + + sslc = sslCtx; + } + + /* + * Run the test. + * + * Sit in a tight loop, both engines calling wrap/unwrap regardless + * of whether data is available or not. We do this until both engines + * report back they are closed. + * + * The main loop handles all of the I/O phases of the SSLEngine's + * lifetime: + * + * initial handshaking + * application data transfer + * engine closing + * + * One could easily separate these phases into separate + * sections of code. + */ + private void runTest() throws Exception { + boolean dataDone = false; + + createSSLEngines(); + createBuffers(); + + SSLEngineResult clientResult; // results from client's last operation + SSLEngineResult serverResult; // results from server's last operation + + /* + * Examining the SSLEngineResults could be much more involved, + * and may alter the overall flow of the application. + * + * For example, if we received a BUFFER_OVERFLOW when trying + * to write to the output pipe, we could reallocate a larger + * pipe, but instead we wait for the peer to drain it. + */ + + /* + * Write one byte in first application packet, the rest + * will come later. + */ + serverOut.limit(1); + + while (!isEngineClosed(clientEngine) || + !isEngineClosed(serverEngine)) { + + log("================"); + + clientResult = clientEngine.wrap(clientOut, cTOs); + log("client wrap: ", clientResult); + runDelegatedTasks(clientResult, clientEngine); + + serverResult = serverEngine.wrap(serverOut, sTOc); + log("server wrap: ", serverResult); + runDelegatedTasks(serverResult, serverEngine); + + // Next wrap will split. + if (serverOut.position() == 1) { + serverOut.limit(serverOut.capacity()); + } + + cTOs.flip(); + sTOc.flip(); + + log("----"); + + clientResult = clientEngine.unwrap(sTOc, clientIn); + log("client unwrap: ", clientResult); + runDelegatedTasks(clientResult, clientEngine); + + serverResult = serverEngine.unwrap(cTOs, serverIn); + log("server unwrap: ", serverResult); + runDelegatedTasks(serverResult, serverEngine); + + cTOs.compact(); + sTOc.compact(); + + /* + * After we've transfered all application data between the client + * and server, we close the clientEngine's outbound stream. + * This generates a close_notify handshake message, which the + * server engine receives and responds by closing itself. + */ + if (!dataDone && (clientOut.limit() == serverIn.position()) && + (serverOut.limit() == clientIn.position())) { + + /* + * A sanity check to ensure we got what was sent. + */ + checkTransfer(serverOut, clientIn); + checkTransfer(clientOut, serverIn); + + log("\tClosing clientEngine's *OUTBOUND*..."); + clientEngine.closeOutbound(); + dataDone = true; + } + } + } + + /* + * Using the SSLContext created during object creation, + * create/configure the SSLEngines we'll use for this test. + */ + private void createSSLEngines() throws Exception { + /* + * Configure the serverEngine to act as a server in the SSL/TLS + * handshake. Also, require SSL client authentication. + */ + serverEngine = sslc.createSSLEngine(); + serverEngine.setUseClientMode(false); + serverEngine.setNeedClientAuth(true); + + // Force a block-oriented ciphersuite. + serverEngine.setEnabledCipherSuites( + new String [] {"TLS_RSA_WITH_AES_128_CBC_SHA"}); + + /* + * Similar to above, but using client mode instead. + */ + clientEngine = sslc.createSSLEngine("client", 80); + clientEngine.setUseClientMode(true); + } + + /* + * Create and size the buffers appropriately. + */ + private void createBuffers() { + + /* + * We'll assume the buffer sizes are the same + * between client and server. + */ + SSLSession session = clientEngine.getSession(); + int appBufferMax = session.getApplicationBufferSize(); + int netBufferMax = session.getPacketBufferSize(); + + /* + * We'll make the input buffers a bit bigger than the max needed + * size, so that unwrap()s following a successful data transfer + * won't generate BUFFER_OVERFLOWS. + * + * We'll use a mix of direct and indirect ByteBuffers for + * tutorial purposes only. In reality, only use direct + * ByteBuffers when they give a clear performance enhancement. + */ + clientIn = ByteBuffer.allocate(appBufferMax + 50); + serverIn = ByteBuffer.allocate(appBufferMax + 50); + + cTOs = ByteBuffer.allocateDirect(netBufferMax); + sTOc = ByteBuffer.allocateDirect(netBufferMax); + + // No need to write anything on the client side, it will + // just confuse the output. + clientOut = ByteBuffer.wrap("".getBytes()); + // 10 bytes long + serverOut = ByteBuffer.wrap("Hi Client!".getBytes()); + } + + /* + * If the result indicates that we have outstanding tasks to do, + * go ahead and run them in this thread. + */ + private static void runDelegatedTasks(SSLEngineResult result, + SSLEngine engine) throws Exception { + + if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) { + Runnable runnable; + while ((runnable = engine.getDelegatedTask()) != null) { + log("\trunning delegated task..."); + runnable.run(); + } + HandshakeStatus hsStatus = engine.getHandshakeStatus(); + if (hsStatus == HandshakeStatus.NEED_TASK) { + throw new Exception( + "handshake shouldn't need additional tasks"); + } + log("\tnew HandshakeStatus: " + hsStatus); + } + } + + private static boolean isEngineClosed(SSLEngine engine) { + return (engine.isOutboundDone() && engine.isInboundDone()); + } + + /* + * Simple check to make sure everything came across as expected. + */ + private static void checkTransfer(ByteBuffer a, ByteBuffer b) + throws Exception { + a.flip(); + b.flip(); + + if (!a.equals(b)) { + throw new Exception("Data didn't transfer cleanly"); + } else { + log("\tData transferred cleanly"); + } + + a.position(a.limit()); + b.position(b.limit()); + a.limit(a.capacity()); + b.limit(b.capacity()); + } + + /* + * Logging code + */ + private static boolean resultOnce = true; + + private static void log(String str, SSLEngineResult result) { + if (!logging) { + return; + } + if (resultOnce) { + resultOnce = false; + System.out.println("The format of the SSLEngineResult is: \n" + + "\t\"getStatus() / getHandshakeStatus()\" +\n" + + "\t\"bytesConsumed() / bytesProduced()\"\n"); + } + HandshakeStatus hsStatus = result.getHandshakeStatus(); + log(str + + result.getStatus() + "/" + hsStatus + ", " + + result.bytesConsumed() + "/" + result.bytesProduced() + + " bytes"); + if (hsStatus == HandshakeStatus.FINISHED) { + log("\t...ready for application data"); + } + } + + private static void log(String str) { + if (logging) { + System.out.println(str); + } + } +} diff -r fc06525cb345 -r 5561a4c99825 jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/EngineArgs/DebugReportsOneExtraByte.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/EngineArgs/DebugReportsOneExtraByte.sh Thu Feb 09 23:17:22 2012 -0800 @@ -0,0 +1,80 @@ +#! /bin/sh + +# +# 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. +# + +# @test +# @bug 7126889 +# @summary Incorrect SSLEngine debug output +# +# ${TESTJAVA} is pointing to the JDK under test. +# +# set platform-dependent variables + +OS=`uname -s` +case "$OS" in + SunOS ) + PS=":" + FS="/" + ;; + Linux ) + PS=":" + FS="/" + ;; + CYGWIN* ) + PS=";" + FS="/" + ;; + Windows* ) + PS=";" + FS="\\" + ;; + * ) + echo "Unrecognized system!" + exit 1; + ;; +esac + +${TESTJAVA}${FS}bin${FS}javac -d . ${TESTSRC}${FS}DebugReportsOneExtraByte.java + +STRING='main, WRITE: TLSv1 Application Data, length = 8' + +echo "Examining debug output for the string:" +echo "${STRING}" +echo "=========" + +${TESTJAVA}${FS}bin${FS}java -Djavax.net.debug=all \ + -Dtest.src=${TESTSRC} \ + DebugReportsOneExtraByte 2>&1 | \ + grep "${STRING}" +RETVAL=$? + +echo "=========" + +if [ ${RETVAL} -ne 0 ]; then + echo "Did NOT see the expected debug output." + exit 1 +else + echo "Received the expected debug output." + exit 0 +fi diff -r fc06525cb345 -r 5561a4c99825 jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/CookieHttpsClientTest.java --- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/CookieHttpsClientTest.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/CookieHttpsClientTest.java Thu Feb 09 23:17:22 2012 -0800 @@ -26,6 +26,11 @@ * @bug 7129083 * @summary Cookiemanager does not store cookies if url is read * before setting cookiemanager + * + * SunJSSE does not support dynamic system properties, no way to re-use + * system properties in samevm/agentvm mode. + * + * @run main/othervm CookieHttpsClientTest */ import java.net.CookieHandler; diff -r fc06525cb345 -r 5561a4c99825 jdk/test/tools/launcher/Arrrghs.java --- a/jdk/test/tools/launcher/Arrrghs.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/test/tools/launcher/Arrrghs.java Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -26,7 +26,7 @@ * @bug 5030233 6214916 6356475 6571029 6684582 6742159 4459600 6758881 6753938 * 6894719 6968053 7067922 * @summary Argument parsing validation. - * @compile -XDignore.symbol.file Arrrghs.java TestHelper.java + * @compile -XDignore.symbol.file Arrrghs.java * @run main Arrrghs */ @@ -38,7 +38,7 @@ import java.io.InputStreamReader; import java.util.Map; -public class Arrrghs { +public class Arrrghs extends TestHelper { private Arrrghs(){} /** * This class provides various tests for arguments processing. @@ -62,7 +62,7 @@ * SIGH, On Windows all strings are quoted, we need to unwrap it */ private static String removeExtraQuotes(String in) { - if (TestHelper.isWindows) { + if (isWindows) { // Trim the string and remove the enclosed quotes if any. in = in.trim(); if (in.startsWith("\"") && in.endsWith("\"")) { @@ -82,7 +82,7 @@ String in = rd.readLine(); while (in != null) { - if (TestHelper.debug) System.out.println(in); + if (debug) System.out.println(in); if (in.startsWith(Cookie)) { String detectedArgument = removeExtraQuotes(in.substring(Cookie.length())); if (expectedArguments.equals(detectedArgument)) { @@ -94,7 +94,7 @@ detectedArgument + "'"); } // Return the value asap if not in debug mode. - if (!TestHelper.debug) { + if (!debug) { rd.close(); istream.close(); return retval; @@ -125,7 +125,7 @@ * Quoting could cause dissimilar testArguments and expected arguments. */ static int doTest(String testArguments, String expectedPattern) { - ProcessBuilder pb = new ProcessBuilder(TestHelper.javaCmd, + ProcessBuilder pb = new ProcessBuilder(javaCmd, VersionStr, testArguments); Map env = pb.environment(); @@ -146,8 +146,7 @@ * These tests require that a JVM (any JVM) be installed in the system registry. * If none is installed, skip this test. */ - TestHelper.TestResult tr = - TestHelper.doExec(TestHelper.javaCmd, VersionStr, "-version"); + TestResult tr = doExec(javaCmd, VersionStr, "-version"); if (!tr.isOK()) { System.err.println("Warning:Argument Passing Tests were skipped, " + "no java found in system registry."); @@ -155,38 +154,38 @@ } // Basic test - TestHelper.testExitValue += doTest("-a -b -c -d"); + testExitValue += doTest("-a -b -c -d"); // Basic test with many spaces - TestHelper.testExitValue += doTest("-a -b -c -d"); + testExitValue += doTest("-a -b -c -d"); // Quoted whitespace does matter ? - TestHelper.testExitValue += doTest("-a \"\"-b -c\"\" -d"); + testExitValue += doTest("-a \"\"-b -c\"\" -d"); // Escaped quotes outside of quotes as literals - TestHelper.testExitValue += doTest("-a \\\"-b -c\\\" -d"); + testExitValue += doTest("-a \\\"-b -c\\\" -d"); // Check for escaped quotes inside of quotes as literal - TestHelper.testExitValue += doTest("-a \"-b \\\"stuff\\\"\" -c -d"); + testExitValue += doTest("-a \"-b \\\"stuff\\\"\" -c -d"); // A quote preceeded by an odd number of slashes is a literal quote - TestHelper.testExitValue += doTest("-a -b\\\\\\\" -c -d"); + testExitValue += doTest("-a -b\\\\\\\" -c -d"); // A quote preceeded by an even number of slashes is a literal quote // see 6214916. - TestHelper.testExitValue += doTest("-a -b\\\\\\\\\" -c -d"); + testExitValue += doTest("-a -b\\\\\\\\\" -c -d"); // Make sure that whitespace doesn't interfere with the removal of the // appropriate tokens. (space-tab-space preceeds -jre-restict-search). - TestHelper.testExitValue += doTest("-a -b \t -jre-restrict-search -c -d","-a -b -c -d"); + testExitValue += doTest("-a -b \t -jre-restrict-search -c -d","-a -b -c -d"); // Make sure that the mJRE tokens being stripped, aren't stripped if // they happen to appear as arguments to the main class. - TestHelper.testExitValue += doTest("foo -version:1.1+"); + testExitValue += doTest("foo -version:1.1+"); System.out.println("Completed arguments quoting tests with " + - TestHelper.testExitValue + " errors"); + testExitValue + " errors"); } /* @@ -194,156 +193,167 @@ */ static void runBasicErrorMessageTests() { // Tests for 5030233 - TestHelper.TestResult tr = TestHelper.doExec(TestHelper.javaCmd, "-cp"); + TestResult tr = doExec(javaCmd, "-cp"); tr.checkNegative(); tr.isNotZeroOutput(); System.out.println(tr); - tr = TestHelper.doExec(TestHelper.javaCmd, "-classpath"); + tr = doExec(javaCmd, "-classpath"); tr.checkNegative(); tr.isNotZeroOutput(); System.out.println(tr); - tr = TestHelper.doExec(TestHelper.javaCmd, "-jar"); + tr = doExec(javaCmd, "-jar"); tr.checkNegative(); tr.isNotZeroOutput(); System.out.println(tr); - tr = TestHelper.doExec(TestHelper.javacCmd, "-cp"); + tr = doExec(javacCmd, "-cp"); tr.checkNegative(); tr.isNotZeroOutput(); System.out.println(tr); // Test for 6356475 "REGRESSION:"java -X" from cmdline fails" - tr = TestHelper.doExec(TestHelper.javaCmd, "-X"); + tr = doExec(javaCmd, "-X"); tr.checkPositive(); tr.isNotZeroOutput(); System.out.println(tr); - tr = TestHelper.doExec(TestHelper.javaCmd, "-help"); + tr = doExec(javaCmd, "-help"); tr.checkPositive(); tr.isNotZeroOutput(); System.out.println(tr); // 6753938, test for non-negative exit value for an incorrectly formed // command line, '% java' - tr = TestHelper.doExec(TestHelper.javaCmd); + tr = doExec(javaCmd); tr.checkNegative(); tr.isNotZeroOutput(); System.out.println(tr); // 6753938, test for non-negative exit value for an incorrectly formed // command line, '% java -Xcomp' - tr = TestHelper.doExec(TestHelper.javaCmd, "-Xcomp"); + tr = doExec(javaCmd, "-Xcomp"); tr.checkNegative(); tr.isNotZeroOutput(); System.out.println(tr); } /* - * A set of tests which tests various dispositions of the main method. + * Tests various dispositions of the main method, these tests are limited + * to English locales as they check for error messages that are localized. */ static void runMainMethodTests() throws FileNotFoundException { - TestHelper.TestResult tr = null; + if (!isEnglishLocale()) { + return; + } + + TestResult tr = null; // a missing class - TestHelper.createJar("MIA", new File("some.jar"), new File("Foo"), + createJar("MIA", new File("some.jar"), new File("Foo"), (String[])null); - tr = TestHelper.doExec(TestHelper.javaCmd, "-jar", "some.jar"); + tr = doExec(javaCmd, "-jar", "some.jar"); tr.contains("Error: Could not find or load main class MIA"); System.out.println(tr); // use classpath to check - tr = TestHelper.doExec(TestHelper.javaCmd, "-cp", "some.jar", "MIA"); + tr = doExec(javaCmd, "-cp", "some.jar", "MIA"); tr.contains("Error: Could not find or load main class MIA"); System.out.println(tr); // incorrect method access - TestHelper.createJar(new File("some.jar"), new File("Foo"), + createJar(new File("some.jar"), new File("Foo"), "private static void main(String[] args){}"); - tr = TestHelper.doExec(TestHelper.javaCmd, "-jar", "some.jar"); + tr = doExec(javaCmd, "-jar", "some.jar"); tr.contains("Error: Main method not found in class Foo"); System.out.println(tr); // use classpath to check - tr = TestHelper.doExec(TestHelper.javaCmd, "-cp", "some.jar", "Foo"); + tr = doExec(javaCmd, "-cp", "some.jar", "Foo"); tr.contains("Error: Main method not found in class Foo"); System.out.println(tr); // incorrect return type - TestHelper.createJar(new File("some.jar"), new File("Foo"), + createJar(new File("some.jar"), new File("Foo"), "public static int main(String[] args){return 1;}"); - tr = TestHelper.doExec(TestHelper.javaCmd, "-jar", "some.jar"); + tr = doExec(javaCmd, "-jar", "some.jar"); tr.contains("Error: Main method must return a value of type void in class Foo"); System.out.println(tr); // use classpath to check - tr = TestHelper.doExec(TestHelper.javaCmd, "-cp", "some.jar", "Foo"); + tr = doExec(javaCmd, "-cp", "some.jar", "Foo"); tr.contains("Error: Main method must return a value of type void in class Foo"); System.out.println(tr); // incorrect parameter type - TestHelper.createJar(new File("some.jar"), new File("Foo"), + createJar(new File("some.jar"), new File("Foo"), "public static void main(Object[] args){}"); - tr = TestHelper.doExec(TestHelper.javaCmd, "-jar", "some.jar"); + tr = doExec(javaCmd, "-jar", "some.jar"); tr.contains("Error: Main method not found in class Foo"); System.out.println(tr); // use classpath to check - tr = TestHelper.doExec(TestHelper.javaCmd, "-cp", "some.jar", "Foo"); + tr = doExec(javaCmd, "-cp", "some.jar", "Foo"); tr.contains("Error: Main method not found in class Foo"); System.out.println(tr); // incorrect method type - non-static - TestHelper.createJar(new File("some.jar"), new File("Foo"), + createJar(new File("some.jar"), new File("Foo"), "public void main(String[] args){}"); - tr = TestHelper.doExec(TestHelper.javaCmd, "-jar", "some.jar"); + tr = doExec(javaCmd, "-jar", "some.jar"); tr.contains("Error: Main method is not static in class Foo"); System.out.println(tr); // use classpath to check - tr = TestHelper.doExec(TestHelper.javaCmd, "-cp", "some.jar", "Foo"); + tr = doExec(javaCmd, "-cp", "some.jar", "Foo"); tr.contains("Error: Main method is not static in class Foo"); System.out.println(tr); // amongst a potpourri of kindred main methods, is the right one chosen ? - TestHelper.createJar(new File("some.jar"), new File("Foo"), + createJar(new File("some.jar"), new File("Foo"), "void main(Object[] args){}", "int main(Float[] args){return 1;}", "private void main() {}", "private static void main(int x) {}", "public int main(int argc, String[] argv) {return 1;}", "public static void main(String[] args) {System.out.println(\"THE_CHOSEN_ONE\");}"); - tr = TestHelper.doExec(TestHelper.javaCmd, "-jar", "some.jar"); + tr = doExec(javaCmd, "-jar", "some.jar"); tr.contains("THE_CHOSEN_ONE"); System.out.println(tr); // use classpath to check - tr = TestHelper.doExec(TestHelper.javaCmd, "-cp", "some.jar", "Foo"); + tr = doExec(javaCmd, "-cp", "some.jar", "Foo"); tr.contains("THE_CHOSEN_ONE"); System.out.println(tr); // test for extraneous whitespace in the Main-Class attribute - TestHelper.createJar(" Foo ", new File("some.jar"), new File("Foo"), + createJar(" Foo ", new File("some.jar"), new File("Foo"), "public static void main(String... args){}"); - tr = TestHelper.doExec(TestHelper.javaCmd, "-jar", "some.jar"); + tr = doExec(javaCmd, "-jar", "some.jar"); tr.checkPositive(); System.out.println(tr); } - // tests 6968053, ie. we turn on the -Xdiag (for now) flag and check if - // the suppressed stack traces are exposed. + /* + * tests 6968053, ie. we turn on the -Xdiag (for now) flag and check if + * the suppressed stack traces are exposed, ignore these tests for localized + * locales, limiting to English only. + */ static void runDiagOptionTests() throws FileNotFoundException { - TestHelper.TestResult tr = null; + if (!isEnglishLocale()) { // only english version + return; + } + TestResult tr = null; // a missing class - TestHelper.createJar("MIA", new File("some.jar"), new File("Foo"), + createJar("MIA", new File("some.jar"), new File("Foo"), (String[])null); - tr = TestHelper.doExec(TestHelper.javaCmd, "-Xdiag", "-jar", "some.jar"); + tr = doExec(javaCmd, "-Xdiag", "-jar", "some.jar"); tr.contains("Error: Could not find or load main class MIA"); tr.contains("java.lang.ClassNotFoundException: MIA"); System.out.println(tr); // use classpath to check - tr = TestHelper.doExec(TestHelper.javaCmd, "-Xdiag", "-cp", "some.jar", "MIA"); + tr = doExec(javaCmd, "-Xdiag", "-cp", "some.jar", "MIA"); tr.contains("Error: Could not find or load main class MIA"); tr.contains("java.lang.ClassNotFoundException: MIA"); System.out.println(tr); // a missing class on the classpath - tr = TestHelper.doExec(TestHelper.javaCmd, "-Xdiag", "NonExistentClass"); + tr = doExec(javaCmd, "-Xdiag", "NonExistentClass"); tr.contains("Error: Could not find or load main class NonExistentClass"); tr.contains("java.lang.ClassNotFoundException: NonExistentClass"); System.out.println(tr); @@ -351,23 +361,29 @@ static void test6894719() { // test both arguments to ensure they exist - TestHelper.TestResult tr = null; - tr = TestHelper.doExec(TestHelper.javaCmd, + TestResult tr = null; + tr = doExec(javaCmd, "-no-jre-restrict-search", "-version"); tr.checkPositive(); System.out.println(tr); - tr = TestHelper.doExec(TestHelper.javaCmd, + tr = doExec(javaCmd, "-jre-restrict-search", "-version"); tr.checkPositive(); System.out.println(tr); } + /* + * a missing manifest entry 7067922, we ignore this test for locales + * which are localized, thus the testing is limited to English locales. + */ static void test7067922() { - // a missing manifest entry 7067922 - TestHelper.TestResult tr = null; - TestHelper.createJar("cvf", "missingmainentry.jar", "."); - tr = TestHelper.doExec(TestHelper.javaCmd, "-jar", "missingmainentry.jar"); + if (!isEnglishLocale()) { + return; + } + TestResult tr = null; + createJar("cvf", "missingmainentry.jar", "."); + tr = doExec(javaCmd, "-jar", "missingmainentry.jar"); tr.contains("no main manifest attribute"); System.out.println(tr); } @@ -377,7 +393,7 @@ * @throws java.io.FileNotFoundException */ public static void main(String[] args) throws FileNotFoundException { - if (TestHelper.debug) { + if (debug) { System.out.println("Starting Arrrghs tests"); } quoteParsingTests(); @@ -386,8 +402,8 @@ test6894719(); test7067922(); runDiagOptionTests(); - if (TestHelper.testExitValue > 0) { - System.out.println("Total of " + TestHelper.testExitValue + " failed"); + if (testExitValue > 0) { + System.out.println("Total of " + testExitValue + " failed"); System.exit(1); } else { System.out.println("All tests pass"); diff -r fc06525cb345 -r 5561a4c99825 jdk/test/tools/launcher/ChangeDataModel.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/launcher/ChangeDataModel.java Thu Feb 09 23:17:22 2012 -0800 @@ -0,0 +1,120 @@ +/* + * 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 4894330 4810347 6277269 + * @compile -XDignore.symbol.file ChangeDataModel.java + * @run main ChangeDataModel + * @summary Verify -d32 and -d64 options are accepted(rejected) on all platforms + * @author Joseph D. Darcy, ksrini + */ +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +public class ChangeDataModel extends TestHelper { + private static final File TestJar = new File("test" + JAR_FILE_EXT); + private static final String OPT_PREFIX = "ARCH_OPT:"; + + public static void main(String... args) throws Exception { + String[] code = { + " public static void main(String argv[]) {", + " System.out.println(\"" + OPT_PREFIX + "-d\" + System.getProperty(\"sun.arch.data.model\", \"none\"));", + " }", + }; + createJar(TestJar, code); + + // verify if data model flag for default data model is accepted + if (is32Bit) { + checkAcceptance(javaCmd, "-d32"); + } else if (is64Bit) { + checkAcceptance(javaCmd, "-d64"); + } else { + throw new Error("unsupported data model"); + } + + // test dual mode systems + if (isDualMode) { + // albeit dual mode we may not have the 64 bit components present + if (dualModePresent()) { + // 32-bit -> 64-bit + checkExecCount(javaCmd, "-d64"); + // 64-bit -> 32-bit + checkExecCount(java64Cmd, "-d32"); + + checkAcceptance(javaCmd, "-d64"); + checkAcceptance(java64Cmd, "-d32"); + } else { + System.out.println("Warning: no 64-bit components found;" + + " only one data model tested."); + } + } else { + // Negative tests: ensure that non-dual mode systems reject the + // complementary (other) data model + if (is32Bit) { + checkRejection(javaCmd, "-d64"); + } else if (is64Bit) { + checkRejection(javaCmd, "-d32"); + } else { + throw new Error("unsupported data model"); + } + } + } + + static void checkExecCount(String cmd, String dmodel) { + Map envMap = new HashMap<>(); + envMap.put(JLDEBUG_KEY, "true"); + TestResult tr = doExec(envMap, javaCmd, "-d64", + "-jar", TestJar.getAbsolutePath()); + int count = 0; + for (String x : tr.testOutput) { + if (x.contains(EXPECTED_MARKER)) { + count++; + if (count > 1) { + System.out.println(tr); + throw new RuntimeException("Maximum exec count of 1 execeeded"); + } + } + } + } + + static void checkAcceptance(String cmd, String dmodel) { + TestResult tr = doExec(cmd, dmodel, "-jar", TestJar.getAbsolutePath()); + if (!tr.contains(OPT_PREFIX + dmodel)) { + System.out.println(tr); + String message = "Data model flag " + dmodel + + " not accepted or had improper effect."; + throw new RuntimeException(message); + } + } + + static void checkRejection(String cmd, String dmodel) { + TestResult tr = doExec(cmd, dmodel, "-jar", TestJar.getAbsolutePath()); + if (tr.contains(OPT_PREFIX + dmodel)) { + System.out.println(tr); + String message = "Data model flag " + dmodel + " was accepted."; + throw new RuntimeException(message); + } + } +} diff -r fc06525cb345 -r 5561a4c99825 jdk/test/tools/launcher/ChangeDataModel.sh --- a/jdk/test/tools/launcher/ChangeDataModel.sh Thu Feb 09 18:26:57 2012 +0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,260 +0,0 @@ -# -# Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# @test -# @bug 4894330 4810347 6277269 -# @run shell ChangeDataModel.sh -# @summary Verify -d32 and -d64 options are accepted(rejected) on all platforms -# @author Joseph D. Darcy - -OS=`uname -s`; - -# To remove CR from output, needed for java apps in CYGWIN, harmless otherwise -SED_CR="sed -e s@\\r@@g" - -case "$OS" in - Windows* | CYGWIN* ) - PATHSEP=";" - ;; - - * ) - PATHSEP=":" - ;; -esac - -# Verify directory context variables are set -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 -fi - -if [ "${TESTSRC}" = "" ] -then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 -fi - -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi - -# Construct paths to default Java executables -JAVA="$TESTJAVA/bin/java -classpath $TESTCLASSES${PATHSEP}." -JAVAC="$TESTJAVA/bin/javac" - - -# Create our little Java test on the fly -( printf "public class GetDataModel {" - printf " public static void main(String argv[]) {" - printf " System.out.println(System.getProperty(\"sun.arch.data.model\", \"none\"));" - printf " }" - printf "}" -) > GetDataModel.java - -$JAVAC GetDataModel.java - - -# All preconditions are met; run the tests. - - -# Verify data model flag for default data model is accepted - -DM=`$JAVA GetDataModel | ${SED_CR}` -case "$DM" in - 32 ) - DM2=`${JAVA} -d32 GetDataModel | ${SED_CR}` - if [ "${DM2}" != "32" ] - then - echo "Data model flag -d32 not accepted or had improper effect." - exit 1 - fi - ;; - - 64 ) - DM2=`${JAVA} -d64 GetDataModel | ${SED_CR}` - if [ "${DM2}" != "64" ] - then - echo "Data model flag -d64 not accepted or had improper effect." - exit 1 - fi - ;; - - * ) - echo "Unrecognized data model: $DM" - exit 1 - ;; -esac - -# Determine if platform might be dual-mode capable. - -case "$OS" in - SunOS ) - # ARCH should be sparc or i386 - ARCH=`uname -p` - case "${ARCH}" in - sparc ) - DUALMODE=true - PATH64=sparcv9 - ;; - - i386 ) - DUALMODE=true - PATH64=amd64 - ;; - - * ) - DUALMODE=false - ;; - esac - ;; - - - Linux ) - # ARCH should be ia64, x86_64, or i*86 - ARCH=`uname -m` - case "${ARCH}" in - ia64 ) - DUALMODE=false - ;; - - x86_64 ) - DUALMODE=true - PATH64=amd64 - ;; - - * ) - DUALMODE=false; - ;; - esac - ;; - - Windows* | CYGWIN* ) - ARCH=`uname -m` - case "${ARCH}" in - * ) - DUALMODE=false; - ;; - esac - ;; - - * ) - echo "Warning: unknown environment." - DUALMODE=false - ;; -esac - -if [ "${DUALMODE}" = "true" ] -then - # Construct path to 64-bit Java executable, might not exist - JAVA64FILE="${TESTJAVA}/bin/${PATH64}/java" - JAVA64="${JAVA64FILE} -classpath ${TESTCLASSES}${PATHSEP}." - - if [ -f ${JAVA64FILE} ]; then - # Verify that, at least on Solaris, only one exec is - # used to change data models - if [ "${OS}" = "SunOS" ] - then - rm -f truss.out - truss -texec ${JAVA} -d64 GetDataModel > /dev/null 2> truss.out - execCount=`grep -c execve truss.out` - if [ "${execCount}" -gt 2 ] - then - echo "Maximum exec count of 2 exceeded: got $execCount." - exit 1 - fi - - rm -f truss.out - truss -texec ${JAVA64} -d32 GetDataModel > /dev/null 2> truss.out - execCount=`grep -c execve truss.out` - if [ "${execCount}" -gt 2 ] - then - echo "Maximum exec count of 2 exceeded: got $execCount." - exit 1 - fi - fi - - DM2=`${JAVA} -d64 GetDataModel` - if [ "${DM2}" != "64" ] - then - echo "Data model flag -d64 not accepted or had improper effect." - exit 1 - fi - - DM2=`${JAVA64} GetDataModel` - if [ "${DM2}" != "64" ] - then - echo "Improper data model returned." - exit 1 - fi - - DM2=`${JAVA64} -d64 GetDataModel` - if [ "${DM2}" != "64" ] - then - echo "Data model flag -d64 not accepted or had improper effect." - exit 1 - fi - - DM2=`${JAVA64} -d32 GetDataModel` - if [ "${DM2}" != "32" ] - then - echo "Data model flag -d32 not accepted or had improper effect." - exit 1 - fi - - else - echo "Warning: no 64-bit components found; only one data model tested." - fi -else -# Negative tests for non-dual mode platforms to ensure the other data model is -# rejected - DM=`$JAVA GetDataModel | ${SED_CR}` - case "$DM" in - 32 ) - DM2=`${JAVA} -d64 GetDataModel | ${SED_CR}` - if [ "x${DM2}" != "x" ] - then - echo "Data model flag -d64 was accepted." - exit 1 - fi - ;; - - 64 ) - DM2=`${JAVA} -d32 GetDataModel | ${SED_CR}` - if [ "x${DM2}" != "x" ] - then - echo "Data model flag -d32 was accepted." - exit 1 - fi - ;; - - * ) - echo "Unrecognized data model: $DM" - exit 1 - ;; - esac -fi - -exit 0; diff -r fc06525cb345 -r 5561a4c99825 jdk/test/tools/launcher/CreatePlatformFile.java --- a/jdk/test/tools/launcher/CreatePlatformFile.java Thu Feb 09 18:26:57 2012 +0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. - * 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. - */ - -/* - * - * - * This class is used by test i18nTest.sh - * - * Class to create various i18n Hello World Java source files using - * the platform's default encoding of a non-ASCII name; create plain - * ASCII Hello World if the platform's default is charset is US-ASCII. - */ - -import java.io.PrintWriter; -import java.io.FileOutputStream; - -public class CreatePlatformFile { - public static void main(String argv[]) { - String fileSep = System.getProperty("file.separator"); - String defaultEncoding = System.getProperty("file.encoding"); - - if(defaultEncoding == null) { - System.err.println("Default encoding not found; Error."); - return; - } - - if (defaultEncoding.equals("Cp1252") ) { - // "HelloWorld" with an accented e - String fileName = "i18nH\u00e9lloWorld.java"; - try { - PrintWriter pw = new PrintWriter(new FileOutputStream("."+fileSep+fileName)); - pw.println("public class i18nH\u00e9lloWorld {"); - pw.println(" public static void main(String [] argv) {"); - pw.println(" System.out.println(\"Hello Cp1252 World\");"); - pw.println(" }"); - pw.println("}"); - pw.flush(); - pw.close(); - } - catch (java.io.FileNotFoundException e) { - System.err.println("Problem opening file; test fails"); - } - - } else { - // ASCII "HelloWorld" - String fileName = "i18nHelloWorld.java"; - try { - PrintWriter pw = new PrintWriter(new FileOutputStream("."+fileSep+fileName)); - pw.println("public class i18nHelloWorld {"); - pw.println(" public static void main(String [] argv) {"); - pw.println(" System.out.println(\"Warning: US-ASCII assumed; filenames with\");"); - pw.println(" System.out.println(\"non-ASCII characters will not be tested\");"); - pw.println(" }"); - pw.println("}"); - pw.flush(); - pw.close(); - } - catch (java.io.FileNotFoundException e) { - System.err.println("Problem opening file; test fails"); - } - } - } -} diff -r fc06525cb345 -r 5561a4c99825 jdk/test/tools/launcher/DefaultLocaleTestRun.java --- a/jdk/test/tools/launcher/DefaultLocaleTestRun.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/test/tools/launcher/DefaultLocaleTestRun.java Thu Feb 09 23:17:22 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 @@ -31,23 +31,24 @@ Following 2 testing scenarios are recommended (1)systemLocale=Japanese, userLocale=English (2)systemLocale=English, userLocale=Japanese - * @compile -XDignore.symbol.file DefaultLocaleTest.java TestHelper.java + * @compile -XDignore.symbol.file DefaultLocaleTest.java * @run main DefaultLocaleTestRun */ -import java.io.File; -public class DefaultLocaleTestRun { +public class DefaultLocaleTestRun extends TestHelper { public static void main(String... args) { - if (!TestHelper.isWindows) { + if (!isWindows) { System.out.println("Test passes vacuously on non-windows"); return; } - TestHelper.TestResult tr = null; - tr = TestHelper.doExec(TestHelper.javaCmd, "DefaultLocaleTest", "-w", - "x.out"); + TestResult tr = null; + tr = doExec(javaCmd, + "-cp", TEST_CLASSES_DIR.getAbsolutePath(), + "DefaultLocaleTest", "-w", "x.out"); System.out.println(tr.testOutput); - tr = TestHelper.doExec(TestHelper.javawCmd, "DefaultLocaleTest", "-r", - "x.out"); + tr = doExec(javawCmd, + "-cp", TEST_CLASSES_DIR.getAbsolutePath(), + "DefaultLocaleTest", "-r", "x.out"); System.out.println(tr.testOutput); if (!tr.isOK()) { throw new RuntimeException("Test failed"); diff -r fc06525cb345 -r 5561a4c99825 jdk/test/tools/launcher/ExecutionEnvironment.java --- a/jdk/test/tools/launcher/ExecutionEnvironment.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/test/tools/launcher/ExecutionEnvironment.java Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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,7 +25,7 @@ * @test * @bug 4780570 4731671 6354700 6367077 6670965 4882974 * @summary Checks for LD_LIBRARY_PATH and execution on *nixes - * @compile -XDignore.symbol.file ExecutionEnvironment.java TestHelper.java + * @compile -XDignore.symbol.file ExecutionEnvironment.java * @run main ExecutionEnvironment */ @@ -60,7 +60,7 @@ import java.util.Map; -public class ExecutionEnvironment { +public class ExecutionEnvironment extends TestHelper { static final String LD_LIBRARY_PATH = "LD_LIBRARY_PATH"; static final String LD_LIBRARY_PATH_32 = LD_LIBRARY_PATH + "_32"; static final String LD_LIBRARY_PATH_64 = LD_LIBRARY_PATH + "_64"; @@ -70,9 +70,6 @@ static final String LD_LIBRARY_PATH_32_VALUE = "/Lawrence/Of/Arabia"; static final String LD_LIBRARY_PATH_64_VALUE = "/A/Passage/To/India"; - static final String JLDEBUG_KEY = "_JAVA_LAUNCHER_DEBUG"; - static final String EXPECTED_MARKER = "TRACER_MARKER:About to EXEC"; - static final String[] LD_PATH_STRINGS = { LD_LIBRARY_PATH + "=" + LD_LIBRARY_PATH_VALUE, LD_LIBRARY_PATH_32 + "=" + LD_LIBRARY_PATH_32_VALUE, @@ -84,11 +81,11 @@ static int errors = 0; static int passes = 0; - static final String LIBJVM = TestHelper.isWindows ? "jvm.dll" : "libjvm.so"; + static final String LIBJVM = isWindows ? "jvm.dll" : "libjvm.so"; static void createTestJar() { try { - List codeList = new ArrayList(); + List codeList = new ArrayList<>(); codeList.add("static void printValue(String name, boolean property) {\n"); codeList.add(" String value = (property) ? System.getProperty(name) : System.getenv(name);\n"); codeList.add(" System.out.println(name + \"=\" + value);\n"); @@ -105,7 +102,7 @@ codeList.add(" printValue(\"" + LD_LIBRARY_PATH_64 + "\", false);\n"); codeList.add("}\n"); String[] clist = new String[codeList.size()]; - TestHelper.createJar(testJarFile, codeList.toArray(clist)); + createJar(testJarFile, codeList.toArray(clist)); } catch (FileNotFoundException fnfe) { throw new RuntimeException(fnfe); } @@ -117,16 +114,15 @@ * environment should be pristine. */ private static void ensureEcoFriendly() { - TestHelper.TestResult tr = null; + TestResult tr = null; - Map env = new HashMap(); + Map env = new HashMap<>(); for (String x : LD_PATH_STRINGS) { String pairs[] = x.split("="); env.put(pairs[0], pairs[1]); } - tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar", - testJarFile.getAbsolutePath()); + tr = doExec(env, javaCmd, "-jar", testJarFile.getAbsolutePath()); if (!tr.isNotZeroOutput()) { System.out.println(tr); @@ -149,10 +145,9 @@ * data model */ static void ensureNoExec() { - Map env = new HashMap(); + Map env = new HashMap<>(); env.put(JLDEBUG_KEY, "true"); - TestHelper.TestResult tr = - TestHelper.doExec(env, TestHelper.javaCmd, "-version"); + TestResult tr = doExec(env, javaCmd, "-version"); if (tr.testOutput.contains(EXPECTED_MARKER)) { System.out.println("FAIL: EnsureNoExecs: found expected warning <" + EXPECTED_MARKER + @@ -176,25 +171,23 @@ */ static void verifyJavaLibraryPath() { - TestHelper.TestResult tr = null; + TestResult tr = null; - Map env = new HashMap(); + Map env = new HashMap<>(); - if (TestHelper.isLinux) { + if (isLinux) { for (String x : LD_PATH_STRINGS) { String pairs[] = x.split("="); env.put(pairs[0], pairs[1]); } - tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar", - testJarFile.getAbsolutePath()); + tr = doExec(env, javaCmd, "-jar", testJarFile.getAbsolutePath()); verifyJavaLibraryPathGeneric(tr); } else { // no override env.clear(); env.put(LD_LIBRARY_PATH, LD_LIBRARY_PATH_VALUE); - tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar", - testJarFile.getAbsolutePath()); + tr = doExec(env, javaCmd, "-jar", testJarFile.getAbsolutePath()); verifyJavaLibraryPathGeneric(tr); env.clear(); @@ -206,53 +199,52 @@ // verify the override occurs, since we know the invocation always // uses by default is 32-bit, therefore we also set the test // expectation to be the same. - tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar", - testJarFile.getAbsolutePath()); + tr = doExec(env, javaCmd, "-jar", testJarFile.getAbsolutePath()); verifyJavaLibraryPathOverride(tr, true); // try changing the model from 32 to 64 bit - if (TestHelper.dualModePresent() && TestHelper.is32Bit) { + if (dualModePresent() && is32Bit) { // verify the override occurs env.clear(); for (String x : LD_PATH_STRINGS) { String pairs[] = x.split("="); env.put(pairs[0], pairs[1]); } - tr = TestHelper.doExec(env, TestHelper.javaCmd, "-d64", "-jar", + tr = doExec(env, javaCmd, "-d64", "-jar", testJarFile.getAbsolutePath()); verifyJavaLibraryPathOverride(tr, false); // no override env.clear(); env.put(LD_LIBRARY_PATH, LD_LIBRARY_PATH_VALUE); - tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar", + tr = doExec(env, javaCmd, "-jar", testJarFile.getAbsolutePath()); verifyJavaLibraryPathGeneric(tr); } // try changing the model from 64 to 32 bit - if (TestHelper.java64Cmd != null && TestHelper.is64Bit) { + if (java64Cmd != null && is64Bit) { // verify the override occurs env.clear(); for (String x : LD_PATH_STRINGS) { String pairs[] = x.split("="); env.put(pairs[0], pairs[1]); } - tr = TestHelper.doExec(env, TestHelper.java64Cmd, "-d32", "-jar", + tr = doExec(env, java64Cmd, "-d32", "-jar", testJarFile.getAbsolutePath()); verifyJavaLibraryPathOverride(tr, true); // no override env.clear(); env.put(LD_LIBRARY_PATH, LD_LIBRARY_PATH_VALUE); - tr = TestHelper.doExec(env, TestHelper.java64Cmd, "-d32", "-jar", + tr = doExec(env, java64Cmd, "-d32", "-jar", testJarFile.getAbsolutePath()); verifyJavaLibraryPathGeneric(tr); } } } - private static void verifyJavaLibraryPathGeneric(TestHelper.TestResult tr) { + private static void verifyJavaLibraryPathGeneric(TestResult tr) { if (!tr.matches("java.library.path=.*" + LD_LIBRARY_PATH_VALUE + ".*")) { System.out.print("FAIL: verifyJavaLibraryPath: "); System.out.println(" java.library.path does not contain " + @@ -264,7 +256,7 @@ } } - private static void verifyJavaLibraryPathOverride(TestHelper.TestResult tr, + private static void verifyJavaLibraryPathOverride(TestResult tr, boolean is32Bit) { // make sure the 32/64 bit value exists if (!tr.matches("java.library.path=.*" + @@ -295,10 +287,10 @@ */ static void verifyVmSelection() { - TestHelper.TestResult tr = null; + TestResult tr = null; - if (TestHelper.is32Bit) { - tr = TestHelper.doExec(TestHelper.javaCmd, "-client", "-version"); + if (is32Bit) { + tr = doExec(javaCmd, "-client", "-version"); if (!tr.matches(".*Client VM.*")) { System.out.println("FAIL: the expected vm -client did not launch"); System.out.println(tr); @@ -307,7 +299,7 @@ passes++; } } - tr = TestHelper.doExec(TestHelper.javaCmd, "-server", "-version"); + tr = doExec(javaCmd, "-server", "-version"); if (!tr.matches(".*Server VM.*")) { System.out.println("FAIL: the expected vm -server did not launch"); System.out.println(tr); @@ -321,14 +313,14 @@ * checks to see there is no extra libjvm.so than needed */ static void verifyNoSymLink() { - if (TestHelper.is64Bit) { + if (is64Bit) { return; } File symLink = null; - String libPathPrefix = TestHelper.isSDK ? "jre/lib" : "/lib"; - symLink = new File(TestHelper.JAVAHOME, libPathPrefix + - TestHelper.getJreArch() + "/" + LIBJVM); + String libPathPrefix = isSDK ? "jre/lib" : "/lib"; + symLink = new File(JAVAHOME, libPathPrefix + + getJreArch() + "/" + LIBJVM); if (symLink.exists()) { System.out.println("FAIL: The symlink exists " + symLink.getAbsolutePath()); @@ -339,7 +331,7 @@ } public static void main(String... args) throws Exception { - if (TestHelper.isWindows) { + if (isWindows) { System.out.println("Warning: noop on windows"); return; } diff -r fc06525cb345 -r 5561a4c99825 jdk/test/tools/launcher/I18NJarTest.java --- a/jdk/test/tools/launcher/I18NJarTest.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/test/tools/launcher/I18NJarTest.java Thu Feb 09 23:17:22 2012 -0800 @@ -26,7 +26,7 @@ * @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 + * @compile -XDignore.symbol.file I18NJarTest.java * @run main/othervm I18NJarTest */ import java.io.File; @@ -48,7 +48,7 @@ * in its own VM (othervm mode), such that the ensuing tests can run unperturbed, * regardless of the outcome. */ -public class I18NJarTest { +public class I18NJarTest extends TestHelper { 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", ""); @@ -78,7 +78,7 @@ } dir.mkdir(); File dirfile = new File(dir, "foo.jar"); - TestHelper.createJar(dirfile, + createJar(dirfile, "public static void main(String... args) {", "System.out.println(\"Hello World\");", "System.exit(0);", @@ -86,22 +86,20 @@ // 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)); + File[] classFiles = cwd.listFiles(createFilter(CLASS_FILE_EXT)); for (File f : classFiles) { f.delete(); } // test with a jar file - TestHelper.TestResult tr = TestHelper.doExec(TestHelper.javaCmd, - "-jar", dirfile.getAbsolutePath()); + TestResult tr = doExec(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"); + tr = doExec(javaCmd, "-cp", dirfile.getAbsolutePath(), "Foo"); System.out.println(tr); if (!tr.isOK()) { throw new RuntimeException("TEST FAILED"); diff -r fc06525cb345 -r 5561a4c99825 jdk/test/tools/launcher/I18NTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/launcher/I18NTest.java Thu Feb 09 23:17:22 2012 -0800 @@ -0,0 +1,89 @@ +/* + * 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 4761384 + * @compile -XDignore.symbol.file I18NTest.java + * @run main I18NTest + * @summary Test to see if class files with non-ASCII characters can be run + * @author Joseph D. Darcy, Kumar Srinivasan + */ + + +import java.util.ArrayList; +import java.io.File; +import java.util.List; + +public class I18NTest extends TestHelper { + static String fileName = null; + public static void main(String... args) throws Exception { + String defaultEncoding = System.getProperty("file.encoding"); + if (defaultEncoding == null) { + System.err.println("Default encoding not found; Error."); + return; + } + if (!defaultEncoding.equals("Cp1252")) { + System.err.println("Warning: required encoding not found, test skipped."); + return; + } + // for some reason the shell test version insisted on cleaning out the + // directory, likely being pedantic. + File cwd = new File("."); + for (File f : cwd.listFiles(createFilter(CLASS_FILE_EXT))) { + f.delete(); + } + for (File f : cwd.listFiles(createFilter(JAVA_FILE_EXT))) { + f.delete(); + } + createPlatformFile(); + + // compile the generate code using the javac compiler vs. the api, to + // as a bonus point to see if the argument is passed correctly + TestResult tr = null; + tr = doExec(javacCmd, fileName + JAVA_FILE_EXT); + if (!tr.isOK()) { + System.out.println(tr); + throw new Error("compilation failed..."); + } + tr = doExec(javaCmd, "-cp", ".", fileName); + if (!tr.isOK()) { + System.out.println(tr); + throw new RuntimeException("run failed with encoding " + defaultEncoding); + } + } + + public static void createPlatformFile() throws Exception { + List buffer = new ArrayList<>(); + // "HelloWorld" with an accented e + fileName = "i18nH\u00e9lloWorld"; + buffer.clear(); + buffer.add("public class i18nH\u00e9lloWorld {"); + buffer.add(" public static void main(String [] argv) {"); + buffer.add(" System.out.println(\"Hello Cp1252 World\");"); + buffer.add(" }"); + buffer.add("}"); + File outFile = new File(fileName + JAVA_FILE_EXT); + createFile(outFile, buffer); + } +} diff -r fc06525cb345 -r 5561a4c99825 jdk/test/tools/launcher/MiscTests.java --- a/jdk/test/tools/launcher/MiscTests.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/test/tools/launcher/MiscTests.java Thu Feb 09 23:17:22 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 @@ -25,7 +25,7 @@ * @test * @bug 6856415 * @summary Miscellaneous tests, Exceptions - * @compile -XDignore.symbol.file MiscTests.java TestHelper.java + * @compile -XDignore.symbol.file MiscTests.java * @run main MiscTests */ @@ -33,12 +33,12 @@ import java.io.File; import java.io.FileNotFoundException; -public class MiscTests { +public class MiscTests extends TestHelper { // 6856415: Checks to ensure that proper exceptions are thrown by java static void test6856415() { // No pkcs library on win-x64, so we bail out. - if (TestHelper.is64Bit && TestHelper.isWindows) { + if (is64Bit && isWindows) { return; } StringBuilder sb = new StringBuilder(); @@ -49,11 +49,11 @@ File testJar = new File("Foo.jar"); testJar.delete(); try { - TestHelper.createJar(testJar, sb.toString()); + createJar(testJar, sb.toString()); } catch (FileNotFoundException fnfe) { throw new RuntimeException(fnfe); } - TestHelper.TestResult tr = TestHelper.doExec(TestHelper.javaCmd, + TestResult tr = doExec(javaCmd, "-Djava.security.manager", "-jar", testJar.getName(), "foo.bak"); for (String s : tr.testOutput) { System.out.println(s); @@ -67,8 +67,8 @@ public static void main(String... args) { test6856415(); - if (TestHelper.testExitValue != 0) { - throw new Error(TestHelper.testExitValue + " tests failed"); + if (testExitValue != 0) { + throw new Error(testExitValue + " tests failed"); } } } diff -r fc06525cb345 -r 5561a4c99825 jdk/test/tools/launcher/Settings.java --- a/jdk/test/tools/launcher/Settings.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/test/tools/launcher/Settings.java Thu Feb 09 23:17:22 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,11 +27,11 @@ * @test * @bug 6994753 7123582 * @summary tests -XshowSettings options - * @compile -XDignore.symbol.file Settings.java TestHelper.java + * @compile -XDignore.symbol.file Settings.java * @run main Settings * @author ksrini */ -public class Settings { +public class Settings extends TestHelper { private static File testJar = null; static void init() throws IOException { @@ -45,17 +45,17 @@ tsrc.append(" System.out.println(x);\n"); tsrc.append(" }\n"); tsrc.append("}\n"); - TestHelper.createJar(testJar, tsrc.toString()); + createJar(testJar, tsrc.toString()); } - static void checkContains(TestHelper.TestResult tr, String str) { + static void checkContains(TestResult tr, String str) { if (!tr.contains(str)) { System.out.println(tr); throw new RuntimeException(str + " not found"); } } - static void checkNoContains(TestHelper.TestResult tr, String str) { + static void checkNoContains(TestResult tr, String str) { if (tr.contains(str)) { System.out.println(tr.status); throw new RuntimeException(str + " found"); @@ -66,22 +66,22 @@ private static final String PROP_SETTINGS = "Property settings:"; private static final String LOCALE_SETTINGS = "Locale settings:"; - static void containsAllOptions(TestHelper.TestResult tr) { + static void containsAllOptions(TestResult tr) { checkContains(tr, VM_SETTINGS); checkContains(tr, PROP_SETTINGS); checkContains(tr, LOCALE_SETTINGS); } static void runTestOptionDefault() throws IOException { - TestHelper.TestResult tr = null; - tr = TestHelper.doExec(TestHelper.javaCmd, "-Xms64m", "-Xmx512m", + TestResult tr = null; + tr = doExec(javaCmd, "-Xms64m", "-Xmx512m", "-Xss128k", "-XshowSettings", "-jar", testJar.getAbsolutePath()); containsAllOptions(tr); if (!tr.isOK()) { System.out.println(tr.status); throw new RuntimeException("test fails"); } - tr = TestHelper.doExec(TestHelper.javaCmd, "-Xms65536k", "-Xmx712m", + tr = doExec(javaCmd, "-Xms65536k", "-Xmx712m", "-Xss122880", "-XshowSettings", "-jar", testJar.getAbsolutePath()); containsAllOptions(tr); if (!tr.isOK()) { @@ -92,38 +92,38 @@ static void runTestOptionAll() throws IOException { init(); - TestHelper.TestResult tr = null; - tr = TestHelper.doExec(TestHelper.javaCmd, "-XshowSettings:all"); + TestResult tr = null; + tr = doExec(javaCmd, "-XshowSettings:all"); containsAllOptions(tr); } static void runTestOptionVM() throws IOException { - TestHelper.TestResult tr = null; - tr = TestHelper.doExec(TestHelper.javaCmd, "-XshowSettings:vm"); + TestResult tr = null; + tr = doExec(javaCmd, "-XshowSettings:vm"); checkContains(tr, VM_SETTINGS); checkNoContains(tr, PROP_SETTINGS); checkNoContains(tr, LOCALE_SETTINGS); } static void runTestOptionProperty() throws IOException { - TestHelper.TestResult tr = null; - tr = TestHelper.doExec(TestHelper.javaCmd, "-XshowSettings:properties"); + TestResult tr = null; + tr = doExec(javaCmd, "-XshowSettings:properties"); checkNoContains(tr, VM_SETTINGS); checkContains(tr, PROP_SETTINGS); checkNoContains(tr, LOCALE_SETTINGS); } static void runTestOptionLocale() throws IOException { - TestHelper.TestResult tr = null; - tr = TestHelper.doExec(TestHelper.javaCmd, "-XshowSettings:locale"); + TestResult tr = null; + tr = doExec(javaCmd, "-XshowSettings:locale"); checkNoContains(tr, VM_SETTINGS); checkNoContains(tr, PROP_SETTINGS); checkContains(tr, LOCALE_SETTINGS); } static void runTestBadOptions() throws IOException { - TestHelper.TestResult tr = null; - tr = TestHelper.doExec(TestHelper.javaCmd, "-XshowSettingsBadOption"); + TestResult tr = null; + tr = doExec(javaCmd, "-XshowSettingsBadOption"); checkNoContains(tr, VM_SETTINGS); checkNoContains(tr, PROP_SETTINGS); checkNoContains(tr, LOCALE_SETTINGS); @@ -131,8 +131,8 @@ } static void runTest7123582() throws IOException { - TestHelper.TestResult tr = null; - tr = TestHelper.doExec(TestHelper.javaCmd, "-XshowSettings", "-version"); + TestResult tr = null; + tr = doExec(javaCmd, "-XshowSettings", "-version"); if (!tr.isOK()) { System.out.println(tr.status); throw new RuntimeException("test fails"); diff -r fc06525cb345 -r 5561a4c99825 jdk/test/tools/launcher/SomeException.java --- a/jdk/test/tools/launcher/SomeException.java Thu Feb 09 18:26:57 2012 +0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. - * 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. - */ - -/* - * - * - * Used by unresolvedExceptions.sh - */ - -public class SomeException extends RuntimeException { - -} diff -r fc06525cb345 -r 5561a4c99825 jdk/test/tools/launcher/Test7029048.java --- a/jdk/test/tools/launcher/Test7029048.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/test/tools/launcher/Test7029048.java Thu Feb 09 23:17:22 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 @@ -25,7 +25,7 @@ * @test * @bug 7029048 * @summary Checks for LD_LIBRARY_PATH on *nixes - * @compile -XDignore.symbol.file ExecutionEnvironment.java TestHelper.java Test7029048.java + * @compile -XDignore.symbol.file ExecutionEnvironment.java Test7029048.java * @run main Test7029048 */ @@ -42,7 +42,7 @@ import java.util.List; import java.util.Map; -public class Test7029048 { +public class Test7029048 extends TestHelper { static int passes = 0; static int errors = 0; @@ -62,7 +62,7 @@ private static final File dstLibDir = new File("lib"); private static final File dstLibArchDir = - new File(dstLibDir, TestHelper.getJreArch()); + new File(dstLibDir, getJreArch()); private static final File dstServerDir = new File(dstLibArchDir, "server"); private static final File dstServerLibjvm = new File(dstServerDir, LIBJVM); @@ -78,8 +78,8 @@ private static final Map env = new HashMap<>(); static { - if (TestHelper.isDualMode) { - dstOtherArchDir = new File(dstLibDir, TestHelper.getComplementaryJreArch()); + if (isDualMode) { + dstOtherArchDir = new File(dstLibDir, getComplementaryJreArch()); dstOtherServerDir = new File(dstOtherArchDir, "server"); dstOtherServerLibjvm = new File(dstOtherServerDir, LIBJVM); } else { @@ -106,10 +106,10 @@ List cmdsList = new ArrayList<>(); // only for a dual-mode system - if (want64 && TestHelper.isDualMode) { - cmdsList.add(TestHelper.java64Cmd); + if (want64 && isDualMode) { + cmdsList.add(java64Cmd); } else { - cmdsList.add(TestHelper.javaCmd); // a 32-bit java command for all + cmdsList.add(javaCmd); // a 32-bit java command for all } /* @@ -127,18 +127,18 @@ cmdsList.add("-jar"); cmdsList.add(ExecutionEnvironment.testJarFile.getAbsolutePath()); String[] cmds = new String[cmdsList.size()]; - TestHelper.TestResult tr = TestHelper.doExec(env, cmdsList.toArray(cmds)); + TestResult tr = doExec(env, cmdsList.toArray(cmds)); analyze(tr, nLLPComponents, caseID); } // no cross launch, ie. no change to the data model. static void run(Map env, int nLLPComponents, String caseID) throws IOException { - boolean want32 = TestHelper.is32Bit; + boolean want32 = is32Bit; run(want32, null, env, nLLPComponents, caseID); } - static void analyze(TestHelper.TestResult tr, int nLLPComponents, String caseID) { + static void analyze(TestResult tr, int nLLPComponents, String caseID) { String envValue = getValue(LD_LIBRARY_PATH, tr.testOutput); /* * the envValue can never be null, since the test code should always @@ -189,12 +189,12 @@ switch (v) { case LLP_SET_WITH_JVM: // copy the files into the directory structures - TestHelper.copyFile(srcLibjvmSo, dstServerLibjvm); + copyFile(srcLibjvmSo, dstServerLibjvm); // does not matter if it is client or a server - TestHelper.copyFile(srcLibjvmSo, dstClientLibjvm); + copyFile(srcLibjvmSo, dstClientLibjvm); // does not matter if the arch do not match either - if (TestHelper.isDualMode) { - TestHelper.copyFile(srcLibjvmSo, dstOtherServerLibjvm); + if (isDualMode) { + copyFile(srcLibjvmSo, dstOtherServerLibjvm); } desc = "LD_LIBRARY_PATH should be set"; break; @@ -211,7 +211,7 @@ Files.deleteIfExists(dstServerLibjvm.toPath()); } - if (TestHelper.isDualMode) { + if (isDualMode) { if (!dstOtherServerDir.exists()) { Files.createDirectories(dstOtherServerDir.toPath()); } else { @@ -223,7 +223,7 @@ break; case LLP_SET_NON_EXISTENT_PATH: if (dstLibDir.exists()) { - TestHelper.recursiveDelete(dstLibDir); + recursiveDelete(dstLibDir); } desc = "LD_LIBRARY_PATH should not be set"; break; @@ -245,18 +245,18 @@ env.put(LD_LIBRARY_PATH, dstClientDir.getAbsolutePath()); run(env, v.value + 1, "Case 2: " + desc); - if (!TestHelper.isDualMode) { + if (!isDualMode) { continue; // nothing more to do for Linux } // Tests applicable only to solaris. // initialize test variables for dual mode operations - final File dst32ServerDir = TestHelper.is32Bit + final File dst32ServerDir = is32Bit ? dstServerDir : dstOtherServerDir; - final File dst64ServerDir = TestHelper.is64Bit + final File dst64ServerDir = is64Bit ? dstServerDir : dstOtherServerDir; @@ -268,7 +268,7 @@ env.clear(); env.put(LD_LIBRARY_PATH_32, dst32ServerDir.getAbsolutePath()); env.put(LD_LIBRARY_PATH_64, dst64ServerDir.getAbsolutePath()); - run(TestHelper.is32Bit, null, env, v.value + 1, "Case 3: " + desc); + run(is32Bit, null, env, v.value + 1, "Case 3: " + desc); /* * Case 4: we are in dual mode environment, running 64-bit then @@ -276,7 +276,7 @@ * java32 -d64, LLP_64 is relevant, LLP_32 is ignored * java64 -d32, LLP_32 is relevant, LLP_64 is ignored */ - if (TestHelper.dualModePresent()) { + if (dualModePresent()) { run(true, "-d64", env, v.value + 1, "Case 4A: " + desc); run(false,"-d32", env, v.value + 1, "Case 4B: " + desc); } @@ -285,7 +285,7 @@ } public static void main(String... args) throws Exception { - if (TestHelper.isWindows) { + if (isWindows) { System.out.println("Warning: noop on windows"); return; } @@ -297,13 +297,13 @@ if (errors > 0) { throw new Exception("Test7029048: FAIL: with " + errors + " errors and passes " + passes); - } else if (TestHelper.dualModePresent() && passes < 15) { + } else if (dualModePresent() && passes < 15) { throw new Exception("Test7029048: FAIL: " + "all tests did not run, expected " + 15 + " got " + passes); - } else if (TestHelper.isSolaris && passes < 9) { + } else if (isSolaris && passes < 9) { throw new Exception("Test7029048: FAIL: " + "all tests did not run, expected " + 9 + " got " + passes); - } else if (TestHelper.isLinux && passes < 6) { + } else if (isLinux && passes < 6) { throw new Exception("Test7029048: FAIL: " + "all tests did not run, expected " + 6 + " got " + passes); } else { diff -r fc06525cb345 -r 5561a4c99825 jdk/test/tools/launcher/TestHelper.java --- a/jdk/test/tools/launcher/TestHelper.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/test/tools/launcher/TestHelper.java Thu Feb 09 23:17:22 2012 -0800 @@ -29,6 +29,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; +import java.nio.charset.Charset; import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.Files; import java.nio.file.FileVisitResult; @@ -36,17 +37,22 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.Map; import javax.tools.JavaCompiler; import javax.tools.ToolProvider; import static java.nio.file.StandardCopyOption.*; +import static java.nio.file.StandardOpenOption.*; /** * This class provides some common utilities for the launcher tests. */ -public enum TestHelper { - INSTANCE; +public class TestHelper { + // commonly used jtreg constants + static final File TEST_CLASSES_DIR; + static final File TEST_SOURCES_DIR; + static final String JAVAHOME = System.getProperty("java.home"); static final boolean isSDK = JAVAHOME.endsWith("jre"); static final String javaCmd; @@ -69,13 +75,30 @@ static final boolean isDualMode = isSolaris; static final boolean isSparc = System.getProperty("os.arch").startsWith("sparc"); + // make a note of the golden default locale + static final Locale DefaultLocale = Locale.getDefault(); + static final String JAVA_FILE_EXT = ".java"; static final String CLASS_FILE_EXT = ".class"; static final String JAR_FILE_EXT = ".jar"; + static final String JLDEBUG_KEY = "_JAVA_LAUNCHER_DEBUG"; + static final String EXPECTED_MARKER = "TRACER_MARKER:About to EXEC"; static int testExitValue = 0; static { + String tmp = System.getProperty("test.classes", null); + if (tmp == null) { + throw new Error("property test.classes not defined ??"); + } + TEST_CLASSES_DIR = new File(tmp).getAbsoluteFile(); + + tmp = System.getProperty("test.src", null); + if (tmp == null) { + throw new Error("property test.src not defined ??"); + } + TEST_SOURCES_DIR = new File(tmp).getAbsoluteFile(); + if (is64Bit && is32Bit) { throw new RuntimeException("arch model cannot be both 32 and 64 bit"); } @@ -181,6 +204,19 @@ } /* + * A convenience method to compile java files. + */ + static void compile(String... compilerArgs) { + if (compiler.run(null, null, null, compilerArgs) != 0) { + String sarg = ""; + for (String x : compilerArgs) { + sarg.concat(x + " "); + } + throw new Error("compilation failed: " + sarg); + } + } + + /* * A generic jar file creator to create a java file, compile it * and jar it up, a specific Main-Class entry name in the * manifest can be specified or a null to use the sole class file name @@ -239,6 +275,11 @@ Files.copy(src.toPath(), dst.toPath(), COPY_ATTRIBUTES, REPLACE_EXISTING); } + static void createFile(File outFile, List content) throws IOException { + Files.write(outFile.getAbsoluteFile().toPath(), content, + Charset.defaultCharset(), CREATE_NEW); + } + static void recursiveDelete(File target) throws IOException { if (!target.exists()) { return; @@ -321,6 +362,10 @@ }; } + static boolean isEnglishLocale() { + return Locale.getDefault().getLanguage().equals("en"); + } + /* * A class to encapsulate the test results and stuff, with some ease * of use methods to check the test results. diff -r fc06525cb345 -r 5561a4c99825 jdk/test/tools/launcher/UnicodeCleanup.java --- a/jdk/test/tools/launcher/UnicodeCleanup.java Thu Feb 09 18:26:57 2012 +0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. - * 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. - */ - - -/* - * - * - * Used by UnicodeTest.sh. - * - * Recursively deletes the given file/directory and its contents. - * Equivalent to "rm -rf args...", but on NT-based Windows can - * handle files with full Unicode names inside the given directories - * while shells are generally limited to names using the system encoding. - * - * @author Norbert Lindenberg - */ - - - -import java.io.File; - -public class UnicodeCleanup { - - public static void main(String[] args) { - - for (int i = 0; i < args.length; i++) { - delete(new File(args[i])); - } - } - - private static void delete(File file) { - // paranoia is healthy in rm -rf - String name = file.toString(); - if (name.equals(".") || name.equals("..") || - name.endsWith(File.separator + ".") || - name.endsWith(File.separator + "..")) { - throw new RuntimeException("too risky to process: " + name); - } - if (file.isDirectory()) { - File[] contents = file.listFiles(); - for (int i = 0; i < contents.length; i++) { - delete(contents[i]); - } - } - if (!file.delete()) { - throw new RuntimeException("Unable to delete " + file); - } - } -} diff -r fc06525cb345 -r 5561a4c99825 jdk/test/tools/launcher/UnicodeTest.java --- a/jdk/test/tools/launcher/UnicodeTest.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/test/tools/launcher/UnicodeTest.java Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2012, 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,12 +21,18 @@ * questions. */ +/* + * @test + * @bug 5030265 + * @compile -XDignore.symbol.file UnicodeTest.java + * @run main/othervm UnicodeTest + * @summary Verify that the J2RE can handle all legal Unicode characters + * in class names unless limited by the file system encoding + * or the encoding used for command line arguments. + * @author Norbert Lindenberg, ksrini + */ /* - * - * - * Used by UnicodeTest.sh. - * * This class creates Java source files using Unicode characters * that test the limits of what's possible * - in situations where the platform encoding imposes limits @@ -35,38 +41,126 @@ * (file system access in UTF-8 locales and on Windows 2000++, * jar file contents) * - * @author Norbert Lindenberg + * This test needs to be run in othervm as the locale is reset. */ - - +import java.io.File; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.nio.charset.Charset; import java.util.Locale; -public class UnicodeTest { +public class UnicodeTest extends TestHelper { + static final File UnicodeTestSrc = new File("UnicodeTest-src"); + static final File UnicodeTestClasses = new File("UnicodeTest-classes"); + static final String UnicodeTestJarName = "UnicodeTest" + JAR_FILE_EXT; + static final File UnicodeTestJar = new File(UnicodeTestJarName); + static final File SolarisUnicodeTestJar = new File(TEST_SOURCES_DIR, + UnicodeTestJarName); + + /* + * the main method is a port of the shell based test to a java, this + * eliminates the need for MKS on windows, thus we can rely on consistent + * results regardless of the shell being used. + */ + public static void main(String... args) throws Exception { + System.out.println("creating test source files"); + UnicodeTestSrc.mkdirs(); + UnicodeTestClasses.mkdirs(); + String classname = generateSources(); + File javaFile = new File(UnicodeTestSrc, classname + JAVA_FILE_EXT); + System.out.println("building test apps"); + compile("-encoding", "UTF-8", + "-sourcepath", UnicodeTestSrc.getAbsolutePath(), + "-d", UnicodeTestClasses.getAbsolutePath(), + javaFile.getAbsolutePath()); + + createJar("-cvfm", UnicodeTestJar.getAbsolutePath(), + new File(UnicodeTestSrc, "MANIFEST.MF").getAbsolutePath(), + "-C", UnicodeTestClasses.getAbsolutePath(), "."); + + if (!UnicodeTestJar.exists()) { + throw new Error("failed to create " + UnicodeTestJar.getAbsolutePath()); + } + + System.out.println("running test app using class file"); + TestResult tr = doExec(javaCmd, + "-cp", UnicodeTestClasses.getAbsolutePath(), classname); + if (!tr.isOK()) { + System.out.println(tr); + throw new RuntimeException("test fails"); + } + + System.out.println("delete generated files with non-ASCII names"); + recursiveDelete(UnicodeTestSrc); + recursiveDelete(UnicodeTestClasses); + + /* + * test in whatever the default locale is + */ + runJarTests(); - public static void main(String[] args) throws Exception { + /* + * if the Japanese locale is available, test in that locale as well + */ + if (setLocale(Locale.JAPANESE)) { + runJarTests(); + } + + /* + * if we can switch to a C locale, then test whether jar files with + * non-ASCII characters in the manifest still work in this crippled + * environment + */ + if (setLocale(Locale.ENGLISH)) { + runJarTests(); + } + // thats it we are outta here + } + + static void runJarTests() { + System.out.println("running test app using newly built jar file in " + + Locale.getDefault()); + runTest(UnicodeTestJar); + System.out.println("running test app using jar file " + + "(built with Solaris UTF-8 locale) in " + Locale.getDefault()); + runTest(SolarisUnicodeTestJar); + } + + static void runTest(File testJar) { + TestResult tr = doExec(javaCmd, "-jar", testJar.getAbsolutePath()); + if (!tr.isOK()) { + System.out.println(tr); + throw new RuntimeException("test fails"); + } + } + + static boolean setLocale(Locale desired) { + if (Locale.getDefault().equals(desired)) { + return true; // already set nothing more + } + for (Locale l : Locale.getAvailableLocales()) { + if (l == desired) { + Locale.setDefault(l); + return true; + } + } + return false; + } + + static String generateSources() throws Exception { String commandLineClassNameSuffix = commandLineClassNameSuffix(); String commandLineClassName = "ClassA" + commandLineClassNameSuffix; - String manifestClassName; - if (hasUnicodeFileSystem()) { - manifestClassName = "ClassB" + unicode; - } else { - manifestClassName = "ClassB" + commandLineClassNameSuffix; - } + String manifestClassName = "ClassB" + + (hasUnicodeFileSystem() ? unicode : commandLineClassNameSuffix); generateSource(commandLineClassName, manifestClassName); generateSource(manifestClassName, commandLineClassName); generateManifest(manifestClassName); - - System.out.println(commandLineClassName); + return commandLineClassName; } - private static final String fileSeparator = System.getProperty("file.separator"); - private static final String osName = System.getProperty("os.name"); private static final String defaultEncoding = Charset.defaultCharset().name(); // language names taken from java.util.Locale.getDisplayLanguage for the respective language @@ -132,12 +226,7 @@ { "tis-620", thai, null }, }; - int column; - if (osName.startsWith("Windows")) { - column = 2; - } else { - column = 1; - } + int column = isWindows ? 2 : 1; for (int i = 0; i < names.length; i++) { if (names[i][0].equalsIgnoreCase(defaultEncoding)) { return names[i][column]; @@ -147,17 +236,12 @@ } private static boolean hasUnicodeFileSystem() { - if (osName.startsWith("Windows")) { - return ! osName.startsWith("Windows 9") && - ! osName.equals("Windows Me"); - } else { - return defaultEncoding.equalsIgnoreCase("UTF-8"); - } + return (isWindows) ? true : defaultEncoding.equalsIgnoreCase("UTF-8"); } private static void generateSource(String thisClass, String otherClass) throws Exception { - String fileName = "UnicodeTest-src" + fileSeparator + thisClass + ".java"; - OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(fileName), "UTF-8"); + File file = new File(UnicodeTestSrc, thisClass + JAVA_FILE_EXT); + OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(file), "UTF-8"); out.write("public class " + thisClass + " {\n"); out.write(" public static void main(String[] args) {\n"); out.write(" if (!" + otherClass + "." + otherClass.toLowerCase() + "().equals(\"" + otherClass + "\")) {\n"); @@ -172,8 +256,8 @@ } private static void generateManifest(String mainClass) throws Exception { - String fileName = "UnicodeTest-src" + fileSeparator + "MANIFEST.MF"; - FileOutputStream out = new FileOutputStream(fileName); + File file = new File(UnicodeTestSrc, "MANIFEST.MF"); + FileOutputStream out = new FileOutputStream(file); out.write("Manifest-Version: 1.0\n".getBytes("UTF-8")); // Header lines are limited to 72 bytes. // The manifest spec doesn't say we have to break at character boundaries, diff -r fc06525cb345 -r 5561a4c99825 jdk/test/tools/launcher/UnicodeTest.sh --- a/jdk/test/tools/launcher/UnicodeTest.sh Thu Feb 09 18:26:57 2012 +0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,106 +0,0 @@ -# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. - -# @test -# @bug 5030265 -# @summary Verify that the J2RE can handle all legal Unicode characters -# in class names unless limited by the file system encoding -# or the encoding used for command line arguments. -# @author Norbert Lindenberg - - -# Verify directory context variables are set -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 -fi - -if [ "${TESTSRC}" = "" ] -then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 -fi - -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi - -JAVAC="${TESTJAVA}"/bin/javac -JAVA="${TESTJAVA}"/bin/java -JAR="${TESTJAVA}"/bin/jar - -mkdir UnicodeTest-src UnicodeTest-classes - -echo "creating test source files" -"$JAVAC" -d . "${TESTSRC}"/UnicodeTest.java -if [ "`uname -s | grep CYGWIN`" != "" ] ; then - CLASS_NAME=`"$JAVA" UnicodeTest | sed -e 's@\\r@@g' ` -else - CLASS_NAME=`"$JAVA" UnicodeTest` -fi - -if [ "$CLASS_NAME" = "" ] -then - echo "CLASS_NAME not generated. Test failed." - exit 1 -fi - -echo "building test apps" -"$JAVAC" -encoding UTF-8 -sourcepath UnicodeTest-src \ - -d UnicodeTest-classes UnicodeTest-src/"${CLASS_NAME}".java || exit 1 -"$JAR" -cvfm UnicodeTest.jar UnicodeTest-src/MANIFEST.MF \ - -C UnicodeTest-classes . || exit 1 - -echo "running test app using class file" -"$JAVA" -classpath UnicodeTest-classes "$CLASS_NAME" || exit 1 - -echo "delete generated files with non-ASCII names" -# do it now because on Unix they may not be accessible when locale changes -# do it in Java because shells on Windows can't handle full Unicode -"$JAVAC" -d . "${TESTSRC}"/UnicodeCleanup.java || exit 1 -"$JAVA" UnicodeCleanup UnicodeTest-src UnicodeTest-classes || exit 1 - -echo "running test app using newly built jar file" -"$JAVA" -jar UnicodeTest.jar || exit 1 - -echo "running test app using jar file built in Solaris UTF-8 locale" -"$JAVA" -jar "${TESTSRC}"/UnicodeTest.jar || exit 1 - -# if we can switch to a C locale, then test whether jar files with -# non-ASCII characters in the manifest still work in this crippled -# environment -if test -n "`locale -a 2>/dev/null | grep '^C$'`" -then - LC_ALL=C - export LC_ALL - - echo "running test app using newly built jar file in C locale" - "$JAVA" -jar UnicodeTest.jar || exit 1 - - echo "running test app using premade jar file in C locale" - "$JAVA" -jar "${TESTSRC}"/UnicodeTest.jar || exit 1 -fi - -exit 0 - diff -r fc06525cb345 -r 5561a4c99825 jdk/test/tools/launcher/UnresolvedExceptions.java --- a/jdk/test/tools/launcher/UnresolvedExceptions.java Thu Feb 09 18:26:57 2012 +0400 +++ b/jdk/test/tools/launcher/UnresolvedExceptions.java Thu Feb 09 23:17:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 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 @@ -22,15 +22,39 @@ */ /* - * - * - * Used by unresolvedExceptions.sh + * @test + * @bug 4529320 + * @compile -XDignore.symbol.file UnresolvedExceptions.java + * @run main UnresolvedExceptions + * @summary Verifying jvm won't segv if exception not available + * @author Joseph D. Darcy, ksrini */ -public class UnresolvedExceptions { - public static void main(String[] argv) throws SomeException { - // main is invoked from a shell so calling exit won't stop all - // tests. - System.exit(0); +import java.io.File; +import java.util.ArrayList; +import java.util.List; + + +public class UnresolvedExceptions extends TestHelper { + + public static void main(String... args) throws Exception { + final String fname = "Foo"; + List buffer = new ArrayList<>(); + buffer.add("public class " + fname + " {"); + buffer.add(" public static void main(String[] argv) throws " + + "Foo.SomeException {"); + buffer.add(" System.exit(0);"); + buffer.add(" }"); + buffer.add(" static class SomeException extends RuntimeException{}"); + buffer.add("}"); + + File testJavaFile = new File("Foo" + JAVA_FILE_EXT); + createFile(testJavaFile, buffer); + compile(testJavaFile.getName()); + TestResult tr = doExec(javaCmd, "-cp", ".", fname); + if (!tr.isOK()) { + System.out.println(tr); + throw new RuntimeException("java -cp ... failed"); } } +} diff -r fc06525cb345 -r 5561a4c99825 jdk/test/tools/launcher/deleteI18n.sh --- a/jdk/test/tools/launcher/deleteI18n.sh Thu Feb 09 18:26:57 2012 +0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -# -# Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. -# 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. -# - -# -# -# This file is used by test i18nTest.sh; this file is called to use -# shell globbing to delete Java source and class files whose names -# include non-ASCII characters. - - -# Verify directory context variables are set -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 -fi - -if [ "${TESTSRC}" = "" ] -then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 -fi - - -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi - -rm -f i18n*.java -rm -f i18n*.class - - diff -r fc06525cb345 -r 5561a4c99825 jdk/test/tools/launcher/i18nTest.sh --- a/jdk/test/tools/launcher/i18nTest.sh Thu Feb 09 18:26:57 2012 +0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -# -# Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. -# 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 4761384 -# @run shell deleteI18n.sh -# @build CreatePlatformFile -# @run main CreatePlatformFile -# @run shell i18nTest.sh -# @summary Test to see if class files with non-ASCII characters can be run -# @author Joseph D. Darcy - - -# Verify directory context variables are set -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 -fi - -if [ "${TESTSRC}" = "" ] -then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 -fi - - -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi - -JAVAC="${TESTJAVA}/bin/javac -d . " -JAVA="${TESTJAVA}/bin/java -classpath . " - -NAME=`ls i18n*.java | sed s/.java//` -echo $NAME -$JAVAC ${NAME}.java - -RESULT=$? -case "$RESULT" in - 0 ) - ;; - - * ) - echo "Compile of i18n*.java failed." - exit 1 -esac - -$JAVA ${NAME} -RESULT=$? - -case "$RESULT" in - 0 ) - exit 0; - ;; - - * ) - echo "Class $NAME did not run successfully." - exit 1 -esac diff -r fc06525cb345 -r 5561a4c99825 jdk/test/tools/launcher/unresolvedExceptions.sh --- a/jdk/test/tools/launcher/unresolvedExceptions.sh Thu Feb 09 18:26:57 2012 +0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -# -# Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. -# 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 4529320 -# @build SomeException -# @build UnresolvedExceptions -# @clean SomeException -# @run shell/timeout=60 unresolvedExceptions.sh -# @summary Verifying jvm won't segv if exception not available -# @author Joseph D. Darcy - -# Verify directory context variables are set -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 -fi - -if [ "${TESTSRC}" = "" ] -then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 -fi - - -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi - -JAVA="${TESTJAVA}/bin/java" - -$JAVA -classpath ${TESTCLASSES} UnresolvedExceptions -RESULT=$? - -case "$RESULT" in - 0 | 1 ) - exit 0; - ;; - - * ) - exit 1 -esac diff -r fc06525cb345 -r 5561a4c99825 langtools/.hgtags --- a/langtools/.hgtags Thu Feb 09 18:26:57 2012 +0400 +++ b/langtools/.hgtags Thu Feb 09 23:17:22 2012 -0800 @@ -145,3 +145,5 @@ bcb21abf1c4177baf4574f99709513dcd4474727 jdk8-b21 390a7828ae18324030c0546b6452d51093ffa451 jdk8-b22 601ffcc6551d5414ef871be306c3a26396cf16a7 jdk8-b23 +6c9d21ca92c41ff5fcfa76c5b7fafe0f042f4aef jdk8-b24 +520c30f85bb529a3daf5d7623764c2464f00fd19 jdk8-b25 diff -r fc06525cb345 -r 5561a4c99825 langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java --- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Thu Feb 09 18:26:57 2012 +0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Thu Feb 09 23:17:22 2012 -0800 @@ -70,6 +70,7 @@ private JavaCompiler compiler; private Locale locale; private String[] args; + private String[] classNames; private Context context; private List fileObjects; private Map notYetEntered; @@ -82,11 +83,13 @@ JavacTaskImpl(Main compilerMain, String[] args, + String[] classNames, Context context, List fileObjects) { this.ccw = ClientCodeWrapper.instance(context); this.compilerMain = compilerMain; this.args = args; + this.classNames = classNames; this.context = context; this.fileObjects = fileObjects; setLocale(Locale.getDefault()); @@ -101,17 +104,14 @@ Context context, Iterable classes, Iterable fileObjects) { - this(compilerMain, toArray(flags, classes), context, toList(fileObjects)); + this(compilerMain, toArray(flags), toArray(classes), context, toList(fileObjects)); } - static private String[] toArray(Iterable flags, Iterable classes) { + static private String[] toArray(Iterable iter) { ListBuffer result = new ListBuffer(); - if (flags != null) - for (String flag : flags) - result.append(flag); - if (classes != null) - for (String cls : classes) - result.append(cls); + if (iter != null) + for (String s : iter) + result.append(s); return result.toArray(new String[result.length()]); } @@ -129,7 +129,7 @@ initContext(); notYetEntered = new HashMap(); compilerMain.setAPIMode(true); - result = compilerMain.compile(args, context, fileObjects, processors); + result = compilerMain.compile(args, classNames, context, fileObjects, processors); cleanup(); return result.isOK(); } else { @@ -159,7 +159,7 @@ initContext(); compilerMain.setOptions(Options.instance(context)); compilerMain.filenames = new LinkedHashSet(); - Collection filenames = compilerMain.processArgs(CommandLine.parse(args)); + Collection filenames = compilerMain.processArgs(CommandLine.parse(args), classNames); if (!filenames.isEmpty()) throw new IllegalArgumentException("Malformed arguments " + toString(filenames, " ")); compiler = JavaCompiler.instance(context); @@ -174,6 +174,7 @@ // endContext will be called when all classes have been generated // TODO: should handle the case after each phase if errors have occurred args = null; + classNames = null; } } @@ -204,6 +205,7 @@ compiler = null; compilerMain = null; args = null; + classNames = null; context = null; fileObjects = null; notYetEntered = null; diff -r fc06525cb345 -r 5561a4c99825 langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Thu Feb 09 18:26:57 2012 +0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Thu Feb 09 23:17:22 2012 -0800 @@ -34,6 +34,7 @@ import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.Type.ForAll.ConstraintKind; import com.sun.tools.javac.code.Symbol.*; +import com.sun.tools.javac.comp.Resolve.InapplicableMethodException; import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; @@ -84,7 +85,7 @@ } - public static class InferenceException extends Resolve.InapplicableMethodException { + public static class InferenceException extends InapplicableMethodException { private static final long serialVersionUID = 0; InferenceException(JCDiagnostic.Factory diags) { @@ -287,6 +288,18 @@ } } + Type asUndetType(Type t, List undetvars) { + return types.subst(t, inferenceVars(undetvars), undetvars); + } + + List inferenceVars(List undetvars) { + ListBuffer tvars = ListBuffer.lb(); + for (Type uv : undetvars) { + tvars.append(((UndetVar)uv).qtype); + } + return tvars.toList(); + } + /*************************************************************************** * Exported Methods ***************************************************************************/ @@ -372,62 +385,11 @@ final Warner warn) throws InferenceException { //-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG List undetvars = Type.map(tvars, fromTypeVarFun); - List formals = mt.argtypes; - //need to capture exactly once - otherwise subsequent - //applicability checks might fail - final List capturedArgs = types.capture(argtypes); - List actuals = capturedArgs; - List actualsNoCapture = argtypes; - // instantiate all polymorphic argument types and - // set up lower bounds constraints for undetvars - Type varargsFormal = useVarargs ? formals.last() : null; - if (varargsFormal == null && - actuals.size() != formals.size()) { - throw unambiguousNoInstanceException - .setMessage("infer.arg.length.mismatch"); - } - while (actuals.nonEmpty() && formals.head != varargsFormal) { - Type formal = formals.head; - Type actual = actuals.head.baseType(); - Type actualNoCapture = actualsNoCapture.head.baseType(); - if (actual.tag == FORALL) - actual = instantiateArg((ForAll)actual, formal, tvars, warn); - Type undetFormal = types.subst(formal, tvars, undetvars); - boolean works = allowBoxing - ? types.isConvertible(actual, undetFormal, warn) - : types.isSubtypeUnchecked(actual, undetFormal, warn); - if (!works) { - throw unambiguousNoInstanceException - .setMessage("infer.no.conforming.assignment.exists", - tvars, actualNoCapture, formal); - } - formals = formals.tail; - actuals = actuals.tail; - actualsNoCapture = actualsNoCapture.tail; - } + //final List capturedArgs = types.capture(argtypes); - if (formals.head != varargsFormal) // not enough args - throw unambiguousNoInstanceException.setMessage("infer.arg.length.mismatch"); - - // for varargs arguments as well - if (useVarargs) { - Type elemType = types.elemtype(varargsFormal); - Type elemUndet = types.subst(elemType, tvars, undetvars); - while (actuals.nonEmpty()) { - Type actual = actuals.head.baseType(); - Type actualNoCapture = actualsNoCapture.head.baseType(); - if (actual.tag == FORALL) - actual = instantiateArg((ForAll)actual, elemType, tvars, warn); - boolean works = types.isConvertible(actual, elemUndet, warn); - if (!works) { - throw unambiguousNoInstanceException - .setMessage("infer.no.conforming.assignment.exists", - tvars, actualNoCapture, elemType); - } - actuals = actuals.tail; - actualsNoCapture = actualsNoCapture.tail; - } - } + final List capturedArgs = + rs.checkRawArgumentsAcceptable(env, undetvars, argtypes, mt.getParameterTypes(), + allowBoxing, useVarargs, warn, new InferenceCheckHandler(undetvars)); // minimize as yet undetermined type variables for (Type t : undetvars) @@ -503,6 +465,31 @@ } //where + /** inference check handler **/ + class InferenceCheckHandler implements Resolve.MethodCheckHandler { + + List undetvars; + + public InferenceCheckHandler(List undetvars) { + this.undetvars = undetvars; + } + + public InapplicableMethodException arityMismatch() { + return unambiguousNoInstanceException.setMessage("infer.arg.length.mismatch"); + } + public InapplicableMethodException argumentMismatch(boolean varargs, Type found, Type expected) { + String key = varargs ? + "infer.varargs.argument.mismatch" : + "infer.no.conforming.assignment.exists"; + return unambiguousNoInstanceException.setMessage(key, + inferenceVars(undetvars), found, expected); + } + public InapplicableMethodException inaccessibleVarargs(Symbol location, Type expected) { + return unambiguousNoInstanceException.setMessage("inaccessible.varargs.type", + expected, Kinds.kindName(location), location); + } + } + /** * A delegated type representing a partially uninferred method type. * The return type of a partially uninferred method type is a ForAll @@ -572,7 +559,7 @@ rs.checkRawArgumentsAcceptable(env, actuals, formals, allowBoxing, useVarargs, warn); } - catch (Resolve.InapplicableMethodException ex) { + catch (InapplicableMethodException ex) { // inferred method is not applicable throw invalidInstanceException.setMessage(ex.getDiagnostic()); } diff -r fc06525cb345 -r 5561a4c99825 langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Thu Feb 09 18:26:57 2012 +0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Thu Feb 09 23:17:22 2012 -0800 @@ -44,6 +44,7 @@ import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.TypeTags.*; import static com.sun.tools.javac.tree.JCTree.Tag.*; +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; /** This is the second phase of Enter, in which classes are completed @@ -142,7 +143,7 @@ JCDiagnostic msg = diags.fragment("fatal.err.no.java.lang"); throw new FatalError(msg); } else { - log.error(pos, "doesnt.exist", tsym); + log.error(DiagnosticFlag.RESOLVE_ERROR, pos, "doesnt.exist", tsym); } } env.toplevel.starImportScope.importAll(tsym.members()); diff -r fc06525cb345 -r 5561a4c99825 langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Feb 09 18:26:57 2012 +0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Feb 09 23:17:22 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 @@ -474,52 +474,126 @@ return false; } } + /** + * A check handler is used by the main method applicability routine in order + * to handle specific method applicability failures. It is assumed that a class + * implementing this interface should throw exceptions that are a subtype of + * InapplicableMethodException (see below). Such exception will terminate the + * method applicability check and propagate important info outwards (for the + * purpose of generating better diagnostics). + */ + interface MethodCheckHandler { + /* The number of actuals and formals differ */ + InapplicableMethodException arityMismatch(); + /* An actual argument type does not conform to the corresponding formal type */ + InapplicableMethodException argumentMismatch(boolean varargs, Type found, Type expected); + /* The element type of a varargs is not accessible in the current context */ + InapplicableMethodException inaccessibleVarargs(Symbol location, Type expected); + } + + /** + * Basic method check handler used within Resolve - all methods end up + * throwing InapplicableMethodException; a diagnostic fragment that describes + * the cause as to why the method is not applicable is set on the exception + * before it is thrown. + */ + MethodCheckHandler resolveHandler = new MethodCheckHandler() { + public InapplicableMethodException arityMismatch() { + return inapplicableMethodException.setMessage("arg.length.mismatch"); + } + public InapplicableMethodException argumentMismatch(boolean varargs, Type found, Type expected) { + String key = varargs ? + "varargs.argument.mismatch" : + "no.conforming.assignment.exists"; + return inapplicableMethodException.setMessage(key, + found, expected); + } + public InapplicableMethodException inaccessibleVarargs(Symbol location, Type expected) { + return inapplicableMethodException.setMessage("inaccessible.varargs.type", + expected, Kinds.kindName(location), location); + } + }; + void checkRawArgumentsAcceptable(Env env, List argtypes, List formals, boolean allowBoxing, boolean useVarargs, Warner warn) { + checkRawArgumentsAcceptable(env, List.nil(), argtypes, formals, + allowBoxing, useVarargs, warn, resolveHandler); + } + + /** + * Main method applicability routine. Given a list of actual types A, + * a list of formal types F, determines whether the types in A are + * compatible (by method invocation conversion) with the types in F. + * + * Since this routine is shared between overload resolution and method + * type-inference, it is crucial that actual types are converted to the + * corresponding 'undet' form (i.e. where inference variables are replaced + * with undetvars) so that constraints can be propagated and collected. + * + * Moreover, if one or more types in A is a poly type, this routine calls + * Infer.instantiateArg in order to complete the poly type (this might involve + * deferred attribution). + * + * A method check handler (see above) is used in order to report errors. + */ + List checkRawArgumentsAcceptable(Env env, + List undetvars, + List argtypes, + List formals, + boolean allowBoxing, + boolean useVarargs, + Warner warn, + MethodCheckHandler handler) { Type varargsFormal = useVarargs ? formals.last() : null; + ListBuffer checkedArgs = ListBuffer.lb(); + if (varargsFormal == null && argtypes.size() != formals.size()) { - throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args + throw handler.arityMismatch(); // not enough args } while (argtypes.nonEmpty() && formals.head != varargsFormal) { - boolean works = allowBoxing - ? types.isConvertible(argtypes.head, formals.head, warn) - : types.isSubtypeUnchecked(argtypes.head, formals.head, warn); - if (!works) - throw inapplicableMethodException.setMessage("no.conforming.assignment.exists", - argtypes.head, - formals.head); + Type undetFormal = infer.asUndetType(formals.head, undetvars); + Type capturedActual = types.capture(argtypes.head); + boolean works = allowBoxing ? + types.isConvertible(capturedActual, undetFormal, warn) : + types.isSubtypeUnchecked(capturedActual, undetFormal, warn); + if (!works) { + throw handler.argumentMismatch(false, argtypes.head, formals.head); + } + checkedArgs.append(capturedActual); argtypes = argtypes.tail; formals = formals.tail; } - if (formals.head != varargsFormal) - throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args + if (formals.head != varargsFormal) { + throw handler.arityMismatch(); // not enough args + } if (useVarargs) { + //note: if applicability check is triggered by most specific test, + //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5) Type elt = types.elemtype(varargsFormal); + Type eltUndet = infer.asUndetType(elt, undetvars); while (argtypes.nonEmpty()) { - if (!types.isConvertible(argtypes.head, elt, warn)) - throw inapplicableMethodException.setMessage("varargs.argument.mismatch", - argtypes.head, - elt); + Type capturedActual = types.capture(argtypes.head); + if (!types.isConvertible(capturedActual, eltUndet, warn)) { + throw handler.argumentMismatch(true, argtypes.head, elt); + } + checkedArgs.append(capturedActual); argtypes = argtypes.tail; } //check varargs element type accessibility - if (!isAccessible(env, elt)) { + if (undetvars.isEmpty() && !isAccessible(env, elt)) { Symbol location = env.enclClass.sym; - throw inapplicableMethodException.setMessage("inaccessible.varargs.type", - elt, - Kinds.kindName(location), - location); + throw handler.inaccessibleVarargs(location, elt); } } - return; + return checkedArgs.toList(); } // where public static class InapplicableMethodException extends RuntimeException { diff -r fc06525cb345 -r 5561a4c99825 langtools/src/share/classes/com/sun/tools/javac/main/Main.java --- a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java Thu Feb 09 18:26:57 2012 +0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java Thu Feb 09 23:17:22 2012 -0800 @@ -31,6 +31,7 @@ import java.net.URL; import java.security.DigestInputStream; import java.security.MessageDigest; +import java.util.Arrays; import java.util.Collection; import java.util.LinkedHashSet; import java.util.Set; @@ -208,6 +209,10 @@ * @param flags The array of command line arguments. */ public Collection processArgs(String[] flags) { // XXX sb protected + return processArgs(flags, null); + } + + public Collection processArgs(String[] flags, String[] classNames) { // XXX sb protected int ac = 0; while (ac < flags.length) { String flag = flags[ac]; @@ -248,6 +253,10 @@ } } + if (this.classnames != null && classNames != null) { + this.classnames.addAll(Arrays.asList(classNames)); + } + if (!checkDirectory(D)) return null; if (!checkDirectory(S)) @@ -346,6 +355,15 @@ List fileObjects, Iterable processors) { + return compile(args, null, context, fileObjects, processors); + } + + public Result compile(String[] args, + String[] classNames, + Context context, + List fileObjects, + Iterable processors) + { context.put(Log.outKey, out); log = Log.instance(context); @@ -361,14 +379,16 @@ * into account. */ try { - if (args.length == 0 && fileObjects.isEmpty()) { + if (args.length == 0 + && (classNames == null || classNames.length == 0) + && fileObjects.isEmpty()) { Option.HELP.process(optionHelper, "-help"); return Result.CMDERR; } Collection files; try { - files = processArgs(CommandLine.parse(args)); + files = processArgs(CommandLine.parse(args), classNames); if (files == null) { // null signals an error in options, abort return Result.CMDERR; diff -r fc06525cb345 -r 5561a4c99825 langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Feb 09 18:26:57 2012 +0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Feb 09 23:17:22 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 @@ -1620,6 +1620,10 @@ compiler.misc.infer.arg.length.mismatch=\ cannot instantiate from arguments because actual and formal argument lists differ in length +# 0: list of type, 1: type, 2: type +compiler.misc.infer.varargs.argument.mismatch=\ + no instance(s) of type variable(s) {0} exist so that argument type {1} conforms to vararg element type {2} + # 0: type, 1: list of type compiler.misc.inferred.do.not.conform.to.bounds=\ inferred type does not conform to declared bound(s)\n\ diff -r fc06525cb345 -r 5561a4c99825 langtools/test/tools/javac/7129225/Anno.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/7129225/Anno.java Thu Feb 09 23:17:22 2012 -0800 @@ -0,0 +1,31 @@ +/* + * 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. + */ + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +public @interface Anno { +} diff -r fc06525cb345 -r 5561a4c99825 langtools/test/tools/javac/7129225/AnnoProcessor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/7129225/AnnoProcessor.java Thu Feb 09 23:17:22 2012 -0800 @@ -0,0 +1,45 @@ +/* + * 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. + */ + +import java.util.Set; +import javax.annotation.processing.*; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.TypeElement; +import javax.tools.Diagnostic.Kind; + +@SupportedAnnotationTypes("Anno") +public class AnnoProcessor extends JavacTestingAbstractProcessor { + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + @Override + public boolean process(Set set, RoundEnvironment re) { + messager.printMessage(Kind.NOTE, "RUNNING - lastRound = " + re.processingOver()); + return true; + } +} + diff -r fc06525cb345 -r 5561a4c99825 langtools/test/tools/javac/7129225/NegTest.ref --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/7129225/NegTest.ref Thu Feb 09 23:17:22 2012 -0800 @@ -0,0 +1,2 @@ +TestImportStar.java:39:1: compiler.err.doesnt.exist: xxx +1 error diff -r fc06525cb345 -r 5561a4c99825 langtools/test/tools/javac/7129225/TestImportStar.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/7129225/TestImportStar.java Thu Feb 09 23:17:22 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. + */ + +/* @test + * @bug 7129225 + * @summary import xxx.* isn't handled correctly by annotation processing + * @library ../lib + * @build JavacTestingAbstractProcessor + * @compile/fail/ref=NegTest.ref -XDrawDiagnostics TestImportStar.java + * @compile Anno.java AnnoProcessor.java + * @compile/ref=TestImportStar.ref -XDrawDiagnostics -processor AnnoProcessor -proc:only TestImportStar.java + */ + + //The @compile/fail... verifies that the fix doesn't break the normal compilation of import xxx.* + //The @comple/ref... verifies the fix fixes the bug + +import xxx.*; + +@Anno +public class TestImportStar { +} diff -r fc06525cb345 -r 5561a4c99825 langtools/test/tools/javac/7129225/TestImportStar.ref --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/7129225/TestImportStar.ref Thu Feb 09 23:17:22 2012 -0800 @@ -0,0 +1,3 @@ +- compiler.note.proc.messager: RUNNING - lastRound = false +TestImportStar.java:39:1: compiler.err.doesnt.exist: xxx +- compiler.note.proc.messager: RUNNING - lastRound = true diff -r fc06525cb345 -r 5561a4c99825 langtools/test/tools/javac/diags/examples/InferVarargsArgumentMismatch.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/InferVarargsArgumentMismatch.java Thu Feb 09 23:17:22 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. + */ + +// key: compiler.err.cant.apply.symbol.1 +// key: compiler.misc.infer.varargs.argument.mismatch + +class InferVarargsArgumentMismatch { + void m(X x1, String... xs) {} + { this.m("", 1); } +} diff -r fc06525cb345 -r 5561a4c99825 langtools/test/tools/javah/T7126832/T7126832.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javah/T7126832/T7126832.java Thu Feb 09 23:17:22 2012 -0800 @@ -0,0 +1,107 @@ +/* + * 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 7126832 + * @compile java.java + * @summary com.sun.tools.javac.api.ClientCodeWrapper$WrappedJavaFileManager cannot be cast + * @run main T7126832 + */ + +import java.io.*; +import java.util.*; + +public class T7126832 { + public static void main(String... args) throws Exception { + new T7126832().run(); + } + + void run() throws Exception { + Locale prev = Locale.getDefault(); + Locale.setDefault(Locale.ENGLISH); + try { + // Verify that a .java file is correctly diagnosed + File ff = writeFile(new File("JavahTest.java"), "class JavahTest {}"); + test(Arrays.asList(ff.getPath()), 1, "Could not find class file for 'JavahTest.java'."); + + // Verify that a class named 'xx.java' is accepted. + // Note that ./xx/java.class exists, so this should work ok + test(Arrays.asList("xx.java"), 0, null); + + if (errors > 0) { + throw new Exception(errors + " errors occurred"); + } + } finally { + Locale.setDefault(prev); + } + } + + void test(List args, int expectRC, String expectOut) { + System.err.println("Test: " + args + + " rc:" + expectRC + + ((expectOut != null) ? " out:" + expectOut : "")); + + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + int rc = 0; + String out = null; + try { + rc = com.sun.tools.javah.Main.run(args.toArray(new String[args.size()]), pw); + out = sw.toString(); + } catch(Exception ee) { + rc = 1; + out = ee.toString();; + } + pw.close(); + if (!out.isEmpty()) { + System.err.println(out); + } + if (rc != expectRC) { + error("Unexpected exit code: " + rc + "; expected: " + expectRC); + } + if (expectOut != null && !out.contains(expectOut)) { + error("Expected string not found: " + expectOut); + } + + System.err.println(); + } + + File writeFile(File ff, String ss) throws IOException { + if (ff.getParentFile() != null) + ff.getParentFile().mkdirs(); + + try (FileWriter out = new FileWriter(ff)) { + out.write(ss); + } + return ff; + } + + void error(String msg) { + System.err.println(msg); + errors++; + } + + int errors; +} + diff -r fc06525cb345 -r 5561a4c99825 langtools/test/tools/javah/T7126832/java.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javah/T7126832/java.java Thu Feb 09 23:17:22 2012 -0800 @@ -0,0 +1,27 @@ +/* + * 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 xx; +class java { + int fred; +} diff -r fc06525cb345 -r 5561a4c99825 make/jprt.properties --- a/make/jprt.properties Thu Feb 09 18:26:57 2012 +0400 +++ b/make/jprt.properties Thu Feb 09 23:17:22 2012 -0800 @@ -63,19 +63,33 @@ # Default jdk test targets (testset=default) jprt.make.rule.default.test.targets= \ - ${jprt.my.test.target.set:TESTNAME=langtools_jtreg}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_beans1}, \ + ${jprt.my.test.target.set:TESTNAME=langtools_jtreg}, \ + ${jprt.my.test.target.set:TESTNAME=jdk_lang}, \ + ${jprt.my.test.target.set:TESTNAME=jdk_math} + +# Default vm test targets (testset=core) +jprt.vm.core.test.targets= \ + ${jprt.vm.default.test.targets} + +# Core jdk test targets (testset=core) +jprt.make.rule.core.test.targets= \ + ${jprt.make.rule.default.test.targets}, \ + ${jprt.my.test.target.set:TESTNAME=jdk_util}, \ ${jprt.my.test.target.set:TESTNAME=jdk_io}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_lang}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_math}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_misc}, \ ${jprt.my.test.target.set:TESTNAME=jdk_net}, \ ${jprt.my.test.target.set:TESTNAME=jdk_nio1}, \ ${jprt.my.test.target.set:TESTNAME=jdk_nio2}, \ ${jprt.my.test.target.set:TESTNAME=jdk_nio3}, \ ${jprt.my.test.target.set:TESTNAME=jdk_security1}, \ + ${jprt.my.test.target.set:TESTNAME=jdk_security2}, \ + ${jprt.my.test.target.set:TESTNAME=jdk_security3}, \ + ${jprt.my.test.target.set:TESTNAME=jdk_rmi}, \ + ${jprt.my.test.target.set:TESTNAME=jdk_management1}, \ + ${jprt.my.test.target.set:TESTNAME=jdk_management2}, \ ${jprt.my.test.target.set:TESTNAME=jdk_text}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_util} + ${jprt.my.test.target.set:TESTNAME=jdk_tools1}, \ + ${jprt.my.test.target.set:TESTNAME=jdk_tools2}, \ + ${jprt.my.test.target.set:TESTNAME=jdk_misc} # All vm test targets (testset=all) jprt.vm.all.test.targets= \ @@ -85,19 +99,13 @@ # All jdk test targets (testset=all) jprt.make.rule.all.test.targets= \ - ${jprt.make.rule.default.test.targets}, \ + ${jprt.make.rule.core.test.targets}, \ ${jprt.my.test.target.set:TESTNAME=jdk_awt}, \ + ${jprt.my.test.target.set:TESTNAME=jdk_beans1}, \ ${jprt.my.test.target.set:TESTNAME=jdk_beans2}, \ ${jprt.my.test.target.set:TESTNAME=jdk_beans3}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_management1}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_management2}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_rmi}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_security2}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_security3}, \ ${jprt.my.test.target.set:TESTNAME=jdk_sound}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_swing}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_tools1}, \ - ${jprt.my.test.target.set:TESTNAME=jdk_tools2} + ${jprt.my.test.target.set:TESTNAME=jdk_swing} # JCK test targets in test/Makefile (no windows) jprt.my.jck.test.target.set= \