OpenJDK / jdk / jdk
changeset 11804:63a73915b4d4
Merge
author | lana |
---|---|
date | Thu, 09 Feb 2012 19:42:39 -0800 |
parents | ac4685ac7cbd 6c805d8ed4e5 |
children | f9020c5bf51d |
files | jdk/test/tools/launcher/ChangeDataModel.sh jdk/test/tools/launcher/CreatePlatformFile.java jdk/test/tools/launcher/SomeException.java jdk/test/tools/launcher/UnicodeCleanup.java jdk/test/tools/launcher/UnicodeTest.sh jdk/test/tools/launcher/deleteI18n.sh jdk/test/tools/launcher/i18nTest.sh jdk/test/tools/launcher/unresolvedExceptions.sh |
diffstat | 257 files changed, 10221 insertions(+), 3863 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Fri Feb 03 09:57:45 2012 -0800 +++ b/.hgtags Thu Feb 09 19:42:39 2012 -0800 @@ -145,3 +145,5 @@ b3a426170188f52981cf4573a2f14d487fddab0d jdk8-b21 e8f03541af27e38aafb619b96863e17f65ffe53b jdk8-b22 498124337041ad53cbaa7eb110f3d7acd6d4eac4 jdk8-b23 +7d3720d8c595d1519c31e9ff7366203fc2c61350 jdk8-b24 +0071a6d64113a35ba345bb1580c256de5ce17d3e jdk8-b25
--- a/.hgtags-top-repo Fri Feb 03 09:57:45 2012 -0800 +++ b/.hgtags-top-repo Thu Feb 09 19:42:39 2012 -0800 @@ -145,3 +145,5 @@ cc771d92284f71765eca14d6d08703c4af254c04 jdk8-b21 7ad075c809952e355d25030605da6af30456ed74 jdk8-b22 60d6f64a86b1e511169d264727f6d51415978df0 jdk8-b23 +1a5f1d6b98d6827cdb529a4abe6e52a886d944f4 jdk8-b24 +221a378e06a326f45e5d89e2123cd6323e0181d1 jdk8-b25
--- a/corba/.hgtags Fri Feb 03 09:57:45 2012 -0800 +++ b/corba/.hgtags Thu Feb 09 19:42:39 2012 -0800 @@ -145,3 +145,5 @@ f157fc2a71a38ce44007a6f18d5b011824dce705 jdk8-b21 a11d0062c445d5f36651c78650ab88aa594bcbff jdk8-b22 5218eb256658442b62b05295aafa5b5f35252972 jdk8-b23 +b98f0e6dddf987df565029a1f58417fc1844c3f3 jdk8-b24 +e45d6b406d5f91ff5256a5c82456ab1e7eb8becd jdk8-b25
--- a/hotspot/.hgtags Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/.hgtags Thu Feb 09 19:42:39 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
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/LoaderConstraintTable.java Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/LoaderConstraintTable.java Thu Feb 09 19:42:39 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) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/SystemDictionary.java Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/SystemDictionary.java Thu Feb 09 19:42:39 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); }
--- a/hotspot/make/Makefile Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/Makefile Thu Feb 09 19:42:39 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
--- a/hotspot/make/bsd/makefiles/adlc.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/bsd/makefiles/adlc.make Thu Feb 09 19:42:39 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) # #########################################################################
--- a/hotspot/make/bsd/makefiles/defs.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/bsd/makefiles/defs.make Thu Feb 09 19:42:39 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_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) + # Universal settings + ifeq ($(MACOSX_UNIVERSAL), true) + + # 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
--- a/hotspot/make/bsd/makefiles/dtrace.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/bsd/makefiles/dtrace.make Thu Feb 09 19:42:39 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 $@
--- a/hotspot/make/bsd/makefiles/gcc.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/bsd/makefiles/gcc.make Thu Feb 09 19:42:39 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
--- a/hotspot/make/bsd/makefiles/launcher.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/bsd/makefiles/launcher.make Thu Feb 09 19:42:39 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...
--- a/hotspot/make/bsd/makefiles/product.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/bsd/makefiles/product.make Thu Feb 09 19:42:39 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))
--- a/hotspot/make/bsd/makefiles/rules.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/bsd/makefiles/rules.make Thu Feb 09 19:42:39 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
--- a/hotspot/make/bsd/makefiles/sparcWorks.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/bsd/makefiles/sparcWorks.make Thu Feb 09 19:42:39 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))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/make/bsd/makefiles/universal.gmk Thu Feb 09 19:42:39 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
--- a/hotspot/make/bsd/makefiles/vm.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/bsd/makefiles/vm.make Thu Feb 09 19:42:39 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; }; \ }
--- a/hotspot/make/defs.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/defs.make Thu Feb 09 19:42:39 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
--- a/hotspot/make/hotspot_version Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/hotspot_version Thu Feb 09 19:42:39 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
--- a/hotspot/make/jprt.properties Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/jprt.properties Thu Feb 09 19:42:39 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, \
--- a/hotspot/make/linux/makefiles/adlc.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/linux/makefiles/adlc.make Thu Feb 09 19:42:39 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) # #########################################################################
--- a/hotspot/make/linux/makefiles/gcc.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/linux/makefiles/gcc.make Thu Feb 09 19:42:39 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
--- a/hotspot/make/linux/makefiles/launcher.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/linux/makefiles/launcher.make Thu Feb 09 19:42:39 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...
--- a/hotspot/make/linux/makefiles/product.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/linux/makefiles/product.make Thu Feb 09 19:42:39 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))
--- a/hotspot/make/linux/makefiles/rules.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/linux/makefiles/rules.make Thu Feb 09 19:42:39 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
--- a/hotspot/make/linux/makefiles/sparcWorks.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/linux/makefiles/sparcWorks.make Thu Feb 09 19:42:39 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))
--- a/hotspot/make/linux/makefiles/vm.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/linux/makefiles/vm.make Thu Feb 09 19:42:39 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 \
--- a/hotspot/make/solaris/makefiles/adlc.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/solaris/makefiles/adlc.make Thu Feb 09 19:42:39 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) # #########################################################################
--- a/hotspot/make/solaris/makefiles/dtrace.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/solaris/makefiles/dtrace.make Thu Feb 09 19:42:39 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 $@
--- a/hotspot/make/solaris/makefiles/gcc.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/solaris/makefiles/gcc.make Thu Feb 09 19:42:39 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)
--- a/hotspot/make/solaris/makefiles/launcher.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/solaris/makefiles/launcher.make Thu Feb 09 19:42:39 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)),)
--- a/hotspot/make/solaris/makefiles/product.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/solaris/makefiles/product.make Thu Feb 09 19:42:39 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
--- a/hotspot/make/solaris/makefiles/rules.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/solaris/makefiles/rules.make Thu Feb 09 19:42:39 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
--- a/hotspot/make/solaris/makefiles/saproc.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/solaris/makefiles/saproc.make Thu Feb 09 19:42:39 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) \
--- a/hotspot/make/solaris/makefiles/sparcWorks.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/solaris/makefiles/sparcWorks.make Thu Feb 09 19:42:39 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.
--- a/hotspot/make/solaris/makefiles/vm.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/solaris/makefiles/vm.make Thu Feb 09 19:42:39 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
--- a/hotspot/make/windows/build_vm_def.sh Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/windows/build_vm_def.sh Thu Feb 09 19:42:39 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
--- a/hotspot/make/windows/get_msc_ver.sh Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/windows/get_msc_ver.sh Thu Feb 09 19:42:39 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
--- a/hotspot/make/windows/makefiles/adlc.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/windows/makefiles/adlc.make Thu Feb 09 19:42:39 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
--- a/hotspot/make/windows/makefiles/compile.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/windows/makefiles/compile.make Thu Feb 09 19:42:39 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
--- a/hotspot/make/windows/makefiles/debug.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/windows/makefiles/debug.make Thu Feb 09 19:42:39 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
--- a/hotspot/make/windows/makefiles/fastdebug.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/windows/makefiles/fastdebug.make Thu Feb 09 19:42:39 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
--- a/hotspot/make/windows/makefiles/launcher.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/windows/makefiles/launcher.make Thu Feb 09 19:42:39 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 $**
--- a/hotspot/make/windows/makefiles/product.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/windows/makefiles/product.make Thu Feb 09 19:42:39 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)" != ""
--- a/hotspot/make/windows/makefiles/projectcreator.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/windows/makefiles/projectcreator.make Thu Feb 09 19:42:39 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 \
--- a/hotspot/make/windows/makefiles/sa.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/windows/makefiles/sa.make Thu Feb 09 19:42:39 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
--- a/hotspot/make/windows/makefiles/sanity.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/windows/makefiles/sanity.make Thu Feb 09 19:42:39 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.
--- a/hotspot/make/windows/makefiles/shared.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/windows/makefiles/shared.make Thu Feb 09 19:42:39 2012 -0800 @@ -30,8 +30,8 @@ DIR=. !endif -!ifndef CPP -CPP=cl.exe +!ifndef CXX +CXX=cl.exe !endif
--- a/hotspot/make/windows/makefiles/vm.make Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/make/windows/makefiles/vm.make Thu Feb 09 19:42:39 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
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Thu Feb 09 19:42:39 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
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp Thu Feb 09 19:42:39 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) {
--- a/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp Thu Feb 09 19:42:39 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");
--- a/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp Thu Feb 09 19:42:39 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);
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp Thu Feb 09 19:42:39 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"
--- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Thu Feb 09 19:42:39 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) {
--- a/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp Thu Feb 09 19:42:39 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?
--- a/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp Thu Feb 09 19:42:39 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);
--- a/hotspot/src/cpu/x86/vm/frame_x86.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp Thu Feb 09 19:42:39 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"
--- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp Thu Feb 09 19:42:39 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); } }
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Thu Feb 09 19:42:39 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; }
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Feb 09 19:42:39 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; }
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Thu Feb 09 19:42:39 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
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Thu Feb 09 19:42:39 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);
--- a/hotspot/src/os/windows/vm/os_windows.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/os/windows/vm/os_windows.cpp Thu Feb 09 19:42:39 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 -
--- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Thu Feb 09 19:42:39 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
--- a/hotspot/src/share/tools/ProjectCreator/BuildConfig.java Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/tools/ProjectCreator/BuildConfig.java Thu Feb 09 19:42:39 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\\\"");
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Thu Feb 09 19:42:39 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; } } }
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp Thu Feb 09 19:42:39 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
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp Thu Feb 09 19:42:39 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
--- a/hotspot/src/share/vm/c1/c1_ValueMap.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/c1/c1_ValueMap.cpp Thu Feb 09 19:42:39 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;
--- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp Thu Feb 09 19:42:39 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(); }
--- a/hotspot/src/share/vm/ci/ciEnv.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/ci/ciEnv.hpp Thu Feb 09 19:42:39 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; }
--- a/hotspot/src/share/vm/classfile/dictionary.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/classfile/dictionary.cpp Thu Feb 09 19:42:39 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");
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Thu Feb 09 19:42:39 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);
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp Thu Feb 09 19:42:39 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;
--- a/hotspot/src/share/vm/code/compiledIC.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/code/compiledIC.cpp Thu Feb 09 19:42:39 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
--- a/hotspot/src/share/vm/code/nmethod.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/code/nmethod.cpp Thu Feb 09 19:42:39 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);
--- a/hotspot/src/share/vm/code/nmethod.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/code/nmethod.hpp Thu Feb 09 19:42:39 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; }
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Thu Feb 09 19:42:39 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<CompilerThread*>* 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();
--- a/hotspot/src/share/vm/compiler/compileBroker.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/compiler/compileBroker.hpp Thu Feb 09 19:42:39 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);
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Feb 09 19:42:39 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,
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Feb 09 19:42:39 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 &&
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Thu Feb 09 19:42:39 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");
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Thu Feb 09 19:42:39 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");
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Thu Feb 09 19:42:39 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()); } -
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Thu Feb 09 19:42:39 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();
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp Thu Feb 09 19:42:39 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<GCMessage>::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() {
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp Thu Feb 09 19:42:39 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<GCMessage> { + private: + void log_heap(bool before); + + public: + GCHeapLog() : EventLogBase<GCMessage>("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;
--- a/hotspot/src/share/vm/memory/gcLocker.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/memory/gcLocker.cpp Thu Feb 09 19:42:39 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(); } }
--- a/hotspot/src/share/vm/memory/gcLocker.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/memory/gcLocker.hpp Thu Feb 09 19:42:39 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; - } + // 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 clear_needs_gc() { - assert_lock_strong(JNICritical_lock); - _needs_gc = false; - } - - 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; } };
--- a/hotspot/src/share/vm/memory/gcLocker.inline.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/memory/gcLocker.inline.hpp Thu Feb 09 19:42:39 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
--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp Thu Feb 09 19:42:39 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();
--- a/hotspot/src/share/vm/memory/genMarkSweep.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/memory/genMarkSweep.cpp Thu Feb 09 19:42:39 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");
--- a/hotspot/src/share/vm/oops/arrayOop.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/oops/arrayOop.cpp Thu Feb 09 19:42:39 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) {
--- a/hotspot/src/share/vm/oops/constantPoolOop.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/oops/constantPoolOop.cpp Thu Feb 09 19:42:39 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)) {
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Thu Feb 09 19:42:39 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);
--- a/hotspot/src/share/vm/oops/klass.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/oops/klass.cpp Thu Feb 09 19:42:39 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);
--- a/hotspot/src/share/vm/oops/klass.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/oops/klass.hpp Thu Feb 09 19:42:39 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(
--- a/hotspot/src/share/vm/oops/methodOop.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/oops/methodOop.cpp Thu Feb 09 19:42:39 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();
--- a/hotspot/src/share/vm/oops/methodOop.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/oops/methodOop.hpp Thu Feb 09 19:42:39 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);
--- a/hotspot/src/share/vm/opto/graphKit.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/opto/graphKit.cpp Thu Feb 09 19:42:39 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 ?
--- a/hotspot/src/share/vm/opto/library_call.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/opto/library_call.cpp Thu Feb 09 19:42:39 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(),
--- a/hotspot/src/share/vm/opto/loopnode.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/opto/loopnode.cpp Thu Feb 09 19:42:39 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;
--- a/hotspot/src/share/vm/opto/macro.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/opto/macro.cpp Thu Feb 09 19:42:39 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()); } }
--- a/hotspot/src/share/vm/prims/jvm.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/prims/jvm.cpp Thu Feb 09 19:42:39 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
--- a/hotspot/src/share/vm/prims/nativeLookup.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/prims/nativeLookup.cpp Thu Feb 09 19:42:39 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.
--- a/hotspot/src/share/vm/prims/nativeLookup.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/prims/nativeLookup.hpp Thu Feb 09 19:42:39 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);
--- a/hotspot/src/share/vm/runtime/arguments.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/runtime/arguments.cpp Thu Feb 09 19:42:39 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.
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/runtime/deoptimization.cpp Thu Feb 09 19:42:39 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<compiledVFrame*>* 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);
--- a/hotspot/src/share/vm/runtime/frame.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/runtime/frame.cpp Thu Feb 09 19:42:39 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");
--- a/hotspot/src/share/vm/runtime/globals.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/runtime/globals.hpp Thu Feb 09 19:42:39 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 " \
--- a/hotspot/src/share/vm/runtime/init.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/runtime/init.cpp Thu Feb 09 19:42:39 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()) {
--- a/hotspot/src/share/vm/runtime/mutex.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/runtime/mutex.cpp Thu Feb 09 19:42:39 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;
--- a/hotspot/src/share/vm/runtime/safepoint.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/runtime/safepoint.cpp Thu Feb 09 19:42:39 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) {
--- a/hotspot/src/share/vm/runtime/safepoint.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/runtime/safepoint.hpp Thu Feb 09 19:42:39 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_Get<Primitive>Field. // 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--; }
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Feb 09 19:42:39 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
--- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp Thu Feb 09 19:42:39 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
--- a/hotspot/src/share/vm/runtime/thread.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/runtime/thread.cpp Thu Feb 09 19:42:39 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)
--- a/hotspot/src/share/vm/runtime/thread.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/runtime/thread.hpp Thu Feb 09 19:42:39 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");
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Feb 09 19:42:39 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 */ \ /***********************************/ \
--- a/hotspot/src/share/vm/runtime/vm_version.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/runtime/vm_version.cpp Thu Feb 09 19:42:39 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") \
--- a/hotspot/src/share/vm/runtime/vm_version.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/runtime/vm_version.hpp Thu Feb 09 19:42:39 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;}
--- a/hotspot/src/share/vm/trace/traceMacros.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/trace/traceMacros.hpp Thu Feb 09 19:42:39 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
--- a/hotspot/src/share/vm/utilities/debug.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/utilities/debug.cpp Thu Feb 09 19:42:39 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
--- a/hotspot/src/share/vm/utilities/debug.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/utilities/debug.hpp Thu Feb 09 19:42:39 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 <size_t bufsz = 256> 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 <size_t bufsz> @@ -54,6 +61,24 @@ } template <size_t bufsz> +FormatBuffer<bufsz>::FormatBuffer() { + _buf[0] = '\0'; +} + +template <size_t bufsz> +void FormatBuffer<bufsz>::print(const char * format, ...) { + va_list argp; + va_start(argp, format); + jio_vsnprintf(_buf, bufsz, format, argp); + va_end(argp); +} + +template <size_t bufsz> +void FormatBuffer<bufsz>::printv(const char * format, va_list argp) { + jio_vsnprintf(_buf, bufsz, format, argp); +} + +template <size_t bufsz> void FormatBuffer<bufsz>::append(const char* format, ...) { // Given that the constructor does a vsnprintf we can assume that // _buf is already initialized.
--- a/hotspot/src/share/vm/utilities/events.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/utilities/events.cpp Thu Feb 09 19:42:39 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 +EventLog* Events::_logs = NULL; +StringEventLog* Events::_messages = NULL; +StringEventLog* Events::_exceptions = NULL; +StringEventLog* Events::_deopt_messages = NULL; -//////////////////////////////////////////////////////////////////////////// -// Event +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; +} -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); } - - 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("-<thd>-<elapsed sec>-<description>---------------------"); - - 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
--- a/hotspot/src/share/vm/utilities/events.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/utilities/events.hpp Thu Feb 09 19:42:39 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(); - // Prints all events in the buffer - static void print_all(outputStream* st) PRODUCT_RETURN; - - // Prints last number events from the event buffer - static void print_last(outputStream *st, int number) PRODUCT_RETURN; + 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 T> class EventLogBase : public EventLog { + template <class X> class EventRecord { + public: + jlong timestamp; + Thread* thread; + X data; + }; + + protected: + Mutex _mutex; + const char* _name; + int _length; + int _index; + int _count; + EventRecord<T>* _records; + + public: + EventLogBase<T>(const char* name, int length = LogEventsBufferEntries): + _name(name), + _length(length), + _count(0), + _index(0), + _mutex(Mutex::event, name) { + _records = new EventRecord<T>[length]; + } + + // 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); + + void print(outputStream* out, EventRecord<T>& 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<StringLogMessage> { + public: + StringEventLog(const char* name, int count = LogEventsBufferEntries) : EventLogBase<StringLogMessage>(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 <class T> +inline void EventLogBase<T>::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 <class T> +inline void EventLogBase<T>::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<StringLogMessage>::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
--- a/hotspot/src/share/vm/utilities/exceptions.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/utilities/exceptions.cpp Thu Feb 09 19:42:39 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); }
--- a/hotspot/src/share/vm/utilities/hashtable.hpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/utilities/hashtable.hpp Thu Feb 09 19:42:39 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);
--- a/hotspot/src/share/vm/utilities/vmError.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/utilities/vmError.cpp Thu Feb 09 19:42:39 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
--- a/hotspot/src/share/vm/utilities/xmlstream.cpp Fri Feb 03 09:57:45 2012 -0800 +++ b/hotspot/src/share/vm/utilities/xmlstream.cpp Thu Feb 09 19:42:39 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/7090976/Test7090976.java Thu Feb 09 19:42:39 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); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/7141637/SpreadNullArg.java Thu Feb 09 19:42:39 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(); + } + +}
--- a/jaxp/.hgtags Fri Feb 03 09:57:45 2012 -0800 +++ b/jaxp/.hgtags Thu Feb 09 19:42:39 2012 -0800 @@ -145,3 +145,5 @@ d41eeadf5c1344b88c5051a997aec9e1ad7ce1db jdk8-b21 cf9d6ec44f891236ad18451021d6dcd57dc82f7b jdk8-b22 95102fd334183d15dc98a95dd0d749527b6c7300 jdk8-b23 +7836655e2495646c462f13de73dcc3ada197b64f jdk8-b24 +bb694c151fc7b5c8f9edc8af6a80738530feacaf jdk8-b25
--- a/jaxws/.hgtags Fri Feb 03 09:57:45 2012 -0800 +++ b/jaxws/.hgtags Thu Feb 09 19:42:39 2012 -0800 @@ -145,3 +145,5 @@ c266cab0e3fff05f2048c23046c14d60f7102175 jdk8-b21 8d3df89b0f2d3c603b2edb0f5e24af1245397cc6 jdk8-b22 25ce7a0004874273f6aeda14e7c3538cba34bdf1 jdk8-b23 +e0d90803439b174fe0b0033e09d50444ba12498f jdk8-b24 +b376d901e006cd9e0c59733c84e190aace23eec6 jdk8-b25
--- a/jdk/.hgtags Fri Feb 03 09:57:45 2012 -0800 +++ b/jdk/.hgtags Thu Feb 09 19:42:39 2012 -0800 @@ -145,3 +145,5 @@ 664fa4fb0ee411ef048903c479f8b962fcdb2f4b jdk8-b21 dda27c73d8db4a9c7a23872b6f0c5106edcb2021 jdk8-b22 54202e0148ec7d4570cab5bc9b00d216a7677569 jdk8-b23 +34029a0c69bba882264a29fc822f8283fd15f104 jdk8-b24 +ec17fbe5b8fbc52da070eec43b4711d9354b2ab8 jdk8-b25
--- a/jdk/make/com/oracle/Makefile Fri Feb 03 09:57:45 2012 -0800 +++ b/jdk/make/com/oracle/Makefile Thu Feb 09 19:42:39 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/make/com/oracle/jfr/Makefile Thu Feb 09 19:42:39 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) +
--- a/jdk/make/common/Defs.gmk Fri Feb 03 09:57:45 2012 -0800 +++ b/jdk/make/common/Defs.gmk Thu Feb 09 19:42:39 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) #
--- a/jdk/make/common/Release-embedded.gmk Fri Feb 03 09:57:45 2012 -0800 +++ b/jdk/make/common/Release-embedded.gmk Thu Feb 09 19:42:39 2012 -0800 @@ -189,7 +189,7 @@ $(RM) -r $(JRE_REDUCED_HEADLESS_IMAGE_DIR)/lib/audio $(RM) -fr $(JRE_REDUCED_HEADLESS_IMAGE_DIR)/lib/applet $(RM) $(JRE_REDUCED_HEADLESS_IMAGE_DIR)/lib/$(LIBARCH)/awt_robot - $(RM) -r $(JRE_REDUCED_HEADLESS_IMAGE_DIR)/lib/$(LIBARCH)/xawt + $(RM) $(JRE_REDUCED_HEADLESS_IMAGE_DIR)/lib/$(LIBARCH)/libawt_xawt.so $(RM) -r $(JRE_REDUCED_HEADLESS_IMAGE_DIR)/lib/$(LIBARCH)/libsplashscreen.so @# Remove oblique fonts and reduce font support to LucidaSansRegular only $(RM) -fr $(JRE_REDUCED_HEADLESS_IMAGE_DIR)/lib/oblique-fonts
--- a/jdk/make/common/Release.gmk Fri Feb 03 09:57:45 2012 -0800 +++ b/jdk/make/common/Release.gmk Thu Feb 09 19:42:39 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) \
--- a/jdk/make/jprt.properties Fri Feb 03 09:57:45 2012 -0800 +++ b/jdk/make/jprt.properties Thu Feb 09 19:42:39 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= \
--- a/jdk/make/sun/font/Makefile Fri Feb 03 09:57:45 2012 -0800 +++ b/jdk/make/sun/font/Makefile Thu Feb 09 19:42:39 2012 -0800 @@ -175,7 +175,7 @@ ifeq ($(PLATFORM), solaris) # Note that on Solaris, fontmanager is built against the headless library. LDFLAGS += -L$(LIBDIR)/$(LIBARCH)/headless - OTHER_LDLIBS += -lawt -L$(LIBDIR)/$(LIBARCH)/xawt -lmawt -lc $(LIBM) $(LIBCXX) + OTHER_LDLIBS += -lawt -lawt_xawt -lc $(LIBM) $(LIBCXX) else # PLATFORM is linux OTHER_LDLIBS += -lawt $(LIBM) $(LIBCXX) ifeq ("$(CC_VER_MAJOR)", "3")
--- a/jdk/make/sun/font/t2k/Makefile Fri Feb 03 09:57:45 2012 -0800 +++ b/jdk/make/sun/font/t2k/Makefile Thu Feb 09 19:42:39 2012 -0800 @@ -99,7 +99,7 @@ endif else ifeq ($(PLATFORM), solaris) - OTHER_LDLIBS += -lawt -L$(LIBDIR)/$(LIBARCH)/xawt -lmawt + OTHER_LDLIBS += -lawt -lawt_xawt endif endif endif
--- a/jdk/make/sun/headless/Makefile Fri Feb 03 09:57:45 2012 -0800 +++ b/jdk/make/sun/headless/Makefile Thu Feb 09 19:42:39 2012 -0800 @@ -28,11 +28,9 @@ NO_ROBOT = true MOTIF_VERSION = none MOTIF_VERSION_STRING=none -LIB_LOCATION = $(LIBDIR)/$(LIBARCH)/headless PACKAGE = sun.awt -LIBRARY = mawt -LIBRARY_OUTPUT = headless +LIBRARY = awt_headless PRODUCT = sun include $(BUILDDIR)/common/Defs.gmk
--- a/jdk/make/sun/jawt/Makefile Fri Feb 03 09:57:45 2012 -0800 +++ b/jdk/make/sun/jawt/Makefile Thu Feb 09 19:42:39 2012 -0800 @@ -113,17 +113,17 @@ # ifeq ($(PLATFORM), solaris) ifndef BUILD_HEADLESS_ONLY - OTHER_LDLIBS = -L$(LIBDIR)/$(LIBARCH) -L$(OPENWIN_LIB) -L$(LIBDIR)/$(LIBARCH)/xawt -lmawt -L/usr/openwin/sfw/lib$(ISA_DIR) -lXrender + OTHER_LDLIBS = -L$(LIBDIR)/$(LIBARCH) -L$(OPENWIN_LIB) -lawt_xawt -L/usr/openwin/sfw/lib$(ISA_DIR) -lXrender else - OTHER_LDLIBS = -L$(LIBDIR)/$(LIBARCH) -L$(OPENWIN_LIB) -L$(LIBDIR)/$(LIBARCH)/headless -lmawt -L/usr/openwin/sfw/lib$(ISA_DIR) -lXrender + OTHER_LDLIBS = -L$(LIBDIR)/$(LIBARCH) -L$(OPENWIN_LIB) -lawt_headless -L/usr/openwin/sfw/lib$(ISA_DIR) -lXrender endif endif # PLATFORM ifeq ($(PLATFORM), linux) ifndef BUILD_HEADLESS_ONLY - OTHER_LDLIBS = -L$(LIBDIR)/$(LIBARCH) -lawt -L$(LIBDIR)/$(LIBARCH)/xawt -lmawt + OTHER_LDLIBS = -L$(LIBDIR)/$(LIBARCH) -lawt -lawt_xawt else - OTHER_LDLIBS = -L$(LIBDIR)/$(LIBARCH) -lawt -L$(LIBDIR)/$(LIBARCH)/headless -lmawt + OTHER_LDLIBS = -L$(LIBDIR)/$(LIBARCH) -lawt -lawt_headless CFLAGS += -DHEADLESS endif endif # PLATFORM
--- a/jdk/make/sun/xawt/Makefile Fri Feb 03 09:57:45 2012 -0800 +++ b/jdk/make/sun/xawt/Makefile Thu Feb 09 19:42:39 2012 -0800 @@ -25,9 +25,7 @@ BUILDDIR = ../.. PACKAGE = sun.awt.X11 -LIBRARY = mawt -LIBRARY_OUTPUT = xawt -LIB_LOCATION = $(LIBDIR)/$(LIBARCH)/xawt +LIBRARY = awt_xawt PRODUCT = sun include $(BUILDDIR)/common/Defs.gmk
--- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath2Filter.java Fri Feb 03 09:57:45 2012 -0800 +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath2Filter.java Thu Feb 09 19:42:39 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<Node> convertNodeListToSet(List<NodeList> l){ - Set<Node> result=new HashSet<Node>(); - - 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<Node> unionNodes, Set<Node> substractNodes, - Set<Node> 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<NodeList> unionNodes, List<NodeList> substractNodes, + List<NodeList> intersectNodes) { + hasUnionFilter=!unionNodes.isEmpty(); + this.unionNodes=convertNodeListToSet(unionNodes); + hasSubstractFilter=!substractNodes.isEmpty(); + this.substractNodes=convertNodeListToSet(substractNodes); + hasIntersectFilter=!intersectNodes.isEmpty(); + this.intersectNodes=convertNodeListToSet(intersectNodes); } Set<Node> unionNodes; Set<Node> 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<Node> nodeList ) { + if (nodeList.isEmpty()) { + return false; + } if (nodeList.contains(currentNode)) { return true; } @@ -302,4 +293,17 @@ static boolean inList(Node currentNode, Set<Node> nodeList ) { return nodeList.contains(currentNode); } + + private static Set<Node> convertNodeListToSet(List<NodeList> l){ + Set<Node> result=new HashSet<Node>(); + + 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; + } }
--- a/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java Fri Feb 03 09:57:45 2012 -0800 +++ b/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java Thu Feb 09 19:42:39 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); }
--- a/jdk/src/share/classes/com/sun/rowset/internal/BaseRow.java Fri Feb 03 09:57:45 2012 -0800 +++ b/jdk/src/share/classes/com/sun/rowset/internal/BaseRow.java Thu Feb 09 19:42:39 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 <code>Row</code> @@ -65,7 +66,8 @@ * original values */ public Object[] getOrigRow() { - return origVals; + Object[] origRow = this.origVals; + return (origRow == null) ? null: Arrays.copyOf(origRow, origRow.length); } /**
--- a/jdk/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java Fri Feb 03 09:57:45 2012 -0800 +++ b/jdk/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java Thu Feb 09 19:42:39 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 <code>java.io.Writer</code> object given * as the second argument to the <code>writeXML</code> method. */ - private java.io.Writer writer; + private transient java.io.Writer writer; /** * The <code>java.util.Stack</code> object that this <code>WebRowSetXmlWriter</code> @@ -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<String, Class<?>> typeMap = caller.getTypeMap(); + if(typeMap != null) { + for(Map.Entry<String, Class<?>> mm : typeMap.entrySet()) { + propString("type", mm.getKey()); + propString("class", mm.getValue().getName()); } } endSection("map");
--- a/jdk/src/share/classes/java/awt/datatransfer/MimeType.java Fri Feb 03 09:57:45 2012 -0800 +++ b/jdk/src/share/classes/java/awt/datatransfer/MimeType.java Thu Feb 09 19:42:39 2012 -0800 @@ -30,6 +30,7 @@ import java.io.ObjectInput; import java.io.IOException; import java.util.Enumeration; +import java.util.Locale; /** @@ -93,14 +94,14 @@ MimeTypeParseException { // check to see if primary is valid if(isValidToken(primary)) { - primaryType = primary.toLowerCase(); + primaryType = primary.toLowerCase(Locale.ENGLISH); } else { throw new MimeTypeParseException("Primary type is invalid."); } // check to see if sub is valid if(isValidToken(sub)) { - subType = sub.toLowerCase(); + subType = sub.toLowerCase(Locale.ENGLISH); } else { throw new MimeTypeParseException("Sub type is invalid."); } @@ -158,17 +159,17 @@ throw new MimeTypeParseException("Unable to find a sub type."); } else if((slashIndex >= 0) && (semIndex < 0)) { // we have a primary and sub type but no parameter list - primaryType = rawdata.substring(0, -slashIndex).trim().toLowerCase(); - subType = rawdata.substring(slashIndex + -1).trim().toLowerCase(); + primaryType = rawdata.substring(0,slashIndex). + trim().toLowerCase(Locale.ENGLISH); + subType = rawdata.substring(slashIndex + 1). + trim().toLowerCase(Locale.ENGLISH); parameters = new MimeTypeParameterList(); } else if (slashIndex < semIndex) { // we have all three items in the proper sequence - primaryType = rawdata.substring(0, -slashIndex).trim().toLowerCase(); + primaryType = rawdata.substring(0, slashIndex). + trim().toLowerCase(Locale.ENGLISH); subType = rawdata.substring(slashIndex + 1, -semIndex).trim().toLowerCase(); + semIndex).trim().toLowerCase(Locale.ENGLISH); parameters = new MimeTypeParameterList(rawdata.substring(semIndex)); } else {
--- a/jdk/src/share/classes/java/awt/event/MouseEvent.java Fri Feb 03 09:57:45 2012 -0800 +++ b/jdk/src/share/classes/java/awt/event/MouseEvent.java Thu Feb 09 19:42:39 2012 -0800 @@ -758,7 +758,6 @@ if (getModifiersEx() != 0) { //There is at least one more button in a pressed state. if (id == MouseEvent.MOUSE_RELEASED || id == MouseEvent.MOUSE_CLICKED){ - System.out.println("MEvent. CASE!"); shouldExcludeButtonFromExtModifiers = true; } }
--- a/jdk/src/share/classes/java/beans/BeanInfo.java Fri Feb 03 09:57:45 2012 -0800 +++ b/jdk/src/share/classes/java/beans/BeanInfo.java Thu Feb 09 19:42:39 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 1999, 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 @@ -25,134 +25,134 @@ package java.beans; +import java.awt.Image; + /** - * A bean implementor who wishes to provide explicit information about - * their bean may provide a BeanInfo class that implements this BeanInfo - * interface and provides explicit information about the methods, - * properties, events, etc, of their bean. + * Use the {@code BeanInfo} interface + * to create a {@code BeanInfo} class + * and provide explicit information about the methods, + * properties, events, and other features of your beans. * <p> - * A bean implementor doesn't need to provide a complete set of - * explicit information. You can pick and choose which information - * you want to provide and the rest will be obtained by automatic - * analysis using low-level reflection of the bean classes' methods + * When developing your bean, you can implement + * the bean features required for your application task + * omitting the rest of the {@code BeanInfo} features. + * They will be obtained through the automatic analysis + * by using the low-level reflection of the bean methods * and applying standard design patterns. + * You have an opportunity to provide additional bean information + * through various descriptor classes. * <p> - * You get the opportunity to provide lots and lots of different - * information as part of the various XyZDescriptor classes. But - * don't panic, you only really need to provide the minimal core - * information required by the various constructors. - * <P> - * See also the SimpleBeanInfo class which provides a convenient - * "noop" base class for BeanInfo classes, which you can override - * for those specific places where you want to return explicit info. - * <P> - * To learn about all the behaviour of a bean see the Introspector class. + * See the {@link SimpleBeanInfo} class that is + * a convenient basic class for {@code BeanInfo} classes. + * You can override the methods and properties of + * the {@code SimpleBeanInfo} class to define specific information. + * <p> + * See also the {@link Introspector} class to learn more about bean behavior. */ - public interface BeanInfo { /** - * Gets the beans <code>BeanDescriptor</code>. + * Returns the bean descriptor + * that provides overall information about the bean, + * such as its display name or its customizer. * - * @return A BeanDescriptor providing overall information about - * the bean, such as its displayName, its customizer, etc. May - * return null if the information should be obtained by automatic - * analysis. + * @return a {@link BeanDescriptor} object, + * or {@code null} if the information is to + * be obtained through the automatic analysis */ BeanDescriptor getBeanDescriptor(); /** - * Gets the beans <code>EventSetDescriptor</code>s. + * Returns the event descriptors of the bean + * that define the types of events fired by this bean. * - * @return An array of EventSetDescriptors describing the kinds of - * events fired by this bean. May return null if the information - * should be obtained by automatic analysis. + * @return an array of {@link EventSetDescriptor} objects, + * or {@code null} if the information is to + * be obtained through the automatic analysis */ EventSetDescriptor[] getEventSetDescriptors(); /** - * A bean may have a "default" event that is the event that will - * mostly commonly be used by humans when using the bean. - * @return Index of default event in the EventSetDescriptor array - * returned by getEventSetDescriptors. - * <P> Returns -1 if there is no default event. + * A bean may have a default event typically applied when this bean is used. + * + * @return index of the default event in the {@code EventSetDescriptor} array + * returned by the {@code getEventSetDescriptors} method, + * or -1 if there is no default event */ int getDefaultEventIndex(); /** * Returns descriptors for all properties of the bean. - * May return {@code null} if the information - * should be obtained by automatic analysis. * <p> * If a property is indexed, then its entry in the result array - * will belong to the {@link IndexedPropertyDescriptor} subclass + * belongs to the {@link IndexedPropertyDescriptor} subclass * of the {@link PropertyDescriptor} class. * A client of the {@code getPropertyDescriptors} method - * can use "{@code instanceof}" to check + * can use the {@code instanceof} operator to check * whether a given {@code PropertyDescriptor} * is an {@code IndexedPropertyDescriptor}. * - * @return an array of {@code PropertyDescriptor}s - * describing all properties supported by the bean - * or {@code null} + * @return an array of {@code PropertyDescriptor} objects, + * or {@code null} if the information is to + * be obtained through the automatic analysis */ PropertyDescriptor[] getPropertyDescriptors(); /** - * A bean may have a "default" property that is the property that will - * mostly commonly be initially chosen for update by human's who are - * customizing the bean. - * @return Index of default property in the PropertyDescriptor array - * returned by getPropertyDescriptors. - * <P> Returns -1 if there is no default property. + * A bean may have a default property commonly updated when this bean is customized. + * + * @return index of the default property in the {@code PropertyDescriptor} array + * returned by the {@code getPropertyDescriptors} method, + * or -1 if there is no default property */ int getDefaultPropertyIndex(); /** - * Gets the beans <code>MethodDescriptor</code>s. + * Returns the method descriptors of the bean + * that define the externally visible methods supported by this bean. * - * @return An array of MethodDescriptors describing the externally - * visible methods supported by this bean. May return null if - * the information should be obtained by automatic analysis. + * @return an array of {@link MethodDescriptor} objects, + * or {@code null} if the information is to + * be obtained through the automatic analysis */ MethodDescriptor[] getMethodDescriptors(); /** - * This method allows a BeanInfo object to return an arbitrary collection - * of other BeanInfo objects that provide additional information on the - * current bean. - * <P> - * If there are conflicts or overlaps between the information provided - * by different BeanInfo objects, then the current BeanInfo takes precedence - * over the getAdditionalBeanInfo objects, and later elements in the array - * take precedence over earlier ones. + * This method enables the current {@code BeanInfo} object + * to return an arbitrary collection of other {@code BeanInfo} objects + * that provide additional information about the current bean. + * <p> + * If there are conflicts or overlaps between the information + * provided by different {@code BeanInfo} objects, + * the current {@code BeanInfo} object takes priority + * over the additional {@code BeanInfo} objects. + * Array elements with higher indices take priority + * over the elements with lower indices. * - * @return an array of BeanInfo objects. May return null. + * @return an array of {@code BeanInfo} objects, + * or {@code null} if there are no additional {@code BeanInfo} objects */ BeanInfo[] getAdditionalBeanInfo(); /** - * This method returns an image object that can be used to - * represent the bean in toolboxes, toolbars, etc. Icon images - * will typically be GIFs, but may in future include other formats. + * Returns an image that can be used to represent the bean in toolboxes or toolbars. * <p> - * Beans aren't required to provide icons and may return null from - * this method. - * <p> - * There are four possible flavors of icons (16x16 color, - * 32x32 color, 16x16 mono, 32x32 mono). If a bean choses to only - * support a single icon we recommend supporting 16x16 color. - * <p> - * We recommend that icons have a "transparent" background - * so they can be rendered onto an existing background. + * There are four possible types of icons: + * 16 x 16 color, 32 x 32 color, 16 x 16 mono, and 32 x 32 mono. + * If you implement a bean so that it supports a single icon, + * it is recommended to use 16 x 16 color. + * Another recommendation is to set a transparent background for the icons. * - * @param iconKind The kind of icon requested. This should be - * one of the constant values ICON_COLOR_16x16, ICON_COLOR_32x32, - * ICON_MONO_16x16, or ICON_MONO_32x32. - * @return An image object representing the requested icon. May - * return null if no suitable icon is available. + * @param iconKind the kind of icon requested + * @return an image object representing the requested icon, + * or {@code null} if no suitable icon is available + * + * @see #ICON_COLOR_16x16 + * @see #ICON_COLOR_32x32 + * @see #ICON_MONO_16x16 + * @see #ICON_MONO_32x32 */ - java.awt.Image getIcon(int iconKind); + Image getIcon(int iconKind); /** * Constant to indicate a 16 x 16 color icon.
--- a/jdk/src/share/classes/java/beans/Introspector.java Fri Feb 03 09:57:45 2012 -0800 +++ b/jdk/src/share/classes/java/beans/Introspector.java Thu Feb 09 19:42:39 2012 -0800 @@ -473,7 +473,7 @@ // Now analyze each method. for (int i = 0; i < methodList.length; i++) { Method method = methodList[i]; - if (method == null || method.isSynthetic()) { + if (method == null) { continue; } // skip static methods.
--- a/jdk/src/share/classes/java/beans/PropertyDescriptor.java Fri Feb 03 09:57:45 2012 -0800 +++ b/jdk/src/share/classes/java/beans/PropertyDescriptor.java Thu Feb 09 19:42:39 2012 -0800 @@ -559,7 +559,7 @@ // Normally give priority to y's readMethod. try { - if (yr != null && yr.getDeclaringClass() == getClass0()) { + if (isAssignable(xr, yr)) { setReadMethod(yr); } else { setReadMethod(xr); @@ -713,4 +713,37 @@ appendTo(sb, "readMethod", this.readMethodRef); appendTo(sb, "writeMethod", this.writeMethodRef); } + + private boolean isAssignable(Method m1, Method m2) { + if (m1 == null) { + return true; // choose second method + } + if (m2 == null) { + return false; // choose first method + } + if (!m1.getName().equals(m2.getName())) { + return true; // choose second method by default + } + Class<?> type1 = m1.getDeclaringClass(); + Class<?> type2 = m2.getDeclaringClass(); + if (!type1.isAssignableFrom(type2)) { + return false; // choose first method: it declared later + } + type1 = getReturnType(getClass0(), m1); + type2 = getReturnType(getClass0(), m2); + if (!type1.isAssignableFrom(type2)) { + return false; // choose first method: it overrides return type + } + Class<?>[] args1 = getParameterTypes(getClass0(), m1); + Class<?>[] args2 = getParameterTypes(getClass0(), m2); + if (args1.length != args2.length) { + return true; // choose second method by default + } + for (int i = 0; i < args1.length; i++) { + if (!args1[i].isAssignableFrom(args2[i])) { + return false; // choose first method: it overrides parameter + } + } + return true; // choose second method + } }
--- a/jdk/src/share/classes/java/io/DataInput.java Fri Feb 03 09:57:45 2012 -0800 +++ b/jdk/src/share/classes/java/io/DataInput.java Thu Feb 09 19:42:39 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 <code>DataInput</code> 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 <code>String</code> + * facility for reconstructing a {@code String} * from data in * <a href="#modified-utf-8">modified UTF-8</a> * 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 <code>EOFException</code> - * (which is a kind of <code>IOException</code>) + * 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 <code>IOException</code> - * other than <code>EOFException</code> is - * thrown. In particular, an <code>IOException</code> + * 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. * <p> - * All characters in the range <code>'\u0001'</code> to - * <code>'\u007F'</code> are represented by a single byte: + * All characters in the range {@code '\u005Cu0001'} to + * {@code '\u005Cu007F'} are represented by a single byte: * * <blockquote> * <table border="1" cellspacing="0" cellpadding="8" width="50%" @@ -83,8 +83,8 @@ * </blockquote> * * <p> - * The null character <code>'\u0000'</code> and characters in the - * range <code>'\u0080'</code> to <code>'\u07FF'</code> are + * The null character {@code '\u005Cu0000'} and characters in the + * range {@code '\u005Cu0080'} to {@code '\u005Cu07FF'} are * represented by a pair of bytes: * * <blockquote> @@ -123,8 +123,8 @@ * </blockquote> * * <br> - * <code>char</code> values in the range <code>'\u0800'</code> to - * <code>'\uFFFF'</code> are represented by three bytes: + * {@code char} values in the range {@code '\u005Cu0800'} to + * {@code '\u005CuFFFF'} are represented by three bytes: * * <blockquote> * <table border="1" cellspacing="0" cellpadding="8" width="50%" @@ -178,7 +178,7 @@ * The differences between this format and the * standard UTF-8 format are the following: * <ul> - * <li>The null byte <code>'\u0000'</code> is encoded in 2-byte format + * <li>The null byte {@code '\u005Cu0000'} is encoded in 2-byte format * rather than 1-byte, so that the encoded strings never have * embedded nulls. * <li>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 <code>b</code>. The number of bytes + * array {@code b}. The number of bytes * read is equal - * to the length of <code>b</code>. + * to the length of {@code b}. * <p> * This method blocks until one of the * following conditions occurs:<p> * <ul> - * <li><code>b.length</code> + * <li>{@code b.length} * bytes of input data are available, in which * case a normal return is made. * * <li>End of - * file is detected, in which case an <code>EOFException</code> + * file is detected, in which case an {@code EOFException} * is thrown. * * <li>An I/O error occurs, in - * which case an <code>IOException</code> other - * than <code>EOFException</code> is thrown. + * which case an {@code IOException} other + * than {@code EOFException} is thrown. * </ul> * <p> - * If <code>b</code> is <code>null</code>, - * a <code>NullPointerException</code> is thrown. - * If <code>b.length</code> 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 <code>b[0]</code>, - * the next one into <code>b[1]</code>, 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 <code>b</code> 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 <code>len</code> + * Reads {@code len} * bytes from * an input stream. * <p> @@ -244,32 +244,32 @@ * blocks until one of the following conditions * occurs:<p> * <ul> - * <li><code>len</code> bytes + * <li>{@code len} bytes * of input data are available, in which case * a normal return is made. * * <li>End of file - * is detected, in which case an <code>EOFException</code> + * is detected, in which case an {@code EOFException} * is thrown. * * <li>An I/O error occurs, in - * which case an <code>IOException</code> other - * than <code>EOFException</code> is thrown. + * which case an {@code IOException} other + * than {@code EOFException} is thrown. * </ul> * <p> - * If <code>b</code> is <code>null</code>, - * a <code>NullPointerException</code> is thrown. - * If <code>off</code> is negative, or <code>len</code> - * is negative, or <code>off+len</code> is - * greater than the length of the array <code>b</code>, - * then an <code>IndexOutOfBoundsException</code> + * 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 <code>len</code> is zero, + * If {@code len} is zero, * then no bytes are read. Otherwise, the first - * byte read is stored into element <code>b[off]</code>, - * the next one into <code>b[off+1]</code>, + * 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 <code>len</code>. + * 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 - * <code>n</code> 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 <code>n</code> bytes + * end of file before {@code n} bytes * have been skipped is * only one possibility. - * This method never throws an <code>EOFException</code>. + * 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 - * <code>true</code> if that byte is nonzero, - * <code>false</code> 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 <code>writeBoolean</code> - * method of interface <code>DataOutput</code>. + * the byte written by the {@code writeBoolean} + * method of interface {@code DataOutput}. * - * @return the <code>boolean</code> 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 <code>-128</code> through <code>127</code>, + * the range {@code -128} through {@code 127}, * inclusive. * This method is suitable for - * reading the byte written by the <code>writeByte</code> - * method of interface <code>DataOutput</code>. + * 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 <code>int</code>, and returns + * it to type {@code int}, and returns * the result, which is therefore in the range - * <code>0</code> - * through <code>255</code>. + * {@code 0} + * through {@code 255}. * This method is suitable for reading - * the byte written by the <code>writeByte</code> - * method of interface <code>DataOutput</code> - * if the argument to <code>writeByte</code> + * 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 - * <code>0</code> through <code>255</code>. + * {@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 <code>short</code> value. Let <code>a</code> - * be the first byte read and <code>b</code> + * 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 @@ * </code></pre> * This method * is suitable for reading the bytes written - * by the <code>writeShort</code> method of - * interface <code>DataOutput</code>. + * 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 <code>int</code> value in the range <code>0</code> - * through <code>65535</code>. Let <code>a</code> + * an {@code int} value in the range {@code 0} + * through {@code 65535}. Let {@code a} * be the first byte read and - * <code>b</code> + * {@code b} * be the second byte. The value returned is: * <p><pre><code>(((a & 0xff) << 8) | (b & 0xff)) * </code></pre> * This method is suitable for reading the bytes - * written by the <code>writeShort</code> method - * of interface <code>DataOutput</code> if - * the argument to <code>writeShort</code> + * 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 - * <code>0</code> through <code>65535</code>. + * {@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 <code>char</code> value. - * Let <code>a</code> - * be the first byte read and <code>b</code> + * 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: * <p><pre><code>(char)((a << 8) | (b & 0xff)) * </code></pre> * This method * is suitable for reading bytes written by - * the <code>writeChar</code> method of interface - * <code>DataOutput</code>. + * the {@code writeChar} method of interface + * {@code DataOutput}. * - * @return the <code>char</code> 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 - * <code>int</code> value. Let <code>a-d</code> + * {@code int} value. Let {@code a-d} * be the first through fourth bytes read. The value returned is: - * <p><pre> - * <code> + * <p><pre><code> * (((a & 0xff) << 24) | ((b & 0xff) << 16) | *  ((c & 0xff) << 8) | (d & 0xff)) * </code></pre> * This method is suitable - * for reading bytes written by the <code>writeInt</code> - * method of interface <code>DataOutput</code>. + * for reading bytes written by the {@code writeInt} + * method of interface {@code DataOutput}. * - * @return the <code>int</code> 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 <code>long</code> value. Let <code>a-h</code> + * a {@code long} value. Let {@code a-h} * be the first through eighth bytes read. * The value returned is: - * <p><pre> <code> + * <p><pre><code> * (((long)(a & 0xff) << 56) | * ((long)(b & 0xff) << 48) | * ((long)(c & 0xff) << 40) | @@ -455,10 +454,10 @@ * </code></pre> * <p> * This method is suitable - * for reading bytes written by the <code>writeLong</code> - * method of interface <code>DataOutput</code>. + * for reading bytes written by the {@code writeLong} + * method of interface {@code DataOutput}. * - * @return the <code>long</code> 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 <code>float</code> value. It does this - * by first constructing an <code>int</code> + * a {@code float} value. It does this + * by first constructing an {@code int} * value in exactly the manner - * of the <code>readInt</code> - * method, then converting this <code>int</code> - * value to a <code>float</code> in - * exactly the manner of the method <code>Float.intBitsToFloat</code>. + * 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 <code>writeFloat</code> - * method of interface <code>DataOutput</code>. + * bytes written by the {@code writeFloat} + * method of interface {@code DataOutput}. * - * @return the <code>float</code> 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 <code>double</code> value. It does this - * by first constructing a <code>long</code> + * a {@code double} value. It does this + * by first constructing a {@code long} * value in exactly the manner - * of the <code>readlong</code> - * method, then converting this <code>long</code> - * value to a <code>double</code> in exactly - * the manner of the method <code>Double.longBitsToDouble</code>. + * 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 <code>writeDouble</code> - * method of interface <code>DataOutput</code>. + * bytes written by the {@code writeDouble} + * method of interface {@code DataOutput}. * - * @return the <code>double</code> 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 <code>String</code>. Note + * returned as a {@code String}. Note * that because this * method processes bytes, * it does not support input of the full Unicode * character set. * <p> * If end of file is encountered - * before even one byte can be read, then <code>null</code> + * before even one byte can be read, then {@code null} * is returned. Otherwise, each byte that is - * read is converted to type <code>char</code> - * by zero-extension. If the character <code>'\n'</code> + * 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 <code>'\r'</code> + * ceases. If the character {@code '\r'} * is encountered, it is discarded and, if * the following byte converts  to the - * character <code>'\n'</code>, 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 <code>'\n'</code> and - * <code>'\r'</code> is encountered, reading - * ceases. Once reading has ceased, a <code>String</code> + * of the characters {@code '\n'} and + * {@code '\r'} is encountered, reading + * ceases. Once reading has ceased, a {@code Stri